📄 txtload.asm
字号:
;this isn't a recursive $INCLUDE call
push ax ;save error code
call StatusMsg0CP ;tell user interface we're done loading
;Now delete any redundant DEFxxx statements which were synthetically
;generated by LoadExitProc.
mov ax,[txdCur.TXD_bdlText_cbLogical]
sub ax,CB_EMPTY_TEXT-StartOtx
cmp ax,[otxDefEnd]
je GotRedundant ;brif module-level-code couldn't have
; been inserted after last loaded proc
dec ax ;don't treat a blank line as significant
dec ax ; only a blank line could be 2 bytes
cmp ax,[otxDefEnd]
jne NoRedundant ;brif module-level-code was inserted
; after last loaded procedure
GotRedundant:
push [otxDefStart]
push ax ;pass otxDefEnd
call TxtDelete
mov si,[otxDefStart] ;update links up to deleted text
NoRedundant:
;update linked lists which thread through pcode
push [otxUpdLinks]
push si
call UpdateLinks
DbChk TxdOps ;check for bad linked lists through
; pcode, bad opcodes, etc.
pop ax ;restore al = error code
;al = fatal error code (or 0)
StillLoading:
cEnd
;*************************************************************
; MakFilename
; Purpose:
; Fill a buffer with <filename>.MAK
; Entry:
; bx points to string descriptor for source of filename
; di points to destination (must be FILNAML bytes long)
; si points to destination string descriptor
; Exit:
; ax = 0, or error code
; es = ds = dgroup
; buffer pointed to by di contains 0-terminated filename.MAK
; si.pb points to 1st byte of destination buffer
;
; Flags set on value in ax
;*************************************************************
cProc MakFilename,<PUBLIC,NEAR>,<di>
cBegin
call NormFilename ;Normalize path of filename and add
; .bas extension
; if filename doesn't already have ext.
;We now know that the filename has
; an extension, either the one supplied
; by user or .BAS
jne BadMakFileName ;brif error - AX = error code
add di,[si.SD_cb] ;di points to 0-byte terminator
;search backward for start of extension
OMakLoop:
cmp di,[si.SD_pb]
jbe OMakDone ;brif got illegal filename like "/"
dec [si.SD_cb]
dec di
cmp BYTE PTR [di],'.'
jne OMakLoop ;brif haven't found extention yet
OMakDone:
mov WORD PTR [di+1],'AM' ;append "MAK" extension
mov WORD PTR [di+3],'K' ;put K and 0-terminator in buf
add [si.SD_cb],4
BadMakFileName:
or ax,ax ;set flags
cEnd
;*************************************************************
; OpenChan
; Purpose:
; Call BASIC Runtime to open a named file.
; Entry:
; dx = open mode
; si points to string descriptor for filename
; Exit:
; [chanCur] = channel #
; al = standard error code if error (0 if not)
; condition codes set based on value in al
; Exceptions:
; assumes caller has called SetRtTrap to trap runtime errors
; like File not found, etc.
;
;*************************************************************
PUBLIC OpenChan
OpenChan PROC NEAR
call RtPushHandler ;save caller's runtime error handler
; (NOTE: alters stack pointer)
; (preserves dx)
mov ax,CPOFFSET OcExit ;if any runtime errors occur,
call RtSetTrap ; branch to OcExit with sp,di =
; current values (preserves dx)
push dx ;save open mode
call B$FREF ;ax = free channel number
pop dx ;dx = open mode
push ax ;preserve channel #
push si ;pass &sdFilenameNew
push ax ;pass channel
sub ax,ax
mov [chanCur],ax ;so CloseChan won't be called
; if error in B$OPEN
dec ax ;ax = UNDEFINED
push ax ;no record size specified
push dx ;pass open mode
call B$OPEN ;open the file. errors trapped OcExit
inc [cChansOpen] ;no error, bump # opened channels
pop [chanCur] ;save channel
call UpdChanCur ;Tell runtime to use [chanCur] for
; following I/O calls, test device type
or al,al ;is this a block device?
mov al,0
jns OcExit ;brif it is - no error
mov al,MSG_NotBlock ;"Can't load from non-block device"
;al = error code (0 if no error)
OcExit:
call RtPopHandler ;restore caller's runtime error handler
; (saved on stack by RtPushHandler)
; (preserves ax)
or al,al ;set condition codes for caller
ret
OpenChan ENDP
;*************************************************************
; CloseChan/CloseMfh (EB)
; Purpose:
; Call BASIC Runtime/OMEGA to close a file
; Entry:
; [chanCur] = the channel-#/module-file-handle to be closed
;
;*************************************************************
cProc CloseChan,<PUBLIC,NEAR>
cBegin
mov cx,[chanCur]
jcxz CcNeverOpened ;brif error before got file opened
sub ax,ax
mov [chanCur],ax ;remember channel is closed
dec [cChansOpen] ; assume close will work
push cx ;pass channel number of current load
inc ax ;ax = 1
push ax ;number of channels on stack
call B$CLOS ;close current file - no error possible
; EXCEPT int 24's.
CcNeverOpened:
cEnd
;***
;UpdChanCur
;
;Purpose:
; Near interface that uses the global 'chanCur' to make sure b$ptrfil
; is updated to reflect the current input/output channel. Should be
; called prior to using save/load I/O whenever the channel is changed,
; or ANY heap movement could have occured.
;Entry:
; chanCur assumed to be set up.
;Exit:
; AL = the device number (as returned by B$CHAN).
; The runtime b$ptrfil is updated.
;Exceptions:
; Same as B$CHAN
;*******************************************************************************
PUBLIC UpdChanCur
UpdChanCur PROC NEAR
push [chanCur]
call B$CHAN ;ensure current output channel correct
ret
UpdChanCur ENDP
;*******************************************************************************
;ModulePermanent
;Purpose:
; Set mrsCur.flags fTemporary bit to FALSE.
; This is called via ForEachCP at the successful conclusion of a LOAD
; for each text table (module and procedures) in every module.
;Entry:
; none.
;Exit:
; AX = TRUE (for ForEachCP)
;
;*******************************************************************************
ProcPerm PROC NEAR
call ClrBpTxt ;clear all breakpoints in this
; text table
;delete all Watch expressions in this text table
or [flagsTM],FTM_WatchPcode ;assume we have watch pcode
call OtxEndProg ;ax = otx to Watch pcode
inc ax ;skip opEndProg
inc ax
push ax ;pass start of block to delete
mov ax,[txdCur.TXD_bdlText_cbLogical]
.erre CB_EMPTY_TEXT - 4 EQ StartOtx
dec ax ;don't count opEot
dec ax
push ax ;pass end of block to delete
call TxtDelete
call TblReInclude
mov ax,sp ;return non-zero for ForEachCP
ProcPerm ENDP
ModulePermanent PROC NEAR
test [mrsCur.MRS_flags],FM_TEMPORARY
je MpExit ;brif this isn't one of the modules
; we just loaded
and [mrsCur.MRS_flags],NOT FM_TEMPORARY
and [mrsCur.MRS_flags2],NOT (FM2_Modified or FM2_ReInclude)
;reset modified and temp flags
test [mrsCur.MRS_flags3],FM3_Translated ; module binary xlated?
jz NotTranslated ; brif not -- FM2_Modified stays 0
and [mrsCur.MRS_flags3],NOT FM3_Translated ; reset temp flag
or [mrsCur.MRS_flags2],FM2_Modified ; mark as modified
; so it will be saved in new format
NotTranslated:
test [mrsCur.MRS_flags2],FM2_AsciiLoaded
jnz MpExit ;brif module was not binary loaded
;re-include all $INCLUDE files in this binary module
;If we did it right after calling BinaryLoad, TxtChange would
;have screwed up because it would think a LOAD was still active.
mov al,FE_CallMrs+FE_PcodePrs+FE_SaveRs
mov bx,OFFSET CP:ProcPerm
call ForEachCP
MpExit:
mov ax,sp ;return TRUE for ForEach...
ret
ModulePermanent ENDP
;**********************************************************************
; TxtGrowPsSrcEmScratch (pBd, cbNew)
; Purpose:
; Called whenever we need to grow ps.bdpSrc or bdEmScratch. The
; editmgr REQUIRES that the logical size of these buffers are
; the same. This routine takes a bd and checks to see if the passed
; bd is either ps.bdpSrc or bdEmScratch. If so, both bds are grown
; to be the same size. If the bd is not either of these then we just
; call BdRealloc. If we get OM while trying to grow either ps.bdpSrc
; or bdEmScratch, we will trim the cbLogical
; routine is a nop.
;
; Added with revision vision [68].
;
; Entry:
; pBd - ptr to bd.
; cbNew - new size of Bd
; Exit:
; AX - 0 if OM error code.
;
;**********************************************************************
cProc TxtGrowPsSrcEmScratch,<PUBLIC,FAR>,<si,di>
parmW pBd
parmW cbNew
cBegin
mov si,dataOffset bdEmScratch
mov di,dataOffset ps.PS_bdpSrc
push pBd ;pass pbdDst to BdRealloc
push cbNew ;pass cbNew to BdRealloc
call BdRealloc
or ax,ax
je TGPSES_OM ;brif out-of-memory
mov bx,di ;assume ps.bdpSrc needs grown too
cmp pBd,si ;is this bdEmScratch?
je GrowSpecBuf ;brif so - grow ps.bdpSrc too
mov bx,si ;assume bdEmScratch should grow
cmp pBd,di ;is this ps.bdpSrc?
jne TGPSES_X ;brif not - nothing special to do
; We get here if we have to grow either ps.bdpSrc or bdEmScratch. These
; two buffers must grow together for the edit mgr.
GrowSpecBuf:
push bx
push cbNew
call BdRealloc ;realloc other buffer too
or ax,ax
je TGPSES_OM ;brif OM error
TGPSES_X:
DbAssertRel ps.PS_bdpSrc.BDP_cbLogical,e,bdEmScratch.BD_cbLogical,CP,<TxtGrowPsSrcEmScratch:bdEmScratch and ps.bdpSrc not same size>
cEnd
;if we get an out of memory while growing ps.bdpSrc or bdEmScratch. Trim them
;both back to the smallest cbLogical.
TGPSES_OM:
cmp pBd,si ;is this bdEmScratch?
je TrimCbLogical ;brif so - trim back size of both
cmp pBd,di ;is this ps.bdpSrc?
jne TGPSES_X ;brif not - nothing special to do
TrimCbLogical:
mov bx,[si].BD_cbLogical ;get size of bdEmScratch
cmp bx,[di].BD_cbLogical
jb TrimPs ;trim Ps since it is larger
mov bx,[di].BD_cbLogical ;get size of ps.bdpSrc
mov [si].BD_cbLogical,bx ;set new size of bdEmScratch
jmp short TGPSES_X
TrimPs:
mov [di].BD_cbLogical,bx ;set new size of ps.bdpSrc
jmp short TGPSES_X
STKCHK_LoadFile EQU 350d ;actually 208d, add 142 for maintenance/uncertainty
;
;STKCHK_ToLoadFile is the number of bytes of stack space needed to get from
; UserInterface (where caller ensures STACK_CHECK bytes exist between sp
; and b$pend) and LoadFile().
; UserInterface->LoadFile (188d) ([67] 174d)
;
STKCHK_ToLoadFile EQU 400d ;actually 188, add 212 for maintenance/uncertainty
;*************************************************************
; ushort LoadFile(psdFilename, otxInsert)
; Purpose:
; This is called by LOAD executor, File/Load&Merge menu items,
; and recursively from TxtChange in response to $INCLUDE.
; If the filename has no extension, .BAS is appended to
; a copy of psdFilename. The copy is then 0-byte terminated.
; It opens the specified file and loads it, optionally doing
; a NEW. Based on 1st byte in file, does an ASCII or BINARY load.
; If a runtime error is encountered at any INCLUDE level,
; this function backs all the way out, returning directly to
; the caller for the 1st level of INCLUDE via RtSetTrap.
;
; Entry:
; psdFilename points to string descriptor for filename to be loaded.
; (the filename itself need not be 0-byte terminated, and
; psdFilename.cb MUST not include any 0-byte terminator)
; otxInsert = LF_NewProg if file may be ASCII or BINARY and if
; a NEW is to be performed before the load
; = LF_NewModule if file may be ASCII or BINARY and if
; a NEW is NOT to be performed before the load
; = LF_NewDoc if file is ASCII document
; = LF_ViewIncl if file is $INCLUDE file which is not
; to be loaded in-place, but into another mrs so user
; can edit it.
; = text offset into current module where text is to be inserted
; for MERGE or INCLUDE. File must be ASCII format for this.
; For example, if otxInsert == 0, file's content will be
; inserted before text offset 0.
; It is important to call TxtDescan before computing
; the text offset for the insert.
; stFileName [only used in EB] Fully qualified FileName in st format.
; OpenMode = [only used in EB] Specifies whether the input file is to
; be loaded from the active database, from a file, or
; whether this is unknown. This parameter is just passed
; through to OpenChan.
;
; Exit:
; ax = Standard BASIC error code (i.e. ER_xxx) if error occurred.
; Possible errors include Out-of-memory (ER_OM)
; file I/O errors, File-not-found (ER_FNF), Duplicate Mrs
; (MSG_DupMrs), Duplicate Prs (MSG_DupPrs)
; For all errors detected by LoadFile, txtErr.oRs is set to UNDEFINED,
; meaning no cursor positioning will take place when error is reported.
; Errors which can be represented with an opReParse are not reported
; until the user attempts to RUN the program, at which time, TxtDirect
; will re-parse and report them.
; If called by an executor, (i.e. ExStRunFile) and an untrappable error
; occurred, grs.otxCur is set to 2, in which case, the module with
; the error is grs.GRS_oRsCur and the text offset is grs.otxCur.
; If called by an executor, and a trappable error occurred,
; grs.otxCur is not altered, and the module with the error
; is grs.GRS_oRsCur and the text offset is grs.otxCur.
;
; txtErr structure is filled in with error info
; ps.bdpSrc is used.
; rsNew is set by MrsMake for all cases but Merge (this tells the
; user interface to show this rs in a list window)
; Preserves grs.fDirect in all cases (needed at least by exStRunFile
; when entered in direct mode and error (like file not found) occurs)
; Preserve's caller's runtime-error-trap handler (if any) and [chanCur]
;
;*************************************************************
J1_RtErrOmStack:
EXTRN RtErrOmStack:NEAR
jmp RtErrOmStack
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -