2 FUJITSU FM Towns Emulator 'eFMTowns'
4 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
10 #ifndef _TOWNS_MEMORY_H_
11 #define _TOWNS_MEMORY_H_
14 #include "../../common.h"
15 #include "../memory.h"
16 #include "./towns_common.h"
18 #define SIG_FMTOWNS_MACHINE_ID 1
19 #define SIG_MEMORY_EXTNMI 2
22 // 00000000 - 000fffff : SYSTEM RAM PAGE 0 (Similar to FMR-50).
23 // 00100000 - 3fffffff : EXTRA RAM (for i386 native mode.Page size is 1MB.)
24 // 40000000 - 7fffffff : External I/O BOX.Not accessible.
25 // 80000000 - bfffffff : VRAM (Reserved 01020000H bytes with earlier Towns.)
26 // c0000000 - c21fffff : ROM card and dictionaly/font/DOS ROMs.
27 // c2200000 - c2200fff : PCM RAM (Banked).
28 // c2201000 - fffbffff : Reserved.
29 // FFFC0000 - FFFFFFFF : Towns System ROM.
33 TOWNS_MEMORY_NORMAL = 0,
34 TOWNS_MEMORY_FMR_VRAM,
35 TOWNS_MEMORY_FMR_TEXT,
36 TOWNS_MEMORY_FMR_VRAM_RESERVE,
37 TOWNS_MEMORY_SPRITE_ANKCG1,
40 TOWNS_MEMORY_MMIO_0CC,
42 TOWNS_MEMORY_TYPE_EXT_MMIO,
43 TOWNS_MEMORY_TYPE_LEARN_RAM,
44 TOWNS_MEMORY_TYPE_WAVERAM,
47 // Please set from config
48 #define TOWNS_EXTRAM_PAGES 6
60 class TOWNS_MEMORY : public MEMORY
64 DEVICE* d_sprite; // 0x81000000 - 0x8101ffff ?
65 DEVICE* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff
66 DEVICE* d_pcm; // 0xc2200000 - 0xc2200fff
82 outputs_t outputs_ram_wait;
83 outputs_t outputs_rom_wait;
96 uint8_t ram_page0[0xc0000]; // 0x00000000 - 0x000bffff : RAM
97 uint8_t ram_pagec[0x10000]; // 0x000c0000 - 0x000cffff : URA? RAM
98 uint8_t ram_paged[0x10000]; // 0x000d0000 - 0x000dffff : RAM
99 uint8_t ram_pagee[0x10000]; // 0x000e0000 - 0x000effff : RAM
100 uint8_t ram_pagef[0x10000]; // 0x000f0000 - 0x000f8fff : RAM
102 uint8_t *extra_ram; // 0x00100000 - (0x3fffffff) : Size is defined by extram_size;
103 uint32_t extram_size;
104 uint32_t cpu_clock_val;
105 uint32_t vram_wait_val;
106 uint32_t mem_wait_val;
108 uint8_t wait_register;
114 bool nmi_vector_protect;
119 uint32_t vram_size; // Normally 512KB.
122 virtual void set_wait_values();
123 virtual void config_page00();
125 inline uint32_t __FASTCALL read_primitive_byte(uint32_t addr)
127 int bank = (addr & addr_mask) >> addr_shift;
128 if(rd_table[bank].device != NULL) {
129 return rd_table[bank].device->read_memory_mapped_io8(addr);
131 return rd_table[bank].memory[addr & bank_mask];
135 inline uint32_t __FASTCALL read_primitive_word(uint32_t addr)
137 int bank = (addr & addr_mask) >> addr_shift;
139 uint32_t naddr = addr & bank_mask;
142 if((addr & bank_mask) == bank_mask) {
143 if(rd_table[bank].device != NULL) {
144 n.b.l = rd_table[bank].device->read_memory_mapped_io8(addr);
146 n.b.l = rd_table[bank].memory[naddr + 0];
148 n.b.h = read_primitive_byte(addr + 1);
150 if(rd_table[bank].device != NULL) {
151 n.w.l = rd_table[bank].device->read_memory_mapped_io16(addr);
153 n.b.l = rd_table[bank].memory[naddr + 0];
154 n.b.h = rd_table[bank].memory[naddr + 1];
159 inline uint32_t __FASTCALL read_primitive_dword(uint32_t addr)
161 int bank = (addr & addr_mask) >> addr_shift;
163 uint32_t naddr = addr & bank_mask;
165 if((addr & bank_mask) > (bank_mask - 3)) {
168 n.w.l = read_primitive_word(addr + 0);
169 n.w.h = read_primitive_word(addr + 2);
172 n.b.l = read_primitive_byte(addr + 0);
173 n.b.h = read_primitive_byte(addr + 1);
174 n.b.h2 = read_primitive_byte(addr + 2);
175 n.b.h3 = read_primitive_byte(addr + 3);
178 n.w.l = read_primitive_word(addr + 0);
179 n.w.h = read_primitive_word(addr + 2);
182 n.b.l = read_primitive_byte(addr + 0);
183 n.b.h = read_primitive_byte(addr + 1);
184 n.b.h2 = read_primitive_byte(addr + 2);
185 n.b.h3 = read_primitive_byte(addr + 3);
189 } else { // Inside of boundary
190 if(rd_table[bank].device != NULL) {
191 return rd_table[bank].device->read_memory_mapped_io32(addr);
193 n.b.l = rd_table[bank].memory[naddr + 0];
194 n.b.h = rd_table[bank].memory[naddr + 1];
195 n.b.h2 = rd_table[bank].memory[naddr + 2];
196 n.b.h3 = rd_table[bank].memory[naddr + 3];
201 inline void __FASTCALL write_primitive_byte(uint32_t addr, uint32_t data)
203 int bank = (addr & addr_mask) >> addr_shift;
204 // if(addr == 0xd000) {
205 // out_debug_log(_T("WRITE %02X to D000 / DEV=%08X"), data, wr_table[bank].device);
207 if(wr_table[bank].device != NULL) {
208 wr_table[bank].device->write_memory_mapped_io8(addr, data);
210 wr_table[bank].memory[addr & bank_mask] = data;
214 inline void __FASTCALL write_primitive_word(uint32_t addr, uint32_t data)
216 int bank = (addr & addr_mask) >> addr_shift;
218 if(wr_table[bank].device != NULL) {
219 if((addr & bank_mask) == bank_mask) {
222 wr_table[bank].device->write_memory_mapped_io8(addr + 0, n.b.l);
223 write_primitive_byte(addr + 1, n.b.h);
225 wr_table[bank].device->write_memory_mapped_io16(addr, data);
229 uint32_t naddr = addr & bank_mask;
231 if((addr & bank_mask) == bank_mask) {
232 wr_table[bank].memory[naddr + 0] = n.b.l;
233 write_primitive_byte(addr + 1, n.b.h);
235 wr_table[bank].memory[naddr + 0] = n.b.l;
236 wr_table[bank].memory[naddr + 1] = n.b.h;
240 inline void __FASTCALL write_primitive_dword(uint32_t addr, uint32_t data)
242 int bank = (addr & addr_mask) >> addr_shift;
243 uint32_t naddr = addr & bank_mask;
246 if((addr & bank_mask) <= (bank_mask - 3)) {
247 if(wr_table[bank].device != NULL) {
248 wr_table[bank].device->write_memory_mapped_io32(addr, data);
250 wr_table[bank].memory[naddr + 0] = n.b.l;
251 wr_table[bank].memory[naddr + 1] = n.b.h;
252 wr_table[bank].memory[naddr + 2] = n.b.h2;
253 wr_table[bank].memory[naddr + 3] = n.b.h3;
259 write_primitive_word(addr + 0, n.w.l);
260 write_primitive_word(addr + 2, n.w.h);
264 write_primitive_byte(addr + 0, n.b.l);
268 write_primitive_word(addr + 1, nn.w);
269 write_primitive_byte(addr + 3, n.b.h3);
273 write_primitive_word(addr + 0, n.w.l);
274 write_primitive_word(addr + 2, n.w.h);
278 write_primitive_byte(addr + 0, n.b.l);
282 write_primitive_word(addr + 1, nn.w);
283 write_primitive_word(addr + 3, n.b.h3);
290 TOWNS_MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) {
291 set_device_name(_T("FMTOWNS_MEMORY"));
292 addr_max = 0x100000000; // 4GiB
293 bank_size = 1024; // 1024
295 bank_size_was_set = false;
296 addr_max_was_set = false;
298 _MEMORY_DISABLE_DMA_MMIO = false;
300 extram_size = 0x00200000; // Basically 2MB
306 d_romcard[0] = d_romcard[1] = NULL;
323 initialize_output_signals(&outputs_ram_wait);
324 initialize_output_signals(&outputs_rom_wait);
325 // Note: machine id must set before initialize() from set_context_machine_id() by VM::VM().
326 // machine_id = 0x0100; // FM-Towns 1,2
327 // machine_id = 0x0200 // FM-Towns 1F/2F/1H/2H
328 // machine_id = 0x0300 // FM-Towns UX10/UX20/UX40
329 // machine_id = 0x0400 // FM-Towns 10F/20F/40H/80H
330 // machine_id = 0x0500 // FM-Towns2 CX10/CX20/CX40/CX100
331 // machine_id = 0x0600 // FM-Towns2 UG10/UG20/UG40/UG80
332 // machine_id = 0x0700 // FM-Towns2 HR20/HR100/HR200
333 // machine_id = 0x0800 // FM-Towns2 HG20/HG40/HG100
334 // machine_id = 0x0900 // FM-Towns2 UR20/UR40/UR80
335 // machine_id = 0x0b00 // FM-Towns2 MA20/MA170/MA340
336 // machine_id = 0x0c00 // FM-Towns2 MX20/MX170/MX340
337 // machine_id = 0x0d00 // FM-Towns2 ME20/ME170
338 // machine_id = 0x0f00 // FM-Towns2 MF20/MF170/Fresh
339 machine_id = 0x0100; // FM-Towns 1,2
341 // Note: cpu id must set before initialize() from set_context_cpu_id() by VM::VM().
342 // cpu_id = 0x00; // 80286.
343 // cpu_id = 0x01; // 80386DX.
344 // cpu_id = 0x02; // 80486SX/DX.
345 // cpu_id = 0x03; // 80386SX.
346 cpu_id = 0x01; // 80386DX.
355 virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data);
356 virtual uint32_t __FASTCALL read_io8(uint32_t addr);
357 virtual uint32_t __FASTCALL read_io16(uint32_t addr);
359 uint32_t __FASTCALL read_data8(uint32_t addr);
360 uint32_t __FASTCALL read_data16(uint32_t addr);
361 uint32_t __FASTCALL read_data32(uint32_t addr);
362 void __FASTCALL write_data8(uint32_t addr, uint32_t data);
363 void __FASTCALL write_data16(uint32_t addr, uint32_t data);
364 void __FASTCALL write_data32(uint32_t addr, uint32_t data);
366 uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait);
367 uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait);
368 uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait);
369 void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait);
370 void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait);
371 void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait);
373 // uint32_t __FASTCALL read_dma_data8w(uint32_t addr, int* wait);
374 // uint32_t __FASTCALL read_dma_data16w(uint32_t addr, int* wait);
375 // uint32_t __FASTCALL read_dma_data32w(uint32_t addr, int* wait);
376 // void __FASTCALL write_dma_data8w(uint32_t addr, uint32_t data, int* wait);
377 // void __FASTCALL write_dma_data16w(uint32_t addr, uint32_t data, int* wait);
378 // void __FASTCALL write_dma_data32w(uint32_t addr, uint32_t data, int* wait);
380 uint32_t __FASTCALL read_dma_data8(uint32_t addr);
381 uint32_t __FASTCALL read_dma_data16(uint32_t addr);
382 uint32_t __FASTCALL read_dma_data32(uint32_t addr);
383 void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data);
384 void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data);
385 void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data);
387 virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data);
388 // virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data);
389 // virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data);
390 virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr);
391 // virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr);
392 // virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr);
395 void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
396 uint32_t __FASTCALL read_signal(int ch);
398 //void event_frame();
399 virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit);
401 bool process_state(FILEIO* state_fio, bool loading);
404 void set_extra_ram_size(uint32_t megabytes)
407 uint32_t minimum = 2;
408 switch(machine_id & 0xff00) {
410 case 0x0100: // Towns Model 1/2
413 case 0x0200: // TOWNS 2F/2H
414 case 0x0400: // TOWNS 10F/10H/20F/20H
415 limit = 8; // 2MB + 2MB x 3
417 case 0x0300: // TOWNS2 UX
418 case 0x0600: // TOWNS2 UG
419 limit = 9; // 2MB + 4MB x 2? - 1MB
421 case 0x0500: // TOWNS2 CX
422 case 0x0800: // TOWNS2 HG
423 limit = 15; // 8MB x 2 - 1MB?
425 case 0x0700: // TOWNS2 HR
426 case 0x0900: // TOWNS2 UR
427 case 0x0B00: // TOWNS2 MA
428 case 0x0C00: // TOWNS2 MX
429 case 0x0D00: // TOWNS2 ME
430 case 0x0F00: // TOWNS2 MF/Fresh
431 limit = 31; // 16MB x 2 - 1MB?
434 if(megabytes > limit) megabytes = limit;
435 if(megabytes < minimum) megabytes = minimum;
436 extram_size = megabytes << 20;
438 void set_context_cpu(I386* device)
442 void set_context_dmac(DEVICE* device)
446 void set_context_vram(DEVICE* device)
450 void set_context_system_rom(DEVICE* device)
454 void set_context_font_rom(DEVICE* device)
458 void set_context_font_20pix_rom(DEVICE* device)
460 d_font_20pix = device;
462 void set_context_dictionary(DEVICE* device)
464 d_dictionary = device;
466 void set_context_msdos(DEVICE* device)
470 void set_context_timer(DEVICE* device)
474 void set_context_sprite(DEVICE* device)
478 void set_context_crtc(DEVICE* device)
482 void set_context_romcard(DEVICE* device, int num)
484 d_romcard[num & 1] = device;
486 void set_context_pcm(DEVICE* device)
490 void set_context_serial_rom(DEVICE* device)
492 d_serialrom = device;
494 void set_context_planevram(DEVICE *dev)
498 void set_context_iccard(DEVICE* device, int num)
500 if((num >= 0) && (num < 2)) {
501 d_iccard[num] = device;
504 void set_machine_id(uint16_t val)
506 machine_id = val & 0xfff8;
508 void set_cpu_id(uint16_t val)