From 51fb2f83cbef4a1b37645b63bbe5a2d490e85ec5 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Thu, 16 Jul 2015 12:19:37 -0500 Subject: [PATCH] O SHIT I COMPILED IT ALL WWWW modified: 16/dos_kb.c modified: 16/dos_kb.h new file: make-lowercase modified: makefile modified: miditest.exe modified: sountest.exe modified: src/lib/16_in.h deleted: src/lib/dos_kb.c deleted: src/lib/dos_kb.h modified: src/lib/doslib/8254.h modified: src/lib/doslib/8259.h modified: src/lib/doslib/adlib.h modified: src/lib/doslib/cpu.c modified: src/lib/doslib/cpu.h modified: src/lib/doslib/dos.c modified: src/lib/doslib/dos.h deleted: src/lib/doslib/dos/CLEAN.BAT deleted: src/lib/doslib/dos/MAKE.BAT deleted: src/lib/doslib/dos/biosext.c deleted: src/lib/doslib/dos/biosext.h deleted: src/lib/doslib/dos/biosmem.c deleted: src/lib/doslib/dos/biosmem.h deleted: src/lib/doslib/dos/biosmem3.c deleted: src/lib/doslib/dos/common.mak deleted: src/lib/doslib/dos/cr3.c deleted: src/lib/doslib/dos/ddpmidos.c deleted: src/lib/doslib/dos/ddpmidsc.c deleted: src/lib/doslib/dos/ddpmilin.c deleted: src/lib/doslib/dos/ddpmiphy.c deleted: src/lib/doslib/dos/dos.c deleted: src/lib/doslib/dos/dos.h deleted: src/lib/doslib/dos/dos386f/dosntast.vdd deleted: src/lib/doslib/dos/dos86c/dosntast.vdd deleted: src/lib/doslib/dos/dos86l/dosntast.vdd deleted: src/lib/doslib/dos/dos86m/dosntast.vdd deleted: src/lib/doslib/dos/dos86s/dosntast.vdd deleted: src/lib/doslib/dos/dos9xvm.c deleted: src/lib/doslib/dos/dos_lol.c deleted: src/lib/doslib/dos/dos_ltp.c deleted: src/lib/doslib/dos/dos_mcb.c deleted: src/lib/doslib/dos/dos_nmi.c deleted: src/lib/doslib/dos/dosasm.asm deleted: src/lib/doslib/dos/dosbox.c deleted: src/lib/doslib/dos/dosbox.h deleted: src/lib/doslib/dos/dosdev.c deleted: src/lib/doslib/dos/dosdpmi.c deleted: src/lib/doslib/dos/dosflavr.c deleted: src/lib/doslib/dos/dosmapal.c deleted: src/lib/doslib/dos/dosntast.c deleted: src/lib/doslib/dos/dosntvdm.c deleted: src/lib/doslib/dos/dosntvdm.h deleted: src/lib/doslib/dos/dospsp.c deleted: src/lib/doslib/dos/dossmdrv.c deleted: src/lib/doslib/dos/dosvbox.c deleted: src/lib/doslib/dos/dosvcpi.c deleted: src/lib/doslib/dos/doswin.c deleted: src/lib/doslib/dos/doswin.h deleted: src/lib/doslib/dos/dosxio.c deleted: src/lib/doslib/dos/dpmiexcp.c deleted: src/lib/doslib/dos/dpmirmcl.c deleted: src/lib/doslib/dos/emm.c deleted: src/lib/doslib/dos/himemsys.h deleted: src/lib/doslib/dos/lol.c deleted: src/lib/doslib/dos/ntastrm.c deleted: src/lib/doslib/dos/readme deleted: src/lib/doslib/dos/test.c deleted: src/lib/doslib/dos/testbext.c deleted: src/lib/doslib/dos/testdpmi.c deleted: src/lib/doslib/dos/testsmrt.c deleted: src/lib/doslib/dos/tgusmega.c deleted: src/lib/doslib/dos/tgusmega.h deleted: src/lib/doslib/dos/tgussbos.c deleted: src/lib/doslib/dos/tgussbos.h deleted: src/lib/doslib/dos/tgusumid.c deleted: src/lib/doslib/dos/tgusumid.h deleted: src/lib/doslib/dos/tmp.cmd deleted: src/lib/doslib/dos/tstbiom.c deleted: src/lib/doslib/dos/tstlp.c deleted: src/lib/doslib/dos/win16vec.c deleted: src/lib/doslib/dos/win3216t.c deleted: src/lib/doslib/dos/win32lrd.c deleted: src/lib/doslib/dos/winfcon.c deleted: src/lib/doslib/dos/winfcon.h deleted: src/lib/doslib/dos/winnt/dosntast.vdd deleted: src/lib/doslib/dosdrv/buildall.bat deleted: src/lib/doslib/dosdrv/clean.bat deleted: src/lib/doslib/dosdrv/hello/CLEAN.BAT deleted: src/lib/doslib/dosdrv/hello/MAKE.BAT deleted: src/lib/doslib/dosdrv/hello/common.mak deleted: src/lib/doslib/dosdrv/hello/config.sys deleted: src/lib/doslib/dosdrv/hello/hello.asm deleted: src/lib/doslib/dosdrv/hello/test.dsk.gz renamed: src/lib/doslib/hw/dos/emm.c -> src/lib/doslib/emm.c renamed: src/lib/doslib/dos/emm.h -> src/lib/doslib/emm.h renamed: src/lib/doslib/dos/himemsys.c -> src/lib/doslib/himemsys.c renamed: src/lib/doslib/hw/dos/himemsys.h -> src/lib/doslib/himemsys.h deleted: src/lib/doslib/hw/8042/8042.c deleted: src/lib/doslib/hw/8042/8042.h deleted: src/lib/doslib/hw/8042/8042aux.c deleted: src/lib/doslib/hw/8042/CLEAN.BAT deleted: src/lib/doslib/hw/8042/MAKE.BAT deleted: src/lib/doslib/hw/8042/common.mak deleted: src/lib/doslib/hw/8042/test.c deleted: src/lib/doslib/hw/8237/8237.c deleted: src/lib/doslib/hw/8237/8237.h deleted: src/lib/doslib/hw/8237/CLEAN.BAT deleted: src/lib/doslib/hw/8237/MAKE.BAT deleted: src/lib/doslib/hw/8237/common.mak deleted: src/lib/doslib/hw/8237/test.c deleted: src/lib/doslib/hw/8250/8250.c deleted: src/lib/doslib/hw/8250/8250.h deleted: src/lib/doslib/hw/8250/8250pnp.c deleted: src/lib/doslib/hw/8250/8250pnp.h deleted: src/lib/doslib/hw/8250/CLEAN.BAT deleted: src/lib/doslib/hw/8250/MAKE.BAT deleted: src/lib/doslib/hw/8250/common.mak deleted: src/lib/doslib/hw/8250/test.c deleted: src/lib/doslib/hw/8250/testpnp.c deleted: src/lib/doslib/hw/8254/8254.c deleted: src/lib/doslib/hw/8254/8254.h deleted: src/lib/doslib/hw/8254/8254rd.c deleted: src/lib/doslib/hw/8254/CLEAN.BAT deleted: src/lib/doslib/hw/8254/MAKE.BAT deleted: src/lib/doslib/hw/8254/common.mak deleted: src/lib/doslib/hw/8254/readme deleted: src/lib/doslib/hw/8254/test.c deleted: src/lib/doslib/hw/8254/test1_22.wav deleted: src/lib/doslib/hw/8254/tmp.cmd deleted: src/lib/doslib/hw/8259/8259.c deleted: src/lib/doslib/hw/8259/8259.h deleted: src/lib/doslib/hw/8259/CLEAN.BAT deleted: src/lib/doslib/hw/8259/MAKE.BAT deleted: src/lib/doslib/hw/8259/common.mak deleted: src/lib/doslib/hw/8259/readme deleted: src/lib/doslib/hw/8259/test.c deleted: src/lib/doslib/hw/8259/tmp.cmd deleted: src/lib/doslib/hw/acpi/CLEAN.BAT deleted: src/lib/doslib/hw/acpi/MAKE.BAT deleted: src/lib/doslib/hw/acpi/acpi.c deleted: src/lib/doslib/hw/acpi/acpi.h deleted: src/lib/doslib/hw/acpi/common.mak deleted: src/lib/doslib/hw/acpi/test.c deleted: src/lib/doslib/hw/adlib/CLEAN.BAT deleted: src/lib/doslib/hw/adlib/MAKE.BAT deleted: src/lib/doslib/hw/adlib/adlib.c deleted: src/lib/doslib/hw/adlib/adlib.h deleted: src/lib/doslib/hw/adlib/common.mak deleted: src/lib/doslib/hw/adlib/dos386f/dos4gw.exe deleted: src/lib/doslib/hw/adlib/dos386f/midi.exe deleted: src/lib/doslib/hw/adlib/dos386f/test.exe deleted: src/lib/doslib/hw/adlib/dos86c/dos4gw.exe deleted: src/lib/doslib/hw/adlib/dos86c/midi.exe deleted: src/lib/doslib/hw/adlib/dos86c/test.exe deleted: src/lib/doslib/hw/adlib/dos86l/dos4gw.exe deleted: src/lib/doslib/hw/adlib/dos86l/midi.exe deleted: src/lib/doslib/hw/adlib/dos86l/test.exe deleted: src/lib/doslib/hw/adlib/dos86m/dos4gw.exe deleted: src/lib/doslib/hw/adlib/dos86m/midi.exe deleted: src/lib/doslib/hw/adlib/dos86m/test.exe deleted: src/lib/doslib/hw/adlib/dos86s/dos4gw.exe deleted: src/lib/doslib/hw/adlib/dos86s/midi.exe deleted: src/lib/doslib/hw/adlib/dos86s/test.exe deleted: src/lib/doslib/hw/adlib/midi.c deleted: src/lib/doslib/hw/adlib/midikeys.gen.pl deleted: src/lib/doslib/hw/adlib/readme deleted: src/lib/doslib/hw/adlib/test.c deleted: src/lib/doslib/hw/adlib/tmp.cmd deleted: src/lib/doslib/hw/apm/CLEAN.BAT deleted: src/lib/doslib/hw/apm/MAKE.BAT deleted: src/lib/doslib/hw/apm/apm.c deleted: src/lib/doslib/hw/apm/apm.h deleted: src/lib/doslib/hw/apm/common.mak deleted: src/lib/doslib/hw/apm/readme deleted: src/lib/doslib/hw/apm/test.c deleted: src/lib/doslib/hw/biosdisk/CLEAN.BAT deleted: src/lib/doslib/hw/biosdisk/MAKE.BAT deleted: src/lib/doslib/hw/biosdisk/biosdisk.c deleted: src/lib/doslib/hw/biosdisk/biosdisk.h deleted: src/lib/doslib/hw/biosdisk/common.mak deleted: src/lib/doslib/hw/biosdisk/dumphdp.c deleted: src/lib/doslib/hw/biosdisk/test.c deleted: src/lib/doslib/hw/buildall.bat deleted: src/lib/doslib/hw/clean.bat deleted: src/lib/doslib/hw/cpu/CLEAN.BAT deleted: src/lib/doslib/hw/cpu/MAKE.BAT deleted: src/lib/doslib/hw/cpu/alignchk.asm deleted: src/lib/doslib/hw/cpu/apic.c deleted: src/lib/doslib/hw/cpu/apiclib.c deleted: src/lib/doslib/hw/cpu/apiclib.h deleted: src/lib/doslib/hw/cpu/bochstst/bochsrc deleted: src/lib/doslib/hw/cpu/common.mak deleted: src/lib/doslib/hw/cpu/config.sys deleted: src/lib/doslib/hw/cpu/cpu.c deleted: src/lib/doslib/hw/cpu/cpu.h deleted: src/lib/doslib/hw/cpu/cpuasm.asm deleted: src/lib/doslib/hw/cpu/cpuid.asm deleted: src/lib/doslib/hw/cpu/cpuidext.c deleted: src/lib/doslib/hw/cpu/cpuidext.h deleted: src/lib/doslib/hw/cpu/cpuiopd.asm deleted: src/lib/doslib/hw/cpu/cpup3sn.asm deleted: src/lib/doslib/hw/cpu/cpup3sn.h deleted: src/lib/doslib/hw/cpu/cpup3snc.c deleted: src/lib/doslib/hw/cpu/cpurdmsr.asm deleted: src/lib/doslib/hw/cpu/cpurdtsc.asm deleted: src/lib/doslib/hw/cpu/cpurdtsc.h deleted: src/lib/doslib/hw/cpu/cpusse.c deleted: src/lib/doslib/hw/cpu/cpusse.h deleted: src/lib/doslib/hw/cpu/cpussea.asm deleted: src/lib/doslib/hw/cpu/cpustrlv.c deleted: src/lib/doslib/hw/cpu/dispsn.c deleted: src/lib/doslib/hw/cpu/emm386.exe.gz deleted: src/lib/doslib/hw/cpu/gdt_enum.c deleted: src/lib/doslib/hw/cpu/gdt_enum.h deleted: src/lib/doslib/hw/cpu/gdtlist.c deleted: src/lib/doslib/hw/cpu/gdttae.c deleted: src/lib/doslib/hw/cpu/gr_add.c deleted: src/lib/doslib/hw/cpu/gr_add_t.bat deleted: src/lib/doslib/hw/cpu/grind.c deleted: src/lib/doslib/hw/cpu/grtest.bat deleted: src/lib/doslib/hw/cpu/hdd.dsk.gz deleted: src/lib/doslib/hw/cpu/libgrind.c deleted: src/lib/doslib/hw/cpu/libgrind.h deleted: src/lib/doslib/hw/cpu/mmx.c deleted: src/lib/doslib/hw/cpu/msdos5m.dsk.gz deleted: src/lib/doslib/hw/cpu/notes deleted: src/lib/doslib/hw/cpu/prot286.asm deleted: src/lib/doslib/hw/cpu/prot386.asm deleted: src/lib/doslib/hw/cpu/protdpmi.asm deleted: src/lib/doslib/hw/cpu/protvcpi.asm deleted: src/lib/doslib/hw/cpu/rdtsc.c deleted: src/lib/doslib/hw/cpu/reset.c deleted: src/lib/doslib/hw/cpu/resetasm.asm deleted: src/lib/doslib/hw/cpu/sse.c deleted: src/lib/doslib/hw/cpu/sseoff.c deleted: src/lib/doslib/hw/cpu/test.c deleted: src/lib/doslib/hw/cpu/tmp.cmd deleted: src/lib/doslib/hw/cpu/tss.asm deleted: src/lib/doslib/hw/cpu/tssring.asm deleted: src/lib/doslib/hw/cpu/v86.asm deleted: src/lib/doslib/hw/cpu/v86kern.asm deleted: src/lib/doslib/hw/cpu/v86kern2.asm deleted: src/lib/doslib/hw/cpu/win95.dsk.gz deleted: src/lib/doslib/hw/dos/CLEAN.BAT deleted: src/lib/doslib/hw/dos/MAKE.BAT deleted: src/lib/doslib/hw/dos/biosext.c deleted: src/lib/doslib/hw/dos/biosext.h deleted: src/lib/doslib/hw/dos/biosmem.c deleted: src/lib/doslib/hw/dos/biosmem.h deleted: src/lib/doslib/hw/dos/biosmem3.c deleted: src/lib/doslib/hw/dos/common.mak deleted: src/lib/doslib/hw/dos/cr3.c deleted: src/lib/doslib/hw/dos/ddpmidos.c deleted: src/lib/doslib/hw/dos/ddpmidsc.c deleted: src/lib/doslib/hw/dos/ddpmilin.c deleted: src/lib/doslib/hw/dos/ddpmiphy.c deleted: src/lib/doslib/hw/dos/dos.c deleted: src/lib/doslib/hw/dos/dos.h deleted: src/lib/doslib/hw/dos/dos386f/dosntast.vdd deleted: src/lib/doslib/hw/dos/dos86c/dosntast.vdd deleted: src/lib/doslib/hw/dos/dos86l/dosntast.vdd deleted: src/lib/doslib/hw/dos/dos86m/dosntast.vdd deleted: src/lib/doslib/hw/dos/dos86s/dosntast.vdd deleted: src/lib/doslib/hw/dos/dos9xvm.c deleted: src/lib/doslib/hw/dos/dos_lol.c deleted: src/lib/doslib/hw/dos/dos_ltp.c deleted: src/lib/doslib/hw/dos/dos_mcb.c deleted: src/lib/doslib/hw/dos/dos_nmi.c deleted: src/lib/doslib/hw/dos/dosasm.asm deleted: src/lib/doslib/hw/dos/dosbox.c deleted: src/lib/doslib/hw/dos/dosbox.h deleted: src/lib/doslib/hw/dos/dosdev.c deleted: src/lib/doslib/hw/dos/dosdpmi.c deleted: src/lib/doslib/hw/dos/dosflavr.c deleted: src/lib/doslib/hw/dos/dosmapal.c deleted: src/lib/doslib/hw/dos/dosntast.c deleted: src/lib/doslib/hw/dos/dosntvdm.c deleted: src/lib/doslib/hw/dos/dosntvdm.h deleted: src/lib/doslib/hw/dos/dospsp.c deleted: src/lib/doslib/hw/dos/dossmdrv.c deleted: src/lib/doslib/hw/dos/dosvbox.c deleted: src/lib/doslib/hw/dos/dosvcpi.c deleted: src/lib/doslib/hw/dos/doswin.c deleted: src/lib/doslib/hw/dos/doswin.h deleted: src/lib/doslib/hw/dos/dosxio.c deleted: src/lib/doslib/hw/dos/dpmiexcp.c deleted: src/lib/doslib/hw/dos/dpmirmcl.c deleted: src/lib/doslib/hw/dos/emm.h deleted: src/lib/doslib/hw/dos/himemsys.c deleted: src/lib/doslib/hw/dos/lol.c deleted: src/lib/doslib/hw/dos/ntastrm.c deleted: src/lib/doslib/hw/dos/readme deleted: src/lib/doslib/hw/dos/test.c deleted: src/lib/doslib/hw/dos/testbext.c deleted: src/lib/doslib/hw/dos/testdpmi.c deleted: src/lib/doslib/hw/dos/testemm.c deleted: src/lib/doslib/hw/dos/testsmrt.c deleted: src/lib/doslib/hw/dos/tgusmega.c deleted: src/lib/doslib/hw/dos/tgusmega.h deleted: src/lib/doslib/hw/dos/tgussbos.c deleted: src/lib/doslib/hw/dos/tgussbos.h deleted: src/lib/doslib/hw/dos/tgusumid.c deleted: src/lib/doslib/hw/dos/tgusumid.h deleted: src/lib/doslib/hw/dos/tmp.cmd deleted: src/lib/doslib/hw/dos/tstbiom.c deleted: src/lib/doslib/hw/dos/tsthimem.c deleted: src/lib/doslib/hw/dos/tstlp.c deleted: src/lib/doslib/hw/dos/win16vec.c deleted: src/lib/doslib/hw/dos/win3216t.c deleted: src/lib/doslib/hw/dos/win32lrd.c deleted: src/lib/doslib/hw/dos/winfcon.c deleted: src/lib/doslib/hw/dos/winfcon.h deleted: src/lib/doslib/hw/dos/winnt/dosntast.vdd deleted: src/lib/doslib/hw/flatreal/CLEAN.BAT deleted: src/lib/doslib/hw/flatreal/MAKE.BAT deleted: src/lib/doslib/hw/flatreal/common.mak deleted: src/lib/doslib/hw/flatreal/flatmode.asm deleted: src/lib/doslib/hw/flatreal/flatreal.c deleted: src/lib/doslib/hw/flatreal/flatreal.h deleted: src/lib/doslib/hw/flatreal/readme deleted: src/lib/doslib/hw/flatreal/test.c deleted: src/lib/doslib/hw/floppy/CLEAN.BAT deleted: src/lib/doslib/hw/floppy/MAKE.BAT deleted: src/lib/doslib/hw/floppy/common.mak deleted: src/lib/doslib/hw/floppy/floppy.c deleted: src/lib/doslib/hw/floppy/floppy.h deleted: src/lib/doslib/hw/floppy/msdos622.dsk.gz deleted: src/lib/doslib/hw/floppy/test.c deleted: src/lib/doslib/hw/floppy/win95.dsk.gz deleted: src/lib/doslib/hw/ide/CLEAN.BAT deleted: src/lib/doslib/hw/ide/MAKE.BAT deleted: src/lib/doslib/hw/ide/common.mak deleted: src/lib/doslib/hw/ide/idelib.c deleted: src/lib/doslib/hw/ide/idelib.h deleted: src/lib/doslib/hw/ide/readme deleted: src/lib/doslib/hw/ide/test.c deleted: src/lib/doslib/hw/ide/test.h deleted: src/lib/doslib/hw/ide/testbusy.c deleted: src/lib/doslib/hw/ide/testbusy.h deleted: src/lib/doslib/hw/ide/testcdej.c deleted: src/lib/doslib/hw/ide/testcdej.h deleted: src/lib/doslib/hw/ide/testcdrm.c deleted: src/lib/doslib/hw/ide/testcdrm.h deleted: src/lib/doslib/hw/ide/testcmui.c deleted: src/lib/doslib/hw/ide/testcmui.h deleted: src/lib/doslib/hw/ide/testidnt.c deleted: src/lib/doslib/hw/ide/testidnt.h deleted: src/lib/doslib/hw/ide/testmbox.c deleted: src/lib/doslib/hw/ide/testmbox.h deleted: src/lib/doslib/hw/ide/testmisc.c deleted: src/lib/doslib/hw/ide/testmisc.h deleted: src/lib/doslib/hw/ide/testmumo.c deleted: src/lib/doslib/hw/ide/testmumo.h deleted: src/lib/doslib/hw/ide/testnop.c deleted: src/lib/doslib/hw/ide/testnop.h deleted: src/lib/doslib/hw/ide/testpiom.c deleted: src/lib/doslib/hw/ide/testpiom.h deleted: src/lib/doslib/hw/ide/testpiot.c deleted: src/lib/doslib/hw/ide/testpiot.h deleted: src/lib/doslib/hw/ide/testpwr.c deleted: src/lib/doslib/hw/ide/testpwr.h deleted: src/lib/doslib/hw/ide/testrdts.c deleted: src/lib/doslib/hw/ide/testrdts.h deleted: src/lib/doslib/hw/ide/testrdtv.c deleted: src/lib/doslib/hw/ide/testrdtv.h deleted: src/lib/doslib/hw/ide/testrdwr.c deleted: src/lib/doslib/hw/ide/testrdwr.h deleted: src/lib/doslib/hw/ide/testrdws.c deleted: src/lib/doslib/hw/ide/testrdws.h deleted: src/lib/doslib/hw/ide/testrvfy.c deleted: src/lib/doslib/hw/ide/testrvfy.h deleted: src/lib/doslib/hw/ide/testtadj.c deleted: src/lib/doslib/hw/ide/testtadj.h deleted: src/lib/doslib/hw/ide/testutil.c deleted: src/lib/doslib/hw/ide/testutil.h deleted: src/lib/doslib/hw/isapnp/CLEAN.BAT deleted: src/lib/doslib/hw/isapnp/MAKE.BAT deleted: src/lib/doslib/hw/isapnp/common.mak deleted: src/lib/doslib/hw/isapnp/isapnp.c deleted: src/lib/doslib/hw/isapnp/isapnp.h deleted: src/lib/doslib/hw/isapnp/other_id.txt deleted: src/lib/doslib/hw/isapnp/test.c deleted: src/lib/doslib/hw/llmem/CLEAN.BAT deleted: src/lib/doslib/hw/llmem/MAKE.BAT deleted: src/lib/doslib/hw/llmem/bochstst/bochsrc deleted: src/lib/doslib/hw/llmem/common.mak deleted: src/lib/doslib/hw/llmem/config.sys deleted: src/lib/doslib/hw/llmem/emm386.exe.gz deleted: src/lib/doslib/hw/llmem/hdd.dsk.gz deleted: src/lib/doslib/hw/llmem/llmem.c deleted: src/lib/doslib/hw/llmem/llmem.h deleted: src/lib/doslib/hw/llmem/llmemasm.asm deleted: src/lib/doslib/hw/llmem/test.c deleted: src/lib/doslib/hw/llmem/win95.dsk.gz deleted: src/lib/doslib/hw/mb/buildall.bat deleted: src/lib/doslib/hw/mb/clean.bat deleted: src/lib/doslib/hw/mb/intel/buildall.bat deleted: src/lib/doslib/hw/mb/intel/clean.bat deleted: src/lib/doslib/hw/mb/intel/piix3/CLEAN.BAT deleted: src/lib/doslib/hw/mb/intel/piix3/MAKE.BAT deleted: src/lib/doslib/hw/mb/intel/piix3/common.mak deleted: src/lib/doslib/hw/mb/intel/piix3/piix3.c deleted: src/lib/doslib/hw/mb/intel/piix3/piix3.h deleted: src/lib/doslib/hw/mb/intel/piix3/readme deleted: src/lib/doslib/hw/mb/intel/piix3/test.c deleted: src/lib/doslib/hw/mb/readme deleted: src/lib/doslib/hw/parport/CLEAN.BAT deleted: src/lib/doslib/hw/parport/MAKE.BAT deleted: src/lib/doslib/hw/parport/common.mak deleted: src/lib/doslib/hw/parport/parpnp.c deleted: src/lib/doslib/hw/parport/parpnp.h deleted: src/lib/doslib/hw/parport/parport.c deleted: src/lib/doslib/hw/parport/parport.h deleted: src/lib/doslib/hw/parport/prnt.c deleted: src/lib/doslib/hw/parport/prntpnp.c deleted: src/lib/doslib/hw/parport/samptest.c deleted: src/lib/doslib/hw/parport/test.c deleted: src/lib/doslib/hw/parport/testpnp.c deleted: src/lib/doslib/hw/parport/todo deleted: src/lib/doslib/hw/pci/CLEAN.BAT deleted: src/lib/doslib/hw/pci/MAKE.BAT deleted: src/lib/doslib/hw/pci/common.mak deleted: src/lib/doslib/hw/pci/pci.c deleted: src/lib/doslib/hw/pci/pci.h deleted: src/lib/doslib/hw/pci/pcibios1.asm deleted: src/lib/doslib/hw/pci/test.c deleted: src/lib/doslib/hw/pcie/CLEAN.BAT deleted: src/lib/doslib/hw/pcie/MAKE.BAT deleted: src/lib/doslib/hw/pcie/common.mak deleted: src/lib/doslib/hw/pcie/pcie.c deleted: src/lib/doslib/hw/pcie/pcie.h deleted: src/lib/doslib/hw/pcie/test.c deleted: src/lib/doslib/hw/readme deleted: src/lib/doslib/hw/rtc/CLEAN.BAT deleted: src/lib/doslib/hw/rtc/MAKE.BAT deleted: src/lib/doslib/hw/rtc/cmos.c deleted: src/lib/doslib/hw/rtc/common.mak deleted: src/lib/doslib/hw/rtc/rtc.c deleted: src/lib/doslib/hw/rtc/rtc.h deleted: src/lib/doslib/hw/rtc/test.c deleted: src/lib/doslib/hw/smbios/CLEAN.BAT deleted: src/lib/doslib/hw/smbios/MAKE.BAT deleted: src/lib/doslib/hw/smbios/common.mak deleted: src/lib/doslib/hw/smbios/smbios.c deleted: src/lib/doslib/hw/smbios/smbios.h deleted: src/lib/doslib/hw/smbios/test.c deleted: src/lib/doslib/hw/sndsb/CLEAN.BAT deleted: src/lib/doslib/hw/sndsb/MAKE.BAT deleted: src/lib/doslib/hw/sndsb/common.mak deleted: src/lib/doslib/hw/sndsb/pnpcfg.c deleted: src/lib/doslib/hw/sndsb/readme deleted: src/lib/doslib/hw/sndsb/sndsb.c deleted: src/lib/doslib/hw/sndsb/sndsb.h deleted: src/lib/doslib/hw/sndsb/sndsbpnp.c deleted: src/lib/doslib/hw/sndsb/sndsbpnp.h deleted: src/lib/doslib/hw/sndsb/test.c deleted: src/lib/doslib/hw/ultrasnd/CLEAN.BAT deleted: src/lib/doslib/hw/ultrasnd/MAKE.BAT deleted: src/lib/doslib/hw/ultrasnd/common.mak deleted: src/lib/doslib/hw/ultrasnd/test.c deleted: src/lib/doslib/hw/ultrasnd/tsrs.c deleted: src/lib/doslib/hw/ultrasnd/ultrasnd.c deleted: src/lib/doslib/hw/ultrasnd/ultrasnd.h deleted: src/lib/doslib/hw/usb/buildall.bat deleted: src/lib/doslib/hw/usb/clean.bat deleted: src/lib/doslib/hw/usb/ohci/CLEAN.BAT deleted: src/lib/doslib/hw/usb/ohci/MAKE.BAT deleted: src/lib/doslib/hw/usb/ohci/common.mak deleted: src/lib/doslib/hw/usb/ohci/ohci.c deleted: src/lib/doslib/hw/usb/ohci/ohci.h deleted: src/lib/doslib/hw/usb/ohci/test.c deleted: src/lib/doslib/hw/usb/ohci/test_ref.dsk.gz deleted: src/lib/doslib/hw/vesa/CLEAN.BAT deleted: src/lib/doslib/hw/vesa/MAKE.BAT deleted: src/lib/doslib/hw/vesa/common.mak deleted: src/lib/doslib/hw/vesa/modeset.c deleted: src/lib/doslib/hw/vesa/test.c deleted: src/lib/doslib/hw/vesa/vesa.c deleted: src/lib/doslib/hw/vesa/vesa.h deleted: src/lib/doslib/hw/vesa/vesa240.c deleted: src/lib/doslib/hw/vga/CLEAN.BAT deleted: src/lib/doslib/hw/vga/MAKE.BAT deleted: src/lib/doslib/hw/vga/common.mak deleted: src/lib/doslib/hw/vga/test.c deleted: src/lib/doslib/hw/vga/tmodeset.c deleted: src/lib/doslib/hw/vga/tmp.cmd deleted: src/lib/doslib/hw/vga/vga.c deleted: src/lib/doslib/hw/vga/vga.h deleted: src/lib/doslib/hw/vga/vga240.c deleted: src/lib/doslib/hw/vga/vgagui.c deleted: src/lib/doslib/hw/vga/vgagui.h deleted: src/lib/doslib/hw/vga/vgatty.c deleted: src/lib/doslib/hw/vga/vgatty.h deleted: src/lib/doslib/mak/bcommon.mak deleted: src/lib/doslib/mak/buildall.bat deleted: src/lib/doslib/mak/clean.bat deleted: src/lib/doslib/mak/comdo286.mak deleted: src/lib/doslib/mak/comdo386.mak deleted: src/lib/doslib/mak/comdo486.mak deleted: src/lib/doslib/mak/comdo586.mak deleted: src/lib/doslib/mak/comdo686.mak deleted: src/lib/doslib/mak/comdos86.mak deleted: src/lib/doslib/mak/comos216.mak deleted: src/lib/doslib/mak/comos232.mak deleted: src/lib/doslib/mak/comw3086.mak deleted: src/lib/doslib/mak/comw3186.mak deleted: src/lib/doslib/mak/comwn300.mak deleted: src/lib/doslib/mak/comwn302.mak deleted: src/lib/doslib/mak/comwn303.mak deleted: src/lib/doslib/mak/comwn312.mak deleted: src/lib/doslib/mak/comwn313.mak deleted: src/lib/doslib/mak/cow38631.mak deleted: src/lib/doslib/mak/cowin32.mak deleted: src/lib/doslib/mak/cowin32s.mak deleted: src/lib/doslib/mak/cowin386.mak deleted: src/lib/doslib/mak/cowinnt.mak deleted: src/lib/doslib/mak/dcommon.mak deleted: src/lib/doslib/mak/dos286c.mak deleted: src/lib/doslib/mak/dos286l.mak deleted: src/lib/doslib/mak/dos286m.mak deleted: src/lib/doslib/mak/dos286s.mak deleted: src/lib/doslib/mak/dos386f.mak deleted: src/lib/doslib/mak/dos486f.mak deleted: src/lib/doslib/mak/dos586f.mak deleted: src/lib/doslib/mak/dos686f.mak deleted: src/lib/doslib/mak/dos86c.mak deleted: src/lib/doslib/mak/dos86l.mak deleted: src/lib/doslib/mak/dos86m.mak deleted: src/lib/doslib/mak/dos86s.mak deleted: src/lib/doslib/mak/os2d3f.mak deleted: src/lib/doslib/mak/os2w2l.mak deleted: src/lib/doslib/mak/win300c.mak deleted: src/lib/doslib/mak/win300l.mak deleted: src/lib/doslib/mak/win300m.mak deleted: src/lib/doslib/mak/win300s.mak deleted: src/lib/doslib/mak/win302c.mak deleted: src/lib/doslib/mak/win302l.mak deleted: src/lib/doslib/mak/win302m.mak deleted: src/lib/doslib/mak/win302s.mak deleted: src/lib/doslib/mak/win303c.mak deleted: src/lib/doslib/mak/win303l.mak deleted: src/lib/doslib/mak/win303m.mak deleted: src/lib/doslib/mak/win303s.mak deleted: src/lib/doslib/mak/win312c.mak deleted: src/lib/doslib/mak/win312l.mak deleted: src/lib/doslib/mak/win312m.mak deleted: src/lib/doslib/mak/win312s.mak deleted: src/lib/doslib/mak/win313c.mak deleted: src/lib/doslib/mak/win313l.mak deleted: src/lib/doslib/mak/win313m.mak deleted: src/lib/doslib/mak/win313s.mak deleted: src/lib/doslib/mak/win32.mak deleted: src/lib/doslib/mak/win32s3.mak deleted: src/lib/doslib/mak/win32s4.mak deleted: src/lib/doslib/mak/win32s5.mak deleted: src/lib/doslib/mak/win32s6.mak deleted: src/lib/doslib/mak/win386.mak deleted: src/lib/doslib/mak/win38631.mak deleted: src/lib/doslib/mak/winnt.mak modified: src/lib/midi.c renamed: src/lib/doslib/dos/testemm.c -> src/testemm.c renamed: src/lib/doslib/dos/tsthimem.c -> src/tsthimem.c new file: testemm.exe new file: tsthimem.exe --- 16/dos_kb.c | 5 +- 16/dos_kb.h | 46 +- make-lowercase | 63 + makefile | 48 +- miditest.exe | Bin 70059 -> 70610 bytes sountest.exe | Bin 68114 -> 68215 bytes src/lib/16_in.h | 2 +- src/lib/dos_kb.c | 143 - src/lib/dos_kb.h | 23 - src/lib/doslib/8254.h | 2 +- src/lib/doslib/8259.h | 2 +- src/lib/doslib/adlib.h | 6 +- src/lib/doslib/cpu.c | 26 +- src/lib/doslib/cpu.h | 3 + src/lib/doslib/dos.c | 2 +- src/lib/doslib/dos.h | 1 + src/lib/doslib/dos/CLEAN.BAT | 9 - src/lib/doslib/dos/MAKE.BAT | 14 - src/lib/doslib/dos/biosext.c | 159 - src/lib/doslib/dos/biosext.h | 16 - src/lib/doslib/dos/biosmem.c | 75 - src/lib/doslib/dos/biosmem.h | 33 - src/lib/doslib/dos/biosmem3.c | 60 - src/lib/doslib/dos/common.mak | 247 - src/lib/doslib/dos/cr3.c | 44 - src/lib/doslib/dos/ddpmidos.c | 64 - src/lib/doslib/dos/ddpmidsc.c | 96 - src/lib/doslib/dos/ddpmilin.c | 106 - src/lib/doslib/dos/ddpmiphy.c | 60 - src/lib/doslib/dos/dos.c | 308 -- src/lib/doslib/dos/dos.h | 444 -- src/lib/doslib/dos/dos386f/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dos/dos86c/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dos/dos86l/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dos/dos86m/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dos/dos86s/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dos/dos9xvm.c | 98 - src/lib/doslib/dos/dos_lol.c | 76 - src/lib/doslib/dos/dos_ltp.c | 303 -- src/lib/doslib/dos/dos_mcb.c | 117 - src/lib/doslib/dos/dos_nmi.c | 78 - src/lib/doslib/dos/dosasm.asm | 645 --- src/lib/doslib/dos/dosbox.c | 140 - src/lib/doslib/dos/dosbox.h | 14 - src/lib/doslib/dos/dosdev.c | 83 - src/lib/doslib/dos/dosdpmi.c | 286 -- src/lib/doslib/dos/dosflavr.c | 50 - src/lib/doslib/dos/dosmapal.c | 61 - src/lib/doslib/dos/dosntast.c | 515 -- src/lib/doslib/dos/dosntvdm.c | 432 -- src/lib/doslib/dos/dosntvdm.h | 26 - src/lib/doslib/dos/dospsp.c | 47 - src/lib/doslib/dos/dossmdrv.c | 244 - src/lib/doslib/dos/dosvbox.c | 178 - src/lib/doslib/dos/dosvcpi.c | 140 - src/lib/doslib/dos/doswin.c | 642 --- src/lib/doslib/dos/doswin.h | 83 - src/lib/doslib/dos/dosxio.c | 105 - src/lib/doslib/dos/dpmiexcp.c | 112 - src/lib/doslib/dos/dpmirmcl.c | 193 - src/lib/doslib/dos/emm.c | 517 -- src/lib/doslib/dos/himemsys.h | 47 - src/lib/doslib/dos/lol.c | 141 - src/lib/doslib/dos/ntastrm.c | 68 - src/lib/doslib/dos/readme | 7 - src/lib/doslib/dos/test.c | 165 - src/lib/doslib/dos/testbext.c | 63 - src/lib/doslib/dos/testdpmi.c | 89 - src/lib/doslib/dos/testemm.c | 271 -- src/lib/doslib/dos/testsmrt.c | 47 - src/lib/doslib/dos/tgusmega.c | 46 - src/lib/doslib/dos/tgusmega.h | 16 - src/lib/doslib/dos/tgussbos.c | 60 - src/lib/doslib/dos/tgussbos.h | 3 - src/lib/doslib/dos/tgusumid.c | 57 - src/lib/doslib/dos/tgusumid.h | 3 - src/lib/doslib/dos/tmp.cmd | 1 - src/lib/doslib/dos/tstbiom.c | 82 - src/lib/doslib/dos/tstlp.c | 110 - src/lib/doslib/dos/win16vec.c | 106 - src/lib/doslib/dos/win3216t.c | 102 - src/lib/doslib/dos/win32lrd.c | 125 - src/lib/doslib/dos/winfcon.c | 723 --- src/lib/doslib/dos/winfcon.h | 46 - src/lib/doslib/dos/winnt/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/dosdrv/buildall.bat | 11 - src/lib/doslib/dosdrv/clean.bat | 5 - src/lib/doslib/dosdrv/hello/CLEAN.BAT | 17 - src/lib/doslib/dosdrv/hello/MAKE.BAT | 26 - src/lib/doslib/dosdrv/hello/common.mak | 43 - src/lib/doslib/dosdrv/hello/config.sys | 2 - src/lib/doslib/dosdrv/hello/hello.asm | 168 - src/lib/doslib/dosdrv/hello/test.dsk.gz | Bin 668115 -> 0 bytes src/lib/doslib/{hw/dos => }/emm.c | 72 +- src/lib/doslib/{dos => }/emm.h | 33 +- src/lib/doslib/{dos => }/himemsys.c | 14 +- src/lib/doslib/{hw/dos => }/himemsys.h | 15 + src/lib/doslib/hw/8042/8042.c | 51 - src/lib/doslib/hw/8042/8042.h | 142 - src/lib/doslib/hw/8042/8042aux.c | 100 - src/lib/doslib/hw/8042/CLEAN.BAT | 17 - src/lib/doslib/hw/8042/MAKE.BAT | 26 - src/lib/doslib/hw/8042/common.mak | 35 - src/lib/doslib/hw/8042/test.c | 1130 ----- src/lib/doslib/hw/8237/8237.c | 468 -- src/lib/doslib/hw/8237/8237.h | 214 - src/lib/doslib/hw/8237/CLEAN.BAT | 17 - src/lib/doslib/hw/8237/MAKE.BAT | 26 - src/lib/doslib/hw/8237/common.mak | 29 - src/lib/doslib/hw/8237/test.c | 1 - src/lib/doslib/hw/8250/8250.c | 387 -- src/lib/doslib/hw/8250/8250.h | 149 - src/lib/doslib/hw/8250/8250pnp.c | 38 - src/lib/doslib/hw/8250/8250pnp.h | 8 - src/lib/doslib/hw/8250/CLEAN.BAT | 17 - src/lib/doslib/hw/8250/MAKE.BAT | 26 - src/lib/doslib/hw/8250/common.mak | 45 - src/lib/doslib/hw/8250/test.c | 849 ---- src/lib/doslib/hw/8250/testpnp.c | 4 - src/lib/doslib/hw/8254/8254.c | 108 - src/lib/doslib/hw/8254/8254.h | 146 - src/lib/doslib/hw/8254/8254rd.c | 69 - src/lib/doslib/hw/8254/CLEAN.BAT | 9 - src/lib/doslib/hw/8254/MAKE.BAT | 14 - src/lib/doslib/hw/8254/common.mak | 35 - src/lib/doslib/hw/8254/readme | 11 - src/lib/doslib/hw/8254/test.c | 284 -- src/lib/doslib/hw/8254/test1_22.wav | Bin 238661 -> 0 bytes src/lib/doslib/hw/8254/tmp.cmd | 1 - src/lib/doslib/hw/8259/8259.c | 99 - src/lib/doslib/hw/8259/8259.h | 116 - src/lib/doslib/hw/8259/CLEAN.BAT | 9 - src/lib/doslib/hw/8259/MAKE.BAT | 14 - src/lib/doslib/hw/8259/common.mak | 33 - src/lib/doslib/hw/8259/readme | 7 - src/lib/doslib/hw/8259/test.c | 145 - src/lib/doslib/hw/8259/tmp.cmd | 1 - src/lib/doslib/hw/acpi/CLEAN.BAT | 17 - src/lib/doslib/hw/acpi/MAKE.BAT | 26 - src/lib/doslib/hw/acpi/acpi.c | 278 -- src/lib/doslib/hw/acpi/acpi.h | 116 - src/lib/doslib/hw/acpi/common.mak | 34 - src/lib/doslib/hw/acpi/test.c | 202 - src/lib/doslib/hw/adlib/CLEAN.BAT | 17 - src/lib/doslib/hw/adlib/MAKE.BAT | 26 - src/lib/doslib/hw/adlib/adlib.c | 290 -- src/lib/doslib/hw/adlib/adlib.h | 137 - src/lib/doslib/hw/adlib/common.mak | 41 - src/lib/doslib/hw/adlib/dos386f/dos4gw.exe | Bin 28172 -> 0 bytes src/lib/doslib/hw/adlib/dos386f/midi.exe | Bin 80214 -> 0 bytes src/lib/doslib/hw/adlib/dos386f/test.exe | Bin 80564 -> 0 bytes src/lib/doslib/hw/adlib/dos86c/dos4gw.exe | Bin 28172 -> 0 bytes src/lib/doslib/hw/adlib/dos86c/midi.exe | Bin 53022 -> 0 bytes src/lib/doslib/hw/adlib/dos86c/test.exe | Bin 50164 -> 0 bytes src/lib/doslib/hw/adlib/dos86l/dos4gw.exe | Bin 28172 -> 0 bytes src/lib/doslib/hw/adlib/dos86l/midi.exe | Bin 54272 -> 0 bytes src/lib/doslib/hw/adlib/dos86l/test.exe | Bin 51360 -> 0 bytes src/lib/doslib/hw/adlib/dos86m/dos4gw.exe | Bin 28172 -> 0 bytes src/lib/doslib/hw/adlib/dos86m/midi.exe | Bin 46796 -> 0 bytes src/lib/doslib/hw/adlib/dos86m/test.exe | Bin 45282 -> 0 bytes src/lib/doslib/hw/adlib/dos86s/dos4gw.exe | Bin 28172 -> 0 bytes src/lib/doslib/hw/adlib/dos86s/midi.exe | Bin 45610 -> 0 bytes src/lib/doslib/hw/adlib/dos86s/test.exe | Bin 44086 -> 0 bytes src/lib/doslib/hw/adlib/midi.c | 871 ---- src/lib/doslib/hw/adlib/midikeys.gen.pl | 26 - src/lib/doslib/hw/adlib/readme | 14 - src/lib/doslib/hw/adlib/test.c | 450 -- src/lib/doslib/hw/adlib/tmp.cmd | 1 - src/lib/doslib/hw/apm/CLEAN.BAT | 17 - src/lib/doslib/hw/apm/MAKE.BAT | 26 - src/lib/doslib/hw/apm/apm.c | 384 -- src/lib/doslib/hw/apm/apm.h | 81 - src/lib/doslib/hw/apm/common.mak | 34 - src/lib/doslib/hw/apm/readme | 5 - src/lib/doslib/hw/apm/test.c | 233 - src/lib/doslib/hw/biosdisk/CLEAN.BAT | 17 - src/lib/doslib/hw/biosdisk/MAKE.BAT | 26 - src/lib/doslib/hw/biosdisk/biosdisk.c | 876 ---- src/lib/doslib/hw/biosdisk/biosdisk.h | 52 - src/lib/doslib/hw/biosdisk/common.mak | 52 - src/lib/doslib/hw/biosdisk/dumphdp.c | 145 - src/lib/doslib/hw/biosdisk/test.c | 499 -- src/lib/doslib/hw/buildall.bat | 141 - src/lib/doslib/hw/clean.bat | 5 - src/lib/doslib/hw/cpu/CLEAN.BAT | 9 - src/lib/doslib/hw/cpu/MAKE.BAT | 14 - src/lib/doslib/hw/cpu/alignchk.asm | 714 --- src/lib/doslib/hw/cpu/apic.c | 59 - src/lib/doslib/hw/cpu/apiclib.c | 73 - src/lib/doslib/hw/cpu/apiclib.h | 33 - src/lib/doslib/hw/cpu/bochstst/bochsrc | 51 - src/lib/doslib/hw/cpu/common.mak | 340 -- src/lib/doslib/hw/cpu/config.sys | 16 - src/lib/doslib/hw/cpu/cpu.c | 157 - src/lib/doslib/hw/cpu/cpu.h | 233 - src/lib/doslib/hw/cpu/cpuasm.asm | 289 -- src/lib/doslib/hw/cpu/cpuid.asm | 109 - src/lib/doslib/hw/cpu/cpuidext.c | 121 - src/lib/doslib/hw/cpu/cpuidext.h | 48 - src/lib/doslib/hw/cpu/cpuiopd.asm | 67 - src/lib/doslib/hw/cpu/cpup3sn.asm | 130 - src/lib/doslib/hw/cpu/cpup3sn.h | 16 - src/lib/doslib/hw/cpu/cpup3snc.c | 6 - src/lib/doslib/hw/cpu/cpurdmsr.asm | 85 - src/lib/doslib/hw/cpu/cpurdtsc.asm | 97 - src/lib/doslib/hw/cpu/cpurdtsc.h | 43 - src/lib/doslib/hw/cpu/cpusse.c | 528 -- src/lib/doslib/hw/cpu/cpusse.h | 12 - src/lib/doslib/hw/cpu/cpussea.asm | 224 - src/lib/doslib/hw/cpu/cpustrlv.c | 14 - src/lib/doslib/hw/cpu/dispsn.c | 74 - src/lib/doslib/hw/cpu/emm386.exe.gz | Bin 45481 -> 0 bytes src/lib/doslib/hw/cpu/gdt_enum.c | 456 -- src/lib/doslib/hw/cpu/gdt_enum.h | 79 - src/lib/doslib/hw/cpu/gdtlist.c | 172 - src/lib/doslib/hw/cpu/gdttae.c | 143 - src/lib/doslib/hw/cpu/gr_add.c | 907 ---- src/lib/doslib/hw/cpu/gr_add_t.bat | 8 - src/lib/doslib/hw/cpu/grind.c | 520 -- src/lib/doslib/hw/cpu/grtest.bat | 9 - src/lib/doslib/hw/cpu/hdd.dsk.gz | Bin 763462 -> 0 bytes src/lib/doslib/hw/cpu/libgrind.c | 159 - src/lib/doslib/hw/cpu/libgrind.h | 247 - src/lib/doslib/hw/cpu/mmx.c | 119 - src/lib/doslib/hw/cpu/msdos5m.dsk.gz | Bin 547118 -> 0 bytes src/lib/doslib/hw/cpu/notes | 6 - src/lib/doslib/hw/cpu/prot286.asm | 263 - src/lib/doslib/hw/cpu/prot386.asm | 294 -- src/lib/doslib/hw/cpu/protdpmi.asm | 206 - src/lib/doslib/hw/cpu/protvcpi.asm | 430 -- src/lib/doslib/hw/cpu/rdtsc.c | 241 - src/lib/doslib/hw/cpu/reset.c | 391 -- src/lib/doslib/hw/cpu/resetasm.asm | 73 - src/lib/doslib/hw/cpu/sse.c | 173 - src/lib/doslib/hw/cpu/sseoff.c | 63 - src/lib/doslib/hw/cpu/test.c | 424 -- src/lib/doslib/hw/cpu/tmp.cmd | 1 - src/lib/doslib/hw/cpu/tss.asm | 515 -- src/lib/doslib/hw/cpu/tssring.asm | 646 --- src/lib/doslib/hw/cpu/v86.asm | 674 --- src/lib/doslib/hw/cpu/v86kern.asm | 2173 --------- src/lib/doslib/hw/cpu/v86kern2.asm | 3079 ------------ src/lib/doslib/hw/cpu/win95.dsk.gz | Bin 711528 -> 0 bytes src/lib/doslib/hw/dos/CLEAN.BAT | 9 - src/lib/doslib/hw/dos/MAKE.BAT | 14 - src/lib/doslib/hw/dos/biosext.c | 159 - src/lib/doslib/hw/dos/biosext.h | 16 - src/lib/doslib/hw/dos/biosmem.c | 75 - src/lib/doslib/hw/dos/biosmem.h | 33 - src/lib/doslib/hw/dos/biosmem3.c | 60 - src/lib/doslib/hw/dos/common.mak | 247 - src/lib/doslib/hw/dos/cr3.c | 44 - src/lib/doslib/hw/dos/ddpmidos.c | 64 - src/lib/doslib/hw/dos/ddpmidsc.c | 96 - src/lib/doslib/hw/dos/ddpmilin.c | 106 - src/lib/doslib/hw/dos/ddpmiphy.c | 60 - src/lib/doslib/hw/dos/dos.c | 308 -- src/lib/doslib/hw/dos/dos.h | 444 -- src/lib/doslib/hw/dos/dos386f/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/dos/dos86c/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/dos/dos86l/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/dos/dos86m/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/dos/dos86s/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/dos/dos9xvm.c | 98 - src/lib/doslib/hw/dos/dos_lol.c | 76 - src/lib/doslib/hw/dos/dos_ltp.c | 303 -- src/lib/doslib/hw/dos/dos_mcb.c | 117 - src/lib/doslib/hw/dos/dos_nmi.c | 78 - src/lib/doslib/hw/dos/dosasm.asm | 645 --- src/lib/doslib/hw/dos/dosbox.c | 140 - src/lib/doslib/hw/dos/dosbox.h | 14 - src/lib/doslib/hw/dos/dosdev.c | 83 - src/lib/doslib/hw/dos/dosdpmi.c | 286 -- src/lib/doslib/hw/dos/dosflavr.c | 50 - src/lib/doslib/hw/dos/dosmapal.c | 61 - src/lib/doslib/hw/dos/dosntast.c | 515 -- src/lib/doslib/hw/dos/dosntvdm.c | 432 -- src/lib/doslib/hw/dos/dosntvdm.h | 26 - src/lib/doslib/hw/dos/dospsp.c | 47 - src/lib/doslib/hw/dos/dossmdrv.c | 244 - src/lib/doslib/hw/dos/dosvbox.c | 178 - src/lib/doslib/hw/dos/dosvcpi.c | 140 - src/lib/doslib/hw/dos/doswin.c | 642 --- src/lib/doslib/hw/dos/doswin.h | 83 - src/lib/doslib/hw/dos/dosxio.c | 105 - src/lib/doslib/hw/dos/dpmiexcp.c | 112 - src/lib/doslib/hw/dos/dpmirmcl.c | 193 - src/lib/doslib/hw/dos/emm.h | 71 - src/lib/doslib/hw/dos/himemsys.c | 682 --- src/lib/doslib/hw/dos/lol.c | 141 - src/lib/doslib/hw/dos/ntastrm.c | 68 - src/lib/doslib/hw/dos/readme | 7 - src/lib/doslib/hw/dos/test.c | 165 - src/lib/doslib/hw/dos/testbext.c | 63 - src/lib/doslib/hw/dos/testdpmi.c | 89 - src/lib/doslib/hw/dos/testsmrt.c | 47 - src/lib/doslib/hw/dos/tgusmega.c | 46 - src/lib/doslib/hw/dos/tgusmega.h | 16 - src/lib/doslib/hw/dos/tgussbos.c | 60 - src/lib/doslib/hw/dos/tgussbos.h | 3 - src/lib/doslib/hw/dos/tgusumid.c | 57 - src/lib/doslib/hw/dos/tgusumid.h | 3 - src/lib/doslib/hw/dos/tmp.cmd | 1 - src/lib/doslib/hw/dos/tstbiom.c | 82 - src/lib/doslib/hw/dos/tsthimem.c | 295 -- src/lib/doslib/hw/dos/tstlp.c | 110 - src/lib/doslib/hw/dos/win16vec.c | 106 - src/lib/doslib/hw/dos/win3216t.c | 102 - src/lib/doslib/hw/dos/win32lrd.c | 125 - src/lib/doslib/hw/dos/winfcon.c | 723 --- src/lib/doslib/hw/dos/winfcon.h | 46 - src/lib/doslib/hw/dos/winnt/dosntast.vdd | Bin 28672 -> 0 bytes src/lib/doslib/hw/flatreal/CLEAN.BAT | 17 - src/lib/doslib/hw/flatreal/MAKE.BAT | 26 - src/lib/doslib/hw/flatreal/common.mak | 38 - src/lib/doslib/hw/flatreal/flatmode.asm | 192 - src/lib/doslib/hw/flatreal/flatreal.c | 78 - src/lib/doslib/hw/flatreal/flatreal.h | 115 - src/lib/doslib/hw/flatreal/readme | 46 - src/lib/doslib/hw/flatreal/test.c | 99 - src/lib/doslib/hw/floppy/CLEAN.BAT | 17 - src/lib/doslib/hw/floppy/MAKE.BAT | 26 - src/lib/doslib/hw/floppy/common.mak | 37 - src/lib/doslib/hw/floppy/floppy.c | 0 src/lib/doslib/hw/floppy/floppy.h | 6 - src/lib/doslib/hw/floppy/msdos622.dsk.gz | Bin 924583 -> 0 bytes src/lib/doslib/hw/floppy/test.c | 3149 ------------ src/lib/doslib/hw/floppy/win95.dsk.gz | Bin 709564 -> 0 bytes src/lib/doslib/hw/ide/CLEAN.BAT | 17 - src/lib/doslib/hw/ide/MAKE.BAT | 26 - src/lib/doslib/hw/ide/common.mak | 50 - src/lib/doslib/hw/ide/idelib.c | 608 --- src/lib/doslib/hw/ide/idelib.h | 172 - src/lib/doslib/hw/ide/readme | 6 - src/lib/doslib/hw/ide/test.c | 1073 ----- src/lib/doslib/hw/ide/test.h | 52 - src/lib/doslib/hw/ide/testbusy.c | 279 -- src/lib/doslib/hw/ide/testbusy.h | 25 - src/lib/doslib/hw/ide/testcdej.c | 227 - src/lib/doslib/hw/ide/testcdej.h | 4 - src/lib/doslib/hw/ide/testcdrm.c | 404 -- src/lib/doslib/hw/ide/testcdrm.h | 4 - src/lib/doslib/hw/ide/testcmui.c | 325 -- src/lib/doslib/hw/ide/testcmui.h | 31 - src/lib/doslib/hw/ide/testidnt.c | 327 -- src/lib/doslib/hw/ide/testidnt.h | 8 - src/lib/doslib/hw/ide/testmbox.c | 53 - src/lib/doslib/hw/ide/testmbox.h | 17 - src/lib/doslib/hw/ide/testmisc.c | 209 - src/lib/doslib/hw/ide/testmisc.h | 3 - src/lib/doslib/hw/ide/testmumo.c | 217 - src/lib/doslib/hw/ide/testmumo.h | 3 - src/lib/doslib/hw/ide/testnop.c | 86 - src/lib/doslib/hw/ide/testnop.h | 3 - src/lib/doslib/hw/ide/testpiom.c | 218 - src/lib/doslib/hw/ide/testpiom.h | 3 - src/lib/doslib/hw/ide/testpiot.c | 237 - src/lib/doslib/hw/ide/testpiot.h | 3 - src/lib/doslib/hw/ide/testpwr.c | 422 -- src/lib/doslib/hw/ide/testpwr.h | 9 - src/lib/doslib/hw/ide/testrdts.c | 766 --- src/lib/doslib/hw/ide/testrdts.h | 3 - src/lib/doslib/hw/ide/testrdtv.c | 383 -- src/lib/doslib/hw/ide/testrdtv.h | 3 - src/lib/doslib/hw/ide/testrdwr.c | 676 --- src/lib/doslib/hw/ide/testrdwr.h | 42 - src/lib/doslib/hw/ide/testrdws.c | 527 -- src/lib/doslib/hw/ide/testrdws.h | 3 - src/lib/doslib/hw/ide/testrvfy.c | 31 - src/lib/doslib/hw/ide/testrvfy.h | 1 - src/lib/doslib/hw/ide/testtadj.c | 178 - src/lib/doslib/hw/ide/testtadj.h | 3 - src/lib/doslib/hw/ide/testutil.c | 154 - src/lib/doslib/hw/ide/testutil.h | 9 - src/lib/doslib/hw/isapnp/CLEAN.BAT | 17 - src/lib/doslib/hw/isapnp/MAKE.BAT | 26 - src/lib/doslib/hw/isapnp/common.mak | 36 - src/lib/doslib/hw/isapnp/isapnp.c | 1326 ----- src/lib/doslib/hw/isapnp/isapnp.h | 314 -- src/lib/doslib/hw/isapnp/other_id.txt | 12 - src/lib/doslib/hw/isapnp/test.c | 989 ---- src/lib/doslib/hw/llmem/CLEAN.BAT | 17 - src/lib/doslib/hw/llmem/MAKE.BAT | 26 - src/lib/doslib/hw/llmem/bochstst/bochsrc | 51 - src/lib/doslib/hw/llmem/common.mak | 42 - src/lib/doslib/hw/llmem/config.sys | 16 - src/lib/doslib/hw/llmem/emm386.exe.gz | Bin 45481 -> 0 bytes src/lib/doslib/hw/llmem/hdd.dsk.gz | Bin 763462 -> 0 bytes src/lib/doslib/hw/llmem/llmem.c | 1187 ----- src/lib/doslib/hw/llmem/llmem.h | 57 - src/lib/doslib/hw/llmem/llmemasm.asm | 462 -- src/lib/doslib/hw/llmem/test.c | 150 - src/lib/doslib/hw/llmem/win95.dsk.gz | Bin 711528 -> 0 bytes src/lib/doslib/hw/mb/buildall.bat | 11 - src/lib/doslib/hw/mb/clean.bat | 5 - src/lib/doslib/hw/mb/intel/buildall.bat | 11 - src/lib/doslib/hw/mb/intel/clean.bat | 5 - src/lib/doslib/hw/mb/intel/piix3/CLEAN.BAT | 17 - src/lib/doslib/hw/mb/intel/piix3/MAKE.BAT | 26 - src/lib/doslib/hw/mb/intel/piix3/common.mak | 35 - src/lib/doslib/hw/mb/intel/piix3/piix3.c | 15 - src/lib/doslib/hw/mb/intel/piix3/piix3.h | 4 - src/lib/doslib/hw/mb/intel/piix3/readme | 3 - src/lib/doslib/hw/mb/intel/piix3/test.c | 559 --- src/lib/doslib/hw/mb/readme | 5 - src/lib/doslib/hw/parport/CLEAN.BAT | 17 - src/lib/doslib/hw/parport/MAKE.BAT | 26 - src/lib/doslib/hw/parport/common.mak | 63 - src/lib/doslib/hw/parport/parpnp.c | 162 - src/lib/doslib/hw/parport/parpnp.h | 9 - src/lib/doslib/hw/parport/parport.c | 439 -- src/lib/doslib/hw/parport/parport.h | 85 - src/lib/doslib/hw/parport/prnt.c | 228 - src/lib/doslib/hw/parport/prntpnp.c | 4 - src/lib/doslib/hw/parport/samptest.c | 283 -- src/lib/doslib/hw/parport/test.c | 85 - src/lib/doslib/hw/parport/testpnp.c | 4 - src/lib/doslib/hw/parport/todo | 9 - src/lib/doslib/hw/pci/CLEAN.BAT | 17 - src/lib/doslib/hw/pci/MAKE.BAT | 26 - src/lib/doslib/hw/pci/common.mak | 43 - src/lib/doslib/hw/pci/pci.c | 328 -- src/lib/doslib/hw/pci/pci.h | 49 - src/lib/doslib/hw/pci/pcibios1.asm | 158 - src/lib/doslib/hw/pci/test.c | 206 - src/lib/doslib/hw/pcie/CLEAN.BAT | 17 - src/lib/doslib/hw/pcie/MAKE.BAT | 26 - src/lib/doslib/hw/pcie/common.mak | 42 - src/lib/doslib/hw/pcie/pcie.c | 341 -- src/lib/doslib/hw/pcie/pcie.h | 46 - src/lib/doslib/hw/pcie/test.c | 216 - src/lib/doslib/hw/readme | 170 - src/lib/doslib/hw/rtc/CLEAN.BAT | 17 - src/lib/doslib/hw/rtc/MAKE.BAT | 26 - src/lib/doslib/hw/rtc/cmos.c | 52 - src/lib/doslib/hw/rtc/common.mak | 40 - src/lib/doslib/hw/rtc/rtc.c | 41 - src/lib/doslib/hw/rtc/rtc.h | 41 - src/lib/doslib/hw/rtc/test.c | 575 --- src/lib/doslib/hw/smbios/CLEAN.BAT | 17 - src/lib/doslib/hw/smbios/MAKE.BAT | 26 - src/lib/doslib/hw/smbios/common.mak | 35 - src/lib/doslib/hw/smbios/smbios.c | 212 - src/lib/doslib/hw/smbios/smbios.h | 114 - src/lib/doslib/hw/smbios/test.c | 181 - src/lib/doslib/hw/sndsb/CLEAN.BAT | 17 - src/lib/doslib/hw/sndsb/MAKE.BAT | 26 - src/lib/doslib/hw/sndsb/common.mak | 71 - src/lib/doslib/hw/sndsb/pnpcfg.c | 281 -- src/lib/doslib/hw/sndsb/readme | 888 ---- src/lib/doslib/hw/sndsb/sndsb.c | 3765 --------------- src/lib/doslib/hw/sndsb/sndsb.h | 377 -- src/lib/doslib/hw/sndsb/sndsbpnp.c | 394 -- src/lib/doslib/hw/sndsb/sndsbpnp.h | 23 - src/lib/doslib/hw/sndsb/test.c | 4797 ------------------- src/lib/doslib/hw/ultrasnd/CLEAN.BAT | 17 - src/lib/doslib/hw/ultrasnd/MAKE.BAT | 26 - src/lib/doslib/hw/ultrasnd/common.mak | 41 - src/lib/doslib/hw/ultrasnd/test.c | 424 -- src/lib/doslib/hw/ultrasnd/tsrs.c | 37 - src/lib/doslib/hw/ultrasnd/ultrasnd.c | 1390 ------ src/lib/doslib/hw/ultrasnd/ultrasnd.h | 87 - src/lib/doslib/hw/usb/buildall.bat | 11 - src/lib/doslib/hw/usb/clean.bat | 5 - src/lib/doslib/hw/usb/ohci/CLEAN.BAT | 17 - src/lib/doslib/hw/usb/ohci/MAKE.BAT | 26 - src/lib/doslib/hw/usb/ohci/common.mak | 42 - src/lib/doslib/hw/usb/ohci/ohci.c | 0 src/lib/doslib/hw/usb/ohci/ohci.h | 1 - src/lib/doslib/hw/usb/ohci/test.c | 1416 ------ src/lib/doslib/hw/usb/ohci/test_ref.dsk.gz | Bin 319621 -> 0 bytes src/lib/doslib/hw/vesa/CLEAN.BAT | 17 - src/lib/doslib/hw/vesa/MAKE.BAT | 26 - src/lib/doslib/hw/vesa/common.mak | 52 - src/lib/doslib/hw/vesa/modeset.c | 598 --- src/lib/doslib/hw/vesa/test.c | 163 - src/lib/doslib/hw/vesa/vesa.c | 745 --- src/lib/doslib/hw/vesa/vesa.h | 172 - src/lib/doslib/hw/vesa/vesa240.c | 241 - src/lib/doslib/hw/vga/CLEAN.BAT | 9 - src/lib/doslib/hw/vga/MAKE.BAT | 14 - src/lib/doslib/hw/vga/common.mak | 64 - src/lib/doslib/hw/vga/test.c | 2644 ---------- src/lib/doslib/hw/vga/tmodeset.c | 1028 ---- src/lib/doslib/hw/vga/tmp.cmd | 1 - src/lib/doslib/hw/vga/vga.c | 982 ---- src/lib/doslib/hw/vga/vga.h | 351 -- src/lib/doslib/hw/vga/vga240.c | 414 -- src/lib/doslib/hw/vga/vgagui.c | 494 -- src/lib/doslib/hw/vga/vgagui.h | 49 - src/lib/doslib/hw/vga/vgatty.c | 106 - src/lib/doslib/hw/vga/vgatty.h | 13 - src/lib/doslib/mak/bcommon.mak | 399 -- src/lib/doslib/mak/buildall.bat | 6 - src/lib/doslib/mak/clean.bat | 5 - src/lib/doslib/mak/comdo286.mak | 6 - src/lib/doslib/mak/comdo386.mak | 77 - src/lib/doslib/mak/comdo486.mak | 8 - src/lib/doslib/mak/comdo586.mak | 9 - src/lib/doslib/mak/comdo686.mak | 10 - src/lib/doslib/mak/comdos86.mak | 69 - src/lib/doslib/mak/comos216.mak | 103 - src/lib/doslib/mak/comos232.mak | 99 - src/lib/doslib/mak/comw3086.mak | 104 - src/lib/doslib/mak/comw3186.mak | 104 - src/lib/doslib/mak/comwn300.mak | 5 - src/lib/doslib/mak/comwn302.mak | 6 - src/lib/doslib/mak/comwn303.mak | 7 - src/lib/doslib/mak/comwn312.mak | 6 - src/lib/doslib/mak/comwn313.mak | 7 - src/lib/doslib/mak/cow38631.mak | 124 - src/lib/doslib/mak/cowin32.mak | 117 - src/lib/doslib/mak/cowin32s.mak | 117 - src/lib/doslib/mak/cowin386.mak | 124 - src/lib/doslib/mak/cowinnt.mak | 117 - src/lib/doslib/mak/dcommon.mak | 340 -- src/lib/doslib/mak/dos286c.mak | 5 - src/lib/doslib/mak/dos286l.mak | 5 - src/lib/doslib/mak/dos286m.mak | 5 - src/lib/doslib/mak/dos286s.mak | 5 - src/lib/doslib/mak/dos386f.mak | 5 - src/lib/doslib/mak/dos486f.mak | 5 - src/lib/doslib/mak/dos586f.mak | 5 - src/lib/doslib/mak/dos686f.mak | 5 - src/lib/doslib/mak/dos86c.mak | 5 - src/lib/doslib/mak/dos86l.mak | 5 - src/lib/doslib/mak/dos86m.mak | 5 - src/lib/doslib/mak/dos86s.mak | 5 - src/lib/doslib/mak/os2d3f.mak | 9 - src/lib/doslib/mak/os2w2l.mak | 8 - src/lib/doslib/mak/win300c.mak | 5 - src/lib/doslib/mak/win300l.mak | 5 - src/lib/doslib/mak/win300m.mak | 5 - src/lib/doslib/mak/win300s.mak | 5 - src/lib/doslib/mak/win302c.mak | 5 - src/lib/doslib/mak/win302l.mak | 5 - src/lib/doslib/mak/win302m.mak | 5 - src/lib/doslib/mak/win302s.mak | 5 - src/lib/doslib/mak/win303c.mak | 5 - src/lib/doslib/mak/win303l.mak | 5 - src/lib/doslib/mak/win303m.mak | 5 - src/lib/doslib/mak/win303s.mak | 5 - src/lib/doslib/mak/win312c.mak | 5 - src/lib/doslib/mak/win312l.mak | 5 - src/lib/doslib/mak/win312m.mak | 5 - src/lib/doslib/mak/win312s.mak | 5 - src/lib/doslib/mak/win313c.mak | 5 - src/lib/doslib/mak/win313l.mak | 5 - src/lib/doslib/mak/win313m.mak | 5 - src/lib/doslib/mak/win313s.mak | 5 - src/lib/doslib/mak/win32.mak | 5 - src/lib/doslib/mak/win32s3.mak | 5 - src/lib/doslib/mak/win32s4.mak | 10 - src/lib/doslib/mak/win32s5.mak | 11 - src/lib/doslib/mak/win32s6.mak | 12 - src/lib/doslib/mak/win386.mak | 5 - src/lib/doslib/mak/win38631.mak | 5 - src/lib/doslib/mak/winnt.mak | 5 - src/lib/midi.c | 3 + src/{lib/doslib/hw/dos => }/testemm.c | 15 +- src/{lib/doslib/dos => }/tsthimem.c | 12 +- testemm.exe | Bin 0 -> 30864 bytes tsthimem.exe | Bin 0 -> 34303 bytes 563 files changed, 249 insertions(+), 91632 deletions(-) create mode 100644 make-lowercase delete mode 100644 src/lib/dos_kb.c delete mode 100644 src/lib/dos_kb.h delete mode 100644 src/lib/doslib/dos/CLEAN.BAT delete mode 100644 src/lib/doslib/dos/MAKE.BAT delete mode 100644 src/lib/doslib/dos/biosext.c delete mode 100644 src/lib/doslib/dos/biosext.h delete mode 100644 src/lib/doslib/dos/biosmem.c delete mode 100644 src/lib/doslib/dos/biosmem.h delete mode 100644 src/lib/doslib/dos/biosmem3.c delete mode 100644 src/lib/doslib/dos/common.mak delete mode 100644 src/lib/doslib/dos/cr3.c delete mode 100644 src/lib/doslib/dos/ddpmidos.c delete mode 100644 src/lib/doslib/dos/ddpmidsc.c delete mode 100644 src/lib/doslib/dos/ddpmilin.c delete mode 100644 src/lib/doslib/dos/ddpmiphy.c delete mode 100644 src/lib/doslib/dos/dos.c delete mode 100644 src/lib/doslib/dos/dos.h delete mode 100644 src/lib/doslib/dos/dos386f/dosntast.vdd delete mode 100644 src/lib/doslib/dos/dos86c/dosntast.vdd delete mode 100644 src/lib/doslib/dos/dos86l/dosntast.vdd delete mode 100644 src/lib/doslib/dos/dos86m/dosntast.vdd delete mode 100644 src/lib/doslib/dos/dos86s/dosntast.vdd delete mode 100644 src/lib/doslib/dos/dos9xvm.c delete mode 100644 src/lib/doslib/dos/dos_lol.c delete mode 100644 src/lib/doslib/dos/dos_ltp.c delete mode 100644 src/lib/doslib/dos/dos_mcb.c delete mode 100644 src/lib/doslib/dos/dos_nmi.c delete mode 100644 src/lib/doslib/dos/dosasm.asm delete mode 100644 src/lib/doslib/dos/dosbox.c delete mode 100644 src/lib/doslib/dos/dosbox.h delete mode 100644 src/lib/doslib/dos/dosdev.c delete mode 100644 src/lib/doslib/dos/dosdpmi.c delete mode 100644 src/lib/doslib/dos/dosflavr.c delete mode 100644 src/lib/doslib/dos/dosmapal.c delete mode 100644 src/lib/doslib/dos/dosntast.c delete mode 100644 src/lib/doslib/dos/dosntvdm.c delete mode 100644 src/lib/doslib/dos/dosntvdm.h delete mode 100644 src/lib/doslib/dos/dospsp.c delete mode 100644 src/lib/doslib/dos/dossmdrv.c delete mode 100644 src/lib/doslib/dos/dosvbox.c delete mode 100644 src/lib/doslib/dos/dosvcpi.c delete mode 100644 src/lib/doslib/dos/doswin.c delete mode 100644 src/lib/doslib/dos/doswin.h delete mode 100644 src/lib/doslib/dos/dosxio.c delete mode 100644 src/lib/doslib/dos/dpmiexcp.c delete mode 100644 src/lib/doslib/dos/dpmirmcl.c delete mode 100644 src/lib/doslib/dos/emm.c delete mode 100644 src/lib/doslib/dos/himemsys.h delete mode 100644 src/lib/doslib/dos/lol.c delete mode 100644 src/lib/doslib/dos/ntastrm.c delete mode 100644 src/lib/doslib/dos/readme delete mode 100644 src/lib/doslib/dos/test.c delete mode 100644 src/lib/doslib/dos/testbext.c delete mode 100644 src/lib/doslib/dos/testdpmi.c delete mode 100644 src/lib/doslib/dos/testemm.c delete mode 100644 src/lib/doslib/dos/testsmrt.c delete mode 100644 src/lib/doslib/dos/tgusmega.c delete mode 100644 src/lib/doslib/dos/tgusmega.h delete mode 100644 src/lib/doslib/dos/tgussbos.c delete mode 100644 src/lib/doslib/dos/tgussbos.h delete mode 100644 src/lib/doslib/dos/tgusumid.c delete mode 100644 src/lib/doslib/dos/tgusumid.h delete mode 100644 src/lib/doslib/dos/tmp.cmd delete mode 100644 src/lib/doslib/dos/tstbiom.c delete mode 100644 src/lib/doslib/dos/tstlp.c delete mode 100644 src/lib/doslib/dos/win16vec.c delete mode 100644 src/lib/doslib/dos/win3216t.c delete mode 100644 src/lib/doslib/dos/win32lrd.c delete mode 100644 src/lib/doslib/dos/winfcon.c delete mode 100644 src/lib/doslib/dos/winfcon.h delete mode 100644 src/lib/doslib/dos/winnt/dosntast.vdd delete mode 100644 src/lib/doslib/dosdrv/buildall.bat delete mode 100644 src/lib/doslib/dosdrv/clean.bat delete mode 100644 src/lib/doslib/dosdrv/hello/CLEAN.BAT delete mode 100644 src/lib/doslib/dosdrv/hello/MAKE.BAT delete mode 100644 src/lib/doslib/dosdrv/hello/common.mak delete mode 100644 src/lib/doslib/dosdrv/hello/config.sys delete mode 100644 src/lib/doslib/dosdrv/hello/hello.asm delete mode 100644 src/lib/doslib/dosdrv/hello/test.dsk.gz rename src/lib/doslib/{hw/dos => }/emm.c (89%) rename src/lib/doslib/{dos => }/emm.h (75%) rename src/lib/doslib/{dos => }/himemsys.c (98%) rename src/lib/doslib/{hw/dos => }/himemsys.h (84%) delete mode 100644 src/lib/doslib/hw/8042/8042.c delete mode 100644 src/lib/doslib/hw/8042/8042.h delete mode 100644 src/lib/doslib/hw/8042/8042aux.c delete mode 100644 src/lib/doslib/hw/8042/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/8042/MAKE.BAT delete mode 100644 src/lib/doslib/hw/8042/common.mak delete mode 100644 src/lib/doslib/hw/8042/test.c delete mode 100644 src/lib/doslib/hw/8237/8237.c delete mode 100644 src/lib/doslib/hw/8237/8237.h delete mode 100644 src/lib/doslib/hw/8237/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/8237/MAKE.BAT delete mode 100644 src/lib/doslib/hw/8237/common.mak delete mode 100644 src/lib/doslib/hw/8237/test.c delete mode 100644 src/lib/doslib/hw/8250/8250.c delete mode 100644 src/lib/doslib/hw/8250/8250.h delete mode 100644 src/lib/doslib/hw/8250/8250pnp.c delete mode 100644 src/lib/doslib/hw/8250/8250pnp.h delete mode 100644 src/lib/doslib/hw/8250/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/8250/MAKE.BAT delete mode 100644 src/lib/doslib/hw/8250/common.mak delete mode 100644 src/lib/doslib/hw/8250/test.c delete mode 100644 src/lib/doslib/hw/8250/testpnp.c delete mode 100644 src/lib/doslib/hw/8254/8254.c delete mode 100644 src/lib/doslib/hw/8254/8254.h delete mode 100644 src/lib/doslib/hw/8254/8254rd.c delete mode 100644 src/lib/doslib/hw/8254/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/8254/MAKE.BAT delete mode 100644 src/lib/doslib/hw/8254/common.mak delete mode 100644 src/lib/doslib/hw/8254/readme delete mode 100644 src/lib/doslib/hw/8254/test.c delete mode 100644 src/lib/doslib/hw/8254/test1_22.wav delete mode 100644 src/lib/doslib/hw/8254/tmp.cmd delete mode 100644 src/lib/doslib/hw/8259/8259.c delete mode 100644 src/lib/doslib/hw/8259/8259.h delete mode 100644 src/lib/doslib/hw/8259/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/8259/MAKE.BAT delete mode 100644 src/lib/doslib/hw/8259/common.mak delete mode 100644 src/lib/doslib/hw/8259/readme delete mode 100644 src/lib/doslib/hw/8259/test.c delete mode 100644 src/lib/doslib/hw/8259/tmp.cmd delete mode 100644 src/lib/doslib/hw/acpi/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/acpi/MAKE.BAT delete mode 100644 src/lib/doslib/hw/acpi/acpi.c delete mode 100644 src/lib/doslib/hw/acpi/acpi.h delete mode 100644 src/lib/doslib/hw/acpi/common.mak delete mode 100644 src/lib/doslib/hw/acpi/test.c delete mode 100644 src/lib/doslib/hw/adlib/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/adlib/MAKE.BAT delete mode 100644 src/lib/doslib/hw/adlib/adlib.c delete mode 100644 src/lib/doslib/hw/adlib/adlib.h delete mode 100644 src/lib/doslib/hw/adlib/common.mak delete mode 100644 src/lib/doslib/hw/adlib/dos386f/dos4gw.exe delete mode 100644 src/lib/doslib/hw/adlib/dos386f/midi.exe delete mode 100644 src/lib/doslib/hw/adlib/dos386f/test.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86c/dos4gw.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86c/midi.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86c/test.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86l/dos4gw.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86l/midi.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86l/test.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86m/dos4gw.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86m/midi.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86m/test.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86s/dos4gw.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86s/midi.exe delete mode 100644 src/lib/doslib/hw/adlib/dos86s/test.exe delete mode 100644 src/lib/doslib/hw/adlib/midi.c delete mode 100644 src/lib/doslib/hw/adlib/midikeys.gen.pl delete mode 100644 src/lib/doslib/hw/adlib/readme delete mode 100644 src/lib/doslib/hw/adlib/test.c delete mode 100644 src/lib/doslib/hw/adlib/tmp.cmd delete mode 100644 src/lib/doslib/hw/apm/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/apm/MAKE.BAT delete mode 100644 src/lib/doslib/hw/apm/apm.c delete mode 100644 src/lib/doslib/hw/apm/apm.h delete mode 100644 src/lib/doslib/hw/apm/common.mak delete mode 100644 src/lib/doslib/hw/apm/readme delete mode 100644 src/lib/doslib/hw/apm/test.c delete mode 100644 src/lib/doslib/hw/biosdisk/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/biosdisk/MAKE.BAT delete mode 100644 src/lib/doslib/hw/biosdisk/biosdisk.c delete mode 100644 src/lib/doslib/hw/biosdisk/biosdisk.h delete mode 100644 src/lib/doslib/hw/biosdisk/common.mak delete mode 100644 src/lib/doslib/hw/biosdisk/dumphdp.c delete mode 100644 src/lib/doslib/hw/biosdisk/test.c delete mode 100644 src/lib/doslib/hw/buildall.bat delete mode 100644 src/lib/doslib/hw/clean.bat delete mode 100644 src/lib/doslib/hw/cpu/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/cpu/MAKE.BAT delete mode 100644 src/lib/doslib/hw/cpu/alignchk.asm delete mode 100644 src/lib/doslib/hw/cpu/apic.c delete mode 100644 src/lib/doslib/hw/cpu/apiclib.c delete mode 100644 src/lib/doslib/hw/cpu/apiclib.h delete mode 100644 src/lib/doslib/hw/cpu/bochstst/bochsrc delete mode 100644 src/lib/doslib/hw/cpu/common.mak delete mode 100644 src/lib/doslib/hw/cpu/config.sys delete mode 100644 src/lib/doslib/hw/cpu/cpu.c delete mode 100644 src/lib/doslib/hw/cpu/cpu.h delete mode 100644 src/lib/doslib/hw/cpu/cpuasm.asm delete mode 100644 src/lib/doslib/hw/cpu/cpuid.asm delete mode 100644 src/lib/doslib/hw/cpu/cpuidext.c delete mode 100644 src/lib/doslib/hw/cpu/cpuidext.h delete mode 100644 src/lib/doslib/hw/cpu/cpuiopd.asm delete mode 100644 src/lib/doslib/hw/cpu/cpup3sn.asm delete mode 100644 src/lib/doslib/hw/cpu/cpup3sn.h delete mode 100644 src/lib/doslib/hw/cpu/cpup3snc.c delete mode 100644 src/lib/doslib/hw/cpu/cpurdmsr.asm delete mode 100644 src/lib/doslib/hw/cpu/cpurdtsc.asm delete mode 100644 src/lib/doslib/hw/cpu/cpurdtsc.h delete mode 100644 src/lib/doslib/hw/cpu/cpusse.c delete mode 100644 src/lib/doslib/hw/cpu/cpusse.h delete mode 100644 src/lib/doslib/hw/cpu/cpussea.asm delete mode 100644 src/lib/doslib/hw/cpu/cpustrlv.c delete mode 100644 src/lib/doslib/hw/cpu/dispsn.c delete mode 100644 src/lib/doslib/hw/cpu/emm386.exe.gz delete mode 100644 src/lib/doslib/hw/cpu/gdt_enum.c delete mode 100644 src/lib/doslib/hw/cpu/gdt_enum.h delete mode 100644 src/lib/doslib/hw/cpu/gdtlist.c delete mode 100644 src/lib/doslib/hw/cpu/gdttae.c delete mode 100644 src/lib/doslib/hw/cpu/gr_add.c delete mode 100644 src/lib/doslib/hw/cpu/gr_add_t.bat delete mode 100644 src/lib/doslib/hw/cpu/grind.c delete mode 100644 src/lib/doslib/hw/cpu/grtest.bat delete mode 100644 src/lib/doslib/hw/cpu/hdd.dsk.gz delete mode 100644 src/lib/doslib/hw/cpu/libgrind.c delete mode 100644 src/lib/doslib/hw/cpu/libgrind.h delete mode 100644 src/lib/doslib/hw/cpu/mmx.c delete mode 100644 src/lib/doslib/hw/cpu/msdos5m.dsk.gz delete mode 100644 src/lib/doslib/hw/cpu/notes delete mode 100644 src/lib/doslib/hw/cpu/prot286.asm delete mode 100644 src/lib/doslib/hw/cpu/prot386.asm delete mode 100644 src/lib/doslib/hw/cpu/protdpmi.asm delete mode 100644 src/lib/doslib/hw/cpu/protvcpi.asm delete mode 100644 src/lib/doslib/hw/cpu/rdtsc.c delete mode 100644 src/lib/doslib/hw/cpu/reset.c delete mode 100644 src/lib/doslib/hw/cpu/resetasm.asm delete mode 100644 src/lib/doslib/hw/cpu/sse.c delete mode 100644 src/lib/doslib/hw/cpu/sseoff.c delete mode 100644 src/lib/doslib/hw/cpu/test.c delete mode 100644 src/lib/doslib/hw/cpu/tmp.cmd delete mode 100644 src/lib/doslib/hw/cpu/tss.asm delete mode 100644 src/lib/doslib/hw/cpu/tssring.asm delete mode 100644 src/lib/doslib/hw/cpu/v86.asm delete mode 100644 src/lib/doslib/hw/cpu/v86kern.asm delete mode 100644 src/lib/doslib/hw/cpu/v86kern2.asm delete mode 100644 src/lib/doslib/hw/cpu/win95.dsk.gz delete mode 100644 src/lib/doslib/hw/dos/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/dos/MAKE.BAT delete mode 100644 src/lib/doslib/hw/dos/biosext.c delete mode 100644 src/lib/doslib/hw/dos/biosext.h delete mode 100644 src/lib/doslib/hw/dos/biosmem.c delete mode 100644 src/lib/doslib/hw/dos/biosmem.h delete mode 100644 src/lib/doslib/hw/dos/biosmem3.c delete mode 100644 src/lib/doslib/hw/dos/common.mak delete mode 100644 src/lib/doslib/hw/dos/cr3.c delete mode 100644 src/lib/doslib/hw/dos/ddpmidos.c delete mode 100644 src/lib/doslib/hw/dos/ddpmidsc.c delete mode 100644 src/lib/doslib/hw/dos/ddpmilin.c delete mode 100644 src/lib/doslib/hw/dos/ddpmiphy.c delete mode 100644 src/lib/doslib/hw/dos/dos.c delete mode 100644 src/lib/doslib/hw/dos/dos.h delete mode 100644 src/lib/doslib/hw/dos/dos386f/dosntast.vdd delete mode 100644 src/lib/doslib/hw/dos/dos86c/dosntast.vdd delete mode 100644 src/lib/doslib/hw/dos/dos86l/dosntast.vdd delete mode 100644 src/lib/doslib/hw/dos/dos86m/dosntast.vdd delete mode 100644 src/lib/doslib/hw/dos/dos86s/dosntast.vdd delete mode 100644 src/lib/doslib/hw/dos/dos9xvm.c delete mode 100644 src/lib/doslib/hw/dos/dos_lol.c delete mode 100644 src/lib/doslib/hw/dos/dos_ltp.c delete mode 100644 src/lib/doslib/hw/dos/dos_mcb.c delete mode 100644 src/lib/doslib/hw/dos/dos_nmi.c delete mode 100644 src/lib/doslib/hw/dos/dosasm.asm delete mode 100644 src/lib/doslib/hw/dos/dosbox.c delete mode 100644 src/lib/doslib/hw/dos/dosbox.h delete mode 100644 src/lib/doslib/hw/dos/dosdev.c delete mode 100644 src/lib/doslib/hw/dos/dosdpmi.c delete mode 100644 src/lib/doslib/hw/dos/dosflavr.c delete mode 100644 src/lib/doslib/hw/dos/dosmapal.c delete mode 100644 src/lib/doslib/hw/dos/dosntast.c delete mode 100644 src/lib/doslib/hw/dos/dosntvdm.c delete mode 100644 src/lib/doslib/hw/dos/dosntvdm.h delete mode 100644 src/lib/doslib/hw/dos/dospsp.c delete mode 100644 src/lib/doslib/hw/dos/dossmdrv.c delete mode 100644 src/lib/doslib/hw/dos/dosvbox.c delete mode 100644 src/lib/doslib/hw/dos/dosvcpi.c delete mode 100644 src/lib/doslib/hw/dos/doswin.c delete mode 100644 src/lib/doslib/hw/dos/doswin.h delete mode 100644 src/lib/doslib/hw/dos/dosxio.c delete mode 100644 src/lib/doslib/hw/dos/dpmiexcp.c delete mode 100644 src/lib/doslib/hw/dos/dpmirmcl.c delete mode 100644 src/lib/doslib/hw/dos/emm.h delete mode 100644 src/lib/doslib/hw/dos/himemsys.c delete mode 100644 src/lib/doslib/hw/dos/lol.c delete mode 100644 src/lib/doslib/hw/dos/ntastrm.c delete mode 100644 src/lib/doslib/hw/dos/readme delete mode 100644 src/lib/doslib/hw/dos/test.c delete mode 100644 src/lib/doslib/hw/dos/testbext.c delete mode 100644 src/lib/doslib/hw/dos/testdpmi.c delete mode 100644 src/lib/doslib/hw/dos/testsmrt.c delete mode 100644 src/lib/doslib/hw/dos/tgusmega.c delete mode 100644 src/lib/doslib/hw/dos/tgusmega.h delete mode 100644 src/lib/doslib/hw/dos/tgussbos.c delete mode 100644 src/lib/doslib/hw/dos/tgussbos.h delete mode 100644 src/lib/doslib/hw/dos/tgusumid.c delete mode 100644 src/lib/doslib/hw/dos/tgusumid.h delete mode 100644 src/lib/doslib/hw/dos/tmp.cmd delete mode 100644 src/lib/doslib/hw/dos/tstbiom.c delete mode 100644 src/lib/doslib/hw/dos/tsthimem.c delete mode 100644 src/lib/doslib/hw/dos/tstlp.c delete mode 100644 src/lib/doslib/hw/dos/win16vec.c delete mode 100644 src/lib/doslib/hw/dos/win3216t.c delete mode 100644 src/lib/doslib/hw/dos/win32lrd.c delete mode 100644 src/lib/doslib/hw/dos/winfcon.c delete mode 100644 src/lib/doslib/hw/dos/winfcon.h delete mode 100644 src/lib/doslib/hw/dos/winnt/dosntast.vdd delete mode 100644 src/lib/doslib/hw/flatreal/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/flatreal/MAKE.BAT delete mode 100644 src/lib/doslib/hw/flatreal/common.mak delete mode 100644 src/lib/doslib/hw/flatreal/flatmode.asm delete mode 100644 src/lib/doslib/hw/flatreal/flatreal.c delete mode 100644 src/lib/doslib/hw/flatreal/flatreal.h delete mode 100644 src/lib/doslib/hw/flatreal/readme delete mode 100644 src/lib/doslib/hw/flatreal/test.c delete mode 100644 src/lib/doslib/hw/floppy/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/floppy/MAKE.BAT delete mode 100644 src/lib/doslib/hw/floppy/common.mak delete mode 100644 src/lib/doslib/hw/floppy/floppy.c delete mode 100644 src/lib/doslib/hw/floppy/floppy.h delete mode 100644 src/lib/doslib/hw/floppy/msdos622.dsk.gz delete mode 100644 src/lib/doslib/hw/floppy/test.c delete mode 100644 src/lib/doslib/hw/floppy/win95.dsk.gz delete mode 100644 src/lib/doslib/hw/ide/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/ide/MAKE.BAT delete mode 100644 src/lib/doslib/hw/ide/common.mak delete mode 100644 src/lib/doslib/hw/ide/idelib.c delete mode 100644 src/lib/doslib/hw/ide/idelib.h delete mode 100644 src/lib/doslib/hw/ide/readme delete mode 100644 src/lib/doslib/hw/ide/test.c delete mode 100644 src/lib/doslib/hw/ide/test.h delete mode 100644 src/lib/doslib/hw/ide/testbusy.c delete mode 100644 src/lib/doslib/hw/ide/testbusy.h delete mode 100644 src/lib/doslib/hw/ide/testcdej.c delete mode 100644 src/lib/doslib/hw/ide/testcdej.h delete mode 100644 src/lib/doslib/hw/ide/testcdrm.c delete mode 100644 src/lib/doslib/hw/ide/testcdrm.h delete mode 100644 src/lib/doslib/hw/ide/testcmui.c delete mode 100644 src/lib/doslib/hw/ide/testcmui.h delete mode 100644 src/lib/doslib/hw/ide/testidnt.c delete mode 100644 src/lib/doslib/hw/ide/testidnt.h delete mode 100644 src/lib/doslib/hw/ide/testmbox.c delete mode 100644 src/lib/doslib/hw/ide/testmbox.h delete mode 100644 src/lib/doslib/hw/ide/testmisc.c delete mode 100644 src/lib/doslib/hw/ide/testmisc.h delete mode 100644 src/lib/doslib/hw/ide/testmumo.c delete mode 100644 src/lib/doslib/hw/ide/testmumo.h delete mode 100644 src/lib/doslib/hw/ide/testnop.c delete mode 100644 src/lib/doslib/hw/ide/testnop.h delete mode 100644 src/lib/doslib/hw/ide/testpiom.c delete mode 100644 src/lib/doslib/hw/ide/testpiom.h delete mode 100644 src/lib/doslib/hw/ide/testpiot.c delete mode 100644 src/lib/doslib/hw/ide/testpiot.h delete mode 100644 src/lib/doslib/hw/ide/testpwr.c delete mode 100644 src/lib/doslib/hw/ide/testpwr.h delete mode 100644 src/lib/doslib/hw/ide/testrdts.c delete mode 100644 src/lib/doslib/hw/ide/testrdts.h delete mode 100644 src/lib/doslib/hw/ide/testrdtv.c delete mode 100644 src/lib/doslib/hw/ide/testrdtv.h delete mode 100644 src/lib/doslib/hw/ide/testrdwr.c delete mode 100644 src/lib/doslib/hw/ide/testrdwr.h delete mode 100644 src/lib/doslib/hw/ide/testrdws.c delete mode 100644 src/lib/doslib/hw/ide/testrdws.h delete mode 100644 src/lib/doslib/hw/ide/testrvfy.c delete mode 100644 src/lib/doslib/hw/ide/testrvfy.h delete mode 100644 src/lib/doslib/hw/ide/testtadj.c delete mode 100644 src/lib/doslib/hw/ide/testtadj.h delete mode 100644 src/lib/doslib/hw/ide/testutil.c delete mode 100644 src/lib/doslib/hw/ide/testutil.h delete mode 100644 src/lib/doslib/hw/isapnp/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/isapnp/MAKE.BAT delete mode 100644 src/lib/doslib/hw/isapnp/common.mak delete mode 100644 src/lib/doslib/hw/isapnp/isapnp.c delete mode 100644 src/lib/doslib/hw/isapnp/isapnp.h delete mode 100644 src/lib/doslib/hw/isapnp/other_id.txt delete mode 100644 src/lib/doslib/hw/isapnp/test.c delete mode 100644 src/lib/doslib/hw/llmem/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/llmem/MAKE.BAT delete mode 100644 src/lib/doslib/hw/llmem/bochstst/bochsrc delete mode 100644 src/lib/doslib/hw/llmem/common.mak delete mode 100644 src/lib/doslib/hw/llmem/config.sys delete mode 100644 src/lib/doslib/hw/llmem/emm386.exe.gz delete mode 100644 src/lib/doslib/hw/llmem/hdd.dsk.gz delete mode 100644 src/lib/doslib/hw/llmem/llmem.c delete mode 100644 src/lib/doslib/hw/llmem/llmem.h delete mode 100644 src/lib/doslib/hw/llmem/llmemasm.asm delete mode 100644 src/lib/doslib/hw/llmem/test.c delete mode 100644 src/lib/doslib/hw/llmem/win95.dsk.gz delete mode 100644 src/lib/doslib/hw/mb/buildall.bat delete mode 100644 src/lib/doslib/hw/mb/clean.bat delete mode 100644 src/lib/doslib/hw/mb/intel/buildall.bat delete mode 100644 src/lib/doslib/hw/mb/intel/clean.bat delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/MAKE.BAT delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/common.mak delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/piix3.c delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/piix3.h delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/readme delete mode 100644 src/lib/doslib/hw/mb/intel/piix3/test.c delete mode 100644 src/lib/doslib/hw/mb/readme delete mode 100644 src/lib/doslib/hw/parport/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/parport/MAKE.BAT delete mode 100644 src/lib/doslib/hw/parport/common.mak delete mode 100644 src/lib/doslib/hw/parport/parpnp.c delete mode 100644 src/lib/doslib/hw/parport/parpnp.h delete mode 100644 src/lib/doslib/hw/parport/parport.c delete mode 100644 src/lib/doslib/hw/parport/parport.h delete mode 100644 src/lib/doslib/hw/parport/prnt.c delete mode 100644 src/lib/doslib/hw/parport/prntpnp.c delete mode 100644 src/lib/doslib/hw/parport/samptest.c delete mode 100644 src/lib/doslib/hw/parport/test.c delete mode 100644 src/lib/doslib/hw/parport/testpnp.c delete mode 100644 src/lib/doslib/hw/parport/todo delete mode 100644 src/lib/doslib/hw/pci/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/pci/MAKE.BAT delete mode 100644 src/lib/doslib/hw/pci/common.mak delete mode 100644 src/lib/doslib/hw/pci/pci.c delete mode 100644 src/lib/doslib/hw/pci/pci.h delete mode 100644 src/lib/doslib/hw/pci/pcibios1.asm delete mode 100644 src/lib/doslib/hw/pci/test.c delete mode 100644 src/lib/doslib/hw/pcie/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/pcie/MAKE.BAT delete mode 100644 src/lib/doslib/hw/pcie/common.mak delete mode 100644 src/lib/doslib/hw/pcie/pcie.c delete mode 100644 src/lib/doslib/hw/pcie/pcie.h delete mode 100644 src/lib/doslib/hw/pcie/test.c delete mode 100644 src/lib/doslib/hw/readme delete mode 100644 src/lib/doslib/hw/rtc/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/rtc/MAKE.BAT delete mode 100644 src/lib/doslib/hw/rtc/cmos.c delete mode 100644 src/lib/doslib/hw/rtc/common.mak delete mode 100644 src/lib/doslib/hw/rtc/rtc.c delete mode 100644 src/lib/doslib/hw/rtc/rtc.h delete mode 100644 src/lib/doslib/hw/rtc/test.c delete mode 100644 src/lib/doslib/hw/smbios/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/smbios/MAKE.BAT delete mode 100644 src/lib/doslib/hw/smbios/common.mak delete mode 100644 src/lib/doslib/hw/smbios/smbios.c delete mode 100644 src/lib/doslib/hw/smbios/smbios.h delete mode 100644 src/lib/doslib/hw/smbios/test.c delete mode 100644 src/lib/doslib/hw/sndsb/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/sndsb/MAKE.BAT delete mode 100644 src/lib/doslib/hw/sndsb/common.mak delete mode 100644 src/lib/doslib/hw/sndsb/pnpcfg.c delete mode 100644 src/lib/doslib/hw/sndsb/readme delete mode 100644 src/lib/doslib/hw/sndsb/sndsb.c delete mode 100644 src/lib/doslib/hw/sndsb/sndsb.h delete mode 100644 src/lib/doslib/hw/sndsb/sndsbpnp.c delete mode 100644 src/lib/doslib/hw/sndsb/sndsbpnp.h delete mode 100644 src/lib/doslib/hw/sndsb/test.c delete mode 100644 src/lib/doslib/hw/ultrasnd/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/ultrasnd/MAKE.BAT delete mode 100644 src/lib/doslib/hw/ultrasnd/common.mak delete mode 100644 src/lib/doslib/hw/ultrasnd/test.c delete mode 100644 src/lib/doslib/hw/ultrasnd/tsrs.c delete mode 100644 src/lib/doslib/hw/ultrasnd/ultrasnd.c delete mode 100644 src/lib/doslib/hw/ultrasnd/ultrasnd.h delete mode 100644 src/lib/doslib/hw/usb/buildall.bat delete mode 100644 src/lib/doslib/hw/usb/clean.bat delete mode 100644 src/lib/doslib/hw/usb/ohci/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/usb/ohci/MAKE.BAT delete mode 100644 src/lib/doslib/hw/usb/ohci/common.mak delete mode 100644 src/lib/doslib/hw/usb/ohci/ohci.c delete mode 100644 src/lib/doslib/hw/usb/ohci/ohci.h delete mode 100644 src/lib/doslib/hw/usb/ohci/test.c delete mode 100644 src/lib/doslib/hw/usb/ohci/test_ref.dsk.gz delete mode 100644 src/lib/doslib/hw/vesa/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/vesa/MAKE.BAT delete mode 100644 src/lib/doslib/hw/vesa/common.mak delete mode 100644 src/lib/doslib/hw/vesa/modeset.c delete mode 100644 src/lib/doslib/hw/vesa/test.c delete mode 100644 src/lib/doslib/hw/vesa/vesa.c delete mode 100644 src/lib/doslib/hw/vesa/vesa.h delete mode 100644 src/lib/doslib/hw/vesa/vesa240.c delete mode 100644 src/lib/doslib/hw/vga/CLEAN.BAT delete mode 100644 src/lib/doslib/hw/vga/MAKE.BAT delete mode 100644 src/lib/doslib/hw/vga/common.mak delete mode 100644 src/lib/doslib/hw/vga/test.c delete mode 100644 src/lib/doslib/hw/vga/tmodeset.c delete mode 100644 src/lib/doslib/hw/vga/tmp.cmd delete mode 100644 src/lib/doslib/hw/vga/vga.c delete mode 100644 src/lib/doslib/hw/vga/vga.h delete mode 100644 src/lib/doslib/hw/vga/vga240.c delete mode 100644 src/lib/doslib/hw/vga/vgagui.c delete mode 100644 src/lib/doslib/hw/vga/vgagui.h delete mode 100644 src/lib/doslib/hw/vga/vgatty.c delete mode 100644 src/lib/doslib/hw/vga/vgatty.h delete mode 100644 src/lib/doslib/mak/bcommon.mak delete mode 100644 src/lib/doslib/mak/buildall.bat delete mode 100644 src/lib/doslib/mak/clean.bat delete mode 100644 src/lib/doslib/mak/comdo286.mak delete mode 100644 src/lib/doslib/mak/comdo386.mak delete mode 100644 src/lib/doslib/mak/comdo486.mak delete mode 100644 src/lib/doslib/mak/comdo586.mak delete mode 100644 src/lib/doslib/mak/comdo686.mak delete mode 100644 src/lib/doslib/mak/comdos86.mak delete mode 100644 src/lib/doslib/mak/comos216.mak delete mode 100644 src/lib/doslib/mak/comos232.mak delete mode 100644 src/lib/doslib/mak/comw3086.mak delete mode 100644 src/lib/doslib/mak/comw3186.mak delete mode 100644 src/lib/doslib/mak/comwn300.mak delete mode 100644 src/lib/doslib/mak/comwn302.mak delete mode 100644 src/lib/doslib/mak/comwn303.mak delete mode 100644 src/lib/doslib/mak/comwn312.mak delete mode 100644 src/lib/doslib/mak/comwn313.mak delete mode 100644 src/lib/doslib/mak/cow38631.mak delete mode 100644 src/lib/doslib/mak/cowin32.mak delete mode 100644 src/lib/doslib/mak/cowin32s.mak delete mode 100644 src/lib/doslib/mak/cowin386.mak delete mode 100644 src/lib/doslib/mak/cowinnt.mak delete mode 100644 src/lib/doslib/mak/dcommon.mak delete mode 100644 src/lib/doslib/mak/dos286c.mak delete mode 100644 src/lib/doslib/mak/dos286l.mak delete mode 100644 src/lib/doslib/mak/dos286m.mak delete mode 100644 src/lib/doslib/mak/dos286s.mak delete mode 100644 src/lib/doslib/mak/dos386f.mak delete mode 100644 src/lib/doslib/mak/dos486f.mak delete mode 100644 src/lib/doslib/mak/dos586f.mak delete mode 100644 src/lib/doslib/mak/dos686f.mak delete mode 100644 src/lib/doslib/mak/dos86c.mak delete mode 100644 src/lib/doslib/mak/dos86l.mak delete mode 100644 src/lib/doslib/mak/dos86m.mak delete mode 100644 src/lib/doslib/mak/dos86s.mak delete mode 100644 src/lib/doslib/mak/os2d3f.mak delete mode 100644 src/lib/doslib/mak/os2w2l.mak delete mode 100644 src/lib/doslib/mak/win300c.mak delete mode 100644 src/lib/doslib/mak/win300l.mak delete mode 100644 src/lib/doslib/mak/win300m.mak delete mode 100644 src/lib/doslib/mak/win300s.mak delete mode 100644 src/lib/doslib/mak/win302c.mak delete mode 100644 src/lib/doslib/mak/win302l.mak delete mode 100644 src/lib/doslib/mak/win302m.mak delete mode 100644 src/lib/doslib/mak/win302s.mak delete mode 100644 src/lib/doslib/mak/win303c.mak delete mode 100644 src/lib/doslib/mak/win303l.mak delete mode 100644 src/lib/doslib/mak/win303m.mak delete mode 100644 src/lib/doslib/mak/win303s.mak delete mode 100644 src/lib/doslib/mak/win312c.mak delete mode 100644 src/lib/doslib/mak/win312l.mak delete mode 100644 src/lib/doslib/mak/win312m.mak delete mode 100644 src/lib/doslib/mak/win312s.mak delete mode 100644 src/lib/doslib/mak/win313c.mak delete mode 100644 src/lib/doslib/mak/win313l.mak delete mode 100644 src/lib/doslib/mak/win313m.mak delete mode 100644 src/lib/doslib/mak/win313s.mak delete mode 100644 src/lib/doslib/mak/win32.mak delete mode 100644 src/lib/doslib/mak/win32s3.mak delete mode 100644 src/lib/doslib/mak/win32s4.mak delete mode 100644 src/lib/doslib/mak/win32s5.mak delete mode 100644 src/lib/doslib/mak/win32s6.mak delete mode 100644 src/lib/doslib/mak/win386.mak delete mode 100644 src/lib/doslib/mak/win38631.mak delete mode 100644 src/lib/doslib/mak/winnt.mak rename src/{lib/doslib/hw/dos => }/testemm.c (97%) rename src/{lib/doslib/dos => }/tsthimem.c (98%) create mode 100644 testemm.exe create mode 100644 tsthimem.exe diff --git a/16/dos_kb.c b/16/dos_kb.c index baffad9e..2bebd707 100644 --- a/16/dos_kb.c +++ b/16/dos_kb.c @@ -1,6 +1,7 @@ /* Thanks to Alex Russell for example code */ /* Thanks to Gary Neal for example code */ -#include "dos_kb.h" +/* working out the licencing~ */ +#include "src/lib/dos_kb.h" // keyboard buffer static byte key[NUM_SCANCODES]; // pressed @@ -18,7 +19,7 @@ static void interrupt (far *oldkb)(void) = NULL; /* BIOS keyboard handler */ * Comment out the following #define if you don't want the testing main() * to be included. */ -#define TESTING +//#define TESTING #define TESTING2 /*****************NEW KEYBOARD 09h ISR***********************/ diff --git a/16/dos_kb.h b/16/dos_kb.h index ea81462a..3161cfe9 100644 --- a/16/dos_kb.h +++ b/16/dos_kb.h @@ -1,23 +1,23 @@ -#ifndef _DOSLIB_KB_H_ -#define _DOSLIB_KB_H_ -#include "lib\lib_com.h" - -/* Maximum number of scan codes on keyboard controllers */ -#define NUM_SCANCODES 128 - -#ifdef __cplusplus /* Functions must be declared C style */ -extern "C" { -#endif -void interrupt far newkb(void); -//extern void interrupt (far *oldkb)(void); -void setkb(int vq); -int keyp(byte c); - -/* Define macro */ -//#define kepn(c) key[c & 0x7F] - -#ifdef __cplusplus -} -#endif - -#endif/*_DOSLIB_KB_H_*/ +#ifndef _DOSLIB_KB_H_ +#define _DOSLIB_KB_H_ +#include "src/lib/16_head.h" + +/* Maximum number of scan codes on keyboard controllers */ +#define NUM_SCANCODES 128 + +#ifdef __cplusplus /* Functions must be declared C style */ +extern "C" { +#endif +void interrupt far newkb(void); +//extern void interrupt (far *oldkb)(void); +void setkb(int vq); +int keyp(byte c); + +/* Define macro */ +//#define kepn(c) key[c & 0x7F] + +#ifdef __cplusplus +} +#endif + +#endif/*_DOSLIB_KB_H_*/ diff --git a/make-lowercase b/make-lowercase new file mode 100644 index 00000000..4e586f22 --- /dev/null +++ b/make-lowercase @@ -0,0 +1,63 @@ +#!/usr/bin/perl +my $top=`pwd`; chomp $top; + +sub vfat_rename($$) { + my $from,$to; + ($from,$to) = @_; + + # uppercase DOS names with the vfat driver need some forceful convincing + # to actually make them lowercase + rename($from,"$to.xxx.xx"); + rename("$to.xxx.xx",$to); +} + +sub scan($) { + my $old = `pwd`; chomp $old; + my $cur = shift @_; + my @x; + + print "scanning $cur\n"; + chdir($cur) || die; + + opendir(X,".") || return; + while (my $name = readdir(X)) { + next unless -f $name; + my $n = lc($name); + next if $n eq $name; + print "$name\n"; + rename($name,$n) || die; + vfat_rename($name,$n); + } + closedir(X); + + opendir(X,".") || return; + while (my $name = readdir(X)) { + next if $name =~ m/^\.+$/; + next if $name eq ".git"; + next if $name eq ".GIT"; + next unless -d $name; + my $n = lc($name); + next if $n eq $name; + print "$name\n"; + rename($name,$n) || die; + vfat_rename($name,$n); + } + closedir(X); + + opendir(X,".") || return; + while (my $name = readdir(X)) { + next if $name =~ m/^\.+$/; + next if $name eq ".git"; + next if $name eq ".GIT"; + next unless -d $name; + push(@x,$name); + } + closedir(X); + foreach my $name (@x) { + scan("$cur/$name"); + } + + chdir($old) || die; +} + +scan($top); diff --git a/makefile b/makefile index 7dded60d..1bdf1263 100644 --- a/makefile +++ b/makefile @@ -12,10 +12,10 @@ TARGET_OS = dos #-zk0 = kanji support~ #-zkl = current codepage -#MFLAGS=-mc# -zm +DFLAGS=-DTARGET_MSDOS=16 -DMSDOS=1# -zm CFLAGS=-zk0 -wo -x -mc# -zdp# -zp16 -zq OFLAGS=-ot -ox -ob -oh -or# -om -ol -ol+ -FLAGS=-0 -d2 -lr $(OFLAGS) $(CFLAGS) +FLAGS=-0 -d2 -lr $(OFLAGS) $(CFLAGS) $(DFLAGS) SRC=src$(DIRSEP) SRCLIB=$(SRC)lib$(DIRSEP) JSMNLIB=$(SRCLIB)jsmn$(DIRSEP) @@ -23,12 +23,12 @@ EXMMLIB=$(SRCLIB)exmm$(DIRSEP) DOSLIB=$(SRCLIB)doslib$(DIRSEP) WCPULIB=$(SRCLIB)wcpu$(DIRSEP) -DOSLIBOBJ = adlib.$(OBJ) midi.$(OBJ) 8254.$(OBJ) 8259.$(OBJ) cpu.$(OBJ) -16LIBOBJS = 16_in.$(OBJ) 16_mm.$(OBJ) wcpu.$(OBJ) 16_head.$(OBJ) scroll16.$(OBJ) 16_ca.$(OBJ) $(DOSLIBOBJ) +DOSLIBEXMMOBJ = himemsys.$(OBJ) emm.$(OBJ) +DOSLIBOBJ = adlib.$(OBJ) midi.$(OBJ) 8254.$(OBJ) 8259.$(OBJ) dos.$(OBJ) cpu.$(OBJ) +16LIBOBJS = 16_in.$(OBJ) 16_mm.$(OBJ) wcpu.$(OBJ) 16_head.$(OBJ) scroll16.$(OBJ) 16_ca.$(OBJ) GFXLIBOBJS = modex16.$(OBJ) bitmap.$(OBJ) planar.$(OBJ) 16text.$(OBJ) -all: 16.exe test.exe pcxtest.exe test2.exe palettec.exe maptest.exe fmemtest.exe fonttest.exe exmmtest.exe fonttes0.exe fontgfx.exe sountest.exe miditest.exe -#inputest.exe +all: 16.exe test.exe pcxtest.exe test2.exe palettec.exe maptest.exe fmemtest.exe fonttest.exe exmmtest.exe fonttes0.exe fontgfx.exe sountest.exe miditest.exe testemm.exe tsthimem.exe inputest.exe # #executables @@ -56,7 +56,7 @@ fontgfx.exe: fontgfx.$(OBJ) 16.lib wcl $(FLAGS) fontgfx.$(OBJ) 16.lib inputest.exe: inputest.$(OBJ) 16.lib - wcl $(FLAGS) inputest.$(OBJ) 16.lib + wcl $(FLAGS) -D__DEBUG_InputMgr__=1 inputest.$(OBJ) 16.lib sountest.exe: sountest.$(OBJ) 16.lib wcl $(FLAGS) sountest.$(OBJ) 16.lib @@ -64,6 +64,12 @@ sountest.exe: sountest.$(OBJ) 16.lib miditest.exe: miditest.$(OBJ) 16.lib wcl $(FLAGS) miditest.$(OBJ) 16.lib +tsthimem.exe: tsthimem.$(OBJ) 16.lib + wcl $(FLAGS) tsthimem.$(OBJ) 16.lib + +testemm.exe: testemm.$(OBJ) 16.lib + wcl $(FLAGS) testemm.$(OBJ) 16.lib + pcxtest.exe: pcxtest.$(OBJ) gfx.lib wcl $(FLAGS) pcxtest.$(OBJ) gfx.lib @@ -139,18 +145,27 @@ sountest.$(OBJ): $(SRC)sountest.c miditest.$(OBJ): $(SRC)miditest.c wcl $(FLAGS) -c $(SRC)miditest.c +testemm.$(OBJ): $(SRC)testemm.c + wcl $(FLAGS) -c $(SRC)testemm.c + +tsthimem.$(OBJ): $(SRC)tsthimem.c + wcl $(FLAGS) -c $(SRC)tsthimem.c + exmmtest.$(OBJ): $(SRC)exmmtest.c wcl $(FLAGS) -c $(SRC)exmmtest.c # #non executable objects libraries # -16.lib: $(16LIBOBJS) gfx.lib - wlib -b 16.lib $(16LIBOBJS) gfx.lib +16.lib: $(16LIBOBJS) gfx.lib doslib.lib + wlib -b 16.lib $(16LIBOBJS) gfx.lib doslib.lib gfx.lib: $(GFXLIBOBJS) wlib -b gfx.lib $(GFXLIBOBJS) +doslib.lib: $(DOSLIBOBJ) $(DOSLIBEXMMOBJ)# $(SRCLIB)cpu.lib + wlib -b doslib.lib $(DOSLIBOBJ) $(DOSLIBEXMMOBJ)# $(SRCLIB)cpu.lib + modex16.$(OBJ): $(SRCLIB)modex16.h $(SRCLIB)modex16.c wcl $(FLAGS) -c $(SRCLIB)modex16.c @@ -190,6 +205,9 @@ mapread.$(OBJ): $(SRCLIB)mapread.h $(SRCLIB)mapread.c 16.lib midi.$(OBJ): $(SRCLIB)midi.h $(SRCLIB)midi.c wcl $(FLAGS) -c $(SRCLIB)midi.c +# +# doslib stuff +# adlib.$(OBJ): $(DOSLIB)adlib.h $(DOSLIB)adlib.c wcl $(FLAGS) -c $(DOSLIB)adlib.c @@ -199,11 +217,19 @@ adlib.$(OBJ): $(DOSLIB)adlib.h $(DOSLIB)adlib.c 8259.$(OBJ): $(DOSLIB)8259.h $(DOSLIB)8259.c wcl $(FLAGS) -c $(DOSLIB)8259.c +dos.$(OBJ): $(DOSLIB)dos.h $(DOSLIB)dos.c + wcl $(FLAGS) -c $(DOSLIB)dos.c + cpu.$(OBJ): $(DOSLIB)cpu.h $(DOSLIB)cpu.c wcl $(FLAGS) -c $(DOSLIB)cpu.c -#dos.$(OBJ): $(DOSLIB)dos.h $(DOSLIB)dos.c -# wcl $(FLAGS) -c $(DOSLIB)dos.c +himemsys.$(OBJ): $(DOSLIB)himemsys.h $(DOSLIB)himemsys.c + wcl $(FLAGS) -c $(DOSLIB)himemsys.c + +emm.$(OBJ): $(DOSLIB)emm.h $(DOSLIB)emm.c + wcl $(FLAGS) -c $(DOSLIB)emm.c + +# end 16_head.$(OBJ): $(SRCLIB)16_head.h $(SRCLIB)16_head.c wcl $(FLAGS) -c $(SRCLIB)16_head.c diff --git a/miditest.exe b/miditest.exe index 3bf1942f3dcec57ff7f6d92256fc019ea25d324e..f9206c6030784b4b85e35be0549de0c2fd44ad5b 100644 GIT binary patch delta 28545 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

1oe#(N2JX%9YdY6LR^lun!{gE!4u^*>}oN3 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 NCC7)^-#$R-{{U@NqR#*T delta 7270 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 jnW4be*1BF8+gM?1n0HGHG_==Ln=L @@ -118,7 +118,7 @@ extern struct adlib_fm_channel adlib_fm_preset_horn; /* NTS: I have a Creative CT1350B card where we really do have to wait at least * 33us per I/O access, because the OPL2 chip on it really is that slow. - * + * * Peior to this fix, the adlib code would often fail on a real CT1350B * (unless run just after the Sound Blaster test program) and even if it * did run, only about 1/3rd of the voices would work. Upping the delay diff --git a/src/lib/doslib/cpu.c b/src/lib/doslib/cpu.c index 9b7caf95..17bf1f83 100644 --- a/src/lib/doslib/cpu.c +++ b/src/lib/doslib/cpu.c @@ -40,7 +40,6 @@ #include #include "src/lib/doslib/cpu.h" -//#include /* DEBUG: Flush out calls that aren't there */ #ifdef TARGET_OS2 @@ -155,3 +154,28 @@ void cpu_probe() { #endif } +int cpu_basic_probe() +{ + __asm + { + push bx + push cx + push dx + push si + push di + push bp +// BUGFIX: Calling near a function that returns far is like taking a long walk off a short pier +// push cs + +// call cpu_basic_probe_f_ + + pop bp + pop di + pop si + pop dx + pop cx + pop bx + //retnative + } + return; +} diff --git a/src/lib/doslib/cpu.h b/src/lib/doslib/cpu.h index f84974bb..5498a3cc 100644 --- a/src/lib/doslib/cpu.h +++ b/src/lib/doslib/cpu.h @@ -14,6 +14,7 @@ #include #include +#include "src/lib/16_head.h" #if !defined(FAR) # if defined(TARGET_WINDOWS) @@ -230,4 +231,6 @@ uint64_t cpu_rdmsr(const uint32_t idx); void cpu_wrmsr(const uint32_t idx,const uint64_t val); #endif +int cpu_basic_probe(); + #endif /* __HW_CPU_CPU_H */ diff --git a/src/lib/doslib/dos.c b/src/lib/doslib/dos.c index 911954a1..86b4c321 100644 --- a/src/lib/doslib/dos.c +++ b/src/lib/doslib/dos.c @@ -9,7 +9,7 @@ */ #ifdef TARGET_WINDOWS -# include +//# include #endif #include diff --git a/src/lib/doslib/dos.h b/src/lib/doslib/dos.h index 7ba0793d..2ae46b5b 100644 --- a/src/lib/doslib/dos.h +++ b/src/lib/doslib/dos.h @@ -12,6 +12,7 @@ #define __HW_DOS_DOS_H #include "src/lib/doslib/cpu.h" +//#include "src/lib/16_head.h" #include #if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) diff --git a/src/lib/doslib/dos/CLEAN.BAT b/src/lib/doslib/dos/CLEAN.BAT deleted file mode 100644 index f5d05fc5..00000000 --- a/src/lib/doslib/dos/CLEAN.BAT +++ /dev/null @@ -1,9 +0,0 @@ -@echo off - -deltree /Y -del /s /q dos386f\*.* -del *.obj -del *.exe -del *.lib -del *.com -del foo.gz diff --git a/src/lib/doslib/dos/MAKE.BAT b/src/lib/doslib/dos/MAKE.BAT deleted file mode 100644 index 53e6119e..00000000 --- a/src/lib/doslib/dos/MAKE.BAT +++ /dev/null @@ -1,14 +0,0 @@ -@echo off -rem ----- Auto-generated by make.sh and Linux make system do not modify - -rem ----- shut up DOS4G/W -set DOS4G=quiet - -if "%1" == "clean" call clean.bat -if "%1" == "clean" goto end - -mkdir dos386f -wmake -f ..\..\mak\dos386f.mak HPS=\ lib REL=..\.. - - -:end diff --git a/src/lib/doslib/dos/biosext.c b/src/lib/doslib/dos/biosext.c deleted file mode 100644 index 89378ee7..00000000 --- a/src/lib/doslib/dos/biosext.c +++ /dev/null @@ -1,159 +0,0 @@ -/* biosext.c - * - * DOS library for carrying out extended memory copy using BIOS INT 15h - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if TARGET_MSDOS == 16 -int bios_extcopy_sub(uint32_t dst,uint32_t src,unsigned long copy/* WARNING: must be multiple of 2, and <= 64KB */) { - /* WARNING: There are better ways to access extended memory. - * But we have this function for those cases where the better ways are - * unavailable. Such as: - * - * a) we're running on a 286, where 32-bit 386 instructions - * are unavailable to carry out flat real mode tricks - * - * b) we're running under Windows, whos DOS VM subsystem - * is intolerant of flat real mode and generally demands that - * we switch into DPMI protected mode to even access it - * - * c) we're running under some other virtual 8086 mode system - * that forbids flat realmode like hacks (such as EMM386.EXE) - * - * There is also another possible danger: Some BIOS implementations emulate 286 behavior (even on - * 386, 486, Pentium, and beyond) by masking off or ignoring the upper 8 bits of the base (24-31). - * On these systems, accessing memory at or above the 16MB mark with the BIOS is impossible. But on - * these same systems, you have 32-bit protected mode and the option to use flat real mode anyway, - * so it doesn't really matter. On a 286 class system where you must use this function, the CPU is - * physically incapable of signalling more than 16MB (24 bit addressing) so again, that doesn't - * matter. - * - * TODO: I need to test this theory: If a BIOS ignores address bits 24-31, but we're running under - * Windows (and therefore the Windows kernel's emulation of the BIOS call), does the address - * masking limitation still apply? */ - /* The following comment is a list of all system & BIOS combinations this code has been tested under. - * - * BIOS/System/Environment Works? At or above 16MB boundary? - * --------------------------------------------------------------------- - * DOSBox 0.74 YES w/ BUGS YES - * Microsoft Virtual PC 2007 YES YES - * Oracle VirtualBox 4.0.4 YES YES - * QEMU YES YES - * DOSBox 0.74 + - * Microsoft Windows 3.0 - * Real mode YES YES - * Standard mode YES YES - * 386 Enhanced mode YES NO - * Microsoft Windows 3.1 - * Standard mode YES YES - * 386 Enhanced mode YES YES - * Microsoft Windows 3.11 - * Standard mode YES YES - * 386 Enhanced mode YES YES - * QEMU + - * Microsoft Windows 95 (4.00.950) - * Normal YES YES - * Safe mode YES YES - * Microsoft Windows 98 (4.10.1998) - * Normal YES YES - * Safe mode YES YES - * Microsoft Windows ME (4.90.3000) - * Normal YES YES - * Safe mode YES YES - * Microsoft Windows 2000 Professional (5.00.2195) - * Normal YES NO - * Microsoft Windows XP Professional (5.1.2600) - * Normal YES NO - * Microsoft Windows XP Professional SP2 (5.1.2600) - * Normal YES NO - * Microsoft Windows Vista Ultimate - * Normal YES NO - * - * Bugs: - * * DOSBox 0.74: DOSBox directly emulates the INT BIOS function. Unfortunately it does it wrong, - * apparently getting bytes 7 and 8 of the descriptor backwards. If this code always - * fills in the flags and limit(16:19) bits, then it causes DOSBox to access addresses - * in the 0x8F000000....0x8FFFFFFF range (because the flags+limit byte is usually 0x8F - * on 386 systems and DOSBox is mistreating it as bits 24-31 of the address). - * - * Unfortunately this bug means that any program relying on this function exclusively - * will be unable to properly target memory above 16MB when running under DOSBox. However, - * DOSBox also fails to enforce segment limits in real mode (emulating a CPU that is - * perpetually in "flat real mode") which means that you are free to abuse 386+ style - * 32-bit addressing, therefore, you should be using flat real mode instead of this function. - * - * It's possible the DOSBox developers missed the bug because they only tested it against - * ancient DOS games written in the 286 era that habitually left bytes 7-8 zero anyway. - * Who knows? - */ - union REGS regs; - struct SREGS sregs; - uint8_t tmp[0x40]; /* the global descriptor table */ - - memset(tmp,0,sizeof(tmp)); - - *((uint16_t*)(tmp+0x10)) = 0xFFFF; /* limit (source) */ - *((uint32_t*)(tmp+0x12)) = 0x93000000UL + (src & 0xFFFFFFUL); /* base and access byte (source) */ - if (src >= 0x1000000UL/*>= 16MB*/) /* see DOSBox bug report listed above to understand why I am filling in bytes 7-8 this way */ - *((uint16_t*)(tmp+0x16)) = ((src >> 16) & 0xFF00UL) + 0x8FUL; /* (386) base bits 24-31, flags, limit bits 16-19 */ - - *((uint16_t*)(tmp+0x18)) = 0xFFFF; /* limit (dest) */ - *((uint32_t*)(tmp+0x1A)) = 0x93000000UL + (dst & 0xFFFFFFUL); /* base and access byte (dest) */ - if (dst >= 0x1000000UL/*>= 16MB*/) /* see DOSBox bug report listed above to understand why I am filling in bytes 7-8 this way */ - *((uint16_t*)(tmp+0x1E)) = ((dst >> 16) & 0xFF00UL) + 0x8FUL; /* (386) base bits 24-31, flags, limit bits 16-19 */ - - regs.h.ah = 0x87; - regs.w.cx = (unsigned int)(copy >> 1UL); /* number of WORDS, not BYTES */ - regs.w.si = FP_OFF((unsigned char*)tmp); - sregs.es = FP_SEG((unsigned char*)tmp); - int86x(0x15,®s,®s,&sregs); /* now call the BIOS */ - return (regs.h.ah == 0) ? 0 : -1; -} - -int bios_extcopy(uint32_t dst,uint32_t src,unsigned long copy) { - if (copy == 0UL) return 0; - /* if we're on anything less than a 286, then this function is meaningless--there is no extended memory */ - if (cpu_basic_level == (signed char)0xFF) cpu_probe(); - if (cpu_basic_level < 2) return -1; - /* carry out the copy operation */ - while (copy >= 0x10000UL) { - if (bios_extcopy_sub(dst,src,0x10000UL)) - return -1; - - copy -= 0x10000UL; - dst += 0x10000UL; - src += 0x10000UL; - } - if (copy >= 2UL) { - if (bios_extcopy_sub(dst,src,copy & 0xFFFFFFFEUL)) - return -1; - - dst += copy & 0xFFFFFFFEUL; - src += copy & 0xFFFFFFFEUL; - copy &= 1UL; - } - if (copy != 0UL) { - unsigned char tmp[2]; - if (bios_extcopy_sub(ptr2phys(tmp),src,2)) return -1; - *((unsigned char far*)MK_FP(dst>>4,dst&0xF)) = tmp[0]; - } - - return 0; -} -#endif - diff --git a/src/lib/doslib/dos/biosext.h b/src/lib/doslib/dos/biosext.h deleted file mode 100644 index 2f5c4b9c..00000000 --- a/src/lib/doslib/dos/biosext.h +++ /dev/null @@ -1,16 +0,0 @@ -/* biosext.h - * - * DOS library for carrying out extended memory copy using BIOS INT 15h - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include - -#if TARGET_MSDOS == 16 -int bios_extcopy(uint32_t dst,uint32_t src,unsigned long copy); -#endif - diff --git a/src/lib/doslib/dos/biosmem.c b/src/lib/doslib/dos/biosmem.c deleted file mode 100644 index f1644c8b..00000000 --- a/src/lib/doslib/dos/biosmem.c +++ /dev/null @@ -1,75 +0,0 @@ -/* biosmem.c - * - * Various BIOS INT 15h extended memory query functions. - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 16 -int biosmem_size_E820(unsigned long *index,struct bios_E820 *nfo) { - if (cpu_basic_level < 3) /* requires a 386 or higher. If the programmer didn't call CPU detection that's OK he gets the crash he deserves */ - return 0; - - return _biosmem_size_E820_3(index,nfo); -} - -int biosmem_size_88(unsigned int *sz) { - union REGS regs={0}; - - regs.x.ax = 0x8800; - int86(0x15,®s,®s); - if (regs.x.cflag & 1) /* CF=1 */ - return 0; - if (regs.x.ax == 0) - return 0; - if (regs.h.ah == 0x86 || regs.h.ah == 0x80) - return 0; - - *sz = regs.x.ax; - return 1; -} - -int biosmem_size_E801(unsigned int *low,unsigned int *high) { - union REGS regs={0}; - - regs.x.ax = 0xE801; - int86(0x15,®s,®s); - if (regs.x.cflag & 1) { /* CF=1 */ - return 0; - } - - if (regs.x.ax == 0) - regs.x.ax = regs.x.cx; - else if (regs.x.cx == 0) - regs.x.cx = regs.x.ax; - - if (regs.x.bx == 0) - regs.x.bx = regs.x.dx; - else if (regs.x.dx == 0) - regs.x.dx = regs.x.bx; - - if (regs.x.ax != regs.x.cx || regs.x.bx != regs.x.dx) - return 0; - - *low = regs.x.ax; - *high = regs.x.bx; - return 1; -} -#endif - diff --git a/src/lib/doslib/dos/biosmem.h b/src/lib/doslib/dos/biosmem.h deleted file mode 100644 index ad156fd0..00000000 --- a/src/lib/doslib/dos/biosmem.h +++ /dev/null @@ -1,33 +0,0 @@ -/* biosmem.h - * - * Various BIOS INT 15h extended memory query functions. - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#pragma pack(push,1) -struct bios_E820 { - uint64_t base,length; - uint32_t type; - uint32_t ext_attributes; -}; -#pragma pack(pop) - -/* INT 15H AX=E820 types */ -enum { - BIOS_E820_NONE=0, - BIOS_E820_RAM, - BIOS_E820_RESERVED, - BIOS_E820_ACPI_RECLAIMABLE, - BIOS_E820_ACPI_NVS, - BIOS_E820_FAULTY -}; - -int _biosmem_size_E820_3(unsigned long *index,struct bios_E820 *nfo); -int biosmem_size_E820(unsigned long *index,struct bios_E820 *nfo); -int biosmem_size_E801(unsigned int *low,unsigned int *high); -int biosmem_size_88(unsigned int *sz); - diff --git a/src/lib/doslib/dos/biosmem3.c b/src/lib/doslib/dos/biosmem3.c deleted file mode 100644 index 82d208a0..00000000 --- a/src/lib/doslib/dos/biosmem3.c +++ /dev/null @@ -1,60 +0,0 @@ -/* biosmem3.c - * - * Support functions for calling BIOS INT 15h E820 to query extended memory layout - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 16 -int _biosmem_size_E820_3(unsigned long *index,struct bios_E820 *nfo) { - unsigned long idx = *index; - unsigned long retv = 0; - unsigned int len = 0; - - memset(nfo,0,sizeof(*nfo)); - - __asm { - push es - mov eax,0xE820 - mov ebx,idx - mov ecx,24 - mov edx,0x534D4150 -#if defined(__LARGE__) || defined(__COMPACT__) - mov di,word ptr [nfo+2] ; segment portion of far pointer - mov es,di -#endif - mov di,word ptr [nfo] ; offset of pointer - int 15h - pop es - jc noway - mov retv,eax - mov idx,ebx - mov len,cx ; Watcom doesn't know what "CL" is? It's only the lower 8 bits of CX/ECX Duhhhh... -noway: - } - - if (retv == 0x534D4150UL) { - *index = idx; - return len & 0xFF; - } - - return 0; -} -#endif - diff --git a/src/lib/doslib/dos/common.mak b/src/lib/doslib/dos/common.mak deleted file mode 100644 index 5105fec5..00000000 --- a/src/lib/doslib/dos/common.mak +++ /dev/null @@ -1,247 +0,0 @@ - -# TODO: OS/2 target: What can we #define to tell the header files which OS/2 -# environment we're doing? (Command prompt app. vs Presentation Manager app vs. -# "fullscreen" app.) - -# this makefile is included from all the dos*.mak files, do not use directly -# NTS: HPS is either \ (DOS) or / (Linux) - -CFLAGS_THIS = -fr=nul -fo=$(SUBDIR)$(HPS).obj -i=.. -i..$(HPS).. -NOW_BUILDING = HW_DOS_LIB - -OBJS = $(SUBDIR)$(HPS)dos.obj $(SUBDIR)$(HPS)dosxio.obj $(SUBDIR)$(HPS)biosext.obj $(SUBDIR)$(HPS)himemsys.obj $(SUBDIR)$(HPS)emm.obj $(SUBDIR)$(HPS)dosbox.obj $(SUBDIR)$(HPS)biosmem.obj $(SUBDIR)$(HPS)biosmem3.obj $(SUBDIR)$(HPS)dosasm.obj $(SUBDIR)$(HPS)tgusmega.obj $(SUBDIR)$(HPS)tgussbos.obj $(SUBDIR)$(HPS)tgusumid.obj $(SUBDIR)$(HPS)dosntvdm.obj $(SUBDIR)$(HPS)doswin.obj $(SUBDIR)$(HPS)dos_lol.obj $(SUBDIR)$(HPS)dossmdrv.obj $(SUBDIR)$(HPS)dosvbox.obj $(SUBDIR)$(HPS)dosmapal.obj $(SUBDIR)$(HPS)dosflavr.obj $(SUBDIR)$(HPS)dos9xvm.obj $(SUBDIR)$(HPS)dos_nmi.obj $(SUBDIR)$(HPS)win32lrd.obj $(SUBDIR)$(HPS)win3216t.obj $(SUBDIR)$(HPS)win16vec.obj $(SUBDIR)$(HPS)dpmiexcp.obj $(SUBDIR)$(HPS)dosvcpi.obj $(SUBDIR)$(HPS)ddpmilin.obj $(SUBDIR)$(HPS)ddpmiphy.obj $(SUBDIR)$(HPS)ddpmidos.obj $(SUBDIR)$(HPS)ddpmidsc.obj $(SUBDIR)$(HPS)dpmirmcl.obj $(SUBDIR)$(HPS)dos_mcb.obj $(SUBDIR)$(HPS)dospsp.obj $(SUBDIR)$(HPS)dosdev.obj $(SUBDIR)$(HPS)dos_ltp.obj $(SUBDIR)$(HPS)dosdpmi.obj -!ifdef TARGET_WINDOWS -OBJS += $(SUBDIR)$(HPS)winfcon.obj -!endif - -#HW_DOS_LIB = $(SUBDIR)$(HPS)dos.lib - -!ifndef TARGET_OS2 -NTVDMLIB_LIB = ..$(HPS)..$(HPS)windows$(HPS)ntvdm$(HPS)$(SUBDIR)$(HPS)ntvdmlib.lib -NTVDMLIB_LIB_WLINK_LIBRARIES = library $(NTVDMLIB_LIB) -NTVDMVDD_LIB = ..$(HPS)..$(HPS)windows$(HPS)ntvdm$(HPS)$(SUBDIR)$(HPS)ntvdmvdd.lib -NTVDMVDD_LIB_WLINK_LIBRARIES = library $(NTVDMVDD_LIB) -!endif - -!ifndef TARGET_WINDOWS -! ifndef TARGET_OS2 -LOL_EXE = $(SUBDIR)$(HPS)lol.exe -TESTSMRT_EXE =$(SUBDIR)$(HPS)testsmrt.exe -NTASTRM_EXE = $(SUBDIR)$(HPS)ntastrm.exe -! ifeq TARGET_MSDOS 16 -TESTDPMI_EXE =$(SUBDIR)$(HPS)testdpmi.exe -! endif -TSTHIMEM_EXE =$(SUBDIR)$(HPS)tsthimem.exe -TESTBEXT_EXE =$(SUBDIR)$(HPS)testbext.exe -TESTEMM_EXE = $(SUBDIR)$(HPS)testemm.exe -TSTBIOM_EXE = $(SUBDIR)$(HPS)tstbiom.exe -TSTLP_EXE = $(SUBDIR)$(HPS)tstlp.exe -! endif -!endif -TEST_EXE = $(SUBDIR)$(HPS)test.exe -CR3_EXE = $(SUBDIR)$(HPS)cr3.exe - -!ifndef TARGET_OS2 -# if targeting Win32, then build the DOS NT assistant DLL that DOS versions -# can use to better interact with Windows NT/2000/XP. Else, copy the winnt -# DLL into the DOS build dir. The DLL is given the .VDD extension to clarify -# that it is intented for use as a VDD for NTVDM.EXE (or as a Win32 extension -# to the Win16 builds). -DOSNTAST_VDD = $(SUBDIR)$(HPS)dosntast.vdd -!endif - -!ifdef TARGET_WINDOWS -! ifeq TARGET_MSDOS 32 -! ifeq TARGET_WINDOWS 40 -DOSNTAST_VDD_BUILD=1 -! endif -! endif -!endif - -$(HW_DOS_LIB): $(OBJS) - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dos.obj -+$(SUBDIR)$(HPS)biosext.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)himemsys.obj -+$(SUBDIR)$(HPS)emm.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dosbox.obj -+$(SUBDIR)$(HPS)biosmem.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)biosmem3.obj -+$(SUBDIR)$(HPS)dosasm.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)tgusmega.obj -+$(SUBDIR)$(HPS)tgussbos.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)tgusumid.obj -+$(SUBDIR)$(HPS)dosntvdm.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)doswin.obj -+$(SUBDIR)$(HPS)dosxio.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dos_lol.obj -+$(SUBDIR)$(HPS)dossmdrv.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dosvbox.obj -+$(SUBDIR)$(HPS)dosmapal.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dosflavr.obj -+$(SUBDIR)$(HPS)dos9xvm.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dos_nmi.obj -+$(SUBDIR)$(HPS)win32lrd.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)win3216t.obj -+$(SUBDIR)$(HPS)win16vec.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dpmiexcp.obj -+$(SUBDIR)$(HPS)dosvcpi.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)ddpmilin.obj -+$(SUBDIR)$(HPS)ddpmiphy.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)ddpmidos.obj -+$(SUBDIR)$(HPS)ddpmidsc.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dpmirmcl.obj -+$(SUBDIR)$(HPS)dos_mcb.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dospsp.obj -+$(SUBDIR)$(HPS)dosdev.obj - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)dos_ltp.obj -+$(SUBDIR)$(HPS)dosdpmi.obj -!ifdef TARGET_WINDOWS - wlib -q -b -c $(HW_DOS_LIB) -+$(SUBDIR)$(HPS)winfcon.obj -!endif - -# some components need a 386 in real mode -$(SUBDIR)$(HPS)biosmem3.obj: biosmem3.c - %write tmp.cmd $(CFLAGS_THIS) $(CFLAGS386) $[@ - @$(CC) @tmp.cmd - -$(SUBDIR)$(HPS)dosntast.obj: dosntast.c - %write tmp.cmd $(CFLAGS_THIS) $(CFLAGS) $[@ - @$(CC) @tmp.cmd - -# NTS we have to construct the command line into tmp.cmd because for MS-DOS -# systems all arguments would exceed the pitiful 128 char command line limit -.C.OBJ: - %write tmp.cmd $(CFLAGS_THIS) $(CFLAGS_CON) $[@ - @$(CC) @tmp.cmd - -.ASM.OBJ: - nasm -o $@ -f obj $(NASMFLAGS) $[@ - -all: lib exe - -exe: $(TESTSMRT_EXE) $(NTASTRM_EXE) $(TEST_EXE) $(CR3_EXE) $(TESTBEXT_EXE) $(TSTHIMEM_EXE) $(TESTEMM_EXE) $(TSTBIOM_EXE) $(LOL_EXE) $(TSTLP_EXE) $(TESTDPMI_EXE) .symbolic - -lib: $(DOSNTAST_VDD) $(HW_DOS_LIB) .symbolic - -!ifdef TESTSMRT_EXE -$(TESTSMRT_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)testsmrt.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) file $(SUBDIR)$(HPS)testsmrt.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TESTSMRT_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef NTASTRM_EXE -$(NTASTRM_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)ntastrm.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) file $(SUBDIR)$(HPS)ntastrm.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(NTASTRM_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef DOSNTAST_VDD_BUILD -$(DOSNTAST_VDD): $(HW_DOS_LIB) $(HW_CPU_LIB) $(NTVDMLIB_LIB) $(NTVDMVDD_LIB) $(SUBDIR)$(HPS)dosntast.obj - %write tmp.cmd option quiet system $(WLINK_DLL_SYSTEM) $(HW_CPU_LIB_WLINK_LIBRARIES) $(HW_DOS_LIB_WLINK_LIBRARIES) $(NTVDMVDD_LIB_WLINK_LIBRARIES) $(NTVDMLIB_LIB_WLINK_LIBRARIES) library winmm.lib file $(SUBDIR)$(HPS)dosntast.obj - %write tmp.cmd option modname='DOSNTAST' -! ifeq TARGET_MSDOS 32 - %write tmp.cmd option nostdcall -! endif -# explanation: if we use the IMPLIB option, Watcom will go off and make an import library that -# cases all references to refer to HELLDLD1.DLL within the NE image, which Windows does NOT like. -# we need to ensure the DLL name is encoded by itself without a .DLL extension which is more -# compatible with Windows and it's internal functions. -# -# Frankly I'm surprised that Watcom has this bug considering how long it's been around... Kind of disappointed really -# %write tmp.cmd option impfile=$(SUBDIR)$(HPS)DOSNTAST.LCF - %write tmp.cmd name $(DOSNTAST_VDD) - @wlink @tmp.cmd -!else -# copy from Win32 dir. Build if necessary -winnt$(HPS)dosntast.vdd: dosntast.c - @$(MAKECMD) build lib winnt - -! ifdef DOSNTAST_VDD -$(DOSNTAST_VDD): winnt$(HPS)dosntast.vdd - @$(COPY) winnt$(HPS)dosntast.vdd $(DOSNTAST_VDD) -! endif -!endif - -!ifdef LOL_EXE -$(LOL_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)lol.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) file $(SUBDIR)$(HPS)lol.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(LOL_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TESTDPMI_EXE -$(TESTDPMI_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)testdpmi.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) file $(SUBDIR)$(HPS)testdpmi.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TESTDPMI_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TEST_EXE -$(TEST_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)test.obj - %write tmp.cmd option quiet system $(WLINK_CON_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)test.obj $(HW_DOS_LIB_WLINK_LIBRARIES) - %write tmp.cmd option map=$(SUBDIR)$(HPS)test.map -! ifdef TARGET_WINDOWS -! ifeq TARGET_MSDOS 16 - %write tmp.cmd segment TYPE CODE PRELOAD FIXED DISCARDABLE SHARED - %write tmp.cmd segment TYPE DATA PRELOAD MOVEABLE -! endif -! endif - %write tmp.cmd name $(TEST_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -! ifdef WIN386 - @$(WIN386_EXE_TO_REX_IF_REX) $(TEST_EXE) - @wbind $(TEST_EXE) -q -n -! endif -! ifdef WIN_NE_SETVER_BUILD - $(WIN_NE_SETVER_BUILD) $(TEST_EXE) -! endif -!endif - -!ifdef CR3_EXE -$(CR3_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)cr3.obj - %write tmp.cmd option quiet system $(WLINK_CON_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)cr3.obj $(HW_DOS_LIB_WLINK_LIBRARIES) - %write tmp.cmd option map=$(SUBDIR)$(HPS)cr3.map -! ifdef TARGET_WINDOWS -! ifeq TARGET_MSDOS 16 - %write tmp.cmd segment TYPE CODE PRELOAD FIXED DISCARDABLE SHARED - %write tmp.cmd segment TYPE DATA PRELOAD MOVEABLE -! endif -! endif - %write tmp.cmd name $(CR3_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -! ifdef WIN386 - @$(WIN386_EXE_TO_REX_IF_REX) $(CR3_EXE) - @wbind $(CR3_EXE) -q -n -! endif -! ifdef WIN_NE_SETVER_BUILD - $(WIN_NE_SETVER_BUILD) $(CR3_EXE) -! endif -!endif - -!ifdef TSTLP_EXE -$(TSTLP_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)tstlp.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)tstlp.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TSTLP_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TESTBEXT_EXE -$(TESTBEXT_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)testbext.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)testbext.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TESTBEXT_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TSTHIMEM_EXE -$(TSTHIMEM_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)tsthimem.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)tsthimem.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TSTHIMEM_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TESTEMM_EXE -$(TESTEMM_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)testemm.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)testemm.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TESTEMM_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -!ifdef TSTBIOM_EXE -$(TSTBIOM_EXE): $(HW_DOS_LIB) $(HW_DOS_LIB_DEPENDENCIES) $(SUBDIR)$(HPS)tstbiom.obj - %write tmp.cmd option quiet system $(WLINK_SYSTEM) $(WLINK_FLAGS) file $(SUBDIR)$(HPS)tstbiom.obj $(HW_DOS_LIB_WLINK_LIBRARIES) name $(TSTBIOM_EXE) - @wlink @tmp.cmd - @$(COPY) ..$(HPS)..$(HPS)dos32a.dat $(SUBDIR)$(HPS)dos4gw.exe -!endif - -clean: .SYMBOLIC - del $(SUBDIR)$(HPS)*.obj - del $(HW_DOS_LIB) - del tmp.cmd - @echo Cleaning done - diff --git a/src/lib/doslib/dos/cr3.c b/src/lib/doslib/dos/cr3.c deleted file mode 100644 index 1a327b7d..00000000 --- a/src/lib/doslib/dos/cr3.c +++ /dev/null @@ -1,44 +0,0 @@ -/* cr3.c - * - * Test program: Attempt to read the CR3 register, see what happens - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef TARGET_WINDOWS -# define WINFCON_STOCK_WIN_MAIN -# include -#endif - -int main() { - uint32_t v_cr3=0; - - probe_dos(); - - __asm { - .386p - int 3 - xor eax,eax - mov eax,cr3 - mov v_cr3,eax - } - - printf("CR3=0x%08lX\n",(unsigned long)v_cr3); - return 0; -} - diff --git a/src/lib/doslib/dos/ddpmidos.c b/src/lib/doslib/dos/ddpmidos.c deleted file mode 100644 index 4830a197..00000000 --- a/src/lib/doslib/dos/ddpmidos.c +++ /dev/null @@ -1,64 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 -void *dpmi_alloc_dos(unsigned long len,uint16_t *selector) { - unsigned short rm=0,pm=0,fail=0; - - /* convert len to paragraphs */ - len = (len + 15) >> 4UL; - if (len >= 0xFF00UL) return NULL; - - __asm { - mov bx,WORD PTR len - mov ax,0x100 - int 0x31 - - mov rm,ax - mov pm,dx - sbb ax,ax - mov fail,ax - } - - if (fail) return NULL; - - *selector = pm; - return (void*)((unsigned long)rm << 4UL); -} - -void dpmi_free_dos(uint16_t selector) { - __asm { - mov ax,0x101 - mov dx,selector - int 0x31 - } -} -#endif - diff --git a/src/lib/doslib/dos/ddpmidsc.c b/src/lib/doslib/dos/ddpmidsc.c deleted file mode 100644 index 0533fe1e..00000000 --- a/src/lib/doslib/dos/ddpmidsc.c +++ /dev/null @@ -1,96 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* TODO: Windows 3.1/95/98/ME have a DPMI server underneath. - * It would be neato at some point if these functions were - * available for use from Windows 3.1 Win16/Win32, and - * Windows 95/98/ME Win32 */ -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -void dpmi_free_descriptor(uint16_t d) { - union REGS regs = {0}; - regs.w.ax = 0x0001; /* DPMI free descriptor */ - regs.w.bx = d; - int386(0x31,®s,®s); -} - -uint16_t dpmi_alloc_descriptors(uint16_t c) { - union REGS regs = {0}; - regs.w.ax = 0x0000; /* allocate descriptor */ - regs.w.cx = 1; /* just one */ - int386(0x31,®s,®s); - if (regs.w.cflag & 1) return 0; - return regs.w.ax; -} - -unsigned int dpmi_set_segment_base(uint16_t sel,uint32_t base) { - union REGS regs = {0}; - regs.w.ax = 0x0007; /* set segment base */ - regs.w.bx = sel; - regs.w.cx = base >> 16UL; - regs.w.dx = base; - int386(0x31,®s,®s); - if (regs.w.cflag & 1) return 0; - return 1; -} - -unsigned int dpmi_set_segment_limit(uint16_t sel,uint32_t limit) { - union REGS regs = {0}; - regs.w.ax = 0x0008; /* set segment limit */ - regs.w.bx = sel; - regs.w.cx = limit >> 16UL; - regs.w.dx = limit; - int386(0x31,®s,®s); - if (regs.w.cflag & 1) return 0; - return 1; -} - -unsigned int dpmi_set_segment_access(uint16_t sel,uint16_t access) { - union REGS regs = {0}; - unsigned char c=0; - - /* the DPL/CPL value we give to the DPMI function below must match our privilege level, so - * get that value from our own selector */ - __asm { - push eax - movzx eax,sel - and al,3 - mov c,al - pop eax - } - - regs.w.ax = 0x0009; /* set segment access rights */ - regs.w.bx = sel; - regs.w.cx = (access & 0xFF9F) | (c << 5); /* readable, code, CPL=same, present=1, 16-bit byte granular */ - int386(0x31,®s,®s); - if (regs.w.cflag & 1) return 0; - return 1; -} -#endif - diff --git a/src/lib/doslib/dos/ddpmilin.c b/src/lib/doslib/dos/ddpmilin.c deleted file mode 100644 index e765b710..00000000 --- a/src/lib/doslib/dos/ddpmilin.c +++ /dev/null @@ -1,106 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 -int dpmi_linear_lock(uint32_t lin,uint32_t size) { - int retv = 0; - - __asm { - mov ax,0x0600 - mov cx,word ptr lin - mov bx,word ptr lin+2 - mov di,word ptr size - mov si,word ptr size+2 - int 0x31 - jc endf - mov retv,1 -endf: - } - - return retv; -} - -int dpmi_linear_unlock(uint32_t lin,uint32_t size) { - int retv = 0; - - __asm { - mov ax,0x0601 - mov cx,word ptr lin - mov bx,word ptr lin+2 - mov di,word ptr size - mov si,word ptr size+2 - int 0x31 - jc endf - mov retv,1 -endf: - } - - return retv; -} - -void *dpmi_linear_alloc(uint32_t try_lin,uint32_t size,uint32_t flags,uint32_t *handle) { - void *retv = 0; - uint32_t han = 0; - - __asm { - mov ax,0x0504 - mov ebx,try_lin - mov ecx,size - mov edx,flags - int 0x31 - jc endf - mov retv,ebx - mov han,esi -endf: - } - - if (retv != NULL && handle != NULL) - *handle = han; - - return retv; -} - -int dpmi_linear_free(uint32_t handle) { - int retv = 0; - - __asm { - mov ax,0x0502 - mov di,word ptr handle - mov si,word ptr handle+2 - int 0x31 - jc endf - mov retv,1 -endf: - } - - return retv; -} -#endif - diff --git a/src/lib/doslib/dos/ddpmiphy.c b/src/lib/doslib/dos/ddpmiphy.c deleted file mode 100644 index 0164a15b..00000000 --- a/src/lib/doslib/dos/ddpmiphy.c +++ /dev/null @@ -1,60 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 -void *dpmi_phys_addr_map(uint32_t phys,uint32_t size) { - uint32_t retv = 0; - - __asm { - mov ax,0x0800 - mov cx,word ptr phys - mov bx,word ptr phys+2 - mov di,word ptr size - mov si,word ptr size+2 - int 0x31 - jc endf - mov word ptr retv,cx - mov word ptr retv+2,bx -endf: - } - - return (void*)retv; -} - -void dpmi_phys_addr_free(void *base) { - __asm { - mov ax,0x0801 - mov cx,word ptr base - mov bx,word ptr base+2 - int 0x31 - } -} -#endif - diff --git a/src/lib/doslib/dos/dos.c b/src/lib/doslib/dos/dos.c deleted file mode 100644 index 0057f975..00000000 --- a/src/lib/doslib/dos/dos.c +++ /dev/null @@ -1,308 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* DEBUG: Flush out calls that aren't there */ -#ifdef TARGET_OS2 -# define int86 ___EVIL___ -# define int386 ___EVIL___ -# define ntvdm_RegisterModule ___EVIL___ -# define ntvdm_UnregisterModule ___EVIL___ -# define _dos_getvect ___EVIL___ -# define _dos_setvect ___EVIL___ -#endif - -struct lib_dos_options lib_dos_option={0}; - -/* DOS version info */ -uint8_t dos_flavor = 0; -uint16_t dos_version = 0; -uint32_t freedos_kernel_version = 0; -const char *dos_version_method = NULL; - -#if TARGET_MSDOS == 32 -char *freedos_kernel_version_str = NULL; -#else -char far *freedos_kernel_version_str = NULL; -#endif - -void probe_dos() { -#if TARGET_MSDOS == 32 && 0 - assert(sizeof(struct dpmi_realmode_call) == 0x32); - assert(offsetof(struct dpmi_realmode_call,ss) == 0x30); - assert(offsetof(struct dpmi_realmode_call,cs) == 0x2C); -#endif - - if (dos_version == 0) { -#ifdef TARGET_WINDOWS -# if TARGET_MSDOS == 32 -# ifdef WIN386 -/* =================== Windows 3.0/3.1 Win386 ================= */ - DWORD raw = GetVersion(); /* NTS: The Win16 version does not tell us if we're running under Windows NT */ - - dos_version_method = "GetVersion"; - dos_version = (((raw >> 24UL) & 0xFFUL) << 8UL) | (((raw >> 16UL) & 0xFFUL) << 0UL); - - /* Windows NT/2000/XP NTVDM.EXE lies to us, reporting Windows 95 numbers and MS-DOS 5.0 */ - if (dos_version == 0x500) { - uint16_t x = 0; - - /* Sorry Microsoft, but you make it hard for us to detect and we have to break your OS to find the info we need */ - __asm { - mov ax,0x3306 - mov bx,0 - int 21h - jc err1 - mov x,bx -err1: - } - - if (x != 0 && x != 0x005) { /* Once pushed to reveal the true DOS version, NTVDM.EXE responds with v5.50 */ - dos_version = (x >> 8) | (x << 8); - dos_version_method = "INT 21h AX=3306h/NTVDM.EXE"; - } - } -# else -/* =================== Windows 32-bit ================== */ - DWORD raw; - /* GetVersion() 32-bit doesn't return the DOS version at all. The upper WORD has build number instead. */ - /* Instead, use GetVersionEx() to detect system. If system is Windows 3.1 or 9x/ME we might be able - * to get away with abusing the DPMI server deep within Windows to get what we want. Else, if it's - * Windows NT, we simply assume v5.50 */ - - /* assume v5.0 */ - dos_version = 0x500; - dos_version_method = "Guessing"; - - /* use the Win32 version of GetVersion() to determine what OS we're under */ - raw = GetVersion(); - if (raw & 0x80000000UL) { /* Windows 9x/ME */ - /* Start by guessing the version number based on which version of Windows we're under */ - unsigned char major = raw & 0xFF,minor = (raw >> 8) & 0xFF,ok=0; - - dos_version_method = "Guessing by Windows version"; - if (major < 4) { /* Windows 3.1 Win32s */ - dos_version = 0x616; /* Assume MS-DOS 6.22, though it could be 6.20 or even 6.00 */ - } - else if (major == 4) { /* Windows 95/98/ME */ - if (minor >= 90) - dos_version = 0x800; /* Windows ME (8.00) */ - else if (minor >= 10) - dos_version = 0x70A; /* Windows 98 (7.10) */ - else - dos_version = 0x700; /* Windows 95 */ - } - - /* Try: Windows 9x/ME QT_Thunk hack to call down into the Win16 layer's version of GetVersion() */ - if (!ok && major == 4 && Win9xQT_ThunkInit()) { - DWORD fptr,raw=0; - - fptr = GetProcAddress16(win9x_kernel_win16,"GETVERSION"); - if (fptr != 0) { - dos_version_method = "Read from Win16 GetVersion() [32->16 QT_Thunk]"; - - { - __asm { - mov edx,fptr - mov eax,dword ptr [QT_Thunk] - - ; QT_Thunk needs 0x40 byte of data storage at [EBP] - ; give it some, right here on the stack - push ebp - mov ebp,esp - sub esp,0x40 - - call eax ; <- QT_Thunk - - ; release stack storage - mov esp,ebp - pop ebp - - ; take Win16 response in DX:AX translate to EAX - shl edx,16 - and eax,0xFFFF - or eax,edx - mov raw,eax - } - } - - if (raw != 0) { - dos_version = (((raw >> 24UL) & 0xFFUL) << 8UL) | (((raw >> 16UL) & 0xFFUL) << 0UL); - ok = 1; - } - } - } - /* Tried: Windows 3.1 with Win32s. Microsoft Win32 documentation gleefully calls Dos3Call "obsolete", - * yet inspection of the Win32s DLLs shows that W32SKRNL.DLL has a _Dos3Call@0 symbol in it - * that acts just like the Win16 version, calling down into DOS, and most of the Win32s DLLs - * rely on it quite heavily to implement Win32 functions (the GetSystemTime function for example - * using it to call INT 21h AH=2Ah). - * - * Some old MSDN documentation I have has a list of INT 21h calls and corresponding Win32 - * functions to use. Again of course, they skip right over "Get MS-DOS version", no help there. - * - * Anyway, calling this function with AX=0x3306 or AH=0x30 yields no results. Apparently, Microsoft - * implemented passing through file I/O, date/time, and code page conversions, yet never considered - * people might use it for something like... asking DOS it's version number. Attempting to make - * these calls yields zero in AX and BX, or for AX=3306, a false return number that would imply - * MS-DOS v1.0 (EAX=1). So, _Dos3Call@0 is not an option. - * - * But then that means we have absolutely no way to determine the DOS kernel version (short of - * poking our nose into segments and memory locations we have no business being in!). We can't - * use _Dos3Call@0, we can't use GetVersion() because the Win32 GetVersion() doesn't return - * the DOS version, and we can't use Win95 style thunks because Win32s doesn't have a publicly - * available and documented way to thunk down into Win16. We have absolutely jack shit to go by. - * - * Hey, Microsoft... When you released Win32s in 1993, did you ever stop to consider someone - * might want to do something as simple as query the DOS version? Why couldn't you guys have - * done something straightforward like a "GetDOSVersion()" API function that works under - * Windows 9x/ME and returns an error under NT? I know it's silly of me to ask this in 2012 - * when Windows 8 is around the corner and Win32s are long dead, but often it seems like you - * guys really don't stop to think about things like that and you make really stupid mistakes - * with your APIs. */ - } - else { - dos_version = 0x532; /* Windows NT v5.50 */ - } -# endif -# elif TARGET_MSDOS == 16 -/* =================== Windows 16-bit ================== */ - DWORD raw = GetVersion(); /* NTS: The Win16 version does not tell us if we're running under Windows NT */ - - dos_version_method = "GetVersion"; - dos_version = (((raw >> 24UL) & 0xFFUL) << 8UL) | (((raw >> 16UL) & 0xFFUL) << 0UL); - - /* Windows NT/2000/XP NTVDM.EXE lies to us, reporting Windows 95 numbers and MS-DOS 5.0 */ - if (dos_version == 0x500) { - uint16_t x = 0; - - /* Sorry Microsoft, but you make it hard for us to detect and we have to break your OS to find the info we need */ - __asm { - mov ax,0x3306 - mov bx,0 - int 21h - jc err1 - mov x,bx -err1: - } - - if (x != 0 && x != 0x005) { /* Once pushed to reveal the true DOS version, NTVDM.EXE responds with v5.50 */ - dos_version = (x >> 8) | (x << 8); - dos_version_method = "INT 21h AX=3306h/NTVDM.EXE"; - } - } - - /* TODO: DOS "flavor" detection */ - /* TODO: If FreeDOS, get the kernel version and allocate a selector to point at FreeDOS's revision string */ -# else -# error dunno -# endif -#elif defined(TARGET_OS2) -/* =================== OS/2 ==================== */ - dos_version = (10 << 8) | 0; - dos_version_method = "Blunt guess"; - -# if TARGET_MSDOS == 32 - { - ULONG major=0,minor=0,rev=0; - DosQuerySysInfo(QSV_VERSION_MAJOR,QSV_VERSION_MAJOR,&major,sizeof(major)); - DosQuerySysInfo(QSV_VERSION_MINOR,QSV_VERSION_MINOR,&minor,sizeof(minor)); - DosQuerySysInfo(QSV_VERSION_REVISION,QSV_VERSION_REVISION,&rev,sizeof(rev)); - if (major != 0) { - dos_version_method = "DosQuerySysInfo (OS/2)"; - dos_version = (major << 8) | minor; - /* TODO: store the revision value too somewhere! */ - } - } -# elif TARGET_MSDOS == 16 - { - USHORT x=0; - DosGetVersion(&x); - if (x != 0) { - dos_version_method = "DosGetVersion (OS/2)"; - dos_version = x; - } - } -# else -# error dunno -# endif -#else -/* =================== MS-DOS ================== */ - union REGS regs; - - regs.w.ax = 0x3000; -# if TARGET_MSDOS == 32 - int386(0x21,®s,®s); -# else - int86(0x21,®s,®s); -# endif - dos_version = (regs.h.al << 8) | regs.h.ah; - dos_version_method = "INT 21h AH=30h"; - - if (dos_version >= 0x500 && regs.h.bh == 0xFD) { - dos_flavor = DOS_FLAVOR_FREEDOS; - freedos_kernel_version = (((uint32_t)regs.h.ch) << 16UL) | - (((uint32_t)regs.h.cl) << 8UL) | - ((uint32_t)regs.h.bl); - - /* now retrieve the FreeDOS kernel string */ - /* FIXME: Does this syscall have a way to return an error or indicate that it didn't return a string? */ - regs.w.ax = 0x33FF; -# if TARGET_MSDOS == 32 - int386(0x21,®s,®s); -# else - int86(0x21,®s,®s); -# endif - -# if TARGET_MSDOS == 32 - freedos_kernel_version_str = (unsigned char*)(((uint32_t)regs.w.dx << 4UL) + (uint32_t)regs.w.ax); -# else - freedos_kernel_version_str = MK_FP(regs.w.dx,regs.w.ax); -# endif - } - else if (dos_version >= 0x200 && regs.h.bh == 0xFF) - dos_flavor = DOS_FLAVOR_MSDOS; - - /* but, SETVER can arrange for DOS to lie to us. so get the real version via - * undocumented subfunctions (DOS 5.0+ or later, apparently) */ - regs.w.ax = 0x3306; /* AH=0x33 AL=0x06 */ - regs.w.bx = 0; /* in case early DOS versions fail to set CF set BX to zero */ -# if TARGET_MSDOS == 32 - int386(0x21,®s,®s); -# else - int86(0x21,®s,®s); -# endif - if ((regs.w.cflag & 1) == 0 && regs.h.bl >= 5 && regs.h.bl <= 8) { - dos_version = (regs.h.bl << 8) | regs.h.bh; - dos_version_method = "INT 21h AX=3306h"; - } -#endif - } -} - diff --git a/src/lib/doslib/dos/dos.h b/src/lib/doslib/dos/dos.h deleted file mode 100644 index 808bbacd..00000000 --- a/src/lib/doslib/dos/dos.h +++ /dev/null @@ -1,444 +0,0 @@ -/* dos.h - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifndef __HW_DOS_DOS_H -#define __HW_DOS_DOS_H - -#include "src/lib/doslib/cpu.h" -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* NTVDM.EXE DOSNTAST.VDD call support */ -#include -#endif - -#if defined(TARGET_OS2) -# define INCL_DOSMISC -# ifdef FAR /* <- conflict between OS/2 headers and cpu.h definition of "FAR" */ -# undef FAR -# endif -# include -#endif - -extern unsigned char FAR *dos_LOL; - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -extern int8_t dpmi_no_0301h; /* -1 = not tested 0 = avail 1 = N/A */ -#else -# define dpmi_no_0301h 0 /* FIXME: Is it possible for DOS extenders to run non-4GW non-LE executables? */ -#endif - -#define DPMI_ENTER_AUTO 0xFF - -/* DOS "Flavor" we are running under. - * I originally didn't care too much until one day some really strange - * fatal bugs popped up when running this code under FreeDOS 1.0, almost - * as if the FreeDOS kernel does something to fuck with the DOS extender's - * mind if our code attempts certain things like reading the ROM area... */ -enum { - DOS_FLAVOR_NONE=0, /* generic DOS */ - DOS_FLAVOR_MSDOS, /* Microsoft MS-DOS */ - DOS_FLAVOR_FREEDOS, /* FreeDOS */ -}; - -extern uint8_t dos_flavor; -extern uint16_t dos_version; -extern const char *dos_version_method; -extern uint32_t freedos_kernel_version; -#if TARGET_MSDOS == 32 -extern char *freedos_kernel_version_str; -#else -extern char far *freedos_kernel_version_str; -#endif -extern unsigned char vcpi_present; -extern unsigned char vcpi_major_version,vcpi_minor_version; - -struct dos_mcb_enum { - uint16_t segment; - uint16_t counter; - /* acquired data */ - unsigned char FAR *ptr; /* pointer to actual memory content */ - uint16_t size,psp,cur_segment; - uint8_t type; - char name[9]; -}; - -#pragma pack(push,1) -struct dpmi_realmode_call { - uint32_t edi,esi,ebp,reserved; - uint32_t ebx,edx,ecx,eax; - uint16_t flags,es,ds,fs,gs,ip,cs,sp,ss; -}; -#pragma pack(pop) - -#ifndef TARGET_OS2 -# if TARGET_MSDOS == 32 -/* WARNING: This is only 100% reliable if the memory in question is below the 1MB mark! - * This may happen to work for pointers above the 1MB mark because DOS4GW and DOS32a tend to - * allocate that way, but that 1:1 correspondence is not guaranteed */ -static inline uint32_t ptr2phys_low1mb(unsigned char *x) { - return (uint32_t)x; -} -# else -static inline uint32_t ptr2phys_low1mb(unsigned char far *x) { - uint32_t r = (uint32_t)FP_SEG(x) << 4UL; - return r + (uint32_t)FP_OFF(x); -} -# endif -#endif - -#if TARGET_MSDOS == 16 && !defined(TARGET_OS2) -static inline void far *normalize_realmode_far_ptr(void far *p) { - return MK_FP( - FP_SEG(p) + (FP_OFF(p) >> 4), - FP_OFF(p) & 0xF); -} -#endif - -#ifndef TARGET_OS2 -# if TARGET_MSDOS == 32 -int _dos_xread(int fd,void *buffer,int bsz); -# else -int _dos_xread(int fd,void far *buffer,int bsz); -# endif - -# if TARGET_MSDOS == 32 -int _dos_xwrite(int fd,void *buffer,int bsz); -# else -int _dos_xwrite(int fd,void far *buffer,int bsz); -# endif -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -# define dpmi_alloc_descriptor() dpmi_alloc_descriptors(1) - -void *dpmi_alloc_dos(unsigned long len,uint16_t *selector); -void dpmi_free_dos(uint16_t selector); - -void dpmi_free_descriptor(uint16_t d); -uint16_t dpmi_alloc_descriptors(uint16_t c); -unsigned int dpmi_set_segment_base(uint16_t sel,uint32_t base); -unsigned int dpmi_set_segment_limit(uint16_t sel,uint32_t limit); -unsigned int dpmi_set_segment_access(uint16_t sel,uint16_t access); -void *dpmi_phys_addr_map(uint32_t phys,uint32_t size); -void dpmi_phys_addr_free(void *base); -#endif - -#if TARGET_MSDOS == 32 -unsigned char *dos_list_of_lists(); -#else -unsigned char far *dos_list_of_lists(); -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -int dpmi_alternate_rm_call(struct dpmi_realmode_call *rc); -int dpmi_alternate_rm_call_stacko(struct dpmi_realmode_call *rc); -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -# if defined(TARGET_WINDOWS) -/* as a 32-bit Windows program: even if DPMI is present, it's useless to us because we can't call into that part of Windows */ -# define dpmi_present 0 -# endif -#endif -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS)) -/* as a 16-bit program (DOS or Windows), DPMI might be present. Note that DPMI can be present even under NTVDM.EXE under Windows NT, - * because NTVDM.EXE will emulate some DPMI functions. */ -extern unsigned char dpmi_present; -extern uint16_t dpmi_flags; -extern unsigned char dpmi_init; -extern uint32_t dpmi_entry_point; /* NTS: This is the real-mode address, even for 32-bit builds */ -extern unsigned char dpmi_processor_type; -extern uint16_t dpmi_version; -extern uint16_t dpmi_private_data_length_paragraphs; -extern uint16_t dpmi_private_data_segment; -extern unsigned char dpmi_entered; /* 0=not yet entered, 16=entered as 16bit, 32=entered as 32bit */ -extern uint64_t dpmi_rm_entry; -extern uint32_t dpmi_pm_entry; -extern uint16_t dpmi_pm_cs,dpmi_pm_ds,dpmi_pm_es,dpmi_pm_ss; - -void __cdecl dpmi_enter_core(); /* Watcom's inline assembler is too limiting to carry out the DPMI entry and switch back */ -#endif - -#if TARGET_MSDOS == 16 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -int dpmi_private_alloc(); -int dpmi_enter(unsigned char mode); -#endif - -void probe_dos(); -void probe_dpmi(); -int probe_vcpi(); - -uint16_t dos_mcb_first_segment(); -int mcb_name_is_junk(char *s/*8 char*/); -int dos_mcb_next(struct dos_mcb_enum *e); -int dos_mcb_first(struct dos_mcb_enum *e); -void mcb_filter_name(struct dos_mcb_enum *e); -unsigned char FAR *dos_mcb_get_psp(struct dos_mcb_enum *e); - -struct dos_psp_cooked { - unsigned char FAR *raw; - uint16_t memsize,callpsp,env; - char cmd[130]; -}; - -int dos_parse_psp(uint16_t seg,struct dos_psp_cooked *e); - -struct dos_device_enum { - unsigned char FAR *raw,FAR *next; - uint16_t ns,no,attr,entry,intent,count; - char name[9]; -}; - -int dos_device_first(struct dos_device_enum *e); -int dos_device_next(struct dos_device_enum *e); - -#if TARGET_MSDOS == 16 && !defined(TARGET_OS2) -uint32_t dos_linear_to_phys_vcpi(uint32_t pn); -#endif - -#if TARGET_MSDOS == 32 -extern struct dos_linear_to_phys_info dos_ltp_info; -extern unsigned char dos_ltp_info_init; - -int dos_ltp_probe(); - -/* NTS: The return value is 64-bit so that in scenarios where we hack DPMI to support PSE and PAE modes, - * the function will still return the physical address associated with the page even when it's above - * the 4GB boundary. But as a 32-bit DOS program, the linear addresses will never exceed 32-bit. */ -uint64_t dos_linear_to_phys(uint32_t linear); - -int dpmi_linear_lock(uint32_t lin,uint32_t size); -int dpmi_linear_unlock(uint32_t lin,uint32_t size); -void *dpmi_linear_alloc(uint32_t try_lin,uint32_t size,uint32_t flags,uint32_t *handle); -int dpmi_linear_free(uint32_t handle); - -#define DOS_LTP_FAILED 0xFFFFFFFFFFFFFFFFULL - -struct dos_linear_to_phys_info { - unsigned char paging:1; /* paging is enabled, therefore mapping will occur. if not set, then linear == physical memory addresses */ - unsigned char dos_remap:1; /* if set, the lower 1MB region (DOS conventional memory) is remapped. if clear, we can assume 1:1 mapping below 1MB */ - unsigned char should_lock_pages:1; /* if set, the program should call DPMI functions to lock pages before attempting to get physical memory address */ - unsigned char cant_xlate:1; /* if set, resources to determine physical memory addresses are not available (such as: running in a Windows DOS Box). however dos_remap=0 means we can assume 1:1 mapping below 1MB */ - unsigned char using_pae:1; /* if set, the DOS extender or DPMI host has PAE/PSE extensions enabled. This changes how page tables are parsed, and can prevent us from mapping */ - unsigned char dma_dos_xlate:1; /* usually set if dos_remap=1 to say the DOS extender or environment translates DMA addresses (i.e. Windows DOS Box), but we can't actually know the physical memory address. We can do DMA from DOS memory */ - unsigned char vcpi_xlate:1; /* use VCPI to translate linear -> phys */ - unsigned char reserved:1; - uint32_t cr0; - uint32_t cr3; /* last known copy of the CR3 (page table base) register */ - uint32_t cr4; /* last known copy of the CR4 register */ -}; -#endif - -#define BIOS_KS_ALT 0x08 -#define BIOS_KT_CTRL 0x04 - -static inline unsigned char read_bios_keystate() { /* from 0x40:0x17 */ -#if TARGET_MSDOS == 32 - return *((unsigned char*)(0x400 + 0x17)); -#else - return *((unsigned char far*)MK_FP(0x40,0x17)); -#endif -} - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 -void far *win16_getexhandler(unsigned char n); -int win16_setexhandler(unsigned char n,void far *x); -void far *win16_getvect(unsigned char n); -int win16_setvect(unsigned char n,void far *x); -#endif - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 -typedef struct Win32OrdinalLookupInfo { - DWORD entries,base,base_addr; - DWORD* table; -} Win32OrdinalLookupInfo; - -DWORD *Win32GetExportOrdinalTable(HMODULE mod,DWORD *entries,DWORD *base,DWORD *base_addr); -void *Win32GetOrdinalAddress(Win32OrdinalLookupInfo *nfo,unsigned int ord); -int Win32GetOrdinalLookupInfo(HMODULE mod,Win32OrdinalLookupInfo *info); -#endif - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 -extern DWORD genthunk32w_ntdll; -extern DWORD genthunk32w_kernel32; -extern DWORD genthunk32w_kernel32_GetVersion; -extern DWORD genthunk32w_kernel32_GetVersionEx; -extern DWORD genthunk32w_kernel32_GetLastError; -extern BOOL __GenThunksExist; -extern BOOL __GenThunksChecked; -extern DWORD (PASCAL FAR *__LoadLibraryEx32W)(LPCSTR lpName,DWORD a,DWORD b); -extern BOOL (PASCAL FAR *__FreeLibrary32W)(DWORD hinst); -extern DWORD (PASCAL FAR *__GetProcAddress32W)(DWORD hinst,LPCSTR name); -extern DWORD (PASCAL FAR *__GetVDMPointer32W)(LPVOID ptr,UINT mask); -extern DWORD (_cdecl _far *__CallProcEx32W)(DWORD params,DWORD convertMask,DWORD procaddr32,...); - -/* NOTE: You call it as if it were declared CallProc32W(..., DWORD hinst,DWORD convertMask,DWORD procaddr32); Ick */ -extern DWORD (PASCAL FAR *__CallProc32W)(DWORD hinst,DWORD convertMask,DWORD procaddr32,...); - -/* it would be nice if Open Watcom defined these constants for Win16 */ -#define CPEX_DEST_STDCALL 0x00000000UL -#define CPEX_DEST_CDECL 0x80000000UL - -int genthunk32_init(); -void genthunk32_free(); -#endif - -#if TARGET_MSDOS == 16 || !defined(TARGET_WINDOWS) -#pragma pack(push,4) -/* OpenWatcom does not define the OSVERSIONINFO struct for Win16 */ -typedef struct OSVERSIONINFO { - uint32_t dwOSVersionInfoSize; - uint32_t dwMajorVersion; - uint32_t dwMinorVersion; - uint32_t dwBuildNumber; - uint32_t dwPlatformId; - char szCSDVersion[128]; -} OSVERSIONINFO; - -#define MAXPNAMELEN 32 - -#define WAVECAPS_PITCH 0x0001 -#define WAVECAPS_PLAYBACKRATE 0x0002 -#define WAVECAPS_VOLUME 0x0004 -#define WAVECAPS_LRVOLUME 0x0008 -#define WAVECAPS_SYNC 0x0010 -#define WAVECAPS_SAMPLEACCURATE 0x0020 - -typedef struct WAVEOUTCAPS { - uint16_t wMid; - uint16_t wPid; - uint32_t vDriverVersion; - char szPname[MAXPNAMELEN]; - uint32_t dwFormats; - uint16_t wChannels; - uint16_t wReserved1; - uint32_t dwSupport; -} WAVEOUTCAPS; -#pragma pack(pop) -#endif - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -void far *dpmi_getexhandler(unsigned char n); -int dpmi_setexhandler(unsigned char n,void far *x); -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* TODO: This should be moved into the hw/DOS library */ -extern unsigned char nmi_32_hooked; -extern int nmi_32_refcount; -extern void (interrupt *nmi_32_old_vec)(); - -void do_nmi_32_unhook(); -void do_nmi_32_hook(); -#endif - -#if defined(TARGET_MSDOS) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -enum { - DOS_CLOSE_AWARENESS_NOT_ACK=0, - DOS_CLOSE_AWARENESS_ACKED=1 -}; - -void dos_vm_yield(); -void dos_close_awareness_ack(); -int dos_close_awareness_query(); -void dos_close_awareness_cancel(); -int dos_close_awareness_available(); -int dos_close_awareness_enable(unsigned char en); -#endif - -/* unlike DOSBox, VirtualBox's ROM BIOS contains it's version number, which we copy down here */ -extern char virtualbox_version_str[64]; - -int detect_virtualbox_emu(); - -#if TARGET_MSDOS == 16 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -int __cdecl dpmi_lin2fmemcpy_32(unsigned char far *dst,uint32_t lsrc,uint32_t sz); -int __cdecl dpmi_lin2fmemcpy_16(unsigned char far *dst,uint32_t lsrc,uint32_t sz); -int dpmi_lin2fmemcpy(unsigned char far *dst,uint32_t lsrc,uint32_t sz); -int dpmi_lin2fmemcpy_init(); -#endif - -struct lib_dos_options { - uint8_t dont_load_dosntast:1; /* do not automatically load DOSNTAST, but use it if loaded. */ - /* if not loaded and the program wants it later on, it should - * call ntvdm_dosntast_load_vdd(); */ - uint8_t dont_use_dosntast:1; /* do not use DOSNTAST, even if loaded */ - uint8_t __reserved__:6; -}; - -extern struct lib_dos_options lib_dos_option; - -# define DOSNTAST_HANDLE_UNASSIGNED 0xFFFFU - -# define DOSNTAST_INIT_REPORT_HANDLE 0xD0500000 -# define DOSNTAST_INIT_REPORT_HANDLE_C 0xD0500000ULL -/* in: EBX = DOSNTAST_INIT_REPORT_HANDLE - * ECX = NTVDM handle - * out: EBX = 0x55AA55AA - * ECX = flat memory address where signature is stored (must be in BIOS data area) */ - -# define DOSNTAST_GETVERSIONEX 0xD0500001 -# define DOSNTAST_GETVERSIONEX_C 0xD0500001ULL -/* in: EBX = - * ECX = protected mode call (1) or real-mode call (0) - * DS:ESI = OSVERSIONINFO struct - * out: EBX = result - * DS:ESI = filled in with OS struct */ - -# define DOSNTAST_GET_TICK_COUNT 0xD0500002 -# define DOSNTAST_GET_TICK_COUNT_C 0xD0500002ULL -/* in: EBX = - * out: EBX = tick count */ - -# define DOSNTAST_GET_IO_PORT 0xD0500003 -# define DOSNTAST_GET_IO_PORT_C 0xD0500003ULL -/* in: EBX = - * out: EBX = 0x55AA55AA - * EDX = I/O port base */ - -# define DOSNTAST_NOTIFY_UNLOAD 0xD050FFFF -# define DOSNTAST_NOTIFY_UNLOAD_C 0xD050FFFFULL -/* in: EBX = - * out: EBX = none */ - -# define DOSNTAST_FUNCTION_GENERAL 0x1000 -# define DOSNTAST_FUN_GEN_SUB_MESSAGEBOX 0x0000 - -# define DOSNTAST_FUNCTION_WINMM 0x1001 -# define DOSNTAST_FUN_WINMM_SUB_waveOutGetNumDevs 0x0000 -# define DOSNTAST_FUN_WINMM_SUB_waveOutGetDevCaps 0x0001 -# define DOSNTAST_FUN_WINMM_SUB_waveOutOpen 0x0002 - -const char *dos_flavor_str(uint8_t f); - -/* Windows NT-friendly version of Win386 MapAliasToFlat. - * The library version is naive and assumes Windows 3.x/9x/ME behavior. - * If you need to convert pointers NOT given by Win386's AllocAlias() functions - * (such as 16:16 pointers given by Window messages) and need the code to gracefully - * handle itself under Windows NT, use this function not MapAliasToFlat() */ -#if TARGET_MSDOS == 32 && defined(WIN386) -void far *win386_alt_winnt_MapAliasToFlat(DWORD farptr); -void far *win386_help_MapAliasToFlat(DWORD farptr); -#endif - -#if (TARGET_MSDOS == 16 || TARGET_MSDOS == 32) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -extern unsigned short smartdrv_version; -extern int smartdrv_fd; - -int smartdrv_close(); -int smartdrv_flush(); -int smartdrv_detect(); -#endif - -uint32_t dos_linear_to_phys_vcpi(uint32_t pn); - -#endif /* __HW_DOS_DOS_H */ - diff --git a/src/lib/doslib/dos/dos386f/dosntast.vdd b/src/lib/doslib/dos/dos386f/dosntast.vdd deleted file mode 100644 index 3b8bad5eedd58e788e1c0645952fa65af742b980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 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

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP 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

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP 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

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP z7hU};c!R5dk#m>O;aU)?Bq)VcdJ4IlLl9*2Sh9+MjFK$xf+ddjbZA0DlU2YfIY&7Gn%{w zF6w^2^XCpXwveIyLYG4vi*roUtr7AV{+Yt-J1d;TE;Jb(hp50&J3c!3;{8B&V3(zf zkiQ)-BXzi7oWD)1d4+Q1Hx2wzHtC}D7^A*u|*p&TrwB7`qI zn(2zqa~oFq=jYU~R3u+;Ui3svuWQ~qGN(;xobUT4WR{^V3nd;A zqcC-02Rgs66LnP!QHNu=8S`M*gnUN=CtVh4Z>#& z+*kbk7@%}COvv`Xshs$Q>4Tl)>+>D;Z@02NpDk%@^mpi$Hf z%V%LYQ&F3``ir&h$6&Ht{dTSUPzVLGv~D^R=IYPT*4~MMqMi29(b=+R)k7a5fJ__0 zbgo2@+y`_t$hrDA@Pez~$=AC2H)(5WKI!T&)YekdQ4w{|5`k^#d0^|`5f-D|UbPS< zoDy#v!kFo3Z?*~;ZxP1r26f%(t+0vO+QSrI9zh$bt0US}DYIp?X9$e?TslRyx)g12 zpW?c2M3KE-8?U7zR6>-v;A;11z(lpXMJ1r_DlzwJZ>ydkEzc>tzd%KLTXBl=Qv?75 z(e6_Sy872?YjcpZ`!Hc(wABV^fI#;WA_>{5Alvy@L6u0VwXYrQP9z41-W&w9uO96F z8J=|qyG?jpdas*ih)fbHe%#PH&Fn5=#VED4w<9n#N#8vm5bc9xo~c{%sHK;b~NbG(rrL{HinZrl9F{#2BNFKy83okf2Fo=2Ns*|ZEB9} zkebq64%OvAy9)hc#?}11=_mX2C9;dkRXZ6HPRQC(Hu-{b$;zm1$ct^9=c2vw^3c5K@A7$0{wU9 zvi4Q*aZKH(f)HyG=Ll*J{w6Uy!edtm%c035jRO%+#7OF4N)m;RL@^G+N0-vpjzXY& zBZ^}hc?IRW`tR1(l@J3LF^2SI`6HWm*r-$9GL#kV19UDG{jhqBtG_^7I}%dqrqh+$ z2X13xUhACQo*fPLsP$~xx-bL-I^B?dwSFWB9wiA5_VT;5bzh(e;t@K1g+-eeQ2{)uI1E`Xz5lk}uJ8)I6KE6l>-U z>=6C};>>lC@u+nH7v1V0Bu59U1Vky5?+se!(hP#!!9q9@khcbXUem#0@#n>RBLueh zn0&1&`ufezKItY5Hf$f-XpSc`*u>0LcW;3%2`ujGLHRGE8L517P@sH8H(6$Rt5N72 zWCYu^frYkRwF)O-B0#U*rULWaU<{;}_3NW{EDGOJg40S^A?ywox*r;k9I^D!x0 zEX@ZE?5LlVmQdhzXyC0_oz#+IBf=*NU(sm&o$d6K(ns)a2og=aAhk{@A31zqNpApZ zYQ{q90!Us1w?Pz{gM9fMLY2zYyvmESC^PP=?Sh`c2JNCQv?#Vm$@jkpkQ zftpJXp~taWzYzeR5Zd9pxxVtgr^RT4j6pM@8E@e9PRqwig(OWrfi8;)>}+CaA5p%( zyzAy)avfMjt;D-?q@2Mk?dbCR_Yzm_p+t-lhY%d}Pe4pmPI622bTg|XRF3#w4hBlH_mg2}dp~0b1t2`o~GSWx_~Iq27;!Hetvm zL{joVl8PAyIr*L$#w~D+lANPsr5$-E6XlzZC?A@3yF4l?jG|6w&qq^fe_Ps!`%7 zpG}R$-*dv^2w#_fakOYx2`e->U?I#$?&0}lMFqcLwa5eijY7e%6vw*GUh}BN3LnDh z$uAPdiW!>Z7Ondr8pWKWs#yt&Vv6Ejaboh@+PYJKhD;JBnHOoCA;NNvaKyhT3Xy8H zd9|)4L|Cmeua3|@*bX!jPKZtzYtA6l1sbAbQw!-h*QoL@iuV0U%$T0sQng3i7Ac0pg@WN>f7i()#5XbW>#bzIdbhjkpck&Z~R&JtXs zk^gi_J{>BJLJxCW^LD_T@DXmSodteDDbYxQ#}xIfLFpcf6S5Z+IPUaW`N<-<(Rp!q z-$*)Mr*cNZQ>}S(=??Vih}YSJtPfeI5P3Wk^Fj&(gWS@PLS}oevybRv1LQ`Ds&|M= za5NM%I}3-OUKE?J$1fa?fBW_LU{~rum6BU|3`yj;E3D z55_-j3#AmrAVxsS`GfhLV*`YoH_HVvr5Z-&LzxWc`w%>^w*v;q1yG2-k9$<{AN1HP)ntve*7f&6(t|( zz7oRgI-m*Jn@9Pzts6zdnoM)8PV?Tp|snx1}tIV3mOyVEkgfb@&X4q+bj7| z4aT9YgtV0?N15iD5FMT!a%&IG1MN=GZV$C1q|c*J2SP5i3dT2bzrpo}Dq@aBI)pzZ z-k-vnBf?&at$uFrVepMDoMxt+&XcUN3>o#L@zH&5I{brYXm0MwGbn@;@cJ8stp-Ev z(Mz#HNW+fXU3h;(fv#ytLqQ*9H>CM<>$Cl}&CaiB%`;tg2D(5F@7o-4UkP)n;4~a1 z{gD))W2N`f$u{NebZJ*0N_fE^H7{P}P+}KDJFCbtu?BC`e5FdOSNbl|!ANg*;PBpT zc6d);?X0ZaP{p&;YDmE$l;F!QL3y)Rh8ou_gvvg5m;@RuNq(~G=3yT+M|hJ}m`8=r zpu(9#xgj(5pn1G@2ULO+JH%G1{y#wiH2{Nq4DFt+8)E!pLmbX)ZD$8O#uV^VayDKpZJ@gRfV?uUZn19tR%@XE!3Bj}S zLMK!JyG=Htv(NX05J^S(p28#rr?RPjWFJ~ZwI^+~p$~5r+$<>F%@(t=YN9x~a|dSW zC#zM$Ny9Zk8S2+!%A~9wAsYeOgY6NNSQidCngojMRYACp_Z~-X)M&KZ%A?3@PBmM! z5<6YegJ?&jeOYEJrB~44dQdN+cVS*Y4`YMWJ6MyrC6!ra*w_JL?!Kg|Wt-?Xitxz>U+{u{`4q`I}YPXvv+jPpuI=!q`pvQw~J8f_3F%_6p=Gr!$WQt zwtuU_`VwdPr-Sjpni>APj~sYE;R1W{1+}i*kAeb=;DIdztOr^D&6zxwi#-^dBQ2W~f0; zC1$90o1gdF+f5l0*z=Lj;;4!W`kcx zzzr$ZsF`!H!M7Vzre)lWPGqV29V!t*B?%cSJXAskZIY^mLVBo#LY0V`XF=1kC;S2y zU_okuLjnQXGg@iAkc(E1HnQ6+)u#*e#sr1DW z3|fN)1=&98dtYukrjx_=q|qNR?%x-Q;^js9M@q$^hE)pkYqMol{TbKWw)!m!>0!*P zpu|3Tv6`n)=mSeEi5eQZ+VbW1=v&5}*|~XHcjhk2Ud#;%TLWg8?cdXgqHFBQhY4PY zLg=i!wzd~7fejyREh)v{QiQh}Mx?az<1A?UY!)1uZNYkTX0OmCd^6)M;gE1q`Xh47 zn^s+>qiw1glR4kJfgF4oqbGThBzs+w&&hK$w#28k9$08r z?ITKU5CTUFHFnRFU`tdn7b%#Y3|}h+;%HX`~I;MuALG7NDAjSk?*3h z86asT&X6%XR4}6z`zoP1Ak0QxoAl5Dd~Ly7kiTC6yFjN^_GKb*A5B0S2~AoL1Z;{y z3LO!sJZ*J3@iuHB8BVY74tF06tv_-rqP{QPecw96q-P<^?&ndsyYH&gBJDx6>5s(A zcHE@R6unB(E{f922koI$Cd$V=i3)x^1SX&gQM|YoN>&eVET6L%_#NO zJQ@?*1|SNZI2-s`&?Zn-v6OSs>za1465?%S73WjTlh1932P~|vmyZ|X zDI9>PO})W5y?BDL@4PUZLU?V6Ic=Hx_%1S@WKZip%I~^TpT6}->ER%Mcr5*V!B!mF6oHX?%>g3CK|{C9-nqGp1Ma}FZPX4 zeX=jbc#30C+G?SnwwHCVU}w<#AhPkUWGhy8Z7Sb~o-~{yAo*Y+qrj|NvfzegO{a7b zxY8WNlD*F3NG*^PT9A}O!B&@Ge7O1nvkD!4UQ+#ZZK=f>b1iKB&Uf0xH z=!NN#c==IK`Xrnt(pYB7JFe+CkX`o(28b_?8T987iD(ae52|RE=_u!zm%n zZ0Be^bQmK30dONci+Iyp!e|a;0AD0rLetj0j38Yu8iFHe%59mgt<6P|-C5LwuVDXp zB?VH9&M>yo*IkGxJBrY~2q7#Ow~lvTG2A}}PC#vK3_#rpxHXcuU%K#*;Hb-JH>4{p zo1FAfm+o=Eu@v%OcazV+{Hx9#^ima7A1Cs(&%UAf3LdW!>D~RX3k;gx{Uw3{M{j^t zirqiJc%Vjf{PEIz1JJ+3DgzA-O;+4! zn~hAJbQpsdy+DYmx#ZNcek=1qonVGUgP=_s`579km6QaCr!k$?2w!~Hql!t8##60m z!~Pw1kd6fiYiqZn9Gm3*6f__SP$+~)_B;Mq#g(=Y8Z>qJM1P4tau519Mn4oPjXVhd zAo5Dr(Dk9Av1oGWLES<~g{C;v46M_3O78>Xx>``FSQ+RC(xmU1CW?-ncVkLth20Owgy3kl!sulSGHD1T`5*=T`eJB zn#r~RTKvko^V-@{fW!&HS9Hh-M-xPakaiWvh@2Ni*+t*Wr{P!?OdF5)Go?Sbqq1+! zWENA5WD|;ON}&Vut1rQ?5KfTfOZScOsI)lhH4nxs`O?;JK2f2+f?1uXV}bRMo&whQbs|IgZijJtH24sTju1z%^LznO0*fjogsT7?Dn^f2n*cR$3_4^JBuV4DWbB99c#@>?$E@mt& zP6j7rE2ZwUC@|1FAbZqXZp-iLIJ8UAiAfKYDeZvo8e7#kQ2~Y&eFAGhY$&4bxbEeo zm9p}m8mP}e{|we&)L^TPh$&hGAM`7g7J{t3d`}P={PIb@GXopR{0urG*zhoIA-m2h zbP5k2)M73_3=?D)WUnUWr{y#0V35Ksri1k@4FaR^kwQMx!jEal4-jkVQjelF zIb~%(wq7JNOIsH(kIB%&b54Jt#3U(Z-+9PPN6Czk=qU z&RsEc`udDFk9?~*@5xe1D(rs3YakB+??T%SNqawm({%;B7LIn+91JDf5C^4dMKjPe zXd~(EGsx7=HgM;`E2Rm+@GO-9&Cw1shTf)zWxbVHkX3z(7x2m9U(G5aP=Y9Vku;`fab`Zr5iB89mxu-)?h@L?|A`6eYlZlTd-e{}SsC^b^ z*A7WabROBl_elRtMKB9L0`(49_+VkOg+Gt{*Cn7WCto3D4q`HUH(=jsz>)2{6YV2h zcDP~SZ^Qv`5z`^+xzI8kejFB^pBvve+Ed51i42ENpE1RO_)L z6RhwER(K2xPjk4pD9I#?Y~<9w*n=`W(G)$tPdC<2X#}hiFx2fm!I-h~z)#N}y1Brh?@X|?qtw3dH`BaIO zG`_WW;6rLYA~~S8!4o55BrC!vab%d|Dbk)f2RZ?jW2JS^hel8oKX+dd*^e!-9}?LQ z^jEfD?8OGu^y*vj#(QgxLDAu<@_RPvcFy8WuE}LGu^gz_B^} zFn=pQf*I++t|X%ff1dV5BYZ#?8^UJ1A-w0jB}idX!ylNH{#c=X@gmwO46n(+lBX+X zv$syqn|~K3 zkmkzRVpw=pXkU`-tyT&r?fGSDF_IR&Sg+E@Cs4p&!PN*c3n!pP2z`N43WQ_yl_ZVO zYJ)O@ldnw8Ltm+2=VgdpwB)<^=o`Ihf+fP85{HheX!hh_rY)^FjfQV!cE<`W%`^4F zGl#Dq;5-Oy0@>O-ur#crML&HoL!N0O^^dQT{$WzoBke{oc=`vODIeq2LY?@O^dO*AOYHYbH)7W)nC-3L()Pvw z7zDn|fWh+Q{RK8V!-6o{KyT>s4mw>}bGyTRANDmDu@@cG4!A|7KhQiG8^V6xNWSb8 z507~jmSaN8^+$AOL>Sz!D?M>Hz=z5kRKCB;vp9UN6!y3c#_y!>yaUct2a3DM4zOc` zN-bGY0Fgg}%s9gSfx}wFw&%BCd!BVz|1@eA|1_FR_@_}z`lpd+z(0+=82)MG#PLrf zhmn6;A-j_k-am~tyZqCB&+fD*@1OPxyVHAb{%KFMyNliFJ!StiQd$2rp4~Iqoj#M} zpY|lX(-)`w)0VP(F}tr}clz*(f7&i~FJ<=w>|V?6_3XZr-8ZrOVRr9i_xIU7x{4_D zuy7O$f5O5NyQ>+5WA}3m@-@4w7(~PFeGGDy-6I%8hx`Bh{?ACDxN@)@0}M_koVw?R zz)XN02CQ!g%naB`z*OV_4*aqK`(#Kw2&bnVX{&Kn;M$6-0oUWWp25|G>oBelarNOE zQO$ADxMFZ+xT>ZErc#bpRO2@StR|T%ExOU=t3>W>L z!Sg^Md=k&k0^zUm48xq~CS0>{#o@Bx%Eo2KwF*};u5w&8xLmjzaP7uLzyH_kw;(Hj zQC42yD>f@~7cE@KzGpM!(>9BiF3(&zC##U&lFumLP+gLPkGzzZVD~-)pKswyvT8~y z_%s~u3dFPViJCM{g-P>YTH-e*& zIb_&5ZX|^=?70<=4V;>VH>_WeqVn)Lj5Kc4b&wVK=mYS-k0dvmQizSEn=4B=4aF92 zD0Y^Y5NuJ=dXVG7zYE1D#m5Xn@Az+>~H!iL;~%Z{_K^ zV0D&m7^ovRm0N-D60vrHc5N)GDOv2~A+XGnnv9}Ks0Xxc5W2{@9tqW?hY-uMN_=mK zVJw7-72REuz5()8aLY3@GfQ&uEvBOK^4!Ha8#dfSQ~T3cM=xVv;+**)d!D>hW#TUE_FYc_7$yyg4L z`_G|qIvYc(4LpA+$M1)vHx3CCzWn){#er`(P37d8;UkrkY}}szjq8Va0o?T?Y5!YE zu{YZW@?S6afrLOH0#5}l^48E55_sbAzx?aNI)~&(KcY=fqJ8~yGCr0;@DzpogfC%O zoZ!Ly*FP!W?g0L8@I;i`wa~^c+UzBKs#zf4{mbw}`Kht^J@wR6w;FOEHXuGFy8Yhh z-~RTu6Zs=qHvlDay!qe9KWxYyHx@snYw7pU$4O&WXKW5XeE6_N<27oUq{l|jDxNwT zbi(#kTEm1#PmWrh{>xDyIqJFhkE!wbK6R}wU5)%BxAwG*eDJ{sM~-ybN1~{aoPPR5 z8^`I_WU_l6-MbdyKE*Ya?)og;Bc98^{r~E3`kvu>5r?=1S0-Hn8^PiC2|m`LiQ>2% zz?a}6d1tPxt}No$mU6ij>tHJX=l9=50y-EaG~myT>Bc%1=Go>L^IUVLdA@nEd4>5lv%_3wt~75md(6KxA21&>e`Nm3e9fF> zv09c|)>uj`>n-PQNJq7KFd>T%TXTxwq`eN|;C>Negu(fD(G=Q7TigsluH5Hgvnu<;9O%0~snVL**n@*V|Q?E%AvoGek7;ns5F<-=7is52!!8ni{J3qEO zwm#Mq`|H@h#l95#O6-Byw?X;6*bieriTx(lA3Gr~8?xi$UXFV$?tI*g_}KWI_(kz0 z@h1}BPy7_x7nY<;icFf56ql5ol$NwS$&vJH=;BjJFC=v(NlCiosN}DcuO+Kf#-v20 z=u_fStSO6AmZjX8(v|W_%5?KAv(X%9PBL4}Ht1lEInQi2FEwv8pEaK|Uo~@<5tcB^ zT^5I>+)`<&v23wCZuyJlQ_H_t&sn$3JvuiuwKDZzQ{PMdIF-Xn;|0hz-1vLrUgK-V z81&9tW9G(eL0|O7Op2Wp7Z*1_ZdKfxxUF%ualemyD(>C5({UfieGwNDuaBP=e`|bp z{IdAn@qdWlAAc%dlQ1@6VnRZKB_TZ_C!r*vEa9Pq7ZP4gIE3DLDxoXk^Mq^YnWGX- ziK`MfC%&5WZE^~F%S=m|Wf%DScZ=6@&5~ig-|DgMwVt+KvPRCGIrpx))pP6T{$}o> zx$n-sF*P>TmddTc|91wS%T1$W7R3B2=6KAwSZC~x*qFF<$osyyV{u(^W8x#@*Tg>_ z|3-Xv!tSJplIoLoByCNqNvcdLODaxUom7~VpOlxBon%W&K?}@Dnx1rXQgqS;v`JW! zD(PBcU*d(tbBUiNb|s!lJf8SgVnY61ODs zi4}>ZiFYN^tSkq7H5!|ZUB+`pM{I;C$`pmwm*K7rVvU>0<>7LNYF3?@|dLWHVI9iv``?lJPImOX=ACS)b^x21~HIU zdwPh&b(njdx#J9o-f;Ev0A@qslIq~MbY|oYxU*pD(=DUuBxJ{&Ea7N znYKNP+AxE)hRE0p87Re*#Ap?K z;AR8KIaMX)8`cIukO3>VYygD?Y#f(99P&T0|85dE?E7{XegkZmsu7g5qd0Dv@TvPg zjl!uGv()=)T{f+uPsJ%dXh93UN!ysXoo+r%PykfJ=hk1|>tCHiVI;;wg*AY)s zWuBUe7da>m29FQr6tozxUydYRh1R{qe_b=LbtiFrn9!nqsntIg%r}xL#WRTi8t}pA zF}Ia6aD0RqNdfm3700WEBifga`Io3eB**?zhY?wliTioiti;{w3<#^d+Rm7-(lqtdgNQbe?X6- ziPr+)7NBvw((f>$JgML(l_?|vLA!Jx?%J1{?NS8-t584TB;89{z8eSf-8GmmmF0^K z=1Uls4?RRyhb{~d1>!OddWypwx)W?V#{}3Fl(*f{sz#~d1oo^{p#0>Ml+1cWAlcob zOzv=wV`?M)7FBWt5*+PHzn@V+f1vUrsEU;+&wWni$+~LSzLcf5OI3cqALTb>U9DFN z=cqu!g~D@ECUC_pjkruLMF7iTj%56e6_@E0N3|~`qaSnVWMkz)-bE!Ul?V-DzQU(C`3q_h+DA10gWL+Sx~!FmkJ=4U@% zmuJ7HF2_R#WK%wbrYxHifeZt68ZPT!45w$L_NxUwsPpm_?sMw>J%H@3ha$CSNi=f9 zc$L}hWj5*2e2x>cK7lD(<%x*eeuWaNr@Tzs^4eJ73nyZmFa8@JIk z^Bq$46!E@KUM69^`ZJ&@&a4nyTDp}NpJ?cCeH3!>@jJJBX(k~|rb0a>=k8pM4s!?f zVb*8chi0(BS&qHLoI}X^I&=z3L7>-@b=>aB`r2Nm@W&HV(giycK=VMhnrMuaj7tmB zgQF#xKxQCH`c|zZ`BMMYgQ!%CQI}+)3X}$E{_MIUhZJ`oiu(?&!1xD3ZYznKbB0R4 zC*2H6w{{15v3D1hxrWNr5$d@dsRY!lFr1yviKS01duo}q3IKmR(U8IsgsJgj6h(Tj zG?n66SEVWJ*(d#DF(iUS?e1pni}cU#clM#1UbRa-NUCer*6u}FXr`TPwDtqY=qZVw z&L3INz)}z#Lf{)^HjV+PeTg-QUD_1H@cV%=Ggv7;RBA-60yRc#K58sy-yO(dFU>$r zJXwu)>F;30eL#bz$qRsjEkisZ(feSgK_y|>?pnB5G1D8%NM-?Kr+c>eO z&^%&w%?N2Mp%*q@1)(Mgl9MFd>;=fD*^dtH7owxL`)JNTn{M~_+*U~Bq*F+;dom5` znJU9>(WdfuAse?uc+cK&q2;W);RL%$K6IPHmBbSJ6_9EmSCsIvxYQ6Ks0=7aC;bLJ z%zZ$$>b3#I06s=>7!sjPc-M4PXtBAHIX)!a_e~iG8Y+AK^0Ke}k+mdwf8+r?0`M{= zl6Cg7uO00uDm-i$j?mXV0!(>aR0L)@EyA&#r=(bL09_5CQTCM3A-PdKgoAjVhY4G3 zmSq?E1tMNgrk>lY+m0r2QKBcG6Hj{sVTSIp(JVx07e3sl-eu#2NJ5r!VQ~DBrQmko zGl;{cO#f#x54!*nS|57>uoek618w2h_aejCuT~Rt7Y;V?r*C`n8Q) z&O{uLO7w1ssi!^E1$;`B+At}BZAFxl2C}1lX{cMam*fI_K0^#A_UjJvTA{;qTKXf& zZ8CwxcxvjpUT5STG$MITN2MK<7)d#O9m`GU{gF!{5Megq$vB`c9xNaQg7!<}$74Bx z2BASj@CyB=W@!&BMAL5I%StId7YT|zQZgQmQ%R~*CU8j014bk1honUu)yClELX`6? zy_pkQq-1Ei+e!+`@jrK4mja!0YE7q?2$M-){gHMQ*`!4VQ!}^($ahv!p^yMfQnO-m zDB;XF)8yOt~$+FrKb1RdCc z8n>xNa8R4U?3~M5hEoO@1KA;|wfoA$G=Fr=bY2&E9 z^dNQcN7@h)I>g8|c(!yY>yA1NQWqLg@YbDn{;U!D$4Q57rsm89#z02ln9wSmlt$db zalYdWn%q$xDYUknRVq%|XflqrZB-?AR9z4z6Kx@!%Dj%s5c@^?EKVjIp-tvWj+u_u zovs-ph7%1_v)iKZJ5!TSRV@`dkMt=zZ34?8-Gt&~eDmb5fw^&-&?)CZosv&gPos?d z6nC>K-Peo464KUTox{pj#=oI3%`%VqDxVvbP z%Vc;~*{)*MUlr7L)}TYuMU`@u7yS#p>4dva$^XLLr*KZqFZ;$H`6M*n%($t(iIKyQ z5VuP>Nqq>(VJt0u4N#K=-g+FOh}noo*B>&vix1QIm6Jn4#kgflc3CbJ}H>2cVCvR-+d6IwBl zg}VFvm^YP!Kk4U~SWvZSprl0SG-)ZpwFD0gpe$1aGVxmJ5{SVYK#>!^_oV5B`>_lo z{aC?70x~&nE3wA$$)?k8E3w9Hn{4W3RS+#BR=C?#8DN$PlTx>S%95l9F`8l6qr7Z_ zPUf&0FoCJR@6SW@aUZE-umxeS(0+m5Gg9sZUg^)6q!5(kP!lRO>4^|!3m|yWcLshi zr^|%bg%iRVdBDX;i-ozXDzcG=SZV!D$V@FY{tg-+3YIVPNAlpG#Yzdq4hRjM5b-T5 zmY4Yp$`qJ9M?ONLeI1JY7X`=Fop(l>npqw|ehWx2)`JPjwreP8@6GT{Q4s^2$pI2C z?0x&pgSoNI7oNFvBsUF{krR`_7B$>Rp_3%$722;~_yiI-Mer9wzhGqW8KxQjOB(nE z;Dzj$^F2Qq;Su($|DGSEqptsVe`H`=rF3*2PoY9_n&gkApU^^GLYfP(&_NbA$Rz2r z&<4qdGQ;AJoDRhi!;P4c)g9E%_DOb7&8OHKF_H;g2-p&d9^U=c+J0(14~|9IH5#d|~6$Vvc$M#ERMYTal3h z)WQ&Ds9QKB=hgwJkvY;nScc9i&L;}Pzy$;jCvK5)!_W*g+>5!$;Orj4Sx_F!3bOKJ zW9DS$<#9_(OZ4k1s`)DCT7KPz3Vji;H*PWpe)_dV&gzn4eUZL+UCp{`O22EfeoIN! z2EC(vLlM8O;%AP8gS6ptla8!KLXdtB}3Cv+C|=zcd@UsO>XwzjCEVgs*VyP*R7I7@)|Q|nYx zv7u^xQMrCYWl0q%{aBqcuB%g3Nl`JeG*nu1!l>Z&CF?g-Z3a8e@?t$Pc2|l1CvsGw zcUBaaR6(>Guj2(`8kFx(t6qhEL(P9qYu>PWg`usg`J%P=4CZBRRDs%5@Fi70(o6-{ z5z5N74_AT;G(8U$sA9TQTr!|ZKedD(uXa_51N>F21&e_e;IgvwhOv;9nL8|=2A0a9 zmC%6yvQ}ng6b_@6l{qvX#$}}sul|oSKhVvt6aJ5MvaIx>1?suka@G=b2resacv|ML zwvn~5vTDQKRYmLd5ZOT64k+1>9!UN2C#&zeijqx5Yk7T5QMt3^Iu#yfB8HlWtb*aq zQot0j*txz^KfRzJC9A+bbCX;m>4XK+18%gr;UgTd81=j``Xj%t`x zA60wWX~0ktE%ep-`3XX+`>Zy%;o;*LU|J+q{SpNV{+#ABt}8}9G~1T$JLKA;*yQ|1 z_=+O`A(tQ?Ex`P1`#JJ$h))}$=&_I!*Q;FCWQ@2RuQfGqKR~IN8{GysQ(Gv(6;dPy zEtK$)bUOxfnwP%YrZRA%!nzB4#9DVFCT3O-3x1cfT(LR$k#FHq7=gnT!vkof2Uf@lch{khCoBSHGftB@VY)l3kHAP@gc z#(9MxwAaz}d>~f`K@I?dLRC~~PSfH5hmTOwp9y(mpwQg}`4@t`3av%MJc<_Nq&k9> z1qkjWNHrk;E3&3)YioZ45>4MSE?z}zqhpAFW%Z2)*-NjJ3r$=11X7w}84{c|N~EwY zK;eSW)6zfX(q$~d$24^_#*uy&%Z&dzL#!x%RJQwdmHS%Gwp!*A7^dRd2i^mN)?Y(q ztEX78NQLG;4@hs;RHe37q>3CxYjh`qKkWni2=`k;s-^l^|Ct4!r65F$tki~0#~{h> z5y((eX#Ewy&fA)Hp`P6rQ3q=%!y~abMas>L&Y?m|)1T!wUKu5Qa|M2b%@Le)e$!(N zXgb|Z&fum8A&%~+DU=F$_hS^g2QAtC2!(EC1h`b@XH$yeTStf>rR{Q;_?!FP) z2k(T6_ziVNqkN^t1ZPGo?!U}lT63%46o0&h_J zBcB69@GofVTtL8_ojKKl{-M>kd3&>`D*2I34JgC+yC!ON->;k8^w`<-06prOYVqj) zC5%{89fj_td3^SChp2Aaj<{p{<@frXVNLavwhU$$=#)3Ri+IFR+sMoK+Cx%_D zX6ud3u21fF2-$i#t`4XnYz!dUy8DqD1PmGf;GUD+sY1?DQ?u!4F_carbhM|b>`;PY zK?$`App(BJ-kt~)E!vhs`LuGR-L@39;8uA>Y#t)Vbx=wh_`(0=KBp%aR9Q6J(!k9C z1%3tkB1X{Wh{_>`ljA>RsX>D_F zilqK3mC#b(?`|GpC8Vm)wqK@aV7=@~Q%Zk^=Cmo4zSrdW$ntt`{fSo}B7%enf~STP z+&Dmxkcc2X`G}Nz71g0csGX?N0@n8x)oVaj6kyW_>IuRJ!dpV7A;;9*R%>tpfc?x& zLmoC0vE{RpN3vO}4Cgk1(zsp++6x0r^O+pseFmhgfrh%_*<~uAE&PBk41C!ue4S8bD)!ud; zuWkUrdWG+?-gZ4dil{pTg>QFnyNy><43P(W+g~WkxZCGv2)NfBy~^T2ZCeec+_pKxiIw^!*R=xv1QJ2v z{qIl!yc`@1hnM?^v&!#qR_T*i#kI9F$udx_wGZhLyuRk2$eotvw3dgu6|?Ht*-v$jnnQ~pbn!wC->(@#SxpZK<)cToB&U{FhR_}Dio;e zj&4o1wP$FcrG8h^9OnXx1S!puDJ2r6n0ppzhEdY^K7w8@P^mAS5q_!mH4P=J0omEM z2Au~MxWBY|rmH_s>)uTK_2)Wuu1$&rXP9e~GEQ4dI!n{-01LiDo=WA$2w;?I>*%

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP 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

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP 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 - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(TARGET_MSDOS) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* Windows 9x/NT Close-awareness */ -void dos_close_awareness_cancel() { - __asm { - .386p - mov ax,0x168F - mov dx,0x0300 - int 0x2F - } -} - -void dos_close_awareness_ack() { - __asm { - .386p - mov ax,0x168F - mov dx,0x0200 - int 0x2F - } -} - -int dos_close_awareness_enable(unsigned char en) { - uint16_t r=0; - - en = (en != 0) ? 1 : 0; - - __asm { - .386p - mov ax,0x168F - xor dx,dx - mov dl,en - int 0x2F - mov r,ax - } - - return (int)r; -} - -int dos_close_awareness_query() { - uint16_t r=0; - - __asm { - .386p - mov ax,0x168F - mov dx,0x0100 - int 0x2F - mov r,ax - } - - if (r == 0x168F) - return -1; - - return (int)r; -} - -int dos_close_awareness_available() { - /* "close-awareness" is provided by Windows */ - return (windows_mode == WINDOWS_ENHANCED || windows_mode == WINDOWS_NT); -} - -void dos_vm_yield() { - __asm { - mov ax,0x1680 /* RELEASE VM TIME SLICE */ - xor bx,bx /* THIS VM */ - int 0x2F - } -} -#endif - diff --git a/src/lib/doslib/dos/dos_lol.c b/src/lib/doslib/dos/dos_lol.c deleted file mode 100644 index 98f46e57..00000000 --- a/src/lib/doslib/dos/dos_lol.c +++ /dev/null @@ -1,76 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* DOS "list of lists" pointer */ -unsigned char FAR *dos_LOL=NULL; - -/* MS-DOS "list of lists" secret call */ -#if TARGET_MSDOS == 32 -# ifdef WIN386 -unsigned char *dos_list_of_lists() { - return NULL;/*not implemented*/ -} -# else -static void dos_realmode_call(struct dpmi_realmode_call *rc) { - __asm { - mov ax,0x0300 - mov bx,0x0021 - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } -} - -unsigned char *dos_list_of_lists() { - struct dpmi_realmode_call rc={0}; - - rc.eax = 0x5200; - dos_realmode_call(&rc); - if (rc.flags & 1) return NULL; /* CF */ - return (dos_LOL = ((unsigned char*)((rc.es << 4) + (rc.ebx & 0xFFFFUL)))); -} -# endif -#else -unsigned char far *dos_list_of_lists() { - unsigned int s=0,o=0; - - __asm { - mov ah,0x52 - int 21h - jc notwork - mov s,es - mov o,bx -notwork: - } - - return (dos_LOL = ((unsigned char far*)MK_FP(s,o))); -} -#endif - diff --git a/src/lib/doslib/dos/dos_ltp.c b/src/lib/doslib/dos/dos_ltp.c deleted file mode 100644 index 8dd97d8a..00000000 --- a/src/lib/doslib/dos/dos_ltp.c +++ /dev/null @@ -1,303 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* TODO: Since VCPI/EMM386.EXE can affect 16-bit real mode, why not enable this API for 16-bit real mode too? */ -/* TODO: Also why not enable this function for 16-bit protected mode under Windows 3.1? */ -#if TARGET_MSDOS == 32 -struct dos_linear_to_phys_info dos_ltp_info; -unsigned char dos_ltp_info_init=0; - -/* WARNING: Caller must have called probe_dos() and detect_windows() */ -int dos_ltp_probe() { - if (!dos_ltp_info_init) { - memset(&dos_ltp_info,0,sizeof(dos_ltp_info)); - - /* part of our hackery needs to know what CPU we're running under */ - if (cpu_basic_level < 0) - cpu_probe(); - - probe_dos(); - -#if defined(TARGET_WINDOWS) - /* TODO: Careful analsys of what version and mode Windows we're running under */ - /* start with the assumption that we don't know where we are and we can't translate to physical. */ - dos_ltp_info.vcpi_xlate = 0; /* TODO: It is said Windows 3.0 has VCPI at the core. Can we detect that? Use it? */ - dos_ltp_info.paging = (windows_mode <= WINDOWS_STANDARD ? 0 : 1); /* paging is not used in REAL or STANDARD modes */ - dos_ltp_info.dos_remap = dos_ltp_info.paging; - dos_ltp_info.should_lock_pages = 1; - dos_ltp_info.cant_xlate = 1; - dos_ltp_info.using_pae = 0; /* TODO: Windows XP SP2 and later can and do use PAE. How to detect that? */ - dos_ltp_info.dma_dos_xlate = 0; - -# if TARGET_MSDOS == 32 -# else - /* TODO: Use GetWinFlags() and version info */ -# endif -#else -/* ================ MS-DOS specific =============== */ - /* we need to know if VCPI is present */ - probe_vcpi(); - - /* NTS: Microsoft Windows 3.0/3.1 Enhanced mode and Windows 95/98/ME all trap access to the control registers. - * But then they emulate the instruction in such a way that we get weird nonsense values. - * - * Windows 95/98/ME: We get CR0 = 2. Why?? - * Windows 3.0/3.1: We get CR0 = 0. - * - * So basically what Windows is telling us... is that we're 32-bit protected mode code NOT running in - * protected mode? What? */ - if (windows_mode == WINDOWS_ENHANCED) { - /* it's pointless, the VM will trap and return nonsense for control register contents */ - dos_ltp_info.cr0 = 0x80000001UL; - dos_ltp_info.cr3 = 0x00000000UL; - dos_ltp_info.cr4 = 0x00000000UL; - } - else if (windows_mode == WINDOWS_NT) { - /* Windows NTVDM will let us read CR0, but CR3 and CR4 come up blank. So what's the point then? */ - uint32_t r0=0; - - __asm { - xor eax,eax - dec eax - - mov eax,cr0 - mov r0,eax - } - dos_ltp_info.cr0 = r0 | 0x80000001UL; /* paging and protected mode are ALWAYS enabled, even if NTVDM should lie to us */ - dos_ltp_info.cr3 = 0x00000000UL; - dos_ltp_info.cr4 = 0x00000000UL; - } - else { - uint32_t r0=0,r3=0,r4=0; - __asm { - xor eax,eax - dec eax - - mov eax,cr0 - mov r0,eax - - mov eax,cr3 - mov r3,eax - - mov eax,cr4 - mov r4,eax - } - dos_ltp_info.cr0 = r0; - dos_ltp_info.cr3 = r3; - dos_ltp_info.cr4 = r4; - } - - dos_ltp_info.vcpi_xlate = vcpi_present?1:0; /* if no other methods available, try asking the VCPI server */ - dos_ltp_info.paging = (dos_ltp_info.cr0 >> 31)?1:0; /* if bit 31 of CR0 is set, the extender has paging enabled */ - dos_ltp_info.dos_remap = vcpi_present?1:0; /* most DOS extenders map 1:1 the lower 1MB, but VCPI can violate that */ - dos_ltp_info.should_lock_pages = dos_ltp_info.paging; /* it's a good assumption if paging is enabled the extender probably pages to disk and may move things around */ - dos_ltp_info.cant_xlate = dos_ltp_info.paging; /* assume we can't translate addresses yet if paging is enabled */ - dos_ltp_info.using_pae = (dos_ltp_info.cr4 & 0x20)?1:0; /* take note if PAE is enabled */ - dos_ltp_info.dma_dos_xlate = dos_ltp_info.paging; /* assume the extender translates DMA if paging is enabled */ - - if (windows_mode == WINDOWS_ENHANCED || windows_mode == WINDOWS_NT) { - dos_ltp_info.should_lock_pages = 1; /* Windows is known to page to disk (the swapfile) */ - dos_ltp_info.dma_dos_xlate = 1; /* Windows virtualizes the DMA controller */ - dos_ltp_info.cant_xlate = 1; /* Windows provides us no way to determine the physical memory address from linear */ - dos_ltp_info.dos_remap = 1; /* Windows remaps the DOS memory area. This is how it makes multiple DOS VMs possible */ - dos_ltp_info.vcpi_xlate = 0; /* Windows does not like VCPI */ - dos_ltp_info.paging = 1; /* Windows uses paging. Always */ - } - - /* this code is ill prepared for PAE modes for the time being, since PAE makes page table entries 64-bit - * wide instead of 32-bit wide. Then again, 99% of DOS out there probably couldn't handle PAE well either. */ - if (dos_ltp_info.using_pae) - dos_ltp_info.cant_xlate = 1; - - /* if NOT running under Windows, and the CR3 register shows something, then we can translate by directly peeking at the page tables */ - if (windows_mode == WINDOWS_NONE && dos_ltp_info.cr3 >= 0x1000) - dos_ltp_info.cant_xlate = 0; -#endif - - dos_ltp_info_init = 1; - } - - return 1; -} -#endif - -#if TARGET_MSDOS == 32 -/* WARNINGS: Worst case scanario this function cannot translate anything at all. - * It will return 0xFFFFFFFFUL if it cannot determine the address. - * If paging is disabled, the linear address will be returned. - * If the environment requires you to lock pages, then you must do so - * before calling this function. Failure to do so will mean erratic - * behavior when the page you were working on moves out from under you! */ - -/* "There is no way in a DPMI environment to determine the physical address corresponding to a given linear address. This is part of the design of DPMI. You must design your application accordingly." - * - * Fuck you. - * I need the damn physical address and you're not gonna stop me! */ - -/* NOTES: - * - * QEMU + Windows 95 + EMM386.EXE: - * - * I don't know if the DOS extender is doing this, or EMM386.EXE is enforcing it, but - * a dump of the first 4MB in the test program reveals our linear address space is - * randomly constructed from 16KB pages taken from all over extended memory. Some of - * them, the pages are arranged BACKWARDS. Yeah, backwards. - * - * Anyone behind DOS4/GW and DOS32a care to explain that weirdness? - * - * Also revealed, DOS4/GW follows the DPMI spec and refuses to map pages from conventional - * memory. So if DOS memory is not mapped 1:1 and the page tables are held down there we - * literally cannot read them! */ -/* NOTE: The return value is 64-bit so that in the future, if we ever run under DOS with PAE or - * PSE-36 trickery, we can still report the correct address even if above 4GB. The parameter - * supplied however remains 32-bit, because as a 32-bit DOS program there's no way any - * linear address will ever exceed 4GB. */ -uint64_t dos_linear_to_phys(uint32_t linear) { - uint32_t off,ent; - uint64_t ret = DOS_LTP_FAILED; - unsigned char lock1=0,lock2=0; - uint32_t *l1=NULL,*l2=NULL; - - if (!dos_ltp_info.paging) - return linear; - if (linear < 0x100000UL && !dos_ltp_info.dos_remap) /* if below 1MB boundary and DOS is not remapped, then no translation */ - return linear; - - /* if VCPI translation is to be used, and lower DOS memory is remapped OR the page requested is >= 1MB (or in adapter ROM/RAM), then call the VCPI server and ask */ - if (dos_ltp_info.vcpi_xlate && (dos_ltp_info.dos_remap || linear >= 0xC0000UL)) { - ent = dos_linear_to_phys_vcpi(linear>>12); - if (ent != 0xFFFFFFFFUL) return ent; - /* Most likely requests for memory >= 1MB will fail, because VCPI is only required to - * provide the system call for lower 1MB DOS conventional memory */ - } - -/* if we can't use VCPI and cannot translate, then give up. */ -/* also, this code does not yet support PAE */ - if (dos_ltp_info.using_pae || dos_ltp_info.cant_xlate) - return ret; - -/* re-read control reg because EMM386, etc. is free to change it at any time */ - { - uint32_t r3=0,r4=0; - __asm { - xor eax,eax - dec eax - - mov eax,cr3 - mov r3,eax - - mov eax,cr4 - mov r4,eax - } - dos_ltp_info.cr3 = r3; - dos_ltp_info.cr4 = r4; - } - - /* OK then, we have to translate */ - off = linear & 0xFFFUL; - linear >>= 12UL; - if (dos_ltp_info.cr3 < 0x1000) /* if the contents of CR3 are not available, then we cannot translate */ - return ret; - - /* VCPI possibility: the page table might reside below 1MB in DOS memory, and remain unmapped. */ - if (dos_ltp_info.dos_remap && dos_ltp_info.vcpi_xlate && dos_ltp_info.cr3 < 0x100000UL) { - lock1 = 0; - if (dos_linear_to_phys_vcpi(dos_ltp_info.cr3>>12) == (dos_ltp_info.cr3&0xFFFFF000UL)) /* if VCPI says it's a 1:1 mapping down there, then it's OK */ - l1 = (uint32_t*)(dos_ltp_info.cr3 & 0xFFFFF000UL); - } - /* DOS4/GW and DOS32A Goodie: the first level of the page table is in conventional memory... and the extender maps DOS 1:1 :) */ - else if (!dos_ltp_info.dos_remap && dos_ltp_info.cr3 < 0x100000UL) { - lock1 = 0; - l1 = (uint32_t*)(dos_ltp_info.cr3 & 0xFFFFF000UL); - } - else { - /* well, then we gotta map it */ - l1 = (uint32_t*)dpmi_phys_addr_map(dos_ltp_info.cr3 & 0xFFFFF000UL,4096); - if (l1 != NULL) lock1 = 1; - } - - if (l1 != NULL) { - /* level 1 lookup */ - ent = l1[linear >> 10UL]; - if (ent & 1) { /* if the page is actually present... */ - /* if the CPU supports PSE (Page Size Extensions) and has them enabled (via CR4) and the page is marked PS=1 */ - if ((cpu_cpuid_features.a.raw[2/*EDX*/] & (1 << 3)) && (dos_ltp_info.cr4 & 0x10) && (ent & 0x80)) { - /* it's a 4MB page, and we stop searching the page hierarchy here */ - ret = ent & 0xFFC00000UL; /* bits 31-22 are the actual page address */ - - /* but wait: if the CPU supports PSE-36, then we need to readback address bits 35...32, - * or if an AMD64 processor, address bits 39...32 */ - /* FIXME: So, we can assume if the CPU supports 64-bit long mode, that we can use bits 39...32? - * Perhaps this is a more in-depth check that we should be doing in the ltp_probe function? */ - if (cpu_cpuid_features.a.raw[2/*E2X*/] & (1 << 17)) { /* If PSE support exists */ - if (cpu_cpuid_features.a.raw[3/*ECX*/] & (1 << 29)) { /* If CPU supports 64-bit long mode */ - /* AMD64 compatible, up to 40 bits */ - ret |= ((uint64_t)((ent >> 13UL) & 0xFFUL)) << 32ULL; - } - else { /* else, assume Pentium III compatible, up to 36 bits */ - ret |= ((uint64_t)((ent >> 13UL) & 0xFUL)) << 32ULL; - } - } - } - else { - /* VCPI possibility: the page table might reside below 1MB in DOS memory, and remain unmapped. */ - if (dos_ltp_info.dos_remap && dos_ltp_info.vcpi_xlate && ent < 0x100000UL) { - lock2 = 0; - if (dos_linear_to_phys_vcpi(ent>>12) == (ent&0xFFFFF000UL)) /* if VCPI says it's a 1:1 mapping down there, then it's OK */ - l2 = (uint32_t*)(ent & 0xFFFFF000UL); - } - /* again the second level is usually in DOS memory where we can assume 1:1 mapping */ - else if (!dos_ltp_info.dos_remap && !dos_ltp_info.dos_remap && ent < 0x100000UL) { - lock2 = 0; - l2 = (uint32_t*)(ent & 0xFFFFF000UL); - } - else { - /* well, then we gotta map it */ - l2 = (uint32_t*)dpmi_phys_addr_map(ent & 0xFFFFF000UL,4096); - if (l2 != NULL) lock2 = 1; - } - } - } - } - - if (l2 != NULL) { - /* level 2 lookup */ - ent = l2[linear & 0x3FF]; - if (ent & 1) { /* if the page is actually present... */ - ret = ent & 0xFFFFF000UL; - } - } - - if (lock2) dpmi_phys_addr_free((void*)l2); - if (lock1) dpmi_phys_addr_free((void*)l1); - return ret; -} -#endif - diff --git a/src/lib/doslib/dos/dos_mcb.c b/src/lib/doslib/dos/dos_mcb.c deleted file mode 100644 index db587fab..00000000 --- a/src/lib/doslib/dos/dos_mcb.c +++ /dev/null @@ -1,117 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -unsigned char FAR *dos_mcb_get_psp(struct dos_mcb_enum *e) { - if (e->psp < 0x80 || e->psp == 0xFFFFU) - return NULL; - -#if TARGET_MSDOS == 32 - return (unsigned char*)((uint32_t)e->psp << 4UL); -#else - return (unsigned char FAR*)MK_FP(e->psp,0); -#endif -} - -int mcb_name_is_junk(char *s/*8 char*/) { - int junk=0,i; - unsigned char c; - - for (i=0;i < 8;i++) { - c = (unsigned char)s[i]; - if (c == 0) - break; - else if (c < 32 || c >= 127) - junk = 1; - } - - return junk; -} - -uint16_t dos_mcb_first_segment() { - if (dos_LOL == NULL) - return 0; - - return *((uint16_t FAR*)(dos_LOL-2)); /* NTS: This is not a mistake. You take the pointer given by DOS and refer to the WORD starting 2 bytes PRIOR. I don't know why they did that... */ -} - -void mcb_filter_name(struct dos_mcb_enum *e) { - if (e->psp > 0 && e->psp < 0x80) { /* likely special DOS segment */ - if (!memcmp(e->name,"SC",2) || !memcmp(e->name,"SD",2)) - memset(e->name+2,0,6); - else - memset(e->name,0,8); - } - else if (mcb_name_is_junk(e->name)) { - memset(e->name,0,8); - } -} - -int dos_mcb_next(struct dos_mcb_enum *e) { - unsigned char FAR *mcb; - unsigned int i; - uint16_t nxt; - - if (e->type == 0x5A || e->segment == 0x0000U || e->segment == 0xFFFFU) - return 0; - if (e->counter >= 16384) - return 0; - -#if TARGET_MSDOS == 32 - mcb = (unsigned char*)((uint32_t)(e->segment) << 4UL); - e->ptr = mcb + 16; -#else - mcb = (unsigned char far*)(MK_FP(e->segment,0)); - e->ptr = (unsigned char far*)(MK_FP(e->segment+1U,0)); -#endif - - e->cur_segment = e->segment; - e->type = *((uint8_t FAR*)(mcb+0)); - e->psp = *((uint16_t FAR*)(mcb+1)); - e->size = *((uint16_t FAR*)(mcb+3)); - for (i=0;i < 8;i++) e->name[i] = mcb[i+8]; e->name[8] = 0; - if (e->type != 0x5A && e->type != 0x4D) return 0; - nxt = e->segment + e->size + 1; - if (nxt <= e->segment) return 0; - e->segment = nxt; - return 1; -} - -int dos_mcb_first(struct dos_mcb_enum *e) { - if (dos_LOL == NULL) - return 0; - - e->counter = 0; - e->segment = dos_mcb_first_segment(); - if (e->segment == 0x0000U || e->segment == 0xFFFFU) - return 0; - - return dos_mcb_next(e); -} - diff --git a/src/lib/doslib/dos/dos_nmi.c b/src/lib/doslib/dos/dos_nmi.c deleted file mode 100644 index b20cc56d..00000000 --- a/src/lib/doslib/dos/dos_nmi.c +++ /dev/null @@ -1,78 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* TODO: This should be moved into the hw/DOS library */ -unsigned char nmi_32_hooked = 0; -int nmi_32_refcount = 0; -void (interrupt *nmi_32_old_vec)() = NULL; -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* NMI reflection (32-bit -> 16-bit) - This code is VITAL if we want to work with SBOS and MEGA-EM - from protected mode. */ -static struct dpmi_realmode_call nmi_32_nr={0}; -static void interrupt far nmi_32() { - /* trigger a real-mode INT 02h */ - __asm { - mov ax,0x0300 - mov bx,0x02 - xor cx,cx - mov edi,offset nmi_32_nr ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } -} - -void do_nmi_32_unhook() { - if (nmi_32_refcount > 0) - nmi_32_refcount--; - - if (nmi_32_refcount == 0) { - if (nmi_32_hooked) { - nmi_32_hooked = 0; - _dos_setvect(0x02,nmi_32_old_vec); - nmi_32_old_vec = NULL; - } - } -} - -void do_nmi_32_hook() { - if (nmi_32_refcount == 0) { - if (!nmi_32_hooked) { - nmi_32_hooked = 1; - nmi_32_old_vec = _dos_getvect(0x02); - _dos_setvect(0x02,nmi_32); - } - } - nmi_32_refcount++; -} -#endif - diff --git a/src/lib/doslib/dos/dosasm.asm b/src/lib/doslib/dos/dosasm.asm deleted file mode 100644 index cac64eee..00000000 --- a/src/lib/doslib/dos/dosasm.asm +++ /dev/null @@ -1,645 +0,0 @@ -; dosasm.asm -; -; Assembly language support routines for dos.c -; (C) 2011-2012 Jonathan Campbell. -; Hackipedia DOS library. -; -; This code is licensed under the LGPL. -; - -extern _dpmi_entered ; BYTE -extern _dpmi_entry_point ; DWORD -extern _dpmi_private_data_segment ; word -extern _dpmi_rm_entry ; qword -extern _dpmi_pm_entry ; dword -extern _dpmi_pm_cs,_dpmi_pm_ds,_dpmi_pm_es,_dpmi_pm_ss - -section .text class=CODE - -; NTS: If we code 'push ax' and 'popf' for the 16-bit tests in 32-bit protected mode we will screw up the stack pointer and crash -; so we avoid duplicate code by defining 'native' pushf/popf functions and 'result' to ax or eax depending on CPU mode -%if TARGET_MSDOS == 32 - %define point_s esi - %define result eax - %define pushfn pushfd - %define popfn popfd -use32 -%else - %define point_s si - %define result ax - %define pushfn pushf - %define popfn popf -use16 -%endif - -%if TARGET_MSDOS == 16 - %ifndef MMODE - %error You must specify MMODE variable (memory model) for 16-bit real mode code - %endif -%endif - -%if TARGET_MSDOS == 16 - %ifidni MMODE,l - %define retnative retf - %define cdecl_param_offset 6 ; RETF addr + PUSH BP - %else - %ifidni MMODE,m - %define retnative retf - %define cdecl_param_offset 6 ; RETF addr + PUSH BP - %else - %define retnative ret - %define cdecl_param_offset 4 ; RET addr + PUSH BP - %endif - %endif -%else - %define retnative ret - %define cdecl_param_offset 8 ; RET addr + PUSH EBP -%endif - -%ifndef TARGET_WINDOWS - %if TARGET_MSDOS == 16 -; cheap coding: put some variables here in the code segment. as real-mode -; code there's nothing to stop us from leaving DS == CS on entry and letting -; DPMI build an alias to our own code segment -l_dpmi_mode db 0 -l_dpmi_rm_entry dd 0 ; also re-used to call entry! - dw 0 -l_dpmi_pm_entry dd 0 -; we also need to record the segments given to us by the DPMI server so -; that we can re-enter protected mode -l_dpmi_segs dw 0,0,0,0 -this_process_psp dw 0 - -; void __cdecl dpmi_enter_core(); /* Watcom's inline assembler is too limiting to carry out the DPMI entry and switch back */ -global _dpmi_enter_core -_dpmi_enter_core: - ; 16-bit or 32-bit? - pushf - pusha - push ds - push es - push cs - push ss - cli - mov ax,seg _dpmi_entered - mov ds,ax - xor ax,ax - mov bl,byte [_dpmi_entered] - mov byte [cs:l_dpmi_mode],bl ; the protected mode side of the function needs this - cmp bl,32 - jnz .not32_ax - or al,1 ; indicate 32-bit DPMI connection -.not32_ax: - ; so: AX=0 if 16-bit setup, AX=1 if 32-bit setup. Now for simplicity set DS==CS - mov bx,seg _dpmi_private_data_segment ; NTS may be zero if DPMI doesn't need it - mov es,bx - mov es,[es:_dpmi_private_data_segment] ; NTS: ES = DPMI private data. Do not modify between here and call to DPMI entry - - mov bx,seg _dpmi_entry_point - mov ds,bx - mov bx,word [_dpmi_entry_point+0] - mov word [cs:l_dpmi_rm_entry+0],bx - mov bx,word [_dpmi_entry_point+2] - mov word [cs:l_dpmi_rm_entry+2],bx - - mov bx,cs - mov ds,bx - call far word [cs:l_dpmi_rm_entry] - jnc .entry_ok - ; ENTRY FAILED. Set entered flag to zero and return - mov ax,seg _dpmi_entered - mov ds,ax - mov byte [_dpmi_entered],0 - add sp,4 ; discard saved CS+SS - pop es - pop ds - popa - popf - retnative -; HERE: Entry succeeded. Get DPMI PM/RM entry points and then switch back to real mode. -; note that because we entered with DS == CS the DPMI server should have CS != DS but both -; refer to the same segment, as aliases. That makes our job simpler as we can use local storage -; privately in the code segment. -.entry_ok: - mov ax,0x0306 - int 31h - - ; BX:CX real to protected mode entry point - mov word [l_dpmi_pm_entry+0],cx - mov word [l_dpmi_pm_entry+2],bx - - ; save the selectors preallocated by DPMI - mov word [l_dpmi_segs+0],cs - mov word [l_dpmi_segs+2],ds - mov word [l_dpmi_segs+4],es - mov word [l_dpmi_segs+6],ss - - ; SI:DI (16-bit) or SI:EDI (32-bit) protected mode to real mode entry point - cmp byte [l_dpmi_mode],32 - jnz .store_16 - ; 32-bit storage, and return - mov dword [l_dpmi_rm_entry+0],edi - mov word [l_dpmi_rm_entry+4],si - pop dx ; restore SS into DX. DX will become SS - pop ax ; restore CS into AX. AX will become DS - mov cx,ax ; CX will become ES - mov si,ax ; SI will become CS - mov bx,sp ; BX will become SP - mov di,.exit_ok ; DI will become IP, so direct it at the exit point below - jmp far dword [l_dpmi_rm_entry] -.store_16: - ; 16-bit storage, and return - mov word [l_dpmi_rm_entry+0],di - mov word [l_dpmi_rm_entry+2],si - pop dx ; restore SS into DX. DX will become SS - pop ax ; restore CS into AX. AX will become DS - mov cx,ax ; CX will become ES - mov si,ax ; SI will become CS - mov bx,sp ; BX will become SP - mov di,.exit_ok ; DI will become IP, so direct it at the exit point below - jmp far word [l_dpmi_rm_entry] -; jump back to realmode here -.exit_ok: - -; copy results to host variables - mov ax,word [cs:l_dpmi_pm_entry] - mov bx,word [cs:l_dpmi_pm_entry+2] - mov cx,seg _dpmi_pm_entry - mov ds,cx - mov word [_dpmi_pm_entry+0],ax - mov word [_dpmi_pm_entry+2],bx - - mov ax,word [cs:l_dpmi_rm_entry] - mov bx,word [cs:l_dpmi_rm_entry+2] - mov cx,word [cs:l_dpmi_rm_entry+4] - mov dx,seg _dpmi_rm_entry - mov ds,dx - mov word [_dpmi_rm_entry+0],ax - mov word [_dpmi_rm_entry+2],bx - mov word [_dpmi_rm_entry+4],cx - - mov ax,word [cs:l_dpmi_segs+0] - mov dx,seg _dpmi_pm_cs - mov ds,dx - mov word [_dpmi_pm_cs],ax - - mov ax,word [cs:l_dpmi_segs+2] - mov dx,seg _dpmi_pm_ds - mov ds,dx - mov word [_dpmi_pm_ds],ax - - mov ax,word [cs:l_dpmi_segs+4] - mov dx,seg _dpmi_pm_es - mov ds,dx - mov word [_dpmi_pm_es],ax - - mov ax,word [cs:l_dpmi_segs+6] - mov dx,seg _dpmi_pm_ss - mov ds,dx - mov word [_dpmi_pm_ss],ax - - ; now that DPMI is active, we have to hook real-mode INT 21h - ; to catch program termination, so we can forward that to the DPMI - ; server for proper DPMI cleanup - call dpmi_hook_int21 - - pop es - pop ds - popa - popf - retnative - %endif -%endif - -; INT 21h hook: -; We use DPMI entry and thunking back to real mode to let the host -; program remain 16-bit. BUT: there's a problem. if the host program -; exits normally with INT 21h via real mode, the DPMI server never gets -; the message and it remains stuck running in the background. To make -; DPMI exit normally, we have to hook INT 21h and reflect AH=0x4C to -; protected mode. -%ifndef TARGET_WINDOWS - %if TARGET_MSDOS == 16 -old_int21h dd 0 -dpmi_hook_int21: - push es - push ax - push bx - push cx - xor ax,ax - mov es,ax - mov ax,cs - mov bx,word [es:(0x21*4)] - mov cx,word [es:(0x21*4)+2] - mov word [es:(0x21*4)],dpmi_int21_hook_exit - mov word [es:(0x21*4)+2],ax - mov word [cs:old_int21h+0],bx - mov word [cs:old_int21h+2],cx - - ; also keep track of this process's PSP segment, so we can readily - ; identify WHO is calling INT 21h AH=0x4C and forward to DPMI only - ; for our process, not any other process. - mov ah,0x62 - int 21h - mov word [cs:this_process_psp],bx - - pop cx - pop bx - pop ax - pop es - ret - -; Our INT 21h hook. We're looking for any INT 21h AH=0x4C call coming from -; this process. If the call comes from any other program in memory, the call -; is forwarded without modification, so that DPMI does not prematurely exit -; when subprocesses started by this program terminate. -; -; This hack seems silly but apparently most DPMI servers do not monitor real-mode -; INT 21h for the AH=0x4C call. If they never see the termination call from -; protected mode, then they never clean up for this process and in most cases -; (especially Windows) end up leaking selectors and other resources. So to avoid -; memory leaks, we must forward INT 21h AH=0x4C to the protected mode side of -; the DPMI server. -; -; TODO: This hook should also catch INT 21h AH=31 Terminate and Stay Resident, -; DPMI needs to keep those too! -; -; FIXME: How will this code catch cases where the calling program calls INT 21h -; from protected mode to terminate? Worst case scenario: DPMI cleans up -; and we never get a chance to remove our INT 21h hook. -dpmi_int21_hook_exit: - cmp ah,0x4C - jz .catch_exit - jmp far word [cs:old_int21h] -.catch_exit: - ; this is our process terminating, not some subprocess, right? - ; we want to forward termination only for this process, not anyone else. - push ax - push bx - mov ah,0x62 ; get PSP segment - int 21h - cmp bx,word [cs:this_process_psp] - jz .catch_exit_psp - pop bx - pop ax - jmp far word [cs:old_int21h] -.catch_exit_psp: - pop bx - pop ax - ; restore the old vector - push es - push ax - push bx - push cx - xor ax,ax - mov es,ax - mov ax,cs - mov bx,word [cs:old_int21h+0] - mov cx,word [cs:old_int21h+2] - mov word [es:(0x21*4)],bx - mov word [es:(0x21*4)+2],cx - pop cx - pop bx - pop ax - pop es - ; OK. Switch into protected mode. - ; use the segment values given to us by the DPMI server. - cli - mov bp,ax ; save AX - mov ax,word [cs:l_dpmi_segs+2] ; AX becomes DS (so load DS from DPMI env) - mov cx,ax ; CX becomes ES - mov dx,ax ; DX becomes SS (doesn't matter) - mov bx,sp ; BX becomes SP (doesn't matter) - mov si,word [cs:l_dpmi_segs+0] ; SI becomes CS (so load CS from DPMI env) - mov di,.catch_exit_pmode ; DI becomes IP - jmp far word [cs:l_dpmi_pm_entry] -.catch_exit_pmode: - mov ax,bp - mov ah,0x4C - int 21h ; now issue INT 21h AH=0x4C where the DPMI server can see it - hlt - %endif -%endif - -%if TARGET_MSDOS == 16 - %ifndef TARGET_WINDOWS - -; WARNING: The caller must have ensured we are running on a 386 or higher, and that -; the DPMI entry points were obtained - -; __cdecl: right-to-left argument passing (meaning: caller does "push sz", "push lsrc", "push dst"...) -l_lin2fm_params: -l_lin2fm_param_dst: dd 0 ; unsigned char far *dst -l_lin2fm_param_lsrc: dd 0 ; uint32_t lsrc -l_lin2fm_param_sz: dd 0 ; uint32_t sz - ; = 12 bytes - -l_rm_ret dw 0 -l_rm_reentry dd 0 - dw 0 - -; TODO: Export these so they are visible as C variables -; we need these selectors for copy operation -l_lin2fm_src_sel dw 0 -l_lin2fm_dst_sel dw 0 - -; dpmi_pm_cs,dpmi_pm_ds,dpmi_pm_es,dpmi_pm_ss -; int __cdecl dpmi_lin2fmemcpy_32(unsigned char far *dst,uint32_t lsrc,uint32_t sz); -global _dpmi_lin2fmemcpy_32 -_dpmi_lin2fmemcpy_32: - push bp - mov bp,sp - - ; copy params, we need them in protected mode - mov eax,dword [bp+cdecl_param_offset+0] - mov dword [cs:l_lin2fm_params+0],eax - mov eax,dword [bp+cdecl_param_offset+4] - mov dword [cs:l_lin2fm_params+4],eax - mov eax,dword [bp+cdecl_param_offset+8] - mov dword [cs:l_lin2fm_params+8],eax - - pusha ; save all regs - - push ds - push es - - push cs ; realmode re-entry needs this - push ss ; realmode re-entry needs this - push ds ; realmode re-entry needs this - - mov ax,seg _dpmi_pm_entry - mov ds,ax - - xor ax,ax - mov word [cs:l_rm_ret],ax - - mov eax,dword [_dpmi_rm_entry+0] - mov dword [cs:l_rm_reentry+0],eax - - mov ax,word [_dpmi_rm_entry+4] - mov word [cs:l_rm_reentry+4],ax - - mov ax,word [_dpmi_pm_ds] - mov cx,ax - mov dx,word [_dpmi_pm_ss] - mov bx,sp - mov si,word [_dpmi_pm_cs] - mov di,.entry_pm - call far word [_dpmi_pm_entry] - ; didn't make it. error return - add sp,6 ; do not restore SS+CS+DS, just discard - pop es - pop ds - popa - pop bp - xor ax,ax ; return 0 == no copy made - retnative -.entry_pm: - - ; we need to allocate two selectors to do the copy operation with - cmp word [l_lin2fm_src_sel],0 - jnz .sel_avail ; if != 0, then skip code - ; allocate two descriptors - xor ax,ax - mov cx,2 - int 31h - jnc .sel_alloced ; if carry clear, continue - jmp .go_to_exit_pm ; else return to RM with retval == 0 -.sel_alloced: - ; we got two descriptors, store them - mov word [l_lin2fm_src_sel],ax - add ax,8 ; obviously... - mov word [l_lin2fm_dst_sel],ax - ; we need to make them data selectors - mov ax,0x0009 ; DPMI Set Descriptor Access Rights - mov bx,word [l_lin2fm_src_sel] - mov cl,0xF0 ; P=1 DPL=3 data expand-up r/o. I know DPMI says it must equal our level, but Windows always runs us Ring-3 so we can assume - xor ch,ch ; 16-bit selector (we are 16-bit code!) - int 31h - jc short $ ; FIXME:For now, hang if the request failed - mov ax,0x0008 ; DPMI Set Selector Limit - mov bx,word [l_lin2fm_src_sel] - xor cx,cx - xor dx,dx - dec dx ; CX:DX = 0000:FFFF - int 31h - ; and the other one - mov ax,0x0009 ; DPMI Set Descriptor Access Rights - mov bx,word [l_lin2fm_dst_sel] - mov cl,0xF2 ; P=1 DPL=3 data expand-up r/w. I know DPMI says it must equal our level, but Windows always runs us Ring-3 so we can assume - xor ch,ch ; 16-bit selector (we are 16-bit code!) - int 31h - jc short $ ; FIXME:For now, hang if the request failed - mov ax,0x0008 ; DPMI Set Selector Limit - mov bx,word [l_lin2fm_dst_sel] - xor cx,cx - xor dx,dx - dec dx ; CX:DX = 0000:FFFF - int 31h -.sel_avail: - ; OK, pull in source address (flat) from param and set the selector base - mov ax,0x0007 - mov bx,word [l_lin2fm_src_sel] - mov dx,word [l_lin2fm_param_lsrc+0] ; CX:DX = base - mov cx,word [l_lin2fm_param_lsrc+2] - int 31h - ; and the dest address (realmode seg:off) too - movzx eax,word [l_lin2fm_param_dst+2] - shl eax,4 - movzx ebx,word [l_lin2fm_param_dst+0] - add eax,ebx - mov dx,ax - shr eax,16 - mov cx,ax - mov bx,word [l_lin2fm_dst_sel] - mov ax,0x0007 - int 31h - ; alright then, do the memcpy - mov cx,word [l_lin2fm_param_sz] - mov word [l_rm_ret],cx ; set return value too - push ds - push es - cld - mov ax,word [l_lin2fm_src_sel] - mov bx,word [l_lin2fm_dst_sel] - mov ds,ax - mov es,bx - xor si,si - mov di,si - rep movsb ; ES:DI <- DS:SI - pop es - pop ds -.go_to_exit_pm: - ; NTS: when dpmi_enter_core() did it's job it made sure DS == CS - ; so the DPMI server would make DS an alias of CS in protected mode - pop ax ; AX = realmode DS - mov cx,ax - pop dx ; DX = realmode SS - pop si ; SI = realmode CS - mov bx,sp - mov di,.exit_pm - call far dword [l_rm_reentry] ; NTS: We're using the 32-bit DPMI server, the RM entry point is 16:32 format -.exit_pm: ; NTS: Don't forget CS+DS+SS was pushed but the PM part popped them as part of returning - pop es - pop ds - popa - - pop bp - mov ax,word [cs:l_rm_ret] - retnative - -; NOTE: This version of the code is written to work with 16-bit DPMI servers, -; and to work within the constraint that we could be run on a 286 where -; 32-bit registers are not available. -; dpmi_pm_cs,dpmi_pm_ds,dpmi_pm_es,dpmi_pm_ss -; int __cdecl dpmi_lin2fmemcpy_16(unsigned char far *dst,uint32_t lsrc,uint32_t sz); -global _dpmi_lin2fmemcpy_16 -_dpmi_lin2fmemcpy_16: - push bp - mov bp,sp - - ; copy params, we need them in protected mode - mov ax,word [bp+cdecl_param_offset+0] - mov word [cs:l_lin2fm_params+0],ax - mov ax,word [bp+cdecl_param_offset+2] - mov word [cs:l_lin2fm_params+2],ax - mov ax,word [bp+cdecl_param_offset+4] - mov word [cs:l_lin2fm_params+4],ax - mov ax,word [bp+cdecl_param_offset+6] - mov word [cs:l_lin2fm_params+6],ax - mov ax,word [bp+cdecl_param_offset+8] - mov word [cs:l_lin2fm_params+8],ax - mov ax,word [bp+cdecl_param_offset+10] - mov word [cs:l_lin2fm_params+10],ax - - pusha ; save all regs - - push ds - push es - - push cs ; realmode re-entry needs this - push ss ; realmode re-entry needs this - push ds ; realmode re-entry needs this - - mov ax,seg _dpmi_pm_entry - mov ds,ax - - xor ax,ax - mov word [cs:l_rm_ret],ax - - mov eax,dword [_dpmi_rm_entry+0] - mov dword [cs:l_rm_reentry+0],eax - - mov ax,word [_dpmi_rm_entry+4] - mov word [cs:l_rm_reentry+4],ax - - mov ax,word [_dpmi_pm_ds] - mov cx,ax - mov dx,word [_dpmi_pm_ss] - mov bx,sp - mov si,word [_dpmi_pm_cs] - mov di,.entry_pm - call far word [_dpmi_pm_entry] - ; didn't make it. error return - add sp,6 ; do not restore SS+CS+DS, just discard - pop es - pop ds - popa - pop bp - xor ax,ax ; return 0 == no copy made - retnative -.entry_pm: - - ; we need to allocate two selectors to do the copy operation with - cmp word [l_lin2fm_src_sel],0 - jnz .sel_avail ; if != 0, then skip code - ; allocate two descriptors - xor ax,ax - mov cx,2 - int 31h - jnc .sel_alloced ; if carry clear, continue - jmp .go_to_exit_pm ; else return to RM with retval == 0 -.sel_alloced: - ; we got two descriptors, store them - mov word [l_lin2fm_src_sel],ax - add ax,8 ; obviously... - mov word [l_lin2fm_dst_sel],ax - ; we need to make them data selectors - mov ax,0x0009 ; DPMI Set Descriptor Access Rights - mov bx,word [l_lin2fm_src_sel] - mov cl,0xF0 ; P=1 DPL=3 data expand-up r/o. I know DPMI says it must equal our level, but Windows always runs us Ring-3 so we can assume - xor ch,ch ; 16-bit selector (we are 16-bit code!) - int 31h - jc short $ ; FIXME:For now, hang if the request failed - mov ax,0x0008 ; DPMI Set Selector Limit - mov bx,word [l_lin2fm_src_sel] - xor cx,cx - xor dx,dx - dec dx ; CX:DX = 0000:FFFF - int 31h - ; and the other one - mov ax,0x0009 ; DPMI Set Descriptor Access Rights - mov bx,word [l_lin2fm_dst_sel] - mov cl,0xF2 ; P=1 DPL=3 data expand-up r/w. I know DPMI says it must equal our level, but Windows always runs us Ring-3 so we can assume - xor ch,ch ; 16-bit selector (we are 16-bit code!) - int 31h - jc short $ ; FIXME:For now, hang if the request failed - mov ax,0x0008 ; DPMI Set Selector Limit - mov bx,word [l_lin2fm_dst_sel] - xor cx,cx - xor dx,dx - dec dx ; CX:DX = 0000:FFFF - int 31h -.sel_avail: - ; OK, pull in source address (flat) from param and set the selector base - mov ax,0x0007 - mov bx,word [l_lin2fm_src_sel] - mov dx,word [l_lin2fm_param_lsrc+0] ; CX:DX = base - mov cx,word [l_lin2fm_param_lsrc+2] - int 31h - ; and the dest address (realmode seg:off) too - mov dx,word [l_lin2fm_param_dst+2] ; DX = (seg << 4) + offset, CX = (seg >> 12) + (carry flag result of computing DX) - mov cx,dx - shr cx,12 - shl dx,4 - add dx,word [l_lin2fm_param_dst+0] - adc cx,0 ; CX:DX = 32-bit linear address - mov bx,word [l_lin2fm_dst_sel] - mov ax,0x0007 - int 31h - ; alright then, do the memcpy - mov cx,word [l_lin2fm_param_sz] - mov word [l_rm_ret],cx ; set return value too - push ds - push es - cld - mov ax,word [l_lin2fm_src_sel] - mov bx,word [l_lin2fm_dst_sel] - mov ds,ax - mov es,bx - xor si,si - mov di,si - rep movsb ; ES:DI <- DS:SI - pop es - pop ds -.go_to_exit_pm: - ; NTS: when dpmi_enter_core() did it's job it made sure DS == CS - ; so the DPMI server would make DS an alias of CS in protected mode - pop ax ; AX = realmode DS - mov cx,ax - pop dx ; DX = realmode SS - pop si ; SI = realmode CS - mov bx,sp - mov di,.exit_pm - call far word [l_rm_reentry] ; NTS: We're using the 16-bit DPMI server, the RM entry point is 16:16 format -.exit_pm: ; NTS: Don't forget CS+DS+SS was pushed but the PM part popped them as part of returning - pop es - pop ds - popa - - pop bp - mov ax,word [cs:l_rm_ret] - retnative - - %endif -%endif diff --git a/src/lib/doslib/dos/dosbox.c b/src/lib/doslib/dos/dosbox.c deleted file mode 100644 index a623a575..00000000 --- a/src/lib/doslib/dos/dosbox.c +++ /dev/null @@ -1,140 +0,0 @@ -/* dosbox.c - * - * Detect whether or not we're running under the DOSBox emulator - * (C) 2010-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if defined(TARGET_WINDOWS) || defined(TARGET_OS2) -#else -static const char *dosbox_fakebios = "DOSBox FakeBIOS v1.0"; -#endif - -/* the ROM area doesn't change. so remember our last result */ -#if defined(TARGET_WINDOWS) || defined(TARGET_OS2) -#else -static signed char dosbox_detect_cache = -1; -#endif - -int detect_dosbox_emu() { -#if defined(TARGET_OS2) - /* TODO: So... how does one read the ROM BIOS area from OS/2? */ - return 0; -#elif defined(TARGET_WINDOWS) - /* TODO: I know that from within Windows there are various ways to scan the ROM BIOS area. - * Windows 1.x and 2.x (if real mode) we can just use MK_FP as we do under DOS, but - * we have to use alternate means if Windows is in protected mode. Windows 2.x/3.x protected - * mode (and because of compatibility, Windows 95/98/ME), there are two methods open to us: - * One is to use selector constants that are hidden away in KRNL386.EXE with names like _A0000, - * _B0000, etc. They are data selectors that when loaded into the segment registers point to - * their respective parts of DOS adapter ROM and BIOS ROM. Another way is to use the Win16 - * API to create a data selector that points to the BIOS. Windows 386 Enhanced mode may map - * additional things over the unused parts of adapter ROM, but experience shows that it never - * relocates or messes with the VGA BIOS or with the ROM BIOS, - * - * My memory is foggy at this point, but I remember that under Windows XP SP2, one of the - * above Win16 methods still worked even from under the NT kernel. - * - * For Win32 applications, if the host OS is Windows 3.1 Win32s or Windows 95/98/ME, we can - * take advantage of a strange quirk in the way the kernel maps the lower 1MB. For whatever - * reason, the VGA RAM, adapter ROM, and ROM BIOS areas are left open even for Win32 applications - * with no protection. Thus, a Win32 programmer can just make a pointer like - * char *a = (char*)0xA0000 and scribble on legacy VGA RAM to his heart's content (though on - * modern PCI SVGA hardware the driver probably instructs the card to disable VGA compatible - * mapping). In fact, this ability to scribble on RAM directly is at the heart of one of Microsoft's - * earliest and hackiest "Direct Draw" interfaces known as "DISPDIB.DLL", a not-to-well documented - * library responsible for those Windows 3.1 multimedia apps and games that were somehow able to - * run full-screen 320x200x256 color VGA despite being Windows GDI-based apps. Ever wonder how the - * MCI AVI player was able to go full-screen when DirectX and WinG were not invented yet? Now you - * know :) - * - * There are some VFW codecs out there as well, that also like to abuse DISPDIB.DLL for "fullscreen" - * modes. One good example is the old "Motion Pixels" codec, that when asked to go fullscreen, - * uses DISPDIB.DLL and direct VGA I/O port trickery to effectively set up a 320x480 256-color mode, - * which it then draws on "fake hicolor" style to display the video (though a bit dim since you're - * sort of watching a video through a dithered mesh, but...) - * - * In case you were probably wondering, no, Windows NT doesn't allow Win32 applications the same - * privilege. Win32 apps writing to 0xA0000 would page fault and crash. Curiously enough though, - * NTVDM.EXE does seem to open up the 0xA0000-0xFFFFF memory area to Win16 applications if they - * use the right selectors and API calls. */ - return 0; -#else - int i; -# if TARGET_MSDOS == 32 - const char *scan; -# else - const char far *scan; -# endif - - probe_dos(); - if (dosbox_detect_cache >= 0) - return (int)dosbox_detect_cache; - -# if TARGET_MSDOS == 32 - if (dos_flavor == DOS_FLAVOR_FREEDOS) { - /* FIXME: I have no idea why but FreeDOS 1.0 has a strange conflict with DOS32a where if this code - * tries to read the ROM BIOS it causes a GPF and crashes (or sometimes runs off into the - * weeds leaving a little garbage on the screen). DOS32a's register dump seems to imply that - * at one point our segment limits were suddenly limited to 1MB (0xFFFFF). I have no clue - * what the hell is triggering it, but I know from testing we can avoid that crash by not - * scanning. */ - if (freedos_kernel_version == 0x000024UL) /* 0.0.36 */ - return (dosbox_detect_cache=0); - } -# endif - -/* signs that we're running under DOSBOX: - * - the majority of the adapter ROM area is 0x00 (not 0xFF or any other value). Here we check 0xE000:0xFF00 and 0xF000:0x000. - * - an ASCII string is visible at 0xF000:0xE061: "DOSBox FakeBIOS v1.0" */ - -# if TARGET_MSDOS == 32 - scan = (const char*)0xEFF00UL; -# else - scan = (const char far*)MK_FP(0xE000,0xFF00); -# endif - - for (i=0;i < 256;i++) { - if (scan[i] != 0) - return (dosbox_detect_cache=0); - } - -# if TARGET_MSDOS == 32 - scan = (const char*)0xF0000UL; -# else - scan = (const char far*)MK_FP(0xF000,0x0000); -# endif - for (i=0;i < 256;i++) { - if (scan[i] != 0) - return (dosbox_detect_cache=0); - } - -# if TARGET_MSDOS == 32 - scan = (const char*)0xFE061UL; -# else - scan = (const char far*)MK_FP(0xF000,0xE061); -# endif - i = 0; - do { - if (dosbox_fakebios[i] != scan[i]) - return (dosbox_detect_cache=0); - } while (dosbox_fakebios[i++] != 0); - - return (dosbox_detect_cache=1); -#endif -} - diff --git a/src/lib/doslib/dos/dosbox.h b/src/lib/doslib/dos/dosbox.h deleted file mode 100644 index 98af3433..00000000 --- a/src/lib/doslib/dos/dosbox.h +++ /dev/null @@ -1,14 +0,0 @@ -/* dosbox.h - * - * Detect whether or not we're running under the DOSBox emulator - * (C) 2010-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include - -int detect_dosbox_emu(); - diff --git a/src/lib/doslib/dos/dosdev.c b/src/lib/doslib/dos/dosdev.c deleted file mode 100644 index 2c6001d8..00000000 --- a/src/lib/doslib/dos/dosdev.c +++ /dev/null @@ -1,83 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int dos_device_next(struct dos_device_enum *e) { - e->raw = e->next; - if (e->raw == NULL || e->count >= 512 || e->no == 0xFFFFU) - return 0; - - e->no = *((uint16_t FAR*)(e->raw + 0x0)); - e->ns = *((uint16_t FAR*)(e->raw + 0x2)); - e->attr = *((uint16_t FAR*)(e->raw + 0x04)); - e->entry = *((uint16_t FAR*)(e->raw + 0x06)); - e->intent = *((uint16_t FAR*)(e->raw + 0x08)); - if (!(e->attr & 0x8000)) { - /* block device */ - _fmemcpy(e->name,e->raw+0x0B,8); e->name[7] = 0; - if (e->name[0] < 33 || e->name[0] >= 127) e->name[0] = 0; - } - else { - /* char device */ - _fmemcpy(e->name,e->raw+0x0A,8); e->name[8] = 0; - } - e->count++; - -#if TARGET_MSDOS == 32 - e->next = (unsigned char*)((((uint32_t)(e->ns)) << 4UL) + e->no); -#else - e->next = (unsigned char FAR*)MK_FP(e->ns,e->no); -#endif - - return 1; -} - -int dos_device_first(struct dos_device_enum *e) { - unsigned int offset = 0x22; /* most common, DOS 3.1 and later */ - - if (dos_LOL == NULL) - return 0; - - if (dos_version < 0x200) /* We don't know where the first device is in DOS 1.x */ - return 0; - else if (dos_version < 0x300) - offset = 0x17; - else if (dos_version == 0x300) - offset = 0x28; - - e->no = 0; - e->ns = 0; - e->count = 0; - e->raw = e->next = dos_LOL + offset; - if (_fmemcmp(e->raw+0xA,"NUL ",8) != 0) /* should be the NUL device driver */ - return 0; - - return dos_device_next(e); -} - diff --git a/src/lib/doslib/dos/dosdpmi.c b/src/lib/doslib/dos/dosdpmi.c deleted file mode 100644 index 3deaaab5..00000000 --- a/src/lib/doslib/dos/dosdpmi.c +++ /dev/null @@ -1,286 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -int8_t dpmi_no_0301h = -1; /* whether or not the DOS extender provides function 0301h */ -#endif - -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS)) -uint16_t dpmi_flags=0; -uint16_t dpmi_version=0; -unsigned char dpmi_init=0; -uint32_t dpmi_entry_point=0; -unsigned char dpmi_present=0; -unsigned char dpmi_processor_type=0; -uint16_t dpmi_private_data_length_paragraphs=0; -uint16_t dpmi_private_data_segment=0xFFFF; /* when we DO enter DPMI, we store the private data segment here. 0 = no private data. 0xFFFF = not yet entered */ -unsigned char dpmi_entered = 0; /* 0=not yet entered, 16=entered as 16bit, 32=entered as 32bit */ -uint64_t dpmi_rm_entry = 0; -uint32_t dpmi_pm_entry = 0; - -/* once having entered DPMI, keep track of the selectors registers given to us in p-mode */ -uint16_t dpmi_pm_cs,dpmi_pm_ds,dpmi_pm_es,dpmi_pm_ss; - -void __cdecl dpmi_enter_core(); /* Watcom's inline assembler is too limiting to carry out the DPMI entry and switch back */ -#endif - -/* 16-bit real mode DOS or 16-bit protected mode Windows */ -void probe_dpmi() { -#if defined(TARGET_OS2) - /* OS/2 apps do not run under DPMI */ -#elif TARGET_MSDOS == 32 && defined(TARGET_WINDOWS) - /* Win32 apps do not bother with DPMI */ -#else - if (!dpmi_init) { - /* BUGFIX: WINE (Wine Is Not an Emulator) can run Win16 applications - * but does not emulate the various low level interrupts one - * can call. To avoid crashing under WINE we must not use - * direct interrupts. */ - if (windows_emulation == WINEMU_WINE) { - dpmi_present = 0; - dpmi_init = 1; - return; - } - - { - unsigned char present=0,proc=0; - uint16_t version=0,privv=0,flags=0; - uint32_t entry=0; - - __asm { - push es - mov ax,0x1687 - int 2Fh - or ax,ax - jnz err1 - mov present,1 - mov flags,bx - mov proc,cl - mov version,dx - mov privv,si - mov word ptr [entry+0],di - mov word ptr [entry+2],es - pop es -err1: - } - - dpmi_flags = flags; - dpmi_present = present; - dpmi_version = version; - dpmi_entry_point = entry; - dpmi_processor_type = proc; - dpmi_private_data_segment = 0xFFFF; - dpmi_private_data_length_paragraphs = privv; - } - -#if TARGET_MSDOS == 32 || defined(TARGET_WINDOWS) - /* when we ask for the "entry point" we mean we want the real-mode entrypoint. - * apparently some DPMI servers like Windows XP+NTVDM.EXE translate ES:DI coming - * back to a protected mode entry point, which is not what we're looking for. - * - * Interesting fact: When compiled as a Win16 app, the DPMI call actually works, - * but returns an entry point appropriate for Win16 apps. So.... apparently we - * can enter DPMI protected mode from within Win16? Hmm.... that might be something - * fun to experiment with :) */ - if (dpmi_present) { - struct dpmi_realmode_call rc={0}; - rc.eax = 0x1687; - mux_realmode_2F_call(&rc); - if ((rc.eax&0xFFFF) == 0) { - dpmi_flags = rc.ebx&0xFFFF; - dpmi_present = 1; - dpmi_version = rc.edx&0xFFFF; - dpmi_entry_point = (((uint32_t)rc.es << 16UL) & 0xFFFF0000UL) + (uint32_t)(rc.edi&0xFFFFUL); - dpmi_processor_type = rc.ecx&0xFF; - dpmi_private_data_segment = 0xFFFF; - dpmi_private_data_length_paragraphs = rc.esi&0xFFFF; - } - else { - dpmi_present = 0; - } - } -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) - dpmi_no_0301h = 0; -#endif - dpmi_init = 1; - -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) - if (dpmi_present) { - /* Thanks to bullshit like DOS4/GW we have to test the extender to know - whether or not core routines we need are actually there or not. If they - are not, then alternative workarounds are required. The primary reason - for this test is to avoid HIMEM.SYS API code returning nonsensical values - caused by DOS4/GW not supporting such vital functions as DPMI 0301H: - Call far real-mode procedure. Knowing this should also fix the VESA BIOS - test bug where the protected-mode version is unable to use the BIOS's - direct-call window bank-switching function. - - At least, this code so far can rely on DPMI function 0300H: call real-mode - interrupt.*/ - - /* test #1: allocate a 16-bit region, put a RETF instruction there, - and ask the DPMI server to call it (0301H test). - - Success: - Registers unchanged - CF=0 - - Failure (DOS4/GW): - CF=1 - AX=0301H (wait wha?) */ - { - uint16_t sel = 0; - struct dpmi_realmode_call rc={0}; - unsigned char *proc = dpmi_alloc_dos(16,&sel); - if (proc != NULL) { - *proc = 0xCB; /* <- RETF */ - - rc.cs = ((size_t)proc) >> 4UL; - rc.ip = ((size_t)proc) & 0xFUL; - if (dpmi_test_rm_entry_call(&rc) != 0) - dpmi_no_0301h = 1; - - dpmi_free_dos(sel); - } - } - } -#endif - } -#endif -} - -#if TARGET_MSDOS == 16 && !defined(TARGET_WINDOWS) -int dpmi_private_alloc() { - unsigned short sss=0; - - if (!dpmi_present || dpmi_private_data_segment != 0xFFFFU) - return 1; /* OK, nothing to do */ - - if (dpmi_private_data_length_paragraphs == 0) { - dpmi_private_data_segment = 0; - return 0; - } - - __asm { - push ds - mov ah,0x48 - mov bx,seg dpmi_private_data_length_paragraphs - mov ds,bx - mov bx,dpmi_private_data_length_paragraphs - int 21h - pop ds - jc fail1 - mov sss,ax -fail1: - } - - if (sss == 0) - return 0; - - dpmi_private_data_segment = sss; - return 1; -} - -/* NTS: This enters DPMI. There is no exit from DPMI. And if you re-enter DPMI by switching back to protected mode, - * you only serve to confuse the server somewhat. - * - * Re-entry results: - * - Windows XP: Allows it, even going 16 to 32 bit mode, but the console window gets confused and drops our - * output when changing bit size. - * - Windows 9x: Allows it, doesn't allow changing bit mode, so once in 16-bit mode you cannot enter 32-bit mode. - * The mode persists until the DOS Box exits. - * - * This also means that once you init in one mode, you cannot re-enter another mode. If you init in 16-bit DPMI, - * you cannot init into 32-bit DPMI. - * - * If all you want is the best mode, call with mode == 0xFF instead to automatically select. */ -int dpmi_enter(unsigned char mode) { -/* TODO: Cache results, only need to scan once */ - if (mode == 0xFF) { - if ((cpu_basic_level == -1 || cpu_basic_level >= 3) && (dpmi_flags&1) == 1) - mode = 32; /* if 32-bit capable DPMI server and 386 or higher, choose 32-bit */ - else - mode = 16; /* for all else, choose 16-bit */ - } - - if (dpmi_entered != 0) { - if (dpmi_entered != mode) return 0; - return 1; - } - - if (mode != 16 && mode != 32) - return 0; - if (mode == 32 && !(dpmi_flags & 1)) - return 0; - if (dpmi_entry_point == 0) - return 0; - if (!dpmi_private_alloc()) - return 0; - if (dpmi_private_data_length_paragraphs != 0 && dpmi_private_data_segment == 0) - return 0; - if (dpmi_private_data_segment == 0xFFFFU) - return 0; - - dpmi_entered = mode; - dpmi_enter_core(); - return (dpmi_entered != 0); /* NTS: dpmi_enter_core() will set dpmi_entered back to zero on failure */ -} -#endif - -#if TARGET_MSDOS == 16 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* TODO: Switch into DPMI protected mode, allocate and setup selectors, do memcpy to - * DOS realmode segment, then return to real mode. When the code is stable, - * move it into hw/dos/dos.c. The purpose of this code is to allow 16-bit realmode - * DOS programs to reach into DPMI linear address space, such as the Win 9x - * kernel area when run under the Win 9x DPMI server. */ -int dpmi_lin2fmemcpy(unsigned char far *dst,uint32_t lsrc,uint32_t sz) { - if (dpmi_entered == 32) - return dpmi_lin2fmemcpy_32(dst,lsrc,sz); - else if (dpmi_entered == 16) { - _fmemset(dst,0,sz); - return dpmi_lin2fmemcpy_16(dst,lsrc,sz); - } - - return 0; -} - -int dpmi_lin2fmemcpy_init() { - probe_dpmi(); - if (!dpmi_present) - return 0; - if (!dpmi_enter(DPMI_ENTER_AUTO)) - return 0; - - return 1; -} -#endif - diff --git a/src/lib/doslib/dos/dosflavr.c b/src/lib/doslib/dos/dosflavr.c deleted file mode 100644 index aaaa588c..00000000 --- a/src/lib/doslib/dos/dosflavr.c +++ /dev/null @@ -1,50 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -const char *windows_emulation_str(uint8_t e) { - switch (e) { - case WINEMU_NONE: return "None"; - case WINEMU_WINE: return "WINE (Wine Is Not an Emulator)"; - default: break; - } - - return "?"; -} - -const char *dos_flavor_str(uint8_t f) { - switch (f) { - case DOS_FLAVOR_NONE: return "None"; - case DOS_FLAVOR_MSDOS: return "MS-DOS"; - case DOS_FLAVOR_FREEDOS: return "FreeDOS"; - } - - return "?"; -} - diff --git a/src/lib/doslib/dos/dosmapal.c b/src/lib/doslib/dos/dosmapal.c deleted file mode 100644 index 3439e0b2..00000000 --- a/src/lib/doslib/dos/dosmapal.c +++ /dev/null @@ -1,61 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 && defined(WIN386) /* Watcom Win386 does NOT translate LPARAM for us */ -void far *win386_alt_winnt_MapAliasToFlat(DWORD farptr) { - /* FIXME: This only works by converting a 16:16 pointer directly to 16:32. - * It works perfectly fine in QEMU and DOSBox, but I seem to remember something - * about the x86 architecture and possible ways you can screw up using 16-bit - * data segments with 32-bit code. Are those rumors true? Am I going to someday - * load up Windows 3.1/95 on an ancient PC and find out this code crashes - * horribly or has random problems? - * - * We need this alternate path for Windows NT/2000/XP/Vista/7 because NTVDM.EXE - * grants Watcom386 a limited ~2GB limit for the flat data segment (usually - * 0x7B000000 or something like that) instead of the full 4GB limit the 3.x/9x/ME - * kernels usually grant. This matters because without the full 4GB limit we can't - * count on overflow/rollover to reach below our data segment base. Watcom386's - * MapAliasToFlat() unfortunately assumes just that. If we were to blindly rely - * on it, then we would work just fine under 3.x/9x/ME but crash under - * NT/2000/XP/Vista/7 the minute we need to access below our data segment (such as, - * when handling the WM_GETMINMAXINFO message the LPARAM far pointer usually - * points somewhere into NTVDM.EXE's DOS memory area when we're usually located - * at the 2MB mark or so) */ - return MK_FP(farptr>>16,farptr&0xFFFF); -} - -void far *win386_help_MapAliasToFlat(DWORD farptr) { - if (windows_mode == WINDOWS_NT) - return win386_alt_winnt_MapAliasToFlat(farptr); - - return (void far*)MapAliasToFlat(farptr); /* MapAliasToFlat() returns near pointer, convert to far! */ -} -#endif - diff --git a/src/lib/doslib/dos/dosntast.c b/src/lib/doslib/dos/dosntast.c deleted file mode 100644 index 1ce97737..00000000 --- a/src/lib/doslib/dos/dosntast.c +++ /dev/null @@ -1,515 +0,0 @@ -/* dosntast.c - * - * Windows NT VDD driver, dynamically loaded by code that needs it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - * - * This driver when loaded allows the DOS program to call Windows NT APIs - * such as version information or to use the WINMM WAVE API instead of - * NTVDM.EXE's shitty Sound Blaster emulation. - */ - -/* This is a Windows NT VDD driver */ -#define NTVDM_VDD_DRIVER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define DEBUG - -/* this is a DLL for Win32 */ -#if TARGET_MSDOS == 16 || !defined(TARGET_WINDOWS) -# error this is a DLL for Win32 only -#endif - -static HMODULE this_vdd = 0; - -/* If the DOS portion of this code calls NTVDM.EXE to load the same DLL again, NTVDM.EXE - * will do it, and allocate another handle. We'd rather not waste handles, so we leave - * a "mark" in the BIOS data area for the DOS program to find and know whether we're - * already loaded, and what handle to use. */ -static unsigned int vm_marked = 0; - -/* since 32-bit DOS builds must thunk to 16-bit mode to make calls, we use "fake" I/O - * ports to control other aspects such as sound output to make it easier for the DOS - * portion's interrupt controller to do it's job. But we never assume a fixed I/O port - * base because, who knows, the user's NTVDM environment may have special VDD drivers - * loaded. */ -static uint16_t vm_io_base = 0; -#define VM_IO_PORTS 0x20 - -/* +0x00 (WORD) W/O Function select. */ -/* +0x01 (WORD) W/O Sub-function select. */ - -/* Interrupt handlers may use these, to save the current state and use the interface themselves - * before restoring the interface for the code they interrupted. - * - * The idea being the DOS program should not have to CLI/STI all the time to avoid conflicts with their - * own interrupt handlers. */ - -/* +0x00 (INSB) R/O Read current function/subfunction selection [24 bytes] */ -/* +0x00 (OUTSB) W/O Write current function/subfunction selection [24 bytes] */ - -#pragma pack(push,1) -typedef struct { - uint16_t function; /* +0x00 */ - uint16_t subfunction; /* +0x02 */ - uint16_t __reserved__1; /* +0x04 */ - uint16_t __reserved__2; /* +0x06 */ - uint16_t __reserved__3; /* +0x08 */ - uint16_t __reserved__4; /* +0x0A */ - uint16_t __reserved__5; /* +0x0C */ - uint16_t __reserved__6; /* +0x0E */ - uint16_t __reserved__7; /* +0x10 */ - uint16_t __reserved__8; /* +0x12 */ - uint16_t __reserved__9; /* +0x14 */ - uint16_t __reserved__A; /* +0x16 */ -} IOIF_STATE; - -typedef struct { - WORD (*iop)(WORD param0); - void (*insb)(BYTE *data,WORD count); - void (*insw)(WORD *data,WORD count); - void (*outsb)(BYTE *data,WORD count); - void (*outsw)(WORD *data,WORD count); -} IOIF_COMMAND; -#pragma pack(pop) - -/* IO interface state */ -IOIF_STATE io_if={0}; -IOIF_COMMAND* io_if_command=NULL; /* what to do on command */ - -/* What the fucking hell Watcom? - * This function obviously never gets called, yet if I don't have it here - * your linker suddenly decides the standard C libray doesn't exist? What the fuck? */ -BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD fdwReason,LPVOID lpvReserved) { - /* FIXME: If Watcom demands this function, then why the fuck isn't it getting called on DLL load? - * What the fuck Open Watcom?!? */ - if (fdwReason == DLL_PROCESS_ATTACH) { - this_vdd = hInstance; - } - - return TRUE; -} - -/* DOSNTAST_FUNCTION_GENERAL------------------------------------------------------------ */ -static void ioif_function_general_messagebox_outsb(BYTE *data,WORD count) { - if (io_if.subfunction == DOSNTAST_FUN_GEN_SUB_MESSAGEBOX) { - /* whatever ASCIIZ string DS:SI points to is passed by NTVDM.EXE to us */ - MessageBoxA(NULL,data,"DOSNTAST.VDD",MB_OK); - } -} - -static IOIF_COMMAND ioif_command_general_messagebox = { - /* If only Watcom C/C++ supported GCC's .name = value structure definition style, - * like what they do in the Linux kernel, we could make this a lot more obvious */ - NULL, /* iop */ - NULL, /* insb */ - NULL, /* insw */ - ioif_function_general_messagebox_outsb, /* outsb */ - NULL /* outsw */ -}; - -/* this is called when Function == general and selection changes */ -static void ioif_function_general__SELECT() { - switch (io_if.subfunction) { - case DOSNTAST_FUN_GEN_SUB_MESSAGEBOX: - io_if_command = &ioif_command_general_messagebox; - break; - default: - io_if_command = NULL; - break; - } -} -/* DOSNTAST_FUNCTION_WINMM-------------------------------------------------------------- */ -static WORD ioif_function_winmm_waveOutGetNumDevs_iop(WORD param0) { - return (WORD)waveOutGetNumDevs(); -} - -static IOIF_COMMAND ioif_command_winmm_waveOutGetNumDevs = { - /* If only Watcom C/C++ supported GCC's .name = value structure definition style, - * like what they do in the Linux kernel, we could make this a lot more obvious */ - ioif_function_winmm_waveOutGetNumDevs_iop,/* iop */ - NULL, /* insb */ - NULL, /* insw */ - NULL, /* outsb */ - NULL /* outsw */ -}; - -static void ioif_function_winmm_waveOutOpen_outsb(BYTE *p,WORD count) { - /* in: EAX = uDeviceID - * EBX = dwCallbackInstance - * DS:ESI = pwfx (WAVEFORMATEX*) - * out: EAX = handle (or 0xFFFFFFFF if error) - * EBX = error */ - /* TODO */ - setEAX(0xFFFFFFFF); - setEBX(0xFFFFFFFF); -} - -static IOIF_COMMAND ioif_command_winmm_waveOutOpen = { - NULL, /* iop */ - NULL, /* insb */ - NULL, /* insw */ - ioif_function_winmm_waveOutOpen_outsb, /* outsb */ - NULL /* outsw */ -}; - -static void ioif_function_winmm_waveOutGetDevCaps_insb(BYTE *p,WORD count) { - /* EAX = uDeviceID - * EBX = cbwoc (sizeof of WAVEOUTCAPS) */ - setEAX(waveOutGetDevCaps(getEAX(),(WAVEOUTCAPS*)p,getEBX())); -} - -static IOIF_COMMAND ioif_command_winmm_waveOutGetDevCaps = { - NULL, /* iop */ - ioif_function_winmm_waveOutGetDevCaps_insb,/* insb */ - NULL, /* insw */ - NULL, /* outsb */ - NULL /* outsw */ -}; - -/* this is called when Function == general and selection changes */ -static void ioif_function_winmm__SELECT() { - switch (io_if.subfunction) { - case DOSNTAST_FUN_WINMM_SUB_waveOutGetNumDevs: - io_if_command = &ioif_command_winmm_waveOutGetNumDevs; - break; - case DOSNTAST_FUN_WINMM_SUB_waveOutGetDevCaps: - io_if_command = &ioif_command_winmm_waveOutGetDevCaps; - break; - case DOSNTAST_FUN_WINMM_SUB_waveOutOpen: - io_if_command = &ioif_command_winmm_waveOutOpen; - break; - default: - io_if_command = NULL; - break; - } -} -/* ------------------------------------------------------------------------------------- */ -void ioif_function__SELECT() { - switch (io_if.function) { - case DOSNTAST_FUNCTION_GENERAL: - ioif_function_general__SELECT(); - break; - case DOSNTAST_FUNCTION_WINMM: - ioif_function_winmm__SELECT(); - break; - default: - io_if_command = NULL; - } -} - -WORD ioif_command(WORD param0) { - if (io_if_command != NULL && io_if_command->iop != NULL) - return io_if_command->iop(param0); - - return 0xFFFFU; -} - -void ioif_command_insb(BYTE *data,WORD count) { - if (io_if_command != NULL && io_if_command->insb != NULL) - io_if_command->insb(data,count); -} - -void ioif_command_insw(WORD *data,WORD count) { - if (io_if_command != NULL && io_if_command->insw != NULL) - io_if_command->insw(data,count); -} - -void ioif_command_outsb(BYTE *data,WORD count) { - if (io_if_command != NULL && io_if_command->outsb != NULL) - io_if_command->outsb(data,count); -} - -void ioif_command_outsw(WORD *data,WORD count) { - if (io_if_command != NULL && io_if_command->outsw != NULL) - io_if_command->outsw(data,count); -} - -void save_ioif_state(IOIF_STATE *data,WORD count) { - if (count < sizeof(IOIF_STATE)) return; - *data = io_if; -} - -void restore_ioif_state(IOIF_STATE *data,WORD count) { - if (count < sizeof(IOIF_STATE)) return; - io_if = *data; - ioif_function__SELECT(); -} - -void ioif_function_select(WORD f) { - /* setting the function resets subfunction to zero */ - io_if.function = f; - io_if.subfunction = 0; - ioif_function__SELECT(); -} - -void ioif_subfunction_select(WORD f) { - io_if.subfunction = f; - ioif_function__SELECT(); -} - -/* when a DOS program does REP OUTSW, NTVDM.EXE provides the translated DS:SI for us. - * Nice. Except... when done from a 32-bit DOS program, it only translates DS:SI for us. - * Not very good when our DOS code uses *DS:ESI* as a flat 32-bit program! - * - * Speaking of which Microsoft why the hell isn't there a function to tell if the DS - * segment is 16-bit or 32-bit?!? - * - * NTS: This code assumes x86 32-bit NTVDM.EXE behavior where DOS memory is mapped to - * the 0x00000-0xFFFFF area within the NTVDM process. */ -BYTE *NTVDM_DS_ESI_correct(BYTE *p) { - /* if protected mode, replace the pointer given with a proper pointer to DS:ESI */ - if (getMSW() & 1) { - /* NTS: x86 behavior: VdmMapFlat() just returns a pointer. There's an - * "unmap" function but it's a stub. We take advantage of that. - * No punishment for "mapping" without "unmapping" */ - return (BYTE*)VdmMapFlat(getDS(),getESI(),VDM_PM); - } - - return (BYTE*)p; -} - -BYTE *NTVDM_ES_EDI_correct(BYTE *p) { - /* if protected mode, replace the pointer given with a proper pointer to DS:ESI */ - if (getMSW() & 1) { - /* NTS: x86 behavior: VdmMapFlat() just returns a pointer. There's an - * "unmap" function but it's a stub. We take advantage of that. - * No punishment for "mapping" without "unmapping" */ - return (BYTE*)VdmMapFlat(getES(),getEDI(),VDM_PM); - } - - return (BYTE*)p; -} - -/* IO handler */ -VOID WINAPI io_inw(WORD iport,WORD *data) { - if (iport == (vm_io_base+0x00)) /* function select */ - *data = io_if.function; - else if (iport == (vm_io_base+0x01)) /* subfunction select */ - *data = io_if.subfunction; - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - *data = ioif_command(0xFFFFU); - else - *data = 0xFFFF; /* default */ -} - -VOID WINAPI io_inb(WORD iport,BYTE *data) { - { - WORD w; - io_inw(iport,&w); - *data = (BYTE)w; /* default: do whatever our word-size version would and return lower bits */ - } -} - -VOID WINAPI io_insw(WORD iport,WORD *data,WORD count) { - data = (WORD*)NTVDM_ES_EDI_correct((BYTE*)data); - - if (iport == (vm_io_base+0x00)) - save_ioif_state((IOIF_STATE*)data,count*2U); /* FIXME: Microsoft isn't clear: is "count" the count of WORDs? or BYTEs? */ - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - ioif_command_insw(data,count); -} - -VOID WINAPI io_insb(WORD iport,BYTE *data,WORD count) { - data = NTVDM_ES_EDI_correct(data); - - if (iport == (vm_io_base+0x00)) - save_ioif_state((IOIF_STATE*)data,count); - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - ioif_command_insb(data,count); -} - -VOID WINAPI io_outw(WORD iport,WORD data) { - if (iport == (vm_io_base+0x00)) /* function select */ - ioif_function_select(data); - else if (iport == (vm_io_base+0x01)) /* subfunction select */ - ioif_subfunction_select(data); - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - ioif_command(data); -} - -VOID WINAPI io_outb(WORD iport,BYTE data) { - io_outw(iport,data); /* default: pass the byte value up to the word-size callback */ -} - -VOID WINAPI io_outsw(WORD iport,WORD *data,WORD count) { - data = (WORD*)NTVDM_DS_ESI_correct((BYTE*)data); - - if (iport == (vm_io_base+0x00)) - restore_ioif_state((IOIF_STATE*)data,count*2U); /* FIXME: Microsoft isn't clear: is "count" the count of WORDs? or BYTEs? */ - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - ioif_command_outsw(data,count); -} - -VOID WINAPI io_outsb(WORD iport,BYTE *data,WORD count) { - data = NTVDM_DS_ESI_correct(data); - - if (iport == (vm_io_base+0x00)) - restore_ioif_state((IOIF_STATE*)data,count); - else if (iport == (vm_io_base+0x02)) /* command (param 0 in data) */ - ioif_command_outsb(data,count); -} - -static void mark_vm() { - unsigned char *ptr; - unsigned int i=0xF0/*start at 0x40:0xF0*/,max=0x200; - - if (vm_marked) return; - - ptr = VdmMapFlat(0x40,0x00,VDM_V86); - if (ptr == NULL) return; - - /* find an empty spot to place our signature. the client is expected - * to write the handle value next to it */ - while (i < max) { - if (!memcmp(ptr+i,"\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0",20)) - break; - - i++; - } - - if (i < max) - memcpy(ptr+i,"DOSNTAST.VDD\xFF\xFF\xFF\xFF",16); - - VdmUnmapFlat(0x40,0x00,(DWORD)ptr,VDM_V86); - vm_marked = i+0x400; -} - -static void remove_vm_mark() { - unsigned char *ptr; - - if (vm_marked >= 0x400 && vm_marked <= 0x600) { - ptr = VdmMapFlat(0x40,0x00,VDM_V86); - if (ptr == NULL) return; - - memset(ptr+vm_marked-0x400,0,16); - - VdmUnmapFlat(0x40,0x00,(DWORD)ptr,VDM_V86); - vm_marked = 0; - } -} - -static void choose_io_port() { - VDD_IO_HANDLERS h; - VDD_IO_PORTRANGE pr; - - if (vm_io_base != 0) return; - - /* FIXME: Remove this when Watcom C/C++ actually calls up to DllMain on entry point */ - if (this_vdd == NULL) - this_vdd = GetModuleHandle("DOSNTAST.VDD"); - if (this_vdd == NULL) { - MessageBox(NULL,"NO!","",MB_OK); - return; - } - - h.inb_handler = io_inb; - h.inw_handler = io_inw; - h.insb_handler = io_insb; - h.insw_handler = io_insw; - h.outb_handler = io_outb; - h.outw_handler = io_outw; - h.outsb_handler = io_outsb; - h.outsw_handler = io_outsw; - - /* choose an I/O port */ - for (vm_io_base=0x1000;vm_io_base <= 0xF000;vm_io_base += 0x80) { - pr.First = vm_io_base; - pr.Last = vm_io_base + VM_IO_PORTS - 1; - - if (VDDInstallIOHook(this_vdd,1/*cPortRange*/,&pr,&h)) { - /* got it */ - break; - } - } - - if (vm_io_base > 0xF000) { - /* didn't find any */ - MessageBox(NULL,"Failed","",MB_OK); - vm_io_base = 0; - } -} - -static void remove_io_port() { - VDD_IO_PORTRANGE r; - - if (vm_io_base == 0) return; - r.First = vm_io_base; - r.Last = vm_io_base + VM_IO_PORTS - 1; - VDDDeInstallIOHook(this_vdd,1,&r); - vm_io_base = 0; -} - -/* Microsoft documentation on this "init" routine is lacking */ -__declspec(dllexport) void WINAPI Init() { - if (!vm_marked) mark_vm(); - if (vm_io_base == 0) choose_io_port(); -} - -__declspec(dllexport) void WINAPI Dispatch() { - uint32_t command; - char tmp[64]; - - command = getEBX(); - if (command == DOSNTAST_INIT_REPORT_HANDLE) { - setEBX(0x55AA55AA); - setECX(vm_marked); - } - else if (command == DOSNTAST_GETVERSIONEX) { - unsigned char *ptr = NULL; - uint16_t seg; - uint32_t ofs; - uint8_t mode; - - seg = getDS(); - ofs = getESI(); - mode = (getCX() == 1) ? VDM_PM : VDM_V86; - - ptr = VdmMapFlat(seg,ofs,mode); - if (ptr != NULL) { - setEBX(GetVersionEx((OSVERSIONINFO*)ptr)); - VdmUnmapFlat(seg,ofs,(DWORD)ptr,mode); - } - } - else if (command == DOSNTAST_GET_TICK_COUNT) { - setEBX(GetTickCount()); - } - /* the DOS program sends this when it's about to unload us. - * I originally wanted DllMain to do this on PROCESS_DETACH but, - * for some reason, that function isn't getting called. */ - else if (command == DOSNTAST_GET_IO_PORT) { - setEBX(0x55AA55AA); - setEDX(vm_io_base); - } - else if (command == DOSNTAST_NOTIFY_UNLOAD) { - if (vm_io_base) remove_io_port(); - if (vm_marked) remove_vm_mark(); - setEBX(0x55AA55AA); - } - else { - sprintf(tmp,"0x%08lX\n",(unsigned long)command); - MessageBox(NULL,tmp,"Unknown command",MB_OK); - } -} - diff --git a/src/lib/doslib/dos/dosntvdm.c b/src/lib/doslib/dos/dosntvdm.c deleted file mode 100644 index 66f01ffd..00000000 --- a/src/lib/doslib/dos/dosntvdm.c +++ /dev/null @@ -1,432 +0,0 @@ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* DEBUG: Flush out calls that aren't there */ -#ifdef TARGET_OS2 -# define int86 ___EVIL___ -# define int386 ___EVIL___ -# define ntvdm_RegisterModule ___EVIL___ -# define ntvdm_UnregisterModule ___EVIL___ -# define _dos_getvect ___EVIL___ -# define _dos_setvect ___EVIL___ -#endif - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) -uint8_t ntvdm_dosntast_tried = 0; -uint16_t ntvdm_dosntast_handle = (~0U); -#endif - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -uint16_t ntvdm_dosntast_io_base = 0; - -uint16_t ntvdm_dosntast_detect() { - const char *str = "DOSNTAST.VDD"; - uint16_t str_len = 12; - uint16_t handle = (~0U); - unsigned int i,max=0x200; -#if TARGET_MSDOS == 32 - unsigned char *p = (unsigned char*)0x400; -#else - unsigned char FAR *p = (unsigned char FAR*)MK_FP(0x40,0x00); -#endif - - for (i=0;i <= (max-str_len);i++) { -#if TARGET_MSDOS == 32 - if (memcmp(str,p+i,str_len) == 0) - handle = *((uint16_t*)(p+i+str_len)); -#else - if (_fmemcmp(str,p+i,str_len) == 0) - handle = *((uint16_t FAR*)(p+i+str_len)); -#endif - - if (ntvdm_RM_ERR(handle)) - handle = DOSNTAST_HANDLE_UNASSIGNED; - else - break; - } - - return handle; -} - -int ntvdm_dosntast_load_vdd() { - uint32_t t1=0,t2=0; - - /* TODO: Right now this works for the current path, or if it's in the Windows system dir. - * Adopt a strategy where the user can also set an environment variable to say where - * the DLL is. */ - ntvdm_dosntast_handle = ntvdm_RegisterModule("DOSNTAST.VDD","Init","Dispatch"); - if (ntvdm_RM_ERR(ntvdm_dosntast_handle)) return 0; - - /* test out the dispatch call: give the DLL back his handle */ -#if TARGET_MSDOS == 32 - { - struct dpmi_realmode_call rc={0}; - rc.ebx = DOSNTAST_INIT_REPORT_HANDLE_C; - rc.ecx = ntvdm_dosntast_handle; - ntvdm_DispatchCall_dpmi(ntvdm_dosntast_handle,&rc); - t1 = rc.ebx; - t2 = rc.ecx; - } -#else - t1 = ntvdm_dosntast_handle; - __asm { - .386p - push ebx - push ecx - mov ebx,DOSNTAST_INIT_REPORT_HANDLE - mov eax,t1 - mov ecx,eax - ntvdm_Dispatch_ins_asm_db - mov t1,ebx - mov t2,ecx - pop ecx - pop ebx - } -#endif - - if (t1 != 0x55AA55AA || !(t2 >= 0x400 && t2 <= 0x600)) { - ntvdm_UnregisterModule(ntvdm_dosntast_handle); - return 0; - } -#if TARGET_MSDOS == 32 - if (memcmp((void*)t2,"DOSNTAST.VDD\xFF\xFF",14)) { - ntvdm_UnregisterModule(ntvdm_dosntast_handle); - return 0; - } - *((uint16_t*)(t2+12)) = ntvdm_dosntast_handle; -#else - if (_fmemcmp(MK_FP(t2>>4,t2&0xF),"DOSNTAST.VDD\xFF\xFF",14)) { - ntvdm_UnregisterModule(ntvdm_dosntast_handle); - return 0; - } - *((uint16_t FAR*)MK_FP((t2+12)>>4,(t2+12)&0xF)) = ntvdm_dosntast_handle; -#endif - - return (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED)?1:0; -} - -unsigned int ntvdm_dosntast_waveOutGetNumDevs() { - if (ntvdm_dosntast_io_base == 0) - return 0; - - /* FUNCTION */ - outpw(ntvdm_dosntast_io_base+0,DOSNTAST_FUNCTION_WINMM); - /* SUBFUNCTION */ - outpw(ntvdm_dosntast_io_base+1,DOSNTAST_FUN_WINMM_SUB_waveOutGetNumDevs); - /* COMMAND */ - return inpw(ntvdm_dosntast_io_base+2); -} - -uint32_t ntvdm_dosntast_waveOutGetDevCaps(uint32_t uDeviceID,WAVEOUTCAPS *pwoc,uint16_t cbwoc) { - uint32_t retv=0,port; - - if (ntvdm_dosntast_io_base == 0) - return 0; - - /* FUNCTION */ - outpw(ntvdm_dosntast_io_base+0,DOSNTAST_FUNCTION_WINMM); - /* SUBFUNCTION */ - outpw(ntvdm_dosntast_io_base+1,DOSNTAST_FUN_WINMM_SUB_waveOutGetDevCaps); - /* COMMAND */ - port = ntvdm_dosntast_io_base+2; - -#if TARGET_MSDOS == 32 - __asm { - .386p - pushad - /* we trust Watcom left ES == DS */ - mov edx,port - mov eax,uDeviceID - movzx ebx,cbwoc - mov ecx,1 - mov edi,pwoc - rep insb - popad - } -#elif defined(__LARGE__) || defined(__COMPACT__) - __asm { - .386p - push es - pushad - mov edx,port - mov eax,uDeviceID - movzx ebx,cbwoc - mov ecx,1 - les di,pwoc - rep insb - popad - pop es - } -#else - __asm { - .386p - pushad - push es - mov ax,ds - mov es,ax - mov edx,port - mov eax,uDeviceID - movzx ebx,cbwoc - mov ecx,1 - mov di,pwoc - rep insb - pop es - popad - } -#endif - - return retv; -} - -int ntvdm_dosntast_MessageBox(const char *text) { - uint16_t port; - - if (ntvdm_dosntast_io_base == 0) - return 0; - - /* FUNCTION */ - outpw(ntvdm_dosntast_io_base+0,DOSNTAST_FUNCTION_GENERAL); - /* SUBFUNCTION */ - outpw(ntvdm_dosntast_io_base+1,DOSNTAST_FUN_GEN_SUB_MESSAGEBOX); - /* COMMAND */ - port = ntvdm_dosntast_io_base+2; -#if TARGET_MSDOS == 32 - __asm { - .386p - push esi - push ecx - push edx - cld - movzx edx,port - mov esi,text - mov ecx,1 /* NTS: duration dosn't matter, our DLL passes DS:SI directly to MessageBoxA */ - rep outsb - pop edx - pop ecx - pop esi - } -#elif defined(__LARGE__) || defined(__COMPACT__) - __asm { - .386p - push ds - push si - push cx - push dx - cld - mov dx,port - lds si,text - mov cx,1 - rep outsb - pop dx - pop cx - pop si - pop ds - } -#else - __asm { - .386p - push si - push cx - push dx - cld - mov dx,port - mov si,text - mov cx,1 - rep outsb - pop dx - pop cx - pop si - } -#endif - - return 1; -} - -/* initialize the library. - * if dont_load_dosntast is set, then it will not load the VDD driver but will use the driver if already loaded */ -int ntvdm_dosntast_init() { - uint32_t t1=0,t2=0; - - if (!ntvdm_dosntast_tried) { - ntvdm_dosntast_tried = 1; - ntvdm_dosntast_io_base = 0; - - if (lib_dos_option.dont_use_dosntast) { - ntvdm_dosntast_handle = DOSNTAST_HANDLE_UNASSIGNED; - return 0; - } - - /* It turns out if you request the same DLL again and again, NTVDM.EXE will not return the - * same handle, it will allocate another one. To avoid exhausting it handles, we first - * detect whether the DLL is already loaded. - * - * We do this by scanning the 0x40-0x50 segments (the BIOS data area) for a signature value - * placed by the DLL. Following the signature is the handle value. */ - ntvdm_dosntast_handle = ntvdm_dosntast_detect(); - if (ntvdm_dosntast_handle == DOSNTAST_HANDLE_UNASSIGNED && !lib_dos_option.dont_load_dosntast) - ntvdm_dosntast_load_vdd(); - - /* we need to know the IO port base */ - if (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED) { - if (!ntvdm_rm_code_alloc()) - return ntvdm_RM_ERR_NOT_AVAILABLE; - -#if TARGET_MSDOS == 32 - { - struct dpmi_realmode_call rc={0}; - rc.ebx = (uint32_t)(DOSNTAST_GET_IO_PORT_C); /* <= FIXME: "constant out of range" what the fuck are you talking about Watcom? */ - ntvdm_DispatchCall_dpmi(ntvdm_dosntast_handle,&rc); - t1 = rc.ebx; - t2 = rc.edx; - } -#else - t1 = ntvdm_dosntast_handle; - __asm { - .386p - push ebx - push edx - mov ebx,DOSNTAST_GET_IO_PORT - mov eax,t1 - ntvdm_Dispatch_ins_asm_db - mov t1,ebx - mov t2,edx - pop edx - pop ebx - } -#endif - - if (t1 == 0x55AA55AAUL) - ntvdm_dosntast_io_base = (uint16_t)t2; - } - } - - return (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED)?1:0; -} - -void ntvdm_dosntast_unload() { - if (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED) { -#if TARGET_MSDOS == 32 - { - struct dpmi_realmode_call rc={0}; - rc.ebx = DOSNTAST_NOTIFY_UNLOAD_C; - ntvdm_DispatchCall_dpmi(ntvdm_dosntast_handle,&rc); - } -#else - { - const uint16_t h = ntvdm_dosntast_handle; - - __asm { - .386p - mov ebx,DOSNTAST_NOTIFY_UNLOAD - mov ax,h - ntvdm_Dispatch_ins_asm_db - } - } -#endif - - ntvdm_UnregisterModule(ntvdm_dosntast_handle); - ntvdm_dosntast_handle = DOSNTAST_HANDLE_UNASSIGNED; - } -} - -uint32_t ntvdm_dosntast_GetTickCount() { - uint32_t retv = 0xFFFFFFFFUL; - - if (ntvdm_dosntast_handle == DOSNTAST_HANDLE_UNASSIGNED) - return 0; /* failed */ - if (!ntvdm_rm_code_alloc()) - return 0; - -#if TARGET_MSDOS == 32 - { - struct dpmi_realmode_call rc={0}; - rc.ebx = DOSNTAST_GET_TICK_COUNT_C; - ntvdm_DispatchCall_dpmi(ntvdm_dosntast_handle,&rc); - retv = rc.ebx; - } -#else - { - const uint16_t h = ntvdm_dosntast_handle; - - __asm { - .386p - push ebx - mov ebx,DOSNTAST_GET_TICK_COUNT - mov ax,h - ntvdm_Dispatch_ins_asm_db - mov retv,ebx - pop ebx - } - } -#endif - - return retv; -} - -unsigned int ntvdm_dosntast_getversionex(OSVERSIONINFO *ovi) { - unsigned int retv=0; - - if (ntvdm_dosntast_handle == DOSNTAST_HANDLE_UNASSIGNED) - return 0; /* failed */ - if (!ntvdm_rm_code_alloc()) - return 0; - -#if TARGET_MSDOS == 32 - { - uint16_t myds=0; - struct dpmi_realmode_call rc={0}; - __asm mov myds,ds - rc.ebx = DOSNTAST_GETVERSIONEX_C; - rc.esi = (uint32_t)ovi; - rc.ecx = 1; - rc.ds = myds; - ntvdm_DispatchCall_dpmi(ntvdm_dosntast_handle,&rc); - retv = rc.ebx; - } -#else - { - const uint16_t s = FP_SEG(ovi),o = FP_OFF(ovi),h = ntvdm_dosntast_handle; - - __asm { - .386p - push ds - push esi - push ecx - mov ebx,DOSNTAST_GETVERSIONEX - xor esi,esi - mov ax,h - mov si,s - mov ds,si - mov si,o - xor cx,cx - ntvdm_Dispatch_ins_asm_db - mov retv,bx - pop esi - pop ebx - pop ds - } - } -#endif - - return retv; -} - -#endif - diff --git a/src/lib/doslib/dos/dosntvdm.h b/src/lib/doslib/dos/dosntvdm.h deleted file mode 100644 index 7857c8b7..00000000 --- a/src/lib/doslib/dos/dosntvdm.h +++ /dev/null @@ -1,26 +0,0 @@ - -#include -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* NTVDM.EXE DOSNTAST.VDD call support */ -#include -#endif - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -extern uint8_t ntvdm_dosntast_tried; -extern uint16_t ntvdm_dosntast_handle; -#endif - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -extern uint16_t ntvdm_dosntast_io_base; - -int ntvdm_dosntast_init(); -void ntvdm_dosntast_unload(); -uint32_t ntvdm_dosntast_GetTickCount(); -int ntvdm_dosntast_MessageBox(const char *text); -unsigned int ntvdm_dosntast_waveOutGetNumDevs(); -unsigned int ntvdm_dosntast_getversionex(OSVERSIONINFO *ovi); -uint32_t ntvdm_dosntast_waveOutGetDevCaps(uint32_t uDeviceID,WAVEOUTCAPS *pwoc,uint16_t cbwoc); -#endif - diff --git a/src/lib/doslib/dos/dospsp.c b/src/lib/doslib/dos/dospsp.c deleted file mode 100644 index 16932cc3..00000000 --- a/src/lib/doslib/dos/dospsp.c +++ /dev/null @@ -1,47 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int dos_parse_psp(uint16_t seg,struct dos_psp_cooked *e) { - unsigned int i,o=0; - -#if TARGET_MSDOS == 32 - e->raw = (unsigned char*)((uint32_t)seg << 4UL); -#else - e->raw = (unsigned char FAR*)MK_FP(seg,0); -#endif - e->memsize = *((uint16_t FAR*)(e->raw + 0x02)); - e->callpsp = *((uint16_t FAR*)(e->raw + 0x16)); - e->env = *((uint16_t FAR*)(e->raw + 0x2C)); - for (i=0;i < (unsigned char)e->raw[0x80] && e->raw[0x81+i] == ' ';) i++; /* why is there all this whitespace at the start? */ - for (;i < (unsigned char)e->raw[0x80];i++) e->cmd[o++] = e->raw[0x81+i]; - e->cmd[o] = 0; - return 1; -} - diff --git a/src/lib/doslib/dos/dossmdrv.c b/src/lib/doslib/dos/dossmdrv.c deleted file mode 100644 index 3c72b909..00000000 --- a/src/lib/doslib/dos/dossmdrv.c +++ /dev/null @@ -1,244 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2)) -unsigned short smartdrv_version = 0xFFFF; -int smartdrv_fd = -1; -#endif - -#if (TARGET_MSDOS == 16 || TARGET_MSDOS == 32) && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -int smartdrv_close() { - if (smartdrv_fd >= 0) { - close(smartdrv_fd); - smartdrv_fd = -1; - } - - return 0; -} - -int smartdrv_flush() { - if (smartdrv_version == 0xFFFF || smartdrv_version == 0) - return 0; - - if (smartdrv_version >= 0x400) { /* SMARTDRV 4.xx and later */ -#if TARGET_MSDOS == 32 - __asm { - push eax - push ebx - mov eax,0x4A10 ; SMARTDRV - mov ebx,0x0001 ; FLUSH BUFFERS (COMMIT CACHE) - int 0x2F - pop ebx - pop eax - } -#else - __asm { - push ax - push bx - mov ax,0x4A10 ; SMARTDRV - mov bx,0x0001 ; FLUSH BUFFERS (COMMIT CACHE) - int 0x2F - pop bx - pop ax - } -#endif - } - else if (smartdrv_version >= 0x300 && smartdrv_version <= 0x3FF) { /* SMARTDRV 3.xx */ - char buffer[0x1]; -#if TARGET_MSDOS == 32 -#else - char far *bptr = (char far*)buffer; -#endif - int rd=0; - - if (smartdrv_fd < 0) - return 0; - - buffer[0] = 0; /* flush cache */ -#if TARGET_MSDOS == 32 - /* FIXME: We do not yet have a 32-bit protected mode version. - * DOS extenders do not appear to translate AX=0x4403 properly */ -#else - __asm { - push ax - push bx - push cx - push dx - push ds - mov ax,0x4403 ; IOCTL SMARTAAR CACHE CONTROL - mov bx,smartdrv_fd - mov cx,0x1 ; 0x01 bytes - lds dx,word ptr [bptr] - int 0x21 - jc err1 - mov rd,ax ; CF=0, AX=bytes written -err1: pop ds - pop dx - pop cx - pop bx - pop ax - } -#endif - - if (rd == 0) - return 0; - } - - return 1; -} - -int smartdrv_detect() { - unsigned int rvax=0,rvbp=0; - - if (smartdrv_version == 0xFFFF) { - /* Is Microsoft SMARTDRV 4.x or equivalent disk cache present? */ - -#if TARGET_MSDOS == 32 - __asm { - push eax - push ebx - push ecx - push edx - push esi - push edi - push ebp - push ds - mov eax,0x4A10 ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS - mov ebx,0 - mov ecx,0xEBAB ; "BABE" backwards - xor ebp,ebp - int 0x2F ; multiplex (hope your DOS extender supports it properly!) - pop ds - mov ebx,ebp ; copy EBP to EBX. Watcom C uses EBP to refer to the stack! - pop ebp - mov rvax,eax ; we only care about EAX and EBP(now EBX) - mov rvbp,ebx - pop edi - pop esi - pop edx - pop ecx - pop ebx - pop eax - } -#else - __asm { - push ax - push bx - push cx - push dx - push si - push di - push bp - push ds - mov ax,0x4A10 ; SMARTDRV 4.xx INSTALLATION CHECK AND HIT RATIOS - mov bx,0 - mov cx,0xEBAB ; "BABE" backwards - xor bp,bp - int 0x2F ; multiplex - pop ds - mov bx,bp ; copy BP to BX. Watcom C uses BP to refer to the stack! - pop bp - mov rvax,ax ; we only care about EAX and EBP(now EBX) - mov rvbp,bx - pop di - pop si - pop dx - pop cx - pop bx - pop ax - } -#endif - - if ((rvax&0xFFFF) == 0xBABE && (rvbp&0xFFFF) >= 0x400 && (rvbp&0xFFFF) <= 0x5FF) { - /* yup. SMARTDRV 4.xx! */ - smartdrv_version = (rvbp&0xFF00) + (((rvbp>>4)&0xF) * 10) + (rvbp&0xF); /* convert BCD to decimal */ - } - - if (smartdrv_version == 0xFFFF) { - char buffer[0x28]; -#if TARGET_MSDOS == 32 -#else - char far *bptr = (char far*)buffer; -#endif - int rd=0; - - memset(buffer,0,sizeof(buffer)); - - /* check for SMARTDRV 3.xx */ - smartdrv_fd = open("SMARTAAR",O_RDONLY); - if (smartdrv_fd >= 0) { - /* FIXME: The DOS library should provide a common function to do IOCTL read/write character "control channel" functions */ -#if TARGET_MSDOS == 32 - /* FIXME: We do not yet have a 32-bit protected mode version. - * DOS extenders do not appear to translate AX=0x4402 properly */ -#else - __asm { - push ax - push bx - push cx - push dx - push ds - mov ax,0x4402 ; IOCTL SMARTAAR GET CACHE STATUS - mov bx,smartdrv_fd - mov cx,0x28 ; 0x28 bytes - lds dx,word ptr [bptr] - int 0x21 - jc err1 - mov rd,ax ; CF=0, AX=bytes read -err1: pop ds - pop dx - pop cx - pop bx - pop ax - } -#endif - - /* NTS: Despite reading back 0x28 bytes of data, this IOCTL - * returns AX=1 for some reason. */ - if (rd > 0 && rd <= 0x28) { - if (buffer[0] == 1/*write through flag*/ && buffer[15] == 3/*major version number*/) { /* SMARTDRV 3.xx */ - smartdrv_version = ((unsigned short)buffer[15] << 8) + ((unsigned short)buffer[14]); - } - else { - close(smartdrv_fd); - } - } - } - } - - /* didn't find anything. then no SMARTDRV */ - if (smartdrv_version == 0xFFFF) - smartdrv_version = 0; - } - - return (smartdrv_version != 0); -} -#endif - diff --git a/src/lib/doslib/dos/dosvbox.c b/src/lib/doslib/dos/dosvbox.c deleted file mode 100644 index 84616ebb..00000000 --- a/src/lib/doslib/dos/dosvbox.c +++ /dev/null @@ -1,178 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(TARGET_WINDOWS) || defined(TARGET_OS2) -#else -/* as seen in the ROM area: "BIOS: "+NUL+"VirtualBox 4.1.8_OSE" around 0xF000:0x0130 */ -static const char *virtualbox_bios_str = "BIOS: "; -static const char *virtualbox_vb_str = "VirtualBox "; -#endif - -/* the ROM area doesn't change. so remember our last result */ -#if defined(TARGET_WINDOWS) || defined(TARGET_OS2) -#else -static signed char virtualbox_detect_cache = -1; -#endif - -/* unlike DOSBox, VirtualBox's ROM BIOS contains it's version number, which we copy down here */ -char virtualbox_version_str[64]={0}; - -int detect_virtualbox_emu() { -#if defined(TARGET_OS2) - /* TODO: So... how does one read the ROM BIOS area from OS/2? */ - return 0; -#elif defined(TARGET_WINDOWS) - /* TODO: I know that from within Windows there are various ways to scan the ROM BIOS area. - * Windows 1.x and 2.x (if real mode) we can just use MK_FP as we do under DOS, but - * we have to use alternate means if Windows is in protected mode. Windows 2.x/3.x protected - * mode (and because of compatibility, Windows 95/98/ME), there are two methods open to us: - * One is to use selector constants that are hidden away in KRNL386.EXE with names like _A0000, - * _B0000, etc. They are data selectors that when loaded into the segment registers point to - * their respective parts of DOS adapter ROM and BIOS ROM. Another way is to use the Win16 - * API to create a data selector that points to the BIOS. Windows 386 Enhanced mode may map - * additional things over the unused parts of adapter ROM, but experience shows that it never - * relocates or messes with the VGA BIOS or with the ROM BIOS, - * - * My memory is foggy at this point, but I remember that under Windows XP SP2, one of the - * above Win16 methods still worked even from under the NT kernel. - * - * For Win32 applications, if the host OS is Windows 3.1 Win32s or Windows 95/98/ME, we can - * take advantage of a strange quirk in the way the kernel maps the lower 1MB. For whatever - * reason, the VGA RAM, adapter ROM, and ROM BIOS areas are left open even for Win32 applications - * with no protection. Thus, a Win32 programmer can just make a pointer like - * char *a = (char*)0xA0000 and scribble on legacy VGA RAM to his heart's content (though on - * modern PCI SVGA hardware the driver probably instructs the card to disable VGA compatible - * mapping). In fact, this ability to scribble on RAM directly is at the heart of one of Microsoft's - * earliest and hackiest "Direct Draw" interfaces known as "DISPDIB.DLL", a not-to-well documented - * library responsible for those Windows 3.1 multimedia apps and games that were somehow able to - * run full-screen 320x200x256 color VGA despite being Windows GDI-based apps. Ever wonder how the - * MCI AVI player was able to go full-screen when DirectX and WinG were not invented yet? Now you - * know :) - * - * There are some VFW codecs out there as well, that also like to abuse DISPDIB.DLL for "fullscreen" - * modes. One good example is the old "Motion Pixels" codec, that when asked to go fullscreen, - * uses DISPDIB.DLL and direct VGA I/O port trickery to effectively set up a 320x480 256-color mode, - * which it then draws on "fake hicolor" style to display the video (though a bit dim since you're - * sort of watching a video through a dithered mesh, but...) - * - * In case you were probably wondering, no, Windows NT doesn't allow Win32 applications the same - * privilege. Win32 apps writing to 0xA0000 would page fault and crash. Curiously enough though, - * NTVDM.EXE does seem to open up the 0xA0000-0xFFFFF memory area to Win16 applications if they - * use the right selectors and API calls. */ - return 0; -#else - int i,j; -# if TARGET_MSDOS == 32 - const char *scan; -# else - const char far *scan; -# endif - - probe_dos(); - if (virtualbox_detect_cache >= 0) - return (int)virtualbox_detect_cache; - - virtualbox_detect_cache=0; - -# if TARGET_MSDOS == 32 - if (dos_flavor == DOS_FLAVOR_FREEDOS) { - /* FIXME: I have no idea why but FreeDOS 1.0 has a strange conflict with DOS32a where if this code - * tries to read the ROM BIOS it causes a GPF and crashes (or sometimes runs off into the - * weeds leaving a little garbage on the screen). DOS32a's register dump seems to imply that - * at one point our segment limits were suddenly limited to 1MB (0xFFFFF). I have no clue - * what the hell is triggering it, but I know from testing we can avoid that crash by not - * scanning. */ - if (freedos_kernel_version == 0x000024UL) /* 0.0.36 */ - return (virtualbox_detect_cache=0); - } -# endif - - /* test #1: the ROM BIOS region just prior to 0xF0000 is all zeros. - * NTS: VirtualBox 4.1.8 also seems to have the ACPI tables at 0xE000:0x0000 */ -# if TARGET_MSDOS == 32 - scan = (const char*)0xEFF00; -# else - scan = (const char far*)MK_FP(0xE000,0xFF00); -# endif - for (i=0;i < 256;i++) { - if (scan[i] != 0) - return virtualbox_detect_cache; - } - - /* test #2: somewhere within the first 4KB, are the strings "BIOS: " and - * "VirtualBox " side by side separated by a NUL. The "VirtualBox" string is - * followed by the version number, and "_OSE" if the open source version. */ -# if TARGET_MSDOS == 32 - scan = (const char*)0xF0000; -# else - scan = (const char far*)MK_FP(0xF000,0x0000); -# endif - for (i=0,j=0;i < 4096;i++) { - if (scan[i] == virtualbox_bios_str[j]) { - j++; - if (virtualbox_bios_str[j] == 0 && scan[i+1] == 0) { - /* good. found it. stop there. */ - i++; - break; - } - } - else { - j=0; - } - } - /* if we didn't find the first string, then give up */ - if (i >= 4096) return virtualbox_detect_cache; - - /* make sure the next string is "VirtualBox " */ - for (/*do not reset 'i'*/j=0;i < 4096;i++) { - if (scan[i] == virtualbox_vb_str[j]) { - j++; - if (virtualbox_vb_str[j] == 0) { - /* good. found it. stop there. */ - virtualbox_detect_cache = 1; - break; - } - } - else { - j=0; - } - } - if (i >= 4096) return virtualbox_detect_cache; - - /* 'i' now points at the version part of the string. copy it down */ - while (i < 4096 && scan[i] == ' ') i++; - for (j=0;j < (sizeof(virtualbox_version_str)-1) && i < 4096;) - virtualbox_version_str[j++] = scan[i++]; - virtualbox_version_str[j] = 0; - - return virtualbox_detect_cache; -#endif -} - diff --git a/src/lib/doslib/dos/dosvcpi.c b/src/lib/doslib/dos/dosvcpi.c deleted file mode 100644 index dacb1a31..00000000 --- a/src/lib/doslib/dos/dosvcpi.c +++ /dev/null @@ -1,140 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -unsigned char vcpi_probed = 0; -unsigned char vcpi_present = 0; -unsigned char vcpi_major_version,vcpi_minor_version; - -/* NTS: According to the VCPI specification this call is only supposed to report - * the physical memory address for anything below the 1MB boundary. And so - * far EMM386.EXE strictly adheres to that rule by not reporting success for - * addresses >= 1MB. The 32-bit limitation is a result of the VCPI system - * call, since the physical address is returned in EDX. */ -uint32_t dos_linear_to_phys_vcpi(uint32_t pn) { - uint32_t r=0xFFFFFFFFUL; - - __asm { - .586p - mov ax,0xDE06 - mov ecx,pn - int 67h - or ah,ah - jnz err1 ; if AH == 0 then EDX = page phys addr - mov r,edx -err1: - } - - return r; -} - -#if !defined(TARGET_WINDOWS) -static int int67_null() { - uint32_t ptr; - -#if TARGET_MSDOS == 32 - ptr = ((uint32_t*)0)[0x67]; -#else - ptr = *((uint32_t far*)MK_FP(0,0x67*4));; -#endif - - return (ptr == 0); -} -#endif - -int probe_vcpi() { -#if defined(TARGET_WINDOWS) - if (!vcpi_probed) { - /* NTS: Whoever said Windows 3.0 used VCPI at it's core, is a liar */ - vcpi_probed = 1; - vcpi_present = 0; - } -#else -/* =================== MSDOS ================== */ - unsigned char err=0xFF; - - if (!vcpi_probed) { - vcpi_probed = 1; - - /* if virtual 8086 mode isn't active, then VCPI isn't there */ - /* FIXME: What about cases where VCPI might be there, but is inactive (such as: EMM386.EXE resident but disabled) */ - if (!cpu_v86_active) - return 0; - - /* NOTE: VCPI can be present whether we're 16-bit real mode or - * 32-bit protected mode. Unlike DPMI we cannot assume it's - * present just because we're 32-bit. */ - - /* Do not call INT 67h if the vector is uninitialized */ - if (int67_null()) - return 0; - - /* Do not attempt to probe for VCPI if Windows 3.1/95/98/ME - * is running. Windows 9x blocks VCPI and if called, interrupts - * our execution to inform the user that the program should be - * run in DOS mode. */ - detect_windows(); - if (windows_mode != WINDOWS_NONE) - return 0; - - /* NTS: we load DS for each var because Watcom might put it in - * another data segment, especially in Large memory model. - * failure to account for this was the cause of mysterious - * hangs and crashes. */ - __asm { - ; NTS: Save DS and ES because Microsoft EMM386.EXE - ; appears to change their contents. - push ds - push es - mov ax,0xDE00 - int 67h - mov err,ah - - mov ax,seg vcpi_major_version - mov ds,ax - mov vcpi_major_version,bh - - mov ax,seg vcpi_minor_version - mov ds,ax - mov vcpi_minor_version,bl - - pop es - pop ds - } - - if (err != 0) - return 0; - - vcpi_present = 1; - } -#endif - - return vcpi_present; -} - diff --git a/src/lib/doslib/dos/doswin.c b/src/lib/doslib/dos/doswin.c deleted file mode 100644 index 973f7e44..00000000 --- a/src/lib/doslib/dos/doswin.c +++ /dev/null @@ -1,642 +0,0 @@ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* DEBUG: Flush out calls that aren't there */ -#ifdef TARGET_OS2 -# define int86 ___EVIL___ -# define int386 ___EVIL___ -# define ntvdm_RegisterModule ___EVIL___ -# define ntvdm_UnregisterModule ___EVIL___ -# define _dos_getvect ___EVIL___ -# define _dos_setvect ___EVIL___ -#endif - -const char *windows_version_method = NULL; - -/* return value: - * 0 = not running under Windows - * 1 = running under Windows */ -const char *windows_emulation_comment_str = NULL; -uint8_t windows_emulation = 0; -uint16_t windows_version = 0; /* NOTE: 0 for Windows NT */ -uint8_t windows_mode = 0; -uint8_t windows_init = 0; - -const char *windows_mode_strs[WINDOWS_MAX] = { - "None", - "Real", - "Standard", - "Enhanced", - "NT", - "OS/2" -}; - -/* TESTING (whether or not it correctly detects the presence of Windows): - * Note that in some columns the API returns insufficient information and the - * API has to use it's best guess on the correct value, which might be - * inaccurate or wrong (marked: GUESSES). - * - * For Windows NT/2000/XP/Vista/7 tests, the code does not have any way of - * knowing (yet) which version of the NT kernel is involved, so the best - * it can offer is "I am running under NT" (marked as ONLY NT) - * - * OS, shell, configuration & mode Detects Correct mode Correct version - * Microsoft Windows 3.0 (DOSBox 0.74) - * 386 Enhanced Mode YES YES YES - * 286 Standard Mode YES GUESSES YES - * 8086 Real Mode YES GUESSES YES - * Microsoft Windows 3.1 (DOSBox 0.74) - * 386 Enhanced Mode YES YES YES - * 286 Standard Mode YES YES YES - * Microsoft Windows 3.11 (DOSBox 0.74) - * 386 Enhanced Mode YES YES YES* - * 286 Standard Mode YES YES YES* - * * = Despite being v3.11 it still reports itself as v3.1 - * Microsoft Windows 95 (4.00.950) (DOS 7.00) (Qemu) - * Normal YES YES* YES (4.0) - * Safe mode YES YES* YES (4.0) - * Prevent DOS apps detecting Windows NO - - - * * = Reports self as "enhanced mode" which is really the only mode supported - * Microsoft Windows 95 OSR2.5 (4.00.950 C) (DOS 7.10) (Qemu) - * Normal YES YES YES (4.0) - * Safe mode YES YES YES (4.0) - * Microsoft Windows 95 SP1 (4.00.950a) (DOS 7.00) (Qemu) - * Normal YES YES YES (4.0) - * Safe mode YES YES YES (4.0) - * Microsoft Windows 98 (4.10.1998) (DOS 7.10) (Qemu) - * Normal YES YES YES (4.10) - * Safe mode YES YES YES (4.10) - * Microsoft Windows 98 SE (4.10.2222 A) (DOS 7.10) (Qemu) - * Normal YES YES YES (4.10) - * Safe mode YES YES YES (4.10) - * Microsoft Windows ME (4.90.3000) (DOS 8.00) (Qemu) - * Normal YES YES YES (4.90) - * Safe mode YES YES YES (4.90) - * Microsoft Windows 2000 Professional (5.00.2195) (VirtualBox) - * Normal YES N/A ONLY NT - * Microsoft Windows XP Professional (5.1.2600) (VirtualBox) - * Normal YES N/A ONLY NT - * Microsoft Windows XP Professional SP1 (5.1.2600) (VirtualBox) - * Normal YES N/A ONLY NT - * Microsoft Windows XP Professional SP2 (5.1.2600) (VirtualBox) - * Normal YES N/A ONLY NT - * Microsoft Windows XP Professional SP3 (5.1.2600) (VirtualBox) - * Normal YES N/A ONLY NT -*/ - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 -/* it's nice to know if we're running under WINE (and therefore possibly Linux) - * as opposed to real Windows, so that we can adjust our techniques accordingly. - * I doubt for example that WINE would support Windows NT's NTVDM.EXE BOP codes, - * or that our Win9x compatible VxD enumeration would know not to try enumerating - * drivers. */ -void win32_probe_for_wine() { /* Probing for WINE from the Win32 layer */ - HMODULE ntdll; - - ntdll = LoadLibrary("NTDLL.DLL"); - if (ntdll) { - const char *(__stdcall *p)() = (const char *(__stdcall *)())GetProcAddress(ntdll,"wine_get_version"); - if (p != NULL) { - windows_emulation = WINEMU_WINE; - windows_emulation_comment_str = p(); /* and the function apparently returns a string */ - } - FreeLibrary(ntdll); - } -} -#elif defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 -void win16_probe_for_wine() { /* Probing for WINE from the Win16 layer */ - DWORD callw,retv; - - if (!genthunk32_init()) return; - if (genthunk32w_ntdll == 0) return; - - callw = __GetProcAddress32W(genthunk32w_ntdll,"wine_get_version"); - if (callw == 0) return; - - retv = __CallProcEx32W(CPEX_DEST_STDCALL/*nothing to convert*/,0/*0 param*/,callw); - if (retv == 0) return; - - windows_emulation = WINEMU_WINE; - { - /* NTS: We assume that WINE, just like real Windows, will not move or relocate - * NTDLL.DLL and will not move the string it just returned. */ - /* TODO: You need a function the host program can call to free the selector - * you allocated here, in case it wants to reclaim resources */ - uint16_t sel; - uint16_t myds=0; - __asm mov myds,ds - sel = AllocSelector(myds); - if (sel != 0) { - /* the selector is directed at the string, then retained in this - * code as a direct FAR pointer to WINE's version string */ - SetSelectorBase(sel,retv); - SetSelectorLimit(sel,0xFFF); /* WINE's version string is rarely longer than 14 chars */ - windows_emulation_comment_str = MK_FP(sel,0); - } - } -} -#endif - -int detect_windows() { -#if defined(TARGET_WINDOWS) -# if TARGET_MSDOS == 32 -# ifdef WIN386 - /* Windows 3.0/3.1 with Win386 */ - if (!windows_init) { - DWORD raw; - - windows_emulation = 0; - windows_init = 1; - windows_mode = WINDOWS_ENHANCED; /* most likely scenario is Windows 3.1 386 enhanced mode */ - - raw = GetVersion(); - windows_version_method = "GetVersion"; - windows_version = (LOBYTE(LOWORD(raw)) << 8) | HIBYTE(LOWORD(raw)); - /* NTS: Microsoft documents GetVersion() as leaving bit 31 unset for NT, bit 31 set for Win32s and Win 9x/ME. - * But that's not what the Win16 version of the function does! */ - - if (dos_version == 0) probe_dos(); - - /* Windows 3.1/9x/ME */ - raw = GetWinFlags(); - if (raw & WF_PMODE) { - if (raw & WF_ENHANCED) - windows_mode = WINDOWS_ENHANCED; - else/* if (raw & WF_STANDARD)*/ - windows_mode = WINDOWS_STANDARD; - } - else { - windows_mode = WINDOWS_REAL; - } - - /* NTS: All 32-bit Windows systems since Windows NT 3.51 and Windows 95 return - * major=3 minor=95 when Win16 applications query the version number. The only - * exception to that rule is Windows NT 3.1, which returns major=3 minor=10, - * the same version number returned by Windows 3.1. */ - if (windows_mode == WINDOWS_ENHANCED && - (dos_version >= 0x510 && dos_version <= 0x57f)/* MS-DOS v5.50 */ && - (windows_version == 0x035F /* Windows NT 4/2000/XP/Vista/7/8 */ || - windows_version == 0x030A /* Windows NT 3.1/3.5x */)) { - /* if the real DOS version is 5.50 then we're under NT */ - windows_mode = WINDOWS_NT; - } - - switch (dos_version>>8) { - case 10: /* OS/2 1.x */ - case 20: /* OS/2 2.x (low=0), and OS/2 Warp 3 (low=30), and OS/2 Warp 4 (low=40) */ - windows_version_method = "Deduce from DOS version"; - windows_version = dos_version; - windows_mode = WINDOWS_OS2; - break; - }; - } -# elif TARGET_WINDOWS >= 40 || defined(WINNT) - /* Windows 95/98/ME/XP/2000/NT/etc. and Windows NT builds: We don't need to do anything. - * The fact we're running means Windows is present */ - /* TODO: Clarify which Windows: Are we running under NT? or 9X/ME? What version? */ - if (!windows_init) { - OSVERSIONINFO ovi; - - windows_emulation = 0; - windows_init = 1; - memset(&ovi,0,sizeof(ovi)); - ovi.dwOSVersionInfoSize = sizeof(ovi); - GetVersionEx(&ovi); - - windows_version_method = "GetVersionEx"; - windows_version = (ovi.dwMajorVersion << 8) | ovi.dwMinorVersion; - if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) - windows_mode = WINDOWS_NT; - else - windows_mode = WINDOWS_ENHANCED; /* Windows 3.1 Win32s, or Windows 95/98/ME */ - - win32_probe_for_wine(); - } -# elif TARGET_WINDOWS == 31 - /* Windows 3.1 with Win32s target build. Note that such programs run in the Win32 layer on Win95/98/ME/NT/2000/etc. */ - /* TODO: Clarify which Windows, using the limited set of functions available under Win32s, or perhaps using GetProcAddress - * to use the later GetVersionEx() functions offered by Win95/98/NT/etc. */ - if (!windows_init) { - DWORD raw; - - windows_emulation = 0; - windows_init = 1; - windows_mode = WINDOWS_ENHANCED; /* Assume Windows 3.1 386 Enhanced Mode. This 32-bit app couldn't run otherwise */ - - raw = GetVersion(); - windows_version_method = "GetVersion"; - windows_version = (LOBYTE(LOWORD(raw)) << 8) | HIBYTE(LOWORD(raw)); - if (!(raw & 0x80000000UL)) { /* FIXME: Does this actually work? */ - /* Windows NT/2000/XP/etc */ - windows_mode = WINDOWS_NT; - } - - /* TODO: GetProcAddress() GetVersionEx() and get the REAL version number from Windows */ - - win32_probe_for_wine(); - } -# else -# error Unknown 32-bit Windows variant -# endif -# elif TARGET_MSDOS == 16 -# if TARGET_WINDOWS >= 30 - /* Windows 3.0/3.1, what we then want to know is what mode we're running under: Real? Standard? Enhanced? - * The API function GetWinFlags() only exists in 3.0 and higher, it doesn't exist under 2.x */ - /* TODO */ - if (!windows_init) { - DWORD raw; - - windows_emulation = 0; - windows_init = 1; - windows_mode = WINDOWS_ENHANCED; /* most likely scenario is Windows 3.1 386 enhanced mode */ - - raw = GetVersion(); - windows_version_method = "GetVersion"; - windows_version = (LOBYTE(LOWORD(raw)) << 8) | HIBYTE(LOWORD(raw)); - /* NTS: Microsoft documents GetVersion() as leaving bit 31 unset for NT, bit 31 set for Win32s and Win 9x/ME. - * But that's not what the Win16 version of the function does! */ - - if (dos_version == 0) probe_dos(); - - /* Windows 3.1/9x/ME */ - raw = GetWinFlags(); - if (raw & WF_PMODE) { - if (raw & WF_ENHANCED) - windows_mode = WINDOWS_ENHANCED; - else/* if (raw & WF_STANDARD)*/ - windows_mode = WINDOWS_STANDARD; - } - else { - windows_mode = WINDOWS_REAL; - } - - /* NTS: All 32-bit Windows systems since Windows NT 3.51 and Windows 95 return - * major=3 minor=95 when Win16 applications query the version number. The only - * exception to that rule is Windows NT 3.1, which returns major=3 minor=10, - * the same version number returned by Windows 3.1. */ - if (windows_mode == WINDOWS_ENHANCED && - (dos_version >= 0x510 && dos_version <= 0x57f)/* MS-DOS v5.50 */ && - (windows_version == 0x035F /* Windows NT 4/2000/XP/Vista/7/8 */ || - windows_version == 0x030A /* Windows NT 3.1/3.5x */)) { - /* if the real DOS version is 5.50 then we're under NT */ - windows_mode = WINDOWS_NT; - } - - switch (dos_version>>8) { - case 10: /* OS/2 1.x */ - case 20: /* OS/2 2.x (low=0), and OS/2 Warp 3 (low=30), and OS/2 Warp 4 (low=40) */ - windows_version_method = "Deduce from DOS version"; - windows_version = dos_version; - windows_mode = WINDOWS_OS2; - break; - }; - - /* If we're running under Windows 9x/ME or Windows NT/2000 we can thunk our way into - * the Win32 world and call various functions to get a more accurate picture of the - * Windows system we are running on */ - /* NTS: Under Windows NT 3.51 or later this technique is the only way to get the - * true system version number. The Win16 GetVersion() will always return - * some backwards compatible version number except for NT 3.1: - * - * Win16 Win32 - * +========================== - * NT 3.1 | 3.1 3.1 - * NT 3.51 | 3.1 3.51 - * NT 4.0 | 3.95 4.0 - * 2000 | 3.95 5.0 - * XP | 3.95 5.1 - * Vista | 3.95 6.0 - * 7 | 3.95 6.1 - * 8 | 3.95 6.2 - * - */ - if (genthunk32_init() && genthunk32w_kernel32_GetVersionEx != 0) { - OSVERSIONINFO osv; - - memset(&osv,0,sizeof(osv)); - osv.dwOSVersionInfoSize = sizeof(osv); - if (__CallProcEx32W(CPEX_DEST_STDCALL | 1/* convert param 1*/, - 1/*1 param*/,genthunk32w_kernel32_GetVersionEx, - (DWORD)((void far*)(&osv))) != 0UL) { - windows_version_method = "GetVersionEx [16->32 CallProcEx32W]"; - windows_version = (osv.dwMajorVersion << 8) | osv.dwMinorVersion; - if (osv.dwPlatformId == 2/*VER_PLATFORM_WIN32_NT*/) - windows_mode = WINDOWS_NT; - else - windows_mode = WINDOWS_ENHANCED; - } - } - - win16_probe_for_wine(); - } -# elif TARGET_WINDOWS >= 20 - /* Windows 2.x or higher. Use GetProcAddress() to locate GetWinFlags() if possible, else assume real mode - * and find some other way to detect if we're running under the 286 or 386 enhanced versions of Windows 2.11 */ - /* TODO */ - if (!windows_init) { - windows_init = 1; - windows_version = 0x200; - windows_mode = WINDOWS_REAL; - windows_version_method = "Assuming"; - } -# else - /* Windows 1.x. No GetProcAddress, no GetWinFlags. Assume Real mode. */ - /* TODO: How exactly DO you get the Windows version in 1.1? */ - if (!windows_init) { - windows_init = 1; - windows_version = 0x101; /* Assume 1.1 */ - windows_mode = WINDOWS_REAL; - windows_version_method = "Assuming"; - } -# endif -# else -# error Unknown Windows bit target -# endif -#elif defined(TARGET_OS2) - /* OS/2 16-bit or 32-bit. Obviously as something compiled for OS/2, we're running under OS/2 */ - if (!windows_init) { - windows_version_method = "I'm an OS/2 program, therefore the environment is OS/2"; - windows_version = dos_version; - windows_mode = WINDOWS_OS2; - windows_init = 1; - } -#else - /* MS-DOS 16-bit or 32-bit. MS-DOS applications must try various obscure interrupts to detect whether Windows is running */ - /* TODO: How can we detect whether we're running under OS/2? */ - if (!windows_init) { - union REGS regs; - - windows_version = 0; - windows_mode = 0; - windows_init = 1; - - switch (dos_version>>8) { - case 10: /* OS/2 1.x */ - case 20: /* OS/2 2.x (low=0), and OS/2 Warp 3 (low=30), and OS/2 Warp 4 (low=40) */ - windows_version_method = "Deduce from DOS version"; - windows_version = dos_version; - windows_mode = WINDOWS_OS2; - break; - }; - - if (windows_version == 0) { - regs.w.ax = 0x160A; -#if TARGET_MSDOS == 32 - int386(0x2F,®s,®s); -#else - int86(0x2F,®s,®s); -#endif - if (regs.w.ax == 0x0000 && regs.w.bx >= 0x300 && regs.w.bx <= 0x700) { /* Windows 3.1 */ - windows_version = regs.w.bx; - switch (regs.w.cx) { - case 0x0002: windows_mode = WINDOWS_STANDARD; break; - case 0x0003: windows_mode = WINDOWS_ENHANCED; break; - default: windows_version = 0; break; - } - - if (windows_mode != 0) - windows_version_method = "INT 2Fh AX=160Ah"; - } - } - - if (windows_version == 0) { - regs.w.ax = 0x4680; -#if TARGET_MSDOS == 32 - int386(0x2F,®s,®s); -#else - int86(0x2F,®s,®s); -#endif - if (regs.w.ax == 0x0000) { /* Windows 3.0 or DOSSHELL in real or standard mode */ - /* FIXME: Okay... if DOSSHELL triggers this test how do I tell between Windows and DOSSHELL? */ - /* Also, this call does NOT work when Windows 3.0 is in enhanced mode, and for Real and Standard modes - * does not tell us which mode is active. - * - * As far as I can tell there really is no way to differentiate whether it is running in Real or - * Standard mode, because on a 286 there is no "virtual 8086" mode. The only way Windows can run - * DOS level code is to thunk back into real mode. So for all purposes whatsoever, we might as well - * say that we're running in Windows Real mode because during that time slice we have complete control - * of the CPU. */ - windows_version = 0x300; - windows_mode = WINDOWS_REAL; - windows_version_method = "INT 2Fh AX=4680h"; - } - } - - if (windows_version == 0) { - regs.w.ax = 0x1600; -#if TARGET_MSDOS == 32 - int386(0x2F,®s,®s); -#else - int86(0x2F,®s,®s); -#endif - if (regs.h.al == 1 || regs.h.al == 0xFF) { /* Windows 2.x/386 */ - windows_version = 0x200; - windows_mode = WINDOWS_ENHANCED; - } - else if (regs.h.al == 3 || regs.h.al == 4) { - windows_version = (regs.h.al << 8) + regs.h.ah; - windows_mode = WINDOWS_ENHANCED; /* Windows 3.0 */ - } - - if (windows_mode != 0) - windows_version_method = "INT 2Fh AX=1600h"; - } - - if (windows_version == 0 && windows_mode == WINDOWS_NONE) { - /* well... if the above fails, but the "true" DOS version is 5.50, then we're running under Windows NT */ - /* NOTE: Every copy of NT/2000/XP/Vista I have reports 5.50, but assuming that will continue is stupid. - * Microsoft is free to change that someday. */ - if (dos_version == 0) probe_dos(); - if (dos_version >= 0x510 && dos_version <= 0x57f) { /* FIXME: If I recall Windows NT really does stick to v5.50, so this range check should be changed into == 5.50 */ - windows_mode = WINDOWS_NT; - windows_version = 0; - windows_version_method = "Assuming from DOS version number"; - } - } - - /* now... if this is Windows NT, the next thing we can do is use NTVDM.EXE's - * BOP opcodes to load a "helper" DLL that allows us to call into Win32 */ -# if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) - if (windows_mode == WINDOWS_NT && ntvdm_dosntast_init()) { - /* OK. Ask for the version number */ - OSVERSIONINFO ovi; - - memset(&ovi,0,sizeof(ovi)); - ovi.dwOSVersionInfoSize = sizeof(ovi); - if (ntvdm_dosntast_getversionex(&ovi)) { - windows_version_method = "GetVersionEx [NTVDM.EXE + DOSNTAST.VDD]"; - windows_version = (ovi.dwMajorVersion << 8) | ovi.dwMinorVersion; - if (ovi.dwPlatformId == 2/*VER_PLATFORM_WIN32_NT*/) - windows_mode = WINDOWS_NT; - else - windows_mode = WINDOWS_ENHANCED; - } - } -# endif - } -#endif - - return (windows_mode != WINDOWS_NONE); -} - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 && !defined(WIN386) -/* API for exploiting the QT_Thunk Win32 -> Win16 thunking offered by Windows 9x/ME */ -unsigned char win9x_qt_thunk_probed = 0; -unsigned char win9x_qt_thunk_available = 0; - -void (__stdcall *QT_Thunk)() = NULL; -DWORD (__stdcall *LoadLibrary16)(LPSTR lpszLibFileName) = NULL; -VOID (__stdcall *FreeLibrary16)(DWORD dwInstance) = NULL; -HGLOBAL16 (__stdcall *GlobalAlloc16)(UINT flags,DWORD size) = NULL; -HGLOBAL16 (__stdcall *GlobalFree16)(HGLOBAL16 handle) = NULL; -DWORD (__stdcall *GlobalLock16)(HGLOBAL16 handle) = NULL; -BOOL (__stdcall *GlobalUnlock16)(HGLOBAL16 handle) = NULL; -VOID (__stdcall *GlobalUnfix16)(HGLOBAL16 handle) = NULL; -VOID (__stdcall *GlobalFix16)(HGLOBAL16 handle) = NULL; -DWORD (__stdcall *GetProcAddress16)(DWORD dwInstance, LPSTR lpszProcName) = NULL; -DWORD win9x_kernel_win16 = 0; -DWORD win9x_user_win16 = 0; - -int Win9xQT_ThunkInit() { - if (!win9x_qt_thunk_probed) { - Win32OrdinalLookupInfo nfo; - HMODULE kern32; - - win9x_qt_thunk_probed = 1; - win9x_qt_thunk_available = 0; - - if (dos_version == 0) probe_dos(); - if (windows_mode == 0) detect_windows(); - if (windows_mode != WINDOWS_ENHANCED) return 0; /* This does not work under Windows NT */ - if (windows_version < 0x400) return 0; /* This does not work on Windows 3.1 Win32s (FIXME: Are you sure?) */ - - /* This hack relies on undocumented Win16 support routines hidden in KERNEL32.DLL. - * They're so super seekret, Microsoft won't even let us get to them through GetProcAddress() */ - kern32 = GetModuleHandle("KERNEL32.DLL"); - if (windows_emulation == WINEMU_WINE) { - /* FIXME: Direct ordinal lookup doesn't work. Returned - * addresses point to invalid regions of KERNEL32.DLL. - * I doubt WINE is even putting a PE-compatible image - * of it out there. - * - * WINE does allow us to GetProcAddress ordinals - * (unlike Windows 9x which blocks it) but I'm not - * really sure the returned functions are anything - * like the Windows 9x equivalent. If we assume they - * are, this code seems unable to get the address of - * KRNL386.EXE's "GETVERSION" function. - * - * So basically WINE's Windows 9x emulation is more - * like Windows XP's Application Compatability modes - * than any serious attempt at pretending to be - * Windows 9x. And the entry points may well be - * stubs or other random functions in the same way - * that ordinal 35 is unrelated under Windows XP. */ - return 0; - } - else if (Win32GetOrdinalLookupInfo(kern32,&nfo)) { - GlobalFix16 = (void*)Win32GetOrdinalAddress(&nfo,27); - GlobalLock16 = (void*)Win32GetOrdinalAddress(&nfo,25); - GlobalFree16 = (void*)Win32GetOrdinalAddress(&nfo,31); - LoadLibrary16 = (void*)Win32GetOrdinalAddress(&nfo,35); - FreeLibrary16 = (void*)Win32GetOrdinalAddress(&nfo,36); - GlobalAlloc16 = (void*)Win32GetOrdinalAddress(&nfo,24); - GlobalUnfix16 = (void*)Win32GetOrdinalAddress(&nfo,28); - GlobalUnlock16 = (void*)Win32GetOrdinalAddress(&nfo,26); - GetProcAddress16 = (void*)Win32GetOrdinalAddress(&nfo,37); - QT_Thunk = (void*)GetProcAddress(kern32,"QT_Thunk"); - } - else { - GlobalFix16 = NULL; - GlobalLock16 = NULL; - GlobalFree16 = NULL; - GlobalUnfix16 = NULL; - LoadLibrary16 = NULL; - FreeLibrary16 = NULL; - GlobalAlloc16 = NULL; - GlobalUnlock16 = NULL; - GetProcAddress16 = NULL; - QT_Thunk = NULL; - } - - if (LoadLibrary16 && FreeLibrary16 && GetProcAddress16 && QT_Thunk) { - /* Prove the API works by loading a reference to KERNEL */ - win9x_kernel_win16 = LoadLibrary16("KERNEL"); - if (win9x_kernel_win16 != 0) { - win9x_qt_thunk_available = 1; - } - - win9x_user_win16 = LoadLibrary16("USER"); - } - } - - return win9x_qt_thunk_available; -} - -void Win9xQT_ThunkFree() { - if (win9x_kernel_win16) { - FreeLibrary16(win9x_kernel_win16); - win9x_kernel_win16 = 0; - } -} -#endif - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 -unsigned char ToolHelpProbed = 0; -HMODULE ToolHelpDLL = 0; -BOOL (PASCAL FAR *__TimerCount)(TIMERINFO FAR *t) = NULL; -BOOL (PASCAL FAR *__InterruptUnRegister)(HTASK htask) = NULL; -BOOL (PASCAL FAR *__InterruptRegister)(HTASK htask,FARPROC callback) = NULL; - -int ToolHelpInit() { - if (!ToolHelpProbed) { - UINT oldMode; - - ToolHelpProbed = 1; - - /* BUGFIX: In case TOOLHELP.DLL is missing (such as when running under Windows 3.0) - * this prevents sudden interruption by a "Cannot find TOOLHELP.DLL" error - * dialog box */ - oldMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - ToolHelpDLL = LoadLibrary("TOOLHELP.DLL"); - SetErrorMode(oldMode); - if (ToolHelpDLL != 0) { - __TimerCount = (void far*)GetProcAddress(ToolHelpDLL,"TIMERCOUNT"); - __InterruptRegister = (void far*)GetProcAddress(ToolHelpDLL,"INTERRUPTREGISTER"); - __InterruptUnRegister = (void far*)GetProcAddress(ToolHelpDLL,"INTERRUPTUNREGISTER"); - } - } - - return (ToolHelpDLL != 0) && (__TimerCount != NULL) && (__InterruptRegister != NULL) && - (__InterruptUnRegister != NULL); -} - -void ToolHelpFree() { - if (ToolHelpDLL) { - FreeLibrary(ToolHelpDLL); - ToolHelpDLL = 0; - } - __InterruptUnRegister = NULL; - __InterruptRegister = NULL; - __TimerCount = NULL; -} -#endif - diff --git a/src/lib/doslib/dos/doswin.h b/src/lib/doslib/dos/doswin.h deleted file mode 100644 index fcc58344..00000000 --- a/src/lib/doslib/dos/doswin.h +++ /dev/null @@ -1,83 +0,0 @@ - -#include -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* NTVDM.EXE DOSNTAST.VDD call support */ -#include -#endif - -enum { - WINEMU_NONE=0, - WINEMU_WINE -}; - -enum { - WINDOWS_NONE=0, - WINDOWS_REAL, - WINDOWS_STANDARD, - WINDOWS_ENHANCED, - WINDOWS_NT, - WINDOWS_OS2, /* Not Windows, OS/2 */ - /* Exact meaning: If we're a DOS/Windows program, then we know we're running under OS/2 - and OS/2 is emulating DOS/Windows. If we're an OS/2 program, then we're in our native - environment */ - WINDOWS_MAX -}; - -extern const char *windows_mode_strs[WINDOWS_MAX]; -#define windows_mode_str(x) windows_mode_strs[x] - -extern uint8_t windows_mode; -extern uint16_t windows_version; -extern uint8_t windows_emulation; -extern const char *windows_version_method; -extern const char *windows_emulation_comment_str; - -/* TODO: Someday, these will become variables */ - -/* whether the Windows emulation allows Win16 to call DPMI */ -#define windows_emulation_includes_dpmi 0 - -int detect_windows(); -const char *windows_emulation_str(uint8_t e); - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 && !defined(WIN386) -# include -# include - -extern unsigned char win9x_qt_thunk_probed; -extern unsigned char win9x_qt_thunk_available; - -typedef WORD HGLOBAL16; /* <- NTS: Taken from WINE header definitions */ - -extern void (__stdcall *QT_Thunk)(); -extern DWORD (__stdcall *LoadLibrary16)(LPSTR lpszLibFileName); -extern VOID (__stdcall *FreeLibrary16)(DWORD dwInstance); -extern HGLOBAL16 (__stdcall *GlobalAlloc16)(UINT flags,DWORD size); -extern HGLOBAL16 (__stdcall *GlobalFree16)(HGLOBAL16 handle); -extern DWORD (__stdcall *GlobalLock16)(HGLOBAL16 handle); -extern BOOL (__stdcall *GlobalUnlock16)(HGLOBAL16 handle); -extern VOID (__stdcall *GlobalUnfix16)(HGLOBAL16 handle); -extern DWORD (__stdcall *GetProcAddress16)(DWORD dwInstance, LPSTR lpszProcName); -extern VOID (__stdcall *GlobalFix16)(HGLOBAL16 handle); - -extern DWORD win9x_kernel_win16; -extern DWORD win9x_user_win16; - -int Win9xQT_ThunkInit(); -void Win9xQT_ThunkFree(); -#endif - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 -# include -extern HMODULE ToolHelpDLL; -extern unsigned char ToolHelpProbed; -extern BOOL (PASCAL FAR *__TimerCount)(TIMERINFO FAR *t); -extern BOOL (PASCAL FAR *__InterruptUnRegister)(HTASK htask); -extern BOOL (PASCAL FAR *__InterruptRegister)(HTASK htask,FARPROC callback); - -int ToolHelpInit(); -void ToolHelpFree(); -#endif - diff --git a/src/lib/doslib/dos/dosxio.c b/src/lib/doslib/dos/dosxio.c deleted file mode 100644 index 6dc82903..00000000 --- a/src/lib/doslib/dos/dosxio.c +++ /dev/null @@ -1,105 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if TARGET_MSDOS == 32 -int _dos_xread(int fd,void *buffer,int bsz) { /* NTS: The DOS extender takes care of translation here for us */ - int rd = -1; - __asm { - mov ah,0x3F - mov ebx,fd - mov ecx,bsz - mov edx,buffer - int 0x21 - mov ebx,eax - sbb ebx,ebx - or eax,ebx - mov rd,eax - } - return rd; -} -#else -int _dos_xread(int fd,void far *buffer,int bsz) { - int rd = -1; - __asm { - mov ah,0x3F - mov bx,fd - mov cx,bsz - mov dx,word ptr [buffer+0] - mov si,word ptr [buffer+2] - push ds - mov ds,si - int 0x21 - pop ds - mov bx,ax - sbb bx,bx - or ax,bx - mov rd,ax - } - return rd; -} -#endif - -#if TARGET_MSDOS == 32 -int _dos_xwrite(int fd,void *buffer,int bsz) { /* NTS: The DOS extender takes care of translation here for us */ - int rd = -1; - __asm { - mov ah,0x40 - mov ebx,fd - mov ecx,bsz - mov edx,buffer - int 0x21 - mov ebx,eax - sbb ebx,ebx - or eax,ebx - mov rd,eax - } - return rd; -} -#else -int _dos_xwrite(int fd,void far *buffer,int bsz) { - int rd = -1; - __asm { - mov ah,0x40 - mov bx,fd - mov cx,bsz - mov dx,word ptr [buffer+0] - mov si,word ptr [buffer+2] - push ds - mov ds,si - int 0x21 - pop ds - mov bx,ax - sbb bx,bx - or ax,bx - mov rd,ax - } - return rd; -} -#endif - diff --git a/src/lib/doslib/dos/dpmiexcp.c b/src/lib/doslib/dos/dpmiexcp.c deleted file mode 100644 index 876d410d..00000000 --- a/src/lib/doslib/dos/dpmiexcp.c +++ /dev/null @@ -1,112 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if !defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -void far *dpmi_getexhandler(unsigned char n) { - unsigned short s=0,o=0; - - __asm { - mov ax,0x202 - mov bl,n - xor cx,cx - xor dx,dx - int 31h - mov s,cx - mov o,dx - } - - return MK_FP(s,o); -} - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -int dpmi_setexhandler(unsigned char n,void far *x) { - unsigned short s=FP_SEG(x),o=FP_OFF(x); - int c=1; - - __asm { - mov ax,0x203 - mov bl,n - mov cx,s - mov dx,o - int 31h - jnc ok - mov c,0 -ok: - } - - return c; -} - -#endif - -#if !defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -void far *dpmi_getexhandler(unsigned char n) { - unsigned short s=0; - unsigned int o=0; - - __asm { - mov ax,0x202 - mov bl,n - xor cx,cx - xor dx,dx - int 31h - mov s,cx - mov o,edx - } - - return MK_FP(s,o); -} - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -int dpmi_setexhandler(unsigned char n,void far *x) { - unsigned short s=FP_SEG(x); - unsigned int o=FP_OFF(x); - int c=1; - - __asm { - mov ax,0x203 - mov bl,n - mov cx,s - mov edx,o - int 31h - jnc ok - mov c,0 -ok: - } - - return c; -} - -#endif - diff --git a/src/lib/doslib/dos/dpmirmcl.c b/src/lib/doslib/dos/dpmirmcl.c deleted file mode 100644 index f4ba557b..00000000 --- a/src/lib/doslib/dos/dpmirmcl.c +++ /dev/null @@ -1,193 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -unsigned int dpmi_test_rm_entry_call(struct dpmi_realmode_call *rc) { - unsigned int res = 0; - - __asm { - mov ax,0x0301 - xor bx,bx - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - jnc ok - - mov res,1 ; just incase some fucked up DPMI server returns CF=1 EAX=0 - or eax,eax - jz ok - - mov res,eax ; OK store the error code as-is -ok: - } - - return res; -} - -static unsigned char *alt_rm_call = NULL; -static uint16_t alt_rm_call_sel = 0; - -/* using this hack, subvert INT 06h (invalid opcode exception) - which the BIOS and DOS are unlikely to use during this hack */ -#define ALT_INT 0x06 - -int dpmi_alternate_rm_call(struct dpmi_realmode_call *rc) { - uint32_t oe; - - if (alt_rm_call == NULL) { - alt_rm_call = dpmi_alloc_dos(32,&alt_rm_call_sel); - if (alt_rm_call == NULL) { - fprintf(stderr,"FATAL: DPMI alternate call: cannot alloc\n"); - return 0; - } - } - - /* Fuck you DOS4/GW! */ - /* prepare executable code */ - alt_rm_call[0] = 0x9A; /* CALL FAR IMM */ - *((uint16_t*)(alt_rm_call+1)) = rc->ip; - *((uint16_t*)(alt_rm_call+3)) = rc->cs; - alt_rm_call[5] = 0xCF; /* IRET */ - - /* replace real-mode interrupt vector */ - _cli(); - oe = ((uint32_t*)0x00000000)[ALT_INT]; - ((uint32_t*)0x00000000)[ALT_INT] = - (((uint32_t)alt_rm_call >> 4UL) << 16UL) | /* seg */ - ((uint32_t)alt_rm_call & 0xFUL); /* ofs */ - _sti(); - - /* call it! */ - __asm { - mov ax,0x0300 - mov bx,ALT_INT - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } - - /* restore interrupt vector */ - _cli(); - ((uint32_t*)0x00000000)[ALT_INT] = oe; - _sti(); - - return 1; -} - -int dpmi_alternate_rm_call_stacko(struct dpmi_realmode_call *rc) { - uint32_t oe; - - if (alt_rm_call == NULL) { - alt_rm_call = dpmi_alloc_dos(32,&alt_rm_call_sel); - if (alt_rm_call == NULL) { - fprintf(stderr,"FATAL: DPMI alternate call: cannot alloc\n"); - return 0; - } - } - - /* Fuck you DOS4/GW! */ - /* prepare executable code */ - { - static unsigned char code[] = { - 0xFC, /* CLD */ - 0x8C,0xD0, /* MOV AX,SS */ - 0x8E,0xD8, /* MOV DS,AX */ - 0x8E,0xC0, /* MOV ES,AX */ - 0x89,0xE5, /* MOV BP,SP */ - 0x8D,0x76,0x06, /* LEA SI,[BP+6] <- 6 byte interrupt stack */ - 0x83,0xEC,0x20, /* SUB SP,0x20 */ - 0xB9,0x10,0x00, /* MOV CX,0x10 */ - 0x89,0xE7, /* MOV DI,SP */ - 0xF3,0xA5 /* REP MOVSW */ - }; - memcpy(alt_rm_call,code,0x16); - } - - alt_rm_call[0x16] = 0x9A; /* CALL FAR IMM */ - *((uint16_t*)(alt_rm_call+0x16+1)) = rc->ip; - *((uint16_t*)(alt_rm_call+0x16+3)) = rc->cs; - alt_rm_call[0x16+5] = 0x89; /* MOV SP,BP */ - alt_rm_call[0x16+6] = 0xEC; - alt_rm_call[0x16+7] = 0xCF; /* IRET */ - - /* replace real-mode interrupt vector */ - _cli(); - oe = ((uint32_t*)0x00000000)[ALT_INT]; - ((uint32_t*)0x00000000)[ALT_INT] = - (((uint32_t)alt_rm_call >> 4UL) << 16UL) | /* seg */ - ((uint32_t)alt_rm_call & 0xFUL); /* ofs */ - _sti(); - - /* call it! */ - __asm { - mov ax,0x0300 - mov bx,ALT_INT - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } - - /* restore interrupt vector */ - _cli(); - ((uint32_t*)0x00000000)[ALT_INT] = oe; - _sti(); - - return 1; -} -#undef ALT_INT -#endif - -#if TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -void mux_realmode_2F_call(struct dpmi_realmode_call *rc) { - __asm { - mov ax,0x0300 - mov bx,0x002F - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } -} -#endif -#if TARGET_MSDOS == 16 && defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -void mux_realmode_2F_call(struct dpmi_realmode_call far *rc) { - __asm { - push es - mov ax,0x0300 - mov bx,0x002F - xor cx,cx - mov di,word ptr [rc+2] - mov es,di - mov di,word ptr [rc] - int 0x31 ; call DPMI - pop es - } -} -#endif - diff --git a/src/lib/doslib/dos/emm.c b/src/lib/doslib/dos/emm.c deleted file mode 100644 index aa8e74f1..00000000 --- a/src/lib/doslib/dos/emm.c +++ /dev/null @@ -1,517 +0,0 @@ -/* emm.c - * - * Expanded Memory Manager library. - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -/* api library for DOS programs that want to use Expanded Memory (usually, EMM386.EXE) - * - * NOTES: - * This code is intended for use with 16-bit real-mode programs. 32-bit programs have whatever the DOS extender - * offers and have no need for expanded memory, in fact, the DOS extender will often take up all extended - * & expanded memory for it's use and leave us nothing, which is why 32-bit builds of this library do not - * function. - * - * Testing: - * - * YES* = Yes, if DOS underneath provides it (or if DOS, when configured to load EMM386.EXE). Otherwise, No - * - * System/configuration Works? Limit? - * DOSBox 0.74 YES NO - * DOSBox 0.74 + - * Microsoft Windows 3.0 - * Real mode YES* NO - * Standard mode NO -- EMM functions present, but will always report 0KB free. If more than 16MB of RAM is present, Windows causes a serious fault and DOSBox aborts - * 386 Enhanced mode YES* ? - * Microsoft Windows 3.1 - * Standard mode NO -- EMM functions present, but will always report 0KB free - * 386 Enhanced mode YES* NO - * Microsoft Windows 3.11 - * Standard mode NO -- EMM functions present, but will always report 0KB free - * 386 Enhanced mode YES* NO - * QEMU/VirtualBox - * Microsoft Windows 95 (4.00.950)[1] - * Normal mode YES* 64MB API usually reports 16MB free. The test VM had 96MB of RAM - * Safe mode YES* 64MB - * MS-DOS mode (official) YES* 32MB - * MS-DOS mode (gui=0) YES* 32MB - * Microsoft Windows 98 (4.10.1998)[1] - * Normal mode YES* 64MB API usually reports 16MB free. The test VM had 96MB of RAM - * MS-DOS mode (gui=0) YES* 32MB - * Microsoft Windows ME (4.90.3000)[2] - * Normal mode YES* 64MB The API will never report more than 16MB free, but you can hack - * the PIF editor for the DOS program to allow up to 65534KB of - * EMM memory. The test program seems to have no problem allocating - * 48MB of expanded memory when said hack is applied. I suppose the - * API could handle more, but remember limits are imposed by the - * DOS Box VM and those are apparently represented by unsigned - * 16-bit integers, thus the 64MB (65534KB) limit. - * MS-DOS mode (bootdisk) ? ? I am unable to get Windows ME to make a bootdisk at this time. - * So I attemped to use a Windows ME bootdisk from bootdisk.com, - * and added DEVICE=EMM386.EXE only to find that at boot time - * it locks up the computer! So, I have no way of knowing what - * a pure MS-DOS mode EMM386.EXE from Windows ME does. It probably - * acts just like the Windows 95/98 versions... - * Microsoft Windows 2000 Professional - * Normal mode YES 32MB For whatever reason NTVDM defaults to NOT providing EMM memory. - * Limits to 32MB even if you type in larger values in the PIF editor. - * - * [1] EMM386.EXE for these systems will not be able to automatically find a page frame in QEMU or VirtualBox, probably because for - * unmapped regions the emulator returns 0x00 not 0xFF. To work around that, open CONFIG.SYS in a text editor and edit the - * line referring to EMM386.EXE. Add I=E000-EFFF and save. It should look like: - * - * DEVICE=C:\WINDOWS\EMM386.EXE I=E000-EFFF. - * - * [2] You're probably wondering... if Windows ME ignores AUTOEXEC.BAT and CONFIG.SYS then how the hell do you get EMM386.EXE - * loaded? Well, it's very obscure and undocumented, but you can get it loaded on boot up as follows: - * - * 1. Go to the start menu, select "run" and type "notepad c:\windows\system.ini" - * 2. Locate the [386Enh] section, go to the bottom of the section, and add the following lines of text to the end of [386Enh] - * - * EMMInclude=E000-EFFF - * ReservePageFrame=yes - * - * 3. Reboot, and enjoy - */ -#if !defined(TARGET_OS2) && !defined(TARGET_WINDOWS) - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -unsigned char emm_status = 0xFF; /* initialize to 0xFF as a way of indicating that nobody checked yet */ -unsigned char emm_present = 0; -unsigned char emm_version = 0; -unsigned char emm_phys_pages = 0; -unsigned short emm_total_pages = 0; -unsigned int emm_page_frame_segment = 0; -unsigned short emm_unallocated_pages = 0; -struct emm_phys_page_map *emm_phys_map = NULL; /* maps physical page number -> segment address */ -static const char *devname = "EMMXXXX0"; -static const char *devname2 = "EMMQXXX0"; /* Microsoft publishes EMM standard then breaks it subtly in non-backwards compatible way... news at 11 */ -#if TARGET_MSDOS == 32 && !defined(TARGET_OS2) -static uint16_t emm_phys_map_sel = 0; - -static void emm_realmode_67_call(struct dpmi_realmode_call *rc) { - __asm { - mov ax,0x0300 - mov bx,0x0067 - xor cx,cx - mov edi,rc ; we trust Watcom has left ES == DS - int 0x31 ; call DPMI - } -} -#endif - -void emm_phys_pages_sort() { - /* TODO */ -} - -#if TARGET_MSDOS == 16 && !defined(TARGET_OS2) -void emm_update_page_count() { - emm_unallocated_pages = 0; - emm_total_pages = 0; - - if (!emm_present) return; - - __asm { - mov ah,0x42 - push es - int 0x67 - pop es - mov emm_unallocated_pages,bx - mov emm_total_pages,dx - } -} - -int probe_emm() { - void far *emmptr; - - emm_present = 0; - emmptr = (void far*)_dos_getvect(0x67); - if (emmptr == (void far*)0) - return 0; - - /* apparently 10 bytes into the segment there is the magic string */ - if ( _fmemcmp((char far*)MK_FP(FP_SEG(emmptr),0x000A),(char far*)devname,8) != 0 && - _fmemcmp((char far*)MK_FP(FP_SEG(emmptr),0x000A),(char far*)devname2,8) != 0) - return 0; - - emm_present = 1; - emm_phys_pages = 1; - emm_page_frame_segment = 0; - - __asm { - mov ah,0x40 - push es - int 0x67 - pop es - mov emm_status,ah - - mov ah,0x41 - push es - int 0x67 - pop es - or ah,ah - jnz pfn_end - mov emm_page_frame_segment,bx - - mov ah,0x46 - push es - int 0x67 - pop es - mov emm_version,al -pfn_end: - } - - if (emm_phys_map != NULL) { - free(emm_phys_map); - emm_phys_map = NULL; - } - - if (emm_phys_map == NULL) { - /* see if the EMM provides a mapping table describing the real-mode segments - * corresponding to each physical page. if not, then assume only one page - * available. the table could be up to 256 entries. the API really doesn't - * have a way to tell us ahead of time, so assume the worst. */ - assert(sizeof(struct emm_phys_page_map) == (size_t)4); - emm_phys_map = malloc(sizeof(struct emm_phys_page_map) * 256); - if (emm_phys_map != NULL) { - const unsigned int s = FP_SEG(emm_phys_map); - const unsigned int o = FP_OFF(emm_phys_map); - unsigned int c = 0; - __asm { - push es - mov ax,0x5800 - mov di,s - mov es,di - mov di,o - int 0x67 - or ah,ah - jnz fail - mov c,cx -fail: pop es - } - - if (c == 0) { - free(emm_phys_map); - emm_phys_map = NULL; - } - else { - emm_phys_pages = c; - if (c < 256) { - void *x = realloc(emm_phys_map,sizeof(struct emm_phys_page_map) * c); - if (x != NULL) { /* NTS: if we cannot realloc, well, too bad */ - emm_phys_map = x; - } - } - - /* WARNING: we are assuming several things about the table. - * - That the table is sorted by real-mode segment (as described in the standard) - * - There are no duplicate page numbers - * - The table has as many entries as physical pages */ - - /* do ourself a favor and sort by page number the table */ - emm_phys_pages_sort(); - } - } - } - - return 1; -} - -int emm_alloc_pages(unsigned int pages) { - int handle = -1; - - if (emm_present) { - __asm { - mov ah,0x43 - mov bx,pages - push es - int 0x67 - pop es - or ah,ah - jnz fail - mov handle,dx -fail: - } - } - - return handle; -} - -int emm_free_pages(unsigned int handle) { - int retv = 0; - - if (emm_present) { - __asm { - mov ah,0x45 - mov dx,handle - push es - int 0x67 - pop es - or ah,ah - jnz fail - mov retv,1 -fail: - } - } - - return retv; -} - -int emm_map_page(unsigned int handle,unsigned int phys_page,unsigned int log_page) { - int retv = 0; - - if (phys_page >= (unsigned int)emm_phys_pages) - return 0; - - if (emm_present) { - __asm { - mov ah,0x44 - mov al,byte ptr phys_page - mov bx,log_page - mov dx,handle - push es - int 0x67 - pop es - or ah,ah - jnz fail - mov retv,1 -fail: - } - } - - return retv; -} - -/* given physical page number, return real-mode segment value */ -unsigned short emm_last_phys_page_segment(unsigned int phys_page) { - unsigned int i; - - if (phys_page >= (unsigned int)emm_phys_pages) - return 0; - - /* if we don't have a copy of the EMM's mapping table, then assume that there is - * only physical page 0 at the page frame address */ - if (phys_page == 0 && emm_phys_map == NULL) - return emm_page_frame_segment; - - for (i=0;i < emm_phys_pages && emm_phys_map != NULL;i++) { - struct emm_phys_page_map *me = emm_phys_map + i; - if (phys_page == me->number) - return me->segment; - } - - return 0; -} -#else -void emm_update_page_count() { - emm_unallocated_pages = 0; - emm_total_pages = 0; - - if (!emm_present) return; - - __asm { - mov ah,0x42 - push es - int 0x67 - pop es - mov emm_unallocated_pages,bx - mov emm_total_pages,dx - } -} - -int probe_emm() {/*32-bit*/ - unsigned int emm_seg; - - sanity(); - emm_present = 0; - /* Tricky. The DOS extender would likely translate the vector, when what we - really want is the segment value of int 67h */ - emm_seg = *((uint16_t*)((0x67 << 2) + 2)); - sanity(); - - /* apparently 10 bytes into the segment there is the magic string */ - if ( memcmp((void*)(((unsigned long)emm_seg << 4UL) + 0x000A),devname,8) != 0 && - memcmp((void*)(((unsigned long)emm_seg << 4UL) + 0x000A),devname2,8) != 0) - return 0; - - sanity(); - emm_present = 1; - emm_phys_pages = 1; - emm_page_frame_segment = 0; - - __asm { - mov ah,0x40 - push es - int 0x67 - pop es - mov emm_status,ah - - mov ah,0x41 - push es - int 0x67 - pop es - or ah,ah - jnz pfn_end - mov word ptr emm_page_frame_segment,bx - - mov ah,0x46 - push es - int 0x67 - pop es - mov emm_version,al -pfn_end: - } - sanity(); - - if (emm_phys_map != NULL) { - dpmi_free_dos(emm_phys_map_sel); - emm_phys_map_sel = 0; - emm_phys_map = NULL; - } - - if (emm_phys_map == NULL) { - /* see if the EMM provides a mapping table describing the real-mode segments - * corresponding to each physical page. if not, then assume only one page - * available. the table could be up to 256 entries. the API really doesn't - * have a way to tell us ahead of time, so assume the worst. */ - assert(sizeof(struct emm_phys_page_map) == (size_t)4); - emm_phys_map = dpmi_alloc_dos(sizeof(struct emm_phys_page_map) * 256,&emm_phys_map_sel); - if (emm_phys_map != NULL) { - const unsigned int s = ((uint32_t)emm_phys_map) >> 4; - const unsigned int o = ((uint32_t)emm_phys_map) & 0xF; - struct dpmi_realmode_call rc={0}; - unsigned int c = 0; - - rc.eax = 0x5800; - rc.edi = o; - rc.es = s; - rc.ds = s; - emm_realmode_67_call(&rc); - if ((rc.eax&0xFF) == 0) c = rc.ecx & 0xFFFF; - - if (c == 0) { - dpmi_free_dos(emm_phys_map_sel); - emm_phys_map_sel = 0; - emm_phys_map = NULL; - } - else { - emm_phys_pages = c; - - /* WARNING: we are assuming several things about the table. - * - That the table is sorted by real-mode segment (as described in the standard) - * - There are no duplicate page numbers - * - The table has as many entries as physical pages */ - - /* do ourself a favor and sort by page number the table */ - emm_phys_pages_sort(); - } - } - } - - return 1; -} - -int emm_alloc_pages(unsigned int pages) { - int handle = -1; - - if (emm_present) { - __asm { - mov ah,0x43 - mov ebx,pages - push es - int 0x67 - pop es - or ah,ah - jnz fail - and edx,0xFFFF - mov handle,edx -fail: - } - } - - return handle; -} - -int emm_free_pages(unsigned int handle) { - int retv = 0; - - if (emm_present) { - __asm { - mov ah,0x45 - mov edx,handle - push es - int 0x67 - pop es - or ah,ah - jnz fail - mov retv,1 -fail: - } - } - - return retv; -} - -int emm_map_page(unsigned int handle,unsigned int phys_page,unsigned int log_page) { - int retv = 0; - - if (phys_page >= (unsigned int)emm_phys_pages) - return 0; - - if (emm_present) { - __asm { - mov ah,0x44 - mov al,byte ptr phys_page - mov ebx,log_page - mov edx,handle - push es - int 0x67 - pop es - or ah,ah - jnz fail - mov retv,1 -fail: - } - } - - return retv; -} - -unsigned short emm_last_phys_page_segment(unsigned int phys_page) { - unsigned int i; - - if (phys_page >= (unsigned int)emm_phys_pages) - return 0; - - /* if we don't have a copy of the EMM's mapping table, then assume that there is - * only physical page 0 at the page frame address */ - if (phys_page == 0 && emm_phys_map == NULL) - return emm_page_frame_segment; - - for (i=0;i < emm_phys_pages && emm_phys_map != NULL;i++) { - struct emm_phys_page_map *me = emm_phys_map + i; - if (phys_page == me->number) - return me->segment; - } - - return 0; -} -#endif - -#endif /* !defined(TARGET_OS2) && !defined(TARGET_WINDOWS) */ - diff --git a/src/lib/doslib/dos/himemsys.h b/src/lib/doslib/dos/himemsys.h deleted file mode 100644 index b2e9e6c3..00000000 --- a/src/lib/doslib/dos/himemsys.h +++ /dev/null @@ -1,47 +0,0 @@ -/* himemsys.h - * - * Support calls to use HIMEM.SYS - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) - -/* HMA memory is present */ -#define HIMEM_F_HMA (1 << 0) -/* HIMEM.SYS supports extended functions to address up to 4GB of RAM (surpassing the older API's 64MB limit) */ -#define HIMEM_F_4GB (1 << 1) - -extern unsigned char himem_sys_present; -extern unsigned int himem_sys_version; -extern unsigned long himem_sys_entry; -extern unsigned char himem_sys_flags; -extern unsigned long himem_sys_total_free; -extern unsigned long himem_sys_largest_free; - -#pragma pack(push,1) -struct himem_block_info { - uint32_t block_length_kb; - unsigned char lock_count; - unsigned char free_handles; -}; -#pragma pack(pop) - -int probe_himem_sys(); -int himem_sys_query_a20(); -int himem_sys_local_a20(int enable); -int himem_sys_global_a20(int enable); -void himem_sys_update_free_memory_status(); -int __cdecl himem_sys_alloc(unsigned long size/* in KB---not bytes*/); -int himem_sys_move(unsigned int dst_handle,uint32_t dst_offset,unsigned int src_handle,uint32_t src_offset,uint32_t length); -int __cdecl himem_sys_realloc(unsigned int handle,unsigned long size/* in KB---not bytes*/); -int himem_sys_get_handle_info(unsigned int handle,struct himem_block_info *b); -uint32_t himem_sys_lock(unsigned int handle); -int himem_sys_unlock(unsigned int handle); -int himem_sys_free(int handle); - -#endif /* !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) */ - diff --git a/src/lib/doslib/dos/lol.c b/src/lib/doslib/dos/lol.c deleted file mode 100644 index d72bf875..00000000 --- a/src/lib/doslib/dos/lol.c +++ /dev/null @@ -1,141 +0,0 @@ -/* lol.c - * - * Test program: Make use of the MS-DOS "List of Lists" to print various things - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -/* FIXME: MS-DOS 6.22 under QEMU: This hangs, or causes QEMU to crash? */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int main() { - int i,c,line = 0; - unsigned char FAR *LOL; - - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - printf(" Flavor: '%s'\n",dos_flavor_str(dos_flavor)); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - if (detect_dosbox_emu()) - printf("I am also running under DOSBox\n"); - - if ((LOL = dos_list_of_lists()) != NULL) { - printf("DOS List of Lists at "); -#if TARGET_MSDOS == 32 - printf("0x%08lX\n",(unsigned long)LOL); -#else - printf("%04x:%04x\n",FP_SEG(LOL),FP_OFF(LOL)); -#endif - } - else { - printf("Unable to locate the DOS 'list of lists'\n"); - return 0; - } - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - - /* list MCBs */ - { - struct dos_psp_cooked pspnfo; - struct dos_mcb_enum men; - - if (dos_mcb_first(&men)) { - printf("Resident MCBs\n"); line++; - do { - mcb_filter_name(&men); - - printf("[%04x]: %02x PSP=%04x size=%04x %-8s ", - men.cur_segment,men.type,men.psp,men.size,men.name); - for (i=0;i < 32;i++) { - c = men.ptr[i]; - if (c >= 32 && c <= 126) printf("%c",c); - else printf("."); - } - printf("\n"); - - if (men.psp >= 0x80 && men.psp < 0xFFFFU && dos_parse_psp(men.psp,&pspnfo)) { - printf(" PSP memsize=%04xh callpsp=%04xh env=%04xh command='%s'\n", - pspnfo.memsize,pspnfo.callpsp,pspnfo.env,pspnfo.cmd); - - if (++line >= 20) { - line -= 20; - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - } - } - - if (++line >= 20) { - line -= 20; - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - } - } while (dos_mcb_next(&men)); - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - } - } - - /* list devices */ - { - struct dos_device_enum denu; - - if (dos_device_first(&denu)) { - printf("Device drivers\n"); line++; - do { - printf(" ATTR=%04Xh entry=%04Xh int=%04Xh %s\n",denu.attr,denu.entry,denu.intent,denu.name); - - if (++line >= 20) { - line -= 20; - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - } - } while (dos_device_next(&denu)); - - /* ENTER for next, ESC to stop */ - while ((c=getch()) != 13) { - if (c == 27) return 0; - } - } - } - - return 0; -} - diff --git a/src/lib/doslib/dos/ntastrm.c b/src/lib/doslib/dos/ntastrm.c deleted file mode 100644 index 97f38a1a..00000000 --- a/src/lib/doslib/dos/ntastrm.c +++ /dev/null @@ -1,68 +0,0 @@ -/* ntastrm.c - * - * Utility program: Manually trigger the removal of the DOSNTAST driver. - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - * - * If a program using DOSNTAST fails to unload the driver, it will remain resident. - * This program allows you to remove it manually if that happens. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef TARGET_WINDOWS -# define WINFCON_STOCK_WIN_MAIN -# include -#endif - -int main() { - /* probe_dos() and detect_windows() should NOT auto-load the DOSNTAST driver. - * we're going to unload it if resident. */ - lib_dos_option.dont_load_dosntast=1; - - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - printf(" Method: '%s'\n",dos_version_method); - - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%u\n",windows_version>>8,windows_version&0xFF); - printf(" Method: '%s'\n",windows_version_method); - if (windows_emulation != WINEMU_NONE) - printf(" Emulation: '%s'\n",windows_emulation_str(windows_emulation)); - if (windows_emulation_comment_str != NULL) - printf(" Emulation comment: '%s'\n",windows_emulation_comment_str); - } - else { - printf("Not running under Windows or OS/2\n"); - } - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) - if (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED) { - printf("DOSNTAST.VDD driver was loaded (handle=%u), unloading...\n",ntvdm_dosntast_handle); - ntvdm_dosntast_unload(); - } -#endif - - return 0; -} - diff --git a/src/lib/doslib/dos/readme b/src/lib/doslib/dos/readme deleted file mode 100644 index 46f7d2b5..00000000 --- a/src/lib/doslib/dos/readme +++ /dev/null @@ -1,7 +0,0 @@ - -DOS support library - dos.obj ......................... Helper functions for DOS I/O to far and huge memory - emm.obj ......................... Utility library to make use of the Expanded Memory Manager (usually, EMM386.EXE) - dosbox.obj ...................... Utility function to detect if we're running in the DOSBox emulator - biosext.obj ..................... Utility function for real-mode software to use BIOS INT 15H AH=0x87 extended memory copy function - himemsys.obj .................... Utility library to make use of Extended Memory via HIMEM.SYS diff --git a/src/lib/doslib/dos/test.c b/src/lib/doslib/dos/test.c deleted file mode 100644 index e3c83e26..00000000 --- a/src/lib/doslib/dos/test.c +++ /dev/null @@ -1,165 +0,0 @@ -/* test.c - * - * Test program: Various info about DOS - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef TARGET_WINDOWS -# define WINFCON_STOCK_WIN_MAIN -# include -#endif - -int main() { - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - printf(" Method: '%s'\n",dos_version_method); - printf(" Flavor: '%s'\n",dos_flavor_str(dos_flavor)); - if (dos_flavor == DOS_FLAVOR_FREEDOS) { - printf(" FreeDOS kernel %u.%u.%u (%lX)\n", - (unsigned int)((freedos_kernel_version >> 16UL) & 0xFFUL), - (unsigned int)((freedos_kernel_version >> 8UL) & 0xFFUL), - (unsigned int)((freedos_kernel_version) & 0xFFUL), - (unsigned long)freedos_kernel_version); - if (freedos_kernel_version_str != NULL) { -#if TARGET_MSDOS == 32 - printf(" FreeDOS kernel version string: %s\n", - freedos_kernel_version_str); -#else - printf(" FreeDOS kernel version string: %Fs\n", - freedos_kernel_version_str); -#endif - } - } - - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%u\n",windows_version>>8,windows_version&0xFF); - printf(" Method: '%s'\n",windows_version_method); - if (windows_emulation != WINEMU_NONE) - printf(" Emulation: '%s'\n",windows_emulation_str(windows_emulation)); - if (windows_emulation_comment_str != NULL) - printf(" Emulation comment: '%s'\n",windows_emulation_comment_str); - } - else { - printf("Not running under Windows or OS/2\n"); - } - -#if defined(NTVDM_CLIENT) && !defined(TARGET_WINDOWS) - if (ntvdm_dosntast_handle != DOSNTAST_HANDLE_UNASSIGNED) { - OSVERSIONINFO o; - WAVEOUTCAPS woc; - unsigned int i,j; - uint32_t dw; - - printf("This program is using the DOSNTAST.VDD driver (handle=%u io=0x%03X)\n",ntvdm_dosntast_handle,ntvdm_dosntast_io_base); - - printf("GetTickCount() = %lu\n",ntvdm_dosntast_GetTickCount()); - printf("waveOutGetNumDevs() = %d\n",j=ntvdm_dosntast_waveOutGetNumDevs()); - for (i=0;i < j;i++) { - memset(&woc,0,sizeof(woc)); - if ((dw=ntvdm_dosntast_waveOutGetDevCaps(i,&woc,sizeof(woc))) == 0) { - printf(" [%u]: %s v%u.%u\n",i,woc.szPname,woc.vDriverVersion>>8,woc.vDriverVersion&0xFF); - printf(" MID=0x%04lX PID=0x%04lX FMTS=0x%08lX chan=%u\n", - (unsigned long)woc.wMid, - (unsigned long)woc.wPid, - (unsigned long)woc.dwFormats, - woc.wChannels); - printf(" CAPS: "); - if (woc.dwSupport & WAVECAPS_LRVOLUME) printf("LRVOL "); - if (woc.dwSupport & WAVECAPS_PITCH) printf("PITCH "); - if (woc.dwSupport & WAVECAPS_PLAYBACKRATE) printf("PLAYRATE "); - if (woc.dwSupport & WAVECAPS_SYNC) printf("SYNC "); - if (woc.dwSupport & WAVECAPS_VOLUME) printf("VOL "); - if (woc.dwSupport & WAVECAPS_SAMPLEACCURATE) printf("SAMPLEACCURATE "); - printf("\n"); - } - else { - printf(" [%u]: Cannot read err=0x%08lX\n",i,dw); - } - } - - printf("GetVersionEx() = "); - o.dwOSVersionInfoSize = sizeof(o); - if (ntvdm_dosntast_getversionex(&o)) { - printf("v%lu.%lu build #%lu platform=%lu '%s'", - o.dwMajorVersion, - o.dwMinorVersion, - o.dwBuildNumber, - o.dwPlatformId, - o.szCSDVersion); - } - else { - printf("failed?"); - } - printf("\n"); - - ntvdm_dosntast_MessageBox("Hello!\n\nIf you can read this, DOS programs are able to use the driver successfully!"); - } -#endif - - if (detect_dosbox_emu()) - printf("I am also running under DOSBox\n"); - if (detect_virtualbox_emu()) - printf("I am also running under Sun/Oracle VirtualBox %s\n",virtualbox_version_str); - - probe_dpmi(); -#if dpmi_present != 0 - if (dpmi_present) { - printf("DPMI present:\n"); -# if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && !defined(TARGET_WINDOWS)) - if (dpmi_no_0301h > 0) printf(" - DPMI function 0301H: Call real-mode far routine NOT AVAILABLE\n"); - printf(" - Flags: 0x%04x\n",dpmi_flags); - printf(" - Entry: %04x:%04x (real mode)\n",(unsigned int)(dpmi_entry_point>>16UL),(unsigned int)(dpmi_entry_point & 0xFFFFUL)); - printf(" - Processor type: %02x\n",dpmi_processor_type); - printf(" - Version: %u.%u\n",dpmi_version>>8,dpmi_version&0xFF); - printf(" - Private data length: %u paras\n",dpmi_private_data_length_paragraphs); -# endif - } -#endif - - if (probe_vcpi()) { - printf("VCPI present (v%d.%d)\n", - vcpi_major_version, - vcpi_minor_version); - } - -#ifdef WINFCON_STOCK_WIN_MAIN - { - char c; - - printf("---------[Type junk here]---------\n"); - do { - c = getch(); - if (c == 27) break; - else if (c == 13) printf("\n"); - else printf("%c",c); - } while (1); - } -#endif - - return 0; -} - diff --git a/src/lib/doslib/dos/testbext.c b/src/lib/doslib/dos/testbext.c deleted file mode 100644 index 2f0ad0d8..00000000 --- a/src/lib/doslib/dos/testbext.c +++ /dev/null @@ -1,63 +0,0 @@ -/* testbext.c - * - * Test program: Use INT 15h to copy extended memory. - * (C) 2010-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - * - * This program shows that the API works, and also reveals whether or not - * the BIOS API is limited to 16MB. */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int main() { -#if TARGET_MSDOS == 16 - { - unsigned int i; - unsigned long addr; - unsigned char tmp[16]; - - printf("Copying data out of extended memory via BIOS\n"); - for (addr=0xFFF80UL;addr < 0x100000UL;addr += sizeof(tmp)) { - memset(tmp,0,sizeof(tmp)); - if (bios_extcopy(ptr2phys(tmp),addr,16)) { - printf("Problem copying\n"); - break; - } - for (i=0;i < 16;i++) printf("%02x ",tmp[i]); - for (i=0;i < 16;i++) printf("%c",tmp[i] >= 32 ? tmp[i] : ' '); - printf("\n"); - } - while (getch() != 13); - - printf("Copying data out of extended memory via BIOS (16MB higher)\n"); - for (addr=0x10FFF80UL;addr < 0x1100000UL;addr += sizeof(tmp)) { - memset(tmp,0,sizeof(tmp)); - if (bios_extcopy(ptr2phys(tmp),addr,16)) { - printf("Problem copying\n"); - break; - } - for (i=0;i < 16;i++) printf("%02x ",tmp[i]); - for (i=0;i < 16;i++) printf("%c",tmp[i] >= 32 ? tmp[i] : ' '); - printf("\n"); - } - while (getch() != 13); - } -#else - printf("Test does not apply to 32-bit builds\n"); -#endif - - return 0; -} - diff --git a/src/lib/doslib/dos/testdpmi.c b/src/lib/doslib/dos/testdpmi.c deleted file mode 100644 index f16aa13c..00000000 --- a/src/lib/doslib/dos/testdpmi.c +++ /dev/null @@ -1,89 +0,0 @@ -/* testdpmi.c - * - * Test program: DPMI entry/exit functions - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef TARGET_WINDOWS -#error wrong target -#endif - -int main(int argc,char **argv) { - unsigned char want = DPMI_ENTER_AUTO; - - if (argc > 1) { - want = atoi(argv[1]); - if (want < 16 || want > 32) return 1; - } - - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - printf(" Method: '%s'\n",dos_version_method); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - printf(" Method: '%s'\n",windows_version_method); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - probe_dpmi(); - if (!dpmi_present) { - printf("This test requires DPMI\n"); - return 1; - } - - printf("DPMI present:\n"); -#if dpmi_no_0301h != 0 - if (dpmi_no_0301h > 0) printf(" - DPMI function 0301H: Call real-mode far routine NOT AVAILABLE\n"); -#endif - printf(" - Flags: 0x%04x\n",dpmi_flags); - printf(" - Entry: %04x:%04x (real mode)\n",(unsigned int)(dpmi_entry_point>>16UL),(unsigned int)(dpmi_entry_point & 0xFFFFUL)); - printf(" - Processor type: %02x\n",dpmi_processor_type); - printf(" - Version: %u.%u\n",dpmi_version>>8,dpmi_version&0xFF); - printf(" - Private data length: %u paras\n",dpmi_private_data_length_paragraphs); - - /* enter DPMI. the routine will briefly run in protected mode before finding it's way - * back to real mode where it can return back to this function */ - if (!dpmi_enter(want)) { - printf("Unable to enter DPMI server\n"); - return 1; - } - printf("Allocated DPMI private segment: 0x%04x\n",dpmi_private_data_segment); - printf("DPMI entered as %u-bit.\n",dpmi_entered); - printf(" - PM CS:%04x DS:%04x ES:%04x SS:%04x\n",dpmi_pm_cs,dpmi_pm_ds,dpmi_pm_es,dpmi_pm_ss); - printf(" - Real to protected entry: %04x:%04x [rmode]\n", - (unsigned int)(dpmi_pm_entry>>16UL),(unsigned int)(dpmi_pm_entry&0xFFFFUL)); - if (dpmi_entered == 32) - printf(" - Protected to real entry: %04x:%08lx [pmode]\n", - (unsigned int)((dpmi_rm_entry>>32ULL)&0xFFFFUL),(unsigned long)(dpmi_rm_entry&0xFFFFFFFFUL)); - else - printf(" - Protected to real entry: %04x:%04x [pmode]\n", - (unsigned int)(dpmi_rm_entry>>16UL),(unsigned int)(dpmi_rm_entry&0xFFFFUL)); - - return 0; -} - diff --git a/src/lib/doslib/dos/testemm.c b/src/lib/doslib/dos/testemm.c deleted file mode 100644 index 329e4e66..00000000 --- a/src/lib/doslib/dos/testemm.c +++ /dev/null @@ -1,271 +0,0 @@ -/* testemm.c - * - * Test program: Expanded Memory Manager functions - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static const char *message = "Hello world. How are you?"; -static const char *message2 = "Pingas. Sup dawg. Hello world. Dork. Hahahajajaja."; -static char tmp[128],tmp2[128]; - -#if 1 -# define x_memcpy(a,b,c) memcpy(a,b,c) -#else -/* what have we come to when friggin' memcpy() causes a GPF?!? */ -static void x_memcpy(unsigned char *dst,const unsigned char *src,size_t c) { - fprintf(stderr,"memcpy %p -> %p (%lu)\n", - dst,src,(unsigned long)c); - - while (c != 0) { - *dst++ = *src++; - c--; - } -} -#endif - -int main() { - size_t message_l = strlen(message),message2_l = strlen(message2); - - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - sanity(); - if (probe_emm()) { - int h1,h2,h3; - - sanity(); - printf("Expanded memory manager present. Status = 0x%02x Page frame @0x%04x v%x.%x\n",emm_status,emm_page_frame_segment,emm_version>>4,emm_version&0x0F); - emm_update_page_count(); - sanity(); - printf(" Unallocated pages: %u (%luKB)\n", - emm_unallocated_pages, - (unsigned long)emm_unallocated_pages << 4UL); /* 2^14 = 16384 */ - printf(" Total pages: %u (%luKB)\n", - emm_total_pages, - (unsigned long)emm_total_pages << 4UL); - printf(" Physical pages: %u (%luKB)\n", - emm_phys_pages, - (unsigned long)emm_phys_pages << 4UL); - - while (getch() != 13); - sanity(); - - /* print out the mapping table, if available */ - if (emm_phys_map != NULL) { - struct emm_phys_page_map *me; - unsigned int i; - - printf("Physical page to segment table\n"); - for (i=0;i < emm_phys_pages;i++) { - me = emm_phys_map + i; - printf(" %02x: 0x%04x",me->number,me->segment); - if ((i%5) == 4) printf("\n"); - } - printf("\n"); - sanity(); - } - - printf("Allocating EMM pages (1): "); - h1 = emm_alloc_pages(1); - sanity(); - if (h1 >= 0) { - printf("OK, handle=%u\n",h1); - if (!emm_free_pages(h1)) printf("cannot free\n"); - } - else printf("FAILED\n"); - - printf("Allocating EMM pages (16KB): "); - h1 = emm_alloc_pages(1); - sanity(); - if (h1 >= 0) printf("OK, handle=%u\n",h1); - else printf("FAILED\n"); - - printf("Allocating EMM pages (1MB): "); - h2 = emm_alloc_pages(0x100000UL >> 14UL); - sanity(); - if (h2 >= 0) printf("OK, handle=%u\n",h2); - else printf("FAILED\n"); - - printf("Allocating EMM pages (12MB): "); - h3 = emm_alloc_pages(0xC00000UL >> 14UL); - sanity(); - if (h3 >= 0) printf("OK, handle=%u\n",h3); - else printf("FAILED\n"); - - while (getch() != 13); - - if (h1 >= 0 && !emm_free_pages(h1)) printf("Cannot free\n"); - sanity(); - if (h2 >= 0 && !emm_free_pages(h2)) printf("Cannot free\n"); - sanity(); - if (h3 >= 0 && !emm_free_pages(h3)) printf("Cannot free\n"); - sanity(); - - printf("Allocating EMM pages (32KB): "); - h1 = emm_alloc_pages(2); - sanity(); - if (h1 >= 0) { - printf("OK, handle=%u\n",h1); - if (emm_map_page(h1,/*physical*/0,/*logical*/0)) { - unsigned int segm = emm_last_phys_page_segment(0); - printf("Seg %04x\n",segm); - sanity(); - if (segm > 0) { -#if TARGET_MSDOS == 16 - char far *ptr = MK_FP(segm,0); -#else - char *ptr = (char*)(segm << 4UL); -#endif - -#if TARGET_MSDOS == 16 - _fmemcpy(ptr,(char far*)message,message_l+1); - _fmemcpy((char far*)tmp,ptr,message_l+1); -#else - x_memcpy(ptr,message,message_l+1); - x_memcpy(tmp,ptr,message_l+1); -#endif - printf("After writing message there, I read back: '%s'\n",tmp); - - if (!emm_map_page(h1,0,1)) printf("Cannot remap\n"); - -#if TARGET_MSDOS == 16 - _fmemcpy(ptr,(char far*)message2,message2_l+1); - _fmemcpy((char far*)tmp,ptr,message2_l+1); -#else - x_memcpy(ptr,message2,message2_l+1); - x_memcpy(tmp,ptr,message2_l+1); -#endif - printf("After mapping to page 2 and writing there, I read back: '%s'\n",tmp); - - if (!emm_map_page(h1,0,0)) printf("Cannot remap\n"); - -#if TARGET_MSDOS == 16 - _fmemcpy((char far*)tmp,ptr,message_l+1); -#else - x_memcpy(tmp,ptr,message_l+1); -#endif - printf("After mapping back to 1, I read back: '%s'\n",tmp); - - if (emm_map_page(h1,0,2)) printf("Whoops, I was able to map logical pages beyond what I allocated\n"); - } - else { - printf("Cannot get segment\n"); - } - if (!emm_map_page(h1,0,0xFFFF)) printf("Cannot unmap\n"); - } - else { - printf("Cannot map\n"); - } - if (!emm_free_pages(h1)) printf("Cannot free\n"); - } - else printf("FAILED\n"); - - printf("Allocating EMM pages (32KB): "); - h1 = emm_alloc_pages(2); - if (h1 >= 0) { - printf("OK, handle=%u\n",h1); - if ( emm_map_page(h1,/*physical*/0,/*logical*/0) && - emm_map_page(h1,/*physical*/1,/*logical*/1)) { - unsigned int seg1 = emm_last_phys_page_segment(0); - unsigned int seg2 = emm_last_phys_page_segment(1); - printf("Seg %04x,%04x\n",seg1,seg2); - if (seg1 > 0 && seg2 > 0) { -#if TARGET_MSDOS == 16 - char far *ptr1 = MK_FP(seg1,0); - char far *ptr2 = MK_FP(seg2,0); -#else - char *ptr1 = (char*)(seg1 << 4UL); - char *ptr2 = (char*)(seg2 << 4UL); -#endif - -#if TARGET_MSDOS == 16 - _fmemcpy(ptr1,(char far*)message,message_l+1); - _fmemcpy(ptr2,(char far*)message2,message2_l+1); -#else - memcpy(ptr1,message,message_l+1); - memcpy(ptr2,message2,message2_l+1); -#endif - -#if TARGET_MSDOS == 16 - _fmemcpy((char far*)tmp,ptr1,message_l+1); - _fmemcpy((char far*)tmp2,ptr2,message2_l+1); -#else - memcpy(tmp,ptr1,message_l+1); - memcpy(tmp2,ptr2,message2_l+1); -#endif - - printf("After writing message there, I read back:\n'%s'\n'%s'\n",tmp,tmp2); - - /* now swap the pages */ - if (!emm_map_page(h1,1,0)) printf("cannot map log 1 -> phys 0\n"); - if (!emm_map_page(h1,0,1)) printf("cannot map log 0 -> phys 1\n"); - -#if TARGET_MSDOS == 16 - _fmemcpy((char far*)tmp,ptr1,message2_l+1); - _fmemcpy((char far*)tmp2,ptr2,message_l+1); -#else - memcpy(tmp,ptr1,message2_l+1); - memcpy(tmp2,ptr2,message_l+1); -#endif - - printf("After swapping pages, I read back:\n'%s'\n'%s'\n",tmp,tmp2); - } - else { - printf("Cannot get segment\n"); - } - if (!emm_map_page(h1,0,0xFFFF) || !emm_map_page(h1,1,0xFFFF)) printf("Cannot unmap\n"); - } - else { - printf("Cannot map\n"); - } - if (!emm_free_pages(h1)) printf("Cannot free\n"); - } - else printf("FAILED\n"); - - /* we do this test because Microsoft EMM386.EXE seems to max out at 32MB. - * the host could have 256MB of total memory and it would still report 32MB in EMS */ - printf("Allocating EMM pages (48MB): "); - h1 = emm_alloc_pages((48UL << 20UL) >> 14UL); - if (h1 >= 0) { - printf("OK, handle=%u\n",h1); - if (!emm_free_pages(h1)) printf("cannot free\n"); - } - else printf("FAILED\n"); - - printf("Allocating EMM pages (96MB): "); - h1 = emm_alloc_pages((96UL << 20UL) >> 14UL); - if (h1 >= 0) { - printf("OK, handle=%u\n",h1); - if (!emm_free_pages(h1)) printf("cannot free\n"); - } - else printf("FAILED\n"); - } - - return 0; -} - diff --git a/src/lib/doslib/dos/testsmrt.c b/src/lib/doslib/dos/testsmrt.c deleted file mode 100644 index ffd31fac..00000000 --- a/src/lib/doslib/dos/testsmrt.c +++ /dev/null @@ -1,47 +0,0 @@ -/* testsmrt.c - * - * Test program: Demonstrate SMARTDRV detection code. - * (C) 2014 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int main() { - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - printf(" Flavor: '%s'\n",dos_flavor_str(dos_flavor)); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - if (smartdrv_detect()) { - printf("SMARTDRV %u.%02u detected!\n",smartdrv_version>>8,smartdrv_version&0xFF); - printf("Now flushing\n"); - smartdrv_flush(); - printf("Made it.\n"); - smartdrv_close(); - } - - return 0; -} - diff --git a/src/lib/doslib/dos/tgusmega.c b/src/lib/doslib/dos/tgusmega.c deleted file mode 100644 index 635dead9..00000000 --- a/src/lib/doslib/dos/tgusmega.c +++ /dev/null @@ -1,46 +0,0 @@ - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -struct mega_em_info megaem_info={0}; - -int gravis_mega_em_detect(struct mega_em_info *x) { -/* TODO: Cache results, only need to scan once */ - union REGS regs={0}; - regs.w.ax = 0xFD12; - regs.w.bx = 0x3457; -#if TARGET_MSDOS == 32 - int386(0x21,®s,®s); -#else - int86(0x21,®s,®s); -#endif - if (regs.w.ax == 0x5678) { - x->intnum = regs.h.cl; - x->version = regs.w.dx; - x->response = regs.w.bx; - - if (x->version == 0) { - if (x->response == 0x1235) - x->version = 0x200; - else if (x->response == 0x1237) - x->version = 0x300; - } - return 1; - } - return 0; -} -#endif - diff --git a/src/lib/doslib/dos/tgusmega.h b/src/lib/doslib/dos/tgusmega.h deleted file mode 100644 index 180a8a23..00000000 --- a/src/lib/doslib/dos/tgusmega.h +++ /dev/null @@ -1,16 +0,0 @@ - -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -# define HAVE_GUS_MEGAEM_DETECT -struct mega_em_info { - unsigned char intnum; - uint16_t version; - uint16_t response; -}; - -extern struct mega_em_info megaem_info; - -int gravis_mega_em_detect(struct mega_em_info *x); -#endif - diff --git a/src/lib/doslib/dos/tgussbos.c b/src/lib/doslib/dos/tgussbos.c deleted file mode 100644 index de4f129f..00000000 --- a/src/lib/doslib/dos/tgussbos.c +++ /dev/null @@ -1,60 +0,0 @@ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* returns interrupt vector */ -/* these functions are duplicates of the ones in the ULTRASND library - because it matters to this library whether or not we're talking to - Gravis Ultrasound and shitty SB emulation */ -int gravis_sbos_detect() { - unsigned char FAR *ex; - uint16_t s,o; - int i = 0x78; - - while (i < 0x90) { -#if TARGET_MSDOS == 32 - o = *((uint16_t*)(i*4U)); - s = *((uint16_t*)((i*4U)+2U)); -#else - o = *((uint16_t far*)MK_FP(0,(uint16_t)i*4U)); - s = *((uint16_t far*)MK_FP(0,((uint16_t)i*4U)+2U)); -#endif - - if (o == 0xFFFF || s == 0x0000 || s == 0xFFFF) { - i++; - continue; - } - - /* we're looking for "SBOS" signature */ -#if TARGET_MSDOS == 32 - ex = (unsigned char*)((s << 4UL) + 0xA); - if (memcmp(ex,"SBOS",4) == 0) return i; -#else - ex = MK_FP(s,0xA); - if (_fmemcmp(ex,"SBOS",4) == 0) return i; -#endif - - i++; - } - - return -1; -} -#endif - diff --git a/src/lib/doslib/dos/tgussbos.h b/src/lib/doslib/dos/tgussbos.h deleted file mode 100644 index 0d7df0d5..00000000 --- a/src/lib/doslib/dos/tgussbos.h +++ /dev/null @@ -1,3 +0,0 @@ - -int gravis_sbos_detect(); - diff --git a/src/lib/doslib/dos/tgusumid.c b/src/lib/doslib/dos/tgusumid.c deleted file mode 100644 index a49c886f..00000000 --- a/src/lib/doslib/dos/tgusumid.c +++ /dev/null @@ -1,57 +0,0 @@ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#if !defined(TARGET_WINDOWS) && !defined(TARGET_OS2) -/* returns interrupt vector */ -int gravis_ultramid_detect() { - unsigned char FAR *ex; - uint16_t s,o; - int i = 0x78; - - while (i < 0x90) { -#if TARGET_MSDOS == 32 - o = *((uint16_t*)(i*4U)); - s = *((uint16_t*)((i*4U)+2U)); -#else - o = *((uint16_t far*)MK_FP(0,(uint16_t)i*4U)); - s = *((uint16_t far*)MK_FP(0,((uint16_t)i*4U)+2U)); -#endif - - if (o == 0xFFFF || s == 0x0000 || s == 0xFFFF) { - i++; - continue; - } - - /* we're looking for "ULTRAMID" signature */ -#if TARGET_MSDOS == 32 - ex = (unsigned char*)((s << 4UL) + 0x103); - if (memcmp(ex,"ULTRAMID",8) == 0) return i; -#else - ex = MK_FP(s,0x103); - if (_fmemcmp(ex,"ULTRAMID",8) == 0) return i; -#endif - - i++; - } - - return -1; -} -#endif /* !defined(TARGET_WINDOWS) */ - diff --git a/src/lib/doslib/dos/tgusumid.h b/src/lib/doslib/dos/tgusumid.h deleted file mode 100644 index dcfa2f58..00000000 --- a/src/lib/doslib/dos/tgusumid.h +++ /dev/null @@ -1,3 +0,0 @@ - -int gravis_ultramid_detect(); - diff --git a/src/lib/doslib/dos/tmp.cmd b/src/lib/doslib/dos/tmp.cmd deleted file mode 100644 index e83b3cbd..00000000 --- a/src/lib/doslib/dos/tmp.cmd +++ /dev/null @@ -1 +0,0 @@ --fr=nul -fo=dos386f/.obj -i=.. -i../.. -e=2 -zq -mf -d0 -bt=dos -oilrtfm -wx -fp3 -3r -dTARGET_MSDOS=32 -dMSDOS=1 -dTARGET86=386 -DMMODE=f -q dosdpmi.c diff --git a/src/lib/doslib/dos/tstbiom.c b/src/lib/doslib/dos/tstbiom.c deleted file mode 100644 index be6fd96c..00000000 --- a/src/lib/doslib/dos/tstbiom.c +++ /dev/null @@ -1,82 +0,0 @@ -/* tstbiom.c - * - * Test program: BIOS extended memory layout and reporting - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -int main() { -#if TARGET_MSDOS == 16 - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - { - unsigned int l; - if (biosmem_size_88(&l)) { - printf("BIOS memory (INT 15H AH=0x88)\n"); - printf(" Total memory: %uKB (%uMB)\n",l,l >> 10UL); - } - } - - { - unsigned int l,h; - if (biosmem_size_E801(&l,&h)) { - printf("BIOS memory (INT 15H AX=0xE801)\n"); - printf(" Total memory: 1MB + %uKB + %luKB = %luKB (%luMB)\n", - l,(unsigned long)h * 64UL,(unsigned long)l + ((unsigned long)h * 64UL) + 1024UL, - ((unsigned long)l + ((unsigned long)h * 64UL) + 1024UL) >> 10UL); - if (l != 0) printf(" 1-16MB: 0x%08lX-0x%08lX\n",0x100000UL,0x100000UL + ((unsigned long)l << 10UL) - 1UL); - if (h != 0) printf(" 16MB+: 0x%08lX-0x%08lX\n",0x1000000UL,0x1000000UL + ((unsigned long)h << 16UL) - 1UL); - } - } - - { - struct bios_E820 nfo; - unsigned long index,pindex; - int len; - - index = pindex = 0; - if ((len=biosmem_size_E820(&index,&nfo)) > 0) { - printf("BIOS memory (INT 15H AX=E820)\n"); - do { - printf(" len=%u index=0x%02lX 0x%012llx-0x%012llx type=0x%02lx attr=0x%02lx\n", - len,(unsigned long)pindex, - (unsigned long long)nfo.base, - (unsigned long long)(nfo.base + nfo.length - 1ULL), - nfo.type,nfo.ext_attributes); - if (index == 0) break; /* the BIOS will return with EBX == 0 when returning the last item */ - pindex = index; - } while ((len=biosmem_size_E820(&index,&nfo)) > 0); - } - } -#else /* == 32 */ - printf("This program is pointless in 32-bit protected mode\n"); -#endif - return 0; -} - diff --git a/src/lib/doslib/dos/tstlp.c b/src/lib/doslib/dos/tstlp.c deleted file mode 100644 index 5f6f8ad8..00000000 --- a/src/lib/doslib/dos/tstlp.c +++ /dev/null @@ -1,110 +0,0 @@ -/* tstlp.c - * - * Test program: DOS memory map awareness library - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if TARGET_MSDOS == 32 -uint16_t cpu_read_my_cs() { - uint16_t r=0; - - __asm { - push cs - pop ax - mov r,ax - } - - return r; -} -#endif - -int main() { -#if TARGET_MSDOS == 32 - uint16_t sg; - int c; -#endif - - probe_dos(); - printf("DOS version %x.%02u\n",dos_version>>8,dos_version&0xFF); - if (detect_windows()) { - printf("I am running under Windows.\n"); - printf(" Mode: %s\n",windows_mode_str(windows_mode)); - printf(" Ver: %x.%02u\n",windows_version>>8,windows_version&0xFF); - } - else { - printf("Not running under Windows or OS/2\n"); - } - - if (detect_dosbox_emu()) - printf("I am also running under DOSBox\n"); - -#if TARGET_MSDOS == 16 - /* TODO: Someday the dos_ltp() code will work in 16-bit mode, for environments like EMM386.EXE v86 or from within - * the 16-bit Windows 3.1 world */ - printf("This program is intended to test memory mapping under 32-bit protected mode and does not apply to 16-bit real mode\n"); -#else - if (!dos_ltp_probe()) { - printf("DOS linear->physical translation probe failed\n"); - return 1; - } - - sg = cpu_read_my_cs(); - printf("Results:\n"); - printf(" Paging: %u (CPU paging enabled)\n",dos_ltp_info.paging); - printf(" DOS remap: %u (memory below 1MB is remapped, not 1:1)\n",dos_ltp_info.dos_remap); - printf(" Should lock pages: %u (Extender may page to disk or move pages)\n",dos_ltp_info.should_lock_pages); - printf(" Can't xlate: %u (No way to determine physical mem addr)\n",dos_ltp_info.cant_xlate); - printf(" Using PAE: %u (DOS extender is using PAE)\n",dos_ltp_info.using_pae); - printf(" DMA DOS xlate: %u (DMA is translated too, virtualized)\n",dos_ltp_info.dma_dos_xlate); - printf(" use VCPI xlate: %u (VCPI server can provide translation)\n",dos_ltp_info.vcpi_xlate); - printf(" CR0: 0x%08lx\n",dos_ltp_info.cr0); - printf(" CR3: 0x%08lx\n",dos_ltp_info.cr3); - printf(" CR4: 0x%08lx\n",dos_ltp_info.cr4); - printf(" CS: 0x%04x %s CPL=%u\n",(unsigned int)sg,sg & 4 ? "LDT" : "GDT",sg&3); - - while ((c=getch()) != 13) { - if (c == 27) return 1; - } - - { - uint32_t l; - uint64_t p; - int line=0; - - printf("Map test (32MB):\n"); - for (l=0;l < (32UL << 20UL);l += 4096) { - printf("0x%08lX: ",l); fflush(stdout); - p = dos_linear_to_phys(l); - if (p == DOS_LTP_FAILED) printf("N/A\n"); - else printf("0x%08llX\n",p); - - if (++line >= 24) { - line -= 24; - while ((c=getch()) != 13) { - if (c == 27) return 1; - } - } - } - } -#endif - - return 0; -} - diff --git a/src/lib/doslib/dos/win16vec.c b/src/lib/doslib/dos/win16vec.c deleted file mode 100644 index 31ef6281..00000000 --- a/src/lib/doslib/dos/win16vec.c +++ /dev/null @@ -1,106 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Watcom C does not provide getvect/setvect for Win16, so we abuse the DPMI server within and provide one anyway */ -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -void far *win16_getexhandler(unsigned char n) { - unsigned short s=0,o=0; - - __asm { - mov ax,0x202 - mov bl,n - xor cx,cx - xor dx,dx - int 31h - mov s,cx - mov o,dx - } - - return MK_FP(s,o); -} - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -int win16_setexhandler(unsigned char n,void far *x) { - unsigned short s=FP_SEG(x),o=FP_OFF(x); - int c=1; - - __asm { - mov ax,0x203 - mov bl,n - mov cx,s - mov dx,o - int 31h - jnc ok - mov c,0 -ok: - } - - return c; -} - -void far *win16_getvect(unsigned char n) { - unsigned short s=0,o=0; - - __asm { - mov ax,0x204 - mov bl,n - xor cx,cx - xor dx,dx - int 31h - mov s,cx - mov o,dx - } - - return MK_FP(s,o); -} - -/* NTS: This only allows for exception interrupts 0x00-0x1F */ -int win16_setvect(unsigned char n,void far *x) { - unsigned short s=FP_SEG(x),o=FP_OFF(x); - int c=1; - - __asm { - mov ax,0x205 - mov bl,n - mov cx,s - mov dx,o - int 31h - jnc ok - mov c,0 -ok: - } - - return c; -} - -#endif - diff --git a/src/lib/doslib/dos/win3216t.c b/src/lib/doslib/dos/win3216t.c deleted file mode 100644 index 984449fa..00000000 --- a/src/lib/doslib/dos/win3216t.c +++ /dev/null @@ -1,102 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 16 - -/* if provided by the system, these functions allow library and application code to call out to the Win32 world from Win16. - * Which is absolutely necessary given that Win16 APIs tend to lie for compatibility reasons. */ - -DWORD genthunk32w_ntdll = 0; -DWORD genthunk32w_kernel32 = 0; -DWORD genthunk32w_kernel32_GetVersion = 0; -DWORD genthunk32w_kernel32_GetVersionEx = 0; -DWORD genthunk32w_kernel32_GetLastError = 0; -BOOL __GenThunksExist = 0; -BOOL __GenThunksChecked = 0; -DWORD (PASCAL FAR *__LoadLibraryEx32W)(LPCSTR lpName,DWORD reservedhfile,DWORD dwFlags) = NULL; -BOOL (PASCAL FAR *__FreeLibrary32W)(DWORD hinst) = NULL; -DWORD (PASCAL FAR *__GetProcAddress32W)(DWORD hinst,LPCSTR name) = NULL; -DWORD (PASCAL FAR *__GetVDMPointer32W)(LPVOID ptr,UINT mask) = NULL; -DWORD (PASCAL FAR *__CallProc32W)(DWORD procaddr32,DWORD convertMask,DWORD params,...) = NULL; /* <- FIXME: How to use? */ -DWORD (_cdecl _far *__CallProcEx32W)(DWORD params,DWORD convertMask,DWORD procaddr32,...) = NULL; - -int genthunk32_init() { - if (!__GenThunksChecked) { - HMODULE kern32; - - genthunk32_free(); - __GenThunksExist = 0; - __GenThunksChecked = 1; - kern32 = GetModuleHandle("KERNEL"); - if (kern32 != NULL) { - __LoadLibraryEx32W = (void far*)GetProcAddress(kern32,"LOADLIBRARYEX32W"); - __FreeLibrary32W = (void far*)GetProcAddress(kern32,"FREELIBRARY32W"); - __GetProcAddress32W = (void far*)GetProcAddress(kern32,"GETPROCADDRESS32W"); - __GetVDMPointer32W = (void far*)GetProcAddress(kern32,"GETVDMPOINTER32W"); - __CallProcEx32W = (void far*)GetProcAddress(kern32,"_CALLPROCEX32W"); /* <- Hey thanks Microsoft - maybe if your docs mentioned - the goddamn underscore I would - have an easier time linking to it */ - __CallProc32W = (void far*)GetProcAddress(kern32,"CALLPROC32W"); - - if (__LoadLibraryEx32W && __FreeLibrary32W && __GetProcAddress32W && __GetVDMPointer32W && - __CallProc32W && __CallProcEx32W) { - __GenThunksExist = 1; - - genthunk32w_kernel32 = __LoadLibraryEx32W("KERNEL32.DLL",0,0); - if (genthunk32w_kernel32 != 0) { - genthunk32w_kernel32_GetVersion = - __GetProcAddress32W(genthunk32w_kernel32,"GetVersion"); - genthunk32w_kernel32_GetVersionEx = - __GetProcAddress32W(genthunk32w_kernel32,"GetVersionExA"); - genthunk32w_kernel32_GetLastError = - __GetProcAddress32W(genthunk32w_kernel32,"GetLastError"); - } - - genthunk32w_ntdll = __LoadLibraryEx32W("NTDLL.DLL",0,0); - } - } - } - - return __GenThunksExist; -} - -void genthunk32_free() { - genthunk32w_kernel32_GetVersion = 0; - genthunk32w_kernel32_GetVersionEx = 0; - genthunk32w_kernel32_GetLastError = 0; - if (genthunk32w_kernel32) { - __FreeLibrary32W(genthunk32w_kernel32); - genthunk32w_kernel32 = 0; - } -} - -#endif - diff --git a/src/lib/doslib/dos/win32lrd.c b/src/lib/doslib/dos/win32lrd.c deleted file mode 100644 index fd39a7a0..00000000 --- a/src/lib/doslib/dos/win32lrd.c +++ /dev/null @@ -1,125 +0,0 @@ -/* dos.c - * - * Code to detect the surrounding DOS/Windows environment and support routines to work with it - * (C) 2009-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -#ifdef TARGET_WINDOWS -# include -#endif - -#include -#include /* this is where Open Watcom hides the outp() etc. functions */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(TARGET_WINDOWS) && TARGET_MSDOS == 32 && !defined(WIN386) - -/* this library of code deals with the problem of getting ordinal-only exported functions out of KERNEL32.DLL in - * Windows 9x/ME. GetProcAddress() won't do it for us, so instead, we forcibly read it out from memory ourself. - * That's what you get for being a jack-ass about Win16 compatibility Microsoft */ - -/* Note that this code would work under Windows 9x/ME and NT/2000/XP, but it is only needed for 9x/ME. - * Windows XP SP2 and later change the handle slightly to try and confuse code like this (they take the HANDLE - * value of the module and set the least significant bit), and I have reason to believe Microsoft will eventually - * outright change the interface to make the handle an actual opaque handle someday (while of course making it - * utterly impossible for programs like us to get to the API functions we need to do our fucking job). Because they're - * Microsoft, and that's what they do with the Windows API. */ - -/* How to use: Use the 32-bit GetModuleHandle() function to get the HMODULE value. In Windows so far, this HMODULE - * value is literally the linear memory address where Windows loaded (or mapped) the base of the DLL image, complete - * with MS-DOS header and PE image. This hack relies on that to then traverse the PE structure directly and forcibly - * retrieve from the ordinal export table the function we desire. */ - -/* returns: DWORD* pointer to PE image's export ordinal table, *entries is filled with the number of entries, *base - * is filled with the ordinal number of the first entry. */ - -static IMAGE_NT_HEADERS *Win32ValidateHModuleMSDOS_PE_Header(BYTE *p) { - if (!memcmp(p,"MZ",2)) { - /* then at offset 0x3C there should be the offset to the PE header */ - DWORD offset = *((DWORD*)(p+0x3C)); - if (offset < 0x40 || offset > 0x10000) return NULL; - p += offset; - if (IsBadReadPtr(p,4096)) return NULL; - if (!memcmp(p,"PE\0\0",4)) { - /* wait, before we celebrate, make sure it's sane! */ - IMAGE_NT_HEADERS *pp = (IMAGE_NT_HEADERS*)p; - - if (pp->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) - return NULL; - if (pp->FileHeader.SizeOfOptionalHeader < 88) /* <- FIXME */ - return NULL; - if (pp->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) - return NULL; - - return pp; - } - } - - return NULL; -} - -static IMAGE_DATA_DIRECTORY *Win32GetDataDirectory(IMAGE_NT_HEADERS *p) { - return p->OptionalHeader.DataDirectory; -} - -DWORD *Win32GetExportOrdinalTable(HMODULE mod,DWORD *entries,DWORD *base,DWORD *base_addr) { - IMAGE_EXPORT_DIRECTORY *exdir; - IMAGE_DATA_DIRECTORY *dir; - IMAGE_NT_HEADERS *ptr; - - /* Hack for Windows XP SP2: Clear the LSB, the OS sets it for some reason */ - mod = (HMODULE)((DWORD)mod & 0xFFFFF000UL); - /* reset vars */ - *entries = *base = 0; - if (mod == NULL) return NULL; - - /* the module pointer should point an image of the DLL in memory. Right at the pointer we should see - * the letters "MZ" and the MS-DOS stub EXE header */ - ptr = Win32ValidateHModuleMSDOS_PE_Header((BYTE*)mod); - if (ptr == NULL) return NULL; - - /* OK, now locate the Data Directory. The number of entries is in ptr->OptionalHeader.NumberOfRvaAndSizes */ - dir = Win32GetDataDirectory(ptr); - if (ptr == NULL) return NULL; - - /* the first directory is the Export Address Table */ - exdir = (IMAGE_EXPORT_DIRECTORY*)((DWORD)mod + (DWORD)dir->VirtualAddress); - if (IsBadReadPtr(exdir,2048)) return NULL; - - *base = exdir->Base; - *entries = exdir->NumberOfFunctions; - *base_addr = (DWORD)mod; - return (DWORD*)((DWORD)mod + exdir->AddressOfFunctions); -} - -int Win32GetOrdinalLookupInfo(HMODULE mod,Win32OrdinalLookupInfo *info) { - DWORD *x = Win32GetExportOrdinalTable(mod,&info->entries,&info->base,&info->base_addr); - if (x == NULL) return 0; - info->table = x; - return 1; -} - -void *Win32GetOrdinalAddress(Win32OrdinalLookupInfo *nfo,unsigned int ord) { - if (nfo == NULL || nfo->table == NULL) return NULL; - if (ord < nfo->base) return NULL; - if (ord >= (nfo->base+nfo->entries)) return NULL; - return (void*)((char*)nfo->table[ord-nfo->base] + nfo->base_addr); -} -#endif - diff --git a/src/lib/doslib/dos/winfcon.c b/src/lib/doslib/dos/winfcon.c deleted file mode 100644 index 56187100..00000000 --- a/src/lib/doslib/dos/winfcon.c +++ /dev/null @@ -1,723 +0,0 @@ -/* winfcon.c - * - * Fake console for Windows applications where a console is not available. - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - * - * This code allows the DOS/CPU test code to print to a console despite the - * fact that Windows 3.0/3.1 and Win32s do not provide a console. For this - * code to work, the program must include specific headers and #define a - * macro. The header will then redefine various standard C functions to - * redirect their use into this program. This code is not used for targets - * that provide a console. - */ - -#ifdef TARGET_WINDOWS -# include -# include -#else -# error what -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef WIN_STDOUT_CONSOLE - -/* _export is not valid for Win32. this silences a Watcom linker warning */ -#if TARGET_MSDOS == 32 -# define winproc_export -#else -# define winproc_export _export -#endif - -#undef read -#undef write -#undef getch -#undef isatty - -#define KBSIZE 256 - -static char _win_WindowProcClass[128]; - -/* If we stick all these variables in the data segment and reference - * them directly, then we'll work from a single instance, but run into - * problems with who's data segment to use once we run in multiple - * instances. The problem, is that when an application creates a - * window of our class, the Window Proc is not guaranteed to be called - * with our DS segment/selector. In fact, it often seems to be the - * data segment of the first instance by which the window class was - * created. And under Windows 3.0, unless you used __loadds and - * MakeProcInstance, the DS segment could be any random segment - * that happened to be there when you were called. - * - * Our Window Proc below absolves itself of these problems by storing - * the pointer to the context in the Window data associated with the - * window (GetWindowLong/SetWindowLong), then using only that context - * pointer for maintaining itself. - * - * This DS segment limitation only affects the Window procedure and - * any functions called by the Window procedure. Other parts, like - * WinMain, do not have to worry about whether DS is correct and the - * data segment will always be the current instance running. - * - * Note that the above limitations are only an issue for the Win16 - * world. The Win32 world is free from this hell and so we only - * have to maintain one context structure. */ -typedef struct _win_console_ctx { - char console[80*25]; - char _win_kb[KBSIZE]; - int conHeight,conWidth; - int _win_kb_i,_win_kb_o; - int monoSpaceFontHeight; -#if TARGET_MSDOS == 32 && defined(WIN386) - short int monoSpaceFontWidth; -#else - int monoSpaceFontWidth; -#endif - HFONT monoSpaceFont; - int pendingSigInt; - int userReqClose; - int allowClose; - int conX,conY; - jmp_buf exit_jmp; - HWND hwndMain; - int myCaret; -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && defined(WIN386)) - WORD my_ds; -#endif -}; - -HINSTANCE _win_hInstance; -static struct _win_console_ctx _this_console; -static char temprintf[1024]; - -#if TARGET_MSDOS == 32 && defined(WIN386) -# define USER_GWW_CTX 0 -# define USER_GWW_MAX 6 -#elif TARGET_MSDOS == 16 -# define USER_GWW_CTX 0 -# define USER_GWW_MAX 4 -#else -# define USER_GWW_MAX 0 -#endif -#define USER_GCW_MAX 0 - -HWND _win_hwnd() { - return _this_console.hwndMain; -} - -int _win_kb_insert(struct _win_console_ctx FAR *ctx,char c) { - if ((ctx->_win_kb_i+1)%KBSIZE == ctx->_win_kb_o) { - MessageBeep(-1); - return -1; - } - - ctx->_win_kb[ctx->_win_kb_i] = c; - if (++ctx->_win_kb_i >= KBSIZE) ctx->_win_kb_i = 0; - return 0; -} - -void _win_sigint() { - void (*sig)(int x) = signal(SIGINT,SIG_DFL); - if (sig != SIG_IGN && sig != SIG_DFL) sig(SIGINT); - signal(SIGINT,sig); - if (sig == SIG_DFL) longjmp(_this_console.exit_jmp,1); -} - -void _win_sigint_post(struct _win_console_ctx FAR *ctx) { - /* because doing a longjmp() out of a Window proc is very foolish */ - ctx->pendingSigInt = 1; -} - -#if ((TARGET_MSDOS == 16 && TARGET_WINDOWS < 31) || (TARGET_MSDOS == 32 && defined(WIN386))) -FARPROC _win_WindowProc_MPI; -#endif -/* NTS: Win16 only: DS (data segment) is NOT necessarily the data segment of the instance - * that spawned the window! Any attempt to access local variables will likely refer - * to the copy in the first instance */ -/* NTS: All code in this routine deliberately does not refer to the local data segment, unless it - * has to (which it does through the segment value in the context). This reduces problems with - * the screwy callback design in Windows 3.0/3.1. */ -/* NTS: Do NOT use __loadds on this function prototype. It will seem to work, but because __loadds - * reloads the (cached) instance data segment it will cause all instances to crash when you - * spawn multiple instances and then close the first one you spawned. NOT using __loadds - * removes that crash. */ -WindowProcType_NoLoadDS winproc_export _win_WindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam) { -#if TARGET_MSDOS == 32 && defined(WIN386) - struct _win_console_ctx FAR *_ctx_console; - { - unsigned short s = GetWindowWord(hwnd,USER_GWW_CTX); - unsigned int o = GetWindowLong(hwnd,USER_GWW_CTX+2); - _ctx_console = (void far *)MK_FP(s,o); - } - if (_ctx_console == NULL) return DefWindowProc(hwnd,message,wparam,lparam); -#elif TARGET_MSDOS == 16 - struct _win_console_ctx FAR *_ctx_console; - _ctx_console = (void far *)GetWindowLong(hwnd,USER_GWW_CTX); - if (_ctx_console == NULL) return DefWindowProc(hwnd,message,wparam,lparam); -#else -# define _ctx_console (&_this_console) -#endif - - if (message == WM_GETMINMAXINFO) { -#if TARGET_MSDOS == 32 && defined(WIN386) /* Watcom Win386 does NOT translate LPARAM for us */ - MINMAXINFO FAR *mm = (MINMAXINFO FAR*)win386_help_MapAliasToFlat(lparam); - if (mm == NULL) return DefWindowProc(hwnd,message,wparam,lparam); -#else - MINMAXINFO FAR *mm = (MINMAXINFO FAR*)(lparam); -#endif - mm->ptMaxSize.x = (_ctx_console->monoSpaceFontWidth * _ctx_console->conWidth) + - (2 * GetSystemMetrics(SM_CXFRAME)); - mm->ptMaxSize.y = (_ctx_console->monoSpaceFontHeight * _ctx_console->conHeight) + - (2 * GetSystemMetrics(SM_CYFRAME)) + GetSystemMetrics(SM_CYCAPTION); - mm->ptMinTrackSize.x = mm->ptMaxSize.x; - mm->ptMinTrackSize.y = mm->ptMaxSize.y; - mm->ptMaxTrackSize.x = mm->ptMaxSize.x; - mm->ptMaxTrackSize.y = mm->ptMaxSize.y; - return 0; - } - else if (message == WM_CLOSE) { - if (_ctx_console->allowClose) DestroyWindow(hwnd); - else _win_sigint_post(_ctx_console); - _ctx_console->userReqClose = 1; - } - else if (message == WM_DESTROY) { - _ctx_console->allowClose = 1; - _ctx_console->userReqClose = 1; - if (_ctx_console->myCaret) { - HideCaret(hwnd); - DestroyCaret(); - _ctx_console->myCaret = 0; - } - - PostQuitMessage(0); - _ctx_console->hwndMain = NULL; - return 0; /* OK */ - } - else if (message == WM_SETCURSOR) { - if (LOWORD(lparam) == HTCLIENT) { - SetCursor(LoadCursor(NULL,IDC_ARROW)); - return 1; - } - else { - return DefWindowProc(hwnd,message,wparam,lparam); - } - } - else if (message == WM_ACTIVATE) { - if (wparam) { - if (!_ctx_console->myCaret) { - CreateCaret(hwnd,NULL,_ctx_console->monoSpaceFontWidth,_ctx_console->monoSpaceFontHeight); - SetCaretPos(_ctx_console->conX * _ctx_console->monoSpaceFontWidth, - _ctx_console->conY * _ctx_console->monoSpaceFontHeight); - ShowCaret(hwnd); - _ctx_console->myCaret = 1; - } - } - else { - if (_ctx_console->myCaret) { - HideCaret(hwnd); - DestroyCaret(); - _ctx_console->myCaret = 0; - } - } - - /* BUGFIX: Microsoft Windows 3.1 SDK says "return 0 if we processed the message". - * Yet if we actually do, we get funny behavior. Like if I minimize another - * application's window and then activate this app again, every keypress - * causes Windows to send WM_SYSKEYDOWN/WM_SYSKEYUP. Somehow passing it - * down to DefWindowProc() solves this. */ - return DefWindowProc(hwnd,message,wparam,lparam); - } - else if (message == WM_CHAR) { - if (wparam > 0 && wparam <= 126) { - if (wparam == 3) { - /* CTRL+C */ - if (_ctx_console->allowClose) DestroyWindow(hwnd); - else _win_sigint_post(_ctx_console); - } - else { - _win_kb_insert(_ctx_console,(char)wparam); - } - } - } - else if (message == WM_ERASEBKGND) { - RECT um; - - if (GetUpdateRect(hwnd,&um,FALSE)) { - HBRUSH oldBrush,newBrush; - HPEN oldPen,newPen; - - newPen = (HPEN)GetStockObject(NULL_PEN); - newBrush = (HBRUSH)GetStockObject(WHITE_BRUSH); - - oldPen = SelectObject((HDC)wparam,newPen); - oldBrush = SelectObject((HDC)wparam,newBrush); - - Rectangle((HDC)wparam,um.left,um.top,um.right+1,um.bottom+1); - - SelectObject((HDC)wparam,oldBrush); - SelectObject((HDC)wparam,oldPen); - } - - return 1; /* Important: Returning 1 signals to Windows that we processed the message. Windows 3.0 gets really screwed up if we don't! */ - } - else if (message == WM_PAINT) { - RECT um; - - if (GetUpdateRect(hwnd,&um,TRUE)) { - PAINTSTRUCT ps; - HFONT of; - int y; - - BeginPaint(hwnd,&ps); - SetBkMode(ps.hdc,OPAQUE); - SetBkColor(ps.hdc,RGB(255,255,255)); - SetTextColor(ps.hdc,RGB(0,0,0)); - of = (HFONT)SelectObject(ps.hdc,_ctx_console->monoSpaceFont); - for (y=0;y < _ctx_console->conHeight;y++) { - TextOut(ps.hdc,0,y * _ctx_console->monoSpaceFontHeight, - _ctx_console->console + (_ctx_console->conWidth * y), - _ctx_console->conWidth); - } - SelectObject(ps.hdc,of); - EndPaint(hwnd,&ps); - } - - return 0; /* Return 0 to signal we processed the message */ - } - else { - return DefWindowProc(hwnd,message,wparam,lparam); - } - - return 0; -} - -int _win_kbhit() { - _win_pump(); - return _this_console._win_kb_i != _this_console._win_kb_o; -} - -int _win_getch() { - do { - if (_win_kbhit()) { - int c = (int)((unsigned char)_this_console._win_kb[_this_console._win_kb_o]); - if (++_this_console._win_kb_o >= KBSIZE) _this_console._win_kb_o = 0; - return c; - } - - _win_pump_wait(); - } while (1); - - return -1; -} - -int _win_kb_read(char *p,int sz) { - int cnt=0; - - while (sz-- > 0) - *p++ = _win_getch(); - - return cnt; -} - -int _win_kb_write(const char *p,int sz) { - int cnt=0; - - while (sz-- > 0) - _win_putc(*p++); - - return cnt; -} - -int _win_read(int fd,void *buf,int sz) { - if (fd == 0) return _win_kb_read((char*)buf,sz); - else if (fd == 1 || fd == 2) return -1; - else return read(fd,buf,sz); -} - -int _win_write(int fd,const void *buf,int sz) { - if (fd == 0) return -1; - else if (fd == 1 || fd == 2) return _win_kb_write(buf,sz); - else return write(fd,buf,sz); -} - -int _win_isatty(int fd) { - if (fd == 0 || fd == 1 || fd == 2) return 1; /* we're emulating one, so, yeah */ - return isatty(fd); -} - -void _win_pump_wait() { - MSG msg; - - if (GetMessage(&msg,NULL,0,0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (_this_console.pendingSigInt) { - _this_console.pendingSigInt = 0; - _win_sigint(); - } -} - -void _win_pump() { - MSG msg; - -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && defined(WIN386)) - /* Hack: Windows has this nice "GetTickCount()" function that has serious problems - * maintaining a count if we don't process the message pump! Doing this - * prevents portions of this code from getting stuck in infinite loops - * waiting for the damn timer to advance. Note that this is a serious - * problem that only plagues Windows 3.1 and earlier. Windows 95 doesn't - * have this problem. */ - PostMessage(_this_console.hwndMain,WM_USER,0,0); -#endif - if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { - do { - TranslateMessage(&msg); - DispatchMessage(&msg); - } while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)); - } - - if (_this_console.pendingSigInt) { - _this_console.pendingSigInt = 0; - _win_sigint(); - } -} - -void _win_update_cursor() { - if (_this_console.myCaret) - SetCaretPos(_this_console.conX * _this_console.monoSpaceFontWidth, - _this_console.conY * _this_console.monoSpaceFontHeight); -} - -void _win_redraw_line_row() { - if (_this_console.conY >= 0 && _this_console.conY < _this_console.conHeight) { - HDC hdc = GetDC(_this_console.hwndMain); - HFONT of; - - SetBkMode(hdc,OPAQUE); - SetBkColor(hdc,RGB(255,255,255)); - SetTextColor(hdc,RGB(0,0,0)); - of = (HFONT)SelectObject(hdc,_this_console.monoSpaceFont); - if (_this_console.myCaret) HideCaret(_this_console.hwndMain); - TextOut(hdc,0,_this_console.conY * _this_console.monoSpaceFontHeight, - _this_console.console + (_this_console.conWidth * _this_console.conY),_this_console.conWidth); - if (_this_console.myCaret) ShowCaret(_this_console.hwndMain); - SelectObject(hdc,of); - ReleaseDC(_this_console.hwndMain,hdc); - } -} - -void _win_redraw_line_row_partial(int x1,int x2) { - if (x1 >= x2) return; - - if (_this_console.conY >= 0 && _this_console.conY < _this_console.conHeight) { - HDC hdc = GetDC(_this_console.hwndMain); - HFONT of; - - SetBkMode(hdc,OPAQUE); - SetBkColor(hdc,RGB(255,255,255)); - SetTextColor(hdc,RGB(0,0,0)); - of = (HFONT)SelectObject(hdc,_this_console.monoSpaceFont); - if (_this_console.myCaret) HideCaret(_this_console.hwndMain); - TextOut(hdc,x1 * _this_console.monoSpaceFontWidth,_this_console.conY * _this_console.monoSpaceFontHeight, - _this_console.console + (_this_console.conWidth * _this_console.conY) + x1,x2 - x1); - if (_this_console.myCaret) ShowCaret(_this_console.hwndMain); - SelectObject(hdc,of); - ReleaseDC(_this_console.hwndMain,hdc); - } -} - -void _win_scrollup() { - HDC hdc = GetDC(_this_console.hwndMain); - if (_this_console.myCaret) HideCaret(_this_console.hwndMain); - BitBlt(hdc,0,0,_this_console.conWidth * _this_console.monoSpaceFontWidth, - _this_console.conHeight * _this_console.monoSpaceFontHeight,hdc, - 0,_this_console.monoSpaceFontHeight,SRCCOPY); - if (_this_console.myCaret) ShowCaret(_this_console.hwndMain); - ReleaseDC(_this_console.hwndMain,hdc); - - memmove(_this_console.console,_this_console.console+_this_console.conWidth, - (_this_console.conHeight-1)*_this_console.conWidth); - memset(_this_console.console+((_this_console.conHeight-1)*_this_console.conWidth), - ' ',_this_console.conWidth); -} - -void _win_newline() { - _this_console.conX = 0; - if ((_this_console.conY+1) == _this_console.conHeight) { - _win_redraw_line_row(); - _win_scrollup(); - _win_redraw_line_row(); - _win_update_cursor(); - _gdi_pause(); - } - else { - _win_redraw_line_row(); - _this_console.conY++; - } -} - -/* write to the console. does NOT redraw the screen unless we get a newline or we need to scroll up */ -void _win_putc(char c) { - if (c == 10) { - _win_newline(); - } - else if (c == 13) { - _this_console.conX = 0; - _win_redraw_line_row(); - _win_update_cursor(); - _gdi_pause(); - } - else { - if (_this_console.conX < _this_console.conWidth) - _this_console.console[(_this_console.conY*_this_console.conWidth)+_this_console.conX] = c; - if (++_this_console.conX == _this_console.conWidth) - _win_newline(); - } -} - -size_t _win_printf(const char *fmt,...) { - int fX = _this_console.conX; - va_list va; - char *t; - - va_start(va,fmt); - vsnprintf(temprintf,sizeof(temprintf)-1,fmt,va); - va_end(va); - - t = temprintf; - if (*t != 0) { - while (*t != 0) { - if (*t == 13 || *t == 10) fX = 0; - _win_putc(*t++); - } - if (fX <= _this_console.conX) _win_redraw_line_row_partial(fX,_this_console.conX); - _win_update_cursor(); - } - - _win_pump(); - return 0; -} - -/* HACK: I don't know if real systems do this or QEMU is doing something wrong, but apparently if a program - * rapidly prints a lot of text under Windows 3.1 (like the RDTSC test program) it can cause the GDI - * to become 100% focused on TextOut() to the point not even the cursor updates when you move it, and - * keyboard events to become severely stalled. Our solution to this problem is to see if we're running - * under Windows 3.1 or earlier, and if so, purposely slow down our output with a software delay */ -void _gdi_pause() { -#if defined(TARGET_WINDOWS) -# if TARGET_MSDOS == 32 && defined(WIN386) -# else - const DWORD ConDelay = 16UL; /* 16ms */ -# endif -#endif - -#if defined(TARGET_WINDOWS) - if (windows_mode != WINDOWS_NT) { -# if TARGET_MSDOS == 32 && defined(WIN386) - /* nothing */ -# else -# if TARGET_MSDOS == 16 - if (ToolHelpInit()) { - DWORD base,m; - TIMERINFO ti; - ti.dwSize = sizeof(ti); - if (__TimerCount(&ti)) { - base = ti.dwmsSinceStart; - - do { - Yield(); - _win_pump(); - if (!__TimerCount(&ti)) break; - m = ti.dwmsSinceStart; - } while ((m - base) < ConDelay); - } - } - else { -# else - { -# endif - DWORD base,m; - - base = GetTickCount(); - do { - Yield(); - _win_pump(); - m = GetTickCount(); - } while ((m - base) < ConDelay); - } -# endif - } -#endif -} - -/* NOTES: - * For Win16, programmers generally use WINAPI WinMain(...) but WINAPI is defined in such a way - * that it always makes the function prolog return FAR. Unfortunately, when Watcom C's runtime - * calls this function in a memory model that's compact or small, the call is made as if NEAR, - * not FAR. To avoid a GPF or crash on return, we must simply declare it PASCAL instead. */ -int PASCAL _win_main_con_entry(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow,int (_cdecl *_main_f)(int argc,char**,char**)) { - WNDCLASS wnd; - MSG msg; - - _win_hInstance = hInstance; - snprintf(_win_WindowProcClass,sizeof(_win_WindowProcClass),"_HW_DOS_WINFCON_%lX",(DWORD)hInstance); -#if ((TARGET_MSDOS == 16 && TARGET_WINDOWS < 31) || (TARGET_MSDOS == 32 && defined(WIN386))) - _win_WindowProc_MPI = MakeProcInstance((FARPROC)_win_WindowProc,hInstance); -#endif - - /* clear the console */ - memset(&_this_console,0,sizeof(_this_console)); - memset(_this_console.console,' ',sizeof(_this_console.console)); - _this_console._win_kb_i = _this_console._win_kb_o = 0; - _this_console.conHeight = 25; - _this_console.conWidth = 80; - _this_console.conX = 0; - _this_console.conY = 0; -#if TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && defined(WIN386)) - { - WORD s=0; - - __asm { - mov ax,ds - mov s,ax - } - _this_console.my_ds = s; - } -#endif - - /* we need to know at this point what DOS/Windows combination we're running under */ - probe_dos(); - detect_windows(); - - /* we want each instance to have it's own WNDCLASS, even though Windows (Win16) considers them all instances - * coming from the same HMODULE. In Win32, there is no such thing as a "previous instance" anyway */ - wnd.style = CS_HREDRAW|CS_VREDRAW; -#if ((TARGET_MSDOS == 16 && TARGET_WINDOWS < 31) || (TARGET_MSDOS == 32 && defined(WIN386))) - wnd.lpfnWndProc = (WNDPROC)_win_WindowProc_MPI; -#else - wnd.lpfnWndProc = _win_WindowProc; -#endif - wnd.cbClsExtra = USER_GCW_MAX; - wnd.cbWndExtra = USER_GWW_MAX; - wnd.hInstance = hInstance; - wnd.hIcon = NULL; - wnd.hCursor = NULL; - wnd.hbrBackground = NULL; - wnd.lpszMenuName = NULL; - wnd.lpszClassName = _win_WindowProcClass; - - if (!RegisterClass(&wnd)) { - MessageBox(NULL,"Unable to register Window class","Oops!",MB_OK); - return 1; - } - -/* Use the full path of our EXE image by default */ - { - char title[256]; - - if (!GetModuleFileName(hInstance,title,sizeof(title)-1)) - strcpy(title,""); - - _this_console.hwndMain = CreateWindow(_win_WindowProcClass,title, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT,CW_USEDEFAULT, - 100,40, - NULL,NULL, - hInstance,NULL); - } - - if (!_this_console.hwndMain) { - MessageBox(NULL,"Unable to create window","Oops!",MB_OK); - return 1; - } - -#if TARGET_MSDOS == 32 && defined(WIN386) - /* our Win386 hack needs the address of our console context */ - SetWindowWord(_this_console.hwndMain,USER_GWW_CTX,(WORD)FP_SEG(&_this_console)); - SetWindowLong(_this_console.hwndMain,USER_GWW_CTX+2,(DWORD)FP_OFF(&_this_console)); -#elif TARGET_MSDOS == 16 - /* our Win16 hack needs the address of our console context */ - SetWindowLong(_this_console.hwndMain,USER_GWW_CTX,(DWORD)(&_this_console)); -#endif - - /* Create the monospace font we use for terminal display */ - { - _this_console.monoSpaceFont = CreateFont(-12,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH | FF_DONTCARE,"Terminal"); - if (!_this_console.monoSpaceFont) { - MessageBox(NULL,"Unable to create Font","Oops!",MB_OK); - return 1; - } - - { - HWND hwnd = GetDesktopWindow(); - HDC hdc = GetDC(hwnd); - _this_console.monoSpaceFontHeight = 12; - if (!GetCharWidth(hdc,'A','A',&_this_console.monoSpaceFontWidth)) _this_console.monoSpaceFontWidth = 9; - ReleaseDC(hwnd,hdc); - } - } - - ShowWindow(_this_console.hwndMain,nCmdShow); - UpdateWindow(_this_console.hwndMain); - SetWindowPos(_this_console.hwndMain,HWND_TOP,0,0, - (_this_console.monoSpaceFontWidth * _this_console.conWidth) + - (2 * GetSystemMetrics(SM_CXFRAME)), - (_this_console.monoSpaceFontHeight * _this_console.conHeight) + - (2 * GetSystemMetrics(SM_CYFRAME)) + GetSystemMetrics(SM_CYCAPTION), - SWP_NOMOVE); - - if (setjmp(_this_console.exit_jmp) == 0) - _main_f(0,NULL,NULL); /* <- FIXME: We need to take the command line and generate argv[]. Also generate envp[] */ - - if (!_this_console.userReqClose) { - _win_printf("\n"); - _this_console.allowClose = 1; - while (GetMessage(&msg,NULL,0,0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - else { - if (IsWindow(_this_console.hwndMain)) { - DestroyWindow(_this_console.hwndMain); - while (GetMessage(&msg,NULL,0,0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - - DeleteObject(_this_console.monoSpaceFont); - _this_console.monoSpaceFont = NULL; - return 0; -} -#endif - diff --git a/src/lib/doslib/dos/winfcon.h b/src/lib/doslib/dos/winfcon.h deleted file mode 100644 index 407ac2dd..00000000 --- a/src/lib/doslib/dos/winfcon.h +++ /dev/null @@ -1,46 +0,0 @@ -/* winfcon.h - * - * Fake console for Windows applications where a console is not available. - * (C) 2011-2012 Jonathan Campbell. - * Hackipedia DOS library. - * - * This code is licensed under the LGPL. - * - */ - -/* Windows 3.1 and earlier, even for Win32s: there is no system given console. - * We either have to draw and maintain our own window, or find some other way to printf() and display it. */ -#if defined(TARGET_WINDOWS) && (TARGET_MSDOS == 16 || (TARGET_MSDOS == 32 && TARGET_WINDOWS == 31) || (defined(WIN386) && TARGET_MSDOS == 32)) -# define WIN_STDOUT_CONSOLE -# define getch _win_getch -# define kbhit _win_kbhit -# define fprintf __XXX_TODO_fprintf -# define printf _win_printf -# define isatty _win_isatty -# define write _win_write -# define read _win_read - -void _win_pump(); -int _win_kbhit(); -int _win_getch(); -HWND _win_hwnd(); -void _gdi_pause(); -void _win_pump_wait(); -void _win_putc(char c); -int _win_isatty(int fd); -int _win_read(int fd,void *buf,int sz); -size_t _win_printf(const char *fmt,...); -int _win_write(int fd,const void *buf,int sz); -int _cdecl main(int argc,char **argv,char **envp); -int PASCAL _win_main_con_entry(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow,int (_cdecl *_main_f)(int argc,char**,char**)); - -extern HINSTANCE _win_hInstance; - -# ifdef WINFCON_STOCK_WIN_MAIN -int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { - return _win_main_con_entry(hInstance,hPrevInstance,lpCmdLine,nCmdShow,main); -} -# endif - -#endif - diff --git a/src/lib/doslib/dos/winnt/dosntast.vdd b/src/lib/doslib/dos/winnt/dosntast.vdd deleted file mode 100644 index 3b8bad5eedd58e788e1c0645952fa65af742b980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 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

Dg)eaRZ*>0M25g&*UFQ6g&9Qxf%B5gP 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�gZ0M3^`i6_N~09Hl}c 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