2 FUJITSU FM Towns Emulator 'eFMTowns'
4 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
10 #include "../../fileio.h"
11 #include "./towns_memory.h"
16 void TOWNS_MEMORY::initialize()
19 extra_nmi_mask = true;
20 extra_nmi_val = false;
26 memset(ram_page0, 0x00, sizeof(ram_page0));
30 if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // 20 pixels FONT : Optional
31 fio->Fread(rom_font20, sizeof(rom_font20), 1);
35 // ToDo: Will move to config.
36 extram_size = TOWNS_EXTRAM_PAGES * 0x100000;
37 // ToDo: Limit extram_size per VM.
38 extram = (uint8_t *)malloc(extram_size);
40 vram_size = 0x80000; // OK?
42 //dma_addr_reg = dma_wrap_reg = 0;
43 dma_addr_mask = 0x00ffffff; // ToDo
48 void TOWNS_MEMORY::reset()
53 dma_addr_reg = dma_wrap_reg = 0;
54 dma_addr_mask = 0x00ffffff;
55 d_cpu->set_address_mask(0xffffffff);
58 bool TOWNS_MEMORY::check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, void** readfn, void** writefn, void** readp, void** writep)
60 uint8_t __type = (uint8_t)(type_bank_adrs_cx[banknum] >> 24);
61 uint32_t __offset = type_bank_adrs_cx[banknum] & 0x00ffffff;
62 if(offset == NULL) return false;
63 if(mask == NULL) return false;
64 if(readfn == NULL) return false;
65 if(writefn == NULL) return false;
66 if(readp == NULL) return false;
67 if(writep == NULL) return false;
76 case TOWNS_MEMORY_FMR_VRAM:
77 if(!mainmem_enabled) {
78 *readfn = (void *)d_vram;
79 *writefn = (void *)d_vram;
80 *offset = FMTOWNS_VRAM_PLANE_ACCESS;
83 *readp = (void *)(&(ram_0c0[addr & 0x7fff]));
84 *writep = (void *)(&(ram_0c0[addr & 0x7fff]));
88 case TOWNS_MEMORY_FMR_TEXT:
89 if(!mainmem_enabled) {
90 if((addr & 0x1000) == 0) {
91 *readfn = (void *)d_vram;
92 *writefn = (void *)d_vram;
93 *offset = FMTOWNS_VRAM_TEXT_VRAM;
97 *readp = (void*)(&(ram_0c8[addr & 0x1fff]));
98 *writedp = (void*)(&(ram_0c8[addr & 0x1fff]));
102 *readp = (void*)(&(ram_0c8[addr & 0x1fff]));
103 *writedp = (void*)(&(ram_0c8[addr & 0x1fff]));
106 case TOWNS_MEMORY_MMIO_0CC:
107 if(!mainmem_enabled) {
108 if((addr & 0xfffff) < 0xcff80) {
110 *readp = (void*)(&(ram_0cc[addr & 0x3fff]));
111 *writedp = (void*)(&(ram_0cc[addr & 0x3fff]));
115 *readp = (void*)(&(ram_0cc[addr & 0x3fff]));
116 *writedp = (void*)(&(ram_0cc[addr & 0x3fff]));
119 case TOWNS_MEMORY_SPRITE_ANKCG1:
120 if(!mainmem_enabled) {
122 *offset = 0x000ca000;
124 *readfn = (void *)d_fonts;
125 *writefn = (void *)d_fonts;
127 *offset = 0x2000 + FMTOWNS_VRAM_TEXT_VRAM;
129 *readfn = (void *)d_vram;
130 *writefn = (void *)d_vram;
133 *readp = (void*)(&(ram_0ca[addr & 0xfff]));
134 *writep = (void*)(&(ram_0ca[addr & 0xfff]));
137 case TOWNS_MEMORY_SPRITE_ANKCG2:
138 if(!(mainmem_enabled) && (ankcg_enabled)) {
139 *offset = 0x000cb000;
141 *readfn = (void *)d_fonts;
142 *writefn = (void *)d_fonts;
144 *readp = (void*)(&(ram_0cb[addr & 0xfff]));
145 *writep = (void*)(&(ram_0cb[addr & 0xfff]));
159 uint32_t TOWNS_MEMORY::read_data_base(uint32_t addr, int* wait, int wordsize)
163 uint32_t banknum = addr >> 12;
167 _naddr = addr & 0xfffffffe;
170 _naddr = addr & 0xfffffffc;
177 maddr = read_bank_adrs_cx[banknum];
180 if(wait != NULL) *wait = mem_wait_val;
184 p = &maddr[addr & 0x00000fff];
185 return (uint32_t)(*p);
190 p = &maddr[addr & 0x00000ffe];
191 #if defined(__LITTLE_ENDIAN__)
192 uint16_t* pp = (uint16_t*)p;
204 p = &maddr[addr & 0x00000ffc];
205 #if defined(__LITTLE_ENDIAN__)
206 uint32_t* pp = (uint32_t*)p;
218 return 0xffffffff; // Word size error
222 daddr = device_bank_adrs_cx[banknum];
227 return daddr->read_data8w(addr, wait);
230 return daddr->read_data16w(addr, wait);
233 return daddr->read_data32w(addr, wait);
246 if(check_bank(_naddr, &_mask, &_offset, (void**)(&readfn), (void**)(&writefn), (void**)(&readp), (void**)(&writep))) {
251 if(wait != NULL) *wait = mem_wait_val;
252 return (uint32_t)(*readp);
253 } else if(readfn != NULL) {
254 return readfn->read_data8w(_naddr, wait);
262 if(wait != NULL) *wait = mem_wait_val;
263 #if defined(__LITTLE_ENDIAN__)
264 uint16_t *pp = (uint16_t*)readp;
265 return (uint32_t)(*pp);
268 pair16_t *pp = (pair16_t*)readp;
273 } else if(readfn != NULL) {
274 return readfn->read_data16w(_naddr, wait);
282 if(wait != NULL) *wait = mem_wait_val;
283 #if defined(__LITTLE_ENDIAN__)
284 uint32_t *pp = (uint32_t*)readp;
285 return (uint32_t)(*pp);
294 } else if(readfn != NULL) {
295 return readfn->read_data32w(_naddr, wait);
304 // Function or memory don't exist this bank.
306 // Bank not registered.
307 if((addr >= 0x000cff80) && (addr <= 0x000cffff)) {
310 val = read_mmio(addr, wait, &_hit);
319 // Neither memory nor device nor bank.
324 uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int *wait)
326 return read_data_base(addr, wait, 1);
328 uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int *wait)
330 return read_data_base(addr, wait, 2);
333 uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int *wait)
335 return read_data_base(addr, wait, 4);
338 void TOWNS_MEMORY::write_data_base(uint32_t addr, uint32_t data, int* wait, int wordsize)
342 uint32_t banknum = addr >> 12;
346 _naddr = addr & 0xfffffffe;
349 _naddr = addr & 0xfffffffc;
356 maddr = write_bank_adrs_cx[banknum];
359 if(wait != NULL) *wait = mem_wait_val;
363 p = &maddr[addr & 0x00000fff];
370 _d.u16 = (uint16_t)data;
371 p = &maddr[addr & 0x00000ffe];
372 #if defined(__LITTLE_ENDIAN__)
373 uint16_t* pp = (uint16_t*)p;
386 p = &maddr[addr & 0x00000ffc];
387 #if defined(__LITTLE_ENDIAN__)
388 uint32_t* pp = (uint32_t*)p;
400 return; // Word size error
404 daddr = device_bank_adrs_cx[banknum];
409 daddr->write_data8w(addr, data, wait);
412 daddr->write_data16w(addr, data, wait);
415 daddr->write_data32w(addr, data, wait);
428 if(check_bank(_naddr, &_mask, &_offset, (void**)(&readfn), (void**)(&writefn), (void**)(&readp), (void**)(&writep))) {
433 if(wait != NULL) *wait = mem_wait_val;
434 *writep = (uint8_t)data;
435 } else if(writefn != NULL) {
436 writefn->write_data8w(_naddr, data, wait);
442 if(wait != NULL) *wait = mem_wait_val;
443 #if defined(__LITTLE_ENDIAN__)
444 uint16_t *pp = (uint16_t*)writep;
445 *pp = (uint16_t)data;
448 _d.u16 = (uint16_t)data;
452 } else if(writefn != NULL) {
453 writefn->write_data16w(_naddr, data, wait);
459 if(wait != NULL) *wait = mem_wait_val;
460 #if defined(__LITTLE_ENDIAN__)
461 uint32_t *pp = (uint32_t*)writep;
462 *pp = (uint32_t)data;
471 } else if(writefn != NULL) {
472 writefn->write_data32w(_naddr, data, wait);
479 // Function or memory don't exist this bank.
481 // Bank not registered.
482 if((addr >= 0x000cff80) && (addr <= 0x000cffff)) {
484 write_mmio(addr, data, wait, &_hit); // ToDo: Not Hit
488 // Neither memory nor device nor bank.
493 void TOWNS_MEMORY::write_data8w(uint32_t addr, uint32_t data, int *wait)
495 write_data_base(addr, data, wait, 1);
498 void TOWNS_MEMORY::write_data16w(uint32_t addr, uint32_t data, int *wait)
500 write_data_base(addr, data, wait, 2);
503 void TOWNS_MEMORY::write_data32w(uint32_t addr, uint32_t data, int *wait)
505 write_data_base(addr, data, wait, 4);
510 uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
512 return read_data_base(addr, NULL, 1);
515 uint32_t TOWNS_MEMORY::read_data16(uint32_t addr)
517 return read_data_base(addr, NULL, 2);
520 uint32_t TOWNS_MEMORY::read_data32(uint32_t addr)
522 return read_data_base(addr, NULL, 4);
525 void TOWNS_MEMORY::write_data8(uint32_t addr, uint32_t data)
527 write_data_base(addr, data, NULL, 1);
530 void TOWNS_MEMORY::write_data16(uint32_t addr, uint32_t data)
532 write_data_base(addr, data, NULL, 2);
535 void TOWNS_MEMORY::write_data32(uint32_t addr, uint32_t data)
537 write_data_base(addr, data, NULL, 4);
540 // Address (TOWNS BASIC):
541 // 0x0020 - 0x0022, 0x0030-0x0031,
545 // 0x05ec (Wait register)
546 // Is set extra NMI (0x05c0 - 0x05c2)?
547 uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
550 switch(addr & 0xffff) {
551 case 0x0020: // Software reset ETC.
552 // reset cause register
553 val = ((software_reset) ? 1 : 0) | ((d_cpu->get_shutdown_flag() != 0) ? 2 : 0);
554 software_reset = false;
555 d_cpu->set_shutdown_flag(0);
563 val = (((machine_id & 0x1f) << 3) | (cpu_id & 7));
567 val = ((machine_id >> 5) & 0xff);
571 //bool __cs = (d_serialrom->read_data8(SIG_SERIALROM_CS) == 0);
572 bool __clk = (d_serialrom->read_data8(SIG_SERIALROM_CLK) != 0);
573 bool __reset = (d_serialrom->read_data8(SIG_SERIALROM_RESET) != 0);
574 bool __dat = (d_serialrom->read_data8(SIG_SERIALROM_DATA) != 0);
575 val = ((__reset) ? 0x80 : 0x00) | ((__clk) ? 0x40 : 0x00) | 0x3e | ((__dat) ? 0x01 : 0x00);
578 case 0x006c: // Wait register.
579 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
583 case 0x0400: // Resolution:
586 case 0x0404: // System Status Reg.
587 val = (bankc0_vram) ? 0x7f : 0xff;
590 val = (extra_nmi_mask) ? 0xf7 : 0xff;
593 val = (extra_nmi_val) ? 0xff : 0xf7;
596 // After Towns1F/2F/1H/2H
598 switch(machine_id & 0xff00) {
611 val = ((extram_size >> 20) & 0x1f);
617 val = ((extram_size >> 20) & 0x7f);
627 if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H?
628 val = 0x00 | ((mem_wait_val > 0) ? 0x01 : 0x00);
637 void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
640 switch(addr & 0xffff) {
641 case 0x0020: // Software reset ETC.
642 // reset cause register
643 if((data & 0x80) != 0) {
644 nmi_vector_protect = true;
646 nmi_vector_protect = false;
648 if((data & 0x01) != 0) {
649 software_reset = true;
651 software_reset = false;
653 if((data & 0x40) != 0) {
654 d_cpu->set_shutdown_flag(1);
662 if((data & 0x40) != 0) {
663 d_cpu->set_shutdown_flag(1);
670 d_serialrom->write_data8(SIG_SERIALROM_CS, ~data, 0x20);
671 d_serialrom->write_data8(SIG_SERIALROM_CLK, data, 0x40);
672 d_serialrom->write_data8(SIG_SERIALROM_RESET, data, 0x80);
675 case 0x006c: // Wait register.
676 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
677 if(event_wait_1us != -1) cancel_event(this, event_wait_1us);
678 register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us);
679 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
682 case 0x0404: // System Status Reg.
683 bankc0_vram = ((data & 0x80) != 0);
686 extra_nmi_mask = ((data & 0x08) == 0);
689 if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H?
690 vram_wait_val = ((data & 0x01) != 0) ? 3 : 6;
691 mem_wait_val = ((data & 0x01) != 0) ? 0 : 3;
692 this->write_signal(SIG_FMTOWNS_SET_VRAMWAIT, vram_wait_val, 0xff);
693 this->write_signal(SIG_FMTOWNS_SET_MEMWAIT, mem_wait_val, 0xff);
702 void TOWNS_MEMORY::event_callback(int id, int err)
707 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
708 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
717 uint32_t TOWNS_MEMORY::read_mmio(uint32_t addr, int *wait, bool *hit)
719 if(hit != NULL) *hit = false;
720 if(wait != NULL) *wait = 0; // OK?
721 if(addr >= 0x000d0000) return 0xffffffff;
722 if(addr < 0x000cff80) return 0xffffffff;
725 switch(addr & 0x7f) {
728 val = d_vram->read_io8(FMTOWNS_VRAM_IO_CURSOR);
734 val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT);
740 val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE);
746 val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL);
751 val = 0x7f; // Reserve.FIRQ
756 val = d_vram->read_io8(FMTOWNS_VRAM_IO_SYNC_STATUS);
765 val = d_vram->read_io8(FMTOWNS_VRAM_KANJICG + (addr & 3));
771 d_beep->write_signal(SIG_BEEP_ON, 1, 1);
776 val = val & ((ankcg_enabled) ? 0x00 : 0x01);
787 if(hit != NULL) *hit = found;
788 return (uint32_t)val;
791 void TOWNS_MEMORY::write_mmio(uint32_t addr, uint32_t data, int *wait, bool *hit)
793 if(hit != NULL) *hit = false;
794 if(wait != NULL) *wait = 0; // OK?
795 if(addr >= 0x000d0000) return;
796 if(addr < 0x000cff80) return;
798 switch(addr & 0x7f) {
801 d_vram->write_io8(FMTOWNS_VRAM_IO_CURSOR, data);
807 d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT, data);
813 d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE, data);
819 d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL, data);
834 d_vram->write_io8(FMTOWNS_VRAM_KANJICG + (addr & 3), data);
840 d_beep->write_signal(SIG_BEEP_ON, 0, 1);
845 ankcg_enabled = ((data & 1) == 0);
854 if(hit != NULL) *hit = found;
858 void TOWNS_MEMORY::initialize_tables(void)
861 memset(write_bank_adrs_cx, 0x00, sizeof(write_bank_adrs_cx));
862 memset(read_bank_adrs_cx, 0x00, sizeof(read_bank_adrs_cx));
863 memset(device_bank_adrs_cx, 0x00, sizeof(device_bank_adrs_cx));
864 memset(type_bank_adrs_cx, 0x00, sizeof(type_bank_adrs_cx));
867 for(uint32_t ui = 0x00000; ui < 0x000c0; ui++) { // $00000000 - $000bffff
868 read_bank_adrs_cx[ui] = &(ram_page0[ui << 12]);
869 write_bank_adrs_cx[ui] = &(ram_page0[ui << 12]);
872 for(uint32_t ui = 0x000c0; ui < 0x000c8; ui++) { // $000c0000 - $000effff
873 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_VRAM << 24) | ((ui - 0xc0) << 12);
875 for(uint32_t ui = 0x000c8; ui < 0x000c9; ui++) { // $000c0000 - $000effff
876 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_TEXT << 24) | ((ui - 0xc8) << 12);
878 for(uint32_t ui = 0x000c9; ui < 0x000ca; ui++) { // $000c0000 - $000effff
879 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_FMR_VRAM_RESERVE << 24) | ((ui - 0xc8) << 12);
881 for(uint32_t ui = 0x000ca; ui < 0x000cb; ui++) { // $000c0000 - $000effff
882 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_SPRITE_ANKCG1 << 24) | ((ui - 0xca) << 12);
884 for(uint32_t ui = 0x000cb; ui < 0x000cc; ui++) { // $000c0000 - $000effff
885 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_ANKCG2 << 24) | ((ui - 0xcb) << 12);
887 for(uint32_t ui = 0x000cc; ui < 0x000d0; ui++) { // $000c0000 - $000effff
888 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_MMIO_0CC << 24) | ((ui - 0xcc) << 12);
890 for(uint32_t ui = 0x000d0; ui < 0x000f0; ui++) { // $000c0000 - $000effff
891 device_bank_adrs_cx[ui] = d_dictionary;
893 for(uint32_t ui = 0x000f0; ui < 0x00100; ui++) { // $000f0000 - $000fffff
894 device_bank_adrs_cx[ui] = d_sysrom;
897 for(uint32_t ui = 0x00100; ui < (0x00100 + (extram_size >> 12)); ui++) {
898 read_bank_adrs_cx[ui] = &(extram[(ui - 0x100) << 12]);
899 write_bank_adrs_cx[ui] = &(extram[(ui - 0x100) << 12]);
901 // ToDo: EXTRA IO(0x40000000 - 0x80000000)
905 for(uint32_t ui = 0x000c0; ui < 0x000ca; ui++) {
906 device_bank_adrs_cx[ui] = d_vram;
908 for(uint32_t ui = 0x000ca; ui < 0x000cb; ui++) {
909 device_bank_adrs_cx[ui] = d_sprite;
912 for(uint32_t ui = 0x80000; ui < (0x80000 + (vram_size >> 12)); ui++) {
913 device_bank_adrs_cx[ui] = d_vram;
915 for(uint32_t ui = 0x80100; ui < (0x80100 + (vram_size >> 12)); ui++) {
916 device_bank_adrs_cx[ui] = d_vram;
918 for(uint32_t ui = 0x81000; ui < 0x81020; ui++) {
919 device_bank_adrs_cx[ui] = d_sprite;
923 for(uint32_t ui = 0xc0000; ui < 0xc1000; ui++) {
924 device_bank_adrs_cx[ui] = d_romcard[0];
927 for(uint32_t ui = 0xc1000; ui < 0xc2000; ui++) {
928 device_bank_adrs_cx[ui] = d_romcard[1];
930 for(uint32_t ui = 0xc2140; ui < 0xc2142; ui++) {
931 device_bank_adrs_cx[ui] = d_dictionary;
933 for(uint32_t ui = 0xc2200; ui < 0xc2201; ui++) {
934 device_bank_adrs_cx[ui] = d_pcm;
937 for(uint32_t ui = 0xc2000; ui < 0xc2080; ui++) {
938 device_bank_adrs_cx[ui] = d_msdos;
940 for(uint32_t ui = 0xc2080; ui < 0xc2100; ui++) {
941 device_bank_adrs_cx[ui] = d_dictionary;
943 for(uint32_t ui = 0xc2100; ui < 0xc2140; ui++) {
944 device_bank_adrs_cx[ui] = d_fonts;
946 for(uint32_t ui = 0xc2180; ui < 0xc2200; ui++) { // 20pixs fonts.
947 device_bank_adrs_cx[ui] = d_fonts;
951 for(uint32_t ui = 0xfffc0; ui < 0x100000; ui++) {
952 device_bank_adrs_cx[ui] = d_sysrom;
957 uint32_t TOWNS_MEMORY::read_data8(uint32_t addr)
960 return read_data8w(addr, &wait);
963 uint32_t TOWNS_MEMORY::read_data16(uint32_t addr)
966 return read_data16w(addr, &wait);
969 uint32_t TOWNS_MEMORY::read_data32(uint32_t addr)
972 return read_data32w(addr, &wait);
975 void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
978 write_data8w(addr & dma_addr_mask, data, &wait);
981 uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr)
984 return read_data8w(addr & dma_addr_mask, &wait);
986 void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
989 write_data16w(addr & dma_addr_mask, data, &wait);
992 uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
995 return read_data16w(addr & dma_addr_mask, &wait);
999 void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask)
1001 if(ch == SIG_MEMORY_EXTNMI) {
1002 extra_nmi_val = ((data & mask) != 0);
1003 } else if(ch == SIG_CPU_NMI) {
1005 d_cpu->write_signal(SIG_CPU_NMI, data, mask);
1006 } else if(ch == SIG_CPU_IRQ) {
1007 d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
1008 } else if(ch == SIG_CPU_BUSREQ) {
1009 d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
1010 } else if(ch == SIG_I386_A20) {
1011 d_cpu->write_signal(SIG_I386_A20, data, mask);
1012 } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
1013 mem_wait_val = (int)data;
1014 d_sysrom->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1015 d_dictionary->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1016 d_msdos->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1017 d_fonts->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1018 } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) {
1019 vram_wait_val = (int)data;
1020 d_vram->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask);
1024 uint32_t TOWNS_MEMORY::read_signal(int ch)
1026 if(ch == SIG_FMTOWNS_MACHINE_ID) {
1027 uint16_t d = (machine_id & 0xfff8) | ((uint16_t)(cpu_id & 0x07));
1029 } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
1030 return (uint32_t)mem_wait_val;
1031 } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) {
1032 return (uint32_t)vram_wait_val;
1038 #define STATE_VERSION 1
1040 bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
1042 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1045 if(!state_fio->StateCheckInt32(this_device_id)) {
1048 state_fio->StateValue(bankc0_vram);
1049 state_fio->StateValue(ankcg_enabled);
1050 state_fio->StateValue(machine_id);
1051 state_fio->StateValue(cpu_id);
1053 state_fio->StateValue(dma_addr_mask);
1054 //state_fio->StateValue(dma_addr_reg);
1055 //state_fio->StateValue(dma_wrap_reg);
1057 state_fio->StateArray(ram_page0, sizeof(ram_page0), 1);
1058 state_fio->StateArray(ram_0c0, sizeof(ram_0c0), 1);
1059 state_fio->StateArray(ram_0c8, sizeof(ram_0c8), 1);
1060 state_fio->StateArray(ram_0ca, sizeof(ram_0ca), 1);
1061 state_fio->StateArray(ram_0cb, sizeof(ram_0cb), 1);
1062 state_fio->StateArray(ram_0cc, sizeof(ram_0cc), 1);
1066 uint32_t length_tmp = state_fio->FgetUint32_LE();
1067 if(extram != NULL) {
1071 length_tmp = length_tmp & 0x3ff00000;
1072 extram_size = length_tmp;
1073 if(length_tmp > 0) {
1074 extram = (uint8_t*)malloc(length_tmp);
1076 if(extram == NULL) {
1080 state_fio->Fread(extram, extram_size, 1);
1083 if(extram == NULL) {
1084 state_fio->FputUint32_LE(0);
1086 state_fio->FputUint32_LE(extram_size & 0x3ff00000);
1087 state_fio->Fwrite(extram, extram_size, 1);
1091 state_fio->StateValue(vram_wait_val);
1092 state_fio->StateValue(mem_wait_val);
1093 state_fio->StateValue(vram_size);
1095 // ToDo: Do save ROMs?
1098 initialize_tables();