概述
上次整理以前DOS下的代码,找了个线性回归分析函数,觉得可能还有用,于是放在了《C语言版的线性回归分析函数》中,今天在CSDN的C/C++版,发现居然还有人求DOS下VGA 12H模式下的直接写屏代码,临时找了2个以前的文件,发了出去供参考。后来仔细找了一会,把以前DOS下写的供Trubo C使用的VGA 12H直接写屏图形函数找齐了,还有鼠标和XMS内存管理函数,决定放在这里,供C语言初学者参考。因为这些函数全部都是外部汇编代码文件,比较长,只得分几篇文章存放,由于时间太长,有些代码我自己现在也说不清楚,除个别情况外,本人不对代码作解释,纯粹代码粘贴。这篇文章中存放VGA 12H图形的基本函数和C调用头文件以及全部汇编函数的MAKEFILE。
有人可能说,Turbo C不是有图形库吗,为啥还要自己写图形库?因为Trubo C自带的图形库通用性太强,导致当时DOS下使用它时,速度很慢,所以我写了供自己用的专用VGA图形库,没有考虑通用性,故而速度相当快,现在的机器速度快,使用Trubo C的图形库当然没有慢的感觉了,不过,我认为这些代码对C初学者来说,还是有价值的:首先可以了解VGA12H模式下的直接写屏技术;其次可以掌握C语言与外部汇编函数的相互调用方式;再次,本图形库中很多函数中包含了一些现在的计算机书中很少有的基础图形算法,如任意直线、圆、弧、图形填充等整数算法。
首先给出全部汇编文件的MAKEFILE,该文件名graph.mak:
TASM = Tasm / ml
#
! if ! $d(MDL)
MDL = s
! endif
#
! if $(MDL) == t
TasmComm = / D__TINY__
! elif$(MDL) == s
TasmComm = / D__SMALL__
! elif$(MDL) == m
TasmComm = / D__MEDIUM__
! elif$(MDL) == c
TasmComm = / D__COMPACT__
! elif$(MDL) == l
TasmComm = / D__LARGE__
! endif
#
#
Dep_graph = graph$(MDL).lib
#
Dep_graphdlib =
xms.asm
mouse.asm
grroll.asm
grputch.asm
grimage.asm
grfill.asm
grellip.asm
grbase.asm
grarc.asm
graph.inc
tasm_c.inc
$(Dep_graph):$(Dep_graphdlib)
del$(Dep_graph)
$(TASM)$(TasmComm)xms.asm
$(TASM)$(TasmComm)mouse.asm
$(TASM)$(TasmComm)grroll.asm
$(TASM)$(TasmComm)grputch.asm
$(TASM)$(TasmComm)grimage.asm
$(TASM)$(TasmComm)grfill.asm
$(TASM)$(TasmComm)grellip.asm
$(TASM)$(TasmComm)grbase.asm
$(TASM)$(TasmComm)grarc.asm
$(TLIB)$(Dep_graph) + xms.obj + mouse.obj + grroll.obj + grputch.obj
+ grimage.obj + grfill.obj + grellip.obj + grbase.obj + grarc.obj
del * .obj
在命令行使用Turbo C的make.exe,可以制造一个TC库文件GraphX.lib,其中X为存储模式,由make命令行的MDL宏指定(缺省为small模式),如制造一个中模式库,命令行为(注:由于10多年没用过这种东西,我的记忆不知道是否正确,如果错误,请原谅):
make -DMDL=m -fgraph.mak
然后给出TC调用的图形汇编函数的头文件,从这个头文件可以看出,在DOS下,不仅TC调用它们,也可供Turbo C++或者Borland C++调用本文的这些函数。需要说明的是,从InitUCDOS开始的函数已经不完全是纯图形函数了,而是与UCDOS有关的字符串显示函数,如果不使用UCDOS,可以将它们以及后面的代码删掉;另外,PutBmp函数只是用来显示16色未压缩过的位图文件的图形数据,没有打开文件功能,本文最后贴出以前的一个测试程序代码:
#ifndef__GRAPH_H
#define __GRAPH_H
#ifdef__cplusplus
extern " C " {
#endif
/* 打开图形屏幕 */
void OpenGraph( void );
/* 以正文方式关闭图形屏幕 */
void CloseGraph( void );
/* 设置图形操作边界,参数:左上角X,Y坐标,右下角X,Y坐标;
除图像保存,移动函数外,所有图形均进行裁剪 */
void SetBorder( int , int , int , int );
/* 使用缺省的屏幕尺寸为图形边界 */
void DefBorder( void );
/* 设置当前作图颜色值为Value,返回当前的值 */
int SetColor( int Value);
/* 返回当前颜色值 */
int GetColor();
/* 置写图型屏幕方式(0-3),返回当前的方式 */
int SetDrMode( int Mode);
/* 在(X,Y)用当前色写点 */
void PutPixel( int X, int Y);
/* 返回(X,Y)的颜色值 */
int GetPixel( int X, int Y);
/* 从(X1,Y1)至(X2,Y2)画直线 */
void Line( int X1, int Y1, int X2, int Y2);
/* 从(X1,Y1)至(X2,Y2)画填充矩形(无边界线) */
void Bar( int X1, int Y1, int X2, int Y2);
/* 用颜色从(X1,Y1)至(X2,Y2)画矩形 */
void Rectangle( int X1, int Y1, int X2, int Y2);
/* 保存(Left,Top)至(Right,Bottom)内的图象到Buf中 */
unsignedGetImage( int Left, int Top, int Right, int Bottom, void far * Buf);
/* 将Buf内保存的图象在(Row,Col)处显示,Mode显示方式(0-3) */
void PutImage( int Row, int Col, void far * Buf, int Mode);
/* 计算并返回保存(Left,Top)至(Right,Bottom)内的图象缓冲区的字节数 */
long ImageSize( int Left, int Top, int Right, int Bottom);
/* 将屏幕区(Left,Top)至(Right,Bottom)垂直移动N线,N上移,-N下移 */
void Roll( int n, int Left, int Top, int Right, int Bottom);
/* 安装用户掩膜LnStyle返回当前的线型 */
int SetLnStyle( int Lnstyle);
/* 安装用户图案Pattern及颜色Color */
void SetPattern( void far * Pattern, int Color);
/* 以(X,Y)为园心,Radius为半径画园 */
void Circle( int X, int Y, int Radius);
/* 以(X,Y)为园心,RadiusX为X半径,RadiusY为Y半径画椭园 */
void Ellipse( int X, int Y, int Radiusx, int Radiusy);
/* 以(X,Y)为园心,Radius为半径,Start为起始角,End为结束角画园弧 */
void Arc( int X, int Y, int Start, int End, int Radius);
/* 以(X,Y)为园心,Radius为半径,Start为起始角,End为结束角画扇形(不填充) */
void Slice( int X, int Y, int Start, int End, int Radius);
/* 以(X,Y)为园心,Radius为半径,Start为起始角,End为结束角画馅饼形(不填充) */
void Pie( int X, int Y, int Start, int End, int Radius);
/* 以(X,Y)为内点,Color为填充色,以当前图案进行区域填充 */
void Fill( int X, int Y, int Color);
/* 改变系统的颜色,Index调色板号(0-15),Red红色值,Green绿色值,Blus蓝色值
颜色值范围为0-63 */
void SetPalette( int Index, int Red, int Green, int Blus);
/* 从(X,Y)开始显示位图数据Bmp */
void PutBmp( int X, int Y, void far * Bmp);
/* 定义字符显示和光标函数 */
/* 判断UCDOS是否启动,已启动,关闭UCDOS光标,重新安装闪烁光标并返回-1,
否则返回0,参数为光标颜色值,用此值与屏幕异或成实际光标颜色 */
int InitUCDOS( int );
/* 撤消自安装的闪烁光标,如果flag=0恢复UCDOS光标 */
void RestUCDOS( int flag);
/* 显示光标 */
void ShowCursor( void );
/* 隐蔽光标,如多次隐蔽后,需多次调用ShowCursor() */
void HideCursor( void );
/* 设置字符坐标点的左上角坐标,参数:X坐标,Y坐标 */
void SetPos( int , int );
/* 返回当前光标处字符的左上角坐标,参数:X坐标指针,Y坐标指针 */
void GetPos( int * , int * );
/* 设置光标状态为插入方式(8*8光标,缺省)或改写方式(8*4光标),分别返回1或0 */
int InsertMode( void );
/* 在当前坐标写字符,参数:字符,字符个数,字符属性(高4位背景色,低4位前景色);
字符为16*16点阵,显示字符后,不改变坐标 */
void Putch( int , int , int );
/* 在给定的坐标处显示字符串,坐标超长或遇结束符0中止,返回实际写的字符数,
参数:X起始坐标,Y坐标,字符串,X结束坐标,字符属性;显示后坐标在字符串尾 */
int Putss( int , int , char * , int , int );
#ifdef__cplusplus
}
#endif
#endif
下面是TC外部汇编(TASM)函数通用的插入文件,该文件定义了一些与存储模式有关的宏,包含它的汇编文件可以用TASM.EXE编译成TC的任意模式obj文件:
IFNDEF__TINY__
IFNDEF__SMALL__
IFNDEF__MEDIUM__
IFNDEF__COMPACT__
IFNDEF__LARGE__
DISPLAY " **Warning**Youmustsupplyamodelsymbol. "
__SMALL__equ 1
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IDEAL
IFDEF__TINY__
LPROGequ 0
LDATAequ 0
MODELTINY,PROLOG
ENDIF
IFDEF__SMALL__
LPROGequ 0
LDATAequ 0
MODELSMALL,PROLOG
ENDIF
IFDEF__MEDIUM__
LPROGequ 1
LDATAequ 0
MODELMEDIUM,PROLOG
ENDIF
IFDEF__COMPACT__
LPROGequ 0
LDATAequ 1
MODELCOMPACT,PROLOG
ENDIF
IFDEF__LARGE__
LPROGequ 1
LDATAequ 1
MODELLARGE,PROLOG
ENDIF
IFLDATA
DPTR_EQUdword
DS_EQUds:
ES_EQUes:
MACROLDS_Register,Memory
ldsRegister,Memory
ENDMLDS_
MACROLES_Register,Memory
lesRegister,Memory
ENDMLES_
MACROPUSHDS_
pushds
ENDMPUSHDS_
MACROPOPDS_
popds
ENDMPOPDS_
MACROPUSHES_
pushes
ENDMPUSHES_
MACROPOPES_
popes
ENDMPOPES_
ELSE
DPTR_EQUword
DS_EQU
ES_EQU
MACROLDS_Register,Memory
movRegister,Memory
ENDMLDS_
MACROLES_Register,Memory
movRegister,Memory
ENDMLES_
MACROPUSHDS_
ENDMPUSHDS_
MACROPOPDS_
ENDMPOPDS_
MACROPUSHES_
ENDMPUSHES_
MACROPOPES_
ENDMPOPES_
ENDIF
;TASM_C.INCEND
基本图形文件,该文件提供了几个基本的图形函数(带下划线的函数)和其它图形汇编文件使用的内部函数(没有下划线的函数,C不能直接调用):
P386N
includetasm_c.inc
MAXCOLORequ 15 ;最大颜色值
MAXXequ 639 ;最大X象素
MAXYequ 479 ;最大Y象素
DSPMEMSEGequ0A000h;屏显起始地址
DMWIDTHequ 80 ;屏幕每线字节数
GRMODEequ12h;屏显方式
DATASEG
PUBLICColor
PUBLICDrMode
PUBLICMinX
PUBLICMinY
PUBLICMaxX
PUBLICMaxY
PUBLICWidthX
PUBLICWidthY
Colordw 7
DrModedw 3
LnStyledw0ffffh
Patterndb 8 dup(0ffh)
MinXdw 0
MinYdw 0
MaxXdwMAXX
MaxYdwMAXY
WidthXdwMAXX
WidthYdwMAXY
CODESEG
PUBLIC_OpenGraph
PUBLIC_CloseGraph
PUBLIC_Line
PUBLIC_PutPixel
PUBLIC_GetPixel
PUBLIC_SetColor
PUBLIC_GetColor
PUBLIC_SetDrMode
PUBLIC_SetLnStyle
PUBLIC_SetPattern
PUBLIC_Rectangle
PUBLIC_Bar
PUBLIC_SetPalette
PUBLIC_SetBorder
PUBLIC_DefBorder
PUBLICGetDspMem
PUBLICGetDspMemOff
PUBLICSetWrMode
PUBLICSetWrMode0
PUBLICRestReg
PUBLICRestReg0
PUBLICTestPoint
PUBLICBar
PUBLICGetPixel
PUBLICPutPixel
;
;GetDspMem;ax = X,bx = Y, return es:bx = DspMem
;
PROCGetDspMem
pushDSPMEMSEG
popes
ENDP
;
PROCGetDspMemOff
pushax
shlbx, 4
movax,bx;bx = Y * 16
shlax, 2
addbx,ax;(bx += (Y * 64 ))or(bx = Y * 80 )
popax
shrax, 3 ;ax = X / 8
addbx,ax; return BX = (Y * 80 + X / 8 )
ret
ENDP
;
PROCSetWrMode0
xoral,al
movah,[ byte Color]
movdx,3ceh
out dx,ax
movax,0f01h
out dx,ax
xorah,ah
ENDP
;
;SetWrMode,ah = Mode( 0 - 3 ); return dx = 3cfh
;
PROCSetWrMode
moval, 5
movdx,3ceh
out dx,ax
movax,[DrMode]
out dx,ax
moval, 8
out dx,al
incdx
ret
ENDP
;
PROCRestReg0
movdx,3ceh
xorax,ax
out dx,ax
incax
out dx,ax
ENDP
;
PROCRestReg
movdx,3ceh
movax,0ff08h
out dx,ax
movax, 5
out dx,ax
movax, 3
out dx,ax
ret
ENDP
;
;TestPoint;ax = x1,bx = y1,si = x2,di = y2,cx = WintdX,dx = WidthY
;
PROCTestPoint
cmpax,si
jle@@ 1
xchgax,si
@@ 1 :
cmpbx,di
jle@@ 2
xchgbx,di
@@ 2 :
ordi,di
js@@ 7
cmpdi,dx
jle@@ 3
movdi,dx
@@ 3 :
orsi,si
js@@ 7
cmpsi,cx
jle@@ 4
movsi,cx
@@ 4 :
cmpbx,dx
jg@@ 7
orbx,bx
jns@@ 5
xorbx,bx
@@ 5 :
cmpax,cx
jg@@ 7
orax,ax
jns@@ 6
xorax,ax
@@ 6 :
clc
ret
@@ 7 :
stc
ret
ENDP
;
; void _SetBorder( int X1, int Y1, int X2, int Y2)
;
PROC_SetBorder
ARGX1:word,Y1:word,X2:word,Y2:word
movax,[X1]
movbx,[X2]
cmpax,bx
jle@@ 1
xchgax,bx
@@ 1 :
orax,ax
jns@@ 2
xorax,ax
orbx,bx
jns@@ 2
xorax,ax
@@ 2 :
cmpbx,MAXX
jle@@ 3
movbx,MAXX
cmpax,MAXX
jle@@ 3
movax,MAXX
@@ 3 :
mov[MinX],ax
mov[MaxX],bx
subbx,ax
mov[WidthX],bx
;
movax,[Y1]
movbx,[Y2]
cmpax,bx
jle@@ 4
xchgax,bx
@@ 4 :
orax,ax
jns@@ 5
xorax,ax
orbx,bx
jns@@ 5
xorax,ax
@@ 5 :
cmpbx,MAXY
jle@@ 6
movbx,MAXY
cmpax,MAXY
jle@@ 6
movax,MAXY
@@ 6 :
mov[MinY],ax
mov[MaxY],bx
subbx,ax
mov[WidthY],bx
ret
ENDP
;
PROC_DefBorder
mov[wordMinX], 0
mov[wordMinY], 0
mov[wordMaxX],MAXX
mov[wordMaxY],MAXY
mov[wordWidthX],MAXX
mov[wordWidthY],MAXY
ret
ENDP
;
; void OpenGraph()
;
PROC_OpenGraph
movax,GRMODE
int 10h
movdx,3c4h
movax,0f02h
out dx,ax
callRestReg0
call_DefBorder
ret
ENDP
;
; void CloseGraph()
;
PROC_CloseGraph
movax, 3
int 10h
ret
ENDP
;
; int SetColor( int Color)
;
PROC_SetColor
ARGcolor:word
movax,[color]
andax,MAXCOLOR
xchgax,[Color]
ret
ENDP
;
; int SetDrMode( int Mode)
;
PROC_SetDrMode
ARGmode:word
movax,[mode]
andax, 3
shlax, 11
orax, 3
xchgax,[DrMode]
shrax, 11
ret
ENDP
;
; int SetLnStyle( int linestyle)
;
PROC_SetLnStyle
ARGlinestyle:word
movax,[linestyle]
xchgax,[LnStyle]
ret
ENDP
;
; void SetPattern( void far * Pat, int color)
;
PROC_SetPattern
ARGpat:farptr,color:word
USESdi,si,ds
push[wordcolor]
call_SetColor
popax
pushds
popes
leadi,[Pattern]
ldssi,[dwordpat]
movcx, 8
cld
repmovsb
ret
ENDP
;
; int GetColor( void )
;
PROC_GetColor
movax,[Color]
ret
ENDP
;
;ax = x,bx = y,dx = 03cfh
;
PROCPutPixel
cmpax,[WidthX]
ja@@ 1
cmpbx,[WidthY]
ja@@ 1
addax,[MinX]
addbx,[MinY]
pushax
callGetDspMem
popcx
andcx, 7
moval,80h
shral,cl
out dx,al
movax,[Color]
xchgal,[ byte es:bx]
@@ 1 :
ret
ENDP
;
; void PutPixel( int x, int y)
;
PROC_PutPixel
ARGx:word,y:word
movah, 2
callSetWrMode
movax,[x]
movbx,[y]
callPutPixel
callRestReg
ret
ENDP
;
;ax = x,bx = y
;
PROCGetPixel
pushax
callGetDspMem
popcx
notcl
andcl, 7
xorch,ch
movdx,3ceh
moval, 4
out dx,al
incdx
moval, 3
@@ 1 :
out dx,al
movah,[ byte es:bx]
shrah,cl
andah, 1
shlch, 1
orch,ah
decal
jns@@ 1
moval,ch
cbw
ret
ENDP
;
; int GetPixel( int x, int y)
;
PROC_GetPixel
ARGx:word,y:word
movax,[x]
movbx,[y]
addax,[MinX]
addbx,[MinY]
callGetPixel
ret
ENDP
;
;(b2 - b1) * (w - a1) / (a2 - a1));
;ax = w,cx = a1,bx = b1,si = a2,di = b2
;
PROCSumXY
pushbx
pushdx
pushax
movax,di
subax,bx
popbx
subbx,cx
imulbx
movbx,si
subbx,cx
idivbx
popdx
popbx
ret
ENDP
;cx = x,bx = y;retax = Code
;
PROCOutCode
xorax,ax
orcx,cx
jns@@ 1
orax,0001b
@@ 1 :
orbx,bx
jns@@ 2
orax,0010b
@@ 2 :
cmpcx,[WidthX]
jle@@ 3
orax,0100b
@@ 3 :
cmpbx,[WidthY]
jle@@ 4
orax,1000b
@@ 4 :
ret
ENDP
;
PROC_Line
ARGx1:word,y1:word,x2:word,y2:word
USESsi,di
movcx,[x2]
movbx,[y2]
callOutCode
movdh,al;dh = p2
movsi,cx
movdi,bx
movcx,[x1]
movbx,[y1]
@@ 1 :
callOutCode
movdl,al;dl = al = p1
testal,dh; if ((p1 & p2)) return
jz@@ 2
jmp@@ 17
@@ 2 :
oral,dh; if ( ! (p1 | p2)line
jz@@ 7
cmpdl, 0 ; if ( ! p1)x1swapx2;y1swapy2;p1swapp2
jne@@ 3
xchgcx,si
xchgbx,di
xchgdh,dl
@@ 3 :
testdl,0001b
jz@@ 4
xorax,ax; if (x1 < 0 )
callSumXY
addbx,ax;y1 += (y2 - y1) * ( - x1) / (x2 - x1)
xorcx,cx;x1 = 0
jmp short @@ 1
@@ 4 :
testdl,0010b
jz@@ 5
xorax,ax; if (y1 < 0 )
xchgcx,bx
xchgsi,di
callSumXY
xchgcx,bx
xchgsi,di
addcx,ax;x1 += (x2 - x1) * ( - y1) / (y2 - y1)
xorbx,bx;y1 = 0
jmp short @@ 1
@@ 5 :
testdl,0100b
jz@@ 6
movax,[WidthX]; if (x1 > WidthX)
callSumXY
addbx,ax;y1 += (y2 - y1) * (WidthX - x1) / (x2 - x1)
movcx,[WidthX];x1 = WidthX
jmp@@ 1
@@ 6 :
testdl,1000b
jz@@ 1
movax,[WidthY]; if (y1 > WidthY)
xchgcx,bx
xchgsi,di
callSumXY
xchgcx,bx
xchgsi,di
addcx,ax;x1 += (x2 - x1) * (WidthY - y1) / (y2 - y1)
movbx,[WidthY];y1 = WidthY
jmp@@ 1
@@ 7 :
movax,cx;line(x1,y1,x2,y2)
addax,[MinX]
addbx,[MinY]
addsi,[MinX]
adddi,[MinY]
mov[wordy1], 80
mov[wordx1], 0
cmpax,si
jle@@ 8
xchgax,si
xchgbx,di
@@ 8 :
subsi,ax
subdi,bx
jge@@ 9
neg[wordy1]
negdi
@@ 9 :
cmpdi,si
jle@@ 10
mov[wordx1], 1
xchgdi,si
@@ 10 :
pushsi
mov[y2],di
mov[x2],si
movdi,si
shrdi, 1
pushax
callGetDspMem
movah, 2
callSetWrMode
movsi,[LnStyle]
popcx
andcl, 7
moval,80h
shral,cl
out dx,al
movah,[ byte Color]
popcx
inccx
@@ 11 :
testsi,8000h
jz@@ 12
pushax
xchg[ byte es:bx],ah
popax
@@ 12 :
rolsi, 1
adddi,[y2]
cmpdi,[wordx2]
jle@@ 13
addbx,[y1]
subdi,[x2]
jmp short @@ 14
@@ 13 :
cmp[wordx1], 0
je@@ 14
addbx,[y1]
loop@@ 11
jmp short @@ 16
@@ 14 :
roral, 1
testal,80h
jz@@ 15
incbx
@@ 15 :
out dx,al
loop@@ 11
@@ 16 :
callRestReg
@@ 17 :
ret
ENDP
;
; void Rectangle( int x1, int y1, int x2, int y2)
;
PROC_Rectangle
ARGx1:word,y1:word,x2:word,y2:word
USESsi,di
movsi,[x1]
movdi,[y1]
pushdi
push[wordx2]
pushdi
pushsi
call_Line
addsp, 8
incdi
push[wordy2]
push[wordx2]
pushdi
push[wordx2]
call_Line
addsp, 8
push[wordy2]
push[wordx2]
push[wordy2]
pushsi
call_Line
addsp, 8
dec[wordy2]
push[wordy2]
pushsi
pushdi
pushsi
call_Line
addsp, 8
ret
ENDP
;
;ax = x1,bx = y1,si = x2,di = y2
;
PROCBar
pushbp
subdi,bx
incdi
pushdi
pushbx
pushax
callGetDspMem
movdi,bx
popax
movcx,ax
movbx,0ffffh
andcl, 7
shrbh,cl
movcx,si
notcl
andcl, 7
shlbl,cl
shrax, 3
shrsi, 3
subsi,ax
movbp,si
popsi
popcx
cld
@@ 1 :
pushcx
pushdi
pushsi
pushds
andsi, 7
moval,[ byte Pattern + si]
movah,al
andal,bh
movcx,bp
movsi,di
pushes
popds
deccx
js@@ 2
out dx,al
movsb
moval,ah
out dx,al
repmovsb
@@ 2 :
andal,bl
out dx,al
movsb
popds
popsi
popdi
popcx
incsi
adddi,DMWIDTH
loop@@ 1
popbp
ret
ENDP
;
; void Bar( int x1, int y1, int x2, int y2)
;
PROC_Bar
ARGx1:word,y1:word,x2:word,y2:word
USESsi,di
movax,[x1]
movbx,[y1]
movsi,[x2]
movdi,[y2]
movcx,[WidthX]
movdx,[WidthY]
callTestPoint
jc@@ 1
addax,[MinX]
addbx,[MinY]
addsi,[MinX]
adddi,[MinY]
pushax
callSetWrMode0
popax
callBar
callRestReg0
@@ 1 :
ret
ENDP
;
; void SetPalette( int index, int Red, int Green, int Blus)
;
PROC_SetPalette
ARGindex:word,red:word,green:word,blus:word
moval,[ byte index]
andal,0fh
cmpal, 6
jl@@ 2
jg@@ 1
moval,14h
jmp short @@ 2
@@ 1 :
cmpal, 7
je@@ 2
addal,30h
@@ 2 :
movdx,3c8h
out dx,al
incdx
moval,[ byte red]
out dx,al
moval,[ byte green]
out dx,al
moval,[ byte blus]
out dx,al
ret
ENDP
;
END
供其它汇编图形文件引用的插入文件:
P386N
includetasm_c.inc
MAXCOLORequ 15 ;最大颜色值
MAXXequ 639 ;最大X象素
MAXYequ 479 ;最大Y象素
DSPMEMSEGequ0A000h;屏显起始地址
DMWIDTHequ 80 ;屏幕每线字节数
GRMODEequ12h;屏显方式
EXTRNColor:word
EXTRNDrMode:word
EXTRNMinX:word
EXTRNMinY:word
EXTRNMaxX:word
EXTRNMaxY:word
EXTRNWidthX:word
EXTRNWidthY:word
;
EXTRN_OpenGraph:proc
EXTRN_CloseGraph:proc
EXTRN_Line:proc
EXTRN_PutPixel:proc
EXTRN_GetPixel:proc
EXTRN_SetColor:proc
EXTRN_GetColor:proc
EXTRN_SetDrMode:proc
EXTRN_SetLnStyle:proc
EXTRN_SetPattern:proc
EXTRN_Rectangle:proc
EXTRN_Bar:proc
EXTRN_SetPalette:proc
EXTRN_SetBorder:proc
EXTRN_DefBorder:proc
EXTRNGetDspMem:proc
EXTRNGetDspMemOff:proc
EXTRNSetWrMode:proc
EXTRNSetWrMode0:proc
EXTRNRestReg:proc
EXTRNRestReg0:proc
EXTRNTestPoint:proc
EXTRNBar:proc
EXTRNGetPixel:proc
EXTRNPutPixel:proc
EXTRN_farmalloc:proc
EXTRN_farfree:proc
显示位图数据函数文件:
includegraph.inc
CODESEG
PUBLIC_PutBmp
;
; void PutBmp( int x, int y, void far * bmp)
;
PROC_PutBmp
ARGx:word,y:word,bmp:farptr
USESsi,di,ds
movah, 2
callSetWrMode
movax,[x]
movbx,[y]
ldssi,[dwordbmp]
pushbp
movbp,[si]
addbx,[si + 2 ]
decbx
pushax
callGetDspMem
popcx
andcx, 7
movah,80h
shrah,cl
movcx,[si + 2 ]
addsi, 4
@@ 1 :
pushbx
pushax
xordi,di
@@ 2 :
moval,ah
out dx,al
testdi, 1
jnz@@ 3
lodsb
shral, 4
jmp short @@ 4
@@ 3 :
moval,[si - 1 ]
andal,0fh
@@ 4 :
xchgal,[ byte es:bx]
rorah, 1
testah,80h
jz@@ 5
incbx
@@ 5 :
incdi
cmpdi,bp
jl@@ 2
popax
popbx
subbx,DMWIDTH
loop@@ 1
popbp
callRestReg
ret
ENDP
;
END
PutBmp函数的测试程序:
#include " graph.h "
#include < stdlib.h >
#include < stdio.h >
#include < string .h >
#include < alloc.h >
char * buf = NULL;
void PutBmp( int , int , void far * );
typedef struct
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
}BMPRGB;
typedef struct
{
char type[ 2 ];
long filesize;
char nul1[ 4 ];
long offbins;
long bisize;
long width;
long high;
int planes;
int bitcount;
long packtype;
long sizeimage;
long xwidth;
long ywidth;
long clrused;
long clrimportant;
BMPRGBbmpcolor[ 16 ];
}BMPTOP;
void main( int argc, char ** argv)
{
int x,y, * t;
char s[ 10 ];
unsignedsize;
BMPTOPp;
BMPRGB * r;
FILE * f;
if (argc < 2 )
{
printf( " WindowsBMP文件显示程序(VGA16色和非压缩格式) " );
printf( " 调用格式:SHOWBMP<BMP文件名> " );
return ;
}
if ((f = fopen(argv[ 1 ], " rb " )) == NULL)
{
printf( " %sFilenotfind! " ,argv[ 1 ]);
return ;
}
fread( & p, 1 , sizeof (BMPTOP),f);
if (memcmp(p.type, " BM " , 2 ) || p.bitcount != 4 || p.packtype != 0 )
{
fclose(f);
printf( " %s文件不是16色模式非压缩形式的BMP文件,不能显示! " );
return ;
}
size = p.filesize - p.offbins;
if ((buf = ( char * )malloc(size + 4 )) == NULL)
{
printf( " 文件太大,内存不够使用! " );
fclose(f);
return ;
}
size = fread( & buf[ 4 ], 1 ,size,f);
fclose(f);
if (size != p.filesize - p.offbins)
{
printf( " %s文件已坏 " );
return ;
}
t = ( int * )buf;
* t ++ = p.width;
* t = p.high;
OpenGraph();
r = (BMPRGB * )p.bmpcolor;
for (x = 0 ;x < 16 ;x ++ )
SetPalette(x,r[x].red >> 2 ,r[x].green >> 2 ,r[x].blue >> 2 );
x = ( 640 - p.width) >> 1 ;
y = ( 480 - p.high) >> 1 ;
SetColor( 8 );
Bar(x - 10 ,y - 10 ,x + p.width + 10 ,y + p.high + 10 );
PutBmp(x,y,buf);
gets(s);
CloseGraph();
}
未完待续。
===================================================================================
更新:有个现成的UCDOS字符串显示测试程序,其中还包括了GetImage和PutImage函数的测试,这些函数代码在《Turbo C使用的汇编函数 -- VGA 12H模式图形函数(二)》中,因那篇文章代码太多,太长,所以补充更新在此,供参考:
#include < alloc.h >
#include < stdio.h >
void main()
{
int i,j,k;
unsigneds1,s2;
char ss[ 9 ];
void far * s;
OpenGraph();
if ( ! InitUCDOS( 2 ))
return ;
for (i = 0 ,k = 1 ;i < 128 ;i += 16 ,k ++ )
{
SetPos( 0 ,i);
Putch(k + 33 , 80 ,k);
}
Putss( 10 , 128 , " 公安县统计局 " , 640 , 15 );
s1 = ImageSize( 0 , 0 , 639 , 127 );
s = farmalloc(s1);
if (s)
{
s2 = GetImage( 0 , 0 , 639 , 127 ,s);
PutImage( 0 , 150 ,s, 0 );
gets(ss);
}
RestUCDOS( 0 );
CloseGraph();
if ( ! s)
printf( " Error! " );
else
printf( " s1=%u,s2=%u " ,s1,s2);
}
最后
以上就是清秀唇彩为你收集整理的Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)的全部内容,希望文章能够帮你解决Turbo C使用的汇编函数 -- VGA 12H模式图形函数(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复