; v0.2.2
;
; Bill O'Neill - Last update: 2011/11/11
;
; Monitor code is Open License and can be used freely
; Tiny Basic code is Copyright, Tom Pitman
;
; Consist of a minimal terminal monitor and Tom
; Pitman's Tiny Basic as a high-level
; programming language
;
; This code assembles as-is with the macro assembler in the
; Michal Kowalski simulator.
;
; It should be easy enough to configure this to run any-
; where in memory or convert it to assemble with any 6502
; assembler.
;
; Next steps:
;        More comments to document this code
;
;
; Revision History:
;
; v0.2.2 - 2011/11/11
;        Reduced version containg only a terminal monitor
;        for an 6850 ACIA ad Tom Pitman's Tiny Basic
;
; v0.2.1 - 2011/05/18
;        Ported to Michal Kowalski's macro assembler
;
; v0.2.0 - 2011/01/04
;        Corrected some label problems
;        Added/corrected some comments
;
; v0.1.3 - 2009/11/28
;        Changed the look-up table for the IL op-code
;          handlers to use labels instead of literal addresses
;          this helps make the code re-locatable.
;        Added some comments to source
;
; v0.1.2 - 2009/01/12
;        Added BREAK routine
;        Fixed my bad reference to error string " AT "
;        Compressed gaps in monitor code
;        Added some comments to source
;
; v0.1.1 - 2008/12/15
;        Initial working version
; 
;
; Notes:
;  - I changed the prompt character from a ":" ($3A) to a ">" ($3E) for no
;    other reason than I think it looks a bit better. The prompt character
;    is the second byte of the IL program table.
;
;  - This version is to run in the OMS-03,  The memory map is as follows.
;
;    $0000-$7FFF     RAM
;    $8000-$EFFF     ROM - Tiny Basic
;    $F000-$F7FF     I/O - ACIA is at $F000
;    $F800-$FFFF     ROM - Simple monitor
;
;  - Starting address in this version (referred to as "S" in the EXPERIMENTER'S
;    KIT) is $8000


;
; Tiny Basic starts here
;
         .org     $8000             ; Start of Basic.


CV       JMP      COLD_S            ; Cold start vector
WV       JMP      WARM_S            ; Warm start vector
IN_V     JMP      RCCHR             ; Input routine address. 
OUT_V    JMP      SNDCHR            ; Output routine address.
BV       JMP      BREAK             ; Begin break routine

;
; Some codes
;
BSC      .db $5f                   ; Backspace code
LSC      .db $18                   ; Line cancel code
PCC      .db $80                   ; Pad character control
TMC      .db $00                   ; Tape mode control
SSS      .db $04                   ; Spare Stack size. (was $04 but documentation suggests $20)

;
; Code fragment for 'PEEK' and 'POKE'
;
PEEK     STX $C3                   ; 'PEEK' - store X in $C3
         BCC LBL008                ; On carry clear goto LBL008
         STX $C3                   ; 'POKE' - store X in $C3
         STA ($C2),Y               ; Store A in location pointed to by $C3 (hi) and Y (lo)
         RTS                       ; Return
LBL008   LDA ($C2),Y               ; Load A with value pointed to by $C3 (hi) and Y (lo)
         LDY #$00                  ; Reset Y
         RTS                       ; Return

;
; The following table contains the addresses for the ML handlers for the IL opcodes.
;
SRVT     .dw  IL_BBR               ; ($40-$5F) Backward Branch Relative
         .dw  IL_FBR               ; ($60-$7F) Forward Branch Relative
         .dw  IL__BC               ; ($80-$9F) String Match Branch
         .dw  IL__BV               ; ($A0-$BF) Branch if not Variable
         .dw  IL__BN               ; ($C0-$DF) Branch if not a Number
         .dw  IL__BE               ; ($E0-$FF) Branch if not End of line
         .dw  IL__NO               ; ($08) No Opertion
         .dw  IL__LB               ; ($09) Push Literal Byte onto Stack
         .dw  IL__LN               ; ($0A) Push Literal Number
         .dw  IL__DS               ; ($0B) Duplicate Top two bytes on Stack
         .dw  IL__SP               ; ($0C) Stack Pop
         .dw  IL__NO               ; ($0D) (Reserved)
         .dw  IL__NO               ; ($0E) (Reserved)
         .dw  IL__NO               ; ($0F) (Reserved)
         .dw  IL__SB               ; ($10) Save Basic Pointer
         .dw  IL__RB               ; ($11) Restore Basic Pointer
         .dw  IL__FV               ; ($12) Fetch Variable
         .dw  IL__SV               ; ($13) Store Variable
         .dw  IL__GS               ; ($14) Save GOSUB line
         .dw  IL__RS               ; ($15) Restore saved line
         .dw  IL__GO               ; ($16) GOTO
         .dw  IL__NE               ; ($17) Negate
         .dw  IL__AD               ; ($18) Add
         .dw  IL__SU               ; ($19) Subtract
         .dw  IL__MP               ; ($1A) Multiply
         .dw  IL__DV               ; ($1B) Divide
         .dw  IL__CP               ; ($1C) Compare
         .dw  IL__NX               ; ($1D) Next BASIC statement
         .dw  IL__NO               ; ($1E) (Reserved)
         .dw  IL__LS               ; ($1F) List the program
         .dw  IL__PN               ; ($20) Print Number
         .dw  IL__PQ               ; ($21) Print BASIC string
         .dw  IL__PT               ; ($22) Print Tab
         .dw  IL__NL               ; ($23) New Line
         .dw  IL__PC               ; ($24) Print Literal String
         .dw  IL__NO               ; ($25) (Reserved)
         .dw  IL__NO               ; ($26) (Reserved)
         .dw  IL__GL               ; ($27) Get input Line
         .dw  ILRES1               ; ($28) (Seems to be reserved - No IL opcode calls this)
         .dw  ILRES2               ; ($29) (Seems to be reserved - No IL opcode calls this)
         .dw  IL__IL               ; ($2A) Insert BASIC Line
         .dw  IL__MT               ; ($2B) Mark the BASIC program space Empty
         .dw  IL__XQ               ; ($2C) Execute
         .dw  WARM_S               ; ($2D) Stop (Warm Start)
         .dw  IL__US               ; ($2E) Machine Language Subroutine Call
         .dw  IL__RT               ; ($2F) IL subroutine return

ERRSTR   .dd $2041, $5420          ; " AT " string used in error reporting.  Tom was right about this.
         .db $80                   ; String terminator
         
LBL002   .dw  ILTBL                ; Address of IL program table

;
; Begin Cold Start
;
; Load start of free ram ($0200) into locations $20 and $21
; and initialize the address for end of free ram ($22 & $23)
;
COLD_S   lda #$00                   ; Load accumulator with $00
         sta $20                    ; Store $00 in $20
         sta $22                    ; Store $00 in $22
         lda #$02                   ; Load accumulator with $02
         sta $21                    ; Store $02 in $21
         sta $23                    ; Store $02 in $23
;
;
; Begin test for free ram
;
         ldy #$01                   ; Load register Y with $01
MEM_T    lda ($22),Y                ; Load accumulator With the contents of a byte of memory
         tax                        ; Save it to X
         eor #$FF                   ; Next 4 instuctions test to see if this memeory location
         sta ($22),Y                ; is ram by trying to write something new to it - new value
         cmp ($22),Y                ; gets created by XORing the old value with $FF - store the
         php                        ; result of the test on the stack to look at later
         txa                        ; Retrieve the old memory value
         sta ($22),Y                ; Put it back where it came from
         inc $22                    ; Increment $22 (for next memory location)
         bne SKP_PI                 ; Skip if we don't need to increment page
         inc $23                    ; Increment $23 (for next memory page)
SKP_PI   plp                        ; Now look at the result of the memory test
         beq MEM_T                  ; Go test the next mempry location if the last one was ram
         dey                        ; If last memory location did not test as ram, decrement Y (should be $00 now)
IL__MT   cld                        ; Make sure we're not in decimal mode
         lda $20                    ; Load up the low-order by of the start of free ram
         adc SSS                    ; Add to the spare stack size
         sta $24                    ; Store the result in $0024
         tya                        ; Retrieve Y
         adc $21                    ; And add it to the high order byte of the start of free ram (this does not look right)
         sta $25                    ; Store the result in $0025
         tya                        ; Retrieve Y again
         sta ($20),Y                ; Store A in the first byte of program memory
         iny                        ; Increment Y
         sta ($20),Y                ; Store A in the second byte of program memory
;
;Begin Warm Start
;
WARM_S   lda $22
         sta $C6
         sta $26
         lda $23
         sta $C7
         sta $27
         jsr P_NWLN                 ; Go print CR, LF and pad charachters
LBL014   lda LBL002                 ; Load up the start of the IL Table 
         sta $2A                    ;
         lda LBL002+$01             ;
         sta $2B
         lda #$80
         sta $C1
         lda #$30
         sta $C0
         ldx #$00
         stx $BE
         stx $C2
         dex
         txs

;
; IL execution loop
;
LBL006   cld                        ; Make sure we're in binary mode 
         jsr LBL004                 ; Go read a byte from the IL program table
         jsr LBL005                 ; Go decide what to do with it
         jmp LBL006                 ; Repeat
;
;
;
         .db $83                   ; No idea about this
         .db $65                   ; No idea about this
;
;
; Routine to service the TBIL Instructions
;
LBL005   cmp #$30                   ;
         bcs LBL011                 ; If it's $30 or higher, it's a Branch or Jump - go handle it
         cmp #$08                   ; 
         bcc LBL007                 ; If it's less than $08 it's a stack exchange - go handle it
         asl                        ; Multiply the OP code by 2 
         tax                        ; Transfer it to X
LBL022   lda SRVT-$03,X             ; Get the hi byte of the OP Code handling routine
         pha                        ; and save it on the stack
         lda SRVT-$04,X             ; Get the lo byte
         pha                        ; and save it on the stack
         php                        ; save the processor status too
         rti                        ; now go execute the OP Code handling routine
;
;
; Routine to handle the stack exchange 
;
LBL007   adc $C1
         tax
         lda ($C1),Y
         pha
         lda $00,X
         sta ($C1),Y
         pla
         sta $00,X
         rts
;
;
;
LBL015   jsr P_NWLN                 ; Go print CR, LF and pad charachters
         lda #$21                   ; Load an ASCII DC2
         jsr OUT_V                  ; Go print it
         lda $2A                    ; Load the current TBIL pointer (lo) 
         sec                        ; Set the carry flag
         sbc LBL002                 ; Subtract the TBIL table origin (lo)
         tax                        ; Move the difference to X
         lda $2B                    ; Load the current TBIL pointer (hi)
         sbc LBL002+$01             ; Subtract the TBIL table origin (hi)
         jsr LBL010
         lda $BE
         beq LBL012
         lda #<ERRSTR               ; Get lo byte of error string address
         sta $2A                    ; Put in $2A
         lda #>ERRSTR               ; Get hi byte of error string address
         sta $2B                    ; Put in $2B
         jsr IL__PC                 ; Go report an error has been detected
         ldx $28
         lda $29
         jsr LBL010
LBL012   lda #$07                   ; ASCII Bell
         jsr OUT_V                  ; Go ring Bell
         jsr P_NWLN                 ; Go print CR, LF and pad charachters
LBL060   lda $26
         sta $C6
         lda $27
         sta $C7
         jmp LBL014
;
;
;
LBL115   ldx #$7C
LBL048   cpx $C1
LBL019   bcc LBL015
         ldx $C1
         inc $C1
         inc $C1
         clc
         rts
;
;
;
IL_BBR   dec $BD                    ; Entry point for TBIL Backward Branch Relative
IL_FBR   lda $BD                    ; Entry point for TBIL Forward Branch Relative
         beq LBL015
LBL017   lda $BC
         sta $2A
         lda $BD
         sta $2B
         rts
;
; Jump handling routine
;
LBL011   cmp #$40
         bcs LBL016                 ; If it's not a Jump, go to branch handler
         pha
         jsr LBL004                 ; Go read a byte from the TBIL table
         adc LBL002
         sta $BC
         pla
         pha
         and #$07
         adc LBL002+$01
         sta $BD
         pla
         and #$08
         bne LBL017
         lda $BC
         ldx $2A
         sta $2A
         stx $BC
         lda $BD
         ldx $2B
         sta $2B
         stx $BD
LBL126   lda $C6
         sbc #$01
         sta $C6
         bcs LBL018
         dec $C7
LBL018   cmp $24
         lda $C7
         sbc $25
         bcc LBL019
         lda $BC
         sta ($C6),Y
         iny
         lda $BD
         sta ($C6),Y
         rts
;
;
; Branch Handler
;
LBL016   pha
         lsr
         lsr
         lsr
         lsr
         and #$0E
         tax
         pla
         cmp #$60
         and #$1F
         bcs LBL020
         ora #$E0
LBL020   clc
         beq LBL021
         adc $2A
         sta $BC
         tya
         adc $2B
LBL021   sta $BD
         jmp LBL022
;
;
;
IL__BC   lda $2C                    ; Entry point for TBIL BC (String Match Branch)
         sta $B8
         lda $2D
         sta $B9
LBL025   jsr LBL023
         jsr LBL024
         eor ($2A),Y
         tax
         jsr LBL004                 ; Go read a byte from the TBIL table
         txa
         beq LBL025
         asl
         beq LBL026
         lda $B8
         sta $2C
         lda $B9
         sta $2D
LBL028   jmp IL_FBR
IL__BE   jsr LBL023                 ; Entry point for TBIL BE (Branch if not End of line)
         cmp #$0D
         bne LBL028
LBL026   rts
;
;
;
IL__BV   jsr LBL023                 ; Entry point for TBIL BV (Branch if not Variable)
         cmp #$5B
         bcs LBL028
         cmp #$41
         bcc LBL028
         asl
         jsr LBL029
LBL024   ldy #$00
         lda ($2C),Y
         inc $2C
         bne LBL030
         inc $2D
LBL030   cmp #$0D
         clc
         rts
;
;
;
LBL031   jsr LBL024
LBL023   lda ($2C),Y
         cmp #$20
         beq LBL031
         cmp #$3A
         clc
         bpl LBL032
         cmp #$30
LBL032   rts
;
;
;
IL__BN   jsr LBL023                 ; Entry point for TBIL BN (Branch if not a Number)
         bcc LBL028
         sty $BC
         sty $BD
LBL033   lda $BC
         ldx $BD
         asl $BC
         rol $BD
         asl $BC
         rol $BD
         clc
         adc $BC
         sta $BC
         txa
         adc $BD
         asl $BC
         rol
         sta $BD
         jsr LBL024
         and #$0F
         adc $BC
         sta $BC
         tya
         adc $BD
         sta $BD
         jsr LBL023
         bcs LBL033
         jmp LBL034
LBL061   jsr IL__SP
         lda $BC
         ora $BD
         beq LBL036
LBL065   lda $20
         sta $2C
         lda $21
         sta $2D
LBL040   jsr LBL037
         beq LBL038
         lda $28
         cmp $BC
         lda $29
         sbc $BD
         bcs LBL038
LBL039   jsr LBL024
         bne LBL039
         jmp LBL040
LBL038   lda $28
         eor $BC
         bne LBL041
         lda $29
         eor $BD
LBL041   rts
;
;
;
LBL043   jsr LBL042
IL__PC   jsr LBL004                 ; Entry point for TBIL PC (print literal) - Go read a byte from the TBIL table
         bpl LBL043
LBL042   inc $BF
         bmi LBL044
         jmp OUT_V                  ; Go print it
LBL044   dec $BF
LBL045   rts
;
;
;
LBL046   cmp #$22
         beq LBL045
         jsr LBL042
IL__PQ   jsr LBL024                 ; Entry point for TBIL PQ
         bne LBL046
LBL036   jmp LBL015
IL__PT   lda #$20                   ; Entry point for TBIL PT
         jsr LBL042
         lda $BF
         and #$87
         bmi LBL045
         bne IL__PT
         rts
;
;
;
IL__CP   ldx #$7B
         jsr LBL048
         inc $C1
         inc $C1
         inc $C1
         sec
         lda $03,X
         sbc $00,X
         sta $00,X
         lda $04,X
         sbc $01,X
         bvc LBL052
         eor #$80
         ora #$01
LBL052   bmi LBL053
         bne LBL054
         ora $00,X
         beq LBL049
LBL054   lsr $02,X
LBL049   lsr $02,X
LBL053   lsr $02,X
         bcc LBL050
LBL004   ldy #$00                   ; Read a byte from the TBIL Table
         lda ($2A),Y               ;
         inc $2A                    ; Increment TBIL Table pointer as required
         bne LBL051                 ;
         inc $2B                    ;
LBL051   ora #$00                   ; Check for $00 and set the 'Z' flag acordingly
LBL050   rts                        ; Return
;
;
;
IL__NX   lda $BE                    ; Entry point for TBIL NX
         beq LBL055
LBL056   jsr LBL024
         bne LBL056
         jsr LBL037
         beq LBL057
LBL062   jsr LBL058
         jsr BV                     ; Test for break
         bcs LBL059
         lda $C4
         sta $2A
         lda $C5
         sta $2B
         rts
;
;
;
LBL059   lda LBL002
         sta $2A
         lda LBL002+$01
         sta $2B
LBL057   jmp LBL015
LBL055   sta $BF
         jmp LBL060
IL__XQ   lda $20                    ; Entry point fro TBIL XQ
         sta $2C
         lda $21
         sta $2D
         jsr LBL037
         beq LBL057
         lda $2A
         sta $C4
         lda $2B
         sta $C5
LBL058   lda #$01
         sta $BE
         rts
;
;
;
IL__GO   jsr LBL061                 ; Entry point for TBIL GO
         beq LBL062
LBL066   lda $BC
         sta $28
         lda $BD
         sta $29
         jmp LBL015
IL__RS   jsr LBL063                 ; Entry point for TBIL RS
         jsr LBL064
         jsr LBL065
         bne LBL066
         rts
;
;
;
LBL037   jsr LBL024
         sta $28
         jsr LBL024
         sta $29
         ora $28
         rts
;
;
;
IL__DS   jsr IL__SP                 ; Entry point for TBIL DS
         jsr LBL034
LBL034   lda $BD
LBL131   jsr LBL029
         lda $BC
LBL029   ldx $C1
         dex
         sta $00,X
         stx $C1
         cpx $C0
         bne IL__NO
LBL068   jmp LBL015
LBL097   ldx $C1
         cpx #$80
         bpl LBL068
         lda $00,X
         inc $C1
IL__NO   rts                        ; Entry point for the TBIL NO
;
;
;
LBL010   sta $BD
         stx $BC
         jmp LBL069
IL__PN   ldx $C1                    ; Entry point for the TBIL PN
         lda $01,X
         bpl LBL070
         jsr IL__NE
         lda #$2D
         jsr LBL042
LBL070   jsr IL__SP
LBL069   lda #$1F
         sta $B8
         sta $BA
         lda #$2A
         sta $B9
         sta $BB
         ldx $BC
         ldy $BD
         sec
LBL072   inc $B8
         txa
         sbc #$10
         tax
         tya
         sbc #$27
         tay
         bcs LBL072
LBL073   dec $B9
         txa
         adc #$E8
         tax
         tya
         adc #$03
         tay
         bcc LBL073
         txa
LBL074   sec
         inc $BA
         sbc #$64
         bcs LBL074
         dey
         bpl LBL074
LBL075   dec $BB
         adc #$0A
         bcc LBL075
         ora #$30
         sta $BC
         lda #$20
         sta $BD
         ldx #$FB
LBL199   stx $C3
         lda $BD,X
         ora $BD
         cmp #$20
         beq LBL076
         ldy #$30
         sty $BD
         ora $BD
         jsr LBL042
LBL076   ldx $C3
         inx
         bne LBL199
         rts
;
;
;
IL__LS   lda $2D                    ; Entry point for TBIL LS
         pha
         lda $2C
         pha
         lda $20
         sta $2C
         lda $21
         sta $2D
         lda $24
         ldx $25
         jsr LBL077
         beq LBL078
         jsr LBL077
LBL078   lda $2C
         sec
         sbc $B6
         lda $2D
         sbc $B7
         bcs LBL079
         jsr LBL037
         beq LBL079
         ldx $28
         lda $29
         jsr LBL010
         lda #$20
LBL080   jsr LBL042
         jsr BV                     ; Test for break
         bcs LBL079
         jsr LBL024
         bne LBL080
         jsr IL__NL
         jmp LBL078
LBL077   sta $B6
         inc $B6
         bne LBL082
         inx
LBL082   stx $B7
         ldy $C1
         cpy #$80
         beq LBL083
         jsr LBL061
LBL099   lda $2C
         ldx $2D
         sec
         sbc #$02
         bcs LBL084
         dex
LBL084   sta $2C
         jmp LBL085
LBL079   pla
         sta $2C
         pla
         sta $2D
LBL083   rts
IL__NL   lda $BF                    ; Entry point for TBIL NL
         bmi LBL083
;
;
; Routine to print a new line.  It handles CR, LF
; and adds pad characters to the ouput
;
P_NWLN   lda #$0D                   ; Load up a CR
         jsr OUT_V                  ; Go print it
         lda PCC                    ; Load the pad character code
         and #$7F                   ; Test to see - 
         sta $BF                    ; how many pad charachters to print
         beq LBL086                 ; Skip if 0
LBL088   jsr LBL087                 ; Go print pad character
         dec $BF                    ; One less
         bne LBL088                 ; Loop until 0
LBL086   lda #$0A                   ; Load up a LF
         jmp LBL089                 ; Go print it
;
;
;
LBL092   ldy TMC
LBL091   sty $BF
         bcs LBL090
IL__GL   lda #$30                   ; Entry pont for TBIL GL
         sta $2C
         sta $C0
         sty $2D
         jsr LBL034
LBL090   eor $80
         sta $80
         jsr IN_V
         ldy #$00
         ldx $C0
         and #$7F
         beq LBL090
         cmp #$7F
         beq LBL090
         cmp #$13
         beq LBL091
         cmp #$0A
         beq LBL092
         cmp LSC
         beq LBL093
         cmp BSC
         bne LBL094
         cpx #$30
         bne LBL095
LBL093   ldx $2C
         sty $BF
         lda #$0D
LBL094   cpx $C1
         bmi LBL096
         lda #$07
         jsr LBL042
         jmp LBL090
LBL096   sta $00,X
         inx
         inx
LBL095   dex
         stx $C0
         cmp #$0D
         bne LBL090
         jsr IL__NL
IL__SP   jsr LBL097                 ; Entry point for TBIL SP
         sta $BC
         jsr LBL097
         sta $BD
         rts
;
;
;
IL__IL   jsr LBL098                 ; Entry point for TBIL IL
         jsr LBL061
         php
         jsr LBL099
         sta $B8
         stx $B9
         lda $BC
         sta $B6
         lda $BD
         sta $B7
         ldx #$00
         plp
         bne LBL100
         jsr LBL037
         dex
         dex
LBL101   dex
         jsr LBL024
         bne LBL101
LBL100   sty $28
         sty $29
         jsr LBL098
         lda #$0D
         cmp ($2C),Y
         beq LBL102
         inx
         inx
         inx
LBL103   inx
         iny
         cmp ($2C),Y
         bne LBL103
         lda $B6
         sta $28
         lda $B7
         sta $29
LBL102   lda $B8
         sta $BC
         lda $B9
         sta $BD
         clc
         ldy #$00
         txa
         beq LBL104
         bpl LBL105
         adc $2E
         sta $B8
         lda $2F
         sbc #$00
         sta $B9
LBL109   lda ($2E),Y
         sta ($B8),Y
         ldx $2E
         cpx $24
         bne LBL106
         lda $2F
         cmp $25
         beq LBL107
LBL106   inx
         stx $2E
         bne LBL108
         inc $2F
LBL108   inc $B8
         bne LBL109
         inc $B9
         bne LBL109
LBL105   adc $24
         sta $B8
         sta $2E
         tya
         adc $25
         sta $B9
         sta $2F
         lda $2E
         sbc $C6
         lda $2F
         sbc $C7
         bcc LBL110
         dec $2A
         jmp LBL015
LBL110   lda ($24),Y
         sta ($2E),Y
         ldx $24
         bne LBL111
         dec $25
LBL111   dec $24
         ldx $2E
         bne LBL112
         dec $2F
LBL112   dex
         stx $2E
         cpx $BC
         bne LBL110
         ldx $2F
         cpx $BD
         bne LBL110
LBL107   lda $B8
         sta $24
         lda $B9
         sta $25
LBL104   lda $28
         ora $29
         beq LBL113
         lda $28
         sta ($BC),Y
         iny
         lda $29
         sta ($BC),Y
LBL114   iny
         sty $B6
         jsr LBL024
         php
         ldy $B6
         sta ($BC),Y
         plp
         bne LBL114
LBL113   jmp LBL014
IL__DV   jsr LBL115
         lda $03,X
         and #$80
         beq LBL116
         lda #$FF
LBL116   sta $BC
         sta $BD
         pha
         adc $02,X
         sta $02,X
         pla
         pha
         adc $03,X
         sta $03,X
         pla
         eor $01,X
         sta $BB
         bpl LBL117
         jsr LBL118
LBL117   ldy #$11
         lda $00,X
         ora $01,X
         bne LBL119
         jmp LBL015
LBL119   sec
         lda $BC
         sbc $00,X
         pha
         lda $BD
         sbc $01,X
         pha
         eor $BD
         bmi LBL120
         pla
         sta $BD
         pla
         sta $BC
         sec
         jmp LBL121
LBL120   pla
         pla
         clc
LBL121   rol $02,X
         rol $03,X
         rol $BC
         rol $BD
         dey
         bne LBL119
         lda $BB
         bpl LBL122
IL__NE   ldx $C1                    ; Entry point for TBIL NE
LBL118   sec
         tya
         sbc $00,X
         sta $00,X
         tya
         sbc $01,X
         sta $01,X
LBL122   rts
;
;
;
IL__SU   jsr IL__NE                 ; Entry point for TBIL SU
IL__AD   jsr LBL115                 ; Entry point for TBIL AD
         lda $00,X
         adc $02,X
         sta $02,X
         lda $01,X
         adc $03,X
         sta $03,X
         rts
;
;
;
IL__MP   jsr LBL115                 ; Entry point for TBIL MP
         ldy #$10
         lda $02,X
         sta $BC
         lda $03,X
         sta $BD
LBL124   asl $02,X
         rol $03,X
         rol $BC
         rol $BD
         bcc LBL123
         clc
         lda $02,X
         adc $00,X
         sta $02,X
         lda $03,X
         adc $01,X
         sta $03,X
LBL123   dey
         bne LBL124
         rts
;
;
;
IL__FV   jsr LBL097                 ; Entry point for TBIL FV
         tax
         lda $00,X
         ldy $01,X
         dec $C1
         ldx $C1
         sty $00,X
         jmp LBL029
IL__SV   ldx #$7D                   ; Entry point for TBIL SV
         jsr LBL048
         lda $01,X
         pha
         lda $00,X
         pha
         jsr LBL097
         tax
         pla
         sta $00,X
         pla
         sta $01,X
         rts
IL__RT   jsr LBL063
         lda $BC
         sta $2A
         lda $BD
         sta $2B
         rts
;
;
;
IL__SB   ldx #$2C                   ; Entry point for TBIL SB 
         bne LBL125
IL__RB   ldx #$2E                   ; Entry point for TBIL RB
LBL125   lda $00,X
         cmp #$80
         bcs LBL098
         lda $01,X
         bne LBL098
         lda $2C
         sta $2E
         lda $2D
         sta $2F
         rts
;
;
;
LBL098   lda $2C
         ldy $2E
         sty $2C
         sta $2E
         lda $2D
         ldy $2F
         sty $2D
         sta $2F
         ldy #$00
         rts
;
;
;
IL__GS   lda $28                    ; Entry point for TBIL GS
         sta $BC
         lda $29
         sta $BD
         jsr LBL126
         lda $C6
         sta $26
         lda $C7
LBL064   sta $27
LBL129   rts
;
;
;
LBL063   lda ($C6),Y
         sta $BC
         jsr LBL127
         lda ($C6),Y
         sta $BD
LBL127   inc $C6
         bne LBL128
         inc $C7
LBL128   lda $22
         cmp $C6
         lda $23
         sbc $C7
         bcs LBL129
         jmp LBL015
IL__US   jsr LBL130
         sta $BC
         tya
         jmp LBL131
LBL130   jsr IL__SP
         lda $BC
         sta $B6
         jsr IL__SP
         lda $BD
         sta $B7
         ldy $BC
         jsr IL__SP
         ldx $B7
         lda $B6
         clc
         jmp ($00BC)
IL__LN   jsr IL__LB                 ; Entry point for TBIL LN
IL__LB   jsr LBL004                 ; Entry point for TBIL LB - Go read a byte from the IL table
         jmp LBL029
LBL085   stx $2D
         cpx #$00
         rts
;
;
;
ILRES2   ldy #$02                   ; These two entry points are for code that
ILRES1   sty $BC                    ;  does not seem to get called.  Need more research.
         ldy #$29
         sty $BD
         ldy #$00
         lda ($BC),Y
         cmp #$08
         bne LBL133
         jmp LBL117
LBL133   rts
;
;
; Subroutine to decide which pad characters to print
;
LBL089   jsr OUT_V                  ; Entry point with a character to print first
LBL087   lda #$FF                   ; Normal entry point - Set pad to $FF
         bit PCC                    ; Check if the pad flag is on
         bmi LBL134                 ; Skip it if not
         lda #$00                   ; set pad to $00
LBL134   jmp OUT_V                  ; Go print it


;
; TBIL program table
;
ILTBL    .db $24, $3E, $91, $27, $10, $E1, $59, $C5, $2A, $56, $10, $11, $2C, $8B, $4C
         .db $45, $D4, $A0, $80, $BD, $30, $BC, $E0, $13, $1D, $94, $47, $CF, $88, $54
         .db $CF, $30, $BC, $E0, $10, $11, $16, $80, $53, $55, $C2, $30, $BC, $E0, $14
         .db $16, $90, $50, $D2, $83, $49, $4E, $D4, $E5, $71, $88, $BB, $E1, $1D, $8F
         .db $A2, $21, $58, $6F, $83, $AC, $22, $55, $83, $BA, $24, $93, $E0, $23, $1D
         .db $30, $BC, $20, $48, $91, $49, $C6, $30, $BC, $31, $34, $30, $BC, $84, $54
         .db $48, $45, $CE, $1C, $1D, $38, $0D, $9A, $49, $4E, $50, $55, $D4, $A0, $10
         .db $E7, $24, $3F, $20, $91, $27, $E1, $59, $81, $AC, $30, $BC, $13, $11, $82
         .db $AC, $4D, $E0, $1D, $89, $52, $45, $54, $55, $52, $CE, $E0, $15, $1D, $85
         .db $45, $4E, $C4, $E0, $2D, $98, $4C, $49, $53, $D4, $EC, $24, $00, $00, $00
         .db $00, $0A, $80, $1F, $24, $93, $23, $1D, $30, $BC, $E1, $50, $80, $AC, $59
         .db $85, $52, $55, $CE, $38, $0A, $86, $43, $4C, $45, $41, $D2, $2B, $84, $52
         .db $45, $CD, $1D, $A0, $80, $BD, $38, $14, $85, $AD, $30, $D3, $17, $64, $81
         .db $AB, $30, $D3, $85, $AB, $30, $D3, $18, $5A, $85, $AD, $30, $D3, $19, $54
         .db $2F, $30, $E2, $85, $AA, $30, $E2, $1A, $5A, $85, $AF, $30, $E2, $1B, $54
         .db $2F, $98, $52, $4E, $C4, $0A, $80, $80, $12, $0A, $09, $29, $1A, $0A, $1A
         .db $85, $18, $13, $09, $80, $12, $01, $0B, $31, $30, $61, $72, $0B, $04, $02
         .db $03, $05, $03, $1B, $1A, $19, $0B, $09, $06, $0A, $00, $00, $1C, $17, $2F
         .db $8F, $55, $53, $D2, $80, $A8, $30, $BC, $31, $2A, $31, $2A, $80, $A9, $2E
         .db $2F, $A2, $12, $2F, $C1, $2F, $80, $A8, $30, $BC, $80, $A9, $2F, $83, $AC
         .db $38, $BC, $0B, $2F, $80, $A8, $52, $2F, $84, $BD, $09, $02, $2F, $8E, $BC
         .db $84, $BD, $09, $93, $2F, $84, $BE, $09, $05, $2F, $09, $91, $2F, $80, $BE
         .db $84, $BD, $09, $06, $2F, $84, $BC, $09, $95, $2F, $09, $04, $2F, $00, $00
         .db $00
;
; End of Tiny Basic



; Start of the OMS-03 Monitor - under contruction.....
;
; Set some symbols
;
ACIAregs = $F000                    ; Base address of 6850
ACIAdata = ACIAregs+$01             ; 6850 registers 


         .ORG  $F800

;
; Begin base system initialization
;
FBLK     LDA #$03                   ; Reset the ACIA
         STA ACIAregs               ; Do the reset
         LDA #$11                   ; 8 bits, 2 stop, divide by 16
         STA ACIAregs               ; Do the configuration
         jsr CLRSC                  ; Go clear the screen
         ldx #$00                   ; Offset for welcome message and prompt
         jsr SNDMSG                 ; Go print it
ST_LP    jsr RCCHR                  ; Go get a character from the console
         cmp #$43                   ; Check for 'C'
         bne IS_WRM                 ; If not branch to next check
         jmp COLD_S                 ; Otherwise cold-start Tiny Basic
IS_WRM   cmp #$57                   ; Check for 'W'
         bne PRMPT                  ; If not, branch to re-prompt them
         jmp WARM_S                 ; Otherwise warm-start Tiny Basic
PRMPT    LDX #$51                   ; Offset of prompt in message block
         jsr SNDMSG                 ; Go print the prompt	 
         jmp ST_LP                  ; Go get the response

;
; The message block. It terminates with an FF.
;
MBLK
         .db  "Open License Monitor, by Bill O'Neill V0.2.2"
         .db  $0D, $0A, $0A
         .db  "TINY BASIC - Copyright, Tom Pitman"
         .db  $0D, $0A, $0A
         .db  "Boot (C/W)? "
         .db  $07, $FF

;
; Begin BIOS subroutines
;

;
; Clear the screen
;
CLRSC    ldx #$19                   ; Load X - we're going tp print 25 lines
         lda #$0D                   ; CR
         jsr SNDCHR                 ; Send a carriage return
         lda #$0A                   ; LF
CSLP     jsr SNDCHR                 ; Send the line feed
         dex                        ; One less to do
         bne CSLP                   ; Go send another untill we're done
         rts                        ; Return

;
; Print a message.
; This sub expects the message offset from MBLK in X.
;
SNDMSG   lda MBLK,X                 ; Get a character from the message block
         cmp #$FF                   ; Look for end of message marker
         beq EXSM                   ; Finish up if it is
         jsr SNDCHR                 ; Otherwise send the character
         inx                        ; Increment the pointer
         jmp SNDMSG                 ; Go get next character
EXSM     rts                        ; Return

;
; Get a character from the ACIA
; Runs into SNDCHR to provide echo
;
RCCHR    lda ACIAregs               ; GET STATUS FROM ACIA
         lsr                        ; CHECK FOR A CHARACTER
         bcc RCCHR                  ; Loop until we get one
         LDA ACIAdata               ; GET CHARACTER

;
;Send a character to the ACIA
;
SNDCHR   sta $FE                    ; Save the character to be printed
         cmp #$FF                   ; Check for a bunch of characters
         BEQ EXSC                   ; that we don't want to print to
         cmp #$00                   ; the terminal and discard them to
         beq EXSC                   ; clean up the output
         cmp #$91                   ;
         beq EXSC                   ;
         cmp #$93                   ;
         beq EXSC                   ;
         cmp #$80                   ;
         beq EXSC                   ;
GETSTS   lda ACIAregs               ; GET ACIA STATUS
         lsr                        ; CHECK TO SEE IF TRANSMITER IS BUSY 
         lsr                        ;
         bcc GETSTS                 ; IF STILL BUSY GO GET STATUS AGAIN
         lda $FE                    ; Restore the character
         STA ACIAdata               ; SEND CHARACTER
EXSC     rts                        ; Return

;
; Break routine
; Any keystroke will produce a break condition (carry set)
;
BREAK    sta $FE                    ; Save A
         clc                        ; Clear carry 
         lda ACIAregs               ; Read the ACAI status to
         lsr                        ; Check if there is character in the receiver
         BCC NO_CHR                 ; Finnish up if no character typed
         sec                        ; Set carry (break detected)
         lda ACIAdata               ; Get the character to reset ACIA status
NO_CHR   lda $FE                    ; Restore the saved A value
         rts                        ; Return

;
; Setup reset vector         
;
         .ORG $FFFC                 ; Address of reset vector

         .DW  FBLK                  ; Reset vector