jds wrote:
The one that is a bit harder to understand is making pointers 4 bytes. Pushing the DB to the stack will always push one byte...
Pushing
DB is unnecessary for stack relative operations, if that is what you are doing. It's also unnecessary if an arbitrary application is calling a function that needs to know in which bank the application is reading and writing data. I'll let you think about why this would be true.
Quote:
...so to expand the pointer you'd need to first push a 1 byte $00 (or possibly any convenient byte value as it's ignored), I haven't found a way to push a $00 to the stack when in 16-bit mode, so I guess that the easiest thing to do would be to push the DB twice.
You could try something like the following:
Code:
; write PB on stack as a word...
;
pea #0 ;write $0000 to SP & SP-1
tsc ;get SP
inc a ;SP = SP + 1
sei ;ignore IRQs
tcs ;set new stack pointer
phb ;push DB
cli ;enable IRQs
The above code assumes the accumulator is 16 bits wide. When executed, whatever is in
PB will be at
SP+1 and
$00 will be at
$SP+2. If
PB were
$21 when the above was executed and you were to later execute
LDA $1,S (assuming the accumulator remains in 16 bit mode) the accumulator would contain
$0021.
Another method would be as follows:
Code:
; push PB as a word to stack...
;
ldx #0 ;assumes .X is 8 bits
phx ;push it
phb ;push DB
The above accomplishes the same thing as the previous code fragment, but is predicated on the index registers being 8 bits wide and you being willing to clobber
.X (or
.Y).
Quote:
So to push a pointer for a system call you'd need something like this:
Code:
PHB ; Push a meaningless byte
PHB ; Push the data bank for real
PEA Buffer ; Buffer is a data label
JSL SysCall
...I've found this interesting because the IIgs operating system is probably the largest body of 65C816 code that was written, so there are probably many things that could be learned from it.
Something to ponder is when the IIgs was in production the 65C816 was very new and thanks(?) to the poor quality of documentation that came from WDC in those days, was not well understood, even by Apple's software engineers. It wasn't until the Eyes & Lichty programming manual was released in 1986 that significant information became available. I would not consider the IIgs operating system to be a best-case example of a source of information on the '816. Things have changed a bit in the last 30 years, y'know.
Incidentally, a better (in my opinion) way of implementing system calls (aka kernel calls) with the '816 is to use the
COP software interrupt. This method, as opposed to using
JSR or
JSL via a jump table, has the distinct advantage of not exposing kernel memory directly to user applications. Also, user applications only have to know API index numbers to make the call, not actual addresses. See
this web page for some information on how to go about it.