	PAGE	,132
	TITLE	DISPREGS - DISPLAY REGISTERS AS SET BY LOADER
	NAME	DISPREGS
;****************************************************************
;* MODULE NAME = DISPREGS
;*
;* COPYRIGHT(C) 1984	SKIP GILBRECH
;*			90 LEXINGTON AVE. #10-G
;*			NEW YORK, NY 10016
;*			212-685-0551
;*
;* AUTHOR = SKIP GILBRECH
;* DATE WRITTEN = 01/13/84
;*
;* ENVIRONMENT:
;*  SYSTEM = IBM PC (DOS 2.0 - SHOULD WORK ON ANY VERSION)
;*  PROCESSOR = MICROSOFT 8086 MACRO ASSEMBLER
;*
;* THIS PROGRAM MAY BE FREELY COPIED/ALTERED FOR ANY NON-COMMERCIAL
;* PURPOSE BUT MAY NOT BE SOLD OR USED IN ANY WAY AS PART OF ANY
;* PROFIT-MAKING VENTURE WITHOUT PERMISSION OF THE AUTHOR.
;* (I.E., IN THE UNLIKELY EVENT THAT ANY MONEY IS MADE OFF THIS,
;* I WANT SOME OF IT...)
;*
;* THIS LITTLE PROGRAM WAS INSPIRED BY SOME OF THE RECENT DISCUSSION
;* ON THE SIG CONCERNING STARTING CONDITIONS (I.E. REGISTER & FLAG
;* SETTINGS) ENCOUNTERED BY FILES LOADED UNDER DEBUG VERSUS THOSE
;* ENCOUNTERED BY FILES LOADED BY COMMAND.COM.	IT WAS NOTED THAT
;* CERTAIN PROGRAMS WORKED UNDER ONE BUT NOT UNDER THE OTHER, AND I
;* REALIZED THAT I HAD ALWAYS ASSUMED THINGS WERE THE SAME EITHER WAY...
;*
;* IT SEEMS, HOWEVER, THAT ALTHOUGH THE DIFFERENCES AREN'T GREAT, THEY
;* DO EXIST.  IT IS, OF COURSE, FOOLISH TO RELY ON REGISTER AND FLAG
;* SETTINGS MADE BY SOMEONE ELSE, BUT THAT DOESN'T MEAN IT ISN'T DONE.
;*
;* THE ONLY ASSUMPTIONS MADE ABOUT REGISTER SETTINGS IN THIS PROGRAM
;* ARE THAT:
;*
;*   -- CS:IP POINTS TO THE BEGINNING OF THE CODE (HARD TO AVOID
;*	THAT ASSUMPTION...)
;*   -- DS:0 CONTAINS AN INT 21H INSTRUCTION (WILL RUN FINE WITHOUT
;*	IT, BUT WILL HAVE TROUBLE EXITING...)
;*
;* BY THE WAY, THIS CAN BE MADE INTO A .COM OR .EXE FILE BY CHANGING
;* THE EQUATE BELOW.  IT WAS NECESSARY TO MAKE TWO VERSIONS AS THE
;* TWO TYPES OF FILES ARE LOADED DIFFERENTLY.  TO MAKE A .COM FILE,
;* USE EXE2BIN AFTER YOU GET THE OBNOXIOUS 'NO STACK SEGMENT' WARNING
;* FROM LINK.  OF COURSE, THE .EXE REGISTER SETTINGS FOR CS,IP,SS AND
;* SP ARE PECULIAR TO THIS FILE, AS THEY ARE DEFINED BY THE LINKER AND
;* PASSED TO DOS IN THE .EXE HEADER.
;*
;****************************************************************
	PAGE
;****************************************************************
;*
;*	CONSTANTS
;*
;****************************************************************

FALSE		EQU	0
TRUE		EQU	NOT FALSE

MAKE_COM	EQU	TRUE		; IF TRUE, MAKE .COM FILE

IF NOT MAKE_COM 			; ELSE MAKE .EXE FILE
MAKE_EXE	EQU	TRUE
ELSE
MAKE_EXE	EQU	FALSE
ENDIF

LF	EQU	10			; LINE FEED
CR	EQU	13			; CARRIAGE RETURN

DOSINT		EQU	21H		; INT. NUMBER FOR DOS FUNCTIONS
PRINT_STRING	EQU	9		; DOS PRINT STRING FUNCTION

;****************************************************************
;*
;*	MACRO
;*
;****************************************************************

MSG_MAC MACRO	TEXT,FORMAT_ROUTINE
	MOV	DX,OFFSET TEXT
	MOV	AH,PRINT_STRING
	INT	DOSINT
	POP	AX
	CALL	FORMAT_ROUTINE
	ENDM

;****************************************************************
;*
;*	STACK SEGMENT IF MAKING .EXE FILE
;*
;****************************************************************

IF MAKE_EXE
STACK	SEGMENT STACK
DW	128 DUP (?)
STACK	ENDS
ENDIF

	PAGE
;****************************************************************
;*
;*	CODE (AND DATA) SEGMENT
;*
;****************************************************************

CODE	SEGMENT
	ASSUME	CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING

IF MAKE_COM
	ORG	100H		; FOR COM FILE
ENDIF

REG_DISP PROC FAR		; SET UP FOR FAR RETURN TO DOS

	JMP	MAINLINE	; JUMP TO PROGRAM CODE

; STRINGS FOR FORMATTING THE REGISTER DISPLAY:

MSG_CS		DB	CR,LF,'CS ==>$'
MSG_DS		DB	'  DS ==>$'
MSG_ES		DB	'  ES ==>$'
MSG_SS		DB	'  SS ==>$'
MSG_AX		DB	CR,LF,'AX ==>$'
MSG_BX		DB	'  BX ==>$'
MSG_CX		DB	'  CX ==>$'
MSG_DX		DB	'  DX ==>$'
MSG_SI		DB	CR,LF,'SI ==>$'
MSG_DI		DB	'  DI ==>$'
MSG_BP		DB	'  BP ==>$'
MSG_SP		DB	'  SP ==>$'
MSG_IP		DB	CR,LF,'IP ==>$'

; BUFFERS FOR OUTPUTTING DIGITS AND PRINTING FLAG SETTINGS:

DIGIT_BUF	DB	'      $'
MSG_FLAGS	DB	CR,LF,'FLAGS ==>  - - - - O D I T S Z - A - P - C'
		DB	CR,LF,'           $'
FLAGBUF 	DB	'                               ',CR,LF,'$'

SAVE_DS 	DW	?
SAVE_ES 	DW	?
SAVE_SS 	DW	?
SAVE_SP 	DW	?
SAVE_AX 	DW	?
SAVE_FL 	DW	?

	PAGE
;****************************************************************
;*
;*	REG_DISP MAINLINE
;*
;****************************************************************

MAINLINE	LABEL NEAR

	MOV	CS:SAVE_DS,DS		; SAVE DS & ES
	MOV	CS:SAVE_ES,ES		;
	MOV	CS:SAVE_SS,SS		; SAVE SS:SP SO WE CAN GET
	MOV	CS:SAVE_SP,SP		;  VALUE OF FLAGS
	MOV	CS:SAVE_AX,AX		; SAVE AX BEFORE USING

; EARLY 8088'S MIGHT BOMB HERE IF INTERRUPTS AREN'T DISABLED, BUT I CAN'T
; THINK OF ANY WAY TO SAVE THE INITIAL FLAG SETTINGS WITHOUT USING THE
; STACK, AND I'M NOT ASSUMING THE STACK IS VALID, SO....

	MOV	AX,CS			; SET SS TO CS
	MOV	SS,AX			;
	MOV	SP,OFFSET SHORT_STACK	; WE CAN NOW USE THE STACK

	PUSHF				; SAVE FLAGS BEFORE WE CHANGE THEM
	POP	CS:SAVE_FL		;

; SET UP FOR FAR RETURN TO DOS:

	PUSH	DS			; PTR TO PSP (EITHER .COM OR .EXE)
	SUB	AX,AX			; OFFSET 0
	PUSH	AX			; PUSH IT

	MOV	AX,CS			; SET DS & ES TO CS FOR ADDRESSING DATA
	MOV	DS,AX			;
	MOV	ES,AX			;

	ASSUME DS:CODE,ES:CODE		; TELL MASM

; SAVE ALL ORIGINAL REGISTER VALUES ON THE STACK

	PUSH	SAVE_FL 		;
	MOV	AX,OFFSET REG_DISP	; STARTING VALUE OF IP -- IF THIS WAS
	PUSH	AX			; WRONG, WE'LL NEVER GET HERE
	PUSH	SAVE_SP 		;
	PUSH	BP			; (NOT CHANGED)
	PUSH	DI			; (NOT CHANGED)
	PUSH	SI			; (NOT CHANGED)
	PUSH	DX			; (NOT CHANGED)
	PUSH	CX			; (NOT CHANGED)
	PUSH	BX			; (NOT CHANGED)
	PUSH	SAVE_AX 		;
	PUSH	SAVE_SS 		;
	PUSH	SAVE_ES 		;
	PUSH	SAVE_DS 		;
	PUSH	CS			; (NOT CHANGED)

; NOW DISPLAY EVERYTHING

	MSG_MAC 	MSG_CS, HEXDIG_OUT
	MSG_MAC 	MSG_DS, HEXDIG_OUT
	MSG_MAC 	MSG_ES, HEXDIG_OUT
	MSG_MAC 	MSG_SS, HEXDIG_OUT
	MSG_MAC 	MSG_AX, HEXDIG_OUT
	MSG_MAC 	MSG_BX, HEXDIG_OUT
	MSG_MAC 	MSG_CX, HEXDIG_OUT
	MSG_MAC 	MSG_DX, HEXDIG_OUT
	MSG_MAC 	MSG_SI, HEXDIG_OUT
	MSG_MAC 	MSG_DI, HEXDIG_OUT
	MSG_MAC 	MSG_BP, HEXDIG_OUT
	MSG_MAC 	MSG_SP, HEXDIG_OUT
	MSG_MAC 	MSG_IP, HEXDIG_OUT
	MSG_MAC 	MSG_FLAGS, PRT_FLAGS

	RET		; FAR RETURN TO OFFSET 0 IN PSP

REG_DISP	ENDP

	PAGE
;****************************************************************
;*
;*	HEXDIG_OUT	OUTPUT VALUE IN AX IN HEX TO CONSOLE
;*
;****************************************************************

HEXDIG_OUT	PROC	NEAR

	PUSH	AX
	PUSH	DX
	PUSH	DI

	MOV	DI,OFFSET DIGIT_BUF	; STRING BUFFER ADDRESS
	PUSH	DI			; SAVE FOR LATER
	ADD	DI,5			; POINT TO LAST DIGIT
	STD				; SET FOR AUTO DECREMENT
	PUSH	AX			; SAVE VALUE IN AH
	CALL	HEXDIG_OUT0		; STORE TWO LEAST SIGNIFICANT DIGITS
	POP	AX			; RESTORE VALUE IN AH
	MOV	AL,AH			; GET TWO MOST SIG. DIGITS
	CALL	HEXDIG_OUT0		; STORE THEM
	POP	DX			; PT DX TO BEGINNING OF STRING
	MOV	AH,PRINT_STRING 	; DOS FUNCTION NUMBER
	INT	DOSINT			;

	POP	DI
	POP	DX
	POP	AX
	RET

HEXDIG_OUT0:
	PUSH	AX			; SAVE AL FOR OTHER HALF OF DIGIT
	AND	AL,0FH			; STRIP OFF HIGH DIGIT
	CALL	HEXDIG_OUT1		; STORE LOWER DIGIT
	POP	AX			; GET AL BACK FOR HIGH DIGIT
	SHR	AL,1			; SHIFT INTO LOWER DIGIT
	SHR	AL,1			;
	SHR	AL,1			;
	SHR	AL,1			;
					; THEN STORE LOWER DIGIT
HEXDIG_OUT1:
	OR	AL,30H			; CONVERT 0-9 TO ASCII
	CMP	AL,3AH			;
	JB	HEXDIG_OUT2		;
	ADD	AL,7			; CONVERT 10-15 TO A-F

HEXDIG_OUT2:
	STOSB				; STORE DIGIT IN BUFFER & PT TO NEXT
	RET				; MOST SIGNIFICANT DIGIT

HEXDIG_OUT	ENDP

	PAGE
;****************************************************************
;*
;*	PRT_FLAGS	PRINT FLAG SETTINGS (IN AX) AS 1 OR 0
;*
;****************************************************************

PRT_FLAGS	PROC NEAR

	PUSH	AX
	PUSH	CX
	PUSH	DX
	PUSH	DI
	MOV	DX,AX			; SAVE FLAG SETTINGS IN DX
	MOV	CX,16			; REPEAT FOR EACH BIT
	MOV	DI,OFFSET FLAGBUF	; SET DI TO BUFFER FOR FLAGS
	PUSH	DI			; SAVE FOR DOS CALL
	CLD				; AUTO-INCREMENT
PF_LOOP:
	ROL	DX,1			; GET FLAG BIT IN BIT 0
	MOV	AL,DL			; MOVE BIT TO AL
	AND	AL,1			; ISOLATE IT
	ADD	AL,'0'                  ; MAKE ASCII
	STOSB				; STORE CHAR. IN BUF, BUMP PTR
	INC	DI			; BUMP AGAIN PAST SPACE
	LOOP	PF_LOOP 		; REPEAT WHILE BITS REMAIN

	POP	DX			; RESTORE ADDRESS OF BUFFER
	MOV	AH,PRINT_STRING 	;
	INT	DOSINT			;

	POP	DI
	POP	DX
	POP	CX
	POP	AX
	RET

PRT_FLAGS	ENDP

	EVEN		; PUT STACK ON WORD BOUNDARY

SHORT_STACK	EQU	$ + 100H

CODE	ENDS

END	REG_DISP
;       ASCADD = ASCII CODE OF OFFSET
;       ALL REGISTERS ARE ALTERED
;
DISPLA: MO