mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 18:15:47 +00:00
838 lines
22 KiB
NASM
838 lines
22 KiB
NASM
|
TITLE DEBUGger for MS-DOS
|
|||
|
; DEBUG-86 8086 debugger runs under 86-DOS version 2.30
|
|||
|
;
|
|||
|
; Modified 5/4/82 by AaronR to do all I/O direct to devices
|
|||
|
; Runs on MS-DOS 1.28 and above
|
|||
|
; REV 1.20
|
|||
|
; Tab expansion
|
|||
|
; New device interface (1.29 and above)
|
|||
|
; REV 2.0
|
|||
|
; line by line assembler added by C. Peters
|
|||
|
; REV 2.1
|
|||
|
; Uses EXEC system call
|
|||
|
; REV 2.2
|
|||
|
; Ztrace mode by zibo.
|
|||
|
; Fix dump display to indent properly
|
|||
|
; Parity nonsense by zibo
|
|||
|
;
|
|||
|
; REV 2.3
|
|||
|
; Split into seperate modules to allow for
|
|||
|
; assembly on an IBM PC
|
|||
|
;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
.xlist
|
|||
|
.xcref
|
|||
|
INCLUDE DEBEQU.ASM
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
.cref
|
|||
|
.list
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
|
|||
|
; Structure for system call 72
|
|||
|
|
|||
|
SYSINITVAR STRUC
|
|||
|
DPBHEAD DD ? ; Pointer to head of DPB-FAT list
|
|||
|
sft_addr DD ? ; Pointer to first FCB table
|
|||
|
; The following address points to the CLOCK device
|
|||
|
BCLOCK DD ?
|
|||
|
; The following address is used by DISKSTATCHK it is always
|
|||
|
; points to the console input device header
|
|||
|
BCON DD ? ; Console device entry points
|
|||
|
NUMIO DB 0 ; Number of disk tables
|
|||
|
MAXSEC DW 0 ; Maximum allowed sector size
|
|||
|
BUFFHEAD DD ?
|
|||
|
DEVHEAD DD ?
|
|||
|
SYSINITVAR ENDS
|
|||
|
|
|||
|
ENDIF
|
|||
|
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC 'CODE'
|
|||
|
CODE ENDS
|
|||
|
|
|||
|
CONST SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN USER_PROC_PDB:WORD,STACK:BYTE,CSSAVE:WORD,DSSAVE:WORD
|
|||
|
EXTRN SPSAVE:WORD,IPSAVE:WORD,LINEBUF:BYTE,QFLAG:BYTE
|
|||
|
EXTRN NEWEXEC:BYTE,HEADSAVE:WORD,LBUFSIZ:BYTE,BACMES:BYTE
|
|||
|
EXTRN BADVER:BYTE,ENDMES:BYTE,CARRET:BYTE,ParityMes:BYTE
|
|||
|
|
|||
|
IF IBMVER
|
|||
|
EXTRN DSIZ:BYTE,NOREGL:BYTE,DISPB:WORD
|
|||
|
ENDIF
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
EXTRN CONFCB:BYTE,POUT:DWORD,COUT:DWORD,CIN:DWORD,IOBUFF:BYTE
|
|||
|
EXTRN IOADDR:DWORD,IOCALL:BYTE,IOCOM:BYTE,IOSTAT:WORD,IOCNT:WORD
|
|||
|
EXTRN IOSEG:WORD,COLPOS:BYTE,BADDEV:BYTE,BADLSTMES:BYTE
|
|||
|
EXTRN LBUFFCNT:BYTE,PFLAG:BYTE
|
|||
|
ENDIF
|
|||
|
|
|||
|
CONST ENDS
|
|||
|
|
|||
|
DATA SEGMENT PUBLIC BYTE
|
|||
|
|
|||
|
EXTRN PARSERR:BYTE,DATAEND:WORD,ParityFlag:BYTE,DISADD:BYTE
|
|||
|
EXTRN ASMADD:BYTE,DEFDUMP:BYTE,BYTEBUF:BYTE
|
|||
|
|
|||
|
DATA ENDS
|
|||
|
|
|||
|
DG GROUP CODE,CONST,DATA
|
|||
|
|
|||
|
|
|||
|
CODE SEGMENT PUBLIC 'CODE'
|
|||
|
ASSUME CS:DG,DS:DG,ES:DG,SS:DG
|
|||
|
|
|||
|
PUBLIC RESTART,SET_TERMINATE_VECTOR,DABORT,TERMINATE,COMMAND
|
|||
|
PUBLIC FIND_DEBUG,CRLF,BLANK,TAB,OUT,INBUF,SCANB,SCANP
|
|||
|
PUBLIC PRINTMES,RPRBUF,HEX,OUTSI,OUTDI,OUT16,DIGIT,BACKUP,RBUFIN
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
PUBLIC SETUDEV,DEVIOCALL
|
|||
|
EXTRN DISPREG:NEAR,IN:NEAR
|
|||
|
ENDIF
|
|||
|
|
|||
|
EXTRN PERR:NEAR,COMPARE:NEAR,DUMP:NEAR,ENTER:NEAR,FILL:NEAR
|
|||
|
EXTRN GO:NEAR,INPUT:NEAR,LOAD:NEAR,MOVE:NEAR,NAME:NEAR
|
|||
|
EXTRN REG:NEAR,SEARCH:NEAR,DWRITE:NEAR,UNASSEM:NEAR,ASSEM:NEAR
|
|||
|
EXTRN OUTPUT:NEAR,ZTRACE:NEAR,TRACE:NEAR,GETHEX:NEAR,GETEOL:NEAR
|
|||
|
|
|||
|
EXTRN PREPNAME:NEAR,DEFIO:NEAR,SKIP_FILE:NEAR,DEBUG_FOUND:NEAR
|
|||
|
EXTRN TrapParity:NEAR,ReleaseParity:NEAR
|
|||
|
|
|||
|
ORG 100H
|
|||
|
|
|||
|
START:
|
|||
|
DEBUG:
|
|||
|
JMP SHORT DSTRT
|
|||
|
|
|||
|
HEADER DB "Vers 2.30"
|
|||
|
|
|||
|
DSTRT:
|
|||
|
DOSVER_HIGH EQU 0200H ; 2.00 in hex
|
|||
|
MOV AH,GET_VERSION
|
|||
|
INT 21H
|
|||
|
XCHG AH,AL ; Turn it around to AH.AL
|
|||
|
CMP AX,DOSVER_HIGH
|
|||
|
JAE OKDOS
|
|||
|
GOTBADDOS:
|
|||
|
MOV DX,OFFSET DG:BADVER
|
|||
|
MOV AH,STD_CON_STRING_OUTPUT
|
|||
|
INT 21H
|
|||
|
INT 20H
|
|||
|
|
|||
|
OKDOS:
|
|||
|
CALL TrapParity ; scarf up those parity guys
|
|||
|
MOV AH,GET_CURRENT_PDB
|
|||
|
INT 21H
|
|||
|
MOV [USER_PROC_PDB],BX ; Initially set to DEBUG
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
MOV [IOSEG],CS
|
|||
|
ENDIF
|
|||
|
|
|||
|
MOV SP,OFFSET DG:STACK
|
|||
|
MOV [PARSERR],AL
|
|||
|
MOV AH,GET_IN_VARS
|
|||
|
INT 21H
|
|||
|
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
LDS SI,ES:[BX.BCON]
|
|||
|
MOV WORD PTR CS:[CIN+2],DS
|
|||
|
MOV WORD PTR CS:[CIN],SI
|
|||
|
MOV WORD PTR CS:[COUT+2],DS
|
|||
|
MOV WORD PTR CS:[COUT],SI
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
MOV DX,OFFSET DG:CONFCB
|
|||
|
MOV AH,FCB_OPEN
|
|||
|
INT 21H
|
|||
|
OR AL,AL
|
|||
|
JZ GOTLIST
|
|||
|
MOV DX,OFFSET DG:BADLSTMES
|
|||
|
CALL RPRBUF
|
|||
|
CALL RBUFIN
|
|||
|
CALL CRLF
|
|||
|
MOV CL,[LBUFFCNT]
|
|||
|
OR CL,CL
|
|||
|
JZ NOLIST1 ; User didn't specify one
|
|||
|
XOR CH,CH
|
|||
|
MOV DI,OFFSET DG:(CONFCB + 1)
|
|||
|
MOV SI,OFFSET DG:LINEBUF
|
|||
|
REP MOVSB
|
|||
|
MOV DX,OFFSET DG:CONFCB
|
|||
|
MOV AH,FCB_OPEN
|
|||
|
INT 21H
|
|||
|
OR AL,AL
|
|||
|
JZ GOTLIST ; GOOD
|
|||
|
MOV DX,OFFSET DG:BADDEV
|
|||
|
CALL RPRBUF
|
|||
|
NOLIST1:
|
|||
|
MOV WORD PTR [POUT+2],CS
|
|||
|
MOV WORD PTR [POUT],OFFSET DG:LONGRET
|
|||
|
JMP NOLIST
|
|||
|
|
|||
|
XXX PROC FAR
|
|||
|
LONGRET:RET
|
|||
|
XXX ENDP
|
|||
|
ENDIF
|
|||
|
|
|||
|
GOTLIST:
|
|||
|
IF SYSVER
|
|||
|
MOV SI,DX
|
|||
|
LDS SI,DWORD PTR DS:[SI.fcb_FIRCLUS]
|
|||
|
MOV WORD PTR CS:[POUT+2],DS
|
|||
|
MOV WORD PTR CS:[POUT],SI
|
|||
|
ENDIF
|
|||
|
NOLIST:
|
|||
|
MOV AX,CS
|
|||
|
MOV DS,AX
|
|||
|
MOV ES,AX
|
|||
|
|
|||
|
; Code to print header
|
|||
|
; MOV DX,OFFSET DG:HEADER
|
|||
|
; CALL RPRBUF
|
|||
|
|
|||
|
CALL SET_TERMINATE_VECTOR
|
|||
|
|
|||
|
IF SETCNTC
|
|||
|
MOV AL,23H ; Set vector 23H
|
|||
|
MOV DX,OFFSET DG:DABORT
|
|||
|
INT 21H
|
|||
|
ENDIF
|
|||
|
|
|||
|
MOV DX,CS ; Get DEBUG's segment
|
|||
|
MOV AX,OFFSET DG:DATAEND + 15 ; End of debug
|
|||
|
SHR AX,1 ; Convert to segments
|
|||
|
SHR AX,1
|
|||
|
SHR AX,1
|
|||
|
SHR AX,1
|
|||
|
ADD DX,AX ; Add siz of debug in paragraphs
|
|||
|
MOV AH,CREATE_PROCESS_DATA_BLOCK ; create program segment just after DEBUG
|
|||
|
INT 21H
|
|||
|
MOV AX,DX
|
|||
|
MOV DI,OFFSET DG:DSSAVE
|
|||
|
CLD
|
|||
|
STOSW
|
|||
|
STOSW
|
|||
|
STOSW
|
|||
|
STOSW
|
|||
|
MOV WORD PTR [DISADD+2],AX
|
|||
|
MOV WORD PTR [ASMADD+2],AX
|
|||
|
MOV WORD PTR [DEFDUMP+2],AX
|
|||
|
MOV AX,100H
|
|||
|
MOV WORD PTR[DISADD],AX
|
|||
|
MOV WORD PTR[ASMADD],AX
|
|||
|
MOV WORD PTR [DEFDUMP],AX
|
|||
|
MOV DS,DX
|
|||
|
MOV ES,DX
|
|||
|
MOV DX,80H
|
|||
|
MOV AH,SET_DMA
|
|||
|
INT 21H ; Set default DMA address to 80H
|
|||
|
MOV AX,WORD PTR DS:[6]
|
|||
|
MOV BX,AX
|
|||
|
CMP AX,0FFF0H
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
JAE SAVSTK
|
|||
|
MOV AX,WORD PTR DS:[6]
|
|||
|
PUSH BX
|
|||
|
MOV BX,OFFSET DG:DATAEND + 15
|
|||
|
AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA)
|
|||
|
SUB AX,BX
|
|||
|
POP BX
|
|||
|
SAVSTK:
|
|||
|
PUSH BX
|
|||
|
DEC AX
|
|||
|
DEC AX
|
|||
|
MOV BX,AX
|
|||
|
MOV WORD PTR [BX],0
|
|||
|
POP BX
|
|||
|
MOV SPSAVE,AX
|
|||
|
DEC AH
|
|||
|
MOV ES:WORD PTR [6],AX
|
|||
|
SUB BX,AX
|
|||
|
MOV CL,4
|
|||
|
SHR BX,CL
|
|||
|
ADD ES:WORD PTR [8],BX
|
|||
|
|
|||
|
IF IBMVER
|
|||
|
; Get screen size and initialize display related variables
|
|||
|
MOV AH,15
|
|||
|
INT 10H
|
|||
|
CMP AH,40
|
|||
|
JNZ PARSCHK
|
|||
|
MOV BYTE PTR DSIZ,7
|
|||
|
MOV BYTE PTR NOREGL,4
|
|||
|
MOV DISPB,64
|
|||
|
ENDIF
|
|||
|
|
|||
|
PARSCHK:
|
|||
|
; Copy rest of command line to test program's parameter area
|
|||
|
MOV DI,FCB
|
|||
|
MOV SI,81H
|
|||
|
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
|
|||
|
INT 21H
|
|||
|
CALL SKIP_FILE ; Make sure si points to delimiter
|
|||
|
CALL PREPNAME
|
|||
|
PUSH CS
|
|||
|
POP ES
|
|||
|
FILECHK:
|
|||
|
MOV DI,80H
|
|||
|
CMP BYTE PTR ES:[DI],0 ; ANY STUFF FOUND?
|
|||
|
JZ COMMAND ; NOPE
|
|||
|
FILOOP: INC DI
|
|||
|
CMP BYTE PTR ES:[DI],13 ; COMMAND LINE JUST SPACES?
|
|||
|
JZ COMMAND
|
|||
|
CMP BYTE PTR ES:[DI]," "
|
|||
|
JZ FILOOP
|
|||
|
CMP BYTE PTR ES:[DI],9
|
|||
|
JZ FILOOP
|
|||
|
|
|||
|
CALL DEFIO ; WELL READ IT IN
|
|||
|
MOV AX,CSSAVE
|
|||
|
MOV WORD PTR DISADD+2,AX
|
|||
|
MOV WORD PTR ASMADD+2,AX
|
|||
|
MOV AX,IPSAVE
|
|||
|
MOV WORD PTR DISADD,AX
|
|||
|
MOV WORD PTR ASMADD,AX
|
|||
|
COMMAND:
|
|||
|
CLD
|
|||
|
MOV AX,CS
|
|||
|
MOV DS,AX
|
|||
|
MOV ES,AX
|
|||
|
MOV SS,AX
|
|||
|
MOV SP,OFFSET DG:STACK
|
|||
|
STI
|
|||
|
CMP [ParityFlag],0 ; did we detect a parity error?
|
|||
|
JZ GoPrompt ; nope, go prompt
|
|||
|
MOV [ParityFlag],0 ; reset flag
|
|||
|
MOV DX,OFFSET DG:ParityMes ; message to print
|
|||
|
MOV AH,STD_CON_STRING_OUTPUT; easy way out
|
|||
|
INT 21h ; blam
|
|||
|
GoPrompt:
|
|||
|
MOV AL,PROMPT
|
|||
|
CALL OUT
|
|||
|
CALL INBUF ; Get command line
|
|||
|
; From now and throughout command line processing, DI points
|
|||
|
; to next character in command line to be processed.
|
|||
|
CALL SCANB ; Scan off leading blanks
|
|||
|
JZ COMMAND ; Null command?
|
|||
|
LODSB ; AL=first non-blank character
|
|||
|
; Prepare command letter for table lookup
|
|||
|
SUB AL,"A" ; Low end range check
|
|||
|
JB ERR1
|
|||
|
CMP AL,"Z"-"A" ; Upper end range check
|
|||
|
JA ERR1
|
|||
|
SHL AL,1 ; Times two
|
|||
|
CBW ; Now a 16-bit quantity
|
|||
|
XCHG BX,AX ; In BX we can address with it
|
|||
|
CALL CS:[BX+COMTAB] ; Execute command
|
|||
|
JMP SHORT COMMAND ; Get next command
|
|||
|
ERR1: JMP PERR
|
|||
|
|
|||
|
SET_TERMINATE_VECTOR:
|
|||
|
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set vector 22H
|
|||
|
MOV DX,OFFSET DG:TERMINATE
|
|||
|
INT 21H
|
|||
|
RET
|
|||
|
|
|||
|
TERMINATE:
|
|||
|
CMP BYTE PTR CS:[QFLAG],0
|
|||
|
JNZ QUITING
|
|||
|
MOV CS:[USER_PROC_PDB],CS
|
|||
|
CMP BYTE PTR CS:[NEWEXEC],0
|
|||
|
JZ NORMTERM
|
|||
|
MOV AX,CS
|
|||
|
MOV DS,AX
|
|||
|
MOV SS,AX
|
|||
|
MOV SP,OFFSET DG:STACK
|
|||
|
MOV AX,[HEADSAVE]
|
|||
|
JMP DEBUG_FOUND
|
|||
|
|
|||
|
NORMTERM:
|
|||
|
MOV DX,OFFSET DG:ENDMES
|
|||
|
JMP SHORT RESTART
|
|||
|
|
|||
|
QUITING:
|
|||
|
MOV AX,(EXIT SHL 8)
|
|||
|
INT 21H
|
|||
|
|
|||
|
DABORT:
|
|||
|
MOV DX,OFFSET DG:CARRET
|
|||
|
RESTART:
|
|||
|
MOV AX,CS
|
|||
|
MOV DS,AX
|
|||
|
MOV SS,AX
|
|||
|
MOV SP,OFFSET DG:STACK
|
|||
|
CALL RPRBUF
|
|||
|
JMP COMMAND
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
SETUDEV:
|
|||
|
MOV DI,OFFSET DG:CONFCB
|
|||
|
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
|
|||
|
INT 21H
|
|||
|
CALL USERDEV
|
|||
|
JMP DISPREG
|
|||
|
|
|||
|
USERDEV:
|
|||
|
MOV DX,OFFSET DG:CONFCB
|
|||
|
MOV AH,FCB_OPEN
|
|||
|
INT 21H
|
|||
|
OR AL,AL
|
|||
|
JNZ OPENERR
|
|||
|
MOV SI,DX
|
|||
|
TEST BYTE PTR [SI.fcb_DEVID],080H ; Device?
|
|||
|
JZ OPENERR ; NO
|
|||
|
LDS SI,DWORD PTR [CONFCB.fcb_FIRCLUS]
|
|||
|
MOV WORD PTR CS:[CIN],SI
|
|||
|
MOV WORD PTR CS:[CIN+2],DS
|
|||
|
MOV WORD PTR CS:[COUT],SI
|
|||
|
MOV WORD PTR CS:[COUT+2],DS
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
OPENERR:
|
|||
|
MOV DX,OFFSET DG:BADDEV
|
|||
|
CALL RPRBUF
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
; Get input line. Convert all characters NOT in quotes to upper case.
|
|||
|
|
|||
|
INBUF:
|
|||
|
CALL RBUFIN
|
|||
|
MOV SI,OFFSET DG:LINEBUF
|
|||
|
MOV DI,OFFSET DG:BYTEBUF
|
|||
|
CASECHK:
|
|||
|
LODSB
|
|||
|
CMP AL,'a'
|
|||
|
JB NOCONV
|
|||
|
CMP AL,'z'
|
|||
|
JA NOCONV
|
|||
|
ADD AL,"A"-"a" ; Convert to upper case
|
|||
|
NOCONV:
|
|||
|
STOSB
|
|||
|
CMP AL,13
|
|||
|
JZ INDONE
|
|||
|
CMP AL,'"'
|
|||
|
JZ QUOTSCAN
|
|||
|
CMP AL,"'"
|
|||
|
JNZ CASECHK
|
|||
|
QUOTSCAN:
|
|||
|
MOV AH,AL
|
|||
|
KILLSTR:
|
|||
|
LODSB
|
|||
|
STOSB
|
|||
|
CMP AL,13
|
|||
|
JZ INDONE
|
|||
|
CMP AL,AH
|
|||
|
JNZ KILLSTR
|
|||
|
JMP SHORT CASECHK
|
|||
|
|
|||
|
INDONE:
|
|||
|
MOV SI,OFFSET DG:BYTEBUF
|
|||
|
|
|||
|
; Output CR/LF sequence
|
|||
|
|
|||
|
CRLF:
|
|||
|
MOV AL,13
|
|||
|
CALL OUT
|
|||
|
MOV AL,10
|
|||
|
JMP OUT
|
|||
|
|
|||
|
; Physical backspace - blank, backspace, blank
|
|||
|
|
|||
|
BACKUP:
|
|||
|
MOV SI,OFFSET DG:BACMES
|
|||
|
|
|||
|
; Print ASCII message. Last char has bit 7 set
|
|||
|
|
|||
|
PRINTMES:
|
|||
|
LODS CS:BYTE PTR [SI] ; Get char to print
|
|||
|
CALL OUT
|
|||
|
SHL AL,1 ; High bit set?
|
|||
|
JNC PRINTMES
|
|||
|
RET
|
|||
|
|
|||
|
; Scan for parameters of a command
|
|||
|
|
|||
|
SCANP:
|
|||
|
CALL SCANB ; Get first non-blank
|
|||
|
CMP BYTE PTR [SI],"," ; One comma between params OK
|
|||
|
JNE EOLCHK ; If not comma, we found param
|
|||
|
INC SI ; Skip over comma
|
|||
|
|
|||
|
; Scan command line for next non-blank character
|
|||
|
|
|||
|
SCANB:
|
|||
|
PUSH AX
|
|||
|
SCANNEXT:
|
|||
|
LODSB
|
|||
|
CMP AL," "
|
|||
|
JZ SCANNEXT
|
|||
|
CMP AL,9
|
|||
|
JZ SCANNEXT
|
|||
|
DEC SI ; Back to first non-blank
|
|||
|
POP AX
|
|||
|
EOLCHK:
|
|||
|
CMP BYTE PTR [SI],13
|
|||
|
RET
|
|||
|
|
|||
|
; Hex addition and subtraction
|
|||
|
|
|||
|
HEXADD:
|
|||
|
MOV CX,4
|
|||
|
CALL GETHEX
|
|||
|
MOV DI,DX
|
|||
|
MOV CX,4
|
|||
|
CALL GETHEX
|
|||
|
CALL GETEOL
|
|||
|
PUSH DX
|
|||
|
ADD DX,DI
|
|||
|
CALL OUT16
|
|||
|
CALL BLANK
|
|||
|
CALL BLANK
|
|||
|
POP DX
|
|||
|
SUB DI,DX
|
|||
|
MOV DX,DI
|
|||
|
CALL OUT16
|
|||
|
JMP SHORT CRLF
|
|||
|
|
|||
|
; Print the hex address of DS:SI
|
|||
|
|
|||
|
OUTSI:
|
|||
|
MOV DX,DS ; Put DS where we can work with it
|
|||
|
CALL OUT16 ; Display segment
|
|||
|
MOV AL,":"
|
|||
|
CALL OUT
|
|||
|
MOV DX,SI
|
|||
|
JMP SHORT OUT16 ; Output displacement
|
|||
|
|
|||
|
; Print hex address of ES:DI
|
|||
|
; Same as OUTSI above
|
|||
|
|
|||
|
OUTDI:
|
|||
|
MOV DX,ES
|
|||
|
CALL OUT16
|
|||
|
MOV AL,":"
|
|||
|
CALL OUT
|
|||
|
MOV DX,DI
|
|||
|
|
|||
|
; Print out 16-bit value in DX in hex
|
|||
|
|
|||
|
OUT16:
|
|||
|
MOV AL,DH ; High-order byte first
|
|||
|
CALL HEX
|
|||
|
MOV AL,DL ; Then low-order byte
|
|||
|
|
|||
|
; Output byte in AL as two hex digits
|
|||
|
|
|||
|
HEX:
|
|||
|
MOV AH,AL ; Save for second digit
|
|||
|
; Shift high digit into low 4 bits
|
|||
|
PUSH CX
|
|||
|
MOV CL,4
|
|||
|
SHR AL,CL
|
|||
|
POP CX
|
|||
|
|
|||
|
CALL DIGIT ; Output first digit
|
|||
|
MOV AL,AH ; Now do digit saved in AH
|
|||
|
DIGIT:
|
|||
|
AND AL,0FH ; Mask to 4 bits
|
|||
|
; Trick 6-byte hex conversion works on 8086 too.
|
|||
|
ADD AL,90H
|
|||
|
DAA
|
|||
|
ADC AL,40H
|
|||
|
DAA
|
|||
|
|
|||
|
; Console output of character in AL. No registers affected but bit 7
|
|||
|
; is reset before output.
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
OUT:
|
|||
|
PUSH AX
|
|||
|
AND AL,7FH
|
|||
|
CMP AL,7FH
|
|||
|
JNZ NOTDEL
|
|||
|
MOV AL,8 ; DELETE same as backspace
|
|||
|
NOTDEL:
|
|||
|
CMP AL,9
|
|||
|
JZ TABDO
|
|||
|
CALL DOCONOUT
|
|||
|
CMP AL,0DH
|
|||
|
JZ ZEROPOS
|
|||
|
CMP AL,0AH
|
|||
|
JZ ZEROPOS
|
|||
|
CMP AL,8
|
|||
|
JNZ OOKRET
|
|||
|
MOV AL," "
|
|||
|
CALL DOCONOUT
|
|||
|
MOV AL,8
|
|||
|
CALL DOCONOUT
|
|||
|
CMP BYTE PTR CS:[COLPOS],0
|
|||
|
JZ NOTINC
|
|||
|
DEC BYTE PTR CS:[COLPOS]
|
|||
|
JMP NOTINC
|
|||
|
ZEROPOS:
|
|||
|
MOV BYTE PTR CS:[COLPOS],0FFH
|
|||
|
OOKRET:
|
|||
|
INC BYTE PTR CS:[COLPOS]
|
|||
|
NOTINC:
|
|||
|
TEST BYTE PTR CS:[PFLAG],1
|
|||
|
JZ POPRET
|
|||
|
CALL LISTOUT
|
|||
|
POPRET:
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
|
|||
|
TABDO:
|
|||
|
MOV AL,CS:[COLPOS]
|
|||
|
OR AL,0F8H
|
|||
|
NEG AL
|
|||
|
PUSH CX
|
|||
|
MOV CL,AL
|
|||
|
XOR CH,CH
|
|||
|
JCXZ POPTAB
|
|||
|
TABLP:
|
|||
|
MOV AL," "
|
|||
|
CALL OUT
|
|||
|
LOOP TABLP
|
|||
|
POPTAB:
|
|||
|
POP CX
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
DOCONOUT:
|
|||
|
PUSH DS
|
|||
|
PUSH SI
|
|||
|
PUSH AX
|
|||
|
CONOWAIT:
|
|||
|
LDS SI,CS:[COUT]
|
|||
|
MOV AH,10
|
|||
|
CALL DEVIOCALL
|
|||
|
MOV AX,CS:[IOSTAT]
|
|||
|
AND AX,200H
|
|||
|
JNZ CONOWAIT
|
|||
|
POP AX
|
|||
|
PUSH AX
|
|||
|
MOV AH,8
|
|||
|
CALL DEVIOCALL
|
|||
|
POP AX
|
|||
|
POP SI
|
|||
|
POP DS
|
|||
|
RET
|
|||
|
|
|||
|
|
|||
|
LISTOUT:
|
|||
|
PUSH DS
|
|||
|
PUSH SI
|
|||
|
PUSH AX
|
|||
|
LISTWAIT:
|
|||
|
LDS SI,CS:[POUT]
|
|||
|
MOV AH,10
|
|||
|
CALL DEVIOCALL
|
|||
|
MOV AX,CS:[IOSTAT]
|
|||
|
AND AX,200H
|
|||
|
JNZ LISTWAIT
|
|||
|
POP AX
|
|||
|
PUSH AX
|
|||
|
MOV AH,8
|
|||
|
CALL DEVIOCALL
|
|||
|
POP AX
|
|||
|
POP SI
|
|||
|
POP DS
|
|||
|
RET
|
|||
|
|
|||
|
DEVIOCALL:
|
|||
|
PUSH ES
|
|||
|
PUSH BX
|
|||
|
PUSH CS
|
|||
|
POP ES
|
|||
|
MOV BX,OFFSET DG:IOCALL
|
|||
|
MOV CS:[IOCOM],AH
|
|||
|
MOV WORD PTR CS:[IOSTAT],0
|
|||
|
MOV WORD PTR CS:[IOCNT],1
|
|||
|
MOV CS:[IOBUFF],AL
|
|||
|
MOV WORD PTR CS:[IOADDR+2],DS
|
|||
|
MOV AX,[SI+6]
|
|||
|
MOV WORD PTR CS:[IOADDR],AX
|
|||
|
CALL DWORD PTR CS:[IOADDR]
|
|||
|
MOV AX,[SI+8]
|
|||
|
MOV WORD PTR CS:[IOADDR],AX
|
|||
|
CALL DWORD PTR CS:[IOADDR]
|
|||
|
MOV AL,CS:[IOBUFF]
|
|||
|
POP BX
|
|||
|
POP ES
|
|||
|
RET
|
|||
|
ELSE
|
|||
|
|
|||
|
OUT:
|
|||
|
PUSH DX
|
|||
|
PUSH AX
|
|||
|
AND AL,7FH
|
|||
|
MOV DL,AL
|
|||
|
MOV AH,2
|
|||
|
INT 21H
|
|||
|
POP AX
|
|||
|
POP DX
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
RBUFIN:
|
|||
|
PUSH AX
|
|||
|
PUSH ES
|
|||
|
PUSH DI
|
|||
|
PUSH CS
|
|||
|
POP ES
|
|||
|
MOV BYTE PTR [LBUFFCNT],0
|
|||
|
MOV DI,OFFSET DG:LINEBUF
|
|||
|
FILLBUF:
|
|||
|
CALL IN
|
|||
|
CMP AL,0DH
|
|||
|
JZ BDONE
|
|||
|
CMP AL,8
|
|||
|
JZ ECHR
|
|||
|
CMP AL,7FH
|
|||
|
JZ ECHR
|
|||
|
CMP BYTE PTR [LBUFFCNT],BUFLEN
|
|||
|
JAE BFULL
|
|||
|
STOSB
|
|||
|
INC BYTE PTR [LBUFFCNT]
|
|||
|
JMP SHORT FILLBUF
|
|||
|
|
|||
|
BDONE:
|
|||
|
STOSB
|
|||
|
POP DI
|
|||
|
POP ES
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
|
|||
|
BFULL:
|
|||
|
MOV AL,8
|
|||
|
CALL OUT
|
|||
|
MOV AL,7
|
|||
|
CALL OUT
|
|||
|
JMP SHORT FILLBUF
|
|||
|
|
|||
|
ECHR:
|
|||
|
CMP DI,OFFSET DG:LINEBUF
|
|||
|
JZ FILLBUF
|
|||
|
DEC DI
|
|||
|
DEC BYTE PTR [LBUFFCNT]
|
|||
|
JMP SHORT FILLBUF
|
|||
|
ELSE
|
|||
|
|
|||
|
RBUFIN:
|
|||
|
PUSH AX
|
|||
|
PUSH DX
|
|||
|
MOV AH,10
|
|||
|
MOV DX,OFFSET DG:LBUFSIZ
|
|||
|
INT 21H
|
|||
|
POP DX
|
|||
|
POP AX
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
|
|||
|
IF SYSVER
|
|||
|
RPRBUF:
|
|||
|
PUSHF
|
|||
|
PUSH AX
|
|||
|
PUSH SI
|
|||
|
MOV SI,DX
|
|||
|
PLOOP:
|
|||
|
LODSB
|
|||
|
CMP AL,"$"
|
|||
|
JZ PRTDONE
|
|||
|
CALL OUT
|
|||
|
JMP SHORT PLOOP
|
|||
|
PRTDONE:
|
|||
|
POP SI
|
|||
|
POP AX
|
|||
|
POPF
|
|||
|
RET
|
|||
|
ELSE
|
|||
|
|
|||
|
RPRBUF:
|
|||
|
MOV AH,9
|
|||
|
INT 21H
|
|||
|
RET
|
|||
|
ENDIF
|
|||
|
|
|||
|
; Output one space
|
|||
|
|
|||
|
BLANK:
|
|||
|
MOV AL," "
|
|||
|
JMP OUT
|
|||
|
|
|||
|
; Output the number of blanks in CX
|
|||
|
|
|||
|
TAB:
|
|||
|
CALL BLANK
|
|||
|
LOOP TAB
|
|||
|
RET
|
|||
|
|
|||
|
; Command Table. Command letter indexes into table to get
|
|||
|
; address of command. PERR prints error for no such command.
|
|||
|
|
|||
|
COMTAB DW ASSEM ; A
|
|||
|
DW PERR ; B
|
|||
|
DW COMPARE ; C
|
|||
|
DW DUMP ; D
|
|||
|
DW ENTER ; E
|
|||
|
DW FILL ; F
|
|||
|
DW GO ; G
|
|||
|
DW HEXADD ; H
|
|||
|
DW INPUT ; I
|
|||
|
DW PERR ; J
|
|||
|
DW PERR ; K
|
|||
|
DW LOAD ; L
|
|||
|
DW MOVE ; M
|
|||
|
DW NAME ; N
|
|||
|
DW OUTPUT ; O
|
|||
|
IF ZIBO
|
|||
|
DW ZTRACE
|
|||
|
ELSE
|
|||
|
DW PERR ; P
|
|||
|
ENDIF
|
|||
|
DW QUIT ; Q (QUIT)
|
|||
|
DW REG ; R
|
|||
|
DW SEARCH ; S
|
|||
|
DW TRACE ; T
|
|||
|
DW UNASSEM ; U
|
|||
|
DW PERR ; V
|
|||
|
DW DWRITE ; W
|
|||
|
IF SYSVER
|
|||
|
DW SETUDEV ; X
|
|||
|
ELSE
|
|||
|
DW PERR
|
|||
|
ENDIF
|
|||
|
DW PERR ; Y
|
|||
|
DW PERR ; Z
|
|||
|
|
|||
|
QUIT:
|
|||
|
INC BYTE PTR [QFLAG]
|
|||
|
MOV BX,[USER_PROC_PDB]
|
|||
|
FIND_DEBUG:
|
|||
|
IF NOT SYSVER
|
|||
|
MOV AH,SET_CURRENT_PDB
|
|||
|
INT 21H
|
|||
|
ENDIF
|
|||
|
CALL ReleaseParity ; let system do normal parity stuff
|
|||
|
MOV AX,(EXIT SHL 8)
|
|||
|
INT 21H
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END START
|
|||
|
|