OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz2500 / mz1e30.cpp
index d37d304..0bcc176 100644 (file)
-/*\r
-       SHARP MZ-2500 Emulator 'EmuZ-2500'\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2004.09.10 -\r
-\r
-       [ MZ-1E30 (SASI) ]\r
-*/\r
-\r
-#include "mz1e30.h"\r
-#include "../../fileio.h"\r
-\r
-#define PHASE_FREE     0\r
-#define PHASE_SELECT   1\r
-#define PHASE_COMMAND  2\r
-#define PHASE_C2       3\r
-#define PHASE_SENSE    4\r
-#define PHASE_READ     5\r
-#define PHASE_WRITE    6\r
-#define PHASE_STATUS   7\r
-#define PHASE_MESSAGE  8\r
-\r
-#define STATUS_IXD     0x04\r
-#define STATUS_CXD     0x08\r
-#define STATUS_MSG     0x10\r
-#define STATUS_BSY     0x20\r
-#define STATUS_REQ     0x80\r
-\r
-#define STATUS_IRQ     0\r
-#define STATUS_DRQ     0\r
-\r
-void MZ1E30::initialize()\r
-{\r
-       // rom file\r
-       FILEIO* fio = new FILEIO();\r
-       if(fio->Fopen(emu->bios_path(_T("MZ-1E30.ROM")), FILEIO_READ_BINARY) ||\r
-          fio->Fopen(emu->bios_path(_T("SASI.ROM")), FILEIO_READ_BINARY) ||\r
-          fio->Fopen(emu->bios_path(_T("FILE.ROM")), FILEIO_READ_BINARY)) {\r
-               fio->Fseek(0, FILEIO_SEEK_END);\r
-               if((rom_size = fio->Ftell()) > 0x1000000) {\r
-                       rom_size = 0x1000000;\r
-               }\r
-               rom_buffer = (uint8*)malloc(rom_size);\r
-               \r
-               fio->Fseek(0, FILEIO_SEEK_SET);\r
-               fio->Fread(rom_buffer, rom_size, 1);\r
-               fio->Fclose();\r
-       } else {\r
-               rom_size = 0;\r
-               rom_buffer = (uint8*)malloc(1);\r
-       }\r
-       delete fio;\r
-       rom_address = 0;\r
-       \r
-       // open hard drive images\r
-       for(int i = 0; i < 2; i++) {\r
-               _TCHAR file_name[_MAX_PATH];\r
-               _stprintf_s(file_name, _MAX_PATH, _T("HDD%d.DAT"), i + 1);\r
-               \r
-               drive[i].fio = new FILEIO();\r
-               if(!drive[i].fio->Fopen(emu->bios_path(file_name), FILEIO_READ_WRITE_BINARY)) {\r
-                       delete drive[i].fio;\r
-                       drive[i].fio = NULL;\r
-               }\r
-               drive[i].access = false;\r
-       }\r
-       \r
-       // initialize sasi interface\r
-       memset(buffer, 0, sizeof(buffer));\r
-       memset(cmd, 0, sizeof(cmd));\r
-       memset(status_buf, 0, sizeof(status_buf));\r
-       \r
-       phase = PHASE_FREE;\r
-       sector = 0;\r
-       blocks = 0;\r
-       cmd_ptr = 0;\r
-       unit = 0;\r
-       buffer_ptr = 0;\r
-       status = 0;\r
-       status_irq_drq = 0;\r
-       error = 0;\r
-       status_ptr = 0;\r
-}\r
-\r
-void MZ1E30::release()\r
-{\r
-       for(int i = 0; i < 2; i++) {\r
-               if(drive[i].fio != NULL) {\r
-                       drive[i].fio->Fclose();\r
-                       delete drive[i].fio;\r
-               }\r
-       }\r
-       if(rom_buffer != NULL) {\r
-               free(rom_buffer);\r
-       }\r
-}\r
-\r
-void MZ1E30::write_io8(uint32 addr, uint32 data)\r
-{\r
-       switch(addr & 0xff) {\r
-       case 0xa4:\r
-               // data\r
-               if(phase == PHASE_COMMAND) {\r
-                       cmd[cmd_ptr++] = data;\r
-                       if(cmd_ptr == 6) {\r
-                               check_cmd();\r
-                       }\r
-               } else if(phase == PHASE_C2) {\r
-                       if(++status_ptr == 10) {\r
-                               set_status(0);\r
-                       }\r
-               } else if(phase == PHASE_WRITE) {\r
-                       buffer[buffer_ptr++] = data;\r
-                       if(buffer_ptr == 256) {\r
-                               flush(unit);\r
-                               if(--blocks) {\r
-                                       sector++;\r
-                                       buffer_ptr = 0;\r
-                                       if(!seek(unit)) {\r
-                                               set_status(0x0f);\r
-                                               set_drq(false);\r
-                                       }\r
-                               } else {\r
-                                       set_status(0);\r
-                                       set_drq(false);\r
-                               }\r
-                       }\r
-               }\r
-               datareg = data;\r
-               break;\r
-       case 0xa5:\r
-               // command\r
-               if(data == 0x00) {\r
-                       if(phase == PHASE_SELECT) {\r
-                               phase = PHASE_COMMAND;\r
-                               cmd_ptr = 0;\r
-                       }\r
-               } else if(data == 0x20) {\r
-                       if(datareg & 1) {\r
-                               phase = PHASE_SELECT;\r
-                       } else {\r
-                               phase = PHASE_FREE;\r
-                       }\r
-               }\r
-               break;\r
-       case 0xa8:\r
-               // rom file\r
-               rom_address = ((addr & 0xff00) << 8) | (data << 8) | (rom_address & 0x0000ff);\r
-               break;\r
-       }\r
-}\r
-\r
-uint32 MZ1E30::read_io8(uint32 addr)\r
-{\r
-       uint32 val = 0;\r
-       \r
-       switch(addr & 0xff) {\r
-       case 0xa4:\r
-               // data\r
-               if(phase == PHASE_READ) {\r
-                       val = buffer[buffer_ptr++];\r
-                       if(buffer_ptr == 256) {\r
-                               if(--blocks) {\r
-                                       sector++;\r
-                                       buffer_ptr = 0;\r
-                                       if(!seek(unit)) {\r
-                                               set_status(0x0f);\r
-                                               set_drq(false);\r
-                                       }\r
-                               } else {\r
-                                       set_status(0);\r
-                                       set_drq(false);\r
-                               }\r
-                       }\r
-               } else if(phase == PHASE_SENSE) {\r
-                       val = status_buf[status_ptr++];\r
-                       if(status_ptr == 4) {\r
-                               set_status(0);\r
-                       }\r
-               } else if(phase == PHASE_STATUS) {\r
-                       val = error ? 0x02 : status;\r
-                       phase = PHASE_MESSAGE;\r
-               } else if(phase == PHASE_MESSAGE) {\r
-                       phase = PHASE_FREE;\r
-               }\r
-               return val;\r
-       case 0xa5:\r
-               // status\r
-               val = status_irq_drq;\r
-               status_irq_drq &= ~STATUS_IRQ;\r
-               if(phase != PHASE_FREE) {\r
-                       val |= STATUS_BSY;\r
-               }\r
-               if(phase > PHASE_SELECT) {\r
-                       val |= STATUS_REQ;\r
-               }\r
-               if(phase == PHASE_COMMAND) {\r
-                       val |= STATUS_CXD;\r
-               }\r
-               if(phase == PHASE_SENSE) {\r
-                       val |= STATUS_IXD;\r
-               }\r
-               if(phase == PHASE_READ) {\r
-                       val |= STATUS_IXD;\r
-               }\r
-               if(phase == PHASE_STATUS) {\r
-                       val |= STATUS_IXD | STATUS_CXD;\r
-               }\r
-               if(phase == PHASE_MESSAGE) {\r
-                       val |= STATUS_IXD | STATUS_CXD | STATUS_MSG;\r
-               }\r
-               return val;\r
-       case 0xa9:\r
-               // rom file\r
-               rom_address = (rom_address & 0xffff00) | ((addr & 0xff00) >> 8);\r
-               if(rom_address < rom_size) {\r
-                       return rom_buffer[rom_address];\r
-               }\r
-               break;\r
-       }\r
-       return 0xff;\r
-}\r
-\r
-void MZ1E30::write_dma_io8(uint32 addr, uint32 data)\r
-{\r
-       write_io8(0xa4, data);\r
-}\r
-\r
-uint32 MZ1E30::read_dma_io8(uint32 addr)\r
-{\r
-       return read_io8(0xa4);\r
-}\r
-\r
-uint32 MZ1E30::read_signal(int ch)\r
-{\r
-       // get access status\r
-       uint32 stat = (drive[0].access ? 0x10 : 0) | (drive[1].access ? 0x20 : 0);\r
-       drive[0].access = drive[1].access = false;\r
-       return stat;\r
-}\r
-\r
-void MZ1E30::check_cmd()\r
-{\r
-       unit = (cmd[1] >> 5) & 1;\r
-       \r
-       switch(cmd[0]) {\r
-       case 0x00:\r
-               // test drive ready\r
-               if(drive[unit].fio != NULL) {\r
-                       status = 0x00;\r
-                       set_status(0x00);\r
-               } else {\r
-                       status = 0x02;\r
-                       set_status(0x7f);\r
-               }\r
-               break;\r
-       case 0x01:\r
-               // recalib\r
-               if(drive[unit].fio != NULL) {\r
-                       sector = 0;\r
-                       status = 0x00;\r
-                       set_status(0x00);\r
-               } else {\r
-                       status = 0x02;\r
-                       set_status(0x7f);\r
-               }\r
-               break;\r
-       case 0x03:\r
-               // request sense status\r
-               phase = PHASE_SENSE;\r
-               status_buf[0] = error;\r
-               status_buf[1] = (uint8)((unit << 5) | ((sector >> 16) & 0x1f));\r
-               status_buf[2] = (uint8)(sector >> 8);\r
-               status_buf[3] = (uint8)sector;\r
-               error = 0;\r
-               status = 0x00;\r
-               status_ptr = 0;\r
-               break;\r
-       case 0x04:\r
-               // format drive\r
-               sector = 0;\r
-               status = 0x00;\r
-               set_status(0x0f);\r
-               break;\r
-       case 0x06:\r
-               // format track\r
-               sector = cmd[1] & 0x1f;\r
-               sector = (sector << 8) | cmd[2];\r
-               sector = (sector << 8) | cmd[3];\r
-               blocks = cmd[4];\r
-               status = 0;\r
-               if(format(unit)) {\r
-                       set_status(0);\r
-               } else {\r
-                       set_status(0x0f);\r
-               }\r
-               break;\r
-       case 0x08:\r
-               // read data\r
-               sector = cmd[1] & 0x1f;\r
-               sector = (sector << 8) | cmd[2];\r
-               sector = (sector << 8) | cmd[3];\r
-               blocks = cmd[4];\r
-               status = 0;\r
-               if(blocks != 0 && seek(unit)) {\r
-                       phase = PHASE_READ;\r
-                       buffer_ptr = 0;\r
-                       set_drq(true);\r
-               } else {\r
-                       set_status(0x0f);\r
-               }\r
-               break;\r
-       case 0x0a:\r
-               sector = cmd[1] & 0x1f;\r
-               sector = (sector << 8) | cmd[2];\r
-               sector = (sector << 8) | cmd[3];\r
-               blocks = cmd[4];\r
-               status = 0;\r
-               if(blocks != 0 && seek(unit)) {\r
-                       phase = PHASE_WRITE;\r
-                       buffer_ptr = 0;\r
-                       memset(buffer, 0, sizeof(buffer));\r
-                       set_drq(true);\r
-               } else {\r
-                       set_status(0x0f);\r
-               }\r
-               break;\r
-       case 0x0b:\r
-               sector = cmd[1] & 0x1f;\r
-               sector = (sector << 8) | cmd[2];\r
-               sector = (sector << 8) | cmd[3];\r
-               blocks = cmd[4];\r
-               status = 0;\r
-               set_status(0);\r
-               break;\r
-       case 0xc2:\r
-               phase = PHASE_C2;\r
-               status_ptr = 0;\r
-               status = 0;\r
-//             error = 0;\r
-               break;\r
-       default:\r
-               // unknown\r
-               set_status(0);\r
-               break;\r
-       }\r
-}\r
-\r
-void MZ1E30::set_status(uint8 err)\r
-{\r
-       error = err;\r
-#if 1\r
-       phase = PHASE_STATUS;\r
-       // raise irq\r
-       status_irq_drq |= STATUS_IRQ;\r
-#else\r
-       vm->register_event(this, 0, 10, false, NULL);\r
-#endif\r
-}\r
-\r
-void MZ1E30::event_callback(int event_id, int err)\r
-{\r
-#if 0\r
-       phase = PHASE_STATUS;\r
-       // raise irq\r
-       status_irq_drq |= STATUS_IRQ;\r
-#endif\r
-}\r
-\r
-void MZ1E30::set_drq(bool flag)\r
-{\r
-       if(flag) {\r
-               status_irq_drq |= STATUS_DRQ;\r
-       } else {\r
-               status_irq_drq &= ~STATUS_DRQ;\r
-       }\r
-}\r
-\r
-bool MZ1E30::seek(int drv)\r
-{\r
-       memset(buffer, 0, sizeof(buffer));\r
-       \r
-       if(drive[drv & 1].fio == NULL) {\r
-               return false;\r
-       }\r
-       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {\r
-               return false;\r
-       }\r
-       if(drive[drv & 1].fio->Fread(buffer, 256, 1) != 1) {\r
-               return false;\r
-       }\r
-       drive[drv & 1].access = true;\r
-       return true;\r
-}\r
-\r
-bool MZ1E30::flush(int drv)\r
-{\r
-       if(drive[drv & 1].fio == NULL) {\r
-               return false;\r
-       }\r
-       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {\r
-               return false;\r
-       }\r
-       if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {\r
-               return false;\r
-       }\r
-       drive[drv & 1].access = true;\r
-       return true;\r
-}\r
-\r
-bool MZ1E30::format(int drv)\r
-{\r
-       if(drive[drv & 1].fio == NULL) {\r
-               return false;\r
-       }\r
-       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {\r
-               return false;\r
-       }\r
-       // format 33 blocks\r
-       memset(buffer, 0, sizeof(buffer));\r
-       for(int i = 0; i < 33; i++) {\r
-               if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {\r
-                       return false;\r
-               }\r
-               drive[drv & 1].access = true;\r
-       }\r
-       return true;\r
-}\r
-\r
-#define STATE_VERSION  1\r
-\r
-void MZ1E30::save_state(FILEIO* state_fio)\r
-{\r
-       state_fio->FputUint32(STATE_VERSION);\r
-       state_fio->FputInt32(this_device_id);\r
-       \r
-       state_fio->FputUint32(rom_address);\r
-       state_fio->Fwrite(buffer, sizeof(buffer), 1);\r
-       state_fio->FputInt32(phase);\r
-       state_fio->FputInt32(sector);\r
-       state_fio->FputInt32(blocks);\r
-       state_fio->Fwrite(cmd, sizeof(cmd), 1);\r
-       state_fio->FputInt32(cmd_ptr);\r
-       state_fio->FputInt32(unit);\r
-       state_fio->FputInt32(buffer_ptr);\r
-       state_fio->FputUint8(status);\r
-       state_fio->FputUint8(status_irq_drq);\r
-       state_fio->FputUint8(error);\r
-       state_fio->Fwrite(status_buf, sizeof(status_buf), 1);\r
-       state_fio->FputInt32(status_ptr);\r
-       state_fio->FputUint8(datareg);\r
-}\r
-\r
-bool MZ1E30::load_state(FILEIO* state_fio)\r
-{\r
-       if(state_fio->FgetUint32() != STATE_VERSION) {\r
-               return false;\r
-       }\r
-       if(state_fio->FgetInt32() != this_device_id) {\r
-               return false;\r
-       }\r
-       rom_address = state_fio->FgetUint32();\r
-       state_fio->Fread(buffer, sizeof(buffer), 1);\r
-       phase = state_fio->FgetInt32();\r
-       sector = state_fio->FgetInt32();\r
-       blocks = state_fio->FgetInt32();\r
-       state_fio->Fread(cmd, sizeof(cmd), 1);\r
-       cmd_ptr = state_fio->FgetInt32();\r
-       unit = state_fio->FgetInt32();\r
-       buffer_ptr = state_fio->FgetInt32();\r
-       status = state_fio->FgetUint8();\r
-       status_irq_drq = state_fio->FgetUint8();\r
-       error = state_fio->FgetUint8();\r
-       state_fio->Fread(status_buf, sizeof(status_buf), 1);\r
-       status_ptr = state_fio->FgetInt32();\r
-       datareg = state_fio->FgetUint8();\r
-       return true;\r
-}\r
-\r
+/*
+       SHARP MZ-2500 Emulator 'EmuZ-2500'
+
+       Author : Takeda.Toshiya
+       Date   : 2004.09.10 -
+
+       [ MZ-1E30 (SASI) ]
+*/
+
+#include "mz1e30.h"
+#include "../../fileio.h"
+
+#define PHASE_FREE     0
+#define PHASE_SELECT   1
+#define PHASE_COMMAND  2
+#define PHASE_C2       3
+#define PHASE_SENSE    4
+#define PHASE_READ     5
+#define PHASE_WRITE    6
+#define PHASE_STATUS   7
+#define PHASE_MESSAGE  8
+
+#define STATUS_IXD     0x04
+#define STATUS_CXD     0x08
+#define STATUS_MSG     0x10
+#define STATUS_BSY     0x20
+#define STATUS_REQ     0x80
+
+#define STATUS_IRQ     0
+#define STATUS_DRQ     0
+
+void MZ1E30::initialize()
+{
+       // rom file
+       FILEIO* fio = new FILEIO();
+       if(fio->Fopen(emu->bios_path(_T("MZ-1E30.ROM")), FILEIO_READ_BINARY) ||
+          fio->Fopen(emu->bios_path(_T("SASI.ROM")), FILEIO_READ_BINARY) ||
+          fio->Fopen(emu->bios_path(_T("FILE.ROM")), FILEIO_READ_BINARY)) {
+               fio->Fseek(0, FILEIO_SEEK_END);
+               if((rom_size = fio->Ftell()) > 0x1000000) {
+                       rom_size = 0x1000000;
+               }
+               rom_buffer = (uint8*)malloc(rom_size);
+               
+               fio->Fseek(0, FILEIO_SEEK_SET);
+               fio->Fread(rom_buffer, rom_size, 1);
+               fio->Fclose();
+       } else {
+               rom_size = 0;
+               rom_buffer = (uint8*)malloc(1);
+       }
+       delete fio;
+       rom_address = 0;
+       
+       // open hard drive images
+       for(int i = 0; i < 2; i++) {
+               _TCHAR file_name[_MAX_PATH];
+               _stprintf_s(file_name, _MAX_PATH, _T("HDD%d.DAT"), i + 1);
+               
+               drive[i].fio = new FILEIO();
+               if(!drive[i].fio->Fopen(emu->bios_path(file_name), FILEIO_READ_WRITE_BINARY)) {
+                       delete drive[i].fio;
+                       drive[i].fio = NULL;
+               }
+               drive[i].access = false;
+       }
+       
+       // initialize sasi interface
+       memset(buffer, 0, sizeof(buffer));
+       memset(cmd, 0, sizeof(cmd));
+       memset(status_buf, 0, sizeof(status_buf));
+       
+       phase = PHASE_FREE;
+       sector = 0;
+       blocks = 0;
+       cmd_ptr = 0;
+       unit = 0;
+       buffer_ptr = 0;
+       status = 0;
+       status_irq_drq = 0;
+       error = 0;
+       status_ptr = 0;
+}
+
+void MZ1E30::release()
+{
+       for(int i = 0; i < 2; i++) {
+               if(drive[i].fio != NULL) {
+                       drive[i].fio->Fclose();
+                       delete drive[i].fio;
+               }
+       }
+       if(rom_buffer != NULL) {
+               free(rom_buffer);
+       }
+}
+
+void MZ1E30::write_io8(uint32 addr, uint32 data)
+{
+       switch(addr & 0xff) {
+       case 0xa4:
+               // data
+               if(phase == PHASE_COMMAND) {
+                       cmd[cmd_ptr++] = data;
+                       if(cmd_ptr == 6) {
+                               check_cmd();
+                       }
+               } else if(phase == PHASE_C2) {
+                       if(++status_ptr == 10) {
+                               set_status(0);
+                       }
+               } else if(phase == PHASE_WRITE) {
+                       buffer[buffer_ptr++] = data;
+                       if(buffer_ptr == 256) {
+                               flush(unit);
+                               if(--blocks) {
+                                       sector++;
+                                       buffer_ptr = 0;
+                                       if(!seek(unit)) {
+                                               set_status(0x0f);
+                                               set_drq(false);
+                                       }
+                               } else {
+                                       set_status(0);
+                                       set_drq(false);
+                               }
+                       }
+               }
+               datareg = data;
+               break;
+       case 0xa5:
+               // command
+               if(data == 0x00) {
+                       if(phase == PHASE_SELECT) {
+                               phase = PHASE_COMMAND;
+                               cmd_ptr = 0;
+                       }
+               } else if(data == 0x20) {
+                       if(datareg & 1) {
+                               phase = PHASE_SELECT;
+                       } else {
+                               phase = PHASE_FREE;
+                       }
+               }
+               break;
+       case 0xa8:
+               // rom file
+               rom_address = ((addr & 0xff00) << 8) | (data << 8) | (rom_address & 0x0000ff);
+               break;
+       }
+}
+
+uint32 MZ1E30::read_io8(uint32 addr)
+{
+       uint32 val = 0;
+       
+       switch(addr & 0xff) {
+       case 0xa4:
+               // data
+               if(phase == PHASE_READ) {
+                       val = buffer[buffer_ptr++];
+                       if(buffer_ptr == 256) {
+                               if(--blocks) {
+                                       sector++;
+                                       buffer_ptr = 0;
+                                       if(!seek(unit)) {
+                                               set_status(0x0f);
+                                               set_drq(false);
+                                       }
+                               } else {
+                                       set_status(0);
+                                       set_drq(false);
+                               }
+                       }
+               } else if(phase == PHASE_SENSE) {
+                       val = status_buf[status_ptr++];
+                       if(status_ptr == 4) {
+                               set_status(0);
+                       }
+               } else if(phase == PHASE_STATUS) {
+                       val = error ? 0x02 : status;
+                       phase = PHASE_MESSAGE;
+               } else if(phase == PHASE_MESSAGE) {
+                       phase = PHASE_FREE;
+               }
+               return val;
+       case 0xa5:
+               // status
+               val = status_irq_drq;
+               status_irq_drq &= ~STATUS_IRQ;
+               if(phase != PHASE_FREE) {
+                       val |= STATUS_BSY;
+               }
+               if(phase > PHASE_SELECT) {
+                       val |= STATUS_REQ;
+               }
+               if(phase == PHASE_COMMAND) {
+                       val |= STATUS_CXD;
+               }
+               if(phase == PHASE_SENSE) {
+                       val |= STATUS_IXD;
+               }
+               if(phase == PHASE_READ) {
+                       val |= STATUS_IXD;
+               }
+               if(phase == PHASE_STATUS) {
+                       val |= STATUS_IXD | STATUS_CXD;
+               }
+               if(phase == PHASE_MESSAGE) {
+                       val |= STATUS_IXD | STATUS_CXD | STATUS_MSG;
+               }
+               return val;
+       case 0xa9:
+               // rom file
+               rom_address = (rom_address & 0xffff00) | ((addr & 0xff00) >> 8);
+               if(rom_address < rom_size) {
+                       return rom_buffer[rom_address];
+               }
+               break;
+       }
+       return 0xff;
+}
+
+void MZ1E30::write_dma_io8(uint32 addr, uint32 data)
+{
+       write_io8(0xa4, data);
+}
+
+uint32 MZ1E30::read_dma_io8(uint32 addr)
+{
+       return read_io8(0xa4);
+}
+
+uint32 MZ1E30::read_signal(int ch)
+{
+       // get access status
+       uint32 stat = (drive[0].access ? 0x10 : 0) | (drive[1].access ? 0x20 : 0);
+       drive[0].access = drive[1].access = false;
+       return stat;
+}
+
+void MZ1E30::check_cmd()
+{
+       unit = (cmd[1] >> 5) & 1;
+       
+       switch(cmd[0]) {
+       case 0x00:
+               // test drive ready
+               if(drive[unit].fio != NULL) {
+                       status = 0x00;
+                       set_status(0x00);
+               } else {
+                       status = 0x02;
+                       set_status(0x7f);
+               }
+               break;
+       case 0x01:
+               // recalib
+               if(drive[unit].fio != NULL) {
+                       sector = 0;
+                       status = 0x00;
+                       set_status(0x00);
+               } else {
+                       status = 0x02;
+                       set_status(0x7f);
+               }
+               break;
+       case 0x03:
+               // request sense status
+               phase = PHASE_SENSE;
+               status_buf[0] = error;
+               status_buf[1] = (uint8)((unit << 5) | ((sector >> 16) & 0x1f));
+               status_buf[2] = (uint8)(sector >> 8);
+               status_buf[3] = (uint8)sector;
+               error = 0;
+               status = 0x00;
+               status_ptr = 0;
+               break;
+       case 0x04:
+               // format drive
+               sector = 0;
+               status = 0x00;
+               set_status(0x0f);
+               break;
+       case 0x06:
+               // format track
+               sector = cmd[1] & 0x1f;
+               sector = (sector << 8) | cmd[2];
+               sector = (sector << 8) | cmd[3];
+               blocks = cmd[4];
+               status = 0;
+               if(format(unit)) {
+                       set_status(0);
+               } else {
+                       set_status(0x0f);
+               }
+               break;
+       case 0x08:
+               // read data
+               sector = cmd[1] & 0x1f;
+               sector = (sector << 8) | cmd[2];
+               sector = (sector << 8) | cmd[3];
+               blocks = cmd[4];
+               status = 0;
+               if(blocks != 0 && seek(unit)) {
+                       phase = PHASE_READ;
+                       buffer_ptr = 0;
+                       set_drq(true);
+               } else {
+                       set_status(0x0f);
+               }
+               break;
+       case 0x0a:
+               sector = cmd[1] & 0x1f;
+               sector = (sector << 8) | cmd[2];
+               sector = (sector << 8) | cmd[3];
+               blocks = cmd[4];
+               status = 0;
+               if(blocks != 0 && seek(unit)) {
+                       phase = PHASE_WRITE;
+                       buffer_ptr = 0;
+                       memset(buffer, 0, sizeof(buffer));
+                       set_drq(true);
+               } else {
+                       set_status(0x0f);
+               }
+               break;
+       case 0x0b:
+               sector = cmd[1] & 0x1f;
+               sector = (sector << 8) | cmd[2];
+               sector = (sector << 8) | cmd[3];
+               blocks = cmd[4];
+               status = 0;
+               set_status(0);
+               break;
+       case 0xc2:
+               phase = PHASE_C2;
+               status_ptr = 0;
+               status = 0;
+//             error = 0;
+               break;
+       default:
+               // unknown
+               set_status(0);
+               break;
+       }
+}
+
+void MZ1E30::set_status(uint8 err)
+{
+       error = err;
+#if 1
+       phase = PHASE_STATUS;
+       // raise irq
+       status_irq_drq |= STATUS_IRQ;
+#else
+       vm->register_event(this, 0, 10, false, NULL);
+#endif
+}
+
+void MZ1E30::event_callback(int event_id, int err)
+{
+#if 0
+       phase = PHASE_STATUS;
+       // raise irq
+       status_irq_drq |= STATUS_IRQ;
+#endif
+}
+
+void MZ1E30::set_drq(bool flag)
+{
+       if(flag) {
+               status_irq_drq |= STATUS_DRQ;
+       } else {
+               status_irq_drq &= ~STATUS_DRQ;
+       }
+}
+
+bool MZ1E30::seek(int drv)
+{
+       memset(buffer, 0, sizeof(buffer));
+       
+       if(drive[drv & 1].fio == NULL) {
+               return false;
+       }
+       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
+               return false;
+       }
+       if(drive[drv & 1].fio->Fread(buffer, 256, 1) != 1) {
+               return false;
+       }
+       drive[drv & 1].access = true;
+       return true;
+}
+
+bool MZ1E30::flush(int drv)
+{
+       if(drive[drv & 1].fio == NULL) {
+               return false;
+       }
+       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
+               return false;
+       }
+       if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {
+               return false;
+       }
+       drive[drv & 1].access = true;
+       return true;
+}
+
+bool MZ1E30::format(int drv)
+{
+       if(drive[drv & 1].fio == NULL) {
+               return false;
+       }
+       if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
+               return false;
+       }
+       // format 33 blocks
+       memset(buffer, 0, sizeof(buffer));
+       for(int i = 0; i < 33; i++) {
+               if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {
+                       return false;
+               }
+               drive[drv & 1].access = true;
+       }
+       return true;
+}
+
+#define STATE_VERSION  1
+
+void MZ1E30::save_state(FILEIO* state_fio)
+{
+       state_fio->FputUint32(STATE_VERSION);
+       state_fio->FputInt32(this_device_id);
+       
+       state_fio->FputUint32(rom_address);
+       state_fio->Fwrite(buffer, sizeof(buffer), 1);
+       state_fio->FputInt32(phase);
+       state_fio->FputInt32(sector);
+       state_fio->FputInt32(blocks);
+       state_fio->Fwrite(cmd, sizeof(cmd), 1);
+       state_fio->FputInt32(cmd_ptr);
+       state_fio->FputInt32(unit);
+       state_fio->FputInt32(buffer_ptr);
+       state_fio->FputUint8(status);
+       state_fio->FputUint8(status_irq_drq);
+       state_fio->FputUint8(error);
+       state_fio->Fwrite(status_buf, sizeof(status_buf), 1);
+       state_fio->FputInt32(status_ptr);
+       state_fio->FputUint8(datareg);
+}
+
+bool MZ1E30::load_state(FILEIO* state_fio)
+{
+       if(state_fio->FgetUint32() != STATE_VERSION) {
+               return false;
+       }
+       if(state_fio->FgetInt32() != this_device_id) {
+               return false;
+       }
+       rom_address = state_fio->FgetUint32();
+       state_fio->Fread(buffer, sizeof(buffer), 1);
+       phase = state_fio->FgetInt32();
+       sector = state_fio->FgetInt32();
+       blocks = state_fio->FgetInt32();
+       state_fio->Fread(cmd, sizeof(cmd), 1);
+       cmd_ptr = state_fio->FgetInt32();
+       unit = state_fio->FgetInt32();
+       buffer_ptr = state_fio->FgetInt32();
+       status = state_fio->FgetUint8();
+       status_irq_drq = state_fio->FgetUint8();
+       error = state_fio->FgetUint8();
+       state_fio->Fread(status_buf, sizeof(status_buf), 1);
+       status_ptr = state_fio->FgetInt32();
+       datareg = state_fio->FgetUint8();
+       return true;
+}
+