1 REM Source for 65Tube Tube client
    2 :
    3 load%=&F800:DIM mcode% &900
    4 :
    5 USERV=&200: BRKV=&202:IRQ1V=&204:IRQ2V=&206
    6  CLIV=&208:BYTEV=&20A:WORDV=&20C:WRCHV=&20E
    7 RDCHV=&210:FILEV=&212:ARGSV=&214:BGetV=&216
    8 BPutV=&218:GBPBV=&21A:FINDV=&21C: FSCV=&21E
    9 EVNTV=&220: UPTV=&222: NETV=&224: VduV=&226
   10  KEYV=&228: INSV=&22A: RemV=&22C: CNPV=&22E
   11 IND1V=&230:IND2V=&232:IND3V=&234
   12 :
   13 FOR P=0TO1
   14   P%=load%:O%=mcode%
   15   [OPT P*3+4
   16   \ &EE/F=
   17   \ &F0/1=>membot, if &F0<>0, membot=0000, memtop=0000
   18   \ &F2/3=>command string
   19   \ &F4/5=>memtop
   20   \ &F6/7= readhex accumulator, ";params" pointer
   21   \ &F8/9=>control block
   22   \ &FA/B=>String to print with PrString
   23   \ &FC  = IRQ A store
   24   \ &FD/E=>last error
   25   \ &FF  = escape flag
   26   \ &0236= command input buffer
   27   \ &03xx= bit16-bit23 of Turbo65 (zp),Y addresses
   28   \ &03F3= b16-b23 of (&F2),Y command string pointer
   29   \ &03F5= b16-b23 of (&F4),Y memtop pointer
   30   \ &03F9= b16-b23 of (&F8),Y control block pointer
   31   \ &03FB= b16-b23 of (&FA),Y string pointer
   32   \ &03FE= b16-b23 of (&FD),Y error pointer
   33   
   34   \ Emulator opcodes
   35   \ &03 - OSCLI
   36   \ &13 - OSBYTE
   37   \ &23 - OSWORD
   38   \ &33 - OSWRCH
   39   \ &43 - OSRDCH
   40   \ &53 - OSFILE
   41   \ &63 - OSARGS
   42   \ &73 - OSBGET
   43   \ &83 - OSBPUT
   44   \ &93 - OSGBPB
   45   \ &A3 - OSFIND
   46   \ &B3 - Called by *CASEASN
   47   \ &C3 - Called by *BASIC and OSBYTE 142
   48   \ &D3
   49   \ &E3
   50   \ &F3
   51   
   52   \ *OS - Enter command prompt
   53   \ ==========================
   54   .CmdOS
   55   JSR ErrorInit:JSR OSNEWL      :\ Point BRKV to ErrorHandler
   56   JSR HelpBanner:JSR OSNEWL     :\ Display Emulator banner
   57   LDY #&04:JSR OSByteA3         :\ Ask host something
   58   TYA:BNE JumpToCode            :\ If Y<>0, enter code at XY
   59   
   60   .CmdOSLoop
   61   JSR PrText                    :\ Display prompt
   62   EQUS "65*":NOP
   63   LDA #&00
   64   LDX #LF84A AND 255
   65   LDY #LF84A DIV 256
   66   JSR OSWORD:BCS OSEscape       :\ Input a command
   67   LDX #&36:LDY #&02:JSR OS_CLI  :\ Execute command
   68   JMP CmdOSLoop                 :\ Jump back for another
   69   
   70   \ *BASIC
   71   \ ======
   72   .CmdBASIC
   73   EQUB &C3                      :\ Pass to host
   74   
   75   \ NMI Handler
   76   \ ===========
   77   .NMIHandler
   78   LDY #&04:JSR OSByteA3         :\ Ask host something
   79   TYA:BEQ CmdOS                 :\ If Y=0, enter command prompt
   80   .JumpToCode
   81   JMP EnterCodeXY               :\ Y<>0, enter code at XY
   82   
   83   .OSEscape
   84   LDA #&7E:JSR OSBYTE           :\ Ack. escape
   85   BRK:EQUB 17:EQUS "Escape":BRK
   86   
   87   .LF84A
   88   EQUW &0236 :\ Input buffer at &0236
   89   EQUB &C9   :\ Max. &C9 characters
   90   EQUB &20   :\ Minimum character
   91   EQUB &FF   :\ Maximum character
   92   
   93   .RESET
   94   LDX #&FF:TXS                  :\ Clear stack
   95   JSR LF87F                     :\ Reset vectors and set memory limits
   96   LDY #&06:JSR OSByteA3         :\ Ask host something
   97   TYA:BNE OscliXY               :\ If Y<>0, execute command at XY
   98   \ If Y=0, display startup banner and enter command prompt
   99   \ If Y<>0, XY=>command to execute
  100   
  101   JSR PrText                    :\ Print startup banner
  102   EQUB 10:EQUS "Acorn 6502 Tube"
  103   EQUB 10:EQUB 10:EQUB 13
  104   NOP
  105   JMP CmdOS                     :\ Jump to command prompt
  106   \ Will then call display help banner,
  107   \ then calls OsByteA3,4 for any entry address
  108   
  109   .OscliXY
  110   JSR ErrorInit                 :\ Set up error handler
  111   JSR OS_CLI:JMP CmdQUIT        :\ Execute command then quit
  112   
  113   \ Reset vectors and set memory limits
  114   \ ===================================
  115   .LF87F
  116   CLD:LDX #&35
  117   .LF882
  118   LDA LFB87,X:STA &0200,X       :\ Copy from default vectors
  119   DEX:BPL LF882
  120   STZ &FF:STZ &F0               :\ Clear escape flag
  121   LDX #&08:STX &F1              :\ Set F0/1=>bottom of memory at &0800
  122   LDX #&00:LDY #&F8             :\ XY=&F800
  123   STX &F4:STY &F5               :\ Set F4/5=>top of memory at &F800
  124   RTS
  125   
  126   \ Interupt handler
  127   \ ================
  128   .InterruptHandler
  129   STA &FC:PLA:PHA           :\ Save A, get flags from stack
  130   AND #&10:BNE BRKHandler   :\ If BRK, jump to BRK handler
  131   JMP (IRQ1V)               :\ Continue via IRQ1V handler
  132   
  133   .IRQ1Handler
  134   JMP (IRQ2V)               :\ No handlers, pass staight on to IRQ2V
  135   
  136   .BRKHandler
  137   TXA:PHA                      :\ Save X
  138   TSX:LDA &0103,X              :\ Get address from stack
  139   CLD:SEC:SBC #&01:STA &FD
  140   LDA &0104,X:SBC #&00:STA &FE :\ &FD/E=>after BRK opcode
  141   LDA #&00:STA &03FE           :\ Error block at (&FD),Y is in block &00
  142   PLA:TAX:LDA &FC              :\ Restore X, get saved A
  143   CLI:JMP (BRKV)               :\ Restore IRQs and jump to Error Handler
  144   
  145   \ Default error handler
  146   \ =====================
  147   .ErrorHandler
  148   LDX #&FF:TXS                 :\ Clear stack
  149   INX:STX &03FE                :\ Error block at (&FD),Y is in block &00
  150   CLI:JSR OSNEWL
  151   LDY #&01
  152   .LF8D7
  153   LDA (&FD),Y:BEQ LF8E1        :\ Print error string
  154   JSR OSWRCH:INY:BNE LF8D7
  155   .LF8E1
  156   JSR OSNEWL:JMP CmdOSLoop     :\ Jump to command prompt
  157   
  158   \ *CASEASN
  159   \ =====
  160   .CmdQUIT
  161   EQUB &B3                     :\ Pass to host
  162   
  163   .OSByteA3
  164   LDA #&A3:LDX #&F3            :\ OSBYTE &A3,&F3
  165   EQUB &13                     :\ Host OSBYTE
  166   RTS
  167   
  168   \ Scan hex
  169   \ ========
  170   .ScanHex
  171   LDX #&00:STX &F6:STX &F7     :\ Clear hex accumulator
  172   STX &03F3                    :\ String at (&F2),Y is in block &00
  173   .LF8F7
  174   LDA (&F2),Y                  :\ Get current character
  175   SEC:SBC #&30:BCC LF921       :\ <'0', exit
  176   CMP #&0A:BCC LF90E           :\ '0'..'9', add into accumator
  177   AND #&DF:SBC #&07            :\ Ignore case, convert letters
  178   CMP #&0A:BCC LF921           :\ <'A', exit
  179   CMP #&10:BCS LF921           :\ >'F', exit
  180   .LF90E
  181   ASL A:ASL A:ASL A:ASL A      :\ *16
  182   LDX #&03
  183   .LF914
  184   ASL A:ROL &F6:ROL &F7        :\ Move bits into accumulator
  185   BCS LF959                    :\ Overflowed, jump to error
  186   DEX:BPL LF914                :\ Loop for four bits
  187   INY:BNE LF8F7                :\ Move to next character
  188   .LF921
  189   JMP SkipSpaces               :\ Skip past any final spaces and exit
  190   
  191   \ Scan hex, error if null string
  192   .LF924
  193   JSR ScanHex:PHP              :\ Save <cr> flag
  194   CPX #&00:BEQ LF959           :\ X=0, nothing read in, 'Bad number' error
  195   PLP:RTS                      :\ Get <cr> flag back
  196   
  197   \ *PAGE - Set PAGE address
  198   \ ========================
  199   .CmdPAGE
  200   JSR SkipSpaces:BEQ LF94A   :\ No parameters, jump to use &0800
  201   JSR LF924:BNE LF959        :\ Error if more parameters
  202   LDY &F7:LDX &F6:BNE LF94E  :\ addr<>&xx00, error as must by 256-byte aligned
  203   CPY #&08:BCC LF94E         :\ addr<&0800, error as too low
  204   CPY #&80:BCS LF94E         :\ addr>&8000, error as too high
  205   .LF946
  206   STY &F1:CLC:RTS            :\ Store PAGE high byte
  207   .LF94A
  208   LDY #&08:BRA LF946         :\ Default to &0800
  209   
  210   .LF94E
  211   BRK
  212   BRK:EQUS "Bad PAGE":BRK    :\ Unusable PAGE value
  213   .LF959
  214   BRK
  215   BRK:EQUS "Bad number":BRK  :\ Bad hex
  216   .LF966
  217   SEC:RTS                    :\ SEC=pass command to host
  218   
  219   \ *GO - Call machine code
  220   \ =======================
  221   .CmdGO
  222   JSR SkipSpaces:BEQ LF984   :\ If no params, re-enter existing code
  223   JSR ScanHex                :\ Scan hex parameter
  224   CPX #&00:BEQ LF966         :\ No hex parameter, pass to host
  225                              :\ eg *GO HELLO
  226   CMP #&3B:BEQ LF97C         :\ ';'
  227   CMP #&0D:BNE LF959         :\ More parameters, error
  228   .LF97C
  229   LDX &F6:LDY &F7            :\ Store parameter pointer
  230                              :\ Enter code at XY
  231   
  232   .EnterCodeXY
  233   STX &F4:STY &F5            :\ Set memtop to entry address
  234   .LF984
  235   LDA &EF:PHA:LDA &EE:PHA    :\ Save current program
  236   JSR EnterCode
  237   PLA:STA &EE:STA &F4        :\ Restore current program and also set memtop
  238   PLA:STA &EF:STA &F5
  239   CLC:RTS                    :\ CLC=command done
  240   
  241   \ Check if code to be entered has a ROM header
  242   .EnterCode
  243   LDA &F4:STA &EE              :\ Current program starts at memtop
  244   LDA &F5:STA &EF
  245   LDX #&00:STX &03F5:STX &03FE :\ Set memtop and errptr are in block &00
  246   LDY #&07:LDA (&F4),Y         :\ Get copyright offset
  247   CLD:CLC:ADC &F4:STA &FD
  248   LDA #&00:ADC &F5:STA &FE     :\ &FD/E=>copyright message
  249   \ Check for &00,"(C)"
  250   LDY #&00:LDA (&FD),Y:BNE LF9FC     :\ Check for initial &00
  251   INY:LDA (&FD),Y:CMP #&28:BNE LF9FC :\ Check for '('
  252   INY:LDA (&FD),Y:CMP #&43:BNE LF9FC :\ Check for 'C'
  253   INY:LDA (&FD),Y:CMP #&29:BNE LF9FC :\ Check for ')'
  254   \ &00,"(C)" exists
  255   LDY #&06:LDA (&F4),Y         :\ Get ROM type
  256   AND #&4D:CMP #&40:BCC LFA2A  :\ b6=0, Not a language
  257   AND #&0D:BEQ LF9E6           :\ code=%x1xx00x0, enter 6502 code
  258   CMP #&01:BNE LFA0E           :\ code<>%x1xx00x1, not 6502 code
  259   .LF9E6
  260   \ romtype=%0000 - A=0 - 6502 BASIC
  261   \ romtype=%0001 - A=1 - Turbo6502
  262   \ romtype=%0010 - A=0 - 6502 nonBASIC
  263   \ romtype=%0011 - A=1 - reserved
  264   PHA:LDY #&09                 :\ Save entry value &00 or &01
  265   .LF9E9
  266   LDA (&F4),Y:BEQ LF9F3        :\ Print ROM title
  267   JSR OSWRCH:INY:BNE LF9E9
  268   .LF9F3
  269   JSR OSNEWL:JSR OSNEWL        :\ Print two NLs
  270   PLA:BRA LF9FE                :\ Get entry value back
  271   .LF9FC                       :\ No (C) string, enter as raw code
  272   LDA #&00                     :\ Set flag=0
  273   .LF9FE
  274   STA &F0                      :\ Store flag at &F0
  275   \ If flag=0, membot=&F0/1, memtop=&F4/5
  276   \ If flag<>0, membot=0000, memtop=0000
  277   LDY #&00:TYA
  278   .LFA03
  279   STA &0300,Y:DEY:BNE LFA03    :\ All (zp),Y accesses to block &00
  280   LDA #&01:JMP (&00F4)         :\ Enter code with A=1
  281   
  282   .LFA0E
  283   JSR ErrorInit
  284   BRK
  285   BRK:EQUS "I cannot run this code":BRK
  286   .LFA2A
  287   JSR ErrorInit
  288   BRK
  289   BRK:EQUS "This is not a language":BRK
  290   
  291   .ErrorInit
  292   LDA #ErrorHandler AND 255:STA BRKV :\ Claim BRKV
  293   LDA #ErrorHandler DIV 256:STA &0203
  294   RTS
  295   
  296   \ *WHILEHIMEM - Display help
  297   \ ====================
  298   .CmdHELP
  299   JSR SkipSpaces:BNE LFA5C :\ Exit if parameters
  300   JSR OSNEWL:JSR HelpBanner:\ Display startup banner
  301   .LFA5C
  302   SEC:RTS                  :\ Return, SEC to pass to host
  303   
  304   .HelpBanner
  305   JSR PrText
  306   EQUS "6502 Emulator OS 0.64 (19 Oct 1988)"
  307   EQUB 10:EQUB 13
  308   NOP
  309   RTS
  310   
  311   .osBYTE               :\ OSBYTE
  312   PHA
  313   CMP #&82:BEQ BYTE82 :\ Read memory high word
  314   CMP #&83:BEQ BYTE83 :\ Read bottom of memory
  315   CMP #&84:BEQ BYTE84 :\ Read top of memory
  316   CMP #&85:BEQ BYTE85 :\ Read top of memory for screen mode
  317   CMP #&8E:BEQ BYTE8E :\ Enter language
  318   CMP #&A3:BNE BYTEnn :\ Jump if not Application OSBYTE
  319   CPX #&FE:BCC BYTEnn :\ Jump if X<&FE
  320   \ OSBYTE &A3,&FE and OSBYTE &A3,FF - return unchanged
  321   PLA
  322   RTS
  323   
  324   .BYTEnn             :\ Pass OSBYTE to host
  325   EQUB &13            :\ MOS_BYTE
  326   PLA:RTS             :\ Return
  327   
  328   .BYTE82             :\ Read memory high word
  329   LDX #&00:LDY #&00   :\ High word=&0000
  330   PLA:RTS
  331   
  332   .BYTE83             :\ Read bottom of memory
  333   PLA                 :\ Get A back
  334   LDX &F0:BEQ LFABC   :\ If &F0=0, &F0/F1=>memory bottom
  335   LDA #&01            :\ Set A=&01
  336   LDX #&00:LDY #&00   :\ Return memory bottom=&0000
  337   RTS
  338   .LFABC
  339   LDX #&00:LDY &F1    :\ Get memory bottom from &F0/F1
  340   RTS
  341   
  342   .BYTE84             :\ Read top of memory
  343   PLA                 :\ Get A back
  344   LDX &F0:BEQ LFACD   :\ If &F0=0, &F4/5=>memory top
  345   LDA #&04            :\ Set A=&04
  346   LDX #&00:LDY #&00   :\ Return memory top=&0000
  347   RTS
  348   .LFACD
  349   LDX &F4:LDY &F5     :\ Get memory top from &F4/F5
  350   RTS
  351   
  352   .BYTE85             :\ Read top of memory for screem
  353   LDX #&00:LDY #&80   :\ Return top of memory=&8000
  354   PLA:RTS             :\ Restore A and return
  355   
  356   .BYTE8E             :\ Enter language
  357   JMP CmdBASIC        :\ Jump to enter BASIC
  358   
  359   .osBGet
  360   EQUB &73            :\ Pass OSBGet to host
  361   RTS
  362   
  363   .osBPut
  364   EQUB &83            :\ Pass OSBPut to host
  365   RTS
  366   
  367   .osFILE
  368   EQUB &53            :\ Pass OSFILE to host
  369   RTS
  370   
  371   .osFIND
  372   EQUB &A3            :\ Pass OSFIND to host
  373   RTS
  374   
  375   .osGBPB
  376   EQUB &93            :\ Pass OSGBPB to host
  377   RTS
  378   
  379   .osRDCH
  380   EQUB &43            :\ Pass OSRDCH to host
  381   RTS
  382   
  383   .osWRCH
  384   EQUB &33            :\ Pass OSWRCH to host
  385   RTS
  386   
  387   .osWORD                :\ OSWORD
  388   CMP #&05:BNE LFB0C   :\ Jump if not Read I/O memory
  389   :
  390   \ OSWORD 5 - Read I/O memory
  391   \ Reads from Tube memory
  392   STX &F8:STY &F9      :\ &F8/9=>control block
  393   LDY #&00:STY &03F9   :\ Control block at (&F8),Y in block &00
  394   LDA (&F8),Y:STA &FA
  395   INY
  396   LDA (&F8),Y:STA &FB  :\ &FA/B=address to read
  397   LDX #&00:LDA (&FA,X) :\ Read from address
  398   LDY #&04:STA (&F8),Y :\ Store byte read in control block
  399   LDX &F8:LDY &F9      :\ Restore X, Y
  400   RTS
  401   
  402   .LFB0C
  403   EQUB &23             :\ Pass OSWORD to host
  404   RTS
  405   
  406   .osARGS              :\ OSARGS
  407   CMP #&01:BNE LFB3C   :\ Jump if not command line/PTR=
  408   CPY #&00:BNE LFB3C   :\ Jump if not command line
  409   :
  410   \ OSARGS 1,0 - Read address of command line
  411   STY &03F3:DEY        :\ String at (&F2),Y is in block &00
  412   .LFB1A
  413   INY:LDA (&F2),Y      :\ Get character from command line
  414   CMP #&20:BCC LFB26   :\ Control character found
  415   BNE LFB1A            :\ Loop if not space
  416   JSR SkipSpaces            :\ Skip any more spaces
  417   .LFB26
  418   CLC:TYA:ADC &F2:STA &00,X    :\ Add Y to base
  419   LDA &F3:ADC #&00:STA &01,X   :\ Set returned address
  420   LDY #&FF:STY &02,X:STY &03,X :\ Set to &FFFFxxxx
  421   INY:LDA #&01                 :\ Return Y=&00, A=&01
  422   RTS
  423   .LFB3C
  424   EQUB &63             :\ Pass OSARGS to host
  425   RTS
  426   
  427   \ Print embedded string
  428   \ =====================
  429   .PrText
  430   PLA:STA &FA:PLA:STA &FB   :\ &FA/B=>embedded string
  431   LDY #&00:STY &03FB        :\ String at (&FA),Y is in block &00
  432   INY
  433   .LFB4A
  434   LDA (&FA),Y               :\ Get character
  435   CMP #&EA:BEQ LFB56        :\ Exit if NOP
  436   JSR OSWRCH:INY:BNE LFB4A  :\ Print char and loop for next
  437   .LFB56
  438   TYA:CLC:ADC &FA
  439   TAX:LDA #&00:ADC &FB      :\ Update return address
  440   PHA:TXA:PHA               :\ Points after string
  441   .NullReturn
  442   RTS
  443   
  444   \ Print string at XY
  445   \ ------------------
  446   .PrString
  447   STX &FA:STY &FB           :\ Store XY in &FA/B
  448   LDY #&00:STY &03FB        :\ String at (&FA),Y is in block &00
  449   .LFB6C
  450   LDA (&FA),Y               :\ Get a character
  451   CMP #&20:BCC LFB78        :\ Exit at control char
  452   JSR OSWRCH:INY:BNE LFB6C  :\ Print character
  453   .LFB78
  454   RTS
  455   
  456   .Unsupported
  457   BRK
  458   BRK:EQUS "Unsupported":BRK
  459   
  460   \ Default vectors
  461   .LFB87
  462   EQUW Unsupported      :\ &200 - USERV
  463   EQUW ErrorHandler     :\ &202 - BRKV
  464   EQUW IRQ1Handler      :\ &204 - IRQ1V
  465   EQUW Unsupported      :\ &206 - IRQ2V
  466   EQUW osCLI            :\ &208 - CLIV
  467   EQUW osBYTE           :\ &20A - BYTEV
  468   EQUW osWORD           :\ &20C - WORDV
  469   EQUW osWRCH           :\ &20E - WRCHV
  470   EQUW osRDCH           :\ &210 - RDCHV
  471   EQUW osFILE           :\ &212 - FILEV
  472   EQUW osARGS           :\ &214 - ARGSV
  473   EQUW osBGet           :\ &216 - BGetV
  474   EQUW osBPut           :\ &218 - BPutV
  475   EQUW osGBPB           :\ &21A - GBPBV
  476   EQUW osFIND           :\ &21C - FINDV
  477   EQUW Unsupported      :\ &21E - FSCV
  478   EQUW NullReturn       :\ &220 - EVNTV
  479   EQUW NullReturn       :\ &222 - UPTV
  480   EQUW NullReturn       :\ &224 - NETV
  481   EQUW Unsupported      :\ &226 - VduV
  482   EQUW Unsupported      :\ &228 - KEYV
  483   EQUW Unsupported      :\ &22A - INSV
  484   EQUW Unsupported      :\ &22C - RemV
  485   EQUW Unsupported      :\ &22E - CNPV
  486   EQUW NullReturn       :\ &230 - IND1V
  487   EQUW NullReturn       :\ &232 - IND2V
  488   EQUW NullReturn       :\ &234 - IND3V
  489   
  490   .osCLI                :\ OSCLI
  491   STX &F2:STY &F3       :\ &F2/3=>command string
  492   LDY #&00:STY &03F3    :\ String at (&F2),Y is in block &00
  493   .LFBC6
  494   LDA (&F2),Y:STA LFC6A,Y  :\ Copy command line to command buffer
  495   CMP #&0D:BEQ LFBD3       :\ Loop until <cr>
  496   INY:BNE LFBC6            :\ Loop for up to 256 characters
  497   .LFBD2
  498   RTS                      :\ No <cr> found, exit
  499   .LFBD3
  500   LDX #LFC6A AND 255
  501   LDY #LFC6A DIV 256       :\ Point XY to command buffer
  502   STX &F2:STY &F3          :\ Point &F2/3 to command buffer
  503   LDX #&00:LDY #&FF
  504   .LFBDF
  505   JSR SkipSpaces1          :\ Move past and skip spaces
  506   CMP #ASC"*":BEQ LFBDF    :\ Skip past '*'s
  507   CMP #&0D:BEQ LFBD2       :\ Null string, exit
  508   CMP #ASC"|":BEQ LFBD2    :\ *|, comment, exit
  509   CLC:TYA:ADC &F2:STA &F2  :\ Adjust &F2/3 to point to start of command
  510   BCC LFBF8:INC &F3
  511   .LFBF8
  512   LDY #&00:LDA (&F2),Y     :\ Get first character
  513   CMP #ASC".":BEQ LFC45    :\ '*.', jump to pass to host
  514   .LFC00
  515   TYA:PHA                  :\ Save command pointer
  516   JSR SkipSpaces           :\ Skip any more spaces
  517   .LFC05
  518   LDA LFF02,X:BMI LFC20    :\ Jump if at end of command table
  519   EOR (&F2),Y              :\ Compare with command table
  520   AND #&DF:BNE LFC14       :\ Ignore case, jump if no match
  521   INX:INY:BRA LFC05        :\ Loop to check next character
  522   
  523   .LFC14
  524   LDA (&F2),Y:INY          :\ Get command character
  525   CMP #ASC".":BEQ LFC29    :\ Abbreviated, jump to execute
  526   .LFC1B
  527   PLA:TAY                  :\ Get command pointer back
  528   SEC:BRA LFC2B            :\ Step to next entry
  529   
  530   .LFC20
  531   ASL A:BMI LFC29
  532   LDA (&F2),Y              :\ Get next character
  533   CMP #ASC"A":BCS LFC1B    :\ Still more letters, try next entry
  534   .LFC29
  535   PLA:CLC                  :\ Drop command pointer
  536   .LFC2B
  537   DEX
  538   .LFC2C
  539   INX:LDA LFF02,X:BPL LFC2C :\ Find end of entry
  540   BCC LFC3C
  541   INX:LDA LFF02,X
  542   BNE LFC00:BEQ LFC45
  543   
  544   .LFC3C
  545   ASL A:AND #&7F            :\ Index into command table
  546   TAX:JSR LFC4B             :\ Call command routine
  547   BCC LFC4A                 :\ If CLC, exit with call claimed
  548   .LFC45
  549   LDX &F2:LDY &F3           :\ &F2/3=XY
  550   EQUB &03                  :\ Pass OSCLI to host
  551   .LFC4A
  552   RTS
  553   
  554   .LFC4B
  555   LDA LFC5E+1,X:PHA         :\ Stack address high byte
  556   LDA LFC5E+0,X:PHA         :\ Stack address low byte
  557   RTS                       :\ Jump to routine
  558   
  559   .SkipSpaces1
  560   INY
  561   .SkipSpaces
  562   LDA (&F2),Y:CMP #&20:BEQ SkipSpaces1
  563   CMP #&0D:RTS
  564   
  565   \ Command addresses
  566   \ -----------------
  567   .LFC5E
  568   EQUW CmdBASIC-1 :\ *BASIC
  569   EQUW CmdQUIT-1  :\ *CASEASN
  570   EQUW CmdHELP-1  :\ *WHILEHIMEM
  571   EQUW CmdGO-1    :\ *GO
  572   EQUW CmdOS-1    :\ *OS
  573   EQUW CmdPAGE-1  :\ *PAGE
  574   
  575   OSCLI command buffer
  576   \ --------------------
  577   .LFC6A
  578   EQUS STRING$(128,CHR$0)
  579   EQUS STRING$(128,CHR$0)
  580   
  581   .LFD6A
  582   BRK:BRK
  583   .LFD6C
  584   STZ &C0
  585   AND #&00
  586   CLC
  587   RTS
  588   
  589   \ This looks like a bit of BASIC code
  590   \ -----------------------------------
  591   .LFD72
  592   LDA &0B:STA &19
  593   LDA &0C:STA &1A
  594   LDA &0A:STA &1B
  595   .LFD7E
  596   LDY &1B:INC &1B
  597   LDA (&19),Y
  598   CMP #&20:BEQ LFD7E
  599   CMP #&3D:BEQ LFDBA
  600   .LFD8C
  601   BRK
  602   EQUB &04:EQUS "Mistake"
  603   .LFD95
  604   BRK
  605   EQUB &10:EQUS "Syntax error"
  606   .LFDA3
  607   BRK
  608   EQUB &0D:EQUS "No ":EQUB &F2
  609   .LFDA9
  610   BRK
  611   EQUB &11:EQUS "Escape"
  612   BRK
  613   
  614   .LFDB2
  615   JSR &C742
  616   CMP #&3D:BNE LFD8C
  617   RTS
  618   
  619   .LFDBA
  620   JSR &D5AF:TXA
  621   LDY &1B:BRA LFDDC
  622   LDY &1B:BRA LFDD4
  623   TSX:CPX #&FC:BCS LFDA3
  624   LDA &01FF:CMP #&F2:BNE LFDA3
  625   LDY &0A
  626   .LFDD4
  627   DEY
  628   .LFDD5
  629   INY:LDA (&0B),Y
  630   CMP #&20:BEQ LFDD5
  631   .LFDDC
  632   CMP #&3A:BEQ LFDE8
  633   CMP #&0D:BEQ LFDE8
  634   CMP #&8B:BNE LFD95
  635   .LFDE8
  636   CLC:TYA:ADC &0B:STA &0B
  637   BCC LFDF2:INC &0C
  638   .LFDF2
  639   LDY #&01:STY &0A
  640   BIT &FF:BMI LFDA9
  641   .LFDFA
  642   RTS
  643   
  644   .LFDFB
  645   JSR &D41A
  646   LDA (&0B):CMP #&3A:BEQ LFDFA
  647   LDA &0C:CMP #&07:BEQ LFE2E
  648   LDY #&01:LDA (&0B),Y:BMI LFE2E
  649   LDX &20:BEQ LFE1E
  650   STA &2B:INY:LDA (&0B),Y:STA &2A
  651   JSR &D4BF
  652   .LFE1E
  653   LDA #&03:CLC:ADC &0B:STA &0B
  654   BCC LFE29:INC &0C
  655   .LFE29
  656   LDY #&01:STY &0A
  657   .LFE2D
  658   RTS
  659   
  660   .LFE2E
  661   JMP &C7FB
  662   
  663   .LFE31
  664   JMP &C905
  665   
  666   .LFE34
  667   JSR &D5A3:BEQ LFE31
  668   BPL LFE3E:JSR &CF38
  669   .LFE3E
  670   LDY &1B:STY &0A:LDA &2A
  671   ORA &2B:ORA &2C:ORA &2D:BEQ LFE63
  672   CPX #&8C:BEQ LFE53
  673   .LFE50
  674   JMP &C880
  675   
  676   .LFE53
  677   INC &0A
  678   .LFE55
  679   JSR &D392:BCC LFE50
  680   JSR &F018:JSR &D43A
  681   JMP &EF05
  682   
  683   .LFE63
  684   LDY &0A
  685   .LFE65
  686   LDA (&0B),Y:CMP #&0D:BEQ LFE74
  687   INY:CMP #&8B:BNE LFE65
  688   STY &0A:BEQ LFE55
  689   .LFE74
  690   JMP &C82D
  691   
  692   .LFE77
  693   LDA &2A:CMP &21:LDA &2B
  694   SBC &22:BCS LFE2D
  695   LDA #&5B:JSR &F58A
  696   JSR &D898:LDA #&5D
  697   JSR &F58A:
  698   JMP &F584
  699   
  700   .LFE91
  701   JSR &F3EC:JSR &D6B7
  702   TAY:JSR &CF52
  703   JSR &F3D6:JSR &DCC4
  704   LDA &2E:EOR &3B:BPL LFEBF
  705   ASL &2E:BRA LFEE1
  706   
  707   .LFEAB
  708   STY &2D:PLA:STA &2C
  709   PLA:STA &2B
  710   PLA:STA &2A
  711   JSR &BA3A
  712   LDA &3B:EOR #&80:STA &3B
  713   .LFEBF
  714   LDA &3C:CMP &30:BNE LFEDD
  715   LDA &3D:CMP &31:BNE LFEDD
  716   LDA &3E:CMP &32:BNE LFEDD
  717   LDA &3F:CMP &33:BNE LFEDD
  718   LDA &40:SBC &34:BEQ LFEE3
  719   .LFEDD
  720   ROR A:EOR &3B:ROL A
  721   .LFEE1
  722   LDA #&FF
  723   .LFEE3
  724   RTS
  725   
  726   .LFEE4
  727   JMP &C905
  728   
  729   .LFEE7
  730   INC &1B:TXA:BEQ LFF2C
  731   BMI LFE91
  732   LDA &2A:PHA
  733   LDA &2B:PHA
  734   LDA &2C:PHA
  735   LDA &2D:PHA
  736   JSR &D6B7:TAY:BMI LFF1C
  737   TRB &FF
  738   
  739   \ Command table
  740   .LFF02
  741   EQUS "GO":EQUB &C3
  742   EQUS "HELP":EQUB &82
  743   EQUS "OS":EQUB &84
  744   EQUS "PAGE":EQUB &C5
  745   EQUS "QUIT":EQUB &81
  746   EQUS "BASIC"
  747   .LFF1C
  748   EQUB &80:EQUB &00
  749   
  750   EQUS STRING$(&FF2C-P%,CHR$0)
  751   .LFF2C
  752   
  753   EQUS STRING$(&FFB6-P%,CHR$0)
  754   .VECDEF        :EQUB &36:EQUW LFB87
  755   .LFFxx         :JMP Unsupported
  756   .LFFxx         :JMP Unsupported
  757   .LFFxx         :JMP Unsupported
  758   .LFFxx         :JMP Unsupported
  759   .LFFxx         :JMP Unsupported
  760   .NVRDCH        :JMP osRDCH
  761   .NVWRCH        :JMP osWRCH
  762   
  763   .OSFIND        :JMP (FINDV)
  764   .OSGBPB        :JMP (GBPBV)
  765   .OSBPUT        :JMP (BPutV)
  766   .OSBGET        :JMP (BGetV)
  767   .OSARGS        :JMP (ARGSV)
  768   .OSFILE        :JMP (FILEV)
  769   
  770   .OSRDCH        :JMP (RDCHV)
  771   .OSASCI        :CMP #&0D:BNE OSWRCH
  772   .OSNEWL        :LDA #&0A:JSR OSWRCH
  773   .OSPRCR        :LDA #&0D
  774   .OSWRCH        :JMP (WRCHV)
  775   .OSWORD        :JMP (WORDV)
  776   .OSBYTE        :JMP (BYTEV)
  777   .OS_CLI        :JMP (CLIV)
  778   
  779   .NMIV          :EQUW NMIHandler
  780   .RESETV        :EQUW RESET
  781   .IRQV          :EQUW InterruptHandler
  782 ]:NEXT