OSDN Git Service

[VM][WIP] Use namespace to devices per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr50 / bios.cpp
index cb0f9ed..34a2d85 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "bios.h"
 #include "../disk.h"
+#include "../harddisk.h"
 
 // regs
 #define AX     regs[0]
@@ -77,6 +78,8 @@
 
 #define BLOCK_SIZE     512
 
+namespace FMR50 {
+       
 static const int iotable[][2] = {
 #ifdef _FMR30
        {0x0100, 0x19}, // pic
@@ -262,40 +265,22 @@ void BIOS::initialize()
 {
        // to increment timeout counter
        register_frame_event(this);
-       
-       // check scsi drives
-       FILEIO* fio = new FILEIO();
-       for(int i = 0; i < MAX_SCSI; i++) {
-               if(fio->Fopen(create_local_path(_T("SCSI%d.DAT"), i), FILEIO_READ_WRITE_BINARY)) {
-                       uint32_t file_size = fio->FileLength();
-                       if(file_size == 0) {
-                               // from ../scsi_hdd.cpp
-                               #define SCSI_BUFFER_SIZE        0x10000
-                               uint32_t remain = (file_size = 0x2800000); // 40MB
-                               void *tmp = calloc(1, SCSI_BUFFER_SIZE);
-                               while(remain > 0) {
-                                       uint32_t length = min(remain, SCSI_BUFFER_SIZE);
-                                       fio->Fwrite(tmp, length, 1);
-                                       remain -= length;
-                               }
-                               free(tmp);
-                               #undef SCSI_BUFFER_SIZE
-                       }
-                       scsi_blocks[i] = file_size / BLOCK_SIZE;
-                       fio->Fclose();
-               } else {
-                       scsi_blocks[i] = 0;
-               }
-       }
-       delete fio;
 }
 
 void BIOS::reset()
 {
        for(int i = 0; i < MAX_DRIVE; i++) {
                access_fdd[i] = false;
+               drive_mode1[i] = 0x03;  // MFM, 2HD, 1024B
+               drive_mode2[i] = 0x208; // 2 Heads, 8 sectors
+       }
+       for(int i = 0; i < USE_HARD_DISK; i++) {
+               if(harddisk[i] != NULL && harddisk[i]->mounted()) {
+                       scsi_blocks[i] = harddisk[i]->sector_size * harddisk[i]->sector_num / BLOCK_SIZE;
+               } else {
+                       scsi_blocks[i] = 0;
+               }
        }
-       access_scsi = false;
        secnum = 1;
        timeout = 0;
 }
@@ -305,7 +290,7 @@ void BIOS::event_frame()
        timeout++;
 }
 
-bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
+bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
 {
        uint8_t *regs8 = (uint8_t *)regs;
        int drv = AL & 0xf;
@@ -314,12 +299,43 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
        if(PC == 0xfffc4) {
                // disk bios
 #ifdef _DEBUG_LOG
-               emu->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);
+               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);
 #endif
-               if(AH == 2) {
+               if(AH == 0) {
+                       // set drive mode
+                       if(!(drv < MAX_DRIVE)) {
+                               AH = 2;
+                               *CarryFlag = 1;
+                               return true;
+                       }
+                       AH = 0;
+                       drive_mode1[drv] = DL;
+                       drive_mode2[drv] = BX;
+                       // ToDo: Trap when not resiztered disk[drv].
+                       switch(DL & 0x30) {
+                       case 0x00: disk[drv]->drive_type = DRIVE_TYPE_2HD; break;
+                       case 0x10: disk[drv]->drive_type = DRIVE_TYPE_2DD; break;
+                       case 0x20: disk[drv]->drive_type = DRIVE_TYPE_2D ; break;
+                       }
+                       *CarryFlag = 0;
+                       return true;
+               } else if(AH == 1) {
+                       // get drive mode
+                       if(!(drv < MAX_DRIVE)) {
+                               AH = 2;
+                               *CarryFlag = 1;
+                               return true;
+                       }
+                       AH = 0;
+                       DL = drive_mode1[drv];
+                       BX = drive_mode2[drv];
+                       *CarryFlag = 0;
+                       return true;
+               } else if(AH == 2) {
                        // drive status
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0x80;
                                        CX = ERR_FDD_NOTREADY;
@@ -327,17 +343,32 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                        return true;
                                }
                                AH = 0;
-                               DL = 4;
+                               if(disk[drv]->get_track(0, 0) && disk[drv]->get_sector(0, 0, 0)) {
+                                       switch(disk[drv]->sector_size.sd) {
+                                       case 128: AH = 0; break;
+                                       case 256: AH = 1; break;
+                                       case 512: AH = 2; break;
+                                       default : AH = 3; break; // 1024
+                                       }
+                               }
+                               DL = 0;
                                if(disk[drv]->write_protected) {
                                        DL |= 2;
                                }
+                               if(disk[drv]->two_side) {
+                                       DL |= 4;
+                               }
+//                             if(disk[drv]->drive_type == DRIVE_TYPE_2D || disk[drv]->drive_type == DRIVE_TYPE_2DD) {
+                               if(disk[drv]->media_type == MEDIA_TYPE_2D || disk[drv]->media_type == MEDIA_TYPE_2DD) {
+                                       DL |= 0x10;
+                               }
                                CX = 0;
                                *CarryFlag = 0;
                                return true;
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
@@ -358,6 +389,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        // restore/seek
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0x80;
                                        CX = ERR_FDD_NOTREADY;
@@ -371,7 +403,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
@@ -389,6 +421,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        // read sectors
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0x80;
                                        CX = ERR_FDD_NOTREADY;
@@ -402,7 +435,13 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int sct = DL;
                                while(BX > 0) {
                                        // search sector
-                                       disk[drv]->get_track(trk, hed);
+                                       // ToDo: Trap when not resiztered disk[drv].
+                                       if(!disk[drv]->get_track(trk, hed)) {
+                                               AH = 0x80;
+                                               CX = ERR_FDD_NOTFOUND;
+                                               *CarryFlag = 1;
+                                               return true;
+                                       }
                                        access_fdd[drv] = true;
                                        secnum = sct;
                                        if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
@@ -453,37 +492,33 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
                                        return true;
                                }
-                               FILEIO* fio = new FILEIO();
-                               if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_BINARY)) {
+                               if(!(harddisk[drv] != NULL && harddisk[drv]->mounted())) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTREADY;
                                        *CarryFlag = 1;
-                                       delete fio;
                                        return true;
                                }
                                // get params
                                int ofs = DS * 16 + DI;
                                int block = (CL << 16) | DX;
-                               fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);
+                               long position = block * BLOCK_SIZE;
                                while(BX > 0) {
                                        // check block
-                                       access_scsi = true;
                                        if(!(block++ < scsi_blocks[drv])) {
                                                AH = 0x80;
                                                CX = ERR_SCSI_PARAMERROR;
                                                *CarryFlag = 1;
-                                               fio->Fclose();
-                                               delete fio;
                                                return true;
                                        }
                                        // data transfer
-                                       fio->Fread(buffer, BLOCK_SIZE, 1);
+                                       harddisk[drv]->read_buffer(position, BLOCK_SIZE, buffer);
+                                       position += BLOCK_SIZE;
                                        for(int i = 0; i < BLOCK_SIZE; i++) {
                                                d_mem->write_data8(ofs++, buffer[i]);
                                        }
@@ -492,8 +527,6 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                AH = 0;
                                CX = 0;
                                *CarryFlag = 0;
-                               fio->Fclose();
-                               delete fio;
                                return true;
                        }
                        AH = 2;
@@ -521,8 +554,14 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int hed = DH & 1;
                                int sct = DL;
                                while(BX > 0) {
+                                       // ToDo: Trap when not resiztered disk[drv].
                                        // search sector
-                                       disk[drv]->get_track(trk, hed);
+                                       if(!disk[drv]->get_track(trk, hed)) {
+                                               AH = 0x80;
+                                               CX = ERR_FDD_NOTFOUND;
+                                               *CarryFlag = 1;
+                                               return true;
+                                       }
                                        access_fdd[drv] = true;
                                        secnum = sct;
                                        if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
@@ -562,47 +601,41 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
                                        return true;
                                }
-                               FILEIO* fio = new FILEIO();
-                               if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_WRITE_BINARY)) {
+                               if(!(harddisk[drv] != NULL && harddisk[drv]->mounted())) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTREADY;
                                        *CarryFlag = 1;
-                                       delete fio;
                                        return true;
                                }
                                // get params
                                int ofs = DS * 16 + DI;
                                int block = (CL << 16) | DX;
-                               fio->Fseek(block * BLOCK_SIZE, FILEIO_SEEK_SET);
+                               long position = block * BLOCK_SIZE;
                                while(BX > 0) {
                                        // check block
-                                       access_scsi = true;
                                        if(!(block++ < scsi_blocks[drv])) {
                                                AH = 0x80;
                                                CX = ERR_SCSI_PARAMERROR;
                                                *CarryFlag = 1;
-                                               fio->Fclose();
-                                               delete fio;
                                                return true;
                                        }
                                        // data transfer
                                        for(int i = 0; i < BLOCK_SIZE; i++) {
                                                buffer[i] = d_mem->read_data8(ofs++);
                                        }
-                                       fio->Fwrite(buffer, BLOCK_SIZE, 1);
+                                       harddisk[drv]->write_buffer(position, BLOCK_SIZE, buffer);
+                                       position += BLOCK_SIZE;
                                        BX--;
                                }
                                AH = 0;
                                CX = 0;
                                *CarryFlag = 0;
-                               fio->Fclose();
-                               delete fio;
                                return true;
                        }
                        AH = 2;
@@ -624,7 +657,13 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int sct = DL;
                                while(BX > 0) {
                                        // search sector
-                                       disk[drv]->get_track(trk, hed);
+                                       // ToDo: Trap when not resiztered disk[drv].
+                                       if(!disk[drv]->get_track(trk, hed)) {
+                                               AH = 0x80;
+                                               CX = ERR_FDD_NOTFOUND;
+                                               *CarryFlag = 1;
+                                               return true;
+                                       }
                                        access_fdd[drv] = true;
                                        secnum = sct;
                                        if(!disk[drv]->get_sector(trk, hed, sct - 1)) {
@@ -665,7 +704,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
@@ -675,7 +714,6 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int block = (CL << 16) | DX;
                                while(BX > 0) {
                                        // check block
-                                       access_scsi = true;
                                        if(!(block++ < scsi_blocks[drv])) {
                                                AH = 0x80;
                                                CX = ERR_SCSI_PARAMERROR;
@@ -702,6 +740,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        // read id
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0x80;
                                        CX = ERR_FDD_NOTREADY;
@@ -713,7 +752,12 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int trk = CX;
                                int hed = DH & 1;
                                // search sector
-                               disk[drv]->get_track(trk, hed);
+                               if(!disk[drv]->get_track(trk, hed)) {
+                                       AH = 0x80;
+                                       CX = ERR_FDD_NOTFOUND;
+                                       *CarryFlag = 1;
+                                       return true;
+                               }
                                access_fdd[drv] = true;
                                if(++secnum > disk[drv]->sector_num.sd) {
                                        secnum = 1;
@@ -747,6 +791,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                        // format track
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0x80;
                                        CX = ERR_FDD_NOTREADY;
@@ -758,6 +803,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                int trk = CX;
                                int hed = DH & 1;
                                // format track
+                               // ToDo: Trap when not resiztered disk[drv].
                                disk[drv]->format_track(trk, hed);
                                access_fdd[drv] = true;
                                bool id_written = false;
@@ -774,6 +820,7 @@ bool BIOS::bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t
                                                if(!id_written) {
                                                        // insert new sector with data crc error
 write_id:
+                                                       // ToDo: Trap when not resiztered disk[drv].
                                                        id_written = true;
                                                        sector_found = false;
                                                        uint8_t c = disk[drv]->track[index - 4];
@@ -795,12 +842,14 @@ write_id:
                                        } else if(id_written) {
                                                if(sector_found) {
                                                        // sector data
+                                                       // ToDo: Trap when not resiztered disk[drv].
                                                        if(sector_index < sector_length) {
                                                                disk[drv]->sector[sector_index] = datareg;
                                                        }
                                                        sector_index++;
                                                } else if(datareg == 0xf8 || datareg == 0xfb) {
                                                        // data mark
+                                                       // ToDo: Trap when not resiztered disk[drv].
                                                        disk[drv]->set_deleted(datareg == 0xf8);
                                                        sector_found = true;
                                                }
@@ -825,6 +874,7 @@ write_id:
                        // disk change ???
                        if((AL & 0xf0) == 0x20) {
                                // floppy
+                               // ToDo: Trap when not resiztered disk[drv].
                                if(!(drv < MAX_DRIVE && disk[drv]->inserted)) {
                                        AH = 0;
                                        CX = 0;
@@ -841,7 +891,7 @@ write_id:
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 3; // ???
                                        CX = 0;
                                        *CarryFlag = 1;
@@ -867,7 +917,7 @@ write_id:
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0x80;
                                        CX = ERR_SCSI_NOTCONNECTED;
                                        *CarryFlag = 1;
@@ -892,7 +942,7 @@ write_id:
                        }
                        if((AL & 0xf0) == 0xb0) {
                                // scsi
-                               if(!(drv < MAX_SCSI && scsi_blocks[drv])) {
+                               if(!(drv < USE_HARD_DISK && scsi_blocks[drv])) {
                                        AH = 0;
                                        CX = 0x200;     // ???
                                        *CarryFlag = 0;
@@ -941,13 +991,17 @@ write_id:
                        return true;
                } else if(AH == 0x81) {
                        // pseudo bios: boot from fdd #0
+                       // ToDo: Trap when not resiztered disk[drv].
                        *ZeroFlag = (timeout > (int)(FRAMES_PER_SEC * 4));
                        if(!disk[0]->inserted) {
                                *CarryFlag = 1;
                                return true;
                        }
                        // load ipl
-                       disk[0]->get_track(0, 0);
+                       if(!disk[0]->get_track(0, 0)) {
+                               *CarryFlag = 1;
+                               return true;
+                       }
                        access_fdd[0] = true;
                        if(!disk[0]->get_sector(0, 0, 0)) {
                                *CarryFlag = 1;
@@ -987,17 +1041,12 @@ write_id:
                                *CarryFlag = 1;
                                return true;
                        }
-                       FILEIO* fio = new FILEIO();
-                       if(!fio->Fopen(create_local_path(_T("SCSI%d.DAT"), drv), FILEIO_READ_BINARY)) {
+                       if(!(harddisk[drv] != NULL && harddisk[drv]->mounted())) {
                                *CarryFlag = 1;
-                               delete fio;
                                return true;
                        }
                        // load ipl
-                       access_scsi = true;
-                       fio->Fread(buffer, BLOCK_SIZE * 4, 1);
-                       fio->Fclose();
-                       delete fio;
+                       harddisk[drv]->read_buffer(0, BLOCK_SIZE * 4, buffer);
                        // check ipl
                        if(!(buffer[0] == 'I' && buffer[1] == 'P' && buffer[2] == 'L' && buffer[3] == IPL_ID)) {
                                *CarryFlag = 1;
@@ -1026,7 +1075,7 @@ write_id:
        } else if(PC == 0xfffc9) {
                // cmos
 #ifdef _DEBUG_LOG
-               emu->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);
+               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);
 #endif
                if(AH == 0) {
                        // init cmos
@@ -1063,7 +1112,7 @@ write_id:
        } else if(PC == 0xfffd3) {
                // wait
 #ifdef _DEBUG_LOG
-               emu->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);
+               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);
 #endif
                *CarryFlag = 0;
                return true;
@@ -1077,7 +1126,7 @@ bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t*
        
        if(intnum == 0x93) {
                // disk bios
-               return bios_call_i86(0xfffc4, regs, sregs, ZeroFlag, CarryFlag);
+               return bios_call_far_i86(0xfffc4, regs, sregs, ZeroFlag, CarryFlag);
        }
        return false;
 }
@@ -1086,48 +1135,44 @@ uint32_t BIOS::read_signal(int ch)
 {
        // get access status
        uint32_t stat = 0;
-       for(int i = 0; i < MAX_DRIVE; i++) {
-               if(access_fdd[i]) {
-                       stat |= 1 << i;
+       if(ch == 0) {
+               for(int i = 0; i < MAX_DRIVE; i++) {
+                       if(access_fdd[i]) {
+                               stat |= 1 << i;
+                       }
+                       access_fdd[i] = false;
                }
-               access_fdd[i] = false;
        }
-       if(access_scsi) {
-               stat |= 0x10;
-       }
-       access_scsi = false;
        return stat;
 }
 
-#define STATE_VERSION  3
+#define STATE_VERSION  5
 
-void BIOS::save_state(FILEIO* state_fio)
+bool BIOS::process_state(FILEIO* state_fio, bool loading)
 {
-       state_fio->FputUint32(STATE_VERSION);
-       state_fio->FputInt32(this_device_id);
-       
-       for(int i = 0; i < MAX_DRIVE; i++) {
-               disk[i]->save_state(state_fio);
-       }
-       state_fio->FputInt32(secnum);
-       state_fio->FputInt32(timeout);
-}
-
-bool BIOS::load_state(FILEIO* state_fio)
-{
-       if(state_fio->FgetUint32() != STATE_VERSION) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
-       if(state_fio->FgetInt32() != this_device_id) {
+       if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
        for(int i = 0; i < MAX_DRIVE; i++) {
-               if(!disk[i]->load_state(state_fio)) {
+               if(!disk[i]->process_state(state_fio, loading)) {
                        return false;
                }
        }
-       secnum = state_fio->FgetInt32();
-       timeout = state_fio->FgetInt32();
+       state_fio->StateInt32(secnum);
+       state_fio->StateInt32(timeout);
+       state_fio->StateBuffer(drive_mode1, sizeof(drive_mode1), 1);
+       //state_fio->StateBuffer(drive_mode2, sizeof(drive_mode2), 1);
+       for(int i = 0; i < (sizeof(drive_mode2) / sizeof(uint16_t)); i++) {
+               state_fio->StateUint16(drive_mode2[i]);
+       }
+       //state_fio->StateBuffer(scsi_blocks, sizeof(scsi_blocks), 1);
+       for(int i = 0; i < (sizeof(scsi_blocks) / sizeof(int)); i++) {
+               state_fio->StateInt32(scsi_blocks[i]);
+       }
        return true;
 }
 
+}