;LOMEM Displays low memory page

;  (C)	GORDON WILK
; 1986	6707 Springpark Ave
;	Los Angeles CA 90056
;
;	Released for private non-commercial use without fee

;	LOMEM displays locations 0-FFh in a more readble form 
;	than SID or DDT.  Locations are displayed as bytes or
;	words as appropriate to the menaing of the location.
;	The assignment of byte and word displays was made with
;	CPM3 in mind and some values will not be relevant to 
;	CPM 2.2.  CERTAIN TV9xx DISPLAY CODES WERE USED TO 
;	CONTROL BRIGHT AND DIM DISPLAY. 
;
;	The display codes as well as how each byte is printed
;	can be changed by altering values in the data section
;	and re-assembling.

;===============================================================
;	EQUATES
;===============================================================

;	BDOS LOCATIONS
BOOT	EQU	00	;warmboot
BDOS	EQU	05	;BDOS call

;       ASCII CONTROLS
LF	EQU	0Ah
CR	EQU	0Dh
ESC	EQU	1Bh

;---------------MACRO-------------------------------------------

PRINT	MACRO	MSG	;;Print string @ MSG
	LXI	D,MSG
	MVI	C,9
	CALL	BDOS
	ENDM

;================================================================
;	MAIN
;================================================================

	ORG	100H
	LXI	SP,STAK

;Each subroutine short circuits loop back to top
;Listed in frequency order for speed.
;
MAINLOOP:
	CALL	NEXT		;Get next code byte
	LXI	D,MAINLOOP	;Set MAINLOOP
	PUSH	D		;    as return address
	CPI	'0'
	JZ	PDIM2X		;2 digit hex number dimly
	CPI	'X'
	JZ	PUTCHAR		;Char if ASCII, else 2 hex digits
	CPI	'2'	
	JZ	PBRT2X		;2 digit hex number
	CPI	'1'	
	JZ	NPDIM2X		;Newline then dim hex byte
	CPI	'9'	
	JZ	P4HEX		;4 digit hex word
	CPI	'3'	
	JZ	NPBRT2X		;Newline then bright hex byte
	CPI	'Y'	
	JZ	NPUTCH		;Newline then char.
	CPI	'Z'
	JZ	BOOT		;Done
	RET

;===============================================================
;	SUBROUTINES
;===============================================================

;Get NEXT address of byte to print and code byte
;Return:  A = code byte determining how to print
;	 HL-> byte to print
;
NEXT:
	LHLD	PNTR	;Get pointer
	INX	H	;increment to
	SHLD	PNTR	; next byte
	XCHG
	LXI	H,CODE
	DAD	D	;HL=CodeBase+byte
	MOV	A,M	;Get code char
	XCHG		;HL->byte to print
	RET

;Print A as a char if it is ASCII printable
; else print it as a 2 digit hex number dimly
;Uses PDIM2X to print.  Returns from BDOS.
;
NPUTCH: 
	CALL	NEWLINE		;Newline then. . . 
PUTCHAR:
	MOV	A,M
	CPI	' '		;IF < space
	JC	PDIM2X		;	print as hex
	CPI	07Eh		;OR IF > '}'
	JNC	PDIM2X		;	print as hex
	MOV	E,A		;ELSE   print as char
	MVI	C,2		
	JMP	BDOS	;return from BDOS to mainloop

;Print A as a 2 digit hex number dimly + space
;Calls P2HEX to print the number.  Returns from BDOS.
;
NPDIM2X:
	CALL	NEWLINE		;Newline then...
PDIM2X:
	PUSH	H
	PRINT	DIM		;dim terminal code
	POP	H
	MOV	A,M
	CALL	P2HEX		;print byte and
	LXI	D,BRT		;end dim terminal code
	MVI	C,9
	JMP	BDOS

;Print A as 2 hex digits + a space
;Calls P2HEX to print. Returns from BDOS
;
NPBRT2X:
	CALL	NEWLINE		;Newline then...
PBRT2X:
	MOV	A,M
	CALL	P2HEX		;print byte 
	MVI	E,' '		;and space
	MVI	C,2
	JMP	BDOS	

;Print (HL) as a hex word and
;increment the pointer beyond the word
;Calls PUTHLX to print.  Returns from BDOS.
;
P4HEX:
	MOV	E,M
	INX	H		;skip over 2nd digit
	SHLD	PNTR
	MOV	D,M
	XCHG
	CALL	PUTHLX		;print hex word 
	MVI	E,' '		;and space
	MVI	C,2
	JMP	BDOS

;---------------------------------------------------------------
;	UTILITIES
;----------------------------------------------------------------

;Print CRLF, then bytecount and colon
;Calls PUTHLX to print.  Return with HL preserved
;
NEWLINE:
	PUSH	H
	PRINT	CRLF	
	POP	H
	PUSH	H
	CALL	PUTHLX
	PRINT	COLON
	POP	H
	RET

;Print HL as a 4 digit hex word		
;Calls P2HEX to print. Returns from BDOS
;
PUTHLX:
	PUSH	H
	MOV	A,H		;first byte
	CALL	P2HEX
	POP	H
	MOV	A,L		;second byte
;;	jmp	P2HEX		;Fall through

;Print A as 2 hex digits
; Since most chars are printed from this routine
; it was unrolled from subroutines and done as 
; in line code for speed.
;Enter A = binary value to print
;Returns from BDOS
;
P2HEX:
	PUSH	A			;Save value
	ANI	0F0h			;Get high nibble
	RRC ! RRC ! RRC ! RRC
	CPI	10			;IF > 10
	JC	P2X01			;
	ADI	7			;	add 7
P2X01:	ADI	'0'			;Convert to ASCII hex
	MOV	E,A			;
	MVI	C,2			; and print it
	CALL	BDOS		
	POP	A			;Restore value
	ANI	0Fh			;Get low nibble	
	CPI	10
	JC	P2X02			;Convert
	ADI	7			;
P2X02:	ADI	'0'			;
	MOV	E,A			;
	MVI	C,2			;and print
	JMP	BDOS			;Return from BDOS

;===============================================================
;	DATA
;===============================================================

;Matrix to tell how to print the char
; 	0: dim hex byte		1: newline + dim hex byte
;	2: brt hex byte		3: newline + brt hex byte
;      99: brt hex word
;	X: char or dim byte	Y: newline + char/dimbyte
;	Z: stop printing
;		
CODE:		;0123456789ABCDEF
	DB	'1990209900000000'	;00
	DB	'1000000000000000'	;10
	DB	'1000000000000000'	;20
	DB	'1000000000000000'	;30
	DB	'1000000000000000'	;40
	DB	'3992992000003XXX'	;50
	DB	'XXXXXXXX00003XXX'	;60
	DB	'XXXXXXXX00002222'	;70
	DB	'YXXXXXXXXXXXXXXX'	;80
	DB	'YXXXXXXXXXXXXXXX'	;90
	DB	'Z'

PNTR	DW	-1		;Pointer to char to print
CRLF	DB	CR,LF,'$'	
DIM	DB	ESC,')$'	;TERMINAL CODE: BEGIN DIM
BRT	DB	ESC,'( $'	;TERMINAL CODE: END DIM + ' '
COLON	DB	': $'

STAK	EQU	$+64
	END

B	ESC,')$'	;TERMINAL CODE: BEGIN DIM
BRT	DB	ESC,'( $'	;TERMINAL CODE: END 