;
;	SELF-RELOCATING 8080 DIS-ASSEMBLER
;	FOR CP/M COM FILES
;
;	CP/M FUNCTION CODES
;
RDCON:	EQU	1
WRTCON:	EQU	2
WRTLST:	EQU	5
CSTAT:	EQU	11
OPENF:	EQU	15
CLOSF:	EQU	16
DSKRD:	EQU	20
DSKWRT:	EQU	21
CREATF:	EQU	22
SETDMA:	EQU	26
;
;	CP/M INTERFACE ADDRESSES
;
BOOT:	EQU	0
CPM:	EQU	5
FCB:	EQU	5CH
FCBCR:	EQU	FCB+32
DBUFF:	EQU	80H
;
;	MISCELLANEOUS EQUATES
;
CR:	EQU	0DH
LF:	EQU	0AH
TAB:	EQU	09H
BSP:	EQU	08H
CTRL:	EQU	40H
;
	ORG	0100H	;BASE OF TPA
;
;	FIRST, RELOCATE THE DIS-ASSEMBLER
;
	LXI	SP,STACK	;SET UP A TEMPORARY STACK
	LXI	H,RELMSG	;POINT TO RELOCATION MESSAGE
	CALL	PMSG	;WRITE IT
	CALL	RDHEX	;READ THE NEW ADDRESS
	PUSH	H	;SAVE IT ON STACK
	LHLD	SBOT	;GET END OF RELOC BLOCK
	XCHG		;PUT IT IN DE
	LHLD	SSTRT	;GET BEGINNING OF RELOC BLOCK
	CALL	COMPH	;COMPLEMENT HL
	DAD	D	;COMPUTE LENGTH
	MOV	B,H	;MOVE IT TO B
	MOV	C,L	;   AND C
	POP	H	;RECOVER DESTINATION
	DAD	B	;ADD LENGTH
MOVER:
	LDAX	D	;GET A BYTE FROM SOURCE
	MOV	M,A	;RELOCATE IT
	MOV	A,B	;TEST REMAINING LENGTH
	ORA	C	;SET FLAGS
	JZ	CHGADR	;DONE MOVING
	DCX	H	;LOWER DESTINATION
	DCX	D	;LOWER ORIGIN
	DCX	B	;LOWER COUNT
	JMP	MOVER	;CONTINUE
CHGADR:
	PUSH	H	;SAVE DESTINATION
	XCHG		;GET BEGINNING
	CALL	COMPH	;COMPLEMENT IT
	POP	D	;RECOVER DESTINATION
	DAD	D	;COMPUTE OFFSET
	SHLD	DISP	;SAVE IT
	XCHG		;SAVE COPY OF DISPLACEMENT
	LHLD	STOP	;END OF DIS-ASSEMBLER
	DAD	D	;DERIVE NEW ADDRESS
	SHLD	STOP	;SAVE IT
	LHLD	STRT	;START OF CODE
	DAD	D	;DERIVE NEW END
	SHLD	STRT	;SAVE IT
	DCX	H	;MINUS ONE TO ENTER LOOP
LOOP:
	INX	H	;NEXT BYTE
	XCHG		;ADDRESS TO DE
	LHLD	STOP	;GET END ADDRESS
	XCHG		;SWITCH BACK
	MOV	A,E	;GET LOW BYTE
	SUB	L	;COMPARE
	MOV	A,D	;GET HIGH BYTE
	SBB	H	;FINISH COMPARE
	JC	COMPLT	;EXIT ADDRESS
	MVI	B,1AH	;GET 3 BYTE OPCODE COUNT
	LXI	D,TAB3	;ADDRESS OF 3 BYTE OPCODE TABLE
CHEK3:
	LDAX	D	;GET TABLE ENTRY
	CMP	M	;COMPARE TO THIS OPCODE
	JZ	ACT	;GOT ONE
	DCR	B	;COUNT - 1
	INX	D	;TABLE + 1
	JNZ	CHEK3	;TRY AGAIN
	MVI	B,12H	;LENGTH OF 2 BYTE TABLE
	LXI	D,TAB2	;ADDRESS OF 2 BYTE TABLE
CHEK2:
	LDAX	D	;GET TABLE ENTRY
	CMP	M	;COMPARE TO THIS OPCODE
	JZ	SKIP	;GOT IT
	DCR	B	;COUNT - 1
	INX	D	;TABLE + 1
	JNZ	CHEK2	;KEEP GOING
	JMP	LOOP	;SKIP THIS BYTE
SKIP:
	INX	H	;SKIP TWO BYTES
	JMP	LOOP	;AND CONTINUE
ACT:
	PUSH	H	;SAVE THIS ADDRESS
	LHLD	SBOT	;GET END OF BLOCK ADDRESS
	XCHG		;PUT IT IN DE
	LHLD	SSTRT	;GET START OF BLOCK
	MOV	B,H	;PUT START ADDRESS
	MOV	C,L	;    IN BC
	POP	H	;RECOVER CURRENT ADDRESS
	INX	H	;ADD 1
	MOV	A,E	;SET UP A SUBTRACT
	SUB	M	;ADJUST THE LOW BYTE
	INX	H	;POINT TO HIGH BYTE
	MOV	A,D	;SET UP SUBTRACT
	SBB	M	;ADJUST HIGH BYTE
	JC	LOOP	;PAST END OF PROGRAM,DON'T ADJUST
	DCX	H	;BACK TO LOW BYTE
	MOV	A,M	;GET IT
	SUB	C	;OFFSET IT
	INX	H	;POINT TO NEXT
	MOV	A,M	;GET HIGH BYTE
	SBB	B	;OFFSET IT
	JC	LOOP	;BEFORE START OF PROGRAM, DON'T ADJUST
	DCX	H	;BACK TO LOW BYTE
	XCHG		;SWITCH WITH DE
	LHLD	DISP	;GET OFFSET
	XCHG		;RESTORE HL
	MOV	A,M	;GET LOW BYTE
	ADD	E	;ADD OFFSET
	MOV	M,A	;REPLACE IT
	INX	H	;POINT TO HIGH BYTE
	MOV	A,M	;GET IT
	ADC	D	;OFFSET IT
	MOV	M,A	;PUT IT BACK
	JMP	LOOP	;ON TO THE NEXT ONE
COMPH:
	MOV	A,H	;GET H
	CMA		;REVERSE IT
	MOV	H,A	;PUT IT BACK
	MOV	A,L	;GET L
	CMA		;REVERSE IT
	MOV	L,A	;PUT IT BACK
	INX	H	;PLUS 1
	RET		;AND GO BACK
COMPLT:
	LXI	D,START	;ORIGINAL START ADDRESS
	LHLD	DISP	;DISPLACEMENT
	DAD	D	;CURRENT ADDRESS
	PCHL		;START DIS-ASSMEBLER
TAB3:
	DB	001H,011H,021H,022H	;LXI B,LXI D,LXI H,SHLD
	DB	02AH,031H,032H,03AH	;LHLD,LXI SP,STA,LDA
	DB	0C2H,0C3H,0C4H,0CAH	;JNZ,JMP,CNZ,JZ
	DB	0CCH,0CDH,0D2H,0D4H	;CZ,CALL,JNC,CNC
	DB	0DAH,0DCH,0E2H,0E4H	;JC,CC,JPO,CPO
	DB	0EAH,0ECH,0F2H,0F4H	;JPE,CPE,JP,CP
	DB	0FAH,0FCH		;JM,CM
TAB2:
	DB	006H,00EH,016H,01EH	;MVI B,MVI C,MVI D,MVI E
	DB	026H,02EH,036H,03EH	;MVI H,MVI L,MVI M,MVI A
	DB	0C6H,0CEH,0D3H,0D6H	;ADI,ACI,OUT,SUI
	DB	0DBH,0DEH,0E6H,0EEH	;IN,SBI,ANI,XRI
	DB	0F6H,0FEH		;ORI,CPI
;
;	STORAGE AREAS FOR RELOCATOR
;
SSTRT:
	DW	START	;START OF SOURCE
SBOT:
	DW	LAST	;BOTTOM OF SOURCE
STRT:
	DW	START	;START OF FIX AREA
STOP:
	DW	DATA	;END OF FIX AREA
DISP:
	DW	0	;DISPLACEMENT
;
	DS	32	;STACK SPACE
;
STACK:	EQU	$
;
;	BEGIN DIS-ASSEMBLER PROGRAM
;
;	SET MEMORY POINTERS
;
START:
	LHLD	CPM+1
	DCX	H
	SPHL	
	MOV	A,L
	SUI	64
	MOV	L,A
	MOV	A,H
	SBI	0
	MOV	H,A
	SHLD	ENDMEM
;
;	OPEN THE TARGET FILE
;
OBJRTY:
	CALL	CLFCB
	LXI	H,OFMSG
	CALL	PMSG
	LXI	H,FCB+1
	CALL	RDFCB
	LXI	D,FCB
	MVI	C,OPENF
	CALL	CPM
	CPI	255
	JNZ	OBJOK
OBJERR:
	LXI	H,FERMSG
	CALL	PMSG
	JMP	OBJRTY
OBJOK:
	LXI	H,FLDMSG
	CALL	PMSG
	CALL	RDHEX
	SHLD	DMA
;
;	READ TARGET FILE
;
NEXSEC:
	XCHG
	LXI	H,START
	MOV	A,L
	SUI	128
	MOV	L,A
	MOV	A,H
	SBI	0
	MOV	H,A
	CALL	TSTHD
	JC	OOMEM
	MVI	C,SETDMA
	CALL	CPM
	LXI	D,FCB
	MVI	C,DSKRD
	CALL	CPM
	ORA	A
	JNZ	OBJDON
	LHLD	DMA
	LXI	D,128
	DAD	D
	SHLD	DMA
	JMP	NEXSEC
OOMEM:
	LXI	H,OMMSG
	JMP	OBJERR+3
;
;	ESTABLISH OPERATING PARAMETERS
;
OBJDON:
	LHLD	DMA
	DCX	H
	XCHG
	LXI	H,ULMSG1
	CALL	DEMEM
	LXI	H,ULMSG
	CALL	PMSG
	LXI	H,DISMSG
	CALL	PMSG
	LXI	H,STAMSG
	CALL	PMSG
	CALL	RDHEX
	SHLD	NXTADD
	SHLD	STADD
	LXI	H,ENDMSG
	CALL	PMSG
	CALL	RDHEX
	SHLD	ENDAD
	SHLD	ENDAD2
	LXI	H,OFSTMS
	CALL	PMSG
	CALL	RDHEX
	SHLD	OFFSET
	LXI	H,PRMSG
	CALL	PMSG
	CALL	CONIN
	MVI	E,0
	CPI	'Y'
	JZ	PRTOPT
	DCR	E
PRTOPT:
	MOV	A,E
	STA	PRSWCH
	LXI	H,SOMSG
	CALL	PMSG
	CALL	CONIN
	MVI	E,0
	CPI	'Y'
	JZ	SRCOPT
	INR	E
SRCOPT:
	MOV	A,E
	STA	SROSW
	JNZ	NOSRC
;
;	DISK OUTPUT IS DESIRED
;
OPNOUT:
	CALL	CLFCB
	LXI	H,SFMSG
	CALL	PMSG
	LXI	H,FCB+1
	CALL	RDFCB
	LXI	D,FCB
	MVI	C,CREATF
	CALL	CPM
	CPI	255
	JNZ	OPENOK
	LXI	H,FERMSG
	CALL	PMSG
	JMP	OPNOUT
OPENOK:
	LXI	H,DBUFF
	SHLD	NXTOUT
	XCHG
	MVI	C,SETDMA
	CALL	CPM
NOSRC:
	MVI	B,6
	PUSH	B
	LXI	D,DATAS
;
;	ESTABLISH KNOWN DATA AREAS
;
SETKDA:
	POP	B
	DCR	B
	PUSH	B
	JZ	NODATA
	LXI	H,KDAMSG
	CALL	PMSG
	CALL	CONIN
	CPI	'N'
	JZ	NODATA
	LXI	H,STAMSG
	CALL	RSTHEX
	LXI	H,ENDMSG
	CALL	RSTHEX
	JMP	SETKDA
NODATA:
	POP	B
	CALL	CLINE
	LXI	H,WRKMSG
	CALL	PMSG
	LHLD	ENDMEM
	XCHG	
	LXI	H,SYMTB
;
;	FILL THE SYMBOL TABLE WITH FF'S
;
CLRTAB:
	XRA	A
	DCR	A
	MOV	M,A
	INX	H
	CALL	TSTHD
	JC	CLRTAB
	CALL	ADDISP
	LXI	H,OPRLEN
	MVI	M,0
	CALL	CHKDTA
	JC	NXTLIN
;
;	BUILD THE SYMBOL TABLE
;	BY SETTING UP ALL ADDRESSES
;	REFERRED TO
;
BLDTBL:
	LHLD	NXTWRK
	XCHG	
	CALL	GETOPC
	LDA	OPRLEN
	CPI	2
	JNZ	NXTLIN
	LHLD	NXTWRK
	INX	H
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG	
	SHLD	TMPSYM
	CALL	SYMTST
	JNC	NXTLIN
	LXI	H,-1
	CALL	SYMTST
	JC	TBLFUL
	LHLD	TMPSYM
	XCHG	
	MOV	M,E
	INX	H
	MOV	M,D
	SHLD	ESYMT
NXTLIN:
	CALL	NXTOPR
	XCHG	
	LHLD	ENDAD
	CALL	TSTHD
	JNC	BLDTBL
	LHLD	ESYMT
	SHLD	ENDMEM
	LXI	D,0
	LXI	H,SYMTB+2
;
;	ASSIGN NUMBERS TO THE SYMBOL ADDRESSES
;
NBRSYM:
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	INX	H
	INX	H
	PUSH	D
	XCHG	
	LHLD	ENDMEM
	INX	H
	INX	H
	CALL	TSTHD
	JC	DOORG
	XCHG	
	POP	D
	MOV	A,E
	ADI	1
	DAA	
	MOV	E,A
	MOV	A,D
	ACI	0
	DAA	
	MOV	D,A
	JMP	NBRSYM
;
;	WRITE AN ORG STATEMENT TO START THE PROGRAM
;
DOORG:
	CALL	SETADD
	CALL	ADDRO
	LXI	H,LOPCOD
	LXI	D,ORGLIT
	CALL	STRMOV
	XCHG	
	LHLD	NXTADD
	XCHG	
	LXI	H,LOPRND
	CALL	DETOLN
	CALL	FINLIN
	LXI	H,LINE
	CALL	PRTLIN
;
;	DECODE THE OBJECT AREA TO INSTRUCTIONS
;
DECODE:
	CALL	ADDRO
	LXI	H,OPRLEN
	MVI	M,0
	CALL	MOVHEX
	CALL	CHKDTA
	JC	ISDATA
	LHLD	NXTWRK
	XCHG	
	CALL	GETOPC
	PUSH	B
	CALL	MOVHEX
	LDA	OPRLEN
	CPI	3
	JZ	ISDATA
	POP	H
	MOV	A,M
	CPI	' '
	JZ	NOREG
	CPI	'S'
	JNZ	NOTSP
	INX	H
	MVI	M,'P'
	JMP	NOTPSW
NOTSP:
	CPI	'P'
	JNZ	NOTPSW
	INX	H
	MVI	M,'S'
	INX	H
	MVI	M,'W'
NOTPSW:
	LDA	OPRLEN
	DCR	A
	JM	NOREG
	INX	H
	MVI	M,','
	INX	H
NOREG:
	SHLD	ENDLIN
	JMP	PUTLAB
ISDATA:
	LXI	H,OPRLEN
	MVI	M,0
	LXI	H,LOPCOD
	LXI	D,DBLIT
	MVI	C,4
PUTOPR:
	LDAX	D
	MOV	M,A
	INX	D
	INX	H
	DCR	C
	JNZ	PUTOPR
	LHLD	NXTWRK
	XCHG	
	LXI	H,LOPRND
	MVI	M,'0'
	INX	H
	LDAX	D
	CALL	VALCH1
	JNC	PUTOP2
	DCX	H
	CALL	PUTLIT
	JMP	PUTOP3
PUTOP2:
	CALL	HEXMEM
	MVI	M,'H'
PUTOP3:
	SHLD	ENDLIN
PUTLAB:
	LHLD	NXTADD
	CALL	SYMTST
	JC	NOTSYM
	LXI	H,LSYMBL
	CALL	PUTSYM
	MVI	M,':'
	LXI	H,SEMICL
	CALL	WRTLIN
NOTSYM:
	LHLD	NXTWRK
	INX	H
	LDA	OPRLEN
	CPI	2
	JNZ	NOT3BT
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG	
	CALL	SYMTST
	JNC	PTCMNT
	XCHG	
	LHLD	ENDLIN
	CALL	DETOLN
	JMP	NOT2BT
;
;	ADD A COMMENT TO SHOW THE ABSOLUTE ADDRESS
;	REFERRED TO IN THE INSTRUCTION
;
PTCMNT:
	LHLD	ENDLIN
	CALL	PUTSYM
	LXI	H,LCOMNT
	MVI	M,';'
	INX	H
	MVI	M,'('
	PUSH	H
	LHLD	NXTWRK
	INX	H
	MOV	E,M
	INX	H
	MOV	D,M
	POP	H
	INX	H
	CALL	DEMEM
	MVI	M,')'
	SHLD	ENDLIN
	JMP	NOT2BT
NOT3BT:
	CPI	1
	JNZ	NOT2BT
	LHLD	ENDLIN
	MVI	M,'0'
	INX	H
	XCHG	
	LHLD	NXTWRK
	INX	H
	MOV	A,M
	CALL	VALCH1
	JNC	LITRAL
	XCHG	
	DCX	H
	CALL	PUTLIT
	JMP	NOTLIT
LITRAL:
	XCHG	
	CALL	HEXMEM
	MVI	M,'H'
NOTLIT:
	SHLD	ENDLIN
NOT2BT:
	CALL	FINLIN
	LXI	H,LINE
	CALL	PRTLIN
	CALL	NXTOPR
	LHLD	NXTADD
	XCHG	
	LHLD	ENDAD
	CALL	TSTHD
	JNC	DECODE
	JMP	ENDDIS
ADDRO:
	CALL	CLINE
	LHLD	NXTADD
	XCHG	
	LXI	H,LINADR
	JMP	DEMEM
DETOLN:
	XRA	A
	CALL	HEXMEM
	CALL	DEMEM
	MVI	M,'H'
	SHLD	ENDLIN
	RET	
STRMOV:
	LDAX	D
	MOV	B,A
STRMV2:
	INX	D
	LDAX	D
	MOV	M,A
	INX	H
	DCR	B
	RZ	
	JMP	STRMV2
PUTLIT:
	MVI	M,''''
	INX	H
	MOV	M,A
	INX	H
	MVI	M,''''
	RET	
;
;	DETERMINE IF THE CURRENT CHARACTER IS A
;	VALID ASCII CHARACTER. THIS ROUTINE HAS A
;	LIMIT CHANGED IN THE SECOND PASS. FIRST PASS
;	DISK OUTPUT USES TABS INSTEAD OF BLANK
;	SPACES FOR DELIMITERS. THE SECOND
;	PASS (PRINT ASCII MAP) CHANGES THE LIMIT TO
;	PRINT SPACES.
;
VALCH1:
	CPI	07FH
	RNC	
	CPI	'!'
;
CHGLIM:	EQU	$-1
;
	CMC	
	RET	
MOVHEX:
	LHLD	NXTWRK
	XCHG	
	LXI	H,LHEXDA
	LDA	OPRLEN
	CPI	3
	JNZ	SKIP1
	XRA	A
SKIP1:
	INR	A
	MOV	C,A
LHXDAT:
	LDAX	D
	CALL	HEXMEM
	INX	D
	DCR	C
	JNZ	LHXDAT
	RET	
CLINE:
	MVI	B,71
	LXI	H,LINADR
	MVI	A,' '
CLIN2:
	MOV	M,A
	INX	H
	DCR	B
	JNZ	CLIN2
	RET	
PUTSYM:
	MVI	M,'L'
	INX	H
	INX	D
	INX	D
	LDAX	D
	MOV	B,A
	INX	D
	LDAX	D
	MOV	D,A
	MOV	E,B
	JMP	DEMEM
;
;	PRINT THE SYMBOL TABLE
;
PRTTBL:
	LXI	H,SROSW
	LXI	D,DSKSWC
	MOV	A,M
	STAX	D
	INR	M
	CALL	CLINE
	LXI	D,SYMTB
TBLOUT:
	MVI	C,5
	LDAX	D
	INR	A
	JNZ	NOTFIN
	INX	D
	LDAX	D
	INR	A
	RZ	
	DCX	D
NOTFIN:
	INX	D
	INX	D
	INX	D
	LXI	H,LINADR
MORSYM:
	MVI	M,'L'
	INX	H
	CALL	LOADAD
	DCX	D
	CALL	LOADAD
	INX	H
	INX	H
	INX	D
	INX	D
	INX	D
	INX	D
	INX	D
	INX	D
	INX	D
	DCR	C
	JNZ	MORSYM
	LXI	H,LINE
	CALL	PRTLIN
	DCX	D
	DCX	D
	DCX	D
	JMP	TBLOUT
LOADAD:
	LDAX	D
	CALL	HEXMEM
	DCX	D
	LDAX	D
	CALL	HEXMEM
	INX	H
	RET	
GETOPC:
	LDAX	D
	CPI	076H
	JNZ	RANGE
	LXI	H,HLTLIT
	JMP	PUTOPC
RANGE:
	MVI	D,040H
	SUB	D
	JC	REGOPT
	SUB	D
	JC	ISMOV
	SUB	D
	JC	FIXOPC
REGOPT:
	ADD	D
	LXI	H,OPTABL
	MVI	D,0
	MOV	E,A
	DAD	D
	DAD	D
	DAD	D
	DAD	D
	DAD	D
PUTOPC:
	LXI	B,LOPCOD
	XCHG	
	MVI	H,4
	CALL	TOLINE
	INX	B
	CALL	XINFO
	RET	
TOLINE:
	LDAX	D
PUTIT:
	STAX	B
	INX	D
	DCR	H
	RZ	
	INX	B
	JMP	TOLINE
;
;	DECODE THE DATA BYTE FOLLOWING THE
;	OPCODE LITERAL FOR INFORMATION ABOUT
;	THE INSTRUCTION BEING DIS-ASSEMBLED.
;
;	BITS 7 & 6 = LENGTH OF OPERAND
;		     (3 = INVALID INSTRUCTION)
;	BITS 5 - 0 = OPERAND MINUS 20H
;
;	NOTE THAT BITS 5-0 ARE AUTOMATICALLY
;	INSERTED INTO THE OUTPUT LINE, THEN
;	OVERLAYED IF THE DIS-ASSEMBLER DETERMINES
;	THAT THE NEXT BYTE IS USED TO DETERMINE
;	WHAT THIS OPERATION IS TO DO.
;
;	SINCE BITS 5-0 HAVE A 20H ADDED TO THEM,
;	SETTING THEM TO ZERO RESULTS IN A BLANK
;	SPACE BEING WRITTEN TO THE OUTPUT LINE.
;
;
XINFO:
	LDAX	D
	RLC	
	RLC	
	MVI	H,003H
	ANA	H
	STA	OPRLEN
	LDAX	D
	MVI	H,3FH
	ANA	H
	ADI	020H
	LXI	B,LOPRND
ALTER2:
	STAX	B
	RET	
ISMOV:
	ADD	D
	STA	ISMOV2+1
	LXI	B,LOPCOD
	LXI	D,MOVLIT
	MVI	H,3
	CALL	TOLINE
	INX	B
ISMOV2:
	MVI	A,0
	MVI	H,007H
	RRC	
	RRC	
	RRC	
	LXI	B,LOPRND
	CALL	MASKRG
	MVI	A,','
	MVI	H,001H
	INX	B
	CALL	PUTIT
	MVI	H,007H
	LDA	ISMOV2+1
	INX	B
	CALL	MASKRG
	XRA	A
	STA	OPRLEN
	RET	
MASKRG:
	ANA	H
REGIN:
	CALL	GETREG
	MVI	H,1
	CALL	TOLINE
	RET	
GETREG:
	LXI	H,REGTAB
	MOV	E,A
	SUB	A
	MOV	D,A
	DAD	D
	XCHG	
	RET	
FIXOPC:
	ADD	D
	ADD	D
	ADD	D
	PUSH	PSW
	ANI	038H
	LXI	H,OPTAB2
	LXI	D,0
	RRC	
	RRC	
	RRC	
	MOV	E,A
	DAD	D
	DAD	D
	DAD	D
	XCHG	
	LXI	B,LOPCOD
	MVI	H,3
	CALL	TOLINE
	XRA	A
	STA	OPRLEN
	LXI	B,LOPRND
	POP	PSW
	ANI	007H
	JMP	REGIN
;
;	THE SYMBOL TABLE IS FULL
;
TBLFUL:
	LXI	H,TFMSG
	CALL	PMSG
;
;	END OF OPERATION DIS-ASSEMBLY PASS
;
ENDDIS:
	CALL	CLINE
	LXI	H,LOPCOD
	MVI	M,'E'
	INX	H
	MVI	M,'N'
	INX	H
	MVI	M,'D'
	CALL	MCRLF
	LXI	H,LINE
	CALL	PRTLIN
	LXI	H,SEMICL
	CALL	PRTLIN
	CALL	PRTTBL
	LXI	H,SEMICL
	CALL	PRTLIN
	MVI	A,' '
	STA	CHGLIM
	CALL	SETADD
	LHLD	OFFSET
	XCHG	
	LHLD	ENDAD
	DAD	D
	SHLD	ENDAD
	LHLD	NXTWRK
	XCHG	
;
;	PRINT ASCII MAP OF PROGRAM AREA
;
PRASCI:
	LXI	H,LINADR
	PUSH	D
	PUSH	H
	LXI	H,OFFSET
	MOV	A,E
	SUB	M
	MOV	E,A
	INX	H
	MOV	A,D
	SBB	M
	MOV	D,A
	POP	H
	CALL	DEMEM
	POP	D
	MVI	M,' '
NXASCI:
	INX	H
	LDAX	D
	CALL	VALCH1
	JNC	GETFIL
	MOV	M,A
GOODCH:
	INX	D
	MOV	A,E
	ANI	00FH
	JNZ	NXASCI
	INX	H
	MVI	M,' '
	MOV	A,E
	ANI	3FH
	JNZ	NXASCI
	CALL	MCRLF
	LXI	H,LINE
	CALL	PRTLIN
	LHLD	ENDAD
	CALL	TSTHD
	JC	DOXREF
	JMP	PRASCI
GETFIL:
	MVI	M,'.'
	JMP	GOODCH
;
;	CROSS-REFERENCE ALL SYMBOLS
;
DOXREF:
	CALL	CLINE
	LXI	H,SEMICL
	CALL	WRTLIN
	LXI	H,PUTIT
	XRA	A
	MOV	M,A
	LXI	H,ALTER2
	MOV	M,A
	LXI	H,0
	SHLD	SYMPTR
XRFNXT:
	CALL	ADDSYM
	CALL	SETADD
XRFSYM:
	LHLD	NXTWRK
	XCHG	
	CALL	GETOPC
	LDA	OPRLEN
	CPI	2
	JNZ	NOXREF
	CALL	ADDSRC
	LHLD	NXTWRK
	INX	H
	MOV	A,M
	CMP	E
	JNZ	NOXREF
	INX	H
	MOV	A,M
	CMP	D
	JNZ	NOXREF
	LHLD	NXTADD
	XCHG	
	LHLD	ENDLIN
	CALL	DEMEM
	INX	H
	SHLD	ENDLIN
	LXI	D,LLAST
	CALL	TSTHD
	JC	NOXREF
	CALL	FINLIN
	LXI	H,LINE
	CALL	PRTLIN
	LXI	H,SYMLOC
	SHLD	ENDLIN
NOXREF:
	CALL	NXTOPR
	XCHG	
	LHLD	ENDAD
	CALL	TSTHD
	JNC	XRFSYM
	CALL	FINLIN
	LXI	H,LINE
	CALL	PRTLIN
	LHLD	SYMPTR
	INX	H
	SHLD	SYMPTR
	LXI	D,SYMTB
	DAD	H
	DAD	H
	DAD	D
	XCHG	
	LHLD	ENDMEM
	CALL	TSTHD
	JC	ENDING
	JMP	XRFNXT
;
;	JOB FINISHED. CLOSE DISK
;	FILE IF NECESSARY.
;
ENDING:
	LDA	DSKSWC
	ADD	A
	JNZ	BOOT
	JMP	DCLOSE
ADDSYM:
	CALL	LBLSCH
	LXI	H,LINADR
	MVI	M,'L'
	INX	H
	CALL	DEMEM
	INX	H
	SHLD	ENDLIN
	RET	
CONSCH:
	LHLD	SYMPTR
	DAD	H
	DAD	H
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	RET	
ADDSRC:
	LXI	D,SYMTB
	JMP	CONSCH
LBLSCH:
	LXI	D,SYMTB+2
	JMP	CONSCH
HANGUP:
	MVI	C,'?'
	CALL	CONOUT
	JMP	START
RDHEX:
	LXI	H,0
NXTHEX:
	CALL	CONIN
	CPI	CR
	RZ	
	CPI	'C'-CTRL
	JZ	START
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	JC	HANGUP
	CALL	TOBINY
	JC	HANGUP
	ORA	L
	MOV	L,A
	JMP	NXTHEX
TOBINY:
	SUI	'0'
	RC	
	ADI	0E9H
	RC	
	ADI	006H
	JP	TOBIN2
	ADI	007H
	RC	
TOBIN2:
	ADI	10
	ORA	A
	RET	
DCLOSE:
	LHLD	NXTOUT
	MOV	A,L
	CPI	DBUFF
	JZ	DONE
	MVI	C,1AH
	CALL	DWRITE
	JMP	DCLOSE
DONE:
	LXI	D,FCB
	MVI	C,CLOSF
	CALL	CPM
	JMP	BOOT
DWRITE:
	PUSH	H
	LHLD	NXTOUT
	MOV	M,C
	INX	H
	SHLD	NXTOUT
	MOV	A,H
	POP	H
	CPI	0
	RZ
	PUSH	B
	PUSH	D
	PUSH	H
	LXI	H,DBUFF
	SHLD	NXTOUT
	LXI	D,FCB
	MVI	C,DSKWRT
	CALL	CPM
	POP	H
	POP	D
	POP	B
	CPI	0
	RZ
	HLT
WAITER:
	PUSH	B
	PUSH	D
	PUSH	H
	MVI	C,CSTAT
	CALL	CPM
	ANI	1
	JNZ	WAITR3
WAITR2:
	POP	H
	POP	D
	POP	B
	RET
WAITR3:
	MVI	C,RDCON
	CALL	CPM
	CPI	'C'-CTRL
	JZ	BOOT
	CPI	'P'-CTRL
	JNZ	WAITR2
	LDA	PRSWCH
	CMA
	STA	PRSWCH
	JMP	WAITR2
CONIN:
	PUSH	B
	PUSH	D
	PUSH	H
	MVI	C,RDCON
USECPM:
	CALL	CPM
	POP	H
	POP	D
	POP	B
	RET
CONOUT:
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,C
	MVI	C,WRTCON
	JMP	USECPM
LSTOUT:
	CALL	WAITER
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,C
	MVI	C,WRTCON
	CALL	CPM
	POP	H
	POP	D
	POP	B
	LDA	PRSWCH
	ORA	A
	RNZ
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,C
	MVI	C,WRTLST
	JMP	USECPM
HEXOUT:
	PUSH	PSW
	RRC	
	RRC	
	RRC	
	RRC	
	CALL	TOASCI
	MOV	C,A
	CALL	LSTOUT
	POP	PSW
	CALL	TOASCI
	MOV	C,A
	JMP	LSTOUT
HEXMEM:
	PUSH	PSW
	RRC	
	RRC	
	RRC	
	RRC	
	CALL	TOASCI
	MOV	M,A
	INX	H
	POP	PSW
	CALL	TOASCI
	MOV	M,A
	INX	H
	RET	
PMSG:
	MOV	B,M
	INX	H
	CALL	CRLF
PMSG1:
	MOV	C,M
	CALL	CONOUT
	DCR	B
	RZ	
	INX	H
	JMP	PMSG1
FINLIN:
	LHLD	ENDLIN
MCRLF:
	INX	H
	MVI	M,CR
	INX	H
	MVI	M,LF
	RET	
TSTHD:
	MOV	A,L
	SUB	E
	MOV	A,H
	SBB	D
	RET	
ADDISP:
	LHLD	OFFSET
	XCHG	
	LHLD	NXTADD
	DAD	D
	SHLD	NXTWRK
	RET	
TOASCI:
	ANI	00FH
	ADI	090H
	DAA	
	ACI	40H
	DAA	
	RET	
DEMEM:
	MOV	A,D
	CALL	HEXMEM
	MOV	A,E
	JMP	HEXMEM
NXTOPR:
	LHLD	NXTADD
	XCHG	
	LHLD	NXTWRK
	LDA	OPRLEN
	INR	A
NXTOP1:
	DCR	A
	JM	NXTOP2
	INX	H
	INX	D
	JMP	NXTOP1
NXTOP2:
	SHLD	NXTWRK
	XCHG	
	SHLD	NXTADD
	RET	
CRLF:
	MVI	C,CR
	CALL	CONOUT
	MVI	C,LF
	JMP	CONOUT
SYMTST:
	LXI	D,SYMTB
SYMTS2:
	LDAX	D
	CMP	L
	JNZ	SYMTS3
	INX	D
	LDAX	D
	CMP	H
	JZ	SYMFND
	JMP	SYMTS3+1
SYMTS3:
	INX	D
	INX	D
	INX	D
	INX	D
	PUSH	H
	LHLD	ENDMEM
	CALL	TSTHD
	POP	H
	JNC	SYMTS2
	RET	
SYMFND:
	STC	
	CMC	
	DCX	D
	RET	
SETADD:
	LHLD	STADD
	SHLD	NXTADD
	LHLD	ENDAD2
	SHLD	ENDAD
	JMP	ADDISP
PRTLIN:
	CALL	WRTLIN
	JMP	CLINE
WRTLIN:
	PUSH	B
	MOV	B,M
WRTLN2:
	INX	H
	MOV	C,M
	MOV	A,M
	STA	CHAR
	PUSH	B
	CALL	LSTOUT
	POP	B
	LDA	SROSW
	ADD	A
	JNZ	NODISK
	MOV	A,B
	CPI	57
	JNC	NODISK
	MOV	A,C
	CPI	' '
	JNZ	OVLFLO
	LDA	THOLD
	CPI	TAB
	JZ	NODISK
	MVI	C,TAB
OVLFLO:
	MOV	A,C
	STA	THOLD
	CALL	DWRITE
NODISK:
	LDA	CHAR
	DCR	B
	CPI	LF
	JNZ	WRTLN2
	POP	B
	RET	
CHKDTA:
	MVI	B,5
	LXI	H,DATAS
CHKDT2:
	CALL	LOADDE
	PUSH	H
	LHLD	NXTADD
	CALL	TSTHD
	POP	H
	JNC	CHKDT4
CHKDT3:
	CMC	
	RET	
CHKDT4:
	CALL	LOADDE
	PUSH	H
	LHLD	NXTADD
	XCHG	
	CALL	TSTHD
	POP	H
	JNC	CHKDT3
	DCR	B
	JNZ	CHKDT2
	CMC	
	RET	
LOADDE:
	MOV	E,M
	INX	H
	MOV	D,M
	INX	H
	RET	
RSTHEX:
	CALL	PMSG
	CALL	RDHEX
	XCHG	
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	XCHG	
	RET	
CLFCB:
	XRA	A
	STA	FCB
	LXI	H,FCB+1
	MVI	B,11
CLFCB2:
	MVI	M,' '
	INX	H
	DCR	B
	JNZ	CLFCB2
	MVI	B,21
CLFCB3:
	MVI	M,0
	INX	H
	DCR	B
	JNZ	CLFCB3
	RET
RDFCB:
	CALL	CONIN
	CPI	CR
	RZ
	CPI	'.'
	JZ	RDFCB1
	CPI	7FH
	JNZ	RDFCB2
	DCX	H
	MVI	C,BSP
	CALL	CONOUT
	JMP	RDFCB
RDFCB2:
	MOV	M,A
	INX	H
	JMP	RDFCB
RDFCB1:
	LXI	H,FCB+9
	JMP	RDFCB
;
;	DATA AREAS
;
DATA:	EQU	$
;
NXTOUT:
	DW	0
NXTADD:
	DW	0
STADD:
	DW	0
ENDAD2:
	DW	0
ENDAD:
	DW	0
OFFSET:
	DW	0
NXTWRK:
	DW	0
OPRLEN:
	DB	0
TMPSYM:
	DW	0
SROSW:
	DB	0
THOLD:
	DB	0
DATAS:
	DB	0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH
CHAR:
	DB	0	
ENDLIN:
	DW	0
DBLIT:
	DB	'DB  ',0C9H
SEMICL:
	DB	03H,';',CR,LF
ORGLIT:
	DB	03H,'ORG'
MOVLIT:
	DB	'MOV '
HLTLIT:
	DB	'HLT ',000H
OPTABL:
	DB	'NOP ',000H
	DB	'LXI ',0A2H
	DB	'STAX',022H
	DB	'INX ',022H
	DB	'INR ',022H
	DB	'DCR ',022H
	DB	'MVI ',062H
	DB	'RLC ',000H
	DB	'ILLG',0C0H
	DB	'DAD ',022H
	DB	'LDAX',022H
	DB	'DCX ',022H
	DB	'INR ',023H
	DB	'DCR ',023H
	DB	'MVI ',063H
	DB	'RRC ',000H
	DB	'ILLG',0C0H
	DB	'LXI ',0A4H
	DB	'STAX',024H
	DB	'INX ',024H
	DB	'INR ',024H
	DB	'DCR ',024H
	DB	'MVI ',064H
	DB	'RAL ',000H
	DB	'ILLG',0C0H
	DB	'DAD ',024H
	DB	'LDAX',024H
	DB	'DCX ',024H
	DB	'INR ',025H
	DB	'DCR ',025H
	DB	'MVI ',065H
	DB	'RAR ',000H
	DB	'ILLG',0C0H
	DB	'LXI ',0A8H
	DB	'SHLD',080H
	DB	'INX ',028H
	DB	'INR ',028H
	DB	'DCR ',028H
	DB	'MVI ',068H
	DB	'DAA ',000H
	DB	'ILLG',0C0H
	DB	'DAD ',028H
	DB	'LHLD',080H
	DB	'DCX ',028H
	DB	'INR ',02CH
	DB	'DCR ',02CH
	DB	'MVI ',06CH
	DB	'CMA ',000H
	DB	'ILLG',0C0H
	DB	'LXI ',0B3H
	DB	'STA ',080H
	DB	'INX ',033H
	DB	'INR ',02DH
	DB	'DCR ',02DH
	DB	'MVI ',06DH
	DB	'STC ',000H
	DB	'ILLG',0C0H
	DB	'DAD ',033H
	DB	'LDA ',080H
	DB	'DCX ',033H
	DB	'INR ',021H
	DB	'DCR ',021H
	DB	'MVI ',061H
	DB	'CMC ',000H
	DB	'RNZ ',000H
	DB	'POP ',022H
	DB	'JNZ ',080H
	DB	'JMP ',080H
	DB	'CNZ ',080H
	DB	'PUSH',022H
	DB	'ADI ',040H
	DB	'RST ',010H
	DB	'RZ  ',000H
	DB	'RET ',000H
	DB	'JZ  ',080H
	DB	'ILLG',0C0H
	DB	'CZ  ',080H
	DB	'CALL',080H
	DB	'ACI ',040H
	DB	'RST ',011H
	DB	'RNC ',000H
	DB	'POP ',024H
	DB	'JNC ',080H
	DB	'OUT ',040H
	DB	'CNC ',080H
	DB	'PUSH',024H
	DB	'SUI ',040H
	DB	'RST ',012H
	DB	'RC  ',000H
	DB	'ILLG',0C0H
	DB	'JC  ',080H
	DB	'IN  ',040H
	DB	'CC  ',080H
	DB	'ILLG',0C0H
	DB	'SBI ',040H
	DB	'RST ',013H
	DB	'RPO ',000H
	DB	'POP ',028H
	DB	'JPO ',080H
	DB	'XTHL',000H
	DB	'CPO ',080H
	DB	'PUSH',028H
	DB	'ANI ',040H
	DB	'RST ',014H
	DB	'RPE ',000H
	DB	'PCHL',000H
	DB	'JPE ',080H
	DB	'XCHG',000H
	DB	'CPE ',080H
	DB	'ILLG',0C0H
	DB	'XRI ',040H
	DB	'RST ',015H
	DB	'RP  ',000H
	DB	'POP ',030H
	DB	'JP  ',080H
	DB	'DI  ',000H
	DB	'CP  ',080H
	DB	'PUSH',030H
	DB	'ORI ',040H
	DB	'RST ',016H
	DB	'RM  ',000H
	DB	'SPHL',000H
	DB	'JM  ',080H
	DB	'EI  ',000H
	DB	'CM  ',080H
	DB	'ILLG',0C0H
	DB	'CPI ',040H
	DB	'RST ',017H
REGTAB:
	DB	'BCDEHLMA'
OPTAB2:
	DB	'ADD'
	DB	'ADC'
	DB	'SUB'
	DB	'SBB'
	DB	'ANA'
	DB	'XRA'
	DB	'ORA'
	DB	'CMP'
SYMPTR:
	DW	0	
DSKSWC:
	DB	0	
PRSWCH:
	DB	0
DMA:
	DW	0
ESYMT:
	DW	0
ENDMEM:
	DW	0
LINE:
	DB	71
LINADR:
	DS	5
LHEXDA:
	DS	1
SYMLOC:
	DS	9
LSYMBL:
	DS	8
LOPCOD:
	DS	8
LOPRND:
	DS	10
LCOMNT:
	DS	20
LLAST:
	DS	10
	DB	CR,LF
TFMSG:
	DB	(FLDMSG-TFMSG)-1
	DB	'SYMBOL TABLE FULL'
;
SYMTB:	EQU	$
;
FLDMSG:
	DB	(STAMSG-FLDMSG)-1
	DB	'ADDRESS TO LOAD FILE AT IN HEX = '
STAMSG:
	DB	(ENDMSG-STAMSG)-1
	DB	'STARTING ADDRESS IN HEX = '
ENDMSG:
	DB	(OFSTMS-ENDMSG)-1
	DB	'ENDING ADDRESS IN HEX = '
OFSTMS:
	DB	(PRMSG-OFSTMS)-1
	DB	'OFFSET IN HEX = '
PRMSG:
	DB	(SOMSG-PRMSG)-1
	DB	'PRINT DIS-ASSEMBLED CODE (Y/N) ? '
SOMSG:
	DB	(KDAMSG-SOMSG)-1
	DB	'SOURCE FILE OUTPUT TO DISK (Y/N) ? '
KDAMSG:
	DB	(WRKMSG-KDAMSG)-1
	DB	'KNOWN DATA AREA (Y/N) ? '
WRKMSG:
	DB	(OFMSG-WRKMSG)-1
	DB	'WORKING',CR,LF
OFMSG:
	DB	(SFMSG-OFMSG)-1
	DB	'NAME OF OBJECT FILE ? '
SFMSG:
	DB	(FERMSG-SFMSG)-1
	DB	'NAME OF SOURCE FILE TO CREATE ? '
FERMSG:
	DB	(OMMSG-FERMSG)-1
	DB	'FILE ERROR'
OMMSG:
	DB	(DISMSG-OMMSG)-1
	DB	'OBJECT FILE TOO LARGE'
DISMSG:
	DB	(RELMSG-DISMSG)-1
	DB	'DIS-ASSEMBLY PARAMETERS ----'
RELMSG:
	DB	(ULMSG-RELMSG)-1
	DB	'ADDRESS TO LOAD DIS-ASSEMBLER IN HEX = '
ULMSG:
	DB	(LAST-ULMSG)-1
	DB	'UPPER LIMIT = '
ULMSG1:
	DS	4
;
LAST	EQU	$
;
	END
