-
mode13
I have attempted Denthor of Asphyxia tutorial on dos graphics[concerted to C++ by Snowman] and writing to graphics memory in mode 13. I have tried to write inn some functions[C++] into my program which are given in the tutorial like:
void SetMCGA()
{
_AX = 0x0013;
geninterrupt (0x10);
}
and
void INTPutpixel(int x, int y, unsigned char Col)
{
_AH = 0x0C;
_AL = Col;
_CX = x;
_DX = y;
_BX = 0x01;
geninterrupt (0x10);
}
Functions like these are really all I need, but I can't get it to compile. Is there something obvious I'm missing. Do I need to include anything more than the dos.h etc...? Is the way assembly code implemented in C++ different in different compilers. I'm using the free C++Builder 5.5 from Borland. Have never ever really used assembly in my C++ code.
If some friendly soul would please help me I would be very thankfull.
Vennlig Hilsen
August
-
I think your compiler doesn't support geninterrupt (..) function. So you should search in your documentation which function you need to work with interrupts.
Or you could use inline assemly. I'm not sure about the syntaxis, but I guess this could work.
Code:
void SetMCGA (void)
{
asm {
mov ax,0x13
int 0x10
}
}
void INTPutpixel(int x, int y, unsigned char Col)
{
asm {
mov ah,0x0c
mov al,col
mov cx,x
mov dx,y
mov bx,0x01
int 0x10
}
}
-
Could the problem be that a dos compiler is required instead of a windows compiler?
-
Code:
//include these 6 lines if you are using pure asm only, not inline
extern "C"
{
void SetMode(void);
void PlotPixel(int x,int y,unsigned char color,
unsigned char *buffer);
void CLS(unsigned char *buffer);
}
//end of extern block
unsigned char *Screen;
unsigned char *Buffer;
int main(void)
{
Screen=(unsigned char *)MK_FP(0xa000,0);
//Do the buffer here -> whatever you need
SetMode13();
CLS(Screen);
PlotPixel(x,y,15,Screen);
getch(); //So we can see if it works
}
Here is what the pure asm file will look like if you opt for that
In pure assembly using TASM
Code:
.MODEL large
.CODE
public _CLS,_PlotPixel,_SetMode
_SetMode PROC
mov ax,013h
int 10h
ret
_SetMode ENDP
_CLS PROC
ARG buffer:DWORD
push bp
mov bp,sp ;housekeeping for C and ARG
push di ;just in case preserve DI
les di,buffer ;load full pointer into ES:DI
mov al,color ;load color in AL
mov cx,0FA00h ;prepare to block fill 64000 bytes
rep stosb ;do it
pop di ;restore DI
pop bp ;restore bp for C
ret ;return to caller
_CLS ENDP
_PlotPixel PROC
ARG x:WORD,y:WORD,color:BYTE,buffer:DWORD
push bp
mov bp,sp
mov ax,SEG buffer
mov es,ax
mov ax,y
shl ax,6
mov bx,y
shl bx,8
add bx,ax
add bx,x
mov al,color
mov es:[bx],al
pop bp
ret
_PlotPixel ENDP
END
In C using inline assembly
Code:
void SetMode(void)
{
union REG regs;
regs.x.ax=0x13;
int86(0x10,& regs,& regs);
//or
// asm {
// mov ax,013h
// int 10h
// }
}
void PlotPixel(int x,int y,unsigned char *color,
unsigned char *buffer)
{
asm {
mov ax,SEG buffer
mov es,ax
mov ax,y
shl ax,6
mov bx,y
shl bx,8
add bx,ax
add bx,x
mov al,color
mov es:[bx],al
}
}
void CLS(unsigned char *buffer)
{
asm {
push di
les di,buffer
mov al,color
mov cx,0FA00h
rep stosb
pop di
}
}
Incidentally do not use geninterrupt() as it does not preserve the registers. Use the int86(), and int86x() family of functions if you are doing interrupts from C.