; Kernel
|
; Kernel
|
; Reads uart input
|
; Reads uart input
|
; Processes the command
|
; Processes the command
|
; raddress = reads one byte outs to uart
|
; raddress = reads one byte outs to uart
|
; Raddress = reads 16 bytes outs to uart
|
; Raddress = reads 16 bytes outs to uart
|
; waddress data = write one databyte to address location
|
; waddress data = write one databyte to address location
|
; Faddress data nn = Fill databyte into nn locations
|
; Faddress data nn = Fill databyte into nn locations
|
; S1bcadd d d d d d chksum= see Motorolla hex format used to load short program
|
; S1bcadd d d d d d chksum= see Motorolla hex format used to load short program
|
; Gaddress start from this address
|
; Gaddress start from this address
|
; Sends the stuff in the output buffer to uart tx.
|
; Sends the stuff in the output buffer to uart tx.
|
;
|
;
|
;
|
;
|
cpu 6502
|
cpu 6502
|
PAGE 40,120
|
PAGE 40,120
|
|
|
led equ $4007
|
led equ $4007
|
dat232 equ $4000
|
dat232 equ $4000
|
stat232 equ $4001
|
stat232 equ $4001
|
tx232 equ $4000
|
tx232 equ $4000
|
|
irq equ $4002
|
|
nmi equ $4003
|
|
break equ $10
|
|
intrpt equ $04
|
|
|
;dat232 equ $290 ;used to help debug
|
;dat232 equ $290 ;used to help debug
|
;stat232 equ $291
|
;stat232 equ $291
|
;tx232 equ $292
|
;tx232 equ $292
|
|
|
tx_rdy equ $80 ;bit 7
|
tx_rdy equ $80 ;bit 7
|
rx_rdy equ $40 ;bit 6
|
rx_rdy equ $40 ;bit 6
|
;
|
;
|
inbuflen equ $40 ;input buffer table length
|
inbuflen equ $40 ;input buffer table length
|
otbuflen equ $40 ;output buffer table length
|
otbuflen equ $40 ;output buffer table length
|
cr equ $0d ;cariage return
|
cr equ $0d ;cariage return
|
|
|
|
|
; ZERO PAGE STUFF
|
; ZERO PAGE STUFF
|
* = $0
|
* = $0
|
ptr dw $0 ;reserve 2 bytes
|
ptr dw $0 ;reserve 2 bytes
|
hexword dw $0 ;accumulates hex word
|
hexword dw $0 ;accumulates hex word
|
|
|
|
|
; STUFF IN UPPER MEMORY
|
; STUFF IN UPPER MEMORY
|
* = $200
|
* = $200
|
|
|
inbuff db 0 ;reserve 64 bytes for command input
|
inbuff db 0 ;reserve 64 bytes for command input
|
* = inbuff + inbuflen
|
* = inbuff + inbuflen
|
outbuff db 0
|
outbuff db 0
|
* = outbuff + otbuflen
|
* = outbuff + otbuflen
|
|
|
txoutpt db 0 ;output pointer index
|
txoutpt db 0 ;output pointer index
|
txinpt db 0 ;input pointer index
|
txinpt db 0 ;input pointer index
|
txoutct db 0 ;Counter
|
txoutct db 0 ;Counter
|
inbufpt db 0 ;Ponts where to put kb text
|
inbufpt db 0 ;Ponts where to put kb text
|
txtpt db 0 ;Points to text to be processed
|
txtpt db 0 ;Points to text to be processed
|
sp1 db $0
|
sp1 db $0
|
sp2 db $0
|
sp2 db $0
|
sp3 db $0
|
sp3 db $0
|
temp_y db 0
|
temp_y db 0
|
bytcnt db 0
|
bytcnt db 0
|
n db 0
|
n db 0
|
|
|
|
|
page
|
page
|
* = $fc00
|
* = $fc00
|
; This is the main loop.
|
; This is the main loop.
|
;
|
;
|
main ldx #$0
|
main ldx #$0
|
txs ;Set stack pointer to x100
|
txs ;Set stack pointer to x100
|
stx txoutpt
|
stx txoutpt
|
stx txinpt
|
stx txinpt
|
stx txoutct
|
stx txoutct
|
stx inbufpt
|
stx inbufpt
|
stx txtpt
|
stx txtpt
|
|
|
lda #"?" ;Illegal char or restart
|
lda #"?" ;Illegal char or restart
|
jsr sendtxt ;or bad frap
|
jsr sendtxt ;or bad frap
|
|
|
loop jmp input ;Read serial character
|
loop jmp input ;Read serial character
|
back1 jmp process ;It's in reg a and stored in inbuff
|
back1 jmp process ;It's in reg a and stored in inbuff
|
back2 jmp sendbuf
|
back2 jmp sendbuf
|
back3 jmp loop
|
back3 jmp loop
|
;
|
;
|
;
|
;
|
page
|
page
|
; This is where the uart receiver character is picked up and dumped
|
; This is where the uart receiver character is picked up and dumped
|
; into the input buffer (inbuff)
|
; into the input buffer (inbuff)
|
code
|
code
|
input jmp getchar
|
input jmp getchar
|
; beq back1 ;No new character
|
; beq back1 ;No new character
|
.loop ldx inbufpt ;Returns with it in y
|
.loop ldx inbufpt ;Returns with it in y
|
sta inbuff,x ;input buffer
|
sta inbuff,x ;input buffer
|
tay
|
tay
|
inx
|
inx
|
txa
|
txa
|
and #inbuflen - 1
|
and #inbuflen - 1
|
sta inbufpt
|
sta inbufpt
|
tya
|
tya
|
jmp back1 ;return with character in a
|
jmp back1 ;return with character in a
|
|
|
getchar lda stat232
|
getchar lda stat232
|
and #rx_rdy
|
and #rx_rdy
|
beq .exit
|
beq .exit
|
lda dat232 ;Character in a
|
lda dat232 ;Character in a
|
jmp .loop
|
jmp .loop
|
.exit lda #$0
|
.exit lda #$0
|
jmp back1
|
jmp back1
|
code
|
code
|
page
|
page
|
code
|
code
|
; This is where the complicated stuff is done
|
; This is where the complicated stuff is done
|
process beq .exit ;It's a null character
|
process beq .exit ;It's a null character
|
pha
|
pha
|
jsr sendtxt ;Echo character to terminal
|
jsr sendtxt ;Echo character to terminal
|
pla
|
pla
|
cmp #"\r"
|
cmp #"\r"
|
beq got_cr
|
beq got_cr
|
cmp #"\n"
|
cmp #"\n"
|
beq got_cr
|
beq got_cr
|
.exit jmp back2
|
.exit jmp back2
|
|
|
got_cr ldx txtpt ;Decode the KB input
|
got_cr ldx txtpt ;Decode the KB input
|
lda inbuff,x
|
lda inbuff,x
|
jsr inctxt
|
jsr inctxt
|
cmp #"r"
|
cmp #"r"
|
beq read1 ;Read one byte rnnnn
|
beq read1 ;Read one byte rnnnn
|
|
|
cmp #"R"
|
cmp #"R"
|
bne next0
|
bne next0
|
jmp readn
|
jmp readn
|
|
|
next0 cmp #"w" ;Write one byte wnnnn xx
|
next0 cmp #"w" ;Write one byte wnnnn xx
|
bne next1
|
bne next1
|
jmp write1
|
jmp write1
|
|
|
next1 cmp #"F" ;Fill Fnnnn nn xx
|
next1 cmp #"F" ;Fill Fnnnn nn xx
|
bne next2
|
bne next2
|
jmp fill
|
jmp fill
|
|
|
next2 cmp #"G" ;goto nnnn
|
next2 cmp #"G" ;goto nnnn
|
bne next3
|
bne next3
|
jmp goto
|
jmp goto
|
|
|
next3 cmp #"g" ;goto 290
|
next3 cmp #"g" ;goto 290
|
bne next4
|
bne next4
|
jsr inctxt ;Get to end of buffer
|
jsr inctxt ;Get to end of buffer
|
jmp $290
|
jmp $290
|
|
|
|
|
next4 cmp #"S"
|
next4 cmp #"S"
|
bne next5
|
bne next5
|
ldx txtpt
|
ldx txtpt
|
lda inbuff,x
|
lda inbuff,x
|
jsr inctxt
|
jsr inctxt
|
cmp #"1"
|
cmp #"1"
|
bne next5
|
bne next5
|
jmp scode
|
jmp scode
|
next5 cmp #"9"
|
next5 cmp #"9"
|
bne next6
|
bne next6
|
jmp flush ;Last S code packet not used so flush
|
jmp flush ;Last S code packet not used so flush
|
|
|
next6 jmp main ;restart bad input
|
next6 jmp main ;restart bad input
|
|
|
|
|
|
|
|
|
code
|
code
|
page
|
page
|
code
|
code
|
; This is where stuff is pulled from the output buffer (outbuff)
|
; This is where stuff is pulled from the output buffer (outbuff)
|
; and sent to the terminal
|
; and sent to the terminal
|
sendbuf lda stat232 ;All regs destroyed
|
sendbuf lda stat232 ;All regs destroyed
|
and #tx_rdy ;Test uart tx status
|
and #tx_rdy ;Test uart tx status
|
bne .exit ;In use
|
bne .exit ;In use
|
jmp .gettxt ;char in A for return
|
jmp .gettxt ;char in A for return
|
.bak sta tx232 ;Byte to terminal
|
.bak sta tx232 ;Byte to terminal
|
.exit jmp back3
|
.exit jmp back3
|
; Pull txt from buffer if not empty
|
; Pull txt from buffer if not empty
|
.gettxt lda txoutct
|
.gettxt lda txoutct
|
beq .exit
|
beq .exit
|
dec txoutct
|
dec txoutct
|
lda txoutpt ;out text out pointer
|
lda txoutpt ;out text out pointer
|
tay
|
tay
|
tax
|
tax
|
iny
|
iny
|
tya
|
tya
|
and #inbuflen - 1
|
and #inbuflen - 1
|
sta txoutpt
|
sta txoutpt
|
lda outbuff,x
|
lda outbuff,x
|
jmp .bak
|
jmp .bak
|
|
|
code
|
code
|
page
|
page
|
|
|
page ;This routing reads one byt"\n"e from address
|
page ;This routing reads one byt"\n"e from address
|
read1 jsr txt2hex ;Convert string to 16 bit word
|
read1 jsr txt2hex ;Convert string to 16 bit word
|
|
|
lda hexword + 1
|
lda hexword + 1
|
jsr hex2txt
|
jsr hex2txt
|
|
|
lda hexword
|
lda hexword
|
jsr hex2txt
|
jsr hex2txt
|
|
|
lda #" "
|
lda #" "
|
jsr sendtxt
|
jsr sendtxt
|
ldy #$0
|
ldy #$0
|
lda (hexword),y
|
lda (hexword),y
|
jsr hex2txt
|
jsr hex2txt
|
lda #"\r"
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
jmp back2
|
jmp back2
|
; ===============================================
|
; ===============================================
|
|
|
readn jsr txt2hex ;Convert string to 16 bit word
|
readn jsr txt2hex ;Convert string to 16 bit word
|
|
|
lda hexword + 1
|
lda hexword + 1
|
sta ptr + 1
|
sta ptr + 1
|
jsr hex2txt
|
jsr hex2txt
|
|
|
lda hexword
|
lda hexword
|
and #$f0
|
and #$f0
|
sta ptr
|
sta ptr
|
jsr hex2txt
|
jsr hex2txt
|
|
|
lda #$0
|
lda #$0
|
sta temp_y
|
sta temp_y
|
read_lp lda #" "
|
read_lp lda #" "
|
jsr sendtxt
|
jsr sendtxt
|
ldy temp_y
|
ldy temp_y
|
lda (ptr),y
|
lda (ptr),y
|
jsr hex2txt
|
jsr hex2txt
|
ldy temp_y
|
ldy temp_y
|
iny
|
iny
|
tya
|
tya
|
sta temp_y
|
sta temp_y
|
cmp #$10
|
cmp #$10
|
bne read_lp
|
bne read_lp
|
|
|
lda #"\r"
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
jmp back2
|
jmp back2
|
; ==================================================
|
; ==================================================
|
|
|
; This routine writes one byte to memory
|
; This routine writes one byte to memory
|
; address space data
|
; address space data
|
write1 jsr txt2hex ;Convert string to 16 bit word
|
write1 jsr txt2hex ;Convert string to 16 bit word
|
|
|
lda hexword + 1 ;Save these locations
|
lda hexword + 1 ;Save these locations
|
sta ptr + 1
|
sta ptr + 1
|
jsr hex2txt
|
jsr hex2txt
|
|
|
lda hexword
|
lda hexword
|
sta ptr
|
sta ptr
|
jsr hex2txt
|
jsr hex2txt
|
|
|
jsr txt2hex ;Convert data
|
jsr txt2hex ;Convert data
|
lda hexword
|
lda hexword
|
|
|
ldy #$0
|
ldy #$0
|
sta (ptr),y
|
sta (ptr),y
|
lda #"\r"
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
jmp back2
|
jmp back2
|
; ==================================================
|
; ==================================================
|
fill jsr txt2hex ;Convert string to 16 bit word
|
fill jsr txt2hex ;Convert string to 16 bit word
|
|
|
lda hexword + 1 ;Save these locations
|
lda hexword + 1 ;Save these locations
|
pha
|
pha
|
lda hexword
|
lda hexword
|
pha
|
pha
|
|
|
jsr txt2hex ;Convert data
|
jsr txt2hex ;Convert data
|
lda hexword
|
lda hexword
|
pha ;Data on stack
|
pha ;Data on stack
|
|
|
jsr txt2hex ;how many bytes?
|
jsr txt2hex ;how many bytes?
|
lda hexword
|
lda hexword
|
sta sp1 ;Number of bytes to fill in sp1
|
sta sp1 ;Number of bytes to fill in sp1
|
|
|
pla
|
pla
|
tay ;Data into y
|
tay ;Data into y
|
pla ;Restore hexword
|
pla ;Restore hexword
|
sta hexword
|
sta hexword
|
pla
|
pla
|
sta hexword + 1
|
sta hexword + 1
|
tya
|
tya
|
pha
|
pha
|
|
|
ldy #$0
|
ldy #$0
|
sta temp_y
|
sta temp_y
|
pla
|
pla
|
fill_lp sta (hexword),y
|
fill_lp sta (hexword),y
|
iny
|
iny
|
sta temp_y
|
sta temp_y
|
cpy sp1
|
cpy sp1
|
bne fill_lp
|
bne fill_lp
|
|
|
lda #"\r"
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
jmp back2
|
jmp back2
|
|
|
goto jsr txt2hex
|
goto jsr txt2hex
|
jmp (hexword) ;goto user code best return to main x"fc00"
|
jmp (hexword) ;goto user code best return to main x"fc00"
|
|
|
page
|
page
|
code
|
code
|
; This routine takes the Motorolla S code generated
|
; This routine takes the Motorolla S code generated
|
; by crasm and loads it into RAM.
|
; by crasm and loads it into RAM.
|
; The checksum is not checked since there is no comms.
|
; The checksum is not checked since there is no comms.
|
|
|
scode ldx #$2 ;convert two bytes byte count
|
scode ldx #$2 ;convert two bytes byte count
|
jsr cod2hex
|
jsr cod2hex
|
lda hexword
|
lda hexword
|
clc
|
clc
|
sbc #3
|
sbc #3
|
sta bytcnt ;total bytes to transfer
|
sta bytcnt ;total bytes to transfer
|
|
|
ldx #$4 ;convert four bytes to address
|
ldx #$4 ;convert four bytes to address
|
jsr cod2hex ;hexword points to where data goes
|
jsr cod2hex ;hexword points to where data goes
|
lda hexword
|
lda hexword
|
sta ptr
|
sta ptr
|
lda hexword + 1
|
lda hexword + 1
|
sta ptr + 1 ;ptr holds point
|
sta ptr + 1 ;ptr holds point
|
|
|
lda #$0
|
lda #$0
|
sta n
|
sta n
|
|
|
scodelp ldx #$2 ;4 or 2 bytes to form number
|
scodelp ldx #$2 ;4 or 2 bytes to form number
|
jsr cod2hex
|
jsr cod2hex
|
ldy n
|
ldy n
|
sta (ptr),y
|
sta (ptr),y
|
iny
|
iny
|
sty n
|
sty n
|
cpy bytcnt
|
cpy bytcnt
|
bne scodelp
|
bne scodelp
|
lda #"\r"
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
jsr inctxt ;skip checksum 1
|
jsr inctxt ;skip checksum 1
|
jsr inctxt ;and cs2
|
jsr inctxt ;and cs2
|
jsr inctxt ;and cr
|
jsr inctxt ;and cr
|
jmp back2
|
jmp back2
|
|
|
cod2hex lda #$0
|
cod2hex lda #$0
|
sta hexword
|
sta hexword
|
sta hexword + 1
|
sta hexword + 1
|
stx sp3 ;Save No of bytes to convert this time
|
stx sp3 ;Save No of bytes to convert this time
|
|
|
.lphex ldx sp3
|
.lphex ldx sp3
|
beq .exit
|
beq .exit
|
ldx txtpt
|
ldx txtpt
|
lda inbuff,x
|
lda inbuff,x
|
jsr inctxt
|
jsr inctxt
|
ldx sp3
|
ldx sp3
|
|
|
ldy #$0
|
ldy #$0
|
.nothis cmp asctbl,y
|
.nothis cmp asctbl,y
|
bne .next
|
bne .next
|
dex ;Got 1 match
|
dex ;Got 1 match
|
stx sp3
|
stx sp3
|
jsr accum
|
jsr accum
|
jmp .lphex
|
jmp .lphex
|
.next iny
|
.next iny
|
cpy #$10
|
cpy #$10
|
bne .nothis ;next hex char
|
bne .nothis ;next hex char
|
.exit rts ;last char
|
.exit rts ;last char
|
|
|
flush jsr cod2hex ;empty buffer
|
flush jsr cod2hex ;empty buffer
|
jmp back2 ;result of subroutine ignored
|
jmp back2 ;result of subroutine ignored
|
|
|
|
|
code
|
code
|
|
|
|
|
page
|
page
|
; This is where the output buffer (outbuf) is loaded.
|
; This is where the output buffer (outbuf) is loaded.
|
code
|
code
|
sendtxt pha ;A hold character to be place in buffer
|
sendtxt pha ;A hold character to be place in buffer
|
sty sp2
|
sty sp2
|
lda txoutct
|
lda txoutct
|
cmp #otbuflen -1
|
cmp #otbuflen -1
|
bpl .exit ;buffer should never be full
|
bpl .exit ;buffer should never be full
|
inc txoutct
|
inc txoutct
|
lda txinpt ;out text out pointer
|
lda txinpt ;out text out pointer
|
tay
|
tay
|
tax
|
tax
|
iny
|
iny
|
tya
|
tya
|
and #otbuflen - 1
|
and #otbuflen - 1
|
sta txinpt
|
sta txinpt
|
pla
|
pla
|
sta outbuff,x
|
sta outbuff,x
|
ldy sp2
|
ldy sp2
|
rts
|
rts
|
.exit pla
|
.exit pla
|
ldy sp2
|
ldy sp2
|
rts
|
rts
|
|
|
|
|
code
|
code
|
page
|
page
|
code
|
code
|
txt2hex ldy #$0
|
txt2hex ldy #$0
|
sty hexword
|
sty hexword
|
sty hexword + 1
|
sty hexword + 1
|
|
irq equ $4002
|
|
nmi equ $4003
|
|
break equ $10
|
|
intrpt equ $04
|
loophex ldx txtpt
|
loophex ldx txtpt
|
lda inbuff,x ;input buffer
|
lda inbuff,x ;input buffer
|
jsr inctxt ;inc counter
|
jsr inctxt ;inc counter
|
ldy #$0
|
ldy #$0
|
nomatch cmp asctbl,y
|
nomatch cmp asctbl,y
|
bne .next
|
bne .next
|
jsr accum
|
jsr accum
|
jmp loophex
|
jmp loophex
|
.next iny
|
.next iny
|
cpy #$10
|
cpy #$10
|
bne nomatch ;next hex char
|
bne nomatch ;next hex char
|
rts ;not hex char
|
rts ;not hex char
|
|
|
|
|
accum stx sp1
|
accum stx sp1
|
ldx #$4 ;y holds hex of character
|
ldx #$4 ;y holds hex of character
|
accloop asl hexword
|
accloop asl hexword
|
rol hexword + 1
|
rol hexword + 1
|
dex
|
dex
|
bne accloop
|
bne accloop
|
tya
|
tya
|
ora hexword
|
ora hexword
|
sta hexword
|
sta hexword
|
ldx sp1
|
ldx sp1
|
rts
|
rts
|
|
|
|
|
hex2txt tay ;A holds byte to convert
|
hex2txt tay ;A holds byte to convert
|
clc
|
clc
|
ror a
|
ror a
|
ror a
|
ror a
|
ror a
|
ror a
|
ror a
|
ror a
|
and #$0f
|
and #$0f
|
tax
|
tax
|
lda asctbl,x
|
lda asctbl,x
|
jsr sendtxt
|
jsr sendtxt
|
tya
|
tya
|
and #$0f
|
and #$0f
|
tax
|
tax
|
lda asctbl,x
|
lda asctbl,x
|
jsr sendtxt
|
jsr sendtxt
|
rts
|
rts
|
; inc after reading from inbuff
|
; inc after reading from inbuff
|
inctxt pha ;NOT before
|
inctxt pha ;NOT before
|
inc txtpt
|
inc txtpt
|
lda txtpt
|
lda txtpt
|
and #inbuflen - 1
|
and #inbuflen - 1
|
sta txtpt
|
sta txtpt
|
pla
|
pla
|
rts
|
rts
|
|
|
asctbl asc "0123456789ABCDEF"
|
asctbl asc "0123456789ABCDEF"
|
code
|
code
|
|
|
page ;All the start up stuff
|
page ;All the start up stuff
|
|
|
nmi_srv lda #"N"
|
nmi_srv lda #$01
|
|
sta nmi
|
|
lda #"N"
|
|
jsr sendtxt
|
|
lda #"M"
|
|
jsr sendtxt
|
|
lda #"I"
|
|
jsr sendtxt
|
|
lda #"\r"
|
jsr sendtxt
|
jsr sendtxt
|
rti
|
rti
|
|
|
irq_srv lda #"I"
|
irq_srv pla
|
|
pha
|
|
and #break
|
|
beq irqish
|
|
lda #"B"
|
jsr sendtxt
|
jsr sendtxt
|
rti
|
lda #"R"
|
|
jsr sendtxt
|
|
lda #"K"
|
|
jsr sendtxt
|
|
lda #"\r"
|
|
jsr sendtxt
|
|
jmp endish
|
|
|
|
|
|
irqish lda #$01
|
|
sta irq
|
|
lda #$01
|
|
sta irq
|
|
lda #"I"
|
|
jsr sendtxt
|
|
lda #"R"
|
|
jsr sendtxt
|
|
lda #"Q"
|
|
jsr sendtxt
|
|
lda #"\r"
|
|
jsr sendtxt
|
|
endish rti
|
|
|
* =$fff0
|
* =$fff0
|
jmp sendtxt ;Links for usrcode
|
jmp sendtxt ;Links for usrcode
|
jmp hex2txt
|
jmp hex2txt
|
dw back2
|
dw back2 ;jmp ($FFF6) in user code.
|
|
|
* = $fff8
|
* = $fff8
|
;
|
;
|
indjmp dw main
|
indjmp dw main
|
nmi dw nmi_srv
|
nmi_int dw nmi_srv
|
rst dw main ;Should be main, this is for test only
|
rst dw main ;Should be main, this is for test only
|
irq dw irq_srv
|
irq_int dw irq_srv
|
|
|