• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: Commit

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

Revision4cb5597006aa42de89c761acc5e73b93f822bd2d (tree)
Time2019-01-09 21:56:55
AuthorK.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][FMTOWNS] Add FONT ROMS, MSDOS ROM, SYSTEM ROM and SERIAL ROM.

Change Summary

Incremental Difference

--- a/source/src/vm/fmtowns/CMakeLists.txt
+++ b/source/src/vm/fmtowns/CMakeLists.txt
@@ -3,13 +3,20 @@ cmake_minimum_required (VERSION 2.6)
33 message("* vm/fm-towns")
44
55 add_library(vm_fmtowns
6- cmos.cpp
76 floppy.cpp
87 keyboard.cpp
98 scsi.cpp
109 timer.cpp
10+
11+ serialrom.cpp
12+ sysrom.cpp
13+ dictionary.cpp
14+ msdosrom.cpp
15+
16+ fontroms.cpp
17+
1118 towns_crtc.cpp
1219 towns_memory.cpp
1320 towns_sprite.cpp
1421 towns_vram.cpp
15-)
\ No newline at end of file
22+)
--- /dev/null
+++ b/source/src/vm/fmtowns/fontroms.cpp
@@ -0,0 +1,89 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09 -
6+
7+ [fonts]
8+*/
9+
10+#inclide "../towns_common.h"
11+#include "../../fileio.h"
12+#include "./fontroms.h"
13+
14+namespace FMTOWNS {
15+
16+void FONT_ROMS::initialize()
17+{
18+ wait_val = 3;
19+ memset(font_kanji16, sizeof(font_kanji16), 0xff);
20+ FILEIO* fio = new FILEIO();
21+
22+ if(fio->Fopen(create_local_path(_T("FMT_FNT.ROM")), FILEIO_READ_BINARY)) { // FONT
23+ fio->Fread(font_kanji16, sizeof(font_kanji16), 1);
24+ fio->Fclose();
25+ }
26+
27+#if defined(HAVE_20PIXS_FONT)
28+ memset(font_kanji20, sizeof(font_kanji20), 0xff);
29+ if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // FONT
30+ fio->Fread(font_kanji20, sizeof(font_kanji20), 1);
31+ fio->Fclose();
32+ }
33+#endif
34+
35+ delete fio;
36+}
37+
38+uint32_t FONT_ROMS::read_data8(uint32_t addr)
39+{
40+ if((addr >= 0xc2100000) && (addr < 0xc2140000)) {
41+ return (uint32_t)(font_kanji16[addr & 0x3ffff]);
42+ } else if((addr >= 0xc2180000) && (addr < 0xc2200000)) {
43+#if defined(HAVE_20PIXS_FONT)
44+ return (uint32_t)(font_kanji20[addr & 0x7ffff]);
45+#else
46+ return 0xff;
47+#endif
48+ } else if((addr >= 0x000ca000) && (addr < 0x000ca800)) {
49+ return (uint32_t)(font_kanji16[0x1e800 + (addr & 0x7ff)]);
50+ } else if((addr >= 0x000cb000) && (addr < 0x000cc000)) {
51+ return (uint32_t)(font_kanji16[0x1f000 + (addr & 0x7ff)]);
52+ }
53+ return 0xff;
54+}
55+
56+uint32_t FONT_ROMS::read_data8w(uint32_t addr, int* wait)
57+{
58+ if(wait != NULL) *wait = wait_val;
59+ return read_data8(addr);
60+}
61+
62+void FONT_ROMS::write_data8w(uint32_t addr, uint32_t data, int* wait)
63+{
64+ if(wait != NULL) *wait = wait_val;
65+}
66+
67+void FONT_ROMS::write_signal(int ch, uint32_t data, uint32_t mask)
68+{
69+ if(ch == SIG_FMTOWNS_SET_MEMWAIT) {
70+ wait_val = (int)data;
71+ }
72+}
73+
74+#define STATE_VERSION 1
75+
76+bool FONT_ROMS::process_state(FILEIO* state_fio, bool loading)
77+{
78+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
79+ return false;
80+ }
81+ if(!state_fio->StateCheckInt32(this_device_id)) {
82+ return false;
83+ }
84+ state_fio->StateValue(wait_val);
85+
86+ return true;
87+}
88+
89+}
--- /dev/null
+++ b/source/src/vm/fmtowns/fontroms.h
@@ -0,0 +1,42 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09 -
6+
7+ [fonts]
8+*/
9+
10+#pragma once
11+
12+#include "../vm.h"
13+#include "../device.h"
14+
15+namespace FMTOWNS {
16+
17+class FONT_ROMS : public DEVICE
18+{
19+protected:
20+ int wait_val;
21+ uint8_t font_kanji16[0x40000];
22+#if defined(HAVE_20PIXS_FONT)
23+ uint8_t font_kanji20[0x80000];
24+#endif
25+public:
26+ FONT_ROMS(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
27+ {
28+ set_device_name("Font Roms");
29+ }
30+ ~FONT_ROMS() {}
31+
32+ void initialize();
33+
34+ uint32_t read_data8(uint32_t addr);
35+ uint32_t read_data8w(uint32_t addr, int* wait);
36+ void write_data8w(uint32_t addr, uint32_t data, int* wait);
37+ void write_signal(int ch, uint32_t data, uint32_t mask);
38+ bool process_state(FILEIO* state_fio, bool loading);
39+};
40+
41+}
42+
--- /dev/null
+++ b/source/src/vm/fmtowns/msdosrom.cpp
@@ -0,0 +1,80 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09 -
6+
7+ [MSDOS ROM]
8+*/
9+
10+#include "./towns_common.h"
11+#include "./msdosrom.h"
12+
13+namespace FMTOWNS {
14+
15+void MSDOSROM::initialize()
16+{
17+ memset(rom, 0xff, sizeof(rom));
18+ FILEIO *fio;
19+ if(fio->Fopen(create_local_path(_T("FMT_DOS.ROM")), FILEIO_READ_BINARY)) { // MSDOS
20+ fio->Fread(rom, sizeof(rom), 1);
21+ fio->Fclose();
22+ }
23+ delete fio;
24+
25+ wait_val = 3;
26+}
27+
28+uint32_t MSDOSROM::read_data8(uint32_t addr)
29+{
30+ uint8_t d = 0xff;
31+ if((addr >= 0xc2000000) && (addr < 0xc2080000)) {
32+ d = rom[addr & 0x7ffff];
33+ }
34+ return (uint32_t)d;
35+}
36+
37+uint32_t MSDOSROM::read_data8w(uint32_t addr, int* wait)
38+{
39+ if(wait != NULL) *wait = wait_val;
40+ return read_data8(addr);
41+}
42+void MSDOSROM::write_data8w(uint32_t addr, uint32_t data, int* wait)
43+{
44+ if(wait != NULL) *wait = wait_val;
45+}
46+
47+void MSDOSROM::write_signal(int ch, uint32_t data, uint32_t mask)
48+{
49+ switch(ch) {
50+ case SIG_FMTOWNS_SET_MEMWAIT:
51+ wait_val = (int)data;
52+ break;
53+ }
54+}
55+
56+uint32_t MSDOSROM::read_signal(int ch)
57+{
58+ switch(ch) {
59+ case SIG_FMTOWNS_SET_MEMWAIT:
60+ return (uint32_t)wait_val;
61+ break;
62+ }
63+ return 0;
64+}
65+
66+#define STATE_VERSION 1
67+
68+bool DICTIONARY::process_state(FILEIO* state_fio, bool loading)
69+{
70+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
71+ return false;
72+ }
73+ if(!state_fio->StateCheckInt32(this_device_id)) {
74+ return false;
75+ }
76+ state_fio->StateValue(wait_val);
77+ return true;
78+}
79+
80+}
--- /dev/null
+++ b/source/src/vm/fmtowns/msdosrom.h
@@ -0,0 +1,30 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2018.01.09 -
6+
7+ [ msdos rom ]
8+*/
9+#pragma once
10+
11+#include "../device.h"
12+
13+namespace FMTOWNS {
14+
15+class MSDOSROM : public DEVICE
16+{
17+private:
18+ uint8_t rom[0x80000]; // 0xc2000000 - 0xc207ffff
19+public:
20+ MSDOSROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {
21+ set_device_name(_T("MSDOS ROM"));
22+ }
23+ ~MSDOSROM() {}
24+
25+ void initialize();
26+
27+};
28+
29+}
30+
--- /dev/null
+++ b/source/src/vm/fmtowns/serialrom.cpp
@@ -0,0 +1,194 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09 -
6+
7+ [serial rom]
8+*/
9+
10+#include "../../fileio.h"
11+#include "./towns_memory.h"
12+#include "./serialrom.h"
13+#include "../i386.h"
14+
15+namespace FMTOWNS {
16+
17+void SERIAL_ROM::initialize()
18+{
19+ cs = true;
20+ clk = false;
21+ reset_reg = false;
22+ reset_state = 0;
23+ rom_addr = 0;
24+
25+ memset(rom, 0xff, sizeof(rom));
26+ FILEIO *fio = new FULEIO();
27+ if(fio->Fopen(create_local_path(_T("MYTOWNS.ROM")), FILEIO_READ_BINARY)) { // FONT
28+ fio->Fread(rom, sizeof(rom), 1);
29+ fio->Fcolose();
30+ } else if(fio->Fopen(create_local_path(_T("SERIAL.ROM")), FILEIO_READ_BINARY)) { // FONT
31+ fio->Fread(rom, sizeof(rom), 1);
32+ fio->Fcolose();
33+ } else {
34+ // Header
35+ const _TCHAR *id = _T("FUJITSU");
36+ int _len = strlen(id);
37+ if(_len < 0) _len = 0; // Bit 251 - 72
38+ if(_len >= 22) _len = 21; // Bit 251 - 72
39+ for(int i = 0; i < (_len + 1); i++) {
40+ rom[32 - i] = 0x00;
41+ }
42+ for(int i = 0; i < _len; i++) {
43+ uint8_t _c = (uint8_t)id[i];
44+ uint8_t _revc = 0x00;
45+ uint8_t val = 0x80;
46+ for(int j = 0; j < 8; j++) {
47+ if((_c & 0x01) != 0) _revc = _revc | val;
48+ val >>= 1;
49+ _c >>= 1;
50+ }
51+ rom[31 - i] = rom[31 - i] | ((_revc & 0xf0) >> 4); // High
52+ rom[31 - (i + 1)] = rom[31 - (i + 1)] | ((_revc & 0x0f) << 4); // Low
53+ }
54+ rom[31 - _len] = rom[31 - _len] | 0x0f; // Last bit
55+ // Machine ID (bit 71 - bit 56) must be dummy.
56+
57+ // Serial (bit 55 - bit20)
58+ auto serial = static_cast<uint64_t>(0x00000123);
59+ auto nmask = static_cast<uint64_t>(0x0f);
60+ nmask = nmask << 32;
61+ int nibblepos = 8;
62+ // Initialize footer and serial ID.
63+ for(int i = 0; i < 7; i++) {
64+ rom[7 - i] = 0x00;
65+ }
66+
67+ for(int i = 0; i < 9; i++) {
68+ uint64_t nval = (nmask & serial) >> 32;
69+ uint8_t _c = ((uint8_t)nval) & 0x0f;
70+ uint8_t _revc = 0x00;
71+ uint8_t val = 0x08;
72+ for(int j = 0; j < 4; j++) {
73+ if((_c & 0x01) != 0) _revc = _revc | val;
74+ val >>= 1;
75+ _c >>= 1;
76+ }
77+ serial <<= 4;
78+ // High
79+ if((i & 1) == 0) { // Lower
80+ rom[6 - (i / 2)] = rom[6 - (i / 2)] | (_revc << 4);
81+ } else { // Lower
82+ rom[6 - (i / 2)] = rom[6 - (i / 2)] | _revc;
83+ }
84+ }
85+ }
86+}
87+
88+void SERIAL_ROM::reset()
89+{
90+// cs = true;
91+// clk = 0;
92+// reset_state = 0;
93+// rom_addr = 0;
94+}
95+
96+void SERIAL_ROM::write_signal(int ch, uint32_t data, uint32_t mask)
97+{
98+ switch(ch) {
99+ case SIG_SERIAL_ROM_CLK:
100+ {
101+ bool oldclk = clk;
102+ bool newclk = clk;
103+ if(cs) {
104+ newclk = ((data & mask) != 0);
105+ }
106+ if((oldclk != newclk) && !(reset_reg)) {
107+ clk = newclk;
108+ if(!(oldclk)) {
109+ // Rise up
110+ rom_addr = (rom_addr + 1) & 0xff;
111+ }
112+ }
113+ }
114+ break;
115+ case SIG_SERIAL_ROM_CS:
116+ cs = ((data & mask) == 0);
117+ break;
118+ case SIG_SERIAL_ROM_RESET:
119+ reset_reg = ((data & mask) != 0);
120+ if((cs) && (clk)) {
121+ switch(reset_state) {
122+ case 0:
123+ if(reset_reg) reset_state++;
124+ break;
125+ case 1:
126+ if(!(reset_reg)) {
127+ // Do Reset
128+ rom_addr = 0;
129+ reset_state = 0;
130+ }
131+ break;
132+ default:
133+ break;
134+ }
135+
136+ }
137+ break;
138+ }
139+}
140+
141+uint32_t SERIAL_ROM::read_signal(int ch)
142+{
143+ switch(ch) {
144+ case SIG_SERIALROM_CLK:
145+ return ((clk) ? 0xffffffff : 0x00000000);
146+ break;
147+ case SIG_SERIALROM_CS:
148+ return 0;
149+ break;
150+ case SIG_SERIALROM_RESET:
151+ return ((reset_reg) ? 0xffffffff : 0x00000000);
152+ break;
153+ case SIG_SERIALROM_DATA:
154+ {
155+ if((rom_addr >= 56) && (rom_addr < 72)) {
156+ // Serial id
157+ uint32_t machine_id = d_mem->read_signal(SIG_FMTOWNS_MACHINE_ID);
158+ uint32_t bitaddr = 15 - (rom_addr - 56);
159+ uint32_t bitmask = 0x8000 >> bitaddr;
160+ return (((bitmask & machine_id) != 0) ? 0xffffffff : 0x00000000);
161+ } else {
162+ uint32_t localaddr = (rom_addr & 0xff) >> 3;
163+ uint32_t localbit = (rom_addr & 0xff) & 0x07;
164+ uint8_t _c = rom[localaddr];
165+ uint8_t _bmask = 0x01 << localbit;
166+ return (((_c & _bmask) != 0) ? 0xffffffff : 0x00000000);
167+ }
168+ }
169+ break;
170+ }
171+ return 0;
172+}
173+
174+#define STATE_VERSION 1
175+
176+bool SERIAL_ROM::process_state(FILEIO* state_fio, bool loading)
177+{
178+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
179+ return false;
180+ }
181+ if(!state_fio->StateCheckInt32(this_device_id)) {
182+ return false;
183+ }
184+ state_fio->StateValue(cs);
185+ state_fio->StateValue(clk);
186+ state_fio->StateValue(reset_reg);
187+ state_fio->StateValue(reset_state);
188+ state_fio->StateValue(rom_addr);
189+ state_fio->StateArray(rom, sizeof(rom), 1);
190+
191+ return true;
192+}
193+
194+}
--- /dev/null
+++ b/source/src/vm/fmtowns/serialrom.h
@@ -0,0 +1,55 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09 -
6+
7+ [serial rom]
8+*/
9+
10+#pragma once
11+
12+#include "../device.h"
13+
14+#define SIG_SERIALROM_CLK 1
15+#define SIG_SERIALROM_CS 2
16+#define SIG_SERIALROM_RESET 3
17+#define SIG_SERIALROM_DATA 4
18+
19+namespace FMTOWNS {
20+
21+class SERIAL_ROM : public DEVICE
22+{
23+protected:
24+ DEVICE* d_mem;
25+
26+ bool cs;
27+ bool clk;
28+ bool reset_reg;
29+ int reset_state;
30+ uint8_t rom_addr;
31+ uint8_t rom[32];
32+
33+public:
34+ SERIAL_ROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {
35+ set_device_name(_T("FMTOWNS_SERIAL_ROM"));
36+ d_mem = NULL;
37+ }
38+ ~SERIAL_ROM() {}
39+
40+ void initialize();
41+ void reset();
42+
43+ void write_signal(int ch, uint32_t data, uint32_t mask);
44+ uint32_t read_signal(int ch);
45+
46+ bool process_state(FILEIO* state_fio, bool loading);
47+
48+ void set_context_mem(DEVICE* dev)
49+ {
50+ d_mem = dev;
51+ }
52+};
53+
54+}
55+
--- /dev/null
+++ b/source/src/vm/fmtowns/towns_dictionary.cpp
@@ -0,0 +1,276 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09-
6+
7+ [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000effff]
8+*/
9+
10+#include "./towns_common.h"
11+#include "./towns_dictrom.h"
12+#include "./towns_sysrom.h"
13+#include "../../fileio.h"
14+
15+namespace FMTOWNS {
16+void DICTIONARY::initialize()
17+{
18+ cmos_dirty = false;
19+
20+ memset(dict_rom, 0xff, sizeof(dict_rom));
21+ memset(dict_ram, 0x00, sizeof(dict_ram));
22+ memset(ram_0d0, 0x00, sizeof(ram_0d0));
23+
24+ FILEIO* fio = new FILEIO();
25+ if(fio->Fopen(create_local_path(_T("FMT_DIC.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES
26+ fio->Fread(dict_rom, sizeof(dict_rom), 1);
27+ fio->Fclose();
28+ }
29+
30+ if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_READ_BINARY)) {
31+ fio->Fread(dict_ram, sizeof(dict_ram), 1);
32+ fio->Fclose();
33+ } else {
34+ cmos_dirty = true;
35+ }
36+ delete fio;
37+
38+ wait_val = 3;
39+ dict_bank = 0;
40+ bankd0_dict = false;
41+}
42+
43+void DICTIONARY::release()
44+{
45+ if(cmos_dirty) {
46+ FILEIO* fio = new FILEIO();
47+ if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_WRITE_BINARY)) {
48+ fio->Fwrite(dict_ram, sizeof(dict_ram), 1);
49+ fio->Fclose();
50+ }
51+ delete fio;
52+ }
53+}
54+
55+void DICTIONARY::reset()
56+{
57+ //wait_val = 6; // OK?
58+ dict_bank = 0;
59+ bankd0_dict = false;
60+
61+}
62+uint32_t DICTIONARY::read_data8(uint32_t addr)
63+{
64+ uint8_t n_data = 0xff;
65+ if((addr < 0x000f0000) && (addr >= 0x000d0000)) {
66+ if(bankd0_dict) {
67+ if(addr < 0x000d8000) {
68+ n_data = dict_rom[(addr & 0x7fff) + (((uint32_t)(dict_bank & 0x0f)) << 15)];
69+ } else if(addr < 0x000da000) {
70+ n_data = dict_ram[addr & 0x1fff];
71+ }/* else { // ToDo: Check correctness
72+ n_data = 0xff;
73+ }*/
74+ } else {
75+ n_data = ram_0d0[addr & 0x1ffff];
76+ }
77+ } else if((addr >= 0xc20800000) && (addr < 0xc2100000)) {
78+ n_data = dict_rom[addr & 0x7ffff];
79+ } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) {
80+ n_data = dict_ram[addr & 0x1fff];
81+ }
82+ return n_data;
83+}
84+
85+void DICTIONARY::write_data8(uint32_t addr, uint32_t data)
86+{
87+ if((addr < 0x000f0000) && (addr >= 0x000d0000)) {
88+ if(bankd0_dict) {
89+ if((addr >= 0x000d8000) && (addr < 0x000da000)) {
90+ cmos_dirty = true;
91+ dict_ram[addr & 0x1fff] = data; // ToDo: Check correctness
92+ } /* else { // ToDo: Check correctness
93+
94+ }*/
95+ } else {
96+ ram_0d0[addr & 0x1ffff] = (uint8_t)data;
97+ }
98+ } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) {
99+ dict_ram[addr & 0x1fff] = (uint8_t)data;
100+ }
101+}
102+
103+uint32_t DICTIONARY::read_data16(uint32_t addr)
104+{
105+ pair16_t n;
106+ addr = addr & 0xfffffffe;
107+ n.l = (uint8_t)read_data8(addr + 0);
108+ n.h = (uint8_t)read_data8(addr + 1);
109+ return (uint32_t)(n.u16);
110+}
111+
112+uint32_t DICTIONARY::read_data32(uint32_t addr)
113+{
114+ pair32_t n;
115+ addr = addr & 0xfffffffc;
116+ n.l = (uint8_t)read_data8(addr + 0);
117+ n.h = (uint8_t)read_data8(addr + 1);
118+ n.h2 = (uint8_t)read_data8(addr + 2);
119+ n.h3 = (uint8_t)read_data8(addr + 3);
120+ return n.u32;
121+}
122+
123+void DICTIONARY::write_data16(uint32_t addr, uint32_t data)
124+{
125+ pair16_t n;
126+ addr = addr & 0xfffffffe;
127+ n.u16 = (uint16_t)data;
128+ write_data8(addr + 0, n.l);
129+ write_data8(addr + 1, n.h);
130+}
131+
132+void DICTIONARY::write_data32(uint32_t addr, uint32_t data)
133+{
134+ pair32_t n;
135+ addr = addr & 0xfffffffc;
136+ n.u32 = data;
137+ write_data8(addr + 0, n.l);
138+ write_data8(addr + 1, n.h);
139+ write_data8(addr + 2, n.h2);
140+ write_data8(addr + 3, n.h3);
141+}
142+
143+uint32_t DICTIONARY::read_data8w(uint32_t addr, int *wait)
144+{
145+ if(wait != NULL) *wait = wait_val;
146+ return read_data8(addr, data);
147+}
148+
149+uint32_t DICTIONARY::read_data16w(uint32_t addr, int *wait)
150+{
151+ if(wait != NULL) *wait = wait_val * 2;
152+ return read_data16(addr, data);
153+}
154+
155+uint32_t DICTIONARY::read_data32w(uint32_t addr, int *wait)
156+{
157+ if(wait != NULL) *wait = wait_val * 4;
158+ return read_data32(addr, data);
159+}
160+
161+
162+void DICTIONARY::write_data8w(uint32_t addr, uint32_t data, int *wait)
163+{
164+ if(wait != NULL) *wait = wait_val;
165+ write_data8(addr, data);
166+}
167+
168+void DICTIONARY::write_data16w(uint32_t addr, uint32_t data, int *wait)
169+{
170+ if(wait != NULL) *wait = wait_val * 2;
171+ write_data16(addr, data);
172+}
173+
174+void DICTIONARY::write_data32w(uint32_t addr, uint32_t data, int *wait)
175+{
176+ if(wait != NULL) *wait = wait_val * 4;
177+ write_data32(addr, data);
178+}
179+
180+void DICTIONARY::write_io8(uint32_t addr, uint32_t data)
181+{
182+ if(addr == 0x0480) {
183+ bankd0_dict = ((data & 0x01) != 0);
184+ d_sysrom->write_signal(SIG_FMTONWS_SYSROMSEL, data, 0x02);
185+ } else if(addr == 0x0484) {
186+ dict_bank = data & 0x0f;
187+ } else if((addr >= 0x3000) && (addr < 0x4000)) {
188+ if((addr & 0x0001) == 0) { // OK?
189+ uint32_t naddr = (addr >> 1) & 0x7ff;
190+ cmos_dirty = true;
191+ dict_ram[naddr] = (uint8_t)data;
192+ }
193+ }
194+}
195+
196+uint32_t DICTIONARY::read_io8(uint32_t addr)
197+{
198+ uint32_t data;
199+ if(addr == 0x0480) {
200+ data = ((bank0_dict) ? 0x01 : 0x00) | ((d_sysrom->read_signal(SIG_FMTOWNS_SYSROMSEL) == 0) ? 0x02 : 0x00);
201+ } else if(addr == 0x0484) {
202+ data = dict_bank & 0x0f;
203+ } else if((addr >= 0x3000) && (addr < 0x4000)) {
204+ if((addr & 0x0001) == 0) { // OK?
205+ uint32_t naddr = (addr >> 1) & 0x7ff;
206+ data = dict_ram[naddr];
207+ } else {
208+ data = 0xff;
209+ }
210+ } else {
211+ data = 0xff;
212+ }
213+ return data;
214+}
215+
216+void DICTIONARY::write_signal(int ch, uint32_t data, uint32_t mask)
217+{
218+ switch(ch) {
219+ case SIG_FMTOWNS_DICTSEL:
220+ bankd0_dict = ((data & mask) != 0);
221+ break;
222+ case SIG_FMTOWNS_DICTBANK:
223+ dict_bank = (uint8_t)(data & 0x0f);
224+ break;
225+ case SIG_FMTOWNS_SET_MEMWAIT:
226+ wait_val = (int)data;
227+ break;
228+ }
229+}
230+
231+uint32_t DICTIONARY::read_signal(int ch)
232+{
233+ switch(ch) {
234+ case SIG_FMTOWNS_DICTSEL:
235+ return ((bankd0_dict) ? 0xffffffff : 0x00000000);
236+ break;
237+ case SIG_FMTOWNS_DICTBANK:
238+ return (uint32_t)(dict_bank & 0x0f);
239+ break;
240+ case SIG_FMTOWNS_SET_MEMWAIT:
241+ return (uinrt32_t)wait_val;
242+ break;
243+ }
244+ return 0x00;
245+}
246+
247+#define STATE_VERSION 1
248+
249+bool DICTIONARY::process_state(FILEIO* state_fio, bool loading)
250+{
251+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
252+ return false;
253+ }
254+ if(!state_fio->StateCheckInt32(this_device_id)) {
255+ return false;
256+ }
257+ state_fio->StateValue(wait_val);
258+ state_fio->StateValue(dict_bank);
259+ state_fio->StateValue(bankd0_dict);
260+ state_fio->StateArray(dict_ram, sizeof(dict_ram), 1);
261+ state_fio->StateArray(ram_0d0, sizeof(ram_0d0), 1);
262+
263+ if(loading) {
264+ cmos_dirty = true;
265+ }/* else {
266+ FILEIO* fio = new FILEIO();
267+ if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_WRITE_BINARY)) {
268+ fio->Fwrite(dict_ram, sizeof(dict_ram), 1);
269+ fio->Fclose();
270+ }
271+ delete fio;
272+ cmos_dirty = false;
273+ } */
274+ return true;
275+}
276+}
--- /dev/null
+++ b/source/src/vm/fmtowns/towns_dictionary.h
@@ -0,0 +1,77 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09-
6+
7+ [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000effff]
8+*/
9+
10+#pragma once
11+
12+#include "../../common.h"
13+#include "../device.h"
14+
15+#define SIG_FMTOWNS_DICTSEL 0x1000
16+#define SIG_FMTOWNS_DICTBANK 0x1001
17+
18+namespace FMTOWNS {
19+
20+class DICTIONARY : public DEVICE
21+{
22+protected:
23+ DEVICE *d_sysrom;
24+
25+ uint8_t dict_rom[0x80000]; // 512KB
26+ uint8_t dict_ram[0x2000]; // 2 + 6KB
27+ uint8_t ram_0d0[0x20000]; // 128KB
28+
29+ bool bankd0_dict;
30+ uint8_t dict_bank;
31+ int wait_val;
32+
33+ bool cmos_dirty;
34+
35+public:
36+ DICTIONARY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
37+ {
38+ set_device_name("FM-Towns Dictionary ROM/RAM 0x000d0000 - 0x000effff with CMOS RAM");
39+ }
40+ ~DICTIONARY() {}
41+ void initialize();
42+ void release();
43+ void reset();
44+
45+ uint32_t read_data8(uint32_t addr);
46+ uint32_t read_data16(uint32_t addr);
47+ uint32_t read_data32(uint32_t addr);
48+
49+ uint32_t read_data8w(uint32_t addr, int* wait);
50+ uint32_t read_data16w(uint32_t addr, int* wait);
51+ uint32_t read_data32w(uint32_t addr, int* wait);
52+
53+ void write_data8(uint32_t addr, uint32_t data);
54+ void write_data16(uint32_t addr, uint32_t data);
55+ void write_data32(uint32_t addr, uint32_t data);
56+
57+ void write_data8w(uint32_t addr, uint32_t data, int* wait);
58+ void write_data16w(uint32_t addr, uint32_t data, int* wait);
59+ void write_data32w(uint32_t addr, uint32_t data, int* wait);
60+
61+ void write_io8(uint32_t addr, uint32_t data);
62+ void read_io8(uint32_t addr, uint32_t data);
63+
64+ void write_signal(int ch, uint32_t data, uint32_t mask);
65+ uint32_t read_signal(int ch);
66+
67+ bool process_state(FILEIO* state_fio, bool loading);
68+
69+ void set_context_sysrom(DEVICE* dev)
70+ {
71+ d_sysrom = dev;
72+ }
73+};
74+
75+}
76+
77+// END
--- a/source/src/vm/fmtowns/towns_memory.cpp
+++ b/source/src/vm/fmtowns/towns_memory.cpp
@@ -4,9 +4,10 @@
44 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
55 Date : 2017.01.01 -
66
7- [ memory]
7+ [memory]
88 */
99
10+#include "../../fileio.h"
1011 #include "./towns_memory.h"
1112 #include "../i386.h"
1213
@@ -15,70 +16,22 @@ namespace FMTOWNS {
1516 void TOWNS_MEMORY::initialize()
1617 {
1718
18- bankf8_ram = false;
19- bankd0_dict = false;
20- dict_bank = 0;
2119 extra_nmi_mask = true;
2220 extra_nmi_val = false;
2321
2422 vram_wait_val = 6;
2523 mem_wait_val = 3;
26- machine_id = 0x0100; // FM-Towns 1,2
27- // machine_id = 0x0200 // FM-Towns 1F/2F/1H/2H
28- // machine_id = 0x0300 // FM-Towns UX10/UX20/UX40
29- // machine_id = 0x0400 // FM-Towns 10F/20F/40H/80H
30- // machine_id = 0x0500 // FM-Towns2 CX10/CX20/CX40/CX100
31- // machine_id = 0x0600 // FM-Towns2 UG10/UG20/UG40/UG80
32- // machine_id = 0x0700 // FM-Towns2 HR20/HR100/HR200
33- // machine_id = 0x0800 // FM-Towns2 HG20/HG40/HG100
34- // machine_id = 0x0900 // FM-Towns2 UR20/UR40/UR80
35- // machine_id = 0x0b00 // FM-Towns2 MA20/MA170/MA340
36- // machine_id = 0x0c00 // FM-Towns2 MX20/MX170/MX340
37- // machine_id = 0x0d00 // FM-Towns2 ME20/ME170
38- // machine_id = 0x0f00 // FM-Towns2 MF20/MF170/Fresh
3924
40- //cpu_id = 0x00; // 80286.
41- cpu_id = 0x01; // 80386DX.
42- //cpu_id = 0x02; // 80486SX/DX.
43- //cpu_id = 0x03; // 80386SX.
44-
45-
46- memset(ram_page0, 0x00, sizeof(ram_page0));
47- memset(ram_0f0, 0x00, sizeof(ram_0f0));
48- memset(ram_0f8, 0x00, sizeof(ram_0f8));
4925
50- memset(rom_msdos, 0xff, sizeof(rom_msdos));
51- memset(rom_font1, 0xff, sizeof(rom_font1));
52-#if 0
53- memset(rom_font20, 0xff, sizeof(rom_font20));
54-#endif
55- memset(rom_dict, 0xff, sizeof(rom_dict));
56- memset(rom_system, 0xff, sizeof(rom_system));
26+ memset(ram_page0, 0x00, sizeof(ram_page0));
5727
5828 // load rom image
59- FILEIO* fio = new FILEIO();
60- if(fio->Fopen(create_local_path(_T("FMT_SYS.ROM")), FILEIO_READ_BINARY)) { // SYSTEM
61- fio->Fread(rom_system, sizeof(rom_system), 1);
62- fio->Fclose();
63- }
64- if(fio->Fopen(create_local_path(_T("FMT_FNT.ROM")), FILEIO_READ_BINARY)) { // FONT
65- fio->Fread(rom_font1, sizeof(rom_font1), 1);
66- fio->Fclose();
67- }
6829 #if 0
6930 if(fio->Fopen(create_local_path(_T("FMT_F20.ROM")), FILEIO_READ_BINARY)) { // 20 pixels FONT : Optional
7031 fio->Fread(rom_font20, sizeof(rom_font20), 1);
7132 fio->Fclose();
7233 }
7334 #endif
74- if(fio->Fopen(create_local_path(_T("FMT_DOS.ROM")), FILEIO_READ_BINARY)) { // MSDOS
75- fio->Fread(msdos_rom, sizeof(msdos_rom), 1);
76- fio->Fclose();
77- }
78- if(fio->Fopen(create_local_path(_T("FMT_DIC.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES
79- fio->Fread(dict_rom, sizeof(dict_rom), 1);
80- fio->Fclose();
81- }
8235 // ToDo: Will move to config.
8336 extram_size = TOWNS_EXTRAM_PAGES * 0x100000;
8437 // ToDo: Limit extram_size per VM.
@@ -165,13 +118,14 @@ bool TOWNS_MEMORY::check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, v
165118 break;
166119 case TOWNS_MEMORY_SPRITE_ANKCG1:
167120 if(!mainmem_enabled) {
168- if((ankcg_enabled) && ((addr & 0xfff) < 0x800)) {
169- *mask = 0x7ff;
170- *readp = (void*)(&(rom_font1[(addr & 0x7ff) + 0x3d000]));
171- *writep = (void*)(&(ram_0ca[addr & 0x7ff]));
121+ if(ankcg_enabled) {
122+ *offset = 0x000ca000;
123+ *mask = 0x0fff;
124+ *readfn = (void *)d_fonts;
125+ *writefn = (void *)d_fonts;
172126 } else {
173127 *offset = 0x2000 + FMTOWNS_VRAM_TEXT_VRAM;
174- *mask = 0xfff;
128+ *mask = 0x0fff;
175129 *readfn = (void *)d_vram;
176130 *writefn = (void *)d_vram;
177131 }
@@ -182,9 +136,10 @@ bool TOWNS_MEMORY::check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, v
182136 break;
183137 case TOWNS_MEMORY_SPRITE_ANKCG2:
184138 if(!(mainmem_enabled) && (ankcg_enabled)) {
185- *readp = (void*)(&(rom_font1[(addr & 0x0fff) + 0x3d800]));
186- *writep = (void*)(&(ram_0cb[addr & 0xfff]));
139+ *offset = 0x000cb000;
187140 *mask = 0x0fff;
141+ *readfn = (void *)d_fonts;
142+ *writefn = (void *)d_fonts;
188143 } else {
189144 *readp = (void*)(&(ram_0cb[addr & 0xfff]));
190145 *writep = (void*)(&(ram_0cb[addr & 0xfff]));
@@ -192,42 +147,6 @@ bool TOWNS_MEMORY::check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, v
192147 *offset = 0;
193148 }
194149 break;
195- case TOWNS_MEMORY_DICT_0D0:
196- if(bankd0_dict) {
197- *readp = (void*)(&(dict_rom[(addr & 0x7fff) + (((uint32_t)(dict_bank & 0x0f)) << 15))]);
198- *writep = (void*)(&(ram_0d0[addr & 0x7fff]));
199- } else {
200- *readp = (void*)(&(ram_0d0[addr & 0x7fff]));
201- *writep = (void*)(&(ram_0d0[addr & 0x7fff]));
202- }
203- break;
204- case TOWNS_MEMORY_CMOS_0D8:
205- if(bankd0_dict) {
206- *offset = 0;
207- *mask = 0x1fff;
208- *readfn = (void *)d_cmos;
209- *writefn = (void *)d_cmos;
210- } else {
211- *offset = 0;
212- *mask = 0x1fff;
213- *readp = (void*)(&(ram_0d8[addr & 0x1fff]));
214- *writep = (void*)(&(ram_0d8[addr & 0x1fff]));
215- }
216- break;
217-
218- case TOWNS_MEMORY_PAGE0F8:
219- if(bankf8_ram) {
220- *offset = 0;
221- *mask = 0x7fff;
222- *readp = (void*)(&(ram_0f8[addr & 0x7fff]));
223- *writep = (void*)(&(ram_0f8[addr & 0x7fff]));
224- } else {
225- *offset = 0;
226- *mask = 0x7fff;
227- *readp = (void*)(&rom_system[0x38000 + (addr & 0x7fff)]);
228- *writep = (void*)(&(ram_0f8[addr & 0x7fff]));
229- }
230- break;
231150 default:
232151 return false;
233152 break;
@@ -622,6 +541,8 @@ void TOWNS_MEMORY::write_data32(uint32_t addr, uint32_t data)
622541 // 0x0020 - 0x0022, 0x0030-0x0031,
623542 // 0x0400 - 0x0404,
624543 // 0x0480 - 0x0484
544+// 0x05c0 - 0x05c2
545+// 0x05ec (Wait register)
625546 // Is set extra NMI (0x05c0 - 0x05c2)?
626547 uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
627548 {
@@ -645,6 +566,15 @@ uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
645566 case 0x0031:
646567 val = ((machine_id >> 5) & 0xff);
647568 break;
569+ case 0x0032:
570+ {
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);
576+ }
577+ break;
648578 case 0x006c: // Wait register.
649579 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
650580 val = 0x7f;
@@ -656,14 +586,7 @@ uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
656586 case 0x0404: // System Status Reg.
657587 val = (bankc0_vram) ? 0x7f : 0xff;
658588 break;
659- case 0x0480: // MEMORY BANK REGISTER
660- val = val & ((bankd0_dict) ? 0xff : 0xfe);
661- val = val & ((bankf8_ram) ? 0xff : 0xfd);
662- break;
663- case 0x0484:
664- val = (val & 0xf0 ) | (dict_bank & 0x0f);
665- break;
666- case 0x05c2:
589+ case 0x05c0:
667590 val = (extra_nmi_mask) ? 0xf7 : 0xff;
668591 break;
669592 case 0x05c2:
@@ -700,6 +623,11 @@ uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
700623 }
701624 break;
702625
626+ case 0x05ec:
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);
629+ }
630+ break;
703631 default:
704632 break;
705633 }
@@ -737,6 +665,13 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
737665 }
738666 // Power register
739667 break;
668+ case 0x0032:
669+ {
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);
673+ }
674+ break;
740675 case 0x006c: // Wait register.
741676 if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H
742677 if(event_wait_1us != -1) cancel_event(this, event_wait_1us);
@@ -747,12 +682,16 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
747682 case 0x0404: // System Status Reg.
748683 bankc0_vram = ((data & 0x80) != 0);
749684 break;
750- case 0x0480: // MEMORY BANK REGISTER
751- bankd0_dict = ((data & 0x01) != 0);
752- bankf8_ram = ((data & 0x02) != 0);
685+ case 0x05c0:
686+ extra_nmi_mask = ((data & 0x08) == 0);
753687 break;
754- case 0x0484:
755- dict_bank = data & 0x0f;
688+ case 0x05ec:
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);
694+ }
756695 break;
757696 default:
758697 break;
@@ -948,22 +887,11 @@ void TOWNS_MEMORY::initialize_tables(void)
948887 for(uint32_t ui = 0x000cc; ui < 0x000d0; ui++) { // $000c0000 - $000effff
949888 type_bank_adrs_cx[ui] = (TOWNS_MEMORY_MMIO_0CC << 24) | ((ui - 0xcc) << 12);
950889 }
951- for(uint32_t ui = 0x000d0; ui < 0x000d8; ui++) { // $000c0000 - $000effff
952- type_bank_adrs_cx[ui] = (TOWNS_MEMORY_DICT_0D0 << 24) | ((ui - 0xd0) << 12);
953- }
954- for(uint32_t ui = 0x000d8; ui < 0x000da; ui++) { // $000c0000 - $000effff
955- type_bank_adrs_cx[ui] = (TOWNS_MEMORY_CMOS_0D8 << 24) | ((ui - 0xd8) << 12);
956- }
957- for(uint32_t ui = 0x000da; ui < 0x000f0; ui++) { // $00000000 - $000bffff
958- read_bank_adrs_cx[ui] = &(ram_0da[ui << 12]);
959- write_bank_adrs_cx[ui] = &(ram_0da[ui << 12]);
890+ for(uint32_t ui = 0x000d0; ui < 0x000f0; ui++) { // $000c0000 - $000effff
891+ device_bank_adrs_cx[ui] = d_dictionary;
960892 }
961- for(uint32_t ui = 0x000f0; ui < 0x000f8; ui++) { // $000f0000 - $000f7fff
962- read_bank_adrs_cx[ui] = &(ram_0f0[(ui - 0xf0) << 12]);
963- write_bank_adrs_cx[ui] = &(ram_0f0[(ui - 0xf0) << 12]);
964- }
965- for(uint32_t ui = 0x000f8; ui < 0x00100; ui++) { // $000c0000 - $000effff
966- type_bank_adrs_cx[ui] = (TOWNS_MEMORY_PAGE0F8 << 24) | ((ui - 0xf8) << 12);
893+ for(uint32_t ui = 0x000f0; ui < 0x00100; ui++) { // $000f0000 - $000fffff
894+ device_bank_adrs_cx[ui] = d_sysrom;
967895 }
968896 // Extra RAM
969897 for(uint32_t ui = 0x00100; ui < (0x00100 + (extram_size >> 12)); ui++) {
@@ -1000,25 +928,28 @@ void TOWNS_MEMORY::initialize_tables(void)
1000928 device_bank_adrs_cx[ui] = d_romcard[1];
1001929 }
1002930 for(uint32_t ui = 0xc2140; ui < 0xc2142; ui++) {
1003- device_bank_adrs_cx[ui] = d_cmos;
931+ device_bank_adrs_cx[ui] = d_dictionary;
1004932 }
1005933 for(uint32_t ui = 0xc2200; ui < 0xc2201; ui++) {
1006934 device_bank_adrs_cx[ui] = d_pcm;
1007935 }
1008936 // ROMs
1009937 for(uint32_t ui = 0xc2000; ui < 0xc2080; ui++) {
1010- read_bank_adrs_cx[ui] = &(rom_msdos[(ui - 0xc2000) << 12]);
938+ device_bank_adrs_cx[ui] = d_msdos;
1011939 }
1012940 for(uint32_t ui = 0xc2080; ui < 0xc2100; ui++) {
1013- read_bank_adrs_cx[ui] = &(rom_dict[(ui - 0xc2080) << 12]);
941+ device_bank_adrs_cx[ui] = d_dictionary;
1014942 }
1015943 for(uint32_t ui = 0xc2100; ui < 0xc2140; ui++) {
1016- read_bank_adrs_cx[ui] = &(rom_font1[(ui - 0xc2100) << 12]);
944+ device_bank_adrs_cx[ui] = d_fonts;
945+ }
946+ for(uint32_t ui = 0xc2180; ui < 0xc2200; ui++) { // 20pixs fonts.
947+ device_bank_adrs_cx[ui] = d_fonts;
1017948 }
1018949
1019950 // SYSTEM CODE ROM
1020951 for(uint32_t ui = 0xfffc0; ui < 0x100000; ui++) {
1021- read_bank_adrs_cx[ui] = &(rom_system[(ui - 0xfffc0) << 12]);
952+ device_bank_adrs_cx[ui] = d_sysrom;
1022953 }
1023954 }
1024955
@@ -1065,21 +996,43 @@ uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
1065996 }
1066997
1067998
1068-void TOWNS_MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
999+void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask)
10691000 {
1070- if(id == SIG_MEMORY_EXTNMI) {
1001+ if(ch == SIG_MEMORY_EXTNMI) {
10711002 extra_nmi_val = ((data & mask) != 0);
1072- } else if(id == SIG_CPU_NMI) {
1003+ } else if(ch == SIG_CPU_NMI) {
10731004 // Check protect
10741005 d_cpu->write_signal(SIG_CPU_NMI, data, mask);
1075- } else if(id == SIG_CPU_IRQ) {
1006+ } else if(ch == SIG_CPU_IRQ) {
10761007 d_cpu->write_signal(SIG_CPU_IRQ, data, mask);
1077- } else if(id == SIG_CPU_BUSREQ) {
1008+ } else if(ch == SIG_CPU_BUSREQ) {
10781009 d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask);
1079- } else if(id == SIG_I386_A20) {
1010+ } else if(ch == SIG_I386_A20) {
10801011 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);
10811021 }
10821022 }
1023+
1024+uint32_t TOWNS_MEMORY::read_signal(int ch)
1025+{
1026+ if(ch == SIG_FMTOWNS_MACHINE_ID) {
1027+ uint16_t d = (machine_id & 0xfff8) | ((uint16_t)(cpu_id & 0x07));
1028+ return (uint32_t)d;
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;
1033+ }
1034+ return 0;
1035+}
10831036 // ToDo: DMA
10841037
10851038 #define STATE_VERSION 1
@@ -1093,10 +1046,7 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
10931046 return false;
10941047 }
10951048 state_fio->StateValue(bankc0_vram);
1096- state_fio->StateValue(bankf8_vram);
1097- state_fio->StateValue(bankd0_dict);
10981049 state_fio->StateValue(ankcg_enabled);
1099- state_fio->StateValue(dict_bank);
11001050 state_fio->StateValue(machine_id);
11011051 state_fio->StateValue(cpu_id);
11021052
@@ -1111,12 +1061,6 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
11111061 state_fio->StateArray(ram_0cb, sizeof(ram_0cb), 1);
11121062 state_fio->StateArray(ram_0cc, sizeof(ram_0cc), 1);
11131063
1114- state_fio->StateArray(ram_0d0, sizeof(ram_0d0), 1);
1115- state_fio->StateArray(ram_0d8, sizeof(ram_0d8), 1);
1116- state_fio->StateArray(ram_0da, sizeof(ram_0da), 1);
1117-
1118- state_fio->StateArray(ram_0f0, sizeof(ram_0f0), 1);
1119- state_fio->StateArray(ram_0f8, sizeof(ram_0f8), 1);
11201064
11211065 if(loading) {
11221066 uint32_t length_tmp = state_fio->FgetUint32_LE();
--- a/source/src/vm/fmtowns/towns_memory.h
+++ b/source/src/vm/fmtowns/towns_memory.h
@@ -10,12 +10,11 @@
1010 #ifndef _TOWNS_MEMORY_H_
1111 #define _TOWNS_MEMORY_H_
1212
13-#include "../vm.h"
14-#include "../../emu.h"
13+//#include "../vm.h"
14+//#include "../../emu.h"
1515 #include "../device.h"
1616
17-//#define SIG_MEMORY_DISP 0
18-//#define SIG_MEMORY_VSYNC 1
17+#define SIG_FMTOWNS_MACHINE_ID 1
1918
2019 class I386;
2120 // Bank size = 1GB / 1MB.
@@ -49,14 +48,10 @@ enum {
4948 TOWNS_MEMORY_ANKCG2,
5049
5150 TOWNS_MEMORY_MMIO_0CC,
52- TOWNS_MEMORY_DICT_0D0,
53- TOWNS_MEMORY_CMOS_0D8,
54- TOWNS_MEMORY_PAGE0F8,
5551
5652 TOWNS_MEMORY_TYPE_EXT_MMIO,
5753 TOWNS_MEMORY_TYPE_LEARN_RAM,
5854 TOWNS_MEMORY_TYPE_WAVERAM,
59- TOWNS_MEMORY_TYPE_SYSTEM_ROM,
6055 };
6156 }
6257 // Please set from config
@@ -69,7 +64,6 @@ namespace FMTOWNS {
6964 class TOWNS_VRAM;
7065 class TOWNS_SPRITE;
7166 class TOWNS_ROM_CARD;
72- class TOWNS_CMOS;
7367 class TOWNS_PCM;
7468 }
7569
@@ -82,15 +76,16 @@ protected:
8276 TOWNS_VRAM* d_vram;
8377 TOWNS_SPRITE* d_sprite; // 0x81000000 - 0x8101ffff ?
8478 TOWNS_ROM_CARD* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff
85- TOWNS_CMOS* d_cmos; // 0xc2140000 - 0xc2141fff
8679 TOWNS_PCM* d_pcm; // 0xc2200000 - 0xc2200fff
8780 BEEP* d_beep;
81+
82+ DEVICE* d_dictionary;
83+ DEVICE* d_sysrom;
84+ DEVICE* d_msdos;
85+ DEVICE* d_serialrom;
8886
8987 bool bankc0_vram;
90- bool bankf8_ram;
91- bool bankd0_dict;
9288 bool ankcg_enabled;
93- uint8_t dict_bank;
9489
9590 uint16_t machine_id;
9691 uint8_t cpu_id;
@@ -114,11 +109,6 @@ protected:
114109 uint8_t ram_0ca[0x1000]; // 0x000ca000 - 0x000cafff : ANKCG1 / IO / RAM
115110 uint8_t ram_0cb[0x1000]; // 0x000cb000 - 0x000cbfff : ANKCG2 / RAM
116111 uint8_t ram_0cc[0x4000]; // 0x000cc000 - 0x000cffff : MMIO / RAM
117- uint8_t ram_0d0[0x8000]; // 0x000d0000 - 0x000d7fff : RAM / BANKED DICTIONARY
118- uint8_t ram_0d8[0x2000]; // 0x000d8000 - 0x000d9fff : RAM / CMOS
119- uint8_t ram_0da[0x16000]; // 0x000da000 - 0x000effff : RAM
120- uint8_t ram_0f0[0x8000]; // 0x000f0000 - 0x000f7fff
121- uint8_t ram_0f8[0x8000]; // 0x000f8000 - 0x000fffff : RAM/ROM
122112
123113 uint8_t *extram; // 0x00100000 - (0x3fffffff) : Size is defined by extram_size;
124114 uint32_t extram_size;
@@ -127,10 +117,7 @@ protected:
127117 uint32_t mem_wait_val;
128118
129119 // ROM
130- uint8_t rom_msdos[0x80000]; // 0xc2000000 - 0xc207ffff
131- uint8_t rom_dict[0x80000]; // 0xc2080000 - 0xc20fffff
132120 uint8_t rom_font1[0x40000]; // 0xc2100000 - 0xc23f0000
133- uint8_t rom_system[0x40000]; // 0xfffc0000 - 0xffffffff
134121 #if 0
135122 uint8_t rom_font20[0x80000];
136123 #endif
@@ -159,7 +146,32 @@ public:
159146 d_sprite = NULL;
160147 d_romcard[0] = d_romcard[1] = NULL;
161148 d_beep = NULL;
162- machine_id = 0;
149+ d_sysrom = NULL;
150+ d_dictionary = NULL;
151+ d_msdos = NULL;
152+ // Note: machine id must set before initialize() from set_context_machine_id() by VM::VM().
153+ // machine_id = 0x0100; // FM-Towns 1,2
154+ // machine_id = 0x0200 // FM-Towns 1F/2F/1H/2H
155+ // machine_id = 0x0300 // FM-Towns UX10/UX20/UX40
156+ // machine_id = 0x0400 // FM-Towns 10F/20F/40H/80H
157+ // machine_id = 0x0500 // FM-Towns2 CX10/CX20/CX40/CX100
158+ // machine_id = 0x0600 // FM-Towns2 UG10/UG20/UG40/UG80
159+ // machine_id = 0x0700 // FM-Towns2 HR20/HR100/HR200
160+ // machine_id = 0x0800 // FM-Towns2 HG20/HG40/HG100
161+ // machine_id = 0x0900 // FM-Towns2 UR20/UR40/UR80
162+ // machine_id = 0x0b00 // FM-Towns2 MA20/MA170/MA340
163+ // machine_id = 0x0c00 // FM-Towns2 MX20/MX170/MX340
164+ // machine_id = 0x0d00 // FM-Towns2 ME20/ME170
165+ // machine_id = 0x0f00 // FM-Towns2 MF20/MF170/Fresh
166+ machine_id = 0x0100; // FM-Towns 1,2
167+
168+ // Note: cpu id must set before initialize() from set_context_cpu_id() by VM::VM().
169+ // cpu_id = 0x00; // 80286.
170+ // cpu_id = 0x01; // 80386DX.
171+ // cpu_id = 0x02; // 80486SX/DX.
172+ // cpu_id = 0x03; // 80386SX.
173+ cpu_id = 0x01; // 80386DX.
174+
163175 }
164176 ~TOWNS_MEMORY() {}
165177
@@ -207,6 +219,18 @@ public:
207219 {
208220 d_vram = device;
209221 }
222+ void set_context_system_rom(DEVICE* device)
223+ {
224+ d_sysrom = device;
225+ }
226+ void set_context_dictionary(DEVICE* device)
227+ {
228+ d_dictionary = device;
229+ }
230+ void set_context_msdos(DEVICE* device)
231+ {
232+ d_msdos = device;
233+ }
210234 void set_context_beep(DEVICE* device)
211235 {
212236 d_beep = device;
@@ -223,7 +247,18 @@ public:
223247 {
224248 d_pcm = device;
225249 }
226-
250+ void set_context_serial_rom(DEVICE* device)
251+ {
252+ d_serialrom = device;
253+ }
254+ void set_context_machine_id(uint16_t val)
255+ {
256+ machine_id = val & 0xfff8;
257+ }
258+ void set_context_cpu_id(uint16_t val)
259+ {
260+ cpu_id = val & 0x07;
261+ }
227262 };
228263
229264 }
--- /dev/null
+++ b/source/src/vm/fmtowns/towns_sysrom.cpp
@@ -0,0 +1,123 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09-
6+
7+ [ system rom & RAM area 0x000f0000 - 0x000fffff]
8+*/
9+
10+#include "./towns_common.h"
11+#include "./towns_sysrom.h"
12+#include "../../fileio.h"
13+
14+namespace FMTOWNS {
15+void SYSROM::initialize()
16+{
17+ cmos_dirty = false;
18+
19+ memset(rom, 0xff, sizeof(rom));
20+ memset(ram, 0x00, sizeof(ram));
21+
22+ FILEIO* fio = new FILEIO();
23+ if(fio->Fopen(create_local_path(_T("FMT_SYS.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES
24+ fio->Fread(rom, sizeof(rom), 1);
25+ fio->Fclose();
26+ }
27+
28+ wait_val = 3;
29+ map_dos = true;
30+}
31+
32+
33+void SYSROM::reset()
34+{
35+ //wait_val = 6; // OK?
36+ //map_dos = true;
37+}
38+
39+uint32_t SYSROM::read_data8(uint32_t addr)
40+{
41+ uint8_t n_data = 0xff;
42+ if(addr < 0xfffc0000) { // Banked (from MSDOS/i86 compatible mode)
43+ if((addr >= 0x000f8000) && (addr < 0x00100000)) {
44+ if(map_dos) {
45+ n_data = rom[(addr & 0x7fff) + 0x38000];
46+ } else {
47+ n_data = ram[addr & 0xffff];
48+ }
49+ } else if((addr >= 0x000f0000) && (addr < 0x00100000)) {
50+ n_data = ram[addr & 0xffff];
51+ }
52+ } else {
53+ n_data = rom[addr & 0x3ffff];
54+ }
55+ return (uint32_t)n_data;
56+}
57+
58+void SYSROM::write_data8(uint32_t addr, uint32_t data)
59+{
60+ if(addr < 0xfffc0000) {
61+ if((addr >= 0x000f8000) && (addr < 0x00100000)) {
62+ if(!(map_dos)) {
63+ ram[addr & 0xffff] = (uint8_t)data;
64+ }
65+ } else if((addr >= 0x000f0000) && (addr < 0x00100000)) {
66+ ram[addr & 0xffff] = (uint8_t)data;
67+ }
68+ }
69+}
70+
71+void SYSROM::write_signal(int ch, uint32_t data, uint32_t mask)
72+{
73+ switch(ch) {
74+ case SIG_FMTOWNS_SYSROMSEL:
75+ map_dos = ((data & mask) == 0);
76+ break;
77+ case SIG_FMTOWNS_SET_MEMWAIT:
78+ wait_val = (int)data;
79+ break;
80+ }
81+}
82+
83+uint32_t SYSROM::read_signal(int ch)
84+{
85+ switch(ch) {
86+ case SIG_FMTOWNS_SYSROMSEL:
87+ return ((map_dos) ? 0x00 : 0x02);
88+ break;
89+ case SIG_FMTOWNS_SET_MEMWAIT:
90+ return (uint32_t)wait_val;
91+ break;
92+ }
93+ return 0x00;
94+}
95+
96+uint32_t SYSROM::read_data8w(uint32_t addr, int *wait)
97+{
98+ if(wait != NULL) *wait = wait_val;
99+ return read_data8(addr, data);
100+}
101+
102+void SYSROM::write_data8w(uint32_t addr, uint32_t data, int *wait)
103+{
104+ if(wait != NULL) *wait = wait_val;
105+ write_data8(addr, data);
106+}
107+
108+#define STATE_VERSION 1
109+
110+bool SYSROM::process_state(FILEIO* state_fio, bool loading)
111+{
112+ if(!state_fio->StateCheckUint32(STATE_VERSION)) {
113+ return false;
114+ }
115+ if(!state_fio->StateCheckInt32(this_device_id)) {
116+ return false;
117+ }
118+ state_fio->StateValue(wait_val);
119+ state_fio->StateValue(map_dos);
120+ state_fio->StateArray(ram, sizeof(ram), 1);
121+ return true;
122+}
123+}
--- /dev/null
+++ b/source/src/vm/fmtowns/towns_sysrom.h
@@ -0,0 +1,52 @@
1+/*
2+ FUJITSU FM Towns Emulator 'eFMTowns'
3+
4+ Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5+ Date : 2019.01.09-
6+
7+ [ SYSTEM rom & RAM area 0x000f0000 - 0x000fffff]
8+*/
9+
10+#pragma once
11+
12+#include "common.h"
13+#include "device.h"
14+
15+#define SIG_FMTOWNS_SYSROMSEL 0x1000
16+
17+namespace FMTOWNS {
18+
19+class SYSROM : public DEVICE
20+{
21+protected:
22+ uint8_t rom[0x40000]; // 256KB
23+ uint8_t ram[0x10000]; // 64KB
24+ int wait_val;
25+
26+ bool map_dos;
27+
28+public:
29+ SYSROM(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
30+ {
31+ set_device_name("FM-Towns SYSTEM ROM/RAM 0x000fxxxx");
32+ }
33+ ~SYSROM() {}
34+ void initialize();
35+ void reset();
36+
37+ uint32_t read_data8(uint32_t addr);
38+ uint32_t read_data8w(uint32_t addr, int* wait);
39+
40+ void write_data8(uint32_t addr, uint32_t data);
41+ void write_data8w(uint32_t addr, uint32_t data, int* wait);
42+
43+ void write_signal(int ch, uint32_t data, uint32_t mask);
44+ uint32_t read_signal(int ch);
45+
46+ bool process_state(FILEIO* state_fio, bool loading);
47+
48+};
49+
50+}
51+
52+// END
Show on old repository browser