OSDN Git Service

[VM][FMTOWNS][CRTC] Implementing CRTC.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 11 Jan 2019 18:43:35 +0000 (03:43 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 11 Jan 2019 18:43:35 +0000 (03:43 +0900)
[VM][FMTOWNS] Will set wait-parameter to single, towns_memory.cpp.

12 files changed:
source/src/vm/fmtowns/fontrom_20pix.cpp [new file with mode: 0644]
source/src/vm/fmtowns/fontrom_20pix.h [new file with mode: 0644]
source/src/vm/fmtowns/fontroms.cpp
source/src/vm/fmtowns/fontroms.h
source/src/vm/fmtowns/msdosrom.cpp
source/src/vm/fmtowns/msdosrom.h
source/src/vm/fmtowns/towns_crtc.cpp
source/src/vm/fmtowns/towns_crtc.h
source/src/vm/fmtowns/towns_dictionary.cpp
source/src/vm/fmtowns/towns_dictionary.h
source/src/vm/fmtowns/towns_sysrom.cpp
source/src/vm/fmtowns/towns_sysrom.h

diff --git a/source/src/vm/fmtowns/fontrom_20pix.cpp b/source/src/vm/fmtowns/fontrom_20pix.cpp
new file mode 100644 (file)
index 0000000..70a2841
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+       FUJITSU FM Towns Emulator 'eFMTowns'
+
+       Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+       Date   : 2019.01.11 -
+
+       [20pixels fonts]
+*/
+
+#include "../../fileio.h"
+#include "./fontrom_20pix.h"
+
+namespace FMTOWNS {
+
+void FONT_ROM_20PIX::initialize()
+{
+       FILEIO* fio = new FILEIO();
+       memset(font_kanji20, sizeof(font_kanji20), 0xff);
+       if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // FONT
+               fio->Fread(font_kanji20, sizeof(font_kanji20), 1);
+               fio->Fclose();
+       }
+       delete fio;
+}
+
+uint32_t FONT_ROM_20PIX::read_data8(uint32_t addr)
+{
+       if((addr >= 0xc2180000) && (addr < 0xc2200000)) {
+               return (uint32_t)(font_kanji20[addr & 0x7ffff]);
+       }
+       return 0xff;
+}
+
+}
diff --git a/source/src/vm/fmtowns/fontrom_20pix.h b/source/src/vm/fmtowns/fontrom_20pix.h
new file mode 100644 (file)
index 0000000..c2b61be
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+       FUJITSU FM Towns Emulator 'eFMTowns'
+
+       Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+       Date   : 2019.01.09 -
+
+       [fonts]
+*/
+
+#pragma once
+
+#include "../device.h"
+
+namespace FMTOWNS {
+
+class FONT_ROM_20PIX : public DEVICE
+{
+protected:
+       uint8_t font_kanji20[0x40000];
+public:
+       FONT_ROM_20PIX(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+       {
+               set_device_name("Font Roms(20pix)");
+       }
+       ~FONT_ROM_20PIX() {}
+
+       void initialize();
+       uint32_t read_data8(uint32_t addr);
+};
+
+}
+
index ed072f6..e937f97 100644 (file)
@@ -7,7 +7,6 @@
        [fonts]
 */
 
-#inclide "../towns_common.h"
 #include "../../fileio.h"
 #include "./fontroms.h"
 
@@ -15,22 +14,12 @@ namespace FMTOWNS {
        
 void FONT_ROMS::initialize()
 {
-       wait_val = 3;
        memset(font_kanji16, sizeof(font_kanji16), 0xff);
        FILEIO* fio = new FILEIO();
-       
        if(fio->Fopen(create_local_path(_T("FMT_FNT.ROM")), FILEIO_READ_BINARY)) { // FONT
                fio->Fread(font_kanji16, sizeof(font_kanji16), 1);
                fio->Fclose();
        }
-       
-#if defined(HAVE_20PIXS_FONT)  
-       memset(font_kanji20, sizeof(font_kanji20), 0xff);
-       if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // FONT
-               fio->Fread(font_kanji20, sizeof(font_kanji20), 1);
-               fio->Fclose();
-       }
-#endif
 
        delete fio;
 }
@@ -39,12 +28,6 @@ uint32_t FONT_ROMS::read_data8(uint32_t addr)
 {
        if((addr >= 0xc2100000) && (addr < 0xc2140000)) {
                return (uint32_t)(font_kanji16[addr & 0x3ffff]);
-       } else if((addr >= 0xc2180000) && (addr < 0xc2200000)) {
-#if defined(HAVE_20PIXS_FONT)  
-               return (uint32_t)(font_kanji20[addr & 0x7ffff]);
-#else
-               return 0xff;
-#endif
        } else if((addr >= 0x000ca000) && (addr < 0x000ca800)) {
                return (uint32_t)(font_kanji16[0x1e800 + (addr & 0x7ff)]);
        } else if((addr >= 0x000cb000) && (addr < 0x000cc000)) {
@@ -53,37 +36,4 @@ uint32_t FONT_ROMS::read_data8(uint32_t addr)
        return 0xff;
 }
 
-uint32_t FONT_ROMS::read_data8w(uint32_t addr, int* wait)
-{
-       if(wait != NULL) *wait = wait_val;
-       return read_data8(addr);
-}
-
-void FONT_ROMS::write_data8w(uint32_t addr, uint32_t data, int* wait)
-{
-       if(wait != NULL) *wait = wait_val;
-}
-
-void FONT_ROMS::write_signal(int ch, uint32_t data, uint32_t mask)
-{
-       if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
-               wait_val = (int)data;
-       }
-}      
-
-#define STATE_VERSION  1
-
-bool FONT_ROMS::process_state(FILEIO* state_fio, bool loading)
-{
-       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
-               return false;
-       }
-       if(!state_fio->StateCheckInt32(this_device_id)) {
-               return false;
-       }
-       state_fio->StateValue(wait_val);
-
-       return true;
-}
-
 }
index de1ea5e..1c260b7 100644 (file)
@@ -17,11 +17,7 @@ namespace FMTOWNS {
 class FONT_ROMS : public DEVICE
 {
 protected:
-       int wait_val;
        uint8_t font_kanji16[0x40000];
-#if defined(HAVE_20PIXS_FONT)  
-       uint8_t font_kanji20[0x80000];
-#endif
 public:
        FONT_ROMS(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
@@ -30,12 +26,7 @@ public:
        ~FONT_ROMS() {}
 
        void initialize();
-       
        uint32_t read_data8(uint32_t addr);
-       uint32_t read_data8w(uint32_t addr, int* wait);
-       void write_data8w(uint32_t addr, uint32_t data, int* wait);
-       void write_signal(int ch, uint32_t data, uint32_t mask);
-       bool process_state(FILEIO* state_fio, bool loading);
 };
 
 }
index b6357ca..bc2b5f5 100644 (file)
@@ -21,8 +21,6 @@ void MSDOSROM::initialize()
                fio->Fclose();
        }
        delete fio;
-
-       wait_val = 3;
 }
 
 uint32_t MSDOSROM::read_data8(uint32_t addr)   
@@ -34,47 +32,5 @@ uint32_t MSDOSROM::read_data8(uint32_t addr)
        return (uint32_t)d;
 }
 
-uint32_t MSDOSROM::read_data8w(uint32_t addr, int* wait)       
-{
-       if(wait != NULL) *wait = wait_val;
-       return read_data8(addr);
-}
-void MSDOSROM::write_data8w(uint32_t addr, uint32_t data, int* wait)   
-{
-       if(wait != NULL) *wait = wait_val;
-}
-
-void MSDOSROM::write_signal(int ch, uint32_t data, uint32_t mask)
-{
-       switch(ch) {
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               wait_val = (int)data;
-               break;
-       }
-}
-
-uint32_t MSDOSROM::read_signal(int ch)
-{
-       switch(ch) {
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               return (uint32_t)wait_val;
-               break;
-       }
-       return 0;
-}
-
-#define STATE_VERSION  1
-
-bool DICTIONARY::process_state(FILEIO* state_fio, bool loading)
-{
-       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
-               return false;
-       }
-       if(!state_fio->StateCheckInt32(this_device_id)) {
-               return false;
-       }
-       state_fio->StateValue(wait_val);
-       return true;
-}
 
 }
index 2f14430..c401137 100644 (file)
@@ -23,7 +23,7 @@ public:
        ~MSDOSROM() {}
 
        void initialize();
-
+       uint32_t read_data8(uint32_t addr);     
 };
 
 }
index 31a67a0..074b9f7 100644 (file)
 
 namespace FMTOWNS {
 enum {
-       EVENT_CRTC_VSTART = 0,
+       EVENT_CRTC_VSTART = 1,
        EVENT_CRTC_VST1   = 2,
-       EVENT_CRTC_VST2   = 4,
-       EVENT_CRTC_VDS    = 6,
-       EVENT_CRTC_VDE    = 8,
-       EVENT_CRTC_HSTART = 10,
-       EVENT_CRTC_HEND   = 12,
-       EVENT_CRTC_HSW    = 14,
+       EVENT_CRTC_VST2   = 3,
+       EVENT_CRTC_HSTART = 4,
+       EVENT_CRTC_HEND   = 5,
+       EVENT_CRTC_HSW    = 6,
+       EVENT_CRTC_EET    = 7,
+       EVENT_CRTC_VDS    = 32,
+       EVENT_CRTC_VDE    = 34,
+       EVENT_CRTC_HDS    = 36,
+       EVENT_CRTC_HDE    = 38,
+       
 };
 
 
@@ -112,137 +116,292 @@ void TOWNS_CRTC::set_crtc_clock(uint16_t val)
 {
        scsel = (val & 0x0c) >> 2;
        clksel = val & 0x03;
-       const double clocks[] = {
+       static const double clocks[] = {
                28.6363e6, 24.5454e6, 25.175e6, 21.0525e6
        };
        if(crtc_clock[clksel] != crtc_clock) {
                crtc_clock = crtc_clock[clksel];
-               force_recalc_crtc_param(-1);
+               force_recalc_crtc_param();
        }
 }
 
-void TOWNS_CRTC::set_crtc_hsw1(void)
-{
-       int val = (int)(regs[ch + TOWNS_CRTC_REG_HSW1] & 0x0fff);
-       horiz_width_posi_us = horiz_us * (double)val;
-       // Update
-}
-void TOWNS_CRTC::set_crtc_hsw2(void)
+void TOWNS_CRTC::force_recalc_crtc_param(void)
 {
-       int val = (int)(regs[TOWNS_CRTC_REG_HSW2] & 0x0fff);
-       horiz_width_nega_us = horiz_us * (double)val;
-       // Update
-}
+       horiz_width_posi_us = crtc_clock * ((double)(regs[0] & 0x00fe)); // HSW1
+       horiz_width_nega_us = crtc_clock * ((double)(regs[1] & 0x00fe)); // HSW2
+       horiz_us = crtc_clock * ((double)((regs[4] & 0x07fe) + 1)); // HST
+       vsync_pre_us = ((double)(regs[5] & 0x1f)) * horiz_us; // VST1
 
-void TOWNS_CRTC::set_crtc_hst(void)
-{
-       int val = (int)(regs[TOWNS_CRTC_REG_HST] & 0x07ff) | 1;
-       next_horiz_us = (double)(val + 1) * 1.0 / crtc_clock;
-       // Update
+       double horiz_ref = horiz_us / 2.0;
+       
+       vst2_us = ((double)(regs[6] & 0x1f)) * horiz_ref; // VST2
+       eet_us = ((double)(regs[7] & 0x1f)) * horiz_ref;  // EET
+       frame_us = ((double)(regs[8] & 0x07ff)) * horiz_ref; // VST
+
+       for(int layer = 0; layer < 2; layer++) {
+               vert_start_us[layer] =  ((double)(regs[(layer << 1) + 13] & 0x07ff)) * horiz_ref;   // VDSx
+               vert_end_us[layer] =    ((double)(regs[(layer << 1) + 13 + 1] & 0x07ff)) * horiz_ref; // VDEx
+               horiz_start_us[layer] = ((double)(regs[(layer << 1) + 9] & 0x07ff)) * crtc_clock ;   // HDSx
+               horiz_end_us[layer] =   ((double)(regs[(layer << 1) + 9 + 1] & 0x07ff)) * crtc_clock ;   // HDEx
+       }
+               
 }
 
-void TOWNS_CRTC::set_crtc_vst1(void)
+
+void TONWS_CRTC::write_io8(uint32_t addr, uint32_t data)
 {
-       int val = (int)regs[TOWNS_CRTC_REG_VST1];
-       vert_sync_pre_us = ((double)val * horiz_us) / 2.0;
+       if(addr == 0x0440) {
+               ch = data & 0x1f;
+       } else if(addr == 0x0442) {
+               pair16_t rdata;
+               rdata.w = regs[ch];
+               rdata.l = (uint8_t)data;
+               write_io16(addr, rdata.w);
+       } else if(addr == 0x0443) {
+               pair16_t rdata;
+               rdata.w = regs[ch];
+               rdata.h = (uint8_t)data;
+               write_io16(addr, rdata.w);
+       }               
 }
 
-void TOWNS_CRTC::set_crtc_vst2(void)
+void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data)
 {
-       int val = (int)regs[TOWNS_CRTC_REG_VST2];
-       vert_sync_end_us = ((double)val * horiz_us) / 2.0;
+       if((addr & 0xfffe) == 0x0442) {
+               if(ch < 32) {
+                       if((ch < 0x09) && ((ch >= 0x04) || (ch <= 0x01))) { // HSW1..VST
+                               if(regs[ch] != (uint16_t)data) {
+                                       force_recalc_crtc_param();
+                               }
+                       } else if(ch < 0x11) { // HDS0..VDE1
+                               uint8_t localch = ((ch  - 0x09) / 2) & 1;
+                               if(regs[ch] != (uint16_t)data) {
+                                       timing_changed[localch] = true;
+                                       // ToDo: Change render parameter within displaying.
+                                       force_recalc_crtc_param();
+                               }
+                       }else if(ch < 0x19) { // FA0..LO1
+                               uint8_t localch = (ch - 0x11) / 4;
+                               uint8_t localreg = (ch - 0x11) & 3;
+                               if(regs[ch] != (uint16_t)data) {
+                                       address_changed[localch] = true;
+                                       switch(localreg) {
+                                       case 0: // FAx
+                                               vstart_addr[localch] = (uint32_t)(data & 0xffff);
+                                               break;
+                                       case 1: // HAJx
+                                               hstart_words[localch] = (uint32_t)(data & 0x07ff);
+                                               break;
+                                       case 2: // FOx
+                                               frame_offet[localch] = (uint32_t)(data & 0xffff);
+                                               break;
+                                       case 3: // LOx
+                                               line_offet[localch] = (uint32_t)(data & 0xffff);
+                                               break;
+                                       }                                       
+                               }
+                       } else  { // All reg
+                               if(regs[ch] != (uint16_t)data) {
+                                       switch(ch - 0x19) {
+                                       case 0: // EHAJ
+                                       case 1: // EVAJ
+                                               // ToDo: External SYNC.
+                                               break;
+                                       case 2: // ZOOM
+                                               {
+                                                       uint8_t zfv[2];
+                                                       uint8_t zfh[2];
+                                                       pair16_t pd;
+                                                       pd.w = (uint16_t)data;
+                                                       zfv[0] = ((pd.l & 0xf0) >> 4) + 1;
+                                                       zfh[0] = (pd.l & 0x0f) + 1;
+                                                       zfv[1] = ((pd.h & 0xf0) >> 4) + 1;
+                                                       zfh[1] = (pd.h & 0x0f) + 1;
+                                                       if((zfv[0] != zoom_factor_vert[0]) || (zfh[0] != zoom_factor_horiz[0])) {
+                                                               timing_changed[0] = true;
+                                                               address_changed[0] = true;
+                                                               if(zfv[0] != zoom_factor_vert[0]) zoom_count_vert[0] = zfv[0];
+                                                       }
+                                                       if((zfv[1] != zoom_factor_vert[1]) || (zfh[1] != zoom_factor_horiz[1])) {
+                                                               timing_changed[0] = true;
+                                                               address_changed[0] = true;
+                                                               if(zfv[1] != zoom_factor_vert[1]) zoom_count_vert[1] = zfv[1];
+                                                       }
+                                                       zoom_factor_vert[0]  = zfv[0];
+                                                       zoom_factor_horiz[0] = zfh[0];
+                                                       zoom_factor_vert[1]  = zfv[1];
+                                                       zoom_factor_horiz[1] = zfh[1];
+                                               }
+                                               break;
+                                       case 3: // CR0
+                                               if(regs[ch] != data) {
+                                                       if((data & 0x8000) == 0) {
+                                                               // START BIT
+                                                               restart_display();
+                                                       } else {
+                                                               stop_display();
+                                                       }
+                                                       if((data & 0x4000) == 0) {
+                                                               // ESYN BIT
+                                                               // EXTERNAL SYNC OFF
+                                                       } else {
+                                                               // EXTERNAL SYNC ON
+                                                       }
+                                                       impose_mode[1]  = ((data & 0x0080) == 0);
+                                                       impose_mode[0]  = ((data & 0x0040) == 0);
+                                                       carry_enable[1] = ((data & 0x0020) != 0);
+                                                       carry_enable[0] = ((data & 0x0010) != 0);
+                                                       uint8_t dmode[2];
+                                                       dmode[0] = data & 0x03;
+                                                       dmode[1] = (data & 0x0c) >> 2;
+                                                       for(int i = 0; i < 2; i++) {
+                                                               if(dmode[0] != display_mode[0]) {
+                                                                       mode_changed[0] = true;
+                                                                       notify_mode_changed(i, dmode[i]);
+                                                               }
+                                                               display_mode[i] = dmode[i];
+                                                       }
+                                               }
+                                               break;
+                                       case 4: // CR1
+                                               set_crtc_clock((uint16_t)data);
+                                               break;
+                                       case 5: // Reserved(REG#30)
+                                               break;
+                                       case 6: // CR2
+                                               // ToDo: External trigger.
+                                               break;
+                                       }
+                               }
+                       }
+                       regs[ch] = (uint16_t)data;
+               }
+       } else if(addr == 0x0440) {
+               ch = data & 0x1f;
+       }
 }
 
-void TOWNS_CRTC::set_crtc_vst2(void)
+uint16_t TOWNS_CRTC::read_reg30()
 {
-       int val = (int)regs[TOWNS_CRTC_REG_VST];
-       next_vert_us = ((double)val * horiz_us) / 2.0;
+       uint16_t data = 0x00f0;
+       data |= ((frame_in[1])   ?  0x8000 : 0);
+       data |= ((frame_in[0])   ?  0x4000 : 0);
+       data |= ((hdisp[1])      ?  0x2000 : 0);
+       data |= ((hdisp[0])      ?  0x1000 : 0);
+       //data |= ((eet)          ?  0x0800 : 0);
+       data |= ((vsync)         ?  0x0400 : 0);
+       data |= (!(hsync)        ?  0x0200 : 0);
+       //data |= ((video_in)     ? 0x0100 : 0);
+       //data |= ((half_tone)    ? 0x0008 : 0);
+       //data |= ((sync_enable)  ? 0x0004 : 0);
+       //data |= ((vcard_enable) ? 0x0002 : 0);
+       //data |= ((sub_carry)    ? 0x0001 : 0);
+       
 }
 
-void TOWNS_CRTC::write_io8(uint32_t addr, uint32_t data)
+uint32_t TOWNS_CRTC::read_io16(uint32_t addr)
 {
-       if(addr & 1) {
-               if(ch < 32) {
-                       if(ch < 16 && regs[ch] != data) {
-                               timing_changed = true;
-                       }
-                       regs[ch] = data;
-                       regs_written[ch] = true;
+       addr = addr & 0xfffe;
+       if(addr == 0x0440) {
+               return (uint32_t)ch;
+       } else if(addr == 0x0442) {
+               if(ch == 30) {
+                       return (uint32_t)read_reg30();
+               } else {
+                       return regs[ch];
                }
-       } else {
-               ch = data;
        }
+       return 0xffff;
 }
 
 uint32_t TOWNS_CRTC::read_io8(uint32_t addr)
 {
-       if(addr & 1) {
-               return (12 <= ch && ch < 18) ? regs[ch] : 0xff;
-       } else {
-               return ch;
+       if(addr == 0x0440) {
+               return (uint32_t)ch;
+       } else if(addr == 0x0442) {
+               pair16_t d;
+               if(ch == 30) {
+                       d.w = read_reg32();
+               } else {
+                       d.w = regs[ch];
+               }
+               return (uint32_t)(d.l);
+       } else if(addr == 0x0443) {
+               pair16_t d;
+               if(ch == 30) {
+                       d.w = read_reg32();
+               } else {
+                       d.w = regs[ch];
+               }
+               return (uint32_t)(d.h);
        }
+       return 0xff;
 }
 
-
-void TOWNS_CRTC::event_pre_frame()
+// Note: This entry 
+void TOWNS_CRTC::event_line_per_layer(int display_line, int layer)
 {
-       if(timing_changed) {
-               if(regs_written[0] && regs_written[1] && regs_written[2] && regs_written[3] && regs_written[4] && regs_written[5] && regs_written[6] && regs_written[7] && regs_written[9]) {
-                       int ch_height = (regs[9] & 0x1f) + 1;
-                       
-                       hz_total = regs[0] + 1;
-                       hz_disp = regs[1];
-                       hs_start = regs[2];
-                       hs_end = hs_start + (regs[3] & 0x0f);
-                       
-                       int new_vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f);
-                       vt_disp = (regs[6] & 0x7f) * ch_height;
-                       vs_start = ((regs[7] & 0x7f) + 1) * ch_height;
-                       vs_end = vs_start + ((regs[3] & 0xf0) ? (regs[3] >> 4) : 16);
-                       
-                       if(vt_total != new_vt_total) {
-                               vt_total = new_vt_total;
-                               set_lines_per_frame(vt_total);
-                       }
-                       timing_changed = false;
-                       disp_end_clock = 0;
-#if defined(TOWNS_CRTC_CHAR_CLOCK)
-                       char_clock = 0;
-#elif defined(TOWNS_CRTC_HORIZ_FREQ)
-                       horiz_freq = 0;
-#endif
-               }
-       }
-#if defined(TOWNS_CRTC_CHAR_CLOCK)
-       if(char_clock != next_char_clock) {
-               char_clock = next_char_clock;
-               frames_per_sec = char_clock / (double)vt_total / (double)hz_total;
-               if(regs[8] & 1) {
-                       frames_per_sec *= 2; // interlace mode
-               }
-               set_frames_per_sec(frames_per_sec);
+       uint32_t startaddr;
+       if(display_line < 0) return;
+       
+       layer = layer & 1;
+       if((one_layer_mode) && (layer != 0)) {
+               d_vram->write_signal(SIG_TOWNS_VRAM_DONT_RENDER, (layer << 24) | ((uint32_t)display_line), 0x100fffff);
+               return; // Not render.
        }
-#elif defined(TOWNS_CRTC_HORIZ_FREQ)
-       if(horiz_freq != next_horiz_freq) {
-               horiz_freq = next_horiz_freq;
-               frames_per_sec = horiz_freq / (double)vt_total;
-               if(regs[8] & 1) {
-                       frames_per_sec *= 2; // interlace mode
+       zoom_count_vert[layer]--;
+       if((zoom_count_vert[layer] == 0) || (display_line == 0)) {
+               int vline = vram_line[layer];
+               
+               startaddr = vstart_addr[layer];
+               if(zoom_count_vert[layer] == 0) vram_line[layer]++;
+               zoom_count_vert[layer] = zoom_factor_vert[layer];
+               
+               uint32_t offset_words = (regs[(layer * 4) + 18] & 0x07ff) - (regs[(layer * 2) + 9] & 0x07ff); // HAJx - HDSx
+               uint32_t offset_per_line = line_offset[layer];
+               uint32_t draw_width  = (regs[0x09 + layer * 2 + 1] & 0x07ff) - (regs[0x09 + layer * 2 + 0] & 0x07ff); // HDEx-HDSx
+               
+               // ToDo: Interlace mode
+               if(one_layer_mode) {
+                       offset_per_line = offset_per_line * 4 * 2; // 4Words.
+                       offset_words    = offset_words    * 4 * 2; // 4Words.
+               } else {
+                       offset_per_line = offset_per_line * 2 * 2; // 2Words.
+                       offset_words    = offset_words    * 2 * 2; // 2Words.
                }
-               set_frames_per_sec(frames_per_sec);
+
+               startaddr = startaddr + offset_per_line * vline;
+       
+               d_vram->write_signal(SIG_TOWNS_VRAM_SET_PARAM,  layer, 0x1); // Begin modify rendering factor
+               d_vram->write_signal(SIG_TOWNS_VRAM_PIX_COUNT,  draw_width, 0xfffffff); // Pixel count
+               d_vram->write_signal(SIG_TOWNS_VRAM_START_ADDR, startaddr, 0xffffffff); // VRAM START ADDRESS
+               d_vram->write_signal(SIG_TOWNS_VRAM_HZOOM, zoom_factor_horiz[layer], 0x0f); // HZOOM factor
+//             d_vram->write_signal(SIG_TOWNS_VRAM_VZOOM, zoom_factor_vert[layer], 0x0f); // OFFSET WORD
+               d_vram->write_signal(SIG_TOWNS_VRAM_OFFSET_WORDS, offset_words, 0xffffffff); // OFFSET WORD
+       } else {
+               d_vram->write_signal(SIG_TOWNS_VRAM_KEEP_PARAM, layer, 0x1); // Begin modify rendering factor
+       }       
+       if(!(frame_in[layer])) {
+               d_vram->write_signal(SIG_TOWNS_VRAM_DONT_RENDER, (layer << 24) | ((uint32_t)display_line), 0x100fffff);
+       } else {
+               d_vram->write_signal(SIG_TOWNS_VRAM_DO_RENDER, (layer << 24) | ((uint32_t)display_line), 0x100fffff);
+       }               
+       if(!(carry_enable[layer])) {
+               vram_line[layer] = vram_line[layer] & 0x00ff;
        }
-#endif
+}
+
+void TOWNS_CRTC::event_pre_frame()
+{
+       // ToDo: Resize frame buffer.
 }
 
 void TOWNS_CRTC::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame)
 {
        cpu_clocks = new_clocks;
-#if !defined(TOWNS_CRTC_CHAR_CLOCK) && !defined(TOWNS_CRTC_HORIZ_FREQ)
        frames_per_sec = new_frames_per_sec;
-#endif
-       
-       // update event clocks
-       disp_end_clock = 0;
+       max_lines = new_lines_per_frame;
+       max_frame_usec = 1.0e6 / frames_per_sec;
 }
 
 void TOWNS_CRTC::event_callback(int event_id, int err)
@@ -259,120 +418,137 @@ void TOWNS_CRTC::event_callback(int event_id, int err)
         * ZOOM (#27) : ToDo
         */
        int eid2 = (event_id / 2) * 2;
-       if(eid2 == EVENT_CRTC_VSTART) {
+       if(event_id == EVENT_CRTC_VSTART) {
+               d_vram->write_signal(SIG_TOWNS_VRAM_VSTART, 0x01, 0x01);
                line_count[0] = line_count[1] = 0;
                if((horiz_us != next_horiz_us) || (vert_us != next_vert_us)) {
                        horiz_us = next_horiz_us;
                        vert_us = next_vert_us;
-                       force_recalc_crtc_param(-1);
-                       if(event_id_vsync >= 0) cancel_event(this, event_id_vsync);
-                       if(event_id_hsw >= 0) cancel_event(this, event_id_hsw);
-                       
-                       register_event(this, EVENT_CRTC_HSTART + 0, vert_sync_pre_us, false, &event_id_hsw); // HSW = HSYNC
-                       register_event(this, EVENT_CRTC_VSTART + 0, vert_us, true, &event_id_vsync); // VST
                }
-               frame_in[0] = frame_in[1] = false;
-               line_count[0] = line_count[1] = 0;
-               line_count_mod[0] = line_count_mod[1] = 0;
                hsync = false;
-               hdisp = false;
-               vdisp = true;
-               vblank = true;
-               vsync = false;
+               for(int i = 0; i < 2; i++) {
+                       hdisp[i] = false;
+               }
                major_line_count = -1;
-               register_event(this, EVENT_CRTC_VST1 + 0, vert_sync_pre_us, false, &event_id_vstn); // VST1
-               register_event(this, EVENT_CRTC_VDS + 0, vert_start_us[0], false, &event_id_vstart[0]); // VDS0 : Layer1
-               register_event(this, EVENT_CRTC_VDS + 1, vert_start_us[1], false, &event_id_vstart[1]); // VDS1 : Layer2
-       } else if(eid2 == EVENT_CRTC_VST1) {
-               vsync = true;
-               if(vert_sync_end_us > 0.0) {
-                       register_event(this, EVENT_CRTC_VST2 + 0, vert_sync_end_us, false, &event_id_vstn); // VST2 - VST1.
-               } else {
+               // ToDo: EET
+               register_event(this, EVENT_CRTC_VSTART, frame_us, false, &event_id_frame);
+               if(vert_sync_pre_us >= 0.0) {
                        vsync = false;
+                       register_event(this, EVENT_CRTC_VST1, vert_sync_pre_us, false, &event_id_vst1); // VST1
+               } else {
+                       vsync = true;
                }
-       } else if (eid2 == EVENT_CRTC_VST2) {
+               register_event(this, EVENT_CRTC_VST2, vst2_us, false, &event_id_vst2);
+               for(int i = 0; i < 2; i++) {
+                       frame_in[i] = false;
+                       if(event_id_vds[i] != -1) {
+                               cancel_event(this, event_id_vds[i]);
+                       }
+                       if(event_id_vde[i] != -1) {
+                               cancel_event(this, event_id_vde[i]);
+                       }
+                       if(vert_start_us[i] > 0.0) {
+                               register_event(this, EVENT_CRTC_VDS + i, vert_start_us[i], false, &event_id_vds[i]); // VDSx
+                       } else {
+                               frame_in[i] = true;
+                       }
+                       if(vert_end_us[i] > 0.0) {
+                               register_event(this, EVENT_CRTC_VDE + i, vert_end_us[i],   false, &event_id_vde[i]); // VDEx
+                       }
+               }
+               
+               if(event_id_hstart != -1) {
+                       cancel_event(this, event_id_hstart);
+                       event_id_hstart = -1;
+               }
+               if(event_id_hsw != -1) {
+                       cancel_event(this, event_id_hsw);
+                       event_id_hsw = -1;
+               }
+       } else if(event_id == EVENT_CRTC_VST1) { // VSYNC
+               vsync = true;
+       } else if (event_id == EVENT_CRTC_VST2) {
                vsync = false;
-               vblank = false;
                event_id_vstn = -1;
        } else if(eid2 == EVENT_CRTC_VDS) { // Display start
                int layer = event_id & 1;
                frame_in[layer] = true;
                // DO ofset line?
-               if(event_id_vend[layer] >= 0) cancel_event(this, event_id_vend[layer]);
-               register_event(this, EVENT_CRTC_VDE + layer, vert_start_us[0], false, &event_id_vend[layer]); // VDEx
                event_id_vstart[layer] = -1;
        } else if(eid2 == EVENT_CRTC_VDE) { // Display end
                int layer = event_id & 1;
                frame_in[layer] = false;
-               if(event_id_vstart[layer] >= 0) cancel_event(this, event_id_vstart[layer]);
-               event_id_vstart[layer] = -1;
                event_id_vend[layer] = -1;
                // DO ofset line?
-       } else if(eid2 == EVENT_CRTC_HSTART) {
+       } else if(event_id == EVENT_CRTC_HSTART) {
                // Do render
-               hsync = true;
-               hdisp = false;
+               event_id_hstart = -1;
                major_line_count++;
-               if(vsync) { // in VSYNC. Not Display.
-                       if(event_id_hswn >= 0) cancel_event(this, event_id_hswn);
-                       register_event(this, EVENT_CRTC_HSW + 0, hsw2_us, false, &event_id_hswn); // Indicate HSYNC
-               } else { // Not in VSYNC. May be displaied.
-                       for(layer = 0; layer < 2; layer++) {
-                               if(frame_in[layer] && (major_line_count >= 0) && (major_line_count < TOWNS_CRTC_MAX_LINES)) {
-                                       if((vstart_lines[layer] <= major_line_count) && (vend_lines[layer] => major_line_count)) {
-                                               // Proccessing zooming by ZOOM register(reg #27).
-                                               {
-                                                       // If zoom is not supported by hardware, if first line : render.
-                                                       // Not first: copy (put here?)
-                                               } // else {
-                                               if(line_changed[layer][line_count[layer]]) {
-                                                       {
-                                                               // Do rendering.
-                                                               line_changed[layer][line_count[layer]] = false;
-                                                               line_rendered[layer][line_count[layer]] = true;
-                                                       }
-                                               }
-                                       }
-                                       {
-                                               // If zoom by hardware
-                                               line_count_mod[layer] += line_count_factor[layer]; // line_count_factor[n] = 2048 / VZOOM_FACTOR[01]
-                                               if(line_count_mod[layer] >= 2048) {
-                                                       line_count[layer]++;
-                                                       line_count_mod[layer] -= 2048;
-                                               }
-                                       }
+               hdisp[0] = false;
+               hdisp[1] = false;
+               if(event_id_hsw != -1) {
+                       cancel_event(this, event_id_hsw);
+                       event_id_hsw = -1;
+               }
+               if(!vsync) {
+                       hsync = true;
+                       register_event(this, EVENT_CRTC_HSW, horiz_width_posi_us, false, &event_id_hsw); // VDEx
+               } else {
+                       hsync = true;
+                       register_event(this, EVENT_CRTC_HSW, horiz_width_nega_us, false, &event_id_hsw); // VDEx
+               }
+               for(int i = 0; i < 2; i++) {
+                       if(event_id_hds[i] != -1) {
+                               cancel_event(this, event_id_hds[i]);
+                       }
+                       event_id_hds[i] = -1;
+                       if(event_id_hde[i] != -1) {
+                               cancel_event(this, event_id_hde[i]);
+                       }
+                       event_id_hde[i] = -1;
+                       
+                       if(horiz_start_us[i] > 0.0) {
+                               register_event(this, EVENT_CRTC_HDS + i, horiz_start_us[i], false, &event_id_hds[i]); // HDS0
+                       } else {
+                               hdisp[i] = true;
+                               if(!vsync) {
+                                       event_line_per_layer(major_line_count, layer);
                                }
                        }
-                       if(event_id_hswn >= 0) cancel_event(this, event_id_hswn);
-                       register_event(this, EVENT_CRTC_HSW + 0, hsw1_us, false, &event_id_hswn); // Indicate HSYNC
+                       if((horiz_end_us[i] > 0.0) && (horiz_end_us[i] > horiz_start_us[i])) {
+                               register_event(this, EVENT_CRTC_HDE + i, horiz_end_us[i], false, &event_id_hde[i]); // HDS0
+                       }
                }
-       } else if(eid2 == EVENT_CRTC_HSW) {
+
+               register_event(this, EVENT_CRTC_HSTART, horiz_us, false, &event_id_hstart); // HSTART
+       } else if(event_id == EVENT_CRTC_HSW) {
+               hsync = false;
+               event_id_hsw = -1;
+       } else if(eid2 == EVENT_CRTC_HDS) {
+               int layer = event_id & 1;
+               hdisp[layer] = true;
                if(!vsync) {
-                       hdisp = true;
+                       event_line_per_layer(major_line_count, layer);
                }
-               hsync = false;
+               if((horiz_end_us[i] <= 0.0) || (horiz_end_us[i] <= horiz_start_us[i])) {
+                       hdisp[layer] = false;
+               }
+               event_id_hds[layer] = -1;
+       } else if(eid2 == EVENT_CRTC_HDE) {
+               int layer = event_id & 1;
+               hdisp[layer] = false;   
+               event_id_hde[layer] = -1;
        }
 
 }
 
-void TOWNS_CRTC::set_display(bool val)
+void TOWNS_CRTC::write_signal(int ch, uint32_t data, uint32_t mask)
 {
-       if(display != val) {
-               write_signals(&outputs_disp, val ? 0xffffffff : 0);
-               display = val;
+       if(ch == SIG_TONWS_CRTC_SINGLE_LAYER) {
+               one_layer_mode = ((data & mask) == 0);
        }
 }
 
-void TOWNS_CRTC::set_vblank(bool val)
-{
-       if(vblank != val) {
-               write_signals(&outputs_vblank, val ? 0xffffffff : 0);
-               vblank = val;
-       }
-}
-
-
-
 #define STATE_VERSION  1
 
 void TOWNS_CRTC::save_state(FILEIO* state_fio)
index 16d2e16..f1733bc 100644 (file)
@@ -125,6 +125,13 @@ namespace FMTOWNS {
                TOWNS_CRTC_REG_DUMMY, // 30
                TOWNS_CRTC_REG_CTRL, // 31
        };
+
+       enum {
+               DISPMODE_NONE = 0,
+               DISPMODE_32768_2,
+               DISPMODE_32768_1,
+               DISPMODE_256_OR_16,
+       };
 }
 
 namespace FMTOWNS {
@@ -134,13 +141,14 @@ private:
        // output signals
        outputs_t outputs_int_vsync;  // Connect to int 11.
        uint16_t regs[32];      // I/O 0442H, 0443H
-       bool regs_written[32];
-       uint8_t reg_ch;         // I/O 0440H
-       bool timing_changed;
-
-       // Not include around video input/dizitize features yet.
-       bool line_changed[2][TOWNS_CRTC_MAX_LINES];
-
+       uint8_t ch;         // I/O 0440H
+       bool timing_changed[2];
+       bool address_changed[2];
+       bool mode_changed[2];
+       
+       uint8_t display_mode[2]; 
+       bool display_enabled;
+       
        double crtc_clock; // 
        // They are not saved.Must be calculate when loading.
        double horiz_us, next_horiz_us; // (HST + 1) * clock
@@ -152,14 +160,18 @@ private:
        // End
 
        double frames_per_sec;
-       
+
+       uint32_t vstart_addr[2];  // VSTART ADDRESS
     uint32_t hstart_words[2]; // HSTART ((HDS[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
     uint32_t hend_words[2];   // HEND   ((HDE[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
     uint32_t vstart_lines[2]; // VSTART ((VDS[01] * clock) : Horizonal offset words (Related by VH[01]).
     uint32_t vend_lines[2];   // VEND   ((VDE[01] * clock) : Horizonal offset words (Related by VH[01]).
-
-       uint32_t zoom_factor_vert; // Related display resolutions of two layers and zoom factors. Multiplied by 1024.
-       uint32_t zoom_factor_horiz; // Related display resolutions of two layers and zoom factors. Multiplied by 1024.
+       uint32_t frame_offset[2]; // FO.
+       uint32_t vram_line[2];
+       
+       uint8_t zoom_factor_vert[2]; // Related display resolutions of two layers and zoom factors.
+       uint8_t zoom_factor_horiz[2]; // Related display resolutions of two layers and zoom factors.
+       uint8_t zoom_count_vert[2];
        
        uint32_t line_count[2]; // Separate per layer.
        
index 6fbe549..4c7fd91 100644 (file)
@@ -35,7 +35,6 @@ void DICTIONARY::initialize()
        }
        delete fio;
 
-       wait_val = 3;
        dict_bank = 0;
        bankd0_dict = false;
 }
@@ -54,7 +53,6 @@ void DICTIONARY::release()
 
 void DICTIONARY::reset()
 {
-       //wait_val = 6; // OK?
        dict_bank = 0;
        bankd0_dict = false;
        
@@ -140,42 +138,6 @@ void DICTIONARY::write_data32(uint32_t addr, uint32_t data)
        write_data8(addr + 3, n.h3);
 }
 
-uint32_t DICTIONARY::read_data8w(uint32_t addr, int *wait)
-{
-       if(wait != NULL) *wait = wait_val;
-       return read_data8(addr, data);
-}
-
-uint32_t DICTIONARY::read_data16w(uint32_t addr, int *wait)
-{
-       if(wait != NULL) *wait = wait_val * 2;
-       return read_data16(addr, data);
-}
-
-uint32_t DICTIONARY::read_data32w(uint32_t addr, int *wait)
-{
-       if(wait != NULL) *wait = wait_val * 4;
-       return read_data32(addr, data);
-}
-
-
-void DICTIONARY::write_data8w(uint32_t addr, uint32_t data, int *wait)
-{
-       if(wait != NULL) *wait = wait_val;
-       write_data8(addr, data);
-}
-
-void DICTIONARY::write_data16w(uint32_t addr, uint32_t data, int *wait)
-{
-       if(wait != NULL) *wait = wait_val * 2;
-       write_data16(addr, data);
-}
-
-void DICTIONARY::write_data32w(uint32_t addr, uint32_t data, int *wait)
-{
-       if(wait != NULL) *wait = wait_val * 4;
-       write_data32(addr, data);
-}
 
 void DICTIONARY::write_io8(uint32_t addr, uint32_t data)
 {
@@ -222,9 +184,6 @@ void DICTIONARY::write_signal(int ch, uint32_t data, uint32_t mask)
        case SIG_FMTOWNS_DICTBANK:
                dict_bank = (uint8_t)(data & 0x0f);
                break;
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               wait_val = (int)data;
-               break;
        }
 }
 
@@ -237,9 +196,6 @@ uint32_t DICTIONARY::read_signal(int ch)
        case SIG_FMTOWNS_DICTBANK:
                return (uint32_t)(dict_bank & 0x0f);
                break;
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               return (uinrt32_t)wait_val;
-               break;
        }
        return 0x00;
 }
@@ -254,7 +210,6 @@ bool DICTIONARY::process_state(FILEIO* state_fio, bool loading)
        if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
-       state_fio->StateValue(wait_val);
        state_fio->StateValue(dict_bank);
        state_fio->StateValue(bankd0_dict);
        state_fio->StateArray(dict_ram, sizeof(dict_ram), 1);
index 1ed8f3b..4c97025 100644 (file)
@@ -28,7 +28,6 @@ protected:
 
        bool bankd0_dict;
        uint8_t dict_bank;
-       int wait_val;
 
        bool cmos_dirty;
 
@@ -46,18 +45,10 @@ public:
        uint32_t read_data16(uint32_t addr);
        uint32_t read_data32(uint32_t addr);
 
-       uint32_t read_data8w(uint32_t addr, int* wait);
-       uint32_t read_data16w(uint32_t addr, int* wait);
-       uint32_t read_data32w(uint32_t addr, int* wait);
-
        void write_data8(uint32_t addr, uint32_t data);
        void write_data16(uint32_t addr, uint32_t data);
        void write_data32(uint32_t addr, uint32_t data);
 
-       void write_data8w(uint32_t addr, uint32_t data, int* wait);
-       void write_data16w(uint32_t addr, uint32_t data, int* wait);
-       void write_data32w(uint32_t addr, uint32_t data, int* wait);
-
        void write_io8(uint32_t addr, uint32_t data);
        void read_io8(uint32_t addr, uint32_t data);
 
index 5be5ddb..ba9ac3e 100644 (file)
@@ -24,15 +24,12 @@ void SYSROM::initialize()
                fio->Fread(rom, sizeof(rom), 1);
                fio->Fclose();
        }
-       
-       wait_val = 3;
        map_dos = true;
 }
 
 
 void SYSROM::reset()
 {
-       //wait_val = 6; // OK?
        //map_dos = true;
 }
 
@@ -74,9 +71,6 @@ void SYSROM::write_signal(int ch, uint32_t data, uint32_t mask)
        case SIG_FMTOWNS_SYSROMSEL:
                map_dos = ((data & mask) == 0);
                break;
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               wait_val = (int)data;
-               break;
        }
 }
 
@@ -86,24 +80,9 @@ uint32_t SYSROM::read_signal(int ch)
        case SIG_FMTOWNS_SYSROMSEL:
                return ((map_dos) ? 0x00 : 0x02);
                break;
-       case SIG_FMTOWNS_SET_MEMWAIT:
-               return (uint32_t)wait_val;
-               break;
        }
        return 0x00;
 }
-       
-uint32_t SYSROM::read_data8w(uint32_t addr, int *wait)
-{
-       if(wait != NULL) *wait = wait_val;
-       return read_data8(addr, data);
-}
-
-void SYSROM::write_data8w(uint32_t addr, uint32_t data, int *wait)
-{
-       if(wait != NULL) *wait = wait_val;
-       write_data8(addr, data);
-}
 
 #define STATE_VERSION  1
 
@@ -115,7 +94,6 @@ bool SYSROM::process_state(FILEIO* state_fio, bool loading)
        if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
-       state_fio->StateValue(wait_val);
        state_fio->StateValue(map_dos);
        state_fio->StateArray(ram, sizeof(ram), 1);
        return true;
index 86d5dee..b3b33d8 100644 (file)
@@ -21,8 +21,7 @@ class SYSROM : public DEVICE
 protected:
        uint8_t rom[0x40000]; // 256KB
        uint8_t ram[0x10000];  // 64KB
-       int wait_val;
-
+       
        bool map_dos;
 
 public:
@@ -35,10 +34,8 @@ public:
        void reset();
 
        uint32_t read_data8(uint32_t addr);
-       uint32_t read_data8w(uint32_t addr, int* wait);
 
        void write_data8(uint32_t addr, uint32_t data);
-       void write_data8w(uint32_t addr, uint32_t data, int* wait);
 
        void write_signal(int ch, uint32_t data, uint32_t mask);
        uint32_t read_signal(int ch);