2 SHARP X1 Emulator 'eX1'
3 SHARP X1twin Emulator 'eX1twin'
4 SHARP X1turbo Emulator 'eX1turbo'
5 SHARP X1turboZ Emulator 'eX1turboZ'
7 Author : Takeda.Toshiya
15 #ifdef _X1TURBO_FEATURE
16 #include "io_wait_hireso.h"
23 #define AEN ((zmode1 & 0x80) != 0)
24 #define APEN ((zmode2 & 0x80) != 0)
25 #define APRD ((zmode2 & 0x08) != 0)
28 void IOBUS::initialize()
30 prev_clock = vram_wait_index = 0;
36 memset(vram, 0, sizeof(vram));
37 vram_b = vram + 0x0000;
38 vram_r = vram + 0x4000;
39 vram_g = vram + 0x8000;
40 vram_mode = signal = false;
42 #ifdef _X1TURBO_FEATURE
43 memset(crtc_regs, 0, sizeof(crtc_regs));
49 void IOBUS::write_signal(int id, uint32_t data, uint32_t mask)
52 bool next = ((data & 0x20) != 0);
57 column40 = ((data & 0x40) != 0);
60 void IOBUS::write_io8w(uint32_t addr, uint32_t data, int* wait)
62 write_port8(addr, data, false, wait);
65 uint32_t IOBUS::read_io8w(uint32_t addr, int* wait)
67 return read_port8(addr, false, wait);
70 void IOBUS::write_dma_io8w(uint32_t addr, uint32_t data, int* wait)
72 write_port8(addr, data, true, wait);
75 uint32_t IOBUS::read_dma_io8w(uint32_t addr, int* wait)
77 return read_port8(addr, true, wait);
80 void IOBUS::write_port8(uint32_t addr, uint32_t data, bool is_dma, int* wait)
83 switch(addr & 0xc000) {
86 vram_b[addr & 0x3fff] = data;
87 vram_r[addr & 0x3fff] = data;
88 vram_g[addr & 0x3fff] = data;
89 *wait = get_vram_wait();
95 vram_r[addr & 0x3fff] = data;
96 vram_g[addr & 0x3fff] = data;
98 vram_b[addr & 0x3fff] = data;
100 *wait = get_vram_wait();
104 vram_b[addr & 0x3fff] = data;
105 vram_g[addr & 0x3fff] = data;
107 vram_r[addr & 0x3fff] = data;
109 *wait = get_vram_wait();
113 vram_b[addr & 0x3fff] = data;
114 vram_r[addr & 0x3fff] = data;
116 vram_g[addr & 0x3fff] = data;
118 *wait = get_vram_wait();
121 #ifdef _X1TURBO_FEATURE
123 int ofs = (data & 0x10) ? 0xc000 : 0;
124 vram_b = vram + 0x0000 + ofs;
125 vram_r = vram + 0x4000 + ofs;
126 vram_g = vram + 0x8000 + ofs;
127 } else if((addr & 0xff0f) == 0x1800) {
129 } else if((addr & 0xff0f) == 0x1801 && crtc_ch < 18) {
130 crtc_regs[crtc_ch] = data;
132 int ch_height = (crtc_regs[9] & 0x1f) + 1;
133 int vt_total = ((crtc_regs[4] & 0x7f) + 1) * ch_height + (crtc_regs[5] & 0x1f);
134 hireso = (vt_total > 400);
136 } else if(addr == 0x1fb0) {
138 } else if(addr == 0x1fc5) {
146 d_io->write_dma_io8(addr, data & 0xff);
148 d_io->write_io8(addr, data & 0xff);
150 switch(addr & 0xff00) {
152 case 0x1000: // analog palette
155 if(AEN && APEN && !APRD) {
157 *wait = get_vram_wait(); // temporary
163 case 0x1900: // sub cpu
174 uint32_t IOBUS::read_port8(uint32_t addr, bool is_dma, int* wait)
178 switch(addr & 0xc000) {
180 *wait = get_vram_wait();
181 return vram_b[addr & 0x3fff];
183 *wait = get_vram_wait();
184 return vram_r[addr & 0x3fff];
186 *wait = get_vram_wait();
187 return vram_g[addr & 0x3fff];
189 uint32_t val = is_dma ? d_io->read_dma_io8(addr) : d_io->read_io8(addr);;
190 if((addr & 0xff0f) == 0x1a01) {
191 // hack: cpu detects vblank
192 if((vdisp & 0x80) && !(val & 0x80)) {
193 d_display->write_signal(SIG_DISPLAY_DETECT_VBLANK, 1, 1);
197 switch(addr & 0xff00) {
199 case 0x1000: // analog palette
202 if(AEN && APEN && APRD) {
204 *wait = get_vram_wait(); // temporary
210 case 0x1900: // sub cpu
222 int IOBUS::get_vram_wait()
224 vram_wait_index += get_passed_clock(prev_clock);
225 vram_wait_index %= 2112;
226 prev_clock = get_current_clock();
227 #ifdef _X1TURBO_FEATURE
228 int tmp_index = (vram_wait_index + d_cpu->get_extra_clock()) % 2112; // consider dma access
230 return column40 ? vram_wait_40_hireso[tmp_index] : vram_wait_80_hireso[tmp_index];
233 #define tmp_index vram_wait_index
235 return column40 ? vram_wait_40[tmp_index] : vram_wait_80[tmp_index];
238 #define STATE_VERSION 3
240 bool IOBUS::process_state(FILEIO* state_fio, bool loading)
242 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
245 if(!state_fio->StateCheckInt32(this_device_id)) {
248 state_fio->StateBuffer(vram, sizeof(vram), 1);
249 state_fio->StateBool(vram_mode);
250 state_fio->StateBool(signal);
252 vram_b = vram + state_fio->FgetInt32_LE();
253 vram_r = vram + state_fio->FgetInt32_LE();
254 vram_g = vram + state_fio->FgetInt32_LE();
256 state_fio->FputInt32_LE((int)(vram_b - vram));
257 state_fio->FputInt32_LE((int)(vram_r - vram));
258 state_fio->FputInt32_LE((int)(vram_g - vram));
260 state_fio->StateValue(vdisp);
261 state_fio->StateValue(prev_clock);
262 state_fio->StateValue(vram_wait_index);
263 state_fio->StateValue(column40);
264 #ifdef _X1TURBO_FEATURE
265 state_fio->StateArray(crtc_regs, sizeof(crtc_regs), 1);
266 state_fio->StateValue(crtc_ch);
267 state_fio->StateValue(hireso);
269 state_fio->StateValue(zmode1);
270 state_fio->StateValue(zmode2);