C02/include/stdiox.a02

331 lines
11 KiB
Plaintext

; C02 library stdiox.h02 assembly language subroutines
SUBROUTINE STDIOX
.ANYKEY BYTE "PRESS ANY KEY...",0
;
;char anykey(nls) - wait for character with ANY KEY prompt
;Args: A = Print Newlines (0 = No, otherwise Yes)
;Calls: GETCPR, NEWLIN - Print Newline to Screen
;Affects: C,N,Z
;Returns: A = Character code of keypress
ANYKEY: JSR NEWLIN ;Start at Beginning of Next Line
.NONL LDY #>.ANYKEY ;Load Prompt High Byte
LDX #<.ANYKEY ;Load Prompt Low Byte
;Drop into GETCPR
;char getcpr(nls, &s) - GET Character with PRompt
;Args: A = Print Newlines (0 = No, otherwise Yes)
; Y,X = Address of Prompt String
;Sets: TEMP0 - Character code of keypress
; TEMP1 - Newline Flag
;Calls: PUTS - Put String to Screen
; GETC - Get Character from Keyboard
; NEWLIN - Print Newline to Screen
;Affects: C,N,Z
;Returns: A = Character code of keypress
GETCPR: JSR PUTS ;Print Prompt
JSR GETC ;Wait for and Return Keypress
STA TEMP0 ;Save Key Code
JSR NEWLIN ;Move to Next Line
JSR NEWLIN ;Generate Blank Line
.NONLS LDA TEMP0 ;Load Key Code
RTS
;void putbin(b) - PUT Binary
;Args: A = number to print
;Destroys: TEMP0, TEMP1
;Affects: A,Y,C,N,X
PUTBIN: LDY #$FF ;Set Bit Mask to All 1's
;void putmsk(b) - PUT Bit Mask
;Args: A = byte to print
; Y = Bit Mask
;Destroys: TEMP0, TEMP1
;Affects: A,Y,C,N,X
PUTMSK: STA TEMP2 ;Save Byte
STY TEMP1 ;Save Bit Mask
LDX #8 ;Print 8 Binary Digits
.MASKL LDA #0 ;Clear Accumulator
ASL TEMP2 ;Shift Top Bit Out of Byte
ADC #$30 ;Convert to '0' or '1'
ASL TEMP1 ;Shift Top Bit Out of Mask
BCC .MASKP ;If Set
JSR PUTCHR ; Print Digit
.MASKP DEX ;Decrement Index
BNE .MASKL ;Loop if Not Done
RTS
;void putdel(b) - PUT DEcimal Left justified
;Args: A = number to print
;Sets: TEMP0 - ones digit
; TEMP1 - tens digit
; TEMP2 - hundreds digit
; TEMP3 - number that was printed
;.putdel - Alternate Entry Point if number is already in TEMP3
;.spaces - Alternate Entry Point to print only padding spaces
PUTDEL: STA TEMP3
.PUTDEL JSR PUTDEC ;Print Decimal Representation of number
LDA TEMP3 ;
.SPACES CMP #100 ;If Number < 100
BCS .ONES ;
JSR PUTSPC ; Print a Space
LDA TEMP3 ;
.ONES CMP #10 ; If Number < 10
BCS .RETURN ;
JSR PUTSPC ; Print another Space
.RETURN RTS
;void putdeh(b) - PUT DEcimal Hundred
;Args: A = number to print
;Sets: TEMP0 - ones digit
; TEMP1 - tens digit
; TEMP2 - hundreds digit
PUTDEH: JSR CUBCD ;Convert Accumulator to Unpacked BCD
LDX #2 ;Print 2 Digits
BNE .DEZLP
;void putdez(b) - PUT DEcimal Zero filled
;Args: A = number to print
;Sets: TEMP0 - ones digit
; TEMP1 - tens digit
; TEMP2 - hundreds digit
PUTDEZ: JSR CUBCD ;Convert Accumulator to Unpacked BCD
LDX #3 ;Print 3 Digits
.DEZLP LDA TEMP0-1,X ;Get Byte
JSR PUTDGT ;Print Digit
DEX ;Decrement Counter
BNE .DEZLP ; And Loop if Not Done
RTS
;void putder(b) - PUT DEcimal Right justified
;Args: A = number to print
;Sets: TEMP0 - ones digit
; TEMP1 - tens digit
; TEMP2 - hundreds digit
; TEMP3 - number that was printed
PUTDER: STA TEMP3
.PUTDER JSR .SPACES
LDA TEMP3
;void putdec(b) - PUT DECimal
;Args: A = number to print
;Sets: TEMP0 - ones digit
; TEMP1 - tens digit
; TEMP2 - hundreds digit
PUTDEC: JSR CUBCD ;Convert Accumulator to Unpacked BCD
LDA TEMP2 ;Get High Byte
BEQ .DIGIT1 ;If Not Zero
JSR PUTDGT ; Print Digit
.DIGIT1 LDA TEMP1 ;Get Low Byte
BNE .DIGIT2 ;If Not Zero
CMP TEMP2 ; and Hundreds
BEQ .DIGIT3 ; not Zero
.DIGIT2 JSR PUTDGT ; Print Digit
.DIGIT3 LDA TEMP0 ;Get Low Byte
PUTDGT: ORA #$30 ;Convert to ASCII digit
JMP PUTCHR ;And Print
;puthex(b) - PUT HEXadecimal
PUTHEX EQU PRBYTE ;Print Byte as Hexadecimal
;putinr(i) - PUT INteger Right justified
PUTINR: SEC ;Mode = Justified
BCS .PUTINT ;Print Integer
;putint(i) - PUT INTeger
PUTINT: CLC ;Mode = Not Justified
.PUTINT JSR CVIBCD ;Convert Integer to Packed BCD
LDY #4 ;Set Initial Digit Number
.IZERO JSR UPBCDI ;Unpack Digit X
BNE .IDIGIT ;If Zero
BCC .INEXT ; If Justified
JSR PUTSPC ; Print a Space
.INEXT DEY ; Decrement Digit Number
BNE .IZERO ; and If Not Zero Loop
.ILOOP JSR UPBCDI ;Unpack Digit X
.IDIGIT JSR PUTDGT ;Print Digit
DEY ;Decrement Digit Number
BPL .ILOOP ;Loop if >= Zero
RTS
;putnyb(b) - PUT NYBble
PUTNYB EQU PRHEX ;Print Nybble as Hexadecimal
;putsqb(&.HEXW) - PUT SesQuiByte
;Args: Y = High Nybble
; X = Low Byte
;Calls: PUTHEX = Print Byte
; PRHEX = Print Hex Digit
; SAVRXY = Save X and Y Registers
;Affects: A,Y,X,N,Z,C
PUTSQB: JSR SAVRXY ;Save Address
.PUTSQB LDA TEMP2 ;Load Address MSB
JSR PRHEX ;Print High Nybble
LDA TEMP1 ;Load Address LSB
JMP PUTHEX ;Print and Return`
;putexh(&.HEXW) - PUT EXtended Hexadecimal
;Args: A = Value Extended Byte
; Y = Value High Byte
; X = Value Low Byte
;Calls: PUTHEX = Print Byte
; SAVRXY = Save X and Y Registers
; PUTWRT = Put .HEXW (Alternate Entry Point)
;Affects: A,Y,X,N,Z,C
PUTEXH: JSR SAVRXY ;Save High and Low Bytes
JSR PUTHEX ;Print Extended Byte
JMP PUTWRT ;Print TEMP2, TEMP1 as HEX word
;putwrd(&HEXW) - PUT WORD
;Args: Y = .HEXW MSB
; X = .HEXW LSB
;Calls: PUTHEX = Print Byte
; SAVRXY = Save X and Y Registers
;Affects: A,Y,X,N,Z,C
PUTWRD: JSR SAVRXY ;Save .HEXW
PUTWRT: LDA TEMP2 ;Load .HEXW MSB
JSR PUTHEX ;Print as Hexadecimal
LDA TEMP1 ;Load .HEXW LSB
JMP PUTHEX ;Print and Return`
;Print a Space
PUTSPC: LDA #32 ;Load Space Character
JMP PUTCHR ;and Print it
;Print Repeated Spaces
PUTRPS: TAY ;Set Counter to Number of Spaces
LDA #32
;Print Repeated Character
PUTRPT: JSR PUTCHR ;Print Space Character
DEY ;Decrement Counter
BNE PUTRPT ;If Not 0, Loop
RTS
;void printf(b, &s) - PRINT Formatted byte and/or string
;Args: A = byte to format
; Y,X = address of formatting string
;Uses: DSTPTR = Address of %S string
;Sets: SRCPTR = Address of formatting string
; TEMP3 - number to format
;Destroys: TEMP0,TEMP1,TEMP2
;Returns: A,Y = Total number of characters printed
PRINTF: STA TEMP3 ;Save Byte to Format
JSR SETSRC ;Initialize Source String
.FLOOP LDA (SRCPTR),Y ;Read next character in string
BEQ .FDONE ;If Not 0
CMP #'%' ; If Format Specified
BEQ .FEVAL ; Jump to Formatter
.FPUTC JSR PUTCHR ; Print character at offset,
.FNEXT INY ; increment offset, and
BPL .FLOOP ; loop if less than 128
.FDONE TYA ;Return Number of
RTS ; characters printed
;Process Format Specifier
.FEVAL: INY ;Increment Offset
LDA (SRCPTR),Y ;Get Formatting Character
BEQ .FDONE ;If NUL, then Exit
CMP #'%' ;If Percent Sign
BEQ .FPUTC ; Print it and Continue
AND #$DF ;Convert to Upper Case
.HNDRD CMP #'H' ;If "z" or "Z"
BNE .ZEROF
LDA TEMP3 ; Load Byte to Format
JSR PUTDEH ; Print Zero Filled
JMP .FNEXT ; and Continue .INTGRng String
.ZEROF CMP #'Z' ;If "z" or "Z"
BNE .LJUST
LDA TEMP3 ; Load Byte to Format
JSR PUTDEZ ; Print Zero Filled
JMP .FNEXT ; and Continue .INTGRng String
.LJUST CMP #'L' ;If "l" or "L"
BNE .RJUST
LDA TEMP3 ; Load Byte to Format
JSR .PUTDEL ; Print Left Justified
JMP .FNEXT ; and Continue .INTGRng String
.RJUST CMP #'R' ;If "r" or "R"
BNE .DECML
LDA TEMP3 ; Load Byte to Format
JSR .PUTDER ; Print Right Justified
JMP .FNEXT ; and Continue .INTGRng String
.DECML CMP #'D' ;Else If "d" or "D"
BNE .NYBBL
LDA TEMP3 ; Load Byte to Format
JSR PUTDEC ; Print as Decimal
JMP .FNEXT ; and Continue .INTGRng String
.NYBBL CMP #'Y' ;Else If "y" or "Y"
BNE .HEXB
LDA TEMP3 ; Load Byte to Format
JSR PUTNYB ; Print as Low Nybble as Hexadecimal
JMP .FNEXT ; and Continue .INTGRng String
.HEXB CMP #'X' ;Else If "x" or "Y"
BNE .BNRY
LDA TEMP3 ; Load Byte to Format
JSR PUTHEX ; Print as Hexadecimal
JMP .FNEXT ; and Continue .INTGRng String
.BNRY CMP #'B' ;Else If "b" or "B"
BNE .NEWLN
STY TEMP0 ; Save Index
LDA TEMP3 ; Load Byte to Format
JSR PUTBIN ; Print as Binary
LDY TEMP0 ; Restore Index
JMP .FNEXT ; and Continue .INTGRng String
.NEWLN CMP #'N' ;Else If "n" or "N"
BNE .STRNG
STY TEMP0 ; Save Index
JSR NEWLIN ; Execute Newline Function
LDY TEMP0 ; Restore Index
JMP .FNEXT ; and Continue .INTGRng String
.STRNG CMP #'S' ;Else If "s" or "S"
BEQ .FDEST ; Print Destination String
.SQBYT CMP #'Q' ;Else If "w" or "W"
BEQ .FDEST ; Print Sesquibyte as Hex
.HEXW CMP #'W' ;Else If "w" or "W"
BEQ .FDEST ; Print Word as Hex
.INTGR CMP #'I' ;Else If "i" or "I"
BEQ .FDEST ; Print Decimal Integer
.IJUST CMP #'J' ;Else If "j" or "J"
BEQ .FDEST ; Print Right-Justified Decimal
.FECHO LDA TEMP3 ;Else
JMP .FPUTC ; Print Raw Byte and Continue
;Process Value in DSTPTR
.FDEST TAX ;Save Specifier
TYA ;Save Index
PHA
TXA ;Restore Specifier
JSR GETDST ;Get Integer in DSTPTR
CMP #'I' ;If 'i' or 'I'
BNE .FDESTJ
JSR PUTINT ; Print Integer Right Justified
BMI .FSKIP
.FDESTJ CMP #'J' ;Else If 'J' or 'J'
BNE .FDESTQ
JSR PUTINR ;Print Integer Right Justified
BMI .FSKIP
.FDESTQ CMP #'Q' ;Else If 'q' or 'Q'
BNE .FDESTW
JSR .PUTSQB ; Print MSB and LSB as Hex
BNE .FSKIP
.FDESTW CMP #'W' ;Else If 'w' or 'J'
BNE .FDESTS
JSR PUTWRD ; Print MSB and LSB as Hex
BNE .FSKIP
.FDESTS JSR PUTDST ;Else Print Destination String
.FSKIP PLA ;Restore Index
TAY
JMP .FNEXT
;char putdst()
PUTDST LDY #0 ;Initialize character offset
.DLOOP LDA (DSTPTR),Y ;Read next character in string
BEQ .DRETY ;If Not 0
JSR PUTC ; Print character at offset,
INY ; increment offset, and
BPL .DLOOP ; loop if less than 128
.DRETY TYA ;Return number of
RTS ; characters printed
ENDSUBROUTINE