2 EPSON HC-20 Emulator 'eHC-20'
4 Author : Takeda.Toshiya
12 #include "../hd6301.h"
13 #include "../z80sio.h"
14 #include "../../fifo.h"
16 #define SET_BANK(s, e, w, r) { \
17 int sb = (s) >> 13, eb = (e) >> 13; \
18 for(int i = sb; i <= eb; i++) { \
22 wbank[i] = (w) + 0x2000 * (i - sb); \
27 rbank[i] = (r) + 0x2000 * (i - sb); \
32 #define INT_KEYBOARD 1
38 static int key_table[8][10] = {
39 // PAUSE=F6, MENU=F7, BREAK=F8 NUM=F9 CLR=F10 SCRN=F11 PRINT=PgUp PAPER=PgDn
40 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x70, 0x00,
41 0x38, 0x39, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0x71, 0x00,
42 0xc0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x72, 0x00,
43 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x73, 0x00,
44 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x74, 0x00,
45 0x58, 0x59, 0x5a, 0xdb, 0xdd, 0xdc, 0x27, 0x25, 0x22, 0x10,
46 0x0d, 0x20, 0x09, 0x00, 0x00, 0x78, 0x00, 0x34, 0x00, 0x11,
47 0x79, 0x7a, 0x77, 0x75, 0x2e, 0x76, 0x00, 0x00, 0x00, 0x21
50 void MEMORY::initialize()
53 memset(ram, 0, sizeof(ram));
54 memset(rom, 0, sizeof(rom));
55 memset(ext, 0, sizeof(ext));
56 memset(rdmy, 0xff, sizeof(rdmy));
58 // load backuped ram / rom images
59 FILEIO* fio = new FILEIO();
60 if(fio->Fopen(create_local_path(_T("DRAM.BIN")), FILEIO_READ_BINARY)) {
61 fio->Fread(ram, sizeof(ram), 1);
63 } else if(fio->Fopen(create_local_path(_T("BACKUP.BIN")), FILEIO_READ_BINARY)) {
65 fio->Fread(ram, sizeof(ram), 1);
68 if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
69 fio->Fread(rom, sizeof(rom), 1);
72 if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
73 fio->Fread(ext, sizeof(ext), 1);
78 // SET_BANK(0x0000, 0x3fff, ram, ram);
79 // SET_BANK(0x4000, 0x7fff, wdmy, rdmy);
80 SET_BANK(0x0000, 0x7fff, ram, ram);
81 SET_BANK(0x8000, 0xffff, wdmy, rom);
83 // init command buffer
84 cmd_buf = new FIFO(512);
85 memset(slave_mem, 0, sizeof(slave_mem));
90 for(int i = 8; i >= 0; i--) {
91 tone_tmp[i] = tone_tmp[i + 1] / 1.05946;
93 for(int i = 10; i < 13; i++) {
94 tone_tmp[i] = tone_tmp[i - 1] * 1.05946;
96 static const int tone_index[7] = {0, 2, 4, 5, 7, 9, 11};
97 for(int i = 0; i < 4; i++) {
98 for(int j = 0; j < 7; j++) {
99 tone_table[i * 7 + j + 1] = tone_tmp[tone_index[j] ] * (2 << i);
100 tone_table[i * 7 + j + 29] = tone_tmp[tone_index[j] + 1] * (2 << i);
106 memset(key_stat, 0, sizeof(key_stat));
107 memset(key_flag, 0, sizeof(key_flag));
109 for(int i = 0; i < 8; i++) {
110 for(int j = 0; j < 10; j++) {
111 key_flag[key_table[i][j]] = 1;
114 key_flag[0] = key_flag[0x10] = key_flag[0x11] = key_flag[0x12] = 0;
118 cmt_play = cmt_rec = false;
119 cmt_fio = new FILEIO();
122 pd = RGB_COLOR(48, 56, 16);
123 pb = RGB_COLOR(160, 168, 160);
124 memset(lcd, 0, sizeof(lcd));
127 register_event_by_clock(this, EVENT_SOUND, 256, true, NULL);
130 void MEMORY::release()
132 // save battery backuped ram
133 FILEIO* fio = new FILEIO();
134 if(fio->Fopen(create_local_path(_T("DRAM.BIN")), FILEIO_WRITE_BINARY)) {
135 fio->Fwrite(ram, sizeof(ram), 1);
144 // release command buffer
151 // select internal rom
152 // SET_BANK(0x4000, 0x7fff, wdmy, rdmy);
153 SET_BANK(0x8000, 0xbfff, wdmy, rom);
157 special_cmd_masked = true;
159 sound_ptr = sound_count = 0;
175 void MEMORY::write_data8(uint32_t addr, uint32_t data)
181 if(key_strobe != data) {
187 lcd_select = data & 0x0f;
188 key_intmask = data & 0x10;
189 // interrupt mask reset in sleep mode
200 // used for interrupt mask setting in sleep mode
207 // SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
208 SET_BANK(0x8000, 0xbfff, wdmy, ext);
212 // SET_BANK(0x4000, 0x7fff, wdmy, rdmy);
213 SET_BANK(0x8000, 0xbfff, wdmy, rom);
217 } else if(addr < 0x80) {
218 d_rtc->write_io8(1, addr & 0x3f);
219 d_rtc->write_io8(0, data);
221 wbank[(addr >> 13) & 7][addr & 0x1fff] = data;
225 uint32_t MEMORY::read_data8(uint32_t addr)
233 return key_data & 0xff;
235 // interrupt mask reset in sleep mode
242 // bit6: power switch interrupt flag (0=active)
243 // bit7: busy signal of lcd controller (0=busy)
244 return ((key_data >> 8) & 3) | ((int_status & INT_POWER) ? 0 : 0x40) | 0xa8;
247 if(lcd_clock > 0 && --lcd_clock <= 0) {
248 int c = lcd_select & 7;
249 if(c >= 1 && c <= 6) {
250 lcd_t *block = &lcd[c - 1];
252 block->bank = lcd_data & 0x40 ? 40 : 0;
253 block->addr = lcd_data & 0x3f;
254 } else if(block->addr < 40) {
255 block->buffer[block->bank + block->addr] = lcd_data;
262 // used for interrupt mask setting in sleep mode
269 // SET_BANK(0x4000, 0x7fff, ram + 0x4000, ram + 0x4000);
270 SET_BANK(0x8000, 0xbfff, ext, rom);
274 // SET_BANK(0x4000, 0x7fff, wdmy, rdmy);
275 SET_BANK(0x8000, 0xbfff, wdmy, rom);
280 } else if(addr < 0x80) {
281 d_rtc->write_io8(1, addr & 0x3f);
282 return d_rtc->read_io8(0);
284 return rbank[(addr >> 13) & 7][addr & 0x1fff];
287 void MEMORY::write_signal(int id, uint32_t data, uint32_t mask)
289 if(id == SIG_MEMORY_PORT_2) {
290 sio_select = ((data & 0x04) != 0);
291 } else if(id == SIG_MEMORY_SIO_MAIN) {
293 d_sio_tf20->write_signal(SIG_Z80SIO_RECV_CH0, data, 0xff);
295 send_to_slave(data & mask);
297 } else if(id == SIG_MEMORY_SIO_TF20) {
299 send_to_main(data & mask);
301 } else if(id == SIG_MEMORY_RTC_IRQ) {
303 if(!(int_status & INT_CLOCK)) {
304 int_status |= INT_CLOCK;
308 if((int_status & INT_CLOCK) && (int_status &= ~INT_CLOCK) == 0) {
315 void MEMORY::event_callback(int event_id, int err)
317 if(event_id == EVENT_SOUND) {
322 void MEMORY::update_sound()
324 if(sound_ptr < sound_count) {
325 if(sound[sound_ptr].remain-- == 0) {
326 if(++sound_ptr == sound_count) {
327 d_beep->write_signal(SIG_BEEP_ON, 0, 0);
328 send_to_main(sound_reply);
331 sound[sound_ptr].remain = sound[sound_ptr].period;
333 if(sound_freq != sound[sound_ptr].freq) {
334 sound_freq = sound[sound_ptr].freq;
335 if(sound_freq != 0) {
336 d_beep->set_frequency(sound_freq);
337 d_beep->write_signal(SIG_BEEP_ON, 1, 1);
339 d_beep->write_signal(SIG_BEEP_ON, 0, 0);
345 void MEMORY::update_keyboard()
349 if(key_strobe == 0) {
350 // clear key interrupt
351 if((int_status & INT_KEYBOARD) && (int_status &= ~INT_KEYBOARD) == 0) {
354 d_cpu->write_signal(SIG_MC6801_PORT_1, 0x20, 0x20);
356 // clear key buffer except shift/ctrl/alt keys
357 uint8_t key_stat_10 = key_stat[0x10];
358 uint8_t key_stat_11 = key_stat[0x11];
359 uint8_t key_stat_12 = key_stat[0x12];
360 memset(key_stat, 0, sizeof(key_stat));
361 key_stat[0x10] = key_stat_10;
362 key_stat[0x11] = key_stat_11;
363 key_stat[0x12] = key_stat_12;
365 for(int i = 0; i < 8; i++) {
366 if(key_strobe & (1 << i)) {
369 for(int j = 0; j < 10; j++) {
370 if(key_stat[key_table[i][j]]) {
371 key_data &= ~(1 << j);
375 if(i < 4 && (config.dipswitch & (1 << i))) {
381 void MEMORY::notify_power_off()
383 int_status |= INT_POWER;
387 void MEMORY::key_down(int code)
392 // raise key interrupt
393 if(!(int_status & INT_KEYBOARD)) {
394 int_status |= INT_KEYBOARD;
397 d_cpu->write_signal(SIG_MC6801_PORT_1, 0, 0x20);
401 void MEMORY::key_up(int code)
406 void MEMORY::update_intr()
408 // d_cpu->write_signal(SIG_CPU_IRQ, (int_status && !int_mask) ? 1 : 0, 1);
409 d_cpu->write_signal(SIG_CPU_IRQ, int_status ? 1 : 0, 1);
412 void MEMORY::send_to_slave(uint8_t val)
415 uint8_t cmd = cmd_buf->read_not_remove(0);
417 // this->out_debug_log(_T("Command = %2x"), cmd);
418 // for(int i = 1; i < cmd_buf->count(); i++) {
419 // this->out_debug_log(_T(" %2x"), cmd_buf->read_not_remove(i));
421 // this->out_debug_log(_T("\n"));
424 case 0x00: // slave mcpu ready check
425 case 0x01: // sets the constants required by slave mcu
426 case 0x02: // initialization
430 case 0x03: // opens masks for special commands
431 if(cmd_buf->count() == 2) {
433 special_cmd_masked = (cmd_buf->read() != 0xaa);
437 case 0x04: // closes masks for special commands
438 special_cmd_masked = true;
442 case 0x05: // reads slave mcu memory
443 if(special_cmd_masked) {
448 if(cmd_buf->count() == 3) {
450 int ofs = cmd_buf->read() << 8;
451 ofs |= cmd_buf->read();
452 send_to_main(slave_mem[ofs]);
457 case 0x06: // stores slave mcu memory
458 case 0x07: // logical or operation
459 case 0x08: // logical and operation
460 if(special_cmd_masked) {
465 if(cmd_buf->count() == 4) {
467 int ofs = cmd_buf->read() << 8;
468 ofs |= cmd_buf->read();
470 slave_mem[ofs] = cmd_buf->read();
471 } else if(cmd == 7) {
472 slave_mem[ofs] |= cmd_buf->read();
473 } else if(cmd == 8) {
474 slave_mem[ofs] &= cmd_buf->read();
479 case 0x09: // bar-code reader power on
480 case 0x0a: // bar-code reader power off
484 case 0x0b: // sets the program counter to a specified value
485 if(special_cmd_masked) {
490 if(cmd_buf->count() == 3) {
492 int ofs = cmd_buf->read() << 8;
493 ofs |= cmd_buf->read();
494 // todo: implements known routines
498 case 0x0c: // terminate process
502 d_beep->write_signal(SIG_BEEP_ON, 0, 0);
503 sound_ptr = sound_count;
505 case 0x0d: // cuts off power supply
506 if(cmd_buf->count() == 2) {
508 if(cmd_buf->read() == 0xaa) {
515 case 0x10: // prints out 6-dot data (bit0-5) to the built-in printer
516 case 0x11: // feeds the specified number of dot lines to the built-in printer
517 if(cmd_buf->count() == 2) {
522 case 0x12: // paper feed operation (1.2sec)
526 case 0x20: // executes external cassette ready check
530 case 0x21: // sets constants for the external cassette
531 if(cmd_buf->count() == 1) {
535 if(cmd_buf->count() == 9) {
540 case 0x22: // turns the external cassette rem terminal on
541 case 0x23: // turns the external cassette rem terminal off
545 case 0x24: // writes 1 block of data in EPSON format
546 if(cmd_buf->count() == 1) {
550 if(cmd_buf->count() >= 5 && cmd_buf->count() == cmd_buf->read_not_remove(3) * 256 + cmd_buf->read_not_remove(4) + 5) {
552 for(int i = 0; i < 5; i++) {
555 while(!cmd_buf->empty()) {
556 cmt_buffer[cmt_count++] = cmd_buf->read();
557 if(cmt_count >= CMT_BUFFER_SIZE) {
558 cmt_fio->Fwrite(cmt_buffer, cmt_count, 1);
568 case 0x25: // outputs number of ff patterns
569 if(cmd_buf->count() == 1) {
573 if(cmd_buf->count() == 3) {
578 case 0x26: // inputs files from the external cassette
579 case 0x27: // inputs files from the external cassette
580 case 0x28: // inputs files from the external cassette
581 if(cmd_buf->count() == 1) {
585 if(cmd_buf->count() == 5) {
586 int len = cmd_buf->read_not_remove(3) * 256 + cmd_buf->read_not_remove(4);
589 for(int i = 0; i < len; i++) {
590 send_to_main(cmt_buffer[cmt_count++]);
598 case 0x2b: // specifies the input signal for the external cassette
599 if(cmd_buf->count() == 1) {
603 if(cmd_buf->count() == 2) {
608 case 0x30: // specifies the tone and duration and sounds the piezo speaker
609 if(cmd_buf->count() == 1) {
613 if(cmd_buf->count() == 3) {
615 int tone = cmd_buf->read();
616 int period = cmd_buf->read();
617 if(tone >= 0 && tone <= 56 && period != 0) {
618 sound[0].freq = tone_table[tone];
619 sound[0].period = CPU_CLOCKS * period / 256 / 10;
620 sound[0].remain = sound[0].period;
629 case 0x31: // specifies the frequency and duration and sounds the piezo speaker
630 if(cmd_buf->count() == 1) {
634 if(cmd_buf->count() == 5) {
636 int freq = cmd_buf->read() << 8;
637 freq |= cmd_buf->read();
638 int period = cmd_buf->read() << 8;
639 period |= cmd_buf->read();
640 if(freq != 0 && period != 0) {
641 sound[0].freq = CPU_CLOCKS / freq / 2.0;
642 sound[0].period = period;
643 sound[0].remain = sound[0].period;
652 case 0x32: // sounds the speaker for 0.03 sec at tone 6
653 case 0x33: // sounds the speaker for 1 sec at tone 20
656 sound[0].freq = tone_table[6];
657 sound[0].period = CPU_CLOCKS * 3 / 256 / 100;
659 sound[0].freq = tone_table[20];
660 sound[0].period = CPU_CLOCKS / 256;
662 sound[0].remain = sound[0].period;
667 case 0x34: // sets melody data in the slave mcu
668 if(cmd_buf->count() == 1) {
675 while(!cmd_buf->empty()) {
676 int tone = cmd_buf->read();
677 int period = cmd_buf->read();
678 if(tone >= 0 && tone <= 56 && period != 0) {
679 sound[sound_count].freq = tone_table[tone];
680 sound[sound_count].period = CPU_CLOCKS * period / 256 / 10;
684 sound_ptr = sound_count;
688 case 0x35: // sounds the melody data specified in command 34
690 sound[0].remain = sound[0].period;
697 case 0x40: // turns the serial driver on
698 case 0x41: // turns the serial driver off
702 case 0x48: // sets the polynomial expression used for CRC check
703 if(cmd_buf->count() == 1) {
707 if(cmd_buf->count() == 3) {
712 case 0x50: // identifies the plug-in option
716 case 0x51: // turns power of plug-in rom cartridge on
717 case 0x52: // turns power of plug-in rom cartridge off
721 case 0x60: // executes micro cassette ready check (no respose)
726 this->out_debug_log(_T("Unknown Command = %2x\n"), cmd);
732 void MEMORY::send_to_main(uint8_t val)
735 d_cpu->write_signal(SIG_MC6801_SIO_RECV, val, 0xff);
738 void MEMORY::play_tape(const _TCHAR* file_path)
742 if(cmt_fio->Fopen(file_path, FILEIO_READ_BINARY)) {
743 memset(cmt_buffer, 0, sizeof(cmt_buffer));
744 cmt_fio->Fread(cmt_buffer, sizeof(cmt_buffer), 1);
751 void MEMORY::rec_tape(const _TCHAR* file_path)
755 if(cmt_fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
756 my_tcscpy_s(cmt_file_path, _MAX_PATH, file_path);
762 void MEMORY::close_tape()
764 if(cmt_fio->IsOpened()) {
765 if(cmt_rec && cmt_count) {
766 cmt_fio->Fwrite(cmt_buffer, cmt_count, 1);
771 cmt_play = cmt_rec = false;
774 void MEMORY::draw_screen()
776 static const int xtop[12] = {0, 0, 40, 40, 80, 80, 0, 0, 40, 40, 80, 80};
777 static const int ytop[12] = {0, 8, 0, 8, 0, 8, 16, 24, 16, 24, 16, 24};
779 for(int c = 0; c < 12; c++) {
782 int ofs = (c & 1) ? 40 : 0;
784 for(int i = 0; i < 40; i++) {
785 uint8_t pat = lcd[c >> 1].buffer[ofs + i];
786 lcd_render[y + 0][x + i] = (pat & 0x01) ? pd : pb;
787 lcd_render[y + 1][x + i] = (pat & 0x02) ? pd : pb;
788 lcd_render[y + 2][x + i] = (pat & 0x04) ? pd : pb;
789 lcd_render[y + 3][x + i] = (pat & 0x08) ? pd : pb;
790 lcd_render[y + 4][x + i] = (pat & 0x10) ? pd : pb;
791 lcd_render[y + 5][x + i] = (pat & 0x20) ? pd : pb;
792 lcd_render[y + 6][x + i] = (pat & 0x40) ? pd : pb;
793 lcd_render[y + 7][x + i] = (pat & 0x80) ? pd : pb;
796 for(int y = 0; y < 32; y++) {
797 scrntype_t* dest = emu->get_screen_buffer(y);
798 my_memcpy(dest, lcd_render[y], sizeof(scrntype_t) * 120);
802 #define STATE_VERSION 1
804 #include "../../statesub.h"
806 void MEMORY::decl_state()
808 enter_decl_state(STATE_VERSION);
810 DECL_STATE_ENTRY_BOOL(tmp_wbank_is_ext); // (wbank[0x8000 >> 13] == ext);
811 DECL_STATE_ENTRY_BOOL(tmp_rbank_is_ext); // (rbank[0x8000 >> 13] == ext);
813 DECL_STATE_ENTRY_1D_ARRAY(rom, sizeof(rom));
814 DECL_STATE_ENTRY_1D_ARRAY(ext, sizeof(ext));
815 DECL_STATE_ENTRY_FIFO(cmd_buf);
817 DECL_STATE_ENTRY_BOOL(sio_select);
818 DECL_STATE_ENTRY_BOOL(special_cmd_masked);
819 DECL_STATE_ENTRY_1D_ARRAY(slave_mem, sizeof(slave_mem));
821 DECL_STATE_ENTRY_DOUBLE_STRIDE((sound[0].freq), sizeof(sound) / sizeof(sound[0]), sizeof(sound[0]));
822 DECL_STATE_ENTRY_INT32_STRIDE((sound[0].period), sizeof(sound) / sizeof(sound[0]), sizeof(sound[0]));
823 DECL_STATE_ENTRY_INT32_STRIDE((sound[0].remain), sizeof(sound) / sizeof(sound[0]), sizeof(sound[0]));
826 DECL_STATE_ENTRY_INT32(sound_ptr);
827 DECL_STATE_ENTRY_INT32(sound_count);
828 DECL_STATE_ENTRY_UINT8(sound_reply);
829 DECL_STATE_ENTRY_DOUBLE(sound_freq);
830 DECL_STATE_ENTRY_1D_ARRAY(key_stat, sizeof(key_stat));
831 DECL_STATE_ENTRY_1D_ARRAY(key_flag, sizeof(key_flag));
832 DECL_STATE_ENTRY_INT32(key_data);
833 DECL_STATE_ENTRY_INT32(key_strobe);
834 DECL_STATE_ENTRY_INT32(key_intmask);
835 DECL_STATE_ENTRY_BOOL(cmt_play);
836 DECL_STATE_ENTRY_BOOL(cmt_rec);
837 DECL_STATE_ENTRY_STRING(cmt_file_path, sizeof(cmt_file_path));
838 DECL_STATE_ENTRY_CMT_RECORDING(cmt_fio, cmt_rec, cmt_file_path);
840 DECL_STATE_ENTRY_INT32(cmt_count);
841 DECL_STATE_ENTRY_1D_ARRAY(cmt_buffer, sizeof(cmt_buffer));
842 for(int i = 0; i < 6; i++) {
843 DECL_STATE_ENTRY_1D_ARRAY_MEMBER((lcd[i].buffer), 80, i);
844 DECL_STATE_ENTRY_INT32_MEMBER((lcd[i].bank), i);
845 DECL_STATE_ENTRY_INT32_MEMBER((lcd[i].addr), i);
848 DECL_STATE_ENTRY_UINT8(lcd_select);
849 DECL_STATE_ENTRY_UINT8(lcd_data);
850 DECL_STATE_ENTRY_INT32(lcd_clock);
851 DECL_STATE_ENTRY_INT32(int_status);
852 DECL_STATE_ENTRY_INT32(int_mask);
857 void MEMORY::save_state(FILEIO* state_fio)
859 tmp_wbank_is_ext = (wbank[0x8000 >> 13] == ext);
860 tmp_rbank_is_ext = (rbank[0x8000 >> 13] == ext);
862 if(state_entry != NULL) {
863 state_entry->save_state(state_fio);
865 // state_fio->FputUint32(STATE_VERSION);
866 // state_fio->FputInt32(this_device_id);
868 // state_fio->FputBool(wbank[0x8000 >> 13] == ext);
869 // state_fio->FputBool(rbank[0x8000 >> 13] == ext);
870 // state_fio->Fwrite(rom, sizeof(rom), 1);
871 // state_fio->Fwrite(ext, sizeof(ext), 1);
872 // cmd_buf->save_state((void *)state_fio);
873 // state_fio->FputBool(sio_select);
874 // state_fio->FputBool(special_cmd_masked);
875 // state_fio->Fwrite(slave_mem, sizeof(slave_mem), 1);
876 // state_fio->Fwrite(sound, sizeof(sound), 1);
877 // state_fio->FputInt32(sound_ptr);
878 // state_fio->FputInt32(sound_count);
879 // state_fio->FputUint8(sound_reply);
880 // state_fio->FputDouble(sound_freq);
881 // state_fio->Fwrite(key_stat, sizeof(key_stat), 1);
882 // state_fio->Fwrite(key_flag, sizeof(key_flag), 1);
883 // state_fio->FputInt32(key_data);
884 // state_fio->FputInt32(key_strobe);
885 // state_fio->FputInt32(key_intmask);
886 // state_fio->FputBool(cmt_play);
887 // state_fio->FputBool(cmt_rec);
888 // state_fio->Fwrite(cmt_file_path, sizeof(cmt_file_path), 1);
889 // if(cmt_rec && cmt_fio->IsOpened()) {
890 // int length_tmp = (int)cmt_fio->Ftell();
891 // cmt_fio->Fseek(0, FILEIO_SEEK_SET);
892 // state_fio->FputInt32(length_tmp);
893 // while(length_tmp != 0) {
894 // uint8_t buffer_tmp[1024];
895 // int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
896 // cmt_fio->Fread(buffer_tmp, length_rw, 1);
897 // state_fio->Fwrite(buffer_tmp, length_rw, 1);
898 // length_tmp -= length_rw;
901 // state_fio->FputInt32(0);
903 // state_fio->FputInt32(cmt_count);
904 // state_fio->Fwrite(cmt_buffer, sizeof(cmt_buffer), 1);
905 // state_fio->Fwrite(lcd, sizeof(lcd), 1);
906 // state_fio->FputUint8(lcd_select);
907 // state_fio->FputUint8(lcd_data);
908 // state_fio->FputInt32(lcd_clock);
909 // state_fio->FputInt32(int_status);
910 // state_fio->FputInt32(int_mask);
913 bool MEMORY::load_state(FILEIO* state_fio)
918 if(state_entry != NULL) {
919 mb = state_entry->load_state(state_fio);
924 // if(state_fio->FgetUint32() != STATE_VERSION) {
927 // if(state_fio->FgetInt32() != this_device_id) {
930 // bool wr = state_fio->FgetBool();
931 // bool rd = state_fio->FgetBool();
932 // state_fio->Fread(rom, sizeof(rom), 1);
933 // state_fio->Fread(ext, sizeof(ext), 1);
934 // if(!cmd_buf->load_state((void *)state_fio)) {
937 // sio_select = state_fio->FgetBool();
938 // special_cmd_masked = state_fio->FgetBool();
939 // state_fio->Fread(slave_mem, sizeof(slave_mem), 1);
940 // state_fio->Fread(sound, sizeof(sound), 1);
941 // sound_ptr = state_fio->FgetInt32();
942 // sound_count = state_fio->FgetInt32();
943 // sound_reply = state_fio->FgetUint8();
944 // sound_freq = state_fio->FgetDouble();
945 // state_fio->Fread(key_stat, sizeof(key_stat), 1);
946 // state_fio->Fread(key_flag, sizeof(key_flag), 1);
947 // key_data = state_fio->FgetInt32();
948 // key_strobe = state_fio->FgetInt32();
949 // key_intmask = state_fio->FgetInt32();
950 // cmt_play = state_fio->FgetBool();
951 // cmt_rec = state_fio->FgetBool();
952 // state_fio->Fread(cmt_file_path, sizeof(cmt_file_path), 1);
953 // int length_tmp = state_fio->FgetInt32();
955 // cmt_fio->Fopen(cmt_file_path, FILEIO_READ_WRITE_NEW_BINARY);
956 // while(length_tmp != 0) {
957 // uint8_t buffer_tmp[1024];
958 // int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
959 // state_fio->Fread(buffer_tmp, length_rw, 1);
960 // if(cmt_fio->IsOpened()) {
961 // cmt_fio->Fread(buffer_tmp, length_rw, 1);
963 // length_tmp -= length_rw;
966 // cmt_count = state_fio->FgetInt32();
967 // state_fio->Fread(cmt_buffer, sizeof(cmt_buffer), 1);
968 // state_fio->Fread(lcd, sizeof(lcd), 1);
969 // lcd_select = state_fio->FgetUint8();
970 // lcd_data = state_fio->FgetUint8();
971 // lcd_clock = state_fio->FgetInt32();
972 // int_status = state_fio->FgetInt32();
973 // int_mask = state_fio->FgetInt32();
976 SET_BANK(0x8000, 0xbfff, tmp_wbank_is_ext ? ext : wdmy, tmp_rbank_is_ext ? ext : rom);