i86.c: Fix shift timing

[mess] pc.c: MT 05069 Fix MC1502 floppy interface
[mess] pc.c: Work around pcjx bios bug and fix pcjr nmi (nw)
[mess] pc.c: Support pcjx floppies
[mess] pc_t1t.c: Add support for pcjx text mode and fix pcjr 4bpp mode
This commit is contained in:
cracyc 2012-12-29 04:25:31 +00:00
parent 8624385a24
commit 015d064c2e
7 changed files with 183 additions and 35 deletions

View File

@ -279,7 +279,7 @@ static const struct i80x86_timing i80286_cycles =
2, 2, 7, 7, /* INC/DEC */
2, 2, 7, 7, /* NEG/NOT */
2, 5, 0, /* reg shift/rotate */
2, 5, 1, /* reg shift/rotate */
7, 8, 1, /* m8 shift/rotate */
7, 8, 1, /* m16 shift/rotate */

View File

@ -139,7 +139,7 @@ static void PREFIX86(_rotate_shift_Byte)(i8086_state *cpustate, unsigned ModRM,
else
{
int tmpcf = CF;
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m8_bit;
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m8_bit * count);
switch (ModRM & 0x38)
{
@ -333,7 +333,7 @@ static void PREFIX86(_rotate_shift_Word)(i8086_state *cpustate, unsigned ModRM,
else
{
int tmpcf = CF;
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + timing.rot_reg_bit : timing.rot_m8_base + timing.rot_m16_bit;
ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m16_bit * count);
switch (ModRM & 0x38)
{

View File

@ -466,11 +466,12 @@ static ADDRESS_MAP_START(ibmpcjr_io, AS_IO, 8, pc_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START(ibmpcjx_map, AS_PROGRAM, 8, pc_state )
AM_RANGE(0x80000, 0x9ffff) AM_ROM AM_REGION("kanji",0)
AM_RANGE(0x80000, 0xb7fff) AM_ROM AM_REGION("kanji",0)
AM_IMPORT_FROM( ibmpcjr_map )
ADDRESS_MAP_END
static ADDRESS_MAP_START(ibmpcjx_io, AS_IO, 8, pc_state )
AM_RANGE(0x01ff, 0x01ff) AM_READWRITE(pcjx_port_1ff_r, pcjx_port_1ff_w)
AM_IMPORT_FROM( ibmpcjr_io )
ADDRESS_MAP_END
@ -858,12 +859,26 @@ static const pc_lpt_interface pc_lpt_config =
DEVCB_CPU_INPUT_LINE("maincpu", 0)
};
static const floppy_interface mc1502_floppy_interface =
{
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
FLOPPY_STANDARD_5_25_DSHD,
LEGACY_FLOPPY_OPTIONS_NAME(pc),
"floppy_5_25",
NULL
};
FLOPPY_FORMATS_MEMBER( pc_state::floppy_formats )
FLOPPY_PC_FORMAT
FLOPPY_FORMATS_END
static SLOT_INTERFACE_START( ibmpc_floppies )
SLOT_INTERFACE( "525dd", FLOPPY_525_DD )
SLOT_INTERFACE( "35dd", FLOPPY_35_DD )
SLOT_INTERFACE_END
SLOT_INTERFACE_START(ibm5150_com)
@ -1333,6 +1348,10 @@ static MACHINE_CONFIG_DERIVED( ibmpcjx, ibmpcjr )
MCFG_CPU_PROGRAM_MAP(ibmpcjx_map)
MCFG_CPU_IO_MAP(ibmpcjx_io)
MCFG_DEVICE_REMOVE("upd765:0");
MCFG_FLOPPY_DRIVE_ADD("upd765:0", ibmpc_floppies, "35dd", 0, pc_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("upd765:1", ibmpc_floppies, "35dd", 0, pc_state::floppy_formats)
MCFG_GFXDECODE(ibmpcjx)
MACHINE_CONFIG_END
@ -1373,7 +1392,7 @@ static MACHINE_CONFIG_START( mc1502, pc_state )
MCFG_CASSETTE_ADD( CASSETTE_TAG, mc1502_cassette_interface ) // has no motor control
MCFG_FD1793_ADD( "vg93", default_wd17xx_interface_2_drives )
MCFG_FLOPPY_DRIVE_ADD(FLOPPY_0, ibmpc_floppies, "525dd", 0, pc_state::floppy_formats)
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mc1502_floppy_interface)
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
@ -1863,17 +1882,24 @@ ROM_END
ROM_START( ibmpcjx )
ROM_REGION(0x100000,"maincpu", ROMREGION_ERASEFF)
ROM_DEFAULT_BIOS("unk")
ROM_SYSTEM_BIOS( 0, "5601jda", "5601jda" )
ROMX_LOAD("5601jda.bin", 0xf0000, 0x10000, CRC(b1e12366) SHA1(751feb16b985aa4f1ec1437493ff77e2ebd5e6a6), ROM_BIOS(1))
ROMX_LOAD("basicjx.rom", 0xe8000, 0x08000, NO_DUMP, ROM_BIOS(1)) // boot fails due of this.
ROM_SYSTEM_BIOS( 1, "unk", "unk" )
ROMX_LOAD("ipljx.rom", 0xe0000, 0x20000, CRC(36a7b2de) SHA1(777db50c617725e149bca9b18cf51ce78f6dc548), ROM_BIOS(2))
ROM_FILL(0xff195, 1, 0x20) // the bios has a bug that causes an interrupt
ROM_FILL(0xff196, 1, 0x06) // to arrive before a flag is set causing the boot to hang
ROM_FILL(0xff197, 1, 0x84) // technically this should be fixed in the PIC by delaying
ROM_FILL(0xff198, 1, 0x04) // sending an irq after the mask is changed but there is
ROM_FILL(0xff199, 1, 0xe6) // a strong possiblility that will cause problems with later
ROM_FILL(0xff19a, 1, 0x21) // faster x86 machines.
ROM_REGION(0x08100,"gfx1", 0) //TODO: needs a different charset
ROM_LOAD("cga.chr", 0x00000, 0x01000, BAD_DUMP CRC(42009069) SHA1(ed08559ce2d7f97f68b9f540bddad5b6295294dd)) // from an unknown clone cga card
ROM_REGION(0x20000,"kanji", 0)
ROM_LOAD("kanji.rom", 0x00000, 0x20000, BAD_DUMP CRC(a313f241) SHA1(c2a4ea7eb38c5ad51e6482abca8f836a2c06e17a)) // hand-made rom
ROM_REGION(0x38000,"kanji", 0)
ROM_LOAD("kanji.rom", 0x00000, 0x38000, BAD_DUMP CRC(eaa6e3c3) SHA1(35554587d02d947fae8446964b1886fff5c9d67f)) // hand-made rom
ROM_END
#ifdef UNUSED_DEFINITION

View File

@ -41,6 +41,10 @@ public:
UINT8 m_pc_input;
UINT8 m_pcjr_dor;
emu_timer *m_pcjr_watchdog;
UINT8 m_pcjx_1ff_count;
UINT8 m_pcjx_1ff_val;
UINT8 m_pcjx_1ff_bankval;
UINT8 m_pcjx_1ff_bank[20][2];
int m_ppi_portc_switch_high;
int m_ppi_speaker;
@ -131,6 +135,9 @@ public:
DECLARE_READ8_MEMBER(mc1502_wd17xx_drq_r);
DECLARE_READ8_MEMBER(mc1502_wd17xx_motor_r);
DECLARE_WRITE8_MEMBER(pcjr_fdc_dor_w);
DECLARE_READ8_MEMBER(pcjx_port_1ff_r);
DECLARE_WRITE8_MEMBER(pcjx_port_1ff_w);
void pcjx_set_bank(int unk1, int unk2, int unk3);
void fdc_interrupt(bool state);
void fdc_dma_drq(bool state);

View File

@ -527,7 +527,7 @@ static UINT8 nmi_enabled;
WRITE8_MEMBER(pc_state::pc_nmi_enable_w)
{
logerror( "%08X: changing NMI state to %s\n", space.device().safe_pc(), data & 0x80 ? "enabled" : "disabled" );
//logerror( "%08X: changing NMI state to %s\n", space.device().safe_pc(), data & 0x80 ? "enabled" : "disabled" ); // this is clogging up the log
nmi_enabled = data & 0x80;
}
@ -582,7 +582,7 @@ static struct {
READ8_MEMBER(pc_state::pcjr_nmi_enable_r)
{
pcjr_keyb.latch = 0;
machine().firstcpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
return nmi_enabled;
}
@ -602,7 +602,6 @@ TIMER_CALLBACK_MEMBER(pc_state::pcjr_keyb_signal_callback)
static void pcjr_set_keyb_int(running_machine &machine, int state)
{
pc_state *st = machine.driver_data<pc_state>();
if ( state )
{
UINT8 data = pc_keyb_read();
@ -634,16 +633,9 @@ static void pcjr_set_keyb_int(running_machine &machine, int state)
/* Set timer */
pcjr_keyb.keyb_signal_timer->adjust( attotime::from_usec(220), 0, attotime::from_usec(220) );
/* Trigger NMI */
if ( ! pcjr_keyb.latch )
{
pcjr_keyb.latch = 1;
if ( nmi_enabled & 0x80 )
{
st->m_pit8253->machine().firstcpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE );
}
}
pcjr_keyb.latch = 1;
}
machine.firstcpu->set_input_line(INPUT_LINE_NMI, pcjr_keyb.latch && nmi_enabled);
}
@ -1181,14 +1173,22 @@ WRITE8_MEMBER(pc_state::pcjr_fdc_dor_w)
logerror("fdc: dor = %02x\n", data);
UINT8 pdor = m_pcjr_dor;
upd765a_device *fdc = machine().device<upd765a_device>("upd765");
floppy_image_device *floppy = machine().device<floppy_connector>("upd765:0")->get_device();
floppy_image_device *floppy0 = fdc->subdevice<floppy_connector>("0")->get_device();
floppy_image_device *floppy1 = NULL;
if(fdc->subdevice("1"))
floppy1 = fdc->subdevice<floppy_connector>("1")->get_device();
m_pcjr_dor = data;
if(floppy)
floppy->mon_w(!(m_pcjr_dor & 1));
if(floppy0)
floppy0->mon_w(!(m_pcjr_dor & 1));
if(floppy1)
floppy1->mon_w(!(m_pcjr_dor & 2));
if(m_pcjr_dor & 1)
fdc->set_floppy(floppy);
fdc->set_floppy(floppy0);
else if(m_pcjr_dor & 2)
fdc->set_floppy(floppy1);
else
fdc->set_floppy(NULL);
@ -1204,6 +1204,42 @@ WRITE8_MEMBER(pc_state::pcjr_fdc_dor_w)
}
}
// pcjx port 0x1ff, some info from Toshiya Takeda
void pc_state::pcjx_set_bank(int unk1, int unk2, int unk3)
{
logerror("pcjx: 0x1ff 0:%02x 1:%02x 2:%02x\n", unk1, unk2, unk3);
}
WRITE8_MEMBER(pc_state::pcjx_port_1ff_w)
{
switch(m_pcjx_1ff_count) {
case 0:
m_pcjx_1ff_bankval = data;
m_pcjx_1ff_count++;
break;
case 1:
m_pcjx_1ff_bank[m_pcjx_1ff_bankval & 0x1f][0] = data;
m_pcjx_1ff_count++;
break;
case 2:
m_pcjx_1ff_bank[m_pcjx_1ff_bankval & 0x1f][1] = data;
m_pcjx_1ff_count = 0;
pcjx_set_bank(m_pcjx_1ff_bankval, m_pcjx_1ff_bank[m_pcjx_1ff_bankval & 0x1f][0], data);
break;
}
}
READ8_MEMBER(pc_state::pcjx_port_1ff_r)
{
if(m_pcjx_1ff_count == 2)
pcjx_set_bank(m_pcjx_1ff_bankval, m_pcjx_1ff_bank[m_pcjx_1ff_bankval & 0x1f][0], m_pcjx_1ff_bank[m_pcjx_1ff_bankval & 0x1f][1]);
m_pcjx_1ff_count = 0;
return 0x60; // expansion?
}
/*
* MC1502 uses a FD1793 clone instead of uPD765
*/
@ -1475,7 +1511,6 @@ MACHINE_START_MEMBER(pc_state,pcjr)
m_pit8253 = machine().device("pit8253");
}
MACHINE_RESET_MEMBER(pc_state,pcjr)
{
device_t *speaker = machine().device(SPEAKER_TAG);
@ -1498,6 +1533,11 @@ MACHINE_RESET_MEMBER(pc_state,pcjr)
m_pcjr_dor = 0;
speaker_level_w( speaker, 0 );
m_pcjx_1ff_count = 0;
m_pcjx_1ff_val = 0;
m_pcjx_1ff_bankval = 0;
memset(m_pcjx_1ff_bank, 0, sizeof(m_pcjx_1ff_bank));
pcjr_keyb_init(machine());
}

View File

@ -355,7 +355,7 @@ INPUT_PORTS_START( t1000_keyboard )
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Print") /* 37 B7 */
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) /* Left Alt 38 B8 */
PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) /* Space 39 B9 */
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE/* Caps Lock 3A BA */
PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) /* Caps Lock 3A BA */
PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) /* F1 3B BB */
PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) /* F2 3C BC */
PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) /* F3 3D BD */
@ -368,7 +368,7 @@ INPUT_PORTS_START( t1000_keyboard )
PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) /* F8 42 C2 */
PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) /* F9 43 C3 */
PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) /* F10 44 C4 */
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NumLock") PORT_CODE(KEYCODE_NUMLOCK) PORT_TOGGLE/* Num Lock 45 C5 */
PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("NumLock") PORT_CODE(KEYCODE_NUMLOCK) /* Num Lock 45 C5 */
PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Hold") PORT_CODE(KEYCODE_SCRLOCK) /* 46 C6 */
PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 7 \\") PORT_CODE(KEYCODE_7_PAD) /* Keypad 7 47 C7 */
PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("KP 8 ~") PORT_CODE(KEYCODE_8_PAD) /* Keypad 8 48 C8 */

View File

@ -148,6 +148,7 @@ static struct
UINT8 display_enable;
UINT8 vsync;
UINT8 palette_base;
UINT8 *jxkanji;
} pcjr = { 0 };
@ -225,6 +226,46 @@ static MC6845_UPDATE_ROW( t1000_text_blink_update_row )
}
}
static MC6845_UPDATE_ROW( pcjx_text_update_row )
{
const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
UINT32 *p = &bitmap.pix32(y);
int i;
for ( i = 0; i < x_count; i++ )
{
UINT16 offset = ( ( ma + i ) << 1 ) & 0x3fff;
UINT8 chr = pcjr.displayram[ offset ];
UINT8 attr = pcjr.displayram[ offset +1 ];
UINT16 fg = pcjr.palette_base + ( attr & 0x07 );
UINT16 bg = pcjr.palette_base + ( ( attr >> 4 ) & 0x07 );
UINT16 code = chr & 0x1f;
if((attr & 0x88) == 0x88)
{
code = pcjr.displayram[ offset - 2 ] & 0x1f;
code = (code << 8) + chr;
}
else if(attr & 0x80)
code = (code << 8) + pcjr.displayram[ offset + 2 ];
else
code = chr;
UINT8 data;
if(ra < 16)
data = pcjr.jxkanji[code * 16 * 2 + (ra * 2) + ((attr & 8)?1:0)];
else
data = ((i == cursor_x) && (pcjr.pc_framecnt & 8)) ? 0xff: 0;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x40 ) ? fg : bg]; p++;
*p = palette[( data & 0x20 ) ? fg : bg]; p++;
*p = palette[( data & 0x10 ) ? fg : bg]; p++;
*p = palette[( data & 0x08 ) ? fg : bg]; p++;
*p = palette[( data & 0x04 ) ? fg : bg]; p++;
*p = palette[( data & 0x02 ) ? fg : bg]; p++;
*p = palette[( data & 0x01 ) ? fg : bg]; p++;
}
}
static MC6845_UPDATE_ROW( t1000_gfx_4bpp_update_row )
{
@ -359,13 +400,13 @@ static MC6845_UPDATE_ROW( t1000_gfx_1bpp_update_row )
data = vid[ offset + 1 ];
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x80 ) ? fg : bg]; p++;
*p = palette[( data & 0x40 ) ? fg : bg]; p++;
*p = palette[( data & 0x20 ) ? fg : bg]; p++;
*p = palette[( data & 0x10 ) ? fg : bg]; p++;
*p = palette[( data & 0x08 ) ? fg : bg]; p++;
*p = palette[( data & 0x04 ) ? fg : bg]; p++;
*p = palette[( data & 0x02 ) ? fg : bg]; p++;
*p = palette[( data & 0x01 ) ? fg : bg]; p++;
}
}
@ -474,6 +515,11 @@ static void pc_pcjr_mode_switch( running_machine &machine )
switch( pcjr.reg.data[0] & 0x1A )
{
case 0x08: /* 01x0x */
if(pcjr.jxkanji)
{
pcjr.update_row = pcjx_text_update_row;
break;
}
if ( pcjr.reg.data[3] & 0x02 )
{
pcjr.update_row = t1000_text_blink_update_row;
@ -751,6 +797,28 @@ static void pc_pcjr_bank_w(running_machine &machine, int data)
}
}
static void pc_pcjx_bank_w(running_machine &machine, int data)
{
if (pcjr.bank != data)
{
int dram, vram;
pcjr.bank = data;
/* this probably isn't right, but otherwise the memory test stomps on the vram */
if ((data&0xc0)==0xc0) /* needed for lemmings */
{
dram = 0x80000 + ((data & 0x06) << 14);
vram = 0x80000 + ((data & 0x30) << (14-3));
}
else
{
dram = 0x80000 + ((data & 0x07) << 14);
vram = 0x80000 + ((data & 0x38) << (14-3));
}
machine.root_device().membank( "bank14" )->set_base( machine.device<ram_device>(RAM_TAG)->pointer() + vram );
pcjr.displayram = machine.device<ram_device>(RAM_TAG)->pointer() + dram;
pc_pcjr_mode_switch(machine);
}
}
static int pc_t1t_bank_r(void)
{
@ -835,7 +903,10 @@ WRITE8_HANDLER( pc_pcjr_w )
case 12:
break;
case 15:
pc_pcjr_bank_w(space.machine(), data);
if(pcjr.jxkanji)
pc_pcjx_bank_w(space.machine(), data);
else
pc_pcjr_bank_w(space.machine(), data);
break;
default:
@ -844,7 +915,7 @@ WRITE8_HANDLER( pc_pcjr_w )
}
READ8_HANDLER ( pc_T1T_r )
READ8_HANDLER ( pc_T1T_r )
{
mc6845_device *mc6845;
int data = 0xff;
@ -960,6 +1031,10 @@ static VIDEO_START( pc_pcjr )
pcjr.bank = 0;
pcjr.mode_control = 0x08;
pcjr.chr_size = 8;
if(!strncmp(machine.system().name, "ibmpcjx", 7))
pcjr.jxkanji = machine.root_device().memregion("kanji")->base();
else
pcjr.jxkanji = NULL;
buswidth = machine.firstcpu->space_config(AS_PROGRAM)->m_databus_width;
switch(buswidth)