From ab847fdecdd9fb2f0885f785a86b7eca672de555 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 01:38:25 +0200 Subject: [PATCH] Applied all the mainline PCem PCI commits; Applied patch from James-F that makes the Sound Blaster filters more accurate. --- src/SOUND/filters.h | 11 ++- src/SOUND/snd_opl.c | 8 +- src/SOUND/snd_sb.c | 8 +- src/VIDEO/vid_ati_mach64.c | 65 ++++++++++--- src/VIDEO/vid_s3.c | 60 ++++++++++-- src/VIDEO/vid_s3_virge.c | 44 ++++++++- src/i430fx.c | 22 ++++- src/i430hx.c | 21 +++- src/i430lx.c | 20 +++- src/i430nx.c | 20 +++- src/i430vx.c | 21 +++- src/i440fx.c | 24 ++++- src/model.c | 139 ++++++++++++++++++--------- src/pci.c | 88 ++++++++++++----- src/pci.h | 19 +++- src/piix.c | 46 ++++++++- src/piix.h | 4 +- src/sio.c | 192 ++++++++++++++++++++++--------------- src/sio.h | 10 +- src/sis496.c | 31 +++++- 20 files changed, 649 insertions(+), 204 deletions(-) diff --git a/src/SOUND/filters.h b/src/SOUND/filters.h index 6269b55e3..528bf0b05 100644 --- a/src/SOUND/filters.h +++ b/src/SOUND/filters.h @@ -131,10 +131,10 @@ static __inline float high_cut_iir(int i, float NewSample) { #undef NCoef -#define NCoef 1 +#define NCoef 2 static __inline float sb_iir(int i, float NewSample) { -/* float ACoef[NCoef+1] = { + float ACoef[NCoef+1] = { 0.03356837051492005100, 0.06713674102984010200, 0.03356837051492005100 @@ -144,9 +144,9 @@ static __inline float sb_iir(int i, float NewSample) { 1.00000000000000000000, -1.41898265221812010000, 0.55326988968868285000 - };*/ + }; - float ACoef[NCoef+1] = { +/* float ACoef[NCoef+1] = { 0.17529642630084405000, 0.17529642630084405000 }; @@ -154,7 +154,8 @@ static __inline float sb_iir(int i, float NewSample) { float BCoef[NCoef+1] = { 1.00000000000000000000, -0.64940759319751051000 - }; + };*/ + static float y[2][NCoef+1]; /* output samples */ static float x[2][NCoef+1]; /* input samples */ int n; diff --git a/src/SOUND/snd_opl.c b/src/SOUND/snd_opl.c index d04b7be9a..c5ccc6070 100644 --- a/src/SOUND/snd_opl.c +++ b/src/SOUND/snd_opl.c @@ -88,8 +88,8 @@ void opl2_update2(opl_t *opl) opl2_update(1, &opl->buffer[opl->pos*2 + 1], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } @@ -101,8 +101,8 @@ void opl3_update2(opl_t *opl) opl3_update(0, &opl->buffer[opl->pos*2], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index d428c1a7d..688cb4cee 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -81,8 +81,8 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); if (sb->mixer.filter) { @@ -132,8 +132,8 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); if (sb->mixer.filter) { diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 261d6681f..aabb9271b 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -83,6 +83,8 @@ typedef struct mach64_t int type; uint8_t pci_regs[256]; + uint8_t int_line; + int card; int bank_r[2]; int bank_w[2]; @@ -209,7 +211,8 @@ typedef struct mach64_t uint16_t pci_id; uint32_t config_chip_id; uint32_t block_decoded_io; - + int use_block_decoded_io; + int pll_addr; uint8_t pll_regs[16]; double pll_freq[4]; @@ -557,6 +560,19 @@ void mach64_updatemapping(mach64_t *mach64) } } +static void mach64_update_irqs(mach64_t *mach64) +{ + if (!PCI) + { + return; + } + + if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) + pci_set_irq(mach64->card, PCI_INTA); + else + pci_clear_irq(mach64->card, PCI_INTA); +} + static __inline void wake_fifo_thread(mach64_t *mach64) { thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ @@ -1652,6 +1668,7 @@ static void mach64_vblank_start(svga_t *svga) int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; mach64->crtc_int_cntl |= 4; + mach64_update_irqs(mach64); svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; @@ -2203,6 +2220,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); if (val & 4) mach64->crtc_int_cntl &= ~4; + mach64_update_irqs(mach64); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -3113,18 +3131,21 @@ static void mach64_io_set(mach64_t *mach64) mach64_io_remove(mach64); io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - for (c = 0; c < 8; c++) - { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } + + if (!mach64->use_block_decoded_io) + { + for (c = 0; c < 8; c++) + { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } + } io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } @@ -3169,6 +3190,11 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return mach64->pci_regs[0x32]; case 0x33: return mach64->pci_regs[0x33]; + + case 0x3c: return mach64->int_line; + case 0x3d: return PCI_INTA; + + case 0x40: return mach64->use_block_decoded_io; } return 0; } @@ -3251,6 +3277,21 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&mach64->bios_rom.mapping); } return; + + case 0x3c: + mach64->int_line = val; + break; + + case 0x40: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->use_block_decoded_io = val & 0x04; + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; } } @@ -3279,7 +3320,7 @@ static void *mach64_common_init() mach64_io_set(mach64); - pci_add(mach64_pci_read, mach64_pci_write, mach64); + mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -3311,6 +3352,8 @@ static void *mach64gx_init() else mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ + mach64->use_block_decoded_io = PCI ? 4 : 0; + ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); rom_init(&mach64->bios_rom, L"roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 9f141668d..5c1ea29cc 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -94,12 +94,15 @@ typedef struct s3_t int chip; uint8_t id, id_ext, id_ext_pci; + + uint8_t int_line; int packed_mmio; uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; uint32_t vram_mask; @@ -150,8 +153,16 @@ typedef struct s3_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; + + uint8_t subsys_cntl, subsys_stat; } s3_t; +#define INT_VSY (1 << 0) +#define INT_GE_BSY (1 << 1) +#define INT_FIFO_OVR (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_MASK 0xf + void s3_updatemapping(); void s3_accel_write(uint32_t addr, uint8_t val, void *p); @@ -173,6 +184,19 @@ static void s3_wait_fifo_idle(s3_t *s3) } } +static void s3_update_irqs(s3_t *s3) +{ + if (!PCI) + { + return; + } + + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) + pci_set_irq(s3->card, PCI_INTA); + else + pci_clear_irq(s3->card, PCI_INTA); +} + void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) switch ((addr) & 3) \ @@ -725,9 +749,19 @@ static void fifo_thread(void *param) s3->blitter_time += end_time - start_time; } s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); } } +static void s3_vblank_start(svga_t *svga) +{ + s3_t *s3 = (s3_t *)svga->p; + + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); +} + static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; @@ -1129,9 +1163,12 @@ void s3_accel_out(uint16_t port, uint8_t val, void *p) else switch (port) { case 0x42e8: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); break; case 0x42e9: - s3->accel.subsys_cntl = val; + s3->subsys_cntl = val; + s3_update_irqs(s3); break; case 0x46e8: s3->accel.setup_md = val; @@ -1161,9 +1198,9 @@ uint8_t s3_accel_in(uint16_t port, void *p) switch (port) { case 0x42e8: - return 0; + return s3->subsys_stat; case 0x42e9: - return 0; + return s3->subsys_cntl; case 0x82e8: s3_wait_fifo_idle(s3); @@ -2060,6 +2097,9 @@ uint8_t s3_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return s3->pci_regs[0x32]; case 0x33: return s3->pci_regs[0x33]; + + case 0x3c: return s3->int_line; + case 0x3d: return PCI_INTA; } return 0; } @@ -2072,7 +2112,7 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { case PCI_REG_COMMAND: - s3->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; if (val & PCI_COMMAND_IO) s3_io_set(s3); else @@ -2101,6 +2141,10 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&s3->bios_rom.mapping); } return; + + case 0x3c: + s3->int_line = val; + return; } } @@ -2153,6 +2197,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x37] = 1 | (7 << 5); + svga->vblank_start = s3_vblank_start; + svga->crtc[0x53] = 1 << 3; svga->crtc[0x59] = 0x70; @@ -2160,9 +2206,9 @@ static void *s3_init(wchar_t *bios_fn, int chip) if (PCI) { - pci_add(s3_pci_read, s3_pci_write, s3); + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); } - + s3->pci_regs[0x04] = 3; s3->pci_regs[0x30] = 0x00; @@ -2174,6 +2220,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); s3->fifo_thread = thread_create(fifo_thread, s3); + + s3->int_line = 0; return s3; } diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 21723de42..49630de9c 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -121,6 +121,7 @@ typedef struct virge_t uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; int is_375; @@ -228,6 +229,8 @@ typedef struct virge_t event_t *fifo_not_full_event; int virge_busy; + + uint8_t subsys_stat, subsys_cntl; } virge_t; static __inline void wake_fifo_thread(virge_t *virge) @@ -292,6 +295,26 @@ enum CMD_SET_COMMAND_NOP = (15 << 27) }; +#define INT_VSY (1 << 0) +#define INT_S3D_DONE (1 << 1) +#define INT_FIFO_OVF (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_3DF_EMP (1 << 6) +#define INT_MASK 0xff + +static void s3_virge_update_irqs(virge_t *virge) +{ + if (!PCI) + { + return; + } + + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) + pci_set_irq(virge->card, PCI_INTA); + else + pci_clear_irq(virge->card, PCI_INTA); +} + static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; @@ -339,6 +362,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: if ((svga->crtc[0x67] & 0xc) != 0xc) svga->vrammask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + s3_virge_update_irqs(virge); break; case 0x50: @@ -691,6 +715,14 @@ static void s3_virge_updatemapping(virge_t *virge) } +static void s3_virge_vblank_start(svga_t *svga) +{ + virge_t *virge = (virge_t *)svga->p; + + virge->subsys_stat |= INT_VSY; + s3_virge_update_irqs(virge); +} + static void s3_virge_wait_fifo_idle(virge_t *virge) { while (!FIFO_EMPTY) @@ -822,6 +854,7 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) ret = (0x10 << 8); else ret = (0x10 << 8) | (1 << 13); + ret |= virge->subsys_stat; if (!virge->virge_busy) wake_fifo_thread(virge); break; @@ -1441,6 +1474,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) svga_recalctimings(svga); svga->fullchange = changeframecount; break; + + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: @@ -3248,6 +3287,8 @@ static void render_thread(void *param) thread_set_event(virge->not_full_event); } virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); } } @@ -3707,6 +3748,7 @@ static void *s3_virge_init() s3_virge_in, s3_virge_out, s3_virge_hwcursor_draw, s3_virge_overlay_draw); + virge->svga.vblank_start = s3_virge_vblank_start; rom_init(&virge->bios_rom, L"roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3774,7 +3816,7 @@ static void *s3_virge_init() virge->is_375 = 0; - pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); diff --git a/src/i430fx.c b/src/i430fx.c index bfc635fed..a5100d789 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -49,15 +49,33 @@ static void i430fx_map(uint32_t addr, uint32_t size, int state) void i430fx_write(int func, int addr, uint8_t val, void *priv) { if (func) - return; + return; + + if (addr >= 0x10 && addr < 0x4f) + return; switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430fx[0x59] ^ val) & 0xf0) { diff --git a/src/i430hx.c b/src/i430hx.c index dc2b75b02..1e83fa513 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -52,13 +52,32 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430hx[0x59] ^ val) & 0xf0) { diff --git a/src/i430lx.c b/src/i430lx.c index ccb44ebff..ff22680bf 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -51,13 +51,31 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430lx[0x59] ^ val) & 0xf0) { diff --git a/src/i430nx.c b/src/i430nx.c index 487aa48bd..2827b293b 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -51,13 +51,31 @@ void i430nx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430nx[0x59] ^ val) & 0xf0) { diff --git a/src/i430vx.c b/src/i430vx.c index e9ff1f42b..bbe88865c 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -52,13 +52,32 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430vx[0x59] ^ val) & 0xf0) { diff --git a/src/i440fx.c b/src/i440fx.c index a315801c9..1a19b10bc 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -52,20 +52,38 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i440fx[0x59] ^ val) & 0xf0) { i440fx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - // pclog("i440fx_write : PAM0 write %02X\n", val); break; case 0x5a: /*PAM1*/ if ((card_i440fx[0x5a] ^ val) & 0x0f) @@ -96,14 +114,12 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) i440fx_map(0xe0000, 0x04000, val & 0xf); if ((card_i440fx[0x5e] ^ val) & 0xf0) i440fx_map(0xe4000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM5 write %02X\n", val); break; case 0x5f: /*PAM6*/ if ((card_i440fx[0x5f] ^ val) & 0x0f) i440fx_map(0xe8000, 0x04000, val & 0xf); if ((card_i440fx[0x5f] ^ val) & 0xf0) i440fx_map(0xec000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM6 write %02X\n", val); break; } diff --git a/src/model.c b/src/model.c index 7eb73479f..675e4d18a 100644 --- a/src/model.c +++ b/src/model.c @@ -609,7 +609,10 @@ void at_sis496_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xd); + pci_slot(0xf); sis496_init(); trc_init(); } @@ -624,8 +627,11 @@ void at_premiere_common_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); - sio_init(1); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); @@ -641,9 +647,12 @@ void at_586mc1_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_2); i430lx_init(); - sio_init(1); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); device_add(&intel_flash_bxt_device); secondary_ide_check(); } @@ -658,9 +667,13 @@ void at_advanced_common_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); pc87306_init(); } @@ -673,34 +686,28 @@ void at_endeavor_init() void at_mb500n_init() { at_ide_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -#if 0 -void at_powermate_v_init() -{ - at_ide_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i430fx_init(); - piix_init(7); - fdc37c665_init(); - acerm3a_io_init(); - device_add(&intel_flash_bxt_device); -} -#endif - void at_p54tp4xe_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -710,9 +717,13 @@ void at_ap53_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c669_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -723,9 +734,13 @@ void at_p55t2s_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); pc87306_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -736,9 +751,13 @@ void at_acerm3a_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -749,9 +768,13 @@ void at_acerv35n_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -761,9 +784,13 @@ void at_p55t2p4_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -772,9 +799,13 @@ void at_i430vx_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); um8669f_init(); device_add(&intel_flash_bxt_device); } @@ -783,9 +814,13 @@ void at_p55tvp4_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -794,9 +829,13 @@ void at_p55va_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } @@ -805,9 +844,13 @@ void at_i440fx_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i440fx_init(); - piix3_init(7); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); + i430vx_init(); + piix3_init(7, 18, 17, 20, 19); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -816,9 +859,13 @@ void at_s1668_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i440fx_init(); - piix3_init(7); + piix3_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } diff --git a/src/pci.c b/src/pci.c index 73b056118..022286669 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,19 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include - #include "ibm.h" #include "io.h" #include "mem.h" +#include "pic.h" #include "pci.h" void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); uint8_t (*pci_card_read[32])(int func, int addr, void *priv); void *pci_priv[32]; -static uint8_t pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; -static int pci_min_card, pci_max_card; +static int pci_irq_routing[32]; +static int pci_irq_active[32]; +static int pci_irqs[4]; +static int pci_card_valid[32]; + +static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; void pci_cf8_write(uint16_t port, uint32_t val, void *p) @@ -37,7 +37,7 @@ void pci_write(uint16_t port, uint8_t val, void *priv) case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return; - + if (!pci_bus && pci_card_write[pci_card]) pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); @@ -57,10 +57,8 @@ uint8_t pci_read(uint16_t port, void *priv) return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); return 0xff; - - default: - return 0xff; } + return 0xff; } void pci_type2_write(uint16_t port, uint8_t val, void *priv); @@ -111,8 +109,40 @@ uint8_t pci_type2_read(uint16_t port, void *priv) } return 0xff; } - -void pci_init(int type, int min_card, int max_card) + +void pci_set_irq_routing(int pci_int, int irq) +{ + pci_irqs[pci_int - 1] = irq; +} + +void pci_set_card_routing(int card, int pci_int) +{ + pci_irq_routing[card] = pci_int; +} + +void pci_set_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) + picint(1 << pci_irqs[irq]); + pci_irq_active[card] = 1; + } +} + +void pci_clear_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) + picintc(1 << pci_irqs[irq]); + pci_irq_active[card] = 0; + } +} + +void pci_init(int type) { int c; @@ -130,14 +160,22 @@ void pci_init(int type, int min_card, int max_card) } for (c = 0; c < 32; c++) - { - pci_card_read[c] = NULL; - pci_card_write[c] = NULL; - pci_priv[c] = NULL; - } + { + pci_card_read[c] = NULL; + pci_card_write[c] = NULL; + pci_priv[c] = NULL; + pci_irq_routing[c] = 0; + pci_irq_active[c] = 0; + pci_card_valid[c] = 0; + } - pci_min_card = min_card; - pci_max_card = max_card; + for (c = 0; c < 4; c++) + pci_irqs[c] = PCI_IRQ_DISABLED; +} + +void pci_slot(int card) +{ + pci_card_valid[card] = 1; } void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) @@ -147,18 +185,20 @@ void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), pci_priv[card] = priv; } -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { int c; - for (c = pci_min_card; c <= pci_max_card; c++) + for (c = 0; c < 32; c++) { - if (!pci_card_read[c] && !pci_card_write[c]) + if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) { pci_card_read[c] = read; pci_card_write[c] = write; pci_priv[c] = priv; - return; + return c; } } + + return -1; } diff --git a/src/pci.h b/src/pci.h index 6c6782e23..6a8778e0f 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,9 +1,11 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void pci_init(int type, int min_card, int max_card); +void pci_init(int type); +void pci_slot(int card); void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +void pci_set_irq_routing(int card, int irq); +void pci_set_card_routing(int card, int pci_int); +void pci_set_irq(int card, int pci_int); +void pci_clear_irq(int card, int pci_int); #define PCI_REG_COMMAND 0x04 @@ -13,4 +15,11 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 + +#define PCI_IRQ_DISABLED -1 + extern int pci_burst_time, pci_nonburst_time; diff --git a/src/piix.c b/src/piix.c index 8e7378dbd..f2a38bf46 100644 --- a/src/piix.c +++ b/src/piix.c @@ -107,12 +107,40 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } else { + if (addr >= 0x0f && addr < 0x4c) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: return; + + case 0x60: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x62: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x63: + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } if (addr == 0x4C) { @@ -576,7 +604,7 @@ void piix_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -615,7 +643,7 @@ void piix3_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x00; card_piix[0x03] = 0x70; /*82371SB (PIIX3)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -650,7 +678,7 @@ void piix3_reset(void) card_piix_ide[0x44] = 0x00; } -void piix_init(int card) +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -669,9 +697,14 @@ void piix_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } -void piix3_init(int card) +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -690,4 +723,9 @@ void piix3_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix3_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/piix.h b/src/piix.h index 00000138c..a922ff41e 100644 --- a/src/piix.h +++ b/src/piix.h @@ -16,8 +16,8 @@ * Copyright 2016-2017 Miran Grca. */ -void piix_init(int card); -void piix3_init(int card); +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); uint8_t piix_bus_master_read(uint16_t port, void *priv); void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); diff --git a/src/sio.c b/src/sio.c index 3250ba2f0..96d2ef375 100644 --- a/src/sio.c +++ b/src/sio.c @@ -6,27 +6,24 @@ * * Emulation of Intel System I/O PCI chip. * - * Version: @(#)sio.c 1.0.0 2017/05/30 + * Version: @(#)sio.c 1.0.1 2017/06/02 * - * Author: Miran Grca, - * Copyright 2017-2017 Miran Grca. + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. */ -/*PRD format : - - word 0 - base address - word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer -*/ #include + #include "ibm.h" -#include "cpu/cpu.h" #include "cdrom.h" #include "disc.h" #include "dma.h" #include "fdc.h" +#include "keyboard_at.h" #include "ide.h" #include "io.h" -#include "keyboard_at.h" #include "mem.h" #include "pci.h" @@ -36,66 +33,99 @@ static uint8_t card_sio[256]; void sio_write(int func, int addr, uint8_t val, void *priv) { -// pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); - - if ((addr & 0xff) < 4) return; - if (func > 0) - return; + return; - if (func == 0) - { - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + if (addr >= 0x0f && addr < 0x4c) return; - } - card_sio[addr] = val; - if (addr == 0x40) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } - if (val & 0x40) - { - dma_alias_remove(); - } - else - { - dma_alias_set(); - } - } - else if (addr == 0x4f) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } + switch (addr) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0e: + return; + + case 0x04: /*Command register*/ + val &= 0x08; + val |= 0x07; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - if (val & 0x40) - { - port_92_add(); - } - else - { - port_92_remove(); - } + case 0x40: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; } + + if (val & 0x40) + { + dma_alias_remove(); + } + else + { + dma_alias_set(); + } + break; + + case 0x4f: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; + } + + if (val & 0x40) + { + port_92_add(); + } + else + { + port_92_remove(); + } + + case 0x60: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x62: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x63: + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } + card_sio[addr] = val; } uint8_t sio_read(int func, int addr, void *priv) { -// pclog("sio_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); - if (func > 0) - return 0xff; + return 0xff; - return card_sio[addr]; + return card_sio[addr]; } static int trc_reg = 0; @@ -164,31 +194,30 @@ void sio_reset(void) { memset(card_sio, 0, 256); card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/ - card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378ZB (SIO)*/ + card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378IB (SIO)*/ card_sio[0x04] = 0x07; card_sio[0x05] = 0x00; - card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; - card_sio[0x08] = 0x00; /*A0 stepping*/ - card_sio[0x40] = 0x20; - card_sio[0x42] = 0x24; - card_sio[0x45] = 0x10; - card_sio[0x46] = 0x0F; - card_sio[0x48] = 0x01; - card_sio[0x4A] = 0x10; - card_sio[0x4B] = 0x0F; - card_sio[0x4C] = 0x56; - card_sio[0x4D] = 0x40; - card_sio[0x4E] = 0x07; - card_sio[0x4F] = 0x4F; - card_sio[0x60] = card_sio[0x61] = card_sio[0x62] = card_sio[0x63] = 0x80; - card_sio[0x80] = 0x78; - card_sio[0xA0] = 0x08; - card_sio[0xA8] = 0x0F; + card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; + card_sio[0x08] = 0x03; /*A0 stepping*/ + + card_sio[0x40] = 0x20; card_sio[0x41] = 0x00; + card_sio[0x42] = 0x04; card_sio[0x43] = 0x00; + card_sio[0x44] = 0x20; card_sio[0x45] = 0x10; + card_sio[0x46] = 0x0f; card_sio[0x47] = 0x00; + card_sio[0x48] = 0x01; card_sio[0x49] = 0x10; + card_sio[0x4a] = 0x10; card_sio[0x4b] = 0x0f; + card_sio[0x4c] = 0x56; card_sio[0x4d] = 0x40; + card_sio[0x4e] = 0x07; card_sio[0x4f] = 0x4f; + card_sio[0x54] = 0x00; card_sio[0x55] = 0x00; card_sio[0x56] = 0x00; + card_sio[0x60] = 0x80; card_sio[0x61] = 0x80; card_sio[0x62] = 0x80; card_sio[0x63] = 0x80; + card_sio[0x80] = 0x78; card_sio[0x81] = 0x00; + card_sio[0xa0] = 0x08; + card_sio[0xa8] = 0x0f; } -void sio_init(int card) +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, sio_read, sio_write, NULL); - + sio_reset(); trc_init(); @@ -200,4 +229,13 @@ void sio_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = sio_reset; + + if (pci_a) + pci_set_card_routing(pci_a, PCI_INTA); + if (pci_b) + pci_set_card_routing(pci_b, PCI_INTB); + if (pci_c) + pci_set_card_routing(pci_c, PCI_INTC); + if (pci_d) + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/sio.h b/src/sio.h index 9aacd3e6b..0e3ea651f 100644 --- a/src/sio.h +++ b/src/sio.h @@ -6,11 +6,13 @@ * * Emulation of Intel System I/O PCI chip. * - * Version: @(#)sio.h 1.0.0 2017/05/30 + * Version: @(#)sio.h 1.0.1 2017/06/02 * - * Author: Miran Grca, - * Copyright 2017-2017 Miran Grca. + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. */ void trc_init(void); -void sio_init(int card); +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); diff --git a/src/sis496.c b/src/sis496.c index a858102a3..cb4d9303d 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -68,8 +68,33 @@ void sis496_write(int func, int addr, uint8_t val, void *p) sis496_recalcmapping(); } break; - } + case 0xc0: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, val & 0xf); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + break; + case 0xc1: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, val & 0xf); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + case 0xc2: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, val & 0xf); + else + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + break; + case 0xc3:// pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, val & 0xf); + else + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + break; + } + if ((addr >= 4 && addr < 8) || addr >= 0x40) sis496.pci_conf[addr] = val; } @@ -118,6 +143,10 @@ void sis496_init(void) sis496_reset(); pci_reset_handler.pci_master_reset = sis496_pci_reset; + + pci_set_card_routing(15, PCI_INTA); + pci_set_card_routing(13, PCI_INTD); + pci_set_card_routing(11, PCI_INTC); } void sis496_close(void *p)