Re: A86: Re: New operating system...


[Prev][Next][Index][Thread]

Re: A86: Re: New operating system...




At 13:31 1999-02-23 -0600, you wrote:

>This is probably the wrong place to ask this, can you explain how Usgard
>relocation works?  As I said before, I spent a good while trying to figure
>it out but the doc's didn't exactly tell you how the preprocessor and shell
>worked :)  All I've programmed for is the 86 meaning fixed-address
>relocation, so if fixed address is the best then I have nothing else to
>compare it to.

"fixed-address relocation"? I wouldn't call it relocation at all, as the
program is simply copied to $D748. Rigel has to move around vars in the
VAT - that's relocation.

> In no way did I want to insult Usgard.  I know it's much better than
>ZShell, and writing any kind of asm shell for a calculator that doesn't even
>support it is a great feat and the authors should be commended.  But what I
>meant (and I did say everything was IMHO) was that fixed style relocation
>_seems_ to me to be much better than Usgard style relocation.

It's easier to program when a program starts at a fixed address as you
don't need to specify in the source what address has to be relocated (done
in Usgard using the & char).

>The 86 along with the 82 and 83 shells use fixed-address relocation, so I
>would assume it's better.  I would be much appreciative if you could explain
>how the relocation table works, along with how the shell and preprocessor
>work.

On the 86 they have reserved memory for an asm program. Upon executing, the
program is simply compied to the reserved memory location. That's _very_
easy to do. That was of course not possible on the 85, with only 28k free

RAM. The 82/83 moves around the vars so the program you are to execute
comes first (I believe). Since this is done by the ROM, you simply just
move the program first. HOWEVER, on the 85/86, you need a program in RAM
which does this. This program (the shell) ALSO has to be at a fixed RAM
location as it gets called by the user program (ROM calls and other shell
functions, like executing another program etc). So you have two programs
which must be at a fixed location. Assuming the shell is 2k, and the shell
starts at $8000, the user program has to be relocated to $8800. But if you
are to update the shell later on, so it gets 50 bytes bigger, then the user
program has to be relocated to $8832 ==> no backward compatibility unless
you "waste" some memory (which Rigel did, though not much).

Well, that was on the 85. On the 86, things are a bit different, especially
if you are to write a complete new OS...


As for Usgard relocation, a lot of people seems to think it takes two bytes
per address to be patched which is wrong. An example below illustrates this:

(& indicates a relocation, xx=opcode/byte)

Addr   Opcode  Mnemonic (sp?)
----   ------  ---------------
0000   CD      call &InitProgram
0003   xx1200  ld hl,&pic
0006   xx00FC  ld de,$FC00
0009   xx0004  ld bc,$400
000C   EDxx    ldir
000E   CDxxxx  call OTH_PAUSE   ; usgard function - fixed in usgard shell
0011   C9      ret
Pic:
0012   xx * $400 (picture data)
InitProgram:
0412   CDxxxx  call ClrLCD      ; or whatever the function was called...
0415   xx1904  ld a,(&chksum)   ; just to get another relocation...
0418   C9      ret
chksum:
0419   xx      ; whatever...

This program contains 3 address to be patched. Usgard (or srcwiz.exe) then
adds a table at the end of the program which will look like this:

041A   01      ; Patch address 0001 (relative location from 0000)
041B   03      ; Addr 0001+0003 (=0004) (again relative)
041C   001604  ; Patch address 0416 (absolute address, indicated by 00)
041F   FBFF    ; FFFB = -5 = address to add to 041F to get to start of table

(I don't remember if Usgard uses exactly this format, but something similar)

So, only one byte per address is needed if the offset to the last patched
address is less than 256. Else it takes 3 bytes, as the 00 indicates
that an absolute patching address is about to follow (this word could
be relative as well as absolute btw). It's interesting to note that
if the InitProgram function was moved before the pic data, the program
would become one byte smaller... (another reason for having all the
data in the end of the program).

When I programmed in Usgard, the srcwiz program wrote how many relocation
of each type (relative, absolute) was necessary, and in all my programs,
only relative relocation was needed. Thus, 1 byte per relocation (+2
for the pointer at the end)

No end-of-table address is needed as the relocation routine can check if the
current table address equals the last word in the variable...

(NOTE: the 01 mark _could_ be used to indicate a relative address
256-511. This is probably pretty unnecessary as it probably loses memory in
the
end as the relocation routine gets bigger).


I hope this clarifies how Usgard relocation work as well as fixed-address
relocation in Rigel.

(I think I'll include this mail in the Usgard FAQ...)

//Jimmy Mårdell

E-mail: yarin@acc.umu.se
Homepage: http://www.acc.umu.se/~yarin/



References: