Comments (3)
hey @breakintoprogram thanks for your insights. (sorry to keep you hanging - I'd intended to respond sooner - took me a while to get over a cold...)
you are of course entirely correct as to how this was practical on a Beeb. the differences and parallels are very interesting.
it's a shame that the eZ80 works in 64kb segments. the restriction of using only z80 code in a segment (and no C) feels like something that could be lived with, but the segment size is really too large to dedicate to a single module. if only there were smaller segments, like 16kb, then this approach would probably be practical, but it is not to be.
this leaves the idea of relocating (e)Z80 code. as you say, doing that at run-time is not trivial. I think though that there may be ways to make it practical.
scanning thru a binary and working out new addresses for absolute jumps, assuming you know the original execution address, and then changing them to be based off a new base address, is not really that hard. if only things were that simple. 😁
as I see it, the main difficulty is jump tables. these are a much harder problem. it may be just about possible to work out code that's doing a jump table, but it's virtually impossible to work out where within a binary file a table begins and ends.
but I have an idea...
I did a great deal of my "learn z80" work by reading the Ms. Pac-Man code. in that code, RST 20
is a jump table handler. this means is that the pacman code only has one way of doing jump tables, so anywhere a jump table is needed there's an RST 20
instruction followed by a list of jump addresses.
what if we had a similar "jump table handler" RST in MOS?
the exact implementation used in pacman is fairly straightforward, but would not be exactly suitable for our needs - we'd probably want to add in a "length" at the beginning of the table so we know how long it is.
having such a RST call means that we could scan thru a binary to find such an instruction and therefore to find jump tables, and then be able to adjust the addresses in that table.
the remaining difficulty in relocating a module would be areas of non-code in the binary. when relocating a module there's essentially two ways to go about things - either non-code areas would need to be "marked" in some way so the relocation routine could skip over them, or the relocation routine could "walk the code" to find all the potential executable code paths. obviously there are issues around this in terms of routines that use addresses of data that need some more thought than I'm giving here in this comment. perhaps there's potential for another RST
call for "get address of data block" (needs more thought).
another potential issue with relocatable ez80 code is self-modifying code, but, well, let's just ignore that. the rules for relocatable modules in MOS should include "no self-modifying code" - essentially the module is a ROM.
these ideas probably mean that relocatable MOS modules would be restricted to assembler (as who knows what a C compiler will produce) but that feels like it could be a reasonable compromise.
from agon-mos.
This is made possible by the BBC Micro being able to page a ROM into a 16K block from address &8000; code can therefore be assembled to run at that address.
In ADL mode, the eZ80 code is compiled / assembled to the address where the code is to execute. Relocating Z80 code at runtime is not trivial.
In Z80 mode, the Z80 code runs within a 64K segment, and the segment can be relocated, but must fall on a 64K boundary. This is achieved by setting the eZ80 MB register, which effectively forms the most significant byte of the address space (bits 16-23), thus where that 64K sits in memory. So each module would occupy 64K & have to be written in Z80 mode. This precludes C, which requires ADL mode.
MOS gets around this by compiling any external MOS command at a fixed address, and this is a reserved block at the top of memory.
from agon-mos.
We could introduce a new style of binary that starts with a header telling that it's a relocatable module. Then incorporate a relative address table with relative addresses need updating in the binary after loading.
Example from MSXDOS in Z80 mode. Something similar could be made for ADL mode.
START:
LD HL, _RAT
LD BC, SOURCE
LD DE, 4000h
CALL RELOCATE
RET
_RAT: DEFW R000C-SOURCE
DEFW R001E+1-SOURCE
DEFW R002F-SOURCE
DEFW 0FFFFH
SOURCE: PUSH IX
PUSH IY
PUSH HL
PUSH DE
PUSH BC
PUSH AF
EXX
EX AF,AF'
PUSH AF
PUSH HL
R000C: LD HL,(D635E+1)
LD A,L
OR H
POP HL
LD IX,KEYINT
LD IY,(EXPTBL+0-1)
JR NZ,J6375
POP AF
R001E: LD (D635E+1),SP
R0021: LD SP,0
CALL CALSLT
DI
D635E: LD SP,0
PUSH HL
LD HL,0
R002F: LD (D635E+1),HL
POP HL
J6369: EX AF,AF'
EXX
POP AF
POP BC
POP DE
A636E: POP HL
POP IY
POP IX
EI
RET
RELOCATE: PUSH DE ; DE = destination, HL = reloctable, BC = source
EX DE,HL
AND A
SBC HL,BC ; delta dest - source
PUSH HL
POP IX ; delta in IX
EX DE,HL
POP DE
J6310: LD C,(HL) ; DE = destination, HL = ptr start reloctable, BC = source
INC HL
LD B,(HL) ; BC holds contents reloctable entry
INC HL
LD A,C
AND B
INC A
RET Z ; ffffh to signal end of relocation table
PUSH DE ; DE = destination, HL = ptr to next entry reloctable, BC reloctable entry
EX DE,HL
ADD HL,BC ; destination + reloctable entry
INC HL ; +1
LD C,(HL)
INC HL
LD B,(HL) ; BC = current contents of destination memory
PUSH HL
PUSH IX
POP HL ; HL = delta
ADD HL,BC ; calculate new value
LD C,L
LD B,H ; BC is new value
POP HL ; HL = ptr to next entry reloctable
LD (HL),B
DEC HL
LD (HL),C ; update contents of destination memory with new value
EX DE,HL
POP DE
JR J6310 ; next entry
from agon-mos.
Related Issues (20)
- Release needs to include/provide hash. HOT 2
- Potential issue with stack splat in exec16 from *RUN <addr> HOT 2
- Using MOS to load a picture directly to the screen, possible ?
- moscall mos_fread in Z80 mode loads only zeros HOT 2
- Documentation about mos_getkbmap HOT 2
- [Feature request]A mos command to load an image to the screen
- Cannot detect retrieval of data from VDP via API HOT 1
- Feature Request: Allocate the null terminal \0 after "MOS" @ $40 for versioning. HOT 1
- mos_getkey responds to shift.
- Date and Time not being updated HOT 8
- Handle final packet(s) from VDP after switching to terminal mode
- Multi-line command history inconsistent behavior HOT 4
- Boot skip
- UART0 full-duplex CTS/RTS HOT 8
- Use 0 wait states for Flash ROM HOT 4
- incorrect work mos 1.04
- RTC info in VDP Protocol doesn't actually fit
- [help wanted] VBlank from assembly ? HOT 1
- Can't get two keycodes simultaneously neither in alternance
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from agon-mos.