10
20
30
40 :
50 IF PAGE>&8000:SYS "OS_GetEnv"TOA$:IFLEFT$(A$,5)<>"B6502":OSCLI"B6502"+MID$(A$,INSTR(A$," "))
60 :
70 load%=&F800:DIM mcode% &900
80 :
90 USERV=&200: BRKV=&202:IRQ1V=&204:IRQ2V=&206
100 CLIV=&208:BYTEV=&20A:WORDV=&20C:WRCHV=&20E
110 RDCHV=&210:FILEV=&212:ARGSV=&214:BGetV=&216
120 BPutV=&218:GBPBV=&21A:FINDV=&21C: FSCV=&21E
130 EVNTV=&220: UPTV=&222: NETV=&224: VduV=&226
140 KEYV=&228: INSV=&22A: RemV=&22C: CNPV=&22E
150 IND1V=&230:IND2V=&232:IND3V=&234
160 :
170 FOR P=0TO1
180 P%=load%:O%=mcode%
190 [OPT P*3+4
200 \ &EE/F=
210 \ &F0/1=>membot, if &F0<>0, membot=0000, memtop=0000
220 \ &F2/3=>command string
230 \ &F4/5=>memtop
240 \ &F6/7= readhex accumulator, ";params" pointer
250 \ &F8/9=>control block
260 \ &FA/B=>String to print with PrString
270 \ &FC = IRQ A store
280 \ &FD/E=>last error
290 \ &FF = escape flag
300 \ &0236= command input buffer
310 \ &03xx= bit16-bit23 of Turbo65 (zp),Y addresses
320 \ &03F3= b16-b23 of (&F2),Y command string pointer
330 \ &03F5= b16-b23 of (&F4),Y memtop pointer
340 \ &03F9= b16-b23 of (&F8),Y control block pointer
350 \ &03FB= b16-b23 of (&FA),Y string pointer
360 \ &03FE= b16-b23 of (&FD),Y error pointer
370
380 \ Emulator opcodes
390 \ &03 - OSCLI
400 \ &13 - OSBYTE
410 \ &23 - OSWORD
420 \ &33 - OSWRCH
430 \ &43 - OSRDCH
440 \ &53 - OSFILE
450 \ &63 - OSARGS
460 \ &73 - OSBGET
470 \ &83 - OSBPUT
480 \ &93 - OSGBPB
490 \ &A3 - OSFIND
500 \ &B3 - Called by *QUIT
510 \ &C3 - Called by *BASIC and OSBYTE 142
520 \ &D3
530 \ &E3
540 \ &F3
550
560 \ *OS - Enter command prompt
570 \ ==========================
580 .CmdOS
590 JSR ErrorInit:JSR OSNEWL :\ Point BRKV to ErrorHandler
600 JSR HelpBanner:JSR OSNEWL :\ Display Emulator banner
610 LDY #&04:JSR OSByteA3 :\ Ask host something
620 TYA:BNE JumpToCode :\ If Y<>0, enter code at XY
630
640 .CmdOSLoop
650 JSR PrText :\ Display prompt
660 EQUS "SYSTEM*":NOP
670 LDA #&00
680 LDX #LF84A AND 255
690 LDY #LF84A DIV 256
700 JSR osWORD:BCS OSEscape :\ Input a command
710 LDX #&36:LDY #&02:JSR OS_CLI :\ Execute command
720 JMP CmdOSLoop :\ Jump back for another
730
740 \ *BASIC
750 \ ======
760 .CmdBASIC
770 EQUB &C3 :\ Pass to host
780
790 \ NMI Handler
800 \ ===========
810 .NMIHandler
820 LDY #&04:JSR OSByteA3 :\ Ask host something
830 TYA:BEQ CmdOS :\ If Y=0, enter command prompt
840 .JumpToCode
850 JMP EnterCodeXY :\ Y<>0, enter code at XY
860
870 .OSEscape
880 LDA #&7E:JSR osBYTE :\ Ack. escape
890 BRK:EQUB 17:EQUS "Escape":BRK
900
910 .LF84A
920 EQUW &0236 :\ Input buffer at &0236
930 EQUB &C9 :\ Max. &C9 characters
940 EQUB &20 :\ Minimum character
950 EQUB &FF :\ Maximum character
960
970 .RESET
980 LDX #&FF:TXS :\ Clear stack
990 JSR LF87F :\ Reset vectors and set memory limits
1000 LDY #&06:JSR OSByteA3 :\ Ask host something
1010 TYA:BNE OscliXY :\ If Y<>0, execute command at XY
1020 \ If Y=0, display startup banner and enter command prompt
1030 \ If Y<>0, XY=>command to execute
1040
1050 JSR PrText :\ Print startup banner
1060 EQUB 10:EQUS "Acorn Atom/System Tube"
1070 EQUB 10:EQUB 10:EQUB 13
1080 NOP
1090 JMP CmdOS :\ Jump to command prompt
1100 \ Will then call display help banner,
1110 \ then calls OsByteA3,4 for any entry address
1120
1130 .OscliXY
1140 JSR ErrorInit :\ Set up error handler
1150 JSR OS_CLI:JMP CmdQUIT :\ Execute command then quit
1160
1170 \ Reset vectors and set memory limits
1180 \ ===================================
1190 .LF87F
1200 CLD:LDX #&35
1210 .LF882
1220 LDA LFB87,X:STA &0200,X :\ Copy from default vectors
1230 DEX:BPL LF882
1240 STZ &FF:STZ &F0 :\ Clear escape flag
1250 LDX #&08:STX &F1 :\ Set F0/1=>bottom of memory at &0800
1260 LDX #&00:LDY #&F8 :\ XY=&F800
1270 STX &F4:STY &F5 :\ Set F4/5=>top of memory at &F800
1280 RTS
1290
1300 \ Interupt handler
1310 \ ================
1320 .InterruptHandler
1330 STA &FC:PLA:PHA :\ Save A, get flags from stack
1340 AND #&10:BNE BRKHandler :\ If BRK, jump to BRK handler
1350 JMP (IRQ1V) :\ Continue via IRQ1V handler
1360
1370 .IRQ1Handler
1380 JMP (IRQ2V) :\ No handlers, pass staight on to IRQ2V
1390
1400 .BRKHandler
1410 TXA:PHA :\ Save X
1420 TSX:LDA &0103,X :\ Get address from stack
1430 CLD:SEC:SBC #&01:STA &FD
1440 LDA &0104,X:SBC #&00:STA &FE :\ &FD/E=>after BRK opcode
1450 LDA #&00:STA &03FE :\ Error block at (&FD),Y is in block &00
1460 PLA:TAX:LDA &FC :\ Restore X, get saved A
1470 CLI:JMP (BRKV) :\ Restore IRQs and jump to Error Handler
1480
1490 \ Default error handler
1500 \ =====================
1510 .ErrorHandler
1520 LDX #&FF:TXS :\ Clear stack
1530 INX:STX &03FE :\ Error block at (&FD),Y is in block &00
1540 CLI:JSR OSNEWL
1550 LDY #&01
1560 .LF8D7
1570 LDA (&FD),Y:BEQ LF8E1 :\ Print error string
1580 JSR OSWRCH:INY:BNE LF8D7
1590 .LF8E1
1600 JSR OSNEWL:JMP CmdOSLoop :\ Jump to command prompt
1610
1620 \ *QUIT
1630 \ =====
1640 .CmdQUIT
1650 EQUB &B3 :\ Pass to host
1660
1670 .OSByteA3
1680 LDA #&A3:LDX #&F3 :\ OSBYTE &A3,&F3
1690 EQUB &13 :\ Host OSBYTE
1700 RTS
1710
1720 \ Scan hex
1730 \ ========
1740 .ScanHex
1750 LDX #&00:STX &F6:STX &F7 :\ Clear hex accumulator
1760 STX &03F3 :\ String at (&F2),Y is in block &00
1770 .LF8F7
1780 LDA (&F2),Y :\ Get current character
1790 SEC:SBC #&30:BCC LF921 :\ <'0', exit
1800 CMP #&0A:BCC LF90E :\ '0'..'9', add into accumator
1810 AND #&DF:SBC #&07 :\ Ignore case, convert letters
1820 CMP #&0A:BCC LF921 :\ <'A', exit
1830 CMP #&10:BCS LF921 :\ >'F', exit
1840 .LF90E
1850 ASL A:ASL A:ASL A:ASL A :\ *16
1860 LDX #&03
1870 .LF914
1880 ASL A:ROL &F6:ROL &F7 :\ Move bits into accumulator
1890 BCS LF959 :\ Overflowed, jump to error
1900 DEX:BPL LF914 :\ Loop for four bits
1910 INY:BNE LF8F7 :\ Move to next character
1920 .LF921
1930 JMP SkipSpaces :\ Skip past any final spaces and exit
1940
1950 \ Scan hex, error if null string
1960 .LF924
1970 JSR ScanHex:PHP :\ Save <cr> flag
1980 CPX #&00:BEQ LF959 :\ X=0, nothing read in, 'Bad number' error
1990 PLP:RTS :\ Get <cr> flag back
2000
2010 \ *PAGE - Set PAGE address
2020 \ ========================
2030 .CmdPAGE
2040 JSR SkipSpaces:BEQ LF94A :\ No parameters, jump to use &0800
2050 JSR LF924:BNE LF959 :\ Error if more parameters
2060 LDY &F7:LDX &F6:BNE LF94E :\ addr<>&xx00, error as must by 256-byte aligned
2070 CPY #&08:BCC LF94E :\ addr<&0800, error as too low
2080 CPY #&80:BCS LF94E :\ addr>&8000, error as too high
2090 .LF946
2100 STY &F1:CLC:RTS :\ Store PAGE high byte
2110 .LF94A
2120 LDY #&08:BRA LF946 :\ Default to &0800
2130
2140 .LF94E
2150 BRK
2160 BRK:EQUS "Bad PAGE":BRK :\ Unusable PAGE value
2170 .LF959
2180 BRK
2190 BRK:EQUS "Bad number":BRK :\ Bad hex
2200 .LF966
2210 SEC:RTS :\ SEC=pass command to host
2220
2230 \ *GO - Call machine code
2240 \ =======================
2250 .CmdGO
2260 JSR SkipSpaces:BEQ LF984 :\ If no params, re-enter existing code
2270 JSR ScanHex :\ Scan hex parameter
2280 CPX #&00:BEQ LF966 :\ No hex parameter, pass to host
2290 :\ eg *GO HELLO
2300 CMP #&3B:BEQ LF97C :\ '
2310 CMP #&0D:BNE LF959 :\ More parameters, error
2320 .LF97C
2330 LDX &F6:LDY &F7 :\ Store parameter pointer
2340 :\ Enter code at XY
2350
2360 .EnterCodeXY
2370 STX &F4:STY &F5 :\ Set memtop to entry address
2380 .LF984
2390 LDA &EF:PHA:LDA &EE:PHA :\ Save current program
2400 JSR EnterCode
2410 PLA:STA &EE:STA &F4 :\ Restore current program and also set memtop
2420 PLA:STA &EF:STA &F5
2430 CLC:RTS :\ CLC=command done
2440
2450 \ Check if code to be entered has a ROM header
2460 .EnterCode
2470 LDA &F4:STA &EE :\ Current program starts at memtop
2480 LDA &F5:STA &EF
2490 LDX #&00:STX &03F5:STX &03FE :\ Set memtop and errptr are in block &00
2500 LDY #&07:LDA (&F4),Y :\ Get copyright offset
2510 CLD:CLC:ADC &F4:STA &FD
2520 LDA #&00:ADC &F5:STA &FE :\ &FD/E=>copyright message
2530 \ Check for &00,"(C)"
2540 LDY #&00:LDA (&FD),Y:BNE LF9FC :\ Check for initial &00
2550 INY:LDA (&FD),Y:CMP #&28:BNE LF9FC :\ Check for '('
2560 INY:LDA (&FD),Y:CMP #&43:BNE LF9FC :\ Check for 'C'
2570 INY:LDA (&FD),Y:CMP #&29:BNE LF9FC :\ Check for ')'
2580 \ &00,"(C)" exists
2590 LDY #&06:LDA (&F4),Y :\ Get ROM type
2600 AND #&4D:CMP #&40:BCC LFA2A :\ b6=0, Not a language
2610 AND #&0D:BEQ LF9E6 :\ code=%x1xx00x0, enter 6502 code
2620 CMP #&01:BNE LFA0E :\ code<>%x1xx00x1, not 6502 code
2630 .LF9E6
2640 \ romtype=%0000 - A=0 - 6502 BASIC
2650 \ romtype=%0001 - A=1 - Turbo6502
2660 \ romtype=%0010 - A=0 - 6502 nonBASIC
2670 \ romtype=%0011 - A=1 - reserved
2680 PHA:LDY #&09 :\ Save entry value &00 or &01
2690 .LF9E9
2700 LDA (&F4),Y:BEQ LF9F3 :\ Print ROM title
2710 JSR OSWRCH:INY:BNE LF9E9
2720 .LF9F3
2730 JSR OSNEWL:JSR OSNEWL :\ Print two NLs
2740 PLA:BRA LF9FE :\ Get entry value back
2750 .LF9FC :\ No (C) string, enter as raw code
2760 LDA #&00 :\ Set flag=0
2770 .LF9FE
2780 STA &F0 :\ Store flag at &F0
2790 \ If flag=0, membot=&F0/1, memtop=&F4/5
2800 \ If flag<>0, membot=0000, memtop=0000
2810 LDY #&00:TYA
2820 .LFA03
2830 STA &0300,Y:DEY:BNE LFA03 :\ All (zp),Y accesses to block &00
2840 LDA #&01:JMP (&00F4) :\ Enter code with A=1
2850
2860 .LFA0E
2870 JSR ErrorInit
2880 BRK
2890 BRK:EQUS "I cannot run this code":BRK
2900 .LFA2A
2910 JSR ErrorInit
2920 BRK
2930 BRK:EQUS "This is not a language":BRK
2940
2950 .ErrorInit
2960 LDA #ErrorHandler AND 255:STA BRKV+0 :\ Claim BRKV
2970 LDA #ErrorHandler DIV 256:STA BRKV+1
2980 RTS
2990
3000 \ *HELP - Display help
3010 \ ====================
3020 .CmdHELP
3030 JSR SkipSpaces:BNE LFA5C :\ Exit if parameters
3040 JSR OSNEWL:JSR HelpBanner:\ Display startup banner
3050 .LFA5C
3060 SEC:RTS :\ Return, SEC to pass to host
3070
3080 .HelpBanner
3090 JSR PrText
3100 EQUS "6502 Emulator OS 0.64 (19 Oct 1988)"
3110 EQUB 10:EQUB 13
3120 NOP
3130 RTS
3140
3150 .osBYTE :\ OSBYTE
3160 PHA
3170 CMP #&82:BEQ BYTE82 :\ Read memory high word
3180 CMP #&83:BEQ BYTE83 :\ Read bottom of memory
3190 CMP #&84:BEQ BYTE84 :\ Read top of memory
3200 CMP #&85:BEQ BYTE85 :\ Read top of memory for screen mode
3210 CMP #&8E:BEQ BYTE8E :\ Enter language
3220 CMP #&A3:BNE BYTEnn :\ Jump if not Application OSBYTE
3230 CPX #&FE:BCC BYTEnn :\ Jump if X<&FE
3240 \ OSBYTE &A3,&FE and OSBYTE &A3,FF - return unchanged
3250 PLA
3260 RTS
3270
3280 .BYTEnn :\ Pass OSBYTE to host
3290 EQUB &13 :\ MOS_BYTE
3300 PLA:RTS :\ Return
3310
3320 .BYTE82 :\ Read memory high word
3330 LDX #&00:LDY #&00 :\ High word=&0000
3340 PLA:RTS
3350
3360 .BYTE83 :\ Read bottom of memory
3370 PLA :\ Get A back
3380 LDX &F0:BEQ LFABC :\ If &F0=0, &F0/F1=>memory bottom
3390 LDA #&01 :\ Set A=&01
3400 LDX #&00:LDY #&00 :\ Return memory bottom=&0000
3410 RTS
3420 .LFABC
3430 LDX #&00:LDY &F1 :\ Get memory bottom from &F0/F1
3440 RTS
3450
3460 .BYTE84 :\ Read top of memory
3470 PLA :\ Get A back
3480 LDX &F0:BEQ LFACD :\ If &F0=0, &F4/5=>memory top
3490 LDA #&04 :\ Set A=&04
3500 LDX #&00:LDY #&00 :\ Return memory top=&0000
3510 RTS
3520 .LFACD
3530 LDX &F4:LDY &F5 :\ Get memory top from &F4/F5
3540 RTS
3550
3560 .BYTE85 :\ Read top of memory for screem
3570 LDX #&00:LDY #&80 :\ Return top of memory=&8000
3580 PLA:RTS :\ Restore A and return
3590
3600 .BYTE8E :\ Enter language
3610 JMP CmdBASIC :\ Jump to enter BASIC
3620
3630 .osBGet
3640 EQUB &73 :\ Pass OSBGet to host
3650 RTS
3660
3670 .osBPut
3680 EQUB &83 :\ Pass OSBPut to host
3690 RTS
3700
3710 .osFILE
3720 EQUB &53 :\ Pass OSFILE to host
3730 RTS
3740
3750 .osFIND
3760 EQUB &A3 :\ Pass OSFIND to host
3770 RTS
3780
3790 .osGBPB
3800 EQUB &93 :\ Pass OSGBPB to host
3810 RTS
3820
3830 .osRDCH
3840 EQUB &43 :\ Pass OSRDCH to host
3850 RTS
3860
3870 .osWRCH
3880 EQUB &33 :\ Pass OSWRCH to host
3890 RTS
3900
3910 .osWORD :\ OSWORD
3920 CMP #&05:BNE LFB0C :\ Jump if not Read I/O memory
3930 :
3940 \ OSWORD 5 - Read I/O memory
3950 \ Reads from Tube memory
3960 STX &F8:STY &F9 :\ &F8/9=>control block
3970 LDY #&00:STY &03F9 :\ Control block at (&F8),Y in block &00
3980 LDA (&F8),Y:STA &FA
3990 INY
4000 LDA (&F8),Y:STA &FB :\ &FA/B=address to read
4010 LDX #&00:LDA (&FA,X) :\ Read from address
4020 LDY #&04:STA (&F8),Y :\ Store byte read in control block
4030 LDX &F8:LDY &F9 :\ Restore X, Y
4040 RTS
4050
4060 .LFB0C
4070 EQUB &23 :\ Pass OSWORD to host
4080 RTS
4090
4100 .osARGS :\ OSARGS
4110 CMP #&01:BNE LFB3C :\ Jump if not command line/PTR=
4120 CPY #&00:BNE LFB3C :\ Jump if not command line
4130 :
4140 \ OSARGS 1,0 - Read address of command line
4150 STY &03F3:DEY :\ String at (&F2),Y is in block &00
4160 .LFB1A
4170 INY:LDA (&F2),Y :\ Get character from command line
4180 CMP #&20:BCC LFB26 :\ Control character found
4190 BNE LFB1A :\ Loop if not space
4200 JSR SkipSpaces :\ Skip any more spaces
4210 .LFB26
4220 CLC:TYA:ADC &F2:STA &00,X :\ Add Y to base
4230 LDA &F3:ADC #&00:STA &01,X :\ Set returned address
4240 LDY #&FF:STY &02,X:STY &03,X :\ Set to &FFFFxxxx
4250 INY:LDA #&01 :\ Return Y=&00, A=&01
4260 RTS
4270 .LFB3C
4280 EQUB &63 :\ Pass OSARGS to host
4290 RTS
4300
4310 \ Print embedded string
4320 \ =====================
4330 .PrText
4340 PLA:STA &FA:PLA:STA &FB :\ &FA/B=>embedded string
4350 LDY #&00:STY &03FB :\ String at (&FA),Y is in block &00
4360 INY
4370 .LFB4A
4380 LDA (&FA),Y :\ Get character
4390 CMP #&EA:BEQ LFB56 :\ Exit if NOP
4400 JSR OSWRCH:INY:BNE LFB4A :\ Print char and loop for next
4410 .LFB56
4420 TYA:CLC:ADC &FA
4430 TAX:LDA #&00:ADC &FB :\ Update return address
4440 PHA:TXA:PHA :\ Points after string
4450 .NullReturn
4460 RTS
4470
4480 \ Print string at XY
4490 \ ------------------
4500 .PrString
4510 STX &FA:STY &FB :\ Store XY in &FA/B
4520 LDY #&00:STY &03FB :\ String at (&FA),Y is in block &00
4530 .LFB6C
4540 LDA (&FA),Y :\ Get a character
4550 CMP #&20:BCC LFB78 :\ Exit at control char
4560 JSR OSWRCH:INY:BNE LFB6C :\ Print character
4570 .LFB78
4580 RTS
4590
4600 .Unsupported
4610 BRK
4620 BRK:EQUS "Unsupported":BRK
4630
4640 \ Default vectors
4650 .LFB87
4660 EQUW Unsupported :\ &200 - USERV
4670 EQUW ErrorHandler :\ &202 - BRKV
4680 EQUW IRQ1Handler :\ &204 - IRQ1V
4690 EQUW Unsupported :\ &206 - IRQ2V
4700 EQUW osCLI :\ &208 - CLIV
4710 EQUW osBYTE :\ &20A - BYTEV
4720 EQUW osWORD :\ &20C - WORDV
4730 EQUW osWRCH :\ &20E - WRCHV
4740 EQUW osRDCH :\ &210 - RDCHV
4750 EQUW osFILE :\ &212 - FILEV
4760 EQUW osARGS :\ &214 - ARGSV
4770 EQUW osBGet :\ &216 - BGetV
4780 EQUW osBPut :\ &218 - BPutV
4790 EQUW osGBPB :\ &21A - GBPBV
4800 EQUW osFIND :\ &21C - FINDV
4810 EQUW Unsupported :\ &21E - FSCV
4820 EQUW NullReturn :\ &220 - EVNTV
4830 EQUW NullReturn :\ &222 - UPTV
4840 EQUW NullReturn :\ &224 - NETV
4850 EQUW Unsupported :\ &226 - VduV
4860 EQUW Unsupported :\ &228 - KEYV
4870 EQUW Unsupported :\ &22A - INSV
4880 EQUW Unsupported :\ &22C - RemV
4890 EQUW Unsupported :\ &22E - CNPV
4900 EQUW NullReturn :\ &230 - IND1V
4910 EQUW NullReturn :\ &232 - IND2V
4920 EQUW NullReturn :\ &234 - IND3V
4930
4940 .osCLI :\ OSCLI
4950 STX &F2:STY &F3 :\ &F2/3=>command string
4960 LDY #&00:STY &03F3 :\ String at (&F2),Y is in block &00
4970 .LFBC6
4980 LDA (&F2),Y:STA LFC6A,Y :\ Copy command line to command buffer
4990 CMP #&0D:BEQ LFBD3 :\ Loop until <cr>
5000 INY:BNE LFBC6 :\ Loop for up to 256 characters
5010 .LFBD2
5020 RTS :\ No <cr> found, exit
5030 .LFBD3
5040 LDX #LFC6A AND 255
5050 LDY #LFC6A DIV 256 :\ Point XY to command buffer
5060 STX &F2:STY &F3 :\ Point &F2/3 to command buffer
5070 LDX #&00:LDY #&FF
5080 .LFBDF
5090 JSR SkipSpaces1 :\ Move past and skip spaces
5100 CMP #ASC"*":BEQ LFBDF :\ Skip past '*'s
5110 CMP #&0D:BEQ LFBD2 :\ Null string, exit
5120 CMP #ASC"|":BEQ LFBD2 :\ *|, comment, exit
5130 CLC:TYA:ADC &F2:STA &F2 :\ Adjust &F2/3 to point to start of command
5140 BCC LFBF8:INC &F3
5150 .LFBF8
5160 LDY #&00:LDA (&F2),Y :\ Get first character
5170 CMP #ASC".":BEQ LFC45 :\ '*.', jump to pass to host
5180 .LFC00
5190 TYA:PHA :\ Save command pointer
5200 JSR SkipSpaces :\ Skip any more spaces
5210 .LFC05
5220 LDA LFF02,X:BMI LFC20 :\ Jump if at end of command table
5230 EOR (&F2),Y :\ Compare with command table
5240 AND #&DF:BNE LFC14 :\ Ignore case, jump if no match
5250 INX:INY:BRA LFC05 :\ Loop to check next character
5260
5270 .LFC14
5280 LDA (&F2),Y:INY :\ Get command character
5290 CMP #ASC".":BEQ LFC29 :\ Abbreviated, jump to execute
5300 .LFC1B
5310 PLA:TAY :\ Get command pointer back
5320 SEC:BRA LFC2B :\ Step to next entry
5330
5340 .LFC20
5350 ASL A:BMI LFC29
5360 LDA (&F2),Y :\ Get next character
5370 CMP #ASC"A":BCS LFC1B :\ Still more letters, try next entry
5380 .LFC29
5390 PLA:CLC :\ Drop command pointer
5400 .LFC2B
5410 DEX
5420 .LFC2C
5430 INX:LDA LFF02,X:BPL LFC2C :\ Find end of entry
5440 BCC LFC3C
5450 INX:LDA LFF02,X
5460 BNE LFC00:BEQ LFC45
5470
5480 .LFC3C
5490 ASL A:AND #&7F :\ Index into command table
5500 TAX:JSR LFC4B :\ Call command routine
5510 BCC LFC4A :\ If CLC, exit with call claimed
5520 .LFC45
5530 LDX &F2:LDY &F3 :\ &F2/3=XY
5540 EQUB &03 :\ Pass OSCLI to host
5550 :\ If host loads code and starts execution,
5560 :\ it generates an NMI and returns <>0 from
5570 :\ Osbyte 163,&F3
5580 .LFC4A
5590 RTS
5600
5610 .LFC4B
5620 LDA LFC5E+1,X:PHA :\ Stack address high byte
5630 LDA LFC5E+0,X:PHA :\ Stack address low byte
5640 RTS :\ Jump to routine
5650
5660 .SkipSpaces1
5670 INY
5680 .SkipSpaces
5690 LDA (&F2),Y:CMP #&20:BEQ SkipSpaces1
5700 CMP #&0D:RTS
5710
5720 \ Command addresses
5730 \ -----------------
5740 .LFC5E
5750 EQUW CmdBASIC-1 :\ *BASIC
5760 EQUW CmdQUIT-1 :\ *QUIT
5770 EQUW CmdHELP-1 :\ *HELP
5780 EQUW CmdGO-1 :\ *GO
5790 EQUW CmdOS-1 :\ *OS
5800 EQUW CmdPAGE-1 :\ *PAGE
5810
5820 \ OSCLI command buffer
5830 \ --------------------
5840 .LFC6A
5850 EQUS STRING$(128,CHR$0)
5860 EQUS STRING$(128,CHR$0)
5870
5880 .LFD6A
5890 BRK:BRK
5900 .LFD6C
5910 STZ &C0
5920 AND #&00
5930 CLC
5940 RTS
5950
5960 \ This looks like a bit of BASIC code
5970 \ -----------------------------------
5980 .LFD72
5990 LDA &0B:STA &19
6000 LDA &0C:STA &1A
6010 LDA &0A:STA &1B
6020 .LFD7E
6030 LDY &1B:INC &1B
6040 LDA (&19),Y
6050 CMP #&20:BEQ LFD7E
6060 CMP #&3D:BEQ LFDBA
6070 .LFD8C
6080 BRK
6090 EQUB &04:EQUS "Mistake"
6100 .LFD95
6110 BRK
6120 EQUB &10:EQUS "Syntax error"
6130 .LFDA3
6140 BRK
6150 EQUB &0D:EQUS "No ":EQUB &F2
6160 .LFDA9
6170 BRK
6180 EQUB &11:EQUS "Escape"
6190 BRK
6200
6210 .LFDB2
6220 JSR &C742
6230 CMP #&3D:BNE LFD8C
6240 RTS
6250
6260 .LFDBA
6270 JSR &D5AF:TXA
6280 LDY &1B:BRA LFDDC
6290 LDY &1B:BRA LFDD4
6300 TSX:CPX #&FC:BCS LFDA3
6310 LDA &01FF:CMP #&F2:BNE LFDA3
6320 LDY &0A
6330 .LFDD4
6340 DEY
6350 .LFDD5
6360 INY:LDA (&0B),Y
6370 CMP #&20:BEQ LFDD5
6380 .LFDDC
6390 CMP #&3A:BEQ LFDE8
6400 CMP #&0D:BEQ LFDE8
6410 CMP #&8B:BNE LFD95
6420 .LFDE8
6430 CLC:TYA:ADC &0B:STA &0B
6440 BCC LFDF2:INC &0C
6450 .LFDF2
6460 LDY #&01:STY &0A
6470 BIT &FF:BMI LFDA9
6480 .LFDFA
6490 RTS
6500
6510 .LFDFB
6520 JSR &D41A
6530 LDA (&0B):CMP #&3A:BEQ LFDFA
6540 LDA &0C:CMP #&07:BEQ LFE2E
6550 LDY #&01:LDA (&0B),Y:BMI LFE2E
6560 LDX &20:BEQ LFE1E
6570 STA &2B:INY:LDA (&0B),Y:STA &2A
6580 JSR &D4BF
6590 .LFE1E
6600 LDA #&03:CLC:ADC &0B:STA &0B
6610 BCC LFE29:INC &0C
6620 .LFE29
6630 LDY #&01:STY &0A
6640 .LFE2D
6650 RTS
6660
6670 .LFE2E
6680 JMP &C7FB
6690
6700 .LFE31
6710 JMP &C905
6720
6730 .LFE34
6740 JSR &D5A3:BEQ LFE31
6750 BPL LFE3E:JSR &CF38
6760 .LFE3E
6770 LDY &1B:STY &0A:LDA &2A
6780 ORA &2B:ORA &2C:ORA &2D:BEQ LFE63
6790 CPX #&8C:BEQ LFE53
6800 .LFE50
6810 JMP &C880
6820
6830 .LFE53
6840 INC &0A
6850 .LFE55
6860 JSR &D392:BCC LFE50
6870 JSR &F018:JSR &D43A
6880 JMP &EF05
6890
6900 .LFE63
6910 LDY &0A
6920 .LFE65
6930 LDA (&0B),Y:CMP #&0D:BEQ LFE74
6940 INY:CMP #&8B:BNE LFE65
6950 STY &0A:BEQ LFE55
6960 .LFE74
6970 JMP &C82D
6980
6990 .LFE77
7000 LDA &2A:CMP &21:LDA &2B
7010 SBC &22:BCS LFE2D
7020 LDA #&5B:JSR &F58A
7030 JSR &D898:LDA #&5D
7040 JSR &F58A:
7050 JMP &F584
7060
7070 .LFE91
7080 JSR &F3EC:JSR &D6B7
7090 TAY:JSR &CF52
7100 JSR &F3D6:JSR &DCC4
7110 LDA &2E:EOR &3B:BPL LFEBF
7120 ASL &2E:BRA LFEE1
7130
7140 .LFEAB
7150 STY &2D:PLA:STA &2C
7160 PLA:STA &2B
7170 PLA:STA &2A
7180 JSR &BA3A
7190 LDA &3B:EOR #&80:STA &3B
7200 .LFEBF
7210 LDA &3C:CMP &30:BNE LFEDD
7220 LDA &3D:CMP &31:BNE LFEDD
7230 LDA &3E:CMP &32:BNE LFEDD
7240 LDA &3F:CMP &33:BNE LFEDD
7250 LDA &40:SBC &34:BEQ LFEE3
7260 .LFEDD
7270 ROR A:EOR &3B:ROL A
7280 .LFEE1
7290 LDA #&FF
7300 .LFEE3
7310 RTS
7320
7330 .LFEE4
7340 JMP &C905
7350
7360 .LFEE7
7370 INC &1B:TXA:BEQ LFF2C
7380 BMI LFE91
7390 LDA &2A:PHA
7400 LDA &2B:PHA
7410 LDA &2C:PHA
7420 LDA &2D:PHA
7430 JSR &D6B7:TAY:BMI P%+29
7440
7450 .LFF00
7460 EQUW LFF17
7470 \ Command table
7480 .LFF02
7490 EQUS "GO" :EQUB &C3
7500 EQUS "HELP" :EQUB &82
7510 EQUS "OS" :EQUB &84
7520 EQUS "PAGE" :EQUB &C5
7530 EQUS "QUIT" :EQUB &81
7540 .LFF17
7550 EQUS "BASIC":EQUB &80
7560 EQUB &00
7570
7580 EQUS STRING$(&FF2C-P%,CHR$0)
7590 .LFF2C
7600
7610 EQUS STRING$(&FFB6-P%,CHR$0)
7620 .VECDEF :EQUB &36:EQUW LFB87
7630 .LFFxx :JMP Unsupported
7640 .LFFxx :JMP Unsupported
7650 .LFFxx :JMP Unsupported
7660 .LFFxx :JMP Unsupported
7670 \.LFFxx :\JMP Unsupported
7680
7690 \ Atom/System Entry Block
7700 \ -----------------------
7710 \.NVRDCH :JMP osRDCH
7720 \.NVWRCH :JMP osWRCH
7730
7740 .OSSHUT :JMP (FINDV)
7750 .OSFIND :JMP (FINDV)
7760 .OSBPUT :JMP (BPutV)
7770 .OSBGET :JMP (BGetV)
7780 .OSSTAR :JMP (ARGSV)
7790 .OSRDAR :JMP (ARGSV)
7800 .OSSAVE :JMP (FILEV)
7810 .OSLOAD :JMP (FILEV)
7820
7830 \.OSFIND :\JMP (FINDV)
7840 \.OSGBPB :\JMP (GBPBV)
7850 \.OSBPUT :\JMP (BPutV)
7860 \.OSBGET :\JMP (BGetV)
7870 \.OSARGS :\JMP (ARGSV)
7880 \.OSFILE :\JMP (FILEV)
7890
7900 .OSRDCH :JMP (RDCHV)
7910 .OSECHO :JSR OSRDCH
7920 .OSASCI :CMP #&0D:BNE OSWRCH
7930 .OSNEWL :LDA #&0A:JSR OSWRCH
7940 .OSPRCR :LDA #&0D
7950 .OSWRCH :JMP (WRCHV)
7960 \.OSWORD :\JMP (WORDV)
7970 \.OSBYTE :\JMP (BYTEV)
7980 .OS_CLI :JMP (CLIV)
7990
8000 .NMIV :EQUW NMIHandler
8010 .RESETV :EQUW RESET
8020 .IRQV :EQUW InterruptHandler
8030 ]:NEXT
8040 OSCLI"Save 65Kernel "+STR$~mcode%+" "+STR$~O%+" "+STR$~load%+" "+STR$~load%
8050 ON ERROR ON ERROR OFF:END
8060 *Quit
8070 :
8080
8090
8100
8110