I feel that what is suggested is way more than necessary, let the
computer do most of the work...
The way the Mac does it is by focusing on 32-64k blocks of pure code with
all internalsegment calls being 16bit pc-relative offsets. The only far
calls are made segment to segment.
How is this handled? One of the registers 'A5' points to what is called
the 'A5 World' which in part contains all of the intersegment jumps code
consisting of two states, Unloaded: Segment offset, Move Code Segment #
to Stack, System call to load and jump to the Segment; Loaded: a far jump
into the desired segment.
Yes, I know that IBM-PC is not a Mac and does not have all many registers
but ELKS does not use all of them anyway! IIRC the ES register is not
used and thus can be used in much the same way. Also, PC code is usually
riddled with Int calls so why not use something like this...
/*
any block of code
*/
mov #0x0000,ax
Int IntersegmentCall
/*
Inside interrupt call
*/
IntersegmentCall:
cmp #0x0003,ax
jg BadCall
rol ax,#0x01
rol ax,#0x01
mov ax,si
pop ax
pop ax
mov call_table[si],ax
push ax
mov call_table[si],ax
iret
call_table:
jmp far_call1
jmp far_call2
jmp far_call3
or like this...
/*
any block of code
*/
mov #0x0000,ax
call IntersegmentCall
/*
Inside intersegment call function
*/
IntersegmentCall:
cmp #0x0003,ax
jg BadCall
rol ax,#0x01
rol ax,#0x01
mov ax,si
jmp call_table[si]
call_table:
jmp far_call1
jmp far_call2
jmp far_call3