Compucolor.org – Virtual Media

Listing of file='DISASM.MAC;01' on disk='vmedia/disassembler-sector.ccvf'

;^RED>DISASM.SRC;8		1980/09/14 1200
;
;	KNOWN BUGS:
;			DOES NOT ALLOW INITIAL VALUE
;				FOR LABELS
;
;
;
; COPYRIGHT 1977	NORDIN ENTERPRISES
;			P.O. BOX 1277
;			CUPERTINO, CA 95014
;
;
;	TITLE	'AUTOMATIC DIS-ASSEMBLER PROGRAM'
;
;
; COMPUCOLOR II		32K SYSTEM
;
; ENTER A 'START ADDR','FINISH ADDR','OFFSET'&'PARAM'
; FROM CONSOLE.  PRINT TO THE LIST DEVICE IN
; ASSEMBLER LANGUAGE FORMAT THE FOLLOWING:
;  HEX ADDR---OBJECT CODE---MNEMONIC---OPERAND
;    PRINT LABELS WHERE FOUND
;
LOAD	EQU	0E400H	;64K MACHINE
			;
	ORG	LOAD
			;
			;
	JMP	FIRST	;FIRST DO COMPUCOLOR THINGS
CI:	JMP	CIX	;CONSOLE INPUT
CO:	JMP	COX	;CONSOLE OUTPUT (DATA IN A REG)
LO:	JMP	LOX	;LIST (PRINT) OUTPUT
MNTR:	JMP	EXIT	;RETURN TO MONITOR
WRTV:	JMP	PUNCH	;PUNCH OUTPUT
UPDAT:	JMP	MNTR
STACK:	DW	THESTK	;LOCATION OF THE STACK
SZTBL	EQU	3	;TABLE SIZE IN KILOBYTES
TBLSZ:	DB	SZTBL	;TABLE SIZE IN KILOBYTES
TABLOC	EQU	LOAD-SZTBL*1024
TABLE:	DW	TABLOC	;START LOCATION OF SYMBOL TABLE
			;
			;
START:	DW	0	;START ADDRESS
FINSH:	DW	0	;FINISH ADDRESS
OFSET:	DW	0	;OFFSET VALUE
HERE:	DW	0	;PRESENT ADDRESS VALUE
TINL:	DW	0	;ADDRESS OF SYMBOL TABLE INSERT
TMPST:	DW	0	;SEARCH ADDRESS FOLLOWING JMP , CALL
PSTAT:	DB	0	;PRINT LABEL STATUS
LABV:	DW	0	;LABEL VALUE -- UP TO 12K LABELS
TABL3:	DW	0	;STARTING ADDRESS OF SYMBOL TABLE
COUNT:	DB	0	;PRINT OUT FORMAT CONTROL
;
;
CR	EQU	0DH	;CARRIAGE RETURN
;
;
;
BEGIN:	LHLD	TABLE
	SHLD	TABL3	;SET UP SYMBOL TABLE START
	LXI	H,MSG1
	CALL	MESAG	;PRINT--PUNCH THE SOURCE ?
	CALL	TI
	CPI	'Y'	;YES?
	JZ	BEG0	;JUMP IF YES
	LXI	H,0C900H;NO
	SHLD	WRTV	;PATCH PUNCH WITH RET IF SO
	JMP	BEG1	;SKIP DISK FILE SETUP
BEG0:	CALL	CRLF
	CALL	SETUP	;SETUP DISK FILE
BEG1:	CALL	CRLF
	LXI	H,MSG2
	CALL	MESAG	;PRINT--PRINT ASCII DUMP ?
	CALL	TI
	CPI	'Y'
	JZ	PASCI	;GO PRINT ASCII FIRST
	CALL	CRLF
	CALL	STFIN	;GET THE START-FINISH PARAMETERS
;
; CLEAR THE SYMBOL TABLE
;
BEG2:	LHLD	TABL3
	LDA	TBLSZ
	RLC
	RLC
	MOV	C,A
	XRA	A
	STA	PSTAT
	MOV	B,A
	DCX	H
CLEAR:	MOV	M,A
	INX	H
	INR	B
	JNZ	CLEAR
	DCR	C
	JNZ	CLEAR
	MVI	A,0FFH
	MVI	B,4
CLR1:	MOV	M,A
	DCX	H
	DCR	B
	JNZ	CLR1
	LHLD	START
	SHLD	HERE
;
; FIRST PASS--BUILD A SYMBOL TABLE ( 3 BYTES PER SYMBOL )
;  SEARCH CODE DELIMITED BY 'START' & 'FINISH' FOR
;  ALL JMP'S & CALL'S.  IF THE ADDRESS WHICH FOLLOWS
;  ISN'T FOUND IN THE TABLE AND IS IN THE RANGE
;  OF 'START & FINISH'---
;  THEN INSERT IT IN A NUMERICALLY ASCENDING ORDER.
;  IF IT IS FOUND IN THE TABLE---
;  INCREMENT THAT LABELS 'NUMBER OF CALLS'
;  COUNTER (UP TO 254 POSSIBLE).
;   FORMAT OF TABL3:
;     CNTR0,MS ADDRESS,LS ADDRESS,CNTR1,MS ADDRESS,LS ADDRESS
;       LAST TABLE POSITION IS 0FFH
;
PASS:	LHLD	HERE	;GET PRESENT CODE POINTER
	LDA	FINSH+1
	CMP	H	;ARE WE FINISHED?
	JZ	PASS1	;MAYBE
	JC	PASSE	;YES
	JMP	PASS2
PASS1:	LDA	FINSH
	CMP	L	;FINISHED?
	JC	PASSE	;YES
PASS2:	MOV	A,M	;NO - GET OPCODE BYTE
	INX	H
	SHLD	HERE	;SAVE POINTER TO NEXT BYTE
	LXI	H,TABL1
	ADD	L
	MOV	L,A
	MVI	A,0
	ADC	H
	MOV	H,A
	MOV	A,M	;GET NUMBER OF BYTES/OPCODE COUNTER
	CPI	1	;ONE BYTE OPCODE?
	JZ	PASS	;YES
	CPI	2
	JZ	PASS3	;TWO BYTE OPCODE
	CPI	3
	JZ	PASS4	;THREE BYTES OTHER THAN JMP , CALL
	LHLD	HERE	;THIS IS A JMP OR CALL OPCODE
	MOV	E,M	;GET LS ADDRESS
	INX	H
	MOV	D,M	;GET MS ADDRESS
	INX	H
	SHLD	HERE	;READY FOR NEXT OPCODE
	XCHG
	SHLD	TMPST	;SAVE DE IN RAM
	LHLD	START
	XCHG
	LHLD	OFSET
	DAD	D	;ADD OFFSET TO START ADDRESS
	XCHG
	LHLD	TMPST	;NOW RETRIEVE COMPARE ADDRESS
	MOV	A,H
	CMP	D	;IF COMPARE ADDRESS < START ADDRESS
	JC	PASS	;THEN GO ON TO NEXT OPCODE
	JNZ	PASS0
	MOV	A,L
	CMP	E
	JC	PASS
PASS0:	LHLD	FINSH
	XCHG
	LHLD	OFSET
	DAD	D	;ADD OFFSET TO FINISH ADDRESS
	XCHG
	LHLD	TMPST
	XCHG
	MOV	A,H
	CMP	D	;IF COMPARE ADDRESS > FINISH ADDRESS
	JC	PASS	;THEN GO ON TO NEXT OPCODE
	JNZ	SERCH
	MOV	A,L
	CMP	E
	JC	PASS
	JMP	SERCH	;COMPARE ADDRESS WAS WITHIN RANGE
PASS3:	LHLD	HERE
	INX	H
	SHLD	HERE
	JMP	PASS
PASS4:	LHLD	HERE
	INX	H
	INX	H
	SHLD	HERE
	JMP	PASS
;
; TABLE SEARCH FOR COMPARE ADDRESS CONTAINED IN DE
;
SERCH:	LHLD	TABL3
SER1:	MOV	A,M	;GET NUMBER OF CALLS COUNTER
	CPI	0FFH	;END OF TABLE?
	JZ	PASS	;YES
	ORA	A
	JZ	INSRT	;THAT WAS END OF TABLE ENTRIES
	INX	H
	MOV	A,D	;GET MS SEARCH VALUE
	CMP	M	;COMPARE TO SYMBOL TABLE VALUE
	JC	SER5	;MS TABLE > MS SEARCH VALUE
	JNZ	SER2	;NOT EQUAL
	INX	H
	MOV	A,E	;GET LS SEARCH VALUE
	CMP	M
	JC	SER4	;LS TABLE > LS SEARCH VALUE
	JNZ	SER3	;NOT EQUAL
	DCX	H	;AHA--THEY ARE EQUAL
	DCX	H
	MOV	A,M	;GET COUNTER
	INR	A
	MOV	M,A
	CPI	0FFH	;REACHED 255 CALLS?
	JNZ	PASS	;NO
	DCR	A	;YES--ONLY ALLOW 254
	MOV	M,A
	JMP	PASS
SER2:	INX	H	;GO TO NEXT TABLE LOCATION
SER3:	INX	H
	JMP	SER1	;AND CONTINUE SEARCH
SER4:	DCX	H	;TABLE VALUE WAS > SEARCH VALUE
SER5:	DCX	H	;SO INSERT SEARCH VALUE IN TABLE
;
; INSERT SEARCH VALUE CONTAINED IN DE INTO SYMBOL TABLE
;
INSRT:	SHLD	TINL	;SAVE PRESENT POSITION IN SYMBOL TABLE
INSR1:	XRA	A
	ORA	M	;END OF TABLE YET?
	JZ	INSR2	;YES
	CPI	0FFH	;MAX END YET?
	JZ	PASS	;YES
	INX	H
	INX	H
	INX	H
	JMP	INSR1	;GO TO NEXT SYMBOL TABLE LOCATION
INSR2:	PUSH	D	;IT IS OK TO INSERT
	INX	H
	INX	H
	XCHG
	LXI	H,3
	DAD	D	;BOTH POINTERS READY
INSR3:	LDAX	D	;GET CHARACTER
	MOV	M,A	;PUT IT IN LOCATION+3 LOCATION
	DCX	H
	DCX	D
	LDA	TINL+1	;HAVE WE REACHED STARTING
	CMP	D	;PLACE IN TABLE?
	JNZ	INSR3	;NO
	LDA	TINL
	CMP	E
	JNZ	INSR3
	LDAX	D
	MOV	M,A
	XCHG
	MVI	M,1	;INITIAL COUNT = 1
	INX	H
	POP	D
	MOV	M,D	;STORE MS ADDRESS VALUE
	INX	H
	MOV	M,E	;STORE LS
	JMP	PASS	;BACK TO NEXT CODE SEARCH
;
; THIS IS BEGINNING OF SECOND PASS
;  WE NOW PRINT OUT THE ASSEMBLY LANGUAGE EQUIVALENT
;  OF THE OPCODES FOUND AND THEIR ARGUMENTS.
;  ALL 3-BYTE CODES FOUND MAKE A SEARCH OF THE
;  SYMBOL TABLE AND COMPARE.  IF THE VALUE IS FOUND
;  IN THE TABLE THEN IT IS REPLACED BY A MANUFACTURED
;  LABEL WHICH RELATES TO ITS POSITION IN THE TABLE.
;
PASSE:	LHLD	START
	SHLD	HERE
AGAIN:	LHLD	HERE
	LDA	FINSH+1
	CMP	H	;EQUAL?
	JZ	AGN1	;YES
	JC	FOUR	;WHOOPS GREATER THAN
	JMP	AGN2
AGN1:	LDA	FINSH
	CMP	L	;GREATER THAN?
	JC	FOUR	;YES
AGN2:	MVI	B,4	;INDENT
	CALL	SPACE	;LISTING FOR 3 HOLE PUNCH
	XCHG
	LHLD	OFSET
	DAD	D	;ADD OFFSET
	CALL	DADR	;PRINT ADDRESS IN HL
	MVI	B,2
	CALL	SPACE
	XCHG
	CALL	FIND	;SEARCH SYMBOL TABLE
	LHLD	HERE
	MOV	A,M	;GET OPCODE BYTE
	PUSH	PSW	;SAVE A COPY
	INX	H
	SHLD	HERE	;SAVE NEXT BYTE ADDRESS
	LXI	H,TABL1	;FORM TABL1 POINTER
	ADD	L
	MOV	L,A
	MVI	A,0
	ADC	H
	MOV	H,A
	MOV	A,M	;GET NUMBER OF BYTES PER OPCODE
	DCR	A
	JZ	ONE	;THAT IS A ONE-BYTE OPCODE
	CPI	1
	JZ	TWO	;THAT IS A TWO-BYTE OPCODE
;
THREE:	POP	PSW	;THIS IS A THREE-BYTE OPCODE
	MOV	E,A	;SAVE OPCODE IN "E"
	CALL	DBYTE	;PRINT IT
	LHLD	HERE
	MOV	A,M	;GET 1ST DATA/ADDRESS BYTE
	PUSH	PSW	;SAVE TO STACK
	CALL	DBYTE	;PRINT IT
	INX	H
	MOV	A,M	;GET 2ND DATA/ADDRESS BYTE
	PUSH	PSW
	CALL	DBYTE
	INX	H
	SHLD	HERE	;SAVE NEXT OPCODE ADDRESS
	MVI	B,2
	CALL	SPACE
	CALL	LABEL	;PRINT LABEL IF APPROPRIATE
	CALL	PRINT
	POP	PSW
	MOV	D,A	;GET MS
	POP	PSW
	MOV	E,A	;GET LS
	CALL	FIND	;IS IT IN SYMBOL TABLE?
	JNC	THRE1	;NO--JUST PRINT THE NUMBER
	CALL	PLAB	;YES--PRINT A LABEL
	JMP	THRE2
THRE1:	XCHG
	CALL	FADR
THRE2:	CALL	FCRLF
	JMP	AGAIN
;
; PRINT THE SYMBOL TABLE WITH NUMBER OF CALLS PER LABEL
;  FORMAT: SMxxx  YY  ADDR
;   WHERE xxx=LABEL NUMBER & YY=NUMBER OF CALLS
;
FOUR:	MVI	B,4
FOUR1:	MVI	A,0AH	;PRINT 4 LINE FEEDS
	CALL	LO
	DCR	B
	JNZ	FOUR1
	LHLD	TABL3
	LXI	D,0
FOUR2:	MVI	A,4
	STA	COUNT
FOUR3:	XRA	A	;GET COUNTER VALUE
	ORA	M	;END OF TABLE ENTRIES?
	JZ	FLOPY	;YES
	CPI	0FFH	;END OF TABLE?
	JZ	FLOPY	;YES
	MOV	A,D	;GET POSITION COUNTER
	STA	LABV+1	;INITIALIZE FOR PRINTING LABEL
	MOV	A,E
	STA	LABV
	CALL	XLAB
	MVI	B,1
	CALL	SPACE
	MOV	A,M	;GET NUMBER OF CALLS COUNTER
	CALL	DBYTE	;PRINT IT
	MVI	B,1
	CALL	SPACE
	INX	H
	MOV	A,M	;GET MS ADDRESS VALUE
	CALL	DBYTE	;PRINT IT
	INX	H
	MOV	A,M	;GET LS ADDRESS VALUE
	CALL	DBYTE	;PRINT IT
	INX	H
	MVI	B,4
	CALL	SPACE
	INX	D	;NO--ADVANCE TABLE POSITION
	LDA	COUNT
	DCR	A
	STA	COUNT
	JNZ	FOUR3	;PRINT 4 GROUPS PER LINE
	CALL	LCRLF	;END OF A LINE
	JMP	FOUR2
;
FLOPY:	MVI	B,8
FLOP1:	CALL	LCRLF
	DCR	B
	JNZ	FLOP1
	MVI	A,FF	;FORM FEED
	CALL	LO
	MVI	A,FF
	CALL	LO
	JMP	UPDAT
;
; ONE BYTE OPCODE PROGRAM PATH
;
ONE:	POP	PSW	;GET OPCODE
	MOV	E,A	;SAVE
	CALL	DBYTE	;PRINT IT
	MVI	B,6
	CALL	SPACE	;PRINT SPACES
	CALL	LABEL
	CALL	PRINT	;PRINT OPCODE MNEMONIC
	JMP	THRE2
;
; TWO BYTE OPCODE PROGRAM PATH
;
TWO:	POP	PSW	;GET OPCODE
	MOV	E,A	;SAVE
	CALL	DBYTE	;PRINT
	LHLD	HERE
	MOV	A,M	;GET DATA BYTE
	PUSH	PSW	;SAVE
	INX	H
	SHLD	HERE	;SAVE NEXT OPCODE ADDRESS
	CALL	DBYTE	;PRINT DATA BYTE
	MVI	B,4
	CALL	SPACE
	CALL	LABEL
	CALL	PRINT
	POP	PSW
	CALL	FBYTE	;GET AND PRINT DATA BYTE
	JMP	THRE2
;
; PRINT A MESSAGE
;  ENTER WITH HL POINTING AT FIRST
;  ASCII DIGIT--WILL PRINT UNTIL A
;  "EOT" (04H) CHARACTER IS FOUND.
;
MESAG:	MOV	A,M	;GET THE CHARACTER
	CPI	4H	;IS IT EOT?
	RZ		;ALL FINISHED
	CALL	CO
	INX	H	;ADVANCE POINTER
	JMP	MESAG
;
FESAG:	MOV	A,M
	CPI	4H
	RZ
	CALL	LO
	CALL	WRTV
	INX	H
	JMP	FESAG
;
; ENTER START, FINISH AND OFFSET
;  PRINTS CR-LF & MESSAGE:
;  "START ADDRESS, FINISH ADDRESS, OFFSET= "
;  ENTRY OF UP TO 4 HEX DIGITS PER VALUE IS
;  EXPECTED.  OFFSET IS SAME VALUE USED IF
;  LOADING A PROGRAM FROM PAPER TAPE OR
;  FLOPPY WITH OFFSET.
;
STFIN:	CALL	CRLF
	LXI	H,MSGST
	CALL	MESAG	;PRINT MESSAGE TO CONSOLE
	MVI	C,3
	CALL	EXPR	;GET 3 PARAMETERS
	POP	H	;GET OFFSET
	XRA	A
	SUB	L	;DO A 2'S COMPLEMENT
	MOV	L,A
	MVI	A,0
	SBB	H
	MOV	H,A
	SHLD	OFSET	;SAVE IT
	POP	H
	SHLD	FINSH
	POP	H
	SHLD	START
	CALL	CRLF
	RET
;
; PRINT NUMBER OF SPACES SPECIFIED IN "B"
;  TO THE LIST DEVICE
;
SPACE:	MVI	A,' '
	CALL	LO	;TO LIST DEVICE
	DCR	B
	JNZ	SPACE
	RET
;
FPACE:	MVI	A,' '
	CALL	LO
	DCR	B
	JNZ	FPACE
	MVI	A,9H	;TAB CHARACTER TO FLOPPY
	CALL	WRTV
	RET
;
; PRINT OPCODE MNEMONIC MESSAGE
;  ENTER WITH OPCODE BYTE IN "E"
;
PRINT:	MVI	D,0
	LXI	H,TABL2
	XCHG
	DAD	H	;DOUBLE OPCODE VALUE
	DAD	D	;NOW ADD TO TABL2 ADDRESS
	MOV	A,M	;GET LS BYTE FROM TABLE2
	INX	H
	MOV	H,M	;GET MS BYTE FROM TABLE
	MOV	L,A
	CALL	FESAG	;NOW PRINT APPROPRIATE MESSAGE
	RET
;
; SEARCH SYMBOL TABLE FOR AN EQUAL COMPARISON
;  WITH THE VALUE IN DE.
; EXIT WITH:  IF FOUND AN EQUAL
;		CY=1,TABLE POSITION IN "LABV"
;	IF NOT FOUND----CY=0
; A,B,H,L,FLAGS USED
;
FIND:	LHLD	TABL3
	LXI	B,0
FIND1:	XRA	A
	ORA	M	;GET TABLE COUNTER VALUE
	JZ	FIND2	;WHOOPS-FOUND END OF ENTRIES
	CPI	0FFH	;AT END OF TABLE?
	JZ	FIND2	;YES-ALL FINISHED
	INX	H
	MOV	A,D	;GET MS TABLE VALUE
	CMP	M
	JC	FIND2	;D > TABLE VALUE
	JNZ	FIND3	;D < TABLE VALUE
	INX	H
	MOV	A,E	;GET LS
	CMP	M
	JC	FIND2	;E > TABLE VALUE
	JNZ	FIND4	;E < TABLE VALUE
	MOV	A,B
	STA	LABV+1	;FOUND EQUAL SO SAVE POSITION COUNT
	MOV	A,C
	STA	LABV
	MVI	A,0FFH
	STA	PSTAT	;SET FOUND STATUS
	STC
	RET
FIND2:	XRA	A
	STA	PSTAT	;NOT FOUND EXIT
	RET
FIND3:	INX	H
FIND4:	INX	H	;ADJUST POINTER
	INX	B	;KEEP TRACK OF TABLE POSITION
	JMP	FIND1
;
; PRINT A LABEL WHOSE VALUE IS FOUND IN "LABV"
;
XLAB:	MVI	A,'S'
	CALL	LO
	MVI	A,'M'
	CALL	LO
	LDA	LABV+1
	CALL	CONV
	CALL	LO
	LDA	LABV
	CALL	DBYTE
	RET
;
;
PLAB:	MVI	A,'S'
	CALL	LO
	CALL	WRTV
	MVI	A,'M'
	CALL	LO
	CALL	WRTV
	LDA	LABV+1
	CALL	CONV
	CALL	LO
	CALL	WRTV
	LDA	LABV
	RRC
	RRC
	RRC
	RRC
	CALL	CONV
	CALL	LO
	CALL	WRTV
	LDA	LABV
	CALL	CONV
	CALL	LO
	CALL	WRTV
	RET
;
; PRINT LABEL PRECEEDING CODE IF PRINT STAT IS ON.
;  OTHERWISE PRINT SPACES.
;
LABEL:	LDA	PSTAT
	ORA	A
	JZ	LAB1
	CALL	PLAB
	MVI	A,':'
	CALL	LO
	CALL	WRTV
	MVI	B,2
	CALL	FPACE
	RET
LAB1:	MVI	B,8
	CALL	FPACE
	RET
;
; PRINT A CR-LF AND SEND TO PUNCH
;
FCRLF:	MVI	A,CR
	CALL	LO
	CALL	WRTV
	MVI	A,LF
	CALL	LO
	CALL	WRTV
	RET
;
CRLF:	MVI	A,CR
	CALL	CO
	MVI	A,LF
	CALL	CO
	RET
;
; PRINT HEX VALUE IN "A" AND SEND TO PUNCH
;  INSERT A LEADING 0 AND APPEND AN "H"
;
FBYTE:	PUSH	PSW
	PUSH	PSW
	MVI	A,'0'
	CALL	LO
	CALL	WRTV
	POP	PSW
	RRC
	RRC
	RRC
	RRC
	CALL	CONV
	CALL	LO
	CALL	WRTV
	POP	PSW
	CALL	CONV
	CALL	LO
	CALL	WRTV
	MVI	A,'H'
	CALL	LO
	CALL	WRTV
	RET
;
; PRINT AN ADDRESS IN HL AND SEND TO PUNCH
;  INSERT A LEADING 0 AND APPEND AN "H"
;
FADR:	MVI	A,'0'
	CALL	LO
	CALL	WRTV
	MOV	A,H
	RRC
	RRC
	RRC
	RRC
	CALL	CONV
	CALL	LO
	CALL	WRTV
	MOV	A,H
	CALL	CONV
	CALL	LO
	CALL	WRTV
	MOV	A,L
	RRC
	RRC
	RRC
	RRC
	CALL	CONV
	CALL	LO
	CALL	WRTV
	MOV	A,L
	CALL	CONV
	CALL	LO
	CALL	WRTV
	MVI	A,'H'
	CALL	LO
	CALL	WRTV
	RET
;
;
GOMON:	CALL	LCRLF
	JMP	MNTR
;
;
TI:	PUSH	B
	CALL	CI
	CALL	UC
	POP	B
	RET
;
;
UC:	CPI	'A'+20H
	RM
	CPI	'Z'+21H
	RP
	ANI	0DFH	;FORCE UPPER CASE
	RET
;
;
LCRLF:	MVI	A,CR
	CALL	LO
	MVI	A,LF
	CALL	LO
	RET
;
;
DADR:	MOV	A,H
	CALL	DBYTE
	MOV	A,L
	CALL	DBYTE
	RET
;
;
DBYTE:	PUSH	PSW
	RRC
	RRC
	RRC
	RRC
	CALL	CONV
	CALL	LO
	POP	PSW
	CALL	CONV
	CALL	LO
	RET
;
;
CONV:	ANI	0FH
	ADI	90H
	DAA
	ACI	40H
	DAA
	RET
;
;
NIBBL:	SUI	'0'
	RC
	ADI	0E9H
	RC
	ADI	6
	JP	NIBB1
	ADI	7
	RC
NIBB1:	ADI	10
	ORA	A
	RET
;
;
HILO:	INX	H
	MOV	A,H
	ORA	L
	STC
	RZ
	MOV	A,E
	SUB	L
	MOV	A,D
	SBB	H	;RETURN WITH CY=1 IF HL > DE
	RET
;
;
EXPR:	CALL	PARAM
	XTHL
	PUSH	H
	DCR	C
	JNC	EXPR1
	JNZ	GOMON
	RET
EXPR1:	JNZ	EXPR
	JMP	GOMON
PARAM:	CALL	PCHK
	JZ	GOMON
	LXI	H,0
PAR1:	MOV	B,A
	CALL	NIBBL
	JC	PAR2
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	ORA	L
	MOV	L,A
	CALL	TI
	JMP	PAR1
PAR2:	MOV	A,B
	CALL	PCHK1
	JNZ	GOMON
	RET
PCHK:	CALL	TI
PCHK1:	CPI	' '
	RZ
	CPI	','
	RZ
	CPI	CR
	STC
	RZ
	CMC
	RET
;
;
; PRINT MEMORY AND LOOK FOR ASCII CHARACTERS
;
PASCI:	LHLD	STACK
	SPHL
	CALL	STFIN
	CALL	LCRLF
	LHLD	FINSH
	XCHG
	LHLD	START
PASC1:	MVI	B,64
	CALL	DADR
	MVI	A,' '
	CALL	LO
PASC2:	MOV	A,M
	CPI	20H
	JC	PASC4
	CPI	5FH
	JNC	PASC4
	MOV	A,M
PASC3:	CALL	LO
	CALL	HILO
	JC	PASC5
	DCR	B
	JNZ	PASC2
	CALL	LCRLF
	JMP	PASC1
PASC4:	MVI	A,'.'
	JMP	PASC3
PASC5:	MVI	B,8
PASC6:	CALL	LCRLF
	DCR	B
	JNZ	PASC6
	JMP	BEG2
;
;
;
MSG1:	DB	'PUNCH THE SOURCE ? ( Y OR ANY CHARACTER ) ',4
MSG2:	DB	'PRINT ASCII DUMP ? ( Y OR ANY CHARACTER ) ',4
MSGST:	DB	'START ADDRESS , FINISH ADDRESS , OFFSET = ',4
;
;
LF	EQU	10	;LINE FEED
FF	EQU	12	;FORM FEED
BS	EQU	26	;LEFT CURSOR (BACKSPACE)
ESC	EQU	27	;ESCAPE
RATE	EQU	0A0H	;PRINTER BAUD RATE 0A0H = 4800 BAUD
;
	END