.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 ;*