; ============================================================= ; kernal-io.asm — Using Kernal Routines for I/O ; Demonstrates: screen output, keyboard input, file I/O ; Assemble to $C000. Run with SYS 49152. ; ============================================================= * = $C000 ; --------------------------------------------------------------- ; MAIN — Demo entry point ; --------------------------------------------------------------- MAIN JSR $FF81 ; CINT — init screen ; Print a string LDA #MSG_WELCOME JSR PRINT_STR ; Read a line of input JSR READ_LINE ; result in INBUF, length in INLEN ; Echo it back LDA #MSG_YOU_TYPED JSR PRINT_STR LDX #0 ECHO LDA INBUF,X BEQ ECHO_DONE JSR $FFD2 ; BSOUT INX BNE ECHO ECHO_DONE: LDA #$0D JSR $FFD2 ; print CR ; Write a file to disk JSR WRITE_FILE RTS ; --------------------------------------------------------------- ; PRINT_STR — Print null-terminated string ; Input: A = low byte, X = high byte of string address ; --------------------------------------------------------------- PRINT_STR: STA $FB ; store address in zero page STX $FC LDY #0 PS_LOOP LDA ($FB),Y ; load character BEQ PS_DONE ; zero = end JSR $FFD2 ; BSOUT — output to screen INY BNE PS_LOOP PS_DONE RTS ; --------------------------------------------------------------- ; READ_LINE — Read keyboard input until RETURN ; Output: INBUF filled, INLEN = number of chars read ; --------------------------------------------------------------- READ_LINE: LDX #0 ; buffer index RL_LOOP JSR $FFE4 ; GETIN — get character (non-blocking) BEQ RL_LOOP ; no key, keep waiting CMP #$0D ; RETURN key? BEQ RL_DONE CMP #$14 ; DELETE key? BEQ RL_DEL CPX #79 ; buffer full? BEQ RL_LOOP STA INBUF,X ; store character JSR $FFD2 ; echo to screen INX BNE RL_LOOP RL_DEL CPX #0 BEQ RL_LOOP ; nothing to delete DEX LDA #$14 JSR $FFD2 ; output DELETE BNE RL_LOOP RL_DONE LDA #0 STA INBUF,X ; null terminate STX INLEN LDA #$0D JSR $FFD2 ; echo CR RTS ; --------------------------------------------------------------- ; WRITE_FILE — Write data to a sequential disk file ; --------------------------------------------------------------- WRITE_FILE: ; SETLFS: logical=2, device=8, secondary=2 LDA #2 LDX #8 LDY #2 JSR $FFBA ; SETLFS ; SETNAM: filename "OUTPUT,S,W" LDA #OUTNAME_LEN LDX #OUTNAME JSR $FFBD ; SETNAM ; OPEN JSR $FFC0 ; OPEN BCS WF_OERR ; error if carry set ; CHKOUT: redirect output to file LDX #2 JSR $FFC9 ; CHKOUT BCS WF_CERR ; Write data LDX #0 WF_LOOP LDA FILEDATA,X BEQ WF_DONE JSR $FFD2 ; BSOUT to file INX BNE WF_LOOP WF_DONE JSR $FFCC ; CLRCH — restore default channels LDA #2 JSR $FFC3 ; CLOSE ; Check disk error channel JSR $FFBA ; reuse: SETLFS 15,8,15 ; Actually let's just print success LDA #MSG_SAVED JMP PRINT_STR WF_OERR LDA #MSG_OERR JMP PRINT_STR WF_CERR LDA #MSG_CERR JMP PRINT_STR ; --------------------------------------------------------------- ; Data ; --------------------------------------------------------------- MSG_WELCOME: .BYTE 147 ; clear screen .TEXT "KERNAL I/O DEMO" .BYTE $0D .TEXT "TYPE SOMETHING AND PRESS RETURN:" .BYTE $0D,0 MSG_YOU_TYPED: .TEXT "YOU TYPED: " .BYTE 0 MSG_SAVED: .BYTE $0D .TEXT "FILE WRITTEN TO DISK." .BYTE $0D,0 MSG_OERR: .TEXT "ERROR: COULD NOT OPEN FILE" .BYTE $0D,0 MSG_CERR: .TEXT "ERROR: COULD NOT REDIRECT OUTPUT" .BYTE $0D,0 OUTNAME: .TEXT "OUTPUT,S,W" OUTNAME_LEN = * - OUTNAME FILEDATA: .TEXT "DATA LINE 1" .BYTE $0D .TEXT "DATA LINE 2" .BYTE $0D,0 ; --------------------------------------------------------------- ; Variables ; --------------------------------------------------------------- INBUF .FILL 80,0 ; 80-byte input buffer INLEN .BYTE 0 ; length of input