;
;THIS IS THE INTERPRETIVE DEBUGGING SIMULATOR
;IT'S BASIC OPERATION IS TO SIMULATE ALL OF THE 8080
;REGISTERS IN MEMORY, & THEN MOVE THE INST. TO BE
;SIMULATED INTO A 3 BYTE AREA IN RAM AND EXECUTE IT
;FOLLOWED BY A JUMP INST WHICH RETURNS CONTROL TO THE
;ROUTINE.  A SIMULATOR SIMILAR TO THIS WAS DESCRIBED IN
;DETAIL IN SEPT. 77 KILOBAUD PG. 64.  HOWEVER ALTHOUGH
;THE PRINCIPLE IS THE SAME, THE CODE IS QUITE DIFFERENT.
;THE SIMULATOR ENTRY POINT IS AT F75C.
;
;COME HERE TO "SIMULATE" A SINGLE INSTRUCTION
;
LF400:	LXI	H,0		;GET TWO ZEROS
	SHLD	LD14C+1		;CLEAR 2ND & 3RD INST BYTES
	LHLD	LD13C		;GET PGM COUNTER
	MOV	A,M		;GET NEXT INST TO SIMULATE
	STA	LD14C		;SAVE IT IN INST REG
	MOV	B,A		;AND IN B
	CPI	40H		;TRYING TO DETERMINE TYPE INST
	JC	LF422		;FOR FURTHER TESTING
	CPI	0C0H		;MORE TESTING
	JNC	LF475		;INST >= C0 HEX
	JMP	LF459		;1 BYTE ACCUM INST
;
;RETURN HERE TO PROCESS 1 BYTE ACCUM. INST
;
LF41B:	INX	H		;INR PGM COUNTER
	SHLD	LD13E		;SAVE ADDR OF NEXT INST
	JMP	LF634		;PROCESS THE INST
;
;GET HERE FOR INST WITH OPCODES LESS THAN 40H
;
LF422:	ANI	7		;MASK LOW 3 BITS
	JZ	LF41B		;NOP IS ONLY LEGAL 8080 INST
	CPI	3		;MASK LOW ORDER TWO BITS
	JC	LF439		;01,02,09,0A,..,31,32,39,3A ETC
	CPI	6		;CHECK FOR MVI
	JNZ	LF41B		;JMP IF NOT MVI
;
;COME HERE FOR ACCUMULATOR IMMEDIATE INST (MVI, ADI, CPI, ETC)
;
LF431:	INX	H		;POINT TO 2ND BYTE
	MOV	A,M		;GET IT
	STA	LD14C+1		;SAVE AS 2ND BYTE TO SIMULATE
	JMP	LF41B		;SIMULATE INST. EXECUTION
;
;COME HERE FOR LXI, STAX, DAD, LDAX, SHLD, LHLD, STA, LDA
;
LF439:	CPI	2		;STAX/LDAX,SHLD/LHLD,STA/LDA
	MOV	A,B		;RESTORE THE FULL OPCODE
	JZ	LF451		;FOR LIST 2 INST PREV.
	ANI	8		;CHECK FOR DAD
	JNZ	LF41B		;PROCESS DAD INST
LF444:	INX	H		;POINT TO 2ND BYTE
	MOV	A,M		;GET IT
	STA	LD14C+1		;PUT IT IN SIM'S INST REG
	INX	H		;POINT TO 3RD BYTE
	MOV	A,M		;GET IT
	STA	LD14C+2		;PUT IT IN AS 3RD BYTE
	JMP	LF41B		;SIMULATE EXECUTION OF THE INST
;
;COME HERE FOR STAX, LDAX, SHLD, LHLD, STA, LDA
;
LF451:	CPI	20H		;DIVIDE GROUP IN 2 PARTS
	JNC	LF444		;FOR SHLD/LHLD, STA/LDA
	JMP	LF41B		;FOR LDAX/STAX
;
;GET HERE FOR 1 BYTE ACCUM. INST > 40H AND < C0H
;MOV,CMP,ANA,ADD,ADC,SUB,SBB,XRA,ORA AND HLT
;
LF459:	CPI	76H		;HALT INST ?
	JZ	LF461		;YES - PROCESS IT
	JMP	LF41B		;NO - PROCESS OTHERS
;
;PROCESS HALT INST
;
LF461:	CALL	CRLF		;DO CR/LF
	CALL	LF6B8		;PRINT OUT SIMULATORS P.C.
	LXI	H,LF470		;POINT TO HALT MESSAGE
	CALL	SCRN		;PRINT "HALT"
	JMP	LF774		;AND THEN RESTART SIMULATOR
LF470:	DB	'HALT',0DH
;
;COME HERE FOR INST WITH OPCODES >= C0 HEX
;
LF475:	ANI	7		;MASK LOW 3 BITS
	JZ	LF49F		;CONDITIONAL RETURN
	CPI	2		;CONDITIONAL JUMP ?
	JZ	LF4CA		;YES - PROCESS CNDX JMP
	JC	LF4B0		;POP, RET, PCHL, SPHL
	CPI	4		;CONDITIONAL CALL ?
	JZ	LF505		;YES - PROCESS IT
	JC	LF4EF		;NO-JMP,IN,OUT,EI,DI,XTHL,XCHG
	CPI	6		;ACCUM. IMMEDIATE ?
	JZ	LF431		;YES - PROCESS
	JC	LF542		;PUSH, CALL & ILLEGAL
;
;GET HERE TO PROCESS RST INSTRUCTIONS
;
	XRA	A		;GET A ZERO
	STA	LD13E+1		;CLEAR HIGH ORDER CALLED ADDR
	MOV	A,B		;RESTORE OPCODE TO A
	ANI	38H		;MASK RST TYPE
	STA	LD13E		;STORE AS LOW ORDER BYTE
	JMP	LF511		;PROCESS AS NORMAL CALL
;
;COME HERE FOR CONDITIONAL RETURN
;
LF49F:	CALL	LF551		;OPERATE ON OPCODE & FLAG REG
	JNZ	LF4DA		;CNDX NOT MET,CLEAN UP, GO HOME
;
;COME HERE TO PROCESS RETURN
;
LF4A5:	XCHG			;SAVE PGM CTR IN D,E
	LHLD	LD140		;GET STACK POINTER H,L
	CALL	LF57F		;POP STK & SAVE AS NEXT ADDR
	INX	H		;INR STACK POINTER FOR 2ND BYTE
	JMP	LF521		;RESET STK PTR & GO TO NXT INST
;
;COME HERE FOR POP, RET, PCHL, SPHL
;
LF4B0:	MOV	A,B		;RESTORE INST TO A
	ANI	8		;POP INST ?
	JZ	LF41B		;YES - PROCESS IT
	MOV	A,B		;NO - RESTORE INST AGAIN
	CPI	0D9H		;ILLEGAL OPCODE ?
	JZ	LF589		;YES - PROCESS ILLEGAL OPCODE
	JC	LF4A5		;NO - RETURN INST IF CARRY
	CPI	0E9H		;NOT RET - PCHL ?
	JNZ	LF41B		;NO - MUST BE SPHL
	LHLD	LD144		;PCHL - GET H,L
	JMP	LF4DB		;MAKE ADDR OF NEXT INST & RET
;
;COME HERE FOR CONDITIONAL JUMP
;
LF4CA:	CALL	LF551		;EVALUATE CONDITION
;
;GET HERE FOR STD JUMP
;
LF4CD:	CALL	LF4E1		;FILL IN 2ND & 3RD BYTES
	JNZ	LF4D9		;JMP IF CNDX NOT MET
	CALL	LF57F		;UPDATE ADDR OF NXT INST
	JMP	LF66A		;DONE W/SIMULATED JUMP
LF4D9:	INX	H		;POINT TO 3RD BYTE
LF4DA:	INX	H		;POINT TO NEXT INST
LF4DB:	SHLD	LD13E		;SAVE H,L AS ADDR OF NXT INST
	JMP	LF66A		;DONE WITH THIS INST
;
;UPDATE 2ND & 3RD BYTES OF INST AT D14C
;DONE EVEN IF INST IS NOT REALLY EXECUTED SO DISPLAY
;OF INST WILL BE CORRECT.
;NOTE REVERSAL OF "BACKWARD" 8080 ADDRESSES
;
LF4E1:	PUSH	PSW		;SAVE PSW
	INX	H		;POINT TO INST 2ND BYTE
	MOV	A,M		;GET IT
	STA	LD14C+2		;SAVE AS SIM 2ND (3RD?) BYTE
	INX	H		;POINT TO INST 3RD BYTE
	MOV	A,M		;GET IT
	STA	LD14C+1		;SAVE AS SIM 3RD (2ND?) BYTE
	DCX	H		;POINT BACK AT 2ND INST BYTE
	POP	PSW		;RESTORE PSW
	RET			;DONE
;
;GET HERE FOR JMP, OUT, IN, XTHL, XCHG, EI, DI INSTRUCTIONS
;
LF4EF:	MOV	A,B		;GET WHOLE INST
	ANI	38H		;MASK
	JZ	LF4CD		;JUMP INST
	CPI	10H		;
	JZ	LF5F2		;OUT INST
	JC	LF589		;ILLEGAL OPCODE
	CPI	18H		;MASK AGAIN
	JZ	LF58F		;INPUT INST
	JMP	LF41B		;EI, DI, XTHL, XCHG
;
;COME HERE FOR CONDITIONAL CALL INST
;
LF505:	CALL	LF551		;EVALUATE CONDITION
	JNZ	LF4CD		;JUMP IF NOT MET
;
;GET HERE FOR CALL INST
;
LF50B:	CALL	LF4E1		;UPDATE DISPLAY INST
	CALL	LF57F		;CALLED ADDR ==> NXT INST
LF511:	INX	H		;POINT TO INST AFTR CALL
	XCHG			;SAVE RET ADDR IN D,E
	LDA	LD135		;GET REAL-TIME RUN FLAG
	ORA	A		;SET FLAGS
	JNZ	LF527		;JUMP IF SIMULATING
LF51A:	LHLD	LD140		;GET STACK POINTER
	DCX	H		;POINT TO NEXT ENTRY 1ST BYTE
	MOV	M,D		;PUT HIGH ORDER RET ADDR IN
	DCX	H		;NOW DO LOW ORDER BYTE
	MOV	M,E		;RET ADDR ON STACK
LF521:	SHLD	LD140		;UPDATE STACK POINTER
	JMP	LF66A		;SIMULATED CALL DONE
LF527:	LHLD	LD13E		;GET CALLED ADDR
	LDA	LD13A		;GET LOW ORDER R.T. RUN ADDR
	CMP	L		;SAME ?
	JNZ	LF51A		;NO - SIMULATE CALL
	LDA	LD13A+1		;GET HIGH ORDER R.T. RUN ADDR
	CMP	H		;SAME ?
	JNZ	LF51A		;NO - SIMULATE CALL
	SHLD	LD14C+1		;SAME - PUT CALL ADDR IN
	XCHG			;RET ADDR TO H,L
	SHLD	LD13E		;NEXT SIM. ADDR TO EXEC
	JMP	LF634		;EXECUTE CALL FOR REAL
;
;GET HERE FOR PUSH, CALL & ILLEGAL OPCODES
;
LF542:	MOV	A,B		;RESTORE INSTRUCTION
	ANI	8		;MASK
	JZ	LF41B		;PUSH, POP
	MOV	A,B		;RESTORE OPCODE AGAIN
	CPI	0CDH		;CALL ?
	JZ	LF50B		;YES - PROCESS IT
	JMP	LF589		;ILLEGAL OPCODE
;
;GET HERE TO EVALUATE CONDITION FOR CONDITIONAL JMP, CALL, RET
;
LF551:	MOV	A,B		;RESTORE OP CODE
	ANI	8		;MASK CNDX TRUE/FALSE BIT
	MOV	C,A		;SAVE TRUE/FALSE STATUS
	JZ	LF55A		;JUMP IF NZ,NC,PO,P
	MVI	C,0C5H		;PSW COND FLAG MASK
LF55A:	MOV	A,B		;RESTORE OPCODE AGAIN
	ANI	30H		;ZERO FLAG CONDITIONAL ?
	JNZ	LF565		;NO - TEST OTHERS
	MVI	D,40H		;PSW ZERO FLAG MASK
	JMP	LF579		;EVALUATE THE CONDITION
LF565:	CPI	20H		;PARITY/SIGN FLAG CONDITION ?
	JZ	LF572		;YES - PARITY FLAG CNDX
	JNC	LF577		;YES - SIGN FLAG CNDX
	MVI	D,1		;CARRY FLAG MASK
	JMP	LF579		;EVALUATE CONDITION
LF572:	MVI	D,4		;PARITY FLAG BIT MASK
	JMP	LF579		;EVALUATE THE CONDITION
LF577:	MVI	D,80H		;SIGN FLAG BIT MASK
LF579:	LDA	LD142		;GET SIMULATOR'S FLAG REGISTER
	XRA	C		;SET CNDX & T/F INTO ACC
	ANA	D		;MASK OUT PROPER FLAG BIT
	RET			;AND GO BACK W/ZERO FLAG SET
;
;SAVE ADDR POINTED TO BY H,L AS NEXT INST TO EXECUTE
;
LF57F:	MOV	A,M		;GET 1ST BYTE
	STA	LD13E		;SAVE IT AS NEXT INST LOW BYTE
	INX	H		;POINT TO 2ND BYTE
	MOV	A,M		;GET IT
	STA	LD13E+1		;SAVE AS HIGH BYTE
	RET			;DONE
;
;ROUTINE TO PROCESS ILLEGAL OPCODES
;
LF589:	CALL	LF6CA		;DISPLAY INST & ALL REGS
	CALL	LF949		;PRINT ?, RESTART (NEVER RET)
;
;ROUTINE TO PROCESS INPUT INST
;
LF58F:	INX	H		;POINT TO PORT
	MOV	A,M		;GET IT
	INX	H		;POINT TO NEXT INST
	SHLD	LD13E		;AND MAKE IT NEXT TO EXEC
	STA	LD14C+1		;PUT PORT INTO SIM'S INST REG
	CALL	LF8A1		;SEARCH INPUT PORT TABLE
	JNZ	LF5AE		;JUMP IF PORT NOT IN TABLE
	MOV	A,M		;GET PORT I/O TYPE
	ORA	A		;SET FLAGS
	JZ	LF5AE		;IF PORT SIMULATED
	JM	LF634		;TO REALLY EXEC I/O INST
	INX	H		;ELSE PRESET, POINT TO VALUE
	MOV	A,M		;GET IT
	STA	LD14A		;TO SIM'S ACCUM (WHERE ELSE ?)
	JMP	LF66A		;TO DISPLAY & DO NEXT INST
;
;COME HERE TO EXECUTE SIMULATED INPUT INST
;
LF5AE:	LXI	D,LF5D2		;POINT TO INPUT MESSAGE
	CALL	LF5D9		;PRINT PGM CTR & MESSAGE
	CALL	READ		;GET USER'S ANSWER
	CALL	ZBUF		;CLEAR ABUF
	LXI	H,IBUF		;POINT TO INPUT BUFFER
	CALL	SBL1		;SCAN PAST SPACES
	CALL	NUMS		;CONVERT TO BINARY
	JC	LF949		;IF ERROR IN ANSWER
	MOV	A,H		;GET HIGH ORDER BYTE
	ORA	A		;SET FLAGS
	JNZ	LF5AE		;MAKE USER DO IT AGAIN IF > 255
	MOV	A,L		;GET LOW ORDER BYTE
	STA	LD14A		;STUFF IT INTO SIM'S ACCUM
	JMP	LF626		;DO CR/LF & FINSIH UP
;
LF5D2:	DB	'INPUT '
	DB	0DH
;
;ROUTINE TO PRINT INPUT OR OUTPUT MESSAGE FOR SIMULATED I/O
;
LF5D9:	CALL	CRLF		;DO CR/LF
	PUSH	D		;SAVE D,E
	CALL	LF6B8		;PRINT PGM COUNTER & SPACES
	POP	D		;RESTORE REGS
	XCHG			;MESSAGE ADDR TO H,L
	CALL	SCRN		;PRINT INPUT OR OUTPUT MSG
	LHLD	LD13C		;GET SIM'S PGM CTR
	INX	H		;INCR, POINTING TO PORT
	MOV	A,M		;GET PORT IN ACCUM
	CALL	DUMO		;PRINT PORT
	MVI	B,'='		;FOLLOWED BY EQUALS SIGN
	JMP	OUT8		;AND THEN RETURN
;
;ROUTINE TO PROCESS OUTPUT INSTRUCTION
;
LF5F2:	INX	H		;POINT TO PORT
	MOV	A,M		;GET IT
	INX	H		;POINT TO NEXT INST
	SHLD	LD13E		;SAVE AS ADDR OF NEXT INST
	STA	LD14C+1		;PUT PORT IN SIM'S INST REG
	CALL	LF897		;SEARCH OUTPUT TABLE
	MVI	A,1		;ASSUME SIMULATED
	JNZ	LF604		;IF PORT NOT IN TABLE
	MOV	A,M		;GET TYPE OUTPUT
LF604:	ORA	A		;SET FLAGS
	JM	LF634		;TO REALLY EXECUTE OUT INST
	PUSH	PSW		;SAVE ACCUM & FLAGS
	LXI	D,LF62C		;POINT TO OUTPUT MESSAGE
	CALL	LF5D9		;PRINT IT
	POP	PSW		;RESTORE FLAGS & ACCUM
	ORA	A		;SET FLAGS
	LDA	LD14A		;GET CONTENTS OF SIM'S ACCUM
	MOV	B,A		;MOVE TO B
	JZ	LF61E		;ASCII MODE (UNLESS CNTL CHAR)
LF618:	CALL	LF747		;PRINT ACC USING CUR MODE
	JMP	LF626		;DO CR/LF, PRINT REGS & DO NEXT
LF61E:	CPI	20H		;TEST FOR CONTROL CHAR
	JC	LF618		;PRT USING CUR MODE, NOT ASCII
	CALL	OUT8		;NOT CNTL CHAR, OK TO OUTPUT
LF626:	CALL	CRLF		;NOW DO CR/LF TO MAKE IT PRETTY
	JMP	LF66A		;THEN PRINT REGS & DO NEXT INST
;
LF62C:	DB	'OUTPUT '
	DB	0DH
;
;COME HERE TO EXECUTE AN INST.
;LOAD REAL 8080 REGS FROM SIMULATORS REGS, EXEC INST
;AND THEN UNLOAD 8080'S REGS TO SIMULATORS REGS
;
LF634:	LXI	SP,LD140	;POINT STACK AT SIMULATORS REGS
	MVI	A,0C3H		;JUMP INST
	STA	LD14F		;STORE JUST AFTER INST TO SIMUL
	LXI	H,LF652		;RETURN POINT AFTER INST EXECUT
	SHLD	LD14F+1		;STORE IT JUST AFTER JUMP INST
	POP	H		;LOAD 8080 H,L FROM SIM STK PTR
	POP	PSW		;LOAD 8080 PSW FROM SIMULATOR
	INX	SP		;SKIP L FOR NOW
	INX	SP		;SKIP H FOR NOW
	POP	D		;LOAD 8080 D,E FROM SIMULATOR
	POP	B		;LOAD 8080 B,C FROM SIMULATOR
	SPHL			;MOVE SIM STACK TO 8080 STACK
	LHLD	LD144		;LOAD 8080 H,L FROM SIM H,L
	LDA	LD14A		;GET SIMULATED ACCUM
	JMP	LD14C		;EXECUTE INST TO BE SIMULATED
;
;RETURN HERE AFTER EXECUTING THE "SIMULATED" INST
;
LF652:	STA	LD14A		;SAVE 8080 ACCUM INTO SIMULTR
	SHLD	LD144		;SAVE 8080 H,L INTO SIMULATOR
	RAL			;SAVE CARRY FLAG DURING DAD
	LXI	H,0		;SETTING UP ....
	DAD	SP		;TO GET THE STACK POINTER
	LXI	SP,LD14A	;POINT CPU STACK TO REG AREA
	PUSH	B		;SAVE 8080 B,C INTO SIMULATOR
	PUSH	D		;SAVE 8080 D,E INTO SIMULATOR
	DCX	SP		;SKIP H (ALREADY STORED)
	DCX	SP		;SKIP L (ALREADY STORED)
	RAR			;RESTORE CARRY FLAG
	PUSH	PSW		;SAVE 8080 PSW INTO SIMULATOR
	PUSH	H		;SAVE 8080 STK PNTR INTO SIM
	LXI	SP,LD12B	;RELOAD 8080'S STACK POINTER
LF66A:	IN	0FFH		;GET SENSE SWITCHES
	ANI	80H		;MASK HIGH ORDER BIT
	JNZ	LF697		;FORCE RETURN TO COMMAND MODE
	CALL	STAT		;SEE IF KEYBOARD CHAR WAITING
	JZ	LF67F		;NO - CONTINUE PROCESSING
	CALL	IN8		;YES - GET CHAR
	CPI	'X'-40H		;CONTROL-X ?
	JZ	LF697		;YES - FORCE RET TO COMND MODE
LF67F:	LDA	LD134		;GET BREAKPOINT FLAG
	ORA	A		;SET FLAGS
	JZ	LF69D		;JMP IF NO BKPT SET
	LHLD	LD138		;BKPT ADDR TO H,L
	LDA	LD13C+1		;HIGH BYTE OF SIM P.C.
	CMP	H		;COMPARE TO BKPT
	JNZ	LF6AF		;BKPT NOT REACHED
	LDA	LD13C		;GET LOW BYTE OF P.C.
	CMP	L		;COMPARE TO BKPT
	JNZ	LF6AF		;BKPT NOT REACHED
;
;COME HERE WHEN BREAKPOINT IS REACHED
;
LF697:	CALL	LF6CA		;PRINT REGS, P.C., ETC.
	JMP	LF774		;RESTART SIMULATOR
;
;GET HERE AFTER EA. INST IN SIMULATED CONT. RUN MODE
;
LF69D:	CALL	LF6CA		;PRINT REGS, PC, ETC
	IN	0FFH		;GET SENSE SWITCHES
	ANI	40H		;MASK CONTINUOUS RUN BIT
	CZ	IN8		;IF CONT RUN, CK KYBD PORT
	CPI	'X'-40H		;CONTROL-X WAITING ?
	JZ	LF774		;YES - RETURN TO SIM COMND MODE
;
;SIMULATOR "GO" COMMAND
;
LF6AC:	CALL	CRLF		;DO CR/LF
LF6AF:	LHLD	LD13E		;GET ADDR OF INST TO SIMULATE
	SHLD	LD13C		;AND SAVE IT AS SIM PGM COUNTER
	JMP	LF400		;SIMULATE THE INSTRUCTION
;
;ROUTINE TO PRINT OUT SIMULATORS P.C. AND TWO SPACES
;
LF6B8:	LDA	LD13C+1		;GET HIGH ORDER SIM P.C. BYTE
	MOV	D,A		;TO D
	LDA	LD13C		;NOW LOW ORDER BYTE
	MOV	E,A		;D,E HAVE P.C.
	CALL	ADOUT		;PRINT IT IN HEX
	CALL	LE35C		;PRINT SPACE
	CALL	LE35C		;PRINT SPACE
	RET			;DONE
;
;ROUTINE TO PRINT OUT SIMULATORS PC AND ALL FLAGS & REGS
;
LF6CA:	CALL	LF6B8		;PRINT PC & SPACES
	LDA	LD142		;GET FLAG REGISTER
	MOV	C,A		;SAVE IT IN C
	ANI	01H		;MASK CARRY BIT
	CALL	LF73C		;PRINT A 0 OR 1
	ANI	80H		;MASK SIGN BIT
	CALL	LF73C		;PRINT A 0 OR 1
	ANI	10H		;MASK AUX CARRY BIT
	CALL	LF73C		;PRINT A 0 OR 1
	ANI	04H		;MASK PARITY BIT
	CALL	LF73C		;PRINT A 0 OR 1
	ANI	40H		;MASK ZERO BIT
	CALL	LF73C		;PRINT A 0 OR 1
	CALL	LE35C		;PRINT A SPACE
	LXI	D,LD14A		;POINT TO ACCUM
	LDAX	D		;GET IT
	CALL	LF756		;PRINT IT USING CUR. MODE
	CALL	LE35C		;PRINT SPACE
	MVI	C,04H		;NO OF REGS TO OUTPUT
LF6F9:	DCX	D		;POINT TO NEXT REG
	LDAX	D		;GET IT
	CALL	LF756		;PRINT IT USING CUR MODE
	DCR	C		;NO OF REGS LEFT
	JNZ	LF6F9		;DO NEXT IF NOT DONE
	CALL	LE35C		;PRINT SPACE
	DCX	D		;POINT TO H
	LDAX	D		;GET IT
	CALL	LF756		;PRINT IT
	DCX	D		;POINT TO L
	LDAX	D		;GET IT
	CALL	LF756		;PRINT IT
	LHLD	LD144		;GET H,L
	MOV	A,M		;GET "M" CHAR
	CALL	LF756		;PRINT IT
	CALL	LE35C		;SPACE
	LDA	LD140+1		;STACK PTR HIGH BYTE
	MOV	D,A		;TO D
	LDA	LD140		;STACK PTR LOW BYTE
	MOV	E,A		;D,E HAS STK PTR ADDR
	CALL	ADOUT		;PRINT STACK POINTER
	LXI	D,LD14C		;POINT TO CURRENT INST
	CALL	LE35C		;PRINT SPACE
	CALL	LF733		;PRINT BYTE & SPACE
	CALL	LF733		;PRINT BYTE & SPACE
	JMP	LF733		;A BIT OF SLOPPY CODE
LF733:	CALL	LE35C		;PRINT A SPACE
	LDAX	D		;GET BYTE POINTED TO BY D,E
	INX	D		;POINT TO NEXT
	CALL	LF747		;PRINT THE BYTE
	RET			;DONE
;
;PRINT A 1 OR A ZERO (USED TO PRINT FLAG BYTES)
;
LF73C:	MVI	B,'1'		;ASSUME 1
	JNZ	LF742		;MUST BE IF IT'S NOT ZERO
	DCR	B		;NOT 1, MAKE IT 0
LF742:	CALL	OUT8		;PRINT IT, WHATEVER
	MOV	A,C		;RESTORE THE FLAG BYTE IN A
	RET			;DONE
;
;PRINT A BYTE USING CURRENT SIMULATOR MODE
;
LF747:	LXI	H,LD14B		;POINT TO SIMULATOR MODE
	MOV	B,M		;GET IT
	DCR	B		;SETTING FLAGS
	JP	LF753		;IF MODE WASN'T ZERO
	CALL	DUMO		;USE ALS-8 MODE
	RET			;DONE
LF753:	JMP	DOUT		;USE DECIMAL
;
;ROUTINE TO PRINT BYTE FOLLOWED BY SPACE
;
LF756:	CALL	LF747		;PRINT THE BYTE
	JMP	LE35C		;THEN DO SPACE & RETURN
;
;THIS IS THE SIMULATOR MAIN ENTRY POINT
;
SIMU:	LDA	IBUF+4		;GET CHAR AFTER 'SIMU'
	CPI	' '+1		;COMPARE TO BLANK
	JNC	LF774		;SKIP INIT. IF NOT BLANK
	XRA	A		;ELSE GET A ZERO
	STA	LD136		;CLEAR INPUT PORT ASSIGN FLAG
	STA	LD14B		;CLEAR SIMULATOR MODE
	STA	LD137		;CLEAR OUTPUT PORT ASSIGN FLAGS
	STA	LD135		;CLEAR REAL TIME RUN FLAG
LF771:	STA	LD134		;CLEAR BRKPT FLAG
;
;WARM RESTART ENTRY POINT
;
LF774:	LXI	SP,SMODE	;SET STACK
	CALL	CRLF		;DO CR/LF
	MVI	B,'*'		;PROMPT
	CALL	OUT8		;PRINT IT
	CALL	READ		;GET A COMND LINE IN IBUF
	LDA	IBUF		;GET 1ST CHAR
	CPI	'P'		;SET PGM COUNTER ?
	JNZ	LF796		;NO - TRY OTHER COMMANDS
	CALL	LF932		;GET OPERAND VALUE TO H,L
	SHLD	LD13E		;? - THIS IS NOT THE SIM P.C.
	SHLD	LD13C		;THE SIMULATORS PGM. COUNTER
	JMP	LF774		;GET NEXT COMMAND
LF796:	CPI	'B'		;SET BREAKPOINT ?
	JNZ	LF7A4		;NO - TRY ANOTHER COMMAND
	CALL	LF932		;GET ADDR TO H,L
	SHLD	LD138		;SET BREAKPOINT ADDR
	JMP	LF771		;SET BKPT FLAG & RESTART
LF7A4:	CPI	'R'		;SET REAL-TIME RUN ADDR ?
	JNZ	LF7B7		;NO - TRY ANOTHER COMMAND
	CALL	LF932		;GET ADDR TO H,L
	SHLD	LD13A		;SET REAL-TIME RUN ADDR
	MVI	A,1		;GET A ONE
	STA	LD135		;AND USE IT TO SET R.T. RUN FLG
	JMP	LF774		;RESTART & GET NEXT COMMAND
;
;TEST FOR AND PROCESS THE CLEAR COMMANDS
;
LF7B7:	CPI	'C'		;CLEAR COMMAND ?
	JNZ	LF7DE		;NO - TRY OTHER COMMANDS
	LDA	IBUF+1		;YES - GET NEXT CHAR
	LXI	H,LD134		;POINT TO BKPT FLAG
	CPI	'B'		;CLEAR BREAKPOINT ?
	JZ	LF7D9		;YES - DO IT
	INX	H		;NO, POINT TO R.T. RUN FLAG
	CPI	'R'		;CLEAR R.T. RUN ADDR ?
	JZ	LF7D9		;YES - DO IT
	INX	H		;NO, POINT TO INPT PT ASGN FLAG
	CPI	'I'		;CLEAR INPUT PORT ASSIGNMENTS ?
	JZ	LF7D9		;YES - DO IT
	INX	H		;NO, POINT TO OUTP PT ASGN FLAG
	CPI	'O'		;CLEAR OUTPUT PORT ASSGNMENTS ?
	JNZ	LF949		;NO - INVALID CLEAR COMMAND
LF7D9:	MVI	M,0		;CLEAR FLG H,L POINT TO
	JMP	LF774		;AND RESTART SIMULATOR
LF7DE:	CPI	'G'		;GO COMMAND ?
	JZ	LF6AC		;YES - DO IT
	CPI	'D'		;DUMP COMMAND ?
	JNZ	LF7F1		;NO - TRY NEXT COMMAND
	CALL	LF932		;GET ADDR IN H,L
	CALL	DUMP+3		;AND USE ALS-8 DUMP CODE
	JMP	LF774		;THEN RESTART THE SIMULATOR
LF7F1:	CPI	'E'		;ENTER COMMAND ?
	JNZ	LF802		;NO, TEST OTHER COMMANDS
	CALL	LF932		;GET ADDRESS TO H,L
	CALL	ENTS		;USE ALS-8 ENTER CODE
	JC	LF949		;IF ERROR
	JMP	LF774		;ELSE RESTART
LF802:	CPI	'X'		;EXIT SIMULATOR COMMAND ?
	JZ	EORMS		;YES - RET TO ALS-8
	CPI	'M'		;MODE COMMAND ?
	JNZ	LF81F		;NO - TEST OTHER COMMANDS
	CALL	LF932		;GET VALUE IN H,L
	MOV	A,L		;NOW TO A
	MVI	B,1		;ASSUME HEX
	CPI	16		;HEX ?
	JZ	LF818		;YES - SKIP NEXT STMNT
	DCR	B		;MAKE IT 0 ==> OCTAL
LF818:	MOV	A,B		;GET FLAG TO A
	STA	LD14B		;AND UPDATE MODE
	JMP	LF774		;THEN RESTART SIMULATOR
;
;PROCESS THE VARIOUS INPUT COMMANDS
;
LF81F:	CPI	'I'		;SET INPUT COMMAND ?
	JNZ	LF863		;NO - TRY OTHER COMMANDS
	CALL	LF932		;GET VALUE TO H,L
	MOV	A,H		;HIGH ORDER BYTE TO A
	ORA	A		;SET FLAGS
	JNZ	LF949		;ERROR IF > 256
	MOV	A,L		;PORT TO A
	CALL	LF8A1		;SEARCH INPUT PORT TABLE
	MOV	A,C		;GET NO OF PORTS IN TABLE
	CPI	16		;TABLE FULL ?
	JNC	LF949		;ERROR THEN
	STA	LD136		;ELSE UPDATE # OF TABLE ENTRIES
	MVI	M,0FFH		;AND MAKE PORT REAL-TIME
	LDA	IBUF+1		;GET CHAR AFTER 'I'
	CPI	'S'		;PRESET ?
	JNZ	LF854		;NO - TRY REAL-TIME & CLEAR
	XCHG			;SAVE TABLE POINTER IN D,E
	LHLD	BBUF+2		;GET VALUE OF PRESET
	MOV	A,H		;GET HIGH BYTE
	ORA	A		;SET FLAGS
	JNZ	LF949		;ERROR IF > 255
	XCHG			;TABLE POINTER BACK TO H,L
	MVI	M,1		;SAY PRESET
	INX	H		;MOVE 1 BEYOND INPUT TYPE
	MOV	M,E		;AND STORE PRESET VALUE
	JMP	LF774		;THEN RESTART SIMULATOR
LF854:	CPI	'R'		;REAL-TIME INPUT ?
	JZ	LF774		;RESTART SIMULATR - ALREADY SET
	MVI	M,0		;ELSE ASSUME SIMULATED
	CPI	'C'		;TEST FOR SIMULATED
	JZ	LF774		;OK IF IT REALLY IS
	JMP	LF949		;ELSE ERROR
;
;TEST FOR AND PROCESS THE OUTPUT COMMANDS
;
LF863:	CPI	'O'		;SET OUTPUT INST ?
	JNZ	LF8BC		;NO - TRY OTHER COMMANDS
	CALL	LF932		;ELSE GET PORT NO IN H,L
	MOV	A,H		;HIGH BYTE TO A
	ORA	A		;SET FLAGS
	JNZ	LF949		;ERROR IF > 255
	MOV	A,L		;PORT TO A
	CALL	LF897		;LOOK UP PORT IN TABLE
	MOV	A,C		;GET NO OF PORTS IN TABLE
	CPI	16		;TABLE FULL ?
	JNC	LF949		;ERROR THEN
	STA	LD137		;ELSE UPDATE # OF TABLE ENTRIES
	MVI	B,0FFH		;ASSUME REAL-TIME
	LDA	IBUF+1		;GET NEXT CHAR OF COMMAND
	CPI	'R'		;REAL-TIME ?
	JZ	LF890		;ENTER R.T. IN TABLE & RESTART
	INR	B		;NOT R.T., ASSUME ASCII
	CPI	'A'		;ASCII ?
	JZ	LF890		;YES - PUT IN TABLE
	INR	B		;NOT R.T. OR ASCII - SIMULATED?
	CPI	'C'		;CLEAR (SIMULATED) ?
LF890:	MOV	M,B		;SET OUTPUT MODE
	JZ	LF774		;MODE SET, RESTART
	JMP	LF949		;ERROR, SIMULATED ASSUMED
LF897:	LXI	H,LD162		;POINT TO OUTPUT TABLE
	MOV	B,A		;PORT NO TO B
	LDA	LD137		;NO OF TABLE ENTRIES
	JMP	LF8A8		;SEARCH TABLE
LF8A1:	LXI	H,LD152		;POINT TO INPUT TABLE
	MOV	B,A		;PORT NO TO B
	LDA	LD136		;NO OF TABLE ENTRIES
LF8A8:	MOV	C,A		;TABLE ENTRIES TO C
	ORA	A		;SET FLAGS
	MOV	A,B		;PORT NO BACK TO A
	MOV	B,C		;NO OF ENTRIES TO B
	JZ	LF8B8		;IF TABLE CURRENTLY EMPTY
LF8AF:	CMP	M		;POINTING AT CORRECT PORT ?
	INX	H		;POINT TO I/O TYPE FOR PORT
	RZ			;IF WE HAVE PORT
	INX	H		;POINT TO I/O BYTE VALUE
	INX	H		;AND TO NEXT PORT
	DCR	B		;DCR NO OF TABLE ENTRIES LEFT
	JNZ	LF8AF		;AND CHECK REMAINING ENTRIES
LF8B8:	MOV	M,A		;PUT PORT IN TABLE
	INX	H		;AND POINT TO I/O TYPE
	INR	C		;INR NO OF ENTRIES IN TABLE
	RET			;AND RETURN DONE
;
;PROCESS THE SET REGISTER/FLAG COMMANDS
;
LF8BC:	CPI	'S'		;SET REGISTERS ?
	JNZ	LF949		;THERE AREN'T ANY COMMANDS LEFT
	LXI	H,IBUF+1	;POINT TO NEXT BYTE
	SHLD	PNTR		;AND SAVE CHAR POINTER
LF8C7:	CALL	ZBUF		;CLEAR ABUF
	CALL	SBLK		;SCAN TO TEXT
	JC	LF774		;RESTART IF C/R FOUND
	XCHG			;LINE PTR TO D,E
	MVI	C,10		;NO OF REGISTERS IN TABLE
	LXI	H,LF954		;POINT TO TABLE
LF8D6:	CMP	M		;SAME ?
	JZ	LF8E2		;FOUND REGISTER TO SET
	INX	H		;ELSE POINT TO NEXT REGISTER
	DCR	C		;AND DCR COUNT
	JNZ	LF8D6		;THEN TEST IT FOR MATCH
	JMP	LF949		;NO MATCH IN TABLE, ERROR
LF8E2:	MOV	A,C		;GET DISPLACEMENT INTO TABLE
	STA	TEMP		;AND SAVE IT
	XCHG			;POINTER TO H,L
	INX	H		;POINT TO NEXT CHAR
	MOV	A,M		;GET IT
	CPI	'='		;EQUALS SIGN ?
	JNZ	LF949		;ERROR IF NOT
	INX	H		;POINT TO ARGUMENT
	MOV	A,M		;GET IT
	LXI	D,ABUF		;POINT TO ABUF
	CALL	LF912		;CONVERT ARGUMENT TO BINARY
	JC	LF949		;IF ERROR
	LDA	TEMP		;GET DISP. INTO TABLE BACK
	CPI	1		;SETTING STACK POINTER ?
	JZ	LF92C		;HANDLE THAT SEPARATELY
	MOV	C,A		;DISPLACEMENT TO C
	MOV	A,H		;GET HIGH ORDER BYTE OF VALUE
	ORA	A		;SET FLAGS
	JNZ	LF949		;ERROR IF > 255
	MOV	A,L		;GET VALUE TO A
	LXI	H,LD140		;REGISTER TABLE IN RAM
	MVI	B,0		;B,C HAS DISPLACEMENT INTO TBL
	DAD	B		;H,L HAS ABSOLUTE ADDR
	MOV	M,A		;UPDATE SIM/8080 REGISTER
	JMP	LF8C7		;DO NEXT REGISTER(S) IF ANY
;
;ROUTINE TO CONVERT KEYED IN VALUE TO 16 BIT VALUE IN H,L
;
LF912:	CALL	ALPS		;PUT ARGUMENT INTO ABUF
	DCX	D		;POINT TO LAST CHAR
	LDAX	D		;GET IT
	LXI	B,ABUF		;POINT TO ARGUMENT
	CPI	'D'		;DECIMAL ?
	JZ	NUM1		;YES
	CPI	'Q'		;OCTAL ?
	JZ	NUM3		;YES
	CPI	'H'		;HEX ?
	JNZ	EMODE		;NO, USE STD MODE
	JMP	NUM2		;ELSE HEX
LF92C:	SHLD	LD140		;UPDATE SIM/8080 STACK PNTR
	JMP	LF8C7		;AND DO NEXT REGISTER(S) IF ANY
;
;ROUTINE TO SET SIMULATED PROGRAM COUNTER
;
LF932:	CALL	ETRA		;GET VALUES FROM COMMAND LINE
	JC	LF949		;IF ERROR
	CALL	LE31E		;VALUES TO BIN IN BBUF & BBUF+2
	JC	LF949		;ON ERROR
	LDA	ABUF		;GET FIRST CHAR OF VALUE
	ORA	A		;AND SET FLAGS
	JZ	LF949		;ERROR IF NO VALUE GIVEN
	LHLD	BBUF		;GET VALUE
	RET			;AND RETURN WITH IT IN H,L
;
;ERROR HANDLER ROUTINE
;
LF949:	CALL	CRLF		;DO CR/LF
	MVI	B,'?'		;GET QUESTION MARK
	CALL	OUT8		;AND PRINT IT
	JMP	LF774		;THEN RESTART SIMULATOR
;
;TABLE OF REGISTER NAMES FOR THE SET COMMANDS
;VALUES ARE STORED IN A TABLE IN MEMORY AT D143, BUT
;IN REVERSE ORDER.  THERE IS ONE ENTRY HERE FOR EACH
;ENTRY IN THAT TABLE.  NOTE THAT THE ACCUM. APPEARS
;TWICE, ONCE BY ITSELF & ONCE WITH THE FLAGS (AS PSW)
;
LF954:	DB	'A'
	DB	'B'
	DB	'C'
	DB	'D'
	DB	'E'
	DB	'H'
	DB	'L'
	DB	'A'
	DB	'F'
	DB	'S'
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
;
;COME HERE TO EXECUTE AUTO-NUMBER INPUT MODE
;
;WHAT THIS CODE ACTUALLY DOES IS TO MODIFY THE INPUT ROUTINE
;TO COME INTO A PRE-PROCESSOR AT F99A INSTEAD OF THE NORMAL
;IN8 INPUT ROUTINE.  THAT ROUTINE ACTUALLY DOES THE LINE
;NUMBER PROCESSING.
;
AUTO:	LHLD	IN8+1		;GET ADDR OF CUR INPUT DRIVER
	SHLD	BBUF+1		;AND SAVE IN BBUF
	LDA	ABUF		;SEE IF OPT PARAMETER GIVEN
	ORA	A		;SET FLAGS
	JZ	LF983		;NOT GIVEN, START WITH 1
	LHLD	MAXL		;GET HALF OF CUR MAX LINE NO
	SHLD	ABUF		;SAVE IT
	LHLD	MAXL+2		;GET OTHER HALF
	JMP	LF989		;SKIP INITIALIZATION
LF983:	LXI	H,3030H		;TWO ZERO'S
	SHLD	ABUF		;SAVE AS TWO HIGH DIGITS
LF989:	SHLD	ABUF+2		;AND SAVE H,L AS LOW ORDER DGTS
	MVI	A,0C3H		;JUMP INST
	STA	BBUF		;BBUF = JUMP INTO AUTO CODE NOW
	LXI	H,LF99A		;GET ADDR OF LINE NO PROCESSOR
	SHLD	IN8+1		;USE IT FOR NEW INPUT ROUTINE
	JMP	EORNS		;EVERYTHING'S SET UP
;
;HERE IS THE ROUTINE WHICH ACTUALLY PUTS LINE NOS. ON LINES.
;IT IS SUBSTITUTED FOR THE STANDARD ROUTINE BY THE CODE ABOVE.
;
LF99A:	CALL	BBUF		;CALL THE STD. INPUT ROUTINE
	MOV	A,L		;GET LOW BYTE ADDR OF CHAR PTR
	CPI	IBUF AND 0FFH	;AT 1ST CHAR OF INPUT BUFFER ?
	JNZ	LF9AE		;NO - SKIP BEG OF LINE PROC.
	MVI	A,1BH		;YES - SEE IF ESCAPE CHAR
	CMP	B		;
	JZ	EORMS		;IT IS ESC - DO COMPLETE RESET
	LXI	H,IBUF+5	;POINT TO NEW CHAR DEST
	MVI	E,7		;AND RESET LINE LENGTH
LF9AE:	MVI	A,0DH		;GET ASCII CAR. RET.
	CMP	B		;END OF LINE ?
	MOV	A,B		;PUT CHAR IN ACCUM.
	RNZ			;AND RETURN IF NOT END OF LINE
	PUSH	H		;ELSE SAVE IBUF POINTER
	PUSH	D		;AND LINE LENGTH
	LXI	D,ABUF		;POINT TO CUR LINE NO.
	LXI	H,ABUF+3	;AND TO END OF LINE NO.
LF9BB:	MOV	A,M		;GET RIGHT-HAND DIGIT
	INR	A		;INCREMENT IT
	CPI	'9'+1		;GONE PAST 9 ?
	JNC	LF9D8		;YES - FIX IT UP
	MOV	M,A		;ELSE PUT IT BACK
	LXI	H,IBUF		;POINT TO IBUF
	MVI	B,4		;LENGTH OF LINE NO
LF9C8:	LDAX	D		;GET CHAR FROM LINE NO.
	MOV	M,A		;AND PUT IT INTO IBUF
	INX	H		;INR IBUF POINTER
	INX	D		;INR LINE NO. POINTER
	DCR	B		;DCR COUNT
	JNZ	LF9C8		;AND CONTINUE TILL DONE
	MVI	M,' '		;THEN PUT A SPACE IN IBUF
	POP	D		;AND RESTORE REGISTERS
	MVI	B,0DH		;AND CHARACTER
	MOV	A,B		;WHICH READ WANTS IN ACCUM
	POP	H		;RESTORE REGS
	RET			;AND GO HOME, DONE
LF9D8:	MVI	A,'0'		;REPLACE DIGIT WITH A ZERO
	MOV	M,A		;AND PUT IT BACK
	DCX	H		;POINT TO HIGHER DIGIT
	JMP	LF9BB		;AND TRY TO INR IT
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
