|
|
| version 1.2, 2004/01/22 04:59:48 | version 1.14, 2004/03/12 18:19:57 |
|---|---|
| Line 6 | Line 6 |
| #include "sxsibios.h" | #include "sxsibios.h" |
| #include "scsicmd.h" | #include "scsicmd.h" |
| #include "sxsi.h" | #include "sxsi.h" |
| #include "timing.h" | |
| typedef REG8 (*SXSIFUNC)(UINT type, SXSIDEV sxsi); | typedef REG8 (*SXSIFUNC)(UINT type, SXSIDEV sxsi); |
| Line 46 static REG8 sxsi_pos(UINT type, SXSIDEV | Line 47 static REG8 sxsi_pos(UINT type, SXSIDEV |
| static REG8 sxsibios_write(UINT type, SXSIDEV sxsi) { | static REG8 sxsibios_write(UINT type, SXSIDEV sxsi) { |
| REG8 ret; | REG8 ret; |
| UINT32 addr; | |
| UINT size; | UINT size; |
| long pos; | long pos; |
| UINT32 addr; | |
| UINT r; | UINT r; |
| BYTE work[1024]; | BYTE work[1024]; |
| addr = (CPU_ES << 4) + CPU_BP; | |
| size = CPU_BX; | size = CPU_BX; |
| if (!size) { | if (!size) { |
| size = 0x10000; | size = 0x10000; |
| } | } |
| ret = sxsi_pos(type, sxsi, &pos); | ret = sxsi_pos(type, sxsi, &pos); |
| if (!ret) { | if (!ret) { |
| addr = (CPU_ES << 4) + CPU_BP; | |
| while(size) { | while(size) { |
| r = min(size, sxsi->size); | r = min(size, sxsi->size); |
| i286_memx_read(addr, work, r); | MEML_READ(addr, work, r); |
| ret = sxsi_write(CPU_AL, pos, work, r); | ret = sxsi_write(CPU_AL, pos, work, r); |
| if (ret >= 0x20) { | if (ret >= 0x20) { |
| break; | break; |
| } | } |
| size -= r; | |
| addr += r; | addr += r; |
| size -= r; | |
| pos++; | pos++; |
| } | } |
| } | } |
| Line 77 static REG8 sxsibios_write(UINT type, SX | Line 78 static REG8 sxsibios_write(UINT type, SX |
| static REG8 sxsibios_read(UINT type, SXSIDEV sxsi) { | static REG8 sxsibios_read(UINT type, SXSIDEV sxsi) { |
| REG8 ret; | REG8 ret; |
| UINT32 addr; | |
| UINT size; | UINT size; |
| long pos; | long pos; |
| UINT32 addr; | |
| UINT r; | UINT r; |
| BYTE work[1024]; | BYTE work[1024]; |
| addr = (CPU_ES << 4) + CPU_BP; | |
| size = CPU_BX; | size = CPU_BX; |
| if (!size) { | if (!size) { |
| size = 0x10000; | size = 0x10000; |
| } | } |
| ret = sxsi_pos(type, sxsi, &pos); | ret = sxsi_pos(type, sxsi, &pos); |
| if (!ret) { | if (!ret) { |
| addr = (CPU_ES << 4) + CPU_BP; | |
| while(size) { | while(size) { |
| r = min(size, sxsi->size); | r = min(size, sxsi->size); |
| ret = sxsi_read(CPU_AL, pos, work, r); | ret = sxsi_read(CPU_AL, pos, work, r); |
| if (ret >= 0x20) { | if (ret >= 0x20) { |
| break; | break; |
| } | } |
| i286_memx_write(addr, work, r); | MEML_WRITE(addr, work, r); |
| size -= r; | |
| addr += r; | addr += r; |
| size -= r; | |
| pos++; | pos++; |
| } | } |
| } | } |
| Line 111 static REG8 sxsibios_format(UINT type, S | Line 112 static REG8 sxsibios_format(UINT type, S |
| long pos; | long pos; |
| if (CPU_AH & 0x80) { | if (CPU_AH & 0x80) { |
| ret = 0xd0; | if (type == SXSIBIOS_SCSI) { // とりあえずSCSIのみ |
| UINT count; | |
| long posmax; | |
| count = timing_getcount(); // 時間を止める | |
| ret = 0; | |
| pos = 0; | |
| posmax = sxsi->surfaces * sxsi->cylinders; | |
| while(pos < posmax) { | |
| ret = sxsi_format(CPU_AL, pos * sxsi->sectors); | |
| if (ret) { | |
| break; | |
| } | |
| pos++; | |
| } | |
| timing_setcount(count); // 再開 | |
| } | |
| else { | |
| ret = 0xd0; | |
| } | |
| } | } |
| else { | else { |
| if (CPU_DL) { | if (CPU_DL) { |
| Line 177 static REG8 sasibios_sense(UINT type, SX | Line 196 static REG8 sasibios_sense(UINT type, SX |
| CPU_DH = sxsi->surfaces; | CPU_DH = sxsi->surfaces; |
| CPU_DL = sxsi->sectors; | CPU_DL = sxsi->sectors; |
| } | } |
| return(0x00); | return(0x0f); |
| } | } |
| } | } |
| Line 201 static const SXSIFUNC sasifunc[16] = { | Line 220 static const SXSIFUNC sasifunc[16] = { |
| REG8 sasibios_operate(void) { | REG8 sasibios_operate(void) { |
| SXSIDEV sxsi; | |
| UINT type; | UINT type; |
| SXSIDEV sxsi; | |
| sxsi = sxsi_getptr(CPU_AL); | if (pccore.hddif & PCHDD_IDE) { |
| if (sxsi == NULL) { | type = SXSIBIOS_IDE; |
| return(0x60); | |
| } | } |
| type = SXSIBIOS_IDE; | |
| #if defined(SUPPORT_SASI) | #if defined(SUPPORT_SASI) |
| if (pccore.hddif & PCHDD_SASI) { | else if (pccore.hddif & PCHDD_SASI) { |
| type = SXSIBIOS_SASI; | type = SXSIBIOS_SASI; |
| } | } |
| #endif | #endif |
| else { | |
| return(0x60); | |
| } | |
| sxsi = sxsi_getptr(CPU_AL); | |
| if (sxsi == NULL) { | |
| return(0x60); | |
| } | |
| return((*sasifunc[CPU_AH & 0x0f])(type, sxsi)); | return((*sasifunc[CPU_AH & 0x0f])(type, sxsi)); |
| } | } |
| Line 221 REG8 sasibios_operate(void) { | Line 245 REG8 sasibios_operate(void) { |
| // ---- scsi | // ---- scsi |
| #if defined(SUPPORT_SCSI) | #if defined(SUPPORT_SCSI) |
| static void scsibios_set(REG8 drv, REG8 sectors, REG8 surfaces, | |
| REG16 cylinders, REG16 size, BOOL hwsec) { | |
| BYTE *scsiinf; | |
| UINT16 inf; | |
| scsiinf = mem + 0x00460 + ((drv & 7) * 4); | |
| inf = 0; | |
| inf = (UINT16)(cylinders & 0xfff); | |
| if (cylinders >= 0x1000) { | |
| inf |= 0x4000; | |
| surfaces |= (cylinders >> 8) & 0xf0; | |
| } | |
| if (size == 512) { | |
| inf |= 0x1000; | |
| } | |
| else if (size == 1024) { | |
| inf |= 0x2000; | |
| } | |
| if (hwsec) { | |
| inf |= 0x8000; | |
| } | |
| scsiinf[0] = (UINT8)sectors; | |
| scsiinf[1] = (UINT8)surfaces; | |
| STOREINTELWORD(scsiinf + 2, inf); | |
| } | |
| static REG8 scsibios_init(UINT type, SXSIDEV sxsi) { | static REG8 scsibios_init(UINT type, SXSIDEV sxsi) { |
| UINT8 i; | UINT8 i; |
| UINT8 bit; | UINT8 bit; |
| UINT16 w; | |
| mem[MEMB_DISK_EQUIPS] = 0; | mem[MEMB_DISK_EQUIPS] = 0; |
| ZeroMemory(&mem[0x00460], 0x20); | ZeroMemory(&mem[0x00460], 0x20); |
| Line 233 static REG8 scsibios_init(UINT type, SXS | Line 285 static REG8 scsibios_init(UINT type, SXS |
| sxsi = sxsi_getptr((REG8)(0x20 + i)); | sxsi = sxsi_getptr((REG8)(0x20 + i)); |
| if ((sxsi) && (sxsi->fname[0])) { | if ((sxsi) && (sxsi->fname[0])) { |
| mem[MEMB_DISK_EQUIPS] |= bit; | mem[MEMB_DISK_EQUIPS] |= bit; |
| mem[0x00460+i*4] = sxsi->sectors; | scsibios_set(i, sxsi->sectors, sxsi->surfaces, |
| mem[0x00461+i*4] = sxsi->surfaces; | sxsi->cylinders, sxsi->size, TRUE); |
| switch(sxsi->size) { | |
| case 256: | |
| w = 0 << 12; | |
| break; | |
| case 512: | |
| w = 1 << 12; | |
| break; | |
| default: | |
| w = 2 << 12; | |
| break; | |
| } | |
| w |= 0xc000; | |
| w |= sxsi->cylinders; | |
| SETBIOSMEM16(0x00462+i*4, w); | |
| } | } |
| } | } |
| (void)type; | (void)type; |
| Line 259 static REG8 scsibios_init(UINT type, SXS | Line 295 static REG8 scsibios_init(UINT type, SXS |
| static REG8 scsibios_sense(UINT type, SXSIDEV sxsi) { | static REG8 scsibios_sense(UINT type, SXSIDEV sxsi) { |
| if (CPU_AH == 0x44) { | BYTE *scsiinf; |
| CPU_BX = 1; | |
| scsiinf = mem + 0x00460 + ((CPU_AL & 7) * 4); | |
| if (CPU_AH == 0x24) { | |
| scsibios_set(CPU_AL, CPU_DL, CPU_DH, CPU_CX, CPU_BX, FALSE); | |
| } | |
| else if (CPU_AH == 0x44) { | |
| CPU_BX = (scsiinf[3] & 0x80)?2:1; | |
| } | } |
| else if (CPU_AH == 0x84) { | else if (CPU_AH == 0x84) { |
| CPU_BX = sxsi->size; | CPU_DL = scsiinf[0]; |
| CPU_CX = sxsi->cylinders; | CPU_DH = scsiinf[1] & 0x0f; |
| CPU_DH = sxsi->surfaces; | CPU_CX = scsiinf[2] + ((scsiinf[3] & 0xf) << 8); |
| CPU_DL = sxsi->sectors; | if (scsiinf[3] & 0x40) { |
| CPU_CX += (scsiinf[1] & 0xf0) << 8; | |
| } | |
| CPU_BX = 256 << ((scsiinf[3] >> 4) & 3); | |
| } | } |
| (void)type; | (void)type; |
| (void)sxsi; | |
| return(0x00); | return(0x00); |
| } | } |
| Line 311 REG8 scsibios_operate(void) { | Line 357 REG8 scsibios_operate(void) { |
| SXSIDEV sxsi; | SXSIDEV sxsi; |
| if (!(pccore.hddif & PCHDD_SCSI)) { | |
| return(0x60); | |
| } | |
| sxsi = sxsi_getptr(CPU_AL); | sxsi = sxsi_getptr(CPU_AL); |
| if (sxsi == NULL) { | if (sxsi == NULL) { |
| return(0x60); | return(0x60); |
| Line 383 static void reg_load(UINT seg, UINT off) | Line 432 static void reg_load(UINT seg, UINT off) |
| B1BREG r; | B1BREG r; |
| i286_memstr_read(seg, off, &r, sizeof(r)); | MEML_READSTR(seg, off, &r, sizeof(r)); |
| CPU_FLAGL = i286_membyte_read(seg, off + 0x16); | CPU_FLAGL = MEML_READ8(seg, off + 0x16); |
| CPU_AX = LOADINTELWORD(r.r_ax); | CPU_AX = LOADINTELWORD(r.r_ax); |
| CPU_BX = LOADINTELWORD(r.r_bx); | CPU_BX = LOADINTELWORD(r.r_bx); |
| CPU_CX = LOADINTELWORD(r.r_cx); | CPU_CX = LOADINTELWORD(r.r_cx); |
| Line 409 static void reg_store(UINT seg, UINT off | Line 458 static void reg_store(UINT seg, UINT off |
| STOREINTELWORD(r.r_di, CPU_DI); | STOREINTELWORD(r.r_di, CPU_DI); |
| STOREINTELWORD(r.r_si, CPU_SI); | STOREINTELWORD(r.r_si, CPU_SI); |
| STOREINTELWORD(r.r_ds, CPU_DS); | STOREINTELWORD(r.r_ds, CPU_DS); |
| i286_memstr_write(seg, off, &r, sizeof(r)); | MEML_WRITESTR(seg, off, &r, sizeof(r)); |
| i286_membyte_write(seg, off + 0x16, CPU_FLAGL); | MEML_WRITE8(seg, off + 0x16, CPU_FLAGL); |
| } | } |
| #endif | #endif |