.title MONDEB - 09 ; ********************************************************* ; * * ; * MONDEB - 09 - a monitor/debugger * ; * for the 6809 microprocessor * ; * * ; ********************************************************* ; ; author: Don Peters (6800 version) ; date: April 1977 ; ; modified for the 6809 ; by: Alan R. Baldwin ; date: Nov 1988 ; ; This 6809 monitor/debugger does not use the ; direct page addressing mode. Thus the user ; program has complete control of the page ; assignment and may use the monitor routines ; without concern for variable locations. ; ; To add user functions to MONDEB - 09 ; ; 1) add your commands to the end of command list #1 ; 2) add the command entry points to the jump table ; 3) append any local command lists after MONDEB's ; 4) provide an external initialization routine to ; set up the console (and/or alternate) ; ports and any other start up processing. ; MONDEB will call 'userinit' if inituser = 1. ; .module mond09 standalone = 0 ; standalone flag indicating the ; vectors and associated code are ; to be included during assembly inituser = 0 ; call 'userinit' flag indicating ; a user startup routine will be ; called during intialization .page .sbttl MONDEB - 09 working variables .radix d .if standalone .area WORKPG (REL,CON) .else .area WORKPG (ABS,OVR) .endif .setdp 0 workpg: .blkb 256-(endpg-mstack) ; main stack storage mstack: .blkb 12 ; stack storage for rti instruction ttybuf: .blkb 72 ; start of input line buffer ttyend: .blkb 1 ; end of input line buffer bufbeg: .blkb 2 ; input line start of buffer bufend: .blkb 2 ; input line end of buffer comadr: .blkb 2 ; address of beginning of command lists synptr: .blkb 2 ; input line character pointer for good syntax linptr: .blkb 2 ; input line character pointer (content => ; content of synptr) bolflg: .blkb 1 ; "beginning of line flg" delim: .blkb 1 ; characters permitted as valid command/modifier ; delimiter ibcode: .blkb 1 ; input base (1=hex, 2=dec, 3=oct) dbcode: .blkb 1 ; display base (1=hex, 2=dec, 3=oct, 4=bin) dbnbr: .blkb 1 ; display base number (e.g., 16,10,8, or 2) nbrhi: .blkb 1 ; most significant byte of scanned number nbrlo: .blkb 1 ; least significant byte of scanned number ranglo: .blkb 2 ; range lower limit picked up by gtrang ranghi: .blkb 2 ; range upper limit picked up by gtrang verfrm: .blkb 2 ; beginning address of range to verify verto: .blkb 2 ; ending address of range to checksum verify chksum: .blkb 1 ; checksum of range given in the verify command brkadr: .blkb 2 ; address of inserted breakpoint brkins: .blkb 1 ; instruction which should be there normally inpflg: .blkb 1 ; alternate input flag outflg: .blkb 1 ; alternate output flag outadr: .blkb 2 ; alternate address that the output chars go to hdxflg: .blkb 1 ; half-duplex terminal flag (if non-zero, no echo) cplcnt: .blkb 1 ; "characters per line" count cplmax: .blkb 1 ; "characters per line" maximum ; temporary (locally used) variables temp1: .blkb 2 ; in: main temp2: .blkb 2 ; in: main temp3: .blkb 2 ; in: main temp4: .blkb 2 ; in: main temp5: .blkb 2 ; in: main temp6: .blkb 2 ; in: main nummat: .blkb 1 ; used in command lisnum: .blkb 1 ; used in command comnum: .blkb 1 ; used in command lisptr: .blkb 2 ; used in command decdig: .blkb 1 ; decimal digit being built numbhi: .blkb 1 ; used by outnum numblo: .blkb 1 ; used by outnum nbr2x: .blkb 2 ; used by number timcon: .blkb 2 ; delay time constant bytect: .blkb 1 ; record byte count used in load command cksm: .blkb 1 ; record checksum used in load command conin: .blkb 2 ; address of console input routine conout: .blkb 2 ; address of console output routine altin: .blkb 2 ; address of alternate input routine altout: .blkb 2 ; address of alternate output routine .rsrvd: .blkb 2 ; reserved vector .swi3: .blkb 2 ; swi3 vector .swi2: .blkb 2 ; swi2 vector .firq: .blkb 2 ; firq vector .irq: .blkb 2 ; irq vector .swi: .blkb 2 ; swi vector .nmi: .blkb 2 ; nmi vector spsave: .blkb 2 ; saved stack pointer endpg: ; convenient equivalences for local variables memadr = temp1 ; display, set, search, test strnum = temp2 ; fndstr eoschr = temp2+1 ; fndstr ; for "search" command bytptr = temp2 nbytes = temp3 nbrmat = temp3+1 bytstr = temp4 ; other constants cr = 13 ; carriage return lf = 10 ; line feed .page .sbttl MOND09 Startup .if standalone .area MONDEB (REL,CON) reset: lds #mstack+12 ; load stack pointer bsr mond09 ; stack pc and start mondeb bra reset .else .area MONDEB (ABS,OVR) .endif mond09: pshs u,y,x,dp,b,a,cc ; pseudo swi sts spsave ; save the pointer orcc #0b01010000 ; hold irq and firq interrupts lds #mstack ; initialize the stack pointer jsr inital ; initialize variables jsr docrlf ; advance to a clean line ldx #msghed ; get address of header jsr outstr ; type it ldx #ttybuf-1 ; get address of terminal input buffer stx bufbeg ; save it ldx #ttyend ; define end of input buffer stx bufend ; 72 char capacity, incl cr lda #3 ; delimiter class definition sta delim ; space or comma (code 3) bra promp1 ; prepare to get a new command prompt: jsr docrlf ; type cr-lf inc bolflg ; set 'beginning of line' flag ldx synptr ; point to current character lda ,x ; get it cmpa #'; ; semicolon? beq getcmd ; continue scan if it is, ; skipping the prompt promp1: ldx #msgprm ; type prompt jsr outstr jsr getlin ; get line of input cmpb #3 ; abort line on a control-c beq prompt ldx bufbeg ; set syntax scanning pointer stx synptr ; to beginning of buffer/line lda 1,x ; get first char jsr tsteol ; reprompt on an empty line beq prompt ; (first char = cr,lf,or ;) .page .sbttl Get Command getcmd: lda #1 ; use list 1 when matching jsr comand ; now go for a match beq prompt ; reprompt if just a cr was typed bgt jmpcmd ; good command if positive badsyn: ldx bufbeg ; get start of line 1$: cpx linptr ; space over to the error in syntax beq 2$ ; at error ? jsr outsp ; output a space inx ; no, move on bra 1$ ; the 'extra' char '1' is compensated for by the prompt ; char on the preceeding line 2$: lda #'^ ; at error - get an up-arrow jsr outchr ; print it jsr docrlf bra promp1 ; ignore any succeeding packed ; commands ; ******* ; *there should be no more characters on the input line ; (except delimiters) nomore: jsr skpdlm bcs prompt ; if carry bit set, end of line ; (normal) bra badsyn ; there is something there but shouldn't be .page .sbttl Command Dispatcher ; ****** ; execute a computed 'goto' to the proper command jmpcmd: asla ; multiply command by 2 ldx #1$-2 jmp [a,x] ; jump to designated command 1$: .word break .word contin .word compar .word copy .word displa .word dbase .word delay .word dump .word goto .word help .word ibase .word load .word reg .word set .word search .word test .word verify .word cli .word clf .word sei .word sef .word xirq .word xfirq .word xnmi .word xrsrvd .word xswi .word xswi2 .word xswi3 .page .sbttl REG - display registers reg: ; print stack stored swi data disreg: ldx spsave ; get saved stack pointer clr comnum ; start at beginning of the ; register name list bsr 1$ ; type condition codes bsr 1$ ; type acca bsr 1$ ; type accb bsr 1$ ; type dp jsr docrlf ; advance to a clean line bsr 2$ ; type index reg x bsr 2$ ; type index reg y bsr 2$ ; type index reg u jsr docrlf ; advance to a clean line leax -9,x ; back to d bsr 2$ ; type d leax 7,x ; back to pc bsr 2$ ; type program counter ; type the stack pointer location bsr 3$ ; type stack pointer id ldx #spsave jsr out2by ; type the value jmp nomore ; output content of a 1 byte register 1$: bsr 3$ jsr out1by inx rts ; output content of a 2 byte register 2$: bsr 3$ jsr out2by leax 2,x ; skip to next word in stack rts ; misc setup for register display 3$: jsr outsp ; output a space inc comnum ; skip to next register name lda #5 ; register name is in list 5 jsr typcmd ; type it jsr outeq ; type an '=' rts .page .sbttl Software Interrupt Entry Point typswi: sts spsave ldx #msgswi jsr outstr ; decrement pc so it points to 'swi' instruction ldx spsave ldd 10,x subd #1 cmpd brkadr ; a break point ? bne disreg ; no - allow to pass std 10,x ; backup PC bra disreg ; go display registers .sbttl GOTO - Go To Memory Address goto: jsr mnumber ; get destination beq contin ; if none, just continue ldd nbrhi lds spsave ; place new PC std 10,s ; fall through to Continue .sbttl Continue - Continue From a 'SWI' contin: lds spsave ; in case sp was modified via set rti ; command .sbttl SEI - Set Interrupt Mask sei: orcc #0b00010000 jmp nomore .sbttl CLI - Clear Interrupt Mask cli: andcc #~0b00010000 jmp nomore .sbttl SEF - Set Fast Interrupt Mask sef: orcc #0b01000000 jmp nomore .sbttl CLF - Clear Fast Interrupt Mask clf: andcc #~0b01000000 jmp nomore .page .sbttl COPY - Copy From One Location To Another copy: jsr gtrang ; get source range into ranglo & ; ranghi lble badsyn ; error if no source jsr mnumber ; get destination lble badsyn ; error if no destination ldx ranglo ; get source address pointer ldu nbrhi ; get destination address pointer lda ,x ; get byte from source 1$: sta ,u+ ; save byte in destination cpx ranghi ; compare to end of input range lbeq nomore ; done if equal lda ,x+ ; get byte from source bra 1$ ; loop for next byte .page .sbttl BREAK - Set Breakpoint at Specified Address break: jsr mnumber ; get breakpoint location bmi 3$ ; if not numeric, look for '?' beq 2$ ; if no modifier, remove old breakpoint ldx brkadr ; get current break address lda ,x ; and the char there cmpa #0x3f ; compare to 'swi' bne 1$ ; equal? lda brkins ; yes, restore the old instruction sta ,x ; restore it 1$: ldx nbrhi ; get new breakpoint stx brkadr ; save it lda ,x ; get instruction stored there sta brkins ; save it lda #0x3f ; get code for software interrupt sta ,x ; put it at breakpoint bra 5$ ; all done 2$: ldx brkadr ; get address of break lda ,x ; get inst. there cmpa #0x3f ; swi? bne 5$ ; if not, return & prompt lda brkins ; was a swi - get previous inst. sta ,x ; & restore it bra 5$ 3$: lda #4 jsr comand ; scan for it lble badsyn ; bad syntax if not '?' ldx brkadr ; it is, get break address lda ,x ; get instruction there cmpa #0x3f ; is it a 'swi'? beq 4$ ; if yes, say so ldx #msgnbr ; get that message jsr outstr ; say it bra 5$ 4$: ldx #msgbat ; get that message jsr outstr ; say it ldx #brkadr ; get break address jsr out2by ; type it 5$: jmp nomore .page .sbttl IBASE - Set Input Base ibase: lda #3 ; look for hex,dec,or oct in list #3 jsr comand bmi 2$ ; unrecognizable base, try'?' bgt 1$ lda #1 ; no base given - default to hex 1$: sta ibcode ; save base code jmp nomore 2$: lda ibcode ; get ib code in case its needed pshs a ; save it on stack temporarily bra ibdbq .sbttl DBASE - Set Display Base dbase: lda #3 ; look for hex,dec,oct, or bin in list #3 jsr comand bmi 3$ ; unrecognizable base, try '?' bgt 1$ lda #1 ; no base given - default to hex 1$: sta dbcode ldx #2$-1 ; get numeric base from table lda a,x sta dbnbr ; save it jmp nomore ; done 2$: .byte 16 ; display base table .byte 10 .byte 8 .byte 2 3$: lda dbcode ; get db code in case its needed pshs a ; save it on stack temporarily ibdbq: lda #4 ; look for '?' in list #4 jsr comand puls b ; retrieve input base/display base code lble badsyn ; error if the 'something' was not a '?' lda #3 ; base code is in list 3 stb comnum ; store base code jsr typcmd ; type out base jmp nomore .page .sbttl Display - Display Memory Data displa: jsr gtrang ; get memory display range lble badsyn ; address is required ldx ranglo ; initialize address pointer stx memadr lda #6 ; search list 6 for jsr comand ; display modifiers 'data' or 'used' lbmi badsyn ; any other modifier is illegal deca ; adj display modifier code so that: sta comnum ; -1=addr & data, 0=data, 1=used clrb ; init 'data values per line' counter incb 1$: ldx #memadr tst comnum ; which display option? bmi 6$ ; if 'address & data', go there decb ; count data values per line bne 2$ ; if count not up, skip address output jsr docrlf ; get to line beginning jsr out2by ; output address jsr outsp ; and a space ldb dbnbr ; reset line counter 2$: ldx memadr ; point to data at that address tst comnum ; want 'data' option? bgt 3$ ; if not, go to 'used' code jsr outsp ; output preceedng space bra 7$ 3$: lda ,x ; get the data bne 4$ lda #'. ; its zero, get a '.' bra 5$ 4$: lda #'+ ; its non-zero, get a '+' 5$: jsr outchr ; output the '.' or '+' bra 8$ 6$: jsr outsp ; output a preceeding space jsr out2by ; type address jsr outeq ; type '=' ldx ,x ; get content 7$: jsr out1by ; type it 8$: cpx ranghi ; are we done lbeq nomore ; if yes, back to prompt inx ; no, inc memory address stx memadr ; save it bra 1$ .page .sbttl SET - Set Memory Locations set: jsr gtrang ; get memory location/range bmi 5$ ; if not an address, look for a ; register name lbeq badsyn ; an address modifier is required ; range of address specified? ldx ranglo cpx ranghi beq 2$ ; if single address, set up ; addresses individually ; set a range of addresses to a single value jsr mnumber ; get that value lble badsyn ; its required lda nbrlo ; put it in acca 1$: sta ,x ; store it in destination cpx ranghi ; end of range hit? lbeq nomore ; if yes, all done inx ; no, on to next address in range bra 1$ ; loop to see it ; set addresses up individually 2$: stx memadr ; save memory loc 3$: jsr mnumber ; get data to put there beq 4$ ; end of line? lblt badsyn ; abort if bad syntax lda nbrlo ; load data byte ldx memadr ; load address sta ,x+ ; store data bra 2$ 4$: ldx synptr ; point to end of line lda ,x ; get char there cmpa #lf ; line feed? lbne nomore ; if not,back to prompt ldx #memadr ; yes, get next address to be set jsr out2by ; type it jsr outsp ; and a space jsr getlin ; get a new line ldx bufbeg ; get buffer beginning stx synptr ; equate it to syntax scan pointer bra 3$ ; go pick up data ; look for (register name, register value) pairs 5$: lda #5 jsr comand ; pick up a register name lbmi badsyn ; error if unrecognizable lbeq nomore ; done if end of line pshs a ; save register name(number) jsr mnumber ; get new register value puls a ; restore register name(number) lble badsyn ; got good register value? deca ldu #6$ lda a,u leau a,u ldx spsave ; yes, point to top of stack ldd nbrhi ; get register value jsr ,u ; go to function bra 5$ ; and loop 6$: .byte 7$-6$ .byte 8$-6$ .byte 9$-6$ .byte 10$-6$ .byte 11$-6$ .byte 12$-6$ .byte 13$-6$ .byte 14$-6$ .byte 15$-6$ .byte 16$-6$ 7$: stb ,x ; condition codes rts 8$: stb 1,x ; acca rts 9$: stb 2,x ; accb rts 10$: stb 3,x ; dp rts 11$: std 4,x ; ix rts 12$: std 6,x ; iy rts 13$: std 8,x ; iu rts 14$: std 1,x ; d rts 15$: std 10,x ; pc rts 16$: std spsave ; sp rts .page .sbttl Checksum Verify a Block of Memory verify: jsr gtrang ; get a number range beq 1$ ; no modifier means check what we have lbmi badsyn ; anything else is illegal ldx ranglo ; good range given, stx verfrm ; transfer it to checksum addresses ldx ranghi stx verto bsr cksum ; compute checksum sta chksum ; save it ldx #chksum ; type the checksum jsr out1by bra 3$ 1$: bsr cksum ; compute checksum cmpa chksum ; same as stored checksum? bne 2$ ldx #msgver ; they verify - say so jsr outstr bra 3$ 2$: ldx #msgnve ; they don't - say so jsr outstr 3$: jmp nomore ; compute the checksum from addresses verfrm to verto ; return the checksum in acca cksum: clra ; init checksum to zero ldx verfrm ; get first address dex ; init to one less 1$: inx ; start of checksum loop adda ,x ; update checksum in acca with ; byte pointed to cpx verto ; hit end of range? bne 1$ ; if not, loop back coma ; complement the sum rts ; return with it .page .sbttl Search Memory for Byte String ; global variables used ; linptr - input line character pointer ; lisptr - command list character pointer ; ranglo - 'search from' address ; ranghi - 'search to' address ; ; local variables used ; memadr - starting memory address where a match ; occurred ; bytptr - address pointer used to fill bytstr and ; substr buffers ; nbytes - number of bytes in byte string ; nbrmat - number of chars that match so far in the ; matching process ; bytstr - starting address of 6 character byte sring ; buffer ; ; the search string occupies temp4, temp5, & temp6 ; (6 bytes max) search: jsr gtrang ; get search range lble badsyn ; abort if no pair ldx #bytstr ; get start of byte string ; to search for stx bytptr ; set pointer to it clr nbytes ; zero # of bytes in byte string 1$: jsr mnumber ; get a byte string beq 2$ ; begin search if eol lblt badsyn ; good byte, add it to string inc nbytes ; count this byte lda nbytes ; don't accept over 6 bytes cmpa #6 lbgt badsyn lda nbrlo ; get (low order) byte ldx bytptr ; get byte pointer sta ,x+ ; save byte, bump pointer stx bytptr ; save it bra 1$ 2$: tst nbytes ; is # of bytes to look for >0 lbeq badsyn ; if not,bad syntax ldx ranglo ; initialize memory pointer dex stx linptr 3$: ldx #bytstr-1 ; initialize byte pointer stx lisptr clr nbrmat ; set 'number of bytes that ; matched' to zero jsr getlst ; get byte from byte string 4$: jsr mgetchr ; get byte from memory range cba ; compare memory & byte string ; characters beq 5$ ; if no match, test for range end cpx ranghi ; have we reached the range ; search upper limit? lbeq nomore ; yes, go prompt for next command bra 4$ 5$: stx memadr ; match achieved - save address of match 6$: inc nbrmat ; bump number matched lda nbrmat cmpa nbytes ; have all characters matched? beq 8$ ; if so, match achieved jsr getlst ; haven't matched all yet, go get next pair jsr mgetchr ; even if past 'search to' address cba beq 6$ 7$: ldx memadr ; mismatch on some byte past the first one cpx ranghi ; this test handles special case lbeq nomore ; of a match on range end stx linptr bra 3$ ; go reset the byte string pointer 8$: ldx #memadr ; match on byte string achieved, jsr out2by ; type out memory address jsr outsp ; and a space bra 7$ .page .sbttl Test Ram test: jsr gtrang ; get an address range lble badsyn ; abort if no pair ldu ranglo ; ranglo holds starting address of range ; ranghi holds ending address of range 1$: lda ,u ; get byte stored at test location pshs a ; save it clr ,u ; zero the location tst ,u ; test it beq 2$ ; ok if = zero ldx #msgccl ; can't clear location bra 4$ 2$: dec ,u ; set location to $ff lda #0xff cmpa ,u ; did it get set to $ff? beq 3$ ldx #msgcso ; can't set location to one's bra 4$ 3$: puls a sta ,u ; restore previous content cmpu ranghi ; hit end of test range? lbeq nomore ; yes, all done leau 1,u ; no, move to test next location bra 1$ 4$: stx temp3 ; save error message temporarily ldx #temp4 stu ,x jsr out2by ; type out bad address jsr outeq ; and equal sign ldx temp4 jsr out1by ; its content jsr outsp ; a space ldx temp3 jsr outstr ; and the type of error jsr docrlf bra 3$ .page .sbttl vector settup commands ; rsrvd - set up rsvd pointer xrsrvd: jsr numinx ; get pointer in ix stx .rsrvd ; save it jmp nomore ; swi3 - set up swi3 pointer xswi3: jsr numinx ; get pointer in ix stx .swi3 ; save it jmp nomore ; swi2 - set up swi2 pointer xswi2: jsr numinx ; get pointer in ix stx .swi2 ; save it jmp nomore ; firq - set up interrupt pointer xfirq: jsr numinx ; get pointer in ix stx .firq ; save it jmp nomore ; irq - set up interrupt pointer xirq: jsr numinx ; get pointer in ix stx .irq ; save it jmp nomore ; swi - set up swi pointer xswi: jsr numinx ; get pointer in ix stx .swi ; save it jmp nomore ; nmi - set up non-maskable interrupt pointer xnmi: jsr numinx ; get ponter in ix stx .nmi ; save it jmp nomore .page .sbttl compare numbers ; compare - output sum & difference of two input numbers compar: jsr numinx ; get first number stx ranglo ; put it in ranglo jsr numinx ; get second number stx nbrhi ; save it in nbrhi ; compute and output the sum jsr sumnum ; compute sum ldx #msgsis ;get its title bsr 1$ ; output title & sum jsr difnum ; compute difference ldx #msgdis ; get its title bsr 1$ ; output title & diff jmp nomore ; compute and output the result 1$: jsr outstr ; output it ldx #ranghi ; get result jsr out2by ; display result rts .page .sbttl dump memory in S1-S9 format ; ***** ; dump - dump portion of memory in S1-S9 format ; ; get address range: start in ranglo (2 bytes), end in ; ranghi (2bytes) ; if no address range is given, use whatever is n ; ranlo & ranghi dump: jsr gtrang clr temp5 ; initialize to dump to terminal 1$: lda #2 ; look for a 'TO' modifier jsr comand beq 2$ lble badsyn ; error if bad syntax cmpa #1 ; TO ? bne 1$ ; go look for another modifier jsr numinx ; get 'TO' address stx outadr ; save it inc temp5 ; remember this bra 1$ ; go look for another modifier 2$: tst temp5 beq 3$ inc outflg ; set flag for proper output device 3$: ldd ranghi ; compute # of bytes to output subd ranglo ; subtract lo bytes cmpd #16 ; diff 0-15. bcs 5$ 4$: ldb #15 ; to get frame count, add 1 ; (diff of 0 implies 1 output) + # of data bytes ; + 2 addr bytes + 1 checksum byte 5$: addb #4 stb temp3 ; temp3 is the frame count subb #3 stb temp4 ; temp4 is the record byte count ldx #msgs1 ; output a 'S1' header data record jsr outstr clrb ; zero checksum ldx #temp3 ; punch frame count bsr 7$ ldx #ranglo ; punch address bsr 7$ bsr 7$ ldx ranglo ; load memory pointer 6$: bsr 7$ ; output data byte dec temp4 ; dec byte count bne 6$ stx ranglo ; save memory pointer comb ; complement checksum pshs b ; put it on stack tfr s,x ; let ix point to it bsr 7$ ; output checksum puls b ; pull it off stack ldx ranglo ; restore memory pointer dex cpx ranghi ; hit end of range? bne 3$ ldx #msgs9 ; yes, output an 'S9' record jsr outstr clr outflg ; set to terminal output jmp nomore 7$: jsr out1by ; output a byte pointed to by ix as addb ,x+ ; 2 hex characters, update checksum rts .page .sbttl Load S1-S9 format Data load: jsr inpchr ; get a char cmpa #'S ; is it an S ? bne load jsr inpchr ; got an 'S', examine next character cmpa #'9 ; done if its a '9' beq 3$ cmpa #'1 ; is it a '1'? bne load ; if not, look for next 'S' clr cksm ; clear checksum jsr 5$ ; read record byte count suba #2 sta bytect ; save count minus 2 address bytes bsr 4$ ; build address 1$: bsr 5$ ; read a data byte into acca dec bytect ; count it beq 2$ ; if done with record, check checksum sta ,x+ ; not done, store byte in memory bra 1$ ; on to next memory address 2$: inc cksm ; test checksum by adding 1 beq load ; if ok, result should be zero ldx #msgnve ; record checksum error jsr outstr ldx #temp1 ; get record address of it jsr out2by ; type it too 3$: clr inpflg ; reset flag to normal terminal input jmp nomore 4$: bsr 5$ ; build address sta temp1 bsr 5$ sta temp1+1 ldx temp1 rts 5$: bsr 6$ ; get left hex digit asla ; move to hi 4 bits asla asla asla tab ; save it in acca bsr 6$ ; get right hex digit aba ; combine then in acca tab ; update the checksum addb cksm stb cksm rts 6$: jsr inpchr ; input a hex char & convert to internal form suba #'0 bmi 8$ ; not hex if below ascii '1' cmpa #'9-'0 ble 7$ ; ok if ascii '9' or less cmpa #'A-'0 ; below ascii 'A'? bmi 8$ ; error if it is cmpa #'F-'0 ; over ascii 'F'? bgt 8$ ; error if it is suba #7 ; conv ascii A-F to hex A-F 7$: rts 8$: ldx #msgcnh ; error - char not hex, say so jsr outstr rts .page .sbttl Delay Function ; ***** ; delay - delay specified # of milliseconds delay: jsr numinx ; get delay time bsr timdel jmp nomore ; ***** ; time delay subroutine ; ix is input as the # of milliseconds to delay ; adj timcon so (7*timcon*cycle time=1 ms) timdel: pshs d 1$: ldd timcon 2$: subd #1 ; a 7 cycle loop bne 2$ dex ; decrement millisecond counter bne 1$ puls d,pc .page .sbttl Help List help: jsr docrlf ; next line ldx #comlst ; command list 1$: ldb #4 ; commands per line stb temp1 2$: ldb #12 ; positions per command ; must be larger than longest command 3$: lda ,x+ ; get character cmpa #cr ; is end of command beq 4$ jsr outchr ; print command character decb bne 3$ 4$: lda ,x ; get character cmpa #lf ; is end of list beq 6$ ; finished dec temp1 ; per line done ? bne 5$ ; no - skip jsr docrlf ; next line bra 1$ 5$: lda #' ; space jsr outchr decb bne 5$ bra 2$ 6$: jsr docrlf ; next line jmp nomore .page .sbttl Command Lists ;================================================ ; ; c o m m a n d l i s t s c a n n i n g ; r o u t i n e ; ; this routine seeks a match of the characters pointed ; at by the input line scanning pointer to one of the ; commands in a list specified by acca. ; the result of the scan for a match is returned in ; acca as follows: ; ; acca=-1: the match was unsuccessful. the syntax ; pointer (synptr) was not updated ; (advanced). ; ; acca= 0: the match was unsuccessful since there ; were ; no more characters, i.e., the end of ; the ; line was reached. ; ; acca=+n: successful match. the syntax pointer ; was updated ; to the first character following the ; command ; delimiter. acca holds the number of ; the ; command matched. ; global variables for external communication ; synptr - good syntax input line char pointer ; linptr - input line character pointer ; delim - class of permissible command delimiters ; ; temporary 2 byte internal variables ; lisptr - command list character pointer ; ; temporary 1 byte internal variables ; nummat - number of characters that successfully match ; lisnum - # of list within which a match will be sought ; comnum - command number matched ; ; constants used ; cr - carriage return ; lf - line feed ; ; a, b & ix are not preserved comand: sta lisnum ; save list # to match within jsr skpdlm ; test if we are at the end of the line bcc 1$ clra rts ; initialize the command list pointer to one less than ; the beginning of the command lists 1$: ldx comadr ; entry point ; move to the beginning of the desired command list lda lisnum ; search for 'string' # lisnum ldb #lf ; use lf as a 'string' terminator bsr fndstr stx lisptr ; the list pointer, lisptr, now points to one less than ; the first character ; of the first command in the desired list clr comnum ; reset input line pointer to: 1) beginning of line, or ; to 2) point where last successful scan terminated 2$: inc comnum ; initialize the command # to 1 ldx synptr stx linptr clr nummat ; clear number of characters ; matched 3$: jsr mgetchr ; get input line char in accb jsr tstdlm ; test for a delimiter bne 4$ ; success (found delimiter) jsr getlst ; get command list char in acca cmpa #lf ; has end of command list been reached ? beq 5$ ; if so, potential match failure cmpa #cr ; has end of command been reached ? beq 5$ ; if so, potential match failure cba ; compare the two characters bne 6$ ; match not possible on this command inc nummat ; they match, compare the succeeding characters bra 3$ ; inc number of characters matched 4$: ldx linptr ; successful match stx synptr ; update good syntax pointer lda comnum ; return command number rts ; no match 5$: tst nummat ; did at least one match? beq 6$ ; to next command if none matched jsr tstdlm ; at least one matched - test for delimiter bne 4$ ; if a delimiter, match has been achieved lda ,x ; retrieve last character ; illegal delimiter ; move to next command within list 6$: cmpa #lf ; end of this list? beq 7$ ; if so, nothing on list matched cmpa #cr ; is it a cr? beq 2$ ; yes, next command jsr getlst ; get next command list character bra 6$ ; no, get to end of command 7$: clra ; match failure deca ; no match possible within this list rts .page .sbttl Typeout Command ;==================================== ; this routine types out command number "comnum" ; the list is specified in acca ; accb & ix are preserved typcmd: pshs b,x ldx #comlst-1 ; move to head of command lists ldb #lf ; and list terminator bsr fndstr ; go to head of desired list lda comnum ; get command number ldb #cr ; get command terminator bsr fndstr ; go to head of desired command 1$: inx ; move to next character lda ,x ; get a command character cmpa #cr ; is it a command terminator? beq 2$ ; if so, return jsr outchr ; no, type it bra 1$ 2$: puls b,x,pc .page .sbttl Find string ;====================================== ; move to beginning of desired string number (in acca) ; each string is terminated by an end of string ; character (in accb) ; the index register is assumed initialized pointing to ; one less than the first character of the first string ; acca, accb & ix are not preserved ; local variables ; strnum - string # to find ; eoschr - "end of string" character fndstr: sta strnum ; save string number stb eoschr ; save terminator clrb 1$: incb ; string 1 is the first string cmpb strnum ; is this the right string? beq 3$ ; if so, done ; no, swallow up characters until an end of string char is hit 2$: inx ; bump pointer to next one lda ,x ; get char pointed at cmpa eoschr ; end of string hit? beq 1$ ; if it is, bump the string counter bra 2$ ; no, move on to next char 3$: rts ; ix set properly, return .page .sbttl Skip Leading Delimiters ;================================================= ; skip leading delimiters ; this routine should be called prior to scanning for ; any information ; on the input line ; the current character is ignored if the scannng ; pointer is at the beginning of a line. if not, the ; scanning pointer skips over spaces and commas ; until an end of line or non-delimiter is found. ; the carry bit is set if and end of line is encountered. ; acca, accb, & ix are not preserved skpdlm: clc tst bolflg ; at beginning of line? bgt 2$ ; look at current input character 1$: ldx synptr ; get pointer to it lda ,x ; get char bsr tsteol ; test for end of line bne 2$ sec ; yes, end hit, set carry rts ; "peek" at next char in line 2$: ldb 1,x ; get it bsr tstdlm ; see if its a delimiter bne 3$ rts ; if not, return ; next char is a delimiter 3$: jsr mgetchr ; move to next char in input line stx synptr ; update syntax pointer bra 1$ ; go test for end of line .page .sbttl Test for End-of-Line Character ;============================================ ; test for end-of-line character ; z bit of cc reg set if char in acca is a terminator ; acca, accb, & ix are preserved tsteol: cmpa #cr ; carriage return? beq 1$ cmpa #lf ; line feed? (continued lines) beq 1$ cmpa #'; ; for several commands on one line 1$: rts .sbttl Test for Delimeter ;=============================================== ; check the character n accb aganst the delimiter(s) ; specified by variable delim ; accb & ix are preserved ; acca is set to 0 if accb is not a delimiter, to 1 ; if it is ; if delim=1, space s delimiter ; if delim=2, comma is delimiter ; if delim=3, space or comma is delimiter ; if delim=4, any non-alphanumeric is a delimiter ; test for end-of-line (logical or physical) tstdlm: pshs b tba bsr tsteol puls b beq 5$ lda delim cmpa #1 bne 1$ cmpb #' ; want a space - is it? bne 6$ bra 5$ 1$: cmpa #2 bne 3$ 2$: cmpb #', ; want a comma - is it? bne 6$ bra 5$ 3$: cmpa #3 bne 4$ cmpb #' ; want either, is it a space? beq 5$ bra 2$ ; or a comma? 4$: cmpa #4 bne 7$ ; error if delm not 1-4 cmpb #'0 ; test if char is 0-9 inclusive blt 5$ cmpb #'9 ble 6$ cmpb #'A ; test if char is A to Z inclusive blt 5$ cmpb #'Z ble 6$ ; over Z - its a delimiter 5$: lda #1 ; char in accb is a delimiter rts 6$: clra ; char in accb is not a delimiter rts ; error in specifying delimiter class 7$: swi ; have monitor type out pertinent ; statistics .page .sbttl Sum Two Numbers ;================================================ ; add the 2 byte number stored in (ranglo,ranglo+1) to ; the number stored in (nbrhi,nbrlo) and put the result ; in (ranghi,ranghi+1) sumnum: pshs d ; add lo order bytes ldd ranglo addd nbrhi std ranghi puls d,pc .sbttl Subtract Two Numbers ;==================================================== ; subtract the 2 byte number stored in (nbrhi,nbrlo) ; from the two byte number stored in (ranglo,ranglo+1) ; and put the result in (ranghi,ranghi+1) ; accb & ix are preserved ; acca is altered difnum: pshs d ; subtract lo order bytes ldd ranglo subd nbrhi std ranghi puls d,pc .page .sbttl Get Range ;=================================================== ; this routine scans the input line for a pair of numbers ; representing an address range. a colon separating the ; pair implies "thru", while an "!" implies "thru the ; following" ; e.g., 100:105 is equivalent to 100!5 ; a single number implies a range of 1 ; on return (ranglo,ranglo+1) holds the range start, and ; (ranghi,ranghi+1) holds the range end ; acca, accb, & ix are not preserved gtrang: bsr mnumber ; pick up first number bgt 1$ blt 2$ rts ; nothing more on input line 1$: ldx nbrhi ; good single number stx ranglo ; transfer it to ranglo bra 3$ ; and to ranghi ; bad number, but is it bad due to a ":" or "!" delimiter? ; get the terminator for the first number 2$: ldx linptr lda ,x cmpa #': ; was it a colon? bne 4$ ; if not, go test for "!" bsr 8$ ; was ":", process first number & ; get next one ble 5$ ; illegal if end of line or non-numeric 3$: ldx nbrhi ; transfer second number to ranghi stx ranghi bra 7$ 4$: cmpa #'! ; was delimiter a "!"? beq 6$ ; if yes, get 2nd number clra ; illegal delimiter, return deca 5$: rts 6$: bsr 8$ ; was "!", process first number & ; get next one ble 5$ bsr sumnum ; compute range end, put into ranghi 7$: lda #1 ; successful exit rts ; update syntax pointer, move first number to ranglo, ; & get 2nd number 8$: stx synptr ; update syntax pointer ldx nbrhi ; get first number of the pair stx ranglo ; save it in "low range" value bsr mnumber ; pick up the second number of the pair rts .page .sbttl Get number in IX ;==================================================== ; get a 2 byte number & return it in the index register numinx: bsr mnumber bgt 1$ jmp badsyn 1$: ldx nbrhi rts .page .sbttl Scan For a Number ;================================================== ; scan for a number ; return the most significant byte in nbrhi ; and the least significant byte in nbrlo ; the result of the scan for a number is returned in ; acca as follows: ; ; acca=-1: the match was unsuccessful. the syntax ; pointer (synptr) was not updated. ; ; acca= 0: the scan was unsuccessful since there ; were no more characters. (i.e., the end ; of the line was encountered.) ; ; acca=+1: the scan was successful. the syntax ; pointer was updated to the first character ; following the command. ; ; ix is preserved ; global variables for external communication ; nbrhi - number hi byte ; nbrlo - number lo byte ; ibcode - input base code ; dbcode - display base code ; ; local variables ; nbr2x - used in decimal conversion ; initialize both bytes to zero mnumber:pshs x ; save ix clr nbrhi clr nbrlo ldx synptr ; initialize the line scanning pointer stx linptr jsr skpdlm ; are we at end of line? bcc 1$ clra ; yes, zero acca puls x,pc 1$: jsr mgetchr ; get a character from the input ; line into accb jsr tstdlm ; test for a delimiter bne 6$ ; good delimiter if acca is non-zero subb #'0 ; subtract ascii 0 bmi 8$ ; error if less lda ibcode ; determine input base & go to right routine cmpa #1 ; hex code ? beq 2$ cmpa #2 ; decimal code ? beq 4$ cmpa #3 ; octal code ? beq 5$ ; hex input processing 2$: cmpb #'9-'0 ; default an illegal input base to hex ble 3$ ; if 9 or less cmpb #'A-'0 bmi 8$ ; not hex if < A cmpb #'F-'0 bgt 8$ ; not hex if > F subb #7 ; move A-F above 0-9 3$: bsr 9$ ; shift lo & hi bytes left 4 bits bsr 9$ orb nbrlo stb nbrlo bra 1$ ; decimal input 4$: cmpb #9 bgt 8$ ; not decimal if > 9 ; multiply saved value by 10 & add in new digit bsr 10$ ; multiply current number by 2 to get 2x value ldx nbrhi ; save this *2 number temporarily stx nbr2x bsr 9$ ; multiply this # by 4 to get 8x value clra ; new digit addd nbr2x ; note that 10x=2x+8x bcs 8$ ; carry out of ms byte is an error addd nbrhi bcs 8$ ; carry out of ms byte is an error std nbrhi ; save result bra 1$ ; octal input 5$: cmpb #7 bgt 8$ ; not octal if > 7 bsr 9$ ; shift hi & lo bytes 3 places left bsr 10$ ; carry out of hibyte is illegal orb nbrlo ; add in new digit stb nbrlo bra 1$ 6$: ldx linptr ; good number - scan was successful stx synptr ; update good syntax line pointer lda #1 ; set "good scan" flag puls x,pc 7$: leas 2,s 8$: clra ; conversion error - scan was unsuccessful deca puls x,pc 9$: asl nbrlo ; shift a two byte number left one position rol nbrhi bcs 7$ 10$: asl nbrlo ; shift a two byte number left one position rol nbrhi bcs 7$ rts .page .sbttl General Output Routines ;=========================================== ; output a space outsp: lda #' jsr outchr rts ;=========================================== ; output an "=" sign outeq: lda #'= jsr outchr rts ;========================================== ; output a 1 byte number out1by: pshs d ldb #1 bsr outnum puls d,pc ;========================================== ; output a 2 byte number out2by: pshs d ldb #2 bsr outnum puls d,pc ;========================================== ; display the number pointed at by the address in the ; index register and output it according to the base ; specified in "dbcode" ; leading zeros are included ; acca & ix are preserved ; accb is input as the number of bytes comprising the ; number. ; global variables for external communication ; ibcode - input base code ; dbcode - display base code ; ; local variables ; decdig - decimal digit being built ; numbhi - hi byte of number being output ; numblo - lo byte of number being output outnum: pshs d,x ; save these ldx ,x ; get the two bytes at that address stx numbhi ; put them in a scratch area for processing lda dbcode ; get display base cmpa #1 beq 1$ cmpa #2 beq 4$ cmpa #3 beq 11$ cmpa #4 beq 14$ ; output a hex number 1$: aslb ; 1 byte=2 chars, 2 bytes=4 chars 2$: bsr 16$ ; get next 4 bits bsr 16$ anda #0x0f ; extract 4 bits cmpa #9 ble 3$ adda #7 ; convert 10:15 to A-F 3$: bsr 18$ decb bne 2$ puls d,x,pc ; restore registers & return ; output a decimal number 4$: decb ; test # of bytes to output beq 5$ ldx #9$ ; initialize for output of a 2 byte number ldd numbhi bra 6$ 5$: ldx #10$ ; initialize for output of a 1 byte number clra ldb numbhi 6$: clr decdig ; clear the digit to output 7$: subd ,x ; subtract the power of 10 conversion constant bcs 8$ ; test for borrow (carry) inc decdig ; no borrow yet - nc digit being built bra 7$ ; repeat loop ; building of digit to output is complete - print it 8$: pshs a ; save lo byte of number being output lda decdig ; get digit bsr 18$ ; print it puls a ; restore lo byte addd ,x++ ; borrow generated - cancel last subtraction cpx #9$+10 ; are we thru with units conversion? bne 6$ ; if not, back to get next digit puls d,x,pc ; if yes, restore registers & return ; decimal output conversion constants 9$: .word 10000 .word 1000 10$: .word 100 .word 10 .word 1 ; output an octal number 11$: aslb ; first approximation of # of clra ; digits to output cmpb #2 bgt 12$ bsr 16$ ; 1 byte - get first 2 bits bsr 18$ bra 13$ ; go output last 2 digits 12$: bsr 17$ ; two byte # - output hi order bit/digit bsr 18$ incb ; 5 more digits to go 13$: bsr 16$ ; get next 3 bits bsr 17$ anda #7 ; extract 3 bits bsr 18$ decb ; count this digit bne 13$ ; are we done? puls d,x,pc ; if yes, restore registers & return 14$: aslb ; output a binary number aslb aslb 15$: bsr 17$ ; get next bit anda #1 ; extract the bit bsr 18$ ; output it decb ; count it bne 15$ ; are we done? puls d,x,pc ; if yes, restore registers & return 16$: bsr 17$ ; left shift 2 bits 17$: asl numblo ; left shift the 3 byte number 1 bit rol numbhi rola rts 18$: adda #'0 ; convert to a numeric ascii digit & output it jsr outchr rts .page .sbttl Get Character Routines ;================================================= ; this routine gets the next character from the input ; line buffer ; acca is preserved ; accb is loaded with the character ; ix is incremented and left pointing to the character ; returned mgetchr: ldx linptr inx ldb ,x stx linptr clr bolflg ; set flag to not at "beginning of line" rts ;================================================== ; this routine gets the next character in the command ; lists ; acca is the character retrieved ; accb is preserved ; ix is incremented & left pointing to the character returned getlst: ldx lisptr ; get current list pointer inx ; move pointer to next character lda ,x ; get character pointed at stx lisptr ; save pointer rts ; and return .page .sbttl Command Lists ;===================================================== ; command lists ; a carriage return signifies end-of-command ; a line feed signifies end-of-command-list ; list 1 - major commands comlst: .ascii /BREAK/ ; set breakpoint (swi code) .byte cr .ascii /CONTINUE/ ; continue from "swi" .byte cr .ascii /COMPARE/ ; print sum & difference of 2 numbers .byte cr .ascii /COPY/ ; copy from one location to another .byte cr .ascii /DISPLAY/ ; display memory data .byte cr .ascii /DBASE/ ; set display base .byte cr .ascii /DELAY/ ; delay specified # of bytes .byte cr .ascii /DUMP/ ; dump memory in mikbug or image format .byte cr .ascii /GOTO/ ; go to memory address .byte cr .ascii /HELP/ ; help listing .byte cr .ascii /IBASE/ ; set input base .byte cr .ascii /LOAD/ ; load mikbug tape .byte cr .ascii /REG/ ; display registers .byte cr .ascii /SET/ ; set memory data .byte cr .ascii /SEARCH/ ; search memory for a byte string .byte cr .ascii /TEST/ ; test a range of memory .byte cr .ascii /VERIFY/ ; verify that memory content is unchanged .byte cr .ascii /CLI/ ; clear interrupt mask .byte cr .ascii /CLF/ ; clear fast interrupt mask .byte cr .ascii /SEI/ ; set interrupt mask .byte cr .ascii /SEF/ ; set fast interrupt mask .byte cr .ascii /IRQ/ ; set interrupt pointer .byte cr .ascii /FIRQ/ ; set fast interrupt pointer .byte cr .ascii /NMI/ ; set non-maskable interrupt pointer .byte cr .ascii /RSRVD/ ; set reserved interrupt pointer .byte cr .ascii /SWI/ ; set software interrupt pointer .byte cr .ascii /SWI2/ ; set swi2 interrupt pointer .byte cr .ascii /SWI3/ ; set swi3 interrupt pointer .byte cr .byte lf ; end of list 1 ; list 2 - modifier to dump .ascii /TO/ ; destination .byte cr .byte lf ; end of list 2 ; list 3 - number base specifiers .ascii /HEX/ ; base 16 .byte cr .ascii /DEC/ ; base 10 .byte cr .ascii /OCT/ ; base 8 .byte cr .ascii /BIN/ ; base 2 .byte cr .byte lf ; end of list 3 ; list 4 - information request .ascii /?/ .byte cr .byte lf ; end of list 4 ; list 5 - register names .ascii /.CC/ .byte cr .ascii /.A/ .byte cr .ascii /.B/ .byte cr .ascii /.DP/ .byte cr .ascii /.IX/ .byte cr .ascii /.IY/ .byte cr .ascii /.IU/ .byte cr .ascii /.AB/ .byte cr .ascii /.PC/ .byte cr .ascii /.SP/ .byte cr .byte lf ; end of list 5 ; list 6 - modifiers to "display" .ascii /DATA/ .byte cr .ascii /USED/ .byte cr .byte lf ; end of list 6 ; list 7 - modifier to "load" .ascii /FROM/ ; source .byte cr .byte lf ; end of list 7 .page .sbttl Get a line ;======================================================= ; ; this routine constructs a line of input by getting all ; input characters up to and including a carriage return ; (which then designates "end of line"). ; typing rubout will delete the previous character ; typing control-c will abort the line ; typing control-z will use the previous line ; the input line is stored beginning at the address ; stored in bufbeg and ending at the address stored ; in bufend ; acca, accb, & ix are not preserved ; ; global variables ; bufbeg - input line start of buffer ; bufend - input line end of buffer ; ; local constants getlin: ldx bufbeg ; set pointer to one less than ; the beginning of the line buffer clrb ; accb holds last input char 1$: cpx bufend ; check current line end against buffer end bne 2$ ; line too long - abort it as if a control-c had been typed ldx #msgltl ; get message jsr outstr ; output it ldb #3 ; put ctl-c in accb rts 2$: jsr inpchr ; get a character (returned in acca) anda #0x7f ; drop parity bit ; control-z copies from present position to previous end of line cmpa #26 ; is char a control-z? bne 3$ jsr docrlf ; yes, type cr-lf rts 3$: cmpa #13 ; is char a cr? beq 4$ cmpa #10 ; or a lf? bne 6$ 4$: inx sta ,x ; yes, store the terminator tst hdxflg ; test for half-duplex terminal bne 5$ jsr docrlf ; type cr-lf 5$: rts ; now return 6$: cmpa #3 ; is char a control-c? bne 7$ ; no tab ; return ctl-c in accb lda #'^ ; echo an up-arrow jsr outchr rts 7$: cmpa #127 ; no, is it delete? beq 10$ ; yes - delete character inx ; not a delete, so advance to next char sta ,x ; store it in inplin tab ; last character in b tst hdxflg ; check half duplex bne 9$ ; yes - skip jsr outchr ; echo character 9$: bra 1$ ; get another ; current character is a delete ; test line length - if its zero, ignore this delete ; since we can't delete prior to first char in input line 10$: cpx bufbeg beq 1$ pshs x ldx #11$ ; delete character on screen bsr outstr puls x ldb ,-x ; last character bra 1$ 11$: .byte 8,32,8,4 ; BS, SPACE, BS, EOT ;==================================================== ; initialization routine inital: lda #1 sta ibcode ; set input base to hex sta dbcode ; set display base to hex ; set up display base number lda #16 sta dbnbr ; max # of characters per line lda #72 sta cplmax clr inpflg ; default input from terminal clr outflg ; default output to terminal clr hdxflg ; clear half-duplex flag ; set up swi interrupt address pointer ldx #typswi ; type "swi" & do "reg" command stx .swi ; clear breakpoint address ldd #0xfffe ; normal systems have rom here std brkadr ; initialize to mondeb's command lists ldx #comlst-1 stx comadr ; time constant for a .5 microsecond clock ldd #285 std timcon .if inituser jmp userinit ; user returns via rts .else rts .endif ;=================================================== ; output a character string which begins at the address ; in the index register ; acca & accb are preserved ; ix is left pointing to the string terminator outstr: pshs a 1$: lda ,x ; get char pointed to cmpa #4 ; is it a string terminator? beq 2$ ; done if it is bsr outchr ; isn't, output it inx ; on to next char bra 1$ 2$: puls a,pc ;===================================================== ; input a character inpchr: tst inpflg ; console ? bne 2$ 1$: jsr [conin] ; tst for a character bcc 1$ ; none - loop until there is rts 2$: jsr [altin] ; tst for a character bcc 2$ ; none - loop until there is rts ;====================================================== ; output the character in acca to the desired output ; device/location ; if outflg = 0, output is to terminal ; if outflg # 0, output is to address in outadr ; & this address is then incremented outchr: pshs d,x ; save d and x ldb outflg ; test output destination flag decb ble 1$ ; skip this code if terminal output ; output to something other than terminal ldx outadr ; get output char destination addr sta ,x+ ; save char in memory stx outadr ; update output address puls d,x,pc 1$: cmpa #lf ; ignore line feeds bne 2$ puls d,x,pc 2$: cmpa #cr ; test for carriage return bne 3$ bsr docrlf puls d,x,pc 3$: ldb cplcnt ; get "chars per line" count cmpb cplmax bge 4$ ; send cr-lf if greater ; less than max, but also send cr-lf if 10 from end and ; printing a space addb #10 cmpb cplmax blt 5$ cmpa #' ; near end, test if about to print a space bne 5$ ; terminal line full or nearly full - interject a cr-lf 4$: bsr docrlf 5$: inc cplcnt ; bump counter bsr chrout ; send it to acia1 puls d,x,pc ;====================================================== ; send a carriage return-line feed to the terminal docrlf: pshs d lda #cr bsr chrout lda #lf bsr chrout clr cplcnt ; zero "chars/line" count puls d,pc ;====================================================== ; send char in acca chrout: tst outflg ; check destination bne 1$ jmp [conout] ; output a character 1$: jmp [altout] ;====================================================== ; misc text msghed: .ascii /MONDEB-09 1.00/ .byte cr,4 msgprm: .byte '*,4 msgswi: .byte cr,lf .ascii /swi:/ .byte cr,lf,4 msgltl: .ascii /too long/ .byte 4 msgnbr: .ascii /not set/ .byte 4 msgbat: .ascii /set @ / .byte 4 msgver: .ascii /ok/ .byte 4 msgnve: .ascii /checksum error / .byte 4 msgccl: .ascii /can't clear/ .byte 4 msgcso: .ascii /can't set to ones/ .byte 4 msgsis: .ascii /sum is / .byte 4 msgdis: .ascii /, dif is / .byte 4 msgs1: .byte cr,lf,0,0,'S,'1,4 msgs9: .byte cr,lf,0 .ascii /S9030000FC/ .byte cr,lf,4 msgcnh: .ascii /char not hex/ .byte cr,4 ;**************************************************** ;* default interrupt transfers * ;**************************************************** .if standalone rsrvd: jmp [.rsrvd] ; reserved vector swi3: jmp [.swi3] ; swi3 vector swi2: jmp [.swi2] ; swi2 vector firq: jmp [.firq] ; firq vector irq: jmp [.irq] ; irq vector swi: jmp [.swi] ; swi vector nmi: jmp [.nmi] ; nmi vector .endif .page .sbttl dispatch table .if standalone .area DISPAT (REL,CON) .word timdel ; time delay for # of ms specified by ix .word cksum ; return checksum of an address range in acca .word mgetchr ; return (in accb) char pointed to by linptr .word getlst ; return (in acca) char pointed to by lisptr .word gtrang ; pick up an address range in ranglo & ranghi .word mnumber ; pick up a number & return it in nbrhi & nbrlo .word skpdlm ; skip over input line delimiters .word tstdlm ; test char in accb for a delimiter .word tsteol ; test char in acca for end-of-line .word comand ; search specified command list for a command .word typcmd ; types out command number "comnum" in list acca .word out1by ; display the 1 byte number pointed at by ix .word out2by ; display the 2 byte number pointed at by ix .word getlin ; get a line of input into the tty buffer .word outstr ; output char string ix points to .word docrlf ; send cr-lf with delay & zero line count .word outchr ; like chrout, but with folding, cr delay, & lf .word chrout ; send acca to console .word inpchr ; get a char, return it in acca .word prompt ; to prompt for new command .word mond09 ; start of mondeb .endif .page .sbttl Hardware Interrupt Tables ;******************************************************** ;* MONDEB-09 hardware vector table ;* ;* this table is used if the MONDEB-09 rom addresses ;* the mc6809 hardware vectors. ;******************************************************** .if standalone .area INTVEC (ABS,OVR) . = 0xFFF0 ; vector position .word rsrvd ; reserved slot .word swi3 ; software interrupt 3 .word swi2 ; software interrupt 2 .word firq ; fast interrupt request .word irq ; interrupt request .word swi ; software interrupt .word nmi ; non-maskable interrupt .word reset ; restart .endif