ioctl.asm

来自「Dos6.0」· 汇编 代码 · 共 1,204 行 · 第 1/2 页

ASM
1,204
字号
ss_while:
	cmp	[si].V_MODE,UNOCCUPIED		; while we have valid entries
	jz	ss_not_found

	mov	al,INT10_V_Mode

	cmp	al,0ffh				; if not issued by Int10 set mode,
	jnz	ss_from_set_mode

	
	mov	al,es:[di].RP_MODE		; load register for compare.
	cmp	[si].D_MODE,al			; match?
	jnz	ss_end_while

	mov	ax,es:[di].RP_COLORS		; yes...prepare next field
	cmp	[si].COLORS,ax			; match?
	jnz	ss_end_while

	cmp	es:[di].RESERVED2,0		; yes, ensure reserved byte is zero
	jnz	ss_end_while

	cmp	es:[di].RP_MODE,GRAPHICS_MODE	; for graphics mode
	jnz	ss_not_graphic			; check the following:

	mov	ax,es:[di].RP_WIDTH		; screen width.
	cmp	[si].SCR_WIDTH,ax
	jnz	ss_end_while

	mov	ax,es:[di].RP_LENGTH		; screen length
	cmp	[si].SCR_LENGTH,ax
	jnz	ss_end_while			; ignore #rows and #coloumns

	jmp	short ss_found

ss_not_graphic:
	mov	ax,es:[di].RP_COLS		; the rows are matched
	cmp	[si].SCR_COLS,ax		; in the main routine
	jnz	ss_end_while

ss_found:
	clc
	jmp	short ss_done

ss_from_set_mode:
	cmp	[si].V_MODE,al			; if V_MODE = AL, we are ok
	jz	ss_found

ss_end_while:
	add	si,type MODE_TABLE		; then, this is not the correct entry.
	loop	ss_while			; Let's find the next entry.

ss_not_found:
	stc

ss_done:
	mov	INT10_V_Mode, 0FFh		; Done. Reset the value
	ret

SET_SEARCH	ENDP




; PROCEDURE_NAME: GET_SEARCH

; FUNCTION:
; THIS PROCEDURE SEARCHES THE VIDEO TABLE LOOKING FOR A MATCHING
; VIDEO MODE.

; AT ENTRY: DS:SI POINTS TO VIDEO TABLE
;		AL CONTAINS THE MODE REQUESTED

; AT EXIT:
;	NORMAL: CARRY CLEAR, DS:SI POINTS TO MATCHING RECORD

;	ERROR: CARRY SET

; WARNING: TRASH CX

GET_SEARCH	PROC	NEAR

	mov	cx,MAX_VIDEO_TAB_NUM		; # of total tables

gs_while:
	cmp	[si].V_MODE,UNOCCUPIED		; while we're not pointing to
	jz	gs_error
	cmp	[si].V_MODE,al			; the right mode and we are still
	jz	gs_got_it

	add	si,TYPE MODE_TABLE		; point to the next mode
	loop	gs_while

gs_error:
	stc					; no, set error flag
	ret

gs_got_it:
	clc
	ret

GET_SEARCH	ENDP



; PROCEDURE_NAME: SET_CURSOR_EMUL

; FUNCTION:
; THIS PROCEDURE SETS THE CURSOR EMULATION BIT OFF IN ROM BIOS. THIS
; IS TO PROVIDE A CURSOR ON THE EGA WITH THE 5154 LOADED WITH AN 8X8
; CHARACTER SET.

; AT ENTRY:

; AT EXIT:
;	NORMAL: CURSOR EMULATION BIT SET FOR APPLICABLE HARDWARE

;	ERROR: N/A



SET_CURSOR_EMUL PROC	NEAR

	test	HDWR_FLAG,E5154_ACTIVE		; EGA with 5154?
	jz	sce_done

	push	si
	push	ds				; yes..so..
	mov	ax,ROM_BIOS			; check cursor emulation..
	mov	ds,ax
	mov	si,CURSOR_FLAG
	mov	al,BYTE PTR [si]

	cmp	cs:REQ_TXT_LENGTH,DEFAULT_LENGTH; >25 lines req?
	jnz	sce_cursor_on

	and	al,TURN_OFF			; no....set it OFF

	jmp	short sce_cursor_ok

sce_cursor_on:
	or	al,TURN_ON			; yes...set it ON

sce_cursor_ok:
	mov	BYTE PTR [si],AL
	pop	ds
	pop	si

sce_done:
	ret					; return to calling module

SET_CURSOR_EMUL	ENDP




; PROCEDURE_NAME: INT10_COM

; FUNCTION:
; THIS IS THE INTERRUPT 10H HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:

;	AH=1H (SET CURSOR TYPE). CURSOR EMULATION IS PERFORMED IF WE HAVE
;		AND EGA WITH A 5151 MONITOR, AND 43 LINES IS REQUESTED.

;M002; What is bellow was modified. The /L option was removed. But ansi
;M002; will still do a GET_IOCTL/SET_IOCTL for the application.
;	AH=0H (SET MODE) SCREEN LENGTH IS MAINTAINED WHEN POSSIBLE. (IE. IN
;		TEXT MODES ONLY.)
;	AN004; Capturing Set Mode call and enforcing the # of Rows based on the
;		previous Set_IOCTL request lines was a design mistake.	ANSI cannot
;		covers the all the application program out there which use INT 10h
;		directly to make a full screen interface by their own way.
;		This part of logic has been taken out by the management decision.
;		Instead, for each set mdoe INT 10h function call, if it were not
;		issued by SET_IOCTL procedures itself, or by DISPLAY.SYS program,
;		then we assume that it was issued by an APPS, that usually does not
;		know the new ANSI GET_IOCTL/SET_IOCTL interfaces.
;		In this case, ANSI is going to call GET_IOCTL and SET_IOCTL function
;		call - This is not to lose the local data consistency in ANSI.

; AT ENTRY:

; AT EXIT:
;	NORMAL:

;	ERROR:



INT10_COM	PROC	NEAR

	sti 					; restore interrupts
	cmp	ah,SET_CURSOR_CALL
	jz	SET_CURSOR_HANDLER
	cmp	ah,SET_MODE
	jz	SET_MODE_HANDLER

	jmp	DWORD PTR cs:ROM_INT10		; no...pass it on.

SET_CURSOR_HANDLER:
	push	ax

	test	cs:HDWR_FLAG,E5151_ACTIVE	; do we have an EGA?
	jz	sch_goto_rom
	cmp	cs:REQ_TXT_LENGTH,DEFAULT_LENGTH
	jz	sch_goto_rom
	cmp	cs:GRAPHICS_FLAG,TEXT_MODE	; with 5151..so perform cursor mapping
	jnz	sch_goto_rom
	cmp	cl,8
	jl	sch_goto_rom

	mov	al,ch				; check for cursor..
	and	al,60h				; off emulation. J.K.

	cmp	al,20h
	jz	sch_goto_rom

	mov	al,ch				; start position for cursor
	call	MAP_DOWN
	mov	ch,al
	mov	al,cl				; end position for cursor
	call	MAP_DOWN
	mov	cl,al

sch_goto_rom:
	pop	ax
	jmp	DWORD PTR CS:ROM_INT10		; continue interrupt processing

SET_MODE_HANDLER:
	pushf					; prepare for IRET
	mov	cs:ANSI_SetMode_Call_Flag, 1	; Used by INT2F_COM
	call	DWORD PTR CS:ROM_INT10		; call INT10 routine
	mov	cs:ANSI_SetMode_Call_Flag, 0	; Reset it
	push	bp
	push	es
	push	ds
	push	si
	push	di
	push	dx
	push	cx
	push	bx
	push	ax
	push	cs
	pop	ds
	mov	ah,REQ_VID_MODE			; get current mode..
	pushf
	call	DWORD PTR ROM_INT10
	and	al,VIDEO_MASK			; mask bit 7 (refresh)
	test	In_Generic_IOCTL_Flag, (I_AM_IN_NOW + SET_MODE_BY_DISPLAY)	; Flag is on?
;If not (I_AM_IN_NOW or SET_MODE_BY_DISPLAY),

	jnz	smh_ioctl_done

;	cmp	SWITCH_L,0			;M002; No more /L
;	jnz	smh_ioctl_done			;M002; No more /L

	push	ax				;Save mode
	push	es
	push	cs
	pop	es
	mov	di,offset My_IOCTL_Req_Packet
	mov	INT10_V_Mode,al			;Save current mode for SET_SEARCH
	call	Get_IOCTL

	jc	smh_set_ioctl_done

	or	In_Generic_IOCTL_Flag, CALLED_BY_INT10COM ;Do not set mode INT 10h again. Already done.
	call	Set_IOCTL
	and	In_Generic_IOCTL_Flag, not CALLED_BY_INT10COM

smh_set_ioctl_done:

	pop	es
	pop	ax				;Restore mode
	mov	INT10_V_Mode,0FFh


smh_ioctl_done:

	lea	si,VIDEO_MODE_TABLE
	call	GET_SEARCH 			; look through table for mode selected.
	jc	smh_graphic_mode		; M001; if not found then
						; M001; assume graphic mode

	cmp	[si].D_MODE,TEXT_MODE		; text mode?
	jz	smh_text_mode

smh_graphic_mode:
	mov	GRAPHICS_FLAG,GRAPHICS_MODE	; no, set graphics flag
	jmp	short smh_flag_done

smh_text_mode:
	mov	GRAPHICS_FLAG,TEXT_MODE		; set TEXT MODE


smh_flag_done:

;	test	In_Generic_IOCTL_Flag, I_AM_IN_NOW
;	jnz	smh_l_done			; M002; No more /L
;	cmp	Graphics_Flag,TEXT_MODE		; M002; No more /L
;	jnz	smh_l_done			; M002; No more /L
;	cmp	SWITCH_L,1			; M002; No more /L
;	jnz	smh_l_done			; M002; No more /L

;	call	DO_ROWS				; M002; No more /L

smh_l_done:

;For each SET mode function int 10h function call, if it is not
;issued by ANSI GET_IOCTL and SET_IOCTL procedure themselves, we assume
;that the APPS, which usually does not know the ANSI GET_IOCTL/SET_IOCTL
;interfaces, intend to change the screen mode.	In this case, ANSI is
;kind enough to call GET_IOCTL and SET_IOCTL function call for themselves.

	pop	ax
	pop	bx
	pop	cx
	pop	dx
	pop	di
	pop	si
	pop	ds
	pop	es
	pop	bp
	iret

INT10_COM	ENDP




; PROCEDURE_NAME: INT2F_COM

; FUNCTION:
; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:

;	ax=1A00H INSTALL REQUEST. ANSI WILL RETURN AL=FFH IF LOADED.

;	AH=1A01H THIS IS THE INT2FH INTERFACE TO THE GENERIC IOCTL.
;	NOTE: THE GET CHARACTERISTICS FUNCTION CALL WILL RETURN
;		THE REQ_TXT_LENGTH IN THE BUFFER AS OPPOSED TO
;		THE ACTUAL HARDWARE SCREEN_LENGTH
;	Ax=1A02h This is an information passing from DISPLAY.SYS about
;		the INT 10h, SET MODE call.

; AT ENTRY:

; AT EXIT:
;	NORMAL:

;	ERROR:



INT2F_COM	PROC	NEAR

	sti
	cmp	ah,multANSI			; is this for ANSI?
	jnz	ic_goto_rom
	cmp	al,DA_INFO_2F
	jle	INT2F_HANDLER

ic_goto_rom:
	jmp	DWORD PTR CS:ROM_INT2F		; no....jump to old INT2F

INT2F_HANDLER:

	cmp	al,INSTALL_CHECK
	jnz	ih_not_check

;	do install check

	mov	al,INSTALLED			; load value to indicate installed
	clc					; clear error flag.
	jmp	ih_iret

ih_not_check:
	cmp	al,DA_INFO_2F			; IOCTL or INFO passing?
	jbe	ih_valid
	jmp	ih_iret

ih_valid:
	push	bp
	push	ax				; s
	push	cx				; a
	push	dx				; v
	push	ds				; e	r
	push	es				;	e
	push	di				;	g
	push	si				;	s.
	push	bx
	push	ds				; load ES with DS (for call)
	pop	es
	mov	di,dx				; load DI with dx (for call)
	push	cs				; setup local addressability
	pop	ds

	cmp	al,IOCTL_2F			; IOCTL request
	jnz	ih_not_ioctl

	cmp	cl,GET_FUNC			; get function requested.
	jnz	ih_not_get

	call	GET_IOCTL

	jc	ih_set_flags			; if no error and
	cmp	HDWR_FLAG,E5151_ACTIVE		; >25 lines supported
	jl	ih_set_flags
	cmp	[si].D_MODE,TEXT_MODE		; this is a text mode then..
	jnz	ih_set_flags


;	cmp	SWITCH_L,1			; M002; No more /L
;	jz	ih_use_rtl			; M002; No more /L

	cmp	ANSI_SetMode_Call_Flag,1
	jnz	ih_use_rtl			; if not originated by ANSI thru AH=0, Int10
	cmp	Display_Loaded_Before_me,1	; or Display.sys not loaded before ANSI,
	jz	ih_get_ok

ih_use_rtl:
	mov	bx,REQ_TXT_LENGTH		; then use REQ_TXT_LENGTH instead..
	mov	es:[di].RP_ROWS,bx

ih_get_ok:
	clc
	jmp	short ih_set_flags

ih_not_get:
	cmp	cl,SET_FUNC
	jnz	ih_invalid

	call	SET_IOCTL			; set function requested.

	jmp	short ih_set_flags

;	invalid function

ih_invalid:
	mov	ax,INVALID_FUNC			; load error and...
	stc 					; set error flag.
	jmp	short ih_set_flags		; Info. passing

ih_not_ioctl:
	cmp	es:[di].DA_INFO_LEVEL,0		; 0 - DA_SETMODE_FLAG request
	jnz	ih_not_info


	cmp	es:[di].DA_SETMODE_FLAG,1
	jnz	ih_not_set

	or	In_Generic_IOCTL_Flag, SET_MODE_BY_DISPLAY	;Turn the flag on
	jmp	short ih_info_ok

ih_not_set:
	and	In_Generic_IOCTL_Flag, not SET_MODE_BY_DISPLAY	;Turn the flag off

	jmp	short ih_info_ok

ih_not_info:

	cmp	es:[di].DA_INFO_LEVEL,1		; 1 = DA_L_STATA query
	jnz	ih_info_ok

;	mov	al,cs:[SWITCH_L]		; M002; No more /L
	mov	al,OFF				; M002; No more /L

	mov	es:[di].DA_L_STATE, al

ih_info_ok:
	clc					; clear carry. There is no Error in DOS 4.00 for this call.

ih_set_flags:
	pop	bx				; restore all..
	pop	si
	pop	di				;	registers except..
	pop	es
	pop	ds				;	BP.
	pop	dx
	pop	cx
	push	ax				; save error condition
	mov	bp,sp				; setup frame pointer
	mov	ax,[bp+10]			; load stack flags
	jc	ih_error			; carry set???

	and	ax,NOT_CY			; no.. set carry off.
	mov	[bp+10],ax			; put back on stack.
	pop	ax				; remove error flag from stack
	pop	ax				; no error so bring back function call
	XCHG	ah,al				; exchange to show that ANSI present
	jmp	short ih_pop_bp

ih_error:
	or	ax,CY				; yes...set carry on.
	mov	[bp+10],ax			; put back on stack.
	pop	ax				; restore error flag
	pop	bp				; pop off saved value of ax (destroyed)

ih_pop_bp:
	pop	bp				; restore final register.
ih_iret:
ABORT:	iret

INT2F_COM	ENDP




; PROCEDURE_NAME: MAP_DOWN

; FUNCTION:
; THIS PROCEDURE MAPS THE CURSOR START (END) POSITION FROM A 14 PEL
; BOX SIZE TO AN 8 PEL BOX SIZE.

; AT ENTRY: AL HAS THE CURSOR START (END) TO BE MAPPED.

; AT EXIT:
;	NORMAL: AL CONTAINS THE MAPPED POSITION FOR CURSOR START (END)

;	ERROR: N/A



MAP_DOWN	PROC	NEAR

	push	bx
	xor	ah,ah 			; clear upper byte of cursor position
	mov	bl,EIGHT		; multiply by current box size.
	push	dx			;	al	x
	mul	bl			;	---- = ---
	pop	dx			;	14	8
	mov	bl,FOURTEEN
	div	bl			; divide by box size expected.
	pop	bx
	ret

MAP_DOWN	ENDP




; PROCEDURE_NAME: SET_VIDEO_MODE

; FUNCTION:
; THIS PROCEDURE SETS THE VIDEO MODE SPECIFIED IN DS:[SI].V_MODE.

; AT ENTRY: DS:SI.V_MODE CONTAINS MODE NUMBER

; AT EXIT:
;	NORMAL: MODE SET

;	ERROR: N/A



SET_VIDEO_MODE PROC	NEAR

	test	In_Generic_IOCTL_Flag,CALLED_BY_INT10COM
	jnz	svm_done

	mov	al,[si].V_MODE			; ..issue set mode

	test	HDWR_FLAG,LCD_ACTIVE
	jnz	svm_update_bios			; is this the LCD?
	test	HDWR_FLAG,VGA_ACTIVE		; or VGA? (done for BRECON card)
	jz	svm_update_done

svm_update_bios:
	push	ds				; yes...
	mov	bl,al				; save mode
	mov	ax,ROM_BIOS
	mov	ds,ax				; get equipment status flag..
	mov	ax,ds:[EQUIP_FLAG]
	and	ax,INIT_VID_MASK		; clear initial video bits..

	cmp	bl,MODE7			; are we setting mono?
	jz	svm_mono
	cmp	bl,MODE15
	jnz	svm_color

svm_mono:
	or	ax,LCD_MONO_MODE		; yes...set bits as mono
	jmp	short svm_update_it

svm_color:
	or	ax,LCD_COLOR_MODE		; no...set bits as color

svm_update_it:
	mov	ds:[EQUIP_FLAG],ax	 	; replace updated flag.
	mov	al,bl			 	; restore mode.
	pop	ds

svm_update_done:
	mov	ah,SET_MODE			; set mode
	int	10H

svm_done:
	ret

SET_VIDEO_MODE	ENDP

CODE		ENDS
		END

⌨️ 快捷键说明

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