BASE	EQU	0100H		;Assembly Address (TPA)
SPTR	EQU	BASE+1FD0H	;Stack Pointer (TPA)

****************************************************
*                                                  *
* Vector Graphic Serial Extended Systems Monitor   *
*                                                  *
*   Version 4.0m3 (1K) for Altair I/O              *
*          and 8080 processors		           *
*        Updated and Modified by                   *
*   Tom Sanderson and Mike Douglas 24 Feb 2022     *
*						   *
*   Original 4.0C VECTOR MZ MONITOR written by	   *
*                                                  *
*       R. S. HARP  10/16/79, Vector Graphic	   *
* 						   *
* 	Original Copyright 1979			   *
* 	Modidications Copyright 2021		   *
* 	Modidications Copyright 2022		   *
*                                                  *		
****************************************************
*    Commands: 					   *
*                                                  *
*    B Jump to Altair Bootstrap Loader  	   *
*    C SSSS FFFF CCCC Compare Blocks 		   *
*    D SSSS FFFF Dump in Hex  			   *
*    E External Communication using next port	   *
*    F SSSS FFFF DD DD Find Two Bytes 		   *
*    G SSSS - Go to and Execute 		   *
*    H Jump to HEX Bootstrap Loader    		    		
*    I PP Input from I/O Port			   *
*    J SSSS - Go to and Execute (Jump and Execute) *
*    L Jump to HEX Bootstrap Loader	  	   *
*    M SSSS FFFF DDDD Move Memory Block		   *
*    N Reserved for Non-destructive Test Memory    *
*    O PP DD Output to Port 			   *
*    P LLLL Program Memory  			   *
*    Q SSSS FFFF Compute Checksum 		   *
*    R Tarbell 1011D Bootstrap Loader		   *
*    S SSSS FFFF DD Search for Single Byte 	   *
*    T SSSS FFFF Test Memory			   *
*    V Jump to Bootstrap Loader        		   *
*    W MBLE Bootstrap Loader  		           *
*    Z Zero or Fill Memory 			   *
*                                                  *
**************************************************
*   Version 4.0m3 (1K) for Altair I/O              *
*          and 8080 processors	24 Feb 2022        *
*						   *
*    8080 conversion from Z80 ZASM code		   *
*                                                  *
*    B Jump to ALTBOOT/CDBL Bootstrap Loader       *
*    H Jump to HEX Bootstrap Loader	           *
*    L Jump to HEX Bootstrap Loader	           *
*    R Jump to TARBOOT Bootstrap Loader	           *
*    V Jump to Bootstrap Loader        		   *
*    W MBLE Bootstrap Loader  		           *
*                                                  *
* A, K, N, X, Y for >1K expansion commands   *
*                                                  *
****************************************************
*						   *
*          4.0x2 Modified 25 July 2021             *
*          by Tom Sanderson (4.0m2)		   *
*						   *
* (1) Modified for MITS I/O using a 		   *
*     Motorola 6850 ACIA			   *
*						   *
* (2) Initialized second serial port		   *
*						   *
* (3) Added L Jump to Tarbell 1011D Boot Loader    *
*						   *
* (4) Added U Jump to Bootstrap Loader (VG FD)     *
*						   *
* (5) Added J Go to and Execute (Jump and Execute) *
*						   *
****************************************************
*                                                  *
*          4.0x Modified 1 July 2021               *
*          by Tom Sanderson & Mike Douglas (4.0x2) *
*						   *
*          (1) Added E External Communications	   *
*						   *
*          (2) Corrected string display when using *
*	       a Windows terminal emulator 	   *
*						   *
****************************************************
*						   *
*          4.0C Modified 10 February 1984          *
*          by Tom Sanderson (4.0x)                 *
*						   *
*	   (1) B Command for Boot A  om E80CH	   *
*	       Floppy Bootstrap	using FD/HD	   *
*	       controller and Tandon drives	   *
*						   *
*	   (2) U Command for CP/M TPA at 0100H	   *
*						   *
*	   (3) V Command for Boot A Prom E800H	   *
*	       Dualstor Bootstrap for System	   *
*	       2800 using Qume Data Track 8 	   *
*	       drives and Vector 8" controller     *
*						   *
*	   (4) W Command for Boot A Prom E802H 	   *
*	       Megastor Bootstrap using FD/HD	   *
*	       contraller and 5 1/4 Hard Disk	   *
*						   *
*	   (5) Serial port initialization from	   *
*	       4.3 Version - ZCB at 6 MHz	   *
*						   *
*	   (6) INIT from 4.3 Version for Boot A	   *
*	       prom - Dump latch at E018H and 	   *
*	       clear controller flag DBUSY	   *
*						   *
*	   (7) The following commands were	   *
*	       removed to reduce the prom size	   *
*	       to 1K:				   *
*						   *
*		A ASCII Dump of Memory		   *
*		E External Communications	   *
*		H Jump to Hi Ram at FC00	   *
*		J Jump to DOS			   *
*		K Set a Breakpoint		   *
*		L Jump to Low Ram at 0		   *
*		N Non Destructive Memory Test	   *
*		R Dump Z80 Registers		   *
*		U Jump to User Area		   *
*		X Exchange Block		   *
*		Y Keyboard Echo			   *
*						   *
****************************************************
*
*    Turnkey Board - set TKYDSBL to 1 to disable Turnkey PROMs. This is
*    done by reading the sense switch input port during initialization.

TKYDSBL	equ	0		;non-zero = disable turnkey PROMs
SENSESW	equ	0FFH		;sense switch input port
 
*
* 88-2SIO equates
*
CONS	EQU	10H		;Console Status Port 
COND	EQU	11H		;Console Data Port
SIOS	EQU	12H		;Port B Status Port
SIOD	EQU	13H		;Port B Data Port
RDA	EQU	01		;Receive Flag
TBE	EQU	02		;Transmit Flag
STPOL	EQU	0		;Status Polarity
*
* System Equates
*
ALTBOOT	EQU	0FF00H		; (0FF00H Altair disk boot loader)
CDBL	EQU	0FF00H		; Same as ALTBOOT
DSBOOT	EQU	0E800H		; (0E800H VG Dualstor Bootstrap)
FLBOOT	EQU	0E80CH		; (0E80CH Tandon Floppy Bootstrap)
HEXBOOT	EQU	0FD00H		; HEX Boot Loader
MBLE	EQU	0FE00H		; MBLE
MSBOOT	EQU	0E802H		; (0E802H VG Megastor Bootstrap)
TARBOOT EQU	0FC00H		; (0EC00H Tarbell 1011D Bootstrap)
UBMON	EQU	0FD00H		; UBMON or TurMon Address
CR	EQU	0DH		;ASCII return
LF	EQU	0AH		;ASCII line feed
*
*
	ORG	BASE
*
* Jump Table Of Entry Points
*
MONIT	JMP	INIT		;Initialize All
KEYTST	JMP	KEYSTAT		;Test Keyboard
KEYDATA	JMP	CONVERT		;Input Keyboard
CRT	JMP	PTCN		;Output To Screen
ESC	JMP	ESCAPE		;Keyboard Input
*
*
INIT	LXI	SP,SPTR		;Init Stack

 if TKYDSBL	
	in	SENSESW		;disable Turnkey PROM
 endif
 
* Give time for two characters at 9600 baud to finish transmitting
*    before resetting the 6850
 
 	LXI	H,625		;2.5ms at 6MHz
 	
DELAY 	DCX	H		;5
 	MOV	A,H		;5
 	ORA	L		;4
 	JNZ	DELAY		;10
*
* Initialize 6850 ACIA
*
	MVI	A,03H		;Reset 6850
	OUT	CONS
	OUT	SIOS
*
* Paired XTHL for command settling delay (not needed for 6850)
*
*	XTHL
*	XTHL

	MVI	A,11H		;8N2
	OUT	CONS
	OUT	SIOS

*	CALL	ESCAPE		;not needed for 6850

*
* Display Sign On
*
	CALL	SIGN	
*
START:		
	LXI	SP,SPTR	
	CALL	PROMPT	
KEYPOL	CALL	ESCAPE	
	JZ	KEYPOL
	ANI	5FH
	LXI	H,START	
	PUSH	H
	SUI	'B'		;validate character is B-Z	
	CPI	'Z'-'B'+1	;beyond Z?		
	RNC			;yes

	LXI	H,CMDTB		;'B' indexes to 1st CMDTB entry
	PUSH	PSW
	ADD	A		;two bytes per entry
	ADD	L
	MOV	L,A		;assuming no carry into H
	MOV	E,M		;E=lsb of jump address
	INX	H
	MOV	D,M		;D=msb of jump address
	XCHG
	POP	PSW
	PCHL
*
* Command Table
*
*				;A - Removed, not used
CMDTB	DW	ALTBOOT		;B - Jump to Altair Floppy Bootstrap Loader 
	DW	COMPR		;C - SSSS FFFF CCCC Compare Blocks
	DW	HEXRUL		;D - SSSS FFFF Dump in Hex
	DW	EXTCOM		;E - External Communications using next port
	DW	FIND		;F - SSSS FFFF DD DD Find Two Bytes
	DW	EXEC		;G - SSSS - Go to and Execute 
	DW	HEXBOOT		;H - Jump to HEX Bootstrap Loader
	DW	PINPT		;I - PP Input from I/O Port
	DW	EXEC		;J - Go to and Execute (Jump and Execute)
	DW	START		;K - not used
	DW	HEXBOOT		;L - Jump to HEX Bootstrap Loader 
	DW	MOVEB		;M - SSSS FFFF DDDD Move Memory Block
	DW	START		;N - Reserved for Non-destructive Test Memory
	DW	POUTP		;O - PP DD Output to Port
	DW	PROGRAM		;P - LLLL Program Memory
	DW	CHKSM		;Q - SSSS FFFF Compute Checksum
	DW	TARBOOT		;R - Jump to Tarbell 1011D Bootstrap Loader
	DW	SRCH		;S - SSSS FFFF DD Search for Single Byte
	DW	TMEM		;T - SSSS FFFF Test Memory
	DW	UBMON		;U - UBMON or TURMON monitor
	DW	MBLE		;V - Jump to Bootstrap Loader, not used
	DW	START		;W - MBLE Bootstrap Loader
	DW	START 		;X - not used
	DW	START		;Y - not used
	DW	ZEROM		;Z - Zero or Fill Memory 
*
*** Execute The Program At The Address ***
*
EXEC	CALL	PTSTNG
	DB	'Go',' '+80H
	CALL	AHEX	
	XCHG
	PCHL
*
*** Convert up to 4 Hex digits to bin
*
AHEX:		
	MVI	C,4
AHE0:		
	LXI	H,0
AHE1:		
	CALL	ESCAPE	
	CPI	' '	
	JZ	SPCOVR	
AHE3:		
	CALL	HEX	
	JC	AHE1	
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	ADD	L
	MOV	L,A
	DCR	C
	JNZ	AHE1	
	XCHG
SPCE:		
	MVI	A,' '	
PTCN:		
	PUSH	PSW		;SAVE BYTE TO SEND

WTOUT:	IN	CONS
	ANI	TBE
	JZ	WTOUT

	POP	PSW
	ANI	7FH		;MSBIT AFFECTS SOME DISPLAY DEVICES
	OUT	COND
	RET

CRLF:		
	MVI	A,CR
	CALL	PTCN	
	MVI	A,LF
	JMP	PTCN	
*
SPCOVR:		
	CALL	PTCN	
	JMP	SPCE-1
*
* Check for Hex value, convert
*
HEX:		
	CPI	'0'	
	RC
	CPI	':'	
	JC	NUM	
	ANI	5FH
	CPI	'A'	
	RC
	CPI	'G'	
	CMC
	RC
NUM:		
	CALL	PTCN	
	SUI	48
	CPI	10
	JC	ALFA	
	SUI	7
ALFA:		
	ANA	A
	RET
*
* Read 2 digits from the console
*
AHE2:		
	MVI	C,2
	JMP	AHE0	
*
* Short routine to save code
*
TAHEX:		
	CALL	AHEX	
	JMP	AHEX	
*
*** Read from the console to reg A ***
*
RDCN:		
	CALL	ESCAPE	
	JZ	RDCN	
	CPI	60H
	JC	PTCN	
	ANI	5FH
	JMP	PTCN	
*
PAUSE:		
	CALL	ESCAPE	
	CPI	20H
	RNZ
PLOOP:		
	CALL	ESCAPE	
	CPI	20H
	JNZ	PLOOP	
	RET
*
ESCAPE:		
	CALL	KEYSTAT	
	RZ
	CALL	CONVERT
	CPI	1BH		;escape?
	JZ	START	
	RET
*
KEYSTAT:		
	IN	CONS
	ANI	RDA
	RET
*
* Keyboard code conversion
*
CONVERT:		
	IN	COND
	ANI	7FH
	RET
*
* Checksum routine
*
CHKSM:		
	CALL	PTSTNG	
	DB	'Chksum',' '+80H
	CALL	TAHEX	
	MVI	B,0
CHKSMLP:		
	MOV	A,M
	ADD	B
	MOV	B,A
	CALL	BMP	
	JNZ	CHKSMLP	
	MOV	A,B
	JMP	PT2	
*
*** Memory test routine ***
*
TMEM	CALL	PTSTNG	
	DB	'Test',' '+80H
	CALL	TAHEX	
	LXI	B,5A5AH
CYCL:		
	CALL	RNDM	
	PUSH	B
	PUSH	H
	PUSH	D
TLOP:		
	MOV	A,H		;on stack page?
	CPI	(SPTR SHR 8)-1	;compare to MSB of stack address
	JZ	SKIPWR		;in stack page, skip
	CALL	RNDM	
	MOV	M,B
SKIPWR:
	CALL	BMP	
	JNZ	TLOP	
	POP	D
	POP	H
	POP	B
	PUSH	H
	PUSH	D
RLOP:		
	MOV	A,H		;on stack page?
	CPI	(SPTR SHR 8)-1	;compare to MSB of stack address
	JZ	SKIPRD		;in stack page, skip
	CALL	RNDM	
	MOV	A,M
	CMP	B
	CNZ	ERR	
SKIPRD:
	CALL	BMP	
	JNZ	RLOP	
	POP	D
	POP	H
	MVI	A,'.'	
	CALL	PTCN	
	JMP	CYCL

*** This routine generates random nos ***
*
RNDM:		
	CALL	PAUSE	
	MOV	A,B
	ANI	0B4H
	ANA	A
	JPE	PEVE	
	STC
PEVE:		
	MOV	A,C
	RAL
	MOV	C,A
	MOV	A,B
	RAL
	MOV	B,A
	RET
*
*** Error print out routine
*
PTAD:		
	CALL	CRLF	
	CALL	PAUSE	
	MOV	A,H
	CALL	PT2	
	MOV	A,L
	JMP	PT2S	
*
ERR:		
	PUSH	PSW
	CALL	PTAD	
	MOV	A,B
	CALL	PT2S	
	POP	PSW
PT2:		
	PUSH	PSW
	CALL	BINH	
	POP	PSW
	JMP	BINL	
BINH:		
	RAR
	RAR
	RAR
	RAR
BINL:		
	ANI	0FH
	ADI	48
	CPI	58
	JC	PTCN	
	ADI	7
	JMP	PTCN	
*
* Compare addresses and increment H
*
BMP:		
	MOV	A,E
	SUB	L
	JNZ	GOON	
	MOV	A,D
	SBB	H
GOON:		
	INX	H
	RET
*
* Zero or fill memory with a constant
*
ZEROM	CALL	PTSTNG
	DB	'Fill',' '+80H
	CALL	TAHEX	
	PUSH	H
	CALL	AHE2	
	XCHG
	XTHL
	POP	B
ZLOOP:		
	MOV	M,C
	CALL	BMP	
	RZ
	JMP	ZLOOP	
MOVEB:		
	MOV	B,A
	CALL	PTSTNG	
	DB	'Move',' '+80H
MOVENTR:		
	CALL	TAHEX	
	PUSH	H
	CALL	AHEX	
	XCHG
	XTHL
MLOOP:		
	MOV	C,M
	XTHL
	MOV	A,B
	CPI	'M'	
	JZ	NEXCH	
	MOV	A,M
	XTHL
	MOV	M,A
	XTHL
NEXCH:		
	MOV	M,C
	INX	H
	XTHL
	CALL	BMP	
	JZ	START	
	JMP	MLOOP	
*
* Compare two blocks of memory
*
COMPR:		
	CALL	PTSTNG	
	DB	'Comp',' '+80H
	CALL	TAHEX	
	PUSH	H
	CALL	AHEX	
	XCHG
VMLOP:		
	MOV	A,M
	INX	H
	XTHL
	CMP	M
	MOV	B,M
	CNZ	ERR	
	CALL	BMP	
	XTHL
	JNZ	VMLOP	
	POP	PSW
	RET
*
* Search for specific codes
*
FIND	PUSH	PSW
	CALL	PTSTNG	
	DB	'Find',' '+80H
	JMP	SRCHENT
SRCH	PUSH	PSW
	CALL	PTSTNG	
	DB	'Search',' '+80H
SRCHENT	CALL	TAHEX	
	PUSH	H
	CALL	AHE2	
	XCHG
	MOV	B,L
	POP	H
	POP	PSW
	CPI	'S'	
	PUSH	PSW
	JZ	CONT	
	PUSH	H
	CALL	AHE2	
	XCHG
	MOV	C,L
	POP	H
CONT:		
	MOV	A,M
	CMP	B
	JNZ	SKP	
	POP	PSW
	CPI	'S'	
	PUSH	PSW
	JZ	OBCP	
	INX	H
	MOV	A,M
	DCX	H
	CMP	C
	JNZ	SKP	
OBCP:		
	INX	H
	MOV	A,M
	DCX	H
	CALL	ERR	
SKP:		
	CALL	BMP	
	JNZ	CONT	
	POP	PSW
	RET
*
* Input data from a port
*
PINPT:		
	CALL	PTSTNG	
	DB	'In',' '+80H
	CALL	AHE2	
	LXI	H,RAMCODE+2	;form IN nn, RET in RAM
	MVI	M,0C9H		;RET opcode
	DCX	H
	MOV	M,E		;input port of IN instruction
	DCX	H
	MVI	M,0DBH		;IN opcode
	CALL	RAMCODE
	JMP	PT2	
*
* Output to a port
*
POUTP:
	CALL	PTSTNG	
	DB	'Out',' '+80H
	CALL	AHE2	
	CALL	AHE2	
	MOV	D,L		;D=port
	LXI	H,RAMCODE+2	;form OUT nn, RET in memory at h
	MVI	M,0C9H		;RET opcode
	DCX	H
	MOV	M,D		;output port for OUT instruction
	DCX	H
	MVI	M,0D3H		;OUT opcode
	MOV	A,E		;A=value to output
	PCHL			;call OUT, RET
*
* Additions to 4.0 Monitor
* Print a string
*
RPTSTNG:		
	CALL	CRLF	
PTSTNG:		
	XTHL			;HL->string, preserve HL
PSLOOP:	
	MOV	A,M
	CALL	PTCN
	CMP	M		;end? (msbit set)
	INX	H
	JZ	PSLOOP		;no

	XTHL			;restore HL, return addr on stack
	RET			;return past string	
*
* Sign on message
*
SIGN:		
	CALL	CRLF	
	CALL	PTSTNG	
	DB	'  VG Altair Mon 4.0m3',LF,LF,CR+80H
*	DB	'VG Altair Monitor 4.0m3',LF,LF,CR+80H 
	CALL	PTSTNG
*	DB	'Copyright 1979',LF,CR+80H	
	DB	' ',LF,CR+80H 	; Copyright in source code to save memory
	RET
PROMPT:		
	CALL	RPTSTNG	
	DB	'-','>'+80H
	RET
WDMP2:		
	MOV	A,M
	ANI	7FH
	CPI	07FH
	JZ	NCNTL-2
	CPI	20H
	JP	NCNTL	
	MVI	A,'.'	
NCNTL:		
	CALL	PTCN
	CALL	BMP	
	RZ
	DCR	C
	RM
	JMP	WDMP2	
*
* Home cursor, Print "ADDR"
*
HOMEC:		
	CALL	RPTSTNG	
	DB	'Addr',' '+80H
	MVI	B,0
	RET
*
* Make a ruler for hex dump
*
HEXRULER:		
	MOV	A,B
	CPI	16
	JZ	HEXRCT	
	CALL	PT2S	
	INR	B
	JMP	HEXRULER	
HEXRCT:		
	CALL	SPCE	
	CALL	SPCE	
	MVI	B,0
HEXRLP:		
	MOV	A,B
	CPI	16
	RZ
	ANI	0FH
	CALL	BINL	
	INR	B
	JMP	HEXRLP	
*
* Hex dump routine
*
HEXRUL	CALL	PTSTNG	
	DB	'Dump',' '+80H
	CALL	TAHEX	
	CALL	HOMEC	
	CALL	HEXRULER	
HLP1:		
	CALL	PTAD	
	PUSH	H
	PUSH	D
	MVI	C,16
HLP2:		
	MOV	A,M
	CALL	PT2S	
	INX	H
	DCR	C
	JNZ	HLP2	
	POP	D
	POP	H
	MVI	C,15
	CALL	SPCE	
	CALL	SPCE	
	CALL	WDMP2	
	JM	HLP1	
	RET
*
* Program Memory
*
PROGRAM	CALL	PTSTNG	
	DB	'Prog',' '+80H
	CALL	AHEX	
	XCHG
	SHLD	TCURPOS
	XCHG
	CALL	HOMEC	
	CALL	HEXRULER	
	CALL	PRT1LINE	
	CALL	CRLF	
PGLP:		
	LHLD	TCURPOS	
	MOV	A,M
	CALL	PT2	
	MVI	A,'-'	
	CALL	PTCN	
CRIG:		
	CALL	ESCAPE	
	JZ	CRIG	
	CPI	' '	
	JZ	NXTLOC	
	MVI	C,2
	LXI	H,0
	CALL	AHE3	
	LHLD	TCURPOS	
	MOV	M,E
NXTLOC:		
	INX	H
	SHLD	TCURPOS	
	JMP	PGLP	
*
* Print a line containing ((H))
*
PRT1LINE:		
	LHLD	TCURPOS	
	PUSH	H
	POP	D
	MOV	A,L
	ORI	0FH
	MOV	E,A
	ANI	0F0H
	MOV	L,A
	JMP	HLP1	
*
PT2S:
	CALL	PT2
	JMP	SPCE
*
*EXTERNAL COMMUNICATIONS
*
EXTCOM:
	CALL	PTSTNG
	DB	'Ext Com',' '+80H
 
RECEIVE:
	IN	SIOS
	ANI	RDA
	JZ	NEXCHAR
	IN	SIOD
	CALL	PTCN

NEXCHAR:
	CALL	ESCAPE       
	JZ	RECEIVE
	OUT	SIOD
	JMP	RECEIVE
*
* Temporary storage locations for registers, etc.
*
	ORG	SPTR-20H
TCURPOS	DS	2
RAMCODE	DS	4
	END
