⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gwio.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	PUSH	SI
	PUSH	AX
	SUB	AL,32D		;make into index into soft key table
	MOV	SI,OFFSET DGROUP:B$SOFT_KEYS
	XOR	AH,AH
	SHL	AL,1		;Soft Key Table entry size is 4
	SHL	AL,1		;[AX] = Key no. * 4
	ADD	SI,AX		;Index into Soft Key Descriptor Table
	MOV	AX,[SI] 	;[AX] = Soft Key string Length
	MOV	B$SOFT_KEY_LEN,AX ;Store Length of Soft Key
	OR	AX,AX		;Null?
	POP	AX		;clean up stack
	JZ	SKEY_RET	;If null then return Scan Code
	MOV	SI,[SI+2]	;[SI] = Addr of Soft Key String
	MOV	B$SOFT_KEY_INDEX,SI ;Store index for SKEY_RD
	JMP	SHORT SKEY_RD_2 ; and return 1st character...

;SKEY_RD -	If Soft Key in Progress, return next character
;		from Soft Key String.

SKEY_RD:
	PUSH	SI
SKEY_RD_2:
	MOV	SI,[B$SOFT_KEY_INDEX]
	MOV	AL,[SI] 	;Get char from Soft Key string
	xor	ah,ah
	cmp	al,0feh 	; soft key assigned to chr$(254) ?
	jne	not_254 	; brif not
	mov	dx,0feh 	; else set [dx] to 00feh bcos $inkmap
				; assumes a three byte code if [al]=254
	mov	[dchar_save],dx ; store the same in [dchar_save] also
not_254:
	INC	[B$SOFT_KEY_INDEX]
	DEC	[B$SOFT_KEY_LEN]
SKEY_RET:
	POP	SI
	JMP	TTYINX

;***
;B$CNTRL - check for control characters during printing
;
;****

cProc	B$CNTRL,<NEAR,PUBLIC>	
cBegin				
	JMP	[B$IPOLKEY]	; wait on pause_key
cEnd	<nogen>			

	PAGE
;***
;B$DOS3CHECK - Check DOS version, return carry set if < DOS 3.00
;OEM-callback routine
;
;Purpose:
;	Common routine to check for DOS 3.  This check is made
;	several places in the runtime.	A near call and a relative
;	jump is smaller than a cmp imm,mem and relative jump.
;
;Entry:
;	__osmajor - byte containing DOS major version number - must be set.
;		     This is done before any OEM routines can be called.
;
;Exit:
;	PSW.C - Set if __osmajor < DOS 3.00
;	PSW.Z - Set if = DOS 3.00
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, BX, CX, DX
;
;Exceptions:
;	None.
;*****************************************************************************
cProc	B$DOS3CHECK,<PUBLIC,NEAR> 
cBegin				
	CMP	__osmajor,3	; check for dos 3
cEnd				

	PAGE
	SUBTTL	DEVR_INT - fatal device error interrupt handler
;***
;DEVR_INT - fatal device error interrupt handler
;
;Purpose:
;
;Entry:
; [BP:SI] = points to the device header
; [AL]	  = has drive number if block device (a=0,b=1,...)
; [DI]	  = Error code as follows:
;		00 - Write Protected.
;		01 - Unknown Unit
;		02 - Not Ready
;		03 - Unknown command
;		04 - Data Error
;		05 - Bad Drive structure length
;		06 - Seek Error
;		07 - Unknown Media
;		08 - Sector not found
;		09 - Printer out of paper
;		10 - Write Fault (hard disks only)
;		11 - Read Fault
;		12 - Other error.
;
; Special handling must be done for "Disk Write Protect"  error  due  to  some
; MS-DOS booboo.   Control  must pass to the standard INT 24h handler in order
; to clean up some (state?)  variables.  But then BASIC cannot trap the error.
; The solution	is  to	modify BASIC's parent pointer to point to itself, then
; if a write protect error occurs, DEVR_INT can  abort	to  MS-DOS  which  will
; return via the parent pointer to BASIC's error handling routine DSKERC.
;
; Note: On entry DS, ES are not pointing to BASIC.
;
;Exit:
;
;Uses:
;
;Preserves: (optional)
; SS, SP, DS, ES, BX, CX, and DX must be preserved if an IRET is executed
;
;Exceptions:
;
;******************************************************************************
DbPub	DEVR_INT		
cProc	DEVR_INT,FAR		
cBegin				
	ASSUME	DS:NOTHING, ES:NOTHING, SS:NOTHING
	STI
	PUSH	DS
	PUSH	BX
	CALL	B$GETDS
	MOV	DS,BX
	ASSUME	DS:DGROUP
	MOV	fInt24Error,-1	; set flag for QB5/COW

	CMP	b$fInt24Err,0	;Should we IGNORE this error?
	JZ	TestWriteProtect ;brif not, test for a write protect sequence

	MOV	b$fInt24Err,DI ; save error in b$fInt24Err
	OR	b$fInt24Err,0FF00h; insure b$fInt24Err does not go to 0.
	JMP	SHORT IgnoreInt24 ;ignore this error

TestWriteProtect:		

	CMP	BYTE PTR [WPRFLG],0 ;Are we in a write protect INT 24 Seqenc
	JZ	DSKER1		;Brif not

IgnoreInt24:			
	XOR	AX,AX		;Tell DOS to ignore the error
	pop	bx
	pop	ds
	IRET			;Back to DOS - ignore dirty buffers

DSKER1: 			;Here if Write protect flag not set
	CLI			; Critical section below.  A second
				; interrupt would blow away the first one
	PUSH	BX		; save basic DGROUP
	MOV	BX,SP		; get psuedo frame pointer
	MOV	CX,[BX+24]	; [CX] = [BP] at INT 21H time (documented)
	POP	BX		; restore basic DGROUP
	mov	es,bx		; ES = DGROUP
	mov	ss,bx		; restore BASIC's stack 
	mov	sp,cx		; new stack pointer = previous BP

	; Stack now back to where it was just after the:
	;	PUSH	BP
	;	MOV	BP,SP
	; of the runtime entry point that caused the error.

	assume	ds:dgroup, es:dgroup, ss:dgroup
	STI			;Turn interrupts back on
	.erre	ID_SSEQDS	; assumes ss equals ds.
	push	cx		; save old BP for later

	mov	cx,di		;get device error into cl
	mov	DEVICE,AL	; device
	AND	AH,80H		;test for char dev or bad FAT
	JZ	CHRDEV		;not either, so not char dev
	PUSH	DS		
	MOV	DS,BP		; get device header segment
	TEST	BYTE PTR DS:[SI+4],80H ; test for character device
	POP	DS		
	JZ	CHRDEV		;jump if char dev, not block dev

	XOR	AH,AH		;clear flag for no char device
CHRDEV:
	mov	al,cl		;error code into al
	mov	DERRCD,AX	; Save error code and device type bit
	assume	es:nothing
	test	al,255		; Is this a write protect error?
	jnz	noprtct 	; Yes: return to MS-DOS with abort request
;	---------------------------	;Mark begining of Wr-Pro Sequence
	mov	byte ptr [wprflg],1 ;"Zibo" method of handling INT 24
	callos	REST		;from write protects.  Forces DOS
	mov	byte ptr [wprflg],0 ;to REALLY ignore error and discard
;	---------------------------	;pending dirty buffers.
noprtct:
	MOV	EXTFLG,0	;no violation yet
	CALL	B$GETEXTERR	; psw.c set if <dos 3
;	JB	NO_VIOLATION	;if DOS2, then branch
	JNZ	NO_VIOLATION	; ZF=1 if violation
	INC	EXTFLG		;set violation flag
NO_VIOLATION:
	callos	VERSN		;Do this for good luck. clears unstable dos
				;state

;Control is passed here after a hard disk error (INT 24H).
;	  Now we decide what the error is and JMP to its error handler.
; Entry DS, ES undefined

	mov	ax,DERRCD	; Restore error code
	MOV	BX,OFFSET DGROUP:b$ERDEVP ;[BX]= ptr to ERDEV$ sd
	TEST	AH,80H		;Character device ?
	jnz	devr_2		;Yes: go copy name
				;No: block oriented device (disk)
	mov	WORD PTR[BX],2	;device name length to 2
	MOV	BX,[BX+2]	;get ptr to erdev$ string
	mov	word ptr [BX],":A" ;damn hi/low
	mov	ch,DEVICE
	add	byte ptr [BX],ch ;set name
	jmp	short devr_3
devr_2:
	PUSH	DS		;save basic data segment
	MOV	DS,BP		;point to device header segment
	add	si,10		;get to character device name
	mov	cx,8
	mov	es:[BX],cx	;store name length
	mov	di,ES:[BX+2]	;target
	cld
	rep	movsb
	pop	ds		;get back ds
devr_3:
	POP	BP		; get frame at error time
	mov	b$ERDEV,ax	;save in error variable
	CALL	[b$pTEST_CLOSE] ; If closing, close it w/o error checks
	CMP	EXTFLG,0	;violation?
	JNZ	FWP		;if so, then PERMISSION DENIED
	cmp	al,0		;Write protected ?
	jz	dwp
	cmp	al,1		;Device available ?
	je	dna		; no
	cmp	al,9		;no paper ?
	je	nopaper
	cmp	al,10		;device fault ?
	je	dvf
	TEST	AH,80H		;Character device ?
	jnz	devr_4		; yes
	cmp	al,2		;disk not ready
	je	dnr
	cmp	al,7		;disk media error
	je	dme
	jmp	short ioe	;device i/o error
devr_4:
	cmp	al,2		;timeout ?
	je	dto
IOE:
	JMP	B$ERR_IOE	; device i/o error

cEnd	<nogen>			

;***
;B$GETEXTERR -- get extended error info.
;
;Purpose:
; Return extended error info, if available.
; Redone, edit [24]
;
;Entry:
; None
;
;Exit:
; CF (and NZ):	No extended info available (running under < DOS 3.x)
; NC:	[AX] = extended error code
;	ZF	if error was either sharing violation or locking violation
;	NZ	Some other error
;
;Uses:
; If C1: nothing, else only AX.
;
;Preserves: (optional)
; BX, CX, DX
;
;******************************************************************************
cProc	B$GETEXTERR,<NEAR,PUBLIC>,<BX,CX,DX,SI,DI,BP,DS,ES> ; extended
				; error call destroys all these
cBegin
	cCall	B$DOS3CHECK	;See if we're DOS 3 or not
	JC	GETEXTERR_90	;just exit if not
	XOR	BX,BX		;clear for call...
	MOV	AH,59H		;extended error code
	INT	21H		;do the call
	CMP	AX,20H		;test if sharing violation
	JE	GACERR_10	;if so, then return it
	CMP	AX,21H		;test if lock violation
GACERR_10:
	CLC			;C0 means okay
GETEXTERR_90:

cEnd


DTO:
	JMP	B$ERR_DTO	
DVF:
	JMP	B$ERR_DVF	
NOPAPER:
	JMP	B$ERR_OTP	
DNA:
	JMP	B$ERR_DNA	

DME:
	JMP	B$ERR_DME	; give disk media error

DWP:				;permission denied due to write protection
FWP:				;permission denied due to open violation
	JMP	B$ERR_FWP	; give permission denied error

DNR:
	JMP	B$ERR_DNR	; give disk not ready error

	PAGE

;***
; B$IOCLOS - Run-time initialization
;
;Purpose: To deinstall handlers for Divide by zero, Oveflow and I/O interrupts.
;
;Entry:
;	None
;Exit:
;	None
;Modifies:
;	Per convention
;Exceptions:
;	None
;
;****

cProc	B$IOCLOS,<PUBLIC,NEAR>	
cBegin				

ASSUME	ES:DGROUP		
ASSUME	DS:NOTHING

	XOR	AX,AX		;Clear segment
	PUSH	DS		;Save DS
	PUSH	DS		; Restore ES
	POP	ES
	MOV	DS,AX		;Set DS to 0:xxxx
	PUSHF			;Save interrupt status
	CLI			;Turn off interrupts
	RSTVEC	0,ES:DIV0_SAVE
	RSTVEC	4,ES:OVRF_SAVE
	RSTVEC	24h,ES:DEVR_SAVE
	POPF			;Restore interrupts
	POP	DS		;Restore DS

ASSUME	DS:DGROUP


cEnd				; End of B$IOCLOS

sEnd	DV_TEXT 		
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -