diff --git a/README.md b/README.md index 9696756bf..7c07f7b76 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# 86Box [![Build Status](http://dome.rol.im/job/86Box/badge/icon)](http://dome.rol.im/job/86Box) -86Box (formerly PCem Unofficial, PCem Experimental, or PCem-X) is an unofficial branch of the PCem emulator, which aims to emulate IBM compatible machines from 1981-2000 period. This branch adds several emulated motherboards. +# 86Box [![Build Status](http://ci.86box.net/job/86Box/badge/icon)](http://ci.86box.net/job/86Box) +86Box (formerly PCem Unofficial, PCem Experimental, or PCem-X) is a fork of the PCem emulator, which aims to emulate IBM compatible machines from 1981-2000 period. This branch adds several emulated motherboards. --- Keep in touch with the 86Box community: diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index 563d4a1aa..d14ac1445 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -426,7 +426,6 @@ void loadseg(uint16_t seg, x86seg *s) if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status |= CPU_STATUS_FLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; } if (s == &_ss) @@ -625,6 +624,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (!(segdat[2]&0x8000)) { + x86np("Load CS JMP system selector not present\n", seg & 0xfffc); return; } type=segdat[2]&0xF00; @@ -637,14 +637,12 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) cgate32=(type&0x800); cgate16=!cgate32; oldcs=CS; - cpu_state.oldpc=cpu_state.pc; -#if 0 + cpu_state.oldpc = cpu_state.pc; if ((DPL < CPL) || (DPL < (seg&3))) { x86gpf(NULL,seg&~3); return; } -#endif if (DPL < CPL) { x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3); @@ -901,7 +899,7 @@ void loadcscall(uint16_t seg) } if (!(segdat[2]&0x8000)) { - x86ss("Load CS call not present", seg & 0xfffc); + x86np("Load CS call not present", seg & 0xfffc); return; } set_use32(segdat[3]&0x40); @@ -939,7 +937,7 @@ void loadcscall(uint16_t seg) cgate16=!cgate32; oldcs=CS; count=segdat[2]&31; - if ((DPL < CPL)) + if (DPL < CPL) { x86gpf("loadcscall(): ex DPL < CPL",seg&~3); return; @@ -1074,7 +1072,7 @@ void loadcscall(uint16_t seg) } if (!(segdat2[2]&0x8000)) { - x86np("Call gate loading SS not present\n", newss & 0xfffc); + x86ss("Call gate loading SS not present\n", newss & 0xfffc); return; } if (!stack32) oldsp &= 0xFFFF; @@ -1483,7 +1481,7 @@ void pmodeint(int num, int soft) uint32_t oldss,oldsp; int type; uint32_t newsp; - uint16_t seg = ds; + uint16_t seg = 0; int new_cpl; if (eflags&VM_FLAG && IOPL!=3 && soft) @@ -1865,7 +1863,7 @@ void pmodeiret(int is32) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); - taskswitch286(seg,segdat,0); + taskswitch286(seg,segdat,segdat[2] & 0x800); cpl_override=0; return; } diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fe81039e5..6bab7835c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -129,6 +129,15 @@ PLATCG = codegen_x86.o endif +ifeq ($(WALTJE), y) +SERIAL = serial.o +WSERIAL = win_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 @@ -151,7 +160,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 \ @@ -232,7 +241,7 @@ WINOBJ = win.o \ win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ win_d3d.o win_d3d_fs.o \ win_language.o win_status.o win_opendir.o win_dynld.o \ - win_video.o win_serial.o win_keyboard.o win_mouse.o \ + win_video.o $(WSERIAL) win_keyboard.o win_mouse.o \ win_iodev.o win_joystick.o win_midi.o \ win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res @@ -251,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/NETWORK/net_ne2000.c b/src/NETWORK/net_ne2000.c index d98fdf019..0b3a04de8 100644 --- a/src/NETWORK/net_ne2000.c +++ b/src/NETWORK/net_ne2000.c @@ -722,13 +722,13 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x07: /* ISR */ val &= 0x7f; /* clear RST bit - status-only bit */ /* All other values are cleared iff the ISR bit is 1 */ - dev->ISR.pkt_rx &= ~((int)((val & 0x01) == 0x01)); - dev->ISR.pkt_tx &= ~((int)((val & 0x02) == 0x02)); - dev->ISR.rx_err &= ~((int)((val & 0x04) == 0x04)); - dev->ISR.tx_err &= ~((int)((val & 0x08) == 0x08)); - dev->ISR.overwrite &= ~((int)((val & 0x10) == 0x10)); - dev->ISR.cnt_oflow &= ~((int)((val & 0x20) == 0x20)); - dev->ISR.rdma_done &= ~((int)((val & 0x40) == 0x40)); + dev->ISR.pkt_rx &= !((int)((val & 0x01) == 0x01)); + dev->ISR.pkt_tx &= !((int)((val & 0x02) == 0x02)); + dev->ISR.rx_err &= !((int)((val & 0x04) == 0x04)); + dev->ISR.tx_err &= !((int)((val & 0x08) == 0x08)); + dev->ISR.overwrite &= !((int)((val & 0x10) == 0x10)); + dev->ISR.cnt_oflow &= !((int)((val & 0x20) == 0x20)); + dev->ISR.rdma_done &= !((int)((val & 0x40) == 0x40)); val = ((dev->ISR.rdma_done << 6) | (dev->ISR.cnt_oflow << 5) | (dev->ISR.overwrite << 4) | diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 0a2e60944..0920e3884 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -591,6 +591,8 @@ void ega_poll(void *p) if (ega->sc == (ega->crtc[9] & 31)) { ega->sc = 0; + if (ega->sc == (ega->crtc[11] & 31)) + ega->con = 0; ega->maback += (ega->rowoffset << 3); ega->maback &= ega->vrammask; @@ -780,10 +782,16 @@ void ega_write(uint32_t addr, uint8_t val, void *p) if (addr & 1) writemask2 <<= 1; addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; + if (addr >= ega->vram_limit) + return; + if (!(ega->gdcreg[6] & 1)) fullchange = 2; @@ -907,10 +915,16 @@ uint8_t ega_read(uint32_t addr, void *p) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; + if (addr >= ega->vram_limit) + return 0xff; + ega->la = ega->vram[addr]; ega->lb = ega->vram[addr | 0x1]; ega->lc = ega->vram[addr | 0x2]; @@ -973,6 +987,10 @@ void ega_init(ega_t *ega) pallook16[c] = makecol32(0xaa, 0x55, 0); } ega->pallook = pallook16; + + ega->vram_limit = 256 * 1024; + ega->vrammask = ega->vram_limit-1; + old_overscan_color = 0; } @@ -1022,6 +1040,9 @@ void *ega_standalone_init() ega_common_defaults(ega); + ega->vram_limit = device_get_config_int("memory") * 1024; + ega->vrammask = ega->vram_limit-1; + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1058,6 +1079,9 @@ void *cpqega_standalone_init() ega_common_defaults(ega); + ega->vram_limit = device_get_config_int("memory") * 1024; + ega->vrammask = ega->vram_limit-1; + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1094,6 +1118,9 @@ void *sega_standalone_init() ega_common_defaults(ega); + ega->vram_limit = device_get_config_int("memory") * 1024; + ega->vrammask = ega->vram_limit-1; + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1236,6 +1263,30 @@ void ega_speed_changed(void *p) ega_recalctimings(ega); } +static device_config_t ega_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 256, + { + { + "64 kB", 64 + }, + { + "128 kB", 128 + }, + { + "256 kB", 256 + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + device_t ega_device = { "EGA", @@ -1245,7 +1296,8 @@ device_t ega_device = ega_standalone_available, ega_speed_changed, NULL, - NULL + NULL, + ega_config }; device_t cpqega_device = @@ -1257,7 +1309,8 @@ device_t cpqega_device = cpqega_standalone_available, ega_speed_changed, NULL, - NULL + NULL, + ega_config }; device_t sega_device = @@ -1269,7 +1322,8 @@ device_t sega_device = sega_standalone_available, ega_speed_changed, NULL, - NULL + NULL, + ega_config }; device_t jega_device = @@ -1281,5 +1335,6 @@ device_t jega_device = sega_standalone_available, ega_speed_changed, NULL, - NULL + NULL, + ega_config }; diff --git a/src/VIDEO/vid_ega.h b/src/VIDEO/vid_ega.h index 90ddf17a4..e7b30b32b 100644 --- a/src/VIDEO/vid_ega.h +++ b/src/VIDEO/vid_ega.h @@ -87,6 +87,8 @@ typedef struct ega_t uint8_t *vram; int vrammask; + uint32_t vram_limit; + int video_res_x, video_res_y, video_bpp; uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL; diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c index eea08992b..66c3f2f65 100644 --- a/src/VIDEO/vid_ega_render.c +++ b/src/VIDEO/vid_ega_render.c @@ -66,85 +66,84 @@ void ega_render_blank(ega_t *ega) } void ega_render_text_standard(ega_t *ega, int drawcursor) -{ +{ + int x, xx; int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); - uint8_t chr, dat, attr; - uint32_t charaddr; - int x, xx; - uint32_t fg, bg; + + for (x = 0; x < ega->hdisp; x++) + { + int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + uint8_t chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + uint8_t attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + uint8_t dat; + uint32_t fg, bg; + uint32_t charaddr; + + if (attr & 8) + charaddr = ega->charsetb + (chr * 128); + else + charaddr = ega->charseta + (chr * 128); - if (fullchange) - { - for (x = 0; x < ega->hdisp; x++) - { - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } + else + { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } - if (attr & 8) charaddr = ega->charsetb + (chr * 128); - else charaddr = ega->charseta + (chr * 128); - - if (drawcursor) - { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } - else - { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } - - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[((x << 4) + 32 + (xx << 1) + x_add) & 2047] = + ((uint32_t *)buffer32->line[dl])[((x << 4) + 33 + (xx << 1) + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + (xx << 1) + x_add) & 2047] = + ((uint32_t *)buffer32->line[dl])[((x * 18) + 33 + (xx << 1) + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 16 + x_add) & 2047] = + ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 17 + x_add) & 2047] = bg; + else + ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 16 + x_add) & 2047] = + ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 17 + x_add) & 2047] = (dat & 1) ? fg : bg; + } + } + else + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[((x << 3) + 32 + xx + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + xx + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + 8 + x_add) & 2047] = bg; + else + ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + 8 + x_add) & 2047] = (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } } static __inline int is_kanji1(uint8_t chr) @@ -381,24 +380,35 @@ void ega_render_2bpp_lowres(ega_t *ega) int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); int x; - int offset; - uint8_t edat[4]; + int offset = ((8 - ega->scrollcache) << 1) + 16; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[2]; + uint32_t addr = ega->ma; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; - edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; - } - else - { - edat[0] = ega->vram[(ega->ma << 1)]; - edat[1] = ega->vram[(ega->ma << 1) + 1]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + if (ega->seqregs[1] & 4) + ega->ma += 2; + else + ega->ma += 4; + + ega->ma &= ega->vrammask; ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; @@ -416,24 +426,35 @@ void ega_render_2bpp_highres(ega_t *ega) int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); int x; - int offset; - uint8_t edat[4]; + int offset = ((8 - ega->scrollcache) << 1) + 16; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[2]; + uint32_t addr = ega->ma; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; - edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; - } - else - { - edat[0] = ega->vram[(ega->ma << 1)]; - edat[1] = ega->vram[(ega->ma << 1) + 1]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + if (ega->seqregs[1] & 4) + ega->ma += 2; + else + ega->ma += 4; + + ega->ma &= ega->vrammask; ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; @@ -450,30 +471,49 @@ void ega_render_4bpp_lowres(ega_t *ega) { int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); - uint8_t dat; int x; - int offset; - uint8_t edat[4]; + int offset = ((8 - ega->scrollcache) << 1) + 16; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + + if (ega->seqregs[1] & 4) + { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } + else + { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; @@ -493,30 +533,48 @@ void ega_render_4bpp_highres(ega_t *ega) { int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); - uint8_t dat; int x; - int offset; - uint8_t edat[4]; + int offset = (8 - ega->scrollcache) + 24; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; - offset = (8 - ega->scrollcache) + 24; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + + if (ega->seqregs[1] & 4) + { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } + else + { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 7b33bdfee..e81dcf330 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -4034,7 +4034,7 @@ static void *s3_virge_375_4_init() static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; -#ifndef RELEASE_BUILD +#if 0 FILE *f = fopen("vram.dmp", "wb"); fwrite(virge->svga.vram, 4 << 20, 1, f); fclose(f); diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 8684de91f..3690bc2ac 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -401,7 +401,7 @@ uint8_t svga_in(uint16_t addr, void *p) case 0x3C1: return svga->attrregs[svga->attraddr]; case 0x3c2: - if ((romset == ROM_IBMPS1_2011) || (romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS2_M30_286)) + if ((romset == ROM_IBMPS1_2011) || (romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS1_2121_ISA) || (romset == ROM_IBMPS1_2133) || (romset == ROM_IBMPS2_M30_286) || (romset == ROM_IBMPS2_M50) || (romset == ROM_IBMPS2_M55SX) || (romset == ROM_IBMPS2_M80)) { if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) { diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index 4c0c5c617..7b4c0c136 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -25,21 +25,105 @@ int invert_display = 0; +int video_grayscale = 0; +int video_graytype = 0; +uint32_t shade[5][256] = +{ + {0}, // RGB Color (unused) + {0}, // RGB Grayscale (unused) + { // Amber monitor + 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, + 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, + 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, + 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, + 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, + 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, + 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, + 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, + 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, + 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, + 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, + 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, + 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, + 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, + 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, + 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 + }, + { // Green monitor + 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, + 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, + 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, + 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, + 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, + 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, + 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, + 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, + 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, + 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, + 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, + 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, + 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, + 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, + 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, + 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 + }, + { // White monitor + 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, + 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, + 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, + 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, + 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, + 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, + 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, + 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, + 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, + 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, + 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, + 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, + 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, + 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, + 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, + 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec + } +}; uint32_t svga_color_transform(uint32_t color) { uint32_t temp = 0; + if (video_grayscale != 0) + { + if (video_graytype) + { + if (video_graytype == 1) + temp = ((54 * ((color & 0xff0000) >> 16)) + (183 * ((color & 0xff00) >> 8)) + (18 * (color & 0xff))) / 255; + else + temp = (((color & 0xff0000) >> 16) + ((color & 0xff00) >> 8) + (color & 0xff)) / 3; + } + else + temp = ((76 * ((color & 0xff0000) >> 16)) + (150 * ((color & 0xff00) >> 8)) + (29 * (color & 0xff))) / 255; + switch (video_grayscale) + { + case 2: + case 3: + case 4: + color = shade[video_grayscale][temp]; + break; + default: + color = temp; + color |= temp << 8; + color |= temp << 16; + break; + } + } if (invert_display) { - temp |= (0xff - (color & 0xff)); + temp = (0xff - (color & 0xff)); temp |= (0xff00 - (color & 0xff00)); temp |= (0xff0000 - (color & 0xff0000)); } else - { - temp = color; - } + return color; return temp; } diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index 339e393b6..9e0d801f8 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -647,6 +647,8 @@ void video_wait_for_buffer() void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { + if (h <= 0) + return; video_wait_for_blit(); blit_data.busy = 1; blit_data.buffer_in_use = 1; @@ -662,6 +664,8 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) void video_blit_memtoscreen_8(int x, int y, int w, int h) { + if (h <= 0) + return; video_wait_for_blit(); blit_data.busy = 1; blit_data.x = x; @@ -714,7 +718,7 @@ void take_screenshot() info = localtime(&now); memset(screenshot_fn, 0, 8192); memset(screenshot_fn_partial, 0, 4096); - memset(screenshot_path, 0, 4096); + memset(screenshot_path, 0, 8192); pclog("Video API is: %i\n", vid_api); append_filename_w(screenshot_path, pcempath, L"screenshots", 4095); if (!DirectoryExists(screenshot_path)) diff --git a/src/VIDEO/video.h b/src/VIDEO/video.h index f9b7fef85..53cb98c5c 100644 --- a/src/VIDEO/video.h +++ b/src/VIDEO/video.h @@ -113,6 +113,9 @@ void ddraw_fs_take_screenshot(wchar_t *fn); extern int cga_palette; extern int vid_cga_contrast; +extern int video_grayscale; +extern int video_graytype; + void loadfont(wchar_t *s, int format); void initvideo(); void video_init(); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index ce74b432f..8ce246530 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -46,7 +46,7 @@ BEGIN BEGIN MENUITEM "&Hard Reset", IDM_ACTION_HRESET MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD - MENUITEM "&Ctrl+Alt+Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR MENUITEM "E&xit", IDM_ACTION_EXIT END @@ -81,6 +81,20 @@ BEGIN BEGIN MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + POPUP "VGA screen &type" + BEGIN + MENUITEM "RGB &Color", IDM_VID_GRAY_RGB + MENUITEM "&RGB Grayscale", IDM_VID_GRAY_MONO + MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER + MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN + MENUITEM "&White monitor", IDM_VID_GRAY_WHITE + END + POPUP "Grayscale &conversion type" + BEGIN + MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 + MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "&Average", IDM_VID_GRAYCT_AVE + END END MENUITEM SEPARATOR MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 @@ -248,7 +262,7 @@ BEGIN LTEXT "MB",IDT_1705,123,64,10,10 LTEXT "Memory:",IDT_1706,7,64,30,10 LTEXT "NVR Path:",IDT_1700,7,83,60,10 - EDITTEXT IDC_EDIT_NVR_PATH,71,82,138,12 + EDITTEXT IDC_EDIT_NVR_PATH,71,82,138,12,ES_AUTOHSCROLL PUSHBUTTON "&Specify...",IDC_BUTTON_NVR_PATH,214,82,46,12 CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,100,94,10 @@ -279,7 +293,7 @@ STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN LTEXT "Mouse :",IDT_1709,7,8,57,10 - COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Joystick :",IDT_1710,7,26,58,10 COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | @@ -917,7 +931,7 @@ BEGIN VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" VALUE "FileVersion", "2.00\0" VALUE "InternalName", "86Box\0" - VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" + VALUE "LegalCopyright", "Copyright � SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "86Box.exe\0" VALUE "PrivateBuild", "\0" diff --git a/src/WIN/resource.h b/src/WIN/resource.h index e5c181fa5..02fa21a9f 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -410,6 +410,14 @@ #define IDM_VID_OVERSCAN 40076 #define IDM_VID_INVERT 40079 #define IDM_VID_CGACON 40080 +#define IDM_VID_GRAYCT_601 40085 +#define IDM_VID_GRAYCT_709 40086 +#define IDM_VID_GRAYCT_AVE 40087 +#define IDM_VID_GRAY_RGB 40090 +#define IDM_VID_GRAY_MONO 40091 +#define IDM_VID_GRAY_AMBER 40092 +#define IDM_VID_GRAY_GREEN 40093 +#define IDM_VID_GRAY_WHITE 40094 #define IDM_LOG_BREAKPOINT 51201 #define IDM_DUMP_VRAM 51202 // should be an Action diff --git a/src/WIN/win.c b/src/WIN/win.c index 4c19e70e1..dc30da3fd 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1532,6 +1532,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); CheckMenuItem(menu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_GRAYCT_601 + video_graytype, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_GRAY_RGB + video_grayscale, MF_CHECKED); d=romset; for (c=0;c=ROM_IBMAT)) diff --git a/src/keyboard.c b/src/keyboard.c index 7a60c5a62..d551fa622 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -422,7 +422,7 @@ static int scorder[272] = {0x38, 0xB8, 0x1D, 0x9D, 0xFF, 0x2A, 0x36,0x103, 0x00, 0xFE,0x100,0x101,0x102,0x104,0x105,0x106,0x107,0x108,0x109,0x10A,0x10B,0x10C,0x10D,0x10E,0x10F}; /* bit 0 = repeat, bit 1 = makes break code? */ -int set3_flags[272]; +uint8_t set3_flags[272]; uint8_t set3_all_repeat = 0; uint8_t set3_all_break = 0; diff --git a/src/keyboard.h b/src/keyboard.h index 217f1cee1..0c3a1b651 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -24,6 +24,6 @@ extern int pcem_key[272]; extern uint8_t mode; void keyboard_process(); -extern int set3_flags[272]; +extern uint8_t set3_flags[272]; extern uint8_t set3_all_repeat; extern uint8_t set3_all_break; diff --git a/src/mem.c b/src/mem.c index 548376a56..d7e181537 100644 --- a/src/mem.c +++ b/src/mem.c @@ -97,8 +97,8 @@ int loadbios() FILE *f=NULL,*ff=NULL; int c; - loadfont(L"roms/graphics/mda/mda.rom", 0); - loadfont(L"roms/graphics/wyse700/wy700.rom", 3); + loadfont(L"roms/video/mda/mda.rom", 0); + loadfont(L"roms/video/wyse700/wy700.rom", 3); biosmask = 0xffff; @@ -217,22 +217,23 @@ int loadbios() return 1; case ROM_PORTABLEII: - f = romfopen(L"roms/machines/portableii/62x0820.u27", L"rb"); - ff =romfopen(L"roms/machines/portableii/62x0821.u47", L"rb"); + f = romfopen(L"roms/machines/portableii/106438-001.BIN", L"rb"); + ff =romfopen(L"roms/machines/portableii/106437-001.BIN", L"rb"); if (!f || !ff) break; - for (c=0x0000;c<0x10000;c+=2) + for (c=0x0000;c<0x8000;c+=2) { rom[c]=getc(f); rom[c+1]=getc(ff); } fclose(ff); fclose(f); + biosmask = 0x7fff; return 1; case ROM_PORTABLEIII: case ROM_PORTABLEIII386: - f = romfopen(L"roms/machines/portableiii/62x0820.u27", L"rb"); - ff =romfopen(L"roms/machines/portableiii/62x0821.u47", L"rb"); + f = romfopen(L"roms/machines/portableiii/109738-002.BIN", L"rb"); + ff =romfopen(L"roms/machines/portableiii/109737-002.BIN", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -2179,7 +2180,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 +2280,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(); } @@ -2316,16 +2323,19 @@ static uint8_t port_92_read(uint16_t port, void *priv) static void port_92_write(uint16_t port, uint8_t val, void *priv) { - if (val & 1) + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + + if ((~port_92_reg & val) & 1) { softresetx86(); cpu_set_edx(); } - port_92_reg = val & ~-1; - - mem_a20_alt = val & 2; - mem_a20_recalc(); + port_92_reg = val; } void port_92_clear_reset() diff --git a/src/model.c b/src/model.c index 311bb1af5..001dc0bcf 100644 --- a/src/model.c +++ b/src/model.c @@ -171,28 +171,28 @@ MODEL models[] = {"[286] Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, {"[286] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL }, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL }, - {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL }, - {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL }, + {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL }, + {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL }, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL }, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, - {"[386SX] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, - {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL }, + {"[386SX] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, + {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL }, {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, {"[386DX] Amstrad MegaPC 386DX",ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL }, {"[386DX] Compaq Portable III 386",ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, - {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL }, + {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL }, {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, {"[486] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, {"[486] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL }, - {"[486] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL }, + {"[486] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL }, {"[486] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL }, {"[Socket 4 LX] Intel Premiere/PCI",ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL }, 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/nvr.c b/src/nvr.c index 392e627eb..f2c5c8659 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -27,6 +27,7 @@ #include "io.h" #include "mem.h" #include "model.h" +#include "nmi.h" #include "nvr.h" #include "pic.h" #include "rom.h" @@ -184,7 +185,11 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) } } } - else nvraddr=val&nvrmask; + else + { + nvraddr=val&nvrmask; + nmi_mask = ~val & 0x80; + } } uint8_t readnvr(uint16_t addr, void *priv) diff --git a/src/pc.c b/src/pc.c index d62a1cfb2..0df42a936 100644 --- a/src/pc.c +++ b/src/pc.c @@ -366,7 +366,9 @@ void initmodules(void) /* Initialize modules. */ network_init(); mouse_init(); +#ifdef WALTJE serial_init(); +#endif disc_random_init(); joystick_init(); @@ -512,6 +514,9 @@ void resetpchard_init(void) fdc_init(); disc_reset(); +#ifndef WALTJE + serial_init(); +#endif model_init(); video_init(); speaker_init(); diff --git a/src/ps1.c b/src/ps1.c index 935bcef0d..3efcc500b 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -300,6 +300,7 @@ void ps1mb_m2121_init(void) 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + ps1_92 = 0; ps1_190 = 0; lpt1_init(0x3bc); @@ -315,6 +316,7 @@ void ps1mb_m2133_init(void) io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + ps1_92 = 0; ps1_190 = 0; lpt1_init(0x3bc); diff --git a/src/ps2.c b/src/ps2.c index 6d9075358..9042b12e8 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -131,6 +131,7 @@ void ps2board_init(void) io_sethandler(0x0322, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + ps2_92 = 0; ps2_190 = 0; lpt1_init(0x3bc); diff --git a/src/scat.c b/src/scat.c index f1b9e8b69..77dd8f308 100644 --- a/src/scat.c +++ b/src/scat.c @@ -494,6 +494,7 @@ void scat_init() scat_regs[SCAT_DRAM_CONFIGURATION] = cpu_waitstates == 1 ? 2 : 0x12; scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; scat_regs[SCAT_EMS_CONTROL] = 0; + scat_port_92 = 0; mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); 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..c6bc83e4c --- /dev/null +++ b/src/serial_old.c @@ -0,0 +1,341 @@ +#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] = { 0x0000, 0x0000 }; + +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; + } + + if (!base_address[port - 1]) + { + return; + } + + pclog("Removing serial port %i at %04X...\n", port, base_address[port - 1]); + + switch(port) + { + case 1: + io_removehandler(base_address[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + base_address[0] = 0x0000; + break; + case 2: + io_removehandler(base_address[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + base_address[1] = 0x0000; + break; + } +} + +void serial_setup(int port, uint16_t addr, int irq) +{ + pclog("Adding serial port %i at %04X...\n", port, addr); + + switch(port) + { + case 1: + if (base_address[0] != 0x0000) + { + serial_remove(port); + } + if (addr != 0x0000) + { + base_address[0] = addr; + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + } + serial1.irq = irq; + break; + case 2: + if (base_address[1] != 0x0000) + { + serial_remove(port); + } + if (addr != 0x0000) + { + base_address[1] = addr; + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + } + serial2.irq = irq; + break; + default: + fatal("serial_setup(): Invalid serial port: %i\n", port); + break; + } +} + +void serial_init(void) +{ + base_address[0] = 0x03f8; + base_address[1] = 0x02f8; + + if (serial_enabled[0]) + { + pclog("Adding serial port 1...\n"); + memset(&serial1, 0, sizeof(serial1)); + io_sethandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = 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"); + memset(&serial2, 0, sizeof(serial2)); + io_sethandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = 3; + serial2.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + } +} diff --git a/src/timer.c b/src/timer.c index d3fd618a7..82eabe39c 100644 --- a/src/timer.c +++ b/src/timer.c @@ -8,7 +8,7 @@ #include "sound_wss.h"*/ #include "timer.h" -#define TIMERS_MAX 32 +#define TIMERS_MAX 64 int TIMER_USEC;