2 CASIO FP-1100 Emulator 'eFP-1100'
4 Author : Takeda.Toshiya
13 #define SET_BANK_W(s, e, w) { \
14 int sb = (s) >> 12, eb = (e) >> 12; \
15 for(int i = sb; i <= eb; i++) { \
19 wbank[i] = (w) + 0x1000 * (i - sb); \
24 #define SET_BANK_R(s, e, r, w) { \
25 int sb = (s) >> 12, eb = (e) >> 12; \
26 for(int i = sb; i <= eb; i++) { \
30 rbank[i] = (r) + 0x1000 * (i - sb); \
36 void MAIN::initialize()
38 memset(rom, 0xff, sizeof(rom));
39 memset(rdmy, 0xff, sizeof(rdmy));
41 FILEIO* fio = new FILEIO();
42 if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
43 fio->Fread(rom, sizeof(rom), 1);
48 SET_BANK_W(0x0000, 0xffff, ram);
49 SET_BANK_R(0x0000, 0xffff, ram, 0);
56 slot_sel = slot_exp[0] = slot_exp[1] = 0;
57 intr_mask = intr_request = intr_in_service = 0;
60 void MAIN::write_data8(uint32_t addr, uint32_t data)
63 wbank[addr >> 12][addr & 0xfff] = data;
66 uint32_t MAIN::read_data8(uint32_t addr)
69 return rbank[addr >> 12][addr & 0xfff];
72 #ifdef Z80_MEMORY_WAIT
73 void MAIN::write_data8w(uint32_t addr, uint32_t data, int *wait)
76 write_data8(addr, data);
79 uint32_t MAIN::read_data8w(uint32_t addr, int *wait)
82 *wait = wait[addr >> 12];
83 return read_data8(addr);
87 void MAIN::write_io8(uint32_t addr, uint32_t data)
90 this->out_debug_log(_T("%06x\tOUT8\t%04x,%02x\n"), get_cpu_pc(0), addr, data);
92 switch(addr & 0xffe0) {
97 slot_exp[slot_sel] = data & 0x0f;
100 if(intr_mask != data) {
101 if(!(intr_mask & 0x80) && (data & 0x80)) {
102 d_sub->write_signal(SIG_SUB_INT2, 1, 1);
103 // FIXME: ugly patch for floppy drives
104 intr_request &= ~0x10;
105 } else if((intr_mask & 0x80) && !(data & 0x80)) {
106 d_sub->write_signal(SIG_SUB_INT2, 0, 1);
113 rom_sel = ((data & 2) == 0);
118 d_sub->write_signal(SIG_SUB_COMM, data, 0xff);
123 if(slot_exp[slot_sel] < 4) {
124 d_slot[slot_sel][slot_exp[slot_sel]]->write_io8(addr & 0xffff, data);
130 uint32_t MAIN::read_io8(uint32_t addr)
133 switch(addr & 0xffe0) {
141 if(slot_exp[slot_sel] < 4) {
142 val = d_slot[slot_sel][slot_exp[slot_sel]]->read_io8(addr & 0xffff);
147 this->out_debug_log(_T("%06x\tIN8\t%04x = %02x\n"), get_cpu_pc(0), addr, val);
153 void MAIN::write_io8w(uint32_t addr, uint32_t data, int *wait)
156 write_io8(addr, data);
159 uint32_t MAIN::read_io8w(uint32_t addr, int *wait)
162 return read_io8(addr);
166 static const uint8_t bits[5] = {
167 0x10, 0x01, 0x02, 0x04, 0x08
169 static const uint32_t vector[5] = {
170 0xf0, 0xf2, 0xf4, 0xf6, 0xf8
173 void MAIN::write_signal(int id, uint32_t data, uint32_t mask)
182 if(!(intr_request & bits[id])) {
183 intr_request |= bits[id];
187 if(intr_request & bits[id]) {
188 intr_request &= ~bits[id];
194 comm_data = data & 0xff;
199 void MAIN::update_memory_map()
202 SET_BANK_R(0x0000, 0x8fff, rom, 24);
204 SET_BANK_R(0x0000, 0x8fff, ram, 0);
208 void MAIN::update_intr()
210 for(int i = 0; i < 5; i++) {
211 if((intr_request & bits[i]) && (intr_mask & bits[i]) && !(intr_in_service & bits[i])) {
212 d_cpu->set_intr_line(true, true, 0);
216 d_cpu->set_intr_line(false, true, 0);
219 uint32_t MAIN::get_intr_ack()
221 for(int i = 0; i < 5; i++) {
222 if((intr_request & bits[i]) && (intr_mask & bits[i]) && !(intr_in_service & bits[i])) {
223 intr_request &= ~bits[i];
224 intr_in_service |= bits[i];
228 // invalid interrupt status
232 void MAIN::notify_intr_reti()
237 void MAIN::notify_intr_ei()
239 // FP-1100 uses EI and RET to leave interrupt routine
240 for(int i = 0; i < 5; i++) {
241 if(intr_in_service & bits[i]) {
242 intr_in_service &= ~bits[i];
249 #define STATE_VERSION 3
251 #include "../../statesub.h"
253 void MAIN::decl_state()
255 enter_decl_state(STATE_VERSION);
257 DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
258 DECL_STATE_ENTRY_UINT8(comm_data);
259 DECL_STATE_ENTRY_BOOL(rom_sel);
260 DECL_STATE_ENTRY_UINT8(slot_sel);
261 DECL_STATE_ENTRY_1D_ARRAY(slot_exp, sizeof(slot_exp));
262 DECL_STATE_ENTRY_UINT8(intr_mask);
263 DECL_STATE_ENTRY_UINT8(intr_request);
264 DECL_STATE_ENTRY_UINT8(intr_in_service);
269 void MAIN::save_state(FILEIO* state_fio)
271 if(state_entry != NULL) {
272 state_entry->save_state(state_fio);
275 // state_fio->FputUint32(STATE_VERSION);
276 // state_fio->FputInt32(this_device_id);
278 // state_fio->Fwrite(ram, sizeof(ram), 1);
279 // state_fio->FputUint8(comm_data);
280 // state_fio->FputBool(rom_sel);
281 // state_fio->FputUint8(slot_sel);
282 // state_fio->Fwrite(slot_exp, sizeof(slot_exp), 1);
283 // state_fio->FputUint8(intr_mask);
284 // state_fio->FputUint8(intr_request);
285 // state_fio->FputUint8(intr_in_service);
288 bool MAIN::load_state(FILEIO* state_fio)
291 if(state_entry != NULL) {
292 mb = state_entry->load_state(state_fio);
298 // if(state_fio->FgetUint32() != STATE_VERSION) {
301 // if(state_fio->FgetInt32() != this_device_id) {
304 // state_fio->Fread(ram, sizeof(ram), 1);
305 // comm_data = state_fio->FgetUint8();
306 // rom_sel = state_fio->FgetBool();
307 // slot_sel = state_fio->FgetUint8();
308 // state_fio->Fread(slot_exp, sizeof(slot_exp), 1);
309 // intr_mask = state_fio->FgetUint8();
310 // intr_request = state_fio->FgetUint8();
311 // intr_in_service = state_fio->FgetUint8();
318 bool MAIN::process_state(FILEIO* state_fio, bool loading)
320 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
323 if(!state_fio->StateCheckInt32(this_device_id)) {
326 state_fio->StateBuffer(ram, sizeof(ram), 1);
327 state_fio->StateUint8(comm_data);
328 state_fio->StateBool(rom_sel);
329 state_fio->StateUint8(slot_sel);
330 state_fio->StateBuffer(slot_exp, sizeof(slot_exp), 1);
331 state_fio->StateUint8(intr_mask);
332 state_fio->StateUint8(intr_request);
333 state_fio->StateUint8(intr_in_service);