.PAGE
;******************************************************
;*						      *
;*		  Disassembler Subroutines	      *
;*						      *
;*  COPYRIGHT (c) 1982, 1983 SAGE Computer Technology *
;*  All Rights Reserved				      *
;*						      *
;******************************************************

;Get next word 
;			A6 : Address of word
;	BSR	GETNEXTW
;			D0 : Word from memory
;			A6 : Address of next word

GETNEXTW
	MOVE.L	A1,-(A7)	;Save A1
	MOVEA.L A6,A1		;Check memory
	BSR	CHKMEM
	BNE	CMNDERRA
	MOVE.W	(A6)+,D0	;Get word
	MOVEA.L (A7)+,A1
	RTS

;Get next long word 
;			A6 : Address of long word
;	BSR	GETNEXTL
;			D0 : Long word from memory
;			A6 : Address of next word

GETNEXTL
	MOVE.L	A1,-(A7)	;Save A1
	MOVEA.L A6,A1		;Check memory
	BSR	CHKMEM
	BNE	CMNDERRA
	ADDQ.L	#2,A1		;Check next word
	BSR	CHKMEM
	MOVE.L	(A6)+,D0	;Get long word
	MOVEA.L (A7)+,A1	;Restore A1
	RTS


;Print operation size (00 = byte, 01 = word, 10 = long word)

;			D5 : bit 6 & 7 size code

;	BSR	PRTOSIZE

;			A1 : ?
;			D1 : ?

PRTOSIZE
	ANDI.W	#0C0H,D5	;Is operation long word
	CMPI.B	#080H,D5
	BNE.S	PRTSIZE		;No
	MOVEQ	#-40H,D5	;Convert to standard long word

;Print operation size (00 = byte, 01 = word, 11 = long word)

;			D5 : Instruction
;	BSR	PRTSIZE
;			A1 : ?
;			D1 : ?

PRTSIZE
	MOVE.W	D5,D1		;Get size specification
	ROR.W	#6,D1
	ANDI.B	#03,D1		;0 - 4
	LEA	INSSIZE,A1
	
;Print instruction

;			A1 : Address of instruction table
;			D1 : Offset in instruction table
;	BSR	PRTINST

PRTINST
	ROL.B	#2,D1		;Convert index into offset
	ANDI.W	#0FFH,D1
	MOVE.L	0(A1,D1.W),D0

;Print instruction in D0

;			D0 : Instruction to be printed
;			D6 : Characters left in field
;	BSR	PRTRINST

PRTRINST
	MOVE.L	D1,-(A7)	;Save D1
	MOVEQ	#3,D1		;Print up to 4 characters
$1
	ROL.L	#8,D0		;Get next byte
	TST.B	D0		;Byte there to be printed
	BEQ	$2		;No - skip printing
	BSR	TERMCHAR	;Print character
	SUBQ.B	#1,D6		;Decrement instruction field size
$2
	DBF	D1,$1		;Repeat for 4 characters
	MOVE.L	(A7)+,D1	;Restore D1
	RTS
	
	
;Move to next field in buffer

;		D6 : Number of characters left in field
;	BSR	NXTFIELD
;		D6 : ?

NXTFIELD
	BSR	TERMSPACE	;Skip space
	DBF	D6,NXTFIELD	;Repeat untill reached operand field
	RTS
	
	
;Print constant
;			D5 : Type of constant
;	BSR	PRTCONST
;			D0 : Value printed

PRTCONST
	MOVEQ	#"#",D0		;Print constant designator
	BSR	TERMCHAR
PRTADDI
	MOVE.W	D5,D1		;Get size of command
	ROR.W	#6,D1
	AND.W	#3,D1
	CMP.B	#2,D1		;Legal size spec
	BEQ.S	$3		;No
	BSR	GETNEXTW	;Get constant
	SUBQ.B	#1,D1		;Length of constant
	BGE.S	$1		;Long or Illegal
	BSR	TERMHEXB	;Print byte
	RTS
$1
	BSR	TERMHEXW	;Print word
	SUBQ.B	#1,D1
	BLT.S	$2		;Word
	BSR	GETNEXTW	;Get long word
	BSR	TERMHEXW
$2
	RTS
$3
	MOVEQ	#"?",D0		;Print unknown size
	BSR	TERMCHAR
	RTS


;Prints effective address of instruction

;			D7 : Effective address (lower 6 bits)
;			D5 : Size specification
;	BSR	QPRTEADD

QPRTEADD
	MOVE.W	D7,D3		;Move instruction to working register
	
;Prints effective address

;			D3 : Effective address
;			D5 : Size of address
;	BSR	SPRTEADD
;	     or
;	BSR	DPRTEADD

SPRTEADD
	MOVE.B	D3,D0		;Swap register and mode
	LSR.B	#3,D0
	ANDI.B	#7,D0		;Save just register number
	LSL.B	#3,D3
	OR.B	D0,D3
	
DPRTEADD
	MOVE.B	D3,D0		;Jump to effective address routine
	ANDI.W	#07H,D0		;Address of routine
	BSR	COMPGOTO	;Jump to routine
$2000	.WORD	DRD-$2000	;Data Register Direct
	.WORD	ARD-$2000	;Address Register Direct
	.WORD	ARI-$2000	;Address Register Indirect
	.WORD	ARIPI-$2000	;Address Register Indirect Post Increment
	.WORD	ARIPD-$2000	;Address Register Indirect Pre Decrement
	.WORD	ARID-$2000	;Address Register Indirect with Displacement
	.WORD	ARII-$2000	;Address Register Indirect with Index
	.WORD	SAM-$2000	;Special Addressing Modes
	
;Data Register Direct

DRD
	MOVEQ	#"D",D1		;Print Data Register
	BRA.S	PRTREG
	
;Address Register Direct

ARD
	MOVEQ	#"A",D1		;Print Address Register
	BRA.S	PRTREG

;Address Register Indirect

ARI
	MOVE.L	FARI,D1
	BRA.S	PRTREG
	
;Address Register Indirect Post Increment

ARIPI
	MOVE.L	FARIPI,D1
	BRA.S	PRTREG
	
;Address Register Indirect Pre Decrement

ARIPD
	MOVE.L	FARIPD,D1
				;This routine must be just above PRTREG
	
;Print register

;			D1 : Format of register print
;	   D3 (bits 3 - 5) : Register
;	BSR	PRTREG

PRTREG
	MOVEQ	#3,D2		;Print a max of 4 characters
$1
	ROL.L	#8,D1		;Get next character
	MOVE.B	D1,D0		;Print character
	BEQ.S	$3		;Nothing to print
	BSR	TERMCHAR
	CMPI.B	#"D",D0		;Data register designator
	BEQ.S	$2		;Yes
	CMPI.B	#"A",D0		;Address register designator
	BNE.S	$3		;No
$2
	MOVE.W	D3,D0
	ROR.B	#3,D0		;Move register to lower 3 bits
	ANDI.B	#7,D0		;Max register is 7
	BSR	TERMDIGT	;Print register number
$3
	DBF	D2,$1		;Repeate until done
	RTS
	
;Print physical address for relative offset

;			A2 : Relative offset
;			A6 : Current address
;	CALL	PRELADDR
;			A0 : ?
;			D0 : ?
;			A2 : ?

PRELADDR
	MOVEQ	#"[",D0		;Print [
	BSR	TERMCHAR
	ADDA.L	A6,A2		;Calculate physical address
	MOVE.L	A2,D0		;Print address
	SUBQ.L	#2,D0
	MOVEA.W LOCCNTR,A0	;Convert to standard address
	ADDA.L	A0,A0		;Compute register offset
	ADDA.L	A0,A0
	SUB.L	BASEADDR(A0),D0 ;Calc standard address
	BSR	TERMHEXL
	MOVEQ	#"]",D0		;Print ]
	BSR	TERMCHAR
	RTS
	
;Address Register Indirect with Displacement

ARID
	BSR	GETNEXTW	;Get displacement
	BSR	TERMHEXW	;Print displacement
	BRA	ARI		;Print register portion
	
;Address Register Indirect with Index

ARII
	BSR	GETNEXTW	;Get control word
	MOVE.W	D0,D4		;Save control word
	BSR	TERMHEXB	;Print displacement
	MOVEQ	#"(",D0		;Print delimiter
	BSR	TERMCHAR
	BSR	ARD		;Register
ARII2
	BSR	TERMCOMA	;Print delimiter
	MOVE.W	D4,D3		;Restore control word
	ROL.W	#7,D3		;Position register number
	BTST	#15,D4		;Address or Data register?
	BNE.S	$1		;Address register
	BSR	DRD
	BRA.S	$2
$1
	BSR	ARD		;Print Address register
$2
	MOVEQ	#".",D0		;Print word or long word access
	BSR	TERMCHAR
	MOVEQ	#"W",D0		;Assume word access
	BTST	#11,D4		;Word or Long word access?
	BEQ.S	$3		;Word access
	MOVEQ	#"L",D0		;Long word access
$3
	BSR	TERMCHAR	;Print size
	MOVEQ	#")",D0		;Print delimiter
	BSR	TERMCHAR
	RTS
	
;Special Addressing Modes
	
SAM
	ROR.B	#3,D3		;Get special function type
	AND.B	#7,D3
	MOVE.B	D3,D0		;Jump to routine
	BSR	COMPGOTO
$2000	.WORD	$100-$2000	;Absolute short addressing
	.WORD	$200-$2000	;Absolute long addressing
	.WORD	$300-$2000	;Program counter with displacement
	.WORD	$400-$2000	;Program counter with index
	.WORD	$500-$2000	;Immediate or Status Register
	.WORD	$10-$2000	;Illegal
	.WORD	$10-$2000	;Illegal
	.WORD	$10-$2000	;Illegal

;Error detected

$10
	RTS
	
;Absolute short addressing

$100
	BSR	GETNEXTW	;Get short absolute address
	BSR	TERMHEXW
	RTS
	
;Absolute long addressing

$200
	BSR	GETNEXTL	;Get long absolute address
	BSR	TERMHEXL
	RTS
	
;Program counter with displacement

$300
	BSR	GETNEXTW	;Get displacement
	MOVEA.W D0,A2		;Save value to be printed
	BSR	TERMHEXW	;Print it
	MOVE.L	FPCD,D1		;Print rest of description
	BSR	PRTREG
	BSR	PRELADDR	;Print physical address
	RTS
	
;Program counter with index

$400
	BSR	GETNEXTW	;Get control word
	MOVE.W	D0,D4		;Save control word
	BSR	TERMHEXB
	MOVE.L	FPCI,D0		;Print delimiter
	BSR	PRTRINST
	BRA	ARII2		;Complete processing

;Immediate or Status Register

$500
	BSR	PRTCONST	;Print constant
	RTS

;Register definitions too long for current assembler

FARI	.ASCII	"(A)"
	.BYTE	0
FARIPI	.ASCII	"(A)+"
FARIPD	.ASCII	"-(A)"
FMOVE	.ASCII	"MOVE"
FWORD	.ASCII	"WORD"
FPCD	.ASCII	"(PC)"
FPCI	.ASCII	"(PC"
	.BYTE	0
FCCR	.ASCII	"CCR"
	.BYTE	0
FSR	.ASCII	"SR"
	.WORD	0
FNBCD	.ASCII	"NBCD"
FPEA	.ASCII	"PEA"
	.BYTE	0
FSWAP	.ASCII	"SWAP"
FEXTL	.ASCII	"EXTL"
FEXTW	.ASCII	"EXTW"
FILLE	.ASCII	"ILLE"
FGAL	.ASCII	"GAL"
	.BYTE	0
FTAS	.ASCII	"TAS"
	.BYTE	0
FBSR	.ASCII	"BSR"
	.BYTE	0
FADDQ	.ASCII	"ADDQ"
FSUBQ	.ASCII	"SUBQ"
FUSP	.ASCII	"USP"
	.BYTE	0
FCMPM	.ASCII	"CMPM"
FEXG	.ASCII	"EXG"
	.BYTE	0

                                                                                                                                                                                                                                                                                                                                                                                                                                                             