Implemented the VIA chipset's PIC shadow mode.
This commit is contained in:
94
src/pic.c
94
src/pic.c
@@ -8,11 +8,11 @@
|
|||||||
*
|
*
|
||||||
* Implementation of the Intel PIC chip emulation.
|
* Implementation of the Intel PIC chip emulation.
|
||||||
*
|
*
|
||||||
* Version: @(#)pic.c 1.0.5 2019/09/20
|
* Version: @(#)pic.c 1.0.6 2020/01/17
|
||||||
*
|
*
|
||||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||||
*
|
*
|
||||||
* Copyright 2016-2018 Miran Grca.
|
* Copyright 2016-2020 Miran Grca.
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -30,12 +30,15 @@
|
|||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
|
|
||||||
|
|
||||||
int output;
|
int output;
|
||||||
int intclear;
|
int intclear;
|
||||||
int keywaiting=0;
|
int keywaiting = 0;
|
||||||
int pic_intpending;
|
int pic_intpending;
|
||||||
PIC pic, pic2;
|
PIC pic, pic2;
|
||||||
uint16_t pic_current;
|
uint16_t pic_current;
|
||||||
|
|
||||||
|
|
||||||
|
static int shadow = 0;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_PIC_LOG
|
#ifdef ENABLE_PIC_LOG
|
||||||
@@ -98,6 +101,13 @@ pic_reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
pic_set_shadow(int sh)
|
||||||
|
{
|
||||||
|
shadow = sh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_update_mask(uint8_t *mask, uint8_t ins)
|
pic_update_mask(uint8_t *mask, uint8_t ins)
|
||||||
{
|
{
|
||||||
@@ -198,6 +208,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
pic_updatepending();
|
pic_updatepending();
|
||||||
}
|
}
|
||||||
else if (!(val & 8)) { /*OCW2*/
|
else if (!(val & 8)) { /*OCW2*/
|
||||||
|
pic.ocw2 = val;
|
||||||
if ((val & 0xE0) == 0x60) {
|
if ((val & 0xE0) == 0x60) {
|
||||||
pic.ins &= ~(1 << (val & 7));
|
pic.ins &= ~(1 << (val & 7));
|
||||||
pic_update_mask(&pic.mask2, pic.ins);
|
pic_update_mask(&pic.mask2, pic.ins);
|
||||||
@@ -226,6 +237,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /*OCW3*/
|
} else { /*OCW3*/
|
||||||
|
pic.ocw3 = val;
|
||||||
if (val & 2)
|
if (val & 2)
|
||||||
pic.read=(val & 1);
|
pic.read=(val & 1);
|
||||||
}
|
}
|
||||||
@@ -236,27 +248,36 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
uint8_t
|
uint8_t
|
||||||
pic_read(uint16_t addr, void *priv)
|
pic_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
addr &= ~0x06;
|
uint8_t ret = 0xff;
|
||||||
|
|
||||||
if (addr & 1) {
|
if ((addr == 0x20) && shadow) {
|
||||||
pic_log("Read PIC mask %02X\n", pic.mask);
|
ret = ((pic.ocw3 & 0x20) >> 5) << 4;
|
||||||
pic_log("%04X:%04X: Read PIC mask %02X\n", CS, cpu_state.pc, pic.mask);
|
ret |= ((pic.ocw2 & 0x80) >> 7) << 3;
|
||||||
return pic.mask;
|
ret |= ((pic.icw4 & 0x10) >> 4) << 2;
|
||||||
}
|
ret |= ((pic.icw4 & 0x02) >> 1) << 1;
|
||||||
if (pic.read) {
|
ret |= ((pic.icw4 & 0x08) >> 3) << 0;
|
||||||
pic_log("Read PIC ins %02X\n", pic.ins);
|
} else if ((addr == 0x21) && shadow)
|
||||||
|
ret = ((pic.vector & 0xf8) >> 3) << 0;
|
||||||
|
else if (addr & 1)
|
||||||
|
ret = pic.mask;
|
||||||
|
else if (pic.read) {
|
||||||
if (AT)
|
if (AT)
|
||||||
return pic.ins | (pic2.ins ? 4 : 0);
|
ret = pic.ins | (pic2.ins ? 4 : 0);
|
||||||
else
|
else
|
||||||
return pic.ins;
|
ret = pic.ins;
|
||||||
}
|
} else
|
||||||
return pic.pend;
|
ret = pic.pend;
|
||||||
|
|
||||||
|
pic_log("%04X:%04X: Read PIC 1 port %04X, value %02X\n", CS, cpu_state.pc, addr, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pic_init()
|
pic_init()
|
||||||
{
|
{
|
||||||
|
shadow = 0;
|
||||||
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL);
|
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +285,7 @@ pic_init()
|
|||||||
void
|
void
|
||||||
pic_init_pcjr()
|
pic_init_pcjr()
|
||||||
{
|
{
|
||||||
|
shadow = 0;
|
||||||
io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL);
|
io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +345,7 @@ pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
pic.pend &= ~4;
|
pic.pend &= ~4;
|
||||||
pic_updatepending();
|
pic_updatepending();
|
||||||
} else if (!(val & 8)) { /*OCW2*/
|
} else if (!(val & 8)) { /*OCW2*/
|
||||||
|
pic2.ocw2 = val;
|
||||||
if ((val & 0xE0) == 0x60) {
|
if ((val & 0xE0) == 0x60) {
|
||||||
pic2.ins &= ~(1 << (val & 7));
|
pic2.ins &= ~(1 << (val & 7));
|
||||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
pic_update_mask(&pic2.mask2, pic2.ins);
|
||||||
@@ -339,6 +362,7 @@ pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { /*OCW3*/
|
} else { /*OCW3*/
|
||||||
|
pic2.ocw3 = val;
|
||||||
if (val & 2)
|
if (val & 2)
|
||||||
pic2.read=(val & 1);
|
pic2.read=(val & 1);
|
||||||
}
|
}
|
||||||
@@ -349,16 +373,26 @@ pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
uint8_t
|
uint8_t
|
||||||
pic2_read(uint16_t addr, void *priv)
|
pic2_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
if (addr&1) {
|
uint8_t ret = 0xff;
|
||||||
pic_log("Read PIC2 mask %02X\n", pic2.mask);
|
|
||||||
return pic2.mask;
|
if ((addr == 0x20) && shadow) {
|
||||||
}
|
ret = ((pic2.ocw3 & 0x20) >> 5) << 4;
|
||||||
if (pic2.read) {
|
ret |= ((pic2.ocw2 & 0x80) >> 7) << 3;
|
||||||
pic_log("Read PIC2 ins %02X\n", pic2.ins);
|
ret |= ((pic2.icw4 & 0x10) >> 4) << 2;
|
||||||
return pic2.ins;
|
ret |= ((pic2.icw4 & 0x02) >> 1) << 1;
|
||||||
}
|
ret |= ((pic2.icw4 & 0x08) >> 3) << 0;
|
||||||
pic_log("Read PIC2 pend %02X\n", pic2.pend);
|
} else if ((addr == 0x21) && shadow)
|
||||||
return pic2.pend;
|
ret = ((pic2.vector & 0xf8) >> 3) << 0;
|
||||||
|
else if (addr & 1)
|
||||||
|
ret = pic2.mask;
|
||||||
|
else if (pic.read)
|
||||||
|
ret = pic2.ins;
|
||||||
|
else
|
||||||
|
ret = pic2.pend;
|
||||||
|
|
||||||
|
pic_log("%04X:%04X: Read PIC 2 port %04X, value %02X\n", CS, cpu_state.pc, addr, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct PIC {
|
typedef struct PIC {
|
||||||
uint8_t icw1,icw3,icw4,mask,ins,pend,mask2;
|
uint8_t icw1, icw3, icw4, mask, ins, pend, mask2, vector, ocw2, ocw3;
|
||||||
int icw;
|
int icw, read;
|
||||||
uint8_t vector;
|
|
||||||
int read;
|
|
||||||
} PIC;
|
} PIC;
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +12,7 @@ extern PIC pic, pic2;
|
|||||||
extern int pic_intpending;
|
extern int pic_intpending;
|
||||||
|
|
||||||
|
|
||||||
|
extern void pic_set_shadow(int sh);
|
||||||
extern void pic_init(void);
|
extern void pic_init(void);
|
||||||
extern void pic_init_pcjr(void);
|
extern void pic_init_pcjr(void);
|
||||||
extern void pic2_init(void);
|
extern void pic2_init(void);
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Emulation of the VIA Apollo MVP3 southbridge
|
* Emulation of the VIA Apollo MVP3 southbridge
|
||||||
*
|
*
|
||||||
* Version: @(#)via_vt82c586b.c 1.0.0 2020/01/14
|
* Version: @(#)via_vt82c586b.c 1.0.1 2020/01/17
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -113,6 +113,8 @@ via_vt82c586b_reset_hard(void *priv)
|
|||||||
dma[i].ac &= 0xffff000f;
|
dma[i].ac &= 0xffff000f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pic_set_shadow(0);
|
||||||
|
|
||||||
/* IDE registers */
|
/* IDE registers */
|
||||||
via_vt82c586b->ide_regs[0x00] = 0x06; via_vt82c586b->ide_regs[0x01] = 0x11; /*VIA*/
|
via_vt82c586b->ide_regs[0x00] = 0x06; via_vt82c586b->ide_regs[0x01] = 0x11; /*VIA*/
|
||||||
via_vt82c586b->ide_regs[0x02] = 0x71; via_vt82c586b->ide_regs[0x03] = 0x05; /*VT82C586B*/
|
via_vt82c586b->ide_regs[0x02] = 0x71; via_vt82c586b->ide_regs[0x03] = 0x05; /*VT82C586B*/
|
||||||
@@ -384,6 +386,7 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case 0x47:
|
case 0x47:
|
||||||
if ((val & 0x81) == 0x81)
|
if ((val & 0x81) == 0x81)
|
||||||
resetx86();
|
resetx86();
|
||||||
|
pic_set_shadow(!!(val & 0x10));
|
||||||
pci_elcr_set_enabled(!!(val & 0x20));
|
pci_elcr_set_enabled(!!(val & 0x20));
|
||||||
dev->pci_isa_regs[0x47] = val & 0xfe;
|
dev->pci_isa_regs[0x47] = val & 0xfe;
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user