; C02 library stdiox.h02 assembly language subroutines

ANYKEP: DC  "PRESS ANY KEY...",0

;
;char anykey() - wait for character with ANY KEY prompt
;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
        LDY #>ANYKEP    ;Load Prompt High Byte
        LDX #<ANYKEP    ;Load Prompt Low Byte
                        ;Drop into GETCPR

;char getcpr(&s) - GET Character with PRompt
;Args: Y,X = Address of Prompt String
;Sets: TEMP0 - Character code of keypress
;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
        LDA TEMP0       ;Load Key Code
        RTS

;void putbin(b) - PUT Binary
;Args: A = number to print
;Sets: TEMP0 = 0
;Affects: A,Y,C,N,X
PUTBIN: STA TEMP0       ;Save Number
        LDX #8          ;Print 8 Binary Digits
PUTBIL: LDA #0
        ASL TEMP0       ;Shift Top Bit Out
        ADC #$30        ;Convert to '0' or '1'
        JSR PUTCHR      ;Print Digit
        DEX             ;Decrement Index
        BNE PUTBIL      ;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
;putdem - Alternate Entry Point if number is already in TEMP3
;putdeh - Alternate Entry Point to print only padding spaces
PUTDEL: STA TEMP3
PUTDEM: JSR PUTDEC      ;Print Decimal Representation of number
        LDA TEMP3       ;
PUTDEH: CMP #100        ;If Number < 100
        BCS PUTDET      ;
        JSR PUTSPC      ;  Print a Space
        LDA TEMP3       ;
PUTDET: CMP #10         ;  If Number < 10  
        BCS PUTDEX      ;
        JSR PUTSPC      ;    Print another Space
PUTDEX: 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
PUTDES: JSR PUTDEH
        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 PUTDE1      ;If Not Zero
        JSR PUTDGT      ;  Print Digit
PUTDE1: LDA TEMP1       ;Get Low Byte
        BNE PUTDE2      ;If Not Zero
        CMP TEMP2       ;  and Hundreds 
        BEQ PUTDE3      ;  not Zero   
PUTDE2: JSR PUTDGT      ;  Print Digit
PUTDE3: LDA TEMP0       ;Get Low Byte
PUTDGT: ORA #$30        ;Convert to ASCII digit
        JMP PUTCHR      ;And Print

;puthex(&word) - PUT HEXadecimal
PUTHEX  EQU PRBYTE      ;Print Byte as Hexadecimal

;putint(&word) - PUT INTeger
PUTINT: JSR CVIBCD      ;Convert Integer to Packed BCD
        LDY #4          ;Set Initial Digit Number
        JSR UPBCDI      ;Unpack Digit X
PUTINZ: BNE PUTINS      ;If Zero
        DEY             ; Decrement Digit Number
        BNE PUTINZ      ; If Not Zero Loop
        BEQ PUTDGT      ; Else Print Digit and Return
PUTINL: JSR UPBCDI      ;Unpack Digit X
PUTINS: JSR PUTDGT      ;Print Digit
        DEY             ;Decrement Digit Number
        BPL PUTINL      ;Loop if >= Zero
        RTS

;putwrd(&word) - PUT WoRD
;Args: Y = Word MSB
;      X = Word LSB
;Calls: PUTS = Put String
;       PRBYTE = Print Byte
;       SAVRXY = Save X and Y Registers
;Affects: A,Y,X,N,Z,C
PUTWRD: JSR SAVRXY      ;Save Address
PUTWRA: LDA TEMP2       ;Load Address MSB
        JSR PRBYTE      ;Print as Hexadecimal
        LDA TEMP1       ;Load Address LSB
        JMP PRBYTE      ;Print and Return`

;Print a Space
PUTSPC: LDA #32         ;Load Space Character
        JMP PUTCHR      ;and Print it

;void printf(b, &s) - PRINT Formatted byte and/or string
;Args: A = byte to format
;      Y,X = address of formatting string
;Uses: DSTLO,DSTHI = Address of %S string
;Sets: SRCLO,SRCHI = Address of formatting string
;      TEMP3 - number to format
;Destroys: TEMP0,TEMP1,TEMP2
;Returns: A,Y = Total number of characters printed
PRINTF: JSR SETSRC      ;Initialize Source String
        STA TEMP3       ;Save Byte to Format
PRINTL: LDA (SRCLO),Y   ;Read next character in string
        BEQ PRINTX      ;If Not 0
        CMP #'%         ;'  If Format Specified 
        BEQ PRINTP      ;    Jump to Formatter
PRINTC: JSR PUTCHR      ;  Print character at offset,
PRINTY: INY             ;  increment offset, and
        BPL PRINTL      ;  loop if less than 128
PRINTX: RTS             ;  characters printed
;Process Format Specifier
PRINTP: INY             ;Increment Offset
        LDA (SRCLO),Y   ;Get Formatting Character
        BEQ PRINTX      ;If NUL, then Exit
        CMP #'%         ;'If Percent Sign 
        BEQ PRINTC      ;  Print it and Continue
        AND #$DF        ;Convert to Upper Case
        CMP #'L         ;'If "l" or "L" 
        BNE PRINTR
        LDA TEMP3       ;  Load Byte to Format
        JSR PUTDEM      ;  Print Left Justified
        JMP PRINTY      ;  and Continue Printing String
PRINTR: CMP #'R         ;'If "r" or "R" 
        BNE PRINTD
        LDA TEMP3       ;  Load Byte to Format
        JSR PUTDES      ;  Print Right Justified
        JMP PRINTY      ;  and Continue Printing String
PRINTD: CMP #'D         ;'Else If "d" or "D" 
        BNE PRINTH
        LDA TEMP3       ;  Load Byte to Format
        JSR PUTDEC      ;  Print as Decimal
        JMP PRINTY      ;  and Continue Printing String
PRINTH: CMP #'H         ;'Else If "h" or "H" 
        BNE PRINTB
        LDA TEMP3       ;  Load Byte to Format
        JSR PUTHEX      ;  Print as Hexadecimal
        JMP PRINTY      ;  and Continue Printing String
PRINTB: CMP #'B         ;'Else If "b" or "B" 
        BNE PRINTN
        LDA TEMP3       ;  Load Byte to Format
        JSR PUTBIN      ;  Print as Binary
        JMP PRINTY      ;  and Continue Printing String
PRINTN: CMP #'N         ;'Else If "n" or "N" 
        BNE PRINTS
        STY TEMP0       ;  Save Index
        JSR NEWLIN      ;  Execute Newline Function
        LDY TEMP0       ;  Restore Index
        JMP PRINTY      ;  and Continue Printing String
PRINTS: CMP #'S         ;'Else If "s" or "S" 
        BNE PRINTW
        STY TEMP0       ;  Save Index
        JSR PUTDST      ;  Print Destination String
        LDY TEMP0       ;  Restore Index
        JMP PRINTY      ;
PRINTW: CMP #'W         ;'Else If "w" or "W" 
        BNE PRINTI
        STY TEMP0       ;  Save Index
        JSR SAVDST      ;  Save Destination Address
        JSR PUTWRA      ;  Print MSB and LSB as Hex
        LDY TEMP0       ;  Restore Index
        JMP PRINTY      ;
PRINTI: CMP #'I         ;'Else If "i" or "I" 
        BNE PRINTZ
        TYA             ;  Save Index
        PHA
        JSR GETDST      ;  Get Integer in DSTLO, DSTHI
        JSR PUTINT      ;  Print Integer as Decimal
        PLA             ;  Restore Index
        TAY
        JMP PRINTY      ;
PRINTZ: LDA TEMP3       ;Else
        JMP PRINTC      ;  Print Raw Byte and Continue

                       ;char putdst()
PUTDST: LDY #0         ;Initialize character offset
PUTDSL: LDA (DSTLO),Y  ;Read next character in string
        BEQ PUTDSX     ;If Not 0
        JSR PUTC       ;  Print character at offset,
        INY            ;  increment offset, and
        BPL PUTDSL     ;  loop if less than 128
PUTDSX: TYA            ;Return number of
        RTS            ;  characters printed
