;Lauren Guimont		1-25-80		Ver. 1.0
;			1-28-80		Ver. 1.1
;			3-20-80		Ver. 1.2
;			6-26-80		Ver. 1.3
;
;This is an assembly language adaption of a program
;written in NorthStar BASIC called `STATUS'.
;
;This program will determine the location of numerous
;addresses, depending on the system size being run.
;It will also present various pieces of information
;concerning the status of many of the options available
;under CP/M 2.20, besides presenting a map of the memory
;of the host system.
;
;
;Set up the equates to use
;
BDOS	EQU	5		;I/O PATCHING
CONOUT	EQU	2		;CONSOLE CHAR OUT
GIOBYTE	EQU	7		;RETURNS I/O BYTE IN A
STROUT	EQU	9		;PRINT STRING OUTPUT
LOGIN	EQU	24		;RETURNS ON-LINE DRIVES
CURDRV	EQU	25		;RETURNS DEFAULT DRIVE#
ALLOC	EQU	27		;RETURNS ALLOCATION ADDRESS
RONLY	EQU	29		;RETURNS READ ONLY VECTOR
DPARA	EQU	31		;RETURNS DISK PARAMETER BLK
PRUSER	EQU	32		;RETURNS PRESENT USER
;
;
BEGIN	ORG	100H		;Start of TPA
	JMP	START		;Actual program start
	DS	64		;Set up a stack area
STACK	EQU	$
;
BEDOS	DS	2
TPA	DS	2
CCP	DS	2
CONTLR	DS	1
OLDSP	DS	2
BYTE	DB	0
IOBYT	DS	1
VECTOR	DS	2
CDRV	DS	1
ALLOCAD	DS	2
;
;
COUT:				;Character output
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,A
	MVI	C,CONOUT
	CALL	BDOS
	POP	H
	POP	D
	POP	B
	RET
;
;The following routine will print the value of
;HL to the console. If entered at HEOUT, it will
;only print the value of the A register
;
ADOUT:				;Output HL to console
	MOV	A,H		;H is first
	CALL	HEOUT
	MOV	A,L		;L is next
HEOUT	MOV	C,A		;Save it
	RRC
	RRC
	RRC
	RRC
	CALL	HEOUT1		;Put it out
	MOV	A,C		;Get it back
HEOUT1	ANI	0FH
	ADI	48
	CPI	58		;0-9?
	JC	OUTCH
	ADI	7		;Make it a letter
OUTCH	CALL	COUT
	RET
;
CLEAR:				;Clear console
	MVI	C,25
	MVI	A,0DH		;C/R
	CALL	COUT
CLEAR1	MVI	A,0AH		;Linefeed
	CALL	COUT
	DCR	C
	JNZ	CLEAR1		;Loop for 25 LF
	RET
;
;
CRLF:				;Send C/R, LF
	MVI	A,0DH
	CALL	COUT
	MVI	A,0AH
	CALL	COUT
	RET
;
SPACE	MVI	A,20H
	CALL	COUT
	RET
;
;PROGRAM MESSAGES
;
MSG0	DB	'STATUS report for CP/M 2.2      '
	DB	'           Version 1.4 (6-27-80)'
	DB	0DH,0AH,0AH,0AH,'$'
MSG1	DB	'    M=RAM memory           R=ROM memory'
	DB	'          .=no memory',0DH,0AH
	DB	'0   1   2   3   4   5   6   7   8   9'
	DB	'   A   B   C   D   E   F'
	DB	0DH,0AH,'$'
MSG2	DB	'CCP starts at $'
MSG3	DB	'BDOS starts at $'
MSG4	DB	'Current logged in drives;  $'
MSG5	DB	'The Allocation address of drive $'
MSG6	DB	': is $'
MSG7	DB	'A$'
MSG8	DB	', B$'
MSG9	DB	', C$'
MSG10	DB	', D$'
MSG11	DB	' bytes$'
MSG12	DB	'The address of the disk '
	DB	'parameter block is $'
MSG13	DB	'Available TPA without '
	DB	'killing the CCP is $'
MSG14	DB	'These drives are vectored'
	DB	' as read only;  $'
MSG15	DB	'BIOS starts at $'
MSG16	DB	'Active I/O ports: $'
MSG17	DB	'None$'
MSG18	DB	'Current drive in use is $'
MSG19	DB	'The present USER number is $'
;
;
START:				;Actual program start
	LXI	H,0		;Clear HL
	DAD	SP		;Get SP from CCP
	SHLD	OLDSP		;Save it
	LXI	SP,STACK	;Point to our stack
	CALL	CLEAR
	LXI	D,MSG0
	MVI	C,STROUT
	CALL	BDOS
	LXI	D,MSG1
	MVI	C,STROUT
	CALL	BDOS
;
;This is the start of the memory map
;
	LXI	H,0000H		;Start memory map
MEMORY:
	MVI	A,0FFH
	CMP	M		;Memory?
	JZ	EMPTY
	MOV	B,M		;Save memory value
	MOV	M,A
	MOV	A,M
	CMP	B		;Same as original?
	JZ	ROM
RAM	MOV	M,B		;Replace original byte
	MVI	B,4DH
	JMP	SHWBY
ROM	MVI	B,52H
	JMP	SHWBY
EMPTY	MVI	A,80H		;Double check W/new value
	MOV	B,M
	MOV	M,A
	MOV	A,M
	CMP	B		;Is it ram?
	JNZ	RAM
	MVI	B,2EH
SHWBY	MOV	A,B
	CALL	COUT		;Output ROM, RAM, or empty
	INR	H
	INR	H
	INR	H
	INR	H
	JNZ	MEMORY		;Loop till done
	CALL	CRLF
	CALL	CRLF
;
;Now we fill in the storage bytes with the proper
;values which are dependent on each particular system.
;
	LHLD	BDOS+1		;Get start of BDOS
	MOV	A,L
	SUI	6
	MOV	L,A
	SHLD	BEDOS		;Store it
	LXI	D,0F700H
	LHLD	BEDOS
	DAD	D		;Add wrap around offset
	SHLD	TPA
	LXI	D,100H
	LHLD	TPA
	DAD	D
	SHLD	CCP		;Store CCP=-100H of TPA
	MVI	C,GIOBYTE
	CALL	BDOS
	STA	IOBYT		;Store the I/O byte
	MVI	C,ALLOC
	CALL	BDOS
	SHLD	ALLOCAD
;
;Now we must output the gathered information
;to the console
;
;Get the CCP address and print it
;
	LXI	D,MSG2
	MVI	C,STROUT
	CALL	BDOS
	LHLD	CCP
	CALL	ADOUT
	CALL	CRLF
;
;Next get the BDOS address and print it
;
	LXI	D,MSG3
	MVI	C,STROUT
	CALL	BDOS
	LHLD	BEDOS
	CALL	ADOUT
	CALL	CRLF
;
;Next get address of BIOS and print it
;
	LXI	D,MSG15
	MVI	C,STROUT
	CALL	BDOS
	LXI	D,0E00H
	LHLD	BEDOS
	DAD	D
	CALL	ADOUT
	CALL	CRLF
;
;Compute TPA without killing CCP and print it
;
	LXI	D,MSG13
	MVI	C,STROUT
	CALL	BDOS
	LHLD	TPA
	CALL	ADOUT
	LXI	D,MSG11
	MVI	C,STROUT
	CALL	BDOS
	CALL	CRLF
;
;Determine which drive is the current drive in
;use, and print the result
;
	LXI	D,MSG18
	MVI	C,STROUT
	CALL	BDOS
	MVI	C,CURDRV
	CALL	BDOS
	ADI	41H
	STA	CDRV
	CALL	COUT
	MVI	A,':'
	CALL	COUT
	CALL	CRLF
;
;Determine Allocation address of current drive, and print it
;
	LXI	D,MSG5
	MVI	C,STROUT
	CALL	BDOS
	LDA	CDRV
	CALL	COUT
	LXI	D,MSG6
	MVI	C,STROUT
	CALL	BDOS
	LHLD	ALLOCAD
	CALL	ADOUT
	MVI	A,48H
	CALL	COUT
	CALL	CRLF
;
;Find out which drives are logged in and print them
;
	MVI	C,LOGIN
	CALL	BDOS
	ANI	0FH
	STA	VECTOR
	LXI	D,MSG4
	MVI	C,STROUT
	CALL	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG7
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG8
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG9
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	LXI	D,MSG10
	MVI	C,STROUT
	CC	BDOS
	CALL	CRLF
;
;Find and show the read only vectors
;
	MVI	C,RONLY
	CALL	BDOS
	ANI	0FH
	STA	VECTOR
	LXI	D,MSG14
	MVI	C,STROUT
	CALL	BDOS
	LDA	VECTOR
	ORA	A
	LXI	D,MSG17
	MVI	C,STROUT
	CZ	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG7
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG8
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	STA	VECTOR
	LXI	D,MSG9
	MVI	C,STROUT
	CC	BDOS
	LDA	VECTOR
	RRC
	LXI	D,MSG10
	MVI	C,STROUT
	CC	BDOS
	CALL	CRLF
;
;Get the disk parameter block and display it
;
	LXI	D,MSG12
	MVI	C,STROUT
	CALL	BDOS
	MVI	C,DPARA
	CALL	BDOS
	CALL	ADOUT
	MVI	A,48H
	CALL	COUT
	CALL	CRLF
;
;Determine the present USER, and print the result
;
	LXI	D,MSG19
	MVI	C,STROUT
	CALL	BDOS
	MVI	E,0FFH
	MVI	C,PRUSER
	CALL	BDOS
	CALL	HEOUT
	MVI	A,48H
	CALL	COUT
	CALL	CRLF
;
;Check all ports (0-255), and determine if they
;are active. If they are, print the port number
;and then do a warm boot (control C)
;
;BE ADVISED!!
;The lable PORT1 gets a byte from storage from a
;lable called BYTE. This value is incremented from
;0-255 and then is written to the second byte from
;the lable PORT2. What I'm saying is that this
;portion of code is SELF MODIFYING!!
;
	LXI	D,MSG16
	MVI	C,STROUT
	CALL	BDOS
PORT1	LDA	BYTE
	STA	PORT2+1
PORT2	IN	0
	CPI	0FFH
	CNZ	PORTOUT
	LDA	BYTE
	CPI	0E0H
	JZ	FINISH
	LDA	BYTE
	INR	A
	STA	BYTE
	JMP	PORT1
FINISH	CALL	CRLF
	CALL	CRLF
	CALL	CRLF
	LHLD	OLDSP
	SPHL
	RET
PORTOUT	LDA	BYTE
	CALL	HEOUT
	CALL	SPACE
	RET



