📄 lsmain.asm
字号:
;===========================================================================
; Stage 2 Node Listing Functions
;
; This section contains one routine for listing each node type.
; On Entry, they can all assume
; DS points to DGROUP segment
; DI points to next destination byte (buffer is within DS)
; SI points to node being listed
; ES contains garbage
;
;===========================================================================
;***************************************************************************
; ListChildList
; Purpose:
; This node has no atomic ASCII source directly associated with it,
; i.e. it is a hierarchy node which exists just to hold children
; to sibling nodes.
;
;***************************************************************************
ListChildList:
push si ;gets popped by EndOfList:
mov si,WORD PTR LN_val_list[si]
;si = offset to start of child list
jmp FindEndOfList ;recursively list it
;***************************************************************************
; ListONamNode
; Purpose:
; Copy the content of an LNT_ONAM node to the output buffer.
; Value is a 16 bit name table offset for identifier associated with
; this node.
;
;***************************************************************************
ListONamNode:
push di ; pass dest byte ptr to CopyONamPb
push word ptr [si.LN_val_oNam] ; pass oNam to CopyONamPb
call CopyONamPb ;copy name to destination buffer
;ax = # bytes in name
add di,ax ;update destination ptr
jmp Stg2Cont
;***************************************************************************
; ListCursorNode
; Purpose:
; Return column offset for this node in colLsCursor.
; It represents the column that corresponds with the opcode
; at text offset otxLsCursor.
;
;***************************************************************************
ListCursorNode:
mov ax,di ;ax points to next destination byte
mov bx,[pbdDst]
sub ax,[bx.BD_pb] ;ax = number bytes listed to buffer
mov [colLsCursor],ax
mov bl,[lnTypeFindSave]
jmp DispNodeBl
;***************************************************************************
; ListCharsNode
; Purpose:
; Copy the content of an LNT_CHAR node to the output buffer.
; Value is 0, 1 or 2 ASCII characters associated with this node.
;
;***************************************************************************
ListCharsNode:
mov ax,WORD PTR [si.LN_val_char]
cmp ax,"OT"
je GotTo
CharLoop:
or al,al
je NoChar ;brif NULL char in this node
CharLoop1:
mov [di],al ;copy char to destination buffer
inc di ;can't use stosb because ES <> DS
mov al,ah ;al = 2nd char (if any)
sub ah,ah ;don't output more than 2 chars
jmp SHORT CharLoop
NoChar:
jmp Stg2Cont
;It is space-cheaper to put spaces around TO here than in
;DIM's Stage1 code.
;
GotTo:
mov [di],"T " ;list " T"
inc di ;can't use stosb because ES <> DS
inc di
mov ax," O" ;list "O "
jmp SHORT CharLoop1
;***************************************************************************
; ListRwNode
; Purpose:
; Copy the content of an LNT_RW node to the output buffer.
; value is a 16 bit reserved word table offset for
; reserved word or special character associated with this node.
;
;***************************************************************************
ListRwNode:
jmp FAR PTR ListRwNodeCP
sEnd LIST
sBegin CP
assumes CS,CP
DbPub ListRwNodeCP
ListRwNodeCP:
push si ;preserve si
mov ax,ds ;don't use push, need speed
mov es,ax ;es = DGROUP
mov ax,WORD PTR [si.LN_val_orw]
mov si,ax ;si = resword offset + 1st letter
mov al,ah ;al = (1st letter - 'A') * 4
xor ah,ah
shr al,1
shr al,1 ;al = 1st letter - 'A'
mov bx,ax
shl bx,1 ;bx = word offset into tRw table
add al,'A' ;al = 1st letter
stosb ;store 1st letter of res word
and si,03FFH ;si = offset into res word table
mov ax,cs ;ax = current address of CP segment
mov es,ax
assumes ES,CP
add si,es:tRw[bx] ;convert offset to ptr
call GetRwFromTabCP ;cx = size of res word's name
;dx = size of res word's atr block
;si points to 1st letter of name
assumes ES,NOTHING
mov ax,es ;don't use push, need speed
mov ds,ax ;ds = CP segment
assumes DS,CP
mov ax,ss ;don't use push, need speed
mov es,ax ;es = DGROUP
rep movsb ;copy reserved word from CP segment
; to DGROUP table
lodsb ;al = res word's flags
test al,RWF_STR
je NotStrRw ;brif res word does not end with '$'
mov al,'$'
stosb ;list "$"
NotStrRw:
mov ax,ss ;don't use push, need speed
mov ds,ax ;ds = DGROUP
assumes DS,DGROUP
pop si ;restore si
jmp FAR PTR Stg2Cont
;*************************************************************************
; GetRwFromTabCP
; Purpose:
; extract an entry from the reserved word table
; Entry:
; si points to first char of entry in reserved word table
; which is the second char of the reserved word since the
; first char is not stored in the table
; for GetRwFromTabList:
; es = segment address of reserved word table (i.e. CP) [09]
; Exit:
; cx = size of res word's name
; dx = size of res word's atr block
; si points to 1st byte of res word name
; preserves bx,di,es
;
; GetRwFromTab is a FAR entry point. It has the following DIFFERENCE:
; es is not expected to be anything on entry,
; on exit ax = size of res word's name instead of cx
; Does not guarantee that bx and es are preserved
;*************************************************************************
PUBLIC GetRwFromTabCP
GetRwFromTabCP PROC NEAR
lods BYTE PTR es:[si] ;al = (cbNam << 4) + cbAtr
inc al ;test al for FF
jz CbsInWord ;brif cbNam and cbAtr stored
; in following word
dec al ;restore al = Cbs
sub ah,ah ;ax = (cbNam << 4) + cbAtr
mov dx,ax ;dx = (cbNam << 4) + cbAtr
shr ax,1
shr ax,1
shr ax,1
shr ax,1 ;ax = cbNam
mov cx,ax ;cx = cbNam
and dl,15 ;dl = cbAtr
ret
CbsInWord:
lods WORD PTR es:[si] ;al = #bytes of attributes
;ah = #bytes in reserved word
mov cl,ah
xor ch,ch ;cx = #bytes in reserved word
xor ah,ah
xchg dx,ax ;dx = #bytes of attributes
ret
GetRwFromTabCP ENDP
sEnd CP
sBegin LIST
assumes CS,LIST
;***************************************************************************
; ListStrNode/ListLitStrNode
; Rewritten for revision [18]
; Purpose:
; Copy the content of an LNT_STR node to the output buffer.
; Value is a 16 bit offset followed by 16 bit count
; which identifies where the string is in the text table.
;
; Special processing is needed for listing LitStrNode's
; to handle listing '"' in a string.
;
; Entry:
; bx = LNT_STR or LNT_LITSTR
;
;***************************************************************************
ListLitStrNode:
DbPub ListStrNode
ListStrNode:
push si ;preserve si
mov cx,WORD PTR [si.LN_val_cbStr]
;cx = length of string
mov si,WORD PTR [si.LN_val_oStr]
;si = offset into text table to string
call ChkDstFull ;make sure there's room for cx bytes
; in dest buffer. If not, don't return
GETSEG ds,[txdCur.TXD_bdlText_seg],,<SIZE,LOAD> ;[4]
;ds = seg for current text table
push ss
pop es ;es = DGROUP
rep movsb
push es
pop ds ;restore ds = DGROUP
LSNZeroLenExit:
pop si ;restore si
jmp Stg2Cont
;***************************************************************************
; ListEnStrNode
; Purpose:
; Decode and copy the content of an LNT_ENSTR node to the output buffer.
; Value is a 16 bit offset followed by 16 bit count
; which identifies where the encoded string is in the text table.
; An encoded string consists of standard ascii text, with character
; runs of > 3 identical chars contained in a "compression" record.
; The compression record, and format is described in prsutil.asm,
; and basically consists of a flag byte, followed by a byte containing
; the repetition factor, and the final byte is the character which
; was repeated.
;
;***************************************************************************
DbPub ListEnStrNode
ListEnStrNode:
push si ;preserve si
mov cx,WORD PTR [si.LN_val_cbEnStr]
;cx = length of string
jcxz ListEnStrExit ;brif no text to list
mov si,WORD PTR [si.LN_val_oEnStr]
;si = offset into text table to string
call ChkDstFull ;make sure there's room for cx bytes
; in dest buffer. If not, don't return
GETSEG ds,[txdCur.TXD_bdlText_seg],,<SIZE,LOAD> ;[4]
;ds = seg for current text table
push ss
pop es ;es = DGROUP
EnStrLoop:
lodsb ;get char
cmp al,STR_EncodedText ;is this the start of a compression
je ExpandText ; record? brif so
stosb ;list char
EnStrCont:
loop EnStrLoop ;continue until all chars listed
push es
pop ds ;restore ds = DGROUP
ListEnStrExit:
pop si ;restore si
jmp Stg2Cont
ExpandText:
lodsw ;al = cbChars, ah = char
dec cx
dec cx ;adjust for size of compression record
push cx ;save cbCompressed
mov bx,di ;bx = current dest ptr
add bx,cx ;bx = result dest ptr (end of string)
; before expanding text
mov cl,al
sub ch,ch ;cx = cbExpand
mov al,ah ;al = char
add bx,cx ;bx = result dest ptr after expansion
jc J1_ListDstFull ;brif wrapped past FFFF (buf too small)
cmp bx,es:[pbDstWarning]
jae J1_ListDstFull ;brif string too big - grow dst buffer
rep stosb ;blast out the encoded char string
pop cx ;recover cbLeft to list
jmp short EnStrCont ;continue listing encoded string
J1_ListDstFull:
push es
pop ds ;reset ds to DGROUP
jmp ListDstFull
;***************************************************************************
; ListCsStrNode
; Purpose:
; Copy the content of an LNT_CSSTR node to the output buffer.
; Value is a 16 bit offset followed by 16 bit count
; which identifies where the string is in the LIST segment.
;
;***************************************************************************
ListCsStrNode:
push si ;preserve si
mov si,WORD PTR [si.LN_val_CsStr]
;si = offset into LIST segment to
; str255 struct for string
push ds
pop es ;es = DGROUP
push cs
pop ds ;ds = code segment (LIST)
lodsb ;al = length of string constant
;si points to 1st byte of string
cbw ;ax = length of string constant
; NOTE: implies no LIST string constant
; is longer than 128 bytes (very safe)
xchg cx,ax ;cx = length of string
rep movsb ;copy string to destination buffer
push es
pop ds ;restore ds = DGROUP
pop si ;restore si
jmp Stg2Cont
;***************************************************************************
; ListSpacesNode
; Purpose:
; Copy the content of an LNT_SPACES node to the output buffer.
; Value is a 16 bit count of spaces
;
;***************************************************************************
ListSpacesNode:
mov cx,WORD PTR [si.LN_val_cbSpaces]
;cx = number of spaces to emit
;cx = number of spaces to list
ListCol1:
call ChkDstFull ;make sure there's room for cx bytes
; in dest buffer. If not, don't return
push ds
pop es ;es = DGROUP
mov al,' '
rep stosb ;store spaces in destination buffer
J1_Stg2Cont:
jmp Stg2Cont ;return to outer loop
;***************************************************************************
; ListColNode
; Purpose:
; Emit white space until we get to indicated column.
; Value is a 16 bit column to advance to.
; High bit of argument is set if at least 1 space needs
; to be output even if we're beyond the specified column.
;
;***************************************************************************
ListColNode:
mov bx,[pbdDst]
mov cx,[bx.BD_pb] ;cx points to destination buffer
mov ax,WORD PTR [si.LN_val_col]
mov dx,ax ;high bit of dx is set if at least
; 1 space is to be output
and ah,7Fh ;ax = column to advance to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -