From 91075fb627c9ed40e4de0b4841fd38c9a13707bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Aug 2016 03:32:38 +0200 Subject: [PATCH] RTL8029AS now works properly (patch from TheCollector1995 with some modifications by me); SVGA emulation now has partial support for 12x24 text mode used by 48k HECON.SYS; LEA AX,DX now once again issues #UD on 286+ like it should; FF /7 is now correctly an alias of FF /6 on 8080x; Hard disk configuration dialog now uses Segoe UI 9pt font instead of MS Sans Serif 8pt; Removed excess logging from serial mouse and x86seg.c; Applied mainline PCem PIT MSW1 fix commit; IMG-based floppy emulation now takes GAP4 and post-sector delays into account; Comemnted out emulation of non-Overdrive Pentium II's. --- src/386_ops.h | 2 + src/808x.c | 1 + src/cpu.c | 14 +- src/cpu.h | 4 +- src/disc_sector.c | 12 +- src/keyboard_at.c | 2 +- src/model.c | 6 +- src/mouse_serial.c | 2 +- src/ne2000.c | 1654 ++++++++++++++++++++++++----------------- src/pc.rc | 12 +- src/pic.c | 4 +- src/vid_svga.c | 120 ++- src/vid_svga_render.c | 112 +++ src/vid_svga_render.h | 2 + src/x86_ops.h | 4 +- src/x86_ops_mov.h | 16 +- src/x86seg.c | 238 +++--- 17 files changed, 1357 insertions(+), 848 deletions(-) diff --git a/src/386_ops.h b/src/386_ops.h index d55f58265..d3ca580b3 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -1018,6 +1018,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; +#if 0 OpFn OP_TABLE(pentium2_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1108,6 +1109,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif OpFn OP_TABLE(pentium2d_0f)[1024] = { diff --git a/src/808x.c b/src/808x.c index 7c586822f..f985bb811 100644 --- a/src/808x.c +++ b/src/808x.c @@ -3404,6 +3404,7 @@ void execx86(int cycs) FETCHCLEAR(); break; case 0x30: /*PUSH w*/ + case 0x38: /*PUSH w alias, reported by reenigne*/ tempw=geteaw(); // if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); if (ssegs) ss=oldss; diff --git a/src/cpu.c b/src/cpu.c index 2488eba79..b6d78f5e1 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -524,6 +524,7 @@ CPU cpus_PentiumPro[] = {"", -1, 0, 0, 0} }; +#if 0 CPU cpus_Pentium2[] = { /*Intel Pentium II Klamath*/ @@ -548,6 +549,7 @@ CPU cpus_Pentium2D[] = {"Pentium II D 500", CPU_PENTIUM2D, 33, 500000000, 5, 50000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC}, {"", -1, 0, 0, 0} }; +#endif void cpu_set_edx() { @@ -1357,7 +1359,8 @@ void cpu_set() codegen_timing_set(&codegen_timing_686); break; - case CPU_PENTIUM2: +#if 0 + case CPU_PENTIUM2: x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; @@ -1388,6 +1391,7 @@ void cpu_set() cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_686); break; +#endif case CPU_PENTIUM2D: x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); @@ -1778,7 +1782,7 @@ void cpu_CPUID() EAX = 0; break; - case CPU_PENTIUM2: + /* case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; @@ -1802,7 +1806,7 @@ void cpu_CPUID() } else EAX = 0; - break; + break; */ case CPU_PENTIUM2D: if (!EAX) @@ -1926,7 +1930,7 @@ void cpu_RDMSR() break; case CPU_PENTIUMPRO: - case CPU_PENTIUM2: + // case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; // pclog("RDMSR, ECX=%08X\n", ECX); @@ -2119,7 +2123,7 @@ void cpu_WRMSR() break; case CPU_PENTIUMPRO: - case CPU_PENTIUM2: + // case CPU_PENTIUM2: case CPU_PENTIUM2D: // pclog("WRMSR, ECX=%08X\n", ECX); switch (ECX) diff --git a/src/cpu.h b/src/cpu.h index 19b394c40..541c790b9 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -40,8 +40,10 @@ extern int cpu, cpu_manufacturer; /*686 class CPUs*/ #define CPU_PENTIUMPRO 25 +/* #define CPU_PENTIUM2 26 -#define CPU_PENTIUM2D 27 +#define CPU_PENTIUM2D 27 */ +#define CPU_PENTIUM2D 26 #define MANU_INTEL 0 #define MANU_AMD 1 diff --git a/src/disc_sector.c b/src/disc_sector.c index e571ad655..0ea1a0814 100644 --- a/src/disc_sector.c +++ b/src/disc_sector.c @@ -501,7 +501,7 @@ void disc_sector_poll() disc_sector_n[drive] != s->n || (fdc_get_bitcell_period() != get_bitcell_period(drive)) || !fdd_can_read_medium(drive ^ fdd_swap) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; @@ -529,7 +529,7 @@ void disc_sector_poll() break; } if (cur_byte[drive] || !index_count[drive] || fdc_get_bitcell_period() != get_bitcell_period(drive) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; @@ -561,7 +561,7 @@ void disc_sector_poll() break; } if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; @@ -601,7 +601,7 @@ void disc_sector_poll() disc_sector_sector[drive] != s->r || disc_sector_n[drive] != s->n || (fdc_get_bitcell_period() != get_bitcell_period(drive)) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; @@ -636,7 +636,7 @@ void disc_sector_poll() break; } if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; @@ -653,7 +653,7 @@ void disc_sector_poll() fdc_writeprotect(); } if (!index_count[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) || - disc_intersector_delay[drive] || disc_track_delay[drive]) + disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive]) { advance_byte(); break; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 2a82b730b..490d087d8 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -616,7 +616,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) case 0x64: temp = (keyboard_at.status & 0xFB) | (mode & CCB_SYSTEM); - if (mode & CCB_IGNORELOCK) temp |= STAT_LOCK; + /* if (mode & CCB_IGNORELOCK) */ temp |= STAT_LOCK; keyboard_at.status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); break; } diff --git a/src/model.c b/src/model.c index a85f69f3d..4cbcb430c 100644 --- a/src/model.c +++ b/src/model.c @@ -156,8 +156,10 @@ MODEL models[] = {"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_i430vx_init}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55tvp4_init}, {"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55va_init}, - {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init}, - {"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_kn97_init}, + {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_i440fx_init}, + {"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_kn97_init}, + // {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init}, + // {"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_kn97_init}, {"", -1, {"", 0, "", 0, "", 0}, 0,0,0, 0} }; diff --git a/src/mouse_serial.c b/src/mouse_serial.c index b5eeb1547..565f25eac 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -31,7 +31,7 @@ void mouse_serial_poll(int x, int y, int b) if (!(serial1.mctrl&0x10)) { - pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); + // pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); serial_write_fifo(&serial1, mousedat[0]); serial_write_fifo(&serial1, mousedat[1]); serial_write_fifo(&serial1, mousedat[2]); diff --git a/src/ne2000.c b/src/ne2000.c index 93813475a..73e247827 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -202,9 +202,6 @@ typedef struct ne2000_t uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) - uint8_t i8029id0; - uint8_t i8029id1; - // // Page 1 // @@ -235,14 +232,6 @@ typedef struct ne2000_t // // Page 3 - should never be modified. // - uint8_t cr; - uint8_t i9346cr; - uint8_t config0; - uint8_t config2; - uint8_t config3; - uint8_t hltclk; - uint8_t i8029asid0; - uint8_t i8029asid1; // Novell ASIC state uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes @@ -260,8 +249,9 @@ typedef struct ne2000_t int disable_netbios = 0; -static void ne2000_tx_event(int val, void *p); - +void ne2000_tx_event(void *p, uint32_t val); +uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len); +void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len); void ne2000_rx_frame(void *p, const void *buf, int io_len); static void ne2000_setirq(ne2000_t *ne2000, int irq) @@ -271,30 +261,30 @@ static void ne2000_setirq(ne2000_t *ne2000, int irq) // // reset - restore state to power-up, cancelling all i/o // -static void ne2000_reset(int type, void *p) +static void ne2000_reset(void *p, int reset) { ne2000_t *ne2000 = (ne2000_t *)p; int i; pclog("ne2000 reset\n"); - // Initialise the mac address area by doubling the physical address - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; + // Initialise the mac address area by doubling the physical address + ne2000->macaddr[0] = ne2000->physaddr[0]; + ne2000->macaddr[1] = ne2000->physaddr[0]; + ne2000->macaddr[2] = ne2000->physaddr[1]; + ne2000->macaddr[3] = ne2000->physaddr[1]; + ne2000->macaddr[4] = ne2000->physaddr[2]; + ne2000->macaddr[5] = ne2000->physaddr[2]; + ne2000->macaddr[6] = ne2000->physaddr[3]; + ne2000->macaddr[7] = ne2000->physaddr[3]; + ne2000->macaddr[8] = ne2000->physaddr[4]; + ne2000->macaddr[9] = ne2000->physaddr[4]; + ne2000->macaddr[10] = ne2000->physaddr[5]; + ne2000->macaddr[11] = ne2000->physaddr[5]; - // ne2k signature - for (i = 12; i < 32; i++) - ne2000->macaddr[i] = 0x57; + // ne2k signature + for (i = 12; i < 32; i++) + ne2000->macaddr[i] = 0x57; // Zero out registers and memory memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); @@ -343,6 +333,111 @@ static void ne2000_reset(int type, void *p) #include "bswap.h" +// +// read_cr/write_cr - utility routines for handling reads/writes to +// the Command Register +// +uint32_t ne2000_read_cr(ne2000_t *ne2000) +{ + uint32_t val; + + val = (((ne2000->CR.pgsel & 0x03) << 6) | + ((ne2000->CR.rdma_cmd & 0x07) << 3) | + (ne2000->CR.tx_packet << 2) | + (ne2000->CR.start << 1) | + (ne2000->CR.stop)); + pclog("%s: read CR returns 0x%02x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); + return val; +} + +void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) +{ + pclog("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); + + // Validate remote-DMA + if ((value & 0x38) == 0x00) { + pclog("CR write - invalid rDMA value 0\n"); + value |= 0x20; /* dma_cmd == 4 is a safe default */ + } + + // Check for s/w reset + if (value & 0x01) { + ne2000->ISR.reset = 1; + ne2000->CR.stop = 1; + } else { + ne2000->CR.stop = 0; + } + + ne2000->CR.rdma_cmd = (value & 0x38) >> 3; + + // If start command issued, the RST bit in the ISR + // must be cleared + if ((value & 0x02) && !ne2000->CR.start) { + ne2000->ISR.reset = 0; + } + + ne2000->CR.start = ((value & 0x02) == 0x02); + ne2000->CR.pgsel = (value & 0xc0) >> 6; + + // Check for send-packet command + if (ne2000->CR.rdma_cmd == 3) { + // Set up DMA read from receive ring + ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; + ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); + pclog("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); + } + + // Check for start-tx + if ((value & 0x04) && ne2000->TCR.loop_cntl) { + if (ne2000->TCR.loop_cntl != 1) { + pclog("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); + } else { + ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], + ne2000->tx_bytes); + } + } else if (value & 0x04) { + if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) { + if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ + return; /* Solaris9 probe */ + pclog("CR write - tx start, dev in reset\n"); + } + + if (ne2000->tx_bytes == 0) + pclog("CR write - tx start, tx bytes == 0\n"); + + // Send the packet to the system driver + ne2000->CR.tx_packet = 1; + if(net_is_slirp) + { + slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pclog("ne2000 slirp sending packet\n"); + } + if(net_is_pcap && net_pcap!=NULL) + { + _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pclog("ne2000 pcap sending packet\n"); + } + + // some more debug + if (ne2000->tx_timer_active) + pclog("CR write, tx timer still active\n"); + + ne2000_tx_event(ne2000, value); + } + + // Linux probes for an interrupt by setting up a remote-DMA read + // of 0 bytes with remote-DMA completion interrupts enabled. + // Detect this here + if (ne2000->CR.rdma_cmd == 0x01 && + ne2000->CR.start && + ne2000->remote_bytes == 0) { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) { + picint(1 << ne2000->base_irq); + } + } +} + // // chipmem_read/chipmem_write - access the 64K private RAM. // The ne2000 memory is accessed through the data port of @@ -351,48 +446,60 @@ static void ne2000_reset(int type, void *p) // The first 16 bytes contains the MAC address at even locations, // and there is 16K of buffer memory starting at 16K // -static inline uint8_t ne2000_chipmem_read_b(uint32_t address, ne2000_t *ne2000) + +uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) { - // ROM'd MAC address -if ((address >=0) && (address <= 31)) { - return ne2000->macaddr[address]; - } + uint32_t retval = 0; - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - return ne2000->mem[address - BX_NE2K_MEMSTART]; - } else { - return (0xff); - } -} + if ((io_len == 2) && (address & 0x1)) + pclog("unaligned chipmem word read\n"); - -static inline uint16_t ne2000_chipmem_read_w(uint32_t address, ne2000_t *ne2000) -{ // ROM'd MAC address if ((address >=0) && (address <= 31)) { - return le16_to_cpu(*(uint16_t *)(ne2000->macaddr + address)); + retval = ne2000->macaddr[address]; + if ((io_len == 2) || (io_len == 4)) { + retval |= (ne2000->macaddr[address + 1] << 8); + } + if (io_len == 4) { + retval |= (ne2000->macaddr[address + 2] << 16); + retval |= (ne2000->macaddr[address + 3] << 24); + } + return (retval); } if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - return le16_to_cpu(*(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART))); - } else { - return (0xffff); + retval = ne2000->mem[address - BX_NE2K_MEMSTART]; + if ((io_len == 2) || (io_len == 4)) { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); + } + if (io_len == 4) { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); + } + return (retval); } + + pclog("out-of-bounds chipmem read, %04X\n", address); + + return (0xff); } -static inline void ne2000_chipmem_write_b(uint32_t address, uint8_t value, ne2000_t *ne2000) +void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { + if ((io_len == 2) && (address & 0x1)) + pclog("unaligned chipmem word write\n"); + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; - } -} - - -static inline void ne2000_chipmem_write_w(uint32_t address, uint16_t value, ne2000_t *ne2000) -{ - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - *(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART)) = cpu_to_le16(value); - } + if ((io_len == 2) || (io_len == 4)) { + ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; + } + if (io_len == 4) { + ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; + ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; + } + } else + pclog("out-of-bounds chipmem write, %04X\n", address); } // @@ -405,68 +512,97 @@ static inline void ne2000_chipmem_write_w(uint32_t address, uint16_t value, ne20 // after that, insw/outsw instructions can be used to move // the appropriate number of bytes to/from the device. // -uint16_t ne2000_dma_read(int io_len, void *p) +uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; + uint32_t retval = 0; + switch (offset) { + case 0x0: // Data register + // + // A read remote-DMA command must have been issued, + // and the source-address and length registers must + // have been initialised. + // + if (io_len > ne2000->remote_bytes) { + pclog("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); + //return 0; + } + + pclog("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); + retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); // // The 8390 bumps the address and decreases the byte count // by the selected word size after every access, not by // the amount of data requested by the host (io_len). // - ne2000->remote_dma += io_len; + if (io_len == 4) { + ne2000->remote_dma += io_len; + } else { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } if (ne2000->remote_dma == ne2000->page_stop << 8) { ne2000->remote_dma = ne2000->page_start << 8; } // keep s.remote_bytes from underflowing - if (ne2000->remote_bytes > 1) - ne2000->remote_bytes -= io_len; + if (ne2000->remote_bytes > ne2000->DCR.wdsize) + if (io_len == 4) { + ne2000->remote_bytes -= io_len; + } else { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } else ne2000->remote_bytes = 0; - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); - } - } - return (0); + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) { + picint(1 << ne2000->base_irq); + } + } + break; + + case 0xf: // Reset register + ne2000_reset(ne2000, BX_RESET_SOFTWARE); + break; + + default: + pclog("asic read invalid address %04x\n", (unsigned) offset); + break; + } + + return (retval); } -uint16_t ne2000_asic_read_w(uint32_t offset, void *p) +void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; - int retval; + pclog("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); + switch (offset) { + case 0x0: // Data register - see asic_read for a description - if (ne2000->DCR.wdsize & 0x01) { - /* 16 bit access */ - retval = ne2000_chipmem_read_w(ne2000->remote_dma, ne2000); - ne2000_dma_read(2, ne2000); - } else { - /* 8 bit access */ - retval = ne2000_chipmem_read_b(ne2000->remote_dma, ne2000); - ne2000_dma_read(1, ne2000); + if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) { + pclog("dma write length %d on byte mode operation\n", io_len); + break; + } + if (ne2000->remote_bytes == 0) { + pclog("dma write, byte count 0\n"); } - pclog("asic read val=0x%04x\n", retval); - - return retval; -} - -void ne2000_dma_write(int io_len, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - - // is this right ??? asic_read uses DCR.wordsize - ne2000->remote_dma += io_len; + ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); + if (io_len == 4) { + ne2000->remote_dma += io_len; + } else { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } if (ne2000->remote_dma == ne2000->page_stop << 8) { ne2000->remote_dma = ne2000->page_start << 8; } - ne2000->remote_bytes -= io_len; + if (io_len == 4) { + ne2000->remote_bytes -= io_len; + } else { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) ne2000->remote_bytes = 0; @@ -474,457 +610,160 @@ void ne2000_dma_write(int io_len, void *p) if (ne2000->remote_bytes == 0) { ne2000->ISR.rdma_done = 1; if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); + picint(1 << ne2000->base_irq); } } -} + break; -void ne2000_asic_write_w(uint32_t offset, uint16_t value, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; + case 0xf: // Reset register + // end of reset pulse + break; - pclog("asic write val=0x%04x\n", value); - - if (ne2000->remote_bytes == 0) - return; - if (ne2000->DCR.wdsize & 0x01) { - /* 16 bit access */ - ne2000_chipmem_write_w(ne2000->remote_dma, value, ne2000); - ne2000_dma_write(2, ne2000); - } else { - /* 8 bit access */ - ne2000_chipmem_write_b(ne2000->remote_dma, value, ne2000); - ne2000_dma_write(1, ne2000); - } -} - -uint8_t ne2000_asic_read_b(uint32_t offset, void *p) -{ - if (offset & 1) - return ne2000_asic_read_w(offset & ~1, p) >> 1; - return ne2000_asic_read_w(offset, p) & 0xff; -} - -void ne2000_asic_write_b(uint32_t offset, uint8_t value, void *p) -{ - if (offset & 1) - ne2000_asic_write_w(offset & ~1, value << 8, p); - else - ne2000_asic_write_w(offset, value, p); -} - -uint16_t ne2000_reset_read(uint32_t offset, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_reset(BX_RESET_SOFTWARE, ne2000); - return 0; -} - -void ne2000_reset_write(uint32_t offset, uint16_t value, void *p) -{ + default: // this is invalid, but happens under win95 device detection + pclog("asic write invalid address %04x, ignoring\n", (unsigned) offset); + break; + } } // -// read_handler/read - i/o 'catcher' function called from BOCHS -// mainline when the CPU attempts a read in the i/o space registered -// by this ne2000 instance +// page0_read/page0_write - These routines handle reads/writes to +// the 'zeroth' page of the DS8390 register file // -uint16_t ne2000_read(uint32_t address, void *p) +uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; - int ret; + uint8_t value = 0; - pclog("read addr %x\n", address); + if (io_len > 1) { + pclog("bad length! page 0 read from register 0x%02x, len=%u\n", offset, + io_len); /* encountered with win98 hardware probe */ + return value; + } - address &= 0xf; - - if (address == 0x00) { - ret = - (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); - pclog("read CR returns 0x%08x\n", ret); - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - pclog("page 0 read from port %04x\n", address); - - switch (address) { + switch (offset) { case 0x1: // CLDA0 - return (ne2000->local_dma & 0xff); + value = (ne2000->local_dma & 0xff); break; case 0x2: // CLDA1 - return (ne2000->local_dma >> 8); + value = (ne2000->local_dma >> 8); break; case 0x3: // BNRY - return (ne2000->bound_ptr); + value = ne2000->bound_ptr; break; case 0x4: // TSR - return ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); + value = ((ne2000->TSR.ow_coll << 7) | + (ne2000->TSR.cd_hbeat << 6) | + (ne2000->TSR.fifo_ur << 5) | + (ne2000->TSR.no_carrier << 4) | + (ne2000->TSR.aborted << 3) | + (ne2000->TSR.collided << 2) | + (ne2000->TSR.tx_ok)); break; case 0x5: // NCR - return (ne2000->num_coll); + value = ne2000->num_coll; break; case 0x6: // FIFO // reading FIFO is only valid in loopback mode pclog("reading FIFO not supported yet\n"); - return (ne2000->fifo); + value = ne2000->fifo; break; case 0x7: // ISR - return ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); + value = ((ne2000->ISR.reset << 7) | + (ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); break; case 0x8: // CRDA0 - return (ne2000->remote_dma & 0xff); + value = (ne2000->remote_dma & 0xff); break; case 0x9: // CRDA1 - return (ne2000->remote_dma >> 8); + value = (ne2000->remote_dma >> 8); break; - case 0xa: // reserved - pclog("reserved read - page 0, 0xa\n"); - if (network_card_current == 2) return ne2000->i8029id0; - return (0xff); + case 0xa: // reserved / RTL8029ID0 + if (network_card_current == 2) { + value = 0x50; + } else { + pclog("reserved read - page 0, 0xa\n"); + value = 0xff; + } break; - case 0xb: // reserved - pclog("reserved read - page 0, 0xb\n"); - if (network_card_current == 2) return ne2000->i8029id1; - return (0xff); + case 0xb: // reserved / RTL8029ID1 + if (network_card_current == 2) { + value = 0x43; + } else { + pclog("reserved read - page 0, 0xb\n"); + value = 0xff; + } break; case 0xc: // RSR - return ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); + value = ((ne2000->RSR.deferred << 7) | + (ne2000->RSR.rx_disabled << 6) | + (ne2000->RSR.rx_mbit << 5) | + (ne2000->RSR.rx_missed << 4) | + (ne2000->RSR.fifo_or << 3) | + (ne2000->RSR.bad_falign << 2) | + (ne2000->RSR.bad_crc << 1) | + (ne2000->RSR.rx_ok)); break; case 0xd: // CNTR0 - return (ne2000->tallycnt_0); + value = ne2000->tallycnt_0; break; case 0xe: // CNTR1 - return (ne2000->tallycnt_1); + value = ne2000->tallycnt_1; break; case 0xf: // CNTR2 - return (ne2000->tallycnt_2); + value = ne2000->tallycnt_2; break; + + default: + pclog("page 0 register 0x%02x out of range\n", offset); + break; } - return(0); - break; - - case 0x01: - pclog("page 1 read from port %04x\n", address); - - switch (address) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - return (ne2000->physaddr[address - 1]); - break; - - case 0x7: // CURR - pclog("returning current page: %02x\n", (ne2000->curr_page)); - return (ne2000->curr_page); - - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - return (ne2000->mchash[address - 8]); - break; - } - - return (0); - break; - - case 0x02: - pclog("page 2 read from port %04x\n", address); - - switch (address) { - case 0x1: // PSTART - return (ne2000->page_start); - break; - - case 0x2: // PSTOP - return (ne2000->page_stop); - break; - - case 0x3: // Remote Next-packet pointer - return (ne2000->rempkt_ptr); - break; - - case 0x4: // TPSR - return (ne2000->tx_page_start); - break; - - case 0x5: // Local Next-packet pointer - return (ne2000->localpkt_ptr); - break; - - case 0x6: // Address counter (upper) - return (ne2000->address_cnt >> 8); - break; - - case 0x7: // Address counter (lower) - return (ne2000->address_cnt & 0xff); - break; - - case 0x8: // Reserved - case 0x9: - case 0xa: - case 0xb: - pclog("reserved read - page 2, 0x%02x\n", address); - break; - - case 0xc: // RCR - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); - break; - - case 0xd: // TCR - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); - break; - - case 0xe: // DCR - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); - break; - - case 0xf: // IMR - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - break; - } - break; - - case 3: - if (network_card_current == 1) fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - - switch(address) - { - case 0: - return ne2000->cr; - case 1: - return ne2000->i9346cr; - case 3: - return ne2000->config0; - case 5: - return ne2000->config2; - case 6: - return ne2000->config3; - case 9: - return 0xFF; - case 0xE: - return ne2000->i8029asid0; - case 0xF: - return ne2000->i8029asid1; - } - break; - - default: - fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - } - } - return ret; + pclog("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); + return value; } -// -// write_handler/write - i/o 'catcher' function called from BOCHS -// mainline when the CPU attempts a write in the i/o space registered -// by this ne2000 instance -// -void ne2000_write(uint32_t address, uint16_t value, void *p) +void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; - - pclog("write address %x, val=%x\n", address, value); - - address &= 0xf; - - // - // The high 16 bytes of i/o space are for the ne2000 asic - - // the low 16 bytes are for the DS8390, with the current - // page being selected by the PS0,PS1 registers in the - // command register - // - if (address == 0x00) { - pclog("wrote 0x%02x to CR\n", value); - - // Validate remote-DMA - if ((value & 0x38) == 0x00) { - pclog("CR write - invalid rDMA value 0\n"); - value |= 0x20; /* dma_cmd == 4 is a safe default */ - //value = 0x22; /* dma_cmd == 4 is a safe default */ - } - - // Check for s/w reset - if (value & 0x01) { - ne2000->ISR.reset = 1; - ne2000->CR.stop = 1; - } else { - ne2000->CR.stop = 0; - } - - ne2000->CR.rdma_cmd = (value & 0x38) >> 3; - - // If start command issued, the RST bit in the ISR - // must be cleared - if ((value & 0x02) && !ne2000->CR.start) { - ne2000->ISR.reset = 0; - } - - ne2000->CR.start = ((value & 0x02) == 0x02); - ne2000->CR.pgsel = (value & 0xc0) >> 6; - - // Check for send-packet command - if (ne2000->CR.rdma_cmd == 3) { - // Set up DMA read from receive ring - ne2000->remote_start = ne2000->remote_dma = - ne2000->bound_ptr * 256; - ne2000->remote_bytes = *((uint16_t*) & - ne2000->mem[ne2000->bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]); - pclog("Sending buffer #x%x length %d\n", - ne2000->remote_start, - ne2000->remote_bytes); - } - - // Check for start-tx - if ((value & 0x04) && ne2000->TCR.loop_cntl) { - // loopback mode - if (ne2000->TCR.loop_cntl != 1) { - pclog("Loop mode %d not supported.\n", ne2000->TCR.loop_cntl); - } else { - ne2000_rx_frame (ne2000, &ne2000->mem[ne2000->tx_page_start*256 - - BX_NE2K_MEMSTART], - ne2000->tx_bytes); - - // do a TX interrupt - // Generate an interrupt if not masked and not one in progress - if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { - //LOG_MSG("tx complete interrupt"); - picint(1 << ne2000->base_irq); - } - ne2000->ISR.pkt_tx = 1; - } - } else if (value & 0x04) { - // start-tx and no loopback - if (ne2000->CR.stop || !ne2000->CR.start) - pclog("CR write - tx start, dev in reset\n"); - - if (ne2000->tx_bytes == 0) - pclog("CR write - tx start, tx bytes == 0\n"); - - // Send the packet to the system driver - /* TODO: Transmit packet */ - //BX_NE2K_THIS ethdev->sendpkt(& ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - //pcap_sendpacket(adhandle,&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); -if(net_is_slirp) { - slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - pclog("ne2000 slirp sending packet\n"); - } -if(net_is_pcap && net_pcap!=NULL) { - _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - pclog("ne2000 pcap sending packet\n"); - } - - ne2000_tx_event(value, ne2000); - // Schedule a timer to trigger a tx-complete interrupt - // The number of microseconds is the bit-time / 10. - // The bit-time is the preamble+sfd (64 bits), the - // inter-frame gap (96 bits), the CRC (4 bytes), and the - // the number of bits in the frame (s.tx_bytes * 8). - // - - /* TODO: Code transmit timer */ - /* - bx_pc_system.activate_timer(ne2000->tx_timer_index, - (64 + 96 + 4*8 + ne2000->tx_bytes*8)/10, - 0); // not continuous - */ - } // end transmit-start branch - - // Linux probes for an interrupt by setting up a remote-DMA read - // of 0 bytes with remote-DMA completion interrupts enabled. - // Detect this here - if (ne2000->CR.rdma_cmd == 0x01 && - ne2000->CR.start && - ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); - } - } - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - pclog("page 0 write to port %04x\n", address); + uint8_t value2; // It appears to be a common practice to use outw on page0 regs... - switch (address) { + // break up outw into two outb's + if (io_len == 2) { + ne2000_page0_write(ne2000, offset, (value & 0xff), 1); + if (offset < 0x0f) { + ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); + } + return; + } + + pclog("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); + + switch (offset) { case 0x1: // PSTART ne2000->page_start = value; break; case 0x2: // PSTOP - // BX_INFO(("Writing to PSTOP: %02x", value)); ne2000->page_stop = value; break; @@ -952,7 +791,7 @@ if(net_is_pcap && net_pcap!=NULL) { value &= 0x7f; // clear RST bit - status-only bit // All other values are cleared iff the ISR bit is 1 ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); + ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); @@ -973,8 +812,7 @@ if(net_is_pcap && net_pcap!=NULL) { (ne2000->IMR.tx_inte << 1) | (ne2000->IMR.rx_inte)); if (value == 0) - picintc(1 << ne2000->base_irq); - //DEV_pic_lower_irq(ne2000->base_irq); + picintc(1 << ne2000->base_irq); break; case 0x8: // RSAR0 @@ -1036,17 +874,11 @@ if(net_is_pcap && net_pcap!=NULL) { // Inhibit-CRC not supported. if (value & 0x01) - { - //fatal("ne2000 TCR write, inhibit-CRC not supported\n"); - pclog("ne2000 TCR write, inhibit-CRC not supported\n"); - return; - } + pclog("TCR write, inhibit-CRC not supported\n"); // Auto-transmit disable very suspicious - if (value & 0x08) { - //fatal("ne2000 TCR write, auto transmit disable not supported\n"); - pclog("ne2000 TCR write, auto transmit disable not supported\n"); - } + if (value & 0x08) + pclog("TCR write, auto transmit disable not supported\m"); // Allow collision-offset to be set, although not used ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); @@ -1075,7 +907,7 @@ if(net_is_pcap && net_pcap!=NULL) { case 0xf: // IMR // Check for reserved bit - if (value & 0x80) + if (value & 0x80) pclog("IMR write, reserved bit set\n"); // Set other values @@ -1086,25 +918,89 @@ if(net_is_pcap && net_pcap!=NULL) { ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - if(ne2000->ISR.pkt_tx && ne2000->IMR.tx_inte) { - pclog("tx irq retrigger\n"); - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - } + value2 = ((ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + if (((value & value2) & 0x7f) == 0) { + picintc(1 << ne2000->base_irq); + } else { + picint(1 << ne2000->base_irq); + } break; - } - break; - case 0x01: - pclog("page 1 w offset %04x\n", address); - switch (address) { + default: + pclog("page 0 write, bad register 0x%02x\n", offset); + break; + } +} + +// +// page1_read/page1_write - These routines handle reads/writes to +// the first page of the DS8390 register file +// +uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +{ + pclog("page 1 read from register 0x%02x, len=%u\n", offset, io_len); + + switch (offset) { case 0x1: // PAR0-5 case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: - ne2000->physaddr[address - 1] = value; + return (ne2000->physaddr[offset - 1]); + break; + + case 0x7: // CURR + pclog("returning current page: 0x%02x\n", (ne2000->curr_page)); + return (ne2000->curr_page); + + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + return (ne2000->mchash[offset - 8]); + break; + + default: + pclog("page 1 read register 0x%02x out of range\n", offset); + break; + } + + return (0); +} + +void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) +{ + pclog("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, + io_len, value); + + switch (offset) { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + ne2000->physaddr[offset - 1] = value; + if (offset == 6) { + pclog("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", + ne2000->physaddr[0], + ne2000->physaddr[1], + ne2000->physaddr[2], + ne2000->physaddr[3], + ne2000->physaddr[4], + ne2000->physaddr[5]); + } break; case 0x7: // CURR @@ -1119,16 +1015,100 @@ if(net_is_pcap && net_pcap!=NULL) { case 0xd: case 0xe: case 0xf: - ne2000->mchash[address - 8] = value; + ne2000->mchash[offset - 8] = value; break; + + default: + pclog("page 1 write register 0x%02x out of range\n", offset); + break; } - break; +} - case 0x02: - if (address != 0) - pclog("page 2 write ?\n"); +// +// page2_read/page2_write - These routines handle reads/writes to +// the second page of the DS8390 register file +// +uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +{ + pclog("page 2 read from register 0x%02x, len=%u\n", offset, io_len); + + switch (offset) { + case 0x1: // PSTART + return (ne2000->page_start); - switch (address) { + case 0x2: // PSTOP + return (ne2000->page_stop); + + case 0x3: // Remote Next-packet pointer + return (ne2000->rempkt_ptr); + + case 0x4: // TPSR + return (ne2000->tx_page_start); + + case 0x5: // Local Next-packet pointer + return (ne2000->localpkt_ptr); + + case 0x6: // Address counter (upper) + return (ne2000->address_cnt >> 8); + + case 0x7: // Address counter (lower) + return (ne2000->address_cnt & 0xff); + + case 0x8: // Reserved + case 0x9: + case 0xa: + case 0xb: + pclog("reserved read - page 2, register 0x%02x\n", offset); + return (0xff); + + case 0xc: // RCR + return ((ne2000->RCR.monitor << 5) | + (ne2000->RCR.promisc << 4) | + (ne2000->RCR.multicast << 3) | + (ne2000->RCR.broadcast << 2) | + (ne2000->RCR.runts_ok << 1) | + (ne2000->RCR.errors_ok)); + + case 0xd: // TCR + return ((ne2000->TCR.coll_prio << 4) | + (ne2000->TCR.ext_stoptx << 3) | + ((ne2000->TCR.loop_cntl & 0x3) << 1) | + (ne2000->TCR.crc_disable)); + + case 0xe: // DCR + return (((ne2000->DCR.fifo_size & 0x3) << 5) | + (ne2000->DCR.auto_rx << 4) | + (ne2000->DCR.loop << 3) | + (ne2000->DCR.longaddr << 2) | + (ne2000->DCR.endian << 1) | + (ne2000->DCR.wdsize)); + + case 0xf: // IMR + return ((ne2000->IMR.rdma_inte << 6) | + (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | + (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | + (ne2000->IMR.tx_inte << 1) | + (ne2000->IMR.rx_inte)); + + default: + pclog("page 2 register 0x%02x out of range\n", offset); + break; + } + + return (0); +} + +void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) +{ + // Maybe all writes here should be BX_PANIC()'d, since they + // affect internal operation, but let them through for now + // and print a warning. + pclog("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, + io_len, value); + + switch (offset) { case 0x1: // CLDA0 // Clear out low byte and re-insert ne2000->local_dma &= 0xff00; @@ -1146,9 +1126,7 @@ if(net_is_pcap && net_pcap!=NULL) { break; case 0x4: - //fatal("page 2 write to reserved offset 4\n"); - //OS/2 Warp can cause this to freak out. - pclog("ne2000 page 2 write to reserved offset 4\n"); + pclog("page 2 write to reserved register 0x04\n"); break; case 0x5: // Local Next-packet pointer @@ -1175,46 +1153,144 @@ if(net_is_pcap && net_pcap!=NULL) { case 0xd: case 0xe: case 0xf: - //fatal("page 2 write to reserved offset %0x\n", address); - pclog("ne2000 page 2 write to reserved offset %0x\n", address); + pclog("page 2 write to reserved register 0x%02x\n", offset); + break; + default: + pclog("page 2 write, illegal register 0x%02x\n", offset); break; } +} + +// +// page3_read/page3_write - writes to this page are illegal +// +uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +{ + if (network_card_current == 2) { + switch (offset) { + case 0x3: // CONFIG0 + return (0); + case 0x5: // CONFIG2 + return (0x40); + case 0x6: // CONFIG3 + return (0x40); + default: + pclog("page 3 read register 0x%02x attempted\n", offset); + return (0); + } + } else { + pclog("page 3 read register 0x%02x attempted\n", offset); + return (0); + } +} + +void ne2000_page3_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) +{ + pclog("page 3 write register 0x%02x attempted\n", offset); + return; +} + +void ne2000_tx_timer(void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + pclog("tx_timer\n"); + ne2000->CR.tx_packet = 0; + ne2000->TSR.tx_ok = 1; + ne2000->ISR.pkt_tx = 1; + // Generate an interrupt if not masked + if (ne2000->IMR.tx_inte) { + picint(1 << ne2000->base_irq); + } + ne2000->tx_timer_active = 0; +} + +void ne2000_tx_event(void *p, uint32_t val) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_tx_timer(ne2000); +} + +// +// read_handler/read - i/o 'catcher' function called from BOCHS +// mainline when the CPU attempts a read in the i/o space registered +// by this ne2000 instance +// +uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) +{ + pclog("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); + uint32_t retval = 0; + int offset = address - ne2000->base_address; + + if (offset >= 0x10) { + retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); + } else if (offset == 0x00) { + retval = ne2000_read_cr(ne2000); + } else { + switch (ne2000->CR.pgsel) { + case 0x00: + retval = ne2000_page0_read(ne2000, offset, io_len); break; - case 3: - if (network_card_current == 1) - { - pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; - } + case 0x01: + retval = ne2000_page1_read(ne2000, offset, io_len); + break; + + case 0x02: + retval = ne2000_page2_read(ne2000, offset, io_len); + break; + + case 0x03: + retval = ne2000_page3_read(ne2000, offset, io_len); + break; - switch (address) - { - case 0: - ne2000->cr = value; - break; - case 1: - ne2000->i9346cr = value; - break; - case 5: - if ((ne2000->i9346cr & 0xC0) == 0xC0) ne2000->config2 = value; - break; - case 6: - if ((ne2000->i9346cr & 0xC0) == 0xC0) ne2000->config3 = value; - break; - case 9: - ne2000->hltclk = value; - break; - } - break; - default: - //fatal("ne2K: unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + pclog("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + break; + } + } + + return (retval); +} + +void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) +{ + pclog("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); + int offset = address - ne2000->base_address; + + // + // The high 16 bytes of i/o space are for the ne2000 asic - + // the low 16 bytes are for the DS8390, with the current + // page being selected by the PS0,PS1 registers in the + // command register + // + if (offset >= 0x10) { + ne2000_asic_write(ne2000, offset - 0x10, value, io_len); + } else if (offset == 0x00) { + ne2000_write_cr(ne2000, value); + } else { + switch (ne2000->CR.pgsel) { + case 0x00: + ne2000_page0_write(ne2000, offset, value, io_len); + break; + + case 0x01: + ne2000_page1_write(ne2000, offset, value, io_len); break; + + case 0x02: + ne2000_page2_write(ne2000, offset, value, io_len); + break; + + case 0x03: + ne2000_page3_write(ne2000, offset, value, io_len); + break; + + default: + pclog("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; } - } + } } /* @@ -1386,29 +1462,49 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) } -void ne2000_tx_timer(void *p) +uint8_t ne2000_readb(uint32_t addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - - pclog("tx_timer\n"); - ne2000->TSR.tx_ok = 1; - // Generate an interrupt if not masked and not one in progress - if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { - //LOG_MSG("tx complete interrupt"); - picint(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); - } //else LOG_MSG("no tx complete interrupt"); - ne2000->ISR.pkt_tx = 1; - ne2000->tx_timer_active = 0; + ne2000_t *ne2000 = (ne2000_t *)p; + return ne2000_read(ne2000, addr, 1); } -static void ne2000_tx_event(int val, void *p) +uint16_t ne2000_readw(uint32_t addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_tx_timer(ne2000); + ne2000_t *ne2000 = (ne2000_t *)p; + if (ne2000->DCR.wdsize & 1) + return ne2000_read(ne2000, addr, 2); + else + return ne2000_read(ne2000, addr, 1); } -static void ne2000_poller(void *p) +uint32_t ne2000_readl(uint32_t addr, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + return ne2000_read(ne2000, addr, 4); +} + +void ne2000_writeb(uint32_t addr, uint8_t val, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_write(ne2000, addr, val, 1); +} + +void ne2000_writew(uint32_t addr, uint16_t val, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + if (ne2000->DCR.wdsize & 1) + ne2000_write(ne2000, addr, val, 2); + else + ne2000_write(ne2000, addr, val, 1); +} + +void ne2000_writel(uint32_t addr, uint32_t val, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_write(ne2000, addr, val, 4); +} + +void ne2000_poller(void *p) { ne2000_t *ne2000 = (ne2000_t *)p; struct queuepacket *qp; @@ -1452,23 +1548,33 @@ if(net_is_pcap && net_pcap!=NULL) } } - -uint16_t io_base = 0x300; +typedef union +{ + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; uint8_t ne2000_pci_regs[256]; +bar_t ne2000_pci_bar[2]; + +int bios_addr = 0xD0000; + +uint32_t bios_size = 0; +uint32_t bios_mask = 0; + void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) -{ - io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); +{ + io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writeb, ne2000_writel, ne2000); } void ne2000_io_remove(uint16_t addr, ne2000_t *ne2000) { - io_removehandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); } uint8_t ne2000_pci_read(int func, int addr, void *p) @@ -1490,7 +1596,7 @@ uint8_t ne2000_pci_read(int func, int addr, void *p) case 0x2F: return 0x11; case 0x04: - return ne2000_pci_regs[0x04] & 3; /*Respond to IO and memory accesses*/ + return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ case 0x05: return ne2000_pci_regs[0x05]; @@ -1502,31 +1608,25 @@ uint8_t ne2000_pci_read(int func, int addr, void *p) case 0x0B: return ne2000_pci_regs[0x0B]; case 0x10: return 1; /*I/O space*/ - case 0x11: return ne2000_pci_regs[0x11]; - case 0x12: return ne2000_pci_regs[0x12]; - case 0x13: return ne2000_pci_regs[0x13]; + case 0x11: return ne2000_pci_bar[0].addr_regs[1]; + case 0x12: return ne2000_pci_bar[0].addr_regs[2]; + case 0x13: return ne2000_pci_bar[0].addr_regs[3]; - case 0x30: return ne2000_pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return (ne2000_pci_regs[0x31] & 0xE0) | 0x18; - case 0x32: return ne2000_pci_regs[0x32]; - case 0x33: return ne2000_pci_regs[0x33]; + case 0x30: return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + // case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & 0xE0) | 0x18; + case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; + case 0x32: return ne2000_pci_bar[1].addr_regs[2]; + case 0x33: return ne2000_pci_bar[1].addr_regs[3]; case 0x3C: return ne2000_pci_regs[0x3C]; case 0x3D: return ne2000_pci_regs[0x3D]; - - default: return 0; } return 0; } -int bios_addr = 0xD0000; - void ne2000_update_bios(ne2000_t *ne2000) { int reg_bios_enable; - FILE *f; - int filelen; - struct stat st; // reg_bios_enable = ne2000_pci_regs[0x30]; reg_bios_enable = 1; @@ -1535,14 +1635,13 @@ void ne2000_update_bios(ne2000_t *ne2000) if (!disable_netbios && reg_bios_enable) { mem_mapping_enable(&ne2000->bios_rom.mapping); - mem_mapping_set_addr(&ne2000->bios_rom.mapping, bios_addr, 0x8000); + mem_mapping_set_addr(&ne2000->bios_rom.mapping, bios_addr, 0x10000); pclog("Network BIOS now at: %08X\n", bios_addr); - // if (network_card_current == 2) *(uint32_t *) &(ne2000_pci_regs[0x30]) = bios_addr | 0x1801; } else { mem_mapping_disable(&ne2000->bios_rom.mapping); - if (network_card_current == 2) *(uint32_t *) &(ne2000_pci_regs[0x30]) = 0; + if (network_card_current == 2) ne2000_pci_bar[1].addr = 0; } } @@ -1550,23 +1649,14 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) { ne2000_t *ne2000 = (ne2000_t *) p; - uint32_t ba1, ba2, ba3, ba4; - // pclog("ne2000_pci_write: addr=%02x val=%02x\n", addr, val); switch (addr) { case 0x04: - ne2000_pci_regs[0x04] = val & 3; if (val & PCI_COMMAND_IO) - { - if (io_base >= 0x280) - { - ne2000_io_set(io_base, ne2000); - ne2000_reset(BX_RESET_SOFTWARE, ne2000); - } - } + ne2000_io_set(ne2000->base_address, ne2000); else - if (io_base >= 0x280) ne2000_io_remove(io_base, ne2000); + ne2000_io_remove(ne2000->base_address, ne2000); break; case 0x10: @@ -1575,27 +1665,23 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) case 0x11: case 0x12: case 0x13: /* I/O Base set. */ /* First, remove the old I/O, if old base was >= 0x280. */ - if (io_base < 0x280) ne2000_io_remove(io_base, ne2000); + ne2000_io_remove(ne2000->base_address, ne2000); /* Then let's set the PCI regs. */ - ne2000_pci_regs[addr] = val; + ne2000_pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - // io_base = (uint16_t) ((*(uint32_t *) (&ne2000_pci_regs[0x10])) & 0xff00); - io_base = (*(uint32_t *) (&ne2000_pci_regs[0x10])) & 0xff00; + ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; /* If the base is below 0x280, return. */ - if (io_base < 0x280) return; - /* Set new I/O base. */ - ne2000_io_set(io_base, ne2000); /* Log the new base. */ - // pclog("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , io_base); + pclog("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); /* We're done, so get out of the here. */ return; - + case 0x30: case 0x31: case 0x32: case 0x33: - ne2000_pci_regs[addr] = val/* | ((addr == 0x30) ? 1 : 0)*/; - bios_addr = (*(uint32_t *) (&ne2000_pci_regs[0x30])) & 0x000f8000; - (*(uint32_t *) (&ne2000_pci_regs[0x30])) &= 0x000f8000; - (*(uint32_t *) (&ne2000_pci_regs[0x30])) |= 0x1801; - // bios_addr = ((ne2000_pci_regs[0x31] & 0x00) << 8) | (ne2000_pci_regs[0x32] << 16) | (ne2000_pci_regs[0x33] << 24); + ne2000_pci_bar[1].addr_regs[addr & 3] = val; + ne2000_pci_bar[1].addr_regs[1] &= bios_mask; + bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; + ne2000_pci_bar[1].addr &= 0xffffe000; + ne2000_pci_bar[1].addr |= 0x1801; ne2000_update_bios(ne2000); return; @@ -1605,54 +1691,41 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) { pclog("NE2000 IRQ now: %i\n", val); ne2000_setirq(ne2000, val); - ne2000_reset(BX_RESET_SOFTWARE, ne2000); } return; } } -void rtl8029as_init(ne2000_t *ne2000) +void ne2000_rom_init(ne2000_t *ne2000, char *s) { - pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + FILE *f = fopen(s, "rb"); + uint32_t temp; + if(!f) + { + disable_netbios = 1; + ne2000_update_bios(ne2000); + return; + } + fseek(f, 0, SEEK_END); + temp = ftell(f); + fclose(f); + bios_size = 0x10000; + if (temp <= 0x8000) + { + bios_size = 0x8000; + } + if (temp <= 0x4000) + { + bios_size = 0x4000; + } + if (temp <= 0x2000) + { + bios_size = 0x2000; + } + bios_mask = (bios_size >> 8) & 0xff; + bios_mask = (0x100 - bios_mask) & 0xff; - memset(ne2000_pci_regs, 0, 256); - - ne2000_pci_regs[0x04] = 3; - ne2000_pci_regs[0x05] = 0; - - ne2000_pci_regs[0x07] = 2; - - /* Network controller. */ - ne2000_pci_regs[0x0B] = 2; - - *(uint32_t *) &(ne2000_pci_regs[0x10]) = 0x0000FF01; - ne2000_io_set(io_base, ne2000); - - *(uint32_t *) &(ne2000_pci_regs[0x30]) = 0x000F8000 | 0x1801; - bios_addr = 0xD0000; - - if (disable_netbios) ne2000_pci_regs[0x33] = 0x00; - - ne2000_pci_regs[0x3C] = 10; - ne2000_pci_regs[0x3D] = 1; - - memset(rtl8029as_eeprom, 0, 128); - rtl8029as_eeprom[0x76] = rtl8029as_eeprom[0x7A] = rtl8029as_eeprom[0x7E] = 0x29; - rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; - rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; - rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; - - ne2000->i8029id0 = 0x50; - ne2000->i8029id1 = 0x43; - - ne2000->cr = 0x21; - ne2000->i9346cr = 0; - ne2000->config0 = 0; - ne2000->config2 = 3; - ne2000->config3 = 0; - ne2000->hltclk = 0x52; - ne2000->i8029asid0 = 0x29; - ne2000->i8029asid1 = 0x80; + rom_init(&ne2000->bios_rom, s, 0xd0000, bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); } void *ne2000_init() @@ -1660,15 +1733,12 @@ void *ne2000_init() int rc; int config_net_type; int net_type; - uint16_t addr = 0xC000; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); - if (network_card_current == 1) addr = device_get_config_int("addr"); + ne2000->base_address = device_get_config_int("addr"); disable_netbios = device_get_config_int("disable_netbios"); - io_base = addr; - if (network_card_current == 1) ne2000_setirq(ne2000, device_get_config_int("irq")); + ne2000_setirq(ne2000, device_get_config_int("irq")); //net_type //0 pcap @@ -1689,29 +1759,16 @@ void *ne2000_init() net_is_pcap = 1; } - ne2000_io_set(addr, ne2000); - memcpy(ne2000->physaddr, maclocal, 6); + ne2000_io_set(ne2000->base_address, ne2000); + memcpy(ne2000->physaddr, maclocal, 6); if (!disable_netbios) - { - if (network_card_current == 2) - { - rtl8029as_init(ne2000); - rom_init(&ne2000->bios_rom, "roms/rtl8029as.rom", 0xd0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ne2000_rom_init(ne2000, "roms/ne2000.rom"); - if (PCI) - mem_mapping_disable(&ne2000->bios_rom.mapping); - } - else - { - rom_init(&ne2000->bios_rom, "roms/ne2000.rom", 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - } - } - - ne2000_reset(BX_RESET_HARDWARE, ne2000); + ne2000_reset(ne2000, BX_RESET_HARDWARE); vlan_handler(ne2000_poller, ne2000); - pclog("ne2000 init 0x%X %d\tslirp is %d net_is_pcap is %d\n",addr,device_get_config_int("irq"),net_is_slirp,net_is_pcap); + pclog("ne2000 isa init 0x%X %d\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,device_get_config_int("irq"),net_is_slirp,net_is_pcap); //need a switch statment for more network types. @@ -1845,24 +1902,239 @@ pclog("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); return ne2000; } +void *rtl8029as_init() +{ + int rc; + int config_net_type; + int net_type; + ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); + memset(ne2000, 0, sizeof(ne2000_t)); + + disable_netbios = device_get_config_int("disable_netbios"); + ne2000_setirq(ne2000, 10); + + //net_type + //0 pcap + //1 slirp + // + config_net_type = device_get_config_int("net_type"); + // net_is_slirp = config_get_int(NULL, "net_type", 1); + /* Network type is now specified in device config. */ + net_is_slirp = config_net_type ? 1 : 0; + // pclog("ne2000 pcap device %s\n",config_get_string(NULL,"pcap_device","nothing")); + + //Check that we have a string setup, otherwise turn pcap off + if(!strcmp("nothing",config_get_string(NULL,"pcap_device","nothing"))) { + net_is_pcap = 0; + } + else { + if( net_is_slirp == 0) + net_is_pcap = 1; + } + + pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + + if (!disable_netbios) + { + ne2000_rom_init(ne2000, "roms/rtl8029as.rom"); + + if (PCI) mem_mapping_disable(&ne2000->bios_rom.mapping); + } + + ne2000_pci_regs[0x04] = 1; + ne2000_pci_regs[0x05] = 0; + + ne2000_pci_regs[0x07] = 2; + + /* Network controller. */ + ne2000_pci_regs[0x0B] = 2; + + ne2000_pci_bar[0].addr_regs[0] = 1; + + if (disable_netbios) + { + ne2000_pci_bar[1].addr = 0; + bios_addr = 0; + } + else + { + ne2000_pci_bar[1].addr = 0x000F8000; + ne2000_pci_bar[1].addr_regs[1] = bios_mask; + ne2000_pci_bar[1].addr |= 0x1801; + bios_addr = 0xD0000; + } + + ne2000_pci_regs[0x3C] = 10; + ne2000_pci_regs[0x3D] = 1; + + memset(rtl8029as_eeprom, 0, 128); + rtl8029as_eeprom[0x76] = rtl8029as_eeprom[0x7A] = rtl8029as_eeprom[0x7E] = 0x29; + rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; + rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; + rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; + + ne2000->base_address = 0x340; + ne2000_io_set(ne2000->base_address, ne2000); + + memcpy(ne2000->physaddr, maclocal, 6); + + ne2000_reset(ne2000, BX_RESET_HARDWARE); + vlan_handler(ne2000_poller, ne2000); + + pclog("ne2000 pci init 0x%X\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,net_is_slirp,net_is_pcap); + + //need a switch statment for more network types. + + if ( net_is_slirp ) { + pclog("ne2000 initalizing SLiRP\n"); + net_is_pcap=0; + rc=slirp_init(); + pclog("ne2000 slirp_init returned: %d\n",rc); + if ( rc == 0 ) + { + pclog("ne2000 slirp initalized!\n"); + + net_slirp_inited=1; + slirpq = QueueCreate(); + net_is_slirp=1; + fizz=0; + pclog("ne2000 slirpq is %x\n",&slirpq); + } + else { + net_slirp_inited=0; + net_is_slirp=0; + } + } + if ( net_is_pcap ) { //pcap + char errbuf[32768]; + + pclog("ne2000 initalizing libpcap\n"); + net_is_slirp=0; + net_hLib = LoadLibraryA(net_lib_name); + if(net_hLib==0) + { + pclog("ne2000 Failed to load %s\n",net_lib_name); + net_is_pcap=0; + //return; + } + _pcap_lib_version =(PCAP_LIB_VERSION)GetProcAddress(net_hLib,"pcap_lib_version"); + _pcap_open_live=(PCAP_OPEN_LIVE)GetProcAddress(net_hLib,"pcap_open_live"); + _pcap_sendpacket=(PCAP_SENDPACKET)GetProcAddress(net_hLib,"pcap_sendpacket"); + _pcap_setnonblock=(PCAP_SETNONBLOCK)GetProcAddress(net_hLib,"pcap_setnonblock"); + _pcap_next=(PCAP_NEXT)GetProcAddress(net_hLib,"pcap_next"); + _pcap_close=(PCAP_CLOSE)GetProcAddress(net_hLib,"pcap_close"); + _pcap_getnonblock=(PCAP_GETNONBLOCK)GetProcAddress(net_hLib,"pcap_getnonblock"); + _pcap_compile=(PCAP_COMPILE)GetProcAddress(net_hLib,"pcap_compile"); + _pcap_setfilter=(PCAP_SETFILTER)GetProcAddress(net_hLib,"pcap_setfilter"); + + if(_pcap_lib_version && _pcap_open_live && _pcap_sendpacket && _pcap_setnonblock && _pcap_next && _pcap_close && _pcap_getnonblock) + { + pclog("ne2000 Pcap version [%s]\n",_pcap_lib_version()); + + //if((net_pcap=_pcap_open_live("\\Device\\NPF_{0CFA803F-F443-4BB9-A83A-657029A98195}",1518,1,15,errbuf))==0) + if((net_pcap=_pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) + { + pclog("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); + net_is_pcap=0; return(ne2000); //YUCK!!! + } + } + else { + pclog("%d %d %d %d %d %d %d\n",_pcap_lib_version, _pcap_open_live,_pcap_sendpacket,_pcap_setnonblock,_pcap_next,_pcap_close,_pcap_getnonblock); + net_is_pcap=1; + } + + //Time to check that we are in non-blocking mode. + rc=_pcap_getnonblock(net_pcap,errbuf); + pclog("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); + switch(rc) + { + case 0: + pclog("ne2000 Setting interface to non-blocking mode.."); + rc=_pcap_setnonblock(net_pcap,1,errbuf); + if(rc==0) { //no errors! + pclog(".."); + rc=_pcap_getnonblock(net_pcap,errbuf); + if(rc==1) { + pclog("..!",rc); + net_is_pcap=1; + } + else{ + pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap=0; + } + }//end set nonblock + else{pclog("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} + pclog("\n"); + break; + case 1: + pclog("non blocking\n"); + break; + default: + pclog("this isn't right!!!\n"); + net_is_pcap=0; + break; + } + if( net_is_pcap ) { + if(_pcap_compile && _pcap_setfilter) { //we can do this! + struct bpf_program fp; + char filter_exp[255]; + pclog("ne2000 Building packet filter..."); + sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); + + //I'm doing a MAC level filter so TCP/IP doesn't matter. + if (_pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { + pclog("\nne2000 Couldn't compile filter\n"); + } + else { + pclog("..."); + if (_pcap_setfilter(net_pcap, &fp) == -1) { + pclog("\nError installing pcap filter.\n"); + }//end of set_filter failure + else { + pclog("...!\n"); + } + } + pclog("ne2000 Using filter\t[%s]\n",filter_exp); + //scanf(filter_exp); //pause + } + else + { + pclog("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); + net_is_pcap=0; + } + pclog("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); + } + } //end pcap setup + + //timer_add(slirp_tic,&delay,TIMER_ALWAYS_ENABLED,NULL); + //timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); +pclog("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); +//exit(0); +return ne2000; +} + + void ne2000_close(void *p) { ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_io_remove(io_base, ne2000); + ne2000_io_remove(ne2000->base_address, ne2000); free(ne2000); -if(net_is_slirp) { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - pclog("ne2000 exiting slirp\n"); - } -if(net_is_pcap && net_pcap!=NULL) - { - _pcap_close(net_pcap); - FreeLibrary(net_hLib); - pclog("ne2000 closing pcap\n"); - } -pclog("ne2000 close\n"); + + if(net_is_slirp) { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited=0; + pclog("ne2000 exiting slirp\n"); + } + if(net_is_pcap && net_pcap!=NULL) + { + _pcap_close(net_pcap); + FreeLibrary(net_hLib); + pclog("ne2000 closing pcap\n"); + } + pclog("ne2000 close\n"); } static device_config_t ne2000_config[] = @@ -2049,7 +2321,7 @@ device_t rtl8029as_device = { "Realtek RTL8029AS", 0, - ne2000_init, + rtl8029as_init, ne2000_close, NULL, NULL, diff --git a/src/pc.rc b/src/pc.rc index 8b1143c62..7d8408517 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -123,13 +123,13 @@ BEGIN COMBOBOX IDC_COMBODRB,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END -HdConfDlg DIALOGEX 0, 0, 210, 310+4*16 +HdConfDlg DIALOGEX 0, 0, 210, 286+4*16 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure Hard Discs" - FONT 8, "MS Sans Serif" + FONT 9, "Segoe UI" BEGIN - DEFPUSHBUTTON "OK",IDOK,31+12,290+64,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101+12,290+64,50,14 + DEFPUSHBUTTON "OK",IDOK,31+12,264+64,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101+12,264+64,50,14 LTEXT "C:",IDC_STATIC,7,6,27,10 RADIOBUTTON "Hard drive", IDC_CHDD, 7+64, 6, 53, 12 , WS_TABSTOP @@ -198,8 +198,8 @@ HdConfDlg DIALOGEX 0, 0, 210, 310+4*16 LTEXT "G:",IDC_STATIC,7,222+64,27,10 RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+128, 222+64, 53, 12 , WS_TABSTOP - LTEXT "H:",IDC_STATIC,7,262+64,27,10 - RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, 262+64, 53, 12 , WS_TABSTOP + LTEXT "H:",IDC_STATIC,7,238+64,27,10 + RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, 238+64, 53, 12 , WS_TABSTOP END diff --git a/src/pic.c b/src/pic.c index e3549f71c..47ac02a63 100644 --- a/src/pic.c +++ b/src/pic.c @@ -105,7 +105,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) { if (val&16) /*ICW1*/ { - pic.mask=0xFF; + pic.mask=0; pic.mask2=0; pic.icw=1; pic.icw1=val; @@ -222,7 +222,7 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv) { if (val&16) /*ICW1*/ { - pic2.mask=0xFF; + pic2.mask=0; pic2.mask2=0; pic2.icw=1; pic2.icw1=val; diff --git a/src/vid_svga.c b/src/vid_svga.c index 160d19430..f75a3a381 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -43,6 +43,19 @@ void svga_set_override(svga_t *svga, int val) svga->override = val; } +typedef union pci_bar +{ + uint16_t word; + uint8_t bytes[2]; +} ichar; + +ichar char12x24[65536][48]; +uint8_t charedit_on = 0; +ichar charcode; +uint8_t charmode = 0; +uint8_t charptr = 0; +uint8_t charsettings = 0xEE; + void svga_out(uint16_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -51,6 +64,40 @@ void svga_out(uint16_t addr, uint8_t val, void *p) // printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { + case 0x32CB: + printf("Write 32CB: %04X\n", val); + charedit_on = (val & 0x10) ? 1 : 0; + charsettings = val; + return; + + case 0x22CB: + printf("Write 22CB: %04X\n", val); + charmode = val; + charptr = 0; + return; + + case 0x22CF: + printf("Write 22CF: %04X\n", val); + // if (!charedit_on) return; + switch(charmode) + { + case 1: case 2: + charcode.bytes[charmode - 1] = val; + return; + case 3: case 4: /* Character bitmaps */ + char12x24[charcode.word][charptr].bytes[(charmode & 1) ^ 1] = val; + charptr++; + charptr %= 48; + return; + case 0xAA: default: + return; + } + return; + + case 0x22CA: case 0x22CE: case 0x32CA: + printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); + return; + case 0x3C0: if (!svga->attrff) { @@ -251,6 +298,41 @@ uint8_t svga_in(uint16_t addr, void *p) // if (addr!=0x3da) pclog("Read port %04X\n",addr); switch (addr) { + case 0x22CA: + pclog("Read port %04X\n", addr); + return 0xAA; + case 0x22CB: + pclog("Read port %04X\n", addr); + // return charmode; + return 0xF0 | (charmode & 0x1F); + case 0x22CE: + pclog("Read port %04X\n", addr); + return 0xCC; + case 0x22CF: /* Read character bitmap */ + pclog("Read port %04X\n", addr); + // if (!charedit_on) return 0xFF; + switch(charmode) + { + case 1: case 2: + return charcode.bytes[charmode - 1]; + case 3: case 4: /* Character bitmaps */ + /* Mode 3 is low bytes, mode 4 is high bytes */ + temp = char12x24[charcode.word][charptr].bytes[(charmode & 1) ^ 1]; + charptr++; + charptr %= 48; + return temp; + case 0xAA: default: + return 0xFF; + } + case 0x32CA: + pclog("Read port %04X\n", addr); + return 0xEE; + case 0x32CB: + pclog("Read port %04X\n", addr); + return 0xEE; + return charsettings; + // return 0xEE | (charedit_on ? 0x10 : 0); + case 0x3C0: return svga->attraddr | svga->attr_palette_enable; case 0x3C1: @@ -384,13 +466,29 @@ void svga_recalctimings(svga_t *svga) { if (svga->seqregs[1] & 8) /*40 column*/ { - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + if (svga->hdisp == 120) + { + svga->render = svga_render_text_40_12; + svga->hdisp *= 16; + } + else + { + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + } } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + if (svga->hdisp == 120) + { + svga->render = svga_render_text_80_12; + svga->hdisp *= 8; + } + else + { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } } svga->hdisp_old = svga->hdisp; } @@ -804,6 +902,10 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->ramdac_type = RAMDAC_6BIT; svga_pointer = svga; + + io_sethandler(0x22ca, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga); + io_sethandler(0x22ce, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga); + io_sethandler(0x32ca, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga); return 0; } @@ -1012,6 +1114,13 @@ void svga_write(uint32_t addr, uint8_t val, void *p) svga->gdcreg[8] = wm; break; } + + if (svga->render == svga_render_text_80_12) + { + FILE *f = fopen("hecon.dmp", "wb"); + fwrite(svga->vram, 1, svga->vram_limit, f); + fclose(f); + } } uint8_t svga_read(uint32_t addr, void *p) @@ -1627,6 +1736,9 @@ void svga_add_status_info(char *s, int max_len, void *p) sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); strncat(s, temps, max_len); + sprintf(temps, "SVGA horizontal display : %i\n", svga->hdisp); + strncat(s, temps, max_len); + sprintf(temps, "SVGA refresh rate : %i Hz (%s)\n\n", svga->frames, svga->interlace ? "i" : "p"); svga->frames = 0; strncat(s, temps, max_len); diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index e95700a9c..bfe7e317d 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -101,6 +101,61 @@ void svga_render_text_40(svga_t *svga) } } +void svga_render_text_40_12(svga_t *svga) +{ + int y_add = (enable_overscan) ? 16 : 0; + int x_add = (enable_overscan) ? 12 : 0; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (svga->fullchange) + { + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + int x, xx; + int drawcursor; + uint8_t chr, attr; + uint16_t dat; + uint32_t charaddr; + int fg, bg; + int xinc = 24; + + for (x = 0; x < svga->hdisp; x += xinc) + { + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[svga->ma << 1]; + attr = svga->vram[(svga->ma << 1) + 1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); + else charaddr = svga->charseta + (chr * 128); + + if (drawcursor) + { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } + else + { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) + { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } + + dat = *(uint16_t *) &(svga->vram[charaddr + (svga->sc << 2) - 1]); + for (xx = 0; xx < 24; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x800 >> (xx >> 1))) ? fg : bg; + svga->ma += 4; + p += xinc; + } + svga->ma = svga_mask_addr(svga->ma, svga); + } +} + void svga_render_text_80(svga_t *svga) { FILE *f; @@ -168,6 +223,63 @@ void svga_render_text_80(svga_t *svga) } } +void svga_render_text_80_12(svga_t *svga) +{ + FILE *f; + int y_add = (enable_overscan) ? 16 : 0; + int x_add = (enable_overscan) ? 12 : 0; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (svga->fullchange) + { + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + int x, xx; + int drawcursor; + uint8_t chr, attr; + uint16_t dat; + uint32_t charaddr; + int fg, bg; + int xinc = 12; + + for (x = 0; x < svga->hdisp; x += xinc) + { + drawcursor = ((svga->ma == (svga->ca + 8)) && svga->con && svga->cursoron); + chr = svga->vram[svga->ma << 1]; + attr = svga->vram[(svga->ma << 1) + 1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); + else charaddr = svga->charseta + (chr * 128); + + if (drawcursor) + { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } + else + { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) + { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } + + dat = svga->vram[charaddr + (svga->sc << 2)] << 4; + dat |= ((svga->vram[charaddr + (svga->sc << 2) + 1]) >> 4); + for (xx = 0; xx < 12; xx++) + p[xx] = (dat & (0x800 >> xx)) ? fg : bg; + svga->ma += 4; + p += xinc; + } + svga->ma = svga_mask_addr(svga->ma, svga); + } +} + void svga_render_2bpp_lowres(svga_t *svga) { int changed_offset; diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index 944d9757b..6a9cade17 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -11,7 +11,9 @@ extern uint8_t edatlookup[4][4]; void svga_render_blank(svga_t *svga); void svga_render_text_40(svga_t *svga); +void svga_render_text_40_12(svga_t *svga); void svga_render_text_80(svga_t *svga); +void svga_render_text_80_12(svga_t *svga); void svga_render_2bpp_lowres(svga_t *svga); void svga_render_2bpp_highres(svga_t *svga); diff --git a/src/x86_ops.h b/src/x86_ops.h index 279f62bbf..3bca88270 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -41,7 +41,7 @@ extern OpFn dynarec_ops_k6_0f[1024]; extern OpFn dynarec_ops_c6x86mx_0f[1024]; extern OpFn dynarec_ops_pentiumpro_0f[1024]; -extern OpFn dynarec_ops_pentium2_0f[1024]; +// extern OpFn dynarec_ops_pentium2_0f[1024]; extern OpFn dynarec_ops_pentium2d_0f[1024]; extern OpFn dynarec_ops_fpu_d8_a16[32]; @@ -106,7 +106,7 @@ extern OpFn ops_k6_0f[1024]; extern OpFn ops_c6x86mx_0f[1024]; extern OpFn ops_pentiumpro_0f[1024]; -extern OpFn ops_pentium2_0f[1024]; +// extern OpFn ops_pentium2_0f[1024]; extern OpFn ops_pentium2d_0f[1024]; extern OpFn ops_fpu_d8_a16[32]; diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index 0499ed315..d5efd5a46 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -329,16 +329,16 @@ static int opMOV_a32_EAX(uint32_t fetchdat) static int opLEA_w_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - // ILLEGAL_ON(mod == 3); - cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr; + ILLEGAL_ON(mod == 3); + cpu_state.regs[reg].w = eaaddr; CLOCK_CYCLES(timing_rr); return 0; } static int opLEA_w_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - // ILLEGAL_ON(mod == 3); - cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr; + ILLEGAL_ON(mod == 3); + cpu_state.regs[reg].w = eaaddr; CLOCK_CYCLES(timing_rr); return 0; } @@ -346,16 +346,16 @@ static int opLEA_w_a32(uint32_t fetchdat) static int opLEA_l_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - // ILLEGAL_ON(mod == 3); - cpu_state.regs[reg].l = ((mod == 3) ? cpu_state.last_ea : eaaddr) & 0xffff; + ILLEGAL_ON(mod == 3); + cpu_state.regs[reg].l = eaaddr & 0xffff; CLOCK_CYCLES(timing_rr); return 0; } static int opLEA_l_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - // ILLEGAL_ON(mod == 3); - cpu_state.regs[reg].l = (mod == 3) ? cpu_state.last_ea : eaaddr; + ILLEGAL_ON(mod == 3); + cpu_state.regs[reg].l = eaaddr; CLOCK_CYCLES(timing_rr); return 0; } diff --git a/src/x86seg.c b/src/x86seg.c index d13824eee..db15a713c 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -78,7 +78,7 @@ void x86_doabrt(int x86_abrt) /* if (CS == 0x3433 && cpu_state.pc == 0x000006B0) { - pclog("Quit it\n"); + // pclog("Quit it\n"); dumpregs(); exit(-1); }*/ @@ -260,7 +260,7 @@ void loadseg(uint16_t seg, x86seg *s) { if (s==&_ss) { - pclog("SS selector = NULL!\n"); + // pclog("SS selector = NULL!\n"); x86ss(NULL,0); return; // dumpregs(); @@ -281,7 +281,7 @@ void loadseg(uint16_t seg, x86seg *s) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, rmdat); + // pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, rmdat); // dumppic(); // dumpregs(); // exit(-1); @@ -294,7 +294,7 @@ void loadseg(uint16_t seg, x86seg *s) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X 1\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X 1\n",seg,gdt.limit); // dumpregs(); // exit(-1); x86gpf("loadseg(): Bigger than GDT limit",seg&~3); @@ -312,13 +312,13 @@ void loadseg(uint16_t seg, x86seg *s) { if (!(seg&~3)) { - pclog("Load SS null selector\n"); + // pclog("Load SS null selector\n"); x86gpf(NULL,seg&~3); return; } if ((seg&3)!=CPL || dpl!=CPL) { - pclog("Invalid SS permiss\n"); + // pclog("Invalid SS permiss\n"); x86gpf(NULL,seg&~3); // x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC); return; @@ -328,14 +328,14 @@ void loadseg(uint16_t seg, x86seg *s) case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/ break; default: - pclog("Invalid SS type\n"); + // pclog("Invalid SS type\n"); x86gpf(NULL,seg&~3); // x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); return; } if (!(segdat[2]&0x8000)) { - pclog("Load SS not present!\n"); + // pclog("Load SS not present!\n"); x86ss(NULL,seg&~3); return; } @@ -354,7 +354,7 @@ void loadseg(uint16_t seg, x86seg *s) // pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,cpu_state.pc); if ((seg&3)>dpl || (CPL)>dpl) { - pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]); + // pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]); x86gpf(NULL,seg&~3); // x86abort("Data segment load - level too low!\n",seg&0xFFFC); return; @@ -363,7 +363,7 @@ void loadseg(uint16_t seg, x86seg *s) case 0x1E: case 0x1F: /*Readable conforming code*/ break; default: - pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]); + // pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]); x86gpf(NULL,seg&~3); return; } @@ -418,7 +418,7 @@ void loadcs(uint16_t seg) // pclog("Load CS %04X\n",seg); if (!(seg&~3)) { - pclog("Trying to load CS with NULL selector! lcs\n"); + // pclog("Trying to load CS with NULL selector! lcs\n"); // dumpregs(); // exit(-1); x86gpf(NULL,0); @@ -430,7 +430,7 @@ void loadcs(uint16_t seg) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); + // pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -440,7 +440,7 @@ void loadcs(uint16_t seg) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -451,7 +451,7 @@ void loadcs(uint16_t seg) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return; - if (optype==JMP) pclog("Code seg - %04X - %04X %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2],segdat[3]); + // if (optype==JMP) pclog("Code seg - %04X - %04X %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2],segdat[3]); // if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n"); // if (output) pclog("Segdat2 %04X\n",segdat[2]); if (segdat[2]&0x1000) /*Normal code segment*/ @@ -461,7 +461,7 @@ void loadcs(uint16_t seg) if ((seg&3)>CPL) { x86gpf(NULL,seg&~3); - pclog("loadcs RPL > CPL %04X %04X %i %02X\n",segdat[2],seg,CPL,opcode); + // pclog("loadcs RPL > CPL %04X %04X %i %02X\n",segdat[2],seg,CPL,opcode); return; } if (CPL != DPL) @@ -505,7 +505,7 @@ void loadcs(uint16_t seg) switch (segdat[2]&0xF00) { default: - pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); + // pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); x86gpf(NULL,seg&~3); return; } @@ -539,7 +539,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (!(seg&~3)) { - pclog("Trying to load CS with NULL selector! lcsjmp\n"); + // pclog("Trying to load CS with NULL selector! lcsjmp\n"); x86gpf(NULL,0); return; // dumpregs(); @@ -550,7 +550,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); + // pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -560,7 +560,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -620,7 +620,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) // pclog("System CS\n"); if (!(segdat[2]&0x8000)) { - x86np("Load CS JMP system selector not present\n", seg & 0xfffc); + // x86np("Load CS JMP system selector not present\n", seg & 0xfffc); return; } type=segdat[2]&0xF00; @@ -662,7 +662,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) if (!(seg2&~3)) { - pclog("Trying to load CS with NULL selector! lcsjmpcg\n"); + // pclog("Trying to load CS with NULL selector! lcsjmpcg\n"); x86gpf(NULL,0); return; // dumpregs(); @@ -673,7 +673,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSJ\n",seg2,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X CSJ\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -683,7 +683,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSJ\n",seg2,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CSJ\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -712,7 +712,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if (DPL > CPL) { - pclog("Call gate DPL > CPL"); + // pclog("Call gate DPL > CPL"); x86gpf(NULL,seg2&~3); return; } @@ -731,7 +731,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) break; default: - pclog("JMP Call gate bad segment type\n"); + // pclog("JMP Call gate bad segment type\n"); x86gpf(NULL,seg2&~3); return; } @@ -752,7 +752,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) return; default: - pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); + // pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); x86gpf(NULL,0); return; // dumpregs(); @@ -865,7 +865,7 @@ void loadcscall(uint16_t seg) if (csout) pclog("Protected mode CS load! %04X\n",seg); if (!(seg&~3)) { - pclog("Trying to load CS with NULL selector! lcscall\n"); + // pclog("Trying to load CS with NULL selector! lcscall\n"); x86gpf(NULL,0); return; // dumpregs(); @@ -876,7 +876,7 @@ void loadcscall(uint16_t seg) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSC\n",seg,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X CSC\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -886,7 +886,7 @@ void loadcscall(uint16_t seg) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CSC\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -908,26 +908,26 @@ void loadcscall(uint16_t seg) { if ((seg&3)>CPL) { - /* if (csout) */ pclog("Not conforming, RPL > CPL\n"); + /* if (csout) */ // pclog("Not conforming, RPL > CPL\n"); x86gpf("loadcscall(): segment > CPL",seg&~3); return; } if (CPL != DPL) { - /* if (csout) */ pclog("Not conforming, CPL != DPL (%i %i)\n",CPL,DPL); + /* if (csout) */ // pclog("Not conforming, CPL != DPL (%i %i)\n",CPL,DPL); x86gpf(NULL,seg&~3); return; } } if (CPL < DPL) { - /* if (csout) */ pclog("CPL < DPL\n"); + /* if (csout) */ // pclog("CPL < DPL\n"); x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - /* if (csout) */ pclog("Not present\n"); + /* if (csout) */ // pclog("Not present\n"); x86np("Load CS call not present", seg & 0xfffc); return; } @@ -998,7 +998,7 @@ void loadcscall(uint16_t seg) if (!(seg2&~3)) { - pclog("Trying to load CS with NULL selector! lcscallcg\n"); + // pclog("Trying to load CS with NULL selector! lcscallcg\n"); x86gpf(NULL,0); return; // dumpregs(); @@ -1009,7 +1009,7 @@ void loadcscall(uint16_t seg) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSC\n",seg2,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X CSC\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -1019,7 +1019,7 @@ void loadcscall(uint16_t seg) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n",seg2,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CSC\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -1073,7 +1073,7 @@ void loadcscall(uint16_t seg) if (output) pclog("New stack %04X:%08X\n",newss,newsp); if (!(newss&~3)) { - pclog("Call gate loading null SS\n"); + // pclog("Call gate loading null SS\n"); x86ts(NULL,newss&~3); return; } @@ -1107,7 +1107,7 @@ void loadcscall(uint16_t seg) if (output) pclog("Read stack seg done!\n"); if (((newss & 3) != DPL) || (DPL2 != DPL)) { - pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]); + // pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]); // dumpregs(); // exit(-1); x86ts(NULL,newss&~3); @@ -1115,13 +1115,13 @@ void loadcscall(uint16_t seg) } if ((segdat2[2]&0x1A00)!=0x1200) { - pclog("Call gate loading SS wrong type\n"); + // pclog("Call gate loading SS wrong type\n"); x86ts(NULL,newss&~3); return; } if (!(segdat2[2]&0x8000)) { - pclog("Call gate loading SS not present\n"); + // pclog("Call gate loading SS not present\n"); x86np("Call gate loading SS not present\n", newss & 0xfffc); return; } @@ -1162,7 +1162,7 @@ void loadcscall(uint16_t seg) PUSHL(oldsp2); if (abrt) { - pclog("ABRT PUSHL\n"); + // pclog("ABRT PUSHL\n"); SS = oldss; ESP = oldsp2; return; @@ -1176,7 +1176,7 @@ void loadcscall(uint16_t seg) PUSHL(readmeml(oldssbase,oldsp+(count*4))); if (abrt) { - pclog("ABRT COPYL\n"); + // pclog("ABRT COPYL\n"); SS = oldss; ESP = oldsp2; return; @@ -1195,7 +1195,7 @@ void loadcscall(uint16_t seg) PUSHW(oldsp2); if (abrt) { - pclog("ABRT PUSHW\n"); + // pclog("ABRT PUSHW\n"); SS = oldss; ESP = oldsp2; return; @@ -1213,7 +1213,7 @@ void loadcscall(uint16_t seg) PUSHW(tempw); if (abrt) { - pclog("ABRT COPYW\n"); + // pclog("ABRT COPYW\n"); SS = oldss; ESP = oldsp2; return; @@ -1230,7 +1230,7 @@ void loadcscall(uint16_t seg) } else if (DPL > CPL) { - pclog("Call gate DPL > CPL"); + // pclog("Call gate DPL > CPL"); x86gpf(NULL,seg2&~3); return; } @@ -1260,7 +1260,7 @@ void loadcscall(uint16_t seg) break; default: - pclog("Call gate bad segment type\n"); + // pclog("Call gate bad segment type\n"); x86gpf(NULL,seg2&~3); return; } @@ -1274,7 +1274,7 @@ void loadcscall(uint16_t seg) default: - pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00); + // pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00); x86gpf(NULL,seg&~3); return; // dumpregs(); @@ -1321,7 +1321,7 @@ void pmoderetf(int is32, uint16_t off) if (output) pclog("Return to %04X:%08X\n",seg,newpc); if ((seg&3)=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X RETF\n",seg,ldt.limit); + // pclog("Bigger than LDT limit %04X %04X RETF\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -1353,7 +1353,7 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X RETF\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X RETF\n",seg,gdt.limit); x86gpf(NULL,seg&~3); // dumpregs(); // exit(-1); @@ -1381,7 +1381,7 @@ void pmoderetf(int is32, uint16_t off) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if (CPL != DPL) { - pclog("RETF non-conforming CPL != DPL\n"); + // pclog("RETF non-conforming CPL != DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1390,20 +1390,20 @@ void pmoderetf(int is32, uint16_t off) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if (CPL < DPL) { - pclog("RETF non-conforming CPL < DPL\n"); + // pclog("RETF non-conforming CPL < DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; } break; default: - pclog("RETF CS not code segment\n"); + // pclog("RETF CS not code segment\n"); x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - pclog("RETF CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); + // pclog("RETF CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); ESP=oldsp; x86np("RETF CS not present\n", seg & 0xfffc); return; @@ -1434,7 +1434,7 @@ void pmoderetf(int is32, uint16_t off) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if ((seg&3) != DPL) { - pclog("RETF non-conforming RPL != DPL\n"); + // pclog("RETF non-conforming RPL != DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1444,7 +1444,7 @@ void pmoderetf(int is32, uint16_t off) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((seg&3) < DPL) { - pclog("RETF non-conforming RPL < DPL\n"); + // pclog("RETF non-conforming RPL < DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1452,14 +1452,14 @@ void pmoderetf(int is32, uint16_t off) if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL); break; default: - pclog("RETF CS not code segment\n"); + // pclog("RETF CS not code segment\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - pclog("RETF CS not present! %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); + // pclog("RETF CS not present! %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); ESP=oldsp; x86np("RETF CS not present\n", seg & 0xfffc); @@ -1482,7 +1482,7 @@ void pmoderetf(int is32, uint16_t off) if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); if (!(newss&~3)) { - pclog("RETF loading null SS\n"); + // pclog("RETF loading null SS\n"); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1492,7 +1492,7 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X RETF SS\n",newss,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X RETF SS\n",newss,gdt.limit); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1503,7 +1503,7 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X RETF SS\n",newss,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X RETF SS\n",newss,gdt.limit); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1519,7 +1519,7 @@ void pmoderetf(int is32, uint16_t off) // if (((newss & 3) != DPL) || (DPL2 != DPL)) if ((newss & 3) != (seg & 3)) { - pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg); + // pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg); ESP=oldsp; // output = 3; // dumpregs(); @@ -1529,7 +1529,7 @@ void pmoderetf(int is32, uint16_t off) } if ((segdat2[2]&0x1A00)!=0x1200) { - pclog("RETF loading SS wrong type\n"); + // pclog("RETF loading SS wrong type\n"); ESP=oldsp; // dumpregs(); // exit(-1); @@ -1538,14 +1538,14 @@ void pmoderetf(int is32, uint16_t off) } if (!(segdat2[2]&0x8000)) { - pclog("RETF loading SS not present\n"); + // pclog("RETF loading SS not present\n"); ESP=oldsp; x86np("RETF loading SS not present\n", newss & 0xfffc); return; } if (DPL2 != (seg & 3)) { - pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); + // pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1609,7 +1609,7 @@ void pmodeint(int num, int soft) if (eflags&VM_FLAG && IOPL!=3 && soft) { if (output) pclog("V86 banned int\n"); - pclog("V86 banned int!\n"); + // pclog("V86 banned int!\n"); x86gpf(NULL,0); return; // dumpregs(); @@ -1621,18 +1621,18 @@ void pmodeint(int num, int soft) if (num==8) { /*Triple fault - reset!*/ - pclog("Triple fault!\n"); + // pclog("Triple fault!\n"); // output=1; softresetx86(); } else if (num==0xD) { - pclog("Double fault!\n"); + // pclog("Double fault!\n"); pmodeint(8,0); } else { - pclog("INT out of range\n"); + // pclog("INT out of range\n"); x86gpf(NULL,(num*8)+2+(soft)?0:1); } if (output) pclog("addr >= IDT.limit\n"); @@ -1643,7 +1643,7 @@ void pmodeint(int num, int soft) segdat[0]=readmemw(0,addr); segdat[1]=readmemw(2,addr); segdat[2]=readmemw(4,addr); - segdat[3]=readmemw(6,addr); cpl_override=0; if (abrt) { pclog("Abrt reading from %08X\n",addr); return; } + segdat[3]=readmemw(6,addr); cpl_override=0; if (abrt) { /* pclog("Abrt reading from %08X\n",addr); */ return; } oaddr = addr; if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]); @@ -1668,7 +1668,7 @@ void pmodeint(int num, int soft) // if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,cpu_state.pc); if (!(segdat[2]&0x8000)) { - pclog("Int gate not present\n"); + // pclog("Int gate not present\n"); x86np("Int gate not present\n", (num << 3) | 2); return; } @@ -1681,7 +1681,7 @@ void pmodeint(int num, int soft) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -1691,7 +1691,7 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); + // pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); x86gpf(NULL,seg&~3); return; } @@ -1699,7 +1699,7 @@ void pmodeint(int num, int soft) } /* if ((seg&3) < CPL) { - pclog("INT to higher level\n"); + // pclog("INT to higher level\n"); x86gpf(NULL,seg&~3); return; }*/ @@ -1712,7 +1712,7 @@ void pmodeint(int num, int soft) if (DPL2 > CPL) { - pclog("INT to higher level 2\n"); + // pclog("INT to higher level 2\n"); x86gpf(NULL,seg&~3); return; } @@ -1725,13 +1725,13 @@ void pmodeint(int num, int soft) stack_changed=1; if (!(segdat2[2]&0x8000)) { - pclog("Int gate CS not present\n"); + // pclog("Int gate CS not present\n"); x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } if ((eflags&VM_FLAG) && DPL2) { - pclog("V86 calling int gate, DPL != 0\n"); + // pclog("V86 calling int gate, DPL != 0\n"); x86gpf(NULL,segdat[1]&0xFFFC); return; } @@ -1754,7 +1754,7 @@ void pmodeint(int num, int soft) cpl_override=0; if (!(newss&~3)) { - pclog("Int gate loading null SS\n"); + // pclog("Int gate loading null SS\n"); x86ss(NULL,newss&~3); return; } @@ -1763,7 +1763,7 @@ void pmodeint(int num, int soft) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n",newss,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n",newss,gdt.limit); x86ss(NULL,newss&~3); return; } @@ -1773,7 +1773,7 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); x86ss(NULL,newss&~3); return; } @@ -1786,19 +1786,19 @@ void pmodeint(int num, int soft) segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return; if (((newss & 3) != DPL2) || (DPL3 != DPL2)) { - pclog("Int gate loading SS with wrong permissions\n"); + // pclog("Int gate loading SS with wrong permissions\n"); x86ss(NULL,newss&~3); return; } if ((segdat3[2]&0x1A00)!=0x1200) { - pclog("Int gate loading SS wrong type\n"); + // pclog("Int gate loading SS wrong type\n"); x86ss(NULL,newss&~3); return; } if (!(segdat3[2]&0x8000)) { - pclog("Int gate loading SS not present\n"); + // pclog("Int gate loading SS not present\n"); x86np("Int gate loading SS not present\n", newss & 0xfffc); return; } @@ -1859,20 +1859,20 @@ void pmodeint(int num, int soft) } else if (DPL2!=CPL) { - pclog("Non-conforming int gate DPL != CPL\n"); + // pclog("Non-conforming int gate DPL != CPL\n"); x86gpf(NULL,seg&~3); return; } case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if (!(segdat2[2]&0x8000)) { - pclog("Int gate CS not present\n"); + // pclog("Int gate CS not present\n"); x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } if ((eflags & VM_FLAG) && DPL2=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -1945,7 +1945,7 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); + // pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); x86gpf(NULL,seg&~3); return; } @@ -1959,7 +1959,7 @@ void pmodeint(int num, int soft) cpl_override=0; if (abrt) return; if (!(segdat2[2]&0x8000)) { - pclog("Int task gate not present\n"); + // pclog("Int task gate not present\n"); x86np("Int task gate not present\n", segdat[1] & 0xfffc); return; } @@ -1970,7 +1970,7 @@ void pmodeint(int num, int soft) break; default: - pclog("Bad int gate type %04X %04X %04X %04X %04X\n",segdat[2]&0x1F00,segdat[0],segdat[1],segdat[2],segdat[3]); + // pclog("Bad int gate type %04X %04X %04X %04X %04X\n",segdat[2]&0x1F00,segdat[0],segdat[1],segdat[2],segdat[3]); x86gpf(NULL,seg&~3); return; } @@ -1992,7 +1992,7 @@ void pmodeiret(int is32) // if (output) pclog("V86 IRET\n"); if (IOPL!=3) { - pclog("V86 IRET! IOPL!=3\n"); + // pclog("V86 IRET! IOPL!=3\n"); x86gpf(NULL,0); return; } @@ -2034,7 +2034,7 @@ void pmodeiret(int is32) { if (addr>=ldt.limit) { - pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); + // pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -2044,7 +2044,7 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); + // pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -2129,7 +2129,7 @@ void pmodeiret(int is32) // pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins); if (!(seg&~3)) { - pclog("IRET CS=0\n"); + // pclog("IRET CS=0\n"); ESP = oldsp; // dumpregs(); // exit(-1); @@ -2143,7 +2143,7 @@ void pmodeiret(int is32) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2154,7 +2154,7 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2163,7 +2163,7 @@ void pmodeiret(int is32) } if ((seg&3) < CPL) { - pclog("IRET to lower level\n"); + // pclog("IRET to lower level\n"); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2180,7 +2180,7 @@ void pmodeiret(int is32) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if ((seg&3) != DPL) { - pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); + // pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); ESP = oldsp; // dumpregs(); // exit(-1); @@ -2191,14 +2191,14 @@ void pmodeiret(int is32) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/ if ((seg&3) < DPL) { - pclog("IRET C DPL\n"); + // pclog("IRET C DPL\n"); ESP = oldsp; x86gpf(NULL,seg&~3); return; } break; default: - pclog("IRET CS != code seg\n"); + // pclog("IRET CS != code seg\n"); ESP = oldsp; x86gpf(NULL,seg&~3); // dumpregs(); @@ -2207,7 +2207,7 @@ void pmodeiret(int is32) } if (!(segdat[2]&0x8000)) { - pclog("IRET CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); + // pclog("IRET CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); ESP = oldsp; x86np("IRET CS not present\n", seg & 0xfffc); return; @@ -2248,7 +2248,7 @@ void pmodeiret(int is32) if (!(newss&~3)) { - pclog("IRET loading null SS\n"); + // pclog("IRET loading null SS\n"); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2258,7 +2258,7 @@ void pmodeiret(int is32) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n",newss,gdt.limit); + // pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n",newss,gdt.limit); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2269,7 +2269,7 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X PMODEIRET\n",newss,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X PMODEIRET\n",newss,gdt.limit); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2285,7 +2285,7 @@ void pmodeiret(int is32) // if (((newss & 3) != DPL) || (DPL2 != DPL)) if ((newss & 3) != (seg & 3)) { - pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg); + // pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg); ESP = oldsp; // dumpregs(); // exit(-1); @@ -2294,21 +2294,21 @@ void pmodeiret(int is32) } if ((segdat2[2]&0x1A00)!=0x1200) { - pclog("IRET loading SS wrong type\n"); + // pclog("IRET loading SS wrong type\n"); ESP = oldsp; x86gpf(NULL,newss&~3); return; } if (DPL2 != (seg & 3)) { - pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); + // pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); ESP = oldsp; x86gpf(NULL,newss&~3); return; } if (!(segdat2[2]&0x8000)) { - pclog("IRET loading SS not present\n"); + // pclog("IRET loading SS not present\n"); ESP = oldsp; x86np("IRET loading SS not present\n", newss & 0xfffc); return; @@ -2483,14 +2483,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (eflags&VM_FLAG) { - pclog("Task switch V86!\n"); + // pclog("Task switch V86!\n"); x86gpf(NULL,0); return; } if (!(new_cs&~3)) { - pclog("TS loading null CS\n"); + // pclog("TS loading null CS\n"); x86gpf(NULL,0); return; } @@ -2499,7 +2499,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); + // pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); x86gpf(NULL,0); return; } @@ -2509,7 +2509,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=gdt.limit) { - pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); + // pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); x86gpf(NULL,0); return; } @@ -2521,7 +2521,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) segdat2[3]=readmemw(0,addr+6); if (!(segdat2[2]&0x8000)) { - pclog("TS loading CS not present\n"); + // pclog("TS loading CS not present\n"); x86np("TS loading CS not present\n", new_cs & 0xfffc); return; } @@ -2530,7 +2530,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if ((new_cs&3) != DPL2) { - pclog("TS load CS non-conforming RPL != DPL"); + // pclog("TS load CS non-conforming RPL != DPL"); x86gpf(NULL,new_cs&~3); return; } @@ -2538,13 +2538,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((new_cs&3) < DPL2) { - pclog("TS load CS non-conforming RPL < DPL"); + // pclog("TS load CS non-conforming RPL < DPL"); x86gpf(NULL,new_cs&~3); return; } break; default: - pclog("TS load CS not code segment\n"); + // pclog("TS load CS not code segment\n"); x86gpf(NULL,new_cs&~3); return; } @@ -2579,7 +2579,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } else { - pclog("16-bit TSS\n"); + // pclog("16-bit TSS\n"); resetx86(); //exit(-1); }