2 FUJITSU FMR-30 Emulator 'eFMR-30'
3 FUJITSU FMR-50 Emulator 'eFMR-50'
4 FUJITSU FMR-60 Emulator 'eFMR-60'
6 Author : Takeda.Toshiya
49 #define ERR_FDD_NOTREADY 1
50 #define ERR_FDD_PROTECTED 2
51 #define ERR_FDD_DELETED 4
52 #define ERR_FDD_NOTFOUND 8
53 #define ERR_FDD_CRCERROR 0x10
54 #define ERR_SCSI_NOTREADY 1
55 #define ERR_SCSI_PARAMERROR 2
56 #define ERR_SCSI_NOTCONNECTED 4
60 #define CMOS_SIZE 0x2000
61 #define VRAM_SIZE 0x20000
62 #define IPL_SIZE 0x10000
66 #define CMOS_SIZE 0x800
67 #define VRAM_SIZE 0x40000
68 #define IPL_SIZE 0x4000
72 #define CMOS_SIZE 0x800
73 #define VRAM_SIZE 0x80000
74 #define IPL_SIZE 0x4000
78 #define BLOCK_SIZE 512
80 static const int iotable[][2] = {
82 {0x0100, 0x19}, // pic
92 {0x0042, 0x00}, // timer
96 {0x000b, 0x02}, // sio
102 {0x001d, 0x02}, // memory
104 {0x0040, 0x9f}, // psg
108 {0x0300, 0x01}, // lcdc
132 {0x0060, 0x00}, // timer
133 {0x0604, 0x00}, // keyboard
134 {0x0000, 0x19}, // pic
145 {0x0046, 0x36}, // pit
148 {0x0404, 0x00}, // memory
149 {0x0500, 0x00}, // crtc
189 {0xfd98, 0x00}, // palette
197 {0xfda0, 0x0f}, // video
203 static const uint8_t cmos_t[] = {
205 0x01,0xff,0x42,0x4f,0x4f,0x54,0xa8,0x00,0x40,0x00,0x01,0xfe,0x53,0x45,0x54,0x55,
206 0xe8,0x00,0x00,0x01,0x01,0xfd,0x4c,0x4f,0x47,0x20,0xe8,0x01,0x10,0x03,0x01,0xfc,
207 0x4f,0x41,0x53,0x59,0xf8,0x04,0x20,0x00,0x01,0xfb,0x44,0x45,0x42,0x20,0x18,0x05,
208 0x00,0x01,0x01,0xfa,0x44,0x45,0x53,0x4b,0x18,0x06,0x32,0x00,0x00,0x00,0x00,0x00,
209 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
211 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
212 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
213 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
214 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
215 0x4a,0x06,0x7b,0x19,0x97,0x62,0x79,0x41
217 0x01,0xff,0x42,0x4f,0x4f,0x54,0xa8,0x00,0x40,0x00,0x01,0xfe,0x53,0x45,0x54,0x55,
218 0xe8,0x00,0x00,0x01,0x01,0xfd,0x4c,0x4f,0x47,0x20,0xe8,0x01,0x10,0x03,0x01,0xfc,
219 0x4f,0x41,0x53,0x59,0xf8,0x04,0x20,0x00,0x01,0xfb,0x58,0x45,0x4e,0x49,0x18,0x05,
220 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
221 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
223 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
224 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
225 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
226 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
227 // 0x28,0x05,0x99,0x02,0xe1,0xe1,0x79,0x41
228 0x28,0x05,0x99,0x02,0x00,0x00,0x79,0x41
231 // FMR-30: cmos $1fd0-
232 // FMR-50: cmos $7d0-
233 static const uint8_t cmos_b[] = {
235 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0xff,0xff,0xff,0xff,0xff,
236 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
237 0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
239 0x00,0x00,0x01,0x02,0x03,0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
240 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
241 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
246 static const uint8_t msg_c[] = {
247 0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,
248 0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,
249 0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,
250 0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07,0xff,0x47,0xff,0x07
253 // '
\83V
\83X
\83e
\83\80\82ð
\83Z
\83b
\83g
\82µ
\82Ä
\82Â
\82¾
\82³
\82¢'
254 static const uint8_t msg_k[] = {
255 0x25,0x37,0x00,0x00,0x25,0x39,0x00,0x00,0x25,0x46,0x00,0x00,0x25,0x60,0x00,0x00,
256 0x24,0x72,0x00,0x00,0x25,0x3b,0x00,0x00,0x25,0x43,0x00,0x00,0x25,0x48,0x00,0x00,
257 0x24,0x37,0x00,0x00,0x24,0x46,0x00,0x00,0x24,0x2f,0x00,0x00,0x24,0x40,0x00,0x00,
258 0x24,0x35,0x00,0x00,0x24,0x24,0x00,0x00,0x21,0x21,0x00,0x00
261 void BIOS::initialize()
263 // to increment timeout counter
264 register_frame_event(this);
267 FILEIO* fio = new FILEIO();
268 for(int i = 0; i < MAX_SCSI; i++) {
269 if(fio->Fopen(create_local_path(_T("SCSI%d.DAT"), i), FILEIO_READ_WRITE_BINARY)) {
270 uint32_t file_size = fio->FileLength();
272 // from ../scsi_hdd.cpp
273 #define SCSI_BUFFER_SIZE 0x10000
274 uint32_t remain = (file_size = 0x2800000); // 40MB
275 void *tmp = calloc(1, SCSI_BUFFER_SIZE);
277 uint32_t length = min(remain, (uint32_t)SCSI_BUFFER_SIZE);
278 fio->Fwrite(tmp, length, 1);
282 #undef SCSI_BUFFER_SIZE
284 scsi_blocks[i] = file_size / BLOCK_SIZE;
295 for(int i = 0; i < MAX_DRIVE; i++) {
296 access_fdd[i] = false;
303 void BIOS::event_frame()
308 bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
310 uint8_t *regs8 = (uint8_t *)regs;
312 uint8_t buffer[BLOCK_SIZE * 4];
317 this->out_debug_log(_T("%6x\tDISK BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);
321 if((AL & 0xf0) == 0x20) {
323 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
325 CX = ERR_FDD_NOTREADY;
331 if(disk[drv]->write_protected) {
338 if((AL & 0xf0) == 0xb0) {
340 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
342 CX = ERR_SCSI_NOTCONNECTED;
347 AL = (BLOCK_SIZE == 128) ? 0 : (BLOCK_SIZE == 256) ? 1 : (BLOCK_SIZE == 512) ? 2 : 3;
348 BX = scsi_blocks[drv] >> 16;
349 DX = scsi_blocks[drv] & 0xffff;
357 } else if(AH == 3 || AH == 4) {
359 if((AL & 0xf0) == 0x20) {
361 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
363 CX = ERR_FDD_NOTREADY;
372 if((AL & 0xf0) == 0xb0) {
374 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
376 CX = ERR_SCSI_NOTCONNECTED;
390 if((AL & 0xf0) == 0x20) {
392 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
394 CX = ERR_FDD_NOTREADY;
399 int ofs = DS * 16 + DI;
405 disk[drv]->get_track(trk, hed);
406 access_fdd[drv] = true;
408 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
410 CX = ERR_FDD_NOTFOUND;
414 // check id crc error
415 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
417 CX = ERR_FDD_NOTFOUND | ERR_FDD_CRCERROR;
421 // check deleted mark
422 if(disk[drv]->deleted) {
424 CX = ERR_FDD_DELETED;
429 for(int i = 0; i < disk[drv]->sector_size.sd; i++) {
430 d_mem->write_data8(ofs++, disk[drv]->sector[i]);
433 // check data crc error
434 if(disk[drv]->data_crc_error && !disk[drv]->ignore_crc()) {
436 CX = ERR_FDD_CRCERROR;
441 if(++sct > disk[drv]->sector_num.sd) {
454 if((AL & 0xf0) == 0xb0) {
456 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
458 CX = ERR_SCSI_NOTCONNECTED;
462 FILEIO* fio = new FILEIO();
463 if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_BINARY)) {
465 CX = ERR_SCSI_NOTREADY;
471 int ofs = DS * 16 + DI;
472 int block = (CL << 16) | DX;
473 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);
477 if(!(block++ < scsi_blocks[drv])) {
479 CX = ERR_SCSI_PARAMERROR;
486 fio->Fread(buffer, BLOCK_SIZE, 1);
487 for(int i = 0; i < BLOCK_SIZE; i++) {
488 d_mem->write_data8(ofs++, buffer[i]);
504 if((AL & 0xf0) == 0x20) {
506 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
508 CX = ERR_FDD_NOTREADY;
512 if(disk[drv]->write_protected) {
514 CX = ERR_FDD_PROTECTED;
519 int ofs = DS * 16 + DI;
525 disk[drv]->get_track(trk, hed);
526 access_fdd[drv] = true;
528 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
530 CX = ERR_FDD_NOTFOUND;
534 // check id crc error
535 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
537 CX = ERR_FDD_NOTFOUND | ERR_FDD_CRCERROR;
542 for(int i = 0; i < disk[drv]->sector_size.sd; i++) {
543 disk[drv]->sector[i] = d_mem->read_data8(ofs++);
546 // clear deleted mark and data crc error
547 disk[drv]->set_deleted(false);
548 disk[drv]->set_data_crc_error(false);
550 if(++sct > disk[drv]->sector_num.sd) {
563 if((AL & 0xf0) == 0xb0) {
565 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
567 CX = ERR_SCSI_NOTCONNECTED;
571 FILEIO* fio = new FILEIO();
572 if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_WRITE_BINARY)) {
574 CX = ERR_SCSI_NOTREADY;
580 int ofs = DS * 16 + DI;
581 int block = (CL << 16) | DX;
582 fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);
586 if(!(block++ < scsi_blocks[drv])) {
588 CX = ERR_SCSI_PARAMERROR;
595 for(int i = 0; i < BLOCK_SIZE; i++) {
596 buffer[i] = d_mem->read_data8(ofs++);
598 fio->Fwrite(buffer, BLOCK_SIZE, 1);
613 if((AL & 0xf0) == 0x20) {
615 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
617 CX = ERR_FDD_NOTREADY;
627 disk[drv]->get_track(trk, hed);
628 access_fdd[drv] = true;
630 if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
632 CX = ERR_FDD_NOTFOUND;
636 // check id crc error
637 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
639 CX = ERR_FDD_NOTFOUND | ERR_FDD_CRCERROR;
645 // check data crc error
646 if(disk[drv]->data_crc_error && !disk[drv]->ignore_crc()) {
648 CX = ERR_FDD_CRCERROR;
653 if(++sct > disk[drv]->sector_num.sd) {
666 if((AL & 0xf0) == 0xb0) {
668 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
670 CX = ERR_SCSI_NOTCONNECTED;
675 int block = (CL << 16) | DX;
679 if(!(block++ < scsi_blocks[drv])) {
681 CX = ERR_SCSI_PARAMERROR;
696 // reset hard drive controller
703 if((AL & 0xf0) == 0x20) {
705 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
707 CX = ERR_FDD_NOTREADY;
712 int ofs = DS * 16 + DI;
716 disk[drv]->get_track(trk, hed);
717 access_fdd[drv] = true;
718 if(++secnum > disk[drv]->sector_num.sd) {
721 if(!disk[drv]->get_sector(trk, hed, secnum - 1)) {
723 CX = ERR_FDD_NOTFOUND;
728 for(int i = 0; i < 6; i++) {
729 d_mem->write_data8(ofs++, disk[drv]->id[i]);
731 // check id crc error
732 if(disk[drv]->addr_crc_error && !disk[drv]->ignore_crc()) {
734 CX = ERR_FDD_CRCERROR;
746 } else if(AH == 0xa) {
748 if((AL & 0xf0) == 0x20) {
750 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
752 CX = ERR_FDD_NOTREADY;
757 int ofs = DS * 16 + DI;
761 disk[drv]->format_track(trk, hed);
762 access_fdd[drv] = true;
763 bool id_written = false;
764 bool sector_found = false;
765 int sector_length, sector_index;
766 for(int index = 0; index < disk[drv]->get_track_size(); index++) {
767 uint8_t datareg = d_mem->read_data8(ofs++);
768 if(datareg == 0xf5) {
769 // write a1h in missing clock
770 } else if(datareg == 0xf6) {
771 // write c2h in missing clock
772 } else if(datareg == 0xf7) {
775 // insert new sector with data crc error
778 sector_found = false;
779 uint8_t c = disk[drv]->track[index - 4];
780 uint8_t h = disk[drv]->track[index - 3];
781 uint8_t r = disk[drv]->track[index - 2];
782 uint8_t n = disk[drv]->track[index - 1];
783 sector_length = 0x80 << (n & 3);
785 disk[drv]->insert_sector(c, h, r, n, false, true, 0xe5, sector_length);
786 } else if(sector_found) {
787 // clear data crc error if all sector data are written
788 disk[drv]->set_data_crc_error(false);
791 // data mark of current sector is not written
792 disk[drv]->set_data_mark_missing();
795 } else if(id_written) {
798 if(sector_index < sector_length) {
799 disk[drv]->sector[sector_index] = datareg;
802 } else if(datareg == 0xf8 || datareg == 0xfb) {
804 disk[drv]->set_deleted(datareg == 0xf8);
808 disk[drv]->track[index] = datareg;
818 } else if(AH == 0xd) {
824 } else if(AH == 0xe) {
826 if((AL & 0xf0) == 0x20) {
828 if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
837 DL = disk[drv]->changed ? 1 : 0;
838 disk[drv]->changed = false;
842 if((AL & 0xf0) == 0xb0) {
844 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
859 } else if(AH == 0xfa) {
861 if((AL & 0xf0) == 0x20) {
868 if((AL & 0xf0) == 0xb0) {
870 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
872 CX = ERR_SCSI_NOTCONNECTED;
884 } else if(AH == 0xfd) {
886 if((AL & 0xf0) == 0x20) {
893 if((AL & 0xf0) == 0xb0) {
895 if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
910 } else if(AH == 0x80) {
911 // pseudo bios: init i/o
912 for(int i = 0;; i++) {
913 if(iotable[i][0] < 0) {
916 d_io->write_io8(iotable[i][0], iotable[i][1]);
919 memset(cmos, 0, CMOS_SIZE);
920 memcpy(cmos, cmos_t, sizeof(cmos_t));
921 memcpy(cmos + CMOS_SIZE - sizeof(cmos_b), cmos_b, sizeof(cmos_b));
923 for(int i = 0, ofs = 0; i < 256; i++) {
924 // int vector = ffff:0008
925 d_mem->write_data16(ofs + 0, 0x0008);
926 d_mem->write_data16(ofs + 2, 0xffff);
930 memset(vram, 0, VRAM_SIZE);
932 memset(cvram, 0, 0x2000);
933 memset(avram, 0, 0x2000);
935 memset(cvram, 0, 0x1000);
936 memset(kvram, 0, 0x1000);
937 memcpy(cvram + 0xf00, msg_c, sizeof(msg_c));
938 memcpy(kvram + 0xf00, msg_k, sizeof(msg_k));
942 } else if(AH == 0x81) {
943 // pseudo bios: boot from fdd #0
944 *ZeroFlag = (timeout > (int)(FRAMES_PER_SEC * 4));
945 if(!disk[0]->inserted) {
950 disk[0]->get_track(0, 0);
951 access_fdd[0] = true;
952 if(!disk[0]->get_sector(0, 0, 0)) {
956 for(int i = 0; i < disk[0]->sector_size.sd; i++) {
957 buffer[i] = disk[0]->sector[i];
960 if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {
965 for(int i = 0; i < disk[0]->sector_size.sd; i++) {
966 d_mem->write_data8(0xb0000 + i, buffer[i]);
970 memset(cvram, 0, 0x2000);
971 memset(avram, 0, 0x2000);
973 memset(cvram, 0, 0x1000);
974 memset(kvram, 0, 0x1000);
983 } else if(AH == 0x82) {
984 // pseudo bios: boot from scsi-hdd #0
986 if(!scsi_blocks[0]) {
990 FILEIO* fio = new FILEIO();
991 if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_BINARY)) {
998 fio->Fread(buffer, BLOCK_SIZE * 4, 1);
1002 if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {
1007 for(int i = 0; i < BLOCK_SIZE * 4; i++) {
1008 d_mem->write_data8(0xb0000 + i, buffer[i]);
1012 memset(cvram, 0, 0x2000);
1013 memset(avram, 0, 0x2000);
1015 memset(cvram, 0, 0x1000);
1016 memset(kvram, 0, 0x1000);
1026 } else if(PC == 0xfffc9) {
1029 this->out_debug_log(_T("%6x\tCMOS BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);
1033 memcpy(cmos, cmos_t, sizeof(cmos_t));
1034 memcpy(cmos + CMOS_SIZE - sizeof(cmos_b), cmos_b, sizeof(cmos_b));
1035 } else if(AH == 5) {
1037 BX = cmos[0xa2] | (cmos[0xa3] << 8);
1038 } else if(AH == 10) {
1040 int block = AL * 10;
1041 int len = cmos[block + 6] | (cmos[block + 7] << 8);
1042 int dst = cmos[block + 8] | (cmos[block + 9] << 8);
1043 int src = DS * 16 + DI;
1044 for(int i = 0; i < len; i++) {
1045 cmos[dst++] = d_mem->read_data8(src++);
1047 } else if(AH == 11) {
1049 int block = AL * 10;
1050 int len = cmos[block + 6] | (cmos[block + 7] << 8);
1051 int src = cmos[block + 8] | (cmos[block + 9] << 8);
1052 int dst = DS * 16 + DI;
1053 for(int i = 0; i < len; i++) {
1054 d_mem->write_data8(dst++, cmos[src++]);
1056 } else if(AH == 20) {
1057 // check block header
1063 } else if(PC == 0xfffd3) {
1066 this->out_debug_log(_T("%6x\tWAIT BIOS: AH=%2x,AL=%2x,CX=%4x,DX=%4x,BX=%4x,DS=%2x,DI=%2x\n"), get_cpu_pc(0), AH,AL,CX,DX,BX,DS,DI);
1074 bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
1076 uint8_t *regs8 = (uint8_t *)regs;
1078 if(intnum == 0x93) {
1080 return bios_call_i86(0xfffc4, regs, sregs, ZeroFlag, CarryFlag);
1085 uint32_t BIOS::read_signal(int ch)
1087 // get access status
1089 for(int i = 0; i < MAX_DRIVE; i++) {
1093 access_fdd[i] = false;
1098 access_scsi = false;
1102 #define STATE_VERSION 3
1104 void BIOS::save_state(FILEIO* state_fio)
1106 state_fio->FputUint32(STATE_VERSION);
1107 state_fio->FputInt32(this_device_id);
1109 for(int i = 0; i < MAX_DRIVE; i++) {
1110 disk[i]->save_state(state_fio);
1112 state_fio->FputInt32(secnum);
1113 state_fio->FputInt32(timeout);
1116 bool BIOS::load_state(FILEIO* state_fio)
1118 if(state_fio->FgetUint32() != STATE_VERSION) {
1121 if(state_fio->FgetInt32() != this_device_id) {
1124 for(int i = 0; i < MAX_DRIVE; i++) {
1125 if(!disk[i]->load_state(state_fio)) {
1129 secnum = state_fio->FgetInt32();
1130 timeout = state_fio->FgetInt32();