mirror of
https://github.com/makarcz/vm6502.git
synced 2024-11-16 05:05:20 +00:00
0d47565b9d
Reset option in dbg console. RESET keyword in memory definition file. Command line arguments added. Save snapshot added. Refactoring - huge switch replaced with array of methods. IRQ support. Cycle accurate emulation. Intel HEX format support.
1500 lines
37 KiB
NASM
1500 lines
37 KiB
NASM
;----------------------------------------------------------------------------------
|
|
; Tiny Basic port to MKHBC-8-R1 6502 computer
|
|
; by Marek Karcz 2012.
|
|
;
|
|
; Based on the work by:
|
|
;
|
|
; ================= ORIGINAL HEADER ======================================
|
|
;
|
|
; 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
|
|
;
|
|
; ============ END OF ORIGINAL HEADER =========================================
|
|
;
|
|
; Revision history (MKHBC-8-R1 port):
|
|
;
|
|
; 1/4/2012:
|
|
; TB port created.
|
|
;
|
|
; 1/5/2012:
|
|
; Version 1.0.1.
|
|
; Added 2-byte peek routine.
|
|
;
|
|
; 1/11/2012:
|
|
; Figured out jump addresses for routines and used symbolic labels
|
|
; instead of hardcoded addresses. Relocated TB to $0400 (from $1400).
|
|
;
|
|
; 2/15/2016
|
|
; Ported to my own 6502 emulator.
|
|
;
|
|
; 3/30/2016
|
|
;
|
|
; Changed char input address from blocking to non-blocking.
|
|
;
|
|
;
|
|
;--------------------------------------------------------------------------------------
|
|
|
|
.segment "BEGN"
|
|
|
|
.ORG $0000
|
|
|
|
.segment "BASIC"
|
|
|
|
;
|
|
; Tiny Basic starts here
|
|
;
|
|
.ORG $4400 ; 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 GetCh ; Input routine address.
|
|
OUT_V: jmp PutCh ; Output routine address.
|
|
BREAK: nop ; Begin dummy break routine
|
|
clc ; Clear the carry flag
|
|
rts ; End break routine
|
|
;
|
|
; Some codes
|
|
;
|
|
BSC: .byte $5f ; Backspace code
|
|
LSC: .byte $18 ; Line cancel code
|
|
PCC: .byte $80 ; Pad character control
|
|
TMC: .byte $00 ; Tape mode control
|
|
;SSS: .byte $04 ; Spare Stack size. (was $04 but documentation suggests $20 ?)
|
|
SSS: .byte $20 ; Spare Stack size. (was $04 but documentation suggests $20 ?)
|
|
|
|
;
|
|
; Code fragment
|
|
; Seems to store or retreive a byte to/from memory and the accumulator
|
|
; ---
|
|
; M.K.: I think this code it is used from Tiny Basic programs by calling USR to store/retrieve
|
|
; data (since TB does not support arrays, this is one way to emulate them).
|
|
; This location is at exactly 20 bytes distance from the start of TB code.
|
|
; TB programs typically make USR calls to locations:
|
|
; SOBAS+20
|
|
; SOBAS+24
|
|
; E.g:
|
|
; LET S=_SOBAS_ REM (_SOBAS_ is TB start)
|
|
; LET B=_ARRAY_SIZE_+2 (_ARRAY_SIZE_ is the size of 2-dim array)
|
|
; Get byte from location V(I,J), store in Z.
|
|
; LET Z=USR(S+20,V+B*I+J,0)
|
|
; Store Z in location V(I,J)
|
|
; LET Z=USR(S+24,V+B*I+J,Z)
|
|
; From TB documentation:
|
|
; For your convenience two subroutines have been included in the TINY BASIC interpreter to access memory.
|
|
; If S contains the address of the beginning of the TINY BASIC interpreter (256 for standard 6800, 512
|
|
; for standard 6502, etc.), then location S+20 (hex 0114) is the entry point of a subroutine to read one
|
|
; byte from the memory address in the index register, and location S+24 (hex 0118) is the entry point of
|
|
; a subroutine to store one byte into memory.
|
|
;-------------------------------------------------
|
|
; USR (address)
|
|
; USR (address,Xreg)
|
|
; USR (address,Xreg,Areg)
|
|
;
|
|
; This function is actually a machine-language subroutine call to the address in the first argument.
|
|
; If the second argument is included the index registers contain that value on entry to the subroutine,
|
|
; with the most significant part in X. If the third argument is included, the accumulators contain that
|
|
; value on entry to the subroutine, with the least significant part in A. On exit, the value in the
|
|
; Accumulators (for the 6800; A and Y for the 6502) becomes the value of the function, with the least
|
|
; significant part in A. All three arguments are evaluated as normal expressions.
|
|
; It should be noted that machine language subroutine addresses are 16-bit Binary numbers. TINY BASIC
|
|
; evaluates all expressions to 16-bit binary numbers, so any valid expression may be used to define a
|
|
; subroutine address. However, most addresses are expressed in hexadecimal whereas TINY BASIC only accepts
|
|
; numerical constants in decimal. Thus to jump to a subroutine at hex address 40AF, you must code USR(16559).
|
|
; Hex address FFB5 is similarly 65461 in decimal, though the equivalent (-75) may be easier to use.
|
|
;
|
|
|
|
OneBytePeek:
|
|
|
|
stx $C3 ; read one byte from memory address in the index register
|
|
bcc LBL008
|
|
|
|
OneBytePoke:
|
|
|
|
stx $C3 ; store one byte into memory
|
|
sta (C_C2),Y
|
|
rts
|
|
LBL008: lda (C_C2),Y
|
|
ldy #$00
|
|
rts
|
|
|
|
|
|
; These seem to be addresses associated with the IL branch instructions
|
|
;.byte $62,$15, $64,$15, $D8,$15, $05,$16, $33,$16, $FD,$15
|
|
.byte <JUMP01,>JUMP01
|
|
.byte <LBL027,>LBL027
|
|
.byte <JUMP02,>JUMP02
|
|
.byte <JUMP03,>JUMP03
|
|
.byte <JUMP04,>JUMP04
|
|
.byte <JUMP05,>JUMP05
|
|
|
|
; NOTE: The original comment below is obsolete now, since I found the jump
|
|
; addresses locations and put them in this table. Now assembler will
|
|
; take care of the reallocation.
|
|
; START OF ORIGINAL COMMENT
|
|
; This appears to be a table of
|
|
; execution addresses to jump to ML routines
|
|
; that handle the the IL instructions.
|
|
; You cannot add code to or relocate this program
|
|
; without updating these
|
|
; END OF ORIGINAL COMMENT
|
|
|
|
;.byte $9F,$17, $42,$1B, $3F,$1B, $7A,$17, $FC,$18, $95,$17, $9F,$17, $9F,$17
|
|
.byte <LBL067,>LBL067
|
|
.byte <LBL132,>LBL132
|
|
.byte <JUMP06,>JUMP06
|
|
.byte <JUMP07,>JUMP07
|
|
.byte <LBL035,>LBL035
|
|
.byte <LBL097,>LBL097
|
|
.byte <LBL067,>LBL067
|
|
.byte <LBL067,>LBL067
|
|
|
|
;.byte $BD,$1A, $C1,$1A, $8A,$1A, $9B,$1A, $E9,$1A, $61,$17, $51,$17, $41,$1A
|
|
.byte <JUMP08,>JUMP08
|
|
.byte <JUMP09,>JUMP09
|
|
.byte <JUMP10,>JUMP10
|
|
.byte <JUMP11,>JUMP11
|
|
.byte <JUMP12,>JUMP12
|
|
.byte <JUMP13,>JUMP13
|
|
.byte <JUMP14,>JUMP14
|
|
.byte <LBL071,>LBL071
|
|
|
|
;.byte $52,$1A, $4F,$1A, $62,$1A, $E7,$19, $CD,$16, $06,$17, $9F,$17, $15,$18
|
|
.byte <JUMP15,>JUMP15
|
|
.byte <JUMP16,>JUMP16
|
|
.byte <JUMP17,>JUMP17
|
|
.byte <JUMP18,>JUMP18
|
|
.byte <JUMP19,>JUMP19
|
|
.byte <JUMP20,>JUMP20
|
|
.byte <LBL067,>LBL067
|
|
.byte <JUMP21,>JUMP21
|
|
|
|
;.byte $A7,$17, $B7,$16, $BF,$16, $83,$18, $A1,$16, $9F,$17, $9F,$17, $A8,$18
|
|
.byte <JUMP22,>JUMP22
|
|
.byte <JUMP23,>JUMP23
|
|
.byte <LBL047,>LBL047
|
|
.byte <LBL081,>LBL081
|
|
.byte <LBL013,>LBL013
|
|
.byte <LBL067,>LBL067
|
|
.byte <LBL067,>LBL067
|
|
.byte <JUMP24,>JUMP24
|
|
|
|
;.byte $4F,$1B, $4D,$1B, $07,$19, $AA,$14, $37,$17, $BD,$14, $1B,$1B, $B1,$1A
|
|
.byte <JUMP25,>JUMP25
|
|
.byte <JUMP26,>JUMP26
|
|
.byte <JUMP27,>JUMP27
|
|
.byte <MEM_T2,>MEM_T2
|
|
.byte <JUMP28,>JUMP28
|
|
.byte <WARM_S,>WARM_S
|
|
.byte <JUMP29,>JUMP29
|
|
.byte <JUMP30,>JUMP30
|
|
|
|
.byte $20,$41, $54,$20 ; No idea ????
|
|
|
|
.byte $80 ; No idea
|
|
|
|
LBL002: .byte <ILTBL ;$70 ; $70 - lo byte of IL address
|
|
LBL003: .byte >ILTBL ;$1B ; $1B - hi byte of IL address
|
|
|
|
;
|
|
;Begin Cold Start
|
|
;
|
|
;
|
|
;
|
|
; Load start of free ram ($1C00) into locations $0020 and $0022
|
|
; The memory between $1000 and $1Bff (3 kB) is free for assembler programs
|
|
; that can be loaded and used simultaneously with TB.
|
|
; $1C00 to the end of writable memory is the BASIC memory space.
|
|
;
|
|
COLD_S: lda #$00 ; Load accumulator with lo byte of lower and upper prg memory limits
|
|
sta $20 ; Store in $20
|
|
sta $22 ; Store in $22
|
|
lda #$50 ; Load accumulator with hi byte of lower and upper prg memory limits
|
|
sta $21 ; Store in $21
|
|
sta $23 ; Store in $23
|
|
; NOTE: $22,$23 vector will be updated by routine below to be the upper RAM limit for TB.
|
|
;
|
|
;
|
|
; Begin test for free ram
|
|
; As a result, memory locations $20,$21 will contain lo,hi byte order address of lower RAM boundary
|
|
; and $22,$23 upper RAM boundary respectively.
|
|
;
|
|
|
|
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)
|
|
MEM_T2: 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
|
|
;
|
|
;
|
|
;
|
|
.byte $83 ; No idea about this
|
|
.byte $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
|
|
;
|
|
;
|
|
;
|
|
JUMP01: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP02: 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
|
|
JUMP05: jsr LBL023
|
|
cmp #$0D
|
|
bne LBL028
|
|
LBL026: rts
|
|
;
|
|
;
|
|
;
|
|
JUMP03: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP04: 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
|
|
JUMP23: jsr LBL024
|
|
bne LBL046
|
|
LBL036: jmp LBL015
|
|
LBL047: lda #$20
|
|
jsr LBL042
|
|
lda $BF
|
|
and #$87
|
|
bmi LBL045
|
|
bne LBL047
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
JUMP19: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP20: 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
|
|
JUMP28: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP14: jsr LBL061
|
|
beq LBL062
|
|
LBL066: lda $BC
|
|
sta $28
|
|
lda $BD
|
|
sta $29
|
|
jmp LBL015
|
|
JUMP13: jsr LBL063
|
|
jsr LBL064
|
|
jsr LBL065
|
|
bne LBL066
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
LBL037: jsr LBL024
|
|
sta $28
|
|
jsr LBL024
|
|
sta $29
|
|
ora $28
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
JUMP07: 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
|
|
JUMP22: ldx $C1 ; entry point to TBIL PN (print number)
|
|
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
|
|
;
|
|
;
|
|
;
|
|
JUMP21: 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
|
|
JUMP24: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP27: 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
|
|
JUMP18: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP16: jsr LBL071
|
|
JUMP15: jsr LBL115
|
|
lda $00,X
|
|
adc $02,X
|
|
sta $02,X
|
|
lda $01,X
|
|
adc $03,X
|
|
sta $03,X
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
JUMP17: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP10: jsr LBL097
|
|
tax
|
|
lda $00,X
|
|
ldy $01,X
|
|
dec $C1
|
|
ldx $C1
|
|
sty $00,X
|
|
jmp LBL029
|
|
JUMP11: ldx #$7D
|
|
jsr LBL048
|
|
lda $01,X
|
|
pha
|
|
lda $00,X
|
|
pha
|
|
jsr LBL097
|
|
tax
|
|
pla
|
|
sta $00,X
|
|
pla
|
|
sta $01,X
|
|
rts
|
|
JUMP30: jsr LBL063
|
|
lda $BC
|
|
sta $2A
|
|
lda $BD
|
|
sta $2B
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
JUMP08: ldx #$2C ; Entry point to Save Basic Pointer SB
|
|
bne LBL125
|
|
JUMP09: 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
|
|
;
|
|
;
|
|
;
|
|
JUMP12: 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
|
|
JUMP29: 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)
|
|
JUMP06: jsr LBL132
|
|
LBL132: jsr LBL004 ; Go read a byte from the TBIL Table
|
|
jmp LBL029
|
|
LBL085: stx $2D
|
|
cpx #$00
|
|
rts
|
|
;
|
|
;
|
|
;
|
|
JUMP26: ldy #$02
|
|
JUMP25: 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: .byte $24, $3A, $91, $27, $10, $E1, $59, $C5, $2A, $56, $10, $11, $2C, $8B, $4C
|
|
.byte $45, $D4, $A0, $80, $BD, $30, $BC, $E0, $13, $1D, $94, $47, $CF, $88, $54
|
|
.byte $CF, $30, $BC, $E0, $10, $11, $16, $80, $53, $55, $C2, $30, $BC, $E0, $14
|
|
.byte $16, $90, $50, $D2, $83, $49, $4E, $D4, $E5, $71, $88, $BB, $E1, $1D, $8F
|
|
.byte $A2, $21, $58, $6F, $83, $AC, $22, $55, $83, $BA, $24, $93, $E0, $23, $1D
|
|
.byte $30, $BC, $20, $48, $91, $49, $C6, $30, $BC, $31, $34, $30, $BC, $84, $54
|
|
.byte $48, $45, $CE, $1C, $1D, $38, $0D, $9A, $49, $4E, $50, $55, $D4, $A0, $10
|
|
.byte $E7, $24, $3F, $20, $91, $27, $E1, $59, $81, $AC, $30, $BC, $13, $11, $82
|
|
.byte $AC, $4D, $E0, $1D, $89, $52, $45, $54, $55, $52, $CE, $E0, $15, $1D, $85
|
|
.byte $45, $4E, $C4, $E0, $2D, $98, $4C, $49, $53, $D4, $EC, $24, $00, $00, $00
|
|
.byte $00, $0A, $80, $1F, $24, $93, $23, $1D, $30, $BC, $E1, $50, $80, $AC, $59
|
|
.byte $85, $52, $55, $CE, $38, $0A, $86, $43, $4C, $45, $41, $D2, $2B, $84, $52
|
|
.byte $45, $CD, $1D, $A0, $80, $BD, $38, $14, $85, $AD, $30, $D3, $17, $64, $81
|
|
.byte $AB, $30, $D3, $85, $AB, $30, $D3, $18, $5A, $85, $AD, $30, $D3, $19, $54
|
|
.byte $2F, $30, $E2, $85, $AA, $30, $E2, $1A, $5A, $85, $AF, $30, $E2, $1B, $54
|
|
.byte $2F, $98, $52, $4E, $C4, $0A, $80, $80, $12, $0A, $09, $29, $1A, $0A, $1A
|
|
.byte $85, $18, $13, $09, $80, $12, $01, $0B, $31, $30, $61, $72, $0B, $04, $02
|
|
.byte $03, $05, $03, $1B, $1A, $19, $0B, $09, $06, $0A, $00, $00, $1C, $17, $2F
|
|
.byte $8F, $55, $53, $D2, $80, $A8, $30, $BC, $31, $2A, $31, $2A, $80, $A9, $2E
|
|
.byte $2F, $A2, $12, $2F, $C1, $2F, $80, $A8, $30, $BC, $80, $A9, $2F, $83, $AC
|
|
.byte $38, $BC, $0B, $2F, $80, $A8, $52, $2F, $84, $BD, $09, $02, $2F, $8E, $BC
|
|
.byte $84, $BD, $09, $93, $2F, $84, $BE, $09, $05, $2F, $09, $91, $2F, $80, $BE
|
|
.byte $84, $BD, $09, $06, $2F, $84, $BC, $09, $95, $2F, $09, $04, $2F, $00, $00
|
|
.byte $00
|
|
;
|
|
; End of Tiny Basic
|
|
|
|
|
|
.segment "MAIN"
|
|
|
|
.org $4CF0 ; Address of main program
|
|
|
|
; Code needs work below here, BIOS must be changed for MKHBC-8-R1
|
|
|
|
;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
|
|
;
|
|
; jmp main ; no 6522 on MKHBC-8-R1
|
|
;--------------------
|
|
; 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
|
|
;--------------------
|
|
|
|
main: cli
|
|
cld
|
|
jsr CLRSC ; Go clear the screen
|
|
ldy #$00 ; Offset for welcome message and prompt
|
|
jsr SNDMSG ; Go print it
|
|
ST_LP: JSR GetCh ; 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: ldy #$00 ; Offset of prompt
|
|
jsr SNDMSG ; Go print the prompt
|
|
jmp ST_LP ; Go get the response
|
|
|
|
.segment "MESG"
|
|
|
|
.org $4E00 ; Address of message area
|
|
MBLK:
|
|
|
|
;
|
|
; The message block begins at $4E00 and is at most 256 bytes long.
|
|
; Messages terminate with an FF.
|
|
;
|
|
.byte "MKHBC-8-R2 TINY BASIC 6502 PORT"
|
|
.byte $0D, $0A ;, $0A
|
|
.byte "Adapted from OMEGA MICRO SYSTEMS."
|
|
.byte $0D, $0A ;, $0A
|
|
.byte "Version: 1.0.3, 3/31/2016"
|
|
.byte $0D, $0A ;, $0A
|
|
.byte "(NOTE: Use upper case letters.)"
|
|
.byte $0D, $0A ;, $0A
|
|
.byte "Boot ([C]old/[W]arm)? "
|
|
.byte $07, $FF
|
|
|
|
.segment "SUBR"
|
|
|
|
.org $4F00 ;address of subroutine area
|
|
|
|
SBLK:
|
|
;
|
|
; Begin BIOS subroutines
|
|
;
|
|
|
|
; M.O.S. API defines.
|
|
|
|
StrPtr = $E0
|
|
|
|
;SNDCHR = PutCh
|
|
;RCCHR = GetCh
|
|
|
|
|
|
;
|
|
; Clear the screen
|
|
;
|
|
ESC = $1b
|
|
|
|
; 2-BYTE PEEK USR FUNCTION
|
|
; For TINY BASIC IL ASSEMBLER VERSION 0
|
|
|
|
TwoBytePeek:
|
|
|
|
STX $C3 ;($C2=00)
|
|
LDA ($C2),Y ;GET MSB
|
|
PHA ;SAVE IT
|
|
INY
|
|
LDA ($C2),Y ;GET LSB
|
|
TAX
|
|
PLA
|
|
TAY ;Y=MSB
|
|
TXA
|
|
RTS
|
|
|
|
|
|
;ClrScrCode:
|
|
|
|
; .BYTE ESC,"[2J",0 ;clear screen sequence (ANSI).
|
|
|
|
;ClearScreen:
|
|
|
|
; lda #<ClrScrCode
|
|
; sta StrPtr
|
|
; lda #>ClrScrCode
|
|
; sta StrPtr+1
|
|
; jsr Puts
|
|
; rts
|
|
|
|
CLRSC: ldx #$19 ; Load X - we're going tp print 25 lines
|
|
lda #$0D ; CR
|
|
jsr PutCh ; Send a carriage retuen
|
|
lda #$0A ; LF
|
|
CSLP: jsr PutCh ; 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,y ; Get a character from teh message block
|
|
cmp #$FF ; Look for end of message marker
|
|
beq EXSM ; Finish up if it is
|
|
jsr PutCh ; Otherwise send the character
|
|
iny ; Increment the pointer
|
|
jmp SNDMSG ; Go get next character
|
|
EXSM: rts ; Return
|
|
|
|
;
|
|
; Get a character from the character input device
|
|
; Runs into SNDCHR to provide echo
|
|
;
|
|
RCCHR: lda $E001 ; Check if a character typed (for emulator, non-blocking)
|
|
beq RCCHR ; Loop until we get one (for emulator)
|
|
cmp #'a' ; < 'a'?
|
|
bcc SNDCHR ; yes, done
|
|
cmp #'{' ; >= '{'?
|
|
bcs SNDCHR ; yes, done
|
|
and #$5f ; convert to upper case
|
|
;
|
|
; Send a character to the character output device
|
|
;
|
|
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 $FE ; Restore the character
|
|
sta $E000 ; Transmit it (for emulator)
|
|
EXSC: rts ; Return
|
|
|
|
; Kernel jump table
|
|
|
|
;GetCh = $FFED
|
|
;PutCh = $FFF0
|
|
;Gets = $FFF3
|
|
;Puts = $FFF6
|
|
|
|
; String I/O not used at this time.
|
|
|
|
STRIN: rts
|
|
STROUT: rts
|
|
|
|
; Vector jumps handlers
|
|
|
|
NmiHandle: rti
|
|
RstHandle: jmp main
|
|
IrqHandle: rti
|
|
|
|
.segment "KERN"
|
|
|
|
.ORG $FFED
|
|
|
|
GetCh: jmp RCCHR
|
|
PutCh: jmp SNDCHR
|
|
Gets: jmp STRIN
|
|
Puts: jmp STROUT
|
|
|
|
.segment "VECT"
|
|
|
|
.ORG $FFFA
|
|
|
|
.byte <NmiHandle, >NmiHandle, <RstHandle, >RstHandle, <IrqHandle, >IrqHandle
|
|
|
|
|
|
|
|
;--------------------------- END ----------------------------------------------------------------------
|