]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/modex16.c
replace inline asm with _fmemcpy to copy ROM font char.
[16.git] / src / lib / modex16.c
index 810fc73beb5e0106b7e630975c117b7d57a301c9..20c468e2372a2750bd37b33a977ce93b26eecd9c 100755 (executable)
@@ -1,11 +1,11 @@
 /* Project 16 Source Code~\r
- * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669\r
+ * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669\r
  *\r
  * This file is part of Project 16.\r
  *\r
  * Project 16 is free software; you can redistribute it and/or modify\r
  * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 3 of the License, or\r
+ * the Free Software Foundation; either verson 3 of the License, or\r
  * (at your option) any later version.\r
  *\r
  * Project 16 is distributed in the hope that it will be useful,\r
@@ -35,7 +35,7 @@ static byte tmppal[PAL_SIZE];
 // setvideo() - This function Manages the video modes                                                                                          //\r
 //                                                                                                                                                                                                                                             //\r
 /////////////////////////////////////////////////////////////////////////////\r
-void VGAmodeX(sword vq, global_game_variables_t *gv)\r
+void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv)\r
 {\r
        union REGS in, out;\r
 \r
@@ -54,7 +54,7 @@ void VGAmodeX(sword vq, global_game_variables_t *gv)
                        //int86(0x10, &in, &out);\r
                        gv->video.old_mode = vgaGetMode();//out.h.al;\r
                        // enter mode\r
-                       modexEnter(vq, gv);\r
+                       modexEnter(vq, cmem, gv);\r
                break;\r
        }\r
 }\r
@@ -62,11 +62,7 @@ void VGAmodeX(sword vq, global_game_variables_t *gv)
 static void\r
 vgaSetMode(byte mode)\r
 {\r
-  union REGS regs;\r
-\r
-  regs.h.ah = SET_MODE;\r
-  regs.h.al = mode;\r
-  int86(VIDEO_INT, &regs, &regs);\r
+  int10_setmode(mode);\r
 }\r
 \r
 //---------------------------------------------------\r
@@ -74,113 +70,79 @@ vgaSetMode(byte mode)
 // Use the bios to get the current video mode\r
 //\r
 \r
-long\r
+byte/*FIXME: why long? "long" is 32-bit datatype, VGA modes are 8-bit numbers. */\r
 vgaGetMode()\r
 {\r
-    union REGS rg;\r
-\r
-    rg.h.ah = 0x0f;\r
-    int86(VIDEO_INT, &rg, &rg);\r
-\r
-    return rg.h.al;\r
+    return int10_getmode();\r
 }\r
 \r
 /* -========================= Entry  Points ==========================- */\r
-void\r
-modexEnter(sword vq, global_game_variables_t *gv)\r
+void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)\r
 {\r
        word i;\r
-       dword far*ptr=(dword far*)VGA;      /* used for faster screen clearing */\r
+       struct vga_mode_params cm;\r
        int CRTParmCount;\r
-       /* common mode X initiation stuff~ */\r
-       modexsetBaseXMode(gv->video.page);\r
+\r
+       vgaSetMode(VGA_256_COLOR_MODE);\r
+       vga_enable_256color_modex();\r
+       update_state_from_vga();\r
+       vga_read_crtc_mode(&cm);\r
 \r
        switch(vq)\r
        {\r
                case 1:\r
-                       CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
-                       /* width and height */\r
-                       gv->video.page[0].sw=320;\r
-                       gv->video.page[0].sh=240;\r
-\r
-                       /* send the CRTParms */\r
-                       for(i=0; i<CRTParmCount; i++) {\r
-                               outpw(CRTC_INDEX, ModeX_320x240regs[i]);\r
-                       }\r
-\r
-                       /* clear video memory */\r
-                       outpw(SC_INDEX, 0x0f02);\r
-                       for(i=0; i<0x8000; i++) {\r
-                               ptr[i] = 0x0000;\r
-                       }\r
-               break;\r
-               case 2:\r
-                       CRTParmCount = sizeof(ModeX_160x120regs) / sizeof(ModeX_160x120regs[0]);\r
-                       /* width and height */\r
-                       gv->video.page[0].sw=120;\r
-                       gv->video.page[0].sh=160;\r
-\r
-                       /* send the CRTParms */\r
-                       for(i=0; i<CRTParmCount; i++) {\r
-                               outpw(CRTC_INDEX, ModeX_160x120regs[i]);\r
-                       }\r
-\r
-                       /* clear video memory */\r
-                       outpw(SC_INDEX, 0x0f02);\r
-                       for(i=0; i<0x8000; i++) {\r
-                               ptr[i] = 0x0000;\r
-                       }\r
-               break;\r
-               case 3:\r
-                       CRTParmCount = sizeof(ModeX_320x200regs) / sizeof(ModeX_320x200regs[0]);\r
-                       /* width and height */\r
-                       gv->video.page[0].sw=320;\r
-                       gv->video.page[0].sh=200;\r
-\r
-                       /* send the CRTParms */\r
-                       for(i=0; i<CRTParmCount; i++) {\r
-                               outpw(CRTC_INDEX, ModeX_320x200regs[i]);\r
-                       }\r
-\r
-                       /* clear video memory */\r
-                       outpw(SC_INDEX, 0x0f02);\r
-                       for(i=0; i<0x8000; i++) {\r
-                               ptr[i] = 0x0000;\r
-                       }\r
-               break;\r
-               case 4:\r
-                       CRTParmCount = sizeof(ModeX_192x144regs) / sizeof(ModeX_192x144regs[0]);\r
-                       /* width and height */\r
-                       gv->video.page[0].sw=192;\r
-                       gv->video.page[0].sh=144;\r
-\r
-                       /* send the CRTParms */\r
-                       for(i=0; i<CRTParmCount; i++) {\r
-                               outpw(CRTC_INDEX, ModeX_192x144regs[i]);\r
-                       }\r
-\r
-                       /* clear video memory */\r
-                       outpw(SC_INDEX, 0x0f02);\r
-                       for(i=0; i<0x8000; i++) {\r
-                               ptr[i] = 0x0000;\r
-                       }\r
-               break;\r
-               case 5:\r
-                       CRTParmCount = sizeof(ModeX_256x192regs) / sizeof(ModeX_256x192regs[0]);\r
+                       //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
                        /* width and height */\r
-                       gv->video.page[0].sw=256;\r
-                       gv->video.page[0].sh=192;\r
+                       gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this\r
+                       gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this\r
+\r
+                       // mode X BYTE mode\r
+                       cm.word_mode = 0;\r
+                       cm.dword_mode = 0;\r
+                       // 320x240 mode 60Hz\r
+                       cm.horizontal_total=0x5f + 5; /* CRTC[0]             -5 */\r
+                       cm.horizontal_display_end=0x4f + 1; /* CRTC[1]       -1 */\r
+                       cm.horizontal_blank_start=0x50 + 1; /* CRTC[2] */\r
+                       cm.horizontal_blank_end=0x82 + 1;   /* CRTC[3] bit 0-4 & CRTC[5] bit 7 */\r
+                       cm.horizontal_start_retrace=0x54;/* CRTC[4] */\r
+                       cm.horizontal_end_retrace=0x80; /* CRTC[5] bit 0-4 */\r
+                       //cm.horizontal_start_delay_after_total=0x3e; /* CRTC[3] bit 5-6 */\r
+                       //cm.horizontal_start_delay_after_retrace=0x41; /* CRTC[5] bit 5-6 */\r
+                       cm.vertical_total = 0x20D + 2;\r
+                       cm.vertical_start_retrace = 0x1EA;\r
+                       cm.vertical_end_retrace = 0x1EC;\r
+                       cm.vertical_display_end = 480;\r
+                       cm.vertical_blank_start = 0x1E7 + 1;\r
+                       cm.vertical_blank_end = 0x206 + 1;\r
+                       cm.clock_select = 0; /* misc register = 0xE3  25MHz */\r
+                       cm.vsync_neg = 1;\r
+                       cm.hsync_neg = 1;\r
+                       cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)\r
+                       break;\r
+               case 2: // TODO: 160x120 according to ModeX_160x120regs\r
+                       return;\r
+               case 3: // TODO: 160x120 according to ModeX_320x200regs\r
+                       return;\r
+               case 4: // TODO: 160x120 according to ModeX_192x144regs\r
+                       return;\r
+               case 5: // TODO: 160x120 according to ModeX_256x192regs\r
+                       return;\r
+               default:\r
+                       return;\r
+       }\r
 \r
-                       /* send the CRTParms */\r
-                       for(i=0; i<CRTParmCount; i++) {\r
-                               outpw(CRTC_INDEX, ModeX_256x192regs[i]);\r
-                       }\r
+       vga_state.vga_stride = cm.offset * 2;\r
+       vga_write_crtc_mode(&cm,0);\r
 \r
+       /* clear video memory */\r
+       switch (cmem)\r
+       {\r
+               case 1: {\r
                        /* clear video memory */\r
-                       outpw(SC_INDEX, 0x0f02);\r
-                       for(i=0; i<0x8000; i++) {\r
-                               ptr[i] = 0x0000;\r
-                       }\r
+                       dword far*ptr=(dword far*)vga_state.vga_graphics_ram;//VGA;      /* used for faster screen clearing */\r
+                       vga_write_sequencer(2/*map mask register*/,0xf/*all 4 planes*/);\r
+                       for(i = 0;i < 0x4000; i++) ptr[i] = 0x0000; // 0x4000 x dword = 64KB\r
+               }\r
                break;\r
        }\r
        gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;\r
@@ -193,39 +155,8 @@ modexEnter(sword vq, global_game_variables_t *gv)
 \r
 void\r
 modexLeave() {\r
-    /* TODO restore original mode and palette */\r
-    vgaSetMode(TEXT_MODE);\r
-}\r
-\r
-//    setBaseXMode() does the initialization to make the VGA ready to\r
-//    accept any combination of configuration register settings.  This\r
-//    involves enabling writes to index 0 to 7 of the CRT controller (port\r
-//    0x3D4), by clearing the most significant bit (bit 7) of index 0x11.\r
-void\r
-modexsetBaseXMode(page_t *page)\r
-{\r
-       word temp;\r
-       /* TODO save current video mode and palette */\r
-       vgaSetMode(VGA_256_COLOR_MODE);\r
-\r
-       /* disable chain4 mode */\r
-       outpw(SC_INDEX, 0x0604);\r
-\r
-       /* synchronous reset while setting Misc Output */\r
-       outpw(SC_INDEX, 0x0100);\r
-\r
-       /* select 25 MHz dot clock & 60 Hz scanning rate */\r
-       outp(MISC_OUTPUT, 0xe3);\r
-\r
-       /* undo reset (restart sequencer) */\r
-       outpw(SC_INDEX, 0x0300);\r
-\r
-       /* reprogram the CRT controller */\r
-       outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */\r
-//     temp = inp(CRTC_DATA) & 0x7F;\r
-//     outp(CRTC_INDEX, 0x11);\r
-       outp(CRTC_DATA, 0x7f);  /* get current write protect on varios regs */\r
-//     outp(CRTC_DATA, temp);  /* get current write protect on varios regs */\r
+       /* TODO restore original mode and palette */\r
+       vgaSetMode(TEXT_MODE);\r
 }\r
 \r
 page_t\r
@@ -234,7 +165,7 @@ modexDefaultPage(page_t *p)
     page_t page;\r
 \r
     /* default page values */\r
-    page.data = VGA;\r
+    page.data = vga_state.vga_graphics_ram;//VGA;\r
     page.dx = 0;\r
     page.dy = 0;\r
        page.sw = p->sw;\r
@@ -394,402 +325,7 @@ modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {
     }\r
 }\r
 \r
-//TODO! ADD CLIPPING!!\r
-//memory management needs to be added\r
-//void\r
-//modexDrawBmpRegion   (page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp)\r
-void modexDrawPBufRegion       (page_t *page, int x, int y, int rx, int ry, int rw, int rh, planar_buf_t *p, boolean sprite)\r
-{\r
-       sword plane;\r
-       int i;\r
-       const int px=x;//-page->dx;\r
-       const int py=y;//-page->dy;\r
-       #define PEEE ((rw)/4)-rx\r
-       //-(rx/4)\r
-       #define PEEEE ((p->pwidth)*(ry))\r
-       //y=py;\r
-       //x=px;\r
-       //printf("%d,%d p(%d,%d) r(%d,%d) rwh(%d,%d)\n", x, y, px, py, rx, ry, rw, rh);\r
-       for(plane=0; plane < 4; plane++) {\r
-               i=PEEE+PEEEE;\r
-               //printf("PEEE=%d ", PEEE);\r
-               //printf("PEEEE=%d ", PEEEE);\r
-               //printf("i=%d\n", i);\r
-               modexSelectPlane(PLANE(plane+x));\r
-               for(; y < py+rh; y++) {\r
-                       //for(px=0; px < p->width; px++) {\r
-                               //printf("%02X ", (int) p->plane[plane][i++]);\r
-//                           _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
-//                           printf("buff %u==%s\n", y, *buff);\r
-                               _fmemcpy(page->data + (((page->width/4) * y) + (x / 4)), &(p->plane[plane][i+=p->pwidth]), (rw/4));\r
-                       //}\r
-                       //if(plane==3) IN_Ack();\r
-               }\r
-               /*printf("y%d=%d ", plane, y);\r
-               if(plane==3) printf("y%d=%d\n", plane, y);*/\r
-               x=px;\r
-               y=py;\r
-               }\r
-}\r
-\r
-\r
-/*temp*/\r
-void\r
-modexDrawPBuf(page_t *page, int x, int y, planar_buf_t *p, boolean sprite)\r
-{\r
-       int plane;\r
-       int i;\r
-//     byte near *buff;\r
-       const int px=x+page->dx;\r
-       const int py=y+page->dy;\r
-       x=px;\r
-       y=py;\r
-//     buff = _nmalloc(p->pwidth+1);\r
-       // TODO Make this fast.  It's SLOOOOOOW\r
-//     for(plane=0; plane < 4; plane++) {\r
-//             i=0;\r
-//             modexSelectPlane(PLANE(plane+x));\r
-//             for(px = plane; px < p->width; px+=4) {\r
-//                     offset=px;\r
-//                     for(py=0; py<p->height/2; py++) {\r
-//                             //SELECT_ALL_PLANES();\r
-//                             if(!sprite || p->plane[offset])\r
-//                                     page->data = &(p->plane[offset][i++]);\r
-//                             offset+=p->width;\r
-//                             offset++;\r
-//                     }\r
-//             }\r
-//     }\r
-       for(plane=0; plane < 4; plane++) {\r
-               i=0;\r
-               modexSelectPlane(PLANE(plane+x));\r
-               for(; y < py+p->height; y++) {\r
-                       //for(px=0; px < p->width; px++) {\r
-                               //printf("%02X ", (int) p->plane[plane][i++]);\r
-//                             _fmemcpy(buff, &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
-//                             printf("buff %u==%s\n", y, *buff);\r
-//                             _fmemcpy(page->data + (((page->width/4) * (y+page->dy)) + ((x+page->dx) / 4)), buff, p->pwidth);\r
-                               _fmemcpy(page->data + (((page->width/4) * y) + (x / 4)), &(p->plane[plane][i+=p->pwidth]), p->pwidth);\r
-                       //}\r
-               }\r
-               x=px;\r
-               y=py;\r
-       }\r
-//     _nfree(buff);\r
-}\r
-\r
-void\r
-oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
-{\r
-       byte plane;\r
-       word px, py;\r
-       word offset;\r
-\r
-       /* TODO Make this fast.  It's SLOOOOOOW */\r
-       for(plane=0; plane < 4; plane++) {\r
-               modexSelectPlane(PLANE(plane+x));\r
-               for(px = plane; px < bmp->width; px+=4) {\r
-                       offset=px;\r
-                       for(py=0; py<bmp->height; py++) {\r
-                       if(!sprite || bmp->data[offset])\r
-                               page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
-                       offset+=bmp->width;\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-//* normal versions *//\r
-void\r
-modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
-    /* draw the region (the entire freakin bitmap) */\r
-    modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-void\r
-modexDrawBmpRegion(page_t *page, int x, int y,\r
-                  int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
-       word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
-       byte *data = bmp->data;//+bmp->offset;\r
-       word bmpOffset = (word) data + ry * bmp->width + rx;\r
-       word width = rw;\r
-       word height = rh;\r
-       byte plane = 1 << ((byte) x & 0x03);\r
-       word scanCount = width/4 + (width%4 ? 1 :0);\r
-       word nextPageRow = page->width/4 - scanCount;\r
-       word nextBmpRow = (word) bmp->width - width;\r
-       word rowCounter;\r
-       byte planeCounter = 4;\r
-\r
-    __asm {\r
-               MOV AX, SCREEN_SEG      ; go to the VGA memory\r
-               MOV ES, AX\r
-\r
-               MOV DX, SC_INDEX        ; point at the map mask register\r
-               MOV AL, MAP_MASK        ;\r
-               OUT DX, AL            ;\r
-\r
-       PLANE_LOOP:\r
-               MOV DX, SC_DATA  ; select the current plane\r
-               MOV AL, plane      ;\r
-               OUT DX, AL            ;\r
-\r
-               ;-- begin plane painting\r
-               MOV AX, height    ; start the row counter\r
-               MOV rowCounter, AX      ;\r
-               MOV DI, poffset  ; go to the first pixel\r
-               MOV SI, bmpOffset       ; go to the bmp pixel\r
-       ROW_LOOP:\r
-               MOV CX, width      ; count the columns\r
-       SCAN_LOOP:\r
-               MOVSB              ; copy the pixel\r
-               SUB CX, 3              ; we skip the next 3\r
-               ADD SI, 3              ; skip the bmp pixels\r
-               LOOP SCAN_LOOP    ; finish the scan\r
-\r
-               MOV AX, nextPageRow\r
-               ADD DI, AX            ; go to the next row on screen\r
-               MOV AX, nextBmpRow\r
-               ADD SI, AX            ; go to the next row on bmp\r
-\r
-               DEC rowCounter\r
-               JNZ ROW_LOOP        ; do all the rows\r
-               ;-- end plane painting\r
-               MOV AL, plane      ; advance to the next plane\r
-               SHL AL, 1              ;\r
-               AND AL, 0x0f        ; mask the plane properly\r
-               MOV plane, AL      ; store the plane\r
-\r
-               INC bmpOffset      ; start bmp at the right spot\r
-\r
-               DEC planeCounter\r
-               JNZ PLANE_LOOP    ; do all 4 planes\r
-    }\r
-}\r
-\r
-void\r
-modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
-    /* draw the whole sprite */\r
-    modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-void\r
-modexDrawSpriteRegion(page_t *page, int x, int y,\r
-                     int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
-       word poffset = (word)page->data + y*(page->width/4) + x/4;\r
-       byte *data = bmp->data;//+bmp->offset;\r
-       word bmpOffset = (word) data + ry * bmp->width + rx;\r
-       word width = rw;\r
-       word height = rh;\r
-       byte plane = 1 << ((byte) x & 0x03);\r
-       word scanCount = width/4 + (width%4 ? 1 :0);\r
-       word nextPageRow = page->width/4 - scanCount;\r
-       word nextBmpRow = (word) bmp->width - width;\r
-       word rowCounter;\r
-       byte planeCounter = 4;\r
-\r
-    __asm {\r
-               MOV AX, SCREEN_SEG      ; go to the VGA memory\r
-               MOV ES, AX\r
-\r
-               MOV DX, SC_INDEX        ; point at the map mask register\r
-               MOV AL, MAP_MASK        ;\r
-               OUT DX, AL            ;\r
-\r
-       PLANE_LOOP:\r
-               MOV DX, SC_DATA  ; select the current plane\r
-               MOV AL, plane      ;\r
-               OUT DX, AL            ;\r
-\r
-               ;-- begin plane painting\r
-               MOV AX, height    ; start the row counter\r
-               MOV rowCounter, AX      ;\r
-               MOV DI, poffset  ; go to the first pixel\r
-               MOV SI, bmpOffset       ; go to the bmp pixel\r
-       ROW_LOOP:\r
-               MOV CX, width      ; count the columns\r
-       SCAN_LOOP:\r
-               LODSB\r
-               DEC SI\r
-               CMP AL, 0\r
-               JNE DRAW_PIXEL    ; draw non-zero pixels\r
-\r
-               INC DI            ; skip the transparent pixel\r
-               ADD SI, 1\r
-               JMP NEXT_PIXEL\r
-       DRAW_PIXEL:\r
-               MOVSB              ; copy the pixel\r
-       NEXT_PIXEL:\r
-               SUB CX, 3              ; we skip the next 3\r
-               ADD SI, 3              ; skip the bmp pixels\r
-               LOOP SCAN_LOOP    ; finish the scan\r
-\r
-               MOV AX, nextPageRow\r
-               ADD DI, AX            ; go to the next row on screen\r
-               MOV AX, nextBmpRow\r
-               ADD SI, AX            ; go to the next row on bmp\r
-\r
-               DEC rowCounter\r
-               JNZ ROW_LOOP        ; do all the rows\r
-               ;-- end plane painting\r
-\r
-               MOV AL, plane      ; advance to the next plane\r
-               SHL AL, 1              ;\r
-               AND AL, 0x0f        ; mask the plane properly\r
-               MOV plane, AL      ; store the plane\r
-\r
-               INC bmpOffset      ; start bmp at the right spot\r
-\r
-               DEC planeCounter\r
-               JNZ PLANE_LOOP    ; do all 4 planes\r
-    }\r
-}\r
-\r
-//* planar buffer versions *//\r
-void\r
-modexDrawBmpPBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
-    /* draw the region (the entire freakin bitmap) */\r
-    modexDrawBmpPBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-void\r
-modexDrawBmpPBufRegion(page_t *page, int x, int y,\r
-                  int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
-       word poffset = (word) page->data  + y*(page->width/4) + x/4;\r
-       byte *data = *bmp->plane;//+bmp->offset;\r
-       word bmpOffset = (word) data + ry * bmp->width + rx;\r
-       word width = rw/4;\r
-       word height = rh/4;\r
-       byte plane = 1 << ((byte) x & 0x03);\r
-       word scanCount = width/4 + (width%4 ? 1 :0);\r
-       word nextPageRow = page->width/4 - scanCount;\r
-       word nextBmpRow = (word) bmp->width - width;\r
-       word rowCounter;\r
-       byte planeCounter = 4;\r
-\r
-    __asm {\r
-               MOV AX, SCREEN_SEG      ; go to the VGA memory\r
-               MOV ES, AX\r
-\r
-               MOV DX, SC_INDEX        ; point at the map mask register\r
-               MOV AL, MAP_MASK        ;\r
-               OUT DX, AL            ;\r
-\r
-       PLANE_LOOP:\r
-               MOV DX, SC_DATA  ; select the current plane\r
-               MOV AL, plane      ;\r
-               OUT DX, AL            ;\r
-\r
-               ;-- begin plane painting\r
-               MOV AX, height    ; start the row counter\r
-               MOV rowCounter, AX      ;\r
-               MOV DI, poffset  ; go to the first pixel\r
-               MOV SI, bmpOffset       ; go to the bmp pixel\r
-       ROW_LOOP:\r
-               MOV CX, width      ; count the columns\r
-       SCAN_LOOP:\r
-               MOVSB              ; copy the pixel\r
-               SUB CX, 3              ; we skip the next 3\r
-               ADD SI, 3              ; skip the bmp pixels\r
-               LOOP SCAN_LOOP    ; finish the scan\r
-\r
-               MOV AX, nextPageRow\r
-               ADD DI, AX            ; go to the next row on screen\r
-               MOV AX, nextBmpRow\r
-               ADD SI, AX            ; go to the next row on bmp\r
-\r
-               DEC rowCounter\r
-               JNZ ROW_LOOP        ; do all the rows\r
-               ;-- end plane painting\r
-               MOV AL, plane      ; advance to the next plane\r
-               SHL AL, 1              ;\r
-               AND AL, 0x0f        ; mask the plane properly\r
-               MOV plane, AL      ; store the plane\r
-\r
-               INC bmpOffset      ; start bmp at the right spot\r
-\r
-               DEC planeCounter\r
-               JNZ PLANE_LOOP    ; do all 4 planes\r
-    }\r
-}\r
-\r
-void\r
-modexDrawSpritePBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
-    /* draw the whole sprite */\r
-    modexDrawSpritePBufRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-void\r
-modexDrawSpritePBufRegion(page_t *page, int x, int y,\r
-                     int rx, int ry, int rw, int rh, planar_buf_t *bmp) {\r
-       word poffset = (word)page->data + y*(page->width/4) + x/4;\r
-       byte *data = *bmp->plane;//+bmp->offset;\r
-       word bmpOffset = (word) data + ry * bmp->width + rx;\r
-       word width = rw/4;\r
-       word height = rh/4;\r
-       byte plane = 1 << ((byte) x & 0x03);\r
-       word scanCount = width/4 + (width%4 ? 1 :0);\r
-       word nextPageRow = page->width/4 - scanCount;\r
-       word nextBmpRow = (word) bmp->width - width;\r
-       word rowCounter;\r
-       byte planeCounter = 4;\r
-\r
-    __asm {\r
-               MOV AX, SCREEN_SEG      ; go to the VGA memory\r
-               MOV ES, AX\r
-\r
-               MOV DX, SC_INDEX        ; point at the map mask register\r
-               MOV AL, MAP_MASK        ;\r
-               OUT DX, AL            ;\r
-\r
-       PLANE_LOOP:\r
-               MOV DX, SC_DATA  ; select the current plane\r
-               MOV AL, plane      ;\r
-               OUT DX, AL            ;\r
-\r
-               ;-- begin plane painting\r
-               MOV AX, height    ; start the row counter\r
-               MOV rowCounter, AX      ;\r
-               MOV DI, poffset  ; go to the first pixel\r
-               MOV SI, bmpOffset       ; go to the bmp pixel\r
-       ROW_LOOP:\r
-               MOV CX, width      ; count the columns\r
-       SCAN_LOOP:\r
-               LODSB\r
-               DEC SI\r
-               CMP AL, 0\r
-               JNE DRAW_PIXEL    ; draw non-zero pixels\r
-\r
-               INC DI            ; skip the transparent pixel\r
-               ADD SI, 1\r
-               JMP NEXT_PIXEL\r
-       DRAW_PIXEL:\r
-               MOVSB              ; copy the pixel\r
-       NEXT_PIXEL:\r
-               SUB CX, 3              ; we skip the next 3\r
-               ADD SI, 3              ; skip the bmp pixels\r
-               LOOP SCAN_LOOP    ; finish the scan\r
-\r
-               MOV AX, nextPageRow\r
-               ADD DI, AX            ; go to the next row on screen\r
-               MOV AX, nextBmpRow\r
-               ADD SI, AX            ; go to the next row on bmp\r
-\r
-               DEC rowCounter\r
-               JNZ ROW_LOOP        ; do all the rows\r
-               ;-- end plane painting\r
-\r
-               MOV AL, plane      ; advance to the next plane\r
-               SHL AL, 1              ;\r
-               AND AL, 0x0f        ; mask the plane properly\r
-               MOV plane, AL      ; store the plane\r
-\r
-               INC bmpOffset      ; start bmp at the right spot\r
-\r
-               DEC planeCounter\r
-               JNZ PLANE_LOOP    ; do all 4 planes\r
-    }\r
-}\r
+/* moved to src/lib/modex16/16render.c */\r
 \r
 /* copy a region of video memory from one page to another.\r
  * It assumes that the left edge of the tile is the same on both\r
@@ -1015,7 +551,8 @@ modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
        static word a[PAL_SIZE];        //palette array of change values!\r
        word z=0, aq=0, aa=0, pp=0;\r
 \r
-       modexWaitBorder();\r
+       //modexWaitBorder();\r
+       vga_wait_for_vsync();\r
        if((*i)==0)\r
        {\r
                memset(a, -1, sizeof(a));\r
@@ -1065,7 +602,8 @@ modexPalUpdate(bitmap_t *bmp, word *i, word qp, word aqoffset)
                //if(qp>0) printf("qp=%d\n", qp);\r
                //if(qp>0) printf("                                          (*i)=%d\n", (*i)/3);\r
        }\r
-       modexWaitBorder();        /* waits one retrace -- less flicker */\r
+       //modexWaitBorder();      /* waits one retrace -- less flicker */\r
+       vga_wait_for_vsync();\r
        if((*i)>=PAL_SIZE/2 && w==0)\r
        {\r
                for(; (*i)<PAL_SIZE; (*i)++)\r
@@ -1104,7 +642,7 @@ printf("\nqqqqqqqq\n\n");
                pp = q;\r
                //printf("1(*i)=%02d\n", (*i)/3);\r
                //printf("1z=%02d\n", z/3);\r
-               chkcolor(bmp, &q, &a, &aa, &z, i);\r
+               modexchkcolor(bmp, &q, &a, &aa, &z, i);\r
                //printf("2(*i)=%02d\n", (*i)/3);\r
                //printf("2z=%02d\n", z/3);\r
                aq=0;\r
@@ -1176,13 +714,15 @@ void
 modexPalUpdate1(byte *p)\r
 {\r
        int i;\r
-       modexWaitBorder();\r
+       //modexWaitBorder();\r
+       vga_wait_for_vsync();\r
        outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
        for(i=0; i<PAL_SIZE/2; i++)\r
        {\r
                outp(PAL_DATA_REG, p[i]);\r
        }\r
-       modexWaitBorder();        /* waits one retrace -- less flicker */\r
+       //modexWaitBorder();      /* waits one retrace -- less flicker */\r
+       vga_wait_for_vsync();\r
        for(; i<PAL_SIZE; i++)\r
        {\r
                outp(PAL_DATA_REG, p[(i)]);\r
@@ -1193,13 +733,15 @@ void
 modexPalUpdate0(byte *p)\r
 {\r
        int i;\r
-       modexWaitBorder();\r
+       //modexWaitBorder();\r
+       vga_wait_for_vsync();\r
        outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
        for(i=0; i<PAL_SIZE/2; i++)\r
        {\r
                outp(PAL_DATA_REG, rand());\r
        }\r
-       modexWaitBorder();        /* waits one retrace -- less flicker */\r
+       //modexWaitBorder();      /* waits one retrace -- less flicker */\r
+       vga_wait_for_vsync();\r
        for(; i<PAL_SIZE; i++)\r
        {\r
                outp(PAL_DATA_REG, rand());\r
@@ -1209,14 +751,15 @@ modexPalUpdate0(byte *p)
 void\r
 modexPalOverscan(byte *p, word col)\r
 {\r
-       modexWaitBorder();\r
+       //modexWaitBorder();\r
+       vga_wait_for_vsync();\r
        outp(PAL_WRITE_REG, 0);  /* start at the beginning of palette */\r
        outp(PAL_DATA_REG, col);\r
 }\r
 \r
 //color checker~\r
 //i want to make another vesion that checks the palette when the palette is being appened~\r
-void chkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
+void modexchkcolor(bitmap_t *bmp, word *q, word *a, word *aa, word *z, word *i/*, word *offset*/)\r
 {\r
                byte *pal;\r
                word zz=0;\r
@@ -1334,99 +877,41 @@ byte modexgetPixel(page_t *page, int x, int y)
 \r
 }\r
 \r
-void modexhlin(page_t *page, word xl, word xh, word y, word color)\r
-{\r
-       word x;\r
-       word yy=0;\r
-\r
-       for(x=0;x<xh*4;x+=4)\r
-       {\r
-               if(x+4>=page[0].sw-1){ x=0; yy+=4; }\r
-               modexClearRegion(page, x+xl, y+yy, 4, 4, color);\r
-       }\r
-       //modexputPixel(page, x+xl, y, color);\r
-}\r
-\r
 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
 {\r
-       word i, s, o, w, j, xp;\r
-       byte l[1024];\r
-       word addr = (word) l;\r
-       word chw=0;\r
+       word s, o, w;\r
+       word x_draw = x;\r
+       word addr = (word) romFontsData.l;\r
+       word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);\r
+       word addrr = addrq;\r
        byte c;\r
-       //byte near *bakapee;\r
-\r
-       switch(t)\r
-       {\r
-               case 0:\r
-                       w=14;\r
-               break;\r
-               case 1:\r
-                       w=8;\r
-               break;\r
-               case 2:\r
-                       w=8;\r
-               break;\r
-               case 3:\r
-                       w=16;\r
-               break;\r
-               default:\r
-                       t=3;\r
-                       w=16;\r
-               break;\r
-       }\r
 \r
        s=romFonts[t].seg;\r
        o=romFonts[t].off;\r
+       w=romFonts[t].charSize;\r
+       romFontsData.chw=0;\r
 \r
        for(; *str != '\0'; str++)\r
        {\r
        c = (*str);\r
-       if((c=='\n'/* || c=="\\r
-"*/) || chw\r
->=page->width)\r
+       if(c=='\n')\r
        {\r
-               chw=0;\r
-               y+=w;\r
+               x = x_draw;\r
+               romFontsData.chw = 0;\r
+               addrq += (page->width / 4) * 8;\r
+               addrr = addrq;\r
+               y += 8;\r
                continue;\r
        }\r
-       //load the letter 'A'\r
-       __asm {\r
-               MOV DI, addr\r
-               MOV SI, o\r
-               MOV ES, s\r
-               SUB AH, AH\r
-               MOV AL, c       ; the letter\r
-               MOV CX, w\r
-               MUL CX\r
-               ADD SI, AX      ;the address of charcter\r
-       L1:     MOV AX, ES:SI\r
-               MOV DS:DI, AX\r
-               INC SI\r
-               INC DI\r
-               DEC CX\r
-               JNZ L1\r
-       }\r
-       //bakapee = _nmalloc(sizeof(byte)*8);\r
-//TODO: OPTIMIZE THIS!!!!\r
-               for(i=0; i<w; i++)\r
-               {\r
-                       /*modexSelectPlane(PLANE(x));\r
-                       j=1<<8;\r
-                       *bakapee=(l[i] & j ? col:bgcol);\r
-                       _fmemcpy(page->data + (((page->width/4) * (y+page->dy+i)) + ((x+page->dx+chw) / 4)), bakapee, 8);*/\r
-                       j=1<<8;\r
-                       xp=0;\r
-                       while(j)\r
-                       {\r
-                               modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
-                               xp++;\r
-                               j>>=1;\r
-                       }\r
-               }\r
-               chw += xp;\r
+\r
+       // load the character into romFontsData.l\r
+       // no need for inline assembly!\r
+       // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.\r
+               _fmemcpy(romFontsData.l,MK_FP(s,o)/*ROM font location*/,w/*char size*/);\r
+               modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);\r
+               x_draw += 8; /* track X for edge of screen */\r
+               addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */\r
        }\r
-       //_nfree(bakapee);\r
 }\r
 \r
 void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
@@ -1505,7 +990,7 @@ void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, c
 }\r
 \r
 /* palette dump on display! */\r
-void pdump(page_t *pee)\r
+void modexpdump(page_t *pee)\r
 {\r
        int mult=(QUADWH);\r
        int palq=(mult)*TILEWH;\r
@@ -1525,22 +1010,49 @@ void pdump(page_t *pee)
 //              the Virtual screen.                                                                                     //\r
 //                                                                                                                                              //\r
 /////////////////////////////////////////////////////////////////////////////\r
-void cls(page_t *page, byte color, byte *Where)\r
+void modexcls(page_t *page, byte color, byte *Where)\r
 {\r
        //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
        /* set map mask to all 4 planes */\r
        outpw(SC_INDEX, 0xff02);\r
        //_fmemset(VGA, color, 16000);\r
-       _fmemset(Where, color, page->width*(page->height));\r
+       _fmemset(Where, color, page->width*(page->height)/4);\r
 }\r
 \r
 void\r
 modexWaitBorder() {\r
     while(inp(INPUT_STATUS_1)  & 8)  {\r
-       /* spin */\r
+       // spin\r
     }\r
 \r
     while(!(inp(INPUT_STATUS_1)  & 8))  {\r
-       /* spin */\r
+       // spin\r
     }\r
 }\r
+\r
+void bios_cls() {\r
+       VGA_ALPHA_PTR ap;\r
+       VGA_RAM_PTR rp;\r
+       unsigned char m;\r
+\r
+       m = int10_getmode();\r
+       if ((rp=vga_state.vga_graphics_ram) != NULL && !(m <= 3 || m == 7)) {\r
+               unsigned int i,im;\r
+\r
+               im = (FP_SEG(vga_state.vga_graphics_ram_fence) - FP_SEG(vga_state.vga_graphics_ram));\r
+               if (im > 0xFFE) im = 0xFFE;\r
+               im <<= 4;\r
+               for (i=0;i < im;i++) vga_state.vga_graphics_ram[i] = 0;\r
+       }\r
+       else if ((ap=vga_state.vga_alpha_ram) != NULL) {\r
+               unsigned int i,im;\r
+\r
+               im = (FP_SEG(vga_state.vga_alpha_ram_fence) - FP_SEG(vga_state.vga_alpha_ram));\r
+               if (im > 0x7FE) im = 0x7FE;\r
+               im <<= 4 - 1; /* because ptr is type uint16_t */\r
+               for (i=0;i < im;i++) vga_state.vga_alpha_ram[i] = 0x0720;\r
+       }\r
+       else {\r
+               printf("WARNING: bios cls no ptr\n");\r
+       }\r
+}\r