#include "objgfx30.h" #include "defpal.inc" #include "ogDisplay_VESA.h" #include <go32.h> // for __tb #include <dpmi.h> #include <sys/movedata.h> #include <sys/farptr.h> #include <pc.h> #include <string.h> /* * * ogDisplay methods * */ void InitVESAMode(uInt16 mode) { __dpmi_regs regs; regs.x.ax=0x4f02; regs.x.bx=mode; __dpmi_int(0x10, ®s); return; } ogDisplay_VESA::ogDisplay_VESA(void) { InGraphics = false; VESARec = new TVESA_Rec; ModeRec = new TMode_Rec; getVESAInfo(); ScreenSelector = __dpmi_allocate_ldt_descriptors(1); return; } // ogDisplay_VESA::ogDisplay_VESA uInt32 ogDisplay_VESA::rawGetPixel(uInt32 x, uInt32 y) { uInt32 result; switch (BPP) { case 8: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " movzbl (%%edi),%%eax \n" // movzx edx,byte ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 15: case 16: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size} " add %%ecx, %%edi \n" // add edi, ecx " movzwl (%%edi),%%eax \n" // movzx edx,word ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 24: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " mov %%ecx, %%eax \n" // mov eax, ecx - adjust for pixel size " add %%ecx, %%ecx \n" // add ecx, ecx - adjust for pixel size " add %%eax, %%ecx \n" // add ecx, eax - adjust for pixel size " add %%esi, %%edi \n" // add edi, esi // " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4] " add %%ecx, %%edi \n" // add edi, ecx " movzwl (%%edi),%%eax \n" // movzx edx,word ptr [edi] " xor %%eax, %%eax \n" " mov 2(%%edi), %%al \n" // mov al, [edi+2] " shl $16, %%eax \n" // shl eax, 16 " mov (%%edi), %%ax \n" // mov ax, [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 32: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " shl $2, %%ecx \n" // shl ecx, 2 {adjust for pixel size} // " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4] " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " mov (%%edi),%%eax \n" // eax,word ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); } // switch return result; } // TScreen::rawGetPixel void ogDisplay_VESA::rawSetPixel(uInt32 x, uInt32 y, uInt32 colour) { switch (BPP) { case 8: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } // " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx * 4] " push %%ds \n" // push ds " mov %%dx, %%ds \n" // mov ds, dx " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%al, (%%edi) \n" // mov [edi], al " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), // %2, %3 "d" (ScreenSelector) // %4 ); break; case 15: case 16: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" // push ds " mov %%dx, %%ds \n" // mov ds, dx " add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size} " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%ax, (%%edi) \n" // mov [edi], al " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), // %2, %3 "d" (ScreenSelector) // %4 ); break; case 24: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } // " add (%%esi,%%ebx,4),%%edi \n" // add edi, [esi + ebx * 4] " push %%ds \n" // push ds " mov %%dx, %%ds \n" // mov ds, dx " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size} " add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size} // { Draw the pixel } " mov %%ax, (%%edi) \n" // mov [edi], ax " shr $16, %%eax \n" // shr eax, 16 " mov %%al, 2(%%edi)\n" // mov [edi+2],al " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), // %2, %3 "d" (ScreenSelector) // %4 ); break; case 32: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" // push ds " mov %%dx, %%ds \n" // mov ds, dx " shl $2, %%ecx \n" // shl eax, 2 {adjust for pixel size} " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%eax, (%%edi) \n" // mov [edi], eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), // %2, %3 "d" (ScreenSelector) // %4 ); } // switch return; } // ogDisplay_VESA::rawSetPixel void ogDisplay_VESA::rawLine(uInt32 x1, uInt32 y1, uInt32 x2, uInt32 y2, uInt32 colour) { /* * ogDisplay_VESA::rawLine() * * private method; draws an unclipped line from (x1,y1) to (x2,y2) * */ int32 tc; if (!ogAvail()) return; switch (BPP) { case 8: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%cx, %%ds \n" // mov ds, cx " mov $1, %%ecx \n" // mov ecx, 1 " bt $15, %%eax \n" // bt eax, 15 " jnc rlxPositive8 \n" " or $-1, %%ecx \n" // or ecx, -1 " neg %%eax \n" // neg eax "rlxPositive8: \n" " add %%eax, %%eax \n" // add eax, eax " bt $15, %%ebx \n" // bt ebx, 15 " jnc rlyPositive8 \n" " neg %%edx \n" // neg edx " neg %%ebx \n" // neg ebx "rlyPositive8: \n" " add %%ebx, %%ebx \n" // add ebx, ebx " cmp %%ebx, %%eax \n" // cmp eax, ebx " jle rlyGreater8 \n" " push %%ecx \n" // push ecx " mov %%eax, %%ecx \n" // mov ecx, eax " mov %%ebx, %6 \n" // mov tc, ebx " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" // pop ecx "rlxTop8: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%al, (%%edi) \n" // mov [edi], al " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone8 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddY8 \n" " add %%edx, %%edi \n" // add edi, edx " sub %%eax, %6 \n" // sub tc, eax "rlNoAddY8: \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ebx, %6 \n" // add tc, ebx " jmp rlxTop8 \n" "rlyGreater8: \n" " push %%ecx \n" // push ecx " mov %%ebx, %%ecx \n" // mov ecx, ebx " mov %%eax, %6 \n" // mov tc, eax " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" "rlyTop8: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%al, (%%edi) \n" // mov [edi], al " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone8 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddX8 \n" " add %%ecx, %%edi \n" // add edi, ecx " sub %%ebx, %6 \n" // sub tc, ebx "rlNoAddX8: \n" " add %%edx, %%edi \n" // add edi, edx " add %%eax, %6 \n" // add tc, eax " jmp rlyTop8 \n" "rlDone8: \n" " pop %%ds \n" // pop ds : : "D" ((uInt8 *)buffer+lineOfs[y1]+x1), // %0 "S" ((uInt8 *)buffer+lineOfs[y2]+x2), // %1 "a" (x2-x1), "b" (y2-y1), // %2, %3 "d" (xRes), "m" (colour), // %4, %5 "m" (tc), "c" (ScreenSelector) // %6, %7 ); break; case 15: case 16: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%cx, %%ds \n" // mov ds, cx " mov $1, %%ecx \n" // mov ecx, 1 " bt $15, %%eax \n" // bt eax, 15 " jnc rlxPositive16 \n" " or $-1, %%ecx \n" // or ecx, -1 " neg %%eax \n" // neg eax "rlxPositive16: \n" " add %%eax, %%eax \n" // add eax, eax " bt $15, %%ebx \n" // bt ebx, 15 " jnc rlyPositive16 \n" " neg %%edx \n" // neg edx " neg %%ebx \n" // neg ebx "rlyPositive16: \n" " add %%ebx, %%ebx \n" // add ebx, ebx " cmp %%ebx, %%eax \n" // cmp eax, ebx " jle rlyGreater16 \n" " push %%ecx \n" // push ecx " mov %%eax, %%ecx \n" // mov ecx, eax " mov %%ebx, %6 \n" // mov tc, ebx " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" // pop ecx "rlxTop16: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%ax, (%%edi) \n" // mov [edi], ax " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone16 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddY16 \n" " add %%edx, %%edi \n" // add edi, edx " sub %%eax, %6 \n" // sub tc, eax "rlNoAddY16: \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ebx, %6 \n" // add tc, ebx " jmp rlxTop16 \n" "rlyGreater16: \n" " push %%ecx \n" // push ecx " mov %%ebx, %%ecx \n" // mov ecx, ebx " mov %%eax, %6 \n" // mov tc, eax " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" "rlyTop16: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%ax, (%%edi) \n" // mov [edi], ax " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone16 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddX16 \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " sub %%ebx, %6 \n" // sub tc, ebx "rlNoAddX16: \n" " add %%edx, %%edi \n" // add edi, edx " add %%eax, %6 \n" // add tc, eax " jmp rlyTop16 \n" "rlDone16: \n" " pop %%ds \n" // pop ds : : "D" ((uInt8 *)buffer+lineOfs[y1]+(x1 << 1)), // %0 "S" ((uInt8 *)buffer+lineOfs[y2]+(x2 << 1)), // %1 "a" (x2-x1), "b" (y2-y1), // %2, %3 "d" (xRes), "m" (colour), // %4, %5 "m" (tc), "c" (ScreenSelector) // %6, %7 ); break; case 24: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%cx, %%ds \n" // mov ds, cx " mov $1, %%ecx \n" // mov ecx, 1 " bt $15, %%eax \n" // bt eax, 15 " jnc rlxPositive24 \n" " or $-1, %%ecx \n" // or ecx, -1 " neg %%eax \n" // neg eax "rlxPositive24: \n" " add %%eax, %%eax \n" // add eax, eax " bt $15, %%ebx \n" // bt ebx, 15 " jnc rlyPositive24 \n" " neg %%edx \n" // neg edx " neg %%ebx \n" // neg ebx "rlyPositive24: \n" " add %%ebx, %%ebx \n" // add ebx, ebx " cmp %%ebx, %%eax \n" // cmp eax, ebx " jle rlyGreater24 \n" " push %%ecx \n" // push ecx " mov %%eax, %%ecx \n" // mov ecx, eax " mov %%ebx, %6 \n" // mov tc, ebx " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" // pop ecx "rlxTop24: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%ax, (%%edi) \n" // mov [edi], ax " shr $16, %%eax \n" // shr eax, 16 " mov %%al, 2(%%edi)\n" // mov [edi+2],al " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone24 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddY24 \n" " add %%edx, %%edi \n" // add edi, edx " sub %%eax, %6 \n" // sub tc, eax "rlNoAddY24: \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ecx, %%edi \n" // add edi, ecx " add %%ebx, %6 \n" // add tc, ebx " jmp rlxTop24 \n" "rlyGreater24: \n" " push %%ecx \n" // push ecx " mov %%ebx, %%ecx \n" // mov ecx, ebx " mov %%eax, %6 \n" // mov tc, eax " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" "rlyTop24: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%ax, (%%edi) \n" // mov [edi], ax " shr $16, %%eax \n" // shr eax, 16 " mov %%al, 2(%%edi)\n" // mov [edi+2],al " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone24 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddX24 \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ecx, %%edi \n" // add edi, ecx " sub %%ebx, %6 \n" // sub tc, ebx "rlNoAddX24: \n" " add %%edx, %%edi \n" // add edi, edx " add %%eax, %6 \n" // add tc, eax " jmp rlyTop24 \n" "rlDone24: \n" " pop %%ds \n" // pop ds : : "D" ((uInt8 *)buffer+lineOfs[y1]+(x1*3)), // %0 "S" ((uInt8 *)buffer+lineOfs[y2]+(x2*3)), // %1 "a" (x2-x1), "b" (y2-y1), // %2, %3 "d" (xRes), "m" (colour), // %4, %5 "m" (tc), "c" (ScreenSelector) // %6, %7 ); break; case 32: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%cx, %%ds \n" // mov ds, cx " mov $1, %%ecx \n" // mov ecx, 1 " bt $15, %%eax \n" // bt eax, 15 " jnc rlxPositive32 \n" " or $-1, %%ecx \n" // or ecx, -1 " neg %%eax \n" // neg eax "rlxPositive32: \n" " add %%eax, %%eax \n" // add eax, eax " bt $15, %%ebx \n" // bt ebx, 15 " jnc rlyPositive32 \n" " neg %%edx \n" // neg edx " neg %%ebx \n" // neg ebx "rlyPositive32: \n" " add %%ebx, %%ebx \n" // add ebx, ebx " cmp %%ebx, %%eax \n" // cmp eax, ebx " jle rlyGreater32 \n" " push %%ecx \n" // push ecx " mov %%eax, %%ecx \n" // mov ecx, eax " mov %%ebx, %6 \n" // mov tc, ebx " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" // pop ecx "rlxTop32: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%eax, (%%edi)\n" // mov [edi], eax " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone32 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddY32 \n" " add %%edx, %%edi \n" // add edi, edx " sub %%eax, %6 \n" // sub tc, eax "rlNoAddY32: \n" " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ebx, %6 \n" // add tc, ebx " jmp rlxTop32 \n" "rlyGreater32: \n" " push %%ecx \n" // push ecx " mov %%ebx, %%ecx \n" // mov ecx, ebx " mov %%eax, %6 \n" // mov tc, eax " shr $1, %%ecx \n" // shr ecx, 1 " sub %%ecx, %6 \n" // sub tc, ecx " pop %%ecx \n" "rlyTop32: \n" " push %%eax \n" // push eax " mov %5, %%eax \n" // mov eax, colour " mov %%eax, (%%edi)\n" // mov [edi], eax " pop %%eax \n" // pop eax " cmp %%edi, %%esi \n" // cmp esi, edi " je rlDone32 \n" " cmp $0, %6 \n" // cmp tc, 0 " jl rlNoAddX32 \n" " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx - pix size " add %%ecx, %%edi \n" // add edi, ecx " sub %%ebx, %6 \n" // sub tc, ebx "rlNoAddX32: \n" " add %%edx, %%edi \n" // add edi, edx " add %%eax, %6 \n" // add tc, eax " jmp rlyTop32 \n" "rlDone32: \n" " pop %%ds \n" // pop ds : : "D" ((uInt8 *)buffer+lineOfs[y1]+(x1 << 2)), // %0 "S" ((uInt8 *)buffer+lineOfs[y2]+(x2 << 2)), // %1 "a" (x2-x1), "b" (y2-y1), // %2, %3 "d" (xRes), "m" (colour), // %4, %5 "m" (tc), "c" (ScreenSelector) // %6, %7 ); break; } // switch return; } // ogDisplay_VESA::rawLine bool ogDisplay_VESA::ogAvail(void) { return ( ((ScreenSelector!=0) || (buffer!=NULL)) && (lineOfs!=NULL)); } // ogDisplay_VESA::ogAvail void ogDisplay_VESA::getModeInfo(uInt16 mode) { __dpmi_regs regs; memset(ModeRec, 0,sizeof(struct TMode_Rec)); memset(®s, 0, sizeof(regs)); dosmemput(ModeRec, sizeof(struct TMode_Rec), __tb); int ofs, seg; seg = __tb; // __tb is a buffer located in "dos memory". This buffer ofs = __tb; // is used because the vesa driver cannot acces memory // above 1 MB (your program is most likely to be located above 1MB). ofs &= 0xffff; // Make a real pointer (segment:offse = 16:16) seg &= 0xffff0000; // from the address of the buffer. seg >>= 4; regs.x.ax = 0x4f01; // Get the modeinfo of a certain vesa video mode, // this is a structure which contains. regs.x.cx = mode; // information needed by other functions below. regs.x.es = seg; regs.x.di = ofs; __dpmi_int(0x10, ®s); dosmemget(__tb,sizeof(struct TMode_Rec),ModeRec); // This info is located in dos memory, so // it has to be moved to your program's // addres space. return; } // ogDisplay_VESA::getModeInfo void ogDisplay_VESA::getVESAInfo(void) { unsigned int seg, ofs; __dpmi_regs regs; if (VESARec==NULL) VESARec = new TVESA_Rec; if (VESARec==NULL) return; memset(VESARec,0,sizeof(struct TVESA_Rec)); memset(®s, 0, sizeof(regs)); VESARec->VBESignature[0] = 'V'; // First off initialize the structure. VESARec->VBESignature[1] = 'B'; VESARec->VBESignature[2] = 'E'; VESARec->VBESignature[3] = '2'; /* Because VBE funtions operate in real mode, we first have to move the initialized structure to real-mode address space, so the structure can be filled by the vesa function in real mode. */ dosmemput(VESARec, sizeof(struct TVESA_Rec), __tb); seg = __tb; // Calculate real mode addres of the buffer. ofs = __tb; ofs &= 0xffff; seg &= 0xffff0000; seg >>= 4; regs.x.ax = 0x4F00; regs.x.es = seg; regs.x.di = ofs; __dpmi_int(0x10, ®s); // Get vesa info. dosmemget(__tb, sizeof(struct TVESA_Rec), VESARec); // Move the structure back to VESARec->OEMStringPtr = (VESARec->OEMStringPtr & 0xFFFF) + ((VESARec->OEMStringPtr & 0xFFFF0000) >> 12); VESARec->OEMVendorNamePtr= (VESARec->OEMVendorNamePtr& 0xFFFF) + ((VESARec->OEMVendorNamePtr& 0xFFFF0000) >> 12); VESARec->OEMProductNamePtr= (VESARec->OEMProductNamePtr& 0xFFFF) + ((VESARec->OEMProductNamePtr& 0xFFFF0000) >> 12); VESARec->OEMProductRevPtr= (VESARec->OEMProductRevPtr& 0xFFFF) + ((VESARec->OEMProductRevPtr& 0xFFFF0000) >> 12); VESARec->VideoModePtr = ((VESARec->VideoModePtr & 0xFFFF0000) >> 12) + (VESARec->VideoModePtr & 0xFFFF); return; } // ogDisplay_VESA::getVESAInfo uInt16 ogDisplay_VESA::findMode(uInt32 _xRes, uInt32 _yRes, uInt32 _BPP) { uInt16 mode; if ((_xRes==320) && (_yRes==200) && (_BPP==8)) return 0x13; // if ((VESARec==NULL) || (VESARec->VideoModePtr==NULL)) return 0; if (ModeRec==NULL) return 0; for (mode = 0x100; mode < 0x1FF; mode++) { getModeInfo(mode); if ((ModeRec->xRes>=_xRes) && (ModeRec->yRes>=_yRes) && (ModeRec->BitsPerPixel==_BPP)) return mode; } return 0; } // ogDisplay_VESA::findMode void ogDisplay_VESA::setMode(uInt16 mode) { uInt32 size, count; __dpmi_meminfo mem_info; if (mode==0x13) { xRes = 320; yRes = 200; maxX = 319; maxY = 199; BPP = 8; redFieldPosition = 0; greenFieldPosition = 0; blueFieldPosition = 0; alphaFieldPosition = 0; redShifter = 0; greenShifter = 0; blueShifter = 0; alphaFieldPosition = 0; mem_info.address = 0xA0000; mem_info.size = 64000; size = 63999; buffer = NULL; __dpmi_physical_address_mapping(&mem_info); __dpmi_set_segment_base_address(ScreenSelector, mem_info.address); __dpmi_set_segment_limit(ScreenSelector,size); __dpmi_set_descriptor_access_rights(ScreenSelector, 0x40F3); } else { buffer = NULL; mode |= 0x4000; // attempt lfb getModeInfo(mode); if (ModeRec->physBasePtr == 0) return; size = ModeRec->yRes*ModeRec->BytesPerLine; xRes = ModeRec->BytesPerLine; yRes = ModeRec->yRes; maxX = ModeRec->xRes-1; maxY = yRes-1; redFieldPosition = ModeRec->RedFieldPosition; greenFieldPosition = ModeRec->GreenFieldPosition; blueFieldPosition = ModeRec->BlueFieldPosition; redShifter = 8-ModeRec->RedMaskSize; greenShifter = 8-ModeRec->GreenMaskSize; blueShifter = 8-ModeRec->BlueMaskSize; BPP = ModeRec->BitsPerPixel; mem_info.address = ModeRec->physBasePtr; mem_info.size = size; size = ((size+4095) >> 12); __dpmi_physical_address_mapping(&mem_info); __dpmi_set_segment_base_address(ScreenSelector, mem_info.address); __dpmi_set_segment_limit(ScreenSelector,size); __dpmi_set_descriptor_access_rights(ScreenSelector, 0xC0F3); } // else owner = this; dataState = ogALIASING; InGraphics = true; if ((lineOfs!=NULL) && (lSize!=0)) delete [] lineOfs; lSize = yRes*sizeof(uInt32); lineOfs = new uInt32[yRes];; if (lineOfs == NULL) return; lineOfs[0] = 0; for (count=1; count<yRes; count++) lineOfs[count] = lineOfs[count-1]+xRes; InitVESAMode(mode); if (pal==NULL) pal = new ogRGBA[256]; memcpy(pal, DEFAULT_PALETTE, sizeof(ogRGBA)*256); InitVESAMode(mode); antiAlias=(BPP>8); if (BPP==8) setPal(); ogClear(0); return; } // ogDisplay_VESA::setMode void ogDisplay_VESA::setPal(void) { uInt32 c; if (BPP!=8) return; outportb(0x3c8,0); for (c=0; c<256; c++) { outportb(0x3c9,pal[c].red >> 2); outportb(0x3c9,pal[c].green >> 2); outportb(0x3c9,pal[c].blue >> 2); } // for return; } // ogDisplay_VESA::setPal bool ogDisplay_VESA::ogAlias(ogSurface& SrcObject, uInt32 x1, uInt32 y1, uInt32 x2, uInt32 y2) { return false; } // ogDisplay_VESA::ogAlias void ogDisplay_VESA::ogClear(uInt32 colour) { uInt32 height; if (!ogAvail()) return; __asm__ __volatile__("cld\n"); switch (BPP) { case 8: __asm__ __volatile__( " push %%es \n" // push es " mov %6, %%ax \n" // mov ax, ScreenSelector " mov %%ax, %%es \n" // mov es, ax " add (%%esi), %%edi \n" // add edi, [esi] " mov %%ecx, %%esi \n" // mov esi, ecx " inc %%edx \n" // inc edx (maxY) " inc %%ebx \n" // inc ebx (maxX) " mov %5, %%eax \n" // mov eax, colour " sub %%edx, %%esi \n" // sub esi, edx " mov %%al, %%ah \n" // mov ah, al " mov %%ax, %%cx \n" // mov cx, ax " shl $16, %%eax \n" // shl eax, 16 " mov %%cx, %%ax \n" // mov ax, cx "loop8: \n" " push %%edx \n" " mov %%edx, %%ecx \n" // mov ecx, edx " and $3, %%edx \n" // and edx, 3 " shr $2, %%ecx \n" // shr ecx, 2 " rep \n" " stosl \n" " mov %%edx, %%ecx \n" // mov ecx, edx " rep \n" " stosb \n" " pop %%edx \n" " add %%esi, %%edi \n" // add edi, esi " dec %%ebx \n" " jnz loop8 \n" " pop %%es \n" // pop es : : "D" (buffer), "S" (lineOfs), // %0, %1 "b" (maxY), "c" (xRes), "d" (maxX), // %2, %3, %4 "m" (colour), "m" (ScreenSelector) // %5, %6 ); break; case 15: case 16: __asm__ __volatile__( " push %%es \n" // push es " mov %6, %%ax \n" // mov ax, ScreenSelector " mov %%ax, %%es \n" // mov es, ax " add (%%esi), %%edi \n" // add edi, [esi] " mov %%ecx, %%esi \n" // mov esi, ecx " inc %%edx \n" // inc edx (maxX) " inc %%ebx \n" // inc ebx (maxY) " sub %%edx, %%esi \n" // sub esi, edx " mov %5, %%eax \n" // mov eax, colour " sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size " mov %%ax, %%cx \n" // mov cx, ax " shl $16, %%eax \n" // shl eax, 16 " mov %%cx, %%ax \n" // mov ax, cx "loop16: \n" " mov %%edx, %%ecx \n" // mov ecx, edx " shr $1, %%ecx \n" // shr ecx, 1 " rep \n" " stosl \n" " jnc noc16 \n" " stosw \n" "noc16: \n" " add %%esi, %%edi \n" // add edi, esi " dec %%ebx \n" " jnz loop16 \n" " pop %%es \n" : : "D" (buffer), "S" (lineOfs), // %0, %1 "b" (maxY), "c" (xRes), "d" (maxX), // %2, %3, %4 "m" (colour), "m" (ScreenSelector) // %5, %6 ); break; case 24: __asm__ __volatile__( " push %%es \n" // push es " mov %7, %%ax \n" // mov ax, ScreenSelector " mov %%ax, %%es \n" // mov es, ax " add (%%esi), %%edi \n" // add edi, [esi] " mov %%ecx, %%esi \n" // mov esi, ecx " inc %%edx \n" // inc edx (maxX) " inc %%ebx \n" // inc ebx (maxY) " mov %5, %%eax \n" // mov eax, colour " sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size " mov %%ebx, %6 \n" // mov height, ebx " sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size " mov %%eax, %%ebx \n" // mov ebx, eax " sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size " shr $16, %%ebx \n" // shr ebx, 16 "oloop24: \n" " mov %%edx, %%ecx \n" // mov ecx, edx "iloop24: \n" " mov %%ax,(%%edi) \n" // mov [edi],ax " movb %%bl,2(%%edi) \n" // mov [edi+2],bl " add $3, %%edi \n" // add edi, 3 " dec %%ecx \n" // dec ecx " jnz iloop24 \n" " add %%esi, %%edi \n" // add edi, esi " decl %6 \n" // dec height " jnz oloop24 \n" " pop %%es \n" // pop es : : "D" (buffer), "S" (lineOfs), // %0, %1 "b" (maxY), "c" (xRes), "d" (maxX), // %2, %3, %4 "m" (colour), "m" (height), // %5, %6 "m" (ScreenSelector) // %7 ); break; case 32: __asm__ __volatile__( " push %%es \n" // push es " mov %6, %%ax \n" // mov ax, ScreenSelector " mov %%ax, %%es \n" // mov es, ax " add (%%esi), %%edi \n" // add edi, [esi] " mov %%ecx, %%esi \n" // mov esi, ecx " inc %%edx \n" // inc edx (maxX) " inc %%ebx \n" // inc ebx (maxY) " mov %5, %%eax \n" // mov eax, colour " mov %%edx, %%ecx \n" // mov ecx, edx " shl $2, %%ecx \n" // shl ecx, 2 " sub %%ecx, %%esi \n" // sub esi, ecx // adjust for pix size "loop32: \n" " mov %%edx, %%ecx \n" // mov ecx, edx " rep \n" " stosl \n" " add %%esi, %%edi \n" // add edi, esi " dec %%ebx \n" " jnz loop32 \n" " pop %%es \n" // pop es : : "D" (buffer), "S" (lineOfs), // %0, %1 "b" (maxY), "c" (xRes), "d" (maxX), // %2, %3, %4 "m" (colour), "m" (ScreenSelector) // %5, %6 ); break; } // switch return; } // ogDisplay_VESA::ogClear void ogDisplay_VESA::ogCopyLineTo(uInt32 dx, uInt32 dy, const void * src, uInt32 size) { /* * ogCopyLineTo() * * Inputs: * * dx - Destination X of the target buffer * dy - Destination Y of the target buffer * src - buffer to copy * size - size in bytes *NOT* pixels * * Copies a run of pixels (of the same format) to (x,y) of a buffer * * This method is required because of the different implementations of * copying a run of pixels to a buffer * * WARNING!!! This does *NO* error checking. It is assumed that you've * done all of that. ogCopyLineTo and ogCopyLineFrom are the only * methods that don't check to make sure you're hosing things. Don't * use this method unless YOU KNOW WHAT YOU'RE DOING!!!!!!!!! */ movedata(_my_ds(),(uInt32)src, ScreenSelector,(uInt32)((uInt8*)buffer+(lineOfs[dy]+dx*( (BPP+7) >> 3) ) ), size); return; } // ogSurface::ogCopyLineTo void ogDisplay_VESA::ogCopyLineFrom(uInt32 sx, uInt32 sy, void * dest, uInt32 size) { /* * ogCopyLineFrom() * * Inputs: * * sx - Source X of the target buffer * sy - Source Y of the target buffer * dest - where to put it * size - size in bytes *NOT* pixels * * Copies a run of pixels (of the same format) to (x,y) of a buffer * * This method is required because of the different implementations of * copying a run of pixels to a buffer * * WARNING!!! This does *NO* error checking. It is assumed that you've * done all of that. ogCopyLineTo and ogCopyLineFrom are the only * methods that don't check to make sure you're hosing things. Don't * use this method unless YOU KNOW WHAT YOU'RE DOING!!!!!!!!! */ movedata(ScreenSelector,(uInt32)((uInt8*)buffer+(lineOfs[sy]+sx*( (BPP+7) >> 3) ) ), _my_ds(),(uInt32)dest, size); return; } // ogDisplay_VESA::ogCopyLineFrom bool ogDisplay_VESA::ogCreate(uInt32 _xRes, uInt32 _yRes,ogPixelFmt _pixFormat) { uInt16 mode; mode = findMode(_xRes, _yRes, _pixFormat.BPP); if ((mode == 0) && ((_pixFormat.BPP==24) || (_pixFormat.BPP==32))) { if (_pixFormat.BPP==24) _pixFormat.BPP=32; else _pixFormat.BPP=24; mode=findMode(_xRes,_yRes,_pixFormat.BPP); } // if if (mode!=0) setMode(mode); return (mode!=0); } // ogDisplay_VESA::ogCreate bool ogDisplay_VESA::ogClone(ogSurface& SrcObject) { return false; } // ogDisplay_VESA::ogClone void ogDisplay_VESA::ogCopyPal(ogSurface& SrcObject) { ogSurface::ogCopyPal(SrcObject); setPal(); return; } // ogDisplay_VESA::ogCopyPal uInt32 ogDisplay_VESA::ogGetPixel(int32 x, int32 y) { uInt32 result; if (!ogAvail()) return transparentColor; if (((uInt32)x>maxX) || ((uInt32)y>maxY)) return transparentColor; switch (BPP) { case 8: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " movzbl (%%edi),%%eax \n" // movzx edx,byte ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 15: case 16: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size} " add %%ecx, %%edi \n" // add edi, ecx " movzwl (%%edi),%%eax \n" // movzx edx,word ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 24: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " mov %%ecx, %%eax \n" // mov eax, ecx - adjust for pixel size " add %%ecx, %%ecx \n" // add ecx, ecx - adjust for pixel size " add %%eax, %%ecx \n" // add ecx, eax - adjust for pixel size " add %%esi, %%edi \n" // add edi, esi // " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4] " add %%ecx, %%edi \n" // add edi, ecx " movzwl (%%edi),%%eax \n" // movzx edx,word ptr [edi] " xor %%eax, %%eax \n" " mov 2(%%edi), %%al \n" // mov al, [edi+2] " shl $16, %%eax \n" // shl eax, 16 " mov (%%edi), %%ax \n" // mov ax, [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); break; case 32: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax (ScreenSelector) " shl $2, %%ecx \n" // shl ecx, 2 {adjust for pixel size} // " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4] " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " mov (%%edi),%%eax \n" // eax,word ptr [edi] " mov %%eax, %4 \n" // mov result, eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (ScreenSelector), "c" (x), "m" (result) // %2, %3, %4 ); } // switch return result; } // TScreen::ogGetPixel void * ogDisplay_VESA::ogGetPtr(uInt32 x, uInt32 y) { return NULL; } // ogDisplay_VESA::ogGetPtr void ogDisplay_VESA::ogHLine(int32 x1, int32 x2, int32 y, uInt32 colour) { int32 tmp; if (!ogAvail()) return; if ((uInt32)y>maxY) return; if (x1>x2) { tmp= x1; x1 = x2; x2 = tmp; } // if if (x1<0) x1 = 0; if (x2>(int32)maxX) x2=maxX; if (x2<x1) return; __asm__ __volatile__("cld \n"); switch (BPP) { case 8: __asm__ __volatile__( " push %%es \n" // push es " mov %%dx, %%es \n" // mov es, dx " add %%ebx, %%edi \n" // add edi, ebx " add %%esi, %%edi \n" // add edi, esi " and $0xff, %%eax \n" // and eax, 0ffh " sub %%ebx, %%ecx \n" // sub ecx, ebx " mov %%al, %%ah \n" // mov ah, al " inc %%ecx \n" // inc ecx " mov %%eax, %%ebx \n" // mov ebx, eax " shl $16, %%ebx \n" // shl ebx, 16 " add %%ebx, %%eax \n" // add eax, ebx " mov %%ecx, %%edx \n" // mov edx, ecx " mov $4, %%ecx \n" // mov ecx, 4 " sub %%edi, %%ecx \n" // sub ecx, edi " and $3, %%ecx \n" // and ecx, 3 " sub %%ecx, %%edx \n" // sub edx, ecx " jle LEndBytes \n" " rep \n" " stosb \n" " mov %%edx, %%ecx \n" // mov ecx, edx " and $3, %%edx \n" // and edx, 3 " shr $2, %%ecx \n" // shr ecx, 2 " rep \n" " stosl \n" "LEndBytes: \n" " add %%edx, %%ecx \n" // add ecx, edx " rep \n" " stosb \n" " pop %%es \n" : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (colour), "b" (x1), // %2, %3 "c" (x2), "d" (ScreenSelector) ); break; case 15: case 16: __asm__ __volatile__( " push %%es \n" " mov %%dx, %%es \n" // mov es, dx " sub %%ebx, %%ecx \n" // sub ecx, ebx " add %%ebx, %%ebx \n" // add ebx, ebx - pix size " inc %%ecx \n" // inc ecx " add %%ebx, %%edi \n" // add edi, ebx " add %%esi, %%edi \n" // add edi, esi " xor %%edx, %%edx \n" // xor edx, edx " mov %%ax, %%dx \n" // mov dx, ax " shl $16, %%eax \n" // shl eax, 16 " add %%edx, %%eax \n" // add eax, edx " shr $1, %%ecx \n" // shr ecx, 1 " rep \n" " stosl \n" " jnc hLnoc16 \n" " stosw \n" "hLnoc16: \n" " pop %%es \n" : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (colour), "b" (x1), // %2, %3 "c" (x2), "d" (ScreenSelector) ); break; case 24: __asm__ __volatile__( " push %%es \n" // push es " mov %%ax, %%es \n" // mov es, ax " mov %2, %%eax \n" " sub %%ebx, %%ecx \n" // sub ecx, ebx " add %%esi, %%edi \n" // add edi, esi " add %%ebx, %%ebx \n" // add ebx, ebx - pix size " inc %%ecx \n" // inc ecx " add %%edx, %%ebx \n" // add ebx, edx - pix size " add %%ebx, %%edi \n" // add edi, ebx " mov %%eax, %%ebx \n" // mov ebx, eax " shr $16, %%ebx \n" // shr ebx, 16 "hLlop24: \n" " mov %%ax, (%%edi) \n" // mov [edi], ax " mov %%bl, 2(%%edi)\n" // mov [edi+2], bl " add $3, %%edi \n" // add edi, 3 " dec %%ecx \n" // dec ecx " jnz hLlop24 \n" " pop %%es \n" // pop es : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "m" (colour), "b" (x1), // %2, %3 "c" (x2), "d" (x1), "a" (ScreenSelector) // %4, %5 ); break; case 32: __asm__ __volatile__( " push %%es \n" // push es " mov %%dx, %%es \n" // mov es, dx " sub %%ebx, %%ecx \n" // sub ecx, ebx " add %%esi, %%edi \n" // add edi, esi " inc %%ecx \n" " shl $2, %%ebx \n" // shl ebx, 2 " add %%ebx, %%edi \n" // add edi, ebx " rep \n" " stosl \n" " pop %%es \n" // pop es : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "a" (colour), "b" (x1), // %2, %3 "c" (x2), "d" (ScreenSelector) // %4, %5 ); break; } // switch return; } // ogDisplay_VESA::ogHLine bool ogDisplay_VESA::ogLoadPal(const char *palfile) { bool result; if ((result = ogSurface::ogLoadPal(palfile))==true) setPal(); return result; } // ogDisplay_VESA::ogLoadPal void ogDisplay_VESA::ogSetPixel(int32 x, int32 y, uInt32 colour) { if (!ogAvail()) return; if (((uInt32)x>maxX) || ((uInt32)y>maxY)) return; switch (BPP) { case 8: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" " mov %4, %%dx \n" " mov %%dx, %%ds \n" " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%al, (%%edi) \n" // mov [edi], al " pop %%ds\n" : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), "m" (ScreenSelector) // %2, %3, %4 ); break; case 15: case 16: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" " mov %4, %%dx \n" " mov %%dx, %%ds \n" " add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size} " add %%esi, %%edi \n" // add edi, esi " mov %3, %%eax \n" // mov eax, colour " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%ax, (%%edi) \n" // mov [edi], al " pop %%ds\n" : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), "m" (ScreenSelector) // %2, %3, %4 ); break; case 24: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" // push ds " mov %4, %%dx \n" // mov dx, ScreenSelector " mov %%dx, %%ds \n" // mov ds, dx " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx " add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size} " add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size} // { Draw the pixel } " mov %%ax, (%%edi) \n" // mov [edi], ax " shr $16, %%eax \n" // shr eax, 16 " mov %%al, 2(%%edi)\n" // mov [edi+2],al " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), "m" (ScreenSelector) // %2, %3, %4 ); break; case 32: __asm__ __volatile__( // { Calculate offset, prepare the pixel to be drawn } " push %%ds \n" // push ds " mov %4, %%dx \n" // mov dx, ScreenSelector " mov %%dx, %%ds \n" // mov ds, dx " shl $2, %%ecx \n" // shl eax, 2 {adjust for pixel size} " add %%esi, %%edi \n" // add edi, esi " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%eax, (%%edi)\n" // mov [edi], eax " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y]), // %0, %1 "c" (x), "a" (colour), "m" (ScreenSelector) // %2, %3, %4 ); } // switch return; } // ogDisplay_VESA::ogSetPixel void ogDisplay_VESA::ogSetRGBPalette(uInt8 colour, uInt8 red, uInt8 green, uInt8 blue) { if (pal==NULL) return; ogSurface::ogSetRGBPalette(colour,red,green,blue); outportb(0x3c8,colour); outportb(0x3c9,red >> 2); outportb(0x3c9,green >> 2); outportb(0x3c9,blue >> 2); return; } // ogDisplay_VESA::ogSetRGBPalette void ogDisplay_VESA::ogVFlip(void) { if (!ogAvail()) return; switch (BPP) { case 8: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax " add %%edi, %%esi \n" // add esi, edi "vf8lop: \n" " push %%esi \n" // push esi " push %%edi \n" // push edi "vf8lop2: \n" " mov (%%edi),%%al \n" // mov al, [edi] " mov (%%esi),%%ah \n" // mov ah, [esi] " mov %%al,(%%esi) \n" // mov [esi], al " mov %%ah,(%%edi) \n" // mov [edi], ah " inc %%edi \n" // inc edi " dec %%esi \n" // dec esi " cmp %%esi, %%edi \n" // cmp edi, esi " jbe vf8lop2 \n" " pop %%edi \n" // pop edi " pop %%esi \n" // pop esi " add %%ebx, %%esi \n" // add esi, ebx " add %%ebx, %%edi \n" // add edi, ebx " dec %%edx \n" " jnz vf8lop \n" " pop %%ds \n" // pop ds : : "D" ((char *)buffer+lineOfs[0]), "S" (maxX), // %0, %1 "b" (xRes), "d" (maxY+1), "a" (ScreenSelector) // %2, %3, %4 ); break; case 15: case 16: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax " add %%edi, %%esi \n" // add esi, edi "vf16lop: \n" " push %%esi \n" // push esi " push %%edi \n" // push edi "vf16lop2: \n" " mov (%%edi),%%ax \n" // mov ax, [edi] " mov (%%esi),%%cx \n" // mov cx, [esi] " mov %%ax,(%%esi) \n" // mov [esi], ax " mov %%cx,(%%edi) \n" // mov [edi], cx " add $2, %%edi \n" // add edi, 2 " sub $2, %%esi \n" // sub esi, 2 " cmp %%esi, %%edi \n" // cmp edi, esi " jbe vf16lop2 \n" " pop %%edi \n" // pop edi " pop %%esi \n" // pop esi " add %%ebx, %%esi \n" // add esi, ebx " add %%ebx, %%edi \n" // add edi, ebx " dec %%edx \n" " jnz vf16lop \n" " pop %%ds \n" // pop ds : : "D" ((char *)buffer+lineOfs[0]), "S" (maxX*2), // %0, %1 "b" (xRes), "d" (maxY+1), "a" (ScreenSelector) // %2, %3, %4 ); break; case 24: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax " add %%edi, %%esi \n" // add esi, edi "vf24lop: \n" " push %%esi \n" // push esi " push %%edi \n" // push edi "vf24lop2: \n" " mov (%%edi),%%ax \n" // mov ax, [edi] " mov 2(%%edi),%%dl \n" // mov dl, [edi+2] " mov (%%esi),%%cx \n" // mov cx, [esi] " mov 2(%%esi),%%dh \n" // mov dh, [esi+2] " mov %%ax,(%%esi) \n" // mov [esi], ax " mov %%dl,2(%%esi) \n" // mov [esi+2], dl " mov %%cx,(%%edi) \n" // mov [edi], cx " mov %%dh,2(%%edi) \n" // mov [edi+2], dh " add $3, %%edi \n" // add edi, 3 " sub $3, %%esi \n" // sub esi, 3 " cmp %%esi, %%edi \n" // cmp edi, esi " jbe vf24lop2 \n" " pop %%edi \n" // pop edi " pop %%esi \n" // pop esi " add %%ebx, %%esi \n" // add esi, ebx " add %%ebx, %%edi \n" // add edi, ebx " decl %3 \n" // dec height " jnz vf24lop \n" " pop %%ds \n" // pop ds : : "D" ((char *)buffer+lineOfs[0]), "S" (maxX*3), // %0, %1 "b" (xRes), "d" (maxY+1), "a" (ScreenSelector) // %2, %3, %4 ); break; case 32: __asm__ __volatile__( " push %%ds \n" // push ds " mov %%ax, %%ds \n" // mov ds, ax " add %%edi, %%esi \n" // add esi, edi "vf32lop: \n" " push %%esi \n" // push esi " push %%edi \n" // push edi "vf32lop2: \n" " mov (%%edi),%%eax \n" // mov eax, [edi] " mov (%%esi),%%ecx \n" // mov ecx, [esi] " mov %%eax,(%%esi) \n" // mov [esi], eax " mov %%ecx,(%%edi) \n" // mov [edi], ecx " add $4, %%edi \n" // add edi, 4 " sub $4, %%esi \n" // sub esi, 4 " cmp %%esi, %%edi \n" // cmp edi, esi " jbe vf32lop2 \n" " pop %%edi \n" // pop edi " pop %%esi \n" // pop esi " add %%ebx, %%esi \n" // add esi, ebx " add %%ebx, %%edi \n" // add edi, ebx " dec %%edx \n" " jnz vf32lop \n" " pop %%ds \n" // pop ds : : "D" ((char *)buffer+lineOfs[0]), "S" (maxX*4), // %0, %1 "b" (xRes), "d" (maxY+1), "a" (ScreenSelector) // %2, %3, %4 ); } // switch return; } // ogDisplay_VESA::ogVFlip void ogDisplay_VESA::ogVLine(int32 x, int32 y1, int32 y2, uInt32 colour) { int32 tmp; if (!ogAvail()) return; if ((uInt32)x>maxX) return; if (y1>y2) { tmp= y1; y1 = y2; y2 = tmp; } // if if (y1<0) y1 = 0; if (y2>(int32)maxY) y2 = maxY; if (y2<y1) return; switch (BPP) { case 8: __asm__ __volatile__( " push %%ds \n" // push ds " add %%esi, %%edi \n" // add edi, esi " mov %7, %%si \n" // mov si, ScreenSelector " mov %%si, %%ds \n" // mov ds, si " mov %6, %%esi \n" // mov esi, y1 " sub %%esi, %%ecx \n" // sub ecx, esi " add %%ebx, %%edi \n" // add edi, ebx " mov %2, %%eax \n" // mov eax, colour " inc %%ecx \n" // inc ecx "vLlop8: \n" " mov %%al, (%%edi) \n" // mov [edi], al " add %%edx, %%edi \n" // add edi, edx " dec %%ecx \n" // dec ecx " jnz vLlop8 \n" " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y1]), // %0, %1 "m" (colour), "b" (x), // %2, %3 "c" (y2), "d" (xRes), // %4, %5 "m" (y1), "m" (ScreenSelector) // %6, %7 ); break; case 15: case 16: __asm__ __volatile__( " push %%ds \n" // push ds " add %%esi, %%edi \n" // add edi, esi " add %%ebx, %%ebx \n" // add ebx, ebx - pix size " mov %7, %%si \n" // mov si, ScreenSelector " mov %%si, %%ds \n" // mov ds, si " mov %6, %%esi \n" // mov esi, y1 " sub %%esi, %%ecx \n" // sub ecx, esi " add %%ebx, %%edi \n" // add edi, ebx " mov %2, %%eax \n" // mov eax, colour " inc %%ecx \n" // inc ecx "vLlop16: \n" " mov %%ax, (%%edi) \n" // mov [edi], ax " add %%edx, %%edi \n" // add edi, edx " dec %%ecx \n" // dec ecx " jnz vLlop16 \n" " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y1]), // %0, %1 "m" (colour), "b" (x), // %2, %3 "c" (y2), "d" (xRes), // %4, %5 "m" (y1), "m" (ScreenSelector) // %6, %7 ); break; case 24: __asm__ __volatile__( " push %%ds \n" // push ds " add %%esi, %%edi \n" // add edi, esi " mov %%ebx, %%esi \n" // mov esi, ebx - pix size " add %%ebx, %%ebx \n" // add ebx, ebx - pix size " add %%esi, %%ebx \n" // add ebx, esi - pix size " mov %7, %%si \n" // mov si, ScreenSelector " mov %%si, %%ds \n" // mov ds, si " mov %6, %%esi \n" // mov esi, y1 " sub %%esi, %%ecx \n" // sub ecx, esi " add %%ebx, %%edi \n" // add edi, ebx " mov %2, %%eax \n" // mov eax, colour " inc %%ecx \n" // inc ecx " mov %%eax, %%ebx \n" // mov ebx, eax " shr $16, %%ebx \n" // shr ebx, 16 "vLlop24: \n" " mov %%ax, (%%edi) \n" // mov [edi], eax " mov %%bl, 2(%%edi)\n" // mov [edi+2], bl " add %%edx, %%edi \n" // add edi, edx " dec %%ecx \n" // dec ecx " jnz vLlop24 \n" " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y1]), // %0, %1 "m" (colour), "b" (x), // %2, %3 "c" (y2), "d" (xRes), // %4, %5 "m" (y1), "m" (ScreenSelector) // %6, %7 ); break; case 32: __asm__ __volatile__( " push %%ds \n" // push ds " add %%esi, %%edi \n" // add edi, esi " shl $2, %%ebx \n" // shl ebx, 2 - pix size " mov %7, %%si \n" // mov si, ScreenSelector " mov %%si, %%ds \n" // mov ds, si " mov %6, %%esi \n" // mov esi, y1 " sub %%esi, %%ecx \n" // sub ecx, esi " add %%ebx, %%edi \n" // add edi, ebx " mov %2, %%eax \n" // mov eax, colour " inc %%ecx \n" // inc ecx "vLlop32: \n" " mov %%eax, (%%edi)\n" // mov [edi],al " add %%edx, %%edi \n" // add edi, edx " dec %%ecx \n" // dec ecx " jnz vLlop32 \n" " pop %%ds \n" // pop ds : : "D" (buffer), "S" (lineOfs[y1]), // %0, %1 "m" (colour), "b" (x), // %2, %3 "c" (y2), "d" (xRes), // %4, %5 "m" (y1), "m" (ScreenSelector) // %6, %7 ); } // switch return; } // ogDisplay_VESA::ogVLine ogDisplay_VESA::~ogDisplay_VESA(void) { __dpmi_regs regs; if (VESARec!=NULL) delete VESARec; if (ModeRec!=NULL) delete ModeRec; if (InGraphics == true) { regs.x.ax = 3; __dpmi_int(0x10, ®s); } // if InGraphics return; }