www.pudn.com > czxtsycx1.zip > P_INT.ASM


;600*800 16色 模式下的中断服务程序 
;By 潘龙平/nuaa/08990115 
;Date:4/30/2002 
;=============================================================== 
 
;INT 21中断服务程序 
;00H 中断:显示一个英文字符 
;01H 中断:显示一个中英文字符串(屏幕划分为37行100列) 
;02H 中断:用一定颜色来清屏 
;03H 中断:显示一个用颜色填充的矩形(屏幕划分为37行100列) 
;04H 中断:显示一个点(600行800列) 
;05H 中断:显示一个图片(600行800列) 
;06H 中断:画一条横/竖线(600行800列) 
;07H 中断:显示一个矩形框(600行800列) 
 
;其他接口:GDT_VRAM_SEL,OS_DATA_SEL(英文字符集),HZK_BUF_SEL(汉字集) 
 
 
SERVE_INT21	PROC FAR 	 
		CMP AH,0 
		JE LBL_INT21_0 
		CMP AH,1 
		JE LBL_INT21_1 
		CMP AH,2 
		JE LBL_INT21_2 
		CMP AH,3 
		JE LBL_INT21_3 
		CMP AH,4 
		JE LBL_INT21_4 
		CMP AH,5 
		JE LBL_INT21_5 
		CMP AH,6 
		JE LBL_INT21_6 
		CMP AH,7 
		JE LBL_INT21_7 
		JMP LBL_INT21_END 
 
LBL_INT21_0: 
		CALL SHOW_CHAR 
		IRETD 
LBL_INT21_1: 
		CALL SHOW_STRING 
		IRETD 
LBL_INT21_2: 
					;CL为颜色 
		PUSH AX 
		PUSH BX 
		PUSH CX 
		PUSH DX 
 
		MOV BX,0 
		MOV DX,0 
		MOV AH,38 
		MOV AL,100 
		CALL RECT 
 
		POP DX 
		POP CX 
		POP BX 
		POP AX 
		IRETD 
LBL_INT21_3: 
		CALL RECT 
		IRETD 
LBL_INT21_4: 
		PUSH DS 
		PUSH AX 
		PUSH CX 
		PUSH DX 
		PUSH DI 
		MOV AX,GDT_VRAM_SEL 
		MOV DS,AX 
		CALL DOT 
		POP DI 
		POP DX 
		POP CX 
		POP AX 
		POP DS 
		IRETD 
LBL_INT21_5: 
		CALL SHOW_BMP 
		IRETD 
LBL_INT21_6: 
		CALL LINE 
		IRETD 
LBL_INT21_7: 
		CALL RECT_FRAME 
		IRETD 
LBL_INT21_END: 
		IRETD 
SERVE_INT21	ENDP 
 
 
;12h模式下显示一个字符串 
;ES:DI字符串所在地址 
;DS:SI为汉字点阵所在的32字节首地址 
;调用GET_HZ_ADDR过程,SHOWHZ过程 
;BX 行(0——29) 
;DX 列(0——79) 
;CL 颜色(0——15) 
 
SHOW_STRING PROC  
	PUSH AX 
	 
LBL_SHOW_STRING_LOOP: 
	MOV AL,ES:[DI] 
	CMP AL,0 
	JZ  LBL_SHOW_STRING_EXIT 
	CMP AL,127 
	JB  LBL_SHOW_STRING_ENG 
	MOV AX,ES:[DI] 
	CALL GET_HZ_ADDR 
	CALL SHOWHZ 
	ADD DI,2 
	ADD DX,2 
	JMP LBL_SHOW_STRING_LOOP 
LBL_SHOW_STRING_ENG: 
	CALL SHOW_CHAR 
	INC DX 
	INC DI 
	JMP LBL_SHOW_STRING_LOOP 
LBL_SHOW_STRING_EXIT: 
	POP AX 
	RET 
SHOW_STRING ENDP 
 
 
 
;102h模式下显示一个英文字符(8*16) 
;AL 字符的ASCII码 
;BX 行(0——36) 
;DX 列(0——99) 
;CL 颜色(0——15) 
SHOW_CHAR PROC  
	PUSH DS 
	PUSH ES 
	PUSH AX 
	PUSH BP 
	PUSH DI 
	PUSH DX		;保存列数 
 
	PUSH CX		;暂存颜色 
	PUSH DX		;暂存列数 
	PUSH BX		;暂存行数 
	PUSH AX		;暂存字符 
 
	MOV AX,GDT_VRAM_SEL 
	MOV DS,AX 
 
	MOV AX,OS_DATA_SEL	;取得字符集的地址ES:BP 
	MOV ES,AX 
	MOV BP,0 
 
	POP AX 
	MOV AH,0 
	SHL AX,1 
	SHL AX,1 
	SHL AX,1 
	SHL AX,1 
	ADD BP,AX		;该字符的属性地址 
	POP BX 
	MOV AX,100*16		;100列 
	MUL BX 
	MOV DI,AX 
	POP DX 
	ADD DI,DX 
	MOV CX,16 
SHOW_CHAR_C1: 
	MOV DX,3CEH 
	MOV AL,8 
	MOV AH,ES:[BP] 
	INC BP 
	OUT DX,AX 
	MOV DX,3C4H 
	MOV AX,0F02H 
	OUT DX,AX 
 
	INC DX 
	MOV AL,[DI]		;必须先读 
	MOV BYTE PTR [DI],0	;回写黑色 
	POP AX			;取颜色 
	PUSH AX 
	OUT DX,AL		;写颜色 
	MOV BYTE PTR [DI],0FFH  ;写内存 
	ADD DI,100				;100列 
LOOP SHOW_CHAR_C1 
 
	POP CX 
	POP DX 
	POP DI 
	POP BP 
	POP AX 
	POP ES 
	POP DS 
	RET 
SHOW_CHAR ENDP 
 
;得到该汉字点阵(16*16) 
;AX为该汉字的内码 
;DS:SI为汉字点阵所在的32字节首地址 
 
GET_HZ_ADDR PROC 
	PUSH CX 
	PUSH DX 
	PUSH DI 
 
	PUSH AX 
	XOR AH,AH 
	SUB AX,0A1H 
	XOR DX,DX 
	MOV CX,94 
	MUL CX 
	INC DI 
	POP CX 
	PUSH CX 
	MOV CL,CH 
	XOR CH,CH 
	ADD AX,CX 
	SUB AX,0A1H 
	MOV CX,32 
	MUL CX 
	XOR ECX,ECX 
	MOV CX,DX 
	XOR EDX,EDX 
	MOV DX,AX 
 
 
	MOV AX,HZK_BUF_SEL 
	MOV DS,AX 
	MOV ESI,ECX 
	SHL ESI,16 
	ADD ESI,EDX 
	POP AX 
 
	POP DI 
	POP DX 
	POP CX 
	RET 
GET_HZ_ADDR ENDP 
 
;12h模式下显示一个16*16汉字 
;DS:SI为汉字点阵所在的32字节首地址 
;BX 行(0——36) 
;DX 列(0——99) 
;CL 颜色(0——15) 
 
SHOWHZ	PROC  
	PUSH ES 
	PUSH AX 
	PUSH DX 
	PUSH DI 
	PUSH SI 
 
	MOV AX,GDT_VRAM_SEL 
	MOV ES,AX 
	MOV CH,0 
	PUSH CX		;暂存颜色 
	PUSH DX		;暂存列数 
 
	MOV AX,100*16			;100列 
	MOV CX,BX 
	XOR DX,DX 
	MUL CX 
	MOV DI,AX 
	POP DX		;取出列数 
	ADD DI,DX 
	MOV CX,16 
C1: 
	MOV DX,3CEH 
	MOV AL,8 
	MOV AH,DS:[ESI] 
	INC SI 
	OUT DX,AX 
	 
	MOV DX,3C4H 
	MOV AX,0F02H 
	OUT DX,AX 
		 
	INC DX 
	MOV AL,ES:[DI]			;必须先读 
	MOV BYTE PTR ES:[DI],0		;回写黑色 
	POP AX				;取颜色 
	OUT DX,AL			;写颜色 
	MOV BYTE PTR ES:[DI],0FFH	;写内存 
	CMP AH,0 
	JNZ LBL_SHOWHZ1 
	MOV AH,1 
	PUSH AX 
	INC DI 
	JMP C1 
LBL_SHOWHZ1: 
	MOV AH,0 
	PUSH AX 
	ADD DI,99			;100列 
LOOP C1 
	POP CX 
 
	POP SI 
	POP DI 
	POP DX 
	POP AX 
	POP ES 
	RET 
SHOWHZ ENDP 
 
;显示一个填充颜色的矩形(102h模式下) 
;调用BLOCK过程 
;BX 起始行(0——36) 
;DX 起始列(0——99) 
;AH 行数 
;AL 列数 
;CL 颜色(0——15) 
 
RECT PROC NEAR 
	PUSH AX 
	PUSH BX 
	PUSH DX 
 
LBL_RECT_ROW: 
	CMP AH,0 
	JZ  LBL_RECT_EXIT 
	PUSH AX 
LBL_RECT_COL: 
	CMP AL,0 
	JZ LBL_RECT_NEXTROW 
	CALL BLOCK 
	INC DX 
	DEC AL 
	JMP LBL_RECT_COL 
LBL_RECT_NEXTROW: 
	POP AX 
	POP DX 
	PUSH DX 
	INC BX 
	DEC AH 
	JMP LBL_RECT_ROW 
LBL_RECT_EXIT: 
	POP DX 
	POP BX 
	POP AX 
	RET 
RECT ENDP 
 
;102h模式下 
;显示一个块(8*16象素) 
;BX 行(0——36) 
;DX 列(0——79) 
;CL 颜色(0——15) 
BLOCK PROC NEAR 
	PUSH DS 
	PUSH AX 
	PUSH DI 
	PUSH DX 
	PUSH CX			 
	PUSH DX 
 
	MOV AX,GDT_VRAM_SEL 
	MOV DS,AX 
 
	MOV DX,3CEH 
	MOV AL,8 
	OUT DX,AL 
 
	MOV DX,3CFH 
	MOV AL,0FFH 
	OUT DX,AL 
 
	MOV DX,3C4H 
	MOV AL,2 
	OUT DX,AL 
	 
	MOV AX,100*16			;100列 
	MUL BX 
	MOV DI,AX 
	POP DX 
	ADD DI,DX 
	 
	MOV CX,16 
	MOV DX,3C5H 
	POP AX 
	PUSH AX 
	MOV AH,AL 
BLOCK1: 
	MOV AL,0FH 
	OUT DX,AL 
	 
	MOV AL,[DI] 
	MOV BYTE PTR [DI],0 
	MOV AL,AH 
	OUT DX,AL 
	MOV BYTE PTR [DI],0FFH	 
 
	ADD DI,100			;100列 
LOOP	BLOCK1 
	POP CX 
	POP DX 
	POP DI 
	POP AX 
	POP DS 
	RET 
BLOCK	ENDP 
 
;画一个点 
;DS图形方式的段地址 
;BX行(0--599) 
;DX列(0--799) 
;CL颜色(0--15) 
;受影响的寄存器有:AX,DI 
DOT	PROC 
	PUSH CX 
	PUSH DX 
	XOR DX,DX 
	MOV AX,100 
	MUL BX 
	MOV DI,AX 
	 
	MOV CH,CL		;暂存颜色 
 
	POP DX 
	PUSH DX 
	MOV AX,DX 
	MOV CL,3 
	SHR AX,CL 
	ADD DI,AX 
 
	MOV AX,DX 
	AND AX,07H 
	MOV CL,AL		;第几位 
	MOV AL,80H 
	SHR AL,CL 
	MOV AH,AL 
 
	MOV AL,8		;寄存器索引 
	MOV DX,3CEH 
	OUT DX,AX 
 
	MOV DX,3C4H 
	MOV AX,0F02H 
	OUT DX,AX 
 
	INC DX 
	MOV AL,[DI]		;必须先读 
	MOV BYTE PTR [DI],0	;回写黑色 
	MOV AL,CH		;取得颜色 
	OUT DX,AL		;写颜色 
	MOV BYTE PTR [DI],0FFH  ;写内存 
 
	POP DX 
	POP CX 
	RET 
DOT	ENDP 
 
 
;画一个点,仅供一些过程用来提高画点速度 
;DS图形方式的段地址 
;DI点所在内存 
;AH屏蔽码 
;CL颜色(0--15) 
;受影响的寄存器有:AL,DX 
 
DOT1	PROC 
	PUSH AX 
	PUSH DX 
	MOV AL,8		;寄存器索引 
	MOV DX,3CEH 
	OUT DX,AX 
 
	MOV DX,3C4H 
	MOV AX,0F02H 
	OUT DX,AX 
 
	INC DX 
	MOV AL,[DI]		;必须先读 
	MOV BYTE PTR [DI],0	;回写黑色 
	MOV AL,CL		;取得颜色 
	OUT DX,AL		;写颜色 
	MOV BYTE PTR [DI],0FFH  ;写内存 
 
	POP DX 
	POP AX 
	RET 
DOT1	ENDP 
 
 
;显示图片 
;ES:SI图片所在内存区域 
;(BX,DX)图片左上角的位置 
;BP图片的宽度 
;CX图片的高度 
 
SHOW_BMP PROC 
	PUSH DS 
	PUSH DI 
	PUSH SI 
	PUSH AX 
	PUSH BX 
	PUSH DX 
	PUSH CX 
	 
	PUSH BP			;暂存宽度 
	PUSH CX			;暂存高度 
 
	PUSH DX			;暂存左上角纵坐标 
 
	XOR DX,DX 
	MOV AX,BP 
	INC AX 
	MUL CX 
	ADD SI,AX 
 
	MOV AX,GDT_VRAM_SEL 
	MOV DS,AX 
 
	XOR DX,DX 
	MOV AX,100 
	MUL BX 
	MOV DI,AX 
 
	POP DX			;取得左上角纵坐标 
	MOV AX,DX 
	AND AX,0F8H 
	ADD DI,AX 
 
	MOV AX,DX 
	AND AX,07H 
	MOV CL,AL		;第几位 
	MOV AL,80H 
	SHR AL,CL 
	MOV AH,AL 
	POP DX			;取得高度 
LBL_BMP_LOOP_H: 
	POP BX			;取得宽度 
	SUB SI,BX 
	SUB SI,BX 
	PUSH BX 
 
	PUSH DI			;保存显示点的内存偏移地址 
	PUSH AX			;保存屏蔽码 
LBL_BMP_LOOP_W: 
	MOV CL,ES:[SI] 
	CALL DOT1 
	INC SI 
	ROR AH,1 
	CMP AH,80H 
	JNZ LBL_BMP_1 
	INC DI 
LBL_BMP_1: 
	DEC BX 
	JNZ LBL_BMP_LOOP_W 
	POP AX			;取得屏蔽码 
	POP DI			;取得显示点的内存偏移地址 
	ADD DI,100 
	DEC DX 
	JNZ LBL_BMP_LOOP_H 
 
	POP BP 
	POP CX 
	POP DX 
	POP BX 
	POP AX 
	POP SI 
	POP DI 
	POP DS 
	RET 
SHOW_BMP ENDP 
 
;06H 中断:画一条横/竖线 
;(BX,DX)起始位置 
;SI 长度 
;CL 颜色 
;AL =0 横线 
;   =1 竖线 
LINE	PROC 
	PUSH DS 
	PUSH BX 
	PUSH DX 
	PUSH SI 
	PUSH DI 
 
	CMP SI,0 
	JZ LBL_LINE_END 
	CMP AL,0 
	MOV AX,GDT_VRAM_SEL 
	MOV DS,AX 
	JNZ LBL_LINE_V_GOON 
LBL_LINE_H_GOON: 
	CALL DOT 
	INC DX 
	DEC SI 
	JNZ LBL_LINE_H_GOON 
	JMP LBL_LINE_END 
LBL_LINE_V_GOON: 
	CALL DOT 
	INC BX 
	DEC SI 
	JNZ LBL_LINE_V_GOON 
LBL_LINE_END: 
 
	POP DI 
	POP SI 
	POP DX 
	POP BX 
	POP DS 
	RET 
LINE	ENDP 
 
 
;07H 中断:显示一个矩形框 
;(BX,DX) 
;SI 宽 
;DI 高 
;CL 左上颜色  
;CH 右下颜色 
RECT_FRAME PROC 
	PUSH BP 
	PUSH BX 
	PUSH CX 
	 
	MOV AL,0 
	CALL LINE 
 
	MOV BP,SI 
	MOV SI,DI 
	MOV AL,1 
	CALL LINE 
 
	MOV CL,CH 
	ADD DX,BP 
	CALL LINE 
 
	SUB DX,BP 
	ADD BX,DI 
	MOV SI,BP 
	MOV AL,0 
	CALL LINE 
 
	POP CX 
	POP BX 
	POP BP 
	RET 
 
RECT_FRAME ENDP