gwini.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:16k
源码类别:
操作系统开发
开发平台:
Visual C++
- TITLE GWINI - GW BASIC 2.0 Initialization/Utility Routines
- ;***
- ; GWINI - GW BASIC 2.0 Initialization/Utility Routines
- ;
- ; Copyright <C> 1986, Microsoft Corporation
- ;
- ;Purpose:
- ;
- ; The routines in this module are always called; regardless of
- ; whether the statements they are initializing are found in the
- ; program or not. This module should not cause any statement
- ; processing module to be linked in (i.e. only low-level routines
- ; should be called).
- ;
- ;******************************************************************************
- INCLUDE switch.inc
- INCLUDE rmacros.inc ; general runtime macros
- UseSeg _BSS
- UseSeg _DATA
- UseSeg ER_TEXT
- UseSeg RT_TEXT
- INCLUDE seg.inc ; Segment definitions
- INCLUDE baslibma.inc
- INCLUDE files.inc
- INCLUDE nhutil.inc
- INCLUDE idmac.inc ; Internal debugging macros
- INCLUDE const.inc ; bit flag constants
- INCLUDE rtps.inc ; constants shared with QBI
- .radix 10
- sBegin _DATA
- globalW b$pCommSave,Near_Ret,1 ; conditional vector to B$CommSave
- globalW b$pCommRestore,Near_Ret,1 ; conditional vector to B$CommRestore
- ; b$TempSD is a general purpose string descriptor for temporary use
- globalW b$TempSD,?,2 ; handle (ppData) & SB
- externB b$CRTWIDTH ; Physical width
- externB b$SCRNWIDTH ; Logical width
- externB b$WDOBOT
- externB b$WDOTOP
- externW b$CURSOR ; (1,1)-relative screen cursor
- externB b$LINCNT
- externW b$VWINI_PTR ;Calls B$GRPINI once initialized
- externW __aenvseg
- ; Added with revision [28]
- ;***
- ;b$IOFLAG - General Purpose IO Bits
- ;OEM-callback routine (variable)
- ;
- ;Purpose:
- ; This variable keeps track of the global state of the I/O module.
- ; Most of the bits in the flag variable are used to handle all the
- ; different cases for I/O redirection.
- ;
- ;Allocation:
- ; b$IOFLAG is a BYTE value declared in the _DATA segment by
- ; the OEM-Independent code.
- ;
- ;Values:
- ; Field definitions of b$IOFLAG are in CONST.INC. Initially, all
- ; fields are set to 0.
- ;
- ; RED_INP is a bit that is set when input from stdin is being redirected
- ; from a file. This field is set during console initialization
- ; by the runtime and is not changed. (01H)
- ;
- ; RED_OUT is a bit that is set when output stdout is being redirected
- ; to a file. This field is set during console initialization
- ; by the runtime and is not changed. (02H)
- ;
- ; LPR_ECHO is a bit that is set when output to the screen is being
- ; echoed to the line printer. Its value does not affect redirected
- ; IO, but the printer will not echo redirected output. (04H)
- ; This field is set/cleared when the Print Scrn key is recognized.
- ;
- ; F_KDSP is a bit that is set when currently updating a function key
- ; display, and output should not be sent to the printer or a
- ; redirected file. A special routine to map the function keys
- ; is called when this is true. (08H)
- ;
- ; IN_INPUT is a bit that is set when redirected output to stdout is
- ; to be inhibited. This is when an INPUT statement is being
- ; processed, and the user is editing his input. Not until the
- ; user hits <return> is the data entered sent to the redirected
- ; file, so that the editing corrections are not present.
- ; However, while IN_INPUT is set , output will go to the screen,
- ; using screen cursor values. (10H)
- ;
- ; F_EDIT is a bit that is set when in the INPUT statement, and B$PRTMAP
- ; should be disabled as B$EDTMAP does the mapping. (20H)
- ;
- ; SCN_INIT is a bit that is set to indicate that the screen has been
- ; physically initialized. This field is set by the OEM at the
- ; time the screen is actually initialized (B$SCINIT). (40H)
- ;
- ; SCN_SCROLL is a bit indicating that we need to scroll the screen
- ; upon the first screen operation because we entered on the last
- ; line of the screen. This flag is only used by the OEM before
- ; the screen has been physically initialized. (80H)
- ;
- ;Initially Set:
- ; RED_INP is set by the OEM-Independent code before B$GWINI or
- ; B$RTLLINIT are called.
- ; RED_OUT is set by the OEM-Independent code before B$GWINI or
- ; B$RTLLINIT are called.
- ; LPR_ECHO is statically initialized to be 0.
- ; F_KDSP is statically initialized to be 0.
- ; IN_INPUT is statically initialized to be 0.
- ; F_EDIT is statically initialized to be 0.
- ; SCN_INIT is statically initialized to be 0.
- ; SCN_SCROLL is statically initialized to be 0.
- ;
- ;Modified By:
- ; RED_INP and RED_OUT should not be modified once initialized.
- ; LPR_ECHO is modified by the OEM-Independent code upon detection
- ; of the Print Screen Key and upon a RUN command.
- ; F_KDSP is set at the beginning of the function key update routines
- ; and cleared at the end of them.
- ; IN_INPUT and F_EDIT are set and cleared by the Screen Editor
- ; SCN_INIT and SCN_SCROLL are only modified by the OEM-Dependent code.
- ;
- ;Used By:
- ; All the fields of b$IOFLAG except for SCN_INIT and SCN_SCROLL are
- ; only used by the OEM-Independent Code. SCN_INIT is used by both
- ; the OEM-Dependent code and the termination code. If SCN_INIT
- ; is 1 at termination time, then B$RESETSCN will be called. Otherwise
- ; B$RESETSCN will not be called by the termination code. SCN_SCROLL
- ; is not used by the OEM-Independent Code in any way. This flag
- ; may be used for any purpose.
- ;****
- globalB b$IOFLAG,0 ; general-purpose IO bits defined above.
- ;***
- ;b$vKEYDSP - Vector for indirect call to B$KEYDSP, display/clear function keys
- ;OEM-callback routine (variable)
- ;
- ;Purpose:
- ; Update the function key display. If b$KEY_SW is set to 0 then
- ; the function key display is disabled and is removed from the
- ; screen if it existed. If b$KEY_SW is set to -1, then the
- ; function key display is enabled and is displayed on the screen
- ; if needed.
- ;
- ; This routine is called indirectly through the vector
- ; b$vKEYDSP
- ;
- ;Entry:
- ; B$KEY_SW set appropriately: 0 = turn off function key display
- ; -1 = display function keys.
- ;
- ;Exit:
- ; None.
- ;
- ;Uses:
- ; Per Convention
- ;
- ;Preserves:
- ; AX, BX, CX, DX
- ;
- ;Exceptions:
- ; Just returns unless B$KEYDSP is linked in by B$INPP or B$KFUN.
- ;
- ;Vector Information:
- ; b$vKeyDSP is a WORD value defined in the _DATA segment by the
- ; OEM-Independent code. It is set up by an initializer before
- ; the BASIC runtime is first called. It should not be modified.
- ;******************************************************************************
- globalW b$vKEYDSP,Near_Ret,1
- sEnd _DATA
- sBegin _BSS
- externB b$KEY_SW ;GWDATA -
- externW B$WNDWSW ;GWDATA -
- ;***
- ; b$HugeShift, b$HugeDelta - OS selector shift count for HUGE access
- ;OEM-callback routine (variable)
- ;
- ;Purpose:
- ; This value is used to access successive pieces of a
- ; HUGE array. To get to the next segment of memory in
- ; which the array exists, use the following formula:
- ; (assuming that the array is accessed through DS:)
- ;
- ; DS: = DS: + (1 << b$HugeShift)
- ;
- ; The value (1 << b$HugeShift) is precomputed and stored
- ; in the variable b$HugeDelta.
- ;
- ; NOTE: For DOS, these variables are guarenteed to be identical
- ; each time the program is run and could be replaced by
- ; constants.
- ;
- ;Allocation:
- ; b$HugeShift is a BYTE value defined in the _BSS segment by
- ; the runtime code.
- ;
- ; b$HugeDelta is a WORD value defined in the _BSS segment by
- ; the runtime code.
- ;
- ;Values:
- ; The values for b$HugeShift and b$HugeDelta are dependent upon
- ; the operating system. Both variables are initialized by the
- ; runtime during runtime initialization and should not be changed.
- ;
- ;Initially Set:
- ; The values of these variables are undefined until they are set
- ; at initialization time. They are initialized after B$GWINI and
- ; and B$RTLLINIT are called but before any user code is executed
- ; or interpreted.
- ;
- ;Modified By:
- ; These variables should not be modified once they are initialized.
- ;
- ;Used By:
- ; These variables are used by anyone who wants to access a dynamic
- ; array bigger than 64K.
- ;****************************************************************************
- globalB b$HugeShift,? ;OS selector shift count for HUGE access
- ;NOTE: this uses an extra byte from
- ;b$HugeDelta when we pass b$HugeShift to
- ;DOSGETHUGESHIFT (which returns a WORD)
- globalW b$HugeDelta,? ;OS selector seg increment for HUGE access
- ;***
- ;b$Buf1, b$Buf2 - temporary buffer space
- ;OEM-callback routine (variable)
- ;
- ;Purpose:
- ; Both b$Buf1 and b$Buf2 are large buffers of temporary storage
- ; for general use. These buffers are used in many places
- ; throughout the runtime. While it is theoretically possible for
- ; the OEM code to use either or both of these buffers any time they
- ; are not in use, there is no way to determine whether they are being
- ; used. The mechanism in the rest of the runtime for determining
- ; availability is visual inspection and use of the routines
- ; B$HoldBuf(n) and B$FreeBuf(n) which do not exist in a release
- ; version.
- ;
- ; These buffers are mainly described here for the understanding
- ; of the sample code supplied by MicroSoft. However, there are a
- ; couple of specific times the buffers are guaranteed to be free,
- ; which are described below.
- ;
- ; Note that b$Buf2 immediately follows b$Buf1, so if both are
- ; available you have a block of 258 contiguous bytes of DGROUP.
- ;
- ;Allocated:
- ; b$Buf1 is a block of 129 BYTES allocated in _BSS by the runtime.
- ; b$Buf2 is a block of 129 BYTES allocated in _BSS by the runtime.
- ;
- ;Values:
- ; Undefined
- ;
- ;Initially Set:
- ; Undefined
- ;
- ;Modified By:
- ; Undefined
- ;
- ;Used By:
- ; b$BUF1 is guaranteed to be available during the calls to
- ; B$GWINI and B$RTLLINI. Furthermore, it is guaranteed
- ; that the value of b$BUF1 will not change between these
- ; two calls.
- ; b$BUF2 is guaranteed to be available with the same conditions as
- ; b$BUF1. Also, b$BUF2 will be available for use during
- ; the execution of any of the routines in LLCOM5.ASM.
- ; However, the contents of the buffer may change between
- ; calls to these routines.
- ;******************************************************************************
- ;
- ; NOTE -- Any (or all) of these LARGE buffers can be used by anyone
- ; that wants to, provided they are not used in a calling routine.
- ; IN DEBUG CODE, call B$HoldBuf(1,2,12,3) to allocate the the buffers to
- ; your routine, and B$FreeBuf(1,2,12,3) to release the buffers.
- ;
- ;#########
- labelB <PUBLIC,b$PATHNAM> ; pathname buffer
- globalB b$Buf1,,FILNAML ; 1st large (pathname-sized) scratch buffer
- globalB b$Buf2,,FILNAML ; 2nd large (pathname-sized) scratch buffer
- globalB b$Buf3,,16 ; 3rd scratch buffer
- ; these buffers MUST remain contiguous
- sEnd _BSS
- sBegin RT_TEXT
- assumes cs,RT_TEXT
- PAGE
- SUBTTL Screen initialization
- ;***
- ; B$WHOME - Home the text cursor
- ; Moved here from iotty.asm with revision [60]. See note below!
- ;
- ; Input:
- ; b$WDOTOP set
- ; Output:
- ; [DL] == home row of cursor
- ; [DH] == home column of cursor
- ; Modifies:
- ; NONE
- ; Note:
- ; IMPORTANT: Must be kept in sync with the local WHOME routine in iotty.asm
- ;****
- cProc B$WHOME,<PUBLIC,NEAR>
- cBegin
- MOV DL,b$WDOTOP
- MOV DH,1
- cEnd
- ;***
- ; B$CRLF - Adust cursor row/column while doing a CR/LF. [61]
- ; Added with [60].
- ;
- ; Purpose:
- ; This routine is called every time a CR/LF is to be output
- ; to the screen. It checks whether the screen will need to be
- ; scrolled and if not, increments DL. Flags are set indicating
- ; whether or not the screen must be scrolled. DH is set to 1.
- ;
- ; Entry:
- ; DL = current line
- ;
- ; Exit:
- ; DH = 1
- ; DL = new line
- ; ZF ==> didn't change DL, since on last line
- ; NZ ==> changed DL, since not on last line
- ;
- ; Modifies:
- ; None
- ;****
- cProc B$CRLF,<PUBLIC,NEAR>
- cBegin
- MOV DH,1 ; reset cursor column to 1
- CMP DL,b$LINCNT ; on status line?
- JNE NOT_STATUS ; brif not -- don't adjust line
- MOV DL,b$WDOBOT ; move cursor to bottom
- ; line of text window
- NOT_STATUS:
- CMP b$WDOBOT,DL ; Are we at bottom of window?
- JE NO_INC ; brif so -- ZF ==> last line
- INC DX ; increment row (NZ)
- NO_INC: ; return with flags set
- cEnd
- ;***
- ;B$SCNCLR - Home Text & Graphics Cursor, Refresh Function Key Display
- ;OEM-callback routine
- ;
- ; Re-written with revision [54].
- ;
- ;Purpose:
- ; This routine is used to initialize the screen editor, reset
- ; the graphics viewport and window to the screen dimensions,
- ; center the graphics cursor, home the text cursor and display
- ; the function keys if needed.
- ;
- ; This routine must be called at initialization and whenever
- ; screen characters are no longer accessible to the user because
- ; the screen dimensions have changed. This routine should only
- ; be called from B$SCRSTT, B$SWIDTH, B$RESETSCN, and during
- ; initialization.
- ;
- ;Entry:
- ; None.
- ;
- ;Exit:
- ; None.
- ;
- ;Uses:
- ; Per Convention
- ;
- ;Preserves:
- ; BX, CX, DX
- ;
- ;Exceptions:
- ; None.
- ;****
- cProc B$SCNCLR,<NEAR,PUBLIC>
- cBegin
- CALL B$WHOME ; DX=text cursor home
- MOV b$CURSOR,DX ; update b$CURSOR
- CALL [b$vKEYDSP] ; Conditionally display softkeys
- ; (displays user cursor at position
- ; b$CURSOR when done)
- cEnd <nogen> ; fall into B$VIEWINIT
- ; Added as part of revision [30]
- ;***
- ;B$VIEWINIT - Initialize viewport, center graphics cursor
- ;OEM-callback routine
- ;
- ;Purpose:
- ; Initialize the graphics viewport and centers the graphics cursor.
- ; Sets the logical coordinate system to be identical to the
- ; physical coordinate system (disable WINDOW command).
- ;
- ;Entry:
- ; None
- ;
- ;Exit:
- ; None
- ;
- ;Uses:
- ; Per Convention
- ;
- ;Preserves:
- ; AX, BX, CX, DX
- ;
- ;Exceptions:
- ; None.
- ;****
- cProc B$VIEWINIT,<NEAR,PUBLIC>
- cBegin
- CALL [b$VWINI_PTR] ;Initialize viewport, center graphics cursor
- MOV B$WNDWSW,0 ;Turn B$WNDWSW and B$WNDWSC off
- Near_Ret: ;near ret for vectors
- cEnd
- ;***
- ;B$SCNSWI - Set screen width(logical/physical) and height
- ;OEM-callback routine
- ;
- ;Purpose:
- ; B$SCNSWI will set the screen width (both logical and physical)
- ; and screen height. Since this routine is used to communicate
- ; the screen dimensions to the Screen Editor, it must be called at
- ; initialization and whenever the character dimensions of the
- ; screen are modified.
- ;
- ;Input:
- ; AL=width, CL=height
- ;
- ;Output:
- ; None.
- ;
- ;Uses:
- ; Per Convention
- ;
- ;Preserves:
- ; AX, BX, CX, DX
- ;
- ;Exceptions:
- ; None.
- ;****
- cProc B$SCNSWI,<PUBLIC,NEAR>
- cBegin
- MOV b$CRTWIDTH,AL ; Set physical width of screen
- MOV b$SCRNWIDTH,AL ; Set SCRN: logical width
- MOV B$LINCNT,CL ;Save physical height
- MOV b$WDOTOP,1 ;Init window top
- PUSH CX
- DEC CL ; Reserve status line
- MOV b$WDOBOT,CL ;Set window bottom
- POP CX
- cEnd ; End of B$SCNSWI
- ;***
- ;B$UPCASE - Convert Character to Upper Case
- ;DBCS-callback
- ;
- ;Purpose:
- ; Convert the character in AL to uppercase if possible. If it is
- ; not a character or it is already uppercase, it is not modified.
- ; This is done by a comparison against the range 'a'-> 'z'. It does
- ; not use the Operating System call to case convert characters
- ; outside of this range.
- ;
- ; NOTE: It is the caller's responsibility to make sure that it is
- ; not sending 1/2 of a KANJI character to this routine.
- ;
- ; WARNING: Because this routine is called by B$GETCH
- ;
- ; DS != DGROUP
- ;
- ; If you go to change the code, keep this in mind!!!
- ;Entry:
- ; AL = Character to convert
- ;
- ;Exit:
- ; AL = UpperCase version of character
- ;
- ;Uses:
- ; Per Convention
- ;
- ;Preserves:
- ; AH, BX, CX, DX
- ;
- ;Exceptions:
- ; None.
- ;****
- cProc B$UPCASE,<PUBLIC,NEAR>
- cBegin
- CMP AL,'a' ;Is AL < 'a'
- JB upret ;Skip it
- CMP AL,'z' ;Is AL > 'z'
- JA upret ;Skit it
- upit:
- AND AL,255-' ' ;Convert to Upper Case
- upret:
- cEnd
- ;***
- ;B$Mul32x16 -- 32 by 16 bit multiply
- ;
- ;Purpose:
- ; Added with revision [68].
- ;
- ;Entry:
- ; [DX|AX] = multiplicand
- ; [CX] = multiplier
- ;
- ;Exit:
- ; [DX|AX] = [DX|AX] * [CX]
- ; CF ==> overflow
- ;
- ;Uses:
- ; BX
- ;
- ;Preserves
- ; CX
- ;
- ;Exceptions:
- ; None
- ;
- ;******************************************************************************
- cProc B$Mul32x16,<PUBLIC,NEAR>
- cBegin
- xchg bx,dx ; [BX|AX] = multiplicand
- mul cx ; multiply low word by 1000 ([DX|AX] = result)
- push ax ; save low word result
- push dx ; save first overflow
- xchg ax,bx ; AX = high word
- mul cx ; [DX|AX] = result of high word multiply
- pop dx ; DX = original high word
- jc Overflow ; brif overflow (need to clean stack)
- add ax,dx ; AX = high word of result (PSW.C if overflow)
- xchg ax,dx ; DX = high word of result
- OverFlow:
- pop ax ; AX = low word of result
- cEnd
- page
- sEnd RT_TEXT
- END