10
20
30 :
40 IF PAGE>&8000:SYS "OS_GetEnv"TOA$:IFLEFT$(A$,5)<>"B6502":OSCLI"B6502"+MID$(A$,INSTR(A$," "))
50 ON ERROR REPORT:PRINT" at line ";ERL:END
60 :
70 fname$="KernelCP"
80 load%=&F800:DIM mcode% &900
90 :
100 nmiv =&200:brkv =&202:irq1v=&204:cliv =&206
110 wrchv=&208:rdchv=&20A:loadv=&20C:savev=&20E
120 rdarv=&210:starv=&212:bgetv=&214:bputv=&216
130 findv=&218:shutv=&21A:EVNTV=&220
140 IOADDR=&FEE0
150 IOTUBE=&FEF8
160
170
180 :
190 ERRBUF=&236:INPBUF=&236
200 :
210
220
230
240
250
260
270
280
290
300
310
320
330 :
340
350
360 :
370 FOR P=0TO1
380 P%=load%:O%=mcode%
390 [OPT P*3+4+16
400 .RESET
410 LDX #&00
420 .LF802
430 LDA &FF00,X:STA &FF00,X :\ Copy entry block to RAM
440 DEX:BNE LF802
450 LDX #&36
460 .LF80D
470 LDA VECTABLE,X:STA &200,X :\ Set up default vectors
480 DEX:BPL LF80D
490 TXS :\ Clear stack
500 LDX #IOADDR AND 255
510 .LF819
520 LDA &FDFF,X:STA &FDFF,X :\ Copy &FE00-&FEEF to RAM, avoiding
530 DEX:BNE LF819 :\ Tube registers at &FEFx
540 LDY #RESET AND 255:STY &F8 :\ Point to start of ROM
550 LDA #RESET DIV 256:STA &F9
560 .LF82A :\ Copy rest of ROM to RAM
570 LDA (&F8),Y:STA (&F8),Y :\ Copy a page to RAM
580 INY:BNE LF82A :\ Loop for 256 bytes
590 INC &F9:LDA &F9 :\ Inc. address high byte
600 CMP #&FE:BNE LF82A :\ Loop from &F800 to &FDFF
610 LDX #&10
620 .LF83B
630 LDA LF859,X:STA &0100,X :\ Copy jump code to &100
640 DEX:BPL LF83B
650 LDA &EE:STA &F6 :\ Copy &EE/F to &F6/7
660 LDA &EF:STA &F7
670 LDA #&00:STA &FF :\ Clear Escape flag
680 STA &F2:LDA #&F8:STA &F3 :\ Set memtop to start of ROM at &F800
690 JMP &0100 :\ Jump via low memory to page ROM out
700
710 \ Executed in low memory to page ROM out
720 \ --------------------------------------
730 .LF859
740 LDA TubeS1:CLI :\ Check Tube R1 status to page ROM out
750 .LF85D
760 JMP LF860 :\ Jump to initilise I/O with banner
770
780 .LF860
790 JSR PrText :\ Display startup banner
800 EQUB 10:EQUS "Acorn Atom/System Tube"
810 EQUB 10:EQUB 10:EQUB 13:EQUB 0
820 NOP
830 LDA #CmdOSLoop AND 255 :\ Next time RESET is soft entered,
840 STA LF85D+1 :\ banner not printed
850 LDA #CmdOSLoop DIV 256
860 STA LF85D+2
870 LDA #&00 :\ Look for a entry point at &EC/D
880 LDX &EC:LDY &ED:STA &ED
890 BNE JumpToCode
900 JSR WaitByte :\ Wait for Acknowledge
910 CMP #&80:BEQ EnterCode :\ If &80, jump to enter code
920 :\ Otherwise, enter command prompt loop
930
940 \ Minimal Command prompt
950 \ ======================
960 .CmdOSLoop
970 JSR PrText
980 EQUS "SYSTEM>* ":NOP :\ Display prompt
990 LDX #LF95D AND 255
1000 LDY #LF95D DIV 256
1010 LDA #&00:JSR XOSWORD :\ Read line to INPBUF
1020 BCS CmdOSEscape
1030 LDX #INPBUF AND 255
1040 LDY #INPBUF DIV 256 :\ Execute command
1050 JSR XOS_CLI:JMP CmdOSLoop :\ and loop back for another
1060 .CmdOSEscape
1070 LDA #&7E:JSR XOSBYTE :\ Acknowledge Escape state
1080 BRK:EQUB 17:EQUS "Escape":BRK
1090
1100
1110 \ Enter Code pointer to by &F6/7
1120 \ ==============================
1130 \ Checks to see if code has a ROM header, and verifies
1140 \ it if it has
1150 .JumpToCode
1160 STX &F6:STY &F7 :\ Enter code at XY
1170 .EnterCode
1180 LDA &F6:STA &EE:STA &F2 :\ Set current program and memtop
1190 LDA &F7:STA &EF:STA &F3 :\ to address beng entered
1200 .z%
1210 LDY #&07:LDA (&EE),Y :\ Get copyright offset
1220 CLD:CLC:ADC &EE:STA &FD
1230 LDA #&00:ADC &EF:STA &FE :\ &FD/E=>copyright message
1240 \
1250 \ Now check for &00,"(C)"
1260 LDY #&00:LDA (&FD),Y:BNE LF8FA :\ Jump if no initial &00
1270 INY:LDA (&FD),Y:CMP #&28:BNE LF8FA :\ Jump if no '('
1280 INY:LDA (&FD),Y:CMP #&43:BNE LF8FA :\ Jump if no 'C'
1290 INY:LDA (&FD),Y:CMP #&29:BNE LF8FA :\ Jump if no ')'
1300 \
1310 \ &00,"(C)" exists
1320 LDY #&06:LDA (&EE),Y :\ Get ROM type
1330 AND #&4F:CMP #&40:BCC NotLanguage :\ b6=0, not a language
1340 AND #&0D:BNE Not6502Code :\ type<>0 and <>2, not 6502 code
1350 ]:z%=P%-z%:P%=P%-z%:O%=O%-z%:[OPT P*3+4
1360 .LF8FA
1370 LDA #&01:JMP (&00F2) :\ Enter code with A=1
1380 \
1390 .z%
1400 \ Any existing error handler will probably have been overwritten
1410 \ Set up new error handler before generating an error
1420 .NotLanguage
1430 LDA #ErrorHandler AND 255:STA brkv+0 :\ Claim error handler
1440 LDA #ErrorHandler DIV 256:STA brkv+1
1450 BRK:EQUB 0:EQUS "This is not a language":EQUB 0
1460
1470 .Not6502Code
1480 LDA #ErrorHandler AND 255:STA brkv+0 :\ Claim error handler
1490 LDA #ErrorHandler DIV 256:STA brkv+1
1500 BRK:EQUB 0:EQUS "I cannot run this code":EQUB 0
1510 ]:z%=P%-z%:P%=P%-z%:O%=O%-z%:[OPT P*3+4
1520
1530 \ Default error handler
1540 \ =====================
1550 \ On Atom/System, adjustment of &FD/E is done in error handler
1560 \ SP=>flags, ret.lo, ret.hi
1570 \
1580 .ErrorHandler
1590 TXA:PHA :\ Save X
1600 TSX:LDA &0103,X :\ Get address from stack
1610 CLD:SEC:SBC #&01:STA &FD
1620 LDA &0104,X:SBC #&00:STA &FE :\ &FD/E=>after BRK opcode
1630 PLA:TAX:LDA &FC:CLI :\ Restore X, get saved A
1640
1650 \ Now continue into normal error handler
1660 LDX #&FF:TXS :\ Clear stack
1670 JSR OSNEWL:LDY #&01
1680 .LF94D
1690 LDA (&FD),Y:BEQ LF957 :\ Print error string
1700 JSR OSWRCH:INY:BNE LF94D
1710 .LF957
1720 JSR OSNEWL:JMP CmdOSLoop :\ Jump to command prompt
1730
1740 \ Control block for command prompt input
1750 \ --------------------------------------
1760 .LF95D
1770 EQUW INPBUF :\ Input text to INPBUF at &236
1780 EQUB &B7 :\ Up to &CA characters
1790 EQUB &20:EQUB &FF :\ Min=&20, Max=&FF
1800
1810
1820 \ MOS INTERFACE
1830 \ =============
1840 \
1850 \
1860 \ OSWRCH - Send character to output stream
1870 \ ========================================
1880 \ On entry, A =character
1890 \ On exit, A =preserved
1900 \
1910 \ Tube data character --
1920 \
1930 .osWRCH:.atomWRCH
1940 BIT TubeS1 :\ Read Tube R1 status
1950 NOP:BVC osWRCH :\ Loop until b6 set
1960 STA TubeR1:RTS :\ Send character to Tube R1
1970
1980
1990 \ A bit of hand-holding for RDCH
2000 \ ------------------------------
2010 .atomRDCH
2020 LDA &FF:BPL doRDCH
2030 LDA #&7E:JSR XOSBYTE :\ Ack. any Escape
2040 .doRDCH
2050 LDA #&FF:STA &0E21 :\ Set 'no key pressed'
2060 :\ Continue into osRDCH
2070
2080
2090 \ OSRDCH - Wait for character from input stream
2100 \ =============================================
2110 \ On exit, A =char, Cy=Escape flag
2120 \
2130 \ Tube data &00 -- Carry Char
2140 \
2150 .osRDCH
2160 LDA #&00:JSR SendCommand :\ Send command &00 - OSRDCH
2170 .WaitCarryChar :\ Wait for Carry and A
2180 JSR WaitByte:ASL A :\ Wait for carry
2190 .WaitByte
2200 BIT TubeS2:BPL WaitByte :\ Loop until Tube R2 has data
2210 LDA TubeR2 :\ Fetch character
2220 .NullReturn
2230 RTS
2240
2250
2260 \ Skip Spaces
2270 \ ===========
2280 .SkipSpaces1
2290 INY
2300 .SkipSpaces
2310 LDA (&F8),Y:CMP #&20:BEQ SkipSpaces1
2320 RTS
2330
2340
2350 \ Scan hex
2360 \ ========
2370 .ScanHex
2380 LDX #&00:STX &F0:STX &F1 :\ Clear hex accumulator
2390 .LF98C
2400 LDA (&F8),Y :\ Get current character
2410 CMP #&30:BCC LF9B1 :\ <'0', exit
2420 CMP #&3A:BCC LF9A0 :\ '0'..'9', add to accumulator
2430 AND #&DF:SBC #&07:BCC LF9B1:\ Convert letter, if <'A', exit
2440 CMP #&40:BCS LF9B1 :\ >'F', exit
2450 .LF9A0
2460 ASL A:ASL A:ASL A:ASL A :\ *16
2470 LDX #&03 :\ Prepare to move 3+1 bits
2480 .LF9A6
2490 ASL A:ROL &F0:ROL &F1 :\ Move bits into accumulator
2500 DEX:BPL LF9A6 :\ Loop for four bits, no overflow check
2510 INY:BNE LF98C :\ Move to next character
2520 .LF9B1
2530 RTS
2540
2550
2560 \ Send string to Tube R2
2570 \ ======================
2580 .SendString
2590 STX &F8:STY &F9 :\ Set &F8/9=>string
2600 .SendStringF8
2610 LDY #&00
2620 .LF9B8
2630 BIT TubeS2:BVC LF9B8 :\ Wait for Tube R2 free
2640 LDA (&F8),Y:STA TubeR2 :\ Send character to Tube R2
2650 INY:CMP #&0D:BNE LF9B8 :\ Loop until <cr> sent
2660 LDY &F9:RTS :\ Restore Y from &F9 and return
2670
2680
2690 \ OSCLI - Execute command
2700 \ =======================
2710 \ Command string is at &100
2720 \
2730 .atomCLI
2740 LDX #&00:LDY #&01 :\ Point XY=>&100, Atom command buffer
2750
2760 \ On entry, XY=>command string
2770 \ On exit, XY= preserved
2780 \
2790 .osCLI
2800 PHA:STX &F8:STY &F9 :\ Save A, &F8/9=>command string
2810 LDY #&00
2820 .LF9D1
2830 JSR SkipSpaces:INY
2840 CMP #ASC"*":BEQ LF9D1 :\ Skip spaces and stars
2850 AND #&DF:TAX :\ Ignore case, and save in X
2860 LDA (&F8),Y :\ Get next character
2870 CPX #ASC"G":BEQ CmdGO :\ Jump to check '*GO'
2880 CPX #ASC"H":BNE osCLI_IO :\ Not "H---", jump to pass to Tube
2890 CMP #ASC".":BEQ CmdHELP :\ "H.", jump to do *HELP
2900 AND #&DF :\ Ignore case
2910 CMP #ASC"E":BNE osCLI_IO :\ Not "HE---", jump to pass to Tube
2920 INY:LDA (&F8),Y :\ Get next character
2930 CMP #ASC".":BEQ CmdHELP :\ "HE.", jump to do *HELP
2940 AND #&DF :\ Ignore case
2950 CMP #ASC"L":BNE osCLI_IO :\ Not "HEL---", jump to pass to Tube
2960 INY:LDA (&F8),Y :\ Get next character
2970 CMP #ASC".":BEQ CmdHELP :\ "HEL.", jump to do *HELP
2980 AND #&DF :\ Ignore case
2990 CMP #ASC"P":BNE osCLI_IO :\ Not "HELP---", jump to pass to Tube
3000 INY:LDA (&F8),Y :\ Get next character
3010 AND #&DF :\ Ignore case
3020 CMP #ASC"A":BCC CmdHELP :\ "HELP" terminated by non-letter, do *HELP
3030 CMP #ASC"[":BCC osCLI_IO :\ "HELP" followed by letter, pass to Tube
3040
3050 \ *Help - Display help information
3060 \ --------------------------------
3070 .CmdHELP
3080 JSR PrText :\ Print help message
3090 EQUB 10:EQUB 13:EQUS "65C102 Tube Atom/System MOS 0.10 (21 Feb 2012)"
3100 EQUB 10:EQUB 13
3110 NOP :\ Continue to pass '*HELP' command to Tube
3120
3130
3140 \ OSCLI - Send command line to host
3150 \ =================================
3160 \ On entry, &F8/9=>command string
3170 \
3180 \ Tube data &02 string &0D -- &7F or &80
3190 \
3200 .osCLI_IO
3210 LDA #&02:JSR SendCommand :\ Send command &02 - OSCLI
3220 JSR SendStringF8 :\ Send command string at &F8/9
3230 .osCLI_Ack
3240 JSR WaitByte :\ Wait for acknowledgement
3250 CMP #&80:BEQ LFA5C :\ Jump if code to be entered
3260 PLA:RTS :\ Restore A and return
3270
3280
3290 \ *GO - call machine code
3300 \ -----------------------
3310 .CmdGO
3320 AND #&DF :\ Ignore case
3330 CMP #ASC"O":BNE osCLI_IO :\ Not '*GO', jump to pass to Tube
3340 JSR SkipSpaces1 :\ Move past any spaces
3350 JSR ScanHex:JSR SkipSpaces :\ Read hex value and move past spaces
3360 CMP #&0D:BNE osCLI_IO :\ More parameters, pass to Tube to deal with
3370 TXA:BEQ LFA5C :\ If no address given, jump to current program
3380 LDA &F0:STA &F6 :\ Set program start to address read
3390 LDA &F1:STA &F7
3400
3410 .LFA5C
3420 LDA &EF:PHA:LDA &EE:PHA :\ Save current program
3430 JSR EnterCode
3440 PLA:STA &EE:STA &F2 :\ Restore current program and
3450 PLA:STA &EF:STA &F3 :\ set address top of memory to it
3460 PLA:RTS
3470
3480 .CheckAck
3490 BEQ osCLI_Ack
3500
3510
3520 \ OSBYTE - Byte MOS functions
3530 \ ===========================
3540 \ On entry, A, X, Y=OSBYTE parameters
3550 \ On exit, A preserved
3560 \ If A<&80, X=returned value
3570 \ If A>&7F, X, Y, Carry=returned values
3580 \
3590 .osBYTE
3600 CMP #&80:BCS ByteHigh :\ Jump for long OSBYTEs
3610 \
3620 \ Tube data &04 X A -- X
3630 \
3640 PHA:LDA #&04
3650 .LFA7A
3660 BIT TubeS2:BVC LFA7A :\ Wait for Tube R2 free
3670 STA TubeR2 :\ Send command &04 - OSBYTELO
3680 .LFA82
3690 BIT TubeS2:BVC LFA82 :\ Wait for Tube R2 free
3700 STX TubeR2:PLA :\ Send single parameter
3710 .LFA8B
3720 BIT TubeS2:BVC LFA8B :\ Wait for Tube R2 free
3730 STA TubeR2 :\ Send function
3740 .LFA93
3750 BIT TubeS2:BPL LFA93 :\ Wait for Tube R2 data present
3760 LDX TubeR2:RTS :\ Get return value
3770
3780 .ByteHigh
3790 CMP #&82:BEQ Byte82 :\ Read memory high word
3800 CMP #&83:BEQ Byte83 :\ Read bottom of memory
3810 CMP #&84:BEQ Byte84 :\ Read top of memory
3820 \
3830 \ Tube data &06 X Y A -- Cy Y X
3840 \
3850 PHA:LDA #&06
3860 .LFAAB
3870 BIT TubeS2:BVC LFAAB :\ Wait for Tube R2 free
3880 STA TubeR2 :\ Send command &06 - OSBYTEHI
3890 .LFAB3
3900 BIT TubeS2:BVC LFAB3 :\ Wait for Tube R2 free
3910 STX TubeR2 :\ Send parameter 1
3920 .LFABB
3930 BIT TubeS2:BVC LFABB :\ Wait for Tube R2 free
3940 STY TubeR2 :\ Send parameter 2
3950 PLA
3960 .LFAC4
3970 BIT TubeS2:BVC LFAC4 :\ Wait for Tube R2 free
3980 STA TubeR2 :\ Send function
3990 CMP #&8E:BEQ CheckAck :\ If select language, check to enter code
4000 CMP #&9D:BEQ LFAEF :\ Fast return with Fast BPUT
4010 PHA :\ Save function
4020 .LFAD5
4030 BIT TubeS2:BPL LFAD5 :\ Wait for Tube R2 data present
4040 LDA TubeR2:ASL A:PLA :\ Get Carry
4050 .LFADF
4060 BIT TubeS2:BPL LFADF :\ Wait for Tube R2 data present
4070 LDY TubeR2 :\ Get return high byte
4080 .LFAE7
4090 BIT TubeS2:BPL LFAE7 :\ Wait for Tube R2 data present
4100 LDX TubeR2 :\ Get return low byte
4110 .LFAEF
4120 RTS
4130
4140 .Byte84:LDX &F2:LDY &F3:RTS :\ Read top of memory from &F2/3
4150 .Byte83:LDX #&00:LDY #&10:RTS :\ Read bottom of memory
4160 .Byte82:LDX #&00:LDY #&00:RTS :\ Return &0000 as memory high word
4170
4180
4190 \ OSWORD - Various functions
4200 \ ==========================
4210 \ On entry, A =function
4220 \ XY=>control block
4230 \
4240 .osWORD
4250 STX &F8:STY &F9 :\ &F8/9=>control block
4260 TAY:BEQ RDLINE :\ OSWORD 0, jump to read line
4270 PHA:LDY #&08
4280 .LFB09
4290 BIT TubeS2:BVC LFB09 :\ Loop until Tube R2 free
4300 STY TubeR2 :\ Send command &08 - OSWORD
4310 .LFB11
4320 BIT TubeS2:BVC LFB11 :\ Loop until Tube R2 free
4330 STA TubeR2 :\ Send function
4340 TAX:BPL WordSendLow :\ Jump with functions<&80
4350 LDY #&00:LDA (&F8),Y :\ Get send block length from control block
4360 TAY:JMP WordSend :\ Jump to send control block
4370
4380 .WordSendLow
4390 LDY WordLengthsLo-1,X :\ Get send block length from table
4400 CPX #&15:BCC WordSend :\ Use this length for OSWORD 1 to &14
4410 LDY #&10 :\ Send 16 bytes for OSWORD &15 to &7F
4420 .WordSend
4430 BIT TubeS2:BVC WordSend :\ Wait until Tube R2 free
4440 STY TubeR2 :\ Send send block length
4450 DEY:BMI LFB45 :\ Zero or &81..&FF length, nothing to send
4460 .LFB38
4470 BIT TubeS2:BVC LFB38 :\ Wait for Tube R2 free
4480 LDA (&F8),Y:STA TubeR2 :\ Send byte from control block
4490 DEY:BPL LFB38 :\ Loop for number to be sent
4500 .LFB45
4510 TXA:BPL WordRecvLow :\ Jump with functions<&80
4520 LDY #&01:LDA (&F8),Y :\ Get receive block length from control block
4530 TAY:JMP WordRecv :\ Jump to receive control block
4540
4550 .WordRecvLow
4560 LDY WordLengthsHi-1,X :\ Get receive length from table
4570 CPX #&15:BCC WordRecv :\ Use this length for OSWORD 1 to &14
4580 LDY #&10 :\ Receive 16 bytes for OSWORD &15 to &7F
4590 .WordRecv
4600 BIT TubeS2:BVC WordRecv :\ Wait for Tube R2 free
4610 STY TubeR2 :\ Send receive block length
4620 DEY:BMI LFB71 :\ Zero of &81..&FF length, nothing to receive
4630 .LFB64
4640 BIT TubeS2:BPL LFB64 :\ Wait for Tube R2 data present
4650 LDA TubeR2:STA (&F8),Y :\ Get byte to control block
4660 DEY:BPL LFB64 :\ Loop for number to receive
4670 .LFB71
4680 LDY &F9:LDX &F8:PLA :\ Restore registers
4690 RTS
4700
4710
4720 \ RDLINE - Read a line of text
4730 \ ============================
4740 \ On entry, A =0
4750 \ XY=>control block
4760 \ On exit, A =undefined
4770 \ Y =length of returned string
4780 \ Cy=0 ok, Cy=1 Escape
4790 \
4800 \ Tube data &0A block -- &FF or &7F string &0D
4810 \
4820 .RDLINE
4830 LDA #&0A:JSR SendCommand :\ Send command &0A - RDLINE
4840 LDY #&04
4850 .LFB7E
4860 BIT TubeS2:BVC LFB7E :\ Wait for Tube R2 free
4870 LDA (&F8),Y:STA TubeR2 :\ Send control block
4880 DEY:CPY #&01:BNE LFB7E :\ Loop for 4, 3, 2
4890 LDA #&07:JSR SendByte :\ Send &07 as address high byte
4900 LDA (&F8),Y:PHA :\ Get text buffer address high byte
4910 DEY
4920 .LFB96
4930 BIT TubeS2:BVC LFB96 :\ Wait for Tube R2 free
4940 STY TubeR2 :\ Send &00 as address low byte
4950 LDA (&F8),Y:PHA :\ Get text buffer address low byte
4960 LDX #&FF:JSR WaitByte :\ Wait for response
4970 CMP #&80:BCS RdLineEscape :\ Jump if Escape returned
4980 PLA:STA &F8:PLA:STA &F9 :\ Set &F8/9=>text buffer
4990 LDY #&00
5000 .RdLineLp
5010 BIT TubeS2:BPL RdLineLp :\ Wait for Tube R2 data present
5020 LDA TubeR2:STA (&F8),Y :\ Store returned character
5030 INY:CMP #&0D:BNE RdLineLp :\ Loop until <cr>
5040 LDA #&00:DEY:CLC:INX :\ Return A=0, Y=len, X=00, Cy=0
5050 RTS
5060 :
5070 .RdLineEscape
5080 PLA:PLA:LDA #&00 :\ Return A=0, Y=len, X=FF, Cy=1
5090 RTS
5100
5110
5120 \ OSARGS - Read info on open file
5130 \ ===============================
5140 \ On entry, A =function
5150 \ X =>data word in zero page
5160 \ Y =handle
5170 \ On exit, A =returned value
5180 \ X preserved
5190 \ Y preserved
5200 \
5210 \ Tube data &0C handle block function -- result block
5220 \
5230 .osARGS
5240 PHA:LDA #&0C:JSR SendCommand :\ Send command &0C - OSARGS
5250 .LFBD2
5260 BIT TubeS2:BVC LFBD2 :\ Loop until Tube R2 free
5270 STY TubeR2 :\ Send handle
5280 LDA &03,X:JSR SendByte :\ Send data word
5290 LDA &02,X:JSR SendByte
5300 LDA &01,X:JSR SendByte
5310 LDA &00,X:JSR SendByte
5320 PLA:JSR SendByte :\ Send function
5330 JSR WaitByte:PHA :\ Get and save result
5340 JSR WaitByte:STA &03,X :\ Receive data word
5350 JSR WaitByte:STA &02,X
5360 JSR WaitByte:STA &01,X
5370 JSR WaitByte:STA &00,X
5380 PLA:RTS :\ Get result back and return
5390
5400
5410 \ OSFIND - Open file
5420 \ ------------------
5430 \ On entry, X=>zero page
5440 \ X+0/1=file name
5450 \ CS=Open file for input
5460 \ CC=Open file for output
5470 \ On exit, A=file handle, 0 if file not found
5480 \ X,Y=preserved
5490 .atomFIND
5500 PHA :\ Space for returned A
5510 TYA:PHA:TXA:PHA :\ Save X,Y
5520 LDA 1,X:TAY :\ XY=>filename
5530 LDA 0,X:TAX
5540 :\ Create OSFIND action
5550 LDA #0 :\ A=00, CS CC
5560 PHP:ROR A:PLP:ROR A :\ C0 00
5570 EOR #&80 :\ 40 80
5580 JSR osFIND :\ Pass OSFIND to host
5590 TSX:STA &103,X :\ Store on stack
5600 PLA:TAX:PLA:TAY :\ Restore X,Y
5610 PLA:RTS :\ Get handle and return
5620
5630 \ OSSHUT - Close a file
5640 \ ---------------------
5650 \ On entry, Y=file handle
5660 \ On exit, all preserved
5670 .atomSHUT
5680 PHA:LDA #0 :\ OSFIND &00 - Close
5690 JSR osFIND :\ Pass OSFIND to host
5700 PLA:RTS
5710
5720
5730 \ OSFIND - Open of Close a file
5740 \ =============================
5750 \ On entry, A =function
5760 \ Y =handle or XY=>filename
5770 \ On exit, A =zero or handle
5780 \
5790 \ Tube data &12 function string &0D -- handle
5800 \ &12 &00 handle -- &7F
5810 \
5820 .osFIND
5830 PHA:LDA #&12:JSR SendCommand :\ Send command &12 - OSFIND
5840 PLA:JSR SendByte :\ Send function
5850 CMP #&00:BNE OPEN :\ If <>0, jump to do OPEN
5860 PHA:TYA:JSR SendByte :\ Send handle
5870 JSR WaitByte:PLA:RTS :\ Wait for acknowledge, restore regs and return
5880 .OPEN
5890 JSR SendString :\ Send pathname
5900 JMP WaitByte :\ Wait for and return handle
5910
5920
5930 \ OSBGET - Get a byte from open file
5940 \ ==================================
5950 \ On entry, Y =handle
5960 \ On exit, A =byte Read
5970 \ Y =preserved
5980 \ Cy set if EOF
5990 \
6000 \ Tube data &0E handle -- Carry byte
6010 \
6020 .osBGET:.atomBGET
6030 LDA #&0E:JSR SendCommand :\ Send command &0E - OSBGET
6040 TYA:JSR SendByte :\ Send handle
6050 JMP WaitCarryChar :\ Jump to wait for Carry and byte
6060
6070
6080 \ OSBPUT - Put a byte to an open file
6090 \ ===================================
6100 \ On entry, A =byte to write
6110 \ Y =handle
6120 \ On exit, A =preserved
6130 \ Y =preserved
6140 \
6150 \ Tube data &10 handle byte -- &7F
6160 \
6170 .osBPUT:.atomBPUT
6180 PHA:LDA #&10:JSR SendCommand :\ Send command &10 - OSBPUT
6190 TYA:JSR SendByte :\ Send handle
6200 PLA:JSR SendByte :\ Send byte
6210 PHA:JSR WaitByte:PLA:RTS :\ Wait for acknowledge and return
6220
6230
6240 \ Send a byte to Tube R2
6250 \ ======================
6260 .SendCommand
6270 .SendByte
6280 BIT TubeS2:BVC SendByte :\ Wait for Tube R2 free
6290 STA TubeR2:RTS :\ Send byte to Tube R2
6300
6310
6320 \ OSLOAD - Load a file
6330 \ --------------------
6340 \ On entry, X=>zero page
6350 \ X+0/1=>file name
6360 \ X+2/3=Load address
6370 \ X+4 =if bit 7=0 use the file's start address
6380 \ CC=Return immediately
6390 \ CS=Wait until IRQ/DMA actions completed
6400 \ On exit, all preserved
6410 \
6420 .atomLOAD
6430 LDA #&FF:BNE doFILE
6440
6450 \ OSSAVE - Save a file
6460 \ --------------------
6470 \ On entry, X=>zero page
6480 \ X+0/1=file name
6490 \ X+2/3=load address
6500 \ X+4/5=execution address
6510 \ X+6/7=start address of data to save
6520 \ X+8/9=(end address)+1 of data to save
6530 \ CC=Return immediately
6540 \ CS=Wait until IRQ/DMA actions completed
6550 \ On exit, all preserved
6560 .atomSAVE
6570 LDA #&00
6580 .doFILE
6590 PHA
6600 TYA:PHA:TXA:PHA
6610 LDA 0,X:STA &2EE :\ =>filename
6620 LDA 1,X:STA &2EF
6630 LDY #0
6640 .doFILElp
6650 LDA 2,X:STA &2F0,Y:INX:INY
6660 LDA 2,X:STA &2F0,Y:INX:INY
6670 LDA #0 :\ Expand control block
6680 STA &2F0,Y:INY
6690 STA &2F0,Y:INY
6700 CPY #16:BNE doFILElp
6710 TSX:LDA &103,X :\ Get OSFILE action
6720 CMP #&FF:BNE callFILE
6730 LDA &2F4:EOR #&FF
6740 STA &2F4:LDA #&FF
6750 .callFILE
6760 LDX #&EE:LDY #&02 :\ Point to control block
6770 JSR osFILE :\ Pass OSFILE to host
6780 TSX:STA &103,X :\ Store return value on stack
6790 PLA:TAX:PLA:TAY :\ Restore registers
6800 PLA:RTS :\ Get return value and return
6810
6820
6830 \ OSFILE - Operate on whole files
6840 \ ===============================
6850 \ On entry, A =function
6860 \ XY=>control block
6870 \ On exit, A =result
6880 \ control block updated
6890 \
6900 \ Tube data &14 block string <cr> function -- result block
6910 \
6920 .osFILE
6930 STY &FB:STX &FA :\ &FA/B=>control block
6940 PHA:LDA #&14:JSR SendCommand :\ Send command &14 - OSFILE
6950 LDY #&11
6960 .LFC5F
6970 LDA (&FA),Y:JSR SendByte :\ Send control block
6980 DEY:CPY #&01:BNE LFC5F :\ Loop for &11..&02
6990 DEY:LDA (&FA),Y:TAX
7000 INY:LDA (&FA),Y:TAY :\ Get pathname address to XY
7010 JSR SendString :\ Send pathname
7020 PLA:JSR SendByte :\ Send function
7030 JSR WaitByte:PHA :\ Wait for result
7040 LDY #&11
7050 .LFC7E
7060 JSR WaitByte:STA (&FA),Y :\ Get control block back
7070 DEY:CPY #&01:BNE LFC7E :\ Loop for &11..&02
7080 LDY &FB:LDX &FA :\ Restore registers
7090 PLA:RTS :\ Get result and return
7100
7110
7120 \ OSGBPB - Multiple byte Read and write
7130 \ =====================================
7140 \ On entry, A =function
7150 \ XY=>control block
7160 \ On exit, A =returned value
7170 \ control block updated
7180 \
7190 \ Tube data &16 block function -- block Carry result
7200 \
7210 .osGBPB
7220 STY &FB:STX &FA :\ &FA/B=>control block
7230 PHA:LDA #&16:JSR SendCommand :\ Send command &16 - OSGBPB
7240 LDY #&0C
7250 .LFC9A
7260 LDA (&FA),Y:JSR SendByte :\ Send control block
7270 DEY:BPL LFC9A :\ Loop for &0C..&00
7280 PLA:JSR SendByte :\ Send function
7290 LDY #&0C
7300 .LFCA8
7310 JSR WaitByte:STA (&FA),Y :\ Get control block back
7320 DEY:BPL LFCA8 :\ Loop for &0C..&00
7330 LDY &FB:LDX &FA :\ Restore registers
7340 JMP WaitCarryChar :\ Jump to get Carry and result
7350
7360
7370 \ OSWORD control block lengths
7380 \ ============================
7390 .WordLengthsLo
7400 EQUB &00:EQUB &05:EQUB &00:EQUB &05
7410 EQUB &04:EQUB &05:EQUB &08:EQUB &0E :\ ** Different, 6502 TUBE sends only 2 bytes for =IO
7420 EQUB &04:EQUB &01:EQUB &01:EQUB &05
7430 EQUB &00:EQUB &01:EQUB &20:EQUB &10
7440 EQUB &0D:EQUB &00:EQUB &04:EQUB &80
7450 .WordLengthsHi
7460 EQUB &05:EQUB &00:EQUB &05:EQUB &00
7470 EQUB &05:EQUB &00:EQUB &00:EQUB &00
7480 EQUB &05:EQUB &09:EQUB &05:EQUB &00
7490 EQUB &08:EQUB &18:EQUB &00:EQUB &01
7500 EQUB &0D:EQUB &80:EQUB &04:EQUB &80
7510
7520
7530 \ Interrupt Handler
7540 \ =================
7550 .InterruptHandler
7560 STA &FC:PLA:PHA :\ Save A, get flags from stack
7570 AND #&10:BNE BRKHandler :\ If BRK, jump to BRK handler
7580 :
7590 BIT TubeS4:BMI LFD3F :\ If data in Tube R4, jump to process errors and transferes
7600 BIT TubeS1:BMI LFD18 :\ If data in Tube R1, jump to process Escape and Events
7610 LDA &FC:PHA:JMP (irq1v) :\ Pass on to IRQ1V
7620
7630 .BRKHandler
7640 LDA &FC:PLP:PHP:JMP (brkv) :\ Restore A and flags, jump to BRK handler
7650
7660
7670 \ Interrupt generated by data in Tube R1
7680 \ --------------------------------------
7690 .LFD18
7700 LDA TubeR1:BMI LFD39 :\ b7=1, jump to set Escape state
7710 TYA:PHA:TXA:PHA :\ Save registers
7720 JSR LFE80:TAY :\ Get Y parameter from Tube R1
7730 JSR LFE80:TAX :\ Get X parameter from Tube R1
7740 JSR LFE80 :\ Get event number from Tube R1
7750 JSR LFD36:PLA:TAX:PLA:TAY :\ Dispatch event, restore registers
7760 LDA &FC:RTI :\ Restore A, return from interrupt
7770 .LFD36
7780 JMP (EVNTV)
7790 .LFD39
7800 ASL A:STA &FF :\ Set Escape flag from b6
7810 LDA &FC:RTI :\ Restore A, return from interrupt
7820
7830
7840 \ Interrupt generated by data in Tube R4
7850 \ --------------------------------------
7860 .LFD3F
7870 LDA TubeR4:BPL LFD65 :\ b7=0, jump for data transfer
7880 CLI
7890 .LFD45
7900 BIT TubeS2:BPL LFD45 :\ Wait for data in Tube R2
7910 LDA TubeR2
7920 LDA #&00:STA ERRBUF:TAY :\ Store BRK opcode in error buffer
7930 JSR WaitByte:STA ERRBUF+1 :\ Get error number
7940 .LFD59
7950 INY:JSR WaitByte :\ Store bytes fetched from Tube R2
7960 STA ERRBUF+1,Y:BNE LFD59 :\ Loop until final zero
7970 JMP ERRBUF :\ Jump to error block to generate error
7980
7990 \ Data transfer initiated by IRQ via Tube R4
8000 \ ------------------------------------------
8010 .LFD65
8020 STA NMIV+0:TYA:PHA :\ Save transfer type, save Y
8030 LDY NMIV+0 :\ Get transfer type back
8040 LDA LFE70,Y:STA NMIV+0 :\ get NMI routine address from table
8050 LDA LFE78,Y:STA NMIV+1 :\ and point NMIV to it
8060 LDA LFE60,Y:STA &F4 :\ Point &F4/5 to transfer address field
8070 LDA LFE68,Y:STA &F5
8080 .LFD83
8090 BIT TubeS4:BPL LFD83 :\ Wait until Tube R4 data present
8100 LDA TubeR4 :\ Get called ID from Tube R4
8110 CPY #&05:BEQ LFDE7 :\ If 'TubeRelease', jump to exit
8120 TYA:PHA:LDY #&01 :\ Save transfer type
8130 .LFD93
8140 BIT TubeS4:BPL LFD93 :\ Wait for Tube R4 data present
8150 LDA TubeR4 :\ Fetch and disgard address byte 4
8160 .LFD9B
8170 BIT TubeS4:BPL LFD9B :\ Wait for Tube R4 data present
8180 LDA TubeR4 :\ Fetch and disgard address byte 3
8190 .LFDA3
8200 BIT TubeS4:BPL LFDA3 :\ Wait for Tube R4 data present
8210 LDA TubeR4:STA (&F4),Y:DEY :\ Fetch address byte 2, store in address
8220 .LFDAE
8230 BIT TubeS4:BPL LFDAE :\ Wait for Tube R4 data present
8240 LDA TubeR4:STA (&F4),Y :\ Fetch address byte 1, store in address
8250 BIT TubeR3:BIT TubeR3 :\ Read from Tube R3 twice
8260 .LFDBE
8270 BIT TubeS4:BPL LFDBE :\ Wait for Tube R4 data present
8280 LDA TubeR4:PLA :\ Get sync byte from Tube R4
8290 CMP #&06:BCC LFDE7 :\ Exit if not 256-byte transfers
8300 BNE LFDEC :\ Jump with 256-byte read
8310
8320 \ Send 256 bytes to Tube via R3
8330 \ -----------------------------
8340 LDY #&00
8350 .LFDCF
8360 LDA TubeS3:AND #&80:BPL LFDCF:\ Wait for Tube R3 free
8370 .NMI6Addr
8380 LDA &FFFF,Y:STA TubeR3 :\ Fetch byte and send to Tube R3
8390 INY:BNE LFDCF :\ Loop for 256 bytes
8400 .LFDDF
8410 BIT TubeS3:BPL LFDDF :\ Wait for Tube R3 free
8420 STA TubeR3 :\ Send final sync byte
8430 .LFDE7
8440 PLA:TAY:LDA &FC:RTI :\ Restore registers and return
8450
8460 \ Read 256 bytes from Tube via R3
8470 \ -------------------------------
8480 .LFDEC
8490 LDY #&00
8500 .LFDEE
8510 LDA TubeS3:AND #&80:BPL LFDEE:\ Wait for Tube R3 data present
8520 LDA TubeR3 :\ Fetch byte from Tube R3
8530 .NMI7Addr
8540 STA &FFFF,Y:INY:BNE LFDEE :\ Store byte and loop for 256 bytes
8550 BEQ LFDE7 :\ Jump to restore registers and return
8560
8570 \ Transfer 0 - Transfer single byte to Tube
8580 \ -----------------------------------------
8590 .NMI0
8600 PHA :\ Save A
8610 .NMI0Addr
8620 LDA &FFFF:STA TubeR3 :\ Get byte and send to Tube R3
8630 INC NMI0Addr+1:BNE LFE0F :\ Increment transfer address
8640 INC NMI0Addr+2
8650 .LFE0F
8660 .NullIRQ
8670 PLA:RTI :\ Restore A and return
8680
8690 \ Transfer 1 - Transfer single byte from Tube
8700 \ -------------------------------------------
8710 .NMI1
8720 PHA:LDA TubeR3 :\ Save A, get byte from Tube R3
8730 .NMI1Addr
8740 STA &FFFF :\ Store byte
8750 INC NMI1Addr+1:BNE LFE20 :\ Increment transfer address
8760 INC NMI1Addr+2
8770 .LFE20
8780 PLA:RTI :\ Restore A and return
8790
8800 \ Transfer 2 - Transfer two bytes to Tube
8810 \ ---------------------------------------
8820 .NMI2
8830 PHA:TYA:PHA:LDY #&00 :\ Save registers
8840 LDA (&F6),Y:STA TubeR3 :\ Get byte and send to Tube R3
8850 INC &F6:BNE LFE32:INC &F7 :\ Increment transfer address
8860 .LFE32
8870 LDA (&F6),Y:STA TubeR3 :\ Get byte and send to Tube R3
8880 INC &F6:BNE LFE3D:INC &F7 :\ Increment transfer address
8890 .LFE3D
8900 PLA:TAY:PLA:RTI :\ Restore registers and return
8910
8920 \ Transfer 3 - Transfer two bytes from Tube
8930 \ -----------------------------------------
8940 .NMI3
8950 PHA:TYA:PHA:LDY #&00 :\ Save registers
8960 LDA TubeR3:STA (&F6),Y :\ Get byte from Tube R3 and store
8970 INC &F6:BNE LFE51:INC &F7 :\ Increment transfer address
8980 .LFE51
8990 LDA TubeR3:STA (&F6),Y :\ Get byte from Tube R3 and store
9000 INC &F6:BNE LFE5C:INC &F7 :\ Increment transfer address
9010 .LFE5C
9020 PLA:TAY:PLA:RTI :\ Restore registers and return
9030
9040 \ Data transfer address pointers
9050 \ ------------------------------
9060 .LFE60
9070 EQUB (NMI0Addr+1) AND 255:EQUB (NMI1Addr+1) AND 255
9080 EQUB &00F6 AND 255 :EQUB &00F6 AND 255
9090 EQUB &00F6 AND 255 :EQUB &00F6 AND 255
9100 EQUB (NMI6Addr+1) AND 255:EQUB (NMI7Addr+1) AND 255
9110 .LFE68
9120 EQUB (NMI0Addr+1) DIV 256:EQUB (NMI1Addr+1) DIV 256
9130 EQUB &00F6 DIV 256 :EQUB &00F6 DIV 256
9140 EQUB &00F6 DIV 256 :EQUB &00F6 DIV 256
9150 EQUB (NMI6Addr+1) DIV 256:EQUB (NMI7Addr+1) DIV 256
9160
9170 \ Data transfer routine addresses
9180 \ -------------------------------
9190 .LFE70
9200 EQUB NMI0 AND 255 :EQUB NMI1 AND 255
9210 EQUB NMI2 AND 255 :EQUB NMI3 AND 255
9220 EQUB NMI_Ack AND 255:EQUB NMI_Ack AND 255
9230 EQUB NMI_Ack AND 255:EQUB NMI_Ack AND 255
9240 .LFE78
9250 EQUB NMI0 DIV 256 :EQUB NMI1 DIV 256
9260 EQUB NMI2 DIV 256 :EQUB NMI3 DIV 256
9270 EQUB NMI_Ack DIV 256:EQUB NMI_Ack DIV 256
9280 EQUB NMI_Ack DIV 256:EQUB NMI_Ack DIV 256
9290
9300
9310 \ Wait for byte in Tube R1 while allowing requests via Tube R4
9320 \ ============================================================
9330 .LFE80
9340 BIT TubeS1:BMI LFE94 :\ If data in Tube R1, jump to fetch it
9350 .LFE85
9360 BIT TubeS4 :\ Check if data present in Tube R4
9370 BPL LFE80 :\ If nothing there, jump back to check Tube R1
9380 LDA &FC :\ Save IRQ's A store in A register
9390 PHP:CLI:PLP :\ Allow an IRQ through to process R4 request
9400 STA &FC:JMP LFE80 :\ Restore IRQ's A store and jump back to check R1
9410 .LFE94
9420 LDA TubeR1:RTS :\ Fetch byte from Tube R1 and return
9430
9440
9450 \ Spare space
9460 \ ===========
9470 EQUS STRING$(IOADDR-P%,CHR$255)
9480
9490
9500 \ I/O Space
9510 \ =========
9520 EQUS STRING$(IOTUBE-P%,CHR$0)
9530
9540 \ Tube I/O Registers
9550 \ ==================
9560 .TubeS1 :\ &FEF8 :EQUB 0
9570 .TubeR1 :\ &FEF9 :EQUB 0
9580 .TubeS2 :\ &FEFA :EQUB 0
9590 .TubeR2 :\ &FEFB :EQUB 0
9600 .TubeS3 :\ &FEFC :EQUB 0
9610 .TubeR3 :\ &FEFD :EQUB 0
9620 .TubeS4 :\ &FEFE :EQUB 0
9630 .TubeR4 :\ &FEFF :EQUB 0
9640
9650 .LFF00
9660 \ Print embedded string
9670 \ =====================
9680 .PrText
9690 PLA:STA &FA:PLA:STA &FB :\ &FA/B=>embedded string
9700 LDY #&00
9710 .LFEA0
9720 INC &FA:BNE LFEA6:INC &FB :\ Increment address
9730 .LFEA6
9740 LDA (&FA),Y:BMI LFEB0 :\ Get character, exit if >&7F
9750 JSR OSWRCH:JMP LFEA0 :\ Print character and loop back for more
9760 .LFEB0
9770 JMP (&00FA) :\ Jump back to code after string
9780
9790 \ Print hex
9800 \ =========
9810 .Pr2Hex
9820 TYA:JSR PrHex:TXA
9830 .PrHex
9840 PHA:LSR A:LSR A:LSR A:LSR A
9850 JSR PrNyb:PLA
9860 .PrNyb
9870 AND #15:CMP #10:BCC P%+4
9880 ADC #6:ADC #48:JMP OSWRCH
9890
9900 \ OSRDAR - Read file's arguments
9910 \ ------------------------------
9920 \ On entry, X=>zero page location
9930 \ Y=handle
9940 \ A=0 - read PTR
9950 \ A=1 - read EXT
9960 \ A=2 - read allocation
9970 \ On exit, X+0-X+3 = returned argument
9980 \ A,X,Y preserved
9990 .atomRDAR
10000 PHA:CLC:BCC doARGS :\ Jump to do even-numbered OSARGS
10010
10020 \ OSSTAR - Set file's arguments
10030 \ -----------------------------
10040 \ On entry, X=>zero page location
10050 \ Y=handle
10060 \ A=0 - write PTR (usually, A=unset)
10070 \ X+0-X+3 = argument
10080 \ On exit, A,X,Y preserved
10090 .atomSTAR
10100 PHA:LDA #0:SEC :\ Do odd-numbered OSARGS
10110 .doARGS
10120 ROL A:JSR osARGS :\ Convert to OSARGS action
10130 PLA:RTS
10140
10150 \ Null NMI code
10160 \ -------------
10170 .NMI_Ack
10180 STA TubeR3:RTI :\ Store to TubeR3 to acknowlege NMI
10190
10200 .Unsupported
10210 BRK:EQUB 255:EQUS "Bad":EQUB 0
10220
10230
10240 \ Copy of BBC MOS API entry block
10250 \ ===============================
10260 EQUS STRING$(&FF4E-P%,CHR$0)
10270 .XOSFIND :\ &FF4E :JMP osFIND
10280 .XOSGBPB :\ &FF51 :JMP osGBPB
10290 .XOSBPUT :\ &FF54 :JMP osBPUT
10300 .XOSBGET :\ &FF57 :JMP osBGET
10310 .XOSARGS :\ &FF5A :JMP osARGS
10320 .XOSFILE :\ &FF5D :JMP osFILE
10330
10340 .XOSRDCH :\ &FF60 :JMP osRDCH
10350 .XOSASCI :\ &FF63 :CMP #&0D:BNE XOSWRCH
10360 .XOSNEWL :\ &FF67 :LDA #&0A:JSR XOSWRCH
10370 .XOSPRCR :\ &FF6C :LDA #&0D
10380 .XOSWRCH :\ &FF6E :JMP osWRCH
10390 .XOSWORD :\ &FF71 :JMP osWORD
10400 .XOSBYTE :\ &FF74 :JMP osBYTE
10410 .XOS_CLI :\ &FF77 :JMP osCLI
10420
10430 .XNMIV :\ &FF7A :EQUW NMI0
10440 .XRESETV :\ &FF7C :EQUW RESET
10450 .XIRQV :\ &FF7E :EQUW InterruptHandler
10460
10470
10480 \ DEFAULT VECTOR TABLE
10490 \ ====================
10500 .VECTABLE
10510 EQUW NullIRQ :\ &200 - nmiv
10520 EQUW ErrorHandler :\ &202 - brkv
10530 EQUW NullIRQ :\ &204 - irq1v
10540 EQUW atomCLI :\ &206 - cliv
10550 EQUW atomWRCH :\ &208 - wrchv
10560 EQUW atomRDCH :\ &20A - rdchv
10570 EQUW atomLOAD :\ &20C - loadv
10580 EQUW atomSAVE :\ &20E - savev
10590 EQUW atomRDAR :\ &210 - rdarv
10600 EQUW atomSTAR :\ &212 - starv
10610 EQUW atomBGET :\ &214 - bgetv
10620 EQUW atomBPUT :\ &216 - bputv
10630 EQUW atomFIND :\ &218 - findv
10640 EQUW atomSHUT :\ &21A - shutv
10650 EQUW NullReturn :\ &21C - v21C
10660 EQUW NullReturn :\ &21E - v21E
10670 EQUW NullReturn :\ &220 - EVNTV
10680 EQUW Unsupported :\ &222 - v222
10690 EQUW Unsupported :\ &224 - v224
10700 EQUW Unsupported :\ &226 - v226
10710 EQUW Unsupported :\ &228 - v228
10720
10730
10740 \ Main MOS API entry block
10750 \ ========================
10760 EQUS STRING$(&FFA1-P%,CHR$255)
10770 .LFFAA :\ &FFAA :JMP PrHex :\ Print A in hex
10780 .LFFAD :\ &FFAD :JMP Pr2Hex :\ Print XY in hex
10790 .LFFB0 :\ &FFB0 :JMP NullReturn :\ IRQ stub
10800 .LFFB3 :\ &FFB3 :JMP PrText :\ Print inline text
10810 .VECDEF :\ &FFB6 :EQUB &2A:EQUW VECTABLE
10820 .LFFB9 :\ &FFB9 :JMP Unsupported
10830 .LFFBC :\ &FFBC :JMP Unsupported
10840 .LFFBF :\ &FFBF :JMP NullReturn :\ Reset vectors, etc.
10850 .LFFC2 :\ &FFC2 :JMP Unsupported
10860 .LFFC5 :\ &FFC5 :JMP Unsupported
10870 .LFFC8 :\ &FFC8 :JMP Unsupported
10880
10890 \ Atom/System Entry Block
10900 \ -----------------------
10910 .OSSHUT :\ &FFCB :JMP (shutv)
10920 .OSFIND :\ &FFCE :JMP (findv)
10930 .OSBPUT :\ &FFD1 :JMP (bputv)
10940 .OSBGET :\ &FFD4 :JMP (bgetv)
10950 .OSSTAR :\ &FFD7 :JMP (starv)
10960 .OSRDAR :\ &FFDA :JMP (rdarv)
10970 .OSSAVE :\ &FFDD :JMP (savev)
10980 .OSLOAD :\ &FFE0 :JMP (loadv)
10990
11000 .OSRDCH :\ &FFE3 :JMP (rdchv)
11010 .OSECHO :\ &FFE6 :JSR OSRDCH
11020 .OSASCI :\ &FFE9 :CMP #&0D:BNE OSWRCH
11030 .OSNEWL :\ &FFED :LDA #&0A:JSR OSWRCH
11040 .OSPRCR :\ &FFF2 :LDA #&0D
11050 .OSWRCH :\ &FFF4 :JMP (wrchv)
11060 .OS_CLI :\ &FFF7 :JMP (cliv)
11070
11080 \ Hardware vectors
11090 \ ----------------
11100 .NMIV :\ &FFFA :EQUW NMI0 :\ NMI Vector
11110 .RESETV :\ &FFFC :EQUW RESET :\ RESET Vector
11120 .IRQV :\ &FFFE :EQUW InterruptHandler :\ IRQ Vector
11130 ]:NEXT
11140 OSCLI"Save "+fname$+" "+STR$~mcode%+" "+STR$~O%+" "+STR$~load%+" "+STR$~load%
11150 ON ERROR ON ERROR OFF:END
11160 *Quit