OSDN Git Service

[VM][STATE] Apply new state framework to some devices a lot (excepts some devices...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / jcommcard.cpp
1 /*
2  * Emulation of Fujitsu Japanese Communication Card.
3  * (C) 2018 K.Ohta.
4  * Note:
5  * Based on XM7 L70 , with permittion from Ryu Takegami. 
6  */
7
8 #include "vm.h"
9 #include "../../fileio.h"
10 #include "emu.h"
11
12 #include "fm7_common.h"
13
14 #include "../mc6809.h"
15 #include "./jcommcard.h"
16
17 FM7_JCOMMCARD::FM7_JCOMMCARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
18 {
19         n_bank = 0;
20         rcb_address = 0;
21         halted = false;
22         kanji_address.d = 0x00000000;
23                 
24         memset(prog_rom, 0xff, sizeof(prog_rom));
25         memset(dict_rom, 0xff, sizeof(dict_rom));
26         memset(p_ram, 0x00, sizeof(p_ram));
27         cpu = NULL;
28         //modified = true;
29         firmware_ok = false;
30         diag_dictrom_load = false;
31 }
32
33 FM7_JCOMMCARD::~FM7_JCOMMCARD()
34 {
35 }
36
37 void FM7_JCOMMCARD::initialize(void)
38 {
39         FILEIO *fio = new FILEIO();
40         bool b_stat = false;
41         bool b_stat_dicrom = false;
42         size_t nsize;
43         if(fio->Fopen(create_local_path(_T(ROM_JCOMM_FIRMWARE)), FILEIO_READ_BINARY)) { // 20180114
44                 fio->Fread(prog_rom, sizeof(prog_rom), 1);
45                 fio->Fclose();
46                 firmware_ok = true;
47         }
48
49         /* Patch from XM7/VM/jsubsys.c */
50         if(prog_rom[0x000d] == 0x8f) {
51                 prog_rom[0x000d] = 0x88;
52         }
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));
56                 fio->Fclose();
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."));
60                 } else {
61                         this->out_debug_log(_T("PARTLY SET OF DICTIONARY ROM LOADED."));
62                 }                       
63         }
64         /* KANJI ROM */
65         
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);
69                         fio->Fclose();
70                         b_stat = true;
71                 } else if(fio->Fopen(create_local_path(_T(ROM_KANJI_CLASS1)), FILEIO_READ_BINARY)) {
72                         fio->Fread(&(dict_rom[0x40000]), 0x20000, 1);
73                         fio->Fclose();
74                         b_stat = true;
75                 } else if(fio->Fopen(create_local_path(_T(ROM_KANJI_CLASS1_FALLBACK)), FILEIO_READ_BINARY)) {
76                         fio->Fread(&(dict_rom[0x40000]), 0x20000, 1);
77                         fio->Fclose();
78                         b_stat = true;
79                 }
80                 this->out_debug_log(_T("KANJIROM READ %s."), b_stat ? "OK" : "FAILED");
81         }
82         delete fio;
83 }
84
85
86 void FM7_JCOMMCARD::write_signal(int id, uint32_t data, uint32_t mask)
87 {
88         bool b = ((data & mask) != 0);
89         switch(id) {
90         case FM7_JCOMMCARD_BUS_HALT:
91                 halted = b;
92                 break;
93         }
94 }
95
96 uint32_t FM7_JCOMMCARD::read_io8(uint32_t address)
97 {
98         uint32_t data = 0xff;
99         switch(address & 3) {
100         case 0:
101                 /* HALT STATUS */
102                 if(halted) {
103                         data &= 0x7f;
104                 }
105                 break;
106         case 1:
107                 /* RCB DATA (Auto increment address) */
108                 if(halted) {
109                         data = p_ram[0x1f00 | rcb_address];
110                         rcb_address++;
111                 }
112                 break;
113         case 2:
114         case 3:
115                 /* Kanji Data */
116                 data = dict_rom[0x40000 + (kanji_address.d << 1) + (address & 1)];
117                 break;
118         }
119         return data;
120 }
121
122 void FM7_JCOMMCARD::write_io8(uint32_t address, uint32_t data)
123 {
124         switch(address & 3) {
125         case 0:
126                 /* Kanji Address High */
127                 kanji_address.b.h = (uint8_t)(data & 0xff);
128                 break;
129         case 1:
130                 /* Kanji Address Low */
131                 kanji_address.b.l = (uint8_t)(data & 0xff);
132                 break;
133         case 2:
134                 /* REQUEST TO HALT */
135                 if((data & 0x80) != 0) {
136                         if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0x00000000, 0xffffffff);
137                         //haltreq = false;
138                         //halted = false;
139                 } else {
140                         if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0xffffffff, 0xffffffff);
141                         //haltreq = true;
142                         //halted = true;
143                         rcb_address = 0;
144                 }
145                 break;
146         case 3:
147                 /* RCB DATA (Auto increment address) */
148                 if(halted) {
149                         p_ram[0x1f00 | rcb_address] = (uint8_t)data;
150                         rcb_address++;
151                 }
152                 break;
153         }
154 }
155
156 uint32_t FM7_JCOMMCARD::read_data8(uint32_t address)
157 {
158         /*
159          * $8000-$9FFE : SRAM
160          * $9FFF       : SYNC/BANK REG
161          * $A000-$AFFF : DICT
162          * $C000-$FFFF : SUB SYSTEM
163          */
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) {
172                 return 0xff;
173         } else if(address < 0x10000) {
174                 return (uint32_t)prog_rom[address & 0x3fff];
175         }
176         return 0xff;
177 }
178
179 void FM7_JCOMMCARD::write_data8(uint32_t address, uint32_t data)
180 {
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) {
188                 //modified = true;
189                 p_ram[address & 0x1fff] = (uint8_t)data;
190         }
191 }
192
193 void FM7_JCOMMCARD::release(void)
194 {
195 #if 0
196         FILEIO *fio = new FILEIO();
197         if(modified) {
198                 if(fio->Fopen(create_local_path(_T(RAM_JCOMM_BACKUP)), FILEIO_WRITE_BINARY)) {
199                         fio->Fwrite(p_ram, sizeof(p_ram), 1);
200                         fio->Fclose();
201                         modified = false;
202                 }
203         }
204         delete fio;
205 #endif
206         if(state_entry != NULL) delete state_entry;
207 }
208         
209 void FM7_JCOMMCARD::reset(void)
210 {
211         rcb_address = 0x00;
212         kanji_address.d = 0x00000000;
213         if(cpu != NULL) {
214                 cpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
215                 cpu->reset();
216         }
217 }
218
219 #define STATE_VERSION 3
220 #include "../../statesub.h"
221
222 void FM7_JCOMMCARD::decl_state(void)
223 {
224         enter_decl_state(STATE_VERSION);
225  
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);
230
231         DECL_STATE_ENTRY_1D_ARRAY(prog_rom, 0x4000);
232         DECL_STATE_ENTRY_1D_ARRAY(dict_rom, 0x60000);
233         DECL_STATE_ENTRY_1D_ARRAY(p_ram, 0x2000);
234         DECL_STATE_ENTRY_BOOL(firmware_ok);
235
236         leave_decl_state();
237 }
238
239 void FM7_JCOMMCARD::save_state(FILEIO *state_fio)
240 {
241         //state_fio->FputUint32_BE(STATE_VERSION);
242         //state_fio->FputInt32_BE(this_device_id);
243         this->out_debug_log(_T("Save State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
244
245         if(state_entry != NULL) state_entry->save_state(state_fio);
246         //state_fio->FputUint8(n_bank & 0x3f);
247         //state_fio->FputUint8(rcb_address);
248         //state_fio->FputUint32_BE(kanji_address.d);
249
250         //state_fio->FputBool(halted);
251
252         //state_fio->Fwrite(prog_rom, sizeof(prog_rom), 1);
253         //state_fio->Fwrite(dict_rom, sizeof(dict_rom), 1);
254         //state_fio->Fwrite(p_ram, sizeof(p_ram), 1);
255         //state_fio->FputBool(firmware_ok);
256
257 }
258
259 bool FM7_JCOMMCARD::load_state(FILEIO *state_fio)
260 {
261         //uint32_t version;
262         //version = state_fio->FgetUint32_BE();
263         //if(this_device_id != state_fio->FgetInt32_BE()) return false;
264         this->out_debug_log(_T("Load State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
265         if(state_entry != NULL) {
266                 if(!(state_entry->load_state(state_fio))) {
267                         return false;
268                 }
269         } else {
270                 return false;
271         }
272         n_bank &= 0x3f;
273
274         //if(version >= 1) {
275         //      n_bank = state_fio->FgetUint8() & 0x3f;
276         //      rcb_address = state_fio->FgetUint8();
277         //      kanji_address.d = state_fio->FgetUint32_BE();
278         //      halted = state_fio->FgetBool();
279         //      state_fio->Fread(prog_rom, sizeof(prog_rom), 1);
280         //      state_fio->Fread(dict_rom, sizeof(dict_rom), 1);
281         //      state_fio->Fread(p_ram, sizeof(p_ram), 1);
282         //      firmware_ok = state_fio->FgetBool();
283         //modified = true; // Abondoned
284         //}
285         return true;
286 }