home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
USCX
/
PGMR-UTS.ZIP
/
LOOK.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-06-26
|
15KB
|
485 lines
PAGE ,132
TITLE LOOK - LOOK AT MEMORY
SUBTTL Look At Memory In Any Segment
; ;
;*****************************************************************************;
; ;
; John R. Pulliam Version 2/21/84 ;
; ;
; For Columbia Data Product Computers and Compatibles ;
; Released to Public Domain ;
; ;
;*****************************************************************************;
; ;
;
; DOS CALL INT 21H FUNCTIONS USED
;
;
; AH = 01H => Input One Character From Keyboard
; AL = Ascii Character Received
;
; AH = 02H => Display One Character On CRT
; DL = Ascii Character to Display
;
; AH = 09H => Display Message on CRT
; DS = Segment of Message
; DX = Offset Address of Message
;
; AH = 0CH &
; AL = 0AH => Clear Then Fetch Keyboard Buffer
; DI = Buffer First Word Address
; [DI] = Number Of Characters Wanted To Input
; [DI+1] = Number Of Characters Actually Received
; [DI+2] = First Character Received
;
;
; DOS INT 20H = Terminate Program And Return To DOS
;
; To Assemble This Program:
;
; 1. Place the source file, LOOK.ASM, in Drive B
;
; 2. MASM B:LOOK,B:LOOK,B:LOOK,NUL.CRF
;
; 3. LINK B:LOOK,B:LOOK,NUL.MAP,NUL.LIB
; (There should be 1 warning error message after linking)
;
; 4. EXE2BIN B:LOOK,B:LOOK.COM
;
; 5. B:LOOK.OBJ and B:LOOK.LST may be deleted if desired.
;
;*****************************************************************************;
;
CSEG SEGMENT PARA PUBLIC
ASSUME CS:CSEG,DS:CSEG,ES:CSEG
ORG 100H
; DEFINE THE CONSTANTS
CR EQU 13 ; CARRIAGE RETURN CODE
LF EQU 10 ; LINE FEED CODE
QT EQU 34 ; QUOTE MARK
BYT EQU 16 ; NUMBER OF BYTES PER LINE
LINES EQU 8 ; NUMBER OF LINES TO DISPLAY
; SET UP THE SEGMENT REGISTERS
LOOK: MOV AX,CS ; GET CURRENT SEGMENT
MOV DS,AX ; SET DS TO THIS SEG
MOV ES,AX ; SET ES TO THIS SEG
MOV WORD PTR SEGADD,AX ; INITIALIZE DISPLAY SEGMENT
; ASK IF ANOTHER SEGMENT IS DESIRED
ASKSEG: MOV DX,OFFSET SEGMSG ;ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
; READ REPLY
MOV AH,1 ; REQUEST "Y" OR "N"
INT 21H ; GET KEY INPUT
AND AL,0DFH ; ALLOW EITHER UPPER OR LOWER CASE
CMP AL,'N' ; BRANCH TO GET STARTING ADD IF "N"
JE DISPSEG
CMP AL,'Y' ; REPEAT QUERY IF NOT "Y"
JNE ASKSEG
; GET THE SEGMENT TO DISPLAY MEMORY FROM
GETSEG: MOV DX,OFFSET SEGMSG2 ; ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
; READ DESIRED SEGMENT
MOV AH,4 ; MAX NUMBER OF CHARACTERS WANTED
MOV DI,OFFSET KBUFSZ ; KEYBOARD BUFFER
CALL KYBD ; INPUT REPLY
CMP AH,4 ; WANT 4 CHARS EXCLUDING THE CR
JE CV1 ; SKIP IF NO LEADING ZEROS
CALL INSERT ; INSERT LEADING ZEROS
CV1: CALL CRLF ; OUTPUT CR AND LF
; CONVERT FOUR ASCII CODES INTO TWO HEX BYTES (FOUR HEX DIGITS)
MOV AX,WORD PTR KBUF ; FIRST TWO ASCII CODES
CALL ASC_HEX ; RETURNS ONE HEX BYTE
JC GETSEG ; REPEAT QUERY IF ILLEGAL INPUT
MOV SEGADD+1,AL ; STORE HIGH SEGMENT BYTE
MOV AX,WORD PTR KBUF+2 ; THIRD AND FOURTH ASCII CODES
CALL ASC_HEX ; RETURNS ONE HEX BYTE
JC GETSEG ; REPEAT QUERY IF ILLEGAL INPUT
MOV SEGADD,AL ; STORE LOW SEGMENT BYTE
; DISPLAY THE SEGMENT FROM WHICH DATA IS TO BE DISPLAYED
DISPSEG:
MOV AL,SEGADD+1 ; GET THE FIRST SEGMENT BYTE
CALL HEX_ASC ; CONVERT TO ASCII
MOV ASCSEG,AX ; SAVE FOR OUTPUT TO CRT
MOV AL,SEGADD ; GET THE SECOND SEGMENT BYTE
CALL HEX_ASC ; CONVERT IT TO ASCII TOO
MOV ASCSEG+2,AX ; AND SAVE IT ALSO
MOV DX,OFFSET SEGMSG3 ; ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
MOV DX,OFFSET ASCSEG ; ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
; ASK FOR THE STARTING ADDRESS
ASKADD: MOV DX,OFFSET STMSG ; ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
; READ REPLY
MOV AH,4 ; MAX NUMBER OF CHARACTERS WANTED
MOV DI,OFFSET KBUFSZ ; KEYBOARD BUFFER
CALL KYBD ; INPUT REPLY
CMP AH,4 ; WANT 4 CHARS EXCLUDING THE CR
JE CV2 ; SKIP IF NO LEADING ZEROS
CALL INSERT ; INSERT LEADING ZEROS
CV2: CALL CRLF ; OUTPUT CR AND LF
CALL CRLF ; OUTPUT CR AND LF
; CONVERT FOUR ASCII CODES INTO TWO HEX BYTES (FOUR HEX DIGITS)
MOV AX,WORD PTR KBUF ; FIRST AND SECOND ASCII CODES
CALL ASC_HEX ; RETURNS ONE HEX BYTE
JC ASKADD ; REPEAT QUERY IF ILLEGAL INPUT
MOV STADD+1,AL ; STORE HIGH ADDRESS BYTE
MOV AX,WORD PTR KBUF+2 ; THIRD AND FOURTH ASCII CODES
CALL ASC_HEX ; RETURNS ONE HEX BYTE
JC ASKADD ; REPEAT QUERY IF ILLEGAL INPUT
MOV STADD,AL ; STORE LOW ADDRESS BYTE
MOV AX,WORD PTR STADD ; GET STARTING ADDRESS
MOV SI,AX ; STARTING ADDRESS IN SI REGISTER
CALL DISPLA ; DISPLAY MEMORY (AT LAST)
; ASK IF WE SHOULD REPEAT
EMSG: MOV DX,OFFSET ENDMSG ; ADDRESS OF MESSAGE
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS
MOV AH,1 ; REQUEST "Y" OR "N"
INT 21H ; GET KEY INPUT
AND AL,0DFH ; ALLOW EITHER UPPER OR LOWER CASE
CMP AL,'N' ; EXIT IF "N"
JE EXIT
CMP AL,'Y' ; REPEAT QUERY IF NOT "Y"
JNE EMSG
JMP ASKSEG ; LOOP TO START OVER
EXIT: INT 20H ; Return to DOS
.XLIST
SUBTTL Miscellaneous Callable Routines
PAGE +
.LIST
;
;
; INSERT LEADING ZEROS INTO KEYBOARD INPUT BUFFER
;
INSERT: MOV AL,4 ; NUMBER OF DIGITS IN NUMBER
SUB AL,AH ; NUMBER OF LEADING ZEROS
INS1: MOV DI,OFFSET KBUF+3 ; DESTINATION ADDRESS
MOV SI,OFFSET KBUF+2 ; SOURCE ADDRESS
MOV CX,3 ; LOOP COUNT
INS2: MOV AH,[SI] ; MOVE ONE
MOV [DI],AH ; CHARACTER
DEC DI ; DEC POINTERS
DEC SI
LOOP INS2 ; SHIFT ALL DIGITS
MOV AH,'0' ; ASCII ZERO
MOV [DI],AH ; ADD LEADING ZERO
DEC AL
JNZ INS1 ; LOOP FOR EACH ZERO TO ADD
;
; WRITE CR LF TO CRT
;
CRLF: MOV DX,OFFSET CRLFM ; ADDRESS OF 'CR,LF'
MOV AH,9
INT 21H ; WRITE CR LF
RET ; RETURN TO CONTINUE
CRLFM DB CR,LF,'$'
;
;
; DISPLAY MEMORY
;
; SI REG = STARTING ADDRESS TO DISPLAY
; SEGADD = SEGMENT TO DISPLAY FROM
; STADD = OFFSET TO DISPLAY FROM
; ASCSEG = ASCII CODE OF SEGMENT
; ASCADD = ASCII CODE OF OFFSET
; ALL REGISTERS ARE ALTERED
;
DISPLA: MOV DX,OFFSET SPACE ; SPACE CODES
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; OUTPUT SPACES
;
; OUTPUT THE TOP LINE
;
MOV CX,BYT ; NUMBER OF BYTES PER LINE
MOV AL,STADD ; GET THE LOW ADDRESS BYTE
LUP1: PUSH AX ; SAVE FOR NEXT OUTPUT
CALL HEX_ASC ; CONVERT TO ASCII
MOV ASCTOP,AH ; SAVE FOR OUTPUT
MOV AH,9 ; OUTPUT STRING FUNCTION
MOV DX,OFFSET ASCTOP ; ADDRESS OF STRING
INT 21H ; OUTPUT ONE DIGIT ON TOP LINE
POP AX ; GET PREVIOUS DIGIT
INC AL ; INCREMENT FOR NEXT DIGIT
LOOP LUP1 ; REPEAT FOR THE REST
CALL CRLF ; CR AND LF
;
MOV BX,LINES ; NUMBER OF LINES TO DISPLAY
MOV AX,WORD PTR SEGADD ; FETCH SEGMENT TO DISPLAY
MOV ES,AX ; PUT DESIRED SEGMENT IN ES REGISTER
;
; OUTPUT ADDRESS AT START OF LINE
;
LUP3: PUSH BX ; SAVE LINE COUNTER
MOV AL,STADD+1 ; GET THE FIRST ADDRESS BYTE
CALL HEX_ASC ; CONVERT TO ASCII
MOV ASCADD,AX ; SAVE FOR OUTPUT TO CRT
MOV AL,STADD ; GET THE SECOND ADDRESS BYTE
CALL HEX_ASC ; CONVERT IT TO ASCII TOO
MOV ASCADD+2,AX ; AND SAVE IT ALSO
;
MOV AH,9 ; DISPLAY STRING FUNCTION
MOV DX,OFFSET ASCADD ; ADDRESS OF MESSAGE
INT 21H ; CALL DOS
MOV AL,STADD ; INCREMENT STARTING ADDRESS
ADD AL,BYT ; BY NUMBER OF BYTES IN A LINE
MOV STADD,AL
JNC DLINES
INC STADD+1 ; INCREMENT HIGH BYTE IF NECESSARY
;
; OUTPUT ONE LINE
;
DLINES: MOV CX,BYT ; NUMBER OF BYTES TO DISPLAY IN A LINE
MOV DI,OFFSET ASCCHAR ; ADDRESS OF ASCII BUFFER
;
LUP4: MOV AL,ES:[SI] ; PICK UP NEXT MEMORY BYTE
PUSH AX ; SAVE IT
CMP AL,7FH ; SEE IF IT CAN BE DISPLAYED ON CRT
JGE DASC1 ; BRANCH IF NOT
CMP AL,20H
JGE DASC2 ; BRANCH IF YES
DASC1: MOV AL,'.' ; SUBSTITUTE PERIOD
DASC2: MOV [DI],AL ; STORE FOR LATER DISPLAY
INC DI ; INCREMENT BUFFER POINTER
POP AX ; RETRIEVE MEMORY BYTE
CALL HEX_ASC ; CONVERT IT TO TWO ASCII CODES
MOV CHARS,AX ; STORE THEM
PUSH SI ; SAVE POINTER
PUSH CX ; SAVE BYTE COUNTER
MOV DX,OFFSET CHARS ; ADDRESS OF STRING
MOV AH,9 ; DISPLAY STRING FUNCTION
INT 21H ; CALL DOS TO DISPLAY THIS BYTE
POP CX ; RESTORE BYTE COUNTER
POP SI ; RESTORE POINTER
INC SI ; INCREMENT SOURCE POINTER
LOOP LUP4 ; REPEAT UNTIL DONE
;
MOV CX,BYT+2 ; NUMBER OF TOTAL SYMBOLS
MOV DI,OFFSET ASCSYM ; ADDRESS OF STRING
LUP5: MOV DL,[DI] ; NEXT CHARACTER TO DISPLAY
PUSH DI ; SAVE REGISTERS
PUSH CX
MOV AH,2 ; DISPLAY CHARACTER FUNCTION
INT 21H ; CALL DOS TO DISPLAY SYMBOLS
POP CX ; RESTORE REGISTERS
POP DI
INC DI ; INCREMENT SYMBOL ADDRESS
LOOP LUP5 ; REPEAT UNTIL FINISHED
;
CALL CRLF ; OUTPUT CR AND LF
POP BX ; RESTORE LINE COUNTER
DEC BX ; DECREMENT LINE COUNTER
JNZ LUP3 ; REPEAT FOR ALL LINES
;
MOV AX,DS
MOV ES,AX ; RESTORE ES REGISTER
RET ; RETURN TO CALLING ROUTINE
PAGE
; ;
;*****************************************************************************;
; ;
; KEYBOARD INPUT SUBROUTINE VERSION 2/19/84 ;
; ;
; THIS ROUTINE READS ASCII CODES FROM THE KEYBOARD INTO A BUFFER ;
; ;
; ENTRY: AH = MAX NUMBER OF CHARACTERS TO READ EXCLUDING ANY CR CODE ;
; DI = FWA OF THE BUFFER IN WHICH TO STORE THE CHARACTERS ;
; ;
; EXIT: AL = THE LAST CHARACTER READ EXCLUDING ANY CR CODE ;
; AH = THE NUMBER OF CHARACTERS READ EXCLUDING BS OR CR CODES ;
; DI = ADDRESS OF THE LAST CHARACTER READ ;
; ONE LESS THAN BUFFER FWA IF ONLY CR IS RECEIVED ;
; ;
; BACKSPACE AND CARRIAGE RETURN CODES ARE PROCESSED BY DOS ;
; ;
; THE BUFFER MUST HAVE THE FIRST TWO BYTES AVAILABLE FOR STORAGE OF ;
; THE MAX NUMBER OF CHARACTERS TO READ AND NUMBER OF CHARACTERS READ ;
; INCLUDING THE CARRAIGE RETURN CODE ;
; ;
; ALTERS: ALL REGISTERS EXCEPT BX ARE ALTERED ;
; ;
;*****************************************************************************;
; ;
KYBD: PUSH BX ; SAVE REGISTER
PUSH DI ; SAVE BUFFER ADDRESS
INC AH ; ALLOW FOR THE CR CODE
MOV [DI],AH ; STORE MAX NUMBER OF WORDS TO READ
MOV AX,0C0AH ; CLEAR AND READ KEYBOARD BUFFER
MOV DX,DI ; BUFFER ADDRESS IN DX
INT 21H ; CALL DOS
POP DI ; GET BUFFER ADDRESS
INC DI
MOV AH,[DI] ; GET NUMBER OF CHARACTERS READ
MOV BL,AH ; PUT IN BASE REGISTER
XOR BH,BH
ADD DI,BX ; SET DI TO LAST CHARACTER POSITION
MOV AL,[DI] ; GET LAST CHARACTER READ
POP BX ; RESTORE REGISTER
RET ; RETURN TO CALLING ROUTINE
PAGE
; ;
;*****************************************************************************;
; ;
; CONVERT ASCII TO HEX VERSION 2/21/84 ;
; ;
; CONVERT TWO ASCII CODES IN AX TO ONE HEX NUMBER IN AL ;
; ;
; ENTRY: AL = UPPER ASCII CODE ;
; AH = LOWER ASCII CODE ;
; ;
; EXIT: AL = ONE HEX NUMBER (TWO HEX DIGITS) ;
; CARRY FLAG IS SET IF AN ILLEGAL HEX DIGIT IS IN THE INPUT ;
; ;
; ALTERS: REGISTERS AL AND AH ARE ALTERED ;
; ;
; NOTE: VALID FOR ALL HEX NUMBERS 00 TO FF ;
; ;
;*****************************************************************************;
; ;
ASC_HEX:PUSH BX ; SAVE REGISTERS
MOV BX,AX ; SAVE THE ASCII CODES
CALL CNVRT1 ; RETURNS UPPER DIGIT IN LOWER AL
SHL AL,1 ; PUT IT IN UPPER AL
SHL AL,1
SHL AL,1
SHL AL,1
XCHG AL,BH ; SAVE IN BH & GET LOWER DIGIT
CALL CNVRT1 ; RETURNS LOWER DIGIT IN LOWER AL
OR AL,BH ; COMBINE BOTH HEX DIGITS INTO AL
POP BX ; RESTORE REGISTERS
CLC ; CLEAR CARRY/ERROR FLAG
RET ; RETURN TO CALLING ROUTINE
;
CNVRT1: SUB AL,30H ; PARTIAL CONVERSION
JL CERR ; AL < 0 => ILLEGAL HEX CODE
CMP AL,9 ; CHECK FOR 0 - 9
JLE CEND ; AL <= 9 => 0 - 9
CMP AL,11H ; CHECK FOR A - F
JL CERR ; AL < 11H => ILLEGAL (between '9' and 'A')
SUB AL,7 ; CONVERT A - F
CMP AL,0FH ; AL > 0FH => ILLEGAL
JG CERR ; ERROR EXIT
CEND: RET ; RETURN TO CONTINUE
;
CERR: POP AX ; ERASE FIRST RETURN ADDRESS
SUB AX,AX ; SET RESULT TO ZERO
POP BX ; ADJUST STACK
STC ; SET CARRY/ERROR FLAG
RET ; RETURN TO CALLING ROUTINE
PAGE
; ;
;*****************************************************************************;
; ;
; CONVERT HEX TO ASCII ;
; ;
; CONVERT FROM TWO HEX DIGITS IN AL TO TWO ASCII CODES IN AX ;
; ;
; ENTRY: AL = HEX NUMBER 00H TO FFH ;
; ;
; EXIT: AL = UPPER ASCII CODE ;
; AH = LOWER ASCII CODE ;
; ;
; ALTERS: REGISTERS AL AND AH ARE ALTERED ;
; ;
; NOTE: THIS CONVERSION IS VALID FOR ALL HEX CODES ;
; ;
;*****************************************************************************;
; ;
HEX_ASC:
MOV AH,AL ; Save upper hex digit
CALL CVRT2 ; Convert hex lower digit
XCHG AH,AL ; Save it in AH / get upper digit to convert
SHR AL,1 ; Shift into low nibble
SHR AL,1
SHR AL,1
SHR AL,1
CALL CVRT2 ; Convert upper hex digit
RET ; Return to calling routine
;
; CONVERT ONE HEX DIGIT IN LOWER NIBBLE OF AL INTO ONE ASCII CODE IN AL
;
CVRT2: AND AL,0FH ; Separate out one hex digit
OR AL,30H ; Convert 0 - 9
CMP AL,'9' ; Check for A - F
JLE CVRT4 ; Skip if 0 - 9
ADD AL,07H ; Convert A - F
CVRT4: RET ; Return to calling routine
.XLIST
SUBTTL Messages and Data Storage
PAGE +
.LIST
;
; MESSAGES and DATA STORAGE
;
SEGMSG DB CR,LF,LF,'DO YOU WANT TO DISPLAY A DIFFERENT SEGMENT ? (Y/N) $'
;
SEGMSG2 DB CR,LF,LF,'ENTER THE SEGMENT IN HEX $'
;
SEGMSG3 DB CR,LF,LF,'DISPLAYING FROM SEGMENT NUMBER $'
;
STMSG DB CR,LF,LF,'ENTER THE HEX STARTING ADDRESS $'
;
ENDMSG DB CR,LF,'REPEAT TO LOOK AT MORE ? (Y/N) $'
;
CHARS DW ' '
DB ' $'
;
SPACE DB ' $'
ASCTOP DB ' $'
;
ASCSYM DB ' '
ASCCHAR DB 16 DUP(' ')
;
SEGADD DB 0,0,0,0
ASCSEG DW 0,0
DB ' $'
;
STADD DB 0,0,0,0
ASCADD DW 0,0
DB ' $'
KBUFSZ DB 0,0
KBUF DB ' $'
;
CSEG ENDS
END LOOK