2 TOSHIBA J-3100GT Emulator 'eJ-3100GT'
3 TOSHIBA J-3100SL Emulator 'eJ-3100SL'
5 Author : Takeda.Toshiya
15 #define PHASE_SELECT 1
16 #define PHASE_COMMAND 2
21 #define PHASE_STATUS 7
22 //#define PHASE_MESSAGE 8
24 #define STATUS_REQ 0x01
25 #define STATUS_IXD 0x02
26 #define STATUS_CXD 0x04
27 #define STATUS_BSY 0x08
28 #define STATUS_DRQ 0x10
29 #define STATUS_IRQ 0x20
30 //#define STATUS_MSG 0
32 #define EVENT_COMMAND 0
33 #define EVENT_STATUS 1
37 void SASI::initialize()
39 // open hard drive images
40 for(int i = 0; i < 2; i++) {
41 drive[i].fio = new FILEIO();
42 if(!drive[i].fio->Fopen(create_local_path(_T("HDD%d.DAT"), i + 1), FILEIO_READ_WRITE_BINARY)) {
46 drive[i].access = false;
52 for(int i = 0; i < 2; i++) {
53 if(drive[i].fio != NULL) {
54 drive[i].fio->Fclose();
63 memset(buffer, 0, sizeof(buffer));
64 memset(cmd, 0, sizeof(cmd));
65 memset(status_buf, 0, sizeof(status_buf));
80 void SASI::write_io8(uint32_t addr, uint32_t data)
85 if(phase == PHASE_COMMAND) {
86 cmd[cmd_ptr++] = data;
90 } else if(phase == PHASE_C2) {
91 if(++status_ptr == 10) {
94 } else if(phase == PHASE_WRITE) {
95 buffer[buffer_ptr++] = data;
96 if(buffer_ptr == 256) {
119 phase = PHASE_SELECT;
120 register_event(this, EVENT_COMMAND, 10, false, NULL);
129 uint32_t SASI::read_io8(uint32_t addr)
136 if(phase == PHASE_READ) {
137 val = buffer[buffer_ptr++];
138 if(buffer_ptr == 256) {
151 } else if(phase == PHASE_SENSE) {
152 val = status_buf[status_ptr++];
153 if(status_ptr == 4) {
156 } else if(phase == PHASE_STATUS) {
157 // val = error ? 0x02 : status;
158 // phase = PHASE_MESSAGE;
159 val = (error ? 2 : 0) | (unit << 5);
161 // } else if(phase == PHASE_MESSAGE) {
162 // phase = PHASE_FREE;
167 val = status_irq_drq;
168 status_irq_drq &= ~STATUS_IRQ;
169 if(phase != PHASE_FREE) {
172 if(phase > PHASE_SELECT) {
175 if(phase == PHASE_COMMAND) {
178 if(phase == PHASE_SENSE) {
181 if(phase == PHASE_READ) {
184 if(phase == PHASE_STATUS) {
185 val |= STATUS_IXD | STATUS_CXD;
187 // if(phase == PHASE_MESSAGE) {
188 // val |= STATUS_IXD | STATUS_CXD | STATUS_MSG;
195 void SASI::write_dma_io8(uint32_t addr, uint32_t data)
197 write_io8(0x1f0, data);
200 uint32_t SASI::read_dma_io8(uint32_t addr)
202 return read_io8(0x1f0);
205 uint32_t SASI::read_signal(int ch)
208 uint32_t stat = (drive[0].access ? 0x10 : 0) | (drive[1].access ? 0x20 : 0);
209 drive[0].access = drive[1].access = false;
213 void SASI::event_callback(int event_id, int err)
215 if(event_id == EVENT_COMMAND) {
216 phase = PHASE_COMMAND;
218 } else if(event_id == EVENT_STATUS) {
219 phase = PHASE_STATUS;
223 d_pic->write_signal(SIG_I8259_IR5 | SIG_I8259_CHIP0, 1, 1);
225 d_pic->write_signal(SIG_I8259_IR6 | SIG_I8259_CHIP1, 1, 1);
228 status_irq_drq |= STATUS_IRQ;
232 void SASI::check_cmd()
234 unit = (cmd[1] >> 5) & 1;
239 if(drive[unit].fio != NULL) {
249 if(drive[unit].fio != NULL) {
259 // request sense status
261 status_buf[0] = error;
262 status_buf[1] = (uint8_t)((unit << 5) | ((sector >> 16) & 0x1f));
263 status_buf[2] = (uint8_t)(sector >> 8);
264 status_buf[3] = (uint8_t)sector;
277 sector = cmd[1] & 0x1f;
278 sector = (sector << 8) | cmd[2];
279 sector = (sector << 8) | cmd[3];
290 sector = cmd[1] & 0x1f;
291 sector = (sector << 8) | cmd[2];
292 sector = (sector << 8) | cmd[3];
295 if(blocks != 0 && seek(unit)) {
304 sector = cmd[1] & 0x1f;
305 sector = (sector << 8) | cmd[2];
306 sector = (sector << 8) | cmd[3];
309 if(blocks != 0 && seek(unit)) {
312 memset(buffer, 0, sizeof(buffer));
319 sector = cmd[1] & 0x1f;
320 sector = (sector << 8) | cmd[2];
321 sector = (sector << 8) | cmd[3];
339 void SASI::set_status(uint8_t err)
342 register_event(this, EVENT_STATUS, 10, false, NULL);
345 void SASI::set_drq(bool flag)
348 status_irq_drq |= STATUS_DRQ;
350 status_irq_drq &= ~STATUS_DRQ;
354 bool SASI::seek(int drv)
356 memset(buffer, 0, sizeof(buffer));
358 if(drive[drv & 1].fio == NULL) {
361 if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
364 if(drive[drv & 1].fio->Fread(buffer, 256, 1) != 1) {
367 drive[drv & 1].access = true;
371 bool SASI::flush(int drv)
373 if(drive[drv & 1].fio == NULL) {
376 if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
379 if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {
382 drive[drv & 1].access = true;
386 bool SASI::format(int drv)
388 if(drive[drv & 1].fio == NULL) {
391 if(drive[drv & 1].fio->Fseek(sector * 256, FILEIO_SEEK_SET) != 0) {
395 memset(buffer, 0, sizeof(buffer));
396 for(int i = 0; i < 33; i++) {
397 if(drive[drv & 1].fio->Fwrite(buffer, 256, 1) != 1) {
400 drive[drv & 1].access = true;