Skip to content

Instantly share code, notes, and snippets.

@cbmeeks
Created November 1, 2018 18:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbmeeks/87bd0c73d5b438b104a6fe3bee46c1fb to your computer and use it in GitHub Desktop.
Save cbmeeks/87bd0c73d5b438b104a6fe3bee46c1fb to your computer and use it in GitHub Desktop.
TinyBASIC
; 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment