; 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