Reworked serial and LPT set up - they can now bet set to any I/O base address (though that capability is not used by anything yet);
The CD-ROM IOCTL direct pass through code now does sanity check on the requested data size before passing the command - fixes crashes with some DMA-only host DVD drives; The network poller is now in its own thread; The hack is back in the emulation of the National Semiconductors PC87306 Super I/O Chip - it's the only way right now to have serial working on that board; Fixed a part of the code that was still using NukedOPL even when OPL 3 was set to DOSBox OPL; Applied all mainline PCem commits.
This commit is contained in:
@@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi
|
||||
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
|
||||
|
||||
|
||||
LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static
|
||||
LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcap
|
||||
|
||||
86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
|
||||
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
|
||||
|
||||
@@ -42,14 +42,14 @@ int cdrom_ioctl_do_log = 0;
|
||||
void cdrom_ioctl_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
if (cdrom_ioctl_do_log)
|
||||
{
|
||||
if (cdrom_ioctl_do_log)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -534,11 +534,33 @@ static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_bl
|
||||
|
||||
if (no_length_check)
|
||||
{
|
||||
return 65534;
|
||||
switch (cdb[0])
|
||||
{
|
||||
case 0x25:
|
||||
/* READ CAPACITY */
|
||||
return 8;
|
||||
case 0x42: /* READ SUBCHANNEL */
|
||||
case 0x43: /* READ TOC */
|
||||
case 0x51: /* READ DISC INFORMATION */
|
||||
case 0x52: /* READ TRACK INFORMATION */
|
||||
case 0x5A: /* MODE SENSE (10) */
|
||||
return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8);
|
||||
default:
|
||||
return 65534;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cdb[0])
|
||||
{
|
||||
case 0x25:
|
||||
/* READ CAPACITY */
|
||||
return 8;
|
||||
case 0x42: /* READ SUBCHANNEL */
|
||||
case 0x43: /* READ TOC */
|
||||
case 0x51: /* READ DISC INFORMATION */
|
||||
case 0x52: /* READ TRACK INFORMATION */
|
||||
case 0x5A: /* MODE SENSE (10) */
|
||||
return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8);
|
||||
case 0x08:
|
||||
case 0x28:
|
||||
case 0xa8:
|
||||
|
||||
76
src/cdrom.c
76
src/cdrom.c
@@ -212,14 +212,14 @@ int cdrom_do_log = 0;
|
||||
void cdrom_log(const char *format, ...)
|
||||
{
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
if (cdrom_do_log)
|
||||
{
|
||||
if (cdrom_do_log)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1857,6 +1857,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
case GPCMD_READ_TOC_PMA_ATIP:
|
||||
cdrom[id].toctimes++;
|
||||
|
||||
max_len = cdb[7];
|
||||
max_len <<= 8;
|
||||
max_len |= cdb[8];
|
||||
|
||||
if (cdrom_drives[id].handler->pass_through)
|
||||
{
|
||||
ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb);
|
||||
@@ -1864,19 +1868,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (len == 65534)
|
||||
alloc_length = cdbufferb[0];
|
||||
alloc_length <<= 8;
|
||||
alloc_length |= cdbufferb[1];
|
||||
alloc_length += 2;
|
||||
if (alloc_length < len)
|
||||
{
|
||||
max_len = cdb[8] + (cdb[7] << 8);
|
||||
len = cdbufferb[0] + (cdbufferb[1] << 8);
|
||||
len += 2;
|
||||
if (max_len < len)
|
||||
{
|
||||
max_len -= 2;
|
||||
cdbufferb[0] = max_len >> 8;
|
||||
cdbufferb[1] = max_len & 0xff;
|
||||
len = max_len + 2;
|
||||
}
|
||||
len = alloc_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2238,11 +2236,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (len == 65534)
|
||||
alloc_length = cdbufferb[0];
|
||||
alloc_length <<= 8;
|
||||
alloc_length |= cdbufferb[1];
|
||||
alloc_length += 2;
|
||||
if (alloc_length < len)
|
||||
{
|
||||
cdbufferb[0] = 0;
|
||||
cdbufferb[1] = 32;
|
||||
len = 34;
|
||||
len = alloc_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2278,12 +2278,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (len == 65534)
|
||||
alloc_length = cdbufferb[0];
|
||||
alloc_length <<= 8;
|
||||
alloc_length |= cdbufferb[1];
|
||||
alloc_length += 2;
|
||||
if (alloc_length < len)
|
||||
{
|
||||
cdbufferb[0] = 0;
|
||||
cdbufferb[1] = 34;
|
||||
len = 36;
|
||||
len = alloc_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2400,20 +2401,21 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
cdbufferb[1] = 0x13;
|
||||
break;
|
||||
}
|
||||
if (len == 65534)
|
||||
switch(cdb[3])
|
||||
{
|
||||
switch(cdb[3])
|
||||
{
|
||||
case 0:
|
||||
len = 4;
|
||||
break;
|
||||
case 1:
|
||||
len = 16;
|
||||
break;
|
||||
default:
|
||||
len = 24;
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
alloc_length = 4;
|
||||
break;
|
||||
case 1:
|
||||
alloc_length = 16;
|
||||
break;
|
||||
default:
|
||||
alloc_length = 24;
|
||||
break;
|
||||
}
|
||||
if (alloc_length < len)
|
||||
{
|
||||
len = alloc_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
14
src/lpt.c
14
src/lpt.c
@@ -65,31 +65,33 @@ uint8_t lpt2_read(uint16_t port, void *priv)
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
uint16_t lpt_addr[2] = { 0x378, 0x278 };
|
||||
|
||||
void lpt_init()
|
||||
{
|
||||
io_sethandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
lpt_addr[0] = 0x378;
|
||||
lpt_addr[1] = 0x378;
|
||||
}
|
||||
|
||||
void lpt1_init(uint16_t port)
|
||||
{
|
||||
io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
lpt_addr[0] = port;
|
||||
}
|
||||
void lpt1_remove()
|
||||
{
|
||||
io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
io_removehandler(lpt_addr[0], 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL);
|
||||
}
|
||||
void lpt2_init(uint16_t port)
|
||||
{
|
||||
io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
lpt_addr[1] = port;
|
||||
}
|
||||
void lpt2_remove()
|
||||
{
|
||||
io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
io_removehandler(lpt_addr[1], 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void lpt2_remove_ams()
|
||||
|
||||
3454
src/ne2000.c
3454
src/ne2000.c
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "ne2000.h"
|
||||
#include "timer.h"
|
||||
#include "thread.h"
|
||||
|
||||
int network_card_current = 0;
|
||||
static int network_card_last = 0;
|
||||
@@ -83,19 +84,95 @@ void vlan_handler(void (*poller)(void *p), void *p)
|
||||
vlan_handlers_num++;
|
||||
}
|
||||
|
||||
static thread_t *network_thread_h;
|
||||
static event_t *network_event;
|
||||
|
||||
static int network_thread_initialized = 0;
|
||||
static int network_thread_enable = 0;
|
||||
|
||||
static void network_thread(void *param)
|
||||
{
|
||||
int c;
|
||||
|
||||
// pclog("Network thread\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
// pclog("Waiting...\n");
|
||||
thread_wait_event(network_event, -1);
|
||||
|
||||
// pclog("Processing\n");
|
||||
|
||||
for (c = 0; c < vlan_handlers_num; c++)
|
||||
vlan_handlers[c].poller(vlan_handlers[c].priv);
|
||||
}
|
||||
}
|
||||
|
||||
void network_thread_init()
|
||||
{
|
||||
pclog("network_thread_init()\n");
|
||||
|
||||
if (network_card_current)
|
||||
{
|
||||
pclog("Thread enabled...\n");
|
||||
|
||||
network_event = thread_create_event();
|
||||
network_thread_h = thread_create(network_thread, NULL);
|
||||
}
|
||||
|
||||
network_thread_enable = network_card_current ? 1 : 0;
|
||||
network_thread_initialized = 1;
|
||||
}
|
||||
|
||||
void network_thread_reset()
|
||||
{
|
||||
if(!network_thread_initialized)
|
||||
{
|
||||
network_thread_init();
|
||||
return;
|
||||
}
|
||||
|
||||
pclog("network_thread_reset()\n");
|
||||
if (network_card_current && !network_thread_enable)
|
||||
{
|
||||
pclog("Thread enabled (disabled before...\n");
|
||||
network_event = thread_create_event();
|
||||
network_thread_h = thread_create(network_thread, NULL);
|
||||
}
|
||||
else if (!network_card_current && network_thread_enable)
|
||||
{
|
||||
pclog("Thread disabled (enabled before...\n");
|
||||
thread_destroy_event(network_event);
|
||||
thread_kill(network_thread_h);
|
||||
network_thread_h = NULL;
|
||||
}
|
||||
|
||||
network_thread_enable = network_card_current ? 1 : 0;
|
||||
}
|
||||
|
||||
void vlan_poller(void *priv)
|
||||
{
|
||||
int c;
|
||||
|
||||
vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0));
|
||||
vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 15000.0));
|
||||
|
||||
for (c = 0; c < vlan_handlers_num; c++)
|
||||
vlan_handlers[c].poller(vlan_handlers[c].priv);
|
||||
if (network_thread_enable && vlan_handlers_num)
|
||||
{
|
||||
// pclog("Setting thread event...\n");
|
||||
thread_set_event(network_event);
|
||||
}
|
||||
}
|
||||
|
||||
void vlan_reset()
|
||||
{
|
||||
timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL);
|
||||
pclog("vlan_reset()\n");
|
||||
|
||||
if (network_card_current)
|
||||
{
|
||||
pclog("Adding timer...\n");
|
||||
|
||||
timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL);
|
||||
}
|
||||
|
||||
vlan_handlers_num = 0;
|
||||
}
|
||||
|
||||
4
src/pc.c
4
src/pc.c
@@ -315,11 +315,14 @@ void initpc(int argc, char *argv[])
|
||||
td0_init();
|
||||
imd_init();
|
||||
|
||||
#if 0
|
||||
if (network_card_current != 0)
|
||||
{
|
||||
vlan_reset(); //NETWORK
|
||||
}
|
||||
network_card_init(network_card_current);
|
||||
network_thread_init();
|
||||
#endif
|
||||
|
||||
disc_load(0, discfns[0]);
|
||||
disc_load(1, discfns[1]);
|
||||
@@ -442,6 +445,7 @@ void resetpchard()
|
||||
vlan_reset(); //NETWORK
|
||||
}
|
||||
network_card_init(network_card_current);
|
||||
network_thread_reset();
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
static int pc87306_locked;
|
||||
static int pc87306_curreg;
|
||||
static uint8_t pc87306_regs[29];
|
||||
static uint8_t pc87306_gpio[2] = {0xFF, 0xFF};
|
||||
static uint8_t pc87306_gpio[2] = {0xFF, 0xFB};
|
||||
static uint8_t tries;
|
||||
static uint16_t lpt_port;
|
||||
static int power_down = 0;
|
||||
@@ -29,10 +29,7 @@ void pc87306_gpio_init();
|
||||
|
||||
void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// pclog("GPIO: Writing %02X on port: %04X\n", val, port);
|
||||
pc87306_gpio[port & 1] = val;
|
||||
}
|
||||
|
||||
@@ -167,13 +164,17 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
if (tries)
|
||||
{
|
||||
if ((pc87306_curreg == 0) && (val == 8))
|
||||
{
|
||||
val = 0x4b;
|
||||
}
|
||||
if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg];
|
||||
tries = 0;
|
||||
if ((pc87306_curreg == 0x19) && !(pc87306_regs[0x1B] & 0x40))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18))
|
||||
if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)/* && (pc87306_curreg != 0x18)*/)
|
||||
{
|
||||
if (pc87306_curreg == 0)
|
||||
{
|
||||
@@ -183,8 +184,8 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
pc87306_gpio_remove();
|
||||
}
|
||||
pc87306_regs[pc87306_curreg] = val;
|
||||
// pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]);
|
||||
pc87306_regs[pc87306_curreg] = val;
|
||||
goto process_value;
|
||||
}
|
||||
}
|
||||
@@ -237,7 +238,7 @@ process_value:
|
||||
|
||||
break;
|
||||
case 1:
|
||||
if (valxor & 1)
|
||||
if (valxor & 3)
|
||||
{
|
||||
lpt1_remove();
|
||||
if (pc87306_regs[0] & 1)
|
||||
@@ -248,22 +249,26 @@ process_value:
|
||||
|
||||
if (valxor & 0xcc)
|
||||
{
|
||||
serial1_remove();
|
||||
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
}
|
||||
else
|
||||
{
|
||||
serial1_remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (valxor & 0xf0)
|
||||
{
|
||||
serial2_remove();
|
||||
|
||||
if (pc87306_regs[0] & 4)
|
||||
{
|
||||
serial2_handler();
|
||||
}
|
||||
else
|
||||
{
|
||||
serial2_remove();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -344,11 +349,8 @@ process_value:
|
||||
}
|
||||
break;
|
||||
case 0x1C:
|
||||
// if (valxor & 0x25)
|
||||
if (valxor)
|
||||
{
|
||||
serial1_remove();
|
||||
serial2_remove();
|
||||
if (pc87306_regs[0] & 2)
|
||||
{
|
||||
serial1_handler();
|
||||
@@ -364,10 +366,7 @@ process_value:
|
||||
|
||||
uint8_t pc87306_gpio_read(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
{
|
||||
return 0xfb; /* Bit 2 clear, since we don't emulate the on-board audio. */
|
||||
}
|
||||
// pclog("Read GPIO on port: %04X (%04X:%04X)\n", port, CS, cpu_state.pc);
|
||||
return pc87306_gpio[port & 1];
|
||||
}
|
||||
|
||||
@@ -393,14 +392,9 @@ uint8_t pc87306_read(uint16_t port, void *priv)
|
||||
}
|
||||
else if (pc87306_curreg == 8)
|
||||
{
|
||||
// pclog("PC87306: Read ID at data register, index 08\n");
|
||||
// pclog("PC87306: Read ID at data register, index 08 (%04X:%04X)\n", CS, cpu_state.pc);
|
||||
return 0x70;
|
||||
}
|
||||
else if (pc87306_curreg == 5)
|
||||
{
|
||||
// pclog("PC87306: Read value %02X at data register, index 05\n", pc87306_regs[pc87306_curreg] | 4);
|
||||
return pc87306_regs[pc87306_curreg] | 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("PC87306: Read value %02X at data register, index %02X\n", pc87306_regs[pc87306_curreg], pc87306_curreg);
|
||||
@@ -433,10 +427,11 @@ void pc87306_reset(void)
|
||||
|
||||
pc87306_regs[0] = 0x4B;
|
||||
pc87306_regs[1] = 0x01;
|
||||
pc87306_regs[3] = 2;
|
||||
pc87306_regs[5] = 0xD;
|
||||
pc87306_regs[3] = 0x01;
|
||||
pc87306_regs[5] = 0x0D;
|
||||
pc87306_regs[8] = 0x70;
|
||||
pc87306_regs[9] = 0xFF;
|
||||
pc87306_regs[9] = 0xC0;
|
||||
pc87306_regs[0xB] = 0x80;
|
||||
pc87306_regs[0xF] = 0x1E;
|
||||
pc87306_regs[0x12] = 0x30;
|
||||
pc87306_regs[0x19] = 0xEF;
|
||||
@@ -449,12 +444,13 @@ void pc87306_reset(void)
|
||||
fdc_update_densel_polarity(1);
|
||||
fdc_update_max_track(85);
|
||||
fdc_remove();
|
||||
fdc_add(0x3f0, 0);
|
||||
fdc_set_base(0x3f0, 0);
|
||||
fdd_swap = 0;
|
||||
serial1_remove();
|
||||
serial2_remove();
|
||||
serial1_handler();
|
||||
serial2_handler();
|
||||
pc87306_gpio_init();
|
||||
}
|
||||
|
||||
void pc87306_init()
|
||||
|
||||
35
src/serial.c
35
src/serial.c
@@ -85,6 +85,7 @@ uint8_t serial_read_fifo(SERIAL *serial)
|
||||
void serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
SERIAL *serial = (SERIAL *)p;
|
||||
// pclog("Serial: Write value %02X on port: %04X\n", val, addr);
|
||||
// pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||
switch (addr&7)
|
||||
{
|
||||
@@ -169,7 +170,7 @@ uint8_t serial_read(uint16_t addr, void *p)
|
||||
{
|
||||
SERIAL *serial = (SERIAL *)p;
|
||||
uint8_t temp = 0;
|
||||
// pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins);
|
||||
// pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, cpu_state.pc, mousedelay, ins);
|
||||
switch (addr&7)
|
||||
{
|
||||
case 0:
|
||||
@@ -228,6 +229,7 @@ uint8_t serial_read(uint16_t addr, void *p)
|
||||
break;
|
||||
}
|
||||
// pclog("%02X\n",temp);
|
||||
// pclog("Serial: Read value %02X on port: %04X\n", temp, addr);
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -245,6 +247,9 @@ void serial_recieve_callback(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t serial_addr[2] = { 0x3f8, 0x2f8 };
|
||||
int serial_irq[2] = { 4, 3 };
|
||||
|
||||
/*Tandy might need COM1 at 2f8*/
|
||||
void serial1_init(uint16_t addr, int irq)
|
||||
{
|
||||
@@ -253,6 +258,8 @@ void serial1_init(uint16_t addr, int irq)
|
||||
serial1.irq = irq;
|
||||
serial1.rcr_callback = NULL;
|
||||
timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1);
|
||||
serial_addr[0] = addr;
|
||||
serial_irq[0] = irq;
|
||||
}
|
||||
void serial1_set(uint16_t addr, int irq)
|
||||
{
|
||||
@@ -260,18 +267,12 @@ void serial1_set(uint16_t addr, int irq)
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
serial1.irq = irq;
|
||||
// pclog("serial1_set(%04X, %02X)\n", addr, irq);
|
||||
serial_addr[0] = addr;
|
||||
serial_irq[0] = irq;
|
||||
}
|
||||
void serial1_remove()
|
||||
{
|
||||
io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
|
||||
}
|
||||
|
||||
void serial2_init(uint16_t addr, int irq)
|
||||
@@ -281,6 +282,8 @@ void serial2_init(uint16_t addr, int irq)
|
||||
serial2.irq = irq;
|
||||
serial2.rcr_callback = NULL;
|
||||
timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2);
|
||||
serial_addr[1] = addr;
|
||||
serial_irq[1] = irq;
|
||||
}
|
||||
void serial2_set(uint16_t addr, int irq)
|
||||
{
|
||||
@@ -288,16 +291,10 @@ void serial2_set(uint16_t addr, int irq)
|
||||
io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
serial2.irq = irq;
|
||||
// pclog("serial2_set(%04X, %02X)\n", addr, irq);
|
||||
serial_addr[1] = addr;
|
||||
serial_irq[1] = irq;
|
||||
}
|
||||
void serial2_remove()
|
||||
{
|
||||
io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
|
||||
}
|
||||
|
||||
@@ -84,18 +84,18 @@ void opl_timer_over(int nr, int timer)
|
||||
void opl_write(int nr, uint16_t addr, uint8_t val)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
{
|
||||
if (!opl[nr].is_opl3)
|
||||
opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff;
|
||||
else
|
||||
opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff;
|
||||
}
|
||||
{
|
||||
if (!opl[nr].is_opl3 || !opl3_type)
|
||||
opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff;
|
||||
else
|
||||
opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!opl[nr].is_opl3)
|
||||
opl[nr].chip.WriteReg(opl[nr].addr, val);
|
||||
else
|
||||
OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val);
|
||||
if (!opl[nr].is_opl3 || !opl3_type)
|
||||
opl[nr].chip.WriteReg(opl[nr].addr, val);
|
||||
else
|
||||
OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val);
|
||||
|
||||
switch (opl[nr].addr)
|
||||
{
|
||||
|
||||
@@ -964,8 +964,8 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
BLTCMD_SRC_TILED = (1 << 10),
|
||||
BLTCMD_DST_TILED = (1 << 12)
|
||||
BLTCMD_SRC_TILED = (1 << 14),
|
||||
BLTCMD_DST_TILED = (1 << 15)
|
||||
};
|
||||
|
||||
#define TEXTUREMODE_MASK 0x3ffff000
|
||||
@@ -1086,7 +1086,9 @@ static void voodoo_recalc(voodoo_t *voodoo)
|
||||
|
||||
voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2;
|
||||
if (voodoo->fbiInit6 & (1 << 30))
|
||||
voodoo->fbiInit1 += 1;
|
||||
voodoo->block_width += 1;
|
||||
if (voodoo->fbiInit1 & (1 << 24))
|
||||
voodoo->block_width += 32;
|
||||
voodoo->row_width = voodoo->block_width * 32 * 2;
|
||||
|
||||
/* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset);
|
||||
@@ -2714,7 +2716,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
|
||||
goto next_line;
|
||||
|
||||
state->fb_mem = fb_mem = &voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)];
|
||||
state->aux_mem = aux_mem = &voodoo->fb_mem[params->aux_offset + (real_y * voodoo->row_width)];
|
||||
state->aux_mem = aux_mem = &voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask];
|
||||
|
||||
if (voodoo_output)
|
||||
pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2);
|
||||
@@ -3100,7 +3102,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
fb_mem[x] = src_b | (src_g << 5) | (src_r << 11);
|
||||
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE))
|
||||
aux_mem[x] = new_depth;
|
||||
}
|
||||
}
|
||||
@@ -3769,6 +3771,7 @@ static void blit_start(voodoo_t *voodoo)
|
||||
{
|
||||
uint16_t src_dat = src[src_x];
|
||||
uint16_t dst_dat = dst[dst_x];
|
||||
int rop = 0;
|
||||
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
|
||||
{
|
||||
@@ -3776,8 +3779,31 @@ static void blit_start(voodoo_t *voodoo)
|
||||
dst_y < voodoo->bltClipLowY || dst_y > voodoo->bltClipHighY)
|
||||
goto skip_pixel_blit;
|
||||
}
|
||||
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[3]);
|
||||
|
||||
if (voodoo->bltCommand & BLIT_SRC_CHROMA)
|
||||
{
|
||||
int r = (src_dat >> 11);
|
||||
int g = (src_dat >> 5) & 0x3f;
|
||||
int b = src_dat & 0x1f;
|
||||
|
||||
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR &&
|
||||
g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG &&
|
||||
b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
|
||||
rop |= BLIT_ROP_SRC_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_DST_CHROMA)
|
||||
{
|
||||
int r = (dst_dat >> 11);
|
||||
int g = (dst_dat >> 5) & 0x3f;
|
||||
int b = dst_dat & 0x1f;
|
||||
|
||||
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR &&
|
||||
g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG &&
|
||||
b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
|
||||
rop |= BLIT_ROP_DST_PASS;
|
||||
}
|
||||
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
|
||||
|
||||
dst[dst_x] = dst_dat;
|
||||
skip_pixel_blit:
|
||||
@@ -3855,7 +3881,7 @@ skip_pixel_fill:
|
||||
size_x = voodoo->bltSizeX & 0x1ff;
|
||||
}
|
||||
|
||||
dst = (uint64_t *)&voodoo->fb_mem[dst_y*512*8 + dst_x*8];
|
||||
dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask];
|
||||
|
||||
for (x = 0; x <= size_x; x++)
|
||||
dst[x] = dat64;
|
||||
@@ -4429,12 +4455,28 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
|
||||
break;
|
||||
|
||||
case SST_clipLeftRight:
|
||||
voodoo->params.clipRight = val & 0x3ff;
|
||||
voodoo->params.clipLeft = (val >> 16) & 0x3ff;
|
||||
if (voodoo->type >= VOODOO_2)
|
||||
{
|
||||
voodoo->params.clipRight = val & 0xfff;
|
||||
voodoo->params.clipLeft = (val >> 16) & 0xfff;
|
||||
}
|
||||
else
|
||||
{
|
||||
voodoo->params.clipRight = val & 0x3ff;
|
||||
voodoo->params.clipLeft = (val >> 16) & 0x3ff;
|
||||
}
|
||||
break;
|
||||
case SST_clipLowYHighY:
|
||||
voodoo->params.clipHighY = val & 0x3ff;
|
||||
voodoo->params.clipLowY = (val >> 16) & 0x3ff;
|
||||
if (voodoo->type >= VOODOO_2)
|
||||
{
|
||||
voodoo->params.clipHighY = val & 0xfff;
|
||||
voodoo->params.clipLowY = (val >> 16) & 0xfff;
|
||||
}
|
||||
else
|
||||
{
|
||||
voodoo->params.clipHighY = val & 0x3ff;
|
||||
voodoo->params.clipLowY = (val >> 16) & 0x3ff;
|
||||
}
|
||||
break;
|
||||
|
||||
case SST_nopCMD:
|
||||
@@ -6285,7 +6327,7 @@ static void fifo_thread(void *param)
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
|
||||
end_time = timer_read();
|
||||
|
||||
@@ -434,7 +434,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0x0c);
|
||||
addbyte(0x82);
|
||||
|
||||
if (state->clamp_s)
|
||||
if (state->clamp_s[tmu])
|
||||
{
|
||||
addbyte(0xeb); /*JMP +*/
|
||||
addbyte(5+5+4+4);
|
||||
@@ -607,7 +607,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0xe8);
|
||||
addbyte(0xd3); /*SHR EBX, CL*/
|
||||
addbyte(0xeb);
|
||||
if (state->clamp_s)
|
||||
if (state->clamp_s[tmu])
|
||||
{
|
||||
addbyte(0x85); /*TEST EAX, EAX*/
|
||||
addbyte(0xc0);
|
||||
@@ -634,7 +634,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0x8e);
|
||||
addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10);
|
||||
}
|
||||
if (state->clamp_t)
|
||||
if (state->clamp_t[tmu])
|
||||
{
|
||||
addbyte(0x85); /*TEST EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
@@ -2980,7 +2980,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(0x56);
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE))
|
||||
{
|
||||
addbyte(0x66); /*MOV AX, new_depth*/
|
||||
addbyte(0x8b);
|
||||
|
||||
@@ -227,8 +227,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0x8b); /*MOV ECX, [ECX+EAX*4]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x81);
|
||||
addbyte(0xbd); /*MOV EBP, 1*/
|
||||
addlong(1);
|
||||
addbyte(0xbd); /*MOV EBP, 8*/
|
||||
addlong(8);
|
||||
addbyte(0x28); /*SUB DL, CL*/
|
||||
addbyte(0xca);
|
||||
addbyte(0xd3); /*SHL EBP, CL*/
|
||||
@@ -236,9 +236,6 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/
|
||||
addbyte(0x87);
|
||||
addlong(offsetof(voodoo_state_t, tex_s));
|
||||
addbyte(0xc1); /*SHL EBP, 3*/
|
||||
addbyte(0xe5);
|
||||
addbyte(3);
|
||||
addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/
|
||||
addbyte(0x9f);
|
||||
addlong(offsetof(voodoo_state_t, tex_t));
|
||||
@@ -416,7 +413,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v
|
||||
addbyte(0x0c);
|
||||
addbyte(0x82);
|
||||
|
||||
if (state->clamp_s)
|
||||
if (state->clamp_s[tmu])
|
||||
{
|
||||
addbyte(0xeb); /*JMP +*/
|
||||
addbyte(5+5+4+4);
|
||||
@@ -2972,7 +2969,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(0x56);
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE))
|
||||
{
|
||||
addbyte(0x66); /*MOV AX, new_depth*/
|
||||
addbyte(0x8b);
|
||||
|
||||
12
src/x86seg.c
12
src/x86seg.c
@@ -2036,20 +2036,16 @@ void pmodeiret(int is32)
|
||||
addr=seg&~7;
|
||||
if (seg&4)
|
||||
{
|
||||
if (addr>=ldt.limit)
|
||||
{
|
||||
// pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
addr+=ldt.base;
|
||||
pclog("TS LDT %04X %04X IRET\n",seg,gdt.limit);
|
||||
x86ts(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr>=gdt.limit)
|
||||
{
|
||||
// pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||
x86gpf(NULL,seg&~3);
|
||||
x86ts(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
addr+=gdt.base;
|
||||
|
||||
Reference in New Issue
Block a user