;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutine: printchr ; ; Print ATASCII character in A, without preserving registers. ; Assumes IOCB #0 is opened on the E: device, which is how the ; Atari boots up. Uses "call-by-RTS" (weird looking but standard). ; ; Note that this will work even if the E: handler has been replaced, ; e.g. with COL80 or COL64 or such. ; ; Hint: if you want to print graphics instead of actual cursor controls ; or insert/delete/clear/etc, print an Escape character ($1B) before each, ; or set DSPFLG ($2FE) to a non-zero value. ; printchr: tay ; save A (character to print). lda ICPTH ; set up stack, so it looks like a JSR to the pha ; put-one-byte address for E:, lda ICPTL ; which the OS has conveniently stashed pha ; in IOCB #0. tya ; restore A (put-one-byte argument). rts ; "return" to put-one-byte, which will return to printchr's caller. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutine: getchr ; ; Read ATASCII character from keyboard, return in A, without ; preserving registers. On return, Y = 1 on success. On error, ; Y will contain the error number (probably 128 for Break key or ; 136 for EOF). Note that getchrx does NOT return the error code in Y! ; ; Uses the published and immutable KEYBDV address in the ROM, meaning ; it (a) doesn't require an IOCB open to the K: device, and (b) ; it will not use any replacement K: handler that might be loaded ; (however, unlike E:, replacing the OS K: device is so rare that ; I've never heard of it being done). ; ; Hint: This is a "blocking" function call: it waits until a key is ; pressed. If you want to poll (only read input when it's available), ; check CH ($02FC): if it's $FF, no key is pressed. ; ; Note: if you really do want to read from the E: device, change ; the two KEYBDV's below to EDITRV. E: will read an entire line, ; including editing (backspace, insert/delete, cursor moves, etc) ; the first time it's called, and return only the first character ; read. Further calls will return the rest of the characters, one at ; a time, with $9B (EOL) as the last one. ; getchr: lda KEYBDV+5 ; set up stack, so it looks like a JSR to the pha ; get-one-byte address for K:, lda KEYBDV+4 ; which the OS ROM keeps in the pha ; KEYBDV table ($E420). rts ; "return" to get-one-byte, which will return to getchr's caller. ; These next two are 'wrappers' for the above, which preserve ; the X register. Very convenient for use in a loop. If you don't ; need these, don't copy them into your code. If you do need them, ; remember that they call printchr and getchr, so you have to copy ; those also. ; Subroutine: Print A register in hex. ; Preserves X (but not A or Y). printhex: pha ; stash argument lsr ; shift right 4 times, lsr ; to get the first hex digit lsr ; (aka nybble) into the bottom lsr ; 4 bit positions. jsr printxdig ; print the top nybble. pla ; restore original value... and #$0f ; mask off high nybble ; fall through to print the 2nd digit. ; Subroutine: Print a nybble (A=0 to $0f) in hex. printxdig: ora #$30 ; 0-9 now ASCII... cmp #$3a ; do we have A-F? bcc xok ; if not, don't adjust it adc #$26 ; A-F now ASCII: $3a + $26 + 1 (carry always set) = $61 (a) xok: ; fall through to print the digit. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutine: printchrx ; ; Print ATASCII character in A, preserving X register. ; ; Preserves X register (but nothing else), so it can be called from ; within a loop that uses X for a counter, without having to worry ; about it. ; ; On exit, A holds a copy of the X register, if you can think of ; a use for that. ; ; Calls printchr. ; printchrx: tay ; save A (character to print). txa ; save X, pha ; on stack. tya ; restore A. jsr printchr ; print the character. pla ; restore X, tax ; from stack. rts ; this a regular RTS (returns to printchrx's caller). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutine: getchrx ; ; Read ATASCII char from keyboard, return in A, preserving X register. ; Actually, the return value here is also in Y, if you can think of a ; use for that. ; ; Note: The CIO error code is NOT returned in Y! Use getchr if you ; need that. ; ; Calls getchr. ; getchrx: txa ; save X, pha ; on stack. jsr getchr ; get the character. tay ; save A (our return value). pla ; restore X, tax ; from stack. tya ; restore return value to A. rts ; regular RTS. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutine: printmsg ; ; Print the null-terminated message pointed to by A (low) and X (high). ; Limited to <= 256 character messages. ; ; Trashes all registers, plus uses FR0 for temp storage. ; Calls printchr. ; printmsg: sta FR0 stx FR0+1 lda #0 sta FR0+2 pmloop: ldy FR0+2 lda (FR0),y beq pmdone jsr printchr inc FR0+2 bne pmloop pmdone: rts