Created
November 1, 2018 18:58
-
-
Save cbmeeks/87bd0c73d5b438b104a6fe3bee46c1fb to your computer and use it in GitHub Desktop.
TinyBASIC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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