Category : Assembly Language Source Code
Archive   : CUG292.ZIP
Filename : AST05.ASM

 
Output of file : AST05.ASM contained in archive : CUG292.ZIP

.title assist05E2 february 18, 1985
;*
;* monitor for the MC146805E2 Evaluation Board
;*
;* (c) copyright 1985 motorola, inc.
;*
;*
;* the monitor has the following commands:
;*
;* r print registers
;*
;* d download from standard host
;*
;* h host communication
;*
;* a display/change a register
;*
;* x display/change x register
;*
;* c display/change condition codes
;*
;* e display/change timer data register
;*
;* f display/change timer control register
;*
;* p display/change program counter
;*
;* i display/change irq vector
;*
;* j display/change timer vector
;*
;* k display/change timer vector (wait mode)
;*
;* b display breakpoints
;*
;* b n xxxx set breakpoint n
;*
;* b n 0 clear breakpoint
;*
;* t trace one instruction
;*
;* t xxxx trace xxxx instructions
;*
;* m xxxx memory examine/change
;*
;* type to examine next
;* ^ to eamine previous
;* = to examine same
;* hh to change hex data
;* . to terminate command
;*
;* g continue execution from current pc
;*
;* g xxxx go execute pgm at specified address
;*
;*
;*
;*
;*
;*
;*
;*
monstr = 0x1800 ; start of monitor
workpg = 0x0010 ; start of monitor variables
numbkp = 3 ; number of breakpoints
duart = 0x17f0 ; duart address
prompt = '> ; prompt character
timer = 8 ; timer data register
timec = 9 ; timer control register
;*
;* equates
;*
;*
eot = 0x04 ; end of text
cr = 0x0d ; carriage return
lf = 0x0a ; line feed
sp = 0x20 ; space
bell = 0x07 ; control-g (bell)
swiop = 0x83 ; software interrupt op code
jmpop = 0xcc ; extended jump op code
ctla = 0x01 ; host communications default terminator
;*
;* work ram
;*
;*
.area ASST05 (ABS,OVR)

.setdp

.org workpg

bkptbl: .blkb 3*numbkp ; breakpoint table
asave: .blkb 1 ; temp save for a
swiflg: .blkb 1 ; swi function flag
work1: .blkb 1 ; chrin/load/store/putbyt
work2: .blkb 1 ; load/store/putbyte
addrh: .blkb 1 ; high address byte
addrl: .blkb 1 ; low address byte
work3: .blkb 1 ; load/store/punch
work4: .blkb 1 ; store/punchpunch
work5: .blkb 1 ; trace/punch
work6: .blkb 1 ; trace
work7: .blkb 1 ; trace
work8: .blkb 1 ; timer restoration
work9: .blkb 1 ; timer restoration
workd: .blkb 1 ; timer restoration
worke: .blkb 1 ; timer restoration
pncnt: .blkb 1 ; punch breakpoint
chksum: .blkb 1 ; punch
cmd: .blkb 3
total: .blkb 1
savea: .blkb 1
sava: .blkb 1
savex: .blkb 1
vecram: .blkb 12 ; vectors
;*
;*
;*
;*
;*
.org monstr ; start of monitor
;*
;* monitor base string/table page
;* (must be at the begining of a page)
;*
;*
;*
mbase = . ; start of work page in rom
;* ; msgup must be the first in the page
msgup: .ascii /assist05E2 3.0/ ; fire-up message
msgnul: .byte eot ; end of string
msgerr: .ascii /- error -/
.byte bell
.byte eot
msgpc: .ascii / Pc A X Cc S/
.byte eot
vectab: .byte jmpop
.word tirq
.byte jmpop
.word tirq
.byte jmpop
.word irq
.byte jmpop
.word swi
;*
;*
;* g - start execuction
;* also used for p - display/set pc
;*
;*
cmdg: lda *work4
bit #0x80
bne nodipc ; don't display pc if a g command
jsr putsp ; send a space
jsr locstk ; obtain current sp-3
lda 7,x ; current pc high
jsr putbyt ; print pc high in hex
lda 8,x ; current pc low
jsr putbyt ; print pc low in hex
nodipc: jsr getadr ; obtain input address
bcc next ; do continue if done
gaddr: jsr locstk ; obtain current sp-3t-3
lda *addrh ; load pc high
sta 7,x ; into stack
lda *addrl ; load pc low
sta 8,x ; into stack also
next: lda *work4
bit #0x80
bne cont ; if g command then continue
jmp cmdnnl ; else just p command - don't continue
cont: jsr scnbkp ; init breakpoint scan parameters
goinsb: lda *bkptbl,x ; load high byte

cmp #0x00 ; check to see if empty
bne gstore
lda *bkptbl+1,x ; get next byte
cmp #0x00 ; really empty?
beq gonob

gstore: lda *bkptbl,x ; go get byte again
sta *addrh ; store high address
sta: lda *bkptbl+1,x ; load low address
sta *addrl ; load low
jsr load ; load opccode
sta *bkptbl+2,x ; store into table
lda #swiop ; replace with opcode
jsr store ; store in place
gonob: incx ; to
incx ; next
incx ; breakpoint
lda *pncnt ; count low
deca
sta *pncnt
bne goinsb ; loop if more
lda *swiflg ; flag breakpoints are in
coma
sta *swiflg
lda *work9 ; reset control register
sta *timec
lda *work8
sta *timer ; then user enviornment
lda *workd ; then the user's vectors
sta *vecram+4
lda *worke
sta *vecram+5
rti ; restart program
cmdmin: jmp cmderr
;*
;*
;* m - examine/change memory
;* mchnge - register change entry point
;*
;*
;*
cmdm: jsr getadr ; obtain address value
bcc cmdmin ; invalid if no address
cmdmlp: jsr prtadr ; print out address and space
mchnge: bsr load ; load acc w/byte
jsr crbyts ; print with a space
jsr getnyb ; see if change wanted
bcc cmdmdl ; branch no
jsr getby2 ; obtain full byte
bne cmdmin ; terminate if invalid hex
bcc cmdmdl ; branch if other delimiter
bsr store ; store new value
bcs cmdmin ; branch of store fails
jsr chrin ; obtain delimiter
;*
;* check out delimiters
cmdmdl: cmp #0x0d ; ? to next byte
beq cmdmlf ; branch if so
cmp #'^ ; ? to previous byte
beq cmdmbk ; branch if so
cmp #'= ; ? reexamine same byte
beq cmcmpr ; branch yes
cmp #'. ; ? carriage return
beq cmdmen1 ; branch yes
jsr pcrlf ; all else: give new line
cmdmen: jmp cmdnnl ; enter command handler
cmdmbk: lda *addrl ; ? low byte zero?
bne cmdmb2 ; no, just adjust it
lda *addrh
deca
sta *addrh ; down high for carry
cmdmb2: lda *addrl
deca
sta *addrl ; down low byte
bsr pcrlf ; to next line
bra cmdmlp ; to next byte
cmcmpr: bsr pcrlf
bra cmdmlp
cmdmlf: lda #cr ; send just a carriage return
jsr chrou2 ; output it
bsr ptrup1 ; up pointer by one
bra cmdmlp ; to next byte

cmdmen1:
jsr pcrlf
bra cmdmen ; add crlf to the <.>
;*
;*
;* load - load into a from address pointer addrh/addrl
;*
;* input: addrh/addrl = address
;*
;* output: a=byte from pointed location
;* x is transparent
;* work1, work2, work3 used
;*
;*
load: stx *work1 ; save x
ldx #0xc6 ; c6=lda 2 byte extended
ldstcm: stx *work2 ; put opcode in place
ldx #0x81 ; 81=rts
stx *work3 ; now the return
jsr *work2 ; execute built in routine
ldx *work1 ; restore x
rts ; and exit
;*
;*
;* store - store a at address in pointer addrh/addrl
;*
;* input: a=byte to store
;* addrh/addrl= address
;* output: c=0 store went ok
;* c=1 store did not take (not ram)
;* registers transparent (a not transparent on
;* invalid store)
;*
;*
store: stx *work1 ; save x
ldx #0xc7 ; c7=sta 2 byte extended
bsr ldstcm ; call store routine
sta *work4 ; save value stored
bsr load ; attempt load
cmp *work4 ; valid store?
beq strts ; branch if valid
sec ; show invalid store
strts: rts ; return
;*
;*
;* ptrup1 - increment memory pointer
;*
;*
ptrup1: lda *addrl
inca
sta *addrl ; increment low byte
bne prtrts ; non zero means no carry
lda *addrh
inca
sta *addrh ; increment high byte
prtrts: rts ; return to caller
;*
;*
;* putbyt - print a in hex
;*
putbyt: sta *work1 ; save a
lsra ; shift to
lsra ; left hex
lsra ; digit
lsra ; shift high nybble down
bsr putnyb ; print it
lda *work1
;*
;* fall into putnyb
;*
;*
;* putnyb - print lower nybble of a in hex
;* a,x transparent
;*
;*
putnyb: and #0xf ; mask off high nybble
add #'0 ; add ascii zero
cmp #'9 ; check for a-f
bhi putny2
jmp chrout ; ok, send out
putny2: add #'a-'9-1 ; adjustment for hex a-f
jmp chrout ; now send out
;*
;*
;* pdata - print monitor string after cr/lf
;* pdata1 - print monitor string
;* pcrlf - print cr/lf
;*
;* input: x=offset to string in base page
;*
;*
pcrlf: ldx #msgnul-mbase ; load null string address
pdata: lda #cr ; prepare carriage return
pdloop: jsr chrout ; send next character
pdata1: lda mbase,x ; load next character
incx ; bump pointer up one
cmp #eot ; end of string?
bne pdloop ; branch no
rts ; return done
;*
;*
;* getnyb - obtain next hex character
;*
;* output: c=0 not hex character,a=delimiter
;* c=1 hex input, a=binary value
;* work1 in use
;*
getnyb = .
jsr chrin ; get char
getnyb2:
cmp #'0
blo getnch ; hex ?
ora #0x20 ; mask for upper/lower case

cmp #'9
bls getnhx
cmp #'a
blo getnch
cmp #'f
bhi getnch

sub #7
getnhx: and #0x0f ; clear ascii bits
sec
rts
getnch: clc
rts
;*
;* getadr - build any size binary number from input
;* leading blanks skipped
;*
;* output: cc = 0 no number entered
;* 1 addrh/addrl has number
;* a = delimiter
;* a,x volatile
;*
;* work1 used
;*
getadr: jsr putsp
lda #0x00
sta *addrh ; clear high byte
bsr getnyb ; obtain first hex value
bcs getgtd ; branch if got it
cmp #0x20 ; is it a space?
beq getadr ; loop if so
clc ; clear carry
rts ; return no number
getgtd: sta *addrl ; initialize low value
getalp: bsr getnyb ; obtain next hex
bcc getarg ; branch if none
asla ; over
asla ; four
asla ; bits
asla ; for shift
ldx #4 ; loop four times
getasf: asla ; shift next bit
sta *asave
lda *addrl
rola
sta *addrl ; into low byte
lda *addrh
rola
sta *addrh ; into hi byte
lda *asave
decx ; count down
bne getasf ; loop until done
bra getalp ; do next hex
getarg: sec ; show number obtained
rts
;*
;* chrin - obtain next input character
;*
;* output: a = character received
;* x is transparent
;* nulls ignored
;* all characters echoed out
;*
;* work1 used
;*
chrin: lda duart+1 ; get status
lsra ; test rcvr reg flag
bcc chrin ; loop until char recvd
lda duart+3 ; get character

and #0x7f ; and off parity
beq chrin ; ignore nulls
sta *work1
bsr chrout ; echo character
lda *work1
rts
;*
;* hochrin - obtain next character from host port
;* same characteristics as chrin
;*
hochrin:
lda duart+9 ; get status
lsra
bcc hochrin ; check rdrf
lda duart+0x0b
and #0x7f ; off with the parity
rts
;*
;*
;* puts - print a space character
;* x unchanged
;*
putsp: lda #sp ; load a space char
;*
;* fall into chrout
;* * chrout - send a character to terminal
;* cr has added line feed
;*
;* input: a = ascii char to send
;*
;* a nopt transparent
;*
chrout: cmp #cr ; cr to send ?
bne chrou2
bsr chrou2 ; recursive call for cr
lda #lf ; send lf char

chrou2: sta *savea
chrou3: lda duart+1 ; get status register
bit #0x04 ; check tdre
beq chrou3 ; branch till done
lda *savea
sta duart+3 ; write data register
rts

;*
;* hosout - send character to host
;*
hosout: sta *savea
chrouh: lda duart+9 ; get status
bit #0x04 ; check tdre
beq chrouh ; branch till done
lda *savea
sta duart+0x0b ; send character
rts

;*
;* reset - power-on reset routine
;*
;* init duart (both sides), put out startup msg
;*
reset: clrx
clra
clear: sta *bkptbl,x ; clear breakpoint table
incx
cpx #0x0a
bne clear

ldx #11 ; move vector table to ram
rst: lda vectab,x ; to allow changes on fly
sta *vecram,x
decx
bpl rst
;*

lda #0x06 ; mode
sta duart
sta duart+8

lda #0xbb ; baud
sta duart+1
sta duart+9

lda #0x07 ; one stopbit
sta duart
sta duart+8

lda #0x80 ; counter mode
sta duart+4
sta duart+0xc

lda #0x08
sta duart+5
sta duart+0xd

lda #0x15 ; init cmd register
sta duart+2
sta duart+0xa

jsr scnbkp ; clear breakpoints
;*
resren: lda #0x0
sta *swiflg ; setup monitor entrance value
swi ; enter monitor
bra resren ; reenter if 'g'
;*
;* command handler
;*
cmdpdt: jsr pdata ; send msg out
cmd1: jsr pcrlf ; to new line
cmdnnl: lda #prompt ; ready prompt char
jsr chrout ; send it out
jsr rembkp ; remove breakpoints
jsr chrin ; get char from user
ora #0x20 ; mask for uc or lc
clrx ; zero for some commands
cmp #0x0d ; ignore a cr
beq cmdnnl
cmp #'c ; dis/chg cc reg ?
beq cmdc
cmp #'x ; dis/chg x reg ?
beq cmdx
cmp #'a ; dis/chg a reg
beq cmda
cmp #'r ; display all registers
bne notv
jmp regr
notv: cmp #'g ; go ?
bne notg
lda *work4
ora #0x80
sta *work4
isp: jmp cmdg ; go to it
;*
notg: cmp #'m ; memory display/change ?
bne notm
jmp cmdm
notm: cmp #'t ; trace ?
bne notw
jmp cmdt
notw = .
cmp #'b ; breakpoint command ?
beq bpnt ; yes
cmp #'p ; pc command ?
bne notp
lda *work4
and #0x7f
sta *work4
bra isp
;*
notp = .
cmp #'e ; display/change timer data
beq cmde
cmp #'f ; display/change timer control
beq cmdf
cmp #'i ; displ/chng interrupt vector
beq cmdi
cmp #'j ; displ/chng timer vector
beq cmdj
cmp #'d ; download
beq downld
cmp #'h ; host comm
beq hostit
cmp #'k ; displ/chng timer wait vector
bne cmderr
jmp cmdk
;*
cmderr: ldx #msgerr-mbase ; load error string
tocpdt: jmp cmdpdt ; and send it out
regr: jmp cmdr
bpnt: jmp cmdb
downld: jmp down
hostit: jmp host
;*
;* x - display/change x register
;*
cmdx: incx
;*
;* a - display change acc
;*
cmda: incx
;*
;* c - display/change cc register
;*
cmdc: jsr putsp ; space before value
stx *work1 ; save index value
jsr locstk ; locate stack address
txa ; stack-2 to a
add *work1 ; add proper offset
add #4 ; make up for address return difference
sta *addrl ; and set inlow
lda #0x0
sta *addrh
tomchg: jmp mchnge ; now enter memory change command
;*
;* e - display/change timer data register
;*
cmde: jsr putsp ; give a space
lda #>(workpg+(work8-bkptbl)) ; high byte of work8 address
sta *addrh ; save in memory pointer
lda #<(workpg+(work8-bkptbl)) ; low byte of work8 address
sta *addrl ; save in memory pointer
jmp mchnge ; handle as memory change
;*
;* f - display/change timer control register
;*
cmdf: jsr putsp ; give a space
lda #>(workpg+(work9-bkptbl)) ; high byte of work9 address
sta *addrh
lda #<(workpg+(work9-bkptbl)) ; low byte of work9 address
sta *addrl
jmp mchnge ; handle as memory change
;*
;* i - display/change interrupt vector
;*
cmdi: jsr putsp ; give a space
lda *vecram+7 ; get current vector hi byte
jsr putbyt ; display it
lda *vecram+8 ; get lo byte
jsr putbyt ; display it
jsr putsp ; separate with a space
jsr getadr ; get address from user
bcc cmdinc ; no number entered ?
;*
cmdiok: sta *vecram+7 ; save hi byte of vector
lda *addrl ; get lo byte
sta *vecram+8 ; save lo byte of vector
;*
cmdinc: jmp cmdnnl ; return to command handler
;*
;* j - display/change timer interrupt vector
;*
cmdj: jsr putsp ; give a space
lda *workd ; get user vector hi byte
jsr putbyt ; display in hex
lda *worke ; get user vector lo byte
jsr putbyt ; display in hex
jsr putsp ; give a space
jsr getadr ; get address from user
bcc cmdjnc ; no number ?
cmdjok = .
sta *workd ; save hi byte
lda *addrl
sta *worke
cmdjnc: jmp cmdnnl ; return to command handler
;*
;* k - display/change timer wait mode vector
;*
cmdk: jsr putsp ; give a space
lda *vecram+1 ; get current vector hi byte
jsr putbyt ; display it in hex
lda *vecram+2 ; getllo byte
jsr putbyt ; display in hex
jsr putsp ; give a space separation
jsr getadr ; get new vector from user
bcc cmdknc ; no number input ?
;*
cmdkok = .
sta *vecram+1 ; save hi byte of new vector
lda *addrl ; get lo byte
sta *vecram+2 ; save lo byte
;*
cmdknc: jmp cmdnnl ; return to command handler
;*
;* swi handler
;*
;* determine processing swiflg value
;*
swi: lda *timec ; save user timer environemt
sta *work9 ; first the control register
lda #0x40 ; then mask timer
sta *timec
lda *timer ; then save the timer register
sta *work8
lda *vecram+4 ; then save users vector
sta *workd
lda *vecram+5
sta *worke
lda #>(monstr+(tirq-mbase)) ; timer vector high address
sta *vecram+4
lda #<(monstr+(tirq-mbase)) ; timer vector low address
sta *vecram+5
clrx ; default to startup msg
lda *swiflg ; is this reset
bne swichk ; if not, remove breakpoints
inca
sta *swiflg ; show we are now initialized
jmp cmdpdt ; to command handler
;*
swichk: jsr scnbkp
swirep: lda *bkptbl,x ; restore opcode
bmi swinob
sta *addrh
lda *bkptbl+1,x
sta *addrl
lda *bkptbl+2,x
jsr store
;*
swinob: incx
incx
incx
lda *pncnt
deca
sta *pncnt
bne swirep
;*
;* trace one instruction if pc at a breakpoint
;*
jsr locstk ; findsstack
lda 8,x ; get pc and adjust
sub #1
sta *work4 ; save pc low byte
lda 7,x
sbc #0
sta *work3 ; save pc hi byte
stx *work5
jsr scnbkp
;*
switry: lda *bkptbl,x
bmi swicmp
cmp *work3
bne swicmp
lda *bkptbl+1,x
cmp *work4
bne swicmp
ldx *work5
sta 8,x
lda *work3
sta 7,x
lda #0x0
sta *work7
lda #1
sta *work6
jmp trace
;*
swicmp: incx
incx
incx
lda *pncnt
deca
sta *pncnt
bne switry
;*
;* fall into register display for breakpoint
;*
;* r - display registers
;*
cmdr: jsr pcrlf ; add text for register displays
stx *savex
ldx #msgpc-mbase
jsr pdata
ldx *savex
jsr pcrlf

jsr putsp ; give a space
bsr locstk ; locate stack-4
lda 7,x
sta 7,x
jsr putbyt ; display in hex
lda 8,x ; offset into pc lo byte
bsr crbyts ; to hex and space
lda 5,x ; offset to accc
bsr crbyts ; to hex and space
lda 6,x ; offset to x reg
bsr crbyts
lda 4,x ; offset to cc reg
ora #0xe0 ; set unused bits on
sta 4,x ; restore
bsr crbyts ; hex and space
txa ; stack pointer -3
add #8 ; to users stack pointer
bsr crbyts ; hex and space
gtocmd: jmp cmd1 ; return to command handler
;*
;* print address subroutine (x unchanged)
;*
prtadr: lda *addrh ; load hi byte
jsr putbyt ; displayphex
lda *addrl ; load lo byte
crbyts: jsr putbyt ; hex out
jmp putsp ; follow with a space
;*
;* locstk - locate callers stack pointer
;*
;* returns x=stack pointer-3
;*
;* a volatile
;*
locstk: bsr locst2 ; leave address on stack
stkhi = >(monstr + (.-mbase)) ; hi byte on stack *******
stklow = <(monstr + (.-mbase)) ; low byte on stack
rts
;*
locst2: ldx #0x7f ; load high stack word address
loclop: lda #stkhi ; high byte for compare
locdwn: decx ; to next lower byte in stack
cmp ,x ; this the same ?
bne locdwn ; if not, try next lower
lda #stklow ; compare with low address byte
cmp 1,x ; found return address ?
bne loclop ; loop if not
rts
;*
;* b - breakpoint clear, set, or display
;*
cmdb: jsr chrin ; read next character
cmp #0x20 ; display only ?
bne bdsply ; branch if so
bsr pgtadr ; obtain breakpoint number
tstx ; any high byte value
bne bkerr ; if so, error
deca ; down count by one
cmp #numbkp ; too high ?
bhs bkerr ; if so, error
asla ; times two
add *addrl ; plus one for three times
deca
sta *work2 ; save address
bsr pgtadr ; obtain address
ldx *work2 ; reload entry pointer
sta *bkptbl+1,x ; save low address
bne bknocl ; branch if not zero
lda *addrh ; load high address
bne bkncr ; branch not null a
sta *bkptbl,x ; store as high byte
jmp cmd1 ; end command
;*
bknocl: lda *addrh ; load high address
bkncr: sta *bkptbl,x ; store high byte
jsr load ; load byte at the address
coma ; invert it
jsr store ; attempt store
bcs bkerr1 ; error if did not store
coma ; restore proper value
jsr store ; store it back
bra gtocmd ; end command
;*
;* display breakpoints
;*
bdsply: jsr scnbkp ; prepare scan of table
bdsplp: lda *bkptbl,x ; obtain high byte
cmp #0x00 ; see if cleared
bne godisp ; it's not, go display em
lda *bkptbl+1,x ; what about lower byte
cmp #0x00 ; is it a 00 also
beq bdskp ; yep, its unused slot

godisp: lda *bkptbl,x ; go get 1st byte againo
jsr putbyt ; print out high byte
lda *bkptbl+1,x ; load low byte
bsr crbyts ; print it out with a space
;*
bdskp: incx ; to next entry
incx
incx
lda *pncnt
deca
sta *pncnt ; count down
bne bdsplp ; loop if more
jmp cmd1 ; end command
bkerr: jmp cmderr ; give error response

bkerr1: clra
sta *bkptbl,x
sta *bkptbl+1,x ; clear out old stuff
bra bkerr
;*
pgtadr: jsr getadr ; obtain input address
bcc bkerr ; abort if none
ldx *addrh ; ready high byte
lda *addrl ; ready low byte
rts
;*
;* t - trace instruction(s) command
;*
cmdt: lda #1 ; default count
sta *addrl ; to one get adr clears addrh
jsr getadr ; build address if any
lda *addrh ; save value in temporary
sta *work7 ; locations for later
lda *addrl
sta *work6
;*
;* setup timer to trigger interrupt
;*
trace = .
jsr locstk
lda 4,x ; get current user i mask
and #8
sta *work5
lda 7,x ; get current user pc
sta *addrh
lda 8,x
sta *addrl
jsr load ; get opcode
cmp #0x83 ; swi ?
bne trace3 ; if so, inc user pc
lda *addrl
add #1
sta 8,x
lda *addrh
adc #0
sta 7,x
bra tirq ; continue to trace
;*
trace3: cmp #0x9b ; sei ?
bne trace2 ; if so, set it in the stack
lda 4,x
ora #8
sta 4,x
lda *addrl
add #1
sta 8,x
lda *addrh
adc #0
sta 7,x

bra tirq ; continue to trace
;*
trace2: cmp #0x9a ; cli ?
bne trace1
lda #0x0
sta *work5
;*
trace1: lda 4,x
and #0xf7
sta 4,x
lda #16 ; then setup timer
sta *timer
lda #8
sta *timec
rti ; execute one instruction
;*
;* tirq - timer interrupt routine
;*
tirq = .
lda #0x40 ; restore i mask to proper state
sta *timec
jsr locstk
lda 4,x
ora *work5
sta 4,x
;*
;* see if more tracing is desired
;*
lda *work6
deca
sta *work6
bne trace
lda *work7
beq disreg
deca
sta *work7
bra trace
disreg: jmp cmdr
;*
;* int - interrupt routine
;*
irq = .
jmp cmderr ; hardware interrupt unused
;*
;* twirq - timer interrupt routine - wait mode
;*
twirq = .
jmp cmderr ; timer wait interrupt unused
;*
;* delbpk - delete breakpoint subroutine
;*
rembkp: bsr scnbkp ; setup parameters
bpl remrts ; return if not in
remlop: lda *bkptbl,x ; load high address
bmi remnob ; skip if null
sta *addrh
lda *bkptbl+1,x ; load low address
sta *addrl
lda *bkptbl+2,x ; load opcode
jsr store
;*
remnob = .
incx ; to next entry
incx
incx
lda *pncnt
deca
sta *pncnt ; count down
bne remlop ; loop if more
lda *swiflg ; make positive to show removed
coma
sta *swiflg
remrts: rts
;*
;* setup for breakpoint table scan
;*
scnbkp = .
lda #numbkp
sta *pncnt
clrx
lda *swiflg
rts

iserr0: jmp cmderr
;*
;********************************************************
;*
;* download from standard host only
;* D
;*
;********************************************************
;*
down: jsr pcrlf ; start new line on terminal
jsr chrin ; get 1st char after "d"

load1: cmp #0x0d ; is it ?
beq iserr0 ; yes - error
cmp #0x20 ; no, is it a space?
bne load2 ; no, start of command
jsr chrin ; yes, extract lead character
bra load1 ; test for valid start character

load0: jsr chrin ; get next char in buffer from term
load2: jsr hosout ; go send to host
cmp #0x0d ; ready, at end of command?
bne load0 ; no, get next character
jsr pcrlf ; clear line for him
jmp cmdlt ; go check for s1-s9

;*
;* clbyte -
;*
;* load subroutne to read next byte, adjust
;* checksum, and decrement count

;* output: A = Byte
;* cc = reflects count decrement
;*

clbyte: jsr hgetbyt ; obtain next byte from host
bcs clbyt1 ; if one
jmp cmdmin ; error if none
clbyt1: sta *work2 ; save value
add *chksum ; add to checksum
sta *chksum ; replace
lda *work2 ; reload value
decx ; count down
rts
;*
;* hgetbyt - ready byte in hex subroutine gotten from host
;*
;* output: c=0,z=1 no number
;* c=0,z=0 invalid number
;* c=1,z=1 A=binary byte value
;*
hgetbyt:
jsr getnyb1 ; get next hex digit
bcc hgetbrz ; return no number
hgetby2:
asla ; shift
asla ; over
asla ; by
asla ; four
sta *work2
jsr getnyb1 ; getlow hex
tsta ; force z=0
bcc hgetbrt ; return if invalid number
ora *work2 ; combine hex digits
hgetbrz:
clr *0x0f ; set z=1
hgetbrt:
rts ; return to caller

getnyb1:
jsr hochrin ; get input from host
jsr getnyb2 ; make sure it's ok
rts


;*
;* getbyt - same as above, but done for term port
;*
getby2: asla
asla
asla
asla
sta *work2
jsr getnyb
tsta
bcc getbrt
ora *work2
getbrz: clr *0x0f
getbrt: rts




;*
;*
;* search for an 'S'
;*
cmdlt: jsr hochrin ; read a character from host
cmdlss: cmp #'S ; is it an s?
bne cmdlt ; loop if not
jsr hochrin ; read second character
cmp #'9 ; is it a 9?
beq cleof ; branch to end of file
cmp #'1 ; an s1 record?
bne cmdlss ; nope, try again
;*
;* read address and count
;*
lda #0x00
sta *chksum ; zer0 checksum
jsr clbyte ; obtain size of record
tax ; start countdown in x reg
jsr clbyte ; obtain start address
sta *addrh ; store it
jsr clbyte ; obtain low address
sta *addrl ; store it
;*
;* now load text
;*
clload: jsr clbyte ; next char
beq cleor ; branch if count done
jsr store ; store character
jsr ptrup1 ; up address pointer
bra clload ; loop until count depleted
;*
;* end of record
;*
cleor: lda *chksum
inca
sta *chksum
beq cmdlt
jmp cmderr
;*
;* end of file
;*
cleof: jsr clbyte ; read s9 length
tax ; prepare s9 flush count
cleofl: jsr clbyte ; skip hex pair
bne cleofl ; branch more
jmp cmd1





;*
;******************************************************************
;*
;* "h" host communications
;*
;* h []
;*
;*****************************************************************
;*
host: ldx #ctla ; default terminator
jsr chrin ; go get next character
cmp #0x0d ; cr?
beq strm ; yes, set default terminator
tax
strm: stx *sava ; save it
jsr pcrlf ; new line
host1: bsr tsthst ; test for host input
;*
;* test for terminal input
;*
tsttrm: lda duart+1 ; terminal input?
rora ; shift rxrdy to carry bit
bcc host1 ; nope, check host
lda duart+3 ; yep, get character
tax ; save it (parity unmasked)
and #0x7f ; now mask
cmp *sava ; char = terminator?
beq mtop ; yep, terminate mode.
dowth: lda duart+9 ; get status of host mode
bit #0x04
beq dowth ; wait till ready to xmit
stx duart+0x0b ; send it!
bra host1 ; continue

mtop: jmp cmd1
;*
;* test for host input
;*
tsthst: lda duart+9 ; host input?
rora ; shift rxrdy to carry bit
bcc return ; no char pending
ldx duart+0x0b ; yep, get character
tstwait:
lda duart+01 ; status of terminal port?
bit #0x04 ; wait till txrdy
beq tstwait
stx duart+3 ; send the char to the terminal
return: rts
;*
;* interrupt vectors
;*
.org 0x1ff6
;*
.word vecram ; timer interrupt wait mode
.word vecram+3 ; timer interrupt
.word vecram+6 ; external interrupt handler
.word vecram+9 ; swi handler
.word reset ; power-on vector
;*