home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
edcom42.a86
< prev
next >
Wrap
Text File
|
1989-12-12
|
47KB
|
2,684 lines
;EDCOM42 WRITTEN BY DOUG COX, OCTOBER 1987, APRIL 1988, JUNE 1988,
;NOVEMBER AND DECEMBER, 1989, USING THE SHAREWARE ASSEMBLER, A86
CODE SEGMENT
JMP MAIN
DB ' (c)1989 by Doug Cox '
EXPLAIN DB 'Type Edcom42 Filename to view/edit Filename$'
NOFILE DB ' not found...$'
DB 8 DUP ('Stack ')
STACKIT DB 'SP'
DISASS DB 0
DB '('
SCRNATTRIB DB 017
TOPATTRIB DB 074
MNEMATTRIB DB 078
INSTRATTRIB DB 01F
CHARATTRIB DB 067
HEXATTRIB DB 047
DB ')'
TOPLINE DB ' CURSOR LOCATION: CONTENTS: '
FIND? DB 'FIND: '
JUMP? DB 'JUMP TO: '
SEARCH DB ' SEARCHING...'
HELP? DB ' (F1 FOR HELP) '
CHARS DB ' EDITING CHARS'
HEXADEC DB ' EDITING HEX '
ESCMSG DB 'ESC or ^KQ : EXIT ^KX or ^KD or ^KS : EXIT & save changes',0
DB 0,'F2 thru F10 : toggle between',0
BLANK DB ' 1. disable edit capability',0
DB ' 2. enable edit capability of typeable chars only',0
DB ' 3. enable edit capability of any character (in hexadecimal)',0
DB 0,' Insert or Delete : toggle assembly language translation on & off',0
DB 0,'Arrow keys or ^S ^E ^X ^D : move cursor ^W : scroll up ^Z : scroll down',0
DB 0,'PgDn or ^C : next screen ^PgDn or ^QC : end of file',0
DB 0,'PgUp or ^R : previous screen ^PgUp or ^QR : beginning of file',0
DB 0,'Home or ^QS: left end of line ^Home or ^QE : top of screen',0
DB 0,'End or ^QD: right end of line ^End or ^QX : bottom of screen',0
DB 0,'TAB or ^F : 10 right Shift-TAB or ^A : 10 left',0
DB 0,'^QF : find hexadecimal or ASCII chars ^L : continue search',0
DB ' (examples: FIND: 07 7F ED FIND: 077FED FIND: ',027,'and the',027
DB ' FIND: "can',027,'t")',0
DB 0,'^J : jump to hexadecimal address in file [ANY KEY TO RETURN...]'
RUTINES DW L00,L01,L02,L03,L04,L05,L06,L06,L00,L01,L02,L03,L04,L05,L0E,RTN ;0
DW L00,L01,L02,L02,L04,L05,L16,L16,L00,L01,L02,L03,L04,L05,L1E,L1E ;1
DW L00,L01,L02,L03,L04,L05,RTN,RTN,L00,L01,L02,L03,L04,L05,RTN,RTN ;2
DW L00,L01,L02,L03,L04,L05,RTN,RTN,L00,L01,L02,L03,L04,L05,RTN,RTN ;3
DW L40,L41,L42,L43,L44,L45,L46,L47,L40,L41,L42,L43,L44,L45,L46,L47 ;4
DW L40,L41,L42,L43,L44,L45,L46,L47,L40,L41,L42,L43,L44,L45,L46,L47 ;5
DW RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN ;6
DW L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70,L70 ;7
DW L80,L81,RTN,L83,L00,L01,L00,L01,L00,L01,L02,L03,L8C,L03,L8E,L01 ;8
DW RTN,L91,L92,L93,L94,L95,L96,L97,RTN,RTN,L9A,RTN,RTN,RTN,RTN,RTN ;9
DW LA0,LA1,LA2,LA3,LA4,LA5,LA4,LA5,L04,L05,LA4,LA5,LA4,LA5,LA4,LA5 ;A
DW LB0,LB1,LB2,LB3,LB4,LB5,LB6,LB7,LB8,LB9,LBA,LBB,LBC,LBD,LBE,LBF ;B
DW RTN,RTN,LCA,RTN,LC4,LC4,LC6,LC7,RTN,RTN,LCA,RTN,RTN,LCD,RTN,RTN ;C
DW LD0,LD1,LD2,LD3,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN,RTN ;D
DW L70,L70,L70,L70,LE4,LE5,LE6,LE7,LE8,LE8,L9A,LEB,LEC,LED,LEE,LEF ;E
DW RTN,RTN,LF2,LF3,RTN,RTN,LF6,LF7,RTN,RTN,RTN,RTN,RTN,RTN,LFE,LFF ;F
EVEN
HANDLE DW 0
BUFOFF DW 0
BUFSEG DW 0
FILEBEG DW 0
FTOPLEF DW 0
TOPLEF DW 0
LTOPLEF DW 0
FILENDO DW 0
FILENDS DW 0
LASTCOL DW 0
FILSIZO DW 0
FILSIZS DW 0
TEMPFIL DW 0
BEGIN DW 0
CURLOC DW 0
SCRNCUR DW 0
OLDSCUR DW 0
ABSLOC1 DW 0
ABSLOC2 DW 0
SAVES DW 0
HEADSIZ DW 0
SAVEBX DW 0
STRCNT DW 0
OLDCUR DW 0
CURSHPE DW 0
CURPTR DW 0
BYTE2 DB 0
ISEXE DB 0
EDFLGS DB 4
MODE DB 0
FINDSTR DB 19 DUP(' ')
REGB DB 'ALCLDLBLAHCHDHBH'
REGW DB 'AXCXDXBXSPBPSIDI'
SEGS DB 'ESCSSSDS'
BW DB ?
ADDR DB '[BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] [BP] [BX] '
__ DB ' '
_AAA DB 'AAA '
_AAD DB 'AAD '
_AAM DB 'AAM '
_AAS DB 'AAS '
_ADC DB 'ADC '
_ADD DB 'ADD '
_AND DB 'AND '
_CALL DB 'CALL '
_CBW DB 'CBW '
_CLC DB 'CLC '
_CLD DB 'CLD '
_CLI DB 'CLI '
_CMC DB 'CMC '
_CMP DB 'CMP '
_CMPS DB 'CMPS '
_CS DB 'CS '
_CWD DB 'CWD '
_DAA DB 'DAA '
_DAS DB 'DAS '
_DEC DB 'DEC '
_DIV DB 'DIV '
_ES DB 'ES '
_HLT DB 'HLT '
_IDIV DB 'IDIV '
_IMUL DB 'IMUL '
_IN DB 'IN '
_INC DB 'INC '
_INT DB 'INT '
_INT3 DB 'INT_3 '
_INTO DB 'INTO '
_IRET DB 'IRET '
_JA DB 'JA '
_JB DB 'JB '
_JBE DB 'JBE '
_JCXZ DB 'JCXZ '
_JG DB 'JG '
_JGE DB 'JGE '
_JL DB 'JL '
_JLE DB 'JLE '
_JMP DB 'JMP '
_JNC DB 'JNC '
_JNO DB 'JNO '
_JNS DB 'JNS '
_JNZ DB 'JNZ '
_JO DB 'JO '
_JP DB 'JP '
_JPE DB 'JPE '
_JPO DB 'JPO '
_JS DB 'JS '
_JZ DB 'JZ '
_LAHF DB 'LAHF '
_LDS DB 'LDS '
_LEA DB 'LEA '
_LES DB 'LES '
_LOCK DB 'LOCK '
_LODS DB 'LODS '
_LOOP DB 'LOOP '
_LOOPNZ DB 'LOOPNZ '
_LOOPZ DB 'LOOPZ '
_MOV DB 'MOV '
_MOVS DB 'MOVS '
_MUL DB 'MUL '
_NEG DB 'NEG '
_NOP DB 'NOP '
_NOT DB 'NOT '
_OR DB 'OR '
_OUT DB 'OUT '
_POP DB 'POP '
_POPF DB 'POPF '
_PUSH DB 'PUSH '
_PUSHF DB 'PUSHF '
_RCL DB 'RCL '
_RCR DB 'RCR '
_REP DB 'REP '
_REPNZ DB 'REPNZ '
_RET DB 'RET '
_RETF DB 'RETF '
_ROL DB 'ROL '
_ROR DB 'ROR '
_SAHF DB 'SAHF '
_SAR DB 'SAR '
_SBB DB 'SBB '
_SCAS DB 'SCAS '
_SHL DB 'SHL '
_SHR DB 'SHR '
_SS DB 'SS '
_STC DB 'STC '
_STD DB 'STD '
_STI DB 'STI '
_STOS DB 'STOS '
_SUB DB 'SUB '
_TEST DB 'TEST '
_WAIT DB 'WAIT '
_XCHG DB 'XCHG '
_XLAT DB 'XLAT '
_XOR DB 'XOR '
INSTRPTR DW _ADD,_ADD,_ADD,_ADD,_ADD,_ADD,_PUSH,_POP ;0
DW _OR,_OR,_OR,_OR,_OR,_OR,_PUSH,__
DW _ADC,_ADC,_ADC,_ADC,_ADC,_ADC,_PUSH,_POP ;1
DW _SBB,_SBB,_SBB,_SBB,_SBB,_SBB,_PUSH,_POP
DW _AND,_AND,_AND,_AND,_AND,_AND,_ES,_DAA ;2
DW _SUB,_SUB,_SUB,_SUB,_SUB,_SUB,_CS,_DAS
DW _XOR,_XOR,_XOR,_XOR,_XOR,_XOR,_SS,_AAA ;3
DW _CMP,_CMP,_CMP,_CMP,_CMP,_CMP,_CS,_AAS
DW _INC,_INC,_INC,_INC,_INC,_INC,_INC,_INC ;4
DW _DEC,_DEC,_DEC,_DEC,_DEC,_DEC,_DEC,_DEC
DW _PUSH,_PUSH,_PUSH,_PUSH,_PUSH,_PUSH,_PUSH,_PUSH ;5
DW _POP,_POP,_POP,_POP,_POP,_POP,_POP,_POP
DW __,__,__,__,__,__,__,__ ;6
DW __,__,__,__,__,__,__,__
DW _JO,_JNO,_JB,_JNC,_JZ,_JNZ,_JBE,_JA ;7
DW _JS,_JNS,_JP,_JPO,_JL,_JGE,_JLE,_JG
DW __,__,__,__,_TEST,_TEST,_XCHG,_XCHG ;8
DW _MOV,_MOV,_MOV,_MOV,_MOV,_LEA,_MOV,_POP
DW _NOP,_XCHG,_XCHG,_XCHG,_XCHG,_XCHG,_XCHG,_XCHG ;9
DW _CBW,_CWD,_CALL,_WAIT,_PUSHF,_POPF,_SAHF,_LAHF
DW _MOV,_MOV,_MOV,_MOV,_MOVS,_MOVS,_CMPS,_CMPS ;A
DW _TEST,_TEST,_STOS,_STOS,_LODS,_LODS,_SCAS,_SCAS
DW _MOV,_MOV,_MOV,_MOV,_MOV,_MOV,_MOV,_MOV ;B
DW _MOV,_MOV,_MOV,_MOV,_MOV,_MOV,_MOV,_MOV
DW __,__,_RET,_RET,_LES,_LDS,_MOV,_MOV ;C
DW __,__,_RETF,_RETF,_INT3,_INT,_INTO,_IRET
DW __,__,__,__,_AAM,_AAD,__,_XLAT ;D
DW __,__,__,__,__,__,__,__
DW _LOOPNZ,_LOOPZ,_LOOP,_JCXZ,_IN,_IN,_OUT,_OUT ;E
DW _CALL,_JMP,_JMP,_JMP,_IN,_IN,_OUT,_OUT
DW _LOCK,__,_REPNZ,_REP,_HLT,_CMC,__,__ ;F
DW _CLC,_STC,_CLI,_STI,_CLD,_STD,__,__
IMMED DW _ADD,_OR,_ADC,_SBB,_AND,_SUB,_XOR,_CMP
SHIFT DW _ROL,_ROR,_RCL,_RCR,_SHL,_SHR,__,_SAR
GRP1 DW _TEST,__,_NOT,_NEG,_MUL,_IMUL,_DIV,_IDIV
GRP2 DW _INC,_DEC,_CALL,_CALL,_JMP,_JMP,_PUSH,__
ISGGPTRS DW IMMED,SHIFT,GRP1,GRP2
MAIN:
;GET MAX FILE SIZE
MOV AH,04A ;FUNCTION TO MODIFY EXTRA MEMORY
MOV BX,0FFFF ;LARGE ENOUGH TO MAKE FUNCTION FAIL (& GIVE AVAIL SPACE)
INT 021
MOV AX,BX ;AVAILABLE MEMORY IN PARAGRAPHS (16 BYTES/PARAGRAPH)
ADD AX,0FB ;EXTRA SPACE USED AT END OF THIS PROGRAM (IN PARAGRAPHS)
SUB DX,DX
MOV BX,16
MUL BX ;TO GET FREE MEMORY SPACE IN BYTES
MOV FILSIZS,DX ;TEMPORARY
MOV FILSIZO,AX ;DITTO
;PREPARE TO READ FILE TO MEMORY BUFFER
MOV AL,B[080] ;DTA
SUB AH,AH
OR AL,AL
JNZ CONTINU ;IF FILENAME WAS ON COMMAND LINE
MOV DX,OFFSET EXPLAIN
MOV AH,9
INT 021
MOV AX,04C00
INT 021
CONTINU:
MOV CX,AX ;SIZE OF FILENAME
ADD AX,081
MOV SI,AX
MOV [SI],AH ;PUT ASCIIZ 0 AT END OF STRING
;CHECK FOR .COM OR .EXE FILE
MOV DI,082
MOV AL,'.'
REPNE SCASB
JCXZ NOEXE
CMP W[DI],'OC'
JNZ NOTCOM
CMP B[DI+2],'M'
JNZ NOTCOM
MOV W[BEGIN],0100 ;BEGINNING ADDRESS OF .COM FILES IS 0100
JMP SHORT NOEXE
NOTCOM:
CMP W[DI],'XE'
JNZ NOEXE
CMP B[DI+2],'E'
JNZ NOEXE
MOV B[ISEXE],0FF ;FLAG
NOEXE:
MOV DX,082
MOV AX,03D02 ;OPEN FUNCTION (FOR READ/WRITE)
INT 021
IF C JMP NOTHERE
MOV HANDLE,AX
;MOVE STACK & CHECK SCREEN
MOV AX,OFFSET STACKIT
MOV SP,AX
MOV AH,0F ;FUNCTION TO CHECK SCREEN MODE
INT 010
MOV MODE,AL ;SAVE IT
;SAVE OLD CURSOR LOCATION
CALL GETCUR
DEC DH
MOV OLDCUR,DX ;ROW IN DH / COL IN DL
MOV CURSHPE,CX ;STARTING & ENDING LINE FOR CURSOR
;SAVE OLD SCREEN
MOV DI,OLDSCR
MOV AX,0B000 ;VIDEO MEMORY ADDRESS
CMP MODE,7
IF NZ MOV AX,0B800 ;IF CGA DISPLAY
MOV DS,AX
SUB SI,SI
MOV CX,2000
REP MOVSW
MOV ES,AX
MOV AX,CS
MOV DS,AX
;GET FILE SIZE
MOV AX,04202
MOV BX,HANDLE
SUB CX,CX
SUB DX,DX
INT 021 ;FILE SIZE IN DX:AX (E.G. 1:2345H)
IF C JMP EXIT
;CHECK IF IT WILL FIT IN AVAILABLE MEMORY
CMP DX,FILSIZS
JC >L1
CMP AX,FILSIZO
IF NC INT 020 ;IF FILE WOULDN'T FIT
L1:
MOV FILSIZS,DX
MOV FILSIZO,AX
;RESET FILE POINTER TO START OF FILE
MOV AX,04200
MOV BX,HANDLE
SUB CX,CX
SUB DX,DX
INT 021
;GET NEW BUFFER SEGMENT ADDRESS & MEMORY ADDR THAT GOES AT TOP LEFT OF SCREEN
MOV AX,PREBUF ;AT END OF THIS CODE (PAST ANOTHER BUFFER)
MOV CL,4
SHR AX,CL ;CHANGE OFFSET-TYPE ADDRESS TO SEGMENT-TYPE ADDRESS
MOV DX,DS
ADD AX,DX
MOV FILEBEG,AX ;NEW SEGMENT ADDRESS BEGINS AT BUFFER
MOV BX,AX
SHL AX,CL ;SHIFT 1 NIBBLE LEFT FOR OFFSET ADDR
ROL BX,CL ;MOVE LEFT NIBBLE TO RIGHT
AND BX,0F ;CLEAR ALL BUT RIGHT-MOST NIBBLE
MOV BUFSEG,BX ;FOR USE IN FIND
MOV BUFOFF,AX ;DITTO
;READ FILE INTO MEMORY BUFFER
MOV BX,HANDLE
MOV BP,FILSIZS
MOV AX,FILSIZO
MOV DX,FILEBEG
READFILE:
MOV TEMPFIL,AX
MOV CX,0FFF0
OR BP,BP
IF Z MOV CX,AX ;IF ONLY 1 SEGMENT TO READ
MOV DS,DX
PUSH DX
SUB DX,DX
MOV AH,03F ;FUNCTION TO READ FILE
INT 021
MOV DX,CS
MOV DS,DX
POP DX
ADD DX,0FFF ;TO INCREMENT DS
IF C JMP EXIT
OR AX,AX
IF Z JMP EXIT
MOV AX,TEMPFIL
SUB AX,0FFF0
SBB BP,0
JNS READFILE ;IF IT DIDN'T DECREMENT LESS THAN 0
CALL DISPLTOP ;PUT TOP LINE ON SCREEN
MOV AH,1 ;FUNCTION TO CHANGE CURSOR SHAPE
MOV CX,7 ;TOP & BOTTOM ROW OF CURSOR
INT 010
;PUT BORDER AROUND SCREEN
MOV AH,0B
MOV BL,SCRNATTRIB
MOV CL,4
SHR BX,CL
AND BX,0F
INT 010
;CHECK FOR .EXE FILE
MOV SI,FILEBEG ;BEGINNING OF FILE IN MEMORY
CMP B[ISEXE],0FF
JNZ NOTEXE
MOV DS,SI
CMP W[0],05A4D ;'MZ' IS AT BEGINNING OF ALL .EXE FILES
JNZ NOTEXE
MOV AX,W[0008] ;WHERE LENGTH OF HEADER IS LOCATED
ADD SI,AX ;MOVE PAST HEADER
MOV CL,4
SHL AX,CL
CS MOV HEADSIZ,AX
MOV AX,W[0016] ;CODE SEGMENT DISPLACEMENT
SUB BX,BX
SHL AX,CL ;CHANGE FROM SEGMENT TO OFFSET
ADC BX,0 ;SEGMENT
ADD AX,W[0014] ;INSTRUCTION POINTER OFFSET
ADC BX,0
MOV DX,CS
MOV DS,DX
MOV SAVES,AX ;OFFSET
MOV SAVEBX,BX ;SEGMENT
NOTEXE:
MOV AX,CS
MOV DS,AX
MOV FTOPLEF,SI
;GET FILE END ADDRESS
MOV BX,BUFSEG
MOV AX,BUFOFF
ADD AX,FILSIZO
ADC BX,FILSIZS
MOV FILENDS,BX
MOV FILENDO,AX
;GET LAST COLUMN
MOV DX,FILSIZS
MOV AX,FILSIZO
SUB AX,1
SBB DX,0
SUB AX,HEADSIZ
SBB DX,0
MOV CX,80
DIV CX ;DX:AX/CX (TO GET REMAINDER IN DX)
MOV LASTCOL,DX ;COLUMNS ON LAST ROW
;GET LAST TOPLEF
MOV AX,FILENDO
MOV BX,FILENDS
SUB FILENDO,1
SBB FILENDS,0
SUB AX,DX ;TO BEGINNING OF LAST LINE
SBB BX,0
SUB AX,1840 ;TO TOP LEFT OF SCREEN (23*80)
SBB BX,0
MOV CL,4
SHR AX,CL
ROR BX,CL ;PUT RIGHT NIBBLE ON LEFT
ADD AX,BX
MOV LTOPLEF,AX
;JUMP TO BEGINNING OF CODE IF .EXE FILE
MOV DI,SAVES
OR DI,DI
JZ FILETOP
MOV BX,SAVEBX
JMP ITSEXE
;JUMPED TO WITH ^PGUP
FILETOP:
MOV SI,FTOPLEF
MOV TOPLEF,SI ;BEGINNING OF SEGMENT IS ALWAYS AT TOPLEF
MOV CURPTR,0 ;CURSOR OFFSET LOCATION
MOV DX,0100 ;ROW 1/COLUMN 0
CALL MOVCUR ;INITIALIZE CURSOR AT TOP LEFT
;DISPLAY FILE
NEWSCRN:
MOV AH,SCRNATTRIB
CMP MODE,7 ;MONOCHROME
IF Z MOV AH,7
SUB SI,SI ;OFFSET OF FILE TO PUT ON SCREEN
MOV DI,160 ;TOP LEFT OF SCREEN
MOV DX,TOPLEF
CMP DX,LTOPLEF
JNC ATEND
MOV CX,1920 ;80*24 SCREEN
CMP DISASS,0
MOV DS,DX ;TOPLEF IS ALSO DATA SEGMENT BEGINNING
JZ DONTSHOALL
CALL MOVIT ;LODSB, STOSW, LOOP
JMP SHORT NEW2
DONTSHOALL:
CALL MOVIT2
JMP SHORT NEW2
ATEND:
MOV BX,FILENDO
MOV DS,DX ;TOPLEF
MOV CL,4
SHL DX,CL ;TO GET OFFSET VALUE OF TOPLEF
NEG DX
ADD BX,DX ;FILENDO-TOPLEF
INC BX
MOV CX,BX
CS CMP DISASS,0
JZ DONTSHOALL2
CALL MOVIT ;PUT LAST PAGE OF FILE ON SCREEN
JMP SHORT >L1
DONTSHOALL2:
CALL MOVIT2
L1:
MOV DX,CS
MOV DS,DX ;PUT DATA SEG BACK
MOV CX,1920 ;80*24 SCREEN (NOT COUNTING TOP LINE)
SUB CX,BX ;SCREEN SIZE - (FILEND-TOPLEF)
MOV AH,SCRNATTRIB
CMP MODE,7 ;MONOCHROME
IF Z MOV AH,7
MOV AL,' '
REP STOSW ;PUT CX BLANKS TO END OF SCREEN
NEW2:
MOV DX,CS
MOV DS,DX ;PUT DATA SEG BACK
;PUT CURSOR LOCATION & CONTENTS AT SCREEN TOP
MOV DX,TOPLEF ;DATA SEGMENT
SUB DX,FTOPLEF ;TO MAKE TOPLEF RELATIVE TO FTOPLEF
MOV BX,DX ;FOR FIRST BIN2HEX CALL
MOV CL,4
SHL DX,CL
ADD DX,CURPTR ;OFFSET ADDR
IF C ADD BX,01000 ;INCREMENT 5TH BYTE
ADD DX,BEGIN
IF C ADD BX,01000
MOV ABSLOC1,BX
MOV ABSLOC2,DX
MOV DI,36 ;LOCATION ON SCREEN
MOV CH,1 ;FOR COUNT
CALL BIN2HEX ;SHOW 5TH BYTE OF LOCATION
MOV BX,DX
MOV CH,4
CALL BIN2HEX ;SHOW OTHER 4 BYTES OF LOCATION
MOV SI,CURPTR ;CURSOR LOCATION IN MEMORY
MOV DS,TOPLEF
MOV BH,[SI] ;CONTENTS
MOV CX,CS
MOV DS,CX
MOV DI,70 ;SCREEN LOC
MOV CH,2 ;2 CHARS
CALL BIN2HEX
DIS:
MOV AH,MNEMATTRIB
CMP MODE,7
IF Z MOV AH,070
CMP EDFLGS,4
JNZ WATE ;IF EDITING CHARS OR HEX
MOV AL,' '
MOV DI,78
MOV CX,25
REP STOSW ;CLEAR PREVIOUS INSTRUCTIONS
CMP DISASS,0FF
JNZ WATE ;IF NOT SHOWING DISASSEMBLY
MOV DX,CURLOC ;CURSOR LOCATION ON SCREEN
SHL DL,1 ;DOUBLE ROW NUMBER
MOV AL,DH ;COLUMN
MOV CL,160
MUL CL
SUB DH,DH
ADD AX,DX
INC AX ;TO WHERE CHAR ATTRIBUTE GOES
MOV DI,AX
MOV OLDSCUR,AX ;OLD SCREEN CURSOR LOCATION
MOV SCRNCUR,AX
MOV AL,INSTRATTRIB
CMP MODE,7
IF Z MOV AL,070
ES MOV B[DI],AL ;HILITE FIRST INSTRUCTION BYTE
ADD SCRNCUR,2
MOV DI,82
DIS2:
MOV BX,OFFSET INSTRPTR
MOV DS,TOPLEF
LODSB
MOV CX,CS
MOV DS,CX
SUB AH,AH
SHL AX,1
PUSH SI,AX
ADD BX,AX
MOV SI,[BX] ;LOCATION OF FIRST INSTRUCTION IN INSTRPTR
MOV AH,MNEMATTRIB
CMP MODE,7
IF Z MOV AH,070
INSTRLP:
LODSB
STOSW
CMP AL,' '
JNZ INSTRLP
POP AX,SI
MOV BX,OFFSET RUTINES
ADD BX,AX
CALL [BX]
;READ KEYBOARD
WATE:
SUB AH,AH ;FUNCTION TO READ KEYBOARD
INT 016 ;PROGRAM STAYS HERE, MOSTLY
OR AL,AL
JZ EXTENDED_CODE
CMP AL,' '
JL CTRL_CODE
JMP INPUT
CTRL_CODE:
CALL CASE ;TO JUMP TO FOLLOWING SUBROUTINES
DB 17 ;NUMBER OF FOLLOWING SUBROUTINES
DB 10 ;^J
DW JUMP
DB 12 ;^L
DW AGAIN
DB 27 ;ESC
DW EXIT
DB 18 ;^R
DW PREV
DB 3 ;^C
DW NEXT
DB 5 ;^E
DW CURUP
DB 24 ;^X
DW CURDN
DB 19 ;^S
DW CURLFT
DB 4 ;^D
DW CURRT
DB 23 ;^W
DW UP
DB 26 ;^Z
DW DOWN
DB 6 ;^F
DW MOVRT
DB 1 ;^A
DW MOVLFT
DB 9 ;TAB
DW MOVRT
DB 11 ;^K
DW KMENU
DB 17 ;^Q
DW QMENU
DB 13 ;ENTER
DW INPUT
DW WATE
EXTENDED_CODE:
MOV AL,AH
CALL CASE
DB 27 ;NUMBER OF SUBROUTINES TO CHECK
DB 59 ;F1
DW EMENU
DB 60 ;F2
DW EDIT
DB 61 ;F3
DW EDIT
DB 62 ;F4
DW EDIT
DB 63
DW EDIT
DB 64
DW EDIT
DB 65
DW EDIT
DB 66
DW EDIT
DB 67
DW EDIT
DB 68 ;F10
DW EDIT
DB 71 ;HOME
DW LFTSIDE
DB 79 ;END
DW RTSIDE
DB 73 ;PGUP
DW PREV
DB 81 ;PGDN
DW NEXT
DB 72 ;UP ARROW
DW CURUP
DB 80 ;DOWN ARROW
DW CURDN
DB 75 ;LEFT ARROW
DW CURLFT
DB 77 ;RIGHT ARROW
DW CURRT
DB 116 ;^RIGHT ARROW
DW MOVRT
DB 115 ;^LEFT ARROW
DW MOVLFT
DB 132 ;^PGUP
DW FILETOP
DB 118 ;^PGDN
DW GOEND
DB 119 ;^HOME
DW SCRTOP
DB 117 ;^END
DW SCRBOT
DB 15 ;SHIFT-TAB
DW MOVLFT
DB 82 ;INSERT
DW TOGGLEDIS
DB 83 ;DELETE
DW TOGGLEDIS
DW WATE ;GO THERE IF NOT ONE OF ABOVE
QMENU:
MOV B ES:[122],'^'
MOV B ES:[124],'Q'
SUB AH,AH
INT 016H
MOV B ES:[122],' '
MOV B ES:[124],' '
AND AL,01F
CALL CASE
DB 7 ;NUMBER OF FOLLOWING SUBROUTINES
DB 18 ;^R
DW FILETOP
DB 3 ;^C
DW GOEND
DB 5 ;^E
DW SCRTOP
DB 24 ;^X
DW SCRBOT
DB 19 ;^S
DW LFTSIDE
DB 4 ;^D
DW RTSIDE
DB 6 ;^F
DW FIND
DW WATE
KMENU:
MOV B ES:[122],'^'
MOV B ES:[124],'K'
SUB AH,AH
INT 016
MOV B ES:[122],' '
MOV B ES:[124],' '
AND AL,01F
CALL CASE
DB 4
DB 17 ;^Q
DW EXIT
DB 24 ;^X
DW WRITE
DB 4 ;^D
DW WRITE
DB 19 ;^S
DW WRITE
DW WATE
INPUT:
CMP DISASS,0FF
JNZ NOJUMP ;IF NOT SHOWING DISASSEMBLY
CMP EDFLGS,4
JNZ NOJUMP ;IF EDITING CHARS OR HEX
MOV CX,SCRNCUR
SUB CX,OLDSCUR
JZ NOJUMP
SHR CX,1
NEXTINSTR:
PUSH CX
CALL RTCUR ;MOVE CURSOR RIGHT TO NEXT INSTRUCTION
POP CX
LOOP NEXTINSTR
JMP NEWSCRN
NOJUMP:
CMP EDFLGS,2
JNZ HEXINPUT
MOV SI,CURPTR
MOV DS,TOPLEF
CMP B[SI],' '
JB NOTHEX
CMP B[SI],'~'
JA NOTHEX
MOV [SI],AL ;PUT INPUT IN MEMORY
MOV DX,CS
MOV DS,DX
MOV AH,0AH ;FUNCTION TO WRITE CHAR TO SCREEN
SUB BH,BH ;SCREEN PAGE
MOV CX,1
INT 010
JMP CURRT
HEXINPUT:
CMP EDFLGS,3
IF NZ JMP WATE
MOV BL,AL ;SAVE INPUT
CALL HEX2BIN
JC NOTHEX ;IF NOT GOOD HEX INPUT
MOV DL,AL ;SAVE BINARY REPRESENTATION
CMP BL,'a'
IF NC SUB BL,020 ;MAKE LETTERS UPPERCASE
ES MOV [70],BL ;DISPLAY FIRST HEX INPUT
ES MOV B[72],'_'
SUB AH,AH
INT 016
MOV BH,AL ;SAVE SECOND HEX INPUT
CALL HEX2BIN
JC NOTHEX
MOV DH,AL ;SAVE SECOND BINARY REPRESENTATION
ES MOV [72],BH ;DISPLAY SECOND INPUT
MOV CL,4
SHL DL,CL
OR DL,DH
MOV SI,CURPTR
MOV DS,TOPLEF
MOV [SI],DL ;PUT REVISION IN MEMORY
MOV CX,CS
MOV DS,CX
JMP NEWSCRN
NOTHEX:
MOV DX,CS
MOV DS,DX
MOV AL,7 ;BEEP
MOV AH,0E ;FUNCTION TO WRITE CHAR
SUB BH,BH ;PAGE
MOV CX,1
INT 010
JMP NEWSCRN
TOGGLEDIS:
XOR DISASS,0FF
JMP NEWSCRN
EDIT:
CALL DISPLTOP
INC EDFLGS
CMP EDFLGS,5
IF Z MOV EDFLGS,2
CMP EDFLGS,2
JZ EDCHARS
CMP EDFLGS,3
JZ EDHEX
UNEDIT:
MOV EDFLGS,4
MOV SI,OFFSET HELP?
MOV AH,TOPATTRIB
JMP SHORT SHOIT
EDCHARS:
MOV SI,OFFSET CHARS
MOV AH,CHARATTRIB
JMP SHORT PRESHOIT
EDHEX:
MOV SI,OFFSET HEXADEC
MOV AH,HEXATTRIB
PRESHOIT:
PUSH AX,SI
MOV AH,TOPATTRIB
CMP MODE,7
IF Z MOV AH,070
MOV SI,OFFSET HELP?
MOV DI,82
MOV CX,20
CALL MOVIT
POP SI,AX
SHOIT:
CMP MODE,7
IF Z MOV AH,070
MOV DI,130
MOV CX,15
CALL MOVIT
JMP NEWSCRN
;F1
EMENU:
MOV SI,OFFSET ESCMSG
EMENU2:
CALL HIDECUR
CALL MENWRT
CMP AL,11 ;^K
JNZ NOTCTRLK
MOV B ES:[442],'^'
MOV B ES:[444],'K'
SUB AH,AH
INT 016
MOV B ES:[442],' '
MOV B ES:[444],' '
AND AL,01F
CMP AL,17 ;^Q
IF Z JMP EXIT
CMP AL,24 ;^X
IF Z JMP WRITE
CMP AL,4 ;^D
IF Z JMP WRITE
CMP AL,19 ;^S
IF Z JMP WRITE
NOTCTRLK:
PUSH AX
MOV DX,CURLOC
CALL MOVCUR
POP AX
CMP AX,03C00 ;F2
JB >L1
CMP AX,04400 ;F10
IF BE JMP EDIT
L1:
PUSH AX
CALL DISPLTOP
POP AX
CMP AX,05200 ;INSERT
IF Z XOR DISASS,0FF
CMP AX,05300 ;DELETE
IF Z XOR DISASS,0FF
CMP EDFLGS,2
IF Z JMP EDCHARS
CMP EDFLGS,3
IF Z JMP EDHEX
JMP NEWSCRN
;***CURSOR MOVEMENT***
;^HOME
SCRTOP:
MOV DX,CURLOC
MOV AL,80
MUL DH
SUB CURPTR,AX
ADD CURPTR,80 ;BECAUSE TOP ROW HERE IS 1 NOT 0
MOV DH,1 ;TOP ROW
CALL MOVCUR
JMP NEWSCRN
;^END
SCRBOT:
MOV DX,CURLOC
MOV AL,24 ;BOTTOM ROW
SUB AL,DH ;CURSOR ROW
MOV AH,80
MUL AH
ADD CURPTR,AX
;NOW TEST FOR END OF FILE
MOV AX,TOPLEF ;SEGMENT & TOPLEFT OF SCREEN
CMP AX,LTOPLEF
JNC SCRBOT2 ;IF AT OR PAST LAST TOPLEFT
MOV DH,24 ;BOTTOM ROW
CALL MOVCUR
JMP NEWSCRN
SCRBOT2:
CALL CUREND
JMP NEWSCRN
;^PGDN
GOEND:
MOV AX,LTOPLEF
CMP AX,TOPLEF
JC SCRBOT ;IF FILE DOESN't fill screen
MOV TOPLEF,AX
MOV AX,LASTCOL
MOV DX,AX
MOV DH,018H ;ROW 24
ADD AX,1840 ;80*23
MOV CURPTR,AX
CALL MOVCUR
JMP NEWSCRN
;HOME
LFTSIDE:
MOV DX,CURLOC
PUSH DX
SUB DH,DH
SUB CURPTR,DX ;DECREMENT CURPTR TO 1ST COL
POP DX
SUB DL,DL
CALL MOVCUR
JMP NEWSCRN
;END
RTSIDE:
MOV AX,TOPLEF
CMP AX,LTOPLEF
JC RTSIDE2
MOV CL,4
SHL AX,CL
ADD AX,CURPTR
MOV BX,FILENDO
SUB BX,LASTCOL
CMP AX,BX ;BEGINNING OF LAST LINE OF FILE
JC RTSIDE2
CALL CUREND
JMP NEWSCRN
RTSIDE2:
MOV DX,CURLOC
MOV AL,79
SUB AL,DL
SUB AH,AH
ADD CURPTR,AX
MOV DL,79
CALL MOVCUR
JMP NEWSCRN
;PGUP
PREV:
MOV AX,FTOPLEF
CMP AX,TOPLEF
IF Z JMP WATE
ADD AX,078 ;1920D SHIFTED RIGHT (24*80) SCREEN
CMP AX,TOPLEF
IF NC JMP FILETOP
SUB TOPLEF,078
JMP NEWSCRN
;PGDN
NEXT:
MOV AX,TOPLEF
CMP AX,LTOPLEF
IF NC JMP WATE ;IF AT END OF FILE
ADD AX,078 ;1920D SHIFTED RIGHT
MOV TOPLEF,AX
CMP AX,LTOPLEF
IF NC CALL CUREND
JMP NEWSCRN
;LEFT ARROW
CURLFT:
CALL LFTCUR
JMP NEWSCRN
;RIGHT ARROW
CURRT:
CALL RTCUR
JMP NEWSCRN
;^RIGHT ARROW
MOVRT:
MOV CX,10
RTLP:
PUSH CX
CALL RTCUR
POP CX
LOOP RTLP
JMP NEWSCRN
;^LEFT ARROW
MOVLFT:
MOV CX,10
LFTLP:
PUSH CX
CALL LFTCUR
POP CX
LOOP LFTLP
JMP NEWSCRN
;UP ARROW
CURUP:
CALL SCRLOCK
JNZ UP ;IF SCROLLLOCK IS ON
MOV DX,CURLOC
CMP DH,1
JE CURUP2 ;IF ON TOP LINE
DEC DH
CALL MOVCUR
SUB CURPTR,80
JMP NEWSCRN
CURUP2:
MOV AX,TOPLEF
CMP AX,FTOPLEF
IF Z JMP WATE
SUB TOPLEF,5
JMP NEWSCRN
;SCROLLLOCK ON
UP:
MOV AX,TOPLEF
CMP AX,FTOPLEF
IF Z JMP WATE ;IF AT BEGINNING OF FILE
SUB TOPLEF,5
MOV DX,CURLOC
CMP DH,24
JE DOWNEND ;IF AT BOTTOM
INC DH
CALL MOVCUR
ADD CURPTR,80 ;BECAUSE OF TOPLEF CHANGE
JMP NEWSCRN
JMPWATE:
JMP WATE
;DOWN ARROW
CURDN:
CALL SCRLOCK
JNZ DOWN ;IF SCROLLLOCK IS ON
MOV AX,TOPLEF
CMP AX,LTOPLEF
JC CURDN3 ;IF NOT AT LAST SCREEN OF FILE
MOV CL,4
SHL AX,CL
ADD AX,CURPTR
MOV BX,FILENDO
NEG AX
ADD BX,AX
CMP BX,80
JC JMPWATE
CURDN3:
MOV DX,CURLOC
CMP DH,24
JE CURDN2 ;IF ON BOTTOM LINE
INC DH
CALL MOVCUR
ADD CURPTR,80
JMP NEWSCRN
CURDN2:
MOV AX,TOPLEF
ADD AX,5
MOV TOPLEF,AX
CMP AX,LTOPLEF
IF NC CALL CUREND ;IF AT LAST SCREEN OF FILE
JMP NEWSCRN ;DON't need to increment curptr
;SCROLLLOCK ON
DOWN:
MOV AX,TOPLEF
CMP AX,LTOPLEF
JNC JMPWATE ;IF AT END OF FILE
ADD TOPLEF,5 ;80 SHIFTED RIGHT
MOV DX,CURLOC
CMP DH,1
JE DOWNEND ;IF CURSOR IS ON TOP LINE
DEC DH
CALL MOVCUR
SUB CURPTR,80 ;BECAUSE OF TOPLEF CHANGE
DOWNEND:
JMP NEWSCRN
;***
;JUMP TO INPUT HEX ADDRESS
JUMP:
MOV SI,OFFSET JUMP?
CALL TOP
MOV BP,96 ;FOR SCREEN LOCATION IN GETSTR
CALL GETSTR ;GET INPUT
IF S JMP FINDXIT ;IF NO INPUT
MOV SI,DI ;JUST AFTER LAST INPUT CHAR ON SCREEN
SUB DI,DI ;FOR OFFSET ADDRESS
SUB BX,BX ;FOR SEGMENT ADDRESS
MOV DX,0004 ;DH FOR CL & DL FOR LOOP
;GET OFFSET ADDRESS
L1:
SUB SI,2
CMP SI,96 ;INPUT SCREEN LOCATION
JL >L2 ;IF NO GOOD INPUT
MOV AL,ES:[SI]
CALL HEX2BIN ;CONVERT TO BINARY
JC L1 ;IF NOT HEXADECIMAL
MOV CL,DH
ADD DH,4 ;TO ROL AX TO NEXT NIBBLE TO LEFT
SUB AH,AH ;ROL CHANGES IT
ROL AX,CL
OR DI,AX ;TA DAA!
DEC DL
JNZ L1
;GET SEGMENT ADDRESS (IF FIFTH CHAR NOT INPUT,IT's 0)
SUB SI,2
MOV AL,ES:[SI]
CALL HEX2BIN
JC >L2
MOV BL,AL
JMP SHORT >L21
L2:
CMP DI,BEGIN
IF C MOV DI,BEGIN
L21:
SUB DI,BEGIN
SBB BX,0
CMP BX,FILSIZS
JC >L4
JG >L3
CMP DI,FILSIZO
JC >L4
L3:
MOV DI,FILSIZO
MOV BX,FILSIZS
L4:
ITSEXE:
MOV SAVES,ES
MOV BP,FTOPLEF
MOV AX,DI
MOV DX,BX
MOV CL,4
ROR BX,CL
JMP THERE
FIND:
MOV SI,OFFSET FIND?
CALL TOP
MOV BP,90 ;SCREEN ADDRESS OFFSET
CALL GETSTR ;GET INPUT & STRING COUNT-1 IN STRCNT
IF S JMP FINDXIT ;IF NO INPUT OR ESC PRESSED
MOV SI,90
MOV DI,OFFSET FINDSTR
;CHECK TO SEE IF ASCII STRING
CMP B ES:[SI],027 ;'
JZ FINDASCII
CMP B ES:[SI],022 ;"
JZ FINDASCII
;CONVERT ASCII HEX TO BINARY & STORE IT IN FINDSTR
MOV STRCNT,0 ;RE-COMPUTE IT
MOV CX,18
CONVHEX:
MOV AL,ES:[SI]
CMP AL,' '
JZ SKIP
CMP AL,','
JZ SKIP
CALL HEX2BIN ;CONVERTS ASCII HEX CHAR TO BINARY
IF C JMP FINDXIT ;IF NOT ASCII HEX INPUT
PUSH CX
MOV CL,4
SHL AL,CL
POP CX
MOV DS:[DI],AL
ADD SI,2 ;TO NEXT ASCII HEX INPUT
MOV AL,ES:[SI]
CALL HEX2BIN
JNC PART2
CMP AL,' '
JZ >L1
CMP AL,','
JZ >L1
JMP FINDXIT
L1:
PUSH CX
MOV CL,4
MOV AL,DS:[DI]
SHR AL,CL ;PUT FIRST DIGIT BACK AT RIGHT SIDE
POP CX
MOV DS:[DI],AL
JMP SHORT PART1
PART2:
OR DS:[DI],AL
PART1:
INC DI
INC STRCNT
SKIP:
ADD SI,2
LOOP CONVHEX
DEC STRCNT
JMP SHORT REPEAT
FINDASCII:
ADD SI,2 ;DON't look for the ' or "
DEC STRCNT
MOV CX,17
;STORE STRING IN FINDSTR
STORSTR:
MOV AL,ES:[SI]
CMP AL,ES:[90] ;' or "
JNZ >L4
DEC STRCNT
MOV AL,' '
L4:
MOV DS:[DI],AL
INC DI
ADD SI,2
LOOP STORSTR
REPEAT:
MOV BP,TOPLEF
MOV SI,OFFSET SEARCH ;'SEARCHING...'
CALL TOP
;SEARCH FOR STRING
MOV DI,BP ;EITHER TOPLEF OR FTOPLEF
MOV BX,DI ;FOR ABSOLUTE SEGMENT ADDR
AND BX,0F000
MOV CL,4
SHL DI,CL
MOV AX,CURPTR
INC AX ;TO START LOOKING 1 BYTE BEYOND CURRENT CURSOR LOCATION
ADD DI,AX ;TO GET ABSOLUTE OFFSET ADDR
IF C ADD BX,01000
MOV BP,BX ;FOR CURRENT ABSOLUTE SEG ADDR
MOV SAVES,ES
MOV ES,BP ;BEGINNING OF FILE SEGMENT
ROL BX,CL ;MOVE LEFT NIBBLE TO RIGHT (CL IS ALREADY 4)
MOV CX,FILENDO ;FOR REPNZ SCASB,BELOW (MAY BE 0,SEE BELOW)
INC CX ;BECAUSE CURPTR WAS INCREMENTED
NEG BX
ADD BX,FILENDS ;TO GET FILENDS - CURRENT SEGMENT IN BX
FINDLOOP:
IF NZ MOV CX,0FFFF ;IF CURSOR NOT IN SAME ABSOLUTE SEGEMENT AS FILEND
SUB CX,DI ;TO GET EITHER FILENDO OR 0FFFF - CURRENT ABSOLUTE OFFSET
FINDLP2:
OR CX,CX
JZ QUITFIND
MOV SI,OFFSET FINDSTR ;ADDRESS OF STRING TO FIND
MOV AL,[SI] ;FIRST CHAR
REPNZ SCASB ;REPEAT UNTIL Z=TRUE OR CX=0
JZ STRCHK ;IF FIRST CHAR FOUND
OR BX,BX ;NO. OF REMAINING SEGMENTS TO SEARCH
JNZ NEWSEG
QUITFIND:
JMP NOTFOUND
NEWSEG:
SCASB ;BECAUSE DI ONLY GOT TO 0FFFF, NOT 0
JZ STRCHK
ADD BP,01000
MOV ES,BP ;INCREMENTS ABSOLUTE SEGMENT
MOV CX,FILENDO
INC CX
DEC BX
JMP SHORT FINDLOOP
;CALLED ONLY IN EXTREMELY RARE CIRCUMSTANCE, BUT I GUESS IT's necessary...
CHNGSEG:
OR BX,BX
JZ NOTFOUND
PUSH BP,ES
ADD BP,01000
MOV ES,BP
REPZ CMPSB
POP ES,BP
JMP SHORT RETCHKLP
STRCHK:
MOV AX,DI ;SAVE IT
MOV DX,CX ;DITTO
MOV CX,STRCNT ;STRING LENGTH-1 FROM GETSTR SUBROUTINE
OR CX,CX
JZ FOUND ;IF ONLY SEARCHING FOR 1 CHAR
INC SI ;POINT TO REMAINDER OF STRING
CHKLP:
OR DI,DI
JZ CHNGSEG ;IF SEARCHING PAST END OF SEGMENT
CMPSB ;COMPARE STRINGS (REPEAT UNTIL Z=FALSE OR CX=0)
LOOPZ CHKLP
RETCHKLP:
MOV CX,DX
MOV DI,AX
JNZ FINDLP2 ;IF STRING NOT FOUND
;JUMP TO ADDRESS
FOUND:
MOV DX,BP ;CURRENT SEGMENT
MOV CL,4
ROL DX,CL
OR DI,DI
JNZ SAMESEG
DEC DX
SUB BP,01000
SAMESEG:
DEC DI ;OFFSET ADDR
MOV AX,DI
SUB AX,BUFOFF
SBB DX,BUFSEG
SUB AX,HEADSIZ
SBB DX,0
MOV BX,BP ;SEG ADDR
SUB BP,BP ;USED LATER (JUMP ALSO USES BP LATER)
THERE:
CMP DX,010 ;SEGMENT ADDRESS
JNC NOTFOUND ;AN IMPOSSIBILITY...
MOV CX,80
DIV CX ;REMAINDER IS IN DX (& DL = COLUMN)
MOV CURPTR,DX ;COLUMN (DH=0)
SUB DI,DX ;TO GET TOPLEF
IF C SUB BX,01000
MOV CL,4
SHR DI,CL
ADD DI,BX
ADD DI,BP
MOV TOPLEF,DI ;TA-DAA!
MOV DH,1 ;PUT CURSOR ON FIRST ROW
MOV CURLOC,DX ;FOR MOVCUR
;CLEAR MESSAGE & EXIT
NOTFOUND:
MOV ES,SAVES
FINDXIT:
CALL WRITEBLANKS
MOV DX,CURLOC
CALL MOVCUR
MOV AH,1 ;FUNCTION TO CHANGE CURSOR SHAPE
MOV CX,7 ;TOP & BOTTOM ROW OF CURSOR
INT 010
JMP NEWSCRN
;LOOK FOR STRING AGAIN
AGAIN:
CALL HIDECUR
JMP SHORT REPEAT
NOTHERE:
MOV SI,081
MOV AL,[080]
SUB AH,AH
ADD SI,AX
MOV B[SI],'$'
MOV DX,081
MOV AH,9
INT 021
MOV DX,OFFSET NOFILE
MOV AH,9
INT 021
MOV AX,04C00
INT 021
WRITE:
MOV AX,04200 ;FUNCTION TO MOVE FILE POINTER TO BEGINNING OF FILE
MOV BX,HANDLE
SUB CX,CX
SUB DX,DX
INT 021
;WRITE FILE TO DISK
MOV BP,FILSIZS
MOV DX,FILEBEG
MOV AX,FILSIZO
WRITELP:
MOV TEMPFIL,AX
MOV CX,0FFF0
OR BP,BP
IF Z MOV CX,AX
MOV DS,DX
PUSH DX
SUB DX,DX
MOV AH,040 ;FUNCTION TO WRITE FILE
INT 021
MOV DX,CS
MOV DS,DX
POP DX
ADD DX,0FFF
JC EXIT
OR AX,AX
JZ EXIT
MOV AX,TEMPFIL
SUB AX,0FFF0
SBB BP,0
JNS WRITELP
;RETURN TO DOS
EXIT:
;RESTORE OLD CURSOR LOCATION
MOV DX,OLDCUR ;OLD CURSOR LOCATION
MOV AH,1 ;FUNCTION TO SET CURSOR TYPE
MOV CX,CURSHPE ;STARTING & ENDING LINE OF CURSOR
INT 010
CALL MOVCUR
;BLANK BORDER
MOV AH,0B
SUB BX,BX
INT 010
;RESTORE OLD SCREEN
SUB DI,DI
MOV SI,OLDSCR
MOV CX,2000
REP MOVSW
MOV AX,04C00 ;TERMINATE WITH RETURN CODE
INT 021 ;RETURN TO DOS
;******SUBROUTINES******
DISPLTOP:
MOV SI,OFFSET TOPLINE
SUB DI,DI ;LOCATION ON SCREEN
MOV CX,41 ;FOR COUNT
MOV AH,TOPATTRIB
CMP MODE,7 ;MONOCHROME
IF Z MOV AH,070 ;REVERSE IMAGE
CALL MOVIT ;MOVE [SI] INTO [DI] & INC DI CX TIMES
MOV AL,' '
MOV CX,24
REP STOSW
MOV SI,OFFSET HELP?
MOV CX,15
CALL MOVIT
RET
;PUT 'FIND:' or 'JUMP TO:' on top line of screen
TOP:
MOV CX,13
MOV DI,78
MOV AH,TOPATTRIB
CMP MODE,7
IF Z MOV AH,070
CALL MOVIT
MOV AL,' '
MOV CX,12
REP STOSW
RET
WRITEBLANKS:
MOV AL,' '
MOV CX,25
MOV DI,78
BLANKLP:
STOSB
INC DI
LOOP BLANKLP
RET
;TO MOVE A STRING AT [DI] TO [SI] (ATTRIBUTE IN AH)
MOVIT:
LODSB
STOSW
LOOP MOVIT
RET
MOVIT2:
LODSB
CMP AL,07F
JNC SHODOT
CMP AL,020
JNC SHOLET
SHODOT:
MOV AL,'.'
SHOLET:
STOSW
LOOP MOVIT2
RET
;TO PUT CURSOR AT END OF FILE
CUREND:
MOV DX,TOPLEF
MOV CL,4
SHL DX,CL
MOV AX,FILENDO
NEG DX
ADD AX,DX
MOV CURPTR,AX
MOV CL,80
DIV CL
INC AL
MOV DH,AL ;QUOTIENT (ANSWER) (FOR ROW)
MOV DL,AH ;REMAINDER (FOR COLUMN)
JMP SHORT MOVCUR
;PUT ROW IN DH & COL IN DL
GETCUR:
MOV AH,3
SUB BH,BH
INT 010
MOV CURLOC,DX
RET
;SAVE CURSOR LOCATION
HIDECUR:
MOV DX,01900 ;ROW 25,COL 0
JMP SHORT MOVCUR2
;MOVE CURSOR TO ROW IN DH & COL IN DL
MOVCUR:
MOV CURLOC,DX
MOVCUR2:
MOV AH,2
SUB BH,BH
INT 010
RET
;TO JUMP TO A SUBROUTINE (SEMI-TRICK)
CASE:
POP BX ;RET ADDRESS
MOV CL,[BX] ;NUMBER OF COMPARISONS TO MAKE
SUB CH,CH
CASLOP:
INC BX ;TO A DB
CMP AL,[BX]
JE GO
ADD BX,2 ;TO A DW
LOOP CASLOP
GO:
INC BX ;TO A DW
JMP [BX]
LCA:
;TO CHANGE BINARY TO HEX
BIN2HEXW:
CALL SHOWORD
MOV DS,TOPLEF
LODSW
BIN2HEXW2:
MOV CH,4
MOV BX,AX
JMP SHORT BIN2HEXSKP
LCD:
BIN2HEXB:
CALL SHOBYTE
MOV DS,TOPLEF
LODSB
MOV CH,2
MOV BH,AL
BIN2HEXSKP:
PUSH CS
POP DS
BIN2HEX:
MOV CL,4
BIN2HEXLP:
ROL BX,CL ;MOVE LEFT BYTE TO RIGHT SIDE
MOV AL,BL ;THIS IS NECESSARY
AND AL,0F ;CLEAR LEFT BYTE
ADD AL,'0'
CMP AL,'9'
IF A ADD AL,7
STOSB
INC DI
DEC CH
JNZ BIN2HEXLP
RET
;CONVERT AL FROM HEX TO BINARY
HEX2BIN:
CMP AL,'0'
JB BADHEX
CMP AL,':'
JB HEX2 ;IF NUMBER
AND AL,0DFH ;MAKE LETTERS UPPERCASE
CMP AL,'A'
JB BADHEX
CMP AL,'F'
JA BADHEX
SUB AL,7
HEX2:
SUB AL,'0'
CLC
RET
BADHEX:
STC
RET
;MOVE CURSOR LEFT
LFTCUR:
MOV DX,CURLOC
CMP DX,0100
JE LFTTOP ;IF AT TOP LEFT OF SCREEN
DEC CURPTR
OR DL,DL
JE PREVLIN
DEC DL
JMP SHORT LFTMOV
PREVLIN:
DEC DH
MOV DL,79
LFTMOV:
CALL MOVCUR
CLC
LFTXIT:
RET
LFTTOP:
MOV AX,TOPLEF
CMP AX,FTOPLEF
JE LFTXIT ;IF AT BEGINNING OF FILE
MOV DL,79
CALL MOVCUR
SUB TOPLEF,5 ;80D SHIFTED RIGHT
ADD CURPTR,79 ;BECAUSE OF TOPLEF CHANGE
STC
RET
;MOVE CURSOR RIGHT
RTCUR:
MOV AX,TOPLEF
CMP AX,LTOPLEF
JC RTCUR2 ;IF NOT AT LAST SCREEN
MOV BX,AX
MOV CL,4
ROL BX,CL
AND BX,0F
SHL AX,CL
ADD AX,CURPTR
IF C INC BX
CMP BX,FILENDS
JC RTCUR2 ;IF CURRENT SEGMENT LESS THAN FILEND SEGMENT
CMP AX,FILENDO
JNC RTEXIT ;IF CURSOR WOULD GO BEYOND FILE END
RTCUR2:
INC CURPTR
MOV DX,CURLOC
CMP DL,79
JE NEXLIN
INC DL
JMP SHORT RTMOV
NEXLIN:
CMP DH,24
JE RTBOT
INC DH
SUB DL,DL
RTMOV:
CALL MOVCUR
RTEXIT:
CLC
RET
RTBOT:
CMP AX,LTOPLEF
JNC RTEXIT
SUB DL,DL
CALL MOVCUR
ADD TOPLEF,5
SUB CURPTR,80 ;BECAUSE OF TOPLEF CHANGE
STC
RET
;CHECK SCROLLLOCK ON OR OFF
SCRLOCK:
PUSH ES
SUB AX,AX
MOV ES,AX
TEST B ES:[0417],010
POP ES
RET
;GET STRING TO SEARCH FOR
GETSTR:
MOV DX,BP
SHR DX,1
CALL MOVCUR2
MOV AH,1 ;FUNCTION TO CHANGE CURSOR SHAPE
MOV CX,0406 ;TOP & BOTTOM ROW OF CURSOR
INT 010
SUB DX,DX ;FOR COUNT IN CMPSB, BELOW
MOV DI,BP
CHKSTR:
SUB AH,AH ;READ KEYBOARD FUNCTION
INT 016
CMP AH,14 ;BACKSPACE KEY
JE ERASTR
CMP AX,04B00 ;LEFT ARROW KEY
JE ERASTR
CMP AL,8 ;^H
JE ERASTR
CMP AL,0D ;ENTER KEY
JE XITSTR
CMP AL,01B ;ESC
JNZ NOTESC
SUB DX,DX ;AS A FLAG (TO SET SIGN FLAG)
JMP SHORT XITSTR
;ERASE CHAR
ERASTR:
CMP DI,BP
JE CHKSTR ;DON'T ERASE IF AT BEGINNING OF INPUT LOCATION
DEC DI
DEC DI
PUSH DX
MOV DX,DI
SHR DX,1
CALL MOVCUR2
POP DX
DEC DX
MOV AH,TOPATTRIB
MOV AL,' '
ES MOV W[DI],AX
CMP MODE,7
IF Z ES MOV B[DI+1],070
JMP SHORT CHKSTR
NOTESC:
CMP AL,' '
JC CHKSTR ;DON'T ACCEPT ANY OTHER ^CHARS
;PUT CHAR ON SCREEN
SHOSTR:
CMP DI,126 ;LAST INPUT SPACE
JE XITSTR ;EXIT
STOSB
INC DI
PUSH DX
MOV DX,DI
SHR DX,1
CALL MOVCUR2
POP DX
INC DX
JMP SHORT CHKSTR
XITSTR:
DEC DX
MOV STRCNT,DX
RET
MENWRT:
MOV AH,SCRNATTRIB
CMP MODE,7
IF Z MOV AH,7
SUB DI,DI
MOV AL,' '
MOV CX,2
REP STOSW
MOV DX,25 ;ROWS
MENLP0:
MOV CX,80 ;COLUMNS
MENLP:
LODSB
OR AL,AL
JE MENSK
STOSW
LOOP MENLP
MENSK:
REP STOSW
OR SI,SI
IF Z ADD DI,160
DEC DX
JNZ MENLP0
MOV AL,179 ;│
MOV DI,160
MOV CX,23
SIDELINES:
STOSB
ADD DI,157
STOSB
INC DI
LOOP SIDELINES
MOV B ES:[0],218 ;┌
MOV B ES:[3840],192 ;└
MOV B ES:[158],191 ;┐
MOV B ES:[3998],217 ;┘
SUB AH,AH
INT 016H ;READ KEYBOARD
RTN:
RET
;********DISASSEMBLE SUBROUTINES
L00:
CALL GETBYTE2
MOV BX,OFFSET REGB
MOV B[BW],'B'
CALL MODRMBITS
MOV AL,','
STOSB
INC DI
MOV BX,OFFSET REGB
JMP NBITS
L01:
CALL GETBYTE2
MOV BX,OFFSET REGW
MOV B[BW],'W'
CALL MODRMBITS
MOV AL,','
STOSB
INC DI
MOV BX,OFFSET REGW
JMP NBITS
L02:
CALL GETBYTE2
MOV BX,OFFSET REGB
CALL NBITS
MOV AL,','
STOSB
INC DI
MOV BX,OFFSET REGB
MOV B[BW],'B'
JMP MODRMBITS
L03:
CALL GETBYTE2
MOV BX,OFFSET REGW
CALL NBITS
MOV AL,','
STOSB
INC DI
MOV BX,OFFSET REGW
MOV B[BW],'W'
JMP MODRMBITS
L04:
MOV AX,'LA'
CALL L045
JMP BIN2HEXB
L05:
MOV AX,'XA'
CALL L045
JMP BIN2HEXW
L045:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
RET
L06:
MOV AX,'SE'
JMP SHORT AXTODI
L0E:
MOV AX,'SC'
JMP SHORT AXTODI
L16:
MOV AX,'SS'
JMP SHORT AXTODI
L1E:
MOV AX,'SD'
JMP SHORT AXTODI
L40:
MOV AX,'XA'
JMP SHORT AXTODI
L41:
MOV AX,'XC'
JMP SHORT AXTODI
L42:
MOV AX,'XD'
JMP SHORT AXTODI
L43:
MOV AX,'XB'
JMP SHORT AXTODI
L44:
MOV AX,'PS'
JMP SHORT AXTODI
L45:
MOV AX,'PB'
JMP SHORT AXTODI
L46:
MOV AX,'IS'
JMP SHORT AXTODI
L47:
MOV AX,'ID'
AXTODI:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
RET
L70:
MOV DS,TOPLEF
LODSB
CBW
MOV DX,2
CALL RELATIVE
JMP SHOBYTE
L80:
SUB BP,BP ;TO INDEX TO IMMED,SHIFT,GRP1,OR GRP2
MOV BX,OFFSET REGB
MOV SAVEBX,BX
MOV B[BW],'B'
CALL EIGHTX
MOV AL,','
STOSB
INC DI
JMP BIN2HEXB
L81:
SUB BP,BP
MOV BX,OFFSET REGW
MOV SAVEBX,BX
MOV B[BW],'W'
CALL EIGHTX
MOV AL,','
STOSB
INC DI
JMP BIN2HEXW
L83:
SUB BP,BP
MOV BX,OFFSET REGW
MOV SAVEBX,BX
MOV B[BW],'W'
CALL EIGHTX
MOV AL,','
STOSB
INC DI
MOV AL,'0'
TEST B[SI],080
IF NZ MOV AL,'F'
STOSB
INC DI
STOSB
INC DI
JMP BIN2HEXB
EIGHTX:
CALL GETBYTE2
SUB DI,2 ;WRITE OVER BLANK
MOV CL,3
SHR AX,CL ;LOOK AT R BITS
AND AX,7 ;CLEAR ALL BUT LOW 3 BITS
SHL AX,1 ;DOUBLE IT
MOV BX,OFFSET ISGGPTRS
ADD BX,BP
MOV BX,[BX]
ADD BX,AX
PUSH SI
MOV SI,[BX] ;POINT TO STRING
ISGGLP:
LODSB
STOSB
INC DI
CMP AL,' '
JNZ ISGGLP
POP SI
MOV BX,SAVEBX
JMP MODRMBITS
L8C:
MOV BX,OFFSET REGW
MOV B[BW],'W'
CALL GETBYTE2
CALL MODRMBITS
MOV AL,','
STOSB
INC DI
PUSH SI
MOV SI,OFFSET SEGS
MOV CL,3
MOV AL,BYTE2
SHR AX,CL
AND AX,7
SHL AX,1
ADD SI,AX
MOVSB
INC DI
MOVSB
INC DI
POP SI
RET
L8E:
CALL GETBYTE2
PUSH SI
MOV SI,OFFSET SEGS
MOV CL,3
SHR AX,CL
AND AX,7
SHL AX,1
ADD SI,AX
MOVSB
INC DI
MOVSB
INC DI
POP SI
MOV AL,','
STOSB
INC DI
L8F:
MOV BX,OFFSET REGW
MOV B[BW],'W'
JMP MODRMBITS
L91:
CALL L41
JMP SHORT L9X
L92:
CALL L42
JMP SHORT L9X
L93:
CALL L43
JMP SHORT L9X
L94:
CALL L44
JMP SHORT L9X
L95:
CALL L45
JMP SHORT L9X
L96:
CALL L46
JMP SHORT L9X
L97:
CALL L47
L9X:
MOV AL,','
STOSB
INC DI
MOV AX,'XA'
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
RET
L9A:
ADD SI,2
CALL BIN2HEXW
MOV AL,':'
STOSB
INC DI
SUB SI,4
CALL BIN2HEXW
ADD SI,2
RET
LA0:
MOV AX,'LA'
MOV B[BW],'B'
JMP SHORT LA01
LA1:
MOV AX,'XA'
MOV B[BW],'W'
LA01:
STOSB
INC DI
XCHG AH,AL
STOSB
INC DI
MOV AL,','
STOSB
INC DI
MOV AL,B[BW]
STOSB
INC DI
MOV AL,'['
STOSB
INC DI
CALL BIN2HEXW
MOV AL,']'
STOSB
RET
LA2:
MOV B[BW],'B'
CALL LA23
MOV AX,'LA'
JMP SHORT LAX
LA3:
MOV B[BW],'W'
CALL LA23
MOV AX,'XA'
LAX:
STOSB
INC DI
XCHG AL,AH
STOSB
RET
LA23:
MOV AL,B[BW]
STOSB
INC DI
MOV AL,'['
STOSB
INC DI
CALL BIN2HEXW
MOV AL,']'
STOSB
INC DI
MOV AL,','
STOSB
INC DI
RET
LA4:
SUB DI,2
ES MOV B[DI],'B'
RET
LA5:
SUB DI,2
ES MOV B[DI],'W'
RET
LB0:
MOV AX,'LA'
JMP SHORT LBX
LB1:
MOV AX,'LC'
JMP SHORT LBX
LB2:
MOV AX,'LD'
JMP SHORT LBX
LB3:
MOV AX,'LB'
JMP SHORT LBX
LB4:
MOV AX,'HA'
JMP SHORT LBX
LB5:
MOV AX,'HC'
JMP SHORT LBX
LB6:
MOV AX,'HD'
JMP SHORT LBX
LB7:
MOV AX,'HB'
JMP SHORT LBX
LB8:
MOV AX,'XA'
JMP SHORT LBX2
LB9:
MOV AX,'XC'
JMP SHORT LBX2
LBA:
MOV AX,'XD'
JMP SHORT LBX2
LBB:
MOV AX,'XB'
JMP SHORT LBX2
LBC:
MOV AX,'PS'
JMP SHORT LBX2
LBD:
MOV AX,'PB'
JMP SHORT LBX2
LBE:
MOV AX,'IS'
JMP SHORT LBX2
LBF:
MOV AX,'ID'
JMP SHORT LBX2
LBX:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
JMP BIN2HEXB
LBX2:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
JMP BIN2HEXW
LC4:
CALL GETBYTE2
MOV BX,OFFSET REGW
CALL NBITS
MOV AL,','
STOSB
INC DI
MOV BX,OFFSET REGW
MOV B[BW],'W'
JMP MODRMBITS
LC6:
MOV BX,OFFSET REGB
MOV B[BW],'B'
CALL LC67
JMP BIN2HEXB
LC7:
MOV BX,OFFSET REGW
MOV B[BW],'W'
CALL LC67
JMP BIN2HEXW
LC67:
CALL GETBYTE2
CALL MODRMBITS
MOV AL,','
STOSB
INC DI
RET
LD0:
MOV BX,OFFSET REGB
MOV B[BW],'B'
JMP SHORT LDX
LD1:
MOV BX,OFFSET REGW
MOV B[BW],'W'
LDX:
MOV SAVEBX,BX
MOV BP,2 ;TO INDEX TO IMMED
CALL EIGHTX
MOV AL,','
STOSB
INC DI
MOV AL,'1'
STOSB
RET
LD2:
MOV BX,OFFSET REGB
MOV B[BW],'B'
JMP SHORT LDX2
LD3:
MOV BX,OFFSET REGW
MOV B[BW],'W'
LDX2:
MOV SAVEBX,BX
MOV BP,2 ;TO INDEX TO SHIFT
CALL EIGHTX
MOV AL,','
STOSB
INC DI
MOV AX,'LC'
STOSB
INC DI
XCHG AL,AH
STOSB
RET
LE4:
MOV AX,'LA'
JMP SHORT LE45
LE5:
MOV AX,'XA'
LE45:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
JMP BIN2HEXB
LE6:
CALL BIN2HEXB
MOV AL,','
STOSB
INC DI
MOV AX,'LA'
JMP SHORT LE67
LE7:
CALL BIN2HEXB
MOV AL,','
STOSB
INC DI
MOV AX,'XA'
LE67:
STOSB
INC DI
XCHG AL,AH
STOSB
RET
LE8:
MOV DS,TOPLEF
LODSW
MOV DX,3
CALL RELATIVE
JMP SHOWORD
LEB:
MOV DS,TOPLEF
LODSB
CBW
MOV DX,2
CALL RELATIVE
JMP SHOBYTE
LEC:
MOV AX,'LA'
JMP SHORT LECD
LED:
MOV AX,'XA'
LECD:
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
MOV AX,'XD'
JMP SHORT LEEF
LEE:
MOV AX,'XD'
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
MOV AX,'LA'
JMP SHORT LEEF
LEF:
MOV AX,'XD'
STOSB
INC DI
XCHG AL,AH
STOSB
INC DI
MOV AL,','
STOSB
INC DI
MOV AX,'XA'
LEEF:
STOSB
INC DI
XCHG AL,AH
STOSB
JMP SHOBYTE
LF3:
MOV DS,TOPLEF
MOV AL,[SI]
MOV CX,CS
MOV DS,CX
AND AL,0A6
CMP AL,0A6
JNZ LF2 ;IF NEXT BYTE ISN'T 0A6, 0A7, 0AE, OR 0AF
SUB DI,2
MOV AL,'E'
STOSB
ADD DI,3
LF2:
CALL SHOBYTE
JMP DIS2
LF6:
MOV BX,OFFSET REGB
MOV B[BW],'B'
CALL LF67
JMP BIN2HEXB
LF7:
MOV BX,OFFSET REGW
MOV B[BW],'W'
CALL LF67
JMP BIN2HEXW
LF67:
CALL GETBYTE2
SUB DI,2 ;WRITE OVER BLANK
MOV CL,3
SHR AX,CL ;LOOK AT R BITS
AND AX,7 ;CLEAR ALL BUT LOW 3 BITS
CMP AL,1
JNZ >L1
L2:
POP CX ;PREVIOUS RET ADDRESS
RET ;NO INSTRUCTION FOR THIS
L1:
MOV SAVES,AX
MOV BP,4 ;TO INDEX TO IMMED,SHIFT,GRP1,OR GRP2
SHL AX,1 ;DOUBLE IT
CALL LFX
CALL MODRMBITS
MOV AX,SAVES
OR AX,AX
JNZ L2 ;ONLY TEST INSTRUCTION NEEDS ANOTHER NUMBER
MOV AL,','
STOSB
INC DI
RET
LFE:
MOV BP,6
MOV BX,OFFSET REGB
MOV B[BW],'B'
CALL GETBYTE2
SUB DI,2 ;WRITE OVER BLANK
MOV CL,3
SHR AX,CL ;LOOK AT R BITS
AND AX,7 ;CLEAR ALL BUT LOW 3 BITS
CMP AX,2
IF NC RET ;ONLY 0FF INSTRUCTION CAN USE HIGHER
SHL AX,1 ;DOUBLE IT
CALL LFX
JMP MODRMBITS
LFF:
MOV BP,6
MOV BX,OFFSET REGW
MOV B[BW],'W'
CALL GETBYTE2
SUB DI,2 ;WRITE OVER BLANK
MOV CL,3
SHR AX,CL ;LOOK AT R BITS
AND AX,7 ;CLEAR ALL BUT LOW 3 BITS
CMP AL,7
IF Z RET ;NO INSTRUCTION FOR THIS
CMP AL,3
IF Z MOV B[BW],'D'
CMP AL,5
IF Z MOV B[BW],'D'
SHL AX,1 ;DOUBLE IT
CALL LFX
JMP MODRMBITS
LFX:
MOV SAVEBX,BX
MOV BX,OFFSET ISGGPTRS
ADD BX,BP
MOV BX,[BX]
ADD BX,AX
PUSH SI
MOV SI,[BX] ;POINT TO STRING
ISGGLP2:
LODSB
STOSB
INC DI
CMP AL,' '
JNZ ISGGLP2
POP SI
MOV BX,SAVEBX
RET
RELATIVE:
MOV CX,CS
MOV DS,CX
MOV BX,ABSLOC1 ;HIGH NIBBLE OF CURRENT LOCATION
ADD DX,ABSLOC2 ;ADD NEXT INSTR ADDR TO LOW NIBBLES OF CURRENT LOCATION
IF O ADD BX,01000
TEST DX,08000
JZ >L1 ;IF HI BIT NOT SET
TEST AX,08000
JZ >L05 ;IF HI BIT NOT SET
ADD DX,AX
JMP SHORT >L2
L05:
ADD DX,AX
IF O ADD BX,01000
JMP SHORT >L2
L1:
TEST AX,08000
JZ >L15 ;IF HI BIT NOT SET
ADD DX,AX
IF O SUB BX,01000
JMP SHORT >L2
L15:
ADD DX,AX
L2:
MOV CH,1
CALL BIN2HEX
MOV BX,DX
MOV CH,4
JMP BIN2HEX
GETBYTE2:
CALL SHOBYTE
MOV DS,TOPLEF
LODSB ;2ND BYTE
MOV CX,CS
MOV DS,CX
MOV BYTE2,AL
RET
;GET N BIT INFO (2ND BYTE = 2MOD BITS, 3 N BITS, & 3 R/M BITS)
NBITS:
MOV AL,BYTE2
MOV CL,3
SHR AX,CL ;LOOK AT 3 REG BITS
AND AX,7
SHL AX,1 ;DOUBLE IT
PUSH SI
MOV SI,BX ;EITHER OFFSET REGB OR REGW OR [ISGGPTRS]
ADD SI,AX
MOVSB
INC DI
MOVSB
INC DI
POP SI
RET
;GET MOD & R/M BIT INFO
MODRMBITS:
MOV AL,BYTE2
MOV DL,AL
AND AX,7 ;TO JUST LOOK AT R/M BITS
MOV CL,6
SHR DL,CL ;LOOK AT 2 MOD BITS
CMP DL,3 ;11B
JNZ NOTREG ;MOD R/M IS NOT TREATED AS A REGISTER
SHL AX,1 ;DOUBLE IT
PUSH SI
MOV SI,BX ;POINTING TO EITHER REGB OR REGW
ADD SI,AX
MOVSB
INC DI
MOVSB
INC DI
POP SI
RET
NOTREG:
OR DL,DL ;MOD BITS
JNZ USEADDR
CMP AL,6 ;110B
JNZ USEADDR ;IF R/M BITS <> 110B
;SPECIAL CASE (HIGH ADDRESS, LOW ADDRESS)
MOV AL,BW
STOSB
INC DI
MOV AL,'['
STOSB
INC DI
ADDRESS:
INC SI
CALL BIN2HEXB
SUB SI,2
CALL BIN2HEXB
INC SI
MOV AL,']'
STOSB
INC DI
RET
USEADDR:
PUSH AX
MOV AL,[BW]
STOSB
INC DI
POP AX
MOV CL,3
SHL AX,CL ;MUL 8 (TO INDEX INTO ADDR)
PUSH SI
MOV SI,OFFSET ADDR
ADD SI,AX
ADDRLP:
MOVSB
INC DI
CMP B[SI],' '
JNZ ADDRLP
POP SI
OR DL,DL ;MOD BITS
IF Z RET ;IF NO EXTRA DISPLACEMENT
SUB DI,2 ;WRITE OVER ']'
MOV AL,'+'
STOSB
INC DI
CMP DL,1
JNZ ADDRESS ;IF FOLLOWING BYTE IS NOT SIGN-EXTENDED TO WORD
MOV DS,TOPLEF
MOV CX,CS
TEST B[SI],080
JZ NOTNEG ;IF HIGH BIT NOT SET
NEG B[SI]
ES MOV B[DI-2],'-'
NOTNEG:
MOV DS,CX
CALL BIN2HEXB
MOV AL,']'
STOSB
INC DI
RET
SHOBYTE:
PUSH DI
MOV AL,INSTRATTRIB
CMP MODE,7
IF Z MOV AL,070
MOV AH,'_'
MOV DI,SCRNCUR
CMP B ES:[DI-1],0
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],020
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],0FF
IF Z MOV ES:[DI-1],AH
STOSB ;HILITE BYTE
POP DI
ADD SCRNCUR,2
RET
SHOWORD:
PUSH DI
MOV AL,INSTRATTRIB
CMP MODE,7
IF Z MOV AL,070
MOV AH,'_'
MOV DI,SCRNCUR
CMP B ES:[DI-1],0
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],020
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],0FF
IF Z MOV ES:[DI-1],AH
STOSB ;HILITE BYTE
INC DI
CMP B ES:[DI-1],0
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],020
IF Z MOV ES:[DI-1],AH
CMP B ES:[DI-1],0FF
IF Z MOV ES:[DI-1],AH
STOSB ;DITTO
POP DI
ADD SCRNCUR,4
SUB BP,BP
RET
OLDSCR EQU $
PREBUF EQU OLDSCR +0FB0 ;4000D + 10H = (25*80) + ROOM TO ZERO LOW NIBBLE