Added a few keyboard controller commands used by the AMI BIOS'es;
The port 92 handler in mem.c now flushes MMU cache when toggling the A20 gate; Added ability to reload previous disc after ejecting it; Fixed the START/STOP UNIT command for both SCSI and ATAPI; Applied mainline PCem commit: All XT models can now use 64kb RAM. Patch from ecksemmess .
This commit is contained in:
45
src/ide.c
45
src/ide.c
@@ -1819,9 +1819,9 @@ static void atapicommand(int ide_board)
|
||||
int real_pos;
|
||||
int track = 0;
|
||||
|
||||
#if 0
|
||||
pclog("ATAPI command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n",idebufferb[0],SCSISense.SenseKey,SCSISense.Asc,SCSISense.Ascq,ins,SCSISense.UnitAttention);
|
||||
|
||||
#if 0
|
||||
int CdbLength;
|
||||
for (CdbLength = 1; CdbLength < 12; CdbLength++)
|
||||
{
|
||||
@@ -2576,23 +2576,30 @@ static void atapicommand(int ide_board)
|
||||
break;
|
||||
|
||||
case GPCMD_START_STOP_UNIT:
|
||||
if ((idebufferb[4] != 2) && (idebufferb[4] != 3) && idebufferb[4])
|
||||
switch(idebufferb[4] & 3)
|
||||
{
|
||||
atapi_illegal_opcode(ide);
|
||||
break;
|
||||
}
|
||||
if (!idebufferb[4])
|
||||
{
|
||||
cdrom->stop();
|
||||
}
|
||||
else if (idebufferb[4]==2)
|
||||
{
|
||||
cdrom->eject();
|
||||
}
|
||||
else
|
||||
{
|
||||
cdrom->load();
|
||||
case 0: /* Stop the disc. */
|
||||
cdrom->stop();
|
||||
break;
|
||||
case 1: /* Start the disc and read the TOC. */
|
||||
cdrom->medium_changed(); /* This causes a TOC reload. */
|
||||
break;
|
||||
case 2: /* Eject the disc if possible. */
|
||||
cdrom->stop();
|
||||
#ifndef __unix
|
||||
win_cdrom_eject();
|
||||
#endif
|
||||
break;
|
||||
case 3: /* Load the disc (close tray). */
|
||||
#ifndef __unix
|
||||
win_cdrom_reload();
|
||||
#else
|
||||
cdrom->load();
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
ide->packetstatus = ATAPI_STATUS_COMPLETE;
|
||||
idecallback[ide_board]=50*IDE_TIME;
|
||||
break;
|
||||
@@ -2674,6 +2681,10 @@ static void atapicommand(int ide_board)
|
||||
atapi_out:
|
||||
idebufferb[size_idx] = idx - preamble_len;
|
||||
len=idx;
|
||||
if (len > alloc_length)
|
||||
{
|
||||
len = alloc_length;
|
||||
}
|
||||
|
||||
atapi_command_send_init(ide, temp_command, len, alloc_length);
|
||||
|
||||
@@ -2743,6 +2754,8 @@ atapi_out:
|
||||
atapi_illegal_opcode(ide);
|
||||
break;
|
||||
}
|
||||
|
||||
pclog("SCSI phase: %02X, length: %i\n", ide->secount, ide->cylinder);
|
||||
}
|
||||
|
||||
static void callnonreadcd(IDE *ide) /* Callabck for non-Read CD commands */
|
||||
|
@@ -44,9 +44,11 @@ struct
|
||||
int wantirq, wantirq12;
|
||||
uint8_t command;
|
||||
uint8_t status;
|
||||
uint8_t mem[0x20];
|
||||
uint8_t mem[0x100];
|
||||
uint8_t out;
|
||||
int out_new;
|
||||
uint8_t secr_phase;
|
||||
uint8_t mem_addr;
|
||||
|
||||
uint8_t input_port;
|
||||
uint8_t output_port;
|
||||
@@ -55,6 +57,9 @@ struct
|
||||
int key_wantdata;
|
||||
|
||||
int last_irq;
|
||||
|
||||
uint8_t last_scan_code;
|
||||
uint8_t default_mode;
|
||||
|
||||
void (*mouse_write)(uint8_t val, void *p);
|
||||
void *mouse_p;
|
||||
@@ -278,6 +283,7 @@ write_register:
|
||||
therefore, set to set 2. */
|
||||
mode |= 2;
|
||||
}
|
||||
keyboard_at.default_mode = (mode & 3);
|
||||
first_write = 0;
|
||||
// pclog("Keyboard set to scan code set %i, mode & 0x60 = 0x%02X\n", mode & 3, mode & 0x60);
|
||||
/* No else because in all other cases, translation is off, so we need to keep it
|
||||
@@ -286,6 +292,29 @@ write_register:
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xaf: /*AMI - set extended controller RAM*/
|
||||
if (keyboard_at.secr_phase == 0)
|
||||
{
|
||||
// pclog("Set extended controller RAM - phase 0 (bad)\n");
|
||||
goto bad_command;
|
||||
}
|
||||
else if (keyboard_at.secr_phase == 1)
|
||||
{
|
||||
// pclog("Set extended controller RAM - phase 1\n");
|
||||
keyboard_at.mem_addr = val;
|
||||
keyboard_at.want60 = 1;
|
||||
keyboard_at.secr_phase = 2;
|
||||
// pclog("Set extended controller RAM - starting phase 2\n");
|
||||
}
|
||||
else if (keyboard_at.secr_phase == 2)
|
||||
{
|
||||
// pclog("Set extended controller RAM - phase 2\n");
|
||||
keyboard_at.mem[keyboard_at.mem_addr] = val;
|
||||
keyboard_at.secr_phase = 0;
|
||||
// pclog("Set extended controller RAM - starting phase 0\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xcb: /*AMI - set keyboard mode*/
|
||||
break;
|
||||
|
||||
@@ -321,6 +350,7 @@ write_register:
|
||||
break;
|
||||
|
||||
default:
|
||||
bad_command:
|
||||
pclog("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command);
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
@@ -379,10 +409,21 @@ write_register:
|
||||
keyboard_at_adddata_keyboard(0xfe);
|
||||
break;
|
||||
|
||||
case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/
|
||||
case 0x82:
|
||||
break;
|
||||
|
||||
case 0xed: /*Set/reset LEDs*/
|
||||
keyboard_at.key_wantdata = 1;
|
||||
keyboard_at_adddata_keyboard(0xfa);
|
||||
break;
|
||||
|
||||
case 0xee: /*Diagnostic echo*/
|
||||
keyboard_at_adddata_keyboard(0xee);
|
||||
break;
|
||||
|
||||
case 0xef: /*NOP (No OPeration). Reserved for future use.*/
|
||||
break;
|
||||
|
||||
case 0xf0: /*Get/set scan code set*/
|
||||
keyboard_at.key_wantdata = 1;
|
||||
@@ -415,7 +456,8 @@ write_register:
|
||||
set3_all_break = 0;
|
||||
set3_all_repeat = 0;
|
||||
memset(set3_flags, 0, 272);
|
||||
mode = (mode & 0xFC) | 2;
|
||||
// mode = (mode & 0xFC) | 2;
|
||||
mode = (mode & 0xFC) | keyboard_at.default_mode;
|
||||
keyboard_at_adddata_keyboard(0xfa);
|
||||
break;
|
||||
|
||||
@@ -440,6 +482,10 @@ write_register:
|
||||
keyboard_at_adddata_keyboard(0xfa);
|
||||
break;
|
||||
|
||||
case 0xfe: /*Resend last scan code*/
|
||||
keyboard_at_adddata_keyboard(keyboard_at.last_scan_code);
|
||||
break;
|
||||
|
||||
case 0xff: /*Reset*/
|
||||
// pclog("KEYBOARD_AT: Set defaults\n");
|
||||
key_queue_start = key_queue_end = 0; /*Clear key queue*/
|
||||
@@ -565,6 +611,36 @@ write_register:
|
||||
keyboard_at.mem[0] &= ~0x10;
|
||||
break;
|
||||
|
||||
case 0xaf:
|
||||
switch(romset)
|
||||
{
|
||||
case ROM_AMI286:
|
||||
case ROM_AMI386SX:
|
||||
case ROM_AMI386DX_OPTI495:
|
||||
case ROM_MR386DX_OPTI495:
|
||||
case ROM_AMI486:
|
||||
case ROM_WIN486:
|
||||
case ROM_REVENGE:
|
||||
case ROM_PLATO:
|
||||
case ROM_ENDEAVOR:
|
||||
case ROM_THOR:
|
||||
case ROM_MRTHOR:
|
||||
/*Set extended controlled RAM*/
|
||||
keyboard_at.want60 = 1;
|
||||
keyboard_at.secr_phase = 1;
|
||||
// pclog("Set extended controller RAM - starting phase 1\n");
|
||||
break;
|
||||
default:
|
||||
/*Read keyboard version*/
|
||||
keyboard_at_adddata(0x00);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xb0 ... 0xbf: /*Set keyboard lines low (B0-B7) or high (B8-BF)*/
|
||||
keyboard_at_adddata(0x00);
|
||||
break;
|
||||
|
||||
case 0xc0: /*Read input port*/
|
||||
keyboard_at_adddata((keyboard_at.input_port & 0xf0) | 0x80);
|
||||
// keyboard_at_adddata(keyboard_at.input_port | 4);
|
||||
@@ -631,16 +707,6 @@ write_register:
|
||||
cpu_set_edx();
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/
|
||||
softresetx86(); /*Pulse reset!*/
|
||||
cpu_set_edx();
|
||||
break;
|
||||
|
||||
case 0xff: /*Pulse output port - but no pins selected - sent by MegaPC BIOS*/
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
pclog("Bad AT keyboard controller command %02X\n", val);
|
||||
@@ -690,12 +756,14 @@ void keyboard_at_reset()
|
||||
keyboard_at.status = STAT_LOCK | STAT_CD;
|
||||
keyboard_at.mem[0] = 0x11;
|
||||
mode = 0x02 | dtrans;
|
||||
keyboard_at.default_mode = 2;
|
||||
first_write = 1;
|
||||
keyboard_at.wantirq = 0;
|
||||
keyboard_at.output_port = 0xcf;
|
||||
keyboard_at.input_port = 0xb0;
|
||||
keyboard_at.out_new = -1;
|
||||
keyboard_at.last_irq = 0;
|
||||
keyboard_at.secr_phase = 0;
|
||||
|
||||
keyboard_at.key_wantdata = 0;
|
||||
|
||||
|
@@ -2169,6 +2169,7 @@ void port_92_reset()
|
||||
port_92_reg = 0;
|
||||
mem_a20_alt = 0;
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
uint32_t get_phys_virt,get_phys_phys;
|
||||
|
16
src/model.c
16
src/model.c
@@ -116,15 +116,15 @@ int AMSTRAD, AT, PCI, TANDY;
|
||||
MODEL models[] =
|
||||
{
|
||||
{"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"AMI XT clone", ROM_AMIXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser Turbo XT",ROM_LTXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser XT3", ROM_LXT3, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Phoenix XT clone", ROM_PXXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Juko XT clone", ROM_JUKOPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 128, 640, 64, xt_init, NULL},
|
||||
{"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"AMI XT clone", ROM_AMIXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser Turbo XT",ROM_LTXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"VTech Laser XT3", ROM_LXT3, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"Phoenix XT clone", ROM_PXXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"Juko XT clone", ROM_JUKOPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL},
|
||||
{"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device},
|
||||
{"Tandy 1000 HX", ROM_TANDY1000HX, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device},
|
||||
{"Tandy 1000 SL/2", ROM_TANDY1000SL2,{ "", cpus_8086, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL},
|
||||
|
@@ -40,7 +40,9 @@ BEGIN
|
||||
MENUITEM "&Enabled", IDM_CDROM_ENABLED
|
||||
MENUITEM "&SCSI", IDM_CDROM_SCSI
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Empty",IDM_CDROM_EMPTY
|
||||
MENUITEM "E&mpty",IDM_CDROM_EMPTY
|
||||
MENUITEM "&Reload previous disc",IDM_CDROM_RELOAD
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&ISO...",IDM_CDROM_ISO
|
||||
END
|
||||
POPUP "E&xtra IDE controllers"
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#define IDM_DISC_3_WP 40083
|
||||
#define IDM_DISC_4_WP 40084
|
||||
#define IDM_CDROM_ISO 40100
|
||||
#define IDM_CDROM_RELOAD 40101
|
||||
#define IDM_CDROM_EMPTY 40200
|
||||
#define IDM_CDROM_REAL 40200
|
||||
#define IDM_CDROM_ENABLED 40300
|
||||
|
@@ -1061,16 +1061,28 @@ SCSIOut:
|
||||
return;
|
||||
|
||||
case GPCMD_START_STOP_UNIT:
|
||||
if (cdb[4]!=2 && cdb[4]!=3 && cdb[4])
|
||||
switch(cdb[4] & 3)
|
||||
{
|
||||
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
|
||||
SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
|
||||
SCSICallback[id]=50*SCSI_TIME;
|
||||
break;
|
||||
case 0: /* Stop the disc. */
|
||||
cdrom->stop();
|
||||
break;
|
||||
case 1: /* Start the disc and read the TOC. */
|
||||
cdrom->medium_changed(); /* This causes a TOC reload. */
|
||||
break;
|
||||
case 2: /* Eject the disc if possible. */
|
||||
cdrom->stop();
|
||||
#ifndef __unix
|
||||
win_cdrom_eject();
|
||||
#endif
|
||||
break;
|
||||
case 3: /* Load the disc (close tray). */
|
||||
#ifndef __unix
|
||||
win_cdrom_reload();
|
||||
#else
|
||||
cdrom->load();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (!cdb[4]) cdrom->stop();
|
||||
else if (cdb[4]==2) cdrom->eject();
|
||||
else cdrom->load();
|
||||
|
||||
SCSIPhase = SCSI_PHASE_STATUS;
|
||||
SCSIStatus = SCSI_STATUS_OK;
|
||||
|
91
src/win.c
91
src/win.c
@@ -1312,6 +1312,73 @@ void video_toggle_option(HMENU hmenu, int *val, int id)
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
void win_cdrom_eject()
|
||||
{
|
||||
HMENU hmenu;
|
||||
hmenu=GetMenu(ghwnd);
|
||||
if (cdrom_drive == 0)
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
cdrom->exit();
|
||||
cdrom_close();
|
||||
cdrom_null_open(0);
|
||||
if (cdrom_enabled)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
SCSICDROM_Insert();
|
||||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
cdrom_drive=0;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED);
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
void win_cdrom_reload()
|
||||
{
|
||||
HMENU hmenu;
|
||||
hmenu=GetMenu(ghwnd);
|
||||
int new_cdrom_drive;
|
||||
if ((cdrom_drive == old_cdrom_drive) || (old_cdrom_drive == 0))
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
if (old_cdrom_drive == 200)
|
||||
{
|
||||
iso_open(iso_path);
|
||||
if (cdrom_enabled)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
SCSICDROM_Insert();
|
||||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
// CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
cdrom_drive = 200;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED);
|
||||
saveconfig();
|
||||
}
|
||||
else
|
||||
{
|
||||
new_cdrom_drive = old_cdrom_drive;
|
||||
ioctl_open(new_cdrom_drive);
|
||||
if (cdrom_enabled)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
SCSICDROM_Insert();
|
||||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
cdrom_drive = new_cdrom_drive;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED);
|
||||
saveconfig();
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HMENU hmenu;
|
||||
@@ -1750,12 +1817,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
break;
|
||||
|
||||
case IDM_CDROM_EMPTY:
|
||||
/* if (!cdrom_enabled)
|
||||
{
|
||||
if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK)
|
||||
break;
|
||||
} */
|
||||
// if ((cdrom_drive == 0) && cdrom_enabled)
|
||||
if (cdrom_drive == 0)
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
@@ -1770,23 +1831,17 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
SCSICDROM_Insert();
|
||||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
// CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
cdrom_drive=0;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED);
|
||||
saveconfig();
|
||||
/* if (!cdrom_enabled)
|
||||
{
|
||||
pause = 1;
|
||||
Sleep(100);
|
||||
cdrom_enabled = 1;
|
||||
saveconfig();
|
||||
resetpchard();
|
||||
pause = 0;
|
||||
} */
|
||||
break;
|
||||
|
||||
case IDM_CDROM_RELOAD:
|
||||
win_cdrom_reload();
|
||||
break;
|
||||
|
||||
case IDM_CDROM_ISO:
|
||||
if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",iso_path))
|
||||
{
|
||||
|
Reference in New Issue
Block a user