; 6809 Serial Tube Client Code ; ============================ ; Copyright (C)2010 J.G.Harston ; ; v0.10 12-Jun-2011 JGH: Converted from Tube client ; Based on 6809 Tube Client and Z80 Serial Tube Client ; v0.21 07-Jan-2012 JGH: Software reset sent on startup ; Added client error handler, version matches Tube client ; This code may be freely reused. ; NOTE! I don't have any 6809 hardware, so I don't know if this executes ; BA/BS Signals are used to remap hardware vectors from &FFFx to &FEFx ; Memory layout: ; -F7FF - System stack ; F800-FFFF - Client ROM, copied to RAM on startup ; F800-F82E - Monitor ROM entry vectors ; FEF0-FEFF - Hardware vectors, remapped from &FFF0-&FFFF ; FF80- - Internal variables ; FFCE-FFE7 - Standard BBC MOS Entry Block ; Client error implemented with SWI (equivalent of 6502 BRK, Z80 RST &38, etc.) ; Serial I/O Addresses ; ==================== ; These are suitable for a 6850 TxSTATUS EQU $FEE0 TxDATA EQU $FEE1 RxSTATUS EQU $FEE0 RxDATA EQU $FEE1 TxRDY EQU 1 RxRDY EQU 2 RxINIT EQU 3 TxINIT EQU $15 ; Serial Tube system values ; ========================= esc EQU 127 ; START OF ROM CODE ; ================= ORG $F800 STACK: ROMSTART: COLD: FDB RESET ; $F800 - cold start WARM: FDB WARMS ; $F802 - warm start INCH: FDB OSRDCH ; $F804 - char input INCHE: FDB INECHO ; $F806 - char input with echo INCHECK: FDB KBDTST ; $F808 - test for char input OUTCH: FDB OSWRCH ; $F80A - char output PDATA: FDB PRDAT ; $F80C - output string until EOT PCRLF: FDB OSNEWL ; $F80E - output CR/LF PSTRING: FDB PRTST ; $F810 - output CR/LF then string until EOT LRA: FDB LREAL ; $F812 - Load Real Address BRA WARMS ; $F814 - for FLEX compatibility BANNER: FCB 13 FCC "6809 SERIAL TUBE 64K v0.21" FCB 13 FCB 13 FCB 0 RESET: ORCC #$50 ; Ensure interupts disabled LDS #STACK ; Put stack at top of memory LDX #ROMSTART ; Start at start of ROM RESETLP1: LDA ,X ; Get a byte from ROM STA ,X+ ; Store to RAM and increment X CMPX #IOADDRS BNE RESETLP1 ; Loop until hit I/O space LDX #ROMHIGH ; Point to ROM after I/O space RESETLP2: LDA ,X STA ,X+ CMPX #0 BNE RESETLP2 ; Copy top part of ROM to RAM ; STARTUP ; ======= ; Serial Tube data: $18 $00 $FF &FF -- Cy Y X ; followed by string ; ; Hardware Tube data: via R1: string $00 -- via R2: $7F or $80 ; STARTUP: ORCC #$50 ; Disable interupts LDS #STACK STS MEMTOP ; Initialise top of memory LEAS -1,S ; Put stack at top of memory LDX #0 STX MEMBOT ; Initialise bottom of memory LDA #TxINIT STA >TxSTATUS ; Initialise serial port LDA #RxINIT STA >RxSTATUS ; Initialise serial port ANDCC #$00 ; Clear all flags, enable interupts JSR INITERR ; Initialise error handler LDA #$FF ; As we are using a serial link, we don't share a LDY #$FF ; hardware Reset, so we have to tell Host we have JSR FSC ; restarted. Send FSC &FF,&00,&FF - Soft Reset command TFR X,D PSHS B ; Save Soft Reset result, will be &00 if no response LDX #BANNER ; Point to startup banner JSR SEND_TXT ; Print it via Tube wrch protocol ; ; Accessing Tube registers pages ROM out LDA #0 STA >ESCFLG ; Clear Escape flag ; If we share a hardware Reset, we wait for an Ack here ; JSR OSWRCH ; Send terminating zero byte ; JSR CLI_WAIT ; Wait for result byte PULS A ; We sent a Software Reset, so use the Ack from that JSR CLI_CHECK ; Check result byte ; ; Fall through to CLICOM if nothing executed ; Command line prompt ; =================== ; Allow user to enter *commands ; WARMS: CLILOOP: LDS MEMTOP ; Reset stack to top of memory JSR INITERR ; Initialise error handler ANDCC #$00 ; Clear all flags, enable interupts LDX #PROMPT JSR SEND_TXT ; Display prompt LDX #COM_BLK ; Point to control block LDA #0 JSR OSWORD ; Read a line of text BCS COM_ESC ; Escape pressed LDX #CLIBUF JSR OS_CLI ; Execute command BRA CLILOOP ; Loop back for another line PROMPT: FCC "6809*" ; Command prompt FCB 0 ; COM_BLK: FDB CLIBUF ; Input buffer FCB 127 ; Up to 127 characters FCB 32 ; Lowest acceptable CHR$32 FCB 255 ; Highest acceptable CHR$255 ; ESCAPE: SWI FCB 17 FCC "Escape" FCB 0 COM_ESC: LDA #124 JSR OSBYTE ; Acknowledge Escape LDX #ESCAPE+1 ; Fall through into error handler COM_ERR: LDS MEMTOP ; Reset stack to top of memory JSR OSNEWL LDA ,X+ ; Step X past error number JSR SEND_TXT ; Print text at X JSR OSNEWL BRA WARMS ; Return to command prompt COM_INIT: LDD #SWI STD XSWIV ; Point SWI vector to error BRK handler LDD #COM_ERR ; Point error vector to command prompt STD BRKV ; error handler RTS ; FLEX/OS-9 BIOS code ; =================== INECHO: JSR INCH JMP OUTCH PRTST: JSR PCRLF PRDAT: LDA ,X+ ; Get character CMPA #4 ; EOT character? BEQ PREND ; End printing JSR OUTCH ; Print character BRA PRDAT ; Loop to next PREND: LREAL: RTS ; Print inline text ; ================= PR_TEXT: PULS X ; Pop PC to X JSR SEND_TXT ; Print text PSHS X ; Push updated X RTS ; And return to it ; Print text string at X ; ====================== SEND_TXT: LDA ,X+ ; Get byte from x, increment x CMPA #0 ; Test current character BEQ SEND_END ; End if $00 byte JSR OSASCI ; Send to OSASCI BRA SEND_TXT ; Loop until $00 byte ; OSRDCH - Wait for character from input stream ; ============================================= ; On exit: A=char, Cy=carry ; RDCH: JSR WaitByte ; Wait for character PSHS A ; Save character LDA >ESCFLG ; Get Escape flag ROLA ; Copy b7 of ESCFLG to Carry PULS A ; Get character back SEND_END: RTS ; OSRDCH_IO - Request character via Tube API ; ========================================== ; Tube data: $00 -- Carry Char ; ; On exit: A=char, Cy=carry ; RDCH_IO: LDA #0 JSR SendCommand ; Send command $00 - OSRDCH WAIT_CHAR: JSR WaitByte ; Get returned byte ADDA #$80 ; Copy b7 into Carry JMP WaitByte ; Jump to get character ; OSCLI - Send command line to host ; ================================= ; Tube data: $02 string $0D -- $7F or $80 ; ; On entry: X=>command string ; CLI: LDA #2 JSR SendCommand ; Send command $02 = OSCLI JSR SEND_STR ; Send string at X CLI_WAIT: JSR WaitByte ; Wait for result via Tube R2 CLI_CHECK: CMPA #$80 ; Check return code BNE CLI_DONE ; Nothing to execute, return CODE_CALL: JSR [ADDRESS+2] ; Call program, 6809 is big-endian CLI_DONE: RTS ; OSBYTE ; ====== ; Tube data: $04 X A -- X ; $06 X Y A -- Cy Y X ; ; On entry: A,X,Y=OSBYTE parameters ; On exit: A preserved ; If A<$80, X=returned value ; If A>$7F, X, Y, Carry=returned values ; BYTE: CMPA #$80 BCC BYTE_HI PSHS A,B LDA #4 JSR SendCommand ; SEND COMMAND $04 - SHORT BYTE TFR X,D ; B=X JSR SendByteB ; SEND SECOND PARAMETER FROM B PULS A,B PSHS A,B JSR SendByte ; SEND FIRST PARAMETER JSR WaitByte ; WAIT FOR RESPONSE TFR A,B ; Move result to low byte LDA #0 ; Ensure AB is only 8-bit value TFR D,X PULS A,B RTS ; OSFSC ; ===== ; Tube data: $18 X Y A -- Cy Y X ; ; On entry: A,X,Y=OSFSC parameters ; NB: Only implemented for A>$7F ; On exit: A preserved ; X, Y, Carry=returned values ; FSC: PSHS A,B LDA #$18 ; Set command $18 - FSC BRA BYTE_CMD ; Jump to send command ; OSBYTE >$7F ; ----------- BYTE_HI: CMPA #$82 BEQ MEM82 ; FETCH ADDRESS HIGH WORD CMPA #$83 BEQ MEM83 ; FETCH LOW MEMORY LIMIT CMPA #$84 BEQ MEM84 ; FETCH HIGH MEMORY LIMIT PSHS A,B LDA #6 ; Set command $06 - long byte BYTE_CMD: JSR SendCommand ; Send command TFR X,D ; B=X - second parameter JSR SendByteB ; Send second parameter from B TFR Y,D ; B=Y - third parameter JSR SendByteB ; Send third parameter from B PULS A,B JSR SendByte ; Send first parameter CMPA #$9D ; Was it fast BPUT? BEQ BYTE_DONE ; Don't wait for response CMPA #$8E ; Was it start language? BEQ CLI_WAIT ; Wait for program start PSHS A,B JSR WaitByte ; Wait for response ADDA #$80 ; Copy b7 into carry PSHS CC ; Save flags JSR WaitByte ; Wait for response TFR A,B ; Move result to low byte LDA #0 ; Ensure AB is only 8-bit value TFR D,Y ; Return result in Y JSR WaitByte ; Wait for response, high byte still in B EXG A,B ; Swap so high byte is Y, low byte is fetched byte TFR D,X ; Return result in X is returned Y*256+X value PULS CC ; Get flags back PULS A,B BYTE_DONE: RTS MEM82: LDX #0 ; Local memory is $0000xxxx RTS MEM83: LDX MEMBOT ; Return bottom of user memory in X RTS MEM84: LDX MEMTOP ; Return top of user memory in X RTS ; OSWORD ; ====== ; On entry: A=OSWORD number ; X=>control block ; WORD: CMPA #0 BEQ RDLINE RTS ; Ignore OSWORD <>0 for the moment ;PSHS A ;LDA #8 ;JSR SendCommand ; SEND COMMAND $08 - OSWORD ; ; SEND PARAM BLOCK, ETC. ; ;RTS ; OSWORD 0 - Read a line of text ; ------------------------------ ; Tube data: $0A block -- $FF or $7F string $0D ; RDLINE: LDA #10 JSR SendCommand ; Send Command $0A - RDLINE LEAX 2,X ; X=X+2, point to parameters LDY #3 JSR SEND_BLK ; Send 3-byte control block LEAX -2,X ; X=X-2, point back to text pointer LDA #7 JSR SendByte ; Send $0700 LDA #0 JSR SendByte JSR WaitByte ; Wait for response ADDA #$80 ; Copy b7 into Carry BCS RD_DONE LDX ,X ; Get text pointer from control block STR_READ: LDY #0 ; Y=number received JSR WaitByte ; Wwait for byte from Tube STA ,X+ ; Store in text buffer, increment X LEAY 1,Y ; Increment character count CMPA #13 ; CHECK CURRENT BYTE BNE STR_READ ; LOOP UNTIL LEAY -1,Y ; Decrement character count to balance ANDCC #$FE ; CLEAR CARRY RD_DONE: RTS ; OSARGS - Read info on open file ; =============================== ; Tube Data: $0C handle block function -- result block ; ; On entry: A=action ; X=>data ; Y=handle ; On exit: A=returned value ; X preserved ; X=>any returned data ; Y preserved ; ARGS: PSHS Y ; Save handle PSHS A,B ; Save function and B LDA #$0C JSR SendCommand ; Send command $0C - OSARGS TFR Y,D JSR SendByteB ; Send handle LDY #4 JSR SEND_BLK ; Send four-byte control block PULS A,B ; Get action back JSR SendByte ; Send action JSR WaitByte ; Wait for returned result PSHS A ; Save result LDY #4 JSR WAIT_BLK ; Wait for four-byte control block PULS A ; Get result back PULS Y ; Get original handle back RTS ; OSBGET - Get a byte from open file ; ================================== ; Tube data: $0E handle -- Carry byte ; ; On entry: Y=handle ; On exit: A=byte Read ; Y=preserved ; Cy set if EOF ; BGet: LDA #$0E JSR SendCommand ; Send command $0E - OSBGET PSHS A,B TFR Y,D JSR SendByteB ; Send handle PULS A,B LBRA WAIT_CHAR ; Wait for Carry, Byte ; OSBPUT - Put a byte to an open file ; =================================== ; Tube data: $10 handle byte -- $7F ; ; On entry: A=byte to write ; Y=handle ; On exit: A=preserved ; Y=preserved ; BPut: PSHS A,B ; Save byte LDA #$10 JSR SendCommand ; Send command $10 - OSBPUT TFR Y,D JSR SendByteB ; Send handle PULS A,B ; Get A and B back PSHS A,B JSR SendByte ; Send byte to Tube JSR WaitByte ; Wait for acknowledgement PULS A,B ; Restore A RTS ; OSFIND - Open or Close a file ; ============================= ; Tube data: $12 function string $0D -- handle ; $12 $00 handle -- $7F ; ; On entry: A=function ; Y=handle or X=>filename ; On exit: A=zero or handle ; FIND: PSHS A,B ; Save A LDA #$12 JSR SendCommand ; Send command $12 - OSFIND PULS A,B ; Get R0 back JSR SendByte ; Send function CMPA #0 ; Check function BEQ Close ; Jump to deal with Close JSR SEND_STR ; Send string at X JSR WaitByte ; Wait for returned handle RTS Close: PSHS B TFR Y,D JSR SendByteB ; Send handle to Tube JSR WaitByte ; Wait for acknowledgement PULS B LDA #0 ; Zero A RTS ; OSFILE - Operate on whole files ; =============================== ; Tube data: $14 block string function -- result block ; ; On entry: A=function ; X=>control block ; On exit: A=result ; X preserved ; control block updated ; FILE: PSHS Y ; Save Y PSHS X ; Save X PSHS A ; Save function LDA #$14 JSR SendCommand ; Send command $14 - OSFILE LEAX 2,X ; Point to control block contents LDY  #16 JSR SEND_BLK ; Send 16-byte control block LEAX -2,X ; Point to filename pointer LDX ,X ; Get filename pointer to X JSR SEND_STR ; Send filename string PULS A JSR SendByte ; Send function JSR WaitByte ; Wait for returned result ; ; Data transfer via interupts may happen while waiting PULS X ; Get control block pointer back PSHS A ; Save result LEAX 2,X ; Point to control block contents LDY #16 JSR WAIT_BLK ; Wait for 16-byte control block PULS A ; Get result back PULS Y ; Get Y back RTS ; OSGBPB - Multiple byte Read and write ; ===================================== ; Tube data: $16 block function -- block Carry result ; ; On entry: A=function ; X=>control block ; On exit: A=returned value ; control block updated ; GBPB: PSHS Y ; Save Y PSHS A ; Save function LDA #$16 JSR SendCommand ; Send command $16 - OSGBPB LDY #13 JSR SEND_BLK ; Send 13-byte control block PULS A JSR SendByte ; Send function LDY #13 JSR WAIT_BLK ; Wait for 13-byte control block PULS Y ; Get Y back LBRA WAIT_CHAR ; Get Carry and result byte ; Tube I/O routines ; ================= ; Send cr-string at X to Tube ; =========================== SEND_STR: LDA ,X+ ; GET BYTE FROM X, INCREMENT X JSR SendByte ; SEND BYTE VIA TUBE R2 CMPA #13 ; TEST CURRENT CHARACTER BNE SEND_STR ; LOOP UNTIL CR SENT RTS ; Send block at X to Tube, Y=block length ; ======================================= SEND_BLK: PSHS B ; Save B TFR Y,D ; B=Y ABX ; X=X+B, X points to end of block+1 PULS B ; Restore B SEND_BLKLP: LDA ,-X ; DECREMENT X, GET BYTE FROM X JSR SendByte ; SEND BYTE VIA TUBE R2 LEAY -1,Y ; DECREMENT COUNT OF BYTES TO SEND BNE SEND_BLKLP ; LOOP UNTIL ALL BYTES SENT RTS ; Wait for block at X from Tube, Y=block length ; ============================================= WAIT_BLK: PSHS B ; Save B TFR Y,D ; B=Y ABX ; X=X+B, X points to end of block+1 PULS B ; Restore B WAIT_BLKLP: JSR WaitByte ; GET BYTE VIA TUBE R2 STA ,-X ; DECREMENT X, STORE BYTE AT X LEAY -1,Y ; DECREMENT COUNT OF BYTES BNE WAIT_BLKLP ; LOOP UNTIL ALL BYTES SENT RTS ; Send byte in B to Tube ; ====================== SendByteB: TFR B,A ; ; Fall through into SendByte ; OSWRCH - Send character in A to Tube ; ==================================== ; On entry, A =character ; On exit, A =preserved WRCH: ; ; WRCH is simply SendByte ; Tube Core I/O Routines ; ====================== ; Characters and commands are sent over the same single port ; Outward commands are escaped, and inward responses are escaped ; ; Outward ; x VDU x ; esc,esc VDU esc ; esc,n MOS function, control block follows ; ; Inward ; x char/byte x ; esc,esc char/byte esc ; esc,&00 BRK, error number+text+null follows ; esc,<&80 read returned control block set length ; esc,&8n Escape change, b0=new state ; esc,&9x,Y,X,A Event ; esc,&Ax reserved for networking ; esc,&Bx end transfer ; esc,&Cx,addr set address ; esc,&Dx,addr execute address ; esc,&Ex,addr start load from address ; esc,&Fx,addr start save from address ; All commands are data inward, except esc,&Fx which is data outward ; Send byte in A, escaping it if needed ; ===================================== SendByte: CMPA #esc ; Escape character? BNE SEND_DATA ; No, send raw JSR SEND_DATA ; Double escape character SEND_DATA: PSHS A ; Save byte SEND_WAIT: LDA >TxSTATUS ANDA #TxRDY BEQ SEND_WAIT ; Loop until data can be sent PULS A ; Get byte back STA >TxDATA ; Send data RTS ; Send an escaped command ; ======================= SendCommand: PSHS A ; Save command byte LDA #esc JSR SEND_DATA ; Send esc prefix PULS A BRA SEND_DATA ; Send command byte ; Check if a byte is waiting, and read it if there ; ================================================ BYTE_READ: LDA >RxSTATUS ANDA #RxRDY BNE WAIT_EXIT ; Nothing pending, return ; ; Continue into WaitByte ; Wait for a byte, decoding escaped data ; ====================================== ; On exit, A =byte ; F =preserved ; WaitByte: PSHS CC ; Save flags WaitByteLP: JSR WAIT_DATA BNE WaitByteOK ; Not esc, return JSR WAIT_DATA ; Get another byte BEQ WaitByteOK ; esc,esc, return PSHS X,Y,B,U ; Push all registers JSR WAIT_COMMAND ; Decode escaped command PULS X,Y,B,U ; Pop all registers BRA WaitByteLP WaitByteOK: PULS CC ; Pop flags WAIT_EXIT: RTS ; Wait for data ; ============= ; On exit, A =byte ; F =Z byte=esc, NZ byte<>esc ; WAIT_DATA: LDA >RxSTATUS ANDA #RxRDY BEQ WAIT_DATA ; Loop until data present LDA >RxDATA ; Fetch data CMPA #esc ; Is it esc prefix? RTS ; Decode escaped command ; ====================== ; On entry, A=command ; All registers can be trashed ; WAIT_COMMAND: ANDA #255 BEQ WAIT_ERROR ; esc,&00 - error BMI WAIT_TRANSFER ; esc,>&7F - data transfer ; esc,1..127 - read a control block ; ================================= ; esc,&00 - error ; =============== WAIT_ERROR: LDX #ERRBLK ; Point to error buffer LDA #$3F ; SWI opcode STA ,X+ ; Store SWI opcode JSR WaitByte ; Get error number STA ,X+ ; Store error number FIRQ_R4LP: JSR WaitByte ; Wait for byte of error string STA ,X+ ; Store in error buffer CMPA #0 ; Check current character BNE FIRQ_R4LP ; Loop until terminating $00 received LDA ERRBLK+1 ORA ERRBLK+2 ; Check for error 0,"" BEQ JMP_START LDX #ERRBLK ; Point to error block JMP ERRJMP ; Jump to generate error JMP_START: JMP STARTUP ; esc,&8n - Escape change ; ======================= WAIT_TRANSFER: CMPA #$C0 BCC WAIT_START CMPA #$A0 BCC WAIT_END CMPA #$90 BCC WAIT_EVENT RORA RORA ; Move b0 into b7 STA >ESCFLG ; Store Escape flag RTS ; esc,&9x - Event ; =============== WAIT_EVENT: JSR WaitByte ; Get event Y parameter TFR A,B LDA #0 TFR D,Y JSR WaitByte ; Get event X parameter TFR A,B LDA #0 TFR D,X JSR WaitByte ; Get event A parameter JSR [EVENTV] ; Dispatch event RTS ; esc,&Ax - Reserved ; ================== WAIT_END: CMPA #$B0 BCS WAIT_EXIT ; &Ax - Return to WaitByte ; esc,&Bx - End transfer ; ====================== PULS X,Y,A,B PULS X,Y ; Drop data from stack to fall ; ; out of WaitSave/WaitLoad loop WAIT_EXIT2: RTS ; Return to WaitByte ; esc,&C0+ - Start transfer ; ========================= WAIT_START: PSHS A ; Save transfer type JSR WaitByte STA ADDRESS+0 ; Note - 6809 is big-endian JSR WaitByte ; Get data address STA ADDRESS+1 JSR WaitByte ; Get data address STA ADDRESS+2 JSR WaitByte ; Get data address LSB STA ADDRESS+3 LDX ADDRESS+2 ; Get transfer address PULS A ; Get transfer type back CMPA #$D0 BCS WAIT_EXIT2 ; &Cx - set address CMPA #$E0 BCS WAIT_CODE ; &Dx - enter code CMPA #$F0 BCC WAIT_SAVE ; &Fx - save data WAIT_LOAD: JSR WaitByte ; &Ex - load data STA ,X+ ; Get byte, store it BRA WAIT_LOAD ; Loop until terminated WAIT_SAVE: LDA ,X+ ; Get byte JSR SendByte ; Send it JSR BYTE_READ ; Poll input for termination BRA WAIT_SAVE ; Loop until terminated WAIT_CODE: JMP CODE_CALL ; SWI - Generate an error ; ======================= SWI: LEAS 10,S ; Step past stack contents PULS X ; Pop PC to X ANDCC #$00 ; Clear all flags, enable interupts ERRHANDLE: STX FAULT ; Save pointer to last error JMP [BRKV] ; Jump to current error handler ; Null interupt routines ; ====================== FIRQ: RES: SWI2: SWI3: IRQ: NMI: RTI ; Null routines ; ============= TSTKBD: ANDCC #$FB ; Clear Z NULL: RTS ERRBLK: RMB 128 ; Buffer to store host error block CLIBUF: RMB 128 ; Space to enter command line from CLI prompt FCB 0 ; Generate a line in the listing ORG $FEE0 IOADDRS: ORG $FEF0 ROMHIGH: XRESV: FDB RES ; $FEF0 ; Hardware vectors, paged in to $FFFx XSWI2V: FDB SWI2 ; $FEF2 XSWI3V: FDB SWI3 ; $FEF4 XFIRQV: FDB FIRQ ; $FEF6 XIRQV: FDB IRQ ; $FEF8 XNMIV: FDB NMI ; $FEFA XSWIV: FDB SWI ; $FEFC XRESETV: FDB RESET ; $FEFE ORG $FF80 ; Use same addresses as Z80 ESCFLG: FCB 0 ; $FF80 ; Escape flag FCB 0 FAULT: FDB 0 ; $FF82 ; Last error message FDB 0 ; $FF84 FDB 0 ; $FF86 MEMBOT: FDB 0 ; $FF88 ; Bottom of user memory MEMTOP: FDB $F800 ; $FF8A ; Top of user memory ADDRESS: FDB 0 ; $FF8C ; Tube transfer address FDB 0 PROGRAM: FDB 0 ; $FF90 ; Program entry address DMA_DONE: FCB 0 ; $FF92 ; Transfer completion flag ORG $FFB0 USERINT: JMP >NULL ; &FFB0 IRQ2V: EQU USERINT+1 PRTEXT: JMP >PR_TEXT ; &FFB3 JMP >NULL ; &FFB6 CLICOM: JMP >CLILOOP ; &FFB9 ERRJMP: JMP >ERRHANDLE; &FFBC INITERR: JMP >COM_INIT ; &FFBF JMP >NULL ; &FFC2 KBDTST: JMP >TSTKBD ; &FFC5 JMP >NULL ; &FFC8 JMP >NULL ; &FFCB OSFIND: JMP >FIND ; $FFCE OSGBPB: JMP >GBPB ; $FFD1 OSBGET: JMP >BGet ; $FFD4 OSBPUT: JMP >BPut ; $FFD7 OSARGS: JMP >ARGS ; $FFDA OSFILE: JMP >FILE ; $FFDD OSRDCH: JMP >RDCH ; $FFE0 OSASCI: CMPA #13 ; $FFE3 BNE OSWRCH OSNEWL: LDA #10 ; $FFE7 JSR OSWRCH OSWRCR: LDA #13 ; $FFEC OSWRCH: JMP >WRCH ; $FFEE OSWORD: JMP >WORD ; $FFF1 OSBYTE: JMP >BYTE ; $FFF4 OS_CLI: JMP >CLI ; $FFF7 BRKV: FDB COM_ERR ; $FF84 ; Error handler EVENTV: FDB NULL ; $FF86 ; Event vector L_FFFE: FDB RESET