home *** CD-ROM | disk | FTP | other *** search
- 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