2018-07-25 23:00:46 +00:00
|
|
|
;C02 library stack.h02 assembly language subroutines
|
|
|
|
;Requires External Zero Page Variables
|
|
|
|
;STKLO, STKHI, DSTLO, DSTHI, SRCLO, SRCHI
|
|
|
|
;External Variables
|
2018-07-27 17:43:32 +00:00
|
|
|
;STKSLO, STKSHI, STKELO, STKEHI, TEMP0, TEMP1, TEMP2, TEMP3
|
2018-07-25 23:00:46 +00:00
|
|
|
;External Routines
|
|
|
|
;MEMCPL, SETDST, SETSRC, STRLEN
|
|
|
|
|
|
|
|
;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
|
|
|
|
|
2018-07-26 14:33:03 +00:00
|
|
|
;stkptr() - Get Stack Pointer
|
2018-07-25 23:00:46 +00:00
|
|
|
;Uses: STKLO,STKHI = Stack Pointer
|
2018-07-26 14:33:03 +00:00
|
|
|
;Affects: N,Z
|
2018-07-25 23:00:46 +00:00
|
|
|
;Returns: X = Stack Pointer LSB
|
|
|
|
; Y = Stack Pointer MSB
|
|
|
|
STKPTR: LDX STKLO ;Load Stack Pointer LSB
|
|
|
|
LDY STKHI ;Load Stack Pointer MSB
|
|
|
|
RTS
|
|
|
|
|
2018-07-26 14:33:03 +00:00
|
|
|
;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
|
|
|
|
|
2018-07-27 17:43:32 +00:00
|
|
|
;stksrc() - Set Source Pointer to Stack Pointer
|
2018-07-25 23:00:46 +00:00
|
|
|
;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
|
2018-07-26 14:33:03 +00:00
|
|
|
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
|
2018-07-25 23:00:46 +00:00
|
|
|
|
|
|
|
;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
|
|
|
|
|
2018-07-27 17:43:32 +00:00
|
|
|
;stkstr(n, &m) - Push String onto Stack
|
|
|
|
;Args: Y,X = Address of Source Array
|
|
|
|
STKSTR: JSR STRLEN ;Get Length of String
|
|
|
|
BEQ STKSTY ;If Length > 0
|
|
|
|
BMI STKSTY ; and < 128
|
|
|
|
INY ; Increment Length to
|
|
|
|
TYA ; include null terminator
|
|
|
|
STKSTY: LDY #0 ;Clear Y Index
|
|
|
|
BEQ STKPSA ;Execute STKPSH, skippping SETSRC
|
|
|
|
|
|
|
|
;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
|
2018-07-25 23:00:46 +00:00
|
|
|
;Args: A=Number of Bytes to Allocate
|
|
|
|
;Updates: STKLO, STKHI = Stack Pointer
|
2018-07-27 17:43:32 +00:00
|
|
|
;Affects: A,C,N,Z
|
|
|
|
STKADD: CLC
|
|
|
|
STKADC: ADC STKLO ;Add to Stack Pointer LSB
|
2018-07-25 23:00:46 +00:00
|
|
|
STA STKLO ;and Save
|
|
|
|
LDA STKHI ;Add Carry
|
|
|
|
ADC #0 ;to Stack Pointer MSB
|
|
|
|
STA STKHI ;and Save
|
2018-07-27 17:43:32 +00:00
|
|
|
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
|
2018-07-25 23:00:46 +00:00
|
|
|
LDA STKEHI ;If Stack End MSB
|
|
|
|
CMP STKHI ; < Stack Pointer MSB
|
2018-07-27 17:43:32 +00:00
|
|
|
BCC STKRPA ; Abort Calling Routine
|
2018-07-25 23:00:46 +00:00
|
|
|
BNE STKALX ;Else if Not Equal
|
|
|
|
LDA STKELO ;and Stack End LSB
|
|
|
|
CMP STKLO ; < Stack Pointer LSB
|
2018-07-27 17:43:32 +00:00
|
|
|
BCC STKRPA ; Abort Calling Routine
|
2018-07-25 23:00:46 +00:00
|
|
|
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 STKCMX ;If Pointer<Start Return C=0, Z=1
|
|
|
|
BNE STKCMX ;If Pointer>Start Return C=1. Z=0
|
|
|
|
LDA STKLO ;If MSB Equal
|
|
|
|
CMP STKSLO ;Compare LSB
|
|
|
|
STKCMX: 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
|
|
|
|
|
|
|
|
;stkdal() - Deallocate Stack Entry
|
2018-07-27 17:43:32 +00:00
|
|
|
;Note: Aborts Calling Routine if Error
|
2018-07-25 23:00:46 +00:00
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
2018-07-27 17:43:32 +00:00
|
|
|
;Sets: TEMP1, TEMP2 = Original Stack Pointer
|
2018-07-25 23:00:46 +00:00
|
|
|
;Updates: STKLO, STKHI = Stack Pointer
|
2018-07-26 14:33:03 +00:00
|
|
|
;Affects: Y,C,N,Z
|
|
|
|
;Returns: A=Number of Bytes in Entry
|
|
|
|
; 0=Error: Stack Underflow
|
|
|
|
; Y=0
|
|
|
|
STKDAL: JSR STKSSP ;Save Stack Pointer
|
|
|
|
STKDAN: JSR STKCMP ;If Stack Pointer
|
2018-07-27 17:43:32 +00:00
|
|
|
BCC STKRPA ; <= Stack Start
|
|
|
|
BEQ STKRPA ; Return 0
|
2018-07-25 23:00:46 +00:00
|
|
|
JSR STKDEC ;Decrement Stack Pointer
|
2018-07-26 14:33:03 +00:00
|
|
|
LDY #0 ;Initialize Index
|
2018-07-25 23:00:46 +00:00
|
|
|
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
|
2018-07-26 14:33:03 +00:00
|
|
|
JSR STKCMP ;If Stack Pointer < Start
|
2018-07-27 17:43:32 +00:00
|
|
|
BCC STKRPA ; Restore Pointer and Return 0
|
2018-07-25 23:00:46 +00:00
|
|
|
STKSUE: LDA TEMP0 ;Retrieve Number of Bytes
|
|
|
|
RTS
|
2018-07-27 17:43:32 +00:00
|
|
|
STKRPA: JSR STKRSP ;Restore Stack Pointer
|
|
|
|
STKABT: PLA ;Drop Return Address from Stack
|
|
|
|
PLA ; Aborting Calling Routine
|
|
|
|
STKZRO: LDA #0 ;Set A to 0
|
2018-07-25 23:00:46 +00:00
|
|
|
RTS
|
|
|
|
|
2018-07-26 14:33:03 +00:00
|
|
|
;stkdrp(&m) - Drop Top Entry from Stack
|
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
|
|
|
;Updates: STKLO, STKHI = Stack Pointer
|
|
|
|
;Affects: C,N,Z
|
|
|
|
;Returns: A = Number of Bytes in Dropped Entry
|
|
|
|
; 0 = Error: Stack Underflow
|
2018-07-27 17:43:32 +00:00
|
|
|
STKDRP JSR STKDAL ;Deallocate Stack Entry
|
|
|
|
RTS
|
2018-07-26 14:33:03 +00:00
|
|
|
|
2018-07-25 23:00:46 +00:00
|
|
|
;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 STKDAL ;Deallocate Stack Entry
|
2018-07-26 14:33:03 +00:00
|
|
|
STKPOS: JSR STKSRC ;Set Source Address to Stack Pointer
|
2018-07-25 23:00:46 +00:00
|
|
|
JMP MEMCPL ;Copy Bytes and Return
|
|
|
|
|
2018-07-26 14:33:03 +00:00
|
|
|
;stktop(&m) - Copy Top Entry off Stack
|
2018-07-25 23:00:46 +00:00
|
|
|
;Args: Y,X = Address of Source Array
|
2018-07-26 14:33:03 +00:00
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
|
|
|
;Affects: C,N,Z
|
|
|
|
;Returns: A,Y = Number of Bytes in Entry
|
|
|
|
; 0 = Error: Stack Underflow
|
|
|
|
STKTOP: JSR STKPOP ;Pop Top Entry Off Stack
|
|
|
|
BEQ STKDER ;If Underflow, Return 0
|
|
|
|
JMP STKRSP ;Else Restore Stack Pointer and Return
|
|
|
|
|
2018-07-27 17:43:32 +00:00
|
|
|
;stkdup(&m) - Duplicate Top Entry on Stack
|
2018-07-26 14:33:03 +00:00
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
|
|
|
; STKELO, STKEHI = Stack End Address
|
|
|
|
;Updates: STKLO, STKHI = Stack Pointer
|
|
|
|
;Affects: C,N,Z
|
|
|
|
;Returns: A,Y = Number of Bytes in Entry
|
2018-07-27 17:43:32 +00:00
|
|
|
; 0 = Error: Stack Overflow or Underflow
|
2018-07-26 14:33:03 +00:00
|
|
|
STKDUP: JSR STKDAL ;Deallocate Top Entry
|
2018-07-27 17:43:32 +00:00
|
|
|
STKDUS: JSR STKSRC ;Set Source Pointer to Stack Pointer
|
2018-07-26 14:33:03 +00:00
|
|
|
JSR STKRSP ;Restore Stack Pointer
|
|
|
|
JMP STKSTY ;Push Top Entry onto Stack
|
|
|
|
|
2018-07-27 17:43:32 +00:00
|
|
|
;stkovr(&m) - Duplicate Second Entry on Stack
|
2018-07-26 14:33:03 +00:00
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
|
|
|
; STKELO, STKEHI = Stack End Address
|
|
|
|
;Updates: STKLO, STKHI = Stack Pointer
|
|
|
|
;Affects: C,N,Z
|
|
|
|
;Returns: A,Y = Number of Bytes in Entry
|
2018-07-27 17:43:32 +00:00
|
|
|
; 0 = Error: Stack Overflow or Underflow
|
|
|
|
STKOVR: JSR STKDAL ;Deallocate Top Entry
|
|
|
|
JSR STKDAN ;Deallocate Second Entry
|
|
|
|
JMP STKDUS ;Restore Pointer and Duplicate
|
|
|
|
|
|
|
|
;stkswp() - Swap Top Entry with Entry Below it
|
|
|
|
;Uses: STKSLO, STKSHI = Stack Start Address
|
|
|
|
; STKELO, STKEHI = Stack End Address
|
|
|
|
;Affects: C,N,Z
|
|
|
|
;Returns: A,Y = Number of Bytes in Entry
|
|
|
|
; 0 = Error: Stack Overflow or Underflow
|
|
|
|
STKSWP: JSR STKOVR ;Duplicate Second Entry
|
|
|
|
BEQ STKDER ;Exit if Error
|
|
|
|
JSR STKDAN ;Deallocate Duplicate
|
|
|
|
STA TEMP3 ;Save Size of Duplicate
|
|
|
|
JSR STKSSP ;Save Pointer to Duplicate
|
|
|
|
JSR STKDAN ;Deallocate Top Entry
|
|
|
|
JSR STKSRC ;Set Source to Top Entry
|
|
|
|
STA DSTLO ;Save Top Entry Size
|
|
|
|
JSR STKDAN ;Deallocate Second Entry
|
|
|
|
LDA DSTLO ;Retrieve Top Entry Size
|
|
|
|
JSR STKSWC ;Copy Top Entry Down
|
|
|
|
JSR RESSRC ;Set Duplicate as Source
|
|
|
|
LDA TEMP3 ;Get Duplicate Length
|
|
|
|
STKSWC: STA TEMP0 ;Save Number of Bytes
|
|
|
|
JSR STKDST ;Set Destination to Stack Pointer
|
|
|
|
LDY #0 ;Clear Index Register
|
|
|
|
JSR MEMCPL ;Copy Bytes and Return
|
|
|
|
STA (DSTLO),Y ;Store Number of Bytes after Entry
|
|
|
|
SEC ;Add Number of Bytes plus 1
|
|
|
|
JSR STKADC ;to Stack Pointer
|
|
|
|
TYA ;Return Number of Bytes
|
|
|
|
RTS
|