; OMS-02 Firmware ; ; Bill O'Neill - Last update: 2008/12/06 ; ; Tiny Basic and minimal Monitor (BIOS) ; ; This version is for the assembler that comes with ; Michal Kowalski's 6502 emulator. To run it, load it ; into the emulator, assemle it, begin debug mode then, ; set the PC to $1CF0 then run. ; ; The emulator was used to help figure out Tiny Basic ; and this code is only documented to that extent. ; ; It should be easy enough to configure this to run any- ; where in memory or convert it to assemble with any 6502 ; assembler. The current location is being used as this is ; to be placed into a controller I designed (OMS-02) around ; a 6507 CPU (a 6502 variant) that has only 8k off memory. ; The memory map for the OMS-02 is; ; ; $0000-$0FFF RAM ; $1000-$13FF I/O space (ACIA is at $1200) ; $1400-$1FFF Tiny Basic and simple monitor ; ; ; Next steps: ; Write a BREAK routine that will enable a break if any charater is typed at the console ; More comments to document this code ; Investigate using assembler variables and directives to make it easy to re-locate this code ; ; .org $1000 ; Address of first byte of EPROM in the system SOROM ; ; Tiny Basic starts here ; .org $1400 ; Start of Basic. First 1K of ROM is shaded by I/O on the OMS-02 SOBAS C_00BC = $00BC ; These are needed because my assembler C_20 = $20 ; does not hanle standard 6502 notation C_22 = $22 ; properly C_24 = $24 ; C_2A = $2A ; I may just fix this someday - HA! C_2C = $2C ; C_2E = $2E ; C_B8 = $B8 ; C_BC = $BC ; C_C1 = $C1 ; C_C2 = $C2 ; C_C6 = $C6 ; SR_V_L = SOBAS + $1E ; Base address for subroutine vector lo byte SR_V_H = SOBAS + $1F ; Base address for subroutine vector hi byte 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. BREAK nop ; Begin dummy break routine clc ; Clear the carry flag rts ; End 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 ; Seems to store or retreive a byte to/from memory and the accumulator ; Don't know what calls it stx $C3 bcc LBL008 stx $C3 sta (C_C2),Y rts LBL008 lda (C_C2),Y ldy #$00 rts .dd $6215, $6415, $D815, $0516, $3316, $FD15 ; These seem to be addresses associated with the IL branch instructions .dd $9F17, $421B, $3F1B, $7A17, $FC18, $9517, $9F17, $9F17 ; This appears to be a table of .dd $BD1A, $C11A, $8A1A, $9B1A, $E91A, $6117, $5117, $411A ; execution addresses to jump to ML routines .dd $521A, $4F1A, $621A, $E719, $CD16, $0617, $9F17, $1518 ; that handle the the IL instructions. .dd $A717, $B716, $BF16, $8318, $A116, $9F17, $9F17, $A818 ; You cannot add code to or relocate this program .dd $4F1B, $4D1B, $0719, $AA14, $3717, $BD14, $1B1B, $B11A ; without updating these .dd $2041, $5420 ; No idea ???? .db $80 ; No idea LBL002 .db $70 ; $70 - lo byte of IL address LBL003 .db $1B ; $1B - hi byte of IL address ; I should figure out a way to ; calculate these at assembly to ; help make this re-locatable. ; ;Begin Cold Start ; ; ; ;Load start of free ram ($0200) into locations $0020 and $0022 ; 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 (C_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 (C_22),Y ; is ram by trying to write something new to it - new value cmp (C_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 (C_22),Y ; Put it back where it came from inc $22 ; Increment $22 (for next memory location) bne SKP_PI ; Goto $14A6 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) 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 (C_20),Y ; Store A in the first byte of program memory iny ; Increment Y sta (C_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 LBL001 ; Go print CR, LF and pad charachters LBL014 lda LBL002 sta $2A lda LBL003 sta $2B lda #$80 sta $C1 lda #$30 sta $C0 ldx #$00 stx $BE stx $C2 dex txs LBL006 cld jsr LBL004 ; Go read a byte from the TBIL table jsr LBL005 jmp LBL006 ; ; ; .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 SR_V_H,X ; Get the hi byte of the OP Code handling routine pha ; and save it on the stack lda SR_V_L,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 (C_C1),Y pha lda $00,X sta (C_C1),Y pla sta $00,X rts ; ; ; LBL015 jsr LBL001 ; 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 LBL003 ; Subtract the TBIL table origin (hi) jsr LBL010 lda $BE beq LBL012 lda #$7E sta $2A lda #$20 sta $2B jsr LBL013 ldx $28 lda $29 jsr LBL010 LBL012 lda #$07 ; ASCII Bell jsr OUT_V ; Go ring Bell jsr LBL001 ; 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 ; ; ; dec $BD LBL027 lda $BD beq LBL015 LBL017 lda $BC sta $2A lda $BD sta $2B rts ; ; Branch 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 LBL003 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 (C_C6),Y iny lda $BD sta (C_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 ; ; ; lda $2C sta $B8 lda $2D sta $B9 LBL025 jsr LBL023 jsr LBL024 eor (C_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 LBL027 jsr LBL023 cmp #$0D bne LBL028 LBL026 rts ; ; ; jsr LBL023 cmp #$5B bcs LBL028 cmp #$41 bcc LBL028 asl jsr LBL029 LBL024 ldy #$00 lda (C_2C),Y inc $2C bne LBL030 inc $2D LBL030 cmp #$0D clc rts ; ; ; LBL031 jsr LBL024 LBL023 lda (C_2C),Y cmp #$20 beq LBL031 cmp #$3A clc bpl LBL032 cmp #$30 LBL032 rts ; ; ; jsr LBL023 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 LBL035 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 LBL013 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 jsr LBL024 bne LBL046 LBL036 jmp LBL015 LBL047 lda #$20 jsr LBL042 lda $BF and #$87 bmi LBL045 bne LBL047 rts ; ; ; 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 (C_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 ; ; ; lda $BE beq LBL055 LBL056 jsr LBL024 bne LBL056 jsr LBL037 beq LBL057 LBL062 jsr LBL058 jsr BREAK bcs LBL059 lda $C4 sta $2A lda $C5 sta $2B rts ; ; ; LBL059 lda LBL002 sta $2A lda LBL003 sta $2B LBL057 jmp LBL015 LBL055 sta $BF jmp LBL060 lda $20 sta $2C lda $21 sta $2D jsr LBL037 beq LBL057 lda $2A sta $C4 lda $2B sta $C5 LBL058 lda #$01 sta $BE rts ; ; ; jsr LBL061 beq LBL062 LBL066 lda $BC sta $28 lda $BD sta $29 jmp LBL015 jsr LBL063 jsr LBL064 jsr LBL065 bne LBL066 rts ; ; ; LBL037 jsr LBL024 sta $28 jsr LBL024 sta $29 ora $28 rts ; ; ; jsr LBL035 jsr LBL034 LBL034 lda $BD LBL131 jsr LBL029 lda $BC LBL029 ldx $C1 dex sta $00,X stx $C1 cpx $C0 bne LBL067 LBL068 jmp LBL015 LBL097 ldx $C1 cpx #$80 bpl LBL068 lda $00,X inc $C1 LBL067 rts ; ; ; LBL010 sta $BD stx $BC jmp LBL069 ldx $C1 lda $01,X bpl LBL070 jsr LBL071 lda #$2D jsr LBL042 LBL070 jsr LBL035 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 ; ; ; lda $2D 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 BREAK bcs LBL079 jsr LBL024 bne LBL080 jsr LBL081 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 LBL081 lda $BF bmi LBL083 ; ; ; Routine to handle CR, LF and pad characters in the ouput ; LBL001 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 charcter 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 lda #$30 ; Entry pont for TBIL GL (get input line) 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 LBL081 LBL035 jsr LBL097 sta $BC jsr LBL097 sta $BD rts ; ; ; jsr LBL098 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 (C_2C),Y beq LBL102 inx inx inx LBL103 inx iny cmp (C_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 (C_2E),Y sta (C_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 (C_24),Y sta (C_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 (C_BC),Y iny lda $29 sta (C_BC),Y LBL114 iny sty $B6 jsr LBL024 php ldy $B6 sta (C_BC),Y plp bne LBL114 LBL113 jmp LBL014 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 LBL071 ldx $C1 LBL118 sec tya sbc $00,X sta $00,X tya sbc $01,X sta $01,X LBL122 rts ; ; ; jsr LBL071 jsr LBL115 lda $00,X adc $02,X sta $02,X lda $01,X adc $03,X sta $03,X rts ; ; ; jsr LBL115 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 ; ; ; jsr LBL097 tax lda $00,X ldy $01,X dec $C1 ldx $C1 sty $00,X jmp LBL029 ldx #$7D jsr LBL048 lda $01,X pha lda $00,X pha jsr LBL097 tax pla sta $00,X pla sta $01,X rts jsr LBL063 lda $BC sta $2A lda $BD sta $2B rts ; ; ; ldx #$2C ; Entry point to Save Basic Pointer SB bne LBL125 ldx #$2E 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 ; ; ; lda $28 sta $BC lda $29 sta $BD jsr LBL126 lda $C6 sta $26 lda $C7 LBL064 sta $27 LBL129 rts ; ; ; LBL063 lda (C_C6),Y sta $BC jsr LBL127 lda (C_C6),Y sta $BD LBL127 inc $C6 bne LBL128 inc $C7 LBL128 lda $22 cmp $C6 lda $23 sbc $C7 bcs LBL129 jmp LBL015 jsr LBL130 sta $BC tya jmp LBL131 LBL130 jsr LBL035 lda $BC sta $B6 jsr LBL035 lda $BD sta $B7 ldy $BC jsr LBL035 ldx $B7 lda $B6 clc jmp (C_00BC) jsr LBL132 LBL132 jsr LBL004 ; Go read a byte from the TBIL Table jmp LBL029 LBL085 stx $2D cpx #$00 rts ; ; ; ldy #$02 sty $BC ldy #$29 sty $BD ldy #$00 lda (C_BC),Y cmp #$08 bne LBL133 jmp LBL117 LBL133 rts ; ; ; Subroutine to decide which pad character to print ; LBL089 jsr OUT_V ; Entry point with a charater 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 Tables ; ILTBL .DB $24, $3A, $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 .org $1CF0 ; Address of main program FBLK ; ; Set some symbols ; ACIARW = $1200 ; Base address of ACIA ACIAST = ACIARW+$01 ; ACIA status register ACIACM = ACIARW+$02 ; ACIA commnad register ACIACN = ACIARW+$03 ; ACIA control register ; ; Begin base system initialization ; sta ACIAST ; Do a soft reset on the ACIA lda #$0B ; Set it up for : sta ACIACM ; no echo, no parity, RTS low, No IRQ, DTR low lda #$1A ; and : sta ACIACN ; 2400, 8 bits, 1 stop bit, external Rx clock 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 #$2F ; Offset of prompt jsr SNDMSG ; Go print the prompt jmp ST_LP ; Go get the response .org $1E00 ; Address of message area MBLK ; ; The message block begins at $1E00 and is at most 256 bytes long. ; Messages terminate with an FF. ; .db "OMEGA MICRO SYSTEMS" .db $0D, $0A, $0A .db "OMS-02 T-Basic Controller" .db $0D, $0A, $0A .db "Boot (C/W)? " .db $07, $FF .org $1F00 ;address of subroutine area SBLK ; ; 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 retuen 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 messsage offset from MBLK in X. ; SNDMSG lda MBLK,X ; Get a character from teh 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 ACIAST ; Read the ACAI status to (for OMS-02) ;and #$08 ; Check if there is character in the receiver (for OMS-02) ;beq RCCHR ; Loop util we get one (for OMS-02) ;lda ACIARW ; Load it into the accumulator (for OMS-02) LDA $E004 ; Check if a character typed (for emulator) BEQ RCCHR ; Loop until we get one (for emulator) ; ;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 ; SCLP ;lda ACIAST ; Check ACIA Status (don't need for emulator) ;and #$10 ; See if transmiter it busy (don't need for emulator) ;beq SCLP ; Wait for it (don't need for emulator) lda $FE ; Restore the character ;sta ACIARW ; Transmit it (for OMS-02) STA $E001 ; Transmit it (for emulator) EXSC rts ; Return .org $1FFC ; Address of reset vector (for 6507 not required for emulator) RSVEC .db $F0, $1C ; Reset vector .org $3000 ; Address of last byte of EPROM EOROM