.psize
|       NOTES   : PORTED TO PC BY DAVE GOODMAN
|               : PORTED TO RAYMATIC 68K BOARD BY RUSSELL G. BROWN
|       ASSEMBLE: mas68k -l vubug.68k
|               : ASSEMBLER WILL TAKE FILE vubug.68k AND
|               : WILL CREATE vubug.o, vubug.l
|       VER 3.0 : VUBUG VER 3.0 PORTEd TO PC FOR ASSEMBLE USING a68K 9/84
|       VER 3.1 : VUBUG VER 3.1 FIXED FOR VU68K BOARD 10/86
|       VER 4.0 : VUBUG VER 4.0 PORTED TO RAYMATIC 68K BOARD 4/88
|	VER 5.0	: VUBUG VER 5.0 Ported to homebuilt board 8/99
|		: - 68681 duart in place of 6840
|	VER 5.1 : VUBUG VER 5.1
|		: - Interrupt vectors placed in RAM
|
| !!! oriented for system with less than 64k of memory.
|
|*******************************************
|*                                         *
|********         V U B U G         ********
|*                                         *
|* Copyright (C) 1983, 1988                *
|*               Vanderbilt Univ.          *
|*               Comp. Sci. dept.          *
|*               PO Box 1679               *
|*               Station B                 *
|*               Nashville, Tenn.          *
|*                          37235          *
|*                                         *
|*       author:                           *
|*              Edward M. Carter           *
|*                                         *
|*******************************************
|*                                         *
|* This software was prepared for distri-  *
|* bution by Russell G. Brown.  Please     *
|* note that it is being distributed at    *
|* the request of several readers of the   *
|* usenet newsgroup comp.sys.m68k.  It has *
|* no warranty of any sort, at all.  I     *
|* think that the code is fairly self      *
|* explanatory.  Good luck in modifying    *
|* it to work on whatever application you  *
|* may have.                               *
|*******************************************
|*                                         *
|* although the information contained here-*
|* in, as well as any information provided *
|* relative thereto, has been carefully re-*
|* viewed and is believed correct, Vander- *
|* bilt University assumes no liability    *
|* arising out of its application or use,  *
|* neither does it convey any license under*
|* its patent rights nor the rights of     *
|* others.                                 *
|*                                         *
|*******************************************
|*                                         *
|* The commands supported are as follows:  *
|*                                         *
|*         m - examine/update memory       *
|*         l - load program from host      *
|*         u - load program from terminal  *
|*         d - display blocks of memory    *
|*         t - single-step a program       *
|*         s - single-step                 *
|*         g - start a user mode program   *
|*         <cr> - short g command          *
|*         b - set/remove breakpoints      *
|*         r - examine/update registers    *
|*         p - prototype commands          *
|*         e - terminal emulator mode      *
|*         c - copy memory blocks          *
|*         x - print help messages         *
|*                                         *
|* Sub-command under each of these commands*
|* are shown in the source code for each   *
|* command.                                *
|*                                         *
|*******************************************
|
| DUART Register Definitions
|
duart   =       0xe00000	| CHD
mr1a    =       0
mr2a    =       0
sra     =       2
csra    =       2
cra     =       4
rba     =       6
tba     =       6
ipcr	=	8
acr	=	8
imr     =       10
tbb     =       0x16
rbb     =       0x16
crb     =       0x14
mr1b    =       0x10
mr2b    =       0x10
srb	=	0x12
csrb    =       0x12
isr     =       0x0a
imr     =       0x0a
ivr     =       0x18
opcr	=	0x1a

|
| Queue structure
|
head    =       0x0000
tail    =       0x0002
count   =       0x0004
queue   =       0x0006
|
| Breakpoint structure
|
instr   =       0x0000
iloc    =       0x0002
|
| The following is the exception vector
| table for the monitor. There should be
| no further "org"s to address contained
| herein as this will destroy the vector
| for iterrupts, breakpoints...
|
|	.org     0x0                      |Reset Vector
	.text
rom_start:				| CHD

	dc.l    stack                   |system stack
	dc.l    start                   |initial pc
	dc.l	vec2
	dc.l	vec3
	dc.l	vec4
	dc.l	vec5
	dc.l	vec6
	dc.l	vec7
	dc.l	vec8
	dc.l	vec9
	dc.l	vec10
	dc.l	vec11
	dc.l	vec12
	dc.l	vec13
	dc.l	vec14
	dc.l	vec15
	dc.l	vec16
	dc.l	vec17
	dc.l	vec18
	dc.l	vec19
	dc.l	vec20
	dc.l	vec21
	dc.l	vec22
	dc.l	vec23
	dc.l	vec24
	dc.l	vec25
	dc.l	vec26
	dc.l	vec27
	dc.l	vec28
	dc.l	vec29
	dc.l	vec30
	dc.l	vec31
	dc.l	vec32
	dc.l	vec33
	dc.l	vec34
	dc.l	vec35
	dc.l	vec36
	dc.l	vec37
	dc.l	vec38
	dc.l	vec39
	dc.l	vec40
	dc.l	vec41
	dc.l	vec42
	dc.l	vec43
	dc.l	vec44
	dc.l	vec45
	dc.l	vec46
	dc.l	vec47
	dc.l	vec48
	dc.l	vec49
	dc.l	vec50
	dc.l	vec51
	dc.l	vec52
	dc.l	vec53
	dc.l	vec54
	dc.l	vec55
	dc.l	vec56
	dc.l	vec57
	dc.l	vec58
	dc.l	vec59
	dc.l	vec60
	dc.l	vec61
	dc.l	vec62
	dc.l	vec63
	dc.l	vec64
	dc.l	vec65
	dc.l	vec66
	dc.l	vec67
	dc.l	vec68
	dc.l	vec69
	dc.l	vec70
	dc.l	vec71
	dc.l	vec72
	dc.l	vec73
	dc.l	vec74
	dc.l	vec75
	dc.l	vec76
	dc.l	vec77
	dc.l	vec78
	dc.l	vec79
	dc.l	vec80
	dc.l	vec81
	dc.l	vec82
	dc.l	vec83
	dc.l	vec84
	dc.l	vec85
	dc.l	vec86
	dc.l	vec87
	dc.l	vec88
	dc.l	vec89
	dc.l	vec90
	dc.l	vec91
	dc.l	vec92
	dc.l	vec93
	dc.l	vec94
	dc.l	vec95
	dc.l	vec96
	dc.l	vec97
	dc.l	vec98
	dc.l	vec99
	dc.l	vec100
	dc.l	vec101
	dc.l	vec102
	dc.l	vec103
	dc.l	vec104
	dc.l	vec105
	dc.l	vec106
	dc.l	vec107
	dc.l	vec108
	dc.l	vec109
	dc.l	vec110
	dc.l	vec111
	dc.l	vec112
	dc.l	vec113
	dc.l	vec114
	dc.l	vec115
	dc.l	vec116
	dc.l	vec117
	dc.l	vec118
	dc.l	vec119
	dc.l	vec120
	dc.l	vec121
	dc.l	vec122
	dc.l	vec123
	dc.l	vec124
	dc.l	vec125
	dc.l	vec126
	dc.l	vec127
	dc.l	vec128
	dc.l	vec129
	dc.l	vec130
	dc.l	vec131
	dc.l	vec132
	dc.l	vec133
	dc.l	vec134
	dc.l	vec135
	dc.l	vec136
	dc.l	vec137
	dc.l	vec138
	dc.l	vec139
	dc.l	vec140
	dc.l	vec141
	dc.l	vec142
	dc.l	vec143
	dc.l	vec144
	dc.l	vec145
	dc.l	vec146
	dc.l	vec147
	dc.l	vec148
	dc.l	vec149
	dc.l	vec150
	dc.l	vec151
	dc.l	vec152
	dc.l	vec153
	dc.l	vec154
	dc.l	vec155
	dc.l	vec156
	dc.l	vec157
	dc.l	vec158
	dc.l	vec159
	dc.l	vec160
	dc.l	vec161
	dc.l	vec162
	dc.l	vec163
	dc.l	vec164
	dc.l	vec165
	dc.l	vec166
	dc.l	vec167
	dc.l	vec168
	dc.l	vec169
	dc.l	vec170
	dc.l	vec171
	dc.l	vec172
	dc.l	vec173
	dc.l	vec174
	dc.l	vec175
	dc.l	vec176
	dc.l	vec177
	dc.l	vec178
	dc.l	vec179
	dc.l	vec180
	dc.l	vec181
	dc.l	vec182
	dc.l	vec183
	dc.l	vec184
	dc.l	vec185
	dc.l	vec186
	dc.l	vec187
	dc.l	vec188
	dc.l	vec189
	dc.l	vec190
	dc.l	vec191
	dc.l	vec192
	dc.l	vec193
	dc.l	vec194
	dc.l	vec195
	dc.l	vec196
	dc.l	vec197
	dc.l	vec198
	dc.l	vec199
	dc.l	vec200
	dc.l	vec201
	dc.l	vec202
	dc.l	vec203
	dc.l	vec204
	dc.l	vec205
	dc.l	vec206
	dc.l	vec207
	dc.l	vec208
	dc.l	vec209
	dc.l	vec210
	dc.l	vec211
	dc.l	vec212
	dc.l	vec213
	dc.l	vec214
	dc.l	vec215
	dc.l	vec216
	dc.l	vec217
	dc.l	vec218
	dc.l	vec219
	dc.l	vec220
	dc.l	vec221
	dc.l	vec222
	dc.l	vec223
	dc.l	vec224
	dc.l	vec225
	dc.l	vec226
	dc.l	vec227
	dc.l	vec228
	dc.l	vec229
	dc.l	vec230
	dc.l	vec231
	dc.l	vec232
	dc.l	vec233
	dc.l	vec234
	dc.l	vec235
	dc.l	vec236
	dc.l	vec236
	dc.l	vec238
	dc.l	vec239
	dc.l	vec240
	dc.l	vec241
	dc.l	vec242
	dc.l	vec243
	dc.l	vec244
	dc.l	vec245
	dc.l	vec246
	dc.l	vec247
	dc.l	vec248
	dc.l	vec249
	dc.l	vec250
	dc.l	vec251
	dc.l	vec252
	dc.l	vec253
	dc.l	vec254
	dc.l	vec255

|	dc.l    abhlr                   |bus error
|	dc.l    abhlr                   |address error
|	dc.l    bhlr                    |illegal instruction vector
|	dc.l    ghlr                    |zero divide
|	dc.l    ghlr                    |chk
|	dc.l    ghlr                    |trapv
|	dc.l    phlr                    |privileged instruction trap
|	dc.l    thlr                    |trace handler  
|	dc.l    bhlr                    |emulator trap 1010
|	dc.l    bhlr                    |emulator trap 1111
|	.org     0x3c
|	.skip	12			|reserved vectors CHD
|	dc.l    ghlr                    |uninitialized iterrupt
|	.org     0x60
|	.skip	32			|reserved vectors CHD	
|	dc.l    ghlr                    |spurious interrupt
|        dc.l    lpint                   |download-line vector
|        dc.l    inint                   |terminal vector
|	dc.l    ghlr | uav1			| CHD			AV Level1
|	dc.l    drtint                  |duart vector		AV Level2
|	dc.l    ghlr | uav3                    |user auto-vectors	AV Level3
|	dc.l    ghlr | uav4 			|			AV Level4
|	dc.l    ghlr | uav5 			|			AV Level5
|	dc.l    ghlr | uav6 			|			AV Level6
|	dc.l    ghlr | uav7			|			AV Level7
|	dc.l    texit                   |exit
|	dc.l    tgetb                   |getb
|	dc.l    tgetw                   |getw
|	dc.l    tgetl                   |getl
|	dc.l    twrtb                   |wrtb
|	dc.l    twrtw                   |wrtw
|	dc.l    twrtl                   |wrtl
|	dc.l    tgetc                   |getc
|	dc.l    twrts                   |wrts
|	dc.l    twrtc                   |wrtc
|	dc.l    tcrlf                   |crlf
|utrpb:  dc.l    utrapb                  |user trap vectors
|utrpc:  dc.l    utrapc
|utrpd:  dc.l    utrapd
|utrpe:  dc.l    utrape
|utrpf:  dc.l    utrapf
|	.skip	64			| reserved CHD
|+++++++++++++++++++++++++++++++++++++++++
|                                        +
|            Start of monitor            +
|                                        +
|+++++++++++++++++++++++++++++++++++++++++

|
| These are seven user interrupt vectors
| which must remain at address 0x0100.
| Please ensure that they do
| CHD
|vect1:  dc.l    userv1
|vect2:  dc.l    userv2
|vect3:  dc.l    userv3
|vect4:  dc.l    userv4
|vect5:  dc.l    userv5
|
|********************************************************************************
| The following block of code is moved to RAM on reset
|
jmptab:
	jmp     stack                   |system stack
	jmp     start                   |initial pc
	jmp     abhlr                   |bus error
	jmp     abhlr                   |address error
	jmp     bhlr                    |illegal instruction vector
	jmp     ghlr                    |zero divide
	jmp     ghlr                    |chk
	jmp     ghlr                    |trapv
	jmp     phlr                    |privileged instruction trap
	jmp     thlr                    |trace handler  
	jmp     bhlr                    |emulator trap 1010
	jmp     bhlr                    |emulator trap 1111
|	.org     0x3c
|	.skip	12			|reserved vectors CHD
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp     ghlr                    |uninitialized iterrupt
|	.org     0x60
|	.skip	32			|reserved vectors CHD	
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp	ghlr
	jmp     ghlr                    |spurious interrupt
|        dc.l    lpint                   |download-line vector
|        dc.l    inint                   |terminal vector
	jmp     ghlr | uav1			| CHD			AV Level1
	jmp     drtint                  |duart vector		AV Level2
	jmp     ghlr | uav3                    |user auto-vectors	AV Level3
	jmp     ghlr | uav4 			|			AV Level4
	jmp     ghlr | uav5 			|			AV Level5
	jmp     ghlr | uav6 			|			AV Level6
	jmp     ghlr | uav7			|			AV Level7
	jmp     texit                   |exit
	jmp     tgetb                   |getb
	jmp     tgetw                   |getw
	jmp     tgetl                   |getl
	jmp     twrtb                   |wrtb
	jmp     twrtw                   |wrtw
	jmp     twrtl                   |wrtl
	jmp     tgetc                   |getc
	jmp     twrts                   |wrts
	jmp     twrtc                   |wrtc
	jmp     tcrlf                   |crlf
utrpb:  jmp     utrapb                  |user trap vectors
utrpc:  jmp     utrapc
utrpd:  jmp     utrapd
utrpe:  jmp     utrape
utrpf:  jmp     utrapf
	.skip	64+32			| reserved CHD
vect1:  jmp     userv1
vect2:  jmp     userv2
vect3:  jmp     userv3
vect4:  jmp     userv4
vect5:  jmp     userv5
jmptab_end:
|
|***********************************************************************************
|
|	csc     =       0x1b45           |clear screen (h-19) CHD
	csc	=	0x0d0a		| return, line feed
	cr      =       0x0d
	lf      =       0x0a
	nul     =       0x00
howdy:  dc.w    csc
	.ascii  "M68000 Monitor VUBUG"
	.ascii  "Version 5.1 17 October, 1999"
rnn0:   dc.b    cr,lf,lf,nul
bcomm:  .ascii  ": Bad Command"
	dc.b    cr,lf,nul
ssri:   dc.w    0x2000           |supervisor SR
ssrn:   dc.w    0x2700           |same w/o interrupts
prmp:   dc.b    cr,lf           
	dc.b    '!'             | command prompt
	dc.b    nul             

|start:  move.b  #0x03,ttyst              |setup ports
|        move.b  #0x03,lpst	| CHD
|        move.b  #0x15,ttyst
|        move.b  #0x15,lpst

start:
	move.w	ssrn,sr			| disable interrupts
	lea     duart,a1		| CHD
	move.b  #0b00010000,cra(a1)     | reset MR?A pointer
	move.b  #0b00100011,mr1a(a1)    | 8 data bits, even parity
	move.b  #0b00010100,mr2a(a1)    | normal mode, CTS, 1 stop
	move.b  #0b10111011,csra(a1)    | set clock to 9600
	move.b  #0b00000101,cra(a1)     | enable Rx and Tx

	move.b  #0b00010000,crb(a1)     | reset MR?A pointer
	move.b  #0b00100011,mr1b(a1)    | 8 data bits, even parity
	move.b  #0b00010100,mr2b(a1)    | normal mode, CTS, 1 stop
	move.b  #0b10111011,csrb(a1)    | set clock to 9600
	move.b  #0b00000101,crb(a1)     | enable Rx and Tx

	move.b	#0b00000010,opcr(a1)	| output config

	move.b	#26,ivr(a1)		| interrupt vector register
	move.b	#0b00100010,imr(a1)	| interrupt mask register

	move.w  #0xffff,d0               |load 0xffff for first memory test
	movea.l #ram_start,a0            |start at 0x0100000 CHD
	move.w  #0x1fff,d2               |0x2000 words of ram
mt1:    move.w  d0,(a0)                 |store value
	move.w  (a0)+,d1                |load it back
	cmp.w   d0,d1
	bne     memerr                  |if not the same, memory error.
	dbf     d2,mt1
	move.w  #0x0000,d0               |load 0x0000 for second mem test
	movea.l #ram_start,a0		| CHD
	move.w  #0x1fff,d2
mt2:    move.w  d0,(a0)
	move.w  (a0)+,d1
	bne     memerr                  |if not zero, memory error.
	dbf     d2,mt2
	bra     gwan
memerr: lea     memnot,a0               |RAM doesn't work right.
	bsr     writs
	bra     gwan
memnot: .ascii  "RAM ERROR!!!!"
	dc.b    cr,lf,nul
gwan:   lea     ibuff,a1                |setup buffers
	move.w  #0x0000,head(a1)
	move.w  #0xffff,tail(a1)
	move.w  #0x0000,count(a1)
	lea     lbuff,a1
	move.w  #0x0,head(a1)            |set queue for lp
	move.w  #0xffff,tail(a1)
	move.w  #0,count(a1)
	move.w  #0,exam                 |initialize control variables
	move.b  #0,ctrls
	move.b  #0,bkptf
	moveq   #0x4,d0                  |clear breakpoint table
	lea     bktab,a1
slp:    move.l  #0,(a1)+
	dbf     d0,slp
	move.w  #0,_sr                  |clear register save area
	move.l  #0x10,d0
	lea     _pc,a0
slp1:   move.l  #0,(a0)+
	dbf     d0,slp1
	lea     ustck,a0                |set user stack pointer
	move.l  a0,ar7
	lea     sarea,a0                |clear system stack
	moveq   #0x3f,d0
slp2:   move.l  #0,(a0)+
	dbf     d0,slp2

	move.l	#jmptab,a0		|move jmp table
	move.l	#jmptab_area,a1
	move.w	#255+128,d0
jmplp:	move.l	(a0)+,d1
	move.l	d1,(a1)+
	dbf	d0,jmplp	

done:   move.w  ssri,sr                 |enable interrupts at CPU
	lea     howdy,a0                |say hello
	bsr     writs
|        move.b  #0x95,ttyst              |enable interrupts from ports
|        move.b  #0x95,lpst		| CHD
	move.b  #0b00100010,imr+duart   | rx int on A and B
	bset    #0x00,echo               |turn on terminal echo

|LP:	move.b	#0x55,d0		|CHD *********
|	move.b	d0,0x0d00000
|	bsr	writ
|	bra	LP

	bra     comm                    |enter command loop

| ***********
.globl _putch_tty
_putch_tty:
	link	a6,#0
	moveb	a6@(11),d0
	bsr	writ
	unlk	a6
	rts

.globl _putch_lp
_putch_lp:
	link	a6,#0
	moveb	a6@(11),d0
	bsr	writu
	unlk	a6
	rts

.globl _getc_tty
_getc_tty:
	bsr	getch
	rts

| ***********

|
| Generalized write facility writes 1 byte
| passed in d0 to tty.
|
writ:   btst    #0,ctrls                |Is ctrl-s active
	beq     cwrit                   |no, so write it
        stop    #0x2000                  |yes, so wait on next character
|	move.w  #0x2000,sr              | enable interrupts
	bra     writ                    |when awakened try to echo
|cwrit:  move.b  d0,ttyd                 |write the character to port
|writa:  move.b  ttyst,d0                |sample control register till done
|        btst    #0x1,d0		| CHD
|        beq     writa
cwrit:  btst    #2,sra+duart            | test xmit data reg empty
	beq     cwrit                   | if not keep polling
	move.b  d0,tba+duart            | transmit the character
	rts
|
| Generalized write facility writes 1 byte
| passed in d0 to serial port.
|
|writu:  move.b  d0,lpd                  |write it
|writp:  move.b  lpst,d0                 |wait for completion
|        btst    #0x1,d0
|        beq     writp			| CHD
writu:  btst	#2,srb+duart		| test xmit data reg empty
	beq	writu			| if not keep polling
	move.b	d0,tbb+duart		| transmit the character
	rts
|
| Generalized routine to write a string which
| must terminate in a null
|
writs:  move.b  (a0)+,d0                |a0 is address of string
	beq     dwrts
	bsr     writ
	bra     writs
dwrts:  rts
|
|Generalized routine to write
|a word, byte or long word.
|
writb:  move.w  #0x1,t1                  |t1 is the number of bytes
	bra     wr
writw:  move.w  #0x3,t1
	bra     wr
writl:  move.w  #0x7,t1
wr:     movem.l #0x6082,-(a7)            |save registers d1,d2,a0,a6
	move.w  t1,d2                   |set count
	move.b  #0x00,t5+1               |set a null at end
	lea     t5+1,a6                 |use temps as a stack
alp:    move.b  d0,d1                   |make each hex digit a
	and.b   #0x0f,d1                 |writable ascii byte
	cmp.b   #0x0a,d1                 |check for abcdef
	blt     or3
	or.b    #0x40,d1
	sub.b   #0x09,d1
	bra     m1
or3:    or.b    #0x30,d1                 |set high-order bits
m1:     move.b  d1,-(a6)                |put on stack
	lsr.l   #0x4,d0                  |get next hex digit
	dbf     d2,alp
	movea.l a6,a0                   | CHD write the stack with writs
	bsr     writs
	movem.l (a7)+,#0x4106            |restore registers d1,d2,a0,a6
	rts
|
| Interrupt handler for the keyboard 
| interrupt. It simply stashes the input
| character in a buffer pointed to by a1.
|
| CHD
drtint: move.w  ssrn,sr                 |disable interrupts
	movem.l #0xe060,-(a7)           |save d0, d1, d2, a1, a2                
	move.b  isr+duart,d0            |which interrupt ?
	btst    #1,d0                   |RxRDY A?
	bne     inint
	btst    #5,d0                   |RxRDY B?
	bne     lpint
	bra     out                     |no int source! just return

| CHD
|inint:  move.w  ssrn,sr                 |disable interrupts
|        movem.l #0xe060,-(a7)            |save registers d0,d1,d2,a1,a2
|        move.b  ttyd,d1                 |get the character
inint:  move.b  rba+duart,d1
	andi.b  #0x7f,d1                 |mask out the parity, if any
	btst    #0x3,bkptf               |In emulator mode ?
	beq     incmp                   |No, so continue
	cmp.b   #0x0c,d1                 |ctrl-l ?
	beq     inld                    |yes, so load
	cmp.b   #0x18,d1                 |No, is it a ctrl-x ?
	bne     inwru                   |No, so write it
inld:   bclr    #0x3,bkptf               |Exit emulator mode
	lea     emudn,a1                |set up return
	move.l  a1,0x16(a7)              |put return deep in stack
	cmp.b   #0x0c,d1                 |ctrl-l ?
	bne     out                     |No
	bra     incmp                   |check for ctrl-s or q
inwru:  move.b  d1,d0                   |write to host
	bsr     writu
	bra     out
incmp:  cmp.b   #0x03,d1                 |check for ctrl-c
	beq     rstrt
	cmp.b   #0x13,d1                 |check for ctrl-s
	bne     ctrlq
	move.b  #0x1,ctrls
	bra     out
ctrlq:  cmp.b   #0x11,d1                 |check for ctrl-q
	bne     c1
	move.b  #0x0,ctrls
	bra     out
c1:     lea     ibuff,a1                |get buffer address
	cmpi.b  #0x10,count(a1)          |overflow ?
	blt     cont                    |No
	bra     out                     |Yes, so ignore character
cont:   addq.b  #0x1,tail(a1)            |add chacter to buffer
	addq.b  #0x1,count(a1)           |add 1 to count
	andi.b  #0x0f,tail(a1)           |modulo-16
	move.w  tail(a1),d2             |get offset of new entry
	ror.w   #0x08,d2                 |in lower 8 bits of d2
	andi.w  #0xff,d2                 |mask off what's left
	lea     queue(a1),a1            |get address of queue
	move.b  d1,0x0(a1,d2:w)          |move byte into buffer
	btst    #0x00,echo               |is the echo turned on?
	beq     out                     |if not, skip the echo,
	move.b  d1,d0                   |else setup for echo
	bsr     writ
out:    movem.l (a7)+,#0x0607            |reset registers d0,d1,a1,a2
	rte
|
| Interrupt handler for the load port.
| It stashes the character in the buffer
| pointed to by a1.
|
| CHD
|lpint:  move.w  ssrn,sr                 |same as above but less complex
|        movem.l #0xe060,-(a7)            |registers d0,d1,d2,a1,a2
|        move.b  lpd,d1
lpint:  move.b  rbb+duart,d1            | get character
	andi.b  #0x7f,d1
	btst    #0x3,bkptf
	beq     lplea
	move.b  d1,d0                   |echo for emulator mode
	bsr     writ
	bra     lout
lplea:  lea     lbuff,a1                |queue a character
	cmpi.b  #0x10,count(a1)
	blt     lcont
	bra     out
lcont:  addq.b  #0x1,tail(a1)
	addq.b  #0x1,count(a1)
	andi.b  #0x0f,tail(a1)
	move.w  tail(a1),d2
	ror.w   #0x08,d2
	andi.w  #0xff,d2
	lea     queue(a1),a1
	move.b  d1,0x0(a1,d2:w)
lout:   movem.l (a7)+,#0x0607            |regs d0,d1,d2,a1,a2
	rte
|
| Lgch - get a character from the serial port
| queue. If none available then wait for one
|
|
lgch:   movem.l #0x2060,-(a7)            |save registers d2,a1,a2
lagn:   ori.w   #0x0700,sr               |diable interrupts
	lea     lbuff,a1                |point at buffer
	move.w  count(a1),t1            |see if there is a cahracter
	beq     lwait                   |No, so wait
	move.w  head(a1),d2             |Yes, find it and update
	ror.w   #0x08,d2
	andi.w  #0x00ff,d2
	addq.b  #0x1,head(a1)
	subq.b  #0x1,count(a1)
	andi.b  #0x0f,head(a1)
	lea     queue(a1),a1            |Return character
	move.b  0x0(a1,d2:w),d0
	andi.w  #0xf8ff,sr               |enable interrupts and
	movem.l (a7)+,#0x0604            |regs d2,a1/a2
	rts
lwait:  stop    #0x2000
|	move.w  #0x2000,sr              | enable interrupts
	bra     lagn
|
| Rstrt - restart from control c
|
rstrt:  movem.l (a7)+,#0x0603            |rest regs d0,d1,a1,a2 frm intrpt hndlr
	movem.l #0xffff,dr0              |save registers d0-a7
	move.l  usp,a0                  |save user stack pointer
	move.l  a0,ar7
	move.w  (a7)+,_sr               |save status register from stack
	move.l  (a7)+,_pc               |save program counter from stack
	pea     comm                    |fake a return to command loop
	move.w  ssri,-(a7)              |fake a new status register
	rte
|
| Getch - get a character from the input
| queue. If none available then wait for it
|
getch:  movem.l #0x2060,-(a7)            |same as lgch above d2,a1,a2
tryag:  ori.w   #0x0700,sr
	lea     ibuff,a1
|	move.w  count(a1),t1		| CHD
	move.b	count(a1),t1
	beq     wait
	moveq   #0x0,d0			| ????
	move.w head(a1),d2              | CHD change -- this was a movea.w
	ror.w   #0x08,d2
	andi.w  #0x00ff,d2
	addq.b  #0x1,head(a1)
	subq.b  #0x1,count(a1)
	andi.b  #0x0f,head(a1)
	lea     queue(a1),a1
	move.b  0x0(a1,d2:w),d0
	andi.w  #0xf8ff,sr
	movem.l (a7)+,#0x0604            |regs d2,a1,a2
	rts
wait:   stop    #0x2000
|	move.w  #0x2000,sr              | enable interrupts
	bra     tryag
|
| CRLF - write a carriage return and
| line feed.
|
cf:     dc.b    cr,lf,nul,nul
crlf:   lea     cf,a0
	bsr     writs
	rts
|
| Generalized number fetcher
|
getb:   move.w  #0x1,t1                  |t1 is byte count
	bra     gb
getw:   move.w  #0x3,t1
	bra     gb
getl:   move.w  #0x7,t1
gb:     movem.l #0x6000,-(a7)            |save registers d1,d2
	move.w  t1,d2
	moveq   #0x0,d1
blp:    jsr     (a0)                    |a0 is address of which..
					|routine to use for getting, i.e.
					|serial or terminal port
	cmp.b   #0x3a,d0                 |check for abcdef
	blt     n1
	add.b   #0x09,d0
n1:     and.b   #0x0f,d0
	asl.l   #0x4,d1                  |place in next hex didgit
	or.b    d0,d1
	dbf     d2,blp
	move.l  d1,d0                   |setup return in d0
	movem.l (a7)+,#0x0006            |restore registers d1,d2
	rts
|
| command interpreter
|
ctab:   dc.w    0x4d00           |m - memory update
	dc.l    mem
	dc.w    0x4c00           |l - load from host (S-format)
	dc.l    load
	dc.w    0x0c00           |ctrl-l - load from host (S-format)
	dc.l    lnoof
	dc.w    0x5500           |u - upload program from terminal port
	dc.l    uload
	dc.w    0x4400           |d - dump contents of memory
	dc.l    _dump
	dc.w    0x5300           |s - single step
	dc.l    singl
	dc.w    0x5400           |t - trace a program's path
	dc.l    trace
	dc.w    0x4700           |g - start user program
	dc.l    go
	dc.w    0x0d00           |<cr> - short g command
	dc.l    ggo
	dc.w    0x4500           |e - enter terminal emulator mode
	dc.l    emul
	dc.w    0x4200           |b - set/remove breakpoints
	dc.l    bkpt
	dc.w    0x4300           |c - copy memory blocks
|	dc.l    copy
	dc.l	_copy		| CHD
	dc.w    0x5200           |r - display/modify registers
	dc.l    regs
	dc.w    0x5000           |p - prototype commands
|	dc.l    proto
	dc.l	_c_link_test	| CHD
	dc.w    0x4800           |h - display help messages
	dc.l    help
	dc.w    0x4100           |a - assembly listing
	dc.l    assem
|
| Structure of each entry is command
| (com) and address of servicing routine
| (code)
|
com     =       0x0
code    =       0x2
comm:   lea     prmp,a0                 |write prompt
	bsr     writs
	bsr     getch                   |get command from buffer
	and.b   #0x5f,d0                 |make upper-case
	lea     ctab-6,a2               |set-up search of ctab
	moveq   #0x0f,d2                 |count is one less
clp:    addq.w  #6,a2
	cmp.b   com(a2),d0
	dbeq    d2,clp
	bne     bad                     |search fails
	movea.l code(a2),a2             |get address for success
	jsr     (a2)                    |go to it
	bra     comm                    |loop back for next command
bad:    lea     bcomm,a0                |say it's bad and return
	bsr     writs
	bra     comm
.if 0				| ******************************
|
| Copy - Copy memory blocks
|
|***************************************
|*                                     *
|* Copy is invoked as follows:         *
|*                                     *
|*          c xxxx=yyyy,zzzz           *
|*                                     *
|* Copy locations yyyy thru zzzz to    *
|* locations xxxx and upward.          *
|*                                     *
|***************************************
|
cdmes:  dc.b    lf,cr
	.asciz  "Copied"
ctom:   .asciz  " to "
cform:  .asciz  " for "
cbyt:   .asciz  " bytes"
	dc.b    nul
copy:   bsr     getch                   |get past blank
	lea     getch,a0                |setup for terminal input
	bsr     getw                    |get target address
	move.l  d0,d2                   |save it
	movea.w d0,a2			|
	bsr     getch                   |get past =
	bsr     getw                    |get start address
	move.l  d0,d3                   |save it
	movea.w d0,a3                   |again
	bsr     getch                   |get past ,
	bsr     getw                    |get ending address
	sub.l   d3,d0                   |calculate byte count
	move.l  d0,d4                   |save it
	addq.b  #0x1,d4
colp:   move.b  (a3)+,(a2)+             |start moving
	dbf     d0,colp
	lea     cdmes,a0                |say we're done
	bsr     writs
	move.l  d3,d0
	bsr     writw
	lea     ctom,a0
	bsr     writs
	move.l  d2,d0
	bsr     writw
	lea     cform,a0
	bsr     writs
	move.l  d4,d0
	bsr     writw
	lea     cbyt,a0
	bsr     writs
	rts
.endif			| *******************************
|
| Mem - memory update 
|
|*******************************************
|*                                         *
|* Memory sub-commands are as follows:     *
|*                                         *
|*          m<cr> - start memory mode      *
|*          m xxxx - start m mode at loca- *
|*                     tion xxxx          *
|*          .xxxx - set pointer to location*
|*                  xxxx                   *
|*          =xx - update current location  *
|*                to xx                    *
|*          ,xx - increment location and   *
|*                update it to xx          *
|*          + - increment location         *
|*          - - decrement location         *
|*          <cr> - print current location  *
|*                 and value               *
|*                                         *
|*******************************************
|
mtab:   dc.w    0x2e00           |.
	dc.w    mdot
	dc.w    0x3d00           |=
	dc.w    mequ
	dc.w    0x2c00           |,
	dc.w    mcom
	dc.w    0x2b00           |+
	dc.w    mplu
	dc.w    0x2d00           |-
	dc.w    mmin
	dc.w    0x0d00           |<CR>
	dc.w    mloc
mmes:   dc.b    lf,lf,cr
	.asciz  "Memory Mode"
mprmp:  dc.b    lf,cr,':',nul
meqm:   .asciz  " == "
mem:    bsr     getch                   |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then enter m
	beq     mnoad
	lea     getch,a0                |else get the address
	bsr     getl
	bra     mplp                    |set the address
mnoad:  moveq   #0x0,d0                  |start with no address
mplp:   move.l  d0,exam                 |set the address
	lea     mmes,a0                 |load message
	bsr     writs
mlp:    lea     mprmp,a0                |write memory prompt
	bsr     writs
	bsr     getch                   |enter memory command loop
	moveq   #0x5,d2                  |set for search
	lea     mtab-4,a0
mmlp:   addq.w  #0x4,a0                  |search loop like comm
	cmp.b   (a0),d0
	dbeq    d2,mmlp
	bne     mexit                   |exit if not found
	movea.w 0x2(a0),a0               |get routine address
	jsr     (a0)                    |go to it
	bra     mlp                     |stay in memory loop
mexit:  rts
mdot:   lea     getch,a0                |handle setting of address
	bsr     getl                    |get address
	move.l  d0,exam                 |set in p[ointer
	bsr     mloc                    |print address and value
	rts
mequ:   lea     getch,a0                |handle new value at pointer
	bsr     getb                    |get new value
	movea.l exam,a0                 |set address
	move.b  d0,(a0)                 |move new value
	bsr     mloc                    |write new value
	rts
mcom:   addq.l  #0x1,exam                |handle pointer increment by ,
	bsr     mequ                    |write new address and value
	rts
mplu:   addq.l  #0x1,exam                |increment pointer
	bsr     mloc                    |write val
	rts
mmin:   subq.l  #0x1,exam                |decrement pointer
	bsr     mloc
	rts
mloc:   bsr     crlf                    |write address and value
	move.l  exam,d0                 |write address
	bsr     writl
	lea     meqm,a0
	bsr     writs
	movea.l exam,a0
	move.b  (a0),d0                 |write value
	bsr     writb
	rts
|
| Regs - Modify/examine registers
|
|***************************************
|*                                     *
|* Register subcommands are as follows:*
|*                                     *
|*      r<cr> - start register mode    *
|*      r xx - start r mode at register*
|*        xx. Where xx :               *
|*            SR/_sr - status register *
|*            PC/_pc - program counter *
|*            d0 - d7 - data registers *
|*            a0 - a7 - address regs.  *
|*     .xx - set pointer to regsister  *
|*     =xxxxxxxx - update current reg- *
|*                 ister to xxxxxxxx   *
|*     <cr> - print all registers      *
|*                                     *
|***************************************
|
rtab:   dc.w    0x2e00           |.
	dc.w    rdot
	dc.w    0x3d00           |=
	dc.w    requ
	dc.w    0x0d00           |<cr>
	dc.w    rall
rtab1:  dc.w    0xcb00           |internal name/offset
	.ascii  "SR"                    |print name
	dc.w    0x9c02
	.ascii  "PC"
	dc.w    0xd006
	.ascii  "d0"
	dc.w    0xd10a
	.ascii  "d1"
	dc.w    0xd20e
	.ascii  "d2"
	dc.w    0xd312
	.ascii  "d3"
	dc.w    0xd416
	.ascii  "d4"
	dc.w    0xd51a
	.ascii  "d5"
	dc.w    0xd61e
	.ascii  "d6"
	dc.w    0xd722
	.ascii  "d7"
	dc.w    0xa026
	.ascii  "a0"
	dc.w    0xa12a
	.ascii  "a1"
	dc.w    0xa22e
	.ascii  "a2"
	dc.w    0xa332
	.ascii  "a3"
	dc.w    0xa436
	.ascii  "a4"
	dc.w    0xa53a
	.ascii  "a5"
	dc.w    0xa63e
	.ascii  "a6"
	dc.w    0xa742
	.ascii  "a7"
rmes:   dc.b    lf,lf,cr
	.asciz  "Register Mode"
rprmp:  dc.b    lf,cr,':',nul
reqm:   .asciz  " == "
regs:   bsr getch                       |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then start at sr
	beq     rnoad
	lea     getch,a0                |else set for terminal input
	bsr     getb                    |get register name
	bsr     raddr                   |set address
	bra     rplp                    |set register pointer
rnoad:  lea     rtab1,a3                |set default pointer value
	move.l  a3,rexam                
rplp:   lea     rmes,a0                 |say hello
	bsr     writs
	bsr     rloc                    |write starting loc value
rlp:    lea     rprmp,a0                |write register prompt
	bsr     writs
	bsr     getch                   |get command
	moveq   #0x2,d2                  |set for search
	lea     rtab-4,a0
rmlp:   addq.w  #0x4,a0                  |search
	cmp.b   (a0),d0
	dbeq    d2,rmlp
	bne     rexit                   |exit if not found
	movea.w 0x2(a0),a0               |found it so go to it
	jsr     (a0)
	bra     rlp                     |go again
rexit:  rts
rdot:   lea     getch,a0                |set register pointer
	bsr     getb
	bsr     raddr                   |set input address
	bsr     rloc                    |write register and value
	rts
requ:   lea     getch,a0                |set new value
	movea.l rexam,a3
	moveq   #0x0,d1                  |clear d1
	move.b  0x1(a3),d1               |get offset
	beq     requs                   |branch if sr is reg
	bsr     getl                    |get new value
	lea     _sr,a4                  |find save area offset
	adda.l  d1,a4                   |add offset
	move.l  d0,(a4)                 |move in new value
	bra     requr                   |print it
requs:  bsr     getw                    |same as above but for sr (word vs. long
	move.w  d0,_sr
requr:  bsr     rloc                    |write new value
	rts
rall:   lea     rtab1-4,a3              |write all registers
	moveq   #0x11,d2                 |set count
ralp:   addq.l  #0x4,a3                  |loop
	move.l  a3,rexam
	bsr     rloc
	dbf     d2,ralp
	rts
raddr:  move.w  #0x11,d4                 |find offset in save area
	lea     rtab1-4,a3
radlp:  addq.l  #0x4,a3
	cmp.b   (a3),d0
	dbeq    d4,radlp
	bne     rexit
	move.l  a3,rexam                |set register pointer
	rts
rloc:   bsr     crlf                    |print register name and value
	movea.l rexam,a4
	move.b  0x2(a4),d0               |write name
	bsr     writ
	move.b  0x3(a4),d0
	bsr     writ
	lea     reqm,a0
	bsr     writs
	moveq   #0x0,d0
	move.b  0x1(a4),d0               |write value
	beq     rpsr                    |branch if sr
	lea     _sr,a0                  |find offset
	adda.l  d0,a0                   |add offset
	move.l  (a0),d0                 |move in new value
	bsr     writl
	bra     rrts
rpsr:   move.w  _sr,d0                  |write sr value
	bsr     writw
rrts:   rts
|
| Load - Load data from host
|
|****************************************
|*                                      *
|* Load is invoked as follows:          *
|*                                      *
|*       l<cr> - load from host with no *
|*               offset                 *
|*       <ff> - same as l<cr> but used  *
|*              only exiting emulator   *
|*       l xxxx - load with offset xxxx *
|*                                      *
|****************************************
|
lmes:   dc.b    lf,cr
	.asciz  "Load..."
slmes:  dc.b    lf,cr
	.asciz  "User PC == "
elmes:  dc.b    lf,cr
	.asciz  "Load done..."
	dc.b    nul

load:   bsr     getch                   |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then no offset
	beq     lnoof
	lea     getch,a0                |get offset
	bsr     getw
	move.l  d0,_pc                  |save load point for go command
	bra     ld1
lnoof:  move.l  #0x0,_pc
ld1:    lea     lbuff,a1                |point at lpbuff
	move.w  #0x0,head(a1)            |set queue for lp
	move.w  #0xffff,tail(a1)         
	move.w  #0x0,count(a1)           
	lea     lmes,a0                 |print starting message
	bsr     writs
	move.b  #0x0d,d0                 |load a <cr>
	bsr     writu                   |send it to the host
	lea     lgch,a0                 |set up for host load routine
llp:    jsr     (a0)                    |get S
	cmp.b   #0x53,d0
	bne     llp                     |No - start over
	jsr     (a0)                    |get 1 or 9 and 3 or 7
	cmp.b   #0x39,d0                 |9 - then done
	beq     ldone
	cmp.b	#0x37,d0		 |7 - then done
	beq	ldone9
	cmp.b	#0x33,d0		 |3 - then another record
	beq	ld3
	cmp.b   #0x31,d0                 |1 - then another record
	bne     llp
	bsr     getb                    |get byte count
	move.l  d0,d1
	subq.w  #0x4,d1                  |remove count for check
	bsr     getw
ldl1:	add.l   _pc,d0                  |add offset
	movea.l d0,a1                   |save starting address
lblp:   bsr     getb                    |get actual data byte
	move.b  d0,(a1)+                |move to memory
	dbf     d1,lblp                 |loop for count
	bsr     getb                    |gobble up check and crlf
	bra     llp                     |try another record
ld3:	bsr	getb			|get byte count
	move.l	d0,d1
	subq.w	#0x6,d1			|remove count for check
	bsr	getl			|get address
	bra	ldl1	
ldone9:	jsr	(a0)			|gobble up byte count
	jsr	(a0)
	bsr	getl			|get address from end macro
	bra	ldon1
ldone:  jsr     (a0)                    |gobble up byte count
	jsr     (a0)
	bsr     getw                    |get address from end macro
ldon1:	add.l   _pc,d0                  |add offset
	move.l  d0,d1                   |save it
	move.l  d0,_pc                  |set starting address for go
	move.w  #0x0,_sr                 |set status register
	move.l  #0x10,d0
	lea     dr0,a1
lreg:   move.l  #0x0,(a1)+
	dbf     d0,lreg
	movea.l a0,a2                   |save the port location in a2
	lea     ustck,a0
	move.l  a0,ar7                  |set user stack
	lea     slmes,a0                |write message
	bsr     writs
	move.l  d1,d0
	bsr     writl                   |write starting address
	move.l  #0x04,d1                 |gobble up last four bytes
	movea.l a2,a0                   |restore the port location to a0
ll2:    jsr     (a0)
	dbf     d1,ll2
	lea     elmes,a0                |send last message
	bsr     writs
	bset    #0x00,echo               |turn terminal echo back on
	rts     
|
| Upload - upload program from terminal port
|
|****************************************
|*                                      *
|* Upload is invoked as follows:        *
|*                                      *
|*       u<cr> - load from terminal     *
|*               with no offset         *
|*       u xxxx - load with offset xxxx *
|*                                      *
|****************************************
|
uload:  bsr     getch                   |same as above, except that it
	cmp.b   #0x0d,d0                 |uses the terminal port for the
	beq     ulnoof                  |load.
	lea     getch,a0
	bsr     getw
	move.l  d0,_pc
	bra     uld1
ulnoof: move.l  #0x0,_pc
uld1:   lea     ibuff,a1
	move.w  #0x0,head(a1)
	move.w  #0xffff,tail(a1)
	move.w  #0x0,count(a1)
	lea     lmes,a0
	bsr     writs
	move.b  #0x0d,d0
	bsr     writu
	lea     getch,a0
	bclr    #0x00,echo
	bra     llp                     |goes to the load routine above
|
| e - Enter terminal emulator mode          *
|
|********************************************
|*                                          *
|* Invoke emulator mode as follows          *
|*                                          *
|*       e                                  *
|*                                          *
|*    NOTE: That in this mode any char-     *
|*    except a ctrl-x may be sent to the    *
|*    host. Ctrl-x is the escape sequence   *
|*    for getting out of terminal emulator  *
|*    mode. Ctrl-l does the same thing      *
|*    except a load (l) command is put      *
|*    in the command buffer.                *
|*                                          *
|********************************************
|
emmes:  dc.b    lf,cr
	.asciz  "Exit terminal mode"
enmes:  dc.b    lf,cr
	.ascii  "Terminal mode:"
	dc.b    lf,cr,nul
emul:   lea     enmes,a0                |write message
	bsr     writs
	bset    #0x3,bkptf               |set emulator mode
emu1:   nop
|       stop    #0x2000                  |wait for interrupt
	move.w  #0x2000,sr              | enable interrupts
					|if interrupted the handlers
					|will buffer and echo input
	bra     emu1
emudn:  lea     emmes,a0                |entered from interrupt handler
	bsr     writs
	rts
|
| Proto - Prototype command in ram
|
|******************************************
|*                                        *
|* Prototype commands are invoked:        *
|*                                        *
|*      px xxxx - load address xxxx for   *
|*                prototype command x.    *
|*      px<cr> - execute prototype com-   *
|*               mand x.                  *
|*                                        *
|*      NOTE: x must be a 1, 2, or 3      *
|*                                        *
|******************************************
|
pmess:  dc.b    lf,cr
	.asciz  "Prototype "
pm1:    .ascii  "running:"
	dc.b    lf,cr,nul
pm2:    .ascii  "installed"
	dc.b    cr,nul,nul
proto:  bsr     getch                   |get prototype number
	move.l  d0,d1                   |save number
	andi.b  #0x0f,d1                 |strip leading hex digit
	subq.b  #0x1,d1                  |normalize to 0
	lsl.l   #0x1,d1                  |multiply by 2
	lea     ptab,a1                 |set starting address
	adda.l  d1,a1                   |add offset
	bsr     getch                   |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then do command
	beq     prun            
	lea     getch,a0                |else install in table
	bsr     getw                    |get address
	move.w  d0,(a1)                 |move in address
	lea     pmess,a0
	bsr     writs
	lea     pm2,a0
	bsr     writs
	bra     prts
prun:   movea.w (a1),a1                 |run prototype command
	lea     pmess,a0
	bsr     writs
	lea     pm1,a0
	bsr     writs
	jsr     (a1)                    |go do it
prts:   rts
|
| Bkpt - Set/Remove breakpoints
|
|
|**********************************************
|*                                            *
|* Breakpoint is invoked as follows:          *
|*                                            *
|*         b<cr> - display breakpoints        *
|*         b+xxxx - add a breakpoint at xxxx  *
|*         b-xxxx - delete breakpoint at xxxx *
|*         b# - delete all breakpoints        *
|*                                            *
|**********************************************
|
brmes:  dc.b    lf,cr
	.asciz  "Bkpts removed"
bdmes:  dc.b    lf,cr
	.ascii  "Bkpts at:"
	dc.b    lf,cr,nul
bpmes:  dc.b    lf,cr
	.asciz  "Bkpt added at "
bmmes:  dc.b    lf,cr
	.asciz  "Bkpt deleted at "
bbmes:  dc.b    lf,cr
	.asciz  "Bkpt error"
	dc.b    nul
bkin:   dc.w    0xFFFF                   |instruction constant
bkpt:   bsr     getch                   |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then print all bkpts
	beq     bdis
	cmp.b   #0x2b,d0                 |if + then add a bkpt
	beq     bpls
	cmp.b   #0x2d,d0                 |if - then delete a bkpt
	beq     bmin
	cmp.b   #0x23,d0                 |if # then delete all bkpts
	bne     bbad                    |else its a bad message
brem:   moveq   #0x4,d1                  |remove all bkpts
	lea     bktab-6,a1              |set for loop
blp1:   adda.l  #0x6,a1
	movea.l iloc(a1),a0             |get address from table
	cmpa.l  #0x00,a0                 |if 0 then not an entry
	beq     bno
	move.w  instr(a1),(a0)          |else move instr back
	move.w  #0x0,instr(a1)           |clear table entry
	move.l	#0x0,iloc(a1)
bno:    dbf     d1,blp1                 |loop
	bclr    #0x0,bkptf               |clear bkpt if in one
	btst    #0x2,bkptf               |In trace ?
	bne     brno                    |Yes.
	andi.w  #0x7fff,_sr              |else clear trace bit
brno:   lea     brmes,a0                |say done
	bsr     writs
	bra     brts
bdis:   lea     bdmes,a0                |handle display all bkpts
	bsr     writs
	lea     bktab-6,a1              |set loop
	moveq   #0x4,d1
bdlp:   adda.l  #0x6,a1                  |loop
	move.l  iloc(a1),d0             |get bkpt
	beq     belp                    |if 0 then not an entry
	bsr     writl
	bsr     crlf
belp:   dbf     d1,bdlp                 |loop
	bra     brts
bpls:   lea     bktab-6,a1              |add a bkpt
	moveq   #0x4,d1                  |set for loop
	lea     getch,a0                |setup to get address
	bsr     getl
bl2:    adda.l  #0x6,a1                  |loop
	cmp.l   iloc(a1),d0             |found entry already in table ?
	bne     bmo                     |yes
	movea.l d0,a2                   |reset it for insurance
	move.w  bkin,(a2)               |set instruction
	bra     bfnd                    |exit for found
bmo:    move.l  iloc(a1),d2             |move to set condition codes
	dbeq    d1,bl2                  |exit if 0 entry found
	bne     bbad                    |if exit is on count and not 0 then error
	move.l  d0,iloc(a1)             |move in address
	movea.l d0,a2                   |point at location
	move.w  (a2),instr(a1)          |get instruction into table
	move.w  bkin,(a2)               |set bkpt instruction
bfnd:   lea     bpmes,a0                |load message
	bsr     writs
	move.l  a2,d0
	bsr     writl
	bclr    #0x1,bkptf               |clear in-single flag
	btst    #0x2,bkptf               |In trace ?
	bne     brts                    |Yes
	andi.w  #0x7fff,_sr              |clear trace bit
	bra     brts
bmin:   lea     bktab-6,a1              |delete a breakpoint entry
	moveq   #0x4,d1                  |setup for search
	lea     getch,a0                |setup for terminal input
	bsr     getl
bl3:    adda.l  #0x6,a1                  |loop
	cmp.l   iloc(a1),d0             |Is this the one ?
	dbeq    d1,bl3                  |if yes then exit else loop
	bne     bbad                    |Exit on count ?
	movea.l d0,a2                   |no, so get address
	move.w  instr(a1),(a2)          |return instruction
	move.w  #0x0,instr(a1)           |clear table entry
	move.l	#0x0,iloc(a1)
	btst    #0x0,bkptf               |In breakpoint ?
	beq     bok                     |No
	cmp.l   _pc,d0                  |Yes, This breakpoint ?
	bne     bok                     |No
	bclr    #0x0,bkptf               |Yes, so clear handling it
	btst    #0x2,bkptf               |In trace ?
	bne     bok                     |Yes
	andi.w  #0x7fff,_sr              |else clear trace flag
bok:    lea     bmmes,a0                |load message
	bsr     writs
	move.l  a2,d0                   |print address
	bsr     writl
	bra     brts
bbad:   lea     bbmes,a0                |error handler
	bsr     writs
brts:   rts

.if 0	| CHD ***********************************************
|
| dump - dump memory
|
|*****************************************
|*                                       *
|*    dump is invoked as follows:        *
|*                                       *
|*    d<cr> - dump the next 64 bytes from*
|*            last examined location     *
|*    d xxxx<cr> - dump the next 64 bytes*
|*                 from address xxxx     *
|*    d xxxx,yyyy - dump the bytes bet-  *
|*                  ween xxxx and yyyy   *
|*                                       *
|*****************************************
|
dmes:   dc.b    lf,lf,cr
	.ascii  "Memory dump"
	dc.b    lf,cr,nul
dhed:   dc.b    lf,cr
	.ascii  "      0  1  2  3"
	.ascii  "  4  5  6  7  8  9  a"
	.ascii  "  B  C  d  E  F"
dcr:    dc.b    lf,cr,nul
dump:   lea     getch,a0                |set for terminal input
	bsr     getch                   |get delimiter
	cmp.b   #0x0d,d0                 |if <cr> then dump from pointer
	bne     dexam                   |else get address
	movea.w exam,a1                 |get exam
	movea.w a1,a2                   |save it for ending address
	adda.w  #0x40,a2                 |add 64 for length of dump
	bra     dgo                     |go do it
dexam:  bsr     getw                    |get starting address
	movea.w d0,a1
	bsr     getch                   |get delimiter
	cmp.b   #0x2c,d0                 |if , the get ending address
	bne     dcom
	bsr     getw                    |get address
	movea.w d0,a2                   |save it
	bra     dgo                     |go dump
dcom:   movea.w a1,a2                   |default to 64 byte dump
	adda.w  #0x40,a2
dgo:    lea     dmes,a0                 |do the dump
	bsr     writs
	lea     dhed,a0                 |print header
	bsr     writs
	move.l  a1,d0                   |set starting address at 16 byte boundary
	and.b   #0xf0,d0
	movea.w d0,a1
	move.l  a2,d0                   |round ending address to boundary
	or.b    #0x0f,d0
	movea.w d0,a2
	moveq   #0x0f,d1                 |move byte count to register
dl1:    move.l  a1,d0                   |write starting address
	bsr     writw
	movea.w a1,a3                   |save starting address
dflp:   moveq   #0x20,d0                 |write a space
	bsr     writ
	move.b  (a1)+,d0                |get next byte
	bsr     writb                   |write it
	dbf     d1,dflp                 |loop
	moveq   #0x0f,d1                 |reset byte count
	movea.w a3,a1                   |refetch starting address
	moveq   #0x20,d0                 |write a space
	bsr     writ
dslp:   move.b  (a1)+,d0                |write the byte representation
	cmp.b   #0x20,d0                 |if not printable then a dot
	bge     dok
	move.b  #0x2e,d0                 |move in the dot
	bra     dwrt
dok:    cmp.b   #0x7f,d0                 |printable again ?
	blt     dwrt                    |yes
	move.b  #0x2e,d0                 |no, move in a dot
dwrt:   bsr     writ                    |write it
	dbf     d1,dslp                 |line done ?
	lea     dcr,a0                  |yes, so cr-lf
	bsr     writs
	moveq   #0x10,d1                 |reset byte count
	cmpa.l  a1,a2                   |done ?
	dblt    d1,dl1                  |NO, so loop
	move.w  a1,exam                 |yes, so update exam
	rts
.endif			| **********************************************
|
| Trace - Set trace mode
|
|*****************************************
|*                                       *
|* Invoke trace as follows:              *
|*                                       *
|*       t+ - trace a program's path     *
|*       t- - turn off trace             *
|*                                       *
|*****************************************
|
tmes:   dc.b    lf,cr
	.asciz  "Trace "
tonm:   .asciz  "on"
toffm:  .asciz  "off"
trace:  bsr     getch                   |get command
	move.l  d0,d1                   |save it
	lea     tmes,a0                 |write message
	bsr     writs
	cmp.b   #0x2b,d1                 |Is it a + ?
	beq     ton                     |yes
	btst    #0x0,bkptf               |In breakpoint ?
	bne     tclr                    |Yes, so don't clear trace
	andi.w  #0x7fff,_sr              |clear trace
tclr:   bclr    #0x2,bkptf               |turn-off in-trace flag
	lea     toffm,a0                |load off message
	bra     tdone                   |exit
ton:    ori.w   #0x8000,_sr              |set trace bit
	bclr    #0x1,bkptf               |clear single step
	bset    #0x2,bkptf               |set in-trace flag
	lea     tonm,a0                 |write message
tdone:  bsr     writs
	rts
|
| Single - set single step                
|
|*****************************************
|*                                       *
|* Invoke single step as follows:        *
|*                                       *
|*       s+ - turn on single step        *
|*       s- - turn off single step       *
|*                                       *
|*****************************************
|
smes:   dc.b    lf,cr
	.asciz  "Single step"
sonm:   .asciz  " on "
soffm:  .asciz  " off "
	dc.b    nul
singl:  bsr     getch                   |get command
	move.l  d0,d1                   |save it
	lea     smes,a0                 |write message
	bsr     writs           
	cmp.b   #0x2b,d1                 |+ ?
	beq     son                     |yes
	btst    #0x0,bkptf               |In breakpoint ?
	bne     sclr                    |Yes, so don't clear trace
	andi.w  #0x7fff,_sr              |clear trace bit
sclr:   bclr    #0x1,bkptf               |turn-off in-single flag
	lea     soffm,a0                |write off message
	bsr     writs           
	bra     sdone                   |exit
son:    bclr    #0x0,bkptf               |clear in-bkpt flag
	bset    #0x1,bkptf               |set in-single flag
	bclr    #0x2,bkptf               |clear in-trace flag
	lea     sonm,a0                 |write message
	bsr     writs           
	bsr     brem                    |remove all breakpoints for single
	ori.w   #0x8000,_sr              |set trace bit
sdone:  rts             
|
| Go - Start user program
|
|*****************************************
|*                                       *
|* Invoke go as follows:                 *
|*                                       *
|*      g<cr> - go from start address in *
|*              last load                *
|*      <cr> - same as g<cr>             *
|*      g xxxx - go from address xxxx    *
|*                                       *
|*****************************************
|
gmes:   dc.w    csc
	.ascii  "Program:"
	dc.b    lf,lf,cr,nul
go:     bsr     getch                   |get seperator
	cmp.b   #0x0d,d0                 |if CR then
	beq     ggo                     |start from default
gget:   lea     getch,a0                |else get start addr
	bsr     getl                    |as given in comm.
	move.l  d0,_pc                  |set for return
ggo:    btst    #0x1,bkptf               |single set ?
	bne     gnom                    |Yes so no message
	lea     gmes,a0                 |write message
	bsr     writs
gnom:   addq.w  #0x4,a7                  |pop the stack
	movem.l dr0,#0x7fff              |get saved values d0-a6
	move.l  a7,t1                   |save system stack pointer
	movea.l ar7,a7                  |get saved user stack pointer
	move.l  a7,usp                  |reset the user stack
	movea.l t1,a7                   |reset system stack
gbmov:  move.l  _pc,-(a7)               |set up return pc
	andi.w  #0xf8ff,_sr              |enable interrupts
	move.w  _sr,-(a7)               |set up return sr
	rte

|++++++++++++++++++++++++++++++++++++++++
|+                                      +
|+     End of commands, Start Handlers  +
|+                                      +
|++++++++++++++++++++++++++++++++++++++++
|
| Generic trap handler
|
ghmes:  dc.b    lf,cr
	.asciz  "Trap at "
	dc.b    nul
ghlr:   movem.l #0xffff,dr0              |save all registers d0-a7
	move.l  usp,a6                  |get user stack pointer
	move.l  a6,ar7                  |and save it
	move.w  (a7)+,_sr               |save current SR
	move.l  (a7)+,_pc               |save current return value
	pea     comm                    |set for return to comm
	move.w  ssri,-(a7)              |enable interrupts on return
ghpr:   lea     ghmes,a0                |wx message
ghpr1:  bsr     writs
	move.l  _pc,d0
	bsr     writl
	rte
|
| Breakpoint handler
|
bhmes:  dc.b    lf,cr
	.asciz  "Breakpoint at "
binin:  dc.b    lf,cr
	.asciz  "Bad Instruction at "
	dc.b    nul
bhlr:   move.w  ssrn,sr                 |disable interrupts
	movem.l #0xffff,dr0              |save registers d0-a7
	move.l  usp,a6                  |get and save user stack pointer
	move.l  a6,ar7
	move.w  (a7)+,_sr               |save status register
	move.l  (a7)+,_pc               |save program counter
	pea     comm                    |set for return to comm
	move.w  ssri,-(a7)              |enable interrupts on return
	movea.l _pc,a0                  |get pc on interrupt
	cmpi.w  #0xffff,(a0)             |was interrupt caused by bkpt instruction ?
	beq     bsnd                    |Yes
	lea     binin,a0                |No, invalid instruction
	bra     ghpr1                   |go wx message
bsnd:   lea     bhmes,a0                |wx bkpt message
	bsr     writs
	move.l  _pc,d0
	bsr     writw
	bsr     crlf
	lea     bktab-4,a1              |find the breakpoint entry
	move.l  #0x4,d1                  |maximum of 5
	move.l  _pc,d0                  |this is where it happened
bhl:    adda.w  #0x4,a1
	cmp.w   iloc(a1),d0             |is this the entry ?
	dbeq    d1,bhl                  |loop if not
	bne     bhrte                   |not found so quit
	movea.w d0,a2                   |point at it
	move.w  instr(a1),(a2)          |move instruction back in
	ori.w   #0x8000,_sr              |set trace mode on
	bset    #0x0,bkptf               |set in-bkpt flag
bhrte:  rte
|
| Trace handler
|
tlocm:  dc.b    lf,cr
	.asciz  "PC == "
	dc.b    nul
thlr:   move.w  ssrn,sr                 |disable interrupts
	move.l  a0,ar0                  |save used registers
	move.l  d0,dr0          
	move.l  a1,ar1
	move.l  d1,dr1
	move.l  a2,ar2
	move.l  d2,dr2
	btst    #0x0,bkptf               |Handling a breakpoint ?
	beq     treal                   |No, so its a real trace
	movea.l _pc,a0                  |Yes, find where it occurred
	move.w  bkin,(a0)               |reset the bkpt instruction
	bclr    #0x0,bkptf               |clear in progress bkpt
	btst    #0x2,bkptf               |In trace mode
	bne     treal                   |yes, go trace it
thma0:  andi.w  #0x7fff,(a7)             |No, so clear the trace bit
	bra     trte            
treal:  move.l  0x2(a7),_pc              |Not (just) a bkpt but trace or single
	btst    #0x1,bkptf               |Trace ?
	beq     trpr                    |Yes
	movem.l #0xffff,dr0              |No,single-step d0-a7
	move.l  usp,a6                  |save registers and stack pointer
	move.l  a6,ar7          
	move.w  (a7)+,_sr               |save status register
	move.l  (a7)+,_pc               |save pc
	pea     comm                    |fake return to comm
	move.w  ssri,-(a7)              |enable interrupts on return
trpr:   lea     tlocm,a0                |wx message
	bsr     writs           
	move.l  _pc,d0          
	bsr     writl           
	bsr     crlf
	move.l  _pc,a1                  |load the current address
	bsr     ass1                    |wx the disassembled instruction
trte:   movea.l ar0,a0                  |restore used registers
	move.l  dr0,d0          
	movea.l ar1,a1
	move.l  dr1,d1
	movea.l ar2,a2
	move.l  dr2,d2
tr:     rte             
|
| Privilege Violation Handler
|
| See generic handler for details
|
prmes:  dc.b    lf,cr
	.asciz  "Privilege Error at "
phlr:   movem.l #0xffff,dr0              |regs d0-a7
	move.l  usp,a6
	move.l  a6,ar7
	move.w  (a7)+,_sr
	move.l  (a7)+,_pc
	pea     comm
	move.w  ssri,-(a7)
prpr:   lea     prmes,a0
	bra     ghpr1
|
| address error/bus error trap
|
abmes:  dc.b    lf,cr
	.asciz  "address error at "
abhlr:  movem.l #0xffff,dr0              |regs d0-a7
	move.l  usp,a6
	move.l  a6,ar7                  |same as above but...
	move.w  0x8(a7),_sr              |status register is deeper in stack
	move.l  0xa(a7),_pc              |also pc
	pea     comm
	move.w  ssri,-(a7)
abpr:   lea     abmes,a0
	bra     ghpr1
|
| Macro instruction handlers
|
|
| Exit
|
texit:  movem.l #0xffff,dr0              |save register values d0-a7
	move.l  usp,a6                  |save user stack pointer
	move.l  a6,ar7          
	move.w  (a7)+,_sr               |save status register
	move.l  (a7)+,_pc               |save pc
	lea     stack,a7                |reset system mode stack
	pea     comm                    |fake return to comm
	move.w  ssri,-(a7)              |ditto for status
	rte             
|
| Getb
|
tgetb:  lea     getch,a0
	bsr     getb
	rte
|
| Getw
|
tgetw:  lea     getch,a0
	bsr     getw
	rte
|
| Getl
|
tgetl:  lea     getch,a0
	bsr     getl
	rte
|
| Wrtb
|
twrtb:  bsr     writb
	rte
|
| Wrtw
|
twrtw:  bsr     writw
	rte
|
| Wrtl
|
twrtl:  bsr     writl
	rte
|
| Getc
|
tgetc:  bsr     getch
	rte
|
| Wrts
|
twrts:  bsr     writs
	rte
|
| Wrtc
|
twrtc:  bsr     writ
	rte
|
| Crlf
|
tcrlf:  bsr     crlf
	rte
|
| Help - display help messages
|
|*****************************************
|*                                       *
|* Invoke help as follows:               *
|*                                       *
|*      h<cr> - print list of available  *
|*              help                     *
|*      hx - print help message for x    *
|*                                       *
|*****************************************
hlph:   .ascii " H - display help messages"
	dc.b    cr,lf,nul
hlph1:  .ascii " Invoke help as follows:"
	dc.b    cr,lf
	.ascii "      h<cr> - print list of available help"
	dc.b    cr,lf
	.ascii "      hx - print help message for x"
	dc.b    cr,lf,nul

hlpc:   .ascii " C - Copy memory blocks (32 bit)"
	dc.b    cr,lf,nul
hlpc1:  .ascii " Copy is invoked as follows:"
	dc.b    cr,lf
	.ascii "          c src dst len<cr>"
	dc.b    cr,lf
	.ascii " Copy block of len bytes from"
	dc.b    cr,lf
	.ascii " locations src to dst."
	dc.b    cr,lf,nul

hlpm:   .ascii " M - memory update"
	dc.b    cr,lf,nul
hlpm1:  .ascii " Memory sub-commands are as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "          m<cr> - start memory mode"
	dc.b    cr,lf
	.ascii "          m xxxx - start m mode at location xxxx"
	dc.b    cr,lf
	.ascii "          .xxxx - set pointer to location xxxx"
	dc.b    cr,lf
	.ascii "          =xx - update current location to xx"
	dc.b    cr,lf
	.ascii "          ,xx - increment location and update it to xx"
	dc.b    cr,lf
	.ascii "          + - increment location"
	dc.b    cr,lf
	.ascii "          - - decrement location"
	dc.b    cr,lf
	.ascii "          <cr> - print current location and value"
	dc.b    cr,lf,nul

hlpr:   .ascii " R - Modify/examine registers"
	dc.b    cr,lf,nul
hlpr1:  .ascii " Register subcommands are as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "      r<cr> - start register mode"
	dc.b    cr,lf
	.ascii "      r xx - start r mode at register xx. Where xx :"
	dc.b    cr,lf
	.ascii "            SR/_sr - status register"
	dc.b    cr,lf
	.ascii "            PC/_pc - program counter"
	dc.b    cr,lf
	.ascii "            d0 - d7 - data registers"
	dc.b    cr,lf
	.ascii "            a0 - a7 - address regs."
	dc.b    cr,lf
	.ascii "     .xx - set pointer to register"
	dc.b    cr,lf
	.ascii "     =xxxxxxxx - update current register to xxxxxxxx"
	dc.b    cr,lf
	.ascii "     <cr> - print all registers"
	dc.b    cr,lf,nul

hlpl:   .ascii " L - Load data from host"
	dc.b    cr,lf,nul
hlpu:   .ascii " U - Load data from terminal port"
	dc.b    cr,lf,nul
hlpl1:  .ascii " Load is invoked as follows:"
	dc.b    cr,lf
	.ascii "       l<cr> - load from host with no offset"
	dc.b    cr,lf
	.ascii "       <ff> - same as l<cr> but used from emulator mode"
	dc.b    cr,lf
	.ascii "       l xxxx - load with offset xxxx"
	dc.b    cr,lf,cr,lf
	.ascii " Upload is invoked as follows:"
	dc.b    cr,lf
	.ascii  "      u<cr> - load from terminal with no offset"
	dc.b    cr,lf
	.ascii  "      u xxxx - load from terminal with offset xxxx"
	dc.b    cr,lf,nul

hlpe:   .ascii " E - Enter terminal emulator mode"
	dc.b    cr,lf,nul
hlpe1:  .ascii " Invoke emulator mode as follows"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "       e"
	dc.b    cr,lf
	.ascii "    NOTE: That in this mode any character except"
	dc.b    cr,lf
	.ascii "    a ctrl-x may be sent to the host. Ctrl-x is the"
	dc.b    cr,lf
	.ascii "    escape sequence for getting out of terminal emulator"
	dc.b    cr,lf
	.ascii "    mode. Ctrl-l does the same thing except a load (l)"
	dc.b    cr,lf
	.ascii "    command is put in the command buffer."
	dc.b    cr,lf,nul

hlpp:   .ascii " P - Prototype commands in RAM"
	dc.b    cr,lf,nul
hlpp1:  .ascii " Prototype commands are invoked:"
	dc.b    cr,lf
	.ascii "      px xxxx - load address xxxx for prototype command x."
	dc.b    cr,lf
	.ascii "      px<cr> - execute prototype command x."
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "      NOTE: x must be a 1, 2, or 3"
	dc.b    cr,lf,nul

hlpb:   .ascii " B - Set/Remove breakpoints"
	dc.b    cr,lf,nul
hlpb1:  .ascii " Breakpoint is invoked as follows:"
	dc.b    cr,lf
	.ascii "         b<cr> - display breakpoints"
	dc.b    cr,lf
	.ascii "         b+xxxx - add a breakpoint at xxxx"
	dc.b    cr,lf
	.ascii "         b-xxxx - delete breakpoint at xxxx"
	dc.b    cr,lf
	.ascii "         b# - delete all breakpoints"
	dc.b    cr,lf,nul

hlpd:   .ascii " D - dump memory (32 bit)"
	dc.b    cr,lf,nul
hlpd1:  .ascii "    dump is invoked as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "    d<cr> - dump the next 128 bytes from last examined location"
	dc.b    cr,lf
	.ascii "    d src<cr> - dump the next 64 bytes from address xxxx"
	dc.b    cr,lf
	.ascii "    d src dst<cr> - dump the bytes between src and dst"
	dc.b    cr,lf,nul

hlpa:   .ascii " A - Assembly listing"
	dc.b    cr,lf,nul
hlpa1:  .ascii "    disassembly is invoked as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "    a<cr> - list the next 20 instructions from last location"
	dc.b    cr,lf
	.ascii "    a xxxx<cr> - list the next 20 instructions from address xxxx"
	dc.b    cr,lf
	.ascii "    a xxxx,yyyy - list the instructions between xxxx and yyyy"
	dc.b    cr,lf,nul

hlpt:   .ascii " T - Set trace mode"
	dc.b    cr,lf,nul
hlpt1:  .ascii " Invoke trace as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "       t+ - trace a program's path"
	dc.b    cr,lf
	.ascii "       t- - turn off trace"
	dc.b    cr,lf,nul

hlps:   .ascii " S - set single step"
	dc.b    cr,lf,nul
hlps1:  .ascii " Invoke single step as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "       s+ - turn on single step"
	dc.b    cr,lf
	.ascii "       s- - turn off single step"
	dc.b    cr,lf,nul

hlpg:   .ascii " G - Start user program"
	dc.b    cr,lf,nul
hlpg1:  .ascii " Invoke go as follows:"
	dc.b    cr,lf
	dc.b    cr,lf
	.ascii "      g<cr> - go from start address in last load"
	dc.b    cr,lf
	.ascii "      <cr> - same as g<cr>"
	dc.b    cr,lf
	.ascii "      g xxxx - go from address xxxx "
	dc.b    cr,lf,nul

htab:   dc.w    0x4800           |h - help
	dc.w    hlph,hlph1
	dc.w    0x4d00           |m - memory
	dc.w    hlpm,hlpm1
	dc.w    0x4c00           |l - load
	dc.w    hlpl,hlpl1
	dc.w    0x5500           |u - upload
	dc.w    hlpu,hlpl1
	dc.w    0x4400           |d - dump
	dc.w    hlpd,hlpd1
	dc.w    0x5300           |s - single step
	dc.w    hlps,hlps1
	dc.w    0x5400           |t - trace program
	dc.w    hlpt,hlpt1
	dc.w    0x4700           |g - start user program
	dc.w    hlpg,hlpg1
	dc.w    0x4500           |e - emulate mode
	dc.w    hlpe,hlpe1
	dc.w    0x4200           |b - breakpoints
	dc.w    hlpb,hlpb1
	dc.w    0x4300           |c - copy
	dc.w    hlpc,hlpc1
	dc.w    0x5200           |r - register modify
	dc.w    hlpr,hlpr1
	dc.w    0x5000           |p - prototype commands
	dc.w    hlpp,hlpp1
	dc.w    0x4100           |a - assembly listing
	dc.w    hlpa,hlpa1
|
| Structure of entry is topic (top),
| address of short message (hshort),
| and address of long message (hlong).
|
help:   bsr     getch           |get argument
	andi.b  #0x5f,d0         |make it uppercase
	cmpi.b  #0x0d,d0         |is it a carriage return?
	bne     htopic          |no, so decode topic
hall:   bsr     crlf
	bsr     crlf
	moveq   #0x0d,d1         |load total # topics - 1
	lea     htab+2,a1       |load location of short help
shlp:   movea.w (a1),a0         |copy help location to a0
	bsr     writs           |write a short help message
	addq.w  #0x06,a1         |increment to next help message
	dbf     d1,shlp         |if not last message, print another one
	rts
htopic: lea     htab,a1         |set up search of ctab
	moveq   #0x0d,d1         |load total # topics - 1
lhlp:   cmp.b   (a1),d0         |is the topic equal to the table value?
	beq     hprn            |if so, print the short and long helps
	addq.w  #0x06,a1         |else go to the next table location
	dbf     d1,lhlp         |if not finished, try again
	bra     hall            |if not one of these, print all shorts
hprn:   bsr     crlf
	bsr     crlf
	addq.w  #0x02,a1         |increment a2 to short help location
	movea.w (a1)+,a0        |transfer address to a0
	bsr     writs           |write the short message
	bsr     crlf            |feed an extra line
	movea.w (a1),a0         |transfer long help address to a0
	bsr     writs           |write the long message
	rts

|
| assem - assembly listing
|
|****************************************
|*                                      *
|*      assem is invoked as follows:    *
|*                                      *
|*      a<cr> - disassemble the next    *
|*              20 instructions from    *
|*              last examined location  *
|*      a xxxx<cr> - disassemble 20     *
|*              instructions from xxxx  *
|*      a xxxx,yyyy - disassemble all   *
|*              instructions from xxxx  *
|*              to yyyy                 *
|*                                      *
|****************************************

ames:   dc.b    lf,lf,cr
	.ascii  "assembly listing:"
	dc.b    lf,cr,nul,nul
assem:  lea     getch,a0        |set for terminal input
	bsr     getch           |get delimiter
	cmp.b   #0x0d,d0         |if <cr> then list from pointer
	bne     aexam           |else get address
	movea.w exam,a1         |get exam
	lea     ames,a0         |write message
	bsr     writs
	move.b  #0x13,d2         |load 19 into d2
ass20:  bsr     ass1            |list a single instruction
	dbf     d2,ass20        |if not finished, decrement and go again
	move.w  a1,exam         |save new examination pointer
	rts
aexam:  bsr     getw            |get starting address
	movea.w d0,a1
	bsr     getch           |get delimiter
	cmpi.b  #0x2c,d0         |if , then get ending address
	bne     acom
	bsr     getw            |get address
	move.w  d0,aend         |save it
	lea     ames,a0         |write message
	bsr     writs
assxy:  bsr     ass1            |list a single instruction
	cmpa.w  aend,a1         |reached the end of the range yet?
	ble     assxy           |if not, do it again
	move.w  a1,exam         |save new examination pointer
	rts
acom:   lea     ames,a0         |write message
	bsr     writs
	move.b  #0x13,d2         |load 19 into d2
	bra     ass20           |jump to dump 20 routine

ass1:   move.w  a1,d0           |load the address
	bsr     writw           |print it out
	bsr     spc
	bsr     spc
	move.w  (a1)+,d0        |load the instruction word
	move.w  d0,d1           |make a copy
	rol.w   #0x06,d0         |get a longword offset for
	and.w   #0x003c,d0       |the instruction group (most sig. 4 bits)
	lea     grtab,a2        |load the address of the group table
	adda.w  d0,a2           |add the group offset
	movea.l (a2),a2         |get the actual address
	jsr     (a2)            |jump to the appropriate subroutine
	rts                     |exit

disend: bra     crlf            |send crlf after instruction
	rts                     |return from instruction subroutine

grtab:  dc.l    gr0
	dc.l    gr1
	dc.l    gr2
	dc.l    gr3
	dc.l    gr4
	dc.l    gr5
	dc.l    gr6
	dc.l    gr7
	dc.l    gr8
	dc.l    gr9
	dc.l    gra
	dc.l    grb
	dc.l    grc
	dc.l    grd
	dc.l    gre
	dc.l    grf

gr0:    move.w  d1,d0
	cmpi.w  #0x023c,d0       |is it ANDIccr?
	bne     ANDIsr          |no.
	lea     mANDI,a0        |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writb           |write it
	bsr     comma
	lea     mccr,a0         |load "ccr"
	bsr     writs
	bra     disend
ANDIsr: cmpi.w  #0x027c,d0       |is it ANDIsr?
	bne     EORIcr          |no.
	lea     mANDI,a0        |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writw           |write it
	bsr     comma
	lea     msr,a0          |load "sr"
	bsr     writs
	bra     disend
EORIcr: cmpi.w  #0x0a3c,d0       |is it EORIccr?
	bne     EORIsr          |no.
	lea     mEORI,a0        |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writb           |write it
	bsr     comma
	lea     mccr,a0         |load "ccr"
	bsr     writs
	bra     disend
EORIsr: cmpi.w  #0x0a7c,d0       |is it EORIsr?
	bne     ORIccr          |no.
	lea     mEORI,a0        |yes, print
	bsr     writs
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writw           |write it
	bsr     comma
	lea     msr,a0          |load "sr"
	bsr     writs           |write it
	bra     disend
ORIccr: cmpi.w  #0x003c,d0       |is it ORIccr?
	bne     ORIsr           |no.
	lea     mORI,a0         |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writb           |write it
	bsr     comma
	lea     mccr,a0         |load "ccr"
	bsr     writs
	bra     disend
ORIsr:  cmpi.w  #0x007c,d0       |is it ORIsr?
	bne     ADDI            |no.
	lea     mORI,a0         |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load the operand
	bsr     writw           |write it
	bsr     comma
	lea     msr,a0          |load "sr"
	bsr     writs
	bra     disend
ADDI:   andi.w  #0x0f00,d0       |mask operation bits
	cmpi.w  #0x0600,d0       |is it ADDI?
	bne     ANDI            |no.
	lea     mADDI,a0        |yes, print
	bsr     writs           |write it
	bra     iops            |go print operands
ANDI:   cmpi.w  #0x0200,d0       |is it ANDI?
	bne     CMPI            |no.
	lea     mANDI,a0        |yes, print
	bsr     writs           |write it
	bra     iops            |go print operands
CMPI:   cmpi.w  #0x0c00,d0       |is it CMPI?
	bne     EORI            |no.
	lea     mCMPI,a0        |yes, print
	bsr     writs           |write it
	bra     iops            |go print operands
EORI:   cmpi.w  #0x0a00,d0       |is it EORI?
	bne     ORI             |no.
	lea     mEORI,a0        |yes, print
	bsr     writs           |write it
	bra     iops            |go print operands
ORI:    cmpi.w  #0x0000,d0       |is it ORI?
	bne     SUBI            |no.
	lea     mORI,a0         |yes, print
	bsr     writs           |write it
	bra     iops            |go print operands
SUBI:   cmpi.w  #0x0400,d0       |is it SUBI?
	bne     MOVEP           |no.
	lea     mSUBI,a0        |yes, print
	bsr     writs           |write it
iops:   move.w  d1,d0
	andi.w  #0x00c0,d0       |check the size to see if it is legal
	cmpi.w  #0x00c0,d0       |is it size 11?
	bne     lops            |if not, it is legal
	bsr     spc           |if so, it is not legal
	bsr     spc
	bra     ILLEG
lops:   bsr     dot
	move.w  d1,d0
	bsr     findsiz         |print the operand size
	bsr     spc
	bsr     pound
	bsr     dollar
	cmpi.b  #0x62,siz        |is byte?
	bne     iopsw           |no
	move.w  (a1)+,d0        |yes
	bsr     writb
	bra     iopsc
iopsw:  cmpi.b  #0x77,siz        |is word?
	bne     iopsl           |no
	move.w  (a1)+,d0        |yes
	bsr     writw
	bra     iopsc
iopsl:  move.l  (a1)+,d0        |size long
	bsr     writl
iopsc:  bsr     comma
	move.w  d1,d0
	bsr     writea          |write the operand
	bra     disend
MOVEP:  move.w  d1,d0
	andi.w  #0x0138,d0       |mask MOVEP bits
	cmpi.w  #0x0108,d0       |is it a MOVEP?
	bne     bitop           |if not, it's a bit operation
	lea     mMOVEP,a0       |load "MOVEP"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	andi.w  #0x0040,d0       |word or longword
	bne     movepl          |longword
	move.b  #0x77,d0         |load a 'W'
	bsr     writ            |write it
	bra     moveps          |go write operands
movepl: move.b  #0x6C,d0         |load an 'L'
	bsr     writ            |write it
moveps: bsr     spc
	move.w  d1,d0
	andi.w  #0x0080,d0       |mask direction bit
	beq     movepr          |if zero, move to reg
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask data reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bsr     comma
	bsr     lparen
	move.w  (a1)+,d0
	bsr     writw           |write the address
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask address reg
	bsr     wareg           |write it
	bsr     rparen
	bra     disend
movepr: move.w  d1,d0
	bsr     lparen
	move.w  (a1)+,d0
	bsr     writw           |write the address
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask address reg
	bsr     wareg           |write it
	bsr     rparen
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask data reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bra     disend
bitop:  move.w  d1,d0
	andi.w  #0x0f00,d0       |mask the subgroup bits
	cmpi.w  #0x0e00,d0       |and make sure this is not illegal, since
	beq     ILLEG           |a non-MOVEP 00001110xxxxxxxx is invalid
	move.w  d1,d0
	andi.w  #0x00c0,d0       |mask bitop select bits
	bne     BCHG            |it's not BTST
	lea     mBTST,a0        |load "BTST"
	bsr     writs           |write it
	bra     bitop2          |go print operands
BCHG:   cmpi.w  #0x0040,d0
	bne     BCLR            |it's not BCHG
	lea     mBCHG,a0        |load "BCHG"
	bsr     writs           |write it
	bra     bitop2          |go print operands
BCLR:   cmpi.w  #0x0080,d0
	bne     BSET            |it's not BCLR
	lea     mBCLR,a0        |load "BCLR"
	bsr     writs           |write it
	bra     bitop2          |go print operands
BSET:   lea     mBSET,a0        |load "BSET"
	bsr     writs           |write it
bitop2: bsr     spc
	move.w  d1,d0
	andi.w  #0x0100,d0       |is it reg or immediate operand?
	bne     bitopr          |if nonzero, it's a reg operand
	bsr     pound
	move.w  (a1)+,d0        |get the bit number
	andi.b  #0x07,d0         |modulo 8
	bsr     writb           |write it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the destination operand
	bra     disend
bitopr: move.w  d1,d0
	andi.w  #0x0e00,d0       |mask off the reg number
	rol.w   #0x07,d0         |get it into rightmost bits
	bsr     wdreg           |write it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the destination operand
	bra     disend

gr1:    move.b  #0x62,siz        |make MOVE a byte operation
	bra     MOVE            |go parse the command type
gr2:    move.b  #0x6c,siz        |make MOVE a word operation
	bra     MOVE            |go parse the command type
gr3:    move.b  #0x77,siz        |make MOVE a long operation
MOVE:   move.w  d1,d0
	andi.w  #0x01c0,d0       |mask the destination opmode
	cmpi.w  #0x0040,d0       |is it MOVEA?
	beq     MOVEA           |if so, go do MOVEA
	lea     mMOVE,a0        |load "MOVE"
	bsr     writs           |write it
	bsr     dot
	bsr     findend         |write the size
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write source operand
	bsr     comma
	move.w  d1,d0
	ror.w   #0x01,d0         |these rols and rors make dest. op. std.
	rol.b   #0x03,d0
	ror.w   #0x08,d0
	ror.b   #0x03,d0
	ror.w   #0x05,d0         |dest. op. now looks like source op.
	bsr     writea          |write it
	bra     disend
MOVEA:  move.b  siz,d0          |load the size.
	cmpi.b  #0x42,d0         |is it a byte?
	beq     ILLEG           |if so, this is not a valid instruction
	lea     mMOVEA,a0       |load "MOVEA"
	bsr     writs           |write it
	bsr     dot
	bsr     findend         |write the size
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write source operand
	bsr     comma
	move.w  d1,d0
	rol.w   #0x07,d0         |get destination into rightmost
	andi.w  #0x07,d0         |mask off the destination bits
	bsr     wareg           |write it
	bra     disend

gr4:    move.w  d1,d0
NOP:    cmpi.w  #0x4e71,d0       |is it a NOP?
	bne     RESET           |no
	lea     mNOP,a0         |yes, print
	bsr     writs           |write it
	bra     disend
RESET:  cmpi.w  #0x4e70,d0       |is it RESET?
	bne     RTE             |no
	lea     mRESET,a0       |yes, print
	bsr     writs           |write it
	bra     disend
RTE:    cmpi.w  #0x4e73,d0       |is it RTE?
	bne     RTR             |no
	lea     mRTE,a0         |yes, print
	bsr     writs           |write it
	bra     disend
RTR:    cmpi.w  #0x4e77,d0       |is it RTR?
	bne     RTS             |no
	lea     mRTR,a0         |yes, print
	bsr     writs           |write it
	bra     disend
RTS:    cmpi.w  #0x4e75,d0       |is it RTS?
	bne     STOP            |no
	lea     mRTS,a0         |yes, print
	bsr     writs           |write it
	bra     disend
STOP:   cmpi.w  #0x4e72,d0       |is it STOP?
	bne     TRAPV           |no
	lea     mSTOP,a0        |yes, print
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load data word
	bsr     writw           |write it
	bra     disend
TRAPV:  cmpi.w  #0x4e76,d0       |is it TRAPV?
	bne     JMP             |no
	lea     mTRAPV,a0       |yes, print
	bsr     writs           |write it
	bra     disend
JMP:    andi.w  #0x0fc0,d0       |mask bits for one <ea> operations
	cmpi.w  #0x0ec0,d0       |is it JMP?
	bne     JSR             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	beq     ILLEG           
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	cmpi.w  #0x0018,d0       |valid modes with
	beq     ILLEG
	cmpi.w  #0x0020,d0       |this instruction
	beq     ILLEG
	lea     mJMP,a0         |yes, print
	bsr     writs
	bra     gtea0           |go write operand
JSR:    cmpi.w  #0x0e80,d0       |is it JSR?
	bne     MOVtc           |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	beq     ILLEG           
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	cmpi.w  #0x0018,d0       |valid modes with
	beq     ILLEG
	cmpi.w  #0x0020,d0       |this instruction
	beq     ILLEG
	lea     mJSR,a0         |yes, print
	bsr     writs
	bra     gtea0           |go write operand
MOVtc:  cmpi.w  #0x04c0,d0       |is it MOVEtoccr?
	bne     MOVfc           |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mMOVE,a0        |yes, print
	bsr     writs
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write the source operand
	bsr     comma
	lea     mccr,a0         |load "ccr"
	bsr     writs
	bra     disend
MOVfc:  cmpi.w  #0x02c0,d0       |is it MOVEfromccr?
	bne     MOVts           |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mMOVE,a0        |yes, print
	bsr     writs
	bsr     spc
	lea     mccr,a0         |load "ccr"
	bsr     writs           |write it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the operand
	bra     disend
MOVts:  cmpi.w  #0x06c0,d0       |is it MOVEtosr?
	bne     MOVfs           |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mMOVE,a0        |yes, print
	bsr     writs
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write the source operand
	bsr     comma
	lea     msr,a0          |load "sr"
	bsr     writs
	bra     disend
MOVfs:  cmpi.w  #0x00c0,d0       |is it MOVEfromsr?
	bne     NBCD            |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mMOVE,a0        |yes, print
	bsr     writs
	bsr     spc
	lea     msr,a0          |load "sr"
	bsr     writs
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the operand
	bra     disend
NBCD:   cmpi.w  #0x0800,d0       |is it NBCD?
	bne     PEA             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mNBCD,a0        |yes, print
	bsr     writs
	bra     gtea0           |go write operand
PEA:    cmpi.w  #0x0840,d0       |is it PEA?
	bne     TAS             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	beq     SWAP           
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	cmpi.w  #0x0018,d0       |valid modes with
	beq     ILLEG
	cmpi.w  #0x0020,d0       |this instruction
	beq     ILLEG
	lea     mPEA,a0         |yes, print
	bsr     writs
	bra     gtea0           |go write operand
TAS:    cmpi.w  #0x0AC0,d0       |is it TAS?
	bne     CLR             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	cmpi.w  #0x0038,d0       |special modes
	bne     tasok
	move.w  d1,d0
	andi.w  #0x0006,d0
	bne     ILLEG           |certain of them are bad
tasok:  lea     mTAS,a0         |yes, print
	bsr     writs
gtea0:  bsr     spc
	move.w  d1,d0
	bsr     writea          |write the operand
	bra     disend
CLR:    andi.w  #0x0f00,d0       |mask <ea> + <size> operations
	cmpi.w  #0x0200,d0       |is it clr?
	bne     NEG             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mCLR,a0         |yes, print
	bsr     writs
	bra     gtea1           |go write operand
NEG:    cmpi.w  #0x0400,d0       |is it NEG?
	bne     NEGX            |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mNEG,a0         |yes, print
	bsr     writs
	bra     gtea1           |go write operand
NEGX:   cmpi.w  #0x0000,d0       |is it NEGX?
	bne     NOT             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mNEGX,a0        |yes, print
	bsr     writs
	bra     gtea1           |go write operand
NOT:    cmpi.w  #0x0600,d0       |is it NOT?
	bne     TST             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mNOT,a0         |yes, print
	bsr     writs
	bra     gtea1           |go write operand
TST:    cmpi.w  #0x0A00,d0       |is it TST?
	bne     BKPT            |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mTST,a0         |yes, print
	bsr     writs
gtea1:  bsr     dot
	move.w  d1,d0
	bsr     findsiz         |print the operand length
	bsr     spc
	move.w  d1,d0
	bsr     writea          |print the operand
	bra     disend
BKPT:   move.w  d1,d0
	andi.w  #0xfff8,d0       |mask out the operand
	cmpi.w  #0x4848,d0       |is it BKPT?
	bne     LINK            |no
	lea     mBKPT,a0        |yes, print
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask BKPT number
	addi.b  #0x30,d0         |make it an ascii numeral
	bsr     writ            |write it
	bra     disend
LINK:   move.w  d1,d0
	andi.w  #0x0f00,d0       |look at bits 8-11
	cmpi.w  #0x0e00,d0       |is it an E?
	bne     SWAP            |no
	move.w  d1,d0
	andi.w  #0xfff8,d0       |mask off reg number
	cmpi.w  #0x4e50,d0       |is it a LINK?
	bne     MOVEsp          |no
	lea     mLINK,a0        |load "LINK"
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask reg bits
	bsr     wareg           |write it
	bsr     comma
	bsr     pound
	bsr     dollar
	move.w  (a1)+,d0        |load displacement
	bsr     writw           |write it
	bra     disend
MOVEsp: move.w  d1,d0
	andi.w  #0xfff0,d0       |mask off operand bits
	cmpi.w  #0x4e60,d0       |is it MOVEusp?
	bne     TRAP            |no
	lea     mMOVE,a0        |yes, so load "MOVE"
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0008,d0       |mask direction bit
	bne     MOVEts          |if zero, move to usp
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask reg bits
	bsr     wareg           |write it
	bsr     comma
	lea     musp,a0         |load "usp"
	bsr     writs           |write it
	bra     disend
MOVEts: lea     musp,a0         |load "usp"
	bsr     writs           |write it
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask reg bits
	bsr     wareg           |write it
	bra     disend
TRAP:   move.w  d1,d0
	andi.w  #0xfff0,d0       |mask operand if TRAP
	cmpi.w  #0x4e40,d0       |is it TRAP?
	bne     SWAP            |no
	lea     mTRAP,a0        |yes
	bsr     writs
	bsr     spc
	bsr     pound
	bsr     dollar
	move.b  d1,d0
	andi.b  #0x0f,d0         |mask off trap number
	bsr     writb           |write it
	bra     disend
SWAP:   move.w  d1,d0
	andi.w  #0xfff8,d0       |mask off operand if SWAP
	cmpi.w  #0x4840,d0       |is it SWAP?
	bne     UNLK            |no
	lea     mSWAP,a0        |load "swap"
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask off the reg bits
	bsr     wdreg           |write the reg
	bra     disend
UNLK:   cmpi.w  #0x4e58,d0       |is it UNLK?
	bne     LEA             |no
	lea     mUNLK,a0        |load "UNLK"
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask off reg number
	bsr     wareg           |write it
	bra     disend
LEA:    move.w  d1,d0
	andi.w  #0xf1c0,d0       |mask for lea
	cmpi.w  #0x41c0,d0       |is it LEA?
	bne     CHK             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	beq     ILLEG           
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	cmpi.w  #0x0018,d0       |valid modes with
	beq     ILLEG
	cmpi.w  #0x0020,d0       |this instruction
	beq     ILLEG
	lea     mLEA,a0         |load "LEA"
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write source op
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask reg number
	rol.w   #0x07,d0         |get reg in rightmost bits
	bsr     wareg           |write it
	bra     disend
CHK:    cmpi.w  #0x4180,d0       |is it CHK?
	bne     EXT             |no
	move.w  d1,d0
	andi.w  #0x0038,d0       |check to see if it's a valid mode
	cmpi.w  #0x0008,d0       |these are not
	beq     ILLEG
	lea     mCHK,a0         |load "CHK"
	bsr     writs           |write it
	move.b  #0x77,siz        |size is word
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write source operand
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bra     disend
EXT:    move.w  d1,d0
	andi.w  #0xffb8,d0       |mask all pertinent bits
	cmpi.w  #0x4880,d0       |is it EXT?
	bne     MOVEC           |no
	lea     mEXT,a0         |yes, load "EXT"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	andi.w  #0x0040,d0       |mask the size bit
	bne     lext            |size long
	move.b  #0x77,d0         |size word, load 'W'
	bsr     writ            |write it
	bra     ext1
lext:   move.b  #0x6c,d0         |load 'L'
	bsr     writ            |write it
ext1:   bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask the reg number
	bsr     wdreg           |write it
	bra     disend
MOVEC:  move.w  d1,d0
	andi.w  #0xfffe,d0       |mask in appropriate bits
	cmpi.w  #0x4e7b,d0       |is it a MOVEC?
	bne     MOVEM           |no
	lea     mCOPOUT,a0      |yes, so load "COPOUT" 
	bsr     writs           |write it 
	move.w  (a1)+,d0        |compensate for the operand word
	bra     disend 
MOVEM:  move.w  d1,d0
	andi.w  #0xfb80,d0       |mask bits
	cmpi.w  #0x4880,d0       |is it MOVEM?
	bne     ILLEG           |no
	lea     mMOVEM,a0       |yes, load "MOVEM"
	bsr     writs
	bsr     dot
	move.w  d1,d0
	andi.w  #0x0040,d0       |mask MOVEM size bit
	bne     MOVEMl          |if nonzero, longword operand
	move.b  #0x77,d0         |load 'W'
	move.b  d0,siz          |save size as 'W'
	bsr     writ            |write it
	bsr     spc
	bra     MOVEMo          |go write operands
MOVEMl: move.b  #0x6c,d0         |load 'L'
	move.b  d0,siz          |save size as 'L'
	bsr     writ            |write it
	bsr     spc
MOVEMo: move.w  d1,d0
	andi.w  #0x0400,d0       |which direction?
	bne     MOVEMr          |to reg
	bsr     dollar
	move.w  (a1)+,d0        |load the reg list
	bsr     writw           |write it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the address
	bra     disend
MOVEMr: move.w  (a1)+,t1        |save the reg list
	move.w  d1,d0
	bsr     writea          |write the address
	bsr     comma
	bsr     dollar
	move.w  t1,d0           |reload the reg list
	bsr     writw           |write it
	bra     disend
ILLEG:  lea     mILLEG,a0       |yes, print
	bsr     writs           |write it
	bra     disend

gr5:    move.w  d1,d0           |refresh the instruction word
	and.w   #0x00c0,d0       |mask bits 6-7
	cmp.w   #0x00c0,d0       |DBcc/Scc?
	bne     addq            |no
	move.w  d1,d0           |yes
	andi.w  #0x0038,d0       |mask DB/S bit
	cmpi.w  #0x0008,d0       |DBcc?
	bne     Scc             |no
	move.b  #0x64,d0         |load D into d0
	bsr     writ            |write it
	move.b  #0x62,d0         |load B into d0
	bsr     writ            |write it
	move.w  d1,d0           |refresh
	bsr     findcon         |print condition
	bsr     spc
	move.w  d1,d0           |refresh
	andi.w  #0x0007,d0       |mask out reg
	bsr     wdreg           |write reg
	bsr     comma
	clr.w   d0              |zero d0 so wdis looks for word disp.
	bsr     wdis            |print the address
	bra     disend

Scc:    move.b  #0x72,d0         |load S into d0
	bsr     writ            |write it
	move.w  d1,d0           |refresh
	bsr     findcon         |print condition
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write operand
	bra     disend

findcon:lea     contab,a0       |load location of beginning of table
	andi.w  #0x0f00,d0       |mask off the condition
	ror.w   #0x07,d0         |make condition a word offset
	adda.w  d0,a0           |add to table location to get ascii
	move.b  (a0)+,d0        |load the first byte
	bsr     writ            |write it
	move.b  (a0)+,d0        |load the second byte
	bsr     writ            |write it
	rts

contab: .ascii  "t "
	.ascii  "f "
	.ascii  "hi"
	.ascii  "ls"
	.ascii  "cc"
	.ascii  "cs"
	.ascii  "ne"
	.ascii  "eq"
	.ascii  "vc"
	.ascii  "vs"
	.ascii  "pl"
	.ascii  "mi"
	.ascii  "ge"
	.ascii  "lt"
	.ascii  "gt"
	.ascii  "le"
  
addq:   move.w  d1,d0
	andi.w  #0x0100,d0       |addq/subq
	bne     subq
	lea     mADDQ,a0        |load "addq"
	bra     qwrit
subq:   lea     mSUBQ,a0        |load "subq"
qwrit:  bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |write size of operand
	bsr     spc
	bsr     pound
	bsr     dollar
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask data
	rol.w   #0x07,d0         |get into rightmost bits
	bne     q8              |if nonzero, range is 1-7
	move.b  #0x08,d0         |if zero, range is 8
q8:     bsr     writb           |write byte
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write dest
	bra     disend

gr6:    move.w  d1,d0
	andi.w  #0x0f00,d0       |mask the cond bit
	bne     BSR             |not BRA
	lea     mBRA,a0         |load "bra"
	bsr     writs           |write it
	bra     Bccw            |go write operand
BSR:    cmp.w   #0x0100,d0       |BSR?
	bne     Bcc             |no
	lea     mBSR,a0         |load "bsr"
	bsr     writs           |write it
	bra     Bccw            |go write operand
Bcc:    move.b  #0x62,d0         |load a B
	bsr     writ            |write it
	move.w  d1,d0          
	bsr     findcon         |print the condition
Bccw:   bsr     spc
	move.w  d1,d0
	bsr     wdis            |write the address
	bra     disend

gr7:    move.w  d1,d0
	andi.w  #0x0100,d0       |check to make sure
	bne     ILLEG
	lea     mMOVEQ,a0       |load "MOVEQ"
	bsr     writs           |write it
	bsr     spc
	bsr     pound
	bsr     dollar
	move.b  d1,d0           |load data
	bsr     writb           |write it
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask off the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bra     disend

gr8:    move.w  d1,d0
	andi.w  #0x01f0,d0       |mask for SBCD.
	cmpi.w  #0x0100,d0       |is it SBCD?
	bne     DIVS
	lea     mSBCD,a0        |load "SBCD"
xBCD:   bsr     writs           |write it
	move.w  d1,d0
	andi.w  #0x0008,d0       |mask reg/memory bit
	beq     sbcdrg          |reg to reg op
	bsr     spc
	bsr     minus
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask source reg
	bsr     wareg           |print it
	bsr     rparen
	bsr     comma
	bsr     minus
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask destination reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |print it
	bsr     rparen
	bra     disend
sbcdrg: bsr     spc
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask source reg
	bsr     wdreg
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask destination reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |print it
	bra     disend

DIVS:   move.w  d1,d0
	andi.w  #0x00c0,d0       |mask mode bits
	cmpi.w  #0x00c0,d0       |is this a DIV operation
	bne     OR              |no.
	move.w  d1,d0           |yes.
	andi.w  #0x0100,d0       |mask the sign bit
	beq     DIVU            |it's unsigned divide
	lea     mDIVS,a0        |load "DIVS"
	bsr     writs           |write it
	bra     divprt          |go decode the rest of the command
DIVU:   lea     mDIVU,a0        |load "DIVU"
	bsr     writs           |write it
divprt: bsr     spc
	move.w  d1,d0
	bsr     writea
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask data reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |print it
	bra     disend

OR:     lea     mOR,a0          |load "OR"
ANDent: bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |print operand size
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0100,d0       |find destination
	beq     ordreg          |if zero, data reg
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |and print it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write the destination
	bra     disend
ordreg: move.w  d1,d0
	bsr     writea          |write the source
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |and print it
	bra     disend

gr9:    lea     mSUB,a0         |load "SUB"
	bsr     writs           |write it
ax:     move.w  d1,d0
	andi.w  #0x00c0,d0       |mask the size bits
	cmpi.w  #0x00c0,d0       |is it ADDA or SUBA?
	bne     SUB             |no
	move.b  #0x61,d0         |yes, so load an 'A'
	bsr     writ            |write it
	bsr     dot
	move.w  d1,d0
	andi.w  #0x0100,d0       |mask size bit
	bne     SUBAl           |if set, longword operand
	move.b  #0x77,d0         |load 'W'
	bsr     writ            |write it
	bra     axa             |go print operands
SUBAl:  move.b  #0x6c,d0         |load 'L'
	bsr     writ            |write it
	bra     axa             |go print operands
SUB:    move.w  d1,d0
	andi.w  #0x0130,d0       |mask appropriate bits
	cmpi.w  #0x0100,d0       |is it ADDX or SUBX?
	beq     SUBX            |yes
	bsr     dot             |no, so continue
	move.w  d1,d0
	bsr     findsiz         |print the size of the operand
axa:    bsr     spc
	move.w  d1,d0
	andi.w  #0x00c0,d0       |mask the size bits
	cmpi.w  #0x00c0,d0       |is it ADDA or SUBA
	beq     subea1          |if so, <ea> is first operand
	move.w  d1,d0
	andi.w  #0x0100,d0       |mask direction bit
	bne     subea2          |if bit is set, <ea> is last operand
	move.w  d1,d0
	bsr     writea          |write the first operand
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |print it
	bra     disend
subea1: move.w  d1,d0
	bsr     writea          |write the first operand
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |print it
	bra     disend
subea2: move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |print it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write second operand
	bra     disend

SUBX:   move.b  #0x78,d0         |load an 'X'
	bsr     writ            |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |write the operand length
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0008,d0       |mask reg/memory bit
	beq     SUBXdr          |reg to reg op
	bsr     minus
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask source reg
	bsr     wareg           |print it
	bsr     rparen
	bsr     comma
	bsr     minus
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask destination reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |print it
	bsr     rparen
	bra     disend
SUBXdr: move.w  d1,d0
	andi.w  #0x0007,d0       |mask source reg
	bsr     wdreg
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask destination reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |print it
	bra     disend

gra:    bra     ILLEG           |not a valid instruction

grb:    move.w  d1,d0
	andi.w  #0x00c0,d0       |mask size bits
	cmpi.w  #0x00c0,d0       |size = 11 ?
	bne     CMP             |no.
	lea     mCMPA,a0        |yes, so load "CMPA"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	andi.w  #0x0100,d0       |mask CMPA size bit
	bne     CMPAl           |if nonzero, longword operand
	move.b  #0x77,d0         |load 'W'
	move.b  d0,siz          |save size as 'W'
	bsr     writ            |write it
	bra     CMPAop          |go write operands
CMPAl:  move.b  #0x6c,d0         |load 'L'
	move.b  d0,siz          |save size as 'L'
	bsr     writ            |write it
CMPAop: bsr     spc
	move.w  d1,d0
	bsr     writea          |go write source operand
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |write it
	bra     disend
CMP:    move.w  d1,d0
	andi.w  #0x0100,d0       |mask CMP/CMPM bit
	bne     CMPM            |if nonzero, it's CMPM
	lea     mCMP,a0         |load "CMP"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |write size of operand
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write source operand
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bra     disend
CMPM:   move.w  d1,d0
	andi.w  #0x0038,d0       |mask mode bits
	cmpi.w  #0x0008,d0       |is it address reg mode?
	bne     EOR             |if not, it's an EOR
	lea     mCMPM,a0        |load "CMPM"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |write the operand size
	bsr     spc
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask source reg bits
	bsr     wareg           |write it
	bsr     rparen
	bsr     plus
	bsr     comma
	bsr     lparen
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask destination reg bits
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |write it
	bsr     rparen
	bsr     plus
	bra     disend                                  
EOR:    lea     mEOR,a0         |load "EOR"
	bsr     writs           |write it
	bsr     dot
	move.w  d1,d0
	bsr     findsiz         |write operand size
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bsr     comma
	move.w  d1,d0
	bsr     writea          |write destination
	bra     disend

grc:    move.w  d1,d0
	andi.w  #0x01f0,d0       |mask for ABCD
	cmpi.w  #0x0100,d0       |is it ABCD?
	bne     MULS            |no.
	lea     mABCD,a0        |load "ABCD"
	bra     xBCD            |go print everything
MULS:   move.w  d1,d0
	andi.w  #0x00c0,d0       |mask mode bits
	cmpi.w  #0x00c0,d0       |is this a MUL operation?
	bne     EXG             |no.
	move.w  d1,d0           |yes.
	andi.w  #0x0100,d0       |mask the sign bit
	beq     MULU            |it's unsigned multiply
	lea     mMULS,a0        |load "MULS"
	bsr     writs           |write it
	bra     divprt          |go decode the rest of the command
MULU:   lea     mMULU,a0        |load "MULU"
	bsr     writs           |write it
	bra     divprt          |go decode the rest of the command
EXG:    move.w  d1,d0
	andi.w  #0x0130,d0       |mask for EXG
	cmpi.w  #0x0100,d0       |is it EXG?
	bne     AND             |no.
	lea     mEXG,a0         |yes, print
	bsr     writs           |write it
	bsr     spc
	move.w  d1,d0
	andi.w  #0x00f8,d0       |mask op-mode bits
	cmpi.w  #0x0040,d0       |is it Di,Dj?
	bne     EXGaa           |no
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask source reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bsr     comma
	move.w  d1,d0           
	andi.w  #0x0007,d0       |mask destination reg number
	bsr     wdreg           |write it
	bra     disend
EXGaa:  cmpi.w  #0x0048,d0       |is it Ai,Aj?
	bne     EXGda           |no
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask source reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wareg           |write it
	bsr     comma
	move.w  d1,d0           
	andi.w  #0x0007,d0       |mask destination reg number
	bsr     wareg           |write it
	bra     disend
EXGda:  cmpi.w  #0x0088,d0       |is it Di,Aj?
	bne     ILLEG
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask source reg number
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write it
	bsr     comma
	move.w  d1,d0           
	andi.w  #0x0007,d0       |mask destination reg number
	bsr     wareg           |write it
	bra     disend
AND:    lea     mAND,a0         |load "AND"
	bra     ANDent          |go write the operation

grd:    lea     mADD,a0         |load "ADD"
	bsr     writs           |write it, then find out which ADD
	bra     ax              |go find out which ADD it is

gre:    move.w  d1,d0
	move.w  d1,t1           |save an extra copy of opcode
	andi.w  #0x00c0,d0       |is this an <ea> instruction?
	cmpi.w  #0x00c0,d0
	bne     fshf            |if not, find out which shift
	move.w  d1,d0           |else adjust the saved opcode
	ror.w   #0x06,d0         |rightward by six bits to allow proper
	move.w  d0,t1           |decoding of the shift type
fshf:   move.w  t1,d0           |load the properly adjusted opcode
	andi.w  #0x0018,d0       |mask operation bits of adjusted opcode
	bne     LS              |not AS
	lea     mAS,a0          |load "AS"
	bra     lr              |find the direction
LS:     cmpi.w  #0x0008,d0       |is it LS?
	bne     ROX             |no
	lea     mLS,a0          |yes, so load "LS"
	bra     lr              |find the direction
ROX:    cmpi.w  #0x0010,d0       |is it ROX?
	bne     RO              |no
	lea     mROX,a0         |yes, so load "ROX"
	bra     lr
RO:     lea     mRO,a0          |load "RO"
lr:     bsr     writs           |write the operation
	move.w  d1,d0
	andi.w  #0x0100,d0       |mask the direction bit
	bne     lsh             |left shift if bit set
	move.b  #0x72,d0         |load 'r'
	bra     shtyp           |go find the shift type
lsh:    move.b  #0x6c,d0         |load 'l'
shtyp:  bsr     writ            |write the direction
	move.w  d1,d0
	andi.w  #0x00c0,d0       |mask the size bits
	cmpi.w  #0x00c0,d0       |is the size 11?
	bne     regsh           |if not, it's a reg shift
	bsr     spc
	move.w  d1,d0
	bsr     writea          |write the operand
	bra     disend
regsh:  bsr     dot
	move.w  d1,d0
	bsr     findsiz         |print the operand length
	bsr     spc
	move.w  d1,d0
	andi.w  #0x0020,d0       |mask the immediate/reg bit
	beq     immsh           |if bit clear, it's an immediate shift
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the count reg
	rol.w   #0x07,d0         |get into rightmost bits
	bsr     wdreg           |write count reg
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask destination reg
	bsr     wdreg           |write destination reg
	bra     disend
immsh:  bsr     spc
	bsr     pound
	bsr     dollar
	move.w  d1,d0
	andi.w  #0x0e00,d0       |mask the count bits
	rol.w   #0x07,d0         |get into rightmost bits
	bne     sh17            |if not zero, 1-7 bit shift
	move.b  #0x08,d0         |if zero, 8 bit shift
sh17:   bsr     writb           |write it
	bsr     comma
	move.w  d1,d0
	andi.w  #0x0007,d0       |mask the reg bits
	bsr     wdreg           |write the destination reg
	bra     disend

grf:    bra     ILLEG           |not a valid instruction

|
|       message table -- the ascii strings for the instructions
|
mCOPOUT:.asciz  "COPOUT"
mABCD:  .asciz  "abcd"
mADD:   .asciz  "add"
mADDA:  .asciz  "adda"
mADDI:  .asciz  "addi"
mADDQ:  .asciz  "addq"
mADDX:  .asciz  "addx"
mAND:   .asciz  "and"
mANDI:  .asciz  "andi"
mAS:    .asciz  "as"
mBCHG:  .asciz  "bchg"
mBCLR:  .asciz  "bclr"
mBKPT:  .asciz  "bkpt"
mBRA:   .asciz  "bra"
mBSET:  .asciz  "bset"
mBSR:   .asciz  "bsr"
mBTST:  .asciz  "btst"
mCHK:   .asciz  "chk"
mCLR:   .asciz  "clr"
mCMP:   .asciz  "cmp"
mCMPA:  .asciz  "cmpa"
mCMPI:  .asciz  "cmpi"
mCMPM:  .asciz  "cmpm"
mDIVS:  .asciz  "divs"
mDIVU:  .asciz  "divu"
mEOR:   .asciz  "eor"
mEORI:  .asciz  "eori"
mEORIcr:.asciz  "eoriccr"
mEXG:   .asciz  "exg"
mEXT:   .asciz  "ext"
mILLEG: .asciz  "ILLEGAL"
mJMP:   .asciz  "jmp"
mJSR:   .asciz  "jsr"
mLEA:   .asciz  "lea"
mLINK:  .asciz  "link"
mLS:    .asciz  "ls"
mMOVE:  .asciz  "move"
mMOVEA: .asciz  "movea"
mMOVEC: .asciz  "movec"
mMOVEM: .asciz  "movem"
mMOVEP: .asciz  "movep"
mMOVEQ: .asciz  "moveq"
mMULS:  .asciz  "muls"
mMULU:  .asciz  "mulu"
mNBCD:  .asciz  "nbcd"
mNEG:   .asciz  "neg"
mNEGX:  .asciz  "negx"
mNOP:   .asciz  "nop"
mNOT:   .asciz  "not"
mOR:    .asciz  "or"
mORI:   .asciz  "ori"
mPEA:   .asciz  "pea"
mRESET: .asciz  "reset"
mRO:    .asciz  "ro"
mROX:   .asciz  "rox"
mRTE:   .asciz  "rte"
mRTR:   .asciz  "rtr"
mRTS:   .asciz  "rts"
mSBCD:  .asciz  "sbcd"
mSTOP:  .asciz  "stop"
mSUB:   .asciz  "sub"
mSUBA:  .asciz  "suba"
mSUBI:  .asciz  "subi"
mSUBQ:  .asciz  "subq"
mSUBX:  .asciz  "subx"
mSWAP:  .asciz  "swap"
mTAS:   .asciz  "tas"
mTRAP:  .asciz  "trap"
mTRAPV: .asciz  "trapv"
mTST:   .asciz  "tst"
mUNLK:  .asciz  "unlk"
mccr:   .asciz  "ccr"
msr:    .asciz  "sr"
musp:   .asciz  "usp"

spc:    move.b  #0x20,d0         |load a spc
	bsr     writ            |write it
	rts

comma:  move.b  #0x2c,d0         |load a comma
	bsr     writ            |write it
	rts

lparen: move.b  #0x28,d0         |load a left parenthesis
	bsr     writ            |write it
	rts

rparen: move.b  #0x29,d0         |load a right parenthesis
	bsr     writ            |write it
	rts

pound:  move.b  #0x23,d0         |load a pound sign
	bsr     writ            |write it
	rts

dot:    move.b  #0x2e,d0         |load a period
	bsr     writ            |write it
	rts

plus:   move.b  #0x2b,d0         |load a plus
	bsr     writ            |write it
	rts

minus:  move.b  #0x2d,d0         |load a minus
	bsr     writ            |write it
	rts

dollar: move.b  #0x24,d0         |load a dollar sign
	bsr     writ            |write it
	rts

findsiz:andi.w  #0x00c0,d0       |mask out the size bits
	bne     wsize           |if nonzero, it's not a byte
	move.b  #0x62,siz        |set size to byte
	bra     findend
wsize:  cmpi.w  #0x0040,d0       |is it a word operand?
	bne     lsize           |no.
	move.b  #0x77,siz        |set size to word
	bra     findend
lsize:  move.b  #0x6c,siz        |set size to longword
findend:move.b  siz,d0
	bsr     writ            |write the size
	rts

wareg:  swap    d0              |save the reg number in upper 16 bits
	move.b  #0x61,d0         |load 'a'
	bsr     writ            |write it
	swap    d0              |restore the reg number
	ori.b   #0x30,d0         |add offset to get digit
	bsr     writ            |write it
	rts

wdreg:  swap    d0              |save the reg number in upper 16 bits
	move.b  #0x64,d0         |load 'a'
	bsr     writ            |write it
	swap    d0              |restore the reg number
	ori.b   #0x30,d0         |add offset to get digit
	bsr     writ            |write it
	rts

mPC:    .asciz  "pc"
mIAM:   .asciz  "ILLEGAL ADDRESS MODE"
writea: move.b  d0,writm        |save the important part of the opcode
	andi.b  #0x38,d0         |mask off all but the mode bits
	bne     mode1           |if zero, it's data reg direct
	move.b  writm,d0
	andi.b  #0x07,d0         |mask the reg number
	bsr     wdreg           |write the data reg
	bra     eaout
mode1:  cmpi.b  #0x08,d0         |is it address reg direct?
	bne     mode2           |no
	move.b  writm,d0        |yes
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bra     eaout
mode2:  cmpi.b  #0x10,d0         |is it address reg indirect?
	bne     mode3           |no
	bsr     lparen          |yes
	move.b  writm,d0
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bsr     rparen
	bra     eaout
mode3:  cmpi.b  #0x18,d0         |is it postincrement?
	bne     mode4           |no
	bsr     lparen          |yes
	move.b  writm,d0
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bsr     rparen
	bsr     plus
	bra     eaout
mode4:  cmpi.b  #0x20,d0         |is it predecrement?
	bne     mode5           |no
	bsr     minus           |yes
	bsr     lparen
	move.b  writm,d0
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bsr     rparen
	bra     eaout
mode5:  cmpi.b  #0x28,d0         |is it reg indirect w/ displacement?
	bne     mode6           |no
	bsr     dollar
	move.w  (a1)+,d0        |yes, so load 16 bit displacement
	bsr     writw           |write it
	bsr     lparen
	move.b  writm,d0
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bsr     rparen
	bra     eaout
mode6:  cmpi.b  #0x30,d0         |is it reg indirect w/ index?
	bne     mode7           |no
	bsr     dollar
	move.w  (a1),d0         |load the index word
	bsr     writb           |write the 8 bit displacement
	bsr     lparen
	move.b  writm,d0
	andi.b  #0x07,d0         |mask reg number
	bsr     wareg           |write address reg
	bsr     comma
m6ad:   move.w  (a1),d0         |load index word again
	bpl     m6d             |if MSB of index word is 0, data reg
	rol.w   #0x04,d0         |rotate reg number into rightmost bits
	andi.w  #0x0007,d0       |mask reg number
	bsr     wareg           |write address reg
	bra     m6no
m6d:    rol.w   #0x04,d0         |rotate reg number into rightmost bits
	andi.w  #0x0007,d0       |mask reg number
	bsr     wdreg           |write data reg
m6no:   bsr     dot
	move.w  (a1)+,d0        |load the index reg a final time
	andi.w  #0x0800,d0       |mask the length bit
	bne     m6l             |if nonzero, long reg index
	move.b  #0x77,d0         |load 'w'
	bsr     writ            |write it
	bsr     rparen
	bra     eaout
m6l:    move.b  #0x6c,d0         |load 'l'
	bsr     writ            |write it
	bsr     rparen
	bra     eaout
mode7:  move.b  writm,d0        |mode seven, so decode reg number
	andi.w  #0x07,d0         |mask reg number
	bne     m71             |if zero, absolute.w
	bsr     dollar
	move.w  (a1)+,d0        |move the address into d0
	bsr     writw           |write it
	bra     eaout
m71:    cmpi.b  #0x01,d0         |is it absolute.l?
	bne     m72             |no
	bsr     dollar
	move.l  (a1)+,d0        |yes, so move the address into d0
	bsr     writl           |write it
	bra     eaout
m72:    cmpi.b  #0x02,d0         |is it relative w/ displacement?
	bne     m73             |no
	bsr     dollar
	move.w  (a1)+,d0        |yes, so load displacement into d0
	bsr     writw           |write it
	bsr     lparen
	lea     mPC,a0          |load "PC"
	bsr     writs           |write it
	bsr     rparen
	bra     eaout
m73:    cmpi.b  #0x03,d0         |is it relative w/ index?
	bne     m74             |no
	bsr     dollar
	move.w  (a1),d0         |load the index word
	bsr     writb           |write the 8 bit displacement
	bsr     lparen
	lea     mPC,a0          |load "PC"
	bsr     writs           |write it
	bsr     comma
	bra     m6ad            |go to reg. indir. routine to finish
m74:    cmpi.b  #0x04,d0         |is it immediate?
	bne     m75             |no
	bsr     pound
	bsr     dollar
	move.b  siz,d0          |load the size byte
	cmpi.b  #0x62,d0         |is it byte data?
	bne     m74w            |no
	move.w  (a1)+,d0        |yes, so load immediate data
	bsr     writb           |write byte data
	bra     eaout
m74w:   cmpi.b  #0x77,d0         |is it word data?
	bne     m74l            |no
	move.w  (a1)+,d0        |yes, so load immediate data
	bsr     writw           |write word data
	bra     eaout
m74l:   move.l  (a1)+,d0        |load long immediate data
	bsr     writl           |write long data
	bra     eaout
m75:    lea     mIAM,a0         |load illegal mode message
	bsr     writs           |write it
eaout:  rts

wdis:   swap    d0              |save opcode in upper 16 so we can
	bsr     dollar          |hexidecimalize the displacement
	swap    d0              |get it back in lower 16
	move.l  a1,d1           |copy current address to d1
	tst.b   d0              |is displacement zero?
	beq     wdisw           |if so, word displacement
	andi.l  #0x00ff,d0       |mask off the displacement
	ext.w   d0              |sign extend the displacement
	ext.l   d0              |to word size
	add.l   d0,d1           |add 8-bit displacement to address
	move.l  d1,d0           |copy into d0
	bsr     writl           |write address
	bra     wdiso
wdisw:  move.w  (a1)+,d0        |load the displacement word
	ext.l   d0              |sign extend it
	add.l   d0,d1           |add displacement
	move.l  d1,d0           |copy to d0
	bsr     writl
wdiso:  rts

|
|************************************
|*                                  *
|*       Monitor data area          *
|*                                  *
|************************************
|
	.bss

ram_start:			| CHD
jmptab_area:			| vector jmp table is placed here
vec0:	.space	6
vec1:	.space	6
vec2:	.space	6
vec3:	.space	6
vec4:	.space	6
vec5:	.space	6
vec6:	.space	6
vec7:	.space	6
vec8:	.space	6
vec9:	.space	6
vec10:	.space	6
vec11:	.space	6
vec12:	.space	6
vec13:	.space	6
vec14:	.space	6
vec15:	.space	6
vec16:	.space	6
vec17:	.space	6
vec18:	.space	6
vec19:	.space	6
vec20:	.space	6
vec21:	.space	6
vec22:	.space	6
vec23:	.space	6
vec24:	.space	6
vec25:	.space	6
vec26:	.space	6
vec27:	.space	6
vec28:	.space	6
vec29:	.space	6
vec30:	.space	6
vec31:	.space	6
vec32:	.space	6
vec33:	.space	6
vec34:	.space	6
vec35:	.space	6
vec36:	.space	6
vec37:	.space	6
vec38:	.space	6
vec39:	.space	6
vec40:	.space	6
vec41:	.space	6
vec42:	.space	6
vec43:	.space	6
vec44:	.space	6
vec45:	.space	6
vec46:	.space	6
vec47:	.space	6
vec48:	.space	6
vec49:	.space	6
vec50:	.space	6
vec51:	.space	6
vec52:	.space	6
vec53:	.space	6
vec54:	.space	6
vec55:	.space	6
vec56:	.space	6
vec57:	.space	6
vec58:	.space	6
vec59:	.space	6
vec60:	.space	6
vec61:	.space	6
vec62:	.space	6
vec63:	.space	6
vec64:	.space	6
vec65:	.space	6
vec66:	.space	6
vec67:	.space	6
vec68:	.space	6
vec69:	.space	6
vec70:	.space	6
vec71:	.space	6
vec72:	.space	6
vec73:	.space	6
vec74:	.space	6
vec75:	.space	6
vec76:	.space	6
vec77:	.space	6
vec78:	.space	6
vec79:	.space	6
vec80:	.space	6
vec81:	.space	6
vec82:	.space	6
vec83:	.space	6
vec84:	.space	6
vec85:	.space	6
vec86:	.space	6
vec87:	.space	6
vec88:	.space	6
vec89:	.space	6
vec90:	.space	6
vec91:	.space	6
vec92:	.space	6
vec93:	.space	6
vec94:	.space	6
vec95:	.space	6
vec96:	.space	6
vec97:	.space	6
vec98:	.space	6
vec99:	.space	6
vec100:	.space	6
vec101:	.space	6
vec102:	.space	6
vec103:	.space	6
vec104:	.space	6
vec105:	.space	6
vec106:	.space	6
vec107:	.space	6
vec108:	.space	6
vec109:	.space	6
vec110:	.space	6
vec111:	.space	6
vec112:	.space	6
vec113:	.space	6
vec114:	.space	6
vec115:	.space	6
vec116:	.space	6
vec117:	.space	6
vec118:	.space	6
vec119:	.space	6
vec120:	.space	6
vec121:	.space	6
vec122:	.space	6
vec123:	.space	6
vec124:	.space	6
vec125:	.space	6
vec126:	.space	6
vec127:	.space	6
vec128:	.space	6
vec129:	.space	6
vec130:	.space	6
vec131:	.space	6
vec132:	.space	6
vec133:	.space	6
vec134:	.space	6
vec135:	.space	6
vec136:	.space	6
vec137:	.space	6
vec138:	.space	6
vec139:	.space	6
vec140:	.space	6
vec141:	.space	6
vec142:	.space	6
vec143:	.space	6
vec144:	.space	6
vec145:	.space	6
vec146:	.space	6
vec147:	.space	6
vec148:	.space	6
vec149:	.space	6
vec150:	.space	6
vec151:	.space	6
vec152:	.space	6
vec153:	.space	6
vec154:	.space	6
vec155:	.space	6
vec156:	.space	6
vec157:	.space	6
vec158:	.space	6
vec159:	.space	6
vec160:	.space	6
vec161:	.space	6
vec162:	.space	6
vec163:	.space	6
vec164:	.space	6
vec165:	.space	6
vec166:	.space	6
vec167:	.space	6
vec168:	.space	6
vec169:	.space	6
vec170:	.space	6
vec171:	.space	6
vec172:	.space	6
vec173:	.space	6
vec174:	.space	6
vec175:	.space	6
vec176:	.space	6
vec177:	.space	6
vec178:	.space	6
vec179:	.space	6
vec180:	.space	6
vec181:	.space	6
vec182:	.space	6
vec183:	.space	6
vec184:	.space	6
vec185:	.space	6
vec186:	.space	6
vec187:	.space	6
vec188:	.space	6
vec189:	.space	6
vec190:	.space	6
vec191:	.space	6
vec192:	.space	6
vec193:	.space	6
vec194:	.space	6
vec195:	.space	6
vec196:	.space	6
vec197:	.space	6
vec198:	.space	6
vec199:	.space	6
vec200:	.space	6
vec201:	.space	6
vec202:	.space	6
vec203:	.space	6
vec204:	.space	6
vec205:	.space	6
vec206:	.space	6
vec207:	.space	6
vec208:	.space	6
vec209:	.space	6
vec210:	.space	6
vec211:	.space	6
vec212:	.space	6
vec213:	.space	6
vec214:	.space	6
vec215:	.space	6
vec216:	.space	6
vec217:	.space	6
vec218:	.space	6
vec219:	.space	6
vec220:	.space	6
vec221:	.space	6
vec222:	.space	6
vec223:	.space	6
vec224:	.space	6
vec225:	.space	6
vec226:	.space	6
vec227:	.space	6
vec228:	.space	6
vec229:	.space	6
vec230:	.space	6
vec231:	.space	6
vec232:	.space	6
vec233:	.space	6
vec234:	.space	6
vec235:	.space	6
vec236:	.space	6
vec237:	.space	6
vec238:	.space	6
vec239:	.space	6
vec240:	.space	6
vec241:	.space	6
vec242:	.space	6
vec243:	.space	6
vec244:	.space	6
vec245:	.space	6
vec246:	.space	6
vec247:	.space	6
vec248:	.space	6
vec249:	.space	6
vec250:	.space	6
vec251:	.space	6
vec252:	.space	6
vec253:	.space	6
vec254:	.space	6
vec255:	.space	6

utrapb: dc.l    0x00000000
utrapc: dc.l    0x00000000
utrapd: dc.l    0x00000000
utrape: dc.l    0x00000000
utrapf: dc.l    0x00000000

userv1: dc.l    0x00000000
userv2: dc.l    0x00000000
userv3: dc.l    0x00000000
userv4: dc.l    0x00000000
userv5: dc.l    0x00000000

uav3:   dc.l    0x00000000
uav4:   dc.l    0x00000000
uav5:   dc.l    0x00000000
uav6:   dc.l    0x00000000
uav7:   dc.l    0x00000000

sarea:  .space   0x40*4,0x00               |system stack
stack   =       .
bktab:  .space   6*5,0x0000               |breakpoint table
_sr:    dc.w    0x0000                   |register save area
_pc:    dc.l    0x00000000
dr0:    dc.l    0x00000000
dr1:    dc.l    0x00000000
dr2:    dc.l    0x00000000
dr3:    dc.l    0x00000000
dr4:    dc.l    0x00000000
dr5:    dc.l    0x00000000
dr6:    dc.l    0x00000000
dr7:    dc.l    0x00000000
ar0:    dc.l    0x00000000
ar1:    dc.l    0x00000000
ar2:    dc.l    0x00000000
ar3:    dc.l    0x00000000
ar4:    dc.l    0x00000000
ar5:    dc.l    0x00000000
ar6:    dc.l    0x00000000
ar7:    dc.l    0x00000000
ptab:   .space   0x8,0000                 |prototype table
rexam:  dc.l    0x0000                   |register examination pointer
exam:   dc.l    0x0000                   |memory examination pointer
t1:     dc.w    0x0000                   |temporary work area
t2:     dc.w    0x0000
t3:     dc.w    0x0000
t4:     dc.w    0x0000
t5:     dc.w    0x0000
ctrls:  dc.w    0x0000                  |ctrl-s,ctrl-q flag
bkptf   =       .-1                     |breakpoint flag
lbuff:  .space   28,0                	|load buffer
ibuff:  .space   28,0                	|terminal buffer
users:  .space   0x40*4,00              |users stack area
ustck   =       .
aend:   dc.w    0x0000
siz:    dc.w    0x0000
writm:  dc.w    0x0000
echo:   dc.w    0x0000                   |terminal port echo flag
|
|Terminal port
|
|ttyst   =       0x0000c000
|ttyd    =       0x0000c002
|
|Load port
|
|lpst    =       0x0000a000
|lpd     =       0x0000a002
