From 71b57d08cb5bcb5c497cfeafc68131748c9bf42a Mon Sep 17 00:00:00 2001 From: mooinglemur Date: Sun, 3 Mar 2024 21:30:32 -0700 Subject: [PATCH] [KERNAL] refactor, comment 65C816 native stack API --- kernal/x16/65c816/stack.s | 131 ++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/kernal/x16/65c816/stack.s b/kernal/x16/65c816/stack.s index 4340232c..32187813 100644 --- a/kernal/x16/65c816/stack.s +++ b/kernal/x16/65c816/stack.s @@ -8,9 +8,10 @@ .setcpu "65816" .segment "KRAM816S" -stack_counter: .res 1 -stack_ptr: .res 1 -stack_one: .res 1 +stack_counter: .res 1 ; depth of the stack chain +stack_ptr: .res 1 ; low byte of the preserved $01xx stack +stack_one: .res 1 ; holds the value #$01 to speed up 16-bit + ; stack restore operations .segment "MACHINE" @@ -25,76 +26,110 @@ stack_one: .res 1 .A16 .I16 +;-------------------------------------------------------------- +; stack_enter_kernal_stack +; +; Function: change SP to KERNAL (page $01) SP +; Flags: m = 0, x = 0, e = 0 +; Input: SP = old stack pointer +; Output: SP = KERNAL stack pointer (after rts) +;-------------------------------------------------------------- +.proc stack_enter_kernal_stack + .A16 + .I16 + ldx stack_ptr + ; fall through +.endproc + ;-------------------------------------------------------------- ; stack_push ; -; Function: -; Flags: M = 0 -; Output: +; Function: change SP to new pointer, preserving the old one +; at the top of the new stack +; Flags: m = 0, x = 0, e = 0 +; Input: X = new stack pointer, SP = old stack pointer +; Output: SP = X - 2 (after rts) ;-------------------------------------------------------------- .proc stack_push .A16 .I16 - ply - lda stack_counter - beq @counter_zero - sei - + ply ; hold the return address + lda stack_counter ; is the stack chain empty + beq @counter_zero ; if so, don't push the old stack + ; instead, treat the old stack + ; as $01xx page, and preserve its location inc - sta stack_counter + sta stack_counter ; otherwise, increment the stack_counter - tsc - txs - pha - phy + tsc ; preserve old SP + txs ; bring new SP into effect + pha ; save old SP on new stack + phy ; restore the return address cli rts @counter_zero: - tsc - xba - sta stack_counter - txs - phy + tsc ; This is inferred to be $01xx + xba ; Swap bytes, $xx01 + sta stack_counter ; Store $01 to stack_counter + ; and $xx to stack_ptr (stack_counter+1) + txs ; bring new SP into effect + phy ; restore return address + cli rts .endproc -.proc stack_pop +;-------------------------------------------------------------- +; stack_leave_kernal_stack +; +; Function: restore old SP, which is assumed to be in page $01 +; Flags: m = 0, x = 0, e = 0 +; Input: (SP+2) = old stack pointer if stack_counter > 1 +; Output: SP = old stack pointer (after rts) +;-------------------------------------------------------------- +.proc stack_leave_kernal_stack .A16 .I16 - ply - lda stack_counter - dec - bit #$00FF - beq @counter_one + ; fall through +.endproc +;-------------------------------------------------------------- +; stack_pop +; +; Function: change SP to old pointer +; Flags: m = 0, x = 0, e = 0 +; Input: (SP+2) = old stack pointer if stack_counter > 1 +; Output: SP = old stack pointer (after rts) +;-------------------------------------------------------------- +.proc stack_pop + .A16 + .I16 sei - sta stack_counter - pla - tcs - phy + ply ; hold the return address + lda stack_counter ; C = $xxyy where $yy = stack_counter + ; and $xx = stack_ptr, the KERNAL + ; stack pointer + dec ; decrement $xxyy + bit #$00FF ; if $yy = 0 + beq @counter_one ; then restore SP to $01xx + + sta stack_counter ; store decremented stack_counter + pla ; pop old SP off existing stack + tcs ; bring old SP into effect + phy ; restore return address + cli rts @counter_one: - stz stack_counter - inc - xba - tcs - phy + stz stack_counter ; reset stack_counter to zero + ; this is the end of the stack popping chain + inc ; C = $xx00 -> $xx01 + xba ; C = $01xx (valid KERNAL SP) + tcs ; bring KERNAL SP into effect + phy ; restore return address + cli rts .endproc -.proc stack_enter_kernal_stack - .A16 - .I16 - lda stack_ptr - jmp stack_push -.endproc - -.proc stack_leave_kernal_stack - .A16 - .I16 - jmp stack_pop -.endproc