*****************************************************************************)
*                                                                           *)
*                                                                           *)
*    Program  : M68000 Monitor for the POSIE Dist. Sys. Monitor Board       *)
*                                                                           *)
*    Purpose  :                                                             *)
*                                                                           *)
*                                                                           *)
*                                                                           *)
*    Name     : Vinod E.F. REBELLO                                          *)
*                                                                           *)
*    Class    : CS & E 4                                                    *)
*                                                                           *)
*    Username : VEFR                                                        *)
*                                                                           *)
*    Date     : 1st April 1989         Version 1.0                          *)
*               10 Oct 1990     Attempted port to Interpretation Processor  *)
*                               Note subr03.asm has changed and prompt(Msgs)*)
*                                                                           *)
*    Tutor    : Damal K. ARVIND                                             *)
*                                                                           *)
*****************************************************************************)


* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* First we have subroutine file
*
	incl	subr03.asm
*
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* INITIALISATION code
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
*
main:	jsr inits	* initialise 
*
* INITIALIZE saved register frame
*
* sets A0 to point at top of frame. D0-7/A0-6 cleared, A7(SSP)
* points to SR,SR: ints disabled, supervisor mode, trace on
* PC :=stoplp,USP :=$016ffe
* note this code cannot be put in a subroutine as adds to stack
*
	pea stoplp	* set up pc
	move.w sr,-(sp)	* save sr
	or.w #$0a700,(sp)	* ints disabled,sup. mode, trace on
	move.l sp,-(sp)	* save sp
	move.l #14,d2	* 15 more registers to save
pushlp:	move.l #0,-(sp)	* save zero long word
	dbra d2,pushlp	* repeat as rqd
	move.l sp,a0	* set a0 to point at frame
	move.l #$016ffe,a4	* init usp
	move.l a4,usp
*
*	move.b #$00,brkflg	* reset breakpoint flag
*	move.b #$00,remflg	* reset network connection flag
*	move.b #$00,pakflg	* reset packet available flag
*	move.b #$0ff,cntflg	* set all packet control lines high
*	move.b cntflg,pacnt	* copy to O/P port
*
	lea intros,a4	*
	move.l #intron-intros,d2	* get message length
	jsr pdata	* print introductory message
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Main command interpreter routine
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
lprom:	lea promms,a4	*
	move.l #prommn-promms,d2	* get message length
	jsr pdata	* print prompt
chinp:	jsr inchu	* get an upper-case character
	cmp.b #cr,d0	* is it <CR>?
	beq lprom	* yes, goto prompt
	cmp.b #$3f,d0	* is it "?"?
	beq query	* yes, goto query
	cmp.b #$41,d0	* is it "A"?
	beq arith	* yes, goto arithmetic
	cmp.b #$42,d0	* is it "B"?
	beq brkpt	* yes, goto set breakpoint
	cmp.b #$43,d0	* is it "C"?
	beq copyr	* yes, goto copy routine
	cmp.b #$44,d0	* is it "D"?
	beq displ	* yes, goto display routine
	cmp.b #$46,d0	* is it "F"?
	beq fillm	* yes, goto fill memory routine
	cmp.b #$47,d0	* is it "G"?
	beq goprg	* yes, goto program routine
	cmp.b #$48,d0	* is it "H"?
	beq hexdc	* yes, goto hex -> decimal routine
	cmp.b #$49,d0	* is it "I"?
	beq diffr	* yes, goto difference routine
	cmp.b #$4a,d0	* is it "J"?
	beq findr	* yes, goto find routine
	cmp.b #$4b,d0	* is it "K"?
	beq killbp	* yes, goto kill breakpoint
*	cmp.b #$4c,d0	* is it "L"?
*	beq loadr	* yes, goto load routine
	cmp.b #$4d,d0	* is it "M"?
	beq modif	* yes, goto modify memory routine
	cmp.b #$50,d0	* is it "P"?
	beq rslink	* yes, goto RS232 link routine
*	cmp.b #$51,d0	* is it "Q"?
*	beq discn0	* yes, goto disconnection routine
	cmp.b #$52,d0	* is it "R"?
	beq regsr	* yes, goto register routine
*	cmp.b #$53,d0	* is it "S"?
*	beq reqcon	* yes, goto request connection routine
	cmp.b #$54,d0	* is it "T"?
	beq tstmem	* yes, goto test memory
	cmp.b #$55,d0	* is it "U"?
	beq setreg	* yes, goto register set routine
	cmp.b #$56,d0	* is it "V"?
	beq compr	* yes, goto compare routine
*	cmp.b #$57,d0	* is it "W"?
*	beq where	* yes, goto where connected routine
	cmp.b #$58,d0	* is it "X"?
	beq xtrace	* yes, goto trace routine
	cmp.b #$5a,d0	* is it "Z"?
	beq ztrace	* yes, goto single step routine
*
* character not found
*
	jsr pbell	* char not found, print bell
	bra chinp	* get next char
*
* Command Jump table
*
lprom1:	jsr outch	* echo character
	bra lprom	* goto prompt
*
* QUERY: print help message* uses D1, D0
*
query:	jsr outch	* output character
	lea helpms,a4	* get message pointer
	move.l #helpmn-helpms,d2	* get message length
	jsr pdata	* print it
	bra lprom	* goto prompt
*
* Copy memory routine
*
copyr:	jsr outch	* echo char
	jsr sin6hx	* get start address
	bcs lprom3	* if carry set, goto prompt
	move.l d1,a6	* save address
	jsr sin6hx	* get end address
	bcs lprom3	* if carry set, goto prompt
	move.l d1,d3	* save address
	lea arrms,a4	* message pointer
	move.l #arrmn-arrms,d2	* message length
	jsr pdata	* print message
	jsr sin6hx	* get destination address
	bcs lprom3	* if carry set, goto prompt
	move.l d1,a5	* dest. string pointer
	move.l d3,d2	*
	sub.l a6,d2	* calculate length
cpylp:	move.b (a6)+,(a5)+	* move byte, update ptrs
cptst:	dbra d2,cpylp	* repeat as rqd
lprom3:	bra lprom	* goto prompt
*
* FILLM: fills memory with value
*
fillm:	jsr outch	* echo character
	jsr sin6hx	* get start address
	bcs lprom3	* goto prompt
	move.l d1,a5	* save address
	jsr sin6hx	* get end address
	bcs lprom3	* if carry set, goto prompt
	move.l d1,d2	*
	sub.l a5,d2	* calculate length
	jsr pspac1	* print space
	jsr pequal	* print equ
	jsr sin2hx	* get value
	bcs lprom3	* if carry set, goto prompt
filllp:	move.b d0,(a5)+	* set byte
flltst:	dbra d2,filllp	* repeat as rqd
	bra lprom3	* goto prompt
*
* MODIF: modify memory locations
*
modif:	jsr outch	* echo character
	jsr sin6hx	* get address
	bcs lprm19	* if carry set, goto prompt
	move.l d1,a4	* save address
modf2:	jsr newlin	* do CR, LF
	move.l a4,d1	* get current address
	jsr sch6hx	* print it
	move.b (a4),d0	* get present value
	jsr sch2hx	* print it
modf5:	jsr inchu	* get character
	cmp.b #cr,d0	* is it CR?
	beq lprm29	* yes, goto prompt
	cmp.b #space,d0	* is it space?
	bne modf1	* no, modify value
modf6:	jsr outch	* echo character
modf9:	add.l #1,a4		* increment pointer
	bra modf2	* continue
modf1:	cmp.b #$2d,d0	* is it '-'?
	bne modf3	* no, new value
	jsr outch	* echo character
	sub.l #1,a4		* back up pointer
	bra modf2	* continue
modf3:	cmp.b #$30,d0	* is it less than '0'?
	blt moder4	* yes, error
	cmp.b #$39,d0	* is it greater than '9'?
	bgt moder2	* yes, possible error
	jsr outch	* echo char
	sub.b #$30,d0	* subtract offset
modf4:	jsr in2hax	* get rest of value
	bcs lprm20	* if carry set, goto prompt
	move.b d0,(a4)	* update value
	cmp.b (a4),d0	* are they equal??
	beq modf9	* yes, next value
	lea wrerms,a4	* pointer to message
	move.l #wrermn-wrerms,d2	* get length
	jsr pdata	* print message
lprm19:	bra lprom	* goto prompt
lprm20	equ	lprm19
moder2:	cmp.b #$41,d0	* is it less than "A"?
	blt moder4	* yes, error
	cmp.b #$46,d0	* is it greater than "F"?
	bgt moder4	* yes, error
	jsr outch	* print char
	sub.b #$37,d0	* subtract char offset
	bra modf4	* continue
moder4:	jsr pbell	* print bell
	bra modf5	* continue
lprm29:	jsr outch	* echo character
	bra lprom	* goto prompt
*
* Display memory routine
*
displ:	jsr outch	* echo char
	jsr sin6hx	* get address
	bcs lprm19	* if carry set, goto prompt
	move.l d1,a4	* start of block pointer in A4
	jsr newln2	* 2x #cr, lf
	jsr pspac7	* 5 spaces
	move.l #$0f,d2	* count
	move.l a4,d1	* get start of block
dislp1:	jsr pspac2	* 2 spaces
	move.b d1,d0	* get lsb
	jsr lohex	* print lsb hex char
	add.b #1,d1	* increment value
	dbra d2,dislp1	* decrement and repeat if not zero
	jsr newln2	* 2x #cr, lf
	move.w #$0f,d3	* row counter - 1
dislp2:	move.l a4,d1	* block address
	jsr sch6hx	* print it
	jsr pspac1	* print space
	move.l #$0f,d2	* byte count - 1
dislp3:	move.b (a4)+,d0	* get value
	jsr sch2hx	* print value
	dbra d2,dislp3	* decrement and repeat if not zero
	jsr pspac2	* 2x space
	sub.w #$10,a4	* back up pointer
	move.l #$0f,d2	* byte count - 1
dislp4:	move.b (a4)+,d0	* get char
	cmp.b #space,d0	* is it less than space?
	blt dispn1	* yes, continue
	cmp.b #$7e,d0	* is it greater than "~"?
	ble dispn2	* no, continue
dispn1:	move.b #$2e,d0	* get "."
dispn2:	jsr outch	* print character
	dbra d2,dislp4	* decrement and repeat if not zero
	jsr newlin	* do CR, LF
	dbra d3,dislp2	* decrement row count and rpt if rqd
lprom6:	bra lprom	* goto prompt
*
* HEXDC: convert to decimal
*
hexdc:	jsr outch	* echo character
	jsr sin6hx	* get hex value
	bcs lprm14	* if carry set, goto prompt
	jsr pspac1	* print space
	jsr pequal	* print "equ"
	jsr pspac1	* print space
	jsr decpt	* print as decimal number
lprm14:	bra lprom2	* goto prompt
*
* ARITH: does hex arithmetic
*
arith:	jsr outch	* output character
	jsr sin6hx	* get 24 bit word
	bcs lprom2	* if carry set, goto prompt
	move.l d1,d2	* save first
	jsr sin6hx	* get 24 bit word
	bcs lprom2	* if carry set, goto prompt
	move.l d1,d3	* save second
	jsr newlin	* do CR, LF
	move.l d2,d1	* get first
	jsr ch6hex	* print first
	move.b #$2b,d0	*
	jsr outch	* print "+"
	move.l d3,d1	* get second
	jsr ch6hex	* print second
	jsr pequal	* print =
	move.l d3,d1	* get second
	add.l d2,d1	* add first
	jsr ch6hex	* output sum
	jsr newlin	* do CR, LF
	move.l d2,d1	* get first
	jsr ch6hex	* print first
	move.b #$2d,d0	*
	jsr outch	* print "-"
	move.l d3,d1	* get second
	jsr ch6hex	* print second
	jsr pequal	* print "="
	move.l d2,d1	* get first
	sub.l d3,d1	* subtract second
	jsr ch6hex	* output difference
lprom2:	bra lprom	* goto prompt
*
* GOPRG: start user program
*
goprg:	jsr outch	* echo char
	jsr sin6hx	* get address
	bcs lprom2	* if carry set, goto prompt
	jsr chkevn	* if not even prints msg, sets carry
	bcs lprom2	* address wasnt even
	jsr newlin	* do cr,lf
	move.l d1,66(a0)	* go address into saved pc
	and.w #$7fff,64(a0)	* unset trace in saved sr
	move.l a0,sp	* set sp to saved reg. frame
	movem.l (sp)+,d0-d7/a0-a6/sp	* restore registers
	rte		* go
*
* DIFFR: finds first location different from a value
*
diffr:	jsr outch	* echo character
	jsr sin6hx	* get first value
	bcs lprm10	* if carry set, goto prompt
	move.l d1,a5	* start address
	jsr sin6hx	* get second value
	bcs lprm10	* if carry set, goto prompt
	move.l d1,d2	* end address
	sub.l a5,d2	* calculate length
	jsr pspac1	* output space
	jsr pequal	* output "="
	jsr sin2hx	* get value
	bcs lprm10	* if carry set, goto prompt
difflp:	cmp.b (a5)+,d0	* scan memory
	bne difdif	* if values different, report
diftst:	dbra d2,difflp	* decrement and repeat if not zero
	jsr pokms	* print OK message
	bra lprom	* goto prompt
difdif:	jsr newlin	* do #cr, lf
	sub.l #1,a5		* decrement pointer
	move.l a5,d1	* get different address
	jsr sch6hx	* print address
	jsr pequal	* print "="
	jsr pspac1	* print space
	move.b (a5),d0	* get value
	jsr ch2hex	* print value
lprm10:	bra lprom	* goto prompt
*
*
* Load program from remote device
*
ploadr: jsr outch	* echo command char
pload1:	jsr hinch	* get char from network
	cmp.b #$53,d0	* is it "S"?
	bne pload1	* no, try again
	jsr outch	* output "S"
	jsr hinch	* get record type no (1,2 or 9)
	cmp.b #$31,d0	* is it 1?
	beq shadd	* yes, short address version
	cmp.b #$32,d0	* is it 2?
	beq lngadd	* yes, long address version
	cmp.b #$39,d0	* is it 9?
	beq windup	* yes, download ending
	bra lprm70	* abort if any other character
shadd:	jsr hin2hx	* get record length
	bcs lprm70	* prompt if <CR>
	clr.l d2
	move.b d0,d2	* record length in D2
	sub.l #4,d2	* adjust it to count data only
	clr.l d3	* clear address pointer
shad2:	jsr hin4hx	* get address
	bcs lprm70	* prompt if <CR>
	move.w d1,d3	* put addr in pointer
	move.l d3,a4	* move it to a4
getbyt:	jsr hin2hx	* get data byte
	bcs lprm70	* prompt if <CR>
	move.b d0,(a4)+	* put in memory
	dbra d2,getbyt	* repeat as rqd
	jsr hin2hx	* throw away checksum
	bcs lprm70	* prompt if <CR>
	bra pload1	* get next record
lngadd:	jsr hin2hx	* get record length
	bcs lprm70	* prompt if <CR>
	clr.l d2
	move.b d0,d2	* record length into d2
	sub.l #5,d2	* adjust to count data only
	clr.l d3
	jsr hin2hx	* get msb of addr to d0
	bcs lprm70	* prompt if <CR>
	move.b d0,d3	* put it in d3
	swap d3		* move it to correct byte of d3
	bra shad2	* continue
windup:	jsr hin4hx
	jsr hin4hx	* throw away 4 bytes
	lea lfinms,a4	* load finished message
	move.l #lfinmn-lfinms,d2
lprm69:	jsr pdata	* print message
	bra lprom	* goto prompt
lprm70:	lea labtms,a4	* load aborted message
	move.l #labtmn-labtms,d2
	bra lprm69
*
* RSLINK: links to auxiliary RS232 port, allows downloading
* 
rslink:	jsr outch	* echo char
rsloop:	jsr inchr2	* get char from aux RS232
	bcc gotch	* branch if char available
	jsr inchr	* get char from terminal
	bcs rsloop	* loop if no char available
	cmp.b #netbrk,d0	* is it NETWORK BREAK char?
	bne rscont	* branch if not
	bra lprom	* goto prompt
rscont:	jsr outch2	* send char to aux RS232 port
	bra rsloop	* loop
gotch:	cmp.b #00,d0	* is it null char?
	beq rsloop	* if so discard and loop
	cmp.b #netbrk,d0	* is it NETWORK BREAK char?
	beq ploadr	* if so, go to program downloader
	jsr outch	* otherwise send to terminal
	bra rsloop	* and loop
*
* FINDR: finds first location equal to a value
*
findr:	jsr outch	* echo character
	jsr sin6hx	* get first value
	bcs lprm11	* if carry set, goto prompt
	move.l d1,a5	* start address
	jsr sin6hx	* get second value
	bcs lprm11	* if carry set, goto prompt
	move.l d1,d2	* end address
	sub.l a5,d2	* calculate length
	jsr pspac1	* output space
	jsr pequal	* output "="
	jsr sin2hx	* get value
	bcs lprm11	* if carry set, goto prompt
findlp:	cmp.b (a5)+,d0	* scan memory
	beq findif	* if equ report
fndtst:	dbra d2,findlp	* decrement and repeat if not zero
	jsr pokms	* print OK message
	bra lprom	* goto prompt
findif:	jsr newlin	* do #cr, lf
	sub.l #1,a5		* decrement pointer
	move.l a5,d1	* get different address
	jsr sch6hx	* print address
	jsr pequal	* print "="
	jsr pspac1	* do space
	move.b (a5),d0	* get value
	jsr ch2hex	* print value
lprm11:	bra lprom	* goto prompt
*
* COMPR: compares two blocks of memory; reports if different
*
compr:	jsr outch	* echo character
	jsr sin6hx	* get first address
	bcs lprm12	* if carry set, goto prompt
	move.l d1,a4	* start address
	jsr sin6hx	* get end address
	bcs lprm12	* if carry set, goto prompt
	move.l d1,d2	* get end
	sub.l a4,d2	* calculate length
	jsr pspac1	* print space
	jsr pequal	* print "="
	jsr sin6hx	* get second address
	bcs lprm12	* if carry set, goto prompt
	move.l d1,a5	* start address
complp:	cmpm.b (a5)+,(a4)+	* compare memory strings
	bne comdif	* if not equ report
cmptst:	dbra d2,complp	* decrement and repeat if not zero
	jsr pokms	* print OK message
	bra lprom	* goto prompt
comdif:	jsr newlin	* do #cr, lf
	sub.l #1,a5		*
	sub.l #1,a4		* decrement pointers
	move.l a4,d1	* get address
	jsr sch6hx	* print different address
	jsr pequal	* print "="
	jsr pspac1	* print space
	move.b (a4),d0	* get value
	jsr sch2hx	* print value
	jsr newlin	* do #cr, lf
	move.l a5,d1	* get address
	jsr sch6hx	* print it
	jsr pequal	* print "="
	jsr pspac1	* print space
	move.b (a5),d0	* get value
	jsr sch2hx	* print value
lprm12:	bra lprom	* goto prompt
*
* TSTMEM: memory test routines
*
tstmem:	jsr outch	* echo character
	jsr sin6hx	* get address
	bcs lprm42	* if carry set, goto prompt
	move.l d1,a6	* save in A6 register
	jsr pspac1	* print space
	move.b #$2d,d0	*
	jsr outch	* print "-"
	jsr sin6hx	* get end address
	bcs lprm43	* if carry set, goto prompt
	move.l d1,d3	*
	sub.l a6,d3	* calculate length
	jsr testms	* print test message
	move.b #$31,d0	*
	jsr outch	* print '1'
	move.b #$0ff,d0	* test pattern - all ONES
	jsr filtst	* test memory
	bne tsterr	* if not equ goto report
	jsr pokms	* print OK message
	jsr testms	* print test message
	move.b #$32,d0	*
	jsr outch	* print '2'
	move.b #$00,d0	* test pattern - all ZEROS
	jsr filtst	* test memory
	bne tsterr	* if not equ goto report
	jsr pokms	* print Ok message
	jsr testms	* print test message
	move.b #$33,d0	*
	jsr outch	* print '3'
	move.b #$01,d0	* initial test pattern
t3loop:	jsr filtst	* test memory
	bne tsterr	* if not equ goto report
	lsl.b #1,d0	* shift pattern
	bne t3loop	* if not zero, repeat loop
	jsr pokms	* print OK message
	jsr testms	* print test message
	move.b #$34,d0	*
	jsr outch	* print '4'
	move.b #$0fe,d0	* initial test pattern
t4loop:	jsr filtst	* test memory
	bne tsterr	* if not equ repeat loop
	rol.b #1,d0	* shift pattern
	bcs t4loop	* if carry set, repeat loop
	jsr pokms	* jsr OK message
lprm42:	bra lprom	* goto prompt
lprm43	equ	lprm42
*
* Memory test error reporting routine
*
tsterr:	lea errms,a4	* pointer to message
	move.l d0,-(sp)		* save test value
	move.l #errmn-errms,d2	* length of message
	jsr pdata	*
	move.l a5,d1	* get address
	jsr sch6hx	* print it
	jsr pequal	* print "="
	jsr pspac1	* print space
	move.b (a4),d0	* get actual value
	jsr sch2hx	* print it
	move.b #$3c,d0	*
	jsr outch	* print "<"
	move.b #$3e,d0	*
	jsr outch	* print ">"
	jsr pspac1	* print space
	move.l (sp)+,d0		* get test value
	jsr ch2hex	* print it
	jsr newlin	* print newline
	bra lprm43	* goto prompt
*
* TESTMS: print test message
*
testms:	lea tstmes,a4	* pointer to message
	move.l #tstmen-tstmes,d2	* length of message
	jsr pdata	* print it
	rts		* return
*
* FILTST: fills memory starting at a6, length dx
*
filtst:	move.l d3,d2	* block length
	move.l a6,a5	* block start address
fltst2: move.b d0,(a5)+	* fill byte
fltst1: dbra d2,fltst2	* loop as rqd
	move.l d3,d2	* block length
	move.l a6,a5	* block start address
fltst4: cmp.b (a5)+,d0	* read byte back to check
	bne flfail	* rts with Z unset if fail
fltst3: dbra d2,fltst4	* loop as rqd
flfail:	rts		* return
*
* REGSR: prints values in processor registers
*
regsr:	jsr outch	* echo character, drop through
*
* REGOUT: prints processor registers
*
	jsr regdsp	* print D & A registers
	jsr srpcds	* print SR,PC,USP
	jsr newlin	* cr,lf
	bra lprom	* goto prompt
*
* REGDSP: prints D & A registers from saved register frame
* 	  pointed to by A0. A0 unchanged. Uses d0,d2,a4
* 	  A6 at end points to saved SR.
*
regdsp:	lea regd1s,a4	* pointer to header msg
	move.l #regd1n-regd1s,d2	* msg length
	jsr pdata	* print header msg
	move.l a0,a6	* get pointer to reg. frame to a6
	move.l #7,d2	* 8 registers to be printed
	jsr stkdsp	* print 8 registers from a6 stack
	lea regd2s,a4	* pointer to 2nd header msg
	move.l #regd2n-regd2s,d2	* msg length
	jsr pdata	* print 2nd header
	move.l #7,d2	* 8 registers to be printed
	jsr stkdsp	* print 8 registers, a6 was already correct
	rts
*
* STKDSP: prints (D2+1) 32 bit values from stack pointed to
* 	  by A6. Uses D0,D1. A6 increased by 4*(D2+1)
*
stkdsp:	move.l (a6)+,d1	* get value
	jsr sch8hx	* print it with space after
	dbra d2,stkdsp	* repeat as rqd
	rts
*
* SRPCDS: prints SR and PC values from A6 stack, then prints USP
* 	  value. Uses D0,D2,A4. A6 increased by 6.
*
srpcds:	lea regd3s,a4	* pointer to header msg
	move.l #regd3n-regd3s,d2	* msg length
	jsr pdata	* print header msg
	jsr pspac2	* 2 spaces before SR value
	move.w (a6)+,d1	* get SR value
	jsr sch4hx	* print it with space after
	jsr pspac2	* 2 extra spaces
	clr.l d2	* zero D2 to print 1 value from a6 stack
	jsr stkdsp	* print value from a6 stack
	move.l usp,a4	* get USP ...
	move.l a4,d1	* ... to D1
	jsr ch8hex	* print value from D1
	rts
*
* Breakpoint set routine
*
brkpt:	jsr outch	* echo command char
	jsr sin6hx	* print space and get address
	bcs lprom	* goto prompt if <CR>
	jsr chkevn	* if odd print msg. and set carry
	bcs lprom	* if odd goto prompt
	btst #0,brkflg	* is a breakpoint set?
	beq nobrk	* branch if not
	jsr unbrk	* unset previous breakpoint
nobrk:	move.b #$01,brkflg	* set breakpoint flag
	move.l d1,brkadd	* save breakpoint address
	move.l d1,a4	* point to breakpoint addr
	move.w (a4),brksav	* save instruction at break addr
	move.w #$4e40,(a4)	* poke TRAP 0 instruction
	lea bsetms,a4	* pointer to message
	move.l #bsetmn-bsetms,d2	* msg length
	jsr pdata	* print message
	jsr ch6hex	* print break addr from D1
	jsr newlin	* cr,lf
	bra lprom	* goto prompt
*
* Kill breakpoint routine
*
killbp: jsr outch	* echo command char
	btst #0,brkflg	* is a breakpoint set?
	beq nobrk2	* branch if not
	jsr unbrk	* unset the breakpoint
	jsr newlin	* cr,lf
	bra lprom	* goto prompt
nobrk2:	lea nobkms,a4	* pointer to no breakpoint msg
	move.l #nobkmn-nobkms,d2	* msg length
	jsr pdata	* print message
	bra lprom	* goto prompt
*
* UNBRK: Unsets the current breakpoint
*
unbrk:	move.l d1,-(sp)	* save D1
	move.b #$00,brkflg	* unset breakpoint flag
	move.l brkadd,a4	* get breakpoint address
	move.w brksav,(a4)	* restore original instr. word
	move.l a4,d1	*break addr to D1
	lea bkilms,a4	* pointer to break killed msg
	move.l #bkilmn-bkilms,d2	* msg length
	jsr pdata	* print message
	jsr ch6hex	* print break addr from D1
	move.l (sp)+,d1	* restore D1
	rts
*
* Set value of saved register routine
*
setreg:	jsr outch	* echo command char
	jsr pspac1	* print space
	jsr inchu	* get upper case char no echo
	cmp.b #$41,d0	* is it "A"?
	beq addreg	* yes, address register
	cmp.b #$44,d0	* is it "D"?
	beq datreg	* yes, data register
	cmp.b #$43,d0	* is it "C"?
	beq ccreg	* yes, CCR
	cmp.b #$50,d0	* is it "P"?
	beq pcreg	* yes, PC
	cmp.b #$53,d0	* is it "S"?
	beq sreg	* yes, SR
	cmp.b #$55,d0	* is it "U"?
	beq uspreg	* yes, USP
regerr:	jsr pbell	* any other char ring bell
	bra lprom	* and goto prompt
ccreg:	lea ccrms,a4	* pointer to message
	move.l #ccrmn-ccrms,d2	* msg length
	jsr pdata	* print message
	jsr sin2hx	* print space and get 2 hex chars to D0
	bcs lprom	* goto prompt if <CR>
	move.b d0,65(a0)	* put value in saved CCR on frame
	bra lprom
sreg:	lea srms,a4	* pointer to msg
	move.l #srmn-srms,d2	* msg length
	jsr pdata	* print message
	jsr sin4hx	* print a space and get 4 digits to d1
	bcs lprom	* goto prompt if <CR>
	move.w d1,64(a0)	* put in SR in saved registers
	bra lprom	* goto prompt
pcreg:	lea pcrms,a4	* pointer to msg
	move.l #pcrmn-pcrms,d2	* msg length
	jsr pdata	* print msg
	jsr sin8hx	* print space & get 8 hex digits to D1
	bcs lprom	* goto prompt if <CR>
	jsr chkevn	* if odd print msg and set carry
	bcs lprom	* goto prompt if it was odd
	move.l d1,66(a0)	* put in saved PC
	bra lprom	* goto prompt
uspreg:	lea usprms,a4	* pointer to message
	move.l #usprmn-usprms,d2	* length of message
	jsr pdata	* print "usp ="
	jsr sin8hx	* print space & get 8 hex digits to D1
	bcs lprom	* goto prompt if <CR>
	jsr chkevn	* if odd print msg and set carry
	bcs lprom	* goto prompt if it was odd
	move.l d1,a4	* move to ...
	move.l a4,usp	* ... usp
	bra lprom	* goto prompt
datreg:	jsr outch	* print the "D"
	jsr inchu	* get upper case char to D0
	cmp.b #$30,d0	* is it <0?
	blt regerr	* yes, error
	cmp.b #$37,d0	* is it >7?
	bgt regerr	* yes, error
	move.b d0,d3	* save register no
	jsr outch	* print it
	jsr pspac1	* print space
	jsr pequal	* print "="
	and.b #$0f,d3	* mask to 4 bits
	lsl.b #2,d3	* multipy by 4
	clr.l d1	* clear all D1
	move.b d3,d1	* set up index ...
	move.l d1,a4	* ... into A4
	jsr sin8hx	* print space & get 8 hex digits to d1
	bcs lprom	* prompt if <CR>
	move.l d1,0(a0,a4)	* move value into saved data reg
	bra lprom	* goto prompt
addreg:	jsr outch	* print the "A"
	jsr inchu	* get upper case char to D0
	cmp.b #$30,d0	* is it <0?
	blt regerr	* yes, error
	cmp.b #$36,d0	* is it >6? (A7 not allowed)
	bgt regerr	* yes, error
	move.b d0,d3	* save register no
	jsr outch	* print it
	jsr pspac1	* print a space
	jsr pequal	* print "="
	and.b #$0f,d3	* mask to 4 bits
	lsl.b #2,d3	* multiply by 4
	clr.l d1	* clear all of D1
	move.b d3,d1	* set up index ...
	move.l d1,a4	* ... into A4
	jsr sin8hx	* print space and get 8 digits to D1
	bcs lprom	* goto prompt if <CR>
	move.l d1,32(a0,a4)	* put into saved address reg
	bra lprom	* goto prompt
*
* X trace command routine
*
xtrace:	jsr outch	* print the command char
	jsr sin2hx	* print space & get a 2 digit hex no into d0
	bcs lprom	* goto prompt if <CR>
	move.b d0,trccnt	* save no of instr. to trace
xtrac2:	jsr newlin	* print cr,lf
	or.w #$8000,64(a0)	* set saved SR to trace mode
	move.l a0,sp	* sp to point at saved reg frame
	movem.l (sp)+,d0-d7/a0-a6/sp	* restore saved register frame
	rte
*
* Z trace (single step) command
*
ztrace:	jsr outch	* print the command char
	move.b #1,trccnt	* 1 instruction only
	bra xtrac2	* goto trace routine
*
* STOP LOOP - entered if trace command done without setting PC
*
stoplp:	bra stoplp
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* EXCEPTION HANDLING ROUTINES
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Address error and Bus error exception handler
*
berr:	movem.l d0-d7/a0-a6/sp,-(sp)	* save registers
adderr	equ	berr
	move.l sp,a0	* get saved register frame pointer
	lea berrms,a4	* pointer to error message
	move.l #berrmn-berrms,d2	* msg length
	jsr pdata	* print message
	jsr regdsp	* print data and address registers
	lea errhds,a4	* pointer to error header msg
	move.l #errhdn-errhds,d2	* msg length
	jsr pdata	* print msg
	jsr pspac2	* two spaces
	move.w (a6)+,d1	* get 1st debug word from stack
	jsr sch4hx	* print space and word
	jsr pspac2	* 2 spaces
	move.l (a6)+,d1	* get next 2 debug words
	jsr sch8hx	* space and print words
	jsr pspac2	* two spaces
	move.w (a6)+,d1	* get last debug word
	jsr sch4hx	* space and print it
	jsr srpcds	* print saved SR,PC and USP
	jsr newlin	* cr,lf
	move.w sr,64(a0)	* put SR into posn in saved regs
	lea stoplp,a6	* saved PC will point to stop loop
	move.l a6,66(a0)	* put into saved PC
* 
* The last 3 instructions are needed because these two exceptions
* store extra things on the stack which must be replaced with a
* reasonable SR and PC before a G,X, or Z command is done
*
	bra lprom	* goto prompt
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Error exception ( nos 4-8,10,11 ) handler routine
*
* This is entered via a set of jumps in RAM which also store
* the exception no in D2/0
*
excep:	movem.l d0-d7/a0-a6/sp,-(sp)	* save registers
	move.l sp,a0	* set a0 to point at saved reg frame
	lea exceps,a4	* pointer to exception message
	move.l #excepn-exceps,d2	* msg length
	jsr pdata	* print msg
	jsr regdsp	* print data and addr regs
	jsr srpcds	* print saved SR,PC, & USP
	jsr newlin	* cr,lf
	bra lprom	* goto prompt
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
* 
* Trace exception handler routine
*
trace:	movem.l d0-d7/a0-a6/sp,-(sp)	* save registers
	move.l sp,a0	* set a0 to point at saved reg frame
	jsr regdsp	* print data and addr registers
	jsr srpcds	* print saved SR,PC,and USP
	jsr newlin	* cr,lf
	jsr inchr	* has a character come in?
	bcs nochar	* branch if not
	cmp.b #space,d0	* is it a space?
	bne nochar	* branch if not
	beq lprom	* stop trace and goto prompt if space
nochar:	sub.b #1,trccnt	* decrement trace instr. count
	beq lprom	* goto prompt if done
	move.l a0,sp	* restore sp to saved reg frame
	movem.l (sp)+,d0-d7/a0-a6/sp	* restore registers
	rte	* go
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Breakpoint (TRAP 0) handler routine
*
trap0:	movem.l d0-d7/a0-a6/sp,-(sp)	* save registers
	move.l sp,a0	* set a0 to point to saved reg frame
	sub.l #2,66(a0)	* back up saved PC by 2 to point at TRAP instr.
	lea brkmss,a4	* pointer to breakpoint message
	move.l #brkmsn-brkmss,d2	* length of message
	jsr pdata	* print msg
	jsr regdsp	* print data and addr registers
	jsr srpcds	* print saved SR,PC and USP
	jsr newlin	* cr,lf
	bra lprom	* goto prompt
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* TRAP 1 (inch4) and TRAP 2 (outch4) handlers to input a char
* with echo, and to output a char, via serial link
*
inch4:	jsr inch	* get character
outch4:	jsr outch	* echo it
	rte		* return from interrupt
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Initialisation routines
*
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
*
* 68681 initialization : 9600 baud,7 data bits, space parity,1 stop bit,
* no parity check
*
inits:	movem.l d0/d1/a0/a1,-(a7)   * save registers
	move.l	#table,a0   * get init parameters
	move.l	#length,d0  * get number of parameters
*
	bra sk0init        * do loop test
lp0init:	move.l (a0)+,a1   * get register address
	move.l (a0)+,d1     * parity etc.
*
	move.b	d1,(a1)   	* put command
sk0init:	dbra	d0,lp0init * loop test
*
	move.b	#noints,imr	* clear all interrupt enables
*
*
     move.l    #$70000,a0     * get  led/gen purpose register address
     move.w    #$fffe,(a0)    * put  green led on only.
*
     move.b    #ten,cmda
     move.b    #ten,cmdb
     move.b    #ren,cmda
     move.b    #ren,cmdb
     movem.l   (a7)+,d0/d1/a0/a1_*restore registers
	rts
*
* set mode of channel A - 7 bits, no parity, 1 stop bit 9600 baud
*  no hsking
*
table:dc.l   imr,noints
     dc.l   cmda,point1
     dc.l   modea,norrts+rirdy+cerr+nopar+bits8
     dc.l   modea,norop+notrts+nocts+stop1
*
* Set mode of Channel B - 7 bits, no parity, 1 stop bit, 9600 baud
* no hsking
*
     dc.l   cmdb,point1
     dc.l   modeb,norrts+rirdy+cerr+nopar+bits8
     dc.l   modeb,norop+notrts+nocts+stop1
*
* set output port config register
*
     dc.l   opcr,allout
*
* Reset and enable channel A
*
     dc.l    cmda,rstrx
     dc.l    cmda,rsttx_* reset transmitter
     dc.l    cmda,rsterr
     dc.l    cmda,rstint
     dc.l    cmda,brkoff+tdis+ren
     dc.l    clka,b9600
*
* Reset and enable channel b
*
     dc.l   cmdb,rstrx
     dc.l   cmdb,rsttx
     dc.l   cmdb,rsterr
     dc.l   cmdb,rstint
     dc.l   cmdb,brkoff+tdis+ren
     dc.l   clkb,b9600
*
* Setup output pins
*
     dc.l   bitset,$ff
length equ   (*-table)/8
     rts
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
* Now we have messages and vector table file
*
	incl	msgoct90.asm
*
*	
* :*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*
*
	end
