OSDN Git Service

[VM][UPD7220] Start to support variable screen pitch.Dragon-Buster for PC-9801 is...
authorK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 20 May 2019 15:28:48 +0000 (00:28 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 20 May 2019 15:28:48 +0000 (00:28 +0900)
source/src/vm/pc9801/cpureg.cpp
source/src/vm/pc9801/display.cpp
source/src/vm/pc9801/membus.cpp
source/src/vm/upd7220.cpp
source/src/vm/upd7220.h

index ef5ef28..55b10e9 100644 (file)
@@ -181,7 +181,8 @@ uint32_t CPUREG::read_io8(uint32_t addr)
 #endif
                // ToDo: AMD98
 //             value |= 0x10; // Unknown
-               value |= ((d_mem->read_signal(SIG_LAST_ACCESS_INTERAM) != 0) ? 0x00: 0x08); // RAM access, 1 = Internal-standard/External-enhanced RAM, 0 = Internal-enhanced RAM
+               value |= 0x08;
+//             value |= ((d_mem->read_signal(SIG_LAST_ACCESS_INTERAM) != 0) ? 0x00: 0x08); // RAM access, 1 = Internal-standard/External-enhanced RAM, 0 = Internal-enhanced RAM
 //             value |= 0x04; // Refresh mode, 1 = Standard, 0 = High speed
 //#if defined(HAS_I86) || defined(HAS_V30)
                // ToDo: Older VMs.
index 3951d24..2ce734b 100644 (file)
@@ -2627,6 +2627,10 @@ void DISPLAY::draw_screen()
                } else {
                        memset(screen_gfx, 0, sizeof(screen_gfx));
                }
+               int _width = d_gdc_gfx->read_signal(SIG_UPD7220_PITCH);
+               _width <<= 4;
+//             _width -= 16;
+               if(_width > SCREEN_WIDTH) _width = SCREEN_WIDTH;
                for(int y = 0; y < SCREEN_HEIGHT; y++) {
                        scrntype_t *dest = emu->get_screen_buffer(y);
                        uint8_t *src_chr = screen_chr[y];
@@ -2640,16 +2644,26 @@ void DISPLAY::draw_screen()
 #if defined(SUPPORT_16_COLORS)
                        if(!modereg2[MODE2_16COLOR]) {
 #endif
-                               for(int x = 0; x < SCREEN_WIDTH; x++) {
+                               for(int x = 0; x < _width; x++) {
                                        uint8_t chr = src_chr[x];
                                        dest[x] = chr ? palette_chr[chr & 7] : palette_gfx8[src_gfx[x] & 7];
                                }
+                               // ToDo: Variable width
+                               for(int x = _width; x < SCREEN_WIDTH; x++) {
+                                       uint8_t chr = src_chr[x];
+                                       dest[x] = (chr) ? palette_chr[chr & 7] : 0x00;
+                               }
 #if defined(SUPPORT_16_COLORS)
                        } else {
-                               for(int x = 0; x < SCREEN_WIDTH; x++) {
+                               for(int x = 0; x < _width; x++) {
                                        uint8_t chr = src_chr[x];
                                        dest[x] = chr ? palette_chr[chr & 7] : palette_gfx16[src_gfx[x]];
                                }
+                               // ToDo: Variable width
+                               for(int x = _width; x < SCREEN_WIDTH; x++) {
+                                       uint8_t chr = src_chr[x];
+                                       dest[x] = (chr) ? palette_chr[chr & 7] : 0x00;
+                               }
                        }
 #endif
                }
@@ -2685,7 +2699,7 @@ void DISPLAY::draw_chr_screen()
        
        // address from gdc
        uint32_t gdc_addr[25][80] = {0};
-       
+       // ToDo: Will Support 30lines project.
        for(int i = 0, ytop = 0; i < 4; i++) {
                uint32_t ra = ra_chr[i * 4];
                ra |= ra_chr[i * 4 + 1] << 8;
@@ -2724,20 +2738,30 @@ void DISPLAY::draw_chr_screen()
        
        memset(screen_chr, 0, sizeof(screen_chr));
        
-       for(int y = 0, cy = 0, ytop = 0; y < SCREEN_HEIGHT && cy < 25; y += bl, cy++) {
+       int _height = d_gdc_chr->read_signal(SIG_UPD7220_HEIGHT);
+       int _width  = d_gdc_chr->read_signal(SIG_UPD7220_PITCH);
+//     if(_height < 0) _height = 0;
+//     if(_height > 480) _height = 480;
+       _height = SCREEN_HEIGHT;
+       _width <<= 3;
+       if(_width  < 0) _width = 0;
+       static const uint32_t __vramsize = SCREEN_HEIGHT * SCREEN_WIDTH;
+       uint32_t of = 0;
+       
+       for(int y = 0, cy = 0, ytop = 0; y < _height && cy < 25; y += bl, cy++) {
                uint32_t gaiji1st = 0, last = 0, offset;
                int kanji2nd = 0;
                if(y == ysur) {
                        ytop = y;
                        y -= ssl;
-                       ysur = SCREEN_HEIGHT;
+                       ysur = _height;
                }
                if(y >= ysdr) {
                        y = ytop = ysdr;
                        addr = addr2;
-                       ysdr = SCREEN_HEIGHT;
+                       ysdr = _height;
                }
-               for(int x = 0, cx = 0; x < SCREEN_WIDTH && cx < 80; x += xofs, cx++) {
+               for(int x = 0, cx = 0; x < _width && cx < 80; x += xofs, cx++) {
                        uint16_t code = *(uint16_t *)(tvram + (*addr));
                        uint8_t attr = tvram[(*addr) | 0x2000];
                        uint8_t color = (attr & ATTR_COL) ? (attr >> 5) : 8;
@@ -2776,7 +2800,7 @@ void DISPLAY::draw_chr_screen()
                        
                        for(int l = 0; l < bl; l++) {
                                int yy = y + l + pl;
-                               if(yy >= ytop && yy < SCREEN_HEIGHT) {
+                               if(yy >= ytop && yy < _height) {
                                        uint8_t *dest = &screen_chr[yy][x];
 #if !defined(SUPPORT_HIRESO)
                                        uint8_t pattern = (l < cl && l < FONT_HEIGHT) ? font[offset + l] : 0;
@@ -2860,14 +2884,25 @@ void DISPLAY::draw_chr_screen()
                                        }
                                }
                        }
+//                     of++;
+//                     if(of >= __vramsize) break;
                }
+//             if(of >= __vramsize) break;
        }
 }
 
 void DISPLAY::draw_gfx_screen()
 {
        // address from gdc
-       uint32_t gdc_addr[SCREEN_HEIGHT][SCREEN_WIDTH >> 3] = {0};
+       int _height = d_gdc_gfx->read_signal(SIG_UPD7220_HEIGHT);
+       int _width  = d_gdc_gfx->read_signal(SIG_UPD7220_PITCH) * 2;
+       
+       uint32_t gdc_addr[480][SCREEN_WIDTH >> 3] = {0}; // Dragon Buster.
+       
+       if(_height < 0) _height = 0;
+       if(_height > 480) _height = 480;
+       _width <<= 3;
+       if(_width  < 0) _width = 0;
        
        for(int i = 0, ytop = 0; i < 4; i++) {
                uint32_t ra = ra_gfx[i * 4];
@@ -2879,19 +2914,21 @@ void DISPLAY::draw_gfx_screen()
                
                if(!len) len = SCREEN_HEIGHT; // Madou Monogatari 1-2-3
                
-               for(int y = ytop; y < (ytop + len) && y < SCREEN_HEIGHT; y++) {
-                       for(int x = 0; x < (SCREEN_WIDTH >> 3); x++) {
+               for(int y = ytop; y < (ytop + len) && y < _height; y++) {
+                       for(int x = 0; x < (_width >> 3); x++) {
                                gdc_addr[y][x] = sad;
                                sad = (sad + 1) & VRAM_PLANE_ADDR_MASK;
                        }
                }
-               if((ytop += len) >= SCREEN_HEIGHT) break;
+               if((ytop += len) >= _height) break;
        }
        uint32_t *addr = &gdc_addr[0][0];
        uint8_t *dest = &screen_gfx[0][0];
-       
-       for(int y = 0; y < SCREEN_HEIGHT; y++) {
-               for(int x = 0; x < SCREEN_WIDTH; x += 8) {
+       //if(_width  > SCREEN_WIDTH) _width = SCRREEN_WIDTH; // OK?
+       static const uint32_t __vramsize = SCREEN_HEIGHT * SCREEN_WIDTH;
+       uint32_t of = 0;
+       for(int y = 0; y < _height; y++) {
+               for(int x = 0; x < _width; x += 8) {
                        uint8_t b = vram_disp_b[(*addr)];
                        uint8_t r = vram_disp_r[(*addr)];
                        uint8_t g = vram_disp_g[(*addr)];
@@ -2910,6 +2947,8 @@ void DISPLAY::draw_gfx_screen()
                        *dest++ = ((b & 0x04) >> 2) | ((r & 0x04) >> 1) | ((g & 0x04)     ) | ((e & 0x04) << 1);
                        *dest++ = ((b & 0x02) >> 1) | ((r & 0x02)     ) | ((g & 0x02) << 1) | ((e & 0x02) << 2);
                        *dest++ = ((b & 0x01)     ) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((e & 0x01) << 3);
+                       of++;
+                       if(of >= __vramsize) break;
                }
                if((cs_gfx[0] & 0x1f) == 1) {
                        // 200 line
@@ -2925,7 +2964,9 @@ void DISPLAY::draw_gfx_screen()
                                my_memcpy(dest, dest - SCREEN_WIDTH, SCREEN_WIDTH);
                        }
                        dest += 640;
+                       if(of >= __vramsize) break;
                        y++;
+                       if(y >= SCREEN_HEIGHT) break; // Temp: Dragon Buster.
                }
        }
 }
index bf600eb..a590ba3 100644 (file)
@@ -238,10 +238,10 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
        case 0x043d:
                switch(data & 0xff) {
        #if defined(SUPPORT_HIRESO)
-               case 0x00:
-               case 0x18:
+               case 0x00: // HIRESO
+               case 0x18: // H98S
        #endif
-               case 0x10:
+               case 0x10: // Normally BIOS, but, MENU ROM will be selected at H98S.
                        if(!itf_selected) {
                                itf_selected = true;
                                update_bios();
@@ -250,7 +250,7 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
        #if defined(SUPPORT_HIRESO)
                case 0x02:
        #endif
-               case 0x12:
+               case 0x12: // BIOS ROM
                        if(itf_selected) {
                                itf_selected = false;
                                update_bios();
@@ -302,12 +302,12 @@ void MEMBUS::write_io8(uint32_t addr, uint32_t data)
 #endif
 #if defined(SUPPORT_SCSI_IF)
                        // Changing ROM/RAM maybe select SCSI I/F board.(Still not tested)20190321 K.O 
-                       if(scsi_bios_selected) {
+                       //if(scsi_bios_selected) {
                                if(scsi_bios_ram_selected) {
                                        scsi_bios_ram_selected = false;
                                        update_scsi_bios();
                                }
-                       }
+                       //}
 #endif
                        break;
                case 0xc2:
@@ -685,6 +685,7 @@ void MEMBUS::update_bios()
                        #endif
                }
        } else {
+               // Internal RAM is not selected.
                // ToDo: Hi reso
                if(window_80000h < 0x80000) {
                #if defined(SUPPORT_BIOS_RAM)
@@ -692,11 +693,13 @@ void MEMBUS::update_bios()
                                unset_memory_rw(0x00080000, 0x0009ffff);
                        } else
                #endif                          
-                       set_memory_rw(0x80000, 0x9ffff, &(ram[window_80000h]));
+                       unset_memory_rw(0x00080000, 0x0009ffff);
+                       //set_memory_rw(0x80000, 0x9ffff, &(ram[window_80000h]));
                } else if(window_80000h == 0x80000) {
                        // ToDo: External BUS
                        unset_memory_rw(0x00080000, 0x0009ffff);
                } else {
+                       //unset_memory_rw(0x00080000, 0x0009ffff);
                        copy_table_rw(0x00080000, window_80000h, window_80000h + 0x1ffff);
                }
        }
index 1817a4a..7f295c5 100644 (file)
@@ -751,6 +751,15 @@ uint32_t UPD7220::read_signal(int ch)
        case SIG_UPD7220_CLOCK_FREQ:
                return clock_freq;
                break;
+       case SIG_UPD7220_WIDTH_BYTES:
+               return (width < 0) ? 0 : width;
+               break;
+       case SIG_UPD7220_HEIGHT:
+               return (height < 0) ? 0 : height;
+               break;
+       case SIG_UPD7220_PITCH:
+               return (pitch < 0) ? 0 : pitch;
+               break;
        }
        return 0;
 }
index 1ddb336..56114a9 100644 (file)
 #define RT_TABLEBIT    12
 #define RT_TABLEMAX    (1 << RT_TABLEBIT)
 
-#define SIG_UPD7220_CLOCK_FREQ 1
-#define SIG_UPD7220_EXT_VSYNC  2
+#define SIG_UPD7220_CLOCK_FREQ 1
+#define SIG_UPD7220_EXT_VSYNC  2
+#define SIG_UPD7220_WIDTH_BYTES        3
+#define SIG_UPD7220_HEIGHT             4
+#define SIG_UPD7220_PITCH              5
 
 class RINGBUFFER;
 class FIFO;