diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 3870b99c8..7019473a8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -131,6 +131,14 @@ PLATCG = codegen_x86.o endif +ifeq ($(WALTJE), y) +SERIAL = serial.o +WFLAGS = -DWALTJE +else +SERIAL = serial_old.o +endif + + MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o @@ -153,7 +161,7 @@ SYSOBJ = model.o \ compaq.o laserxt.o jim.o \ olivetti_m24.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o -DEVOBJ = bugger.o lpt.o serial.o \ +DEVOBJ = bugger.o lpt.o $(SERIAL) \ fdc37c665.o fdc37c669.o fdc37c932fr.o \ pc87306.o sis85c471.o w83877f.o \ keyboard.o \ @@ -252,15 +260,15 @@ LIBS = -mwindows \ # Build rules. %.o: %.c @echo $< - @$(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) $(WFLAGS) -c $< %.o: %.cc @echo $< - @$(CPP) $(CFLAGS) -c $< + @$(CPP) $(CFLAGS) $(WFLAGS) -c $< %.o: %.cpp @echo $< - @$(CPP) $(CFLAGS) -c $< + @$(CPP) $(CFLAGS) $(WFLAGS) -c $< all: $(PROG).exe pcap_if.exe diff --git a/src/mem.c b/src/mem.c index fb6b701d6..cedac258f 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2179,7 +2179,12 @@ void mem_init() if (mem_size > 768) mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); + if (romset == ROM_IBMPS1_2011) + mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); + + mem_a20_key = 2; + mem_a20_alt = 0; + mem_a20_recalc(); } static void mem_remap_top(int max_size) @@ -2274,6 +2279,7 @@ void mem_resize() mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); mem_a20_key = 2; + mem_a20_alt = 0; mem_a20_recalc(); } diff --git a/src/model.c b/src/model.c index c0f31f1f7..311bb1af5 100644 --- a/src/model.c +++ b/src/model.c @@ -415,7 +415,6 @@ void xt_laserxt_init(void) void at_init(void) { AT = 1; - mem_a20_key = mem_a20_alt = 0; common_init(); if (lpt_enabled) { diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 04f23a8d9..208f95378 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -22,6 +22,7 @@ #include "mouse_serial.h" +#ifdef WALTJE #define SERMOUSE_TYPE_MSYSTEMS 1 /* Mouse Systems */ #define SERMOUSE_TYPE_MICROSOFT 2 /* Microsoft */ #define SERMOUSE_TYPE_LOGITECH 3 /* Logitech */ @@ -228,3 +229,195 @@ mouse_t mouse_serial_logitech = { sermouse_close, sermouse_poll }; + + +#else + + +typedef struct mouse_serial_t +{ + int mousepos, mousedelay; + int oldb; + int type; + SERIAL *serial; +} mouse_serial_t; + +uint8_t mouse_serial_poll(int x, int y, int z, int b, void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + SERIAL *serial = mouse->serial; + uint8_t mousedat[4]; + + if (!(serial->ier & 1)) + return 0xff; + if (!x && !y && b == mouse->oldb) + return 0xff; + + mouse->oldb = b; + if (x>127) x=127; + if (y>127) y=127; + if (x<-128) x=-128; + if (y<-128) y=-128; + + /*Use Microsoft format*/ + mousedat[0]=0x40; + mousedat[0]|=(((y>>6)&3)<<2); + mousedat[0]|=((x>>6)&3); + if (b&1) mousedat[0]|=0x20; + if (b&2) mousedat[0]|=0x10; + mousedat[1]=x&0x3F; + mousedat[2]=y&0x3F; + + if (!(serial->mctrl & 0x10)) + { + serial_write_fifo(mouse->serial, mousedat[0]); + serial_write_fifo(mouse->serial, mousedat[1]); + serial_write_fifo(mouse->serial, mousedat[2]); + if ((b&0x04) && mouse->type) + { + serial_write_fifo(mouse->serial, 0x20); + } + } + + return 0; +} + +uint8_t mouse_serial_msystems_poll(int x, int y, int z, int b, void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + SERIAL *serial = mouse->serial; + uint8_t mousedat[4]; + + if (!(serial->ier & 1)) + return 0xff; + if (!x && !y && b == mouse->oldb) + return 0xff; + + y = -y; + + mouse->oldb = b; + if (x>127) x=127; + if (y>127) y=127; + if (x<-128) x=-128; + if (y<-128) y=-128; + + /*Use Mouse Systems format*/ + mousedat[0] = 0x80; + mousedat[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */ + mousedat[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */ + mousedat[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */ + mousedat[1] = x; + mousedat[2] = y; + mousedat[3] = x; /* same as byte 1 */ + mousedat[4] = y; /* same as byte 2 */ + + if (!(serial->mctrl & 0x10)) + { + serial_write_fifo(mouse->serial, mousedat[0]); + serial_write_fifo(mouse->serial, mousedat[1]); + serial_write_fifo(mouse->serial, mousedat[2]); + serial_write_fifo(mouse->serial, mousedat[3]); + serial_write_fifo(mouse->serial, mousedat[4]); + } + + return 0; +} + +void mouse_serial_rcr(struct SERIAL *serial, void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + + mouse->mousepos = -1; + mouse->mousedelay = 5000 * (1 << TIMER_SHIFT); +} + +void mousecallback(void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + + mouse->mousedelay = 0; + if (mouse->mousepos == -1) + { + mouse->mousepos = 0; + if (mouse->type < 2) + { + serial_write_fifo(mouse->serial, 'M'); + if (mouse->type == 1) + { + serial_write_fifo(mouse->serial, '3'); + } + } + } +} + +void *mouse_serial_common_init(int type) +{ + mouse_serial_t *mouse = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(mouse, 0, sizeof(mouse_serial_t)); + + mouse->serial = &serial1; + serial1.rcr_callback = mouse_serial_rcr; + serial1.rcr_callback_p = mouse; + timer_add(mousecallback, &mouse->mousedelay, &mouse->mousedelay, mouse); + + mouse->type = type; + + return mouse; +} + +void *mouse_serial_init() +{ + return mouse_serial_common_init(0); +} + +void *mouse_serial_logitech_init() +{ + return mouse_serial_common_init(1); +} + +void *mouse_serial_msystems_init() +{ + return mouse_serial_common_init(2); +} + +void mouse_serial_close(void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + + free(mouse); + + serial1.rcr_callback = NULL; +} + +mouse_t mouse_serial_microsoft = +{ + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + mouse_serial_init, + mouse_serial_close, + mouse_serial_poll +}; + +mouse_t mouse_serial_logitech = +{ + "Logitech 3-button mouse (serial)", + "lserial", + MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON, + mouse_serial_logitech_init, + mouse_serial_close, + mouse_serial_poll +}; + +mouse_t mouse_msystems = +{ + "Mouse Systems Mouse (serial)", + "mssystems", + MOUSE_TYPE_MSYSTEMS, + mouse_serial_msystems_init, + mouse_serial_close, + mouse_serial_msystems_poll +}; + + +#endif \ No newline at end of file diff --git a/src/pc.c b/src/pc.c index d62a1cfb2..dc4ba68ae 100644 --- a/src/pc.c +++ b/src/pc.c @@ -512,6 +512,9 @@ void resetpchard_init(void) fdc_init(); disc_reset(); +#ifndef WALTJE + serial_init(); +#endif model_init(); video_init(); speaker_init(); diff --git a/src/serial.h b/src/serial.h index fec2d2b5c..4decfec6f 100644 --- a/src/serial.h +++ b/src/serial.h @@ -17,6 +17,7 @@ # define EMU_SERIAL_H +#ifdef WALTJE /* Default settings for the standard ports. */ #define SERIAL1_ADDR 0x03f8 #define SERIAL1_IRQ 4 @@ -72,4 +73,45 @@ extern int serial_link(int, char *); extern void serial_write_fifo(SERIAL *, uint8_t, int); -#endif /*EMU_SERIAL_H*/ +#else + + +void serial_remove(int port); +void serial_setup(int port, uint16_t addr, int irq); +void serial_init(void); +void serial_reset(); + +struct SERIAL; + +typedef struct +{ + uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; + uint8_t dlab1,dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + int irq; + + void (*rcr_callback)(struct SERIAL *serial, void *p); + void *rcr_callback_p; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int recieve_delay; +} SERIAL; + +void serial_write_fifo(SERIAL *serial, uint8_t dat); + +extern SERIAL serial1, serial2; + +/* Default settings for the standard ports. */ +#define SERIAL1_ADDR 0x03f8 +#define SERIAL1_IRQ 4 +#define SERIAL2_ADDR 0x02f8 +#define SERIAL2_IRQ 3 +#endif + + +#endif /*EMU_SERIAL_H*/ \ No newline at end of file diff --git a/src/serial_old.c b/src/serial_old.c new file mode 100644 index 000000000..639c792cd --- /dev/null +++ b/src/serial_old.c @@ -0,0 +1,327 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "mouse.h" +#include "pic.h" +#include "serial.h" +#include "timer.h" + +enum +{ + SERIAL_INT_LSR = 1, + SERIAL_INT_RECEIVE = 2, + SERIAL_INT_TRANSMIT = 4, + SERIAL_INT_MSR = 8 +}; + +SERIAL serial1, serial2; + + +void serial_reset() +{ + serial1.iir = serial1.ier = serial1.lcr = 0; + serial2.iir = serial2.ier = serial2.lcr = 0; + serial1.fifo_read = serial1.fifo_write = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + +void serial_update_ints(SERIAL *serial) +{ + int stat = 0; + + serial->iir = 1; + + if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ + { + stat = 1; + serial->iir = 6; + } + else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ + { + stat = 1; + serial->iir = 4; + } + else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ + { + stat = 1; + serial->iir = 2; + } + else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ + { + stat = 1; + serial->iir = 0; + } + + if (stat && ((serial->mctrl & 8) || PCJR)) + picintlevel(1 << serial->irq); + else + picintc(1 << serial->irq); +} + +void serial_write_fifo(SERIAL *serial, uint8_t dat) +{ + serial->fifo[serial->fifo_write] = dat; + serial->fifo_write = (serial->fifo_write + 1) & 0xFF; + if (!(serial->lsr & 1)) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } +} + +uint8_t serial_read_fifo(SERIAL *serial) +{ + if (serial->fifo_read != serial->fifo_write) + { + serial->dat = serial->fifo[serial->fifo_read]; + serial->fifo_read = (serial->fifo_read + 1) & 0xFF; + } + return serial->dat; +} + +void serial_write(uint16_t addr, uint8_t val, void *p) +{ + SERIAL *serial = (SERIAL *)p; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + serial->dlab1 = val; + return; + } + serial->thr = val; + serial->lsr |= 0x20; + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + if (serial->mctrl & 0x10) + { + serial_write_fifo(serial, val); + } + break; + case 1: + if (serial->lcr & 0x80) + { + serial->dlab2 = val; + return; + } + serial->ier = val & 0xf; + serial_update_ints(serial); + break; + case 2: + serial->fcr = val; + break; + case 3: + serial->lcr = val; + break; + case 4: + if ((val & 2) && !(serial->mctrl & 2)) + { + if (serial->rcr_callback) + serial->rcr_callback((struct SERIAL *)serial, serial->rcr_callback_p); + } + serial->mctrl = val; + if (val & 0x10) + { + uint8_t new_msr; + + new_msr = (val & 0x0c) << 4; + new_msr |= (val & 0x02) ? 0x10: 0; + new_msr |= (val & 0x01) ? 0x20: 0; + + if ((serial->msr ^ new_msr) & 0x10) + new_msr |= 0x01; + if ((serial->msr ^ new_msr) & 0x20) + new_msr |= 0x02; + if ((serial->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((serial->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + serial->msr = new_msr; + } + break; + case 5: + serial->lsr = val; + if (serial->lsr & 0x01) + serial->int_status |= SERIAL_INT_RECEIVE; + if (serial->lsr & 0x1e) + serial->int_status |= SERIAL_INT_LSR; + if (serial->lsr & 0x20) + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + break; + case 6: + serial->msr = val; + if (serial->msr & 0x0f) + serial->int_status |= SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + serial->scratch = val; + break; + } +} + +uint8_t serial_read(uint16_t addr, void *p) +{ + SERIAL *serial = (SERIAL *)p; + uint8_t temp = 0; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + temp = serial->dlab1; + break; + } + + serial->lsr &= ~1; + serial->int_status &= ~SERIAL_INT_RECEIVE; + serial_update_ints(serial); + temp = serial_read_fifo(serial); + if (serial->fifo_read != serial->fifo_write) + serial->recieve_delay = 1000 * TIMER_USEC; + break; + case 1: + if (serial->lcr & 0x80) + temp = serial->dlab2; + else + temp = serial->ier; + break; + case 2: + temp = serial->iir; + if ((temp & 0xe) == 2) + { + serial->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + } + if (serial->fcr & 1) + temp |= 0xc0; + break; + case 3: + temp = serial->lcr; + break; + case 4: + temp = serial->mctrl; + break; + case 5: + if (serial->lsr & 0x20) + serial->lsr |= 0x40; + serial->lsr |= 0x20; + temp = serial->lsr; + if (serial->lsr & 0x1f) + serial->lsr &= ~0x1e; + serial->int_status &= ~SERIAL_INT_LSR; + serial_update_ints(serial); + break; + case 6: + temp = serial->msr; + serial->msr &= ~0x0f; + serial->int_status &= ~SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + temp = serial->scratch; + break; + } + return temp; +} + +void serial_recieve_callback(void *p) +{ + SERIAL *serial = (SERIAL *)p; + + serial->recieve_delay = 0; + + if (serial->fifo_read != serial->fifo_write) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } +} + +uint16_t base_address[2] = { 0x3f8, 0x2f8 }; + +void serial_remove(int port) +{ + if ((port < 1) || (port > 2)) + { + fatal("serial_remove(): Invalid serial port: %i\n", port); + exit(-1); + } + + if (!serial_enabled[port - 1]) + { + return; + } + + pclog("Removing serial port %i at %04X...\n", port, base_address[port - 1]); + + io_removehandler(base_address[port - 1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, (port == 1) ? &serial1 : &serial2); + base_address[port - 1] = 0x0000; +} + +void serial_setup(int port, uint16_t addr, int irq) +{ + SERIAL *p; + + if ((port < 1) || (port > 2)) + { + fatal("serial_setup(): Invalid serial port: %i\n", port); + exit(-1); + } + + if (!serial_enabled[port - 1]) + { + return; + } + + if (base_address[port - 1] != 0x0000) + { + serial_remove(port); + } + + if (addr == 0x0000) + { + pclog("Serial port %i at %04X, ignoring...\n", port, base_address[port - 1]); + return; + } + + if (port == 1) + { + p = &serial1; + } + else if (port == 2) + { + p = &serial2; + } + + pclog("Adding serial port %i at %04X...\n", port, addr); + + base_address[port - 1] = addr; + io_sethandler(base_address[port - 1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, p); + + p->irq = irq; +} + +void serial_init(void) +{ + if (serial_enabled[0]) + { + pclog("Adding serial port 1...\n"); + serial_setup(1, 0x3f8, 4); + serial1.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + } + if (serial_enabled[1]) + { + pclog("Adding serial port 2...\n"); + serial_setup(2, 0x2f8, 3); + serial2.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + } +}