exstmisc.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:8k
源码类别:
操作系统开发
开发平台:
Visual C++
- page 49,132
- TITLE exstmisc.asm - misc. statement executors
- ;***
- ;exstmisc.asm - statement executors for QBI
- ;
- ; Copyright <C> 1986, Microsoft Corporation
- ;
- ;Purpose:
- ;
- ;
- ;****************************************************************************
- .xlist
- include version.inc
- EXSTMISC_ASM = ON
- IncludeOnce architec
- IncludeOnce context
- IncludeOnce executor
- IncludeOnce extort
- IncludeOnce exint
- IncludeOnce opstmt
- IncludeOnce opmin
- IncludeOnce opcontrl
- IncludeOnce opintrsc
- IncludeOnce opaftqb4
- IncludeOnce qbimsgs
- IncludeOnce rtinterp
- .list
- sBegin DATA
- sEnd DATA
- assumes es, NOTHING
- assumes ss, DATA
- EXTRN B$SERR:FAR
- sBegin CODE
- assumes cs, CODE
- extrn I4ToU2:near
- ;==============================================================================
- ; Error-related Statements
- ;==============================================================================
- MakeExe exStError,opStError
- ;note that error code is on stack here - - -
- CALLRT B$SERR,DispMov ;Never returns. DispMov variant used
- ;just so non-RELEASE case won't have
- ;non-RELEASE static data screwed up.
- ;Note that calling via ExToRt ensures
- ;that grs.GRS_oTxCur is set up for
- ;B$IONERR
- ;==============================================================================
- ; Sound-related Statements
- ;==============================================================================
- MakeExe exStBeep0,opStBeep
- CALLRT B$BEEP,Disp
- MakeExe exStPlay,opStPlay
- CALLRT B$SPLY,Disp
- MakeExe exStSound,opStSound
- ;Added with [11]
- sub sp,4 ;Make room for argument
- mov bx,sp
- fstp dword ptr DGROUP:[bx] ;Copy to local stack
- fwait
- ;End of [11]
- CALLRT B$SOND,Disp
- ;==============================================================================
- ; Heap-related Statements
- ;==============================================================================
- MakeExe exStDefSeg0,opStDefSeg0
- CALLRT B$DSG0,Disp
- MakeExe exStDefSeg1,opStDefSeg1
- call I4toU2 ;coerce I4 addr on stack to a U2
- CALLRT B$DSEG,Disp
- MakeExe exStPoke,opStPoke
- pop bx ;preserve value to be poked
- call I4toU2 ;coerce I4 addr on stack to a U2
- push bx ;(I4toU2 preserves bx)
- CALLRT B$POKE,Disp
- ;==============================================================================
- ; Math-related Statements
- ;==============================================================================
- MakeExe exStRandomize0,opStRandomize0
- CALLRT B$RNZ0,Disp
- MakeExe exStRandomize1,opStRandomize1
- ;Added with [11]
- sub sp,8 ;Make room for argument
- mov bx,sp
- fstp qword ptr DGROUP:[bx] ;Copy to local stack
- fwait
- ;End of [11]
- CALLRT B$RNZP,Disp
- ;==============================================================================
- ; READ/DATA Support
- ;==============================================================================
- ;NOTE: The actual READ executors are exactly the same as the INPUT executors,
- ;NOTE: so they share code in exio.asm
- ;NOTE: The otxFirst field is a pointer to the link field in the first DATA
- ;NOTE: statement in the module. The otxCur field, however, is a pointer to
- ;NOTE: the exStData pcode - - - this inconsistency is required by the scanner,
- ;NOTE: which treats otxFirst as an otx head-of-chain, and otxCur as a 'normal'
- ;NOTE: otx - - - each of which is updated differently for Edit & CONTinue.
- ;NOTE: The oLineCur initialization value is 6 bytes to account for the fact
- ;NOTE: that otxCur points to the exStData pcode.
- MakeExe exStRestore0,opStRestore0
- xor cx,cx ;remember this is exStRestore0
- jmp short Restore_Common
- MakeExe exStRestore1,opStRestore1
- DbAssertRel ax,nz,0,CODE,<exStRestore1 finds AX == 0>
- xchg ax,cx ;cx != 0 indicates exStRestore1
- LODSWTX ;ax = oTx. We want the next READ
- ; to use the first piece of
- ; data in the first DATA stmt
- ; found subsequent to this oTx
- Restore_Common:
- call GetDataSeg ;set up bx and es (preserves ax)
- mov di,PTRRS[bx.MRS_data_otxFirst] ; oTx of link field of first DATA
- ; statement
- mov es,dx
- jcxz Restore_Common1 ;brif exStRestore0
- Walk_Data_Stmts:
- cmp ax,di
- jbe Restore_Common1 ;brif di contains oTx we want to
- ; restore to
- DbAssertRel di,nz,UNDEFINED,CODE,<exStRestore1 error2>
- ;if di == UNDEFINED, the above branch should have been taken
- mov di,es:[di] ;move to next DATA stmt, if any
- jmp short Walk_Data_Stmts
- Restore_Common1: ;di = oTx to the link field
- ; of a DATA statement
- inc di
- .errnz UNDEFINED - 0FFFFH
- jz Restore_Common2 ;brif no DATA statements
- sub di,5 ;di = oTx to exStData
- GETRS_SEG es
- mov PTRRS[bx.MRS_data_otxCur],di
- mov PTRRS[bx.MRS_data_oLineCur],6 ; offset into current DATA stmt
- Restore_Common2:
- jmp DispMov ;NOTE: just using the 'Mov'
- ;NOTE: varient of 'Disp' so that
- ;NOTE: DI & ES will get reloaded
- ;Helper routine for B$IRDPTR and B$IRDPTRUPD, below - - - returns
- ; the segment part of the address of mrsCur in ES. Note that DATA statements
- ; are NEVER found at proc level, because QBI moves all DATA statements to
- ; module level at text insertion.
- ;Output:
- ; dx = segment of current mrs table
- ; bx = pMrsCur
- ; es = segment of the global Rs table
- ;Preserves: ax, cx
- GetDataSeg PROC NEAR
- mov bx,[grs.GRS_oMrsCur]
- RS_BASE add,bx
- GETRS_SEG es
- GETSEG dx,PTRRS[bx.MRS_txd.TXD_bdlText_seg] ;[4][2]
- ret
- GetDataSeg ENDP
- ;***
- ;B$IRDPTR - call back to give far ptr to runtime for next data item to read
- ;Input:
- ; none
- ;Output:
- ; far ptr to data item in DS:SI
- ;Destroys:
- ; ES
- ;Exceptions:
- ; Runtime error if no more data to be read
- ;*******************************************************************************
- PUBLIC B$IRDPTR
- B$IRDPTR PROC FAR
- mov bx,[grs.GRS_oMrsCur]
- RS_BASE add,bx
- GETRS_SEG es ; es:bx points to mrsCur
- mov si,PTRRS[bx.MRS_data_otxCur]
- inc si
- .errnz UNDEFINED - 0FFFFH
- jz Out_Of_Data
- dec si
- add si,PTRRS[bx.MRS_data_oLineCur] ; ax now oTx of next item to read
- call GetDataSeg ; returns seg in dx
- push dx
- pop ds
- RET
- Out_Of_Data:
- mov al,ER_OD ;Out of Data error
- call RtErrorNoSi ;never returns - runtime error
- B$IRDPTR ENDP
- ;***
- ;B$IRDPTRUPD - call back to allow us to update data ptr after a READ occurs
- ;Input:
- ; AL = 0 if last item was just read in current DATA statement, non-zero
- ; otherwise
- ; BX = Number of bytes 'eaten' by the latest READ.
- ;Output:
- ; current mrs (in the global Rs table) updated with correct data pointer
- ;Destroys:
- ; ES
- ;*******************************************************************************
- PUBLIC B$IRDPTRUPD
- B$IRDPTRUPD PROC FAR
- xchg ax,cx ;remember if @ end of DATA stmt
- xchg ax,bx
- mov bx,[grs.GRS_oMrsCur]
- RS_BASE add,bx
- GETRS_SEG es
- add PTRRS[bx.MRS_data_oLineCur],ax ; assume not end of data stmt
- or cl,cl
- jnz RTPTRUPD_Exit ;brif not end of DATA stmt
- call GetDataSeg ;seg address is in dx, Rs seg in es
- mov ax,bx
- mov bx,PTRRS[bx.MRS_data_otxCur]
- DbAssertRel bx,nz,UNDEFINED,CODE,<B$IRDPTRUPD error in exstmisc.asm>
- mov es,dx ; mrs text seg
- mov dx,es:[bx+4] ;dx = pointer to link field of
- ; next DATA stmt or UNDEFINED
- inc dx
- .errnz UNDEFINED - 0FFFFH
- jnz Not_EndOf_Data ;brif not end of data
- mov dl,4 ;so sub dx,5 will set dx = FFFF
- Not_EndOf_Data:
- xchg ax,bx
- sub dx,5 ;dx = UNDEFINED or pointer to
- ; an exStData pcode
- GETRS_SEG es
- mov PTRRS[bx.MRS_data_otxCur],dx
- mov PTRRS[bx.MRS_data_oLineCur],6
- RTPTRUPD_Exit:
- RET
- B$IRDPTRUPD ENDP
- ;==============================================================================
- ; SWAP
- ;==============================================================================
- .errnz SizeD
- MakeExe exStSwap2,opStSwap
- inc si
- inc si
- CALLRT B$SWP2,Disp
- MakeExe exStSwap4,opStSwap
- inc si
- inc si
- CALLRT B$SWP4,Disp
- MakeExe exStSwap8,opStSwap
- inc si
- inc si
- CALLRT B$SWP8,Disp
- MakeExe exStSwapSD,opStSwap
- inc si
- inc si
- pop ax
- pop bx
- xor cx,cx
- push ds
- push bx
- push cx
- push ds
- push ax
- push cx
- CALLRT B$SWPN,Disp
- MakeExe exStSwapTyp,opStSwap
- LODSWTX ;Get size to swap
- pop dx
- pop bx
- push ax ;Add length to arg on stack
- push bx
- push dx
- push ax
- CALLRT B$SWPN,Disp
- ;seg_code = segment address for the CODE segment
- ;It can be referenced from any module as follows:
- ; EXTRN seg_code:abs
- ; mov ax,SEG seg_code
- PUBLIC seg_code
- seg_code EQU SEG B$IRDPTRUPD
- sEnd CODE
- end