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

📄 vid.8

📁 tiny bios--了解BIOS非常好的资料
💻 8
字号:
	;
	; Hercules monochrome video BIOS
	;
	; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
	; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
	;
	; Limitations:
	;
	; - No CGA / graphics support - CGA cards / monitors are no longer
	;   available. VGA is handled by separate BIOS anyway, Hercules
	;   support is mainly for debug purposes.
	; - No light pen support
	; - No print screen function (risky for embedded systems)
	; - Video mode ignored (monochrome only supports 80x25)
	; - INT 1D (pointer to video parameters) not supported.
	; - Font not supported.
	; - Historic entry points not supported.
	; - INT 1F extended font not supported.
	; - AH=13 Write string not supported (AT only)
	;
	
	;
	; Initialize text mode
	;
vid_init:	mov	al,21h	;disable video, high res bit
	mov	dx,crtc+4
	out	dx,al

	mov	si,offset v_parm	;set text mode
	mov	bl,0
	mov	dl,low(crtc)
hercloop:	mov	al,bl
	out	dx,al
	inc	dx
	cs:	lodsb	
	out	dx,al
	dec	dx
	inc	bx
	cmp	bl,16
	jb	hercloop

	mov	ax,vidseg	;clear screen
	mov	es,ax
	mov	ax,vid_fill	;fill value
	mov	cx,2048
	mov	di,0
	rep	stosw
	
	mov	al,29h	;enable video
	mov	dl,low(crtc+4)
	out	dx,al
	ret
	;
	; initialize video variables
	;
vid_vars:	mov	word [m_vcrt],crtc	;video I/O port
	mov	si,offset v_parm	;video parameters
	mov	byte [m_vpgno],0	;page number = 0
	mov	byte [m_vmsel],29h	;mode register shadow
	mov	byte [m_vpal],30h	;palette shadow
	mov	word [m_vmode],7	;force mode 7
	mov	word [m_vcol],80	;80 columns per line
	mov	word [m_vrow],24	;25-1 rows
	mov	word [m_vpgsz],2048	;video page size
	push	ds           	;clear video positions per page
	pop	es
	mov	di,offset m_vpage  	;& m_vcolrow
	xor	ax,ax
	mov	cx,9	;also set page offset
	rep	stosw
	mov	ax,0b0ch	;m_vcursor cursor end line, start line
	stosw
	mov	al,0
	stosb		;m_vpgno
	ret
	;
	; INT 10 entry
	;
int10:	cmp	ah,10h	;max command code
	jae	int10_ret
	sti
	cld		;forward mode
	push	ds
	push	es
	pusha
	xor	si,si	;DS = BIOS segment
	mov	ds,si
	mov	si,vidseg
#if def	VID_CGA
	cmp	byte [m_vcrt],0d4h	;CGA ?
	jnz	vid_cga1
	mov	si,0b800h	;CGA segment
vid_cga1:
#endif
	mov	es,si
	mov	si,ax	;calculate jump table vector
	shr	si,8
	shl	si,1
	jmp	[cs:si+int10_tab]	;jump to individual routine

int10_ret: iret
	;
	; video dispatch table
	;
	even

int10_tab: dw	v_mode	;00 = set video mode
	dw	v_cursor	;01 = set cursor characteristics
	dw	v_setcur	;02 = set cursor position
	dw	v_getcur	;03 = get cursor position
	dw	v_getpen	;04 = get light pen position
	dw	v_setpage	;05	= set display page
	dw	v_scrlup	;06 = scroll up
	dw	v_scrldn	;07 = scroll down
	dw	v_rdattr	;08 = read character attribute
	dw	v_wrattr	;09 = write character attribute
	dw	v_wrchar	;0A = write character
	dw	v_exit	;0B = set palette
	dw	v_exit	;0C = write pixel
	dw	v_exit	;0D = read pixel
	dw	v_tty	;0E = write TTY
	dw	v_stat	;0F = read video status
	;
	; AH=00: set video mode
	;
v_mode:
#if def	VID_CGA
	cmp	byte [m_vcrt],0d4h	;CGA mode ?
	jz	v_mode9	;:bail
#endif
	call	vid_init	;initialize video
	call	vid_vars	;set video variables
v_mode9:	jmp	v_exit	;return
	;
	; video mode settings
	;
v_parm:	db	61h,50h,52h,0Fh,19h,06h,19h,19h,02h,0Dh,0Bh,0Ch,0,0,0,0
	;
	; AH=01: set cursor characteristics
	;
v_cursor:	mov	[m_vcursor],cx	;save cursor value
	mov	al,10
	jmp	v_set
	;
	; AH=02: set cursor position
	;
v_setcur:	mov	bl,0	;page number -> index
	mov	si,bx
	shr	si,7
	mov	[si+m_vcolrow],dx	;save position
	cmp	[m_vpgno],bh	;same page ?
	jnz	v_setc2	;:no
	jmp	v_tty3	;set cursor
v_setc2:	jmp	v_exit
	;
	; AH=03: get cursor position
	;
v_getcur:	mov	bp,sp	;access stack frame
	mov	bl,0	;page number -> index
	shr	bx,7
	mov	ax,[bx+m_vcolrow]	;get cursor pos from table
	mov	[bp._dx],ax	;-> DX
	mov	ax,[m_vcursor]	;cursor shape
	mov	[bp._cx],ax	;-> CX
	jmp	v_exit
	;
	; AH=04: get light pen position
	;
	; anyone remember what a light pen looks like ? ;-)
	;
v_getpen:	mov	bp,sp	;access stack frame
	mov	byte [bp._ah],0	;not activated -> AH
	jmp	v_exit
	;
	; AH = 05: set video page
	;
v_setpage: mov	[m_vpgno],al	;page number
	shl	ax,1
	mov	bx,ax	;table index
	shl	ax,11
	mov	[m_vpage],ax	;page offset
	shr	ax,1
	mov	cx,ax
#if def	VID_CGA
	mov	dx,[m_vcrt]
#else
	mov	dx,crtc
#endif
	mov	al,12 	;set display offset
	mov	ah,ch
	out	dx,ax
	inc	ax
	mov	ah,cl
	out	dx,ax
	mov	dx,[bx+m_vcolrow]	;page cursor position
	jmp	v_tty3	;set cursor position
	;
	; AH=06: scroll window up
	;
v_scrlup:	mov	bl,dh	;row difference
	sub	bl,ch
	sub	bl,al	;- scroll count
	inc	bl	;+1 -> number of lines to scroll
	sub	dl,cl	;character count
	inc	dl
	mov	dh,al	;number of lines to clear
	mul	byte [m_vcol]	;scroll count
	add	ax,ax
	mov	si,ax	;-> start offset
	mov	al,ch	;start row
	mul	byte [m_vcol]	;* columns
	add	al,cl	;add start column
	adc	ah,0
	add	ax,ax
	add	ax,[m_vpage]	;+ page offset
	mov	di,ax	;DI = destination offset
	add	si,ax	;add to SI -> source offset
	mov	ax,[m_vcol]	;calculate line skip
	sub	al,dl
	add	ax,ax
	mov	bp,ax
	;
	; AX = fill character
	; BL = lines to scroll
	; DL = character count
	; DH = lines to clear
	; SI = source offset
	; DI = destination offset
	; BP = columns per line - character count
	;
v_scroll:	mov	al," "	;fill pattern
	mov	ah,bh
	xor	cx,cx
	and	dh,dh	;0 lines to clear ?
	jz	v_scroll2
	push	es
	pop	ds
v_scroll1: mov	cl,dl	;character count
	rep	movsw	;scroll a line
	add	si,bp	;go to next line
	add	di,bp	
	dec	bl
	jnz	v_scroll1	;:another line
	mov	bl,dh
v_scroll2: mov	cl,dl	;character count
	rep	stosw	;clear a line
	add	di,bp
	dec	bl
	jnz	v_scroll2
	jmp	v_exit
	;
	; AH=07: scroll window down
	;
v_scrldn:	sub	dl,cl	;number of characters
	inc	dl
	mov	bl,dh	;row difference
	sub	bl,ch
	sub	bl,al	;- scroll count
	inc	bl	;+1 -> number of lines to scroll
	mov	ch,al	;number of lines to clear
	mul	byte [m_vcol]	;scroll count
	add	ax,ax
	neg	ax
	mov	si,ax	;-> start offset
	mov	al,dh	;end row
	mul	byte [m_vcol]	;* columns
	add	al,cl	;add start column
	adc	ah,0
	add	ax,ax
	add	ax,[m_vpage]	;+ page offset
	mov	di,ax	;DI = destination offset
	add	si,ax	;add to SI -> source offset
	mov	ah,0	;calculate line skip
	mov	al,dl	;- characters per line - window width
	add	ax,[m_vcol]	;(move is forward)
	add	ax,ax
	neg	ax
	mov	bp,ax
	mov	dh,ch	;number of lines to clear
	jmp	v_scroll	;do the actual scroll
	;
	; AH=08: read character + attribute
	;
v_rdattr:	call	v_pos	;calculate position
	mov	bp,sp
	mov 	ax,[es:di]	;read character
	mov	[bp._ax],ax	;-> AX
	jmp	v_exit
	;
	; calculate video offset
	;
	; -> DI offset
	; -> AX character, attribute
	; -> SI page number * 2
	;
v_pos:	mov	dh,bl	;attribute
	mov	dl,al	;character
	mov	di,bx	;save BX &pd 980406 fixed
	mov	bl,0	;page -> index
	mov	si,bx
	shr	si,7
	mov	ax,[si+m_vcolrow]	;get cursor position for page
	shl	bx,4	;-> page offset
	add	bl,al	;column offset
	adc	bl,0
	mov	al,ah	;row offset
	mul	byte [m_vcol]
	add	bx,ax
	add	bx,bx
	xchg	di,bx	;-> page offset, restore BX
	mov	ax,dx	;restore character, attribute
	ret
	;
	; AH=09: write character + attribute
	;
v_wrattr:	call	v_pos	;calculate position
	rep	stosw	;write characters
	jmp	short v_exit
	;
	; AH=0A: write character only, no attribute
	;
v_wrchar:	call	v_pos	;calculate position
v_wrc1:	stosb
	inc	di
	loop	v_wrc1
	jmp	short v_exit
	;
	; AH=0E: write character TTY
	;	
v_tty:

#if def	CONSOLE

	; serial port console
	;
	; if m_vpal bit 0 is set, we copy characters to the console.

	test	byte [m_console],1	;serial port redirect ?
	jz	v_ttys9	;:no
	push	dx
	push	ax
	mov	dx,CONSOLE+5
v_ttys1:	in	al,dx    	;wait for transmit ready
	out	iowait,ax
	test	al,40h
	jz	v_ttys1
	mov	dl,low(CONSOLE)
	pop	ax
	out	dx,al
	pop	dx
v_ttys9:

#endif
	call	v_pos
	mov	dx,[si+m_vcolrow]	;get cursor position
	cmp	al,cr
	jbe	v_ctrl
v_tty1:	stosb
	inc	dl	;inc column
	cmp	dl,[m_vcol]	;max ?
	jz	v_lf0	;yes: line feed
	;
	; set cursor position
	;
v_tty2:	mov	[si+m_vcolrow],dx	;save position
	cmp	[m_vpgno],bh	;same page ?
	jnz	v_exit	;:no
v_tty3:	mov	cx,[m_vpage]	;page offset / 2
	shr	cx,1
	mov	cl,dl	;column
	mov	al,dh	;row * column width
	mul	byte [m_vcol]
	add	cx,ax	;get address
	mov	al,14 	;set cursor offset
v_set:
#if def	VID_CGA
	mov	dx,[m_vcrt]
#else
	mov	dx,crtc
#endif
	mov	ah,ch
	out	dx,ax
	inc	ax
	mov	ah,cl
	out	dx,ax
v_exit:	popa	
	pop	es
	pop	ds
	iret
	;
	; display control characters
	;	
v_ctrl:	jnz	v_ctrl2	;:not carriage return
	;
	; carriage return
	;
v_cr:	mov	dl,0	;beginning of line
	jmp	v_tty2	;set cursor position

v_ctrl2:	cmp	al,lf
	jz	v_lf
	cmp	al,bs
	jz	v_bs
	cmp	al,bell
	jz	v_bell
#if def	MEDIAGX
	cmp	al,0bh	;clear to beginning of line
	jz	v_cr
#endif
	jmp	v_tty1
	;
	; line feed
	;
v_lf0:	mov	dl,0	;beginning of line
v_lf:	inc	dh	;increment line
#if def	VID_CGA
	cmp	dh,[m_vrow]	;last line ?
	jbe	v_tty2	;:no scroll, set cursor
#else
	cmp	dh,25	;last line ?
	jb	v_tty2	;:no scroll, set cursor
#endif
	dec	dh	;restore
	push	si	;pd 980422: fix LF bug
	and	di,0f000h	;keep page offset
#if def	VID_CGA
	mov	al,[m_vcol]	;columns
	mov	ah,0
	push	ax	;save columns
	mov	si,di	;SI = point to next line
	add	si,ax
	add	si,ax
	mov	bx,ax	;save...
	mul	byte [m_vrow]	;* rows -> characters to scroll
	mov	cx,ax
#else
	lea	si,[di+160]
	mov	cx,24*80	;scroll full screen
#endif
	mov	ax,es	;DS = video segment
	mov	ds,ax
	rep	movsw
	mov	al," "	;fill with same attribute
	mov	ah,[di+1]
#if def	VID_CGA
	pop	cx	;number of columns
#else
	mov	cx,80	;fill bottom line
#endif
	rep	stosw
	xor	ax,ax	;restore DS
	mov	ds,ax
	pop	si	;pd 980422: fix LF bug
	jmp	v_tty2
	;
	; backspace
	;
v_bs:	sub	dl,1
	adc	dl,0	;limit to 0
	jmp	v_tty2	;set cursor position
	;
	; bell
	;
v_bell:	call	beep
	jmp	v_exit
	;
	; AH=0F: get video status
	;
v_stat:	mov	bp,sp
	mov	ax,[m_vmode]	;& m_vcol
 	mov	[bp._ax],ax
 	mov	al,[m_vpgno]	;page number
 	mov	[bp._bh],al
 	jmp	v_exit
	;
	; display string [SI] -> TTY
	;
v_msg:	cs: 	lodsb	;get character
	and	al,al	;0 = end
	jz	v_msg9
	mov	ah,0eh	;TTY output
	mov	bh,0	;page 0
	int	10h
	jmp	v_msg
v_msg9:	ret
	;
	; ring bell
	;
beep:	push	ax
	push	cx
	mov	al,0b6h     	;set beep timer
	out	timer+3,al
	mov	al,33h	;beep frequency
	out	timer+2,al
	mov	al,05h
	out	timer+2,al
	in	al,port61             ;enable beep
	mov	ah,al
	or	al,3	
	out	port61,al
	xor	cx,cx	;delay
bell1:	out	iowait,ax
	loop	bell1
	mov	al,ah
	out	port61,al
	pop	cx
	pop	ax
	ret

⌨️ 快捷键说明

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