2 * Emulation of Fujitsu Japanese Communication Card.
5 * Based on XM7 L70 , with permittion from Ryu Takegami.
9 #include "../../fileio.h"
12 #include "fm7_common.h"
14 #include "../mc6809.h"
15 #include "./jcommcard.h"
17 FM7_JCOMMCARD::FM7_JCOMMCARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
22 kanji_address.d = 0x00000000;
24 memset(prog_rom, 0xff, sizeof(prog_rom));
25 memset(dict_rom, 0xff, sizeof(dict_rom));
26 memset(p_ram, 0x00, sizeof(p_ram));
30 diag_dictrom_load = false;
33 FM7_JCOMMCARD::~FM7_JCOMMCARD()
37 void FM7_JCOMMCARD::initialize(void)
39 FILEIO *fio = new FILEIO();
41 bool b_stat_dicrom = false;
43 if(fio->Fopen(create_local_path(_T(ROM_JCOMM_FIRMWARE)), FILEIO_READ_BINARY)) { // 20180114
44 fio->Fread(prog_rom, sizeof(prog_rom), 1);
49 /* Patch from XM7/VM/jsubsys.c */
50 if(prog_rom[0x000d] == 0x8f) {
51 prog_rom[0x000d] = 0x88;
53 /* Change: DICT.ROM to JSUBDICT.ROM */
54 if(fio->Fopen(create_local_path(_T(ROM_JCOMM_DICTIONARY)), FILEIO_READ_BINARY)) {
55 nsize = fio->Fread(dict_rom, 1, sizeof(dict_rom));
57 if(nsize >= sizeof(dict_rom)) {
58 diag_dictrom_load = true;
59 this->out_debug_log(_T("FULL SET OF DICTIONARY ROM WITH KANJI LOADED."));
61 this->out_debug_log(_T("PARTLY SET OF DICTIONARY ROM LOADED."));
66 if(!diag_dictrom_load) {
67 if(fio->Fopen(create_local_path(_T(ROM_JCOMM_KANJI)), FILEIO_READ_BINARY)) {
68 fio->Fread(&(dict_rom[0x40000]), 0x20000, 1);
71 } else if(fio->Fopen(create_local_path(_T(ROM_KANJI_CLASS1)), FILEIO_READ_BINARY)) {
72 fio->Fread(&(dict_rom[0x40000]), 0x20000, 1);
75 } else if(fio->Fopen(create_local_path(_T(ROM_KANJI_CLASS1_FALLBACK)), FILEIO_READ_BINARY)) {
76 fio->Fread(&(dict_rom[0x40000]), 0x20000, 1);
80 this->out_debug_log(_T("KANJIROM READ %s."), b_stat ? "OK" : "FAILED");
86 void FM7_JCOMMCARD::write_signal(int id, uint32_t data, uint32_t mask)
88 bool b = ((data & mask) != 0);
90 case FM7_JCOMMCARD_BUS_HALT:
96 uint32_t FM7_JCOMMCARD::read_io8(uint32_t address)
107 /* RCB DATA (Auto increment address) */
109 data = p_ram[0x1f00 | rcb_address];
116 data = dict_rom[0x40000 + (kanji_address.d << 1) + (address & 1)];
122 void FM7_JCOMMCARD::write_io8(uint32_t address, uint32_t data)
124 switch(address & 3) {
126 /* Kanji Address High */
127 kanji_address.b.h = (uint8_t)(data & 0xff);
130 /* Kanji Address Low */
131 kanji_address.b.l = (uint8_t)(data & 0xff);
134 /* REQUEST TO HALT */
135 if((data & 0x80) != 0) {
136 if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0x00000000, 0xffffffff);
140 if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0xffffffff, 0xffffffff);
147 /* RCB DATA (Auto increment address) */
149 p_ram[0x1f00 | rcb_address] = (uint8_t)data;
156 uint32_t FM7_JCOMMCARD::read_data8(uint32_t address)
160 * $9FFF : SYNC/BANK REG
162 * $C000-$FFFF : SUB SYSTEM
164 if(address < 0x8000) return 0xff; /* NOOP */
165 if(address <= 0x9ffe) { /* SRAM */
166 return (uint32_t)p_ram[address & 0x1fff];
167 } else if(address == 0x9fff) { /* RCB BANK REGISTER */
168 return (uint32_t)n_bank;
169 } else if(address < 0xb000) { /* DICT ROM */
170 return (uint32_t)(dict_rom[(address & 0x0fff) | (((uint32_t)n_bank) << 12)]);
171 } else if(address < 0xc000) {
173 } else if(address < 0x10000) {
174 return (uint32_t)prog_rom[address & 0x3fff];
179 void FM7_JCOMMCARD::write_data8(uint32_t address, uint32_t data)
181 if(address < 0x8000) return;
182 if(address >= 0xa000) return;
183 if(address == 0x9fff) {
184 if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, ((data & 0x80) == 0) ? 0xffffffff : 0, 0xffffffff);
185 //halted = ((data & 0x80) == 0);
186 n_bank = (uint8_t)(data & 0x3f);
187 } else if(address < 0x9fff) {
189 p_ram[address & 0x1fff] = (uint8_t)data;
193 void FM7_JCOMMCARD::release(void)
196 FILEIO *fio = new FILEIO();
198 if(fio->Fopen(create_local_path(_T(RAM_JCOMM_BACKUP)), FILEIO_WRITE_BINARY)) {
199 fio->Fwrite(p_ram, sizeof(p_ram), 1);
206 if(state_entry != NULL) delete state_entry;
209 void FM7_JCOMMCARD::reset(void)
212 kanji_address.d = 0x00000000;
214 cpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
219 #define STATE_VERSION 3
220 #include "../../statesub.h"
222 void FM7_JCOMMCARD::decl_state(void)
224 state_entry = new csp_state_utils(STATE_VERSION, this_device_id, _T("FM7_JCOMM_CARD"));
226 DECL_STATE_ENTRY_SINGLE(n_bank);
227 DECL_STATE_ENTRY_SINGLE(rcb_address);
228 DECL_STATE_ENTRY_SINGLE(kanji_address);
229 DECL_STATE_ENTRY_SINGLE(halted);
231 DECL_STATE_ENTRY_1DARRAY(prog_rom, 0x4000);
232 DECL_STATE_ENTRY_1DARRAY(dict_rom, 0x60000);
233 DECL_STATE_ENTRY_1DARRAY(p_ram, 0x2000);
234 DECL_STATE_ENTRY_BOOL(firmware_ok);
237 void FM7_JCOMMCARD::save_state(FILEIO *state_fio)
239 //state_fio->FputUint32_BE(STATE_VERSION);
240 //state_fio->FputInt32_BE(this_device_id);
241 this->out_debug_log(_T("Save State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
243 if(state_entry != NULL) state_entry->save_state(state_fio);
244 //state_fio->FputUint8(n_bank & 0x3f);
245 //state_fio->FputUint8(rcb_address);
246 //state_fio->FputUint32_BE(kanji_address.d);
248 //state_fio->FputBool(halted);
250 //state_fio->Fwrite(prog_rom, sizeof(prog_rom), 1);
251 //state_fio->Fwrite(dict_rom, sizeof(dict_rom), 1);
252 //state_fio->Fwrite(p_ram, sizeof(p_ram), 1);
253 //state_fio->FputBool(firmware_ok);
257 bool FM7_JCOMMCARD::load_state(FILEIO *state_fio)
260 //version = state_fio->FgetUint32_BE();
261 //if(this_device_id != state_fio->FgetInt32_BE()) return false;
262 this->out_debug_log(_T("Load State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
263 if(state_entry != NULL) {
264 if(!(state_entry->load_state(state_fio))) {
273 // n_bank = state_fio->FgetUint8() & 0x3f;
274 // rcb_address = state_fio->FgetUint8();
275 // kanji_address.d = state_fio->FgetUint32_BE();
276 // halted = state_fio->FgetBool();
277 // state_fio->Fread(prog_rom, sizeof(prog_rom), 1);
278 // state_fio->Fread(dict_rom, sizeof(dict_rom), 1);
279 // state_fio->Fread(p_ram, sizeof(p_ram), 1);
280 // firmware_ok = state_fio->FgetBool();
281 //modified = true; // Abondoned