]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/modex16.c
test.exe shows that the overscan is showing up where it should not thus end horizonta...
[16.git] / src / lib / modex16.c
index 2d4c00242676ffd4401578c3fb6f024599199c21..62f5c4ef547aac9c64b767a742c53912e624cb19 100755 (executable)
@@ -62,7 +62,12 @@ void VGAmodeX(sword vq, boolean cmem, global_game_variables_t *gv)
 static void\r
 vgaSetMode(byte mode)\r
 {\r
-  int10_setmode(mode);\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
@@ -85,8 +90,13 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
 \r
        vgaSetMode(VGA_256_COLOR_MODE);\r
        vga_enable_256color_modex();\r
+\r
        update_state_from_vga();\r
-       vga_read_crtc_mode(&cm);\r
+       vga_read_crtc_mode_(&cm);\r
+\r
+       /* reprogram the CRT controller */\r
+       //outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */\r
+       //outp(CRTC_DATA, 0x7f);  /* get current write protect on varios regs */\r
 \r
        switch(vq)\r
        {\r
@@ -109,7 +119,7 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
                        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_blank_end=0x82 + 1;   /* CRTC[3] bit 0-4 & CRTC[5] bit 7 *///skewing ^^;\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
@@ -187,7 +197,8 @@ modexDefaultPage(page_t *p)
        page.tilesh=page.height/TILEWH;\r
        page.tilemidposscreenx = page.tw/2;\r
        page.tilemidposscreeny = (page.th/2)+1;\r
-       page.pagesize = (sdiword)(page.width/4)*page.height;\r
+       page.stridew=page.width/4;\r
+       page.pagesize = (word)(page.width/4)*page.height;\r
        page.id = 0;\r
 \r
     return page;\r
@@ -203,6 +214,8 @@ modexNextPage(page_t *p) {
     result.data = p->data + (p->pagesize);\r
     result.dx = 0;\r
     result.dy = 0;\r
+       result.sw = p->sw;\r
+       result.sh = p->sh;\r
     result.width = p->width;\r
     result.height = p->height;\r
        result.tw = p->tw;\r
@@ -210,6 +223,7 @@ modexNextPage(page_t *p) {
        result.tilesw = p->tilesw;\r
        result.tilesh = p->tilesh;\r
        result.id = p->id+1;\r
+       result.stridew=p->stridew;\r
        result.pagesize = p->pagesize;\r
 \r
        return result;\r
@@ -224,6 +238,8 @@ modexNextPageFlexibleSize(page_t *p, word x, word y)
        result.data = p->data + (p->pagesize);  /* compute the offset */\r
        result.dx = 0;\r
        result.dy = 0;\r
+       result.sw = x;\r
+       result.sh = y;\r
        result.width = x;\r
        result.height = y;\r
        result.tw = result.sw/TILEWH;\r
@@ -231,7 +247,8 @@ modexNextPageFlexibleSize(page_t *p, word x, word y)
        result.tilesw=result.width/TILEWH;\r
        result.tilesh=result.height/TILEWH;\r
        result.id = p->id+1;\r
-       result.pagesize = (sdiword)(result.width/4)*result.height;\r
+       result.stridew=result.width/4;\r
+       result.pagesize = (word)(result.width/4)*result.height;\r
 \r
        return result;\r
 }\r
@@ -239,26 +256,28 @@ modexNextPageFlexibleSize(page_t *p, word x, word y)
 void modexCalcVmemRemain(video_t *video)\r
 {\r
        byte i;\r
-       //printf("\n\n  1st vmem_remain=%ld\n", video->vmem_remain);\r
-       for(i=0; i<=video->num_of_pages-1; i++)\r
+       //printf("\n\n  1st vmem_remain=%u\n", video->vmem_remain);\r
+       for(i=0; i<video->num_of_pages; i++)\r
        {\r
                video->vmem_remain-=video->page[i].pagesize;\r
-               //printf("              [%u], video->page[i].pagesize=%ld\n", i, video->page[i].pagesize);\r
-               //printf("              [%u], vmem_remain=%ld\n", i, video->vmem_remain);\r
+               //printf("              [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);\r
+               //printf("              [%u], vmem_remain=%u\n", i, video->vmem_remain);\r
        }\r
 }\r
 \r
 void modexHiganbanaPageSetup(video_t *video)\r
 {\r
-       video->vmem_remain=262144L;\r
+       video->vmem_remain=65535U;\r
        video->num_of_pages=0;\r
-       (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;\r
-       //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);\r
+       (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;  //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);\r
        (video->page[1]) = modexNextPage(&(video->page[0]));    video->num_of_pages++;\r
-       //(video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, video->page[0].sh-40);  video->num_of_pages++;\r
-       //(video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), TILEWH, TILEWH);      video->num_of_pages++;\r
+       (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4);            video->num_of_pages++;\r
+       (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208);        video->num_of_pages++;\r
+//     (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172);     video->num_of_pages++;\r
+//     (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128);               video->num_of_pages++;\r
        modexCalcVmemRemain(video);\r
        video->p=0;\r
+       video->r=1;\r
 }\r
 \r
 void\r
@@ -311,8 +330,8 @@ modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {
     word pageOff = (word) page->data;\r
     word xoff=x/4;       /* xoffset that begins each row */\r
     word scanCount=w/4;  /* number of iterations per row (excluding right clip)*/\r
-    word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */\r
-    word nextRow = page->width/4-scanCount-1;  /* loc of next row */\r
+    word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */\r
+    word nextRow = page->stridew-scanCount-1;  /* loc of next row */\r
     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
     byte rclip[] = {0x00, 0x01, 0x03, 0x07};\r
     byte left = lclip[x&0x03];\r
@@ -388,11 +407,11 @@ modexCopyPageRegion(page_t *dest, page_t *src,
                    word dx, word dy,\r
                    word width, word height)\r
 {\r
-    word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;\r
-    word soffset = (word)src->data + sy*(src->width/4) + sx/4;\r
+    word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;\r
+    word soffset = (word)src->data + sy*(src->stridew) + sx/4;\r
     word scans   = vga_state.vga_stride;\r
-    word nextSrcRow = src->width/4 - scans - 1;\r
-    word nextDestRow = dest->width/4 - scans - 1;\r
+    word nextSrcRow = src->stridew - scans - 1;\r
+    word nextDestRow = dest->stridew - scans - 1;\r
     byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08};  /* clips for rectangles not on 4s */\r
     byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
     byte left = lclip[sx&0x03];\r
@@ -818,7 +837,7 @@ modexPalUpdate0(byte *p)
 }\r
 \r
 void\r
-modexPalOverscan(byte *p, word col)\r
+modexPalOverscan(word col)\r
 {\r
        //modexWaitBorder();\r
        vga_wait_for_vsync();\r
@@ -1108,13 +1127,13 @@ void modexcls(page_t *page, byte color, byte *Where)
 \r
 void\r
 modexWaitBorder() {\r
-    while(inp(INPUT_STATUS_1)  & 8)  {\r
+       while(inp(INPUT_STATUS_1)  & 8)  {\r
        // spin\r
-    }\r
+       }\r
 \r
-    while(!(inp(INPUT_STATUS_1)  & 8))  {\r
-       // spin\r
-    }\r
+       while(!(inp(INPUT_STATUS_1)  & 8))  {\r
+       //spin\r
+       }\r
 }\r
 \r
 void bios_cls() {\r
@@ -1143,3 +1162,168 @@ void bios_cls() {
                printf("WARNING: bios cls no ptr\n");\r
        }\r
 }\r
+\r
+void modexprintmeminfo(video_t *v)\r
+{\r
+       byte i;\r
+       printf("video memory remaining: %u\n", v->vmem_remain);\r
+       printf("page ");\r
+       for(i=0; i<v->num_of_pages;i++)\r
+       {\r
+               printf("        [%u]=", i);\r
+               printf("(%Fp)", (v->page[i].data));\r
+               printf(" size=%u", v->page[i].pagesize);\r
+               printf(" sw=%lu  sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);\r
+               printf(" width=%lu  height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);\r
+               printf("\n");\r
+       }\r
+}\r
+\r
+void vga_write_crtc_mode_(struct vga_mode_params *p,unsigned int flags) {\r
+       unsigned char c,c2,syncreset=0;\r
+\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA))\r
+               return;\r
+\r
+       /* sync disable unless told not to */\r
+       if (!(flags & VGA_WRITE_CRTC_MODE_NO_CLEAR_SYNC)) {\r
+               c = vga_read_CRTC(0x17);\r
+               vga_write_CRTC(0x17,c&0x7F);\r
+       }\r
+\r
+       c = inp(0x3CC); /* misc out reg */\r
+       /* if changing the clock select bits then we need to do a reset of the sequencer */\r
+       if (p->clock_select != ((c >> 2) & 3)) syncreset=1;\r
+       /* proceed to change bits */\r
+       c &= ~((3 << 2) | (1 << 6) | (1 << 7));\r
+       c |= (p->clock_select&3) << 2;\r
+       c |= p->hsync_neg << 6;\r
+       c |= p->vsync_neg << 7;\r
+       if (syncreset) vga_write_sequencer(0,0x01/*SR=0 AR=1 start synchronous reset*/);\r
+       outp(0x3C2,c); /* misc out */\r
+       if (syncreset) vga_write_sequencer(0,0x03/*SR=1 AR=1 restart sequencer*/);\r
+\r
+       vga_write_sequencer(1,\r
+               (p->shift_load_rate << 2) |\r
+               (p->shift4_enable << 4) |\r
+               ((p->clock9 ^ 1) << 0) |\r
+               (p->clock_div2 << 3));\r
+\r
+       c = 0; /* use 'c' as overflow register */\r
+       c2 = vga_read_CRTC(0x09); /* read max scan line */\r
+       c2 &= ~(1 << 5); /* mask out start vertical blank bit 9 */\r
+       vga_write_CRTC(0x11, /* NTS: we leave bit 7 (protect) == 0 so we can program regs 0-7 in this routine */\r
+               (((p->refresh_cycles_per_scanline == 5) ? 1 : 0) << 6) |\r
+               (p->vertical_end_retrace & 0xF));\r
+       vga_write_CRTC(0x06,(p->vertical_total - 2));\r
+               c |= (((p->vertical_total - 2) >> 8) & 1) << 0;\r
+               c |= (((p->vertical_total - 2) >> 9) & 1) << 5;\r
+       vga_write_CRTC(0x10,p->vertical_start_retrace);\r
+               c |= ((p->vertical_start_retrace >> 8) & 1) << 2;\r
+               c |= ((p->vertical_start_retrace >> 9) & 1) << 7;\r
+       vga_write_CRTC(0x12,p->vertical_display_end - 1);\r
+               c |= (((p->vertical_display_end - 1) >> 8) & 1) << 1;\r
+               c |= (((p->vertical_display_end - 1) >> 9) & 1) << 6;\r
+       vga_write_CRTC(0x15,p->vertical_blank_start - 1);\r
+               c |= (((p->vertical_blank_start - 1) >> 8) & 1) << 3;\r
+               c2|= (((p->vertical_blank_start - 1) >> 9) & 1) << 5;\r
+\r
+       /* NTS: this field is 7 bits wide but "Some SVGA chipsets use all 8" as VGADOC says. */\r
+       /*      writing it in this way resolves the partial/full screen blanking problems with Intel 855/915/945 chipsets */\r
+       vga_write_CRTC(0x16,p->vertical_blank_end - 1);\r
+\r
+       vga_write_CRTC(0x14, /* NTS we write "underline location == 0" */\r
+               (p->dword_mode << 6) |\r
+               (p->inc_mem_addr_only_every_4th << 5));\r
+       vga_write_CRTC(0x07,c); /* overflow reg */\r
+\r
+       c2 &= ~(0x9F);  /* mask out SD + Max scanline */\r
+       c2 |= (p->scan_double << 7);\r
+       c2 |= (p->max_scanline - 1) & 0x1F;\r
+       vga_write_CRTC(0x09,c2);\r
+       vga_write_CRTC(0x13,p->offset);\r
+       vga_write_CRTC(0,(p->horizontal_total - 5));\r
+       vga_write_CRTC(1,(p->horizontal_display_end - 1));\r
+       vga_write_CRTC(2,p->horizontal_blank_start - 1);\r
+       vga_write_CRTC(3,((p->horizontal_blank_end - 1) & 0x1F) | (p->horizontal_start_delay_after_total << 5) | 0x80);\r
+       vga_write_CRTC(4,p->horizontal_start_retrace);\r
+       vga_write_CRTC(5,((((p->horizontal_blank_end - 1) >> 5) & 1) << 7) | (p->horizontal_start_delay_after_retrace << 5) |\r
+               (p->horizontal_end_retrace & 0x1F));\r
+\r
+       /* finish by writing reg 0x17 which also enables sync */\r
+       vga_write_CRTC(0x17,\r
+               (p->sync_enable << 7) |\r
+               (vga_read_CRTC(0x17) & 0x10) | /* NTS: one undocumented bit, perhaps best not to change it */\r
+               ((p->word_mode^1) << 6) |\r
+               (p->address_wrap_select << 5) |\r
+               (p->memaddr_div2 << 3) |\r
+               (p->scanline_div2 << 2) |\r
+               ((p->map14 ^ 1) << 1) |\r
+               ((p->map13 ^ 1) << 0));\r
+\r
+       /* reinforce write protect */\r
+       c = vga_read_CRTC(0x11);\r
+       vga_write_CRTC(0x11,c|0x80);\r
+}\r
+\r
+void vga_read_crtc_mode_(struct vga_mode_params *p) {\r
+       unsigned char c,c2;\r
+\r
+       if (!(vga_state.vga_flags & VGA_IS_VGA))\r
+               return;\r
+\r
+       c = inp(0x3CC); /* misc out reg */\r
+       p->clock_select = (c >> 2) & 3;\r
+       p->hsync_neg = (c >> 6) & 1;\r
+       p->vsync_neg = (c >> 7) & 1;\r
+\r
+       c = vga_read_sequencer(1);\r
+       p->clock9 = (c & 1) ^ 1;\r
+       p->clock_div2 = (c >> 3) & 1;\r
+       p->shift4_enable = (c >> 4) & 1;\r
+       p->shift_load_rate = (c >> 2) & 1;\r
+\r
+       p->sync_enable = (vga_read_CRTC(0x17) >> 7) & 1;\r
+       p->word_mode = ((vga_read_CRTC(0x17) >> 6) & 1) ^ 1;\r
+       p->address_wrap_select = (vga_read_CRTC(0x17) >> 5) & 1;\r
+       p->memaddr_div2 = (vga_read_CRTC(0x17) >> 3) & 1;\r
+       p->scanline_div2 = (vga_read_CRTC(0x17) >> 2) & 1;\r
+       p->map14 = ((vga_read_CRTC(0x17) >> 1) & 1) ^ 1;\r
+       p->map13 = ((vga_read_CRTC(0x17) >> 0) & 1) ^ 1;\r
+\r
+       p->dword_mode = (vga_read_CRTC(0x14) >> 6) & 1;\r
+       p->horizontal_total = vga_read_CRTC(0) + 5;\r
+       p->horizontal_display_end = vga_read_CRTC(1);// + 1;\r
+       p->horizontal_blank_start = vga_read_CRTC(2) + 1;\r
+       p->horizontal_blank_end = ((vga_read_CRTC(3) & 0x1F) | ((vga_read_CRTC(5) >> 7) << 5) |\r
+               ((p->horizontal_blank_start - 1) & (~0x3F))) + 1;\r
+       if (p->horizontal_blank_start >= p->horizontal_blank_end)\r
+               p->horizontal_blank_end += 0x40;\r
+       p->horizontal_start_retrace = vga_read_CRTC(4);\r
+       p->horizontal_end_retrace = (vga_read_CRTC(5) & 0x1F) |\r
+               (p->horizontal_start_retrace & (~0x1F));\r
+       if ((p->horizontal_start_retrace&0x1F) >= (p->horizontal_end_retrace&0x1F))\r
+               p->horizontal_end_retrace += 0x20;\r
+       p->horizontal_start_delay_after_total = (vga_read_CRTC(3) >> 5) & 3;\r
+       p->horizontal_start_delay_after_retrace = (vga_read_CRTC(5) >> 5) & 3;\r
+\r
+       c = vga_read_CRTC(7); /* c = overflow reg */\r
+       c2 = vga_read_CRTC(9);\r
+\r
+       p->scan_double = (c2 >> 7) & 1;\r
+       p->max_scanline = (c2 & 0x1F) + 1;\r
+       p->offset = vga_read_CRTC(0x13);\r
+       p->vertical_total = (vga_read_CRTC(6) | ((c & 1) << 8) | (((c >> 5) & 1) << 9)) + 2;\r
+       p->vertical_start_retrace = (vga_read_CRTC(0x10) | (((c >> 2) & 1) << 8) | (((c >> 7) & 1) << 9));\r
+       p->vertical_end_retrace = (vga_read_CRTC(0x11) & 0xF) |\r
+               (p->vertical_start_retrace & (~0xF));\r
+       if ((p->vertical_start_retrace&0xF) >= (p->vertical_end_retrace&0xF))\r
+               p->vertical_end_retrace += 0x10;\r
+       p->refresh_cycles_per_scanline = ((vga_read_CRTC(0x11) >> 6) & 1) ? 5 : 3;\r
+       p->inc_mem_addr_only_every_4th = (vga_read_CRTC(0x14) >> 5) & 1;\r
+       p->vertical_display_end = ((vga_read_CRTC(0x12) | (((c >> 1) & 1) << 8) | (((c >> 6) & 1) << 9))) + 1;\r
+       p->vertical_blank_start = ((vga_read_CRTC(0x15) | (((c >> 3) & 1) << 8) | (((c2 >> 5) & 1) << 9))) + 1;\r
+       p->vertical_blank_end = ((vga_read_CRTC(0x16) & 0x7F) | ((p->vertical_blank_start - 1) & (~0x7F))) + 1;\r
+       if (p->vertical_blank_start >= p->vertical_blank_end)\r
+               p->vertical_blank_end += 0x80;\r
+}\r