1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-28 10:51:14 +00:00
C02/include/stack.a02
2018-09-23 18:39:27 -04:00

245 lines
8.2 KiB
Plaintext

;C02 stack module assembly language subroutines
;Requires external zero page variables
;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI
;external variables
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2
;external routines
;MEMCPL, SETDST, SETSRC
;Implementation Notes:
;Stack starts at STKSLO,STKSHI and builds upward tp STKELO, STKEHI
;Each entry on the stack consists of the entry data followed
;by a single byte containing the length of the entry data
;stkbgn(&b) - Set Stack Start Address
;Args: X,Y = Address
;Sets: STKSLO, STKSHI = Stack Start Address
;Affects: Z, N
STKBGN: STX STKSLO ;Save Stack Start LSB
STY STKSHI ;Save Stack Start MSB
RTS
;stkend(&b) - Set Stack End Address (+1)
;Args: X,Y = Address
;Sets: STKELO, STKEHI = Stack End Address
;Affects: Z, N
STKEND: STX STKELO ;Save Stack End LSB
STY STKEHI ;Save Stack End MSB
RTS
;stkptr() - Get Stack Pointer
;Uses: STKLO,STKHI = Stack Pointer
;Affects: N,Z
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKPTR: LDX STKLO ;Load Stack Pointer LSB
LDY STKHI ;Load Stack Pointer MSB
RTS
;stkssp() - Save Stack Pointer
;Uses: STKLO,STKHI = Stack Pointer
;Sets: TEMP1.TEMP2 = Stack Pointer
;Affects: N,Z
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKSSP: JSR STKPTR ;Get Stack Pointer
JMP SAVRXY ;Save in TEMP1, TEMP2
;stksrc() - Set Source Pointer to Stack Pointer
;Uses: STKLO,STKHI = Stack Pointer
;Sets: SRCLO,SRCHI = Source Array Pointer
;Affects: X,N,Z
;Returns: Y = 0
STKSRC: JSR STKPTR ;Get Stack Pointer Address
JMP SETSRC ;Set Source/ an/d Return
;stkdst() - Set Destination Pointer to Stack Pointer
;Uses: STKLO,STKHI = Stack Pointer
;Sets: DSTLO,DSTHI = Destination Array Pointer
;Affects: N,Z
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKDST: JSR STKPTR ;Get Stack Pointer Address
JMP SETDST ;Set Destination and Return
;stkrst() - Reset Stack Pointer to Start Address
;Uses: STKSLO, STKSHI = Stack Start Address
;Sets: STKLO, STKHI = Stack Pointer
;Affects: Z, N
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKRST: LDX STKSLO ;Load X with Stack Start LSB
LDY STKSHI ;Load X with Stack Start MSB
JMP STKSET ;Store in Stack Pointer
;stkrsp() - Restore Stack Pointer
;Uses: TEMP1.TEMP2 = Stack Pointer
;Sets: STKLO,STKHI = Stack Pointer
;Affects: N,Z
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKRSP: JSR RESRXY ;Get TEMP1, TEMP2
;and fall into STKSET
;stkset() - Set Stack Pointer Address
;Args: X,Y = Address
;Sets: STKLO, STKHI = Stack Pointer Address
;Affects: Z, N
;Returns: X = Stack Pointer LSB
; Y = Stack Pointer MSB
STKSET: STX STKLO ;Store X in Stack Pointer LSB
STY STKHI ;Store Y in Stack Pointer MSB
RTS ;Exit Routine
;stkpsh(n, &m) - Push n Bytes of m onto Stack
;Args: A = Number of Bytes to Append
; Y,X = Address of Source Array
;Uses: STKELO, STKEHI = Stack End Address
;Sets: DSTLO, DSTHI = Pointer to Stack Entry
; SRCHI, SRCLO = Pointer to Source Array
; TEMP0 = Number of Bytes to Append
;Updates: STKLO, STKHI = Stack Pointer
;Returns: A=Number of Bytes Pushed
; 0 = Error: Stack Underflow
STKPSH: JSR SETSRC ;Set Source Address
STKPSA: STA TEMP0 ;Save Number of Bytes
JSR STKDST ;Set Destination to Stack Pointer
JSR STKALC ;Allocate Space on Stack
JMP MEMCPL ;Copy Bytes and Return
;stkadd(n) - Add N Bytes to Stack Pointer
;Args: A=Number of Bytes to Allocate
;Updates: STKLO, STKHI = Stack Pointer
;Affects: A,C,N,Z
STKADD: CLC
STKADC: ADC STKLO ;Add to Stack Pointer LSB
STA STKLO ;and Save
LDA STKHI ;Add Carry
ADC #0 ;to Stack Pointer MSB
STA STKHI ;and Save
RTS
;stkalc(n) - Allocate Space on Stack
;Args: A=Number of Bytes to Allocate
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A = Number of Bytes Allocated
; 0 if Error: Pointer Overflow or Length 0
; Y=0
STKALC: JSR STKSSP ;Save Stack Pointer
LDA TEMP0 ;If No Bytes
BEQ STKABT ; Abort Calling Routine
JSR STKADD ;Add to Stack Pointer
LDA STKEHI ;If Stack End MSB
CMP STKHI ; < Stack Pointer MSB
BCC STKRPA ; Abort Calling Routine
BNE STKALX ;Else if Not Equal
LDA STKELO ;and Stack End LSB
CMP STKLO ; < Stack Pointer LSB
BCC STKRPA ; Abort Calling Routine
STKALX: LDA TEMP0 ;Get Number of Bytes from X Register
LDY #0 ;Initialize Index
STA (STKLO),Y ;Store after Allocated Area
;and fall inro STKINC
;stkinc(n) - Increment Stack Pointer
;Sets: STKLO, STKHI = Stack Pointer Address
;Affects: Y,Z,N
STKINC: INC STKLO ;Increment LSB
BNE STKINX ;If Zero
INC STKHI ; Increment MSB
STKINX: RTS
;stkcmp - Compare Stack Pointer to Stack Start Address
;Uses: STKLO, STKHI = Stack Pointer Address
; STKSLO, STKSHI = Stack Start Address
;Returns: C=1,Z=1 if Stack Pointer = Stack Start
; C=1,Z=0 if Stack Pointer > Stack Start
; C=0,Z=0 if Stack Pointer < Stack Start
STKCMP: LDA STKHI ;Compare MSB
CMP STKSHI
BCC STKRTS ;If Pointer<Start Return C=0, Z=1
BNE STKRTS ;If Pointer>Start Return C=1. Z=0
LDA STKLO ;If MSB Equal
CMP STKSLO ;Compare LSB
STKRTS: RTS
;stkdec(n) - Decrement Stack Pointer
;Sets: STKLO, STKHI = Stack Pointer Address
;Affects: X,Z,N
STKDEC: LDX STKLO ;If LSB
BNE STKDEL ; is Zero
DEC STKHI ; Decrement MSB
STKDEL: DEC STKLO ; Decrement LSB
STKDER: RTS
;stksiz() - Get Stack Size in Bytes
;Uses: STKLO,STKHI = Stack Pointer
;Sets: STKSLO, STKSHI = Stack Start Address
;Returns: A = $FF if Stack Size is Non-Zero
; $00 if Stack is Empty
; Y,X = Stack Size (MSB, LSB)
STKSIZ: LDA STKLO ;Subtract
SEC ;Start Address LSB
SBC STKSLO ;from Pointer LSB
TAX ;and Copy to X
LDA STKHI ;Subtract Start MSB
SBC STKSHI ;from Pointer MSB
TAY ;and Copy to Y
BCC STKZRO ;Return FALSE if <=0
BNE STKTRU ;Return TRUE if MSB <> 0
TXA ;Else
BEQ STKRTS ;Return FALSE if LSB = 0
STKTRU: LDA #$FF ;Else Return TRUE
RTS
;stkdrp(&m) - Drop Top Entry from Stack
;Note: Aborts Calling Routine if Error
;Uses: STKSLO, STKSHI = Stack Start Address
;Sets: TEMP1, TEMP2 = Original Stack Pointer
;Updates: STKLO, STKHI = Stack Pointer
;Affects: Y,C,N,Z
;Returns: A=Number of Bytes in Entry
; 0=Error: Stack Underflow
; Y=0
STKDRP: JSR STKSSP ;Save Stack Pointer
STKDRN: JSR STKCMP ;If Stack Pointer
BCC STKRPA ; <= Stack Start
BEQ STKRPA ; Return 0
JSR STKDEC ;Decrement Stack Pointer
LDY #0 ;Initialize Index
LDA (STKLO),Y ;Get Number of Bytes in Entry
;and fall into STKSUB
;stksub(n) - Reduce Stack Pointer by A
STKSUB: STA TEMP0 ;Save Number in TEMP0
LDA STKLO
SEC ;Subtract A from LSB
SBC TEMP0
STA STKLO
LDA STKHI ;Subtract 0 from LSB
SBC #0 ;For Borrow
STA STKHI
JSR STKCMP ;If Stack Pointer < Start
BCC STKRPA ; Restore Pointer and Return 0
STKSUE: LDA TEMP0 ;Retrieve Number of Bytes
RTS
STKRPA: JSR STKRSP ;Restore Stack Pointer
STKABT: PLA ;Drop Return Address from Stack
PLA ; Aborting Calling Routine
STKZRO: LDA #0 ;Set A to 0
RTS
;stkpop(&m) - Pop Top Entry off Stack
;Args: Y,X = Address of Source Array
;Uses: STKSLO, STKSHI = Stack Start Address
;Updates: STKLO, STKHI = Stack Pointer
;Affects: C,N,Z
;Returns: A,Y = Number of Bytes in Entry
; 0 = Error: Stack Underflow
STKPOP: JSR SETDST ;Set Destination Address
JSR STKDRP ;Deallocate Stack Entry
STKPOS: JSR STKSRC ;Set Source Address to Stack Pointer
JMP MEMCPL ;Copy Bytes and Return