2 EPSON HC-80 Emulator 'eHC-80'
4 Author : Takeda.Toshiya
13 #include "../../fifo.h"
48 #define DID_FIRST 0x31
55 // intelligent ram disk
56 #define IRAMDISK_WAIT 1
58 #define IRAMDISK_OUT 1
64 static const int key_tbl[256] = {
65 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x56,0x57,0xff,0xff,0xff,0x71,0xff,0xff,
66 0xb3,0xb2,0xff,0x10,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,
67 0x73,0xff,0xff,0xff,0xff,0x63,0x55,0x65,0x64,0xff,0xff,0xff,0xff,0x80,0x81,0xff,
68 0x52,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x50,0x51,0xff,0xff,0xff,0xff,0xff,0xff,
69 0xff,0x66,0x40,0x76,0x30,0x22,0x31,0x32,0x33,0x27,0x34,0x35,0x36,0x42,0x41,0x60,
70 0x61,0x20,0x23,0x67,0x24,0x26,0x77,0x21,0x75,0x25,0x74,0xff,0xff,0xff,0xff,0xff,
71 0x52,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x50,0x51,0xff,0xff,0xff,0xff,0xff,0xff,
72 0x03,0x04,0x05,0x06,0x07,0xff,0xff,0xff,0xff,0xff,0x01,0x02,0xff,0xff,0xff,0xff,
73 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
74 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
75 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
76 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x70,0x37,0x43,0x53,0x44,0x45,
77 0x62,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
78 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x46,0x72,0x47,0x54,0xff,
79 0xff,0xff,0x72,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
80 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
83 static const uint8_t dot_tbl[8] = {
84 0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1
87 DLL_PREFIX_I struct cur_time_s cur_time;
90 void HC80_IO::initialize()
93 device_type = config.device_type;
95 // init ram and external ram disk
96 memset(ram, 0, sizeof(ram));
97 memset(ext, 0, 0x20000);
98 memset(ext + 0x20000, 0xff, 0x20000);
103 FILEIO* fio = new FILEIO();
104 if(fio->Fopen(create_local_path(_T("BASIC.ROM")), FILEIO_READ_BINARY)) {
105 fio->Fread(basic, 0x4000, 1);
106 memcpy(basic + 0x4000, basic, 0x4000);
107 fio->Fread(basic + 0x4000, 0x4000, 1);
110 if(fio->Fopen(create_local_path(_T("UTIL.ROM")), FILEIO_READ_BINARY)) {
111 fio->Fread(util, 0x4000, 1);
112 memcpy(util + 0x4000, util, 0x4000);
113 fio->Fread(util + 0x4000, 0x4000, 1);
116 if(fio->Fopen(create_local_path(_T("VRAM.BIN")), FILEIO_READ_BINARY)) {
117 fio->Fread(ram + 0x8000, 0x1800, 1);
120 if(fio->Fopen(create_local_path(_T("EXTRAM.BIN")), FILEIO_READ_BINARY)) {
121 fio->Fread(ext, 0x20000, 1);
124 if(fio->Fopen(create_local_path(_T("INTRAM.BIN")), FILEIO_READ_BINARY)) {
125 fio->Fread(iramdisk_sectors, sizeof(iramdisk_sectors), 1);
128 if(fio->Fopen(create_local_path(_T("EXT.ROM")), FILEIO_READ_BINARY)) {
129 fio->Fread(ext + 0x20000, 0x20000, 1);
132 if(fio->Fopen(create_local_path(_T("FONT.ROM")), FILEIO_READ_BINARY)) {
133 fio->Fread(font, sizeof(font), 1);
139 cmd6303_buf = new FIFO(1024);
140 rsp6303_buf = new FIFO(1024);
141 tf20_buf = new FIFO(1024);
143 cmd7508_buf = new FIFO(16);
144 rsp7508_buf = new FIFO(16);
145 key_buf = new FIFO(7);
148 pd = RGB_COLOR(48, 56, 16);
149 pb = RGB_COLOR(160, 168, 160);
152 get_host_time(&cur_time);
153 onesec_intr = alarm_intr = false;
154 onesec_intr_enb = alarm_intr_enb = kb_intr_enb = true;
155 res_7508 = kb_caps = false;
158 register_frame_event(this);
159 register_event_by_clock(this, EVENT_FRC, 0x40000, true, NULL);
160 register_event_by_clock(this, EVENT_1SEC, CPU_CLOCKS, true, ®ister_id);
161 register_event_by_clock(this, EVENT_6303, 100, true, NULL);
164 void HC80_IO::release()
166 // save external ram disk
167 FILEIO* fio = new FILEIO();
168 if(fio->Fopen(create_local_path(_T("VRAM.BIN")), FILEIO_WRITE_BINARY)) {
169 fio->Fwrite(ram + 0x8000, 0x1800, 1);
172 if(fio->Fopen(create_local_path(_T("EXTRAM.BIN")), FILEIO_WRITE_BINARY)) {
173 fio->Fwrite(ext, 0x20000, 1);
176 if(fio->Fopen(create_local_path(_T("INTRAM.BIN")), FILEIO_WRITE_BINARY)) {
177 fio->Fwrite(iramdisk_sectors, sizeof(iramdisk_sectors), 1);
182 cmd6303_buf->release();
184 rsp6303_buf->release();
189 cmd7508_buf->release();
191 rsp7508_buf->release();
197 void HC80_IO::reset()
200 bcr = slbcr = isr = ier = ioctlr = 0;
214 cs_blocks = gs_blocks = 0;
215 memset(cs_block, 0, sizeof(cs_block));
216 memset(gs_block, 0, sizeof(gs_block));
217 memset(udgc, 0, sizeof(udgc));
218 wnd_ptr_x = wnd_ptr_y = 0;
221 // reset intelligent ram disk
223 iramdisk_ptr = iramdisk_buf;
226 void HC80_IO::sysreset()
229 onesec_intr = alarm_intr = false;
230 onesec_intr_enb = alarm_intr_enb = kb_intr_enb = true;
234 void HC80_IO::write_signal(int id, uint32_t data, uint32_t mask)
236 if(id == SIG_IO_RXRDY) {
237 // notify rxrdy is changed from i8251
244 } else if(id == SIG_IO_BARCODE) {
245 // signal from barcode reader
247 bool next = ((data & mask) != 0);
248 if((bcr == 2 && ear && !next) || (bcr == 4 && !ear && next) || (bcr == 6 && ear != next)) {
249 icrb = get_passed_clock(cur_clock) / 4;
255 } else if(id == SIG_IO_TF20) {
257 tf20_buf->write(data);
261 void HC80_IO::event_frame()
263 d_beep->write_signal(SIG_BEEP_ON, beep ? 1 : 0, 1);
268 void HC80_IO::event_callback(int event_id, int err)
270 if(event_id == EVENT_FRC) {
271 // FRC overflow event
272 cur_clock = get_current_clock();
275 } else if(event_id == EVENT_1SEC) {
277 if(cur_time.initialized) {
278 cur_time.increment();
280 get_host_time(&cur_time); // resync
281 cur_time.initialized = true;
284 if(onesec_intr_enb) {
288 } else if(event_id == EVENT_6303) {
289 // communicate between z80 and 6303
294 if(!rsp6303_buf->empty()) {
300 void HC80_IO::write_io8(uint32_t addr, uint32_t data)
302 //this->out_debug_log(_T("OUT %2x,%2x\n"), addr & 0xff, data);
303 switch(addr & 0xff) {
307 d_mem->write_signal(0, data, 1);
335 d_sio->write_io8(0, data);
338 // 8251 command write
339 d_sio->write_io8(1, data);
343 cmd6303_buf->write(data);
346 this->out_debug_log(_T("%4x\tDAT %2x\n"), get_cpu_pc(0), data);
354 this->out_debug_log(_T("\n%4x\tCMD %2x\n"), vm->get_cpu_pc(), data);
358 if(device_type == 1) {
359 iramdisk_write_data(data);
363 if(device_type == 1) {
364 iramdisk_write_cmd(data);
369 if(device_type == 2) {
370 extar = (extar & 0xffff00) | data;
375 if(device_type == 2) {
376 extar = (extar & 0xff00ff) | (data << 8);
381 if(device_type == 2) {
382 extar = (extar & 0x00ffff) | ((data & 7) << 16);
387 if(device_type == 2) {
388 if(extar < 0x20000) {
391 extar = (extar & 0xffff00) | ((extar + 1) & 0xff);
396 if(device_type == 2) {
403 uint32_t HC80_IO::read_io8(uint32_t addr)
406 // this->out_debug_log(_T("IN %2x\n"), addr & 0xff);
408 switch(addr & 0xff) {
410 // ICRL.C (latch FRC value)
411 icrc = get_passed_clock(cur_clock) / 4;
415 return (icrc >> 8) & 0xff;
423 return (icrb >> 8) & 0xff;
429 return 8 | 4 | (ear ? 1 : 0); // always rdysio=rdy=true
432 return rec_from_7508();
437 return d_sio->read_io8(0);
440 return d_sio->read_io8(1);
446 val = rsp6303_buf->read();
448 if(!rsp6303_buf->empty()) {
452 this->out_debug_log(_T("%4x\tRCV %2x\n"), vm->get_cpu_pc(), val);
456 if(device_type == 1) {
457 return iramdisk_read_data();
461 if(device_type == 1) {
462 return iramdisk_read_stat();
467 if(device_type == 2) {
468 if(extar < 0x40000) {
471 extar = (extar & 0xffff00) | ((extar + 1) & 0xff);
477 if(device_type == 2) {
478 return extcr & ~0x80;
485 uint32_t HC80_IO::get_intr_ack()
490 } else if(isr & BIT_8251) {
492 } else if(isr & BIT_CD) {
494 } else if(isr & BIT_ICF) {
496 } else if(isr & BIT_OVF) {
498 } else if(isr & BIT_EXT) {
505 void HC80_IO::update_intr()
508 bool next = ((isr & ier & 0x3f) != 0);
509 d_cpu->set_intr_line(next, true, 0);
512 // ----------------------------------------------------------------------------
514 // ----------------------------------------------------------------------------
516 void HC80_IO::send_to_7508(uint8_t val)
521 cmd7508_buf->write(val);
522 uint8_t cmd = cmd7508_buf->read_not_remove(0);
532 if((onesec_intr && onesec_intr_enb) || (alarm_intr && alarm_intr_enb) || res_z80 || res_7508) {
534 res |= (onesec_intr && onesec_intr_enb) ? 0x20 : 0;
535 res |= (res_z80 ? 0x10 : 0) | (res_7508 ? 8 : 0);
536 res |= (alarm_intr && alarm_intr_enb) ? 2 : 0;
538 onesec_intr = alarm_intr = res_z80 = res_7508 = false;
539 } else if(key_buf->count()) {
540 res = key_buf->read();
544 rsp7508_buf->write(res);
545 // request next interrupt
546 if(key_buf->count() && kb_intr_enb) {
555 kb_rep_spd1 = 42 | 0x80;
556 kb_rep_spd2 = 18 | 0x80;
560 // kb repeat timer 1 set
561 if(cmd7508_buf->count() == 2) {
563 kb_rep_spd1 = cmd7508_buf->read();
579 rsp7508_buf->write(TO_BCD_HI(cur_time.year));
580 rsp7508_buf->write(TO_BCD_LO(cur_time.year));
581 rsp7508_buf->write(TO_BCD(cur_time.month));
582 rsp7508_buf->write(TO_BCD(cur_time.day));
583 rsp7508_buf->write(TO_BCD(cur_time.hour));
584 rsp7508_buf->write(TO_BCD(cur_time.minute));
585 rsp7508_buf->write(TO_BCD(cur_time.second));
586 rsp7508_buf->write(cur_time.day_of_week);
591 rsp7508_buf->write(1);
596 rsp7508_buf->write(alarm[0]);
597 rsp7508_buf->write(alarm[1]);
598 rsp7508_buf->write(alarm[2]);
599 rsp7508_buf->write(alarm[3]);
600 rsp7508_buf->write(alarm[4]);
601 rsp7508_buf->write(alarm[5]);
606 res = 0xf; // ascii keyboard
607 rsp7508_buf->write(res);
610 // set power failure detect voltage
611 if(cmd7508_buf->count() == 2) {
617 // read buttery voltage
619 rsp7508_buf->write(0xe0);
622 // 1 sec interrupt off
624 onesec_intr_enb = false;
637 // kb repeat timer 2 set
638 if(cmd7508_buf->count() == 2) {
640 kb_rep_spd2 = cmd7508_buf->read();
655 if(cmd7508_buf->count() == 9) {
657 int year10 = cmd7508_buf->read();
658 int year1 = cmd7508_buf->read();
659 int month = cmd7508_buf->read();
660 int day = cmd7508_buf->read();
661 int hour = cmd7508_buf->read();
662 int minute = cmd7508_buf->read();
663 int second = cmd7508_buf->read();
664 int day_of_week = cmd7508_buf->read();
666 if((month & 0x0f) == 0 || (day & 0x0f) == 0) {
668 get_host_time(&cur_time);
670 bool changed = false;
671 if((year10 & 0x0f) != 0x0f && (year1 & 0x0f) != 0x0f) {
672 cur_time.year = (year10 & 0x0f) * 10 + (year1 & 0x0f);
673 cur_time.update_year();
676 if((month & 0x0f) != 0x0f) {
677 cur_time.month = FROM_BCD(month & 0x1f);
680 if((day & 0x0f) != 0x0f) {
681 cur_time.day = FROM_BCD(day & 0x3f);
684 if((hour & 0x0f) != 0x0f) {
685 cur_time.hour = FROM_BCD(hour & 0x3f);
688 if((minute & 0x0f) != 0x0f) {
689 cur_time.minute = FROM_BCD(minute & 0x7f);
692 if((second & 0x0f) != 0x0f) {
693 cur_time.second = FROM_BCD(second & 0x7f);
696 // if((day_of_week & 0x0f) != 0x0f) {
697 // cur_time.day_of_week = day_of_week & 0x07;
701 cur_time.update_day_of_week();
703 cancel_event(this, register_id);
704 register_event_by_clock(this, EVENT_1SEC, CPU_CLOCKS, true, ®ister_id);
711 if(cmd7508_buf->count() == 7) {
713 alarm[0] = cmd7508_buf->read();
714 alarm[1] = cmd7508_buf->read();
715 alarm[2] = cmd7508_buf->read();
716 alarm[3] = cmd7508_buf->read();
717 alarm[4] = cmd7508_buf->read();
718 alarm[5] = cmd7508_buf->read();
722 // set full charge voltage
723 if(cmd7508_buf->count() == 2) {
731 rsp7508_buf->write(0x90);
734 // 1 sec interrupt on
736 onesec_intr_enb = true;
739 // kb repeat timer 1 read
741 rsp7508_buf->write(kb_rep_spd1);
746 alarm_intr_enb = false;
749 // read analog jack 1
751 rsp7508_buf->write(0);
754 // kb repeat timer 2 read
756 rsp7508_buf->write(kb_rep_spd2);
761 alarm_intr_enb = true;
764 // read analog jack 2
766 rsp7508_buf->write(0);
771 this->out_debug_log(_T("unknown cmd %2x\n"), cmd);
775 uint8_t HC80_IO::rec_from_7508()
777 return rsp7508_buf->read();
780 void HC80_IO::key_down(int code)
785 update_key(kb_caps ? 0xb4 : 0xa4);
786 update_key(kb_caps ? 0xa4 : 0xb4);
788 update_key(key_tbl[code & 0xff]);
792 void HC80_IO::key_up(int code)
795 update_key(0xa3); // break shift
796 } else if(code == 0x11) {
797 update_key(0xa2); // break ctrl
801 void HC80_IO::update_key(int code)
808 key_buf->write(code);
810 key_buf->write(code);
814 if(kb_intr_enb || (!kb_intr_enb && code == 0x10)) {
821 // ----------------------------------------------------------------------------
823 // ----------------------------------------------------------------------------
825 void HC80_IO::process_6303()
830 if(cmd6303_buf->count() == 2) {
831 uint16_t addr = cmd6303_buf->read() << 8;
832 addr |= cmd6303_buf->read();
833 rsp6303_buf->write(RCD00);
834 rsp6303_buf->write(ram[addr]);
840 if(cmd6303_buf->count() == 4) {
841 uint16_t addr = cmd6303_buf->read() << 8;
842 addr |= cmd6303_buf->read();
843 uint8_t val = cmd6303_buf->read();
844 uint8_t ope = cmd6303_buf->read();
847 } else if(ope == 2) {
849 } else if(ope == 3) {
854 rsp6303_buf->write(RCD00);
860 if(cmd6303_buf->count() == 2) {
861 uint16_t addr = cmd6303_buf->read() << 8;
862 addr |= cmd6303_buf->read();
864 rsp6303_buf->write(RCD00);
869 // unknown (initialize???)
870 rsp6303_buf->write(RCD00);
874 // define screen mode
875 if(cmd6303_buf->count() == 16) {
876 cs_addr = cmd6303_buf->read() << 8;
877 cs_addr |= cmd6303_buf->read();
878 gs_addr = cmd6303_buf->read() << 8;
879 gs_addr |= cmd6303_buf->read();
888 uint16_t bottom = cmd6303_buf->read() << 8;
889 bottom |= cmd6303_buf->read();
892 rsp6303_buf->write(RCD00);
894 // go to character screen mode ???
896 // stop block flashing ???
898 cs_blocks = gs_blocks = 0;
900 memset(&ram[cs_addr], 0, bottom - cs_addr);
905 if(cmd6303_buf->count() == 1) {
906 lcd_on = cmd6303_buf->read();
907 rsp6303_buf->write(RCD00);
913 if(cmd6303_buf->count() == 1) {
914 scr_mode = cmd6303_buf->read();
918 rsp6303_buf->write(RCD00);
923 // read screen pointer
924 rsp6303_buf->write(RCD00);
925 rsp6303_buf->write(scr_ptr >> 8);
926 rsp6303_buf->write(scr_ptr & 0xff);
930 // set screen pointer
931 if(cmd6303_buf->count() == 2) {
932 scr_ptr = cmd6303_buf->read() << 8;
933 scr_ptr |= cmd6303_buf->read();
934 rsp6303_buf->write(RCD00);
936 // stop block flashing ???
938 cs_blocks = gs_blocks = 0;
942 // define number of lines
943 if(cmd6303_buf->count() == 1) {
944 num_lines = cmd6303_buf->read();
945 rsp6303_buf->write(RCD00);
950 // define cursor mode
951 if(cmd6303_buf->count() == 1) {
952 curs_mode = cmd6303_buf->read();
953 rsp6303_buf->write(RCD00);
958 // read cursur position
959 rsp6303_buf->write(RCD00);
960 rsp6303_buf->write(curs_x);
961 rsp6303_buf->write(curs_y);
965 // set cursor position
966 if(cmd6303_buf->count() == 2) {
967 curs_x = cmd6303_buf->read();
968 curs_y = cmd6303_buf->read();
969 rsp6303_buf->write(RCD00);
974 // start/stop control block flashing
975 if(cmd6303_buf->count() == 1) {
976 flash_block = cmd6303_buf->read();
977 rsp6303_buf->write(RCD00);
983 if(cmd6303_buf->count() == 4) {
984 uint8_t scr = cmd6303_buf->read();
985 uint8_t code = cmd6303_buf->read();
986 int sy = cmd6303_buf->read();
987 int num = cmd6303_buf->read();
990 for(int y = 0; y < num; y++) {
992 memset(&ram[cs_addr + (sy + y) * 80], code, 80);
997 for(int y = 0; y < num; y++) {
999 memset(&ram[gs_addr + (sy + y) * 60 * 8], code, 60 * 8);
1003 rsp6303_buf->write(RCD00);
1008 // read character font
1009 if(cmd6303_buf->count() == 1) {
1010 int ofs = cmd6303_buf->read() << 3;
1011 rsp6303_buf->write(RCD00);
1012 for(int i = 0; i < 8; i++) {
1013 rsp6303_buf->write(font[ofs + i]);
1019 // define user defined graphic character
1020 if(cmd6303_buf->count() >= 3) {
1021 int lx = cmd6303_buf->read_not_remove(1);
1022 int ly = cmd6303_buf->read_not_remove(2);
1023 if(cmd6303_buf->count() == lx * ly + 3) {
1024 uint8_t code = cmd6303_buf->read();
1025 bool pre = (udgc[code][0] && udgc[code][1]);
1026 for(int i = 0; i < lx * ly + 2; i++) {
1027 uint8_t d = cmd6303_buf->read();
1033 memset(udgc, 0, sizeof(udgc));
1035 rsp6303_buf->write(RCD00);
1041 // define graphic screen block flashing data
1042 if(cmd6303_buf->count() >= 1) {
1043 int cnt = cmd6303_buf->read_not_remove(0);
1044 if(cmd6303_buf->count() == cnt * 3 + 1) {
1045 gs_blocks = cmd6303_buf->read();
1046 for(int i = 0; i < gs_blocks; i++) {
1047 gs_block[i][0] = cmd6303_buf->read();
1048 gs_block[i][1] = cmd6303_buf->read();
1049 gs_block[i][2] = cmd6303_buf->read();
1051 rsp6303_buf->write(RCD00);
1057 // draw character font on graphic screen
1058 if(cmd6303_buf->count() == 4) {
1059 int x = cmd6303_buf->read() << 8;
1060 x |= cmd6303_buf->read();
1061 int y = cmd6303_buf->read();
1062 int ofs = cmd6303_buf->read() << 3;
1063 for(int l = 0; l < 8; l++) {
1064 uint8_t pat = font[ofs + l];
1065 draw_point(x + 0, y + l, pat & 0x20);
1066 draw_point(x + 1, y + l, pat & 0x10);
1067 draw_point(x + 2, y + l, pat & 0x08);
1068 draw_point(x + 3, y + l, pat & 0x04);
1069 draw_point(x + 4, y + l, pat & 0x02);
1070 draw_point(x + 5, y + l, pat & 0x01);
1072 rsp6303_buf->write(RCD00);
1077 // draw user defined character on graphics screen
1078 if(cmd6303_buf->count() >= 3) {
1079 int dx = cmd6303_buf->read();
1080 int dy = cmd6303_buf->read();
1081 uint8_t code = cmd6303_buf->read();
1082 int lx = udgc[code][0];
1083 int ly = udgc[code][1];
1084 uint8_t* pat = &udgc[code][2];
1086 for(int y = 0; y < ly; y++) {
1087 for(int x = 0; x < lx; x++) {
1088 if(dx + x < 60 && dy + y < 64) {
1089 ram[gs_addr + (dx + x + (dy + y) * 60)] = *pat++;
1094 rsp6303_buf->write(RCD00);
1099 // read graphics screen data
1100 if(cmd6303_buf->count() == 3) {
1101 int x = cmd6303_buf->read();
1102 int y = cmd6303_buf->read();
1103 uint8_t* src = &ram[gs_addr + (x + y * 60)];
1104 int cnt = cmd6303_buf->read();
1105 rsp6303_buf->write(RCD00);
1106 for(int i = 0; i < cnt; i++) {
1107 rsp6303_buf->write(src[i]);
1113 // display data on graphics screen
1114 if(cmd6303_buf->count() >= 4) {
1115 int lx = cmd6303_buf->read_not_remove(2);
1116 int ly = cmd6303_buf->read_not_remove(3);
1117 if(cmd6303_buf->count() == lx * ly + 5) {
1118 int dx = cmd6303_buf->read();
1119 int dy = cmd6303_buf->read();
1120 lx = cmd6303_buf->read();
1121 ly = cmd6303_buf->read();
1122 uint8_t ope = cmd6303_buf->read();
1123 for(int y = 0; y < ly; y++) {
1124 for(int x = 0; x < lx; x++) {
1125 uint8_t d = cmd6303_buf->read();
1126 if(dx + x < 60 && dy + y < 64) {
1128 ram[gs_addr + (dx + x + (dy + y) * 60)] &= d;
1129 } else if(ope == 2) {
1130 ram[gs_addr + (dx + x + (dy + y) * 60)] |= d;
1131 } else if(ope == 3) {
1132 ram[gs_addr + (dx + x + (dy + y) * 60)] ^= d;
1134 ram[gs_addr + (dx + x + (dy + y) * 60)] = d;
1139 rsp6303_buf->write(RCD00);
1145 // move graphics screen block
1146 if(cmd6303_buf->count() == 6) {
1147 int sx = cmd6303_buf->read();
1148 int sy = cmd6303_buf->read();
1149 int lx = cmd6303_buf->read();
1150 int ly = cmd6303_buf->read();
1151 int dx = cmd6303_buf->read();
1152 int dy = cmd6303_buf->read();
1153 for(int y = 0; y < ly; y++) {
1154 for(int x = 0; x < lx; x++) {
1155 if(sx + x < 60 && sy + y < 64) {
1156 mov[y][x] = ram[gs_addr + (sx + x + (sy + y) * 60)];
1157 ram[gs_addr + (sx + x + (sy + y) * 60)] = 0;
1161 for(int y = 0; y < ly; y++) {
1162 for(int x = 0; x < lx; x++) {
1163 if(dx + x < 60 && dy + y < 64) {
1164 ram[gs_addr + (dx + x + (dy + y) * 60)] = mov[y][x];
1168 rsp6303_buf->write(RCD00);
1174 if(cmd6303_buf->count() == 4) {
1175 int x = cmd6303_buf->read() << 8;
1176 x |= cmd6303_buf->read();
1177 int y = cmd6303_buf->read();
1178 uint8_t ope = cmd6303_buf->read();
1180 draw_point(x, y, 0);
1182 draw_point(x, y, 1);
1184 rsp6303_buf->write(RCD00);
1190 if(cmd6303_buf->count() == 3) {
1191 int x = cmd6303_buf->read() << 8;
1192 x |= cmd6303_buf->read();
1193 int y = cmd6303_buf->read();
1194 rsp6303_buf->write(RCD00);
1195 rsp6303_buf->write(get_point(x, y));
1201 if(cmd6303_buf->count() == 11) {
1202 int sx = cmd6303_buf->read() << 8;
1203 sx |= cmd6303_buf->read();
1204 int sy = cmd6303_buf->read() << 8;
1205 sy |= cmd6303_buf->read();
1206 int ex = cmd6303_buf->read() << 8;
1207 ex |= cmd6303_buf->read();
1208 int ey = cmd6303_buf->read() << 8;
1209 ey |= cmd6303_buf->read();
1210 uint16_t ope = cmd6303_buf->read() << 8;
1211 ope |= cmd6303_buf->read();
1212 uint8_t mode = cmd6303_buf->read();
1214 draw_line(sx, sy, ex, ey, ~ope);
1216 draw_line(sx, sy, ex, ey, ope);
1218 rsp6303_buf->write(RCD00);
1223 // user defined character
1224 if(cmd6303_buf->count() == 9) {
1225 int code = cmd6303_buf->read();
1227 for(int i = 0; i < 8; i++) {
1228 cmd6303_buf->read();
1230 rsp6303_buf->write(RCD06);
1232 int ofs = code << 3;
1233 for(int i = 0; i < 8; i++) {
1234 font[ofs + i] = cmd6303_buf->read();
1236 rsp6303_buf->write(RCD00);
1242 // define character screen block flashing data
1243 if(cmd6303_buf->count() >= 1) {
1244 int cnt = cmd6303_buf->read_not_remove(0);
1245 if(cmd6303_buf->count() == cnt * 3 + 1) {
1246 cs_blocks = cmd6303_buf->read();
1247 for(int i = 0; i < cs_blocks; i++) {
1248 cs_block[i][0] = cmd6303_buf->read();
1249 cs_block[i][1] = cmd6303_buf->read();
1250 cs_block[i][2] = cmd6303_buf->read();
1252 rsp6303_buf->write(RCD00);
1258 // read window pointer
1259 rsp6303_buf->write(RCD00);
1260 rsp6303_buf->write(wnd_ptr_x);
1261 rsp6303_buf->write(wnd_ptr_y);
1265 // set window pointer
1266 if(cmd6303_buf->count() == 2) {
1267 wnd_ptr_x = cmd6303_buf->read();
1268 wnd_ptr_y = cmd6303_buf->read();
1269 rsp6303_buf->write(RCD00);
1274 // read character screen data
1275 if(cmd6303_buf->count() == 3) {
1276 int x = cmd6303_buf->read();
1277 int y = cmd6303_buf->read();
1278 uint8_t* src = &ram[cs_addr + (x + y * 80)];
1279 int cnt = cmd6303_buf->read();
1280 rsp6303_buf->write(RCD00);
1281 for(int i = 0; i < cnt; i++) {
1282 rsp6303_buf->write(src[i]);
1288 // display data on character screen
1289 if(cmd6303_buf->count() >= 4) {
1290 int cnt = cmd6303_buf->read_not_remove(2);
1291 if(cmd6303_buf->count() == cnt + 3) {
1292 int x = cmd6303_buf->read();
1293 int y = cmd6303_buf->read();
1294 uint8_t* dest = &ram[cs_addr + (x + y * 80)];
1295 cnt = cmd6303_buf->read();
1296 for(int i = 0; i < cnt; i++) {
1297 dest[i] = cmd6303_buf->read();
1299 rsp6303_buf->write(RCD00);
1305 // move character screen block
1306 if(cmd6303_buf->count() == 6) {
1307 int sx = cmd6303_buf->read();
1308 int sy = cmd6303_buf->read();
1309 int lx = cmd6303_buf->read();
1310 int ly = cmd6303_buf->read();
1311 int dx = cmd6303_buf->read();
1312 int dy = cmd6303_buf->read();
1313 for(int y = 0; y < ly; y++) {
1314 for(int x = 0; x < lx; x++) {
1315 if(sx + x < 80 && sy + y < 64) {
1316 mov[y][x] = ram[cs_addr + (sx + x + (sy + y) * 80)];
1317 // ram[cs_addr + (sx + x + (sy + y) * 80)] = 0;
1321 for(int y = 0; y < ly; y++) {
1322 for(int x = 0; x < lx; x++) {
1323 if(dx + x < 80 && dy + y < 64) {
1324 ram[cs_addr + (dx + x + (dy + y) * 80)] = mov[y][x];
1328 rsp6303_buf->write(RCD00);
1333 // read microcassette status
1334 rsp6303_buf->write(RCD00);
1335 rsp6303_buf->write(0);
1340 rsp6303_buf->write(RCD07);
1345 rsp6303_buf->write(RCD00);
1351 // fast foward n counts
1352 if(cmd6303_buf->count() == 2) {
1353 cmd6303_buf->read();
1354 cmd6303_buf->read();
1355 rsp6303_buf->write(RCD07);
1363 rsp6303_buf->write(RCD07);
1374 rsp6303_buf->write(RCD00);
1378 // read write protect pin
1379 rsp6303_buf->write(RCD00);
1380 rsp6303_buf->write(0);
1385 rsp6303_buf->write(RCD00);
1386 rsp6303_buf->write(0);
1387 rsp6303_buf->write(0);
1392 if(cmd6303_buf->count() == 2) {
1393 cmd6303_buf->read();
1394 cmd6303_buf->read();
1395 rsp6303_buf->write(RCD00);
1400 // set write protect area pointer
1401 if(cmd6303_buf->count() == 2) {
1402 cmd6303_buf->read();
1403 cmd6303_buf->read();
1404 rsp6303_buf->write(RCD00);
1409 // reset write protect area pointer
1410 rsp6303_buf->write(RCD00);
1414 // read serial i/o status
1415 rsp6303_buf->write(RCD00);
1416 rsp6303_buf->write(0x20 | (tf20_buf->count() ? 0x80 : 0));
1420 // set serial port bit rate
1421 if(cmd6303_buf->count() == 1) {
1422 cmd6303_buf->read();
1423 rsp6303_buf->write(RCD00);
1429 rsp6303_buf->write(RCD00);
1430 rsp6303_buf->write(tf20_buf->read());
1435 if(cmd6303_buf->count() == 1) {
1436 d_tf20->write_signal(SIGNAL_TF20_SIO, cmd6303_buf->read(), 0xff);
1437 rsp6303_buf->write(RCD00);
1442 // send data with header
1443 if(cmd6303_buf->count() >= 6) {
1444 int cnt = cmd6303_buf->read_not_remove(5);
1445 if(cmd6303_buf->count() == cnt + 7) {
1446 int rcv = cmd6303_buf->read();
1447 int fmt = cmd6303_buf->read();
1448 int did = cmd6303_buf->read();
1449 int sid = cmd6303_buf->read();
1450 int fnc = cmd6303_buf->read();
1451 int siz = cmd6303_buf->read();
1455 d_tf20->write_signal(SIGNAL_TF20_SIO, DID_FIRST, 0xff);
1456 d_tf20->write_signal(SIGNAL_TF20_SIO, did, 0xff);
1457 d_tf20->write_signal(SIGNAL_TF20_SIO, sid, 0xff);
1458 d_tf20->write_signal(SIGNAL_TF20_SIO, DS_SEL, 0xff);
1459 tf20_buf->read(); // recv ack
1460 d_tf20->write_signal(SIGNAL_TF20_SIO, SOH, 0xff);
1461 d_tf20->write_signal(SIGNAL_TF20_SIO, fmt, 0xff);
1462 d_tf20->write_signal(SIGNAL_TF20_SIO, did, 0xff);
1463 d_tf20->write_signal(SIGNAL_TF20_SIO, sid, 0xff);
1464 d_tf20->write_signal(SIGNAL_TF20_SIO, fnc, 0xff);
1465 d_tf20->write_signal(SIGNAL_TF20_SIO, siz, 0xff);
1466 d_tf20->write_signal(SIGNAL_TF20_SIO, 0, 0xff);
1467 tf20_buf->read(); // recv ack
1468 d_tf20->write_signal(SIGNAL_TF20_SIO, STX, 0xff);
1469 for(int i = 0; i < siz + 1; i++) {
1470 d_tf20->write_signal(SIGNAL_TF20_SIO, cmd6303_buf->read(), 0xff);
1472 d_tf20->write_signal(SIGNAL_TF20_SIO, 0, 0xff);
1473 d_tf20->write_signal(SIGNAL_TF20_SIO, 0, 0xff);
1474 tf20_buf->read(); // recv ack
1475 d_tf20->write_signal(SIGNAL_TF20_SIO, EOT, 0xff);
1477 rsp6303_buf->write(RCD00);
1479 rsp6303_buf->write(0);
1481 rsp6303_buf->write(fmt = tf20_buf->read());
1482 rsp6303_buf->write(did = tf20_buf->read());
1483 rsp6303_buf->write(sid = tf20_buf->read());
1484 rsp6303_buf->write(fnc = tf20_buf->read());
1485 rsp6303_buf->write(siz = tf20_buf->read());
1487 d_tf20->write_signal(SIGNAL_TF20_SIO, ACK, 0xff); // ack
1489 for(int i = 0; i < siz + 1; i++) {
1490 rsp6303_buf->write(tf20_buf->read());
1492 d_tf20->write_signal(SIGNAL_TF20_SIO, ACK, 0xff); // ack
1493 d_tf20->write_signal(SIGNAL_TF20_SIO, EOT, 0xff); // eot
1501 // receive data with header
1502 rsp6303_buf->write(RCD00);
1505 int fmt, did, sid, fnc, siz;
1506 rsp6303_buf->write(0);
1508 rsp6303_buf->write(fmt = tf20_buf->read());
1509 rsp6303_buf->write(did = tf20_buf->read());
1510 rsp6303_buf->write(sid = tf20_buf->read());
1511 rsp6303_buf->write(fnc = tf20_buf->read());
1512 rsp6303_buf->write(siz = tf20_buf->read());
1514 d_tf20->write_signal(SIGNAL_TF20_SIO, ACK, 0xff); // ack
1516 for(int i = 0; i < siz + 1; i++) {
1517 rsp6303_buf->write(tf20_buf->read());
1519 d_tf20->write_signal(SIGNAL_TF20_SIO, ACK, 0xff); // ack
1520 d_tf20->write_signal(SIGNAL_TF20_SIO, EOT, 0xff); // eot
1526 // turn on/off prom cupsule power
1527 if(cmd6303_buf->count() == 1) {
1528 cmd6303_buf->read();
1529 rsp6303_buf->write(RCD00);
1535 if(cmd6303_buf->count() == 4) {
1536 cmd6303_buf->read();
1537 uint16_t addr = cmd6303_buf->read() << 8;
1538 addr |= cmd6303_buf->read();
1540 int cnt = cmd6303_buf->read();
1541 if(cnt == 0) cnt = 256;
1542 rsp6303_buf->write(RCD00);
1543 for(int i = 0; i < cnt; i++) {
1545 rsp6303_buf->write(util[(addr + i) & 0x7fff]);
1547 rsp6303_buf->write(basic[(addr + i) & 0x7fff]);
1554 // turn on/off speaker power
1555 if(cmd6303_buf->count() == 1) {
1556 cmd6303_buf->read();
1557 rsp6303_buf->write(RCD00);
1562 // turn on/off speaker power
1563 if(cmd6303_buf->count() == 3) {
1564 cmd6303_buf->read();
1565 cmd6303_buf->read();
1566 cmd6303_buf->read();
1567 rsp6303_buf->write(RCD00);
1573 if(cmd6303_buf->count() == 3) {
1574 cmd6303_buf->read();
1575 cmd6303_buf->read();
1576 cmd6303_buf->read();
1577 rsp6303_buf->write(RCD00);
1584 uint8_t HC80_IO::get_point(int x, int y)
1586 if(0 <= x && x < 480 && 0 <= y && y < 64) {
1587 uint8_t bit = dot_tbl[x & 7];
1588 int ofs = y * 60 + (x >> 3);
1589 return ram[gs_addr + ofs] & bit;
1594 void HC80_IO::draw_point(int x, int y, uint16_t dot)
1596 if(0 <= x && x < 480 && 0 <= y && y < 64) {
1597 uint8_t bit = dot_tbl[x & 7];
1598 int ofs = y * 60 + (x >> 3);
1600 ram[gs_addr + ofs] |= bit;
1602 ram[gs_addr + ofs] &= ~bit;
1607 void HC80_IO::draw_line(int sx, int sy, int ex, int ey, uint16_t ope)
1609 int next_x = sx, next_y = sy;
1610 int delta_x = abs(ex - sx) * 2;
1611 int delta_y = abs(ey - sy) * 2;
1612 int step_x = (ex < sx) ? -1 : 1;
1613 int step_y = (ey < sy) ? -1 : 1;
1615 draw_point(sx, sy, ope & 0x8000);
1616 ope = (ope << 1) | (ope & 0x8000 ? 1 : 0);
1617 if(delta_x > delta_y) {
1618 int frac = delta_y - delta_x / 2;
1619 while(next_x != ex) {
1626 draw_point(next_x, next_y, ope & 0x8000);
1627 ope = (ope << 1) | (ope & 0x8000 ? 1 : 0);
1630 int frac = delta_x - delta_y / 2;
1631 while(next_y != ey) {
1638 draw_point(next_x, next_y, ope & 0x8000);
1639 ope = (ope << 1) | (ope & 0x8000 ? 1 : 0);
1642 draw_point(ex, ey, ope & 0x8000);
1645 // ----------------------------------------------------------------------------
1646 // intelligent ram disk by Mr.Dennis Heynlein
1647 // ----------------------------------------------------------------------------
1650 0x81 (W) CommandByte c to RAMDisk
1652 Bit 0 : Readable DataByte on 0x81 is pending
1653 Bit 1 : Receive of Data/Command is busy
1654 Bit 7 and 6 = 0 (ident the RAMdisc)
1656 0x80 (R/W) DataByte d
1658 Commands: RESET - input: c(00)
1659 output: d(SWITCHSTATE)
1661 READSECTOR - input: c(01) d(TRACK) d(SECTOR)
1662 output: d(ERRORSTATE) d(SECTORBYTE)*128
1664 READMEMDIRECT - input: c(02) d(BANK) d(HIGHBYTE) d(LOWBYTE)
1665 output: d(ERRORSTATE) d(BYTE)
1667 WRITESECTOR - input: c(03) d(TRACK) d(SECTOR) d(SECTORBYTE)*128
1668 output: d(ERRORSTATE)
1670 WRITEMEMDIRECT - input: c(04) d(HIGHBYTE) d(LOWBYTE) d(BYTE)
1671 output: d(ERRORSTATE)
1673 INIT_BITMAP - input: c(05)
1674 output: d(ERRORSTATE)
1676 ERRORSTATE: Bit 0 = Ramdiscsize
1678 Bit 2 = Writeprotect
1687 void HC80_IO::iramdisk_write_data(uint8_t val)
1689 if(iramdisk_dest == IRAMDISK_IN && iramdisk_count) {
1690 *(iramdisk_ptr++) = val;
1693 if(!iramdisk_count) {
1694 iramdisk_dest = IRAMDISK_OUT;
1695 iramdisk_ptr = iramdisk_buf;
1696 int track = iramdisk_buf[0];
1697 int sector = iramdisk_buf[1];
1699 switch(iramdisk_cmd) {
1700 case 1: //READSECTOR
1701 if(track > 14 || sector > 63) {
1702 iramdisk_buf[0] = 2;
1704 iramdisk_buf[0] = 0;
1705 for(int t = 0;t < 128; t++) {
1706 iramdisk_buf[t + 1] = iramdisk_sectors[track][sector][t];
1709 iramdisk_count = 129; //ERRORCODE + 128 Bytes
1711 case 3: //WRITESECTOR
1712 if(track > 14 || sector > 63) {
1713 iramdisk_buf[0] = 2;
1715 iramdisk_buf[0] = 0;
1716 for(int t = 0; t < 128; t++) {
1717 iramdisk_sectors[track][sector][t] = iramdisk_buf[t+2];
1720 iramdisk_count = 1; //ERRORCODE
1722 case 2: //READMEMDIRECT
1723 iramdisk_count = 2; //ERRORCODE + 1 Byte
1725 case 4: //WRITEMEMDIRECT
1726 iramdisk_count = 1; //ERRORCODE
1732 void HC80_IO::iramdisk_write_cmd(uint8_t val)
1736 iramdisk_ptr = iramdisk_buf;
1737 iramdisk_dest = IRAMDISK_IN;
1739 switch(iramdisk_cmd) {
1748 iramdisk_count = 130;
1751 //PROCESS-1-BYTE_CMDs
1753 iramdisk_dest = IRAMDISK_OUT;
1754 if(iramdisk_cmd == 0) {
1755 iramdisk_buf[0] = 1; // RESET
1757 iramdisk_buf[0] = 0; //INIT
1762 uint8_t HC80_IO::iramdisk_read_data()
1764 if(iramdisk_dest == IRAMDISK_OUT) {
1765 if(iramdisk_count) {
1767 if(!iramdisk_count) {
1768 iramdisk_dest = IRAMDISK_IN;
1770 return *(iramdisk_ptr++);
1776 uint8_t HC80_IO::iramdisk_read_stat()
1778 if(iramdisk_dest == IRAMDISK_OUT) {
1779 return IRAMDISK_WAIT;
1785 // ----------------------------------------------------------------------------
1787 // ----------------------------------------------------------------------------
1790 void HC80_IO::draw_screen()
1793 memset(lcd, 0, sizeof(lcd));
1796 uint8_t* vram = &ram[scr_ptr];
1797 for(int y = 0; y < (num_lines ? 7 : 8); y++) {
1798 int py = num_lines ? (y * 9 + 1) : y * 8;
1799 for(int x = 0; x < 80; x++) {
1801 int ofs = vram[y * 80 + x] << 3;
1802 for(int l = 0; l < 8; l++) {
1803 uint8_t pat = font[ofs + l];
1804 lcd[py + l][px + 0] = (pat & 0x20) ? 0xff : 0;
1805 lcd[py + l][px + 1] = (pat & 0x10) ? 0xff : 0;
1806 lcd[py + l][px + 2] = (pat & 0x08) ? 0xff : 0;
1807 lcd[py + l][px + 3] = (pat & 0x04) ? 0xff : 0;
1808 lcd[py + l][px + 4] = (pat & 0x02) ? 0xff : 0;
1809 lcd[py + l][px + 5] = (pat & 0x01) ? 0xff : 0;
1815 int yofs = (scr_ptr - cs_addr) / 80;
1816 for(int i = 0; i < cs_blocks; i++) {
1817 int x = cs_block[i][0];
1818 int y = cs_block[i][1] - yofs;
1819 if(0 <= x && x < 80 && 0 <= y && y < 8) {
1822 for(int l = 0; l < 8; l++) {
1823 lcd[py + l][px + 0] = ~lcd[py + l][px + 0];
1824 lcd[py + l][px + 1] = ~lcd[py + l][px + 1];
1825 lcd[py + l][px + 2] = ~lcd[py + l][px + 2];
1826 lcd[py + l][px + 3] = ~lcd[py + l][px + 3];
1827 lcd[py + l][px + 4] = ~lcd[py + l][px + 4];
1828 lcd[py + l][px + 5] = ~lcd[py + l][px + 5];
1835 if(!(curs_mode & 2) || (blink & 32)) {
1836 int px = curs_x * 6;
1837 int py = curs_y * 8;
1838 int st = (curs_mode & 4) ? 0 : 7;
1839 if(px + 6 - 1 < SCREEN_WIDTH) {
1840 for(int l = st; l < 8 && py + l < SCREEN_HEIGHT; l++) {
1841 memset(&lcd[py + l][px], 0xff, 6);
1848 uint8_t* vram = &ram[gs_addr];
1849 for(int y = 0; y < 64; y++) {
1850 for(int x = 0; x < 60; x++) {
1852 uint8_t pat = *vram++;
1853 lcd[y][px + 0] = (pat & 0x80) ? 0xff : 0;
1854 lcd[y][px + 1] = (pat & 0x40) ? 0xff : 0;
1855 lcd[y][px + 2] = (pat & 0x20) ? 0xff : 0;
1856 lcd[y][px + 3] = (pat & 0x10) ? 0xff : 0;
1857 lcd[y][px + 4] = (pat & 0x08) ? 0xff : 0;
1858 lcd[y][px + 5] = (pat & 0x04) ? 0xff : 0;
1859 lcd[y][px + 6] = (pat & 0x02) ? 0xff : 0;
1860 lcd[y][px + 7] = (pat & 0x01) ? 0xff : 0;
1865 for(int i = 0; i < gs_blocks; i++) {
1866 int x = gs_block[i][0];
1867 int y = gs_block[i][1];
1868 if(0 <= x && x < 60 && 0 <= y && y < 8) {
1871 for(int l = 0; l < 8; l++) {
1872 lcd[py + l][px + 0] = ~lcd[py + l][px + 0];
1873 lcd[py + l][px + 1] = ~lcd[py + l][px + 1];
1874 lcd[py + l][px + 2] = ~lcd[py + l][px + 2];
1875 lcd[py + l][px + 3] = ~lcd[py + l][px + 3];
1876 lcd[py + l][px + 4] = ~lcd[py + l][px + 4];
1877 lcd[py + l][px + 5] = ~lcd[py + l][px + 5];
1878 lcd[py + l][px + 6] = ~lcd[py + l][px + 6];
1879 lcd[py + l][px + 7] = ~lcd[py + l][px + 7];
1885 for(int y = 0; y < 64; y++) {
1886 scrntype_t* dest = emu->get_screen_buffer(y);
1887 for(int x = 0; x < 480; x++) {
1888 dest[x] = lcd[y][x] ? pd : pb;
1892 for(int y = 0; y < 64; y++) {
1893 scrntype_t* dest = emu->get_screen_buffer(y);
1894 for(int x = 0; x < 480; x++) {
1901 #define STATE_VERSION 1
1903 bool HC80_IO::process_state(FILEIO* state_fio, bool loading)
1905 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1908 if(!state_fio->StateCheckInt32(this_device_id)) {
1911 state_fio->StateUint32(cur_clock);
1912 state_fio->StateUint8(bcr);
1913 state_fio->StateUint8(slbcr);
1914 state_fio->StateUint8(isr);
1915 state_fio->StateUint8(ier);
1916 state_fio->StateUint8(ioctlr);
1917 state_fio->StateUint32(icrc);
1918 state_fio->StateUint32(icrb);
1919 state_fio->StateBool(ear);
1920 state_fio->StateUint8(vadr);
1921 state_fio->StateUint8(yoff);
1922 if(!cmd7508_buf->process_state((void *)state_fio, loading)) {
1925 if(!rsp7508_buf->process_state((void *)state_fio, loading)) {
1928 if(!cur_time.process_state((void *)state_fio, loading)) {
1931 state_fio->StateInt32(register_id);
1932 state_fio->StateBool(onesec_intr);
1933 state_fio->StateBool(onesec_intr_enb);
1934 state_fio->StateBool(alarm_intr);
1935 state_fio->StateBool(alarm_intr_enb);
1936 state_fio->StateBuffer(alarm, sizeof(alarm), 1);
1937 if(!key_buf->process_state((void *)state_fio, loading)) {
1940 state_fio->StateBool(kb_intr_enb);
1941 state_fio->StateBool(kb_rep_enb);
1942 state_fio->StateBool(kb_caps);
1943 state_fio->StateUint8(kb_rep_spd1);
1944 state_fio->StateUint8(kb_rep_spd2);
1945 state_fio->StateBool(beep);
1946 state_fio->StateBool(res_z80);
1947 state_fio->StateBool(res_7508);
1948 state_fio->StateUint8(cmd6303);
1949 state_fio->StateUint8(psr);
1950 if(!cmd6303_buf->process_state((void *)state_fio, loading)) {
1953 if(!rsp6303_buf->process_state((void *)state_fio, loading)) {
1956 state_fio->StateBuffer(ram, sizeof(ram), 1);
1957 state_fio->StateUint16(cs_addr);
1958 state_fio->StateUint16(gs_addr);
1959 state_fio->StateUint8(lcd_on);
1960 state_fio->StateUint8(scr_mode);
1961 state_fio->StateUint16(scr_ptr);
1962 state_fio->StateUint8(num_lines);
1963 state_fio->StateUint8(curs_mode);
1964 state_fio->StateUint8(curs_x);
1965 state_fio->StateUint8(curs_y);
1966 state_fio->StateUint8(wnd_ptr_x);
1967 state_fio->StateUint8(wnd_ptr_y);
1968 state_fio->StateUint8(flash_block);
1969 state_fio->StateUint8(cs_blocks);
1970 state_fio->StateBuffer(cs_block, sizeof(cs_block), 1);
1971 state_fio->StateUint8(gs_blocks);
1972 state_fio->StateBuffer(gs_block, sizeof(gs_block), 1);
1973 state_fio->StateBuffer(font, sizeof(font), 1);
1974 state_fio->StateBuffer(udgc, sizeof(udgc), 1);
1975 state_fio->StateBuffer(mov, sizeof(mov), 1);
1976 state_fio->StateBuffer(lcd, sizeof(lcd), 1);
1977 state_fio->StateInt32(blink);
1978 if(!tf20_buf->process_state((void *)state_fio, loading)) {
1981 state_fio->StateInt32(device_type);
1982 state_fio->StateBuffer(ext, sizeof(ext), 1);
1983 state_fio->StateUint32(extar);
1984 state_fio->StateUint8(extcr);
1985 state_fio->StateBuffer(iramdisk_sectors, sizeof(iramdisk_sectors), 1);
1986 state_fio->StateUint8(iramdisk_cmd);
1987 state_fio->StateInt32(iramdisk_count);
1988 state_fio->StateInt32(iramdisk_dest);
1989 state_fio->StateBuffer(iramdisk_buf, sizeof(iramdisk_buf), 1);
1991 iramdisk_ptr = iramdisk_buf + state_fio->FgetInt32_LE();
1993 state_fio->FputInt32_LE((int)(iramdisk_ptr - iramdisk_buf));