diff --git a/src/86Box.rc b/src/86Box.rc index 07282d465..388ab93b7 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -63,7 +63,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_1_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_1_ISO + MENUITEM "&Image...", IDM_CDROM_1_IMAGE END POPUP "CD-ROM 2" BEGIN @@ -72,7 +72,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_2_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_2_ISO + MENUITEM "&Image...", IDM_CDROM_2_IMAGE END POPUP "CD-ROM 3" BEGIN @@ -81,7 +81,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_3_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_3_ISO + MENUITEM "&Image...", IDM_CDROM_3_IMAGE END POPUP "CD-ROM 4" BEGIN @@ -90,7 +90,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_4_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_4_ISO + MENUITEM "&Image...", IDM_CDROM_4_IMAGE END END @@ -142,6 +142,41 @@ BEGIN MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "S&tatus", IDM_STATUS +#ifdef ENABLE_LOG_TOGGLES +#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG + MENUITEM SEPARATOR +#endif +#ifdef ENABLE_BUSLOGIC_LOG + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC +#endif +#ifdef ENABLE_CDROM_LOG + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM +#endif +#ifdef ENABLE_D86F_LOG + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F +#endif +#ifdef ENABLE_FDC_LOG + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC +#endif +#ifdef ENABLE_IDE_LOG + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE +#endif +#ifdef ENABLE_NE2000_LOG + MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + MENUITEM SEPARATOR + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +#ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#else +#ifdef ENABLE_VRAM_DUMP + MENUITEM SEPARATOR + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#endif END POPUP "&Help" BEGIN @@ -157,6 +192,32 @@ END MAINACCEL ACCELERATORS MOVEABLE PURE BEGIN +#ifdef ENABLE_VRAM_DUMP + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_CDROM_LOG + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_D86F_LOG + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_FDC_LOG + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_IDE_LOG + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_NE2000_LOG + VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY +#endif VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL END @@ -189,8 +250,8 @@ FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,55,89,50,14 PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14 - EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,188,12 - PUSHBUTTON "...",IDC_CFILE,195,16,16,12 + EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12 + PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12 EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12 EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12 EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12 @@ -453,12 +514,14 @@ END 163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" 164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" 165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -178 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -179 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -180 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -181 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" +177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" +178 ICON DISCARDABLE "ICONS/hard_disk.ico" +179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" 256 ICON DISCARDABLE "ICONS/machine.ico" 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" @@ -599,7 +662,7 @@ BEGIN 2048 "86Box" IDS_STRING2049 "86Box Error" IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nDo you want to save the settings?" + IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" IDS_STRING2052 "DirectDraw Screenshot Error" IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" @@ -708,10 +771,10 @@ BEGIN 2137 "Mid VLB/PCI" 2138 "Fast VLB/PCI" 2139 "Microsoft 2-button mouse (serial)" - 2140 "2-button mouse (PS/2)" - 2141 "Microsoft Intellimouse (PS/2)" - 2142 "Amstrad mouse" - 2143 "Olivetti M24 mouse" + 2140 "Mouse Systems mouse (serial)" + 2141 "2-button mouse (PS/2)" + 2142 "Microsoft Intellimouse (PS/2)" + 2143 "Bus mouse" END STRINGTABLE DISCARDABLE @@ -729,17 +792,17 @@ BEGIN 2154 "Internal IDE" 2155 "IRQ %i" 2156 "MFM (%01i:%01i)" - 2157 "IDE (%01i:%01i)" + 2157 "IDE (PIO+DMA) (%01i:%01i)" 2158 "SCSI (%02i:%02i)" - 2159 "IDE (PIO-only)" + 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" 2160 "%" PRIu64 - 2161 "Microsoft Bus mouse" - 2162 "Mouse Systems mouse" + 2161 "Genius Bus mouse" + 2162 "Amstrad mouse" 2163 "Attempting to create a spuriously large hard disk image" 2164 "Invalid number of sectors (valid values are between 1 and 99)" - 2165 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2166 "MFM" - 2167 "IDE" + 2165 "MFM" + 2166 "IDE (PIO-only)" + 2167 "IDE (PIO and DMA)" 2168 "SCSI" 2169 "%01i:%01i" 2170 "Custom..." @@ -747,15 +810,15 @@ BEGIN 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Microsoft InPort mouse" - 2178 "Genius Bus mouse" - 2179 "Floppy %i (%s): %s" - 2180 "CD-ROM %i: %s" - 2181 "Removable disk %i: %s" - 2182 "MFM hard disk" - 2183 "IDE hard disk" + 2177 "Olivetti M24 mouse" + 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" + 2179 "Floppy %i (%s): %ws" + 2180 "CD-ROM %i: %ws" + 2181 "MFM hard disk" + 2182 "IDE hard disk (PIO-only)" + 2183 "IDE hard disk (PIO and DMA)" 2184 "SCSI hard disk" 2185 "(empty)" 2186 "(host drive %c:)" @@ -766,8 +829,12 @@ BEGIN 2191 "ATAPI (PIO-only) (%01i:%01i)" 2192 "ATAPI (PIO and DMA) (%01i:%01i)" 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "" - 2195 "English (United States)" + 2194 "Unable to create bitmap file: %s" + 2195 "IDE (PIO-only) (%01i:%01i)" + 2196 "Add New Hard Disk" + 2197 "Add Existing Hard Disk" + 2198 "Removable disk %i: %s" + 2199 "English (United States)" END diff --git a/src/86box.h b/src/86box.h index 09f0a8a15..ef0a45e15 100644 --- a/src/86box.h +++ b/src/86box.h @@ -2,3 +2,4 @@ see COPYING for more details */ #define emulator_version "1.20" +#define emulator_version_w L"1.20" diff --git a/src/CMakeModules/FindD3D9.cmake b/src/CMakeModules/FindD3D9.cmake deleted file mode 100644 index 6e7ed3237..000000000 --- a/src/CMakeModules/FindD3D9.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directdraw -# This module defines -# D3D9_LIBRARIES -# D3D9_FOUND, if false, do not try to link to directinput -# D3D9_INCLUDE_DIR, where to find the headers -# -# $D3D9_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( D3D9_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( D3D9_ROOT_DIR Include/D3D9.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( D3D9_INCLUDE_DIR d3d9.h - PATHS - ${D3D9_ROOT_DIR}/Include - ) - - FIND_LIBRARY( D3D9_LIBRARY d3d9.lib d3dx9 - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( D3D9_GUID_LIBRARY dxguid.lib - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( D3D9_ERR_LIBRARY dxerr.lib - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - SET( D3D9_LIBRARIES - ${D3D9_LIBRARY} - ${D3D9_GUID_LIBRARY} - ${D3D9_ERR_LIBRARY} - ) - - IF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES ) - SET( D3D9_FOUND TRUE ) - ENDIF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( D3D9_FOUND ) \ No newline at end of file diff --git a/src/CMakeModules/FindDirectDraw.cmake b/src/CMakeModules/FindDirectDraw.cmake deleted file mode 100644 index c5f995313..000000000 --- a/src/CMakeModules/FindDirectDraw.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directdraw -# This module defines -# DDRAW_LIBRARIES -# DDRAW_FOUND, if false, do not try to link to directinput -# DDRAW_INCLUDE_DIR, where to find the headers -# -# $DDRAW_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( DDRAW_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( DDRAW_ROOT_DIR Include/D3D10.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( DDRAW_INCLUDE_DIR ddraw.h - PATHS - ${DDRAW_ROOT_DIR}/Include - ) - - FIND_LIBRARY( DDRAW_LIBRARY ddraw.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DDRAW_GUID_LIBRARY dxguid.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DDRAW_ERR_LIBRARY dxerr.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - SET( DDRAW_LIBRARIES - ${DDRAW_LIBRARY} - ${DDRAW_GUID_LIBRARY} - ${DDRAW_ERR_LIBRARY} - ) - - IF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES ) - SET( DDRAW_FOUND TRUE ) - ENDIF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( DDRAW_FOUND ) \ No newline at end of file diff --git a/src/CMakeModules/FindDirectInput.cmake b/src/CMakeModules/FindDirectInput.cmake deleted file mode 100644 index b7b457527..000000000 --- a/src/CMakeModules/FindDirectInput.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directinput -# This module defines -# DIRECTINPUT_LIBRARIES -# DIRECTINPUT_FOUND, if false, do not try to link to directinput -# DIRECTINPUT_INCLUDE_DIR, where to find the headers -# -# $DIRECTINPUT_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( DIRECTINPUT_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( DIRECTINPUT_ROOT_DIR Include/D3D10.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( DIRECTINPUT_INCLUDE_DIR dinput.h - PATHS - ${DIRECTINPUT_ROOT_DIR}/Include - ) - - FIND_LIBRARY( DIRECTINPUT_LIBRARY dinput7.lib dinput8.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DIRECTINPUT_GUID_LIBRARY dxguid.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DIRECTINPUT_ERR_LIBRARY dxerr.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - SET( DIRECTINPUT_LIBRARIES - ${DIRECTINPUT_LIBRARY} - ${DIRECTINPUT_GUID_LIBRARY} - ${DIRECTINPUT_ERR_LIBRARY} - ) - - IF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES ) - SET( DIRECTINPUT_FOUND TRUE ) - ENDIF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( DIRECTINPUT_FOUND ) \ No newline at end of file diff --git a/src/386.c b/src/CPU/386.c similarity index 99% rename from src/386.c rename to src/CPU/386.c index 256a1ce88..6bd69af85 100644 --- a/src/386.c +++ b/src/CPU/386.c @@ -5,15 +5,15 @@ #include #include #include -#include "ibm.h" +#include "../ibm.h" +#include "cpu.h" #include "x86.h" #include "x87.h" -#include "mem.h" -#include "cpu.h" -#include "disc.h" -#include "fdc.h" -#include "pic.h" -#include "timer.h" +#include "../mem.h" +#include "../disc.h" +#include "../fdc.h" +#include "../pic.h" +#include "../timer.h" #include "386_common.h" diff --git a/src/386.h b/src/CPU/386.h similarity index 100% rename from src/386.h rename to src/CPU/386.h diff --git a/src/386_common.h b/src/CPU/386_common.h similarity index 100% rename from src/386_common.h rename to src/CPU/386_common.h diff --git a/src/386_dynarec.c b/src/CPU/386_dynarec.c similarity index 99% rename from src/386_dynarec.c rename to src/CPU/386_dynarec.c index 69a3df8a8..06066223f 100644 --- a/src/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -5,17 +5,17 @@ #include #include #include -#include "ibm.h" +#include "../ibm.h" +#include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" -#include "cpu.h" -#include "disc.h" -#include "fdc.h" -#include "pic.h" -#include "timer.h" +#include "../disc.h" +#include "../fdc.h" +#include "../pic.h" +#include "../timer.h" #include "386_common.h" diff --git a/src/386_dynarec_ops.c b/src/CPU/386_dynarec_ops.c similarity index 97% rename from src/386_dynarec_ops.c rename to src/CPU/386_dynarec_ops.c index 7b5a5c7f5..e0e018872 100644 --- a/src/386_dynarec_ops.c +++ b/src/CPU/386_dynarec_ops.c @@ -2,15 +2,15 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif -#include "ibm.h" +#include "../ibm.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" -#include "pic.h" +#include "../pic.h" #define CPU_BLOCK_END() cpu_block_end = 1 diff --git a/src/386_ops.h b/src/CPU/386_ops.h similarity index 100% rename from src/386_ops.h rename to src/CPU/386_ops.h diff --git a/src/808x.c b/src/CPU/808x.c similarity index 99% rename from src/808x.c rename to src/CPU/808x.c index 6f72fb613..c102fa45f 100644 --- a/src/808x.c +++ b/src/CPU/808x.c @@ -12,16 +12,14 @@ 2 clocks - fetch opcode 2 etc*/ #include #include - -#include "ibm.h" - +#include "../ibm.h" #include "cpu.h" -#include "keyboard.h" -#include "mem.h" -#include "nmi.h" -#include "pic.h" -#include "timer.h" #include "x86.h" +#include "../keyboard.h" +#include "../mem.h" +#include "../nmi.h" +#include "../pic.h" +#include "../timer.h" int xt_cpu_multi; int nmi = 0; @@ -481,7 +479,7 @@ void dumpregs(int force) #ifndef RELEASE_BUILD indump = 1; output=0; - chdir(pcempath); + _wchdir(pcempath); nopageerrors=1; f=fopen("ram.dmp","wb"); fwrite(ram,mem_size*1024,1,f); @@ -579,7 +577,6 @@ void resetx86() codegen_reset(); x86_was_reset = 1; port_92_clear_reset(); - BuslogicSoftReset(); } void softresetx86() @@ -598,7 +595,6 @@ void softresetx86() x86seg_reset(); x86_was_reset = 1; port_92_clear_reset(); - BuslogicSoftReset(); } static void setznp8(uint8_t val) @@ -2000,7 +1996,7 @@ void execx86(int cycs) case 0xA1: /*MOV AX,(w)*/ addr=getword(); AX=readmemw(ds,addr); - cycles-=!4; + cycles-=14; break; case 0xA2: /*MOV (w),AL*/ addr=getword(); diff --git a/src/codegen.c b/src/CPU/codegen.c similarity index 94% rename from src/codegen.c rename to src/CPU/codegen.c index 5667c9bad..afe795601 100644 --- a/src/codegen.c +++ b/src/CPU/codegen.c @@ -1,6 +1,6 @@ -#include "ibm.h" +#include "../ibm.h" #include "x86_ops.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" void (*codegen_timing_start)(); diff --git a/src/codegen.h b/src/CPU/codegen.h similarity index 100% rename from src/codegen.h rename to src/CPU/codegen.h diff --git a/src/codegen_ops.c b/src/CPU/codegen_ops.c similarity index 99% rename from src/codegen_ops.c rename to src/CPU/codegen_ops.c index a1f846a52..2bd6550e2 100644 --- a/src/codegen_ops.c +++ b/src/CPU/codegen_ops.c @@ -1,4 +1,5 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "x86.h" #include "x86_ops.h" #include "x86_flags.h" diff --git a/src/codegen_ops.h b/src/CPU/codegen_ops.h similarity index 100% rename from src/codegen_ops.h rename to src/CPU/codegen_ops.h diff --git a/src/codegen_ops_arith.h b/src/CPU/codegen_ops_arith.h similarity index 100% rename from src/codegen_ops_arith.h rename to src/CPU/codegen_ops_arith.h diff --git a/src/codegen_ops_fpu.h b/src/CPU/codegen_ops_fpu.h similarity index 100% rename from src/codegen_ops_fpu.h rename to src/CPU/codegen_ops_fpu.h diff --git a/src/codegen_ops_jump.h b/src/CPU/codegen_ops_jump.h similarity index 100% rename from src/codegen_ops_jump.h rename to src/CPU/codegen_ops_jump.h diff --git a/src/codegen_ops_logic.h b/src/CPU/codegen_ops_logic.h similarity index 100% rename from src/codegen_ops_logic.h rename to src/CPU/codegen_ops_logic.h diff --git a/src/codegen_ops_misc.h b/src/CPU/codegen_ops_misc.h similarity index 100% rename from src/codegen_ops_misc.h rename to src/CPU/codegen_ops_misc.h diff --git a/src/codegen_ops_mmx.h b/src/CPU/codegen_ops_mmx.h similarity index 100% rename from src/codegen_ops_mmx.h rename to src/CPU/codegen_ops_mmx.h diff --git a/src/codegen_ops_mov.h b/src/CPU/codegen_ops_mov.h similarity index 100% rename from src/codegen_ops_mov.h rename to src/CPU/codegen_ops_mov.h diff --git a/src/codegen_ops_shift.h b/src/CPU/codegen_ops_shift.h similarity index 100% rename from src/codegen_ops_shift.h rename to src/CPU/codegen_ops_shift.h diff --git a/src/codegen_ops_stack.h b/src/CPU/codegen_ops_stack.h similarity index 100% rename from src/codegen_ops_stack.h rename to src/CPU/codegen_ops_stack.h diff --git a/src/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h similarity index 100% rename from src/codegen_ops_x86-64.h rename to src/CPU/codegen_ops_x86-64.h diff --git a/src/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h similarity index 100% rename from src/codegen_ops_x86.h rename to src/CPU/codegen_ops_x86.h diff --git a/src/codegen_ops_xchg.h b/src/CPU/codegen_ops_xchg.h similarity index 100% rename from src/codegen_ops_xchg.h rename to src/CPU/codegen_ops_xchg.h diff --git a/src/codegen_timing_486.c b/src/CPU/codegen_timing_486.c similarity index 99% rename from src/codegen_timing_486.c rename to src/CPU/codegen_timing_486.c index 19b958931..ddcbc260c 100644 --- a/src/codegen_timing_486.c +++ b/src/CPU/codegen_timing_486.c @@ -1,9 +1,9 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" #define CYCLES(c) (int *)c diff --git a/src/codegen_timing_686.c b/src/CPU/codegen_timing_686.c similarity index 99% rename from src/codegen_timing_686.c rename to src/CPU/codegen_timing_686.c index c4b4cc456..eab10357b 100644 --- a/src/codegen_timing_686.c +++ b/src/CPU/codegen_timing_686.c @@ -7,13 +7,12 @@ - FPU queue - Out of order execution (beyond most simplistic approximation) */ - -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ diff --git a/src/codegen_timing_pentium.c b/src/CPU/codegen_timing_pentium.c similarity index 99% rename from src/codegen_timing_pentium.c rename to src/CPU/codegen_timing_pentium.c index 6d678915e..2812e63ae 100644 --- a/src/codegen_timing_pentium.c +++ b/src/CPU/codegen_timing_pentium.c @@ -8,13 +8,12 @@ - FPU latencies - MMX latencies */ - -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ diff --git a/src/codegen_timing_winchip.c b/src/CPU/codegen_timing_winchip.c similarity index 99% rename from src/codegen_timing_winchip.c rename to src/CPU/codegen_timing_winchip.c index 5d1a26bf3..a76a08e7a 100644 --- a/src/codegen_timing_winchip.c +++ b/src/CPU/codegen_timing_winchip.c @@ -1,9 +1,9 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" #define CYCLES(c) (int *)c diff --git a/src/codegen_x86-64.c b/src/CPU/codegen_x86-64.c similarity index 100% rename from src/codegen_x86-64.c rename to src/CPU/codegen_x86-64.c diff --git a/src/codegen_x86-64.h b/src/CPU/codegen_x86-64.h similarity index 100% rename from src/codegen_x86-64.h rename to src/CPU/codegen_x86-64.h diff --git a/src/codegen_x86.c b/src/CPU/codegen_x86.c similarity index 99% rename from src/codegen_x86.c rename to src/CPU/codegen_x86.c index e7971c383..a42b32104 100644 --- a/src/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1,13 +1,12 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 - #include -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "386_common.h" diff --git a/src/codegen_x86.h b/src/CPU/codegen_x86.h similarity index 100% rename from src/codegen_x86.h rename to src/CPU/codegen_x86.h diff --git a/src/cpu.c b/src/CPU/cpu.c similarity index 99% rename from src/cpu.c rename to src/CPU/cpu.c index d2e1b26f7..453e8626a 100644 --- a/src/cpu.c +++ b/src/CPU/cpu.c @@ -1,13 +1,13 @@ /* Copyright holders: Sarah Walker, Tenshi, leilei see COPYING for more details */ -#include "ibm.h" +#include "../ibm.h" #include "cpu.h" -#include "model.h" -#include "io.h" +#include "../model.h" +#include "../io.h" #include "x86_ops.h" -#include "mem.h" -#include "pci.h" +#include "../mem.h" +#include "../pci.h" #include "codegen.h" int isa_cycles; diff --git a/src/cpu.h b/src/CPU/cpu.h similarity index 100% rename from src/cpu.h rename to src/CPU/cpu.h diff --git a/src/x86.h b/src/CPU/x86.h similarity index 100% rename from src/x86.h rename to src/CPU/x86.h diff --git a/src/x86_flags.h b/src/CPU/x86_flags.h similarity index 100% rename from src/x86_flags.h rename to src/CPU/x86_flags.h diff --git a/src/x86_ops.h b/src/CPU/x86_ops.h similarity index 100% rename from src/x86_ops.h rename to src/CPU/x86_ops.h diff --git a/src/x86_ops_arith.h b/src/CPU/x86_ops_arith.h similarity index 100% rename from src/x86_ops_arith.h rename to src/CPU/x86_ops_arith.h diff --git a/src/x86_ops_atomic.h b/src/CPU/x86_ops_atomic.h similarity index 100% rename from src/x86_ops_atomic.h rename to src/CPU/x86_ops_atomic.h diff --git a/src/x86_ops_bcd.h b/src/CPU/x86_ops_bcd.h similarity index 100% rename from src/x86_ops_bcd.h rename to src/CPU/x86_ops_bcd.h diff --git a/src/x86_ops_bit.h b/src/CPU/x86_ops_bit.h similarity index 100% rename from src/x86_ops_bit.h rename to src/CPU/x86_ops_bit.h diff --git a/src/x86_ops_bitscan.h b/src/CPU/x86_ops_bitscan.h similarity index 100% rename from src/x86_ops_bitscan.h rename to src/CPU/x86_ops_bitscan.h diff --git a/src/x86_ops_call.h b/src/CPU/x86_ops_call.h similarity index 100% rename from src/x86_ops_call.h rename to src/CPU/x86_ops_call.h diff --git a/src/x86_ops_flag.h b/src/CPU/x86_ops_flag.h similarity index 100% rename from src/x86_ops_flag.h rename to src/CPU/x86_ops_flag.h diff --git a/src/x86_ops_fpu.h b/src/CPU/x86_ops_fpu.h similarity index 100% rename from src/x86_ops_fpu.h rename to src/CPU/x86_ops_fpu.h diff --git a/src/x86_ops_i686.h b/src/CPU/x86_ops_i686.h similarity index 100% rename from src/x86_ops_i686.h rename to src/CPU/x86_ops_i686.h diff --git a/src/x86_ops_inc_dec.h b/src/CPU/x86_ops_inc_dec.h similarity index 100% rename from src/x86_ops_inc_dec.h rename to src/CPU/x86_ops_inc_dec.h diff --git a/src/x86_ops_int.h b/src/CPU/x86_ops_int.h similarity index 100% rename from src/x86_ops_int.h rename to src/CPU/x86_ops_int.h diff --git a/src/x86_ops_io.h b/src/CPU/x86_ops_io.h similarity index 100% rename from src/x86_ops_io.h rename to src/CPU/x86_ops_io.h diff --git a/src/x86_ops_jump.h b/src/CPU/x86_ops_jump.h similarity index 100% rename from src/x86_ops_jump.h rename to src/CPU/x86_ops_jump.h diff --git a/src/x86_ops_misc.h b/src/CPU/x86_ops_misc.h similarity index 100% rename from src/x86_ops_misc.h rename to src/CPU/x86_ops_misc.h diff --git a/src/x86_ops_mmx.h b/src/CPU/x86_ops_mmx.h similarity index 100% rename from src/x86_ops_mmx.h rename to src/CPU/x86_ops_mmx.h diff --git a/src/x86_ops_mmx_arith.h b/src/CPU/x86_ops_mmx_arith.h similarity index 100% rename from src/x86_ops_mmx_arith.h rename to src/CPU/x86_ops_mmx_arith.h diff --git a/src/x86_ops_mmx_cmp.h b/src/CPU/x86_ops_mmx_cmp.h similarity index 100% rename from src/x86_ops_mmx_cmp.h rename to src/CPU/x86_ops_mmx_cmp.h diff --git a/src/x86_ops_mmx_logic.h b/src/CPU/x86_ops_mmx_logic.h similarity index 100% rename from src/x86_ops_mmx_logic.h rename to src/CPU/x86_ops_mmx_logic.h diff --git a/src/x86_ops_mmx_mov.h b/src/CPU/x86_ops_mmx_mov.h similarity index 100% rename from src/x86_ops_mmx_mov.h rename to src/CPU/x86_ops_mmx_mov.h diff --git a/src/x86_ops_mmx_pack.h b/src/CPU/x86_ops_mmx_pack.h similarity index 100% rename from src/x86_ops_mmx_pack.h rename to src/CPU/x86_ops_mmx_pack.h diff --git a/src/x86_ops_mmx_shift.h b/src/CPU/x86_ops_mmx_shift.h similarity index 100% rename from src/x86_ops_mmx_shift.h rename to src/CPU/x86_ops_mmx_shift.h diff --git a/src/x86_ops_mov.h b/src/CPU/x86_ops_mov.h similarity index 100% rename from src/x86_ops_mov.h rename to src/CPU/x86_ops_mov.h diff --git a/src/x86_ops_mov_ctrl.h b/src/CPU/x86_ops_mov_ctrl.h similarity index 100% rename from src/x86_ops_mov_ctrl.h rename to src/CPU/x86_ops_mov_ctrl.h diff --git a/src/x86_ops_mov_seg.h b/src/CPU/x86_ops_mov_seg.h similarity index 100% rename from src/x86_ops_mov_seg.h rename to src/CPU/x86_ops_mov_seg.h diff --git a/src/x86_ops_movx.h b/src/CPU/x86_ops_movx.h similarity index 100% rename from src/x86_ops_movx.h rename to src/CPU/x86_ops_movx.h diff --git a/src/x86_ops_msr.h b/src/CPU/x86_ops_msr.h similarity index 100% rename from src/x86_ops_msr.h rename to src/CPU/x86_ops_msr.h diff --git a/src/x86_ops_mul.h b/src/CPU/x86_ops_mul.h similarity index 100% rename from src/x86_ops_mul.h rename to src/CPU/x86_ops_mul.h diff --git a/src/x86_ops_pmode.h b/src/CPU/x86_ops_pmode.h similarity index 100% rename from src/x86_ops_pmode.h rename to src/CPU/x86_ops_pmode.h diff --git a/src/x86_ops_prefix.h b/src/CPU/x86_ops_prefix.h similarity index 100% rename from src/x86_ops_prefix.h rename to src/CPU/x86_ops_prefix.h diff --git a/src/x86_ops_rep.h b/src/CPU/x86_ops_rep.h similarity index 100% rename from src/x86_ops_rep.h rename to src/CPU/x86_ops_rep.h diff --git a/src/x86_ops_ret.h b/src/CPU/x86_ops_ret.h similarity index 100% rename from src/x86_ops_ret.h rename to src/CPU/x86_ops_ret.h diff --git a/src/x86_ops_set.h b/src/CPU/x86_ops_set.h similarity index 100% rename from src/x86_ops_set.h rename to src/CPU/x86_ops_set.h diff --git a/src/x86_ops_shift.h b/src/CPU/x86_ops_shift.h similarity index 100% rename from src/x86_ops_shift.h rename to src/CPU/x86_ops_shift.h diff --git a/src/x86_ops_stack.h b/src/CPU/x86_ops_stack.h similarity index 100% rename from src/x86_ops_stack.h rename to src/CPU/x86_ops_stack.h diff --git a/src/x86_ops_string.h b/src/CPU/x86_ops_string.h similarity index 100% rename from src/x86_ops_string.h rename to src/CPU/x86_ops_string.h diff --git a/src/x86_ops_xchg.h b/src/CPU/x86_ops_xchg.h similarity index 100% rename from src/x86_ops_xchg.h rename to src/CPU/x86_ops_xchg.h diff --git a/src/x86seg.c b/src/CPU/x86seg.c similarity index 99% rename from src/x86seg.c rename to src/CPU/x86seg.c index 1042712ae..cc0cc6dbc 100644 --- a/src/x86seg.c +++ b/src/CPU/x86seg.c @@ -4,9 +4,9 @@ #include #include #include -#include "ibm.h" -#include "mem.h" -#include "nvr.h" +#include "../ibm.h" +#include "../mem.h" +#include "../nvr.h" #include "x86.h" #include "386.h" #include "386_common.h" @@ -49,7 +49,7 @@ void x86abort(const char *format, ...) va_end(ap); fflush(stdout); savenvr(); - dumpregs(); + dumpregs(1); fflush(stdout); exit(-1); } diff --git a/src/x86seg.h b/src/CPU/x86seg.h similarity index 100% rename from src/x86seg.h rename to src/CPU/x86seg.h diff --git a/src/x87.c b/src/CPU/x87.c similarity index 98% rename from src/x87.c rename to src/CPU/x87.c index a729a14c4..a241130fb 100644 --- a/src/x87.c +++ b/src/CPU/x87.c @@ -1,14 +1,14 @@ #define fplog 0 - #include -#include "ibm.h" -#include "pic.h" +#include "../ibm.h" +#include "../pic.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" #include "386_common.h" + uint16_t x87_gettag() { uint16_t ret = 0; diff --git a/src/x87.h b/src/CPU/x87.h similarity index 100% rename from src/x87.h rename to src/CPU/x87.h diff --git a/src/x87_ops.h b/src/CPU/x87_ops.h similarity index 100% rename from src/x87_ops.h rename to src/CPU/x87_ops.h diff --git a/src/x87_ops_arith.h b/src/CPU/x87_ops_arith.h similarity index 100% rename from src/x87_ops_arith.h rename to src/CPU/x87_ops_arith.h diff --git a/src/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h similarity index 100% rename from src/x87_ops_loadstore.h rename to src/CPU/x87_ops_loadstore.h diff --git a/src/x87_ops_misc.h b/src/CPU/x87_ops_misc.h similarity index 100% rename from src/x87_ops_misc.h rename to src/CPU/x87_ops_misc.h diff --git a/src/ICONS/hard_disk_mfm.ico b/src/ICONS/hard_disk_mfm.ico new file mode 100644 index 000000000..ee44a85a0 Binary files /dev/null and b/src/ICONS/hard_disk_mfm.ico differ diff --git a/src/ICONS/hard_disk_mfm_active.ico b/src/ICONS/hard_disk_mfm_active.ico new file mode 100644 index 000000000..caf8ef541 Binary files /dev/null and b/src/ICONS/hard_disk_mfm_active.ico differ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index b29478e4d..25f80b092 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.5 2017/05/05 +# Version: @(#)Makefile.mingw 1.0.12 2017/05/12 # # Authors: Kotori, # Fred N. van Kempen, @@ -30,30 +30,65 @@ EXTRAS = # Do we want a debugging build? DEBUG = n +OPTIM = n +X64 = n ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . dosbox lzf resid-fp slirp +VPATH = . cpu sound sound/resid-fp video lzf slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe OPTS = -DWIN32 $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) -DFLAGS = -march=i686 -Og -ggdb -DDEBUG +ifeq ($(VRAMDUMP), y) +DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP else -ifeq ($(OPTIMIZED), y) -DFLAGS = -march=native -mtune=native -O6 +DFLAGS = -march=i686 -ggdb -DDEBUG +endif +COPTIM = -Og else -DFLAGS = -march=i686 -O3 +ifeq ($(OPTIM), y) +DFLAGS = -march=native +COPTIM = -O6 +else +ifeq ($(X64), y) +DFLAGS = +else +DFLAGS = -march=i686 +endif +COPTIM = -O3 endif endif -AFLAGS = -msse -msse2 -mfpmath=sse -CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ +ifeq ($(OPTIM), y) +AOPTIM = -mtune=native +else +AOPTIM = +endif +AFLAGS = -msse -msse2 \ + -mfpmath=sse +ifeq ($(RELEASE), y) +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign -DRELEASE_BUILD +RFLAGS = --input-format=rc -O coff -DRELEASE_BUILD +else +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ -fomit-frame-pointer -mstackrealign +ifeq ($(VRAMDUMP), y) +RFLAGS = --input-format=rc -O coff -DENABLE_VRAM_DUMP +else RFLAGS = --input-format=rc -O coff +endif +endif + +ifeq ($(X64), y) +PLATCG = codegen_x86-64.o +else +PLATCG = codegen_x86.o +endif MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ @@ -63,7 +98,7 @@ CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ codegen.o \ codegen_ops.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_x86.o \ + codegen_timing_winchip.o $(PLATCG) \ x86seg.o x87.o SYSOBJ = model.o \ headland.o \ @@ -88,22 +123,34 @@ DEVOBJ = bugger.o lpt.o serial.o \ mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ fdd.o fdc.o \ fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ - hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ + hdd.o \ + mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ - cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o + cdrom.o \ + cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o -NETOBJ = ne2000.o nethandler.o -SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o -SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ - sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ - sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ - sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ - sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ - sound_ym7128.o soundopenal.o +NETOBJ = network.o \ + net_pcap.o net_slirp.o \ + net_ne2000.o +SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o +SNDOBJ = sound.o \ + convolve.o convolve-sse.o envelope.o extfilt.o \ + filter.o pot.o sid.o voice.o wave6581__ST.o \ + wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ + wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o \ + dbopl.o nukedopl.o openal.o \ + snd_speaker.o snd_ps1.o snd_pssj.o \ + snd_adlib.o snd_adlibgold.o snd_ad1848.o \ + snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ + snd_emu8k.o snd_gus.o snd_opl.o \ + snd_mpu401.o snd_pas16.o snd_resid.o \ + snd_sn76489.o snd_ssi2001.o snd_wss.o \ + snd_ym7128.o VIDOBJ = video.o \ - vid_mda.o vid_cga.o vid_ega.o \ + vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ vid_vga.o vid_svga.o vid_svga_render.o \ vid_hercules.o vid_herculesplus.o vid_incolor.o \ vid_colorplus.o \ @@ -129,33 +176,28 @@ VIDOBJ = video.o \ WINOBJ = win.o \ win-d3d.o win-d3d-fs.o \ win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-video.o \ - win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ + win-language.o win-status.o win-opendir.o \ + win-video.o win-serial.o win-mouse.o \ + win-joystick.o win-midi.o \ win-settings.o win-deviceconfig.o win-joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ - sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ - wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o -SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ - queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ - udp.o if.o mbuf.o slirp.o tcp_subr.o +SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ + ip_input.o queue.o tcp_input.o debug.o ip_output.o \ + sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ - -static -L. -lwpcapdelay + -lstdc++ -lpsapi -static-libstdc++ -static-libgcc # Build rules. %.o: %.c @echo $< - $(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< @@ -165,17 +207,27 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ @echo $< @$(CPP) $(CFLAGS) -c $< -$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) +all: $(PROG).exe pcap_if.exe + + +$(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe \ - $(OBJ) \ - $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ - $(LIBS) + $(OBJ) $(LZFOBJ) $(SLIRPOBJ) \ + $(LIBS) -static -Lpcap -lwpcapdelay ifneq ($(DEBUG), y) - strip $(PROG).exe + @strip $(PROG).exe endif -all: $(PROG).exe +pcap_if.exe: pcap_if.o pcap_if.res + @echo Linking pcap_if.exe .. + @$(CC) -o pcap_if.exe \ + pcap_if.o pcap_if.res -static -Lpcap -lwpcapdelay +ifneq ($(DEBUG), y) + @strip pcap_if.exe +endif + + clean: rm *.o @@ -186,5 +238,9 @@ clean: @echo Processing $< @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res +pcap_if.res: pcap_if.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i pcap_if.rc -o pcap_if.res + # End of Makefile.mingw. diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 7dfc840ac..2f0f9b408 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,9 +6,9 @@ # # This file is part of the 86Box distribution. # -# Modified Makefile for Win32 MinGW 32-bit environment. +# Modified Makefile for Win64 MinGW 64-bit environment. # -# Version: @(#)Makefile.mingw64 1.0.0 2017/05/05 +# Version: @(#)Makefile.mingw64 1.0.2 2017/05/06 # # Authors: Kotori, # Fred N. van Kempen, @@ -16,174 +16,18 @@ # Richard G., # +# Include the default Makefile. +include Makefile.mingw + # Name of the executable. PROG = 86Box64 # Various compile-time options. -# -DROM_TRACE=0xcd800 traces ROM access from segment C800 -# -DIO_TACE=0x66 traces I/O on port 0x66 STUFF = - -# Add feature selections here. -# -DBUGGER adds the ISA BusBugger emulation. EXTRAS = - -# Do we want a debugging build? DEBUG = n +OPTIM = n +X64 = y -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH = . dosbox lzf resid-fp slirp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe - -OPTS = -DWIN32 $(EXTRAS) $(STUFF) -ifeq ($(DEBUG), y) -DFLAGS = -march=i686 -Og -ggdb -DDEBUG -else -ifeq ($(OPTIMIZED), y) -DFLAGS = -march=native -mtune=native -O6 -else -DFLAGS = -O3 -endif -endif -AFLAGS = -msse -msse2 -mfpmath=sse -CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ - -fomit-frame-pointer -mstackrealign -RFLAGS = --input-format=rc -O coff - - -MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ - mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ - memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o -CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ - codegen.o \ - codegen_ops.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_x86-64.o \ - x86seg.o x87.o -SYSOBJ = model.o \ - headland.o \ - i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ - neat.o \ - ali1429.o \ - opti495.o \ - scat.o \ - sis496.o \ - wd76c10.o \ - acer386sx.o acerm3a.o amstrad.o \ - compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ - tandy_eeprom.o tandy_rom.o -DEVOBJ = bugger.o lpt.o serial.o \ - um8669f.o pc87306.o sis85c471.o w83877f.o \ - keyboard.o \ - keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ - keyboard_amstrad.o keyboard_olim24.o \ - gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o \ - mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ - fdd.o fdc.o \ - fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ - hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ - disc.o \ - disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ - disc_random.o disc_td0.o \ - cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o -USBOBJ = usb.o -NETOBJ = ne2000.o nethandler.o -SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o -SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ - sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ - sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ - sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ - sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ - sound_ym7128.o soundopenal.o -VIDOBJ = video.o \ - vid_mda.o vid_cga.o vid_ega.o \ - vid_vga.o vid_svga.o vid_svga_render.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_s3.o vid_s3_virge.o \ - vid_et4000.o vid_et4000w32.o vid_icd2061.o \ - vid_oti067.o \ - vid_paradise.o \ - vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ - vid_ati68860_ramdac.o vid_ati_mach64.o \ - vid_ics2595.o \ - vid_sdac_ramdac.o \ - vid_stg_ramdac.o \ - vid_unk_ramdac.o \ - vid_wy700.o \ - vid_voodoo.o \ - vid_pcjr.o vid_ps1_svga.o \ - vid_olivetti_m24.o \ - vid_pc1512.o vid_pc1640.o vid_pc200.o \ - vid_tandy.o vid_tandysl.o -WINOBJ = win.o \ - win-d3d.o win-d3d-fs.o \ - win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-video.o \ - win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ - win-settings.o win-deviceconfig.o win-joystickconfig.o \ - 86Box.res -OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ - $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) - -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o -LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ - sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ - wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o -SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ - queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ - udp.o if.o mbuf.o slirp.o tcp_subr.o - -LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ - -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ - -static -L. -lwpcapdelay - - -# Build rules. -%.o: %.c - @echo $< - $(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CFLAGS) -c $< - -$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) - @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe \ - $(OBJ) \ - $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ - $(LIBS) -ifneq ($(DEBUG), y) - strip $(PROG).exe -endif - -all: $(PROG).exe - -clean: - rm *.o - rm *.exe - rm *.res - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res - - -# End of Makefile.mingw. +# End of Makefile.mingw64. diff --git a/src/dosbox/dbopl.cpp b/src/SOUND/dbopl.cpp similarity index 100% rename from src/dosbox/dbopl.cpp rename to src/SOUND/dbopl.cpp diff --git a/src/dosbox/dbopl.h b/src/SOUND/dbopl.h similarity index 100% rename from src/dosbox/dbopl.h rename to src/SOUND/dbopl.h diff --git a/src/filters.h b/src/SOUND/filters.h similarity index 100% rename from src/filters.h rename to src/SOUND/filters.h diff --git a/src/dosbox/nukedopl.cpp b/src/SOUND/nukedopl.cpp similarity index 100% rename from src/dosbox/nukedopl.cpp rename to src/SOUND/nukedopl.cpp diff --git a/src/dosbox/nukedopl.h b/src/SOUND/nukedopl.h similarity index 100% rename from src/dosbox/nukedopl.h rename to src/SOUND/nukedopl.h diff --git a/src/soundopenal.c b/src/SOUND/openal.c similarity index 96% rename from src/soundopenal.c rename to src/SOUND/openal.c index 8cb065fbd..9f20b57de 100644 --- a/src/soundopenal.c +++ b/src/SOUND/openal.c @@ -3,13 +3,14 @@ #include #include #ifdef USE_OPENAL -#include -#include -#include +# include +# include +# include #endif -#include "ibm.h" +#include "../ibm.h" #include "sound.h" + FILE *allog; #ifdef USE_OPENAL ALuint buffers[4]; /* front and back buffers */ @@ -19,7 +20,8 @@ static ALuint source[2]; /* audio source */ #define FREQ 48000 #define BUFLEN SOUNDBUFLEN -void closeal(); + +void closeal(ALvoid); ALvoid alutInit(ALint *argc,ALbyte **argv) { ALCcontext *Context; @@ -60,14 +62,14 @@ void initalmain(int argc, char *argv[]) #endif } -void closeal() +void closeal(ALvoid) { #ifdef USE_OPENAL alutExit(); #endif } -void inital() +void inital(ALvoid) { #ifdef USE_OPENAL int c; diff --git a/src/resid-fp/AUTHORS b/src/SOUND/resid-fp/AUTHORS similarity index 100% rename from src/resid-fp/AUTHORS rename to src/SOUND/resid-fp/AUTHORS diff --git a/src/resid-fp/COPYING b/src/SOUND/resid-fp/COPYING similarity index 100% rename from src/resid-fp/COPYING rename to src/SOUND/resid-fp/COPYING diff --git a/src/resid-fp/ChangeLog b/src/SOUND/resid-fp/ChangeLog similarity index 100% rename from src/resid-fp/ChangeLog rename to src/SOUND/resid-fp/ChangeLog diff --git a/src/resid-fp/INSTALL b/src/SOUND/resid-fp/INSTALL similarity index 100% rename from src/resid-fp/INSTALL rename to src/SOUND/resid-fp/INSTALL diff --git a/src/resid-fp/Makefile.am b/src/SOUND/resid-fp/Makefile.am similarity index 100% rename from src/resid-fp/Makefile.am rename to src/SOUND/resid-fp/Makefile.am diff --git a/src/resid-fp/Makefile.in b/src/SOUND/resid-fp/Makefile.in similarity index 100% rename from src/resid-fp/Makefile.in rename to src/SOUND/resid-fp/Makefile.in diff --git a/src/resid-fp/NEWS b/src/SOUND/resid-fp/NEWS similarity index 100% rename from src/resid-fp/NEWS rename to src/SOUND/resid-fp/NEWS diff --git a/src/resid-fp/README b/src/SOUND/resid-fp/README similarity index 100% rename from src/resid-fp/README rename to src/SOUND/resid-fp/README diff --git a/src/resid-fp/README.VICE b/src/SOUND/resid-fp/README.VICE similarity index 100% rename from src/resid-fp/README.VICE rename to src/SOUND/resid-fp/README.VICE diff --git a/src/resid-fp/aclocal.m4 b/src/SOUND/resid-fp/aclocal.m4 similarity index 100% rename from src/resid-fp/aclocal.m4 rename to src/SOUND/resid-fp/aclocal.m4 diff --git a/src/resid-fp/configure b/src/SOUND/resid-fp/configure similarity index 100% rename from src/resid-fp/configure rename to src/SOUND/resid-fp/configure diff --git a/src/resid-fp/configure.in b/src/SOUND/resid-fp/configure.in similarity index 100% rename from src/resid-fp/configure.in rename to src/SOUND/resid-fp/configure.in diff --git a/src/resid-fp/convolve-sse.cc b/src/SOUND/resid-fp/convolve-sse.cc similarity index 100% rename from src/resid-fp/convolve-sse.cc rename to src/SOUND/resid-fp/convolve-sse.cc diff --git a/src/resid-fp/convolve.cc b/src/SOUND/resid-fp/convolve.cc similarity index 100% rename from src/resid-fp/convolve.cc rename to src/SOUND/resid-fp/convolve.cc diff --git a/src/resid-fp/envelope.cc b/src/SOUND/resid-fp/envelope.cc similarity index 100% rename from src/resid-fp/envelope.cc rename to src/SOUND/resid-fp/envelope.cc diff --git a/src/resid-fp/envelope.h b/src/SOUND/resid-fp/envelope.h similarity index 100% rename from src/resid-fp/envelope.h rename to src/SOUND/resid-fp/envelope.h diff --git a/src/resid-fp/extfilt.cc b/src/SOUND/resid-fp/extfilt.cc similarity index 100% rename from src/resid-fp/extfilt.cc rename to src/SOUND/resid-fp/extfilt.cc diff --git a/src/resid-fp/extfilt.h b/src/SOUND/resid-fp/extfilt.h similarity index 100% rename from src/resid-fp/extfilt.h rename to src/SOUND/resid-fp/extfilt.h diff --git a/src/resid-fp/filter.cc b/src/SOUND/resid-fp/filter.cc similarity index 100% rename from src/resid-fp/filter.cc rename to src/SOUND/resid-fp/filter.cc diff --git a/src/resid-fp/filter.h b/src/SOUND/resid-fp/filter.h similarity index 100% rename from src/resid-fp/filter.h rename to src/SOUND/resid-fp/filter.h diff --git a/src/resid-fp/pot.cc b/src/SOUND/resid-fp/pot.cc similarity index 100% rename from src/resid-fp/pot.cc rename to src/SOUND/resid-fp/pot.cc diff --git a/src/resid-fp/pot.h b/src/SOUND/resid-fp/pot.h similarity index 100% rename from src/resid-fp/pot.h rename to src/SOUND/resid-fp/pot.h diff --git a/src/resid-fp/samp2src.pl b/src/SOUND/resid-fp/samp2src.pl similarity index 100% rename from src/resid-fp/samp2src.pl rename to src/SOUND/resid-fp/samp2src.pl diff --git a/src/resid-fp/sid.cc b/src/SOUND/resid-fp/sid.cc similarity index 100% rename from src/resid-fp/sid.cc rename to src/SOUND/resid-fp/sid.cc diff --git a/src/resid-fp/sid.h b/src/SOUND/resid-fp/sid.h similarity index 100% rename from src/resid-fp/sid.h rename to src/SOUND/resid-fp/sid.h diff --git a/src/resid-fp/siddefs-fp.h b/src/SOUND/resid-fp/siddefs-fp.h similarity index 100% rename from src/resid-fp/siddefs-fp.h rename to src/SOUND/resid-fp/siddefs-fp.h diff --git a/src/resid-fp/siddefs-fp.h.in b/src/SOUND/resid-fp/siddefs-fp.h.in similarity index 100% rename from src/resid-fp/siddefs-fp.h.in rename to src/SOUND/resid-fp/siddefs-fp.h.in diff --git a/src/resid-fp/version.cc b/src/SOUND/resid-fp/version.cc similarity index 100% rename from src/resid-fp/version.cc rename to src/SOUND/resid-fp/version.cc diff --git a/src/resid-fp/voice.cc b/src/SOUND/resid-fp/voice.cc similarity index 100% rename from src/resid-fp/voice.cc rename to src/SOUND/resid-fp/voice.cc diff --git a/src/resid-fp/voice.h b/src/SOUND/resid-fp/voice.h similarity index 100% rename from src/resid-fp/voice.h rename to src/SOUND/resid-fp/voice.h diff --git a/src/resid-fp/wave.cc b/src/SOUND/resid-fp/wave.cc similarity index 100% rename from src/resid-fp/wave.cc rename to src/SOUND/resid-fp/wave.cc diff --git a/src/resid-fp/wave.h b/src/SOUND/resid-fp/wave.h similarity index 100% rename from src/resid-fp/wave.h rename to src/SOUND/resid-fp/wave.h diff --git a/src/resid-fp/wave6581_PST.cc b/src/SOUND/resid-fp/wave6581_PST.cc similarity index 100% rename from src/resid-fp/wave6581_PST.cc rename to src/SOUND/resid-fp/wave6581_PST.cc diff --git a/src/resid-fp/wave6581_PST.dat b/src/SOUND/resid-fp/wave6581_PST.dat similarity index 100% rename from src/resid-fp/wave6581_PST.dat rename to src/SOUND/resid-fp/wave6581_PST.dat diff --git a/src/resid-fp/wave6581_PS_.cc b/src/SOUND/resid-fp/wave6581_PS_.cc similarity index 100% rename from src/resid-fp/wave6581_PS_.cc rename to src/SOUND/resid-fp/wave6581_PS_.cc diff --git a/src/resid-fp/wave6581_PS_.dat b/src/SOUND/resid-fp/wave6581_PS_.dat similarity index 100% rename from src/resid-fp/wave6581_PS_.dat rename to src/SOUND/resid-fp/wave6581_PS_.dat diff --git a/src/resid-fp/wave6581_P_T.cc b/src/SOUND/resid-fp/wave6581_P_T.cc similarity index 100% rename from src/resid-fp/wave6581_P_T.cc rename to src/SOUND/resid-fp/wave6581_P_T.cc diff --git a/src/resid-fp/wave6581_P_T.dat b/src/SOUND/resid-fp/wave6581_P_T.dat similarity index 100% rename from src/resid-fp/wave6581_P_T.dat rename to src/SOUND/resid-fp/wave6581_P_T.dat diff --git a/src/resid-fp/wave6581__ST.cc b/src/SOUND/resid-fp/wave6581__ST.cc similarity index 100% rename from src/resid-fp/wave6581__ST.cc rename to src/SOUND/resid-fp/wave6581__ST.cc diff --git a/src/resid-fp/wave6581__ST.dat b/src/SOUND/resid-fp/wave6581__ST.dat similarity index 100% rename from src/resid-fp/wave6581__ST.dat rename to src/SOUND/resid-fp/wave6581__ST.dat diff --git a/src/resid-fp/wave8580_PST.cc b/src/SOUND/resid-fp/wave8580_PST.cc similarity index 100% rename from src/resid-fp/wave8580_PST.cc rename to src/SOUND/resid-fp/wave8580_PST.cc diff --git a/src/resid-fp/wave8580_PST.dat b/src/SOUND/resid-fp/wave8580_PST.dat similarity index 100% rename from src/resid-fp/wave8580_PST.dat rename to src/SOUND/resid-fp/wave8580_PST.dat diff --git a/src/resid-fp/wave8580_PS_.cc b/src/SOUND/resid-fp/wave8580_PS_.cc similarity index 100% rename from src/resid-fp/wave8580_PS_.cc rename to src/SOUND/resid-fp/wave8580_PS_.cc diff --git a/src/resid-fp/wave8580_PS_.dat b/src/SOUND/resid-fp/wave8580_PS_.dat similarity index 100% rename from src/resid-fp/wave8580_PS_.dat rename to src/SOUND/resid-fp/wave8580_PS_.dat diff --git a/src/resid-fp/wave8580_P_T.cc b/src/SOUND/resid-fp/wave8580_P_T.cc similarity index 100% rename from src/resid-fp/wave8580_P_T.cc rename to src/SOUND/resid-fp/wave8580_P_T.cc diff --git a/src/resid-fp/wave8580_P_T.dat b/src/SOUND/resid-fp/wave8580_P_T.dat similarity index 100% rename from src/resid-fp/wave8580_P_T.dat rename to src/SOUND/resid-fp/wave8580_P_T.dat diff --git a/src/resid-fp/wave8580__ST.cc b/src/SOUND/resid-fp/wave8580__ST.cc similarity index 100% rename from src/resid-fp/wave8580__ST.cc rename to src/SOUND/resid-fp/wave8580__ST.cc diff --git a/src/resid-fp/wave8580__ST.dat b/src/SOUND/resid-fp/wave8580__ST.dat similarity index 100% rename from src/resid-fp/wave8580__ST.dat rename to src/SOUND/resid-fp/wave8580__ST.dat diff --git a/src/sound_ad1848.c b/src/SOUND/snd_ad1848.c similarity index 98% rename from src/sound_ad1848.c rename to src/SOUND/snd_ad1848.c index c97a6d518..10ff8b2b3 100644 --- a/src/sound_ad1848.c +++ b/src/SOUND/snd_ad1848.c @@ -3,15 +3,17 @@ AD1848 CODEC emulation (Windows Sound System compatible)*/ #include - -#include "ibm.h" -#include "dma.h" -#include "pic.h" +#include "../ibm.h" +#include "../dma.h" +#include "../pic.h" +#include "../timer.h" #include "sound.h" -#include "sound_ad1848.h" +#include "snd_ad1848.h" + static int ad1848_vols[64]; + void ad1848_setirq(ad1848_t *ad1848, int irq) { ad1848->irq = irq; diff --git a/src/sound_ad1848.h b/src/SOUND/snd_ad1848.h similarity index 97% rename from src/sound_ad1848.h rename to src/SOUND/snd_ad1848.h index 6c5e02c55..3a0dd4e46 100644 --- a/src/sound_ad1848.h +++ b/src/SOUND/snd_ad1848.h @@ -1,5 +1,3 @@ -#include "timer.h" - typedef struct ad1848_t { int index; diff --git a/src/sound_adlib.c b/src/SOUND/snd_adlib.c similarity index 95% rename from src/sound_adlib.c rename to src/SOUND/snd_adlib.c index 70ed47b7a..e131d04c3 100644 --- a/src/sound_adlib.c +++ b/src/SOUND/snd_adlib.c @@ -1,12 +1,12 @@ #include -#include "ibm.h" -#include "io.h" -#include "device.h" +#include "../ibm.h" +#include "../io.h" +#include "../mca.h" +#include "../device.h" #include "sound.h" -#include "mca.h" +#include "snd_adlib.h" +#include "snd_opl.h" -#include "sound_adlib.h" -#include "sound_opl.h" typedef struct adlib_t { @@ -15,6 +15,7 @@ typedef struct adlib_t uint8_t pos_regs[8]; } adlib_t; + static void adlib_get_buffer(int32_t *buffer, int len, void *p) { adlib_t *adlib = (adlib_t *)p; diff --git a/src/sound_adlib.h b/src/SOUND/snd_adlib.h similarity index 100% rename from src/sound_adlib.h rename to src/SOUND/snd_adlib.h diff --git a/src/sound_adlibgold.c b/src/SOUND/snd_adlibgold.c similarity index 99% rename from src/sound_adlibgold.c rename to src/SOUND/snd_adlibgold.c index 398ed139c..e03a9cf9b 100644 --- a/src/sound_adlibgold.c +++ b/src/SOUND/snd_adlibgold.c @@ -1,18 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" - -#include "sound_opl.h" -#include "sound_ym7128.h" -#include "dma.h" -#include "io.h" -#include "pic.h" -#include "pit.h" +#include "../ibm.h" +#include "../io.h" +#include "../dma.h" +#include "../pic.h" +#include "../pit.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "timer.h" - #include "filters.h" +#include "snd_opl.h" +#include "snd_ym7128.h" + typedef struct adgold_t { @@ -772,7 +773,7 @@ void *adgold_init() for (; c >= 0; c--) attenuation[c] = 0; - f = romfopen("nvr/adgold.bin", "rb"); + f = nvrfopen(L"adgold.bin", L"rb"); if (f) { fread(adgold->adgold_eeprom, 0x18, 1, f); @@ -812,7 +813,7 @@ void adgold_close(void *p) FILE *f; adgold_t *adgold = (adgold_t *)p; - f = romfopen("nvr/adgold.bin", "wb"); + f = nvrfopen(L"adgold.bin", L"wb"); if (f) { fwrite(adgold->adgold_eeprom, 0x18, 1, f); diff --git a/src/sound_adlibgold.h b/src/SOUND/snd_adlibgold.h similarity index 100% rename from src/sound_adlibgold.h rename to src/SOUND/snd_adlibgold.h diff --git a/src/sound_cms.c b/src/SOUND/snd_cms.c similarity index 98% rename from src/sound_cms.c rename to src/SOUND/snd_cms.c index 93a2aab1f..1cbf723b2 100644 --- a/src/sound_cms.c +++ b/src/SOUND/snd_cms.c @@ -1,14 +1,15 @@ #include #include -#include "ibm.h" - -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" -#include "sound_cms.h" +#include "snd_cms.h" + #define MASTER_CLOCK 7159090 + typedef struct cms_t { int addrs[2]; diff --git a/src/sound_cms.h b/src/SOUND/snd_cms.h similarity index 100% rename from src/sound_cms.h rename to src/SOUND/snd_cms.h diff --git a/src/sound_dbopl.cc b/src/SOUND/snd_dbopl.cc similarity index 96% rename from src/sound_dbopl.cc rename to src/SOUND/snd_dbopl.cc index 8f7463357..cecc1c35e 100644 --- a/src/sound_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -1,12 +1,14 @@ /* Copyright holders: The DOSBox Team, SA1988 see COPYING for more details */ -#include "dosbox/dbopl.h" -#include "dosbox/nukedopl.h" -#include "sound_dbopl.h" +#include "dbopl.h" +#include "nukedopl.h" +#include "snd_dbopl.h" + int opl3_type = 0; + static struct { DBOPL::Chip chip; @@ -42,8 +44,8 @@ void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), vo { if (!is_opl3 || !opl3_type) { - DBOPL::InitTables(); - opl[nr].chip.Setup(48000, 0); + DBOPL::InitTables(); + opl[nr].chip.Setup(48000, is_opl3); opl[nr].timer_callback = timer_callback; opl[nr].timer_param = timer_param; opl[nr].is_opl3 = is_opl3; diff --git a/src/sound_dbopl.h b/src/SOUND/snd_dbopl.h similarity index 100% rename from src/sound_dbopl.h rename to src/SOUND/snd_dbopl.h diff --git a/src/sound_emu8k.c b/src/SOUND/snd_emu8k.c similarity index 99% rename from src/sound_emu8k.c rename to src/SOUND/snd_emu8k.c index 1d82385f1..670e057a1 100644 --- a/src/sound_emu8k.c +++ b/src/SOUND/snd_emu8k.c @@ -5,12 +5,15 @@ highest (10.72 Hz) = 2^12 steps = 4096*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_emu8k.h" -#include "timer.h" +#include "snd_emu8k.h" + enum { @@ -671,7 +674,7 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) int c; double out; - f = romfopen("roms/awe32.raw", "rb"); + f = romfopen(L"roms/awe32.raw", L"rb"); if (!f) fatal("ROMS/AWE32.RAW not found\n"); diff --git a/src/sound_emu8k.h b/src/SOUND/snd_emu8k.h similarity index 100% rename from src/sound_emu8k.h rename to src/SOUND/snd_emu8k.h diff --git a/src/sound_gus.c b/src/SOUND/snd_gus.c similarity index 99% rename from src/sound_gus.c rename to src/SOUND/snd_gus.c index 34b0416e4..2735d77fd 100644 --- a/src/sound_gus.c +++ b/src/SOUND/snd_gus.c @@ -1,15 +1,15 @@ #include #include #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_gus.h" -#include "timer.h" +#include "snd_gus.h" + typedef struct gus_t { diff --git a/src/sound_gus.h b/src/SOUND/snd_gus.h similarity index 100% rename from src/sound_gus.h rename to src/SOUND/snd_gus.h diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c new file mode 100644 index 000000000..eace343f3 --- /dev/null +++ b/src/SOUND/snd_mpu401.c @@ -0,0 +1,729 @@ +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../timer.h" +#include "../plat-midi.h" +#include "snd_mpu401.h" + +#include + +enum +{ + STATUS_OUTPUT_NOT_READY = 0x40, + STATUS_INPUT_NOT_READY = 0x80 +}; + +static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); +static void MPU401_EOIHandlerDispatch(void *p); + +static int mpu401_event_callback = 0; +static int mpu401_eoi_callback = 0; +static int mpu401_reset_callback = 0; + +#ifdef ENABLE_MPU401_LOG +static int mpu401_do_log = 1; +static char logfmt[512]; +#endif + +static void +mpulog(const char *fmt, ...) +{ +#ifdef ENABLE_MPU401_LOG + va_list ap; + + if (mpu401_do_log) { + va_start(ap, fmt); + memset(logfmt, 0, 512); + strcpy(logfmt, "MPU-401: "); + strcpy(logfmt + strlen(logfmt), fmt); + vprintf(logfmt, ap); + va_end(ap); + } +#endif +} +#define pclog mpulog + + +static void QueueByte(mpu_t *mpu, uint8_t data) +{ + if (mpu->state.block_ack) + { + mpu->state.block_ack=0; + return; + } + + if (mpu->queue_used == 0 && mpu->intelligent) + { + mpu->state.irq_pending=1; + //PIC_ActivateIRQ(mpu->irq); + picint(1 << mpu->irq); + } + if (mpu->queue_used < MPU401_QUEUE) + { + int pos = mpu->queue_used+mpu->queue_pos; + + if (mpu->queue_pos >= MPU401_QUEUE) + mpu->queue_pos -= MPU401_QUEUE; + + if (pos>=MPU401_QUEUE) + pos-=MPU401_QUEUE; + + mpu->queue_used++; + mpu->queue[pos]=data; + } + else + pclog("MPU401:Data queue full\n"); +} + +static void ClrQueue(mpu_t *mpu) +{ + mpu->queue_used=0; + mpu->queue_pos=0; +} + +static void MPU401_Reset(mpu_t *mpu) +{ + uint8_t i; + + picintc(1 << mpu->irq); + mpu->mode=(mpu->intelligent ? M_INTELLIGENT : M_UART); + mpu->state.eoi_scheduled=0; + mpu->state.wsd=0; + mpu->state.wsm=0; + mpu->state.conductor=0; + mpu->state.cond_req=0; + mpu->state.cond_set=0; + mpu->state.playing=0; + mpu->state.run_irq=0; + mpu->state.irq_pending=0; + mpu->state.cmask=0xff; + mpu->state.amask=mpu->state.tmask=0; + mpu->state.midi_mask=0xffff; + mpu->state.data_onoff=0; + mpu->state.command_byte=0; + mpu->state.block_ack=0; + mpu->clock.tempo=mpu->clock.old_tempo=100; + mpu->clock.timebase=mpu->clock.old_timebase=120; + mpu->clock.tempo_rel=mpu->clock.old_tempo_rel=40; + mpu->clock.tempo_grad=0; + mpu->clock.clock_to_host=0; + mpu->clock.cth_rate=60; + mpu->clock.cth_counter=0; + ClrQueue(mpu); + mpu->state.req_mask=0; + mpu->condbuf.counter=0; + mpu->condbuf.type=T_OVERFLOW; + for (i=0;i<8;i++) {mpu->playbuf[i].type=T_OVERFLOW;mpu->playbuf[i].counter=0;} +} + +static void MPU401_ResetDone(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + + pclog("MPU-401 reset callback\n"); + + mpu401_reset_callback = 0; + + mpu->state.reset=0; + if (mpu->state.cmd_pending) + { + MPU401_WriteCommand(mpu, mpu->state.cmd_pending-1); + mpu->state.cmd_pending=0; + } +} + +static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) +{ + uint8_t i; + + if (mpu->state.reset) + { + mpu->state.cmd_pending=val+1; + return; + } + + if (val<=0x2f) + { + switch (val&3) + { /* MIDI stop, start, continue */ + case 1: {midi_write(0xfc);break;} + case 2: {midi_write(0xfa);break;} + case 3: {midi_write(0xfb);break;} + } +// if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",(int)val); + switch (val&0xc) + { + case 0x4: /* Stop */ + mpu->state.playing=0; + mpu401_event_callback = 0; + for (i=0xb0;i<0xbf;i++) + { /* All notes off */ + midi_write(i); + midi_write(0x7b); + midi_write(0); + } + break; + case 0x8: /* Play */ +// LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started"); + mpu->state.playing=1; + mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * 1000 * TIMER_USEC; + ClrQueue(mpu); + break; + } + } + else if (val>=0xa0 && val<=0xa7) + { /* Request play counter */ + if (mpu->state.cmask&(1<<(val&7))) QueueByte(mpu, mpu->playbuf[val&7].counter); + } + else if (val>=0xd0 && val<=0xd7) + { /* Send data */ + mpu->state.old_chan=mpu->state.channel; + mpu->state.channel=val&7; + mpu->state.wsd=1; + mpu->state.wsm=0; + mpu->state.wsd_start=1; + } + else + switch (val) + { + case 0xdf: /* Send system message */ + mpu->state.wsd=0; + mpu->state.wsm=1; + mpu->state.wsd_start=1; + break; + case 0x8e: /* Conductor */ + mpu->state.cond_set=0; + break; + case 0x8f: + mpu->state.cond_set=1; + break; + case 0x94: /* Clock to host */ + mpu->clock.clock_to_host=0; + break; + case 0x95: + mpu->clock.clock_to_host=1; + break; + case 0xc2: /* Internal timebase */ + mpu->clock.timebase=48; + break; + case 0xc3: + mpu->clock.timebase=72; + break; + case 0xc4: + mpu->clock.timebase=96; + break; + case 0xc5: + mpu->clock.timebase=120; + break; + case 0xc6: + mpu->clock.timebase=144; + break; + case 0xc7: + mpu->clock.timebase=168; + break; + case 0xc8: + mpu->clock.timebase=192; + break; + /* Commands with data byte */ + case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: + case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: + mpu->state.command_byte=val; + break; + /* Commands 0xa# returning data */ + case 0xab: /* Request and clear recording counter */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, 0); + return; + case 0xac: /* Request version */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, MPU401_VERSION); + return; + case 0xad: /* Request revision */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, MPU401_REVISION); + return; + case 0xaf: /* Request tempo */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, mpu->clock.tempo); + return; + case 0xb1: /* Reset relative tempo */ + mpu->clock.tempo_rel=40; + break; + case 0xb9: /* Clear play map */ + case 0xb8: /* Clear play counters */ + for (i=0xb0;i<0xbf;i++) + { /* All notes off */ + midi_write(i); + midi_write(0x7b); + midi_write(0); + } + for (i=0;i<8;i++) + { + mpu->playbuf[i].counter=0; + mpu->playbuf[i].type=T_OVERFLOW; + } + mpu->condbuf.counter=0; + mpu->condbuf.type=T_OVERFLOW; + if (!(mpu->state.conductor=mpu->state.cond_set)) mpu->state.cond_req=0; + mpu->state.amask=mpu->state.tmask; + mpu->state.req_mask=0; + mpu->state.irq_pending=1; + break; + case 0xff: /* Reset MPU-401 */ + pclog("MPU-401:Reset %X\n",val); + mpu401_reset_callback = MPU401_RESETBUSY * 33 * TIMER_USEC; + mpu->state.reset=1; + MPU401_Reset(mpu); + if (mpu->mode==M_UART) return;//do not send ack in UART mode + break; + case 0x3f: /* UART mode */ + pclog("MPU-401:Set UART mode %X\n",val); + mpu->mode=M_UART; + break; + default:; + //LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val); + } + QueueByte(mpu, MSG_MPU_ACK); +} + +static void MPU401_WriteData(mpu_t *mpu, uint8_t val) +{ + if (mpu->mode==M_UART) {midi_write(val); return;} + + switch (mpu->state.command_byte) + { /* 0xe# command data */ + case 0x00: + break; + case 0xe0: /* Set tempo */ + mpu->state.command_byte=0; + mpu->clock.tempo=val; + return; + case 0xe1: /* Set relative tempo */ + mpu->state.command_byte=0; + if (val!=0x40) //default value + pclog("MPU-401:Relative tempo change not implemented\n"); + return; + case 0xe7: /* Set internal clock to host interval */ + mpu->state.command_byte=0; + mpu->clock.cth_rate=val>>2; + return; + case 0xec: /* Set active track mask */ + mpu->state.command_byte=0; + mpu->state.tmask=val; + return; + case 0xed: /* Set play counter mask */ + mpu->state.command_byte=0; + mpu->state.cmask=val; + return; + case 0xee: /* Set 1-8 MIDI channel mask */ + mpu->state.command_byte=0; + mpu->state.midi_mask&=0xff00; + mpu->state.midi_mask|=val; + return; + case 0xef: /* Set 9-16 MIDI channel mask */ + mpu->state.command_byte=0; + mpu->state.midi_mask&=0x00ff; + mpu->state.midi_mask|=((uint16_t)val)<<8; + return; + //case 0xe2: /* Set graduation for relative tempo */ + //case 0xe4: /* Set metronome */ + //case 0xe6: /* Set metronome measure length */ + default: + mpu->state.command_byte=0; + return; + } + static int length,cnt,posd; + if (mpu->state.wsd) + { /* Directly send MIDI message */ + if (mpu->state.wsd_start) + { + mpu->state.wsd_start=0; + cnt=0; + switch (val&0xf0) { + case 0xc0:case 0xd0: + mpu->playbuf[mpu->state.channel].value[0]=val; + length=2; + break; + case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0: + mpu->playbuf[mpu->state.channel].value[0]=val; + length=3; + break; + case 0xf0: + //pclog("MPU-401:Illegal WSD byte\n"); + mpu->state.wsd=0; + mpu->state.channel=mpu->state.old_chan; + return; + default: /* MIDI with running status */ + cnt++; + midi_write(mpu->playbuf[mpu->state.channel].value[0]); + } + } + if (cntstate.wsd=0; + mpu->state.channel=mpu->state.old_chan; + } + return; + } + if (mpu->state.wsm) + { /* Directly send system message */ + if (val==MSG_EOX) {midi_write(MSG_EOX);mpu->state.wsm=0;return;} + if (mpu->state.wsd_start) { + mpu->state.wsd_start=0; + cnt=0; + switch (val) + { + case 0xf2:{ length=3; break;} + case 0xf3:{ length=2; break;} + case 0xf6:{ length=1; break;} + case 0xf0:{ length=0; break;} + default: + length=0; + } + } + if (!length || cntstate.wsm=0; + return; + } + if (mpu->state.cond_req) + { /* Command */ + switch (mpu->state.data_onoff) { + case -1: + return; + case 0: /* Timing byte */ + mpu->condbuf.vlength=0; + if (val<0xf0) mpu->state.data_onoff++; + else { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + return; + } + if (val==0) mpu->state.send_now=1; + else mpu->state.send_now=0; + mpu->condbuf.counter=val; + break; + case 1: /* Command byte #1 */ + mpu->condbuf.type=T_COMMAND; + if (val==0xf8 || val==0xf9) mpu->condbuf.type=T_OVERFLOW; + mpu->condbuf.value[mpu->condbuf.vlength]=val; + mpu->condbuf.vlength++; + if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch(mpu); + else mpu->state.data_onoff++; + break; + case 2:/* Command byte #2 */ + mpu->condbuf.value[mpu->condbuf.vlength]=val; + mpu->condbuf.vlength++; + MPU401_EOIHandlerDispatch(mpu); + break; + } + return; + } + switch (mpu->state.data_onoff) + { /* Data */ + case -1: + return; + case 0: /* Timing byte */ + if (val<0xf0) mpu->state.data_onoff=1; + else { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + return; + } + if (val==0) mpu->state.send_now=1; + else mpu->state.send_now=0; + mpu->playbuf[mpu->state.channel].counter=val; + break; + case 1: /* MIDI */ + mpu->playbuf[mpu->state.channel].vlength++; + posd=mpu->playbuf[mpu->state.channel].vlength; + if (posd==1) { + switch (val&0xf0) { + case 0xf0: /* System message or mark */ + if (val>0xf7) { + mpu->playbuf[mpu->state.channel].type=T_MARK; + mpu->playbuf[mpu->state.channel].sys_val=val; + length=1; + } else { + //LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); + mpu->playbuf[mpu->state.channel].type=T_MIDI_SYS; + mpu->playbuf[mpu->state.channel].sys_val=val; + length=1; + } + break; + case 0xc0: case 0xd0: /* MIDI Message */ + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length=2; + break; + case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length=3; + break; + default: /* MIDI data with running status */ + posd++; + mpu->playbuf[mpu->state.channel].vlength++; + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length; + break; + } + } + if (!(posd==1 && val>=0xf0)) mpu->playbuf[mpu->state.channel].value[posd-1]=val; + if (posd==length) MPU401_EOIHandlerDispatch(mpu); + } +} + +static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t chan) +{ + uint8_t val; + uint8_t i; + switch (mpu->playbuf[chan].type) + { + case T_OVERFLOW: + break; + case T_MARK: + val=mpu->playbuf[chan].sys_val; + if (val==0xfc) + { + midi_write(val); + mpu->state.amask&=~(1<state.req_mask&=~(1<playbuf[chan].vlength;i++) + midi_write(mpu->playbuf[chan].value[i]); + break; + default: + break; + } +} + +static void UpdateTrack(mpu_t *mpu, uint8_t chan) +{ + MPU401_IntelligentOut(mpu, chan); + if (mpu->state.amask&(1<playbuf[chan].vlength=0; + mpu->playbuf[chan].type=T_OVERFLOW; + mpu->playbuf[chan].counter=0xf0; + mpu->state.req_mask|=(1<state.amask==0 && !mpu->state.conductor) mpu->state.req_mask|=(1<<12); + } +} + +static void UpdateConductor(mpu_t *mpu) +{ + if (mpu->condbuf.value[0]==0xfc) + { + mpu->condbuf.value[0]=0; + mpu->state.conductor=0; + mpu->state.req_mask&=~(1<<9); + if (mpu->state.amask==0) mpu->state.req_mask|=(1<<12); + return; + } + mpu->condbuf.vlength=0; + mpu->condbuf.counter=0xf0; + mpu->state.req_mask|=(1<<9); +} + +//Updates counters and requests new data on "End of Input" +static void MPU401_EOIHandler(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + uint8_t i; + + pclog("MPU-401 end of input callback\n"); + + mpu401_eoi_callback = 0; + mpu->state.eoi_scheduled=0; + if (mpu->state.send_now) + { + mpu->state.send_now=0; + if (mpu->state.cond_req) UpdateConductor(mpu); + else UpdateTrack(mpu, mpu->state.channel); + } + mpu->state.irq_pending=0; + if (!mpu->state.playing || !mpu->state.req_mask) return; + i=0; + do { + if (mpu->state.req_mask&(1<state.req_mask&=~(1<state.send_now) + { + mpu->state.eoi_scheduled=1; + mpu401_eoi_callback = 60 * TIMER_USEC; /* Possible a bit longer */ + } + else if (!mpu->state.eoi_scheduled) + MPU401_EOIHandler(mpu); +} + +static void imf_write(uint16_t addr, uint8_t val, void *p) +{ + pclog("IMF:Wr %4X,%X\n", addr, val); +} + +uint8_t MPU401_ReadData(mpu_t *mpu) +{ + uint8_t ret; + + ret = MSG_MPU_ACK; + if (mpu->queue_used) + { + if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; + ret=mpu->queue[mpu->queue_pos]; + mpu->queue_pos++;mpu->queue_used--; + } + if (!mpu->intelligent) return ret; + + if (mpu->queue_used == 0) picintc(1 << mpu->irq); + + if (ret>=0xf0 && ret<=0xf7) + { /* MIDI data request */ + mpu->state.channel=ret&7; + mpu->state.data_onoff=0; + mpu->state.cond_req=0; + } + if (ret==MSG_MPU_COMMAND_REQ) + { + mpu->state.data_onoff=0; + mpu->state.cond_req=1; + if (mpu->condbuf.type!=T_OVERFLOW) + { + mpu->state.block_ack=1; + MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); + if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); + } + mpu->condbuf.type=T_OVERFLOW; + } + if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + } + + return ret; +} + +static void mpu401_write(uint16_t addr, uint8_t val, void *p) +{ + mpu_t *mpu = (mpu_t *)p; + + /* pclog("MPU401 Write Port %04X, val %x\n", addr, val); */ + + switch (addr & 1) + { + case 0: /*Data*/ + MPU401_WriteData(mpu, val); + pclog("Write Data (0x330) %X\n", val); + break; + + case 1: /*Command*/ + MPU401_WriteCommand(mpu, val); + pclog("Write Command (0x331) %x\n", val); + break; + } +} + +static uint8_t mpu401_read(uint16_t addr, void *p) +{ + mpu_t *mpu = (mpu_t *)p; + uint8_t ret; + + switch (addr & 1) + { + case 0: //Read Data + ret = MPU401_ReadData(mpu); + pclog("Read Data (0x330) %X\n", ret); + break; + + case 1: //Read Status + ret = 0x3f; /* Bits 6 and 7 clear */ + if (mpu->state.cmd_pending) ret|=STATUS_OUTPUT_NOT_READY; + if (!mpu->queue_used) ret|=STATUS_INPUT_NOT_READY; + pclog("Read Status (0x331) %x\n", ret); + break; + } + /* pclog("MPU401 Read Port %04X, ret %x\n", addr, ret); */ + return ret; +} + + +static void MPU401_Event(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + uint8_t i; + int new_time; + + pclog("MPU-401 event callback\n"); + + if (mpu->mode==M_UART) + { + mpu401_event_callback = 0; + return; + } + if (mpu->state.irq_pending) goto next_event; + for (i=0;i<8;i++) { /* Decrease counters */ + if (mpu->state.amask&(1<playbuf[i].counter--; + if (mpu->playbuf[i].counter<=0) UpdateTrack(mpu, i); + } + } + if (mpu->state.conductor) { + mpu->condbuf.counter--; + if (mpu->condbuf.counter<=0) UpdateConductor(mpu); + } + if (mpu->clock.clock_to_host) { + mpu->clock.cth_counter++; + if (mpu->clock.cth_counter >= mpu->clock.cth_rate) { + mpu->clock.cth_counter=0; + mpu->state.req_mask|=(1<<13); + } + } + if (!mpu->state.irq_pending && mpu->state.req_mask) MPU401_EOIHandler(mpu); +next_event: + /* mpu401_event_callback = 0; */ + new_time = (mpu->clock.tempo * mpu->clock.timebase); + if (new_time == 0) + { + mpu401_event_callback = 0; + return; + } + else + { + mpu401_event_callback += (MPU401_TIMECONSTANT/new_time) * 1000 * TIMER_USEC; + pclog("Next event after %i us (time constant: %i)\n", (int) ((MPU401_TIMECONSTANT/new_time) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); + } +} + +void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) +{ + mpu->status = STATUS_INPUT_NOT_READY; + mpu->irq = irq; + mpu->queue_used = 0; + mpu->queue_pos = 0; + mpu->mode = M_UART; + + mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; + pclog("Starting as %s (mode is %s)\n", mpu->intelligent ? "INTELLIGENT" : "UART", (mode == M_INTELLIGENT) ? "INTELLIGENT" : "UART"); + + mpu401_event_callback = 0; + mpu401_eoi_callback = 0; + mpu401_reset_callback = 0; + + io_sethandler(addr, 0x0002, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(0x2A20, 0x0010, NULL, NULL, NULL, imf_write, NULL, NULL, mpu); + timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); + timer_add(MPU401_EOIHandler, &mpu401_eoi_callback, &mpu401_eoi_callback, mpu); + timer_add(MPU401_ResetDone, &mpu401_reset_callback, &mpu401_reset_callback, mpu); + + MPU401_Reset(mpu); +} diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h new file mode 100644 index 000000000..8cb721883 --- /dev/null +++ b/src/SOUND/snd_mpu401.h @@ -0,0 +1,63 @@ +#define MPU401_VERSION 0x15 +#define MPU401_REVISION 0x01 +#define MPU401_QUEUE 32 +#define MPU401_TIMECONSTANT (60000000/1000.0f) +#define MPU401_RESETBUSY 27.0f + +typedef enum MpuMode { M_UART,M_INTELLIGENT } MpuMode; +typedef enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND} MpuDataType; + +/* Messages sent to MPU-401 from host */ +#define MSG_EOX 0xf7 +#define MSG_OVERFLOW 0xf8 +#define MSG_MARK 0xfc + +/* Messages sent to host from MPU-401 */ +#define MSG_MPU_OVERFLOW 0xf8 +#define MSG_MPU_COMMAND_REQ 0xf9 +#define MSG_MPU_END 0xfc +#define MSG_MPU_CLOCK 0xfd +#define MSG_MPU_ACK 0xfe + +typedef struct mpu_t +{ + int intelligent; + MpuMode mode; + int irq; + uint8_t status; + uint8_t queue[MPU401_QUEUE]; + int queue_pos,queue_used; + struct track + { + int counter; + uint8_t value[8],sys_val; + uint8_t vlength,length; + MpuDataType type; + } playbuf[8],condbuf; + struct { + int conductor,cond_req,cond_set, block_ack; + int playing,reset; + int wsd,wsm,wsd_start; + int run_irq,irq_pending; + int send_now; + int eoi_scheduled; + int data_onoff; + uint32_t command_byte,cmd_pending; + uint8_t tmask,cmask,amask; + uint16_t midi_mask; + uint16_t req_mask; + uint8_t channel,old_chan; + } state; + struct { + uint8_t timebase,old_timebase; + uint8_t tempo,old_tempo; + uint8_t tempo_rel,old_tempo_rel; + uint8_t tempo_grad; + uint8_t cth_rate,cth_counter; + int clock_to_host,cth_active; + } clock; +} mpu_t; + +uint8_t MPU401_ReadData(mpu_t *mpu); + +void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); diff --git a/src/sound_opl.c b/src/SOUND/snd_opl.c similarity index 97% rename from src/sound_opl.c rename to src/SOUND/snd_opl.c index 28647f6dc..d04b7be9a 100644 --- a/src/sound_opl.c +++ b/src/SOUND/snd_opl.c @@ -3,11 +3,13 @@ */ #include #include -#include "ibm.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../timer.h" #include "sound.h" -#include "sound_opl.h" -#include "sound_dbopl.h" +#include "snd_opl.h" +#include "snd_dbopl.h" + /*Interfaces between PCem and the actual OPL emulator*/ diff --git a/src/sound_opl.h b/src/SOUND/snd_opl.h similarity index 100% rename from src/sound_opl.h rename to src/SOUND/snd_opl.h diff --git a/src/sound_pas16.c b/src/SOUND/snd_pas16.c similarity index 99% rename from src/sound_pas16.c rename to src/SOUND/snd_pas16.c index 69c245f5e..e91b7a09a 100644 --- a/src/sound_pas16.c +++ b/src/SOUND/snd_pas16.c @@ -1,17 +1,17 @@ #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "filters.h" -#include "io.h" -#include "pic.h" -#include "pit.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../pit.h" +#include "../dma.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_opl.h" -#include "sound_pas16.h" -#include "sound_sb_dsp.h" -#include "timer.h" +#include "snd_opl.h" +#include "snd_pas16.h" +#include "snd_sb_dsp.h" +#include "filters.h" + /* Original PAS uses 2 x OPL2 diff --git a/src/sound_pas16.h b/src/SOUND/snd_pas16.h similarity index 100% rename from src/sound_pas16.h rename to src/SOUND/snd_pas16.h diff --git a/src/sound_ps1.c b/src/SOUND/snd_ps1.c similarity index 96% rename from src/sound_ps1.c rename to src/SOUND/snd_ps1.c index 6c2498e7e..85334101a 100644 --- a/src/sound_ps1.c +++ b/src/SOUND/snd_ps1.c @@ -1,11 +1,13 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_ps1.h" -#include "sound_sn76489.h" +#include "snd_ps1.h" +#include "snd_sn76489.h" + typedef struct ps1_audio_t { diff --git a/src/sound_ps1.h b/src/SOUND/snd_ps1.h similarity index 100% rename from src/sound_ps1.h rename to src/SOUND/snd_ps1.h diff --git a/src/sound_pssj.c b/src/SOUND/snd_pssj.c similarity index 97% rename from src/sound_pssj.c rename to src/SOUND/snd_pssj.c index bda1442fd..dc52aee46 100644 --- a/src/sound_pssj.c +++ b/src/SOUND/snd_pssj.c @@ -1,14 +1,14 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../dma.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_pssj.h" -#include "sound_sn76489.h" +#include "snd_pssj.h" +#include "snd_sn76489.h" -#include "dma.h" -#include "pic.h" -#include "timer.h" typedef struct pssj_t { diff --git a/src/sound_pssj.h b/src/SOUND/snd_pssj.h similarity index 100% rename from src/sound_pssj.h rename to src/SOUND/snd_pssj.h diff --git a/src/sound_resid.cc b/src/SOUND/snd_resid.cc similarity index 98% rename from src/sound_resid.cc rename to src/SOUND/snd_resid.cc index 8185b6046..ef1d32854 100644 --- a/src/sound_resid.cc +++ b/src/SOUND/snd_resid.cc @@ -3,7 +3,8 @@ #include #include #include "resid-fp/sid.h" -#include "sound_resid.h" +#include "snd_resid.h" + typedef struct psid_t { @@ -12,9 +13,11 @@ typedef struct psid_t int16_t last_sample; } psid_t; + psid_t *psid; -void *sid_init() + +void *sid_init(void) { // psid_t *psid; int c; diff --git a/src/sound_resid.h b/src/SOUND/snd_resid.h similarity index 100% rename from src/sound_resid.h rename to src/SOUND/snd_resid.h diff --git a/src/sound_sb.c b/src/SOUND/snd_sb.c similarity index 92% rename from src/sound_sb.c rename to src/SOUND/snd_sb.c index d29f5028e..d1471ee34 100644 --- a/src/sound_sb.c +++ b/src/SOUND/snd_sb.c @@ -1,19 +1,19 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mca.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mca.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "sound.h" -#include "sound_emu8k.h" -#include "sound_mpu401_uart.h" -#include "sound_opl.h" -#include "sound_sb.h" -#include "sound_sb_dsp.h" - +#include "snd_emu8k.h" +#include "snd_mpu401.h" +#include "snd_opl.h" +#include "snd_sb.h" +#include "snd_sb_dsp.h" #include "filters.h" + typedef struct sb_mixer_t { int master_l, master_r; @@ -33,7 +33,7 @@ typedef struct sb_t opl_t opl; sb_dsp_t dsp; sb_mixer_t mixer; - mpu401_uart_t mpu; + mpu_t mpu; emu8k_t emu8k; int pos; @@ -631,7 +631,7 @@ void *sb_16_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); - mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); + mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); sb->mixer.regs[0x30] = 31 << 3; sb->mixer.regs[0x31] = 31 << 3; @@ -655,7 +655,7 @@ void *sb_16_init() int sb_awe32_available() { - return rom_present("roms/awe32.raw"); + return rom_present(L"roms/awe32.raw"); } void *sb_awe32_init() @@ -677,7 +677,7 @@ void *sb_awe32_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); + mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); emu8k_init(&sb->emu8k, onboard_ram); sb->mixer.regs[0x30] = 31 << 3; @@ -780,6 +780,9 @@ static device_config_t sb_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -818,6 +821,9 @@ static device_config_t sb_mcv_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -873,6 +879,9 @@ static device_config_t sb_pro_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -934,6 +943,32 @@ static device_config_t sb_16_config[] = } } }, + { + "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { @@ -971,6 +1006,20 @@ static device_config_t sb_16_config[] = { "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, + { + "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, { "", "", -1 } @@ -1032,6 +1081,32 @@ static device_config_t sb_awe32_config[] = } } }, + { + "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { @@ -1069,6 +1144,20 @@ static device_config_t sb_awe32_config[] = { "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, + { + "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, { diff --git a/src/sound_sb.h b/src/SOUND/snd_sb.h similarity index 100% rename from src/sound_sb.h rename to src/SOUND/snd_sb.h diff --git a/src/sound_sb_dsp.c b/src/SOUND/snd_sb_dsp.c similarity index 98% rename from src/sound_sb_dsp.c rename to src/SOUND/snd_sb_dsp.c index 13298d446..92f7cacd0 100644 --- a/src/sound_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -3,24 +3,24 @@ 486-33 - 20kHz 486-50 - 32kHz Pentium - 45kHz*/ - #include #include -#include "ibm.h" - - -#include "dma.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../plat-midi.h" +#include "../timer.h" #include "sound.h" -#include "sound_sb_dsp.h" -#include "timer.h" +#include "snd_mpu401.h" +#include "snd_sb_dsp.h" + +mpu_t mpu; void pollsb(void *p); void sb_poll_i(void *p); - static int sbe2dat[4][9] = { { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, @@ -324,6 +324,29 @@ void sb_exec_command(sb_dsp_t *dsp) temp = 1000000 / temp; dsp->sb_freq = temp; break; + + case 0x30: + case 0x31: + break; + + case 0x34: + dsp->uart_midi = 1; + dsp->uart_irq = 0; + break; + + case 0x35: + dsp->uart_midi = 1; + dsp->uart_irq = 1; + break; + + case 0x36: + case 0x37: + break; + + case 0x38: + dsp->onebyte_midi = 1; + break; + case 0x41: /*Set output sampling rate*/ case 0x42: /*Set input sampling rate*/ if (dsp->sb_type < SB16) break; @@ -517,6 +540,12 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; return; case 0xC: /*Command/data write*/ + if (dsp->uart_midi || dsp->onebyte_midi) + { + midi_write(v); + dsp->onebyte_midi = 0; + return; + } timer_process(); dsp->wb_time = TIMER_USEC * 1; dsp->wb_full = 1; @@ -552,6 +581,10 @@ uint8_t sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0xA: /*Read data*/ + if (dsp->uart_midi) + { + return MPU401_ReadData(&mpu); + } dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; if (dsp->sb_read_rp != dsp->sb_read_wp) { diff --git a/src/sound_sb_dsp.h b/src/SOUND/snd_sb_dsp.h similarity index 96% rename from src/sound_sb_dsp.h rename to src/SOUND/snd_sb_dsp.h index 9d4dee133..fb14284fa 100644 --- a/src/sound_sb_dsp.h +++ b/src/SOUND/snd_sb_dsp.h @@ -1,5 +1,9 @@ typedef struct sb_dsp_t -{ +{ + int uart_midi; + int uart_irq; + int onebyte_midi; + int sb_type; int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; diff --git a/src/sound_sn76489.c b/src/SOUND/snd_sn76489.c similarity index 99% rename from src/sound_sn76489.c rename to src/SOUND/snd_sn76489.c index 7d6fe80a1..574769322 100644 --- a/src/sound_sn76489.c +++ b/src/SOUND/snd_sn76489.c @@ -1,13 +1,15 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" -#include "sound_sn76489.h" +#include "snd_sn76489.h" + int sn76489_mute; + static float volslog[16]= { 0.00000f,0.59715f,0.75180f,0.94650f, diff --git a/src/sound_sn76489.h b/src/SOUND/snd_sn76489.h similarity index 100% rename from src/sound_sn76489.h rename to src/SOUND/snd_sn76489.h diff --git a/src/sound_speaker.c b/src/SOUND/snd_speaker.c similarity index 93% rename from src/sound_speaker.c rename to src/SOUND/snd_speaker.c index f4bc7086d..25344d922 100644 --- a/src/sound_speaker.c +++ b/src/SOUND/snd_speaker.c @@ -1,17 +1,18 @@ -#include "ibm.h" +#include "../ibm.h" #include "sound.h" -#include "sound_speaker.h" +#include "snd_speaker.h" + int speaker_mute = 0; - -static int16_t speaker_buffer[SOUNDBUFLEN]; - -static int speaker_pos = 0; - int speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; -void speaker_update() + +static int16_t speaker_buffer[SOUNDBUFLEN]; +static int speaker_pos = 0; + + +void speaker_update(void) { int16_t val; @@ -51,7 +52,8 @@ static void speaker_get_buffer(int32_t *buffer, int len, void *p) speaker_pos = 0; } -void speaker_init() + +void speaker_init(void) { sound_add_handler(speaker_get_buffer, NULL); speaker_mute = 0; diff --git a/src/sound_speaker.h b/src/SOUND/snd_speaker.h similarity index 100% rename from src/sound_speaker.h rename to src/SOUND/snd_speaker.h diff --git a/src/sound_ssi2001.c b/src/SOUND/snd_ssi2001.c similarity index 94% rename from src/sound_ssi2001.c rename to src/SOUND/snd_ssi2001.c index d0a7e2136..d42898b9d 100644 --- a/src/sound_ssi2001.c +++ b/src/SOUND/snd_ssi2001.c @@ -1,11 +1,11 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" +#include "snd_resid.h" +#include "snd_ssi2001.h" -#include "sound_resid.h" -#include "sound_ssi2001.h" typedef struct ssi2001_t { diff --git a/src/sound_ssi2001.h b/src/SOUND/snd_ssi2001.h similarity index 100% rename from src/sound_ssi2001.h rename to src/SOUND/snd_ssi2001.h diff --git a/src/sound_wss.c b/src/SOUND/snd_wss.c similarity index 93% rename from src/sound_wss.c rename to src/SOUND/snd_wss.c index f8a5bcbd6..a58bc0b64 100644 --- a/src/sound_wss.c +++ b/src/SOUND/snd_wss.c @@ -2,18 +2,18 @@ Windows Sound System emulation*/ -#include #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "io.h" -#include "pic.h" +#include +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../device.h" #include "sound.h" -#include "sound_ad1848.h" -#include "sound_opl.h" -#include "sound_wss.h" +#include "snd_ad1848.h" +#include "snd_opl.h" +#include "snd_wss.h" + /*530, 11, 3 - 530=23*/ /*530, 11, 1 - 530=22*/ @@ -29,6 +29,7 @@ static int wss_dma[4] = {0, 0, 1, 3}; static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/ + typedef struct wss_t { uint8_t config; diff --git a/src/sound_wss.h b/src/SOUND/snd_wss.h similarity index 100% rename from src/sound_wss.h rename to src/SOUND/snd_wss.h diff --git a/src/sound_ym7128.c b/src/SOUND/snd_ym7128.c similarity index 99% rename from src/sound_ym7128.c rename to src/SOUND/snd_ym7128.c index be0b3946c..4bea44f53 100644 --- a/src/sound_ym7128.c +++ b/src/SOUND/snd_ym7128.c @@ -1,9 +1,11 @@ -#include "ibm.h" -#include "sound_ym7128.h" +#include "../ibm.h" +#include "snd_ym7128.h" + static int attenuation[32]; static int tap_position[32]; + void ym7128_init(ym7128_t *ym7128) { int c; diff --git a/src/sound_ym7128.h b/src/SOUND/snd_ym7128.h similarity index 100% rename from src/sound_ym7128.h rename to src/SOUND/snd_ym7128.h diff --git a/src/sound.c b/src/SOUND/sound.c similarity index 90% rename from src/sound.c rename to src/SOUND/sound.c index a00f7f9ca..aa4c944bd 100644 --- a/src/sound.c +++ b/src/SOUND/sound.c @@ -1,30 +1,26 @@ #include #include #include - -#include "cdrom.h" -#include "ibm.h" - -#include "device.h" - +#include "../ibm.h" +#include "../device.h" +#include "../timer.h" +#include "../thread.h" +#include "../cdrom.h" +#include "sound.h" +#include "snd_opl.h" +#include "snd_adlib.h" +#include "snd_adlibgold.h" +#include "snd_pas16.h" +#include "snd_sb.h" +#include "snd_sb_dsp.h" +#include "snd_wss.h" #include "filters.h" -#include "sound_opl.h" - -#include "sound.h" -#include "sound_adlib.h" -#include "sound_adlibgold.h" -#include "sound_pas16.h" -#include "sound_sb.h" -#include "sound_sb_dsp.h" -#include "sound_wss.h" - -#include "timer.h" -#include "thread.h" int sound_card_current = 0; static int sound_card_last = 0; + typedef struct { char name[64]; @@ -274,7 +270,6 @@ void sound_poll(void *priv) if (sound_pos_global == SOUNDBUFLEN) { int c; -/* int16_t buf16[SOUNDBUFLEN * 2 ];*/ memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int32_t)); @@ -282,19 +277,6 @@ void sound_poll(void *priv) sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); -/* for (c=0;c 32767) - buf16[c] = 32767; - else - buf16[c] = outbuffer[c]; - } - - if (!soundf) soundf=fopen("sound.pcm","wb"); - fwrite(buf16,(SOUNDBUFLEN)*2*2,1,soundf);*/ - for (c = 0; c < SOUNDBUFLEN * 2; c++) { outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; diff --git a/src/sound.h b/src/SOUND/sound.h similarity index 97% rename from src/sound.h rename to src/SOUND/sound.h index 23eea439e..ffa9d87af 100644 --- a/src/sound.h +++ b/src/SOUND/sound.h @@ -1,5 +1,3 @@ -#include "timer.h" - void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p); extern int sound_card_current; diff --git a/src/vid_ati18800.c b/src/VIDEO/vid_ati18800.c similarity index 95% rename from src/vid_ati18800.c rename to src/VIDEO/vid_ati18800.c index 068d2bcd5..ecbb4fe40 100644 --- a/src/vid_ati18800.c +++ b/src/VIDEO/vid_ati18800.c @@ -3,16 +3,17 @@ */ /*ATI 18800 emulation (VGA Edge-16)*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" + typedef struct ati18800_t { svga_t svga; @@ -162,7 +163,7 @@ void *ati18800_init() ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); - rom_init(&ati18800->bios_rom, "roms/vga88.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati18800->bios_rom, L"roms/vga88.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ NULL, @@ -175,14 +176,14 @@ void *ati18800_init() ati18800->svga.miscout = 1; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, L"ati18800.nvr", 0); return ati18800; } static int ati18800_available() { - return rom_present("roms/vga88.BIN"); + return rom_present(L"roms/vga88.BIN"); } void ati18800_close(void *p) diff --git a/src/vid_ati18800.h b/src/VIDEO/vid_ati18800.h similarity index 100% rename from src/vid_ati18800.h rename to src/VIDEO/vid_ati18800.h diff --git a/src/vid_ati28800.c b/src/VIDEO/vid_ati28800.c similarity index 96% rename from src/vid_ati28800.c rename to src/VIDEO/vid_ati28800.c index 821185883..84d8ec8e4 100644 --- a/src/vid_ati28800.c +++ b/src/VIDEO/vid_ati28800.c @@ -3,17 +3,18 @@ */ /*ATI 28800 emulation (VGA Charger)*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" +#include "../timer.h" #include "video.h" #include "vid_ati28800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "timer.h" + typedef struct ati28800_t { @@ -361,19 +362,19 @@ void *ati28800_init() if (gfxcard == GFX_VGAWONDERXL) { rom_init_interleaved(&ati28800->bios_rom, - "roms/XLEVEN.BIN", - "roms/XLODD.BIN", + L"roms/XLEVEN.BIN", + L"roms/XLODD.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); } else if (gfxcard == GFX_VGAWONDERXL24) { rom_init_interleaved(&ati28800->bios_rom, - "roms/112-14318-102.bin", - "roms/112-14319-102.bin", + L"roms/112-14318-102.bin", + L"roms/112-14319-102.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); } else - rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati28800->bios_rom, L"roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati28800->svga, ati28800, memory, /*512kb*/ ati28800_recalctimings, @@ -386,24 +387,24 @@ void *ati28800_init() ati28800->svga.miscout = 1; - ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, L"ati28800.nvr", 0); return ati28800; } static int ati28800_available() { - return rom_present("roms/bios.bin"); + return rom_present(L"roms/bios.bin"); } static int compaq_ati28800_available() { - return (rom_present("roms/XLEVEN.bin") && rom_present("roms/XLODD.bin")); + return (rom_present(L"roms/XLEVEN.bin") && rom_present(L"roms/XLODD.bin")); } static int ati28800_wonderxl24_available() { - return (rom_present("roms/112-14318-102.bin") && rom_present("roms/112-14319-102.bin")); + return (rom_present(L"roms/112-14318-102.bin") && rom_present(L"roms/112-14319-102.bin")); } void ati28800_close(void *p) diff --git a/src/vid_ati28800.h b/src/VIDEO/vid_ati28800.h similarity index 100% rename from src/vid_ati28800.h rename to src/VIDEO/vid_ati28800.h diff --git a/src/vid_ati68860_ramdac.c b/src/VIDEO/vid_ati68860_ramdac.c similarity index 99% rename from src/vid_ati68860_ramdac.c rename to src/VIDEO/vid_ati68860_ramdac.c index a8c2f132d..f1d1d6b84 100644 --- a/src/vid_ati68860_ramdac.c +++ b/src/VIDEO/vid_ati68860_ramdac.c @@ -21,13 +21,14 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT 5-6 Always set ? 7 If set can remove "snow" in some cases (A860_Delay_L ?) ?? */ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_ati68860_ramdac.h" #include "vid_svga_render.h" + void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { switch (addr) diff --git a/src/vid_ati68860_ramdac.h b/src/VIDEO/vid_ati68860_ramdac.h similarity index 100% rename from src/vid_ati68860_ramdac.h rename to src/VIDEO/vid_ati68860_ramdac.h diff --git a/src/vid_ati_eeprom.c b/src/VIDEO/vid_ati_eeprom.c similarity index 97% rename from src/vid_ati_eeprom.c rename to src/VIDEO/vid_ati_eeprom.c index ffc2a04d8..198575a60 100644 --- a/src/vid_ati_eeprom.c +++ b/src/VIDEO/vid_ati_eeprom.c @@ -1,9 +1,12 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" +#include "../rom.h" #include "vid_ati_eeprom.h" + enum { EEPROM_IDLE, @@ -31,12 +34,12 @@ enum EEPROM_OP_EWEN = 3 }; -void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) +void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type) { FILE *f; eeprom->type = type; - strcpy(eeprom->fn, fn); - f = romfopen(eeprom->fn, "rb"); + wcscpy(eeprom->fn, fn); + f = nvrfopen(eeprom->fn, L"rb"); if (!f) { memset(eeprom->data, 0, eeprom->type ? 512 : 128); @@ -48,7 +51,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) void ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = romfopen(eeprom->fn, "wb"); + FILE *f = nvrfopen(eeprom->fn, L"wb"); if (!f) return; fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(f); diff --git a/src/vid_ati_eeprom.h b/src/VIDEO/vid_ati_eeprom.h similarity index 80% rename from src/vid_ati_eeprom.h rename to src/VIDEO/vid_ati_eeprom.h index 540f2c3f9..786ae0c8b 100644 --- a/src/vid_ati_eeprom.h +++ b/src/VIDEO/vid_ati_eeprom.h @@ -11,9 +11,9 @@ typedef struct ati_eeprom_t uint32_t dat; int type; - char fn[256]; + wchar_t fn[256]; } ati_eeprom_t; -void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); +void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c similarity index 99% rename from src/vid_ati_mach64.c rename to src/VIDEO/vid_ati_mach64.c index 46d7f53a7..12bbf2383 100644 --- a/src/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -1,12 +1,12 @@ /*ATI Mach64 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../thread.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -14,6 +14,7 @@ #include "vid_ati_eeprom.h" #include "vid_ics2595.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) @@ -3293,9 +3294,9 @@ static void *mach64gx_init() else mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); - rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, L"roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return mach64; } @@ -3310,9 +3311,9 @@ static void *mach64vt2_init() mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ mach64->config_stat0 = 4; - ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); + ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); - rom_init(&mach64->bios_rom, "roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, L"roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga->vblank_start = mach64_vblank_start; @@ -3321,12 +3322,12 @@ static void *mach64vt2_init() int mach64gx_available() { - return rom_present("roms/mach64gx/bios.bin"); + return rom_present(L"roms/mach64gx/bios.bin"); } int mach64vt2_available() { - return rom_present("roms/atimach64vt2pci.bin"); + return rom_present(L"roms/atimach64vt2pci.bin"); } void mach64_close(void *p) diff --git a/src/vid_ati_mach64.h b/src/VIDEO/vid_ati_mach64.h similarity index 100% rename from src/vid_ati_mach64.h rename to src/VIDEO/vid_ati_mach64.h diff --git a/src/vid_bt485_ramdac.c b/src/VIDEO/vid_bt485_ramdac.c similarity index 99% rename from src/vid_bt485_ramdac.c rename to src/VIDEO/vid_bt485_ramdac.c index 57848a128..e11f69132 100644 --- a/src/vid_bt485_ramdac.c +++ b/src/VIDEO/vid_bt485_ramdac.c @@ -3,12 +3,13 @@ */ /*Brooktree BT485 true colour RAMDAC emulation*/ /*Currently only a dummy stub for logging and passing output to the generic SVGA handler*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_bt485_ramdac.h" + int bt485_get_clock_divider(bt485_ramdac_t *ramdac) { return 1; /* Will be implemented later. */ diff --git a/src/vid_bt485_ramdac.h b/src/VIDEO/vid_bt485_ramdac.h similarity index 100% rename from src/vid_bt485_ramdac.h rename to src/VIDEO/vid_bt485_ramdac.h diff --git a/src/vid_cga.c b/src/VIDEO/vid_cga.c similarity index 99% rename from src/vid_cga.c rename to src/VIDEO/vid_cga.c index a665e45d9..41553f671 100644 --- a/src/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -4,18 +4,19 @@ /*CGA emulation*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + #define CGA_RGB 0 #define CGA_COMPOSITE 1 @@ -468,7 +469,7 @@ void *cga_standalone_init() cga_comp_init(cga->revision); timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); overscan_x = overscan_y = 16; diff --git a/src/vid_cga.h b/src/VIDEO/vid_cga.h similarity index 100% rename from src/vid_cga.h rename to src/VIDEO/vid_cga.h diff --git a/src/dosbox/vid_cga_comp.c b/src/VIDEO/vid_cga_comp.c similarity index 99% rename from src/dosbox/vid_cga_comp.c rename to src/VIDEO/vid_cga_comp.c index 63e54cdad..a63d69f2e 100644 --- a/src/dosbox/vid_cga_comp.c +++ b/src/VIDEO/vid_cga_comp.c @@ -8,11 +8,13 @@ #include "../ibm.h" #include "../device.h" #include "../mem.h" -#include "../vid_cga.h" +#include "vid_cga.h" #include "vid_cga_comp.h" + int CGA_Composite_Table[1024]; + static double brightness = 0; static double contrast = 100; static double saturation = 100; diff --git a/src/dosbox/vid_cga_comp.h b/src/VIDEO/vid_cga_comp.h similarity index 100% rename from src/dosbox/vid_cga_comp.h rename to src/VIDEO/vid_cga_comp.h diff --git a/src/vid_cl5429.h b/src/VIDEO/vid_cl5429.h similarity index 100% rename from src/vid_cl5429.h rename to src/VIDEO/vid_cl5429.h diff --git a/src/vid_cl_gd.c b/src/VIDEO/vid_cl_gd.c similarity index 95% rename from src/vid_cl_gd.c rename to src/VIDEO/vid_cl_gd.c index 7c0899a95..89d9d3c77 100644 --- a/src/vid_cl_gd.c +++ b/src/VIDEO/vid_cl_gd.c @@ -1,10 +1,10 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -12,6 +12,7 @@ #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + void cirrus_update_bank_ptr(clgd_t *clgd, uint8_t bank_index); void clgd_recalctimings(svga_t *svga); @@ -806,7 +807,7 @@ uint8_t cirrus_read(uint32_t addr, void *p) return ret; } -void *clgd_common_init(char *romfn, uint8_t id) +void *clgd_common_init(wchar_t *romfn, uint8_t id) { clgd = malloc(sizeof(clgd_t)); svga_t *svga = &clgd->svga; @@ -880,92 +881,92 @@ void *clgd_common_init(char *romfn, uint8_t id) void *gd6235_init() { - return clgd_common_init("roms/vga6235.rom", CIRRUS_ID_CLGD6235); + return clgd_common_init(L"roms/vga6235.rom", CIRRUS_ID_CLGD6235); } void *gd5422_init() { - return clgd_common_init("roms/CL5422.ROM", CIRRUS_ID_CLGD5422); + return clgd_common_init(L"roms/CL5422.ROM", CIRRUS_ID_CLGD5422); } void *gd5429_init() { - return clgd_common_init("roms/5429.vbi", CIRRUS_ID_CLGD5429); + return clgd_common_init(L"roms/5429.vbi", CIRRUS_ID_CLGD5429); } void *gd5430_init() { - return clgd_common_init("roms/pci.BIN", CIRRUS_ID_CLGD5430); + return clgd_common_init(L"roms/pci.BIN", CIRRUS_ID_CLGD5430); } void *dia5430_init() { - return clgd_common_init("roms/diamondvlbus.BIN", CIRRUS_ID_CLGD5430); + return clgd_common_init(L"roms/diamondvlbus.BIN", CIRRUS_ID_CLGD5430); } void *gd5434_init() { - return clgd_common_init("roms/japan.BIN", CIRRUS_ID_CLGD5434); + return clgd_common_init(L"roms/japan.BIN", CIRRUS_ID_CLGD5434); } void *gd5436_init() { - return clgd_common_init("roms/5436.VBI", CIRRUS_ID_CLGD5436); + return clgd_common_init(L"roms/5436.VBI", CIRRUS_ID_CLGD5436); } void *gd5440_init() { - return clgd_common_init("roms/5440BIOS.BIN", CIRRUS_ID_CLGD5440); + return clgd_common_init(L"roms/5440BIOS.BIN", CIRRUS_ID_CLGD5440); } void *gd5446_init() { - return clgd_common_init("roms/5446BV.VBI", CIRRUS_ID_CLGD5446); + return clgd_common_init(L"roms/5446BV.VBI", CIRRUS_ID_CLGD5446); } static int gd5422_available() { - return rom_present("roms/CL5422.ROM"); + return rom_present(L"roms/CL5422.ROM"); } static int gd5429_available() { - return rom_present("roms/5429.vbi"); + return rom_present(L"roms/5429.vbi"); } static int gd5430_available() { - return rom_present("roms/pci.BIN"); + return rom_present(L"roms/pci.BIN"); } static int dia5430_available() { - return rom_present("roms/diamondvlbus.BIN"); + return rom_present(L"roms/diamondvlbus.BIN"); } static int gd5434_available() { - return rom_present("roms/japan.BIN"); + return rom_present(L"roms/japan.BIN"); } static int gd5436_available() { - return rom_present("roms/5436.VBI"); + return rom_present(L"roms/5436.VBI"); } static int gd5440_available() { - return rom_present("roms/5440BIOS.BIN"); + return rom_present(L"roms/5440BIOS.BIN"); } static int gd5446_available() { - return rom_present("roms/5446BV.VBI"); + return rom_present(L"roms/5446BV.VBI"); } static int gd6235_available() { - return rom_present("roms/vga6235.rom"); + return rom_present(L"roms/vga6235.rom"); } void clgd_close(void *p) @@ -1113,4 +1114,4 @@ device_t gd6235_device = clgd_speed_changed, clgd_force_redraw, clgd_add_status_info -}; \ No newline at end of file +}; diff --git a/src/vid_cl_gd.h b/src/VIDEO/vid_cl_gd.h similarity index 100% rename from src/vid_cl_gd.h rename to src/VIDEO/vid_cl_gd.h diff --git a/src/vid_cl_gd_blit.c b/src/VIDEO/vid_cl_gd_blit.c similarity index 99% rename from src/vid_cl_gd_blit.c rename to src/VIDEO/vid_cl_gd_blit.c index b312f0012..18d6642f3 100644 --- a/src/vid_cl_gd_blit.c +++ b/src/VIDEO/vid_cl_gd_blit.c @@ -1,10 +1,10 @@ /*This is the CL-GD 5446 blitter, directly from QEMU*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -12,6 +12,7 @@ #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + // Same for all the svga->vrammask which are -s>cirrus_addr_mask in the original. // Eventually this needs to be configurable diff --git a/src/vid_cl_gd_blit.h b/src/VIDEO/vid_cl_gd_blit.h similarity index 100% rename from src/vid_cl_gd_blit.h rename to src/VIDEO/vid_cl_gd_blit.h diff --git a/src/vid_cl_gd_vga_rop.h b/src/VIDEO/vid_cl_gd_vga_rop.h similarity index 100% rename from src/vid_cl_gd_vga_rop.h rename to src/VIDEO/vid_cl_gd_vga_rop.h diff --git a/src/vid_cl_gd_vga_rop2.h b/src/VIDEO/vid_cl_gd_vga_rop2.h similarity index 100% rename from src/vid_cl_gd_vga_rop2.h rename to src/VIDEO/vid_cl_gd_vga_rop2.h diff --git a/src/vid_cl_ramdac.c b/src/VIDEO/vid_cl_ramdac.c similarity index 97% rename from src/vid_cl_ramdac.c rename to src/VIDEO/vid_cl_ramdac.c index 2520038ea..340d27c88 100644 --- a/src/vid_cl_ramdac.c +++ b/src/VIDEO/vid_cl_ramdac.c @@ -1,13 +1,14 @@ -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_cl_ramdac.h" #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + void cl_ramdac_out(uint16_t addr, uint8_t val, cl_ramdac_t *ramdac, void *clgd, svga_t *svga) { clgd_t *real_clgd = (clgd_t *) clgd; @@ -97,4 +98,4 @@ uint8_t cl_ramdac_in(uint16_t addr, cl_ramdac_t *ramdac, void *clgd, svga_t *svg break; } return svga_in(addr, svga); -} \ No newline at end of file +} diff --git a/src/vid_cl_ramdac.h b/src/VIDEO/vid_cl_ramdac.h similarity index 100% rename from src/vid_cl_ramdac.h rename to src/VIDEO/vid_cl_ramdac.h diff --git a/src/vid_colorplus.c b/src/VIDEO/vid_colorplus.c similarity index 99% rename from src/vid_colorplus.c rename to src/VIDEO/vid_colorplus.c index 13a661b04..ab07127f7 100644 --- a/src/vid_colorplus.c +++ b/src/VIDEO/vid_colorplus.c @@ -1,15 +1,16 @@ /*Plantronics ColorPlus emulation*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_colorplus.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" + /* Bits in the colorplus control register: */ #define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ @@ -378,7 +379,7 @@ void *colorplus_standalone_init() cga_comp_init(1); timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus); + mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); return colorplus; diff --git a/src/vid_colorplus.h b/src/VIDEO/vid_colorplus.h similarity index 100% rename from src/vid_colorplus.h rename to src/VIDEO/vid_colorplus.h diff --git a/src/vid_ega.c b/src/VIDEO/vid_ega.c similarity index 98% rename from src/vid_ega.c rename to src/VIDEO/vid_ega.c index 2e98235d3..d97f13ba1 100644 --- a/src/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -1,14 +1,15 @@ /*EGA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_ega.h" + extern uint8_t edatlookup[4][4]; static uint8_t ega_rotate[8][256]; @@ -900,7 +901,7 @@ void *ega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -924,7 +925,7 @@ void *ega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -938,7 +939,7 @@ void *cpqega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/108281-001.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/108281-001.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -960,7 +961,7 @@ void *cpqega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -974,7 +975,7 @@ void *sega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/lega.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/lega.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -996,7 +997,7 @@ void *sega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -1004,17 +1005,17 @@ void *sega_standalone_init() static int ega_standalone_available() { - return rom_present("roms/ibm_6277356_ega_card_u44_27128.bin"); + return rom_present(L"roms/ibm_6277356_ega_card_u44_27128.bin"); } static int cpqega_standalone_available() { - return rom_present("roms/108281-001.bin"); + return rom_present(L"roms/108281-001.bin"); } static int sega_standalone_available() { - return rom_present("roms/lega.vbi"); + return rom_present(L"roms/lega.vbi"); } void ega_close(void *p) diff --git a/src/vid_ega.h b/src/VIDEO/vid_ega.h similarity index 100% rename from src/vid_ega.h rename to src/VIDEO/vid_ega.h diff --git a/src/vid_et4000.c b/src/VIDEO/vid_et4000.c similarity index 95% rename from src/vid_et4000.c rename to src/VIDEO/vid_et4000.c index ca845982b..9ee0255a6 100644 --- a/src/vid_et4000.c +++ b/src/VIDEO/vid_et4000.c @@ -3,17 +3,17 @@ */ /*ET4000 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" - #include "vid_et4000.h" + typedef struct et4000_t { svga_t svga; @@ -144,7 +144,7 @@ void *et4000_init() et4000_t *et4000 = malloc(sizeof(et4000_t)); memset(et4000, 0, sizeof(et4000_t)); - rom_init(&et4000->bios_rom, "roms/et4000.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, L"roms/et4000.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); @@ -159,7 +159,7 @@ void *et4000_init() static int et4000_available() { - return rom_present("roms/et4000.BIN"); + return rom_present(L"roms/et4000.BIN"); } void et4000_close(void *p) diff --git a/src/vid_et4000.h b/src/VIDEO/vid_et4000.h similarity index 100% rename from src/vid_et4000.h rename to src/VIDEO/vid_et4000.h diff --git a/src/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c similarity index 99% rename from src/vid_et4000w32.c rename to src/VIDEO/vid_et4000w32.c index bac8c5fa7..69b21af50 100644 --- a/src/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -4,18 +4,19 @@ - Accelerator doesn't work in planar modes */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_svga.h" #include "vid_icd2061.h" #include "vid_stg_ramdac.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) @@ -1160,7 +1161,7 @@ void *et4000w32p_init() et4000w32p_hwcursor_draw, NULL); - rom_init(&et4000->bios_rom, "roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, L"roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&et4000->bios_rom.mapping); @@ -1195,7 +1196,7 @@ void *et4000w32p_init() int et4000w32p_available() { - return rom_present("roms/et4000w32.bin"); + return rom_present(L"roms/et4000w32.bin"); } void et4000w32p_close(void *p) diff --git a/src/vid_et4000w32.h b/src/VIDEO/vid_et4000w32.h similarity index 100% rename from src/vid_et4000w32.h rename to src/VIDEO/vid_et4000w32.h diff --git a/src/vid_et4000w32i.c b/src/VIDEO/vid_et4000w32i.c similarity index 100% rename from src/vid_et4000w32i.c rename to src/VIDEO/vid_et4000w32i.c diff --git a/src/vid_genius.c b/src/VIDEO/vid_genius.c similarity index 98% rename from src/vid_genius.c rename to src/VIDEO/vid_genius.c index bc9ca6e1c..35db8905f 100644 --- a/src/vid_genius.c +++ b/src/VIDEO/vid_genius.c @@ -1,19 +1,20 @@ /* MDSI Genius VHR emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_genius.h" + #define GENIUS_XSIZE 728 #define GENIUS_YSIZE 1008 + void updatewindowsize(int x, int y); -void loadfont(char *s, int format); extern uint8_t fontdat8x12[256][16]; @@ -561,7 +562,7 @@ void *genius_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); @@ -606,7 +607,7 @@ void genius_close(void *p) static int genius_available() { - return rom_present("roms/8x12.bin"); + return rom_present(L"roms/8x12.bin"); } void genius_speed_changed(void *p) diff --git a/src/vid_genius.h b/src/VIDEO/vid_genius.h similarity index 100% rename from src/vid_genius.h rename to src/VIDEO/vid_genius.h diff --git a/src/vid_hercules.c b/src/VIDEO/vid_hercules.c similarity index 98% rename from src/vid_hercules.c rename to src/VIDEO/vid_hercules.c index 4a9606b32..a7c5ab73a 100644 --- a/src/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -3,17 +3,18 @@ */ /*Hercules emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../mem.h" +#include "../io.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_hercules.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + typedef struct hercules_t { mem_mapping_t mapping; @@ -319,7 +320,7 @@ void *hercules_init() hercules->vram = malloc(0x10000); timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, 0, hercules); + mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules); io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); for (c = 0; c < 256; c++) diff --git a/src/vid_hercules.h b/src/VIDEO/vid_hercules.h similarity index 100% rename from src/vid_hercules.h rename to src/VIDEO/vid_hercules.h diff --git a/src/vid_herculesplus.c b/src/VIDEO/vid_herculesplus.c similarity index 99% rename from src/vid_herculesplus.c rename to src/VIDEO/vid_herculesplus.c index 7af5d4a9c..459107d03 100644 --- a/src/vid_herculesplus.c +++ b/src/VIDEO/vid_herculesplus.c @@ -4,11 +4,11 @@ /*Hercules InColor emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_herculesplus.h" @@ -667,7 +667,7 @@ void *herculesplus_init() herculesplus->vram = malloc(0x10000); /* 64k VRAM */ timer_add(herculesplus_poll, &herculesplus->vidtime, TIMER_ALWAYS_ENABLED, herculesplus); - mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, 0, herculesplus); + mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, herculesplus); io_sethandler(0x03b0, 0x0010, herculesplus_in, NULL, NULL, herculesplus_out, NULL, NULL, herculesplus); for (c = 0; c < 256; c++) diff --git a/src/vid_herculesplus.h b/src/VIDEO/vid_herculesplus.h similarity index 100% rename from src/vid_herculesplus.h rename to src/VIDEO/vid_herculesplus.h diff --git a/src/vid_icd2061.c b/src/VIDEO/vid_icd2061.c similarity index 99% rename from src/vid_icd2061.c rename to src/VIDEO/vid_icd2061.c index bc75d4999..04c2db166 100644 --- a/src/vid_icd2061.c +++ b/src/VIDEO/vid_icd2061.c @@ -5,9 +5,10 @@ ICD2061 clock generator emulation Used by ET4000w32/p (Diamond Stealth 32)*/ -#include "ibm.h" +#include "../ibm.h" #include "vid_icd2061.h" + void icd2061_write(icd2061_t *icd2061, int val) { int q, p, m, a; diff --git a/src/vid_icd2061.h b/src/VIDEO/vid_icd2061.h similarity index 100% rename from src/vid_icd2061.h rename to src/VIDEO/vid_icd2061.h diff --git a/src/vid_ics2595.c b/src/VIDEO/vid_ics2595.c similarity index 98% rename from src/vid_ics2595.c rename to src/VIDEO/vid_ics2595.c index 15c397729..ffe6f504c 100644 --- a/src/vid_ics2595.c +++ b/src/VIDEO/vid_ics2595.c @@ -3,10 +3,10 @@ */ /*ICS2595 clock chip emulation Used by ATI Mach64*/ - -#include "ibm.h" +#include "../ibm.h" #include "vid_ics2595.h" + enum { ICS2595_IDLE = 0, @@ -14,8 +14,10 @@ enum ICS2595_READ }; + static int ics2595_div[4] = {8, 4, 2, 1}; + void ics2595_write(ics2595_t *ics2595, int strobe, int dat) { if (strobe) diff --git a/src/vid_ics2595.h b/src/VIDEO/vid_ics2595.h similarity index 100% rename from src/vid_ics2595.h rename to src/VIDEO/vid_ics2595.h diff --git a/src/vid_incolor.c b/src/VIDEO/vid_incolor.c similarity index 99% rename from src/vid_incolor.c rename to src/VIDEO/vid_incolor.c index 4185978b0..636697c1a 100644 --- a/src/vid_incolor.c +++ b/src/VIDEO/vid_incolor.c @@ -2,13 +2,12 @@ see COPYING for more details */ /*Hercules InColor emulation*/ - #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_incolor.h" @@ -1015,7 +1014,7 @@ void *incolor_init() incolor->vram = malloc(0x40000); /* 4 planes of 64k */ timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor); - mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, 0, incolor); + mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor); io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); for (c = 0; c < 64; c++) diff --git a/src/vid_incolor.h b/src/VIDEO/vid_incolor.h similarity index 100% rename from src/vid_incolor.h rename to src/VIDEO/vid_incolor.h diff --git a/src/vid_mda.c b/src/VIDEO/vid_mda.c similarity index 98% rename from src/vid_mda.c rename to src/VIDEO/vid_mda.c index 4b45debc3..7180a4921 100644 --- a/src/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -3,17 +3,18 @@ */ /*MDA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_mda.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + typedef struct mda_t { mem_mapping_t mapping; @@ -268,7 +269,7 @@ void *mda_init() mda->vram = malloc(0x1000); timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, mda); + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); for (c = 0; c < 256; c++) diff --git a/src/vid_mda.h b/src/VIDEO/vid_mda.h similarity index 100% rename from src/vid_mda.h rename to src/VIDEO/vid_mda.h diff --git a/src/vid_nv_riva128.c b/src/VIDEO/vid_nv_riva128.c similarity index 98% rename from src/vid_nv_riva128.c rename to src/VIDEO/vid_nv_riva128.c index 3d6483f77..a0bea095c 100644 --- a/src/vid_nv_riva128.c +++ b/src/VIDEO/vid_nv_riva128.c @@ -3,20 +3,21 @@ */ /*nVidia RIVA 128 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "pic.h" -#include "rom.h" -#include "thread.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../pic.h" +#include "../rom.h" +#include "../thread.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_nv_riva128.h" #include "vid_svga.h" #include "vid_svga_render.h" + typedef struct riva128_t { mem_mapping_t linear_mapping; @@ -2714,7 +2715,7 @@ static void *riva128_init() riva128_in, riva128_out, NULL, NULL); - rom_init(&riva128->bios_rom, "roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&riva128->bios_rom.mapping); @@ -2812,7 +2813,7 @@ static void riva128_close(void *p) static int riva128_available() { - return rom_present("roms/Diamond_V330_rev-e.vbi"); + return rom_present(L"roms/Diamond_V330_rev-e.vbi"); } static void riva128_speed_changed(void *p) @@ -3016,7 +3017,7 @@ static void *rivatnt_init() riva128_in, riva128_out, NULL, NULL); - rom_init(&riva128->bios_rom, "roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&riva128->bios_rom.mapping); @@ -3098,7 +3099,7 @@ static void rivatnt_close(void *p) static int rivatnt_available() { - return rom_present("roms/NV4_diamond_revB.rom"); + return rom_present(L"roms/NV4_diamond_revB.rom"); } static void rivatnt_speed_changed(void *p) @@ -3220,13 +3221,13 @@ static void *rivatnt2_init() switch(model) { case 0: - rom_init(&riva128->bios_rom, "roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; case 1: - rom_init(&riva128->bios_rom, "roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; case 2: - rom_init(&riva128->bios_rom, "roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; } if (PCI) @@ -3310,7 +3311,7 @@ static void rivatnt2_close(void *p) static int rivatnt2_available() { - return rom_present("roms/NV5diamond.bin") || rom_present("roms/inno3d64bit.BIN") || rom_present("roms/creative.BIN"); + return rom_present(L"roms/NV5diamond.bin") || rom_present(L"roms/inno3d64bit.BIN") || rom_present(L"roms/creative.BIN"); } static void rivatnt2_speed_changed(void *p) diff --git a/src/vid_nv_riva128.h b/src/VIDEO/vid_nv_riva128.h similarity index 100% rename from src/vid_nv_riva128.h rename to src/VIDEO/vid_nv_riva128.h diff --git a/src/vid_olivetti_m24.c b/src/VIDEO/vid_olivetti_m24.c similarity index 99% rename from src/vid_olivetti_m24.c rename to src/VIDEO/vid_olivetti_m24.c index 8b6e62983..f130c69fb 100644 --- a/src/vid_olivetti_m24.c +++ b/src/VIDEO/vid_olivetti_m24.c @@ -4,14 +4,15 @@ /*Olivetti M24 video emulation Essentially double-res CGA*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_olivetti_m24.h" + typedef struct m24_t { mem_mapping_t mapping; diff --git a/src/vid_olivetti_m24.h b/src/VIDEO/vid_olivetti_m24.h similarity index 100% rename from src/vid_olivetti_m24.h rename to src/VIDEO/vid_olivetti_m24.h diff --git a/src/vid_oti067.c b/src/VIDEO/vid_oti067.c similarity index 87% rename from src/vid_oti067.c rename to src/VIDEO/vid_oti067.c index c1f0f0b0c..c04a43778 100644 --- a/src/vid_oti067.c +++ b/src/VIDEO/vid_oti067.c @@ -3,15 +3,16 @@ */ /*Oak OTI067 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_oti067.h" #include "vid_svga.h" + typedef struct oti067_t { svga_t svga; @@ -157,7 +158,7 @@ void oti067_recalctimings(svga_t *svga) } } -void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) +void *oti067_common_init(wchar_t *bios_fn, int vram_size, int chip_id) { oti067_t *oti067 = malloc(sizeof(oti067_t)); memset(oti067, 0, sizeof(oti067_t)); @@ -182,47 +183,26 @@ void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) return oti067; } -/* void *oti037_init() -{ - int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/hyundai_oti037c.bin", vram_size, 0); -} */ - void *oti067_init() { int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/oti067/bios.bin", vram_size, 2); + return oti067_common_init(L"roms/oti067/bios.bin", vram_size, 2); } void *oti077_init() { int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/oti077.vbi", vram_size, 5); + return oti067_common_init(L"roms/oti077.vbi", vram_size, 5); } -void *oti067_acer386_init() -{ - oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512, 2); - - /* if (oti067) - oti067->bios_rom.rom[0x5d] = 0x74; */ - - return oti067; -} - -/* static int oti037_available() -{ - return rom_present("roms/hyundai_oti037c.bin"); -} */ - static int oti067_available() { - return rom_present("roms/oti067/bios.bin"); + return rom_present(L"roms/oti067/bios.bin"); } static int oti077_available() { - return rom_present("roms/oti077.vbi"); + return rom_present(L"roms/oti077.vbi"); } void oti067_close(void *p) @@ -312,17 +292,6 @@ device_t oti067_device = oti067_add_status_info, oti067_config }; -device_t oti067_acer386_device = -{ - "Oak OTI-067 (Acermate 386SX/25N)", - 0, - oti067_acer386_init, - oti067_close, - oti067_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info -}; device_t oti077_device = { "Oak OTI-077", diff --git a/src/vid_oti067.h b/src/VIDEO/vid_oti067.h similarity index 100% rename from src/vid_oti067.h rename to src/VIDEO/vid_oti067.h diff --git a/src/vid_paradise.c b/src/VIDEO/vid_paradise.c similarity index 92% rename from src/vid_paradise.c rename to src/VIDEO/vid_paradise.c index 859695459..4527619fe 100644 --- a/src/vid_paradise.c +++ b/src/VIDEO/vid_paradise.c @@ -7,17 +7,18 @@ MegaPC uses W90C11A */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_paradise.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_unk_ramdac.h" + typedef struct paradise_t { svga_t svga; @@ -323,7 +324,7 @@ static void *paradise_pvga1a_pc2086_init() paradise_t *paradise = paradise_pvga1a_init(); if (paradise) - rom_init(¶dise->bios_rom, "roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(¶dise->bios_rom, L"roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; } @@ -332,7 +333,7 @@ static void *paradise_pvga1a_pc3086_init() paradise_t *paradise = paradise_pvga1a_init(); if (paradise) - rom_init(¶dise->bios_rom, "roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(¶dise->bios_rom, L"roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; } @@ -343,8 +344,8 @@ static void *paradise_wd90c11_megapc_init() if (paradise) rom_init_interleaved(¶dise->bios_rom, - "roms/megapc/41651-bios lo.u18", - "roms/megapc/211253-bios hi.u19", + L"roms/megapc/41651-bios lo.u18", + L"roms/megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; @@ -352,24 +353,9 @@ static void *paradise_wd90c11_megapc_init() static int paradise_wd90c11_standalone_available() { - return rom_present("roms/megapc/41651-bios lo.u18") && rom_present("roms/megapc/211253-bios hi.u19"); + return rom_present(L"roms/megapc/41651-bios lo.u18") && rom_present(L"roms/megapc/211253-bios hi.u19"); } -/* static void *cpqvga_init() -{ - paradise_t *paradise = paradise_pvga1a_init(); - - if (paradise) - rom_init(¶dise->bios_rom, "roms/1988-05-18.rom", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static int cpqvga_standalone_available() -{ - return rom_present("roms/1988-05-18.rom"); -} */ - void paradise_close(void *p) { paradise_t *paradise = (paradise_t *)p; @@ -444,14 +430,3 @@ device_t paradise_wd90c11_device = paradise_force_redraw, paradise_add_status_info }; -/* device_t cpqvga_device = -{ - "Compaq/Paradise VGA", - 0, - cpqvga_init, - paradise_close, - cpqvga_standalone_available, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info -}; */ diff --git a/src/vid_paradise.h b/src/VIDEO/vid_paradise.h similarity index 100% rename from src/vid_paradise.h rename to src/VIDEO/vid_paradise.h diff --git a/src/vid_pc1512.c b/src/VIDEO/vid_pc1512.c similarity index 99% rename from src/vid_pc1512.c rename to src/VIDEO/vid_pc1512.c index 466db6f8f..832bde2ea 100644 --- a/src/vid_pc1512.c +++ b/src/VIDEO/vid_pc1512.c @@ -10,14 +10,15 @@ The Technical Reference Manual lists the video waitstate time as between 12 and 46 cycles. PCem currently always uses the lower number.*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_pc1512.h" + typedef struct pc1512_t { mem_mapping_t mapping; diff --git a/src/vid_pc1512.h b/src/VIDEO/vid_pc1512.h similarity index 100% rename from src/vid_pc1512.h rename to src/VIDEO/vid_pc1512.h diff --git a/src/vid_pc1640.c b/src/VIDEO/vid_pc1640.c similarity index 95% rename from src/vid_pc1640.c rename to src/VIDEO/vid_pc1640.c index 610f322c0..3db12e57d 100644 --- a/src/vid_pc1640.c +++ b/src/VIDEO/vid_pc1640.c @@ -4,17 +4,18 @@ /*PC1640 video emulation. Mostly standard EGA, but with CGA & Hercules emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_ega.h" #include "vid_pc1640.h" + typedef struct pc1640_t { mem_mapping_t cga_mapping; @@ -125,7 +126,7 @@ void *pc1640_init() ega_t *ega = &pc1640->ega; memset(pc1640, 0, sizeof(pc1640_t)); - rom_init(&pc1640->bios_rom, "roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); + rom_init(&pc1640->bios_rom, L"roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); ega_init(&pc1640->ega); pc1640->cga.vram = pc1640->ega.vram; diff --git a/src/vid_pc1640.h b/src/VIDEO/vid_pc1640.h similarity index 100% rename from src/vid_pc1640.h rename to src/VIDEO/vid_pc1640.h diff --git a/src/vid_pc200.c b/src/VIDEO/vid_pc200.c similarity index 97% rename from src/vid_pc200.c rename to src/VIDEO/vid_pc200.c index 99eeb3171..eef181c33 100644 --- a/src/vid_pc200.c +++ b/src/VIDEO/vid_pc200.c @@ -5,15 +5,16 @@ CGA with some NMI stuff. But we don't need that as it's only used for TV and LCD displays, and we're emulating a CRT*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_pc200.h" + typedef struct pc200_t { mem_mapping_t mapping; diff --git a/src/vid_pc200.h b/src/VIDEO/vid_pc200.h similarity index 100% rename from src/vid_pc200.h rename to src/VIDEO/vid_pc200.h diff --git a/src/vid_pcjr.c b/src/VIDEO/vid_pcjr.c similarity index 99% rename from src/vid_pcjr.c rename to src/VIDEO/vid_pcjr.c index b10cb475c..0557967d9 100644 --- a/src/vid_pcjr.c +++ b/src/VIDEO/vid_pcjr.c @@ -1,18 +1,20 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pic.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "video.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" #include "vid_pcjr.h" + #define PCJR_RGB 0 #define PCJR_COMPOSITE 1 + typedef struct pcjr_t { mem_mapping_t mapping; diff --git a/src/vid_pcjr.h b/src/VIDEO/vid_pcjr.h similarity index 100% rename from src/vid_pcjr.h rename to src/VIDEO/vid_pcjr.h diff --git a/src/vid_ps1_svga.c b/src/VIDEO/vid_ps1_svga.c similarity index 98% rename from src/vid_ps1_svga.c rename to src/VIDEO/vid_ps1_svga.c index 86b10c8ec..9bb6acafc 100644 --- a/src/vid_ps1_svga.c +++ b/src/VIDEO/vid_ps1_svga.c @@ -8,15 +8,16 @@ it's just a VGA for now. */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_vga.h" + typedef struct ps1_m2121_svga_t { svga_t svga; diff --git a/src/vid_ps1_svga.h b/src/VIDEO/vid_ps1_svga.h similarity index 100% rename from src/vid_ps1_svga.h rename to src/VIDEO/vid_ps1_svga.h diff --git a/src/vid_s3.c b/src/VIDEO/vid_s3.c similarity index 97% rename from src/vid_s3.c rename to src/VIDEO/vid_s3.c index 3c0a3371b..ae5c8c701 100644 --- a/src/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1,18 +1,19 @@ /*S3 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../thread.h" +#include "../device.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" + enum { S3_VISION864, @@ -735,8 +736,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (val & 8 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; } break; @@ -766,6 +769,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x32: svga->vrammask = (val & 0x40) ? 0x3ffff : s3->vram_mask; @@ -789,19 +796,25 @@ void s3_out(uint16_t addr, uint8_t val, void *p) case 0x35: s3->bank = (s3->bank & 0x70) | (val & 0xf); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: s3->bank = val; - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x3a: @@ -980,7 +993,12 @@ void s3_updatemapping(s3_t *s3) return; } - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) + { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + else switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -1645,9 +1663,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { - READ(s3->accel.src + s3->accel.cx, src_dat); - - dest_dat = src_dat; + READ(s3->accel.src + s3->accel.cx, dest_dat); + + MIX WRITE(s3->accel.dest + s3->accel.dx); } @@ -1671,8 +1689,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; return; } } @@ -2063,7 +2079,7 @@ static int vram_sizes[] = 3 /*8 MB*/ }; -static void *s3_init(char *bios_fn, int chip) +static void *s3_init(wchar_t *bios_fn, int chip) { s3_t *s3 = malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; @@ -2124,7 +2140,7 @@ static void *s3_init(char *bios_fn, int chip) return s3; } -void *s3_vision864_init(char *bios_fn) +void *s3_vision864_init(wchar_t *bios_fn) { s3_t *s3 = s3_init(bios_fn, S3_VISION864); @@ -2140,29 +2156,29 @@ void *s3_vision864_init(char *bios_fn) void *s3_bahamas64_init() { - s3_t *s3 = s3_vision864_init("roms/bahamas64.BIN"); + s3_t *s3 = s3_vision864_init(L"roms/bahamas64.BIN"); return s3; } void *s3_phoenix_vision864_init() { - s3_t *s3 = s3_vision864_init("roms/86c864p.bin"); + s3_t *s3 = s3_vision864_init(L"roms/86c864p.bin"); return s3; } int s3_bahamas64_available() { - return rom_present("roms/bahamas64.BIN"); + return rom_present(L"roms/bahamas64.BIN"); } int s3_phoenix_vision864_available() { - return rom_present("roms/86c864p.bin"); + return rom_present(L"roms/86c864p.bin"); } void *s3_phoenix_trio32_init() { - s3_t *s3 = s3_init("roms/86C732P.bin", S3_TRIO32); + s3_t *s3 = s3_init(L"roms/86C732P.bin", S3_TRIO32); s3->id = 0xe1; /*Trio32*/ s3->id_ext = 0x10; @@ -2177,24 +2193,14 @@ void *s3_phoenix_trio32_init() int s3_phoenix_trio32_available() { - return rom_present("roms/86C732P.bin"); + return rom_present(L"roms/86C732P.bin"); } -void *s3_trio64_init(char *bios_fn) +void *s3_trio64_init(wchar_t *bios_fn) { - int card_id = 0; s3_t *s3 = s3_init(bios_fn, S3_TRIO64); - card_id = device_get_config_int("card_id"); - - if (card_id) - { - s3->id = 0xc1; /*Vision864P*/ - } - else - { - s3->id = 0xe1; /*Trio64*/ - } + s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; @@ -2206,35 +2212,35 @@ void *s3_trio64_init(char *bios_fn) void *s3_9fx_init() { - s3_t *s3 = s3_trio64_init("roms/s3_764.bin"); + s3_t *s3 = s3_trio64_init(L"roms/s3_764.bin"); return s3; } void *s3_phoenix_trio64_init() { - s3_t *s3 = s3_trio64_init("roms/86C764X1.bin"); + s3_t *s3 = s3_trio64_init(L"roms/86C764X1.bin"); return s3; } void *s3_diamond_stealth64_init() { - s3_t *s3 = s3_trio64_init("roms/STEALT64.BIN"); + s3_t *s3 = s3_trio64_init(L"roms/STEALT64.BIN"); return s3; } int s3_9fx_available() { - return rom_present("roms/s3_764.bin"); + return rom_present(L"roms/s3_764.bin"); } int s3_phoenix_trio64_available() { - return rom_present("roms/86C764X1.bin"); + return rom_present(L"roms/86C764X1.bin"); } int s3_diamond_stealth64_available() { - return rom_present("roms/STEALT64.BIN"); + return rom_present(L"roms/STEALT64.BIN"); } void s3_close(void *p) @@ -2389,20 +2395,6 @@ static device_config_t s3_phoenix_trio64_config[] = } } }, - { - "card_id", "Card ID", CONFIG_SELECTION, "", 1, - { - { - "S3 Trio64", 0 - }, - { - "S3 Vision864", 1 - }, - { - "" - } - } - }, { "", "", -1 } diff --git a/src/vid_s3.h b/src/VIDEO/vid_s3.h similarity index 100% rename from src/vid_s3.h rename to src/VIDEO/vid_s3.h diff --git a/src/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c similarity index 99% rename from src/vid_s3_virge.c rename to src/VIDEO/vid_s3_virge.c index cecdcb427..21723de42 100644 --- a/src/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -3,18 +3,19 @@ */ /*S3 ViRGE emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" + static uint64_t virge_time = 0; static uint64_t status_time = 0; static int reg_writes = 0, reg_reads = 0; @@ -3707,7 +3708,7 @@ static void *s3_virge_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -3802,7 +3803,7 @@ static void *s3_virge_988_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/diamondstealth3000.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/diamondstealth3000.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -3897,7 +3898,7 @@ static void *s3_virge_375_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -4003,17 +4004,17 @@ static void s3_virge_close(void *p) static int s3_virge_available() { - return rom_present("roms/s3virge.bin"); + return rom_present(L"roms/s3virge.bin"); } static int s3_virge_988_available() { - return rom_present("roms/diamondstealth3000.VBI"); + return rom_present(L"roms/diamondstealth3000.VBI"); } static int s3_virge_375_available() { - return rom_present("roms/86c375_1.bin"); + return rom_present(L"roms/86c375_1.bin"); } static void s3_virge_speed_changed(void *p) diff --git a/src/vid_s3_virge.h b/src/VIDEO/vid_s3_virge.h similarity index 100% rename from src/vid_s3_virge.h rename to src/VIDEO/vid_s3_virge.h diff --git a/src/vid_sdac_ramdac.c b/src/VIDEO/vid_sdac_ramdac.c similarity index 99% rename from src/vid_sdac_ramdac.c rename to src/VIDEO/vid_sdac_ramdac.c index c1dad85d2..3bff85104 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/VIDEO/vid_sdac_ramdac.c @@ -3,12 +3,13 @@ */ /*87C716 'SDAC' true colour RAMDAC emulation*/ /*Misidentifies as AT&T 21C504*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_sdac_ramdac.h" + /* Returning divider * 2 */ int sdac_get_clock_divider(sdac_ramdac_t *ramdac) { diff --git a/src/vid_sdac_ramdac.h b/src/VIDEO/vid_sdac_ramdac.h similarity index 100% rename from src/vid_sdac_ramdac.h rename to src/VIDEO/vid_sdac_ramdac.h diff --git a/src/vid_stg_ramdac.c b/src/VIDEO/vid_stg_ramdac.c similarity index 99% rename from src/vid_stg_ramdac.c rename to src/VIDEO/vid_stg_ramdac.c index 2aa3fee19..2881fff91 100644 --- a/src/vid_stg_ramdac.c +++ b/src/VIDEO/vid_stg_ramdac.c @@ -2,15 +2,17 @@ see COPYING for more details */ /*STG1702 true colour RAMDAC emulation*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_stg_ramdac.h" + static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; + void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { if (ramdac->command & 0x8) diff --git a/src/vid_stg_ramdac.h b/src/VIDEO/vid_stg_ramdac.h similarity index 100% rename from src/vid_stg_ramdac.h rename to src/VIDEO/vid_stg_ramdac.h diff --git a/src/vid_svga.c b/src/VIDEO/vid_svga.c similarity index 97% rename from src/vid_svga.c rename to src/VIDEO/vid_svga.c index 9db83a709..6da19608d 100644 --- a/src/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -5,16 +5,21 @@ /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ #include #include -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#ifdef ENABLE_VRAM_DUMP +#include "../rom.h" +#endif +#include "../timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "io.h" -#include "timer.h" + #define svga_output 0 + void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); extern uint8_t edatlookup[4][4]; @@ -914,6 +919,11 @@ void svga_poll(void *p) } } +#ifdef ENABLE_VRAM_DUMP +uint8_t *ext_vram; +int ext_memsize; +#endif + int svga_init(svga_t *svga, void *p, int memsize, void (*recalctimings_ex)(struct svga_t *svga), uint8_t (*video_in) (uint16_t addr, void *p), @@ -948,6 +958,10 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->bpp = 8; svga->vram = malloc(memsize); +#ifdef ENABLE_VRAM_DUMP + ext_vram = svga->vram; + ext_memsize = memsize; +#endif svga->vram_limit = memsize; svga->vrammask = memsize - 1; svga->changedvram = malloc(/*(memsize >> 12) << 1*/memsize >> 12); @@ -957,7 +971,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); memset(svga->vgapal, 0, sizeof(PALETTE)); @@ -1006,21 +1020,38 @@ void svga_write(uint32_t addr, uint8_t val, void *p) if (!(svga->gdcreg[6] & 1)) svga->fullchange=2; if (svga->chain4 || svga->fb_only) { + /* + 00000 -> writemask 1, addr 0 -> vram addr 00000 + 00001 -> writemask 2, addr 0 -> vram addr 00001 + 00002 -> writemask 4, addr 0 -> vram addr 00002 + 00003 -> writemask 8, addr 0 -> vram addr 00003 + 00004 -> writemask 1, addr 4 -> vram addr 00004 + 00005 -> writemask 2, addr 4 -> vram addr 00005 + 00006 -> writemask 4, addr 4 -> vram addr 00006 + 00007 -> writemask 8, addr 4 -> vram addr 00007 + */ writemask2=1<<(addr&3); addr&=~3; } else if (svga->chain2_write) { - if ((svga->gdcreg[6] & 0xC) == 0x4) +#if 0 + if (svga->oddeven_page) { - writemask2 &= (svga->oddeven_page ? ~0xe : ~0xb); + /* Odd/Even page is 1, mask out plane 2 or 3, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 8 : 4; } else { - writemask2 &= ~0xa; + /* Odd/Even page is 2, mask out plane 0 or 1, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 2 : 1; } +#endif + + writemask2 &= ~0xa; if (addr & 1) - writemask2 <<= 1; + writemask2 <<= 1; + addr &= ~1; addr <<= 2; } @@ -1205,12 +1236,17 @@ uint8_t svga_read(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { if (addr >= svga->vram_limit) - return 0xff; + return 0x00; return svga->vram[svga_mask_addr(addr, svga)]; } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); + readplane = addr & 1; + if (svga->oddeven_page) + { + readplane |= 2; + } + addr &= ~1; addr <<= 2; } @@ -1218,7 +1254,7 @@ uint8_t svga_read(uint32_t addr, void *p) addr<<=2; if (addr >= svga->vram_limit) - return 0xff; + return 0x00; addr = svga_mask_addr(addr, svga); @@ -1273,16 +1309,23 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) } else if (svga->chain2_write) { - if ((svga->gdcreg[6] & 0xC) == 0x4) +#if 0 + if (svga->oddeven_page) { - writemask2 &= (svga->oddeven_page ? ~0xe : ~0xb); + /* Odd/Even page is 1, mask out plane 2 or 3, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 8 : 4; } else { - writemask2 &= ~0xa; + /* Odd/Even page is 2, mask out plane 0 or 1, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 2 : 1; } +#endif + + writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; + addr &= ~1; addr <<= 2; } @@ -1467,7 +1510,12 @@ uint8_t svga_read_linear(uint32_t addr, void *p) } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); + readplane = addr & 1; + if (svga->oddeven_page) + { + readplane |= 2; + } + addr &= ~1; addr <<= 2; } @@ -1814,6 +1862,28 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) } +#ifdef ENABLE_VRAM_DUMP +void svga_dump_vram() +{ + FILE *f; + + if (ext_vram == NULL) + { + return; + } + + f = nvrfopen(L"svga_vram.dmp", L"wb"); + if (f == NULL) + { + return; + } + + fwrite(ext_vram, ext_memsize, 1, f); + + fclose(f); +} +#endif + void svga_add_status_info(char *s, int max_len, void *p) { svga_t *svga = (svga_t *)p; @@ -1842,4 +1912,4 @@ void svga_add_status_info(char *s, int max_len, void *p) sprintf(temps, "SVGA DAC in %i-bit mode\n", (svga->attrregs[0x10] & 0x80) ? 8 : 6); strncat(s, temps, max_len); -} \ No newline at end of file +} diff --git a/src/vid_svga.h b/src/VIDEO/vid_svga.h similarity index 100% rename from src/vid_svga.h rename to src/VIDEO/vid_svga.h diff --git a/src/vid_svga_render.c b/src/VIDEO/vid_svga_render.c similarity index 99% rename from src/vid_svga_render.c rename to src/VIDEO/vid_svga_render.c index cf6caac68..fb8845a75 100644 --- a/src/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -1,15 +1,17 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#include "ibm.h" -#include "mem.h" +#include +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include + int invert_display = 0; + uint32_t svga_color_transform(uint32_t color) { uint32_t temp = 0; diff --git a/src/vid_svga_render.h b/src/VIDEO/vid_svga_render.h similarity index 100% rename from src/vid_svga_render.h rename to src/VIDEO/vid_svga_render.h diff --git a/src/vid_tandy.c b/src/VIDEO/vid_tandy.c similarity index 99% rename from src/vid_tandy.c rename to src/VIDEO/vid_tandy.c index e9deb6798..d6151e44e 100644 --- a/src/vid_tandy.c +++ b/src/VIDEO/vid_tandy.c @@ -1,17 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_tandy.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" + #define TANDY_RGB 0 #define TANDY_COMPOSITE 1 + typedef struct tandy_t { mem_mapping_t mapping; diff --git a/src/vid_tandy.h b/src/VIDEO/vid_tandy.h similarity index 100% rename from src/vid_tandy.h rename to src/VIDEO/vid_tandy.h diff --git a/src/vid_tandysl.c b/src/VIDEO/vid_tandysl.c similarity index 99% rename from src/vid_tandysl.c rename to src/VIDEO/vid_tandysl.c index 0ad656aaf..0c4225525 100644 --- a/src/vid_tandysl.c +++ b/src/VIDEO/vid_tandysl.c @@ -3,14 +3,15 @@ */ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_tandysl.h" + typedef struct tandysl_t { mem_mapping_t mapping; diff --git a/src/vid_tandysl.h b/src/VIDEO/vid_tandysl.h similarity index 100% rename from src/vid_tandysl.h rename to src/VIDEO/vid_tandysl.h diff --git a/src/vid_tgui9440.c b/src/VIDEO/vid_tgui9440.c similarity index 99% rename from src/vid_tgui9440.c rename to src/VIDEO/vid_tgui9440.c index f369c8370..e365ed4ac 100644 --- a/src/vid_tgui9440.c +++ b/src/VIDEO/vid_tgui9440.c @@ -3,19 +3,20 @@ */ /*Trident TGUI9440 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_tkd8001_ramdac.h" #include "vid_tgui9440.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) @@ -510,7 +511,7 @@ void *tgui9440_init() tgui->vram_size = device_get_config_int("memory") << 20; tgui->vram_mask = tgui->vram_size - 1; - rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tgui->bios_rom, L"roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tgui->svga, tgui, tgui->vram_size, tgui_recalctimings, @@ -536,7 +537,7 @@ void *tgui9440_init() static int tgui9440_available() { - return rom_present("roms/9440.vbi"); + return rom_present(L"roms/9440.vbi"); } void tgui_close(void *p) diff --git a/src/vid_tgui9440.h b/src/VIDEO/vid_tgui9440.h similarity index 100% rename from src/vid_tgui9440.h rename to src/VIDEO/vid_tgui9440.h diff --git a/src/vid_tkd8001_ramdac.c b/src/VIDEO/vid_tkd8001_ramdac.c similarity index 97% rename from src/vid_tkd8001_ramdac.c rename to src/VIDEO/vid_tkd8001_ramdac.c index 3d22d987c..553bc489f 100644 --- a/src/vid_tkd8001_ramdac.c +++ b/src/VIDEO/vid_tkd8001_ramdac.c @@ -2,12 +2,13 @@ see COPYING for more details */ /*Trident TKD8001 RAMDAC emulation*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_tkd8001_ramdac.h" + void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { switch (addr) diff --git a/src/vid_tkd8001_ramdac.h b/src/VIDEO/vid_tkd8001_ramdac.h similarity index 100% rename from src/vid_tkd8001_ramdac.h rename to src/VIDEO/vid_tkd8001_ramdac.h diff --git a/src/vid_tvga.c b/src/VIDEO/vid_tvga.c similarity index 97% rename from src/vid_tvga.c rename to src/VIDEO/vid_tvga.c index 3e70422cb..7c6c7f255 100644 --- a/src/vid_tvga.c +++ b/src/VIDEO/vid_tvga.c @@ -3,17 +3,18 @@ */ /*Trident TVGA (8900D) emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_tkd8001_ramdac.h" #include "vid_tvga.h" + typedef struct tvga_t { mem_mapping_t linear_mapping; @@ -285,7 +286,7 @@ void *tvga8900d_init() tvga->vram_size = device_get_config_int("memory") << 10; tvga->vram_mask = tvga->vram_size - 1; - rom_init(&tvga->bios_rom, "roms/TRIDENT.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tvga->bios_rom, L"roms/TRIDENT.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, @@ -300,7 +301,7 @@ void *tvga8900d_init() static int tvga8900d_available() { - return rom_present("roms/TRIDENT.BIN"); + return rom_present(L"roms/TRIDENT.BIN"); } void tvga_close(void *p) diff --git a/src/vid_tvga.h b/src/VIDEO/vid_tvga.h similarity index 100% rename from src/vid_tvga.h rename to src/VIDEO/vid_tvga.h diff --git a/src/vid_unk_ramdac.c b/src/VIDEO/vid_unk_ramdac.c similarity index 98% rename from src/vid_unk_ramdac.c rename to src/VIDEO/vid_unk_ramdac.c index 0b6fc6aea..c2fb35bae 100644 --- a/src/vid_unk_ramdac.c +++ b/src/VIDEO/vid_unk_ramdac.c @@ -5,12 +5,13 @@ It is possibly a Sierra 1502x It's addressed by the TLIVESA1 driver for ET4000*/ /* Note by Tenshi: Not possibly, this *IS* a Sierra 1502x. */ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" + void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga) { int oldbpp = 0; diff --git a/src/vid_unk_ramdac.h b/src/VIDEO/vid_unk_ramdac.h similarity index 100% rename from src/vid_unk_ramdac.h rename to src/VIDEO/vid_unk_ramdac.h diff --git a/src/vid_vga.c b/src/VIDEO/vid_vga.c similarity index 80% rename from src/vid_vga.c rename to src/VIDEO/vid_vga.c index f5ff18ed6..e1570b3c4 100644 --- a/src/vid_vga.c +++ b/src/VIDEO/vid_vga.c @@ -3,15 +3,16 @@ */ /*IBM VGA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_vga.h" + typedef struct vga_t { svga_t svga; @@ -84,7 +85,7 @@ void *vga_init() vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, L"roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, @@ -100,36 +101,13 @@ void *vga_init() return vga; } -#if 0 -void *vga_chips_init() -{ - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); - - rom_init(&vga->bios_rom, "roms/SD620.04M", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - vga->svga.bpp = 8; - vga->svga.miscout = 1; - - return vga; -} -#endif - #ifdef DEV_BRANCH void *trigem_unk_init() { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, L"roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, @@ -172,14 +150,9 @@ void *ps1vga_init() static int vga_available() { - return rom_present("roms/ibm_vga.bin"); + return rom_present(L"roms/ibm_vga.bin"); } -/* static int vga_chips_available() -{ - return rom_present("roms/SD620.04M"); -} */ - void vga_close(void *p) { vga_t *vga = (vga_t *)p; @@ -221,17 +194,6 @@ device_t vga_device = vga_force_redraw, vga_add_status_info }; -/* device_t vga_chips_device = -{ - "Chips VGA", - 0, - vga_chips_init, - vga_close, - vga_chips_available, - vga_speed_changed, - vga_force_redraw, - vga_add_status_info -}; */ #ifdef DEV_BRANCH device_t trigem_unk_device = { diff --git a/src/vid_vga.h b/src/VIDEO/vid_vga.h similarity index 100% rename from src/vid_vga.h rename to src/VIDEO/vid_vga.h diff --git a/src/vid_voodoo.c b/src/VIDEO/vid_voodoo.c similarity index 99% rename from src/vid_voodoo.c rename to src/VIDEO/vid_voodoo.c index a1a5e93e7..57bb0084a 100644 --- a/src/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -1,16 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "pci.h" -#include "thread.h" -#include "timer.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../mem.h" +#include "../rom.h" +#include "../pci.h" +#include "../thread.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_voodoo.h" #include "vid_voodoo_dither.h" + #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) @@ -2212,7 +2215,7 @@ static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) /*Perform texture fetch and blending for both TMUs*/ -static __inline voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +static __inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { int r,g,b,a; int c_reverse, a_reverse; @@ -7040,12 +7043,12 @@ void voodoo_close(void *p) int c; #ifndef RELEASE_BUILD - f = romfopen("texram.dmp", "wb"); + f = romfopen(L"texram.dmp", L"wb"); fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f); fclose(f); if (voodoo->dual_tmus) { - f = romfopen("texram2.dmp", "wb"); + f = romfopen(L"texram2.dmp", L"wb"); fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); fclose(f); } diff --git a/src/vid_voodoo.h b/src/VIDEO/vid_voodoo.h similarity index 100% rename from src/vid_voodoo.h rename to src/VIDEO/vid_voodoo.h diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/VIDEO/vid_voodoo_codegen_x86-64.h similarity index 100% rename from src/vid_voodoo_codegen_x86-64.h rename to src/VIDEO/vid_voodoo_codegen_x86-64.h diff --git a/src/vid_voodoo_codegen_x86.h b/src/VIDEO/vid_voodoo_codegen_x86.h similarity index 100% rename from src/vid_voodoo_codegen_x86.h rename to src/VIDEO/vid_voodoo_codegen_x86.h diff --git a/src/vid_voodoo_dither.h b/src/VIDEO/vid_voodoo_dither.h similarity index 100% rename from src/vid_voodoo_dither.h rename to src/VIDEO/vid_voodoo_dither.h diff --git a/src/vid_wy700.c b/src/VIDEO/vid_wy700.c similarity index 99% rename from src/vid_wy700.c rename to src/VIDEO/vid_wy700.c index 80def235f..0091ba534 100644 --- a/src/vid_wy700.c +++ b/src/VIDEO/vid_wy700.c @@ -1,18 +1,19 @@ /* Wyse-700 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_wy700.h" + #define WY700_XSIZE 1280 #define WY700_YSIZE 800 + void updatewindowsize(int x, int y); -void loadfont(char *s, int format); /* The Wyse 700 is an unusual video card. Though it has an MC6845 CRTC, this @@ -883,7 +884,7 @@ void *wy700_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, 0, wy700); + mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); diff --git a/src/vid_wy700.h b/src/VIDEO/vid_wy700.h similarity index 100% rename from src/vid_wy700.h rename to src/VIDEO/vid_wy700.h diff --git a/src/video.c b/src/VIDEO/video.c similarity index 96% rename from src/video.c rename to src/VIDEO/video.c index 48fd4ff16..c7bbe2c79 100644 --- a/src/video.c +++ b/src/VIDEO/video.c @@ -5,21 +5,22 @@ #include #include #include -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "mem.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../config.h" +#include "../device.h" +#include "../thread.h" +#include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "io.h" -#include "cpu.h" -#include "rom.h" -#include "thread.h" -#include "timer.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + #include "vid_ati18800.h" #include "vid_ati28800.h" #include "vid_ati_mach64.h" @@ -57,6 +58,7 @@ #include "vid_vga.h" #include "vid_wy700.h" + int cga_palette = 0; typedef struct @@ -362,9 +364,9 @@ int xsize=1,ysize=1; PALETTE cgapal; -void loadfont(char *s, int format) +void loadfont(wchar_t *s, int format) { - FILE *f=romfopen(s,"rb"); + FILE *f=romfopen(s,L"rb"); int c,d; if (!f) { @@ -690,21 +692,21 @@ void take_screenshot() #else time_t now; struct tm *info; -char screenshot_fn_partial[2048]; -char screenshot_fn[4096]; +wchar_t screenshot_fn_partial[2048]; +wchar_t screenshot_fn[4096]; void take_screenshot() { if ((vid_api < 0) || (vid_api > 1)) return; time(&now); info = localtime(&now); - memset(screenshot_fn, 0, 4096); - memset(screenshot_fn_partial, 0, 2048); + memset(screenshot_fn, 0, 8192); + memset(screenshot_fn_partial, 0, 4096); pclog("Video API is: %i\n", vid_api); if (vid_api == 1) { - strftime(screenshot_fn_partial, 2048, "screenshots\\%Y%m%d_%H%M%S.png", info); - append_filename(screenshot_fn, pcempath, screenshot_fn_partial, 4095); + wcsftime(screenshot_fn_partial, 2048, L"screenshots\\%Y%m%d_%H%M%S.png", info); + append_filename_w(screenshot_fn, pcempath, screenshot_fn_partial, 4095); if (video_fullscreen) { d3d_fs_take_screenshot(screenshot_fn); @@ -717,8 +719,8 @@ void take_screenshot() } else if (vid_api == 0) { - strftime(screenshot_fn_partial, 1024, "screenshots\\%Y%m%d_%H%M%S.bmp", info); - append_filename(screenshot_fn, pcempath, screenshot_fn_partial, 4095); + wcsftime(screenshot_fn_partial, 2048, L"screenshots\\%Y%m%d_%H%M%S.bmp", info); + append_filename_w(screenshot_fn, pcempath, screenshot_fn_partial, 4095); if (video_fullscreen) { ddraw_fs_take_screenshot(screenshot_fn); diff --git a/src/video.h b/src/VIDEO/video.h similarity index 90% rename from src/video.h rename to src/VIDEO/video.h index 33aed0400..7054c33b3 100644 --- a/src/video.h +++ b/src/VIDEO/video.h @@ -103,17 +103,17 @@ extern "C" { #endif void take_screenshot(); -void d3d_take_screenshot(char *fn); -void d3d_fs_take_screenshot(char *fn); -void ddraw_take_screenshot(char *fn); -void ddraw_fs_take_screenshot(char *fn); +void d3d_take_screenshot(wchar_t *fn); +void d3d_fs_take_screenshot(wchar_t *fn); +void ddraw_take_screenshot(wchar_t *fn); +void ddraw_fs_take_screenshot(wchar_t *fn); #ifdef __cplusplus } #endif extern int cga_palette; -void loadfont(char *s, int format); +void loadfont(wchar_t *s, int format); void initvideo(); void video_init(); void closevideo(); @@ -121,3 +121,7 @@ void video_updatetiming(); void hline(BITMAP *b, int x1, int y, int x2, uint32_t col); void updatewindowsize(int x, int y); + +#ifdef ENABLE_VRAM_DUMP +void svga_dump_vram(); +#endif diff --git a/src/acer386sx.c b/src/acer386sx.c index ea3bfe74d..4f6ce5eed 100644 --- a/src/acer386sx.c +++ b/src/acer386sx.c @@ -2,14 +2,15 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "cpu.h" - #include "acer386sx.h" + static int acer_index = 0; static uint8_t acer_regs[256]; + void acer386sx_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) diff --git a/src/ali1429.c b/src/ali1429.c index f1fa8fa3f..e0c348829 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -3,9 +3,9 @@ */ #include #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "cpu.h" #include "ali1429.h" diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c deleted file mode 100644 index dd7c50b2a..000000000 --- a/src/allegro-gui-configure.c +++ /dev/null @@ -1,639 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "cpu.h" -#include "fdd.h" -#include "gameport.h" -#include "model.h" -#include "sound.h" -#include "video.h" -#include "vid_voodoo.h" - -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; - -typedef struct allegro_list_t -{ - char name[256]; - int num; -} allegro_list_t; - -static allegro_list_t model_list[ROM_MAX+1]; -static allegro_list_t video_list[GFX_MAX+1]; -static allegro_list_t sound_list[GFX_MAX+1]; -static allegro_list_t cpumanu_list[4]; -static allegro_list_t cpu_list[32]; -static allegro_list_t joystick_list[32]; - -static char mem_size_str[10], mem_size_units[3]; - -static allegro_list_t cache_list[] = -{ - {"A little", 0}, - {"A bit", 1}, - {"Some", 2}, - {"A lot", 3}, - {"Infinite", 4}, - {"", -1} -}; - -static allegro_list_t vidspeed_list[] = -{ - {"8-bit", 0}, - {"Slow 16-bit", 1}, - {"Fast 16-bit", 2}, - {"Slow VLB/PCI", 3}, - {"Mid VLB/PCI", 4}, - {"Fast VLB/PCI", 5}, - {"", -1} -}; - -static allegro_list_t fdd_list[] = -{ - {"None", 0}, - {"5.25\" 360k", 1}, - {"5.25\" 1.2M", 2}, - {"5.25\" 1.2M Dual RPM", 3}, - {"3.5\" 720k", 4}, - {"3.5\" 1.44M", 5}, - {"3.5\" 1.44M 3-Mode", 6}, - {"3.5\" 2.88M", 7}, - {"", -1} -}; - -static void reset_list(); - -static char *list_proc_model(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (model_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return model_list[index].name; -} - -static char *list_proc_video(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (video_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return video_list[index].name; -} - -static char *list_proc_cache(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cache_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cache_list[index].name; -} - -static char *list_proc_vidspeed(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (vidspeed_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return vidspeed_list[index].name; -} - -static char *list_proc_sound(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (sound_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return sound_list[index].name; -} - -static char *list_proc_cpumanu(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cpumanu_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cpumanu_list[index].name; -} - -static char *list_proc_cpu(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cpu_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cpu_list[index].name; -} - -static char *list_proc_fdd(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (fdd_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return fdd_list[index].name; -} - -static char *list_proc_joystick(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (joystick_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return joystick_list[index].name; -} - -static int voodoo_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - deviceconfig_open(&voodoo_device); - return D_O_K; - } - - return ret; -} - - -static int video_config_proc(int msg, DIALOG *d, int c); -static int sound_config_proc(int msg, DIALOG *d, int c); -static int list_proc(int msg, DIALOG *d, int c); - -static DIALOG configure_dialog[] = -{ - {d_shadow_box_proc, 0, 0, 568,352,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 226, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 296, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {list_proc, 70*2, 12, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_model, 0, 0}, - - {list_proc, 70*2, 32, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_video, 0, 0}, - - {list_proc, 70*2, 52, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpumanu, 0, 0}, //5 - {list_proc, 70*2, 72, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpu, 0, 0}, - {d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cache, 0, 0}, - {d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, - {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9 - - {d_edit_proc, 70*2, 236, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0}, - - {d_text_proc, 98*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, - - {d_check_proc, 14*2, 252, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0}, - {d_check_proc, 14*2, 268, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0}, - {d_check_proc, 14*2, 284, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0}, - {d_check_proc, 14*2, 300, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0}, - {d_check_proc, 14*2, 316, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0}, - - {d_text_proc, 16*2, 16, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Machine :", 0, 0}, - {d_text_proc, 16*2, 36, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video :", 0, 0}, - {d_text_proc, 16*2, 56, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU type :", 0, 0}, - {d_text_proc, 16*2, 76, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU :", 0, 0}, - {d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0}, - {d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0}, - {d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0}, - {d_text_proc, 16*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0}, - - {d_check_proc, 14*2, 92, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Dynamic Recompiler", 0, 0}, - - {d_text_proc, 16*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive A: :", 0, 0}, - {d_text_proc, 16*2, 196, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive B: :", 0, 0}, - {d_list_proc, 70*2, 172, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, - {d_list_proc, 70*2, 192, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, - - {video_config_proc, 452, 32+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, //30 - {sound_config_proc, 452, 152+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - {voodoo_config_proc, 452, 316, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - - {d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Joystick :", 0, 0}, - {d_list_proc, 70*2, 212, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, //34 - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int list_proc(int msg, DIALOG *d, int c) -{ - int old = d->d1; - int ret = d_list_proc(msg, d, c); - - if (d->d1 != old) - { - int new_model = model_list[configure_dialog[3].d1].num; - int new_cpu_m = configure_dialog[5].d1; - int new_cpu = configure_dialog[6].d1; - int new_dynarec = configure_dialog[25].flags & D_SELECTED; - int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num); - int new_mem_size; - int cpu_flags; - - reset_list(); - - if (models[new_model].fixed_gfxcard) - configure_dialog[4].flags |= D_DISABLED; - else - configure_dialog[4].flags &= ~D_DISABLED; - - cpu_flags = models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_flags; - configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && new_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - configure_dialog[25].flags |= D_DISABLED; - - sscanf(mem_size_str, "%i", &new_mem_size); - new_mem_size &= ~(models[new_model].ram_granularity - 1); - if (new_mem_size < models[new_model].min_ram) - new_mem_size = models[new_model].min_ram; - else if (new_mem_size > models[new_model].max_ram) - new_mem_size = models[new_model].max_ram; - sprintf(mem_size_str, "%i", new_mem_size); - - if (models[new_model].is_at) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - if (!video_card_has_config(new_gfxcard)) - configure_dialog[30].flags |= D_DISABLED; - else - configure_dialog[30].flags &= ~D_DISABLED; - - if (!sound_card_has_config(configure_dialog[9].d1)) - configure_dialog[31].flags |= D_DISABLED; - else - configure_dialog[31].flags &= ~D_DISABLED; - - return D_REDRAW; - } - - return ret; -} - -static int video_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num); - - deviceconfig_open(video_card_getdevice(new_gfxcard)); - return D_O_K; - } - - return ret; -} -static int sound_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int new_sndcard = sound_list[configure_dialog[9].d1].num; - - deviceconfig_open(sound_card_getdevice(new_sndcard)); - return D_O_K; - } - - return ret; -} - -static void reset_list() -{ - int model = model_list[configure_dialog[3].d1].num; - int cpumanu = configure_dialog[5].d1; - int cpu = configure_dialog[6].d1; - int c; - - memset(cpumanu_list, 0, sizeof(cpumanu_list)); - memset(cpu_list, 0, sizeof(cpu_list)); - - c = 0; - while (models[model].cpu[c].cpus != NULL && c < 3) - { - strcpy(cpumanu_list[c].name, models[model].cpu[c].name); - cpumanu_list[c].num = c; - c++; - } - - if (cpumanu >= c) - cpumanu = configure_dialog[6].d1 = c-1; - - c = 0; - while (models[model].cpu[cpumanu].cpus[c].cpu_type != -1) - { - strcpy(cpu_list[c].name, models[model].cpu[cpumanu].cpus[c].name); - cpu_list[c].num = c; - c++; - } - - if (cpu >= c) - cpu = configure_dialog[7].d1 = c-1; -} - -int settings_configure() -{ - int c, d; - int cpu_flags; - - memset(model_list, 0, sizeof(model_list)); - memset(video_list, 0, sizeof(video_list)); - memset(sound_list, 0, sizeof(sound_list)); - - for (c = 0; c < ROM_MAX; c++) - romstolist[c] = 0; - c = d = 0; - while (models[c].id != -1) - { - pclog("INITDIALOG : %i %i %i\n",c,models[c].id,romspresent[models[c].id]); - if (romspresent[models[c].id]) - { - strcpy(model_list[d].name, models[c].name); - model_list[d].num = c; - if (c == model) - configure_dialog[3].d1 = d; - d++; - } - c++; - } - - if (models[model].fixed_gfxcard) - configure_dialog[4].flags |= D_DISABLED; - else - configure_dialog[4].flags &= ~D_DISABLED; - - c = d = 0; - while (1) - { - char *s = video_card_getname(c); - - if (!s[0]) - break; -pclog("video_card_available : %i\n", c); - if (video_card_available(c)) - { - strcpy(video_list[d].name, video_card_getname(c)); - video_list[d].num = video_new_to_old(c); - if (video_new_to_old(c) == gfxcard) - configure_dialog[4].d1 = d; - d++; - } - - c++; - } - - if (!video_card_has_config(video_old_to_new(gfxcard))) - configure_dialog[30].flags |= D_DISABLED; - else - configure_dialog[30].flags &= ~D_DISABLED; - - c = d = 0; - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - break; - - if (sound_card_available(c)) - { - strcpy(sound_list[d].name, sound_card_getname(c)); - sound_list[d].num = c; - if (c == sound_card_current) - configure_dialog[9].d1 = d; - d++; - } - - c++; - } - - c = 0; - while (joystick_get_name(c)) - { - strcpy(joystick_list[c].name, joystick_get_name(c)); - if (c == joystick_type) - configure_dialog[34].d1 = c; - - c++; - } - - if (!sound_card_has_config(configure_dialog[9].d1)) - configure_dialog[31].flags |= D_DISABLED; - else - configure_dialog[31].flags &= ~D_DISABLED; - - configure_dialog[5].d1 = cpu_manufacturer; - configure_dialog[6].d1 = cpu; - configure_dialog[7].d1 = cache; - configure_dialog[8].d1 = video_speed; - reset_list(); -// strcpy(cpumanu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].name); -// strcpy(cpu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].name); -// strcpy(cache_str, cache_str_list[cache]); -// strcpy(vidspeed_str, vidspeed_str_list[video_speed]); - -// strcpy(soundcard_str, sound_card_getname(sound_card_current)); - - if (GAMEBLASTER) - configure_dialog[12].flags |= D_SELECTED; - else - configure_dialog[12].flags &= ~D_SELECTED; - - if (GUS) - configure_dialog[13].flags |= D_SELECTED; - else - configure_dialog[13].flags &= ~D_SELECTED; - - if (SSI2001) - configure_dialog[14].flags |= D_SELECTED; - else - configure_dialog[14].flags &= ~D_SELECTED; - - if (cga_comp) - configure_dialog[15].flags |= D_SELECTED; - else - configure_dialog[15].flags &= ~D_SELECTED; - - if (voodoo_enabled) - configure_dialog[16].flags |= D_SELECTED; - else - configure_dialog[16].flags &= ~D_SELECTED; - - if (models[model].is_at) - sprintf(mem_size_str, "%i", mem_size / 1024); - else - sprintf(mem_size_str, "%i", mem_size); - - if (models[model].is_at) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - cpu_flags = models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; - configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - configure_dialog[25].flags |= D_DISABLED; - - configure_dialog[28].d1 = fdd_get_type(0); - configure_dialog[29].d1 = fdd_get_type(1); - - while (1) - { - position_dialog(configure_dialog, SCREEN_W/2 - configure_dialog[0].w/2, SCREEN_H/2 - configure_dialog[0].h/2); - - c = popup_dialog(configure_dialog, 1); - - position_dialog(configure_dialog, -(SCREEN_W/2 - configure_dialog[0].w/2), -(SCREEN_H/2 - configure_dialog[0].h/2)); - - if (c == 1) - { - int new_model = model_list[configure_dialog[3].d1].num; - int new_gfxcard = video_list[configure_dialog[4].d1].num; - int new_sndcard = sound_list[configure_dialog[9].d1].num; - int new_cpu_m = configure_dialog[5].d1; - int new_cpu = configure_dialog[6].d1; - int new_mem_size; - int new_has_fpu = (models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_type >= CPU_i486DX) ? 1 : 0; - int new_GAMEBLASTER = (configure_dialog[12].flags & D_SELECTED) ? 1 : 0; - int new_GUS = (configure_dialog[13].flags & D_SELECTED) ? 1 : 0; - int new_SSI2001 = (configure_dialog[14].flags & D_SELECTED) ? 1 : 0; - int new_voodoo = (configure_dialog[16].flags & D_SELECTED) ? 1 : 0; - int new_dynarec = (configure_dialog[25].flags & D_SELECTED) ? 1 : 0; - int new_fda = configure_dialog[28].d1; - int new_fdb = configure_dialog[29].d1; - - sscanf(mem_size_str, "%i", &new_mem_size); - new_mem_size &= ~(models[new_model].ram_granularity - 1); - if (new_mem_size < models[new_model].min_ram) - new_mem_size = models[new_model].min_ram; - else if (new_mem_size > models[new_model].max_ram) - new_mem_size = models[new_model].max_ram; - if (models[new_model].is_at) - new_mem_size *= 1024; - - if (new_model != model || new_gfxcard != gfxcard || new_mem_size != mem_size || - new_has_fpu != hasfpu || new_GAMEBLASTER != GAMEBLASTER || new_GUS != GUS || - new_SSI2001 != SSI2001 || new_sndcard != sound_card_current || new_voodoo != voodoo_enabled || - new_dynarec != cpu_use_dynarec || new_fda != fdd_get_type(0) || new_fdb != fdd_get_type(1)) - { - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1) - continue; - - model = new_model; - romset = model_getromset(); - gfxcard = new_gfxcard; - mem_size = new_mem_size; - cpu_manufacturer = new_cpu_m; - cpu = new_cpu; - GAMEBLASTER = new_GAMEBLASTER; - GUS = new_GUS; - SSI2001 = new_SSI2001; - sound_card_current = new_sndcard; - voodoo_enabled = new_voodoo; - cpu_use_dynarec = new_dynarec; - - mem_resize(); - loadbios(); - resetpchard(); - - fdd_set_type(0, new_fda); - fdd_set_type(1, new_fdb); - } - - video_speed = configure_dialog[8].d1; - - cga_comp = (configure_dialog[15].flags & D_SELECTED) ? 1 : 0; - - cpu_manufacturer = new_cpu_m; - cpu = new_cpu; - cpu_set(); - - cache = configure_dialog[7].d1; - mem_updatecache(); - - joystick_type = configure_dialog[34].d1; - gameport_update_joystick_type(); - - saveconfig(); - - speedchanged(); - - return D_O_K; - } - - if (c == 2) - return D_O_K; - } - - return D_O_K; -} - diff --git a/src/allegro-gui-deviceconfig.c b/src/allegro-gui-deviceconfig.c deleted file mode 100644 index 9dcbb5011..000000000 --- a/src/allegro-gui-deviceconfig.c +++ /dev/null @@ -1,306 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "config.h" - -static device_t *config_device; - -#define MAX_CONFIG_SIZE 64 -#define MAX_CONFIG_SELECTIONS 8 - -static device_config_selection_t *config_selections[MAX_CONFIG_SELECTIONS]; - -#define list_proc_device_func(i) \ - static char *list_proc_device_ ## i(int index, int *list_size) \ - { \ - device_config_selection_t *config = config_selections[i]; \ - \ - if (index < 0) \ - { \ - int c = 0; \ - \ - while (config[c].description[0]) \ - c++; \ - \ - *list_size = c; \ - return NULL; \ - } \ - \ - return config[index].description; \ - } - -list_proc_device_func(0) -list_proc_device_func(1) -list_proc_device_func(2) -list_proc_device_func(3) -list_proc_device_func(4) -list_proc_device_func(5) -list_proc_device_func(6) -list_proc_device_func(7) - -static DIALOG deviceconfig_dialog[MAX_CONFIG_SIZE] = -{ - {d_shadow_box_proc, 0, 0, 568,332,0,0xffffff,0,0, 0,0,0,0,0} // 0 -}; - -void deviceconfig_open(device_t *device) -{ - DIALOG *d; - device_config_t *config = device->config; - int y = 10; - int dialog_pos = 1; - int list_pos = 0; - int c; - int id_ok, id_cancel; - - memset((void *)((uintptr_t)deviceconfig_dialog) + sizeof(DIALOG), 0, sizeof(deviceconfig_dialog) - sizeof(DIALOG)); - deviceconfig_dialog[0].x = deviceconfig_dialog[0].y = 0; - - while (config->type != -1) - { - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - d->x = 32; - d->y = y; - - d->w = 118*2; - d->h = 15; - - d->dp = config->description; - d->proc = d_check_proc; - - d->flags = config_get_int(device->name, config->name, config->default_int) ? D_SELECTED : 0; - d->bg = 0xffffff; - d->fg = 0; - - dialog_pos++; - - y += 20; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d->x = 32; - d->y = y; - - d->w = 80; - d->h = 15; - - d->dp = config->description; - d->proc = d_text_proc; - - d->flags = 0; - d->bg = 0xffffff; - d->fg = 0; - - d++; - - d->x = 250; - d->y = y; - - d->w = 304; - d->h = 20; - - switch (list_pos) - { - case 0 : d->dp = list_proc_device_0; break; - case 1 : d->dp = list_proc_device_1; break; - case 2 : d->dp = list_proc_device_2; break; - case 3 : d->dp = list_proc_device_3; break; - case 4 : d->dp = list_proc_device_4; break; - case 5 : d->dp = list_proc_device_5; break; - case 6 : d->dp = list_proc_device_6; break; - case 7 : d->dp = list_proc_device_7; break; - } - d->proc = d_list_proc; - - d->flags = 0; - d->bg = 0xffffff; - d->fg = 0; - - config_selections[list_pos++] = config->selection; - - c = 0; - while (config->selection[c].description[0]) - { - if (config_get_int(device->name, config->name, config->default_int) == config->selection[c].value) - d->d1 = c; - c++; - } - - dialog_pos += 2; - - y += 20; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - d = &deviceconfig_dialog[dialog_pos]; - - id_ok = dialog_pos; - id_cancel = dialog_pos + 1; - - d->x = 226; - d->y = y+8; - - d->w = 50; - d->h = 16; - - d->dp = "OK"; - d->proc = d_button_proc; - - d->flags = D_EXIT; - d->bg = 0xffffff; - d->fg = 0; - - d++; - - d->x = 296; - d->y = y+8; - - d->w = 50; - d->h = 16; - - d->dp = "Cancel"; - d->proc = d_button_proc; - - d->flags = D_EXIT; - d->bg = 0xffffff; - d->fg = 0; - - deviceconfig_dialog[0].h = y + 28; - - config_device = device; - - while (1) - { - position_dialog(deviceconfig_dialog, SCREEN_W/2 - deviceconfig_dialog[0].w/2, SCREEN_H/2 - deviceconfig_dialog[0].h/2); - - c = popup_dialog(deviceconfig_dialog, 1); - - position_dialog(deviceconfig_dialog, -(SCREEN_W/2 - deviceconfig_dialog[0].w/2), -(SCREEN_H/2 - deviceconfig_dialog[0].h/2)); - - if (c == id_ok) - { - int changed = 0; - - dialog_pos = 1; - config = device->config; - - while (config->type != -1) - { - int val; - - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - val = (d->flags & D_SELECTED) ? 1 : 0; - - if (val != config_get_int(device->name, config->name, config->default_int)) - changed = 1; - - dialog_pos++; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d++; - - val = config->selection[d->d1].value; - - if (val != config_get_int(device->name, config->name, config->default_int)) - changed = 1; - - dialog_pos += 2; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - if (!changed) - return; - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1) - continue; - - dialog_pos = 1; - config = device->config; - - while (config->type != -1) - { - int val; - - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - val = (d->flags & D_SELECTED) ? 1 : 0; - - config_set_int(config_device->name, config->name, val); - - dialog_pos++; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d++; - - val = config->selection[d->d1].value; - - config_set_int(config_device->name, config->name, val); - - dialog_pos += 2; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - saveconfig(); - - resetpchard(); - - return; - } - - if (c == id_cancel) - break; - } -} diff --git a/src/allegro-gui-hdconf.c b/src/allegro-gui-hdconf.c deleted file mode 100644 index a493c319f..000000000 --- a/src/allegro-gui-hdconf.c +++ /dev/null @@ -1,516 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE - -#include -#include "ibm.h" -#include "device.h" -#include "ide.h" -#include "allegro-main.h" -#include "allegro-gui.h" - -static char hd_path[4][260]; -static char hd_sectors[4][10]; -static char hd_heads[4][10]; -static char hd_cylinders[4][10]; -static char hd_size[4][20]; - -static char hd_path_new[260]; -static char hd_sectors_new[10]; -static char hd_heads_new[10]; -static char hd_cylinders_new[10]; -static char hd_size_new[20]; - -static int new_cdrom_channel; - -static hard_disk_t hdc_new[4]; - -static DIALOG hdparams_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_text_proc, 7*2, 6, 170, 10, 0, 0xffffff, 0, 0, 0, 0, "Initial settings are based on file size", 0, 0}, - - {d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0}, - {d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0}, - {d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0}, - {d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size_new, 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int hdconf_open(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - char fn[260]; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - - strcpy(fn, hd_path[drv]); - ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize); - if (ret) - { - uint64_t sz; - FILE *f = fopen64(fn, "rb"); - if (!f) - { - return D_REDRAW; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - sprintf(hd_sectors_new, "63"); - sprintf(hd_heads_new, "16"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 16) / 63); - - while (1) - { - position_dialog(hdparams_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2); - - ret = popup_dialog(hdparams_dialog, 1); - - position_dialog(hdparams_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2)); - - if (ret == 1) - { - int spt, hpc, cyl; - sscanf(hd_sectors_new, "%i", &spt); - sscanf(hd_heads_new, "%i", &hpc); - sscanf(hd_cylinders_new, "%i", &cyl); - - if (spt > 63) - { - alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (hpc > 128) - { - alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (cyl > 16383) - { - alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - - hdc_new[drv].spt = spt; - hdc_new[drv].hpc = hpc; - hdc_new[drv].tracks = cyl; - - strcpy(hd_path[drv], fn); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - if (ret == 2) - break; - } - } - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_new_file(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - char fn[260]; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - - strcpy(fn, hd_path_new); - ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize); - if (ret) - strcpy(hd_path_new, fn); - - return D_REDRAW; - } - - return ret; -} - -static DIALOG hdnew_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_edit_proc, 7*2, 6, 136*2, 10, 0, 0xffffff, 0, 0, 0, 0, hd_path_new, 0, 0}, - {hdconf_new_file, 143*2, 6, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0}, - - {d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0}, - {d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0}, - {d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0}, -// {d_text_proc, 7*2, 54, 136, 12, 0, -1, 0, 0, 0, 0, hd_size_new, 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int create_hd(char *fn, int cyl, int hpc, int spt) -{ - int c; - int e; - uint8_t buf[512]; - FILE *f = fopen64(hd_path_new, "wb"); - e = errno; - if (!f) - { - alert("Can't open file for write", NULL, NULL, "OK", NULL, 0, 0); - return -1; - } - memset(buf, 0, 512); - for (c = 0; c < (cyl * hpc * spt); c++) - { - fwrite(buf, 512, 1, f); - } - fclose(f); -} - -static int hdconf_new(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - sprintf(hd_sectors_new, "63"); - sprintf(hd_heads_new, "16"); - sprintf(hd_cylinders_new, "511"); - strcpy(hd_path_new, ""); - - while (1) - { - position_dialog(hdnew_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2); - - ret = popup_dialog(hdnew_dialog, 1); - - position_dialog(hdnew_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2)); - - if (ret == 1) - { - int spt, hpc, cyl; - int c, d; - FILE *f; - uint8_t *buf; - - sscanf(hd_sectors_new, "%i", &spt); - sscanf(hd_heads_new, "%i", &hpc); - sscanf(hd_cylinders_new, "%i", &cyl); - - if (spt > 63) - { - alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (hpc > 128) - { - alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (cyl > 16383) - { - alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (create_hd(hd_path_new, cyl, hpc, spt)) - return D_REDRAW; - - alert("Remember to partition and format the new drive", NULL, NULL, "OK", NULL, 0, 0); - - hdc_new[drv].spt = spt; - hdc_new[drv].hpc = hpc; - hdc_new[drv].tracks = cyl; - - strcpy(hd_path[drv], hd_path_new); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - if (ret == 2) - break; - } - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_eject(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - hdc_new[drv].spt = 0; - hdc_new[drv].hpc = 0; - hdc_new[drv].tracks = 0; - strcpy(hd_path[drv], ""); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_radio_hd(int msg, DIALOG *d, int c); -static int hdconf_radio_cd(int msg, DIALOG *d, int c); - -static DIALOG hdconf_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 210*2,354,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 150, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 220, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_text_proc, 7*2, 6, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "C:", 0, 0}, - {hdconf_radio_hd, 7*2, 22, 96, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "Hard drive", 0, 0}, // 4 - {hdconf_radio_cd, 100*2, 22, 64, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "CD-ROM", 0, 0}, // 5 - {d_edit_proc, 7*2, 38, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[0], 0, 0}, - {hdconf_open, 143*2, 38, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0}, - {hdconf_new, 159*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "New", 0, 0}, - {hdconf_eject, 183*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Eject", 0, 0}, - - {d_text_proc, 7*2, 54, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 54, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 54, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[0], 0, 0}, - {d_edit_proc, 92*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[0], 0, 0}, - {d_edit_proc, 168*2, 54, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[0], 0, 0}, - {d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[0], 0, 0}, - - {d_text_proc, 7*2, 76, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "D:", 0, 0}, - {hdconf_radio_hd, 7*2, 92, 96, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "Hard drive", 0, 0}, // 18 - {hdconf_radio_cd, 100*2, 92, 64, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "CD-ROM", 0, 0}, // 19 - {d_edit_proc, 7*2, 108, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[1], 0, 0}, - {hdconf_open, 143*2, 108, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "...", 0, 0}, - {hdconf_new, 159*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "New", 0, 0}, - {hdconf_eject, 183*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[1], 0, 0}, - {d_edit_proc, 92*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[1], 0, 0}, - {d_edit_proc, 168*2, 124, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[1], 0, 0}, - {d_text_proc, 7*2, 124, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 124, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 124, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 140, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[1], 0, 0}, - - {d_text_proc, 7*2, 162, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "E:", 0, 0}, - {hdconf_radio_hd, 7*2, 178, 96, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "Hard drive", 0, 0}, // 32 - {hdconf_radio_cd, 100*2, 178, 64, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "CD-ROM", 0, 0}, // 33 - {d_edit_proc, 7*2, 194, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[2], 0, 0}, - {hdconf_open, 143*2, 194, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "...", 0, 0}, - {hdconf_new, 159*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "New", 0, 0}, - {hdconf_eject, 183*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[2], 0, 0}, - {d_edit_proc, 92*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[2], 0, 0}, - {d_edit_proc, 168*2, 210, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[2], 0, 0}, - {d_text_proc, 7*2, 210, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 210, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 210, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 226, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[2], 0, 0}, - - {d_text_proc, 7*2, 248, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "F:", 0, 0}, - {hdconf_radio_hd, 7*2, 264, 96, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "Hard drive", 0, 0}, // 46 - {hdconf_radio_cd, 100*2, 264, 64, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "CD-ROM", 0, 0}, // 47 - {d_edit_proc, 7*2, 280, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[3], 0, 0}, - {hdconf_open, 143*2, 280, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "...", 0, 0}, - {hdconf_new, 159*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "New", 0, 0}, - {hdconf_eject, 183*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[3], 0, 0}, - {d_edit_proc, 92*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[3], 0, 0}, - {d_edit_proc, 168*2, 296, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[3], 0, 0}, - {d_text_proc, 7*2, 296, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 296, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 296, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 312, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[3], 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static void update_hdd_cdrom() -{ - if (new_cdrom_channel == 0) - { - hdconf_dialog[4].flags &= ~D_SELECTED; - hdconf_dialog[5].flags |= D_SELECTED; - } - else - { - hdconf_dialog[4].flags |= D_SELECTED; - hdconf_dialog[5].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 1) - { - hdconf_dialog[18].flags &= ~D_SELECTED; - hdconf_dialog[19].flags |= D_SELECTED; - } - else - { - hdconf_dialog[18].flags |= D_SELECTED; - hdconf_dialog[19].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 2) - { - hdconf_dialog[32].flags &= ~D_SELECTED; - hdconf_dialog[33].flags |= D_SELECTED; - } - else - { - hdconf_dialog[32].flags |= D_SELECTED; - hdconf_dialog[33].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 3) - { - hdconf_dialog[46].flags &= ~D_SELECTED; - hdconf_dialog[47].flags |= D_SELECTED; - } - else - { - hdconf_dialog[46].flags |= D_SELECTED; - hdconf_dialog[47].flags &= ~D_SELECTED; - } -} - -static int hdconf_radio_hd(int msg, DIALOG *d, int c) -{ - int ret = d_radio_proc(msg, d, c); - - if (ret == D_CLOSE) - { - if (new_cdrom_channel == d->d1) - { - new_cdrom_channel = -1; - update_hdd_cdrom(); - } - - return D_REDRAW; - } - - return ret; -} -static int hdconf_radio_cd(int msg, DIALOG *d, int c) -{ - int ret = d_radio_proc(msg, d, c); - - if (ret == D_CLOSE) - { - if (new_cdrom_channel != d->d1) - { - new_cdrom_channel = d->d1; - update_hdd_cdrom(); - } - - return D_REDRAW; - } - - return ret; -} - -int disc_hdconf() -{ - int c; - int changed=0; - - hdc_new[0] = hdc[0]; - hdc_new[1] = hdc[1]; - hdc_new[2] = hdc[2]; - hdc_new[3] = hdc[3]; - strcpy(hd_path[0], ide_fn[0]); - strcpy(hd_path[1], ide_fn[1]); - strcpy(hd_path[2], ide_fn[2]); - strcpy(hd_path[3], ide_fn[3]); - sprintf(hd_sectors[0], "%i", hdc[0].spt); - sprintf(hd_sectors[1], "%i", hdc[1].spt); - sprintf(hd_sectors[2], "%i", hdc[2].spt); - sprintf(hd_sectors[3], "%i", hdc[3].spt); - sprintf(hd_heads[0], "%i", hdc[0].hpc); - sprintf(hd_heads[1], "%i", hdc[1].hpc); - sprintf(hd_heads[2], "%i", hdc[2].hpc); - sprintf(hd_heads[3], "%i", hdc[3].hpc); - sprintf(hd_cylinders[0], "%i", hdc[0].tracks); - sprintf(hd_cylinders[1], "%i", hdc[1].tracks); - sprintf(hd_cylinders[2], "%i", hdc[2].tracks); - sprintf(hd_cylinders[3], "%i", hdc[3].tracks); - sprintf(hd_size[0], "Size : %imb", (((((uint64_t)hdc[0].tracks*(uint64_t)hdc[0].hpc)*(uint64_t)hdc[0].spt)*512)/1024)/1024); - sprintf(hd_size[1], "Size : %imb", (((((uint64_t)hdc[1].tracks*(uint64_t)hdc[1].hpc)*(uint64_t)hdc[1].spt)*512)/1024)/1024); - sprintf(hd_size[2], "Size : %imb", (((((uint64_t)hdc[2].tracks*(uint64_t)hdc[2].hpc)*(uint64_t)hdc[2].spt)*512)/1024)/1024); - sprintf(hd_size[3], "Size : %imb", (((((uint64_t)hdc[3].tracks*(uint64_t)hdc[3].hpc)*(uint64_t)hdc[3].spt)*512)/1024)/1024); - - new_cdrom_channel = cdrom_channel; - - update_hdd_cdrom(); - - while (1) - { - position_dialog(hdconf_dialog, SCREEN_W/2 - hdconf_dialog[0].w/2, SCREEN_H/2 - hdconf_dialog[0].h/2); - - c = popup_dialog(hdconf_dialog, 1); - - position_dialog(hdconf_dialog, -(SCREEN_W/2 - hdconf_dialog[0].w/2), -(SCREEN_H/2 - hdconf_dialog[0].h/2)); - - if (c == 1) - { - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - hdc[0] = hdc_new[0]; - hdc[1] = hdc_new[1]; - hdc[2] = hdc_new[2]; - hdc[3] = hdc_new[3]; - - strcpy(ide_fn[0], hd_path[0]); - strcpy(ide_fn[1], hd_path[1]); - strcpy(ide_fn[2], hd_path[2]); - strcpy(ide_fn[3], hd_path[3]); - - cdrom_channel = new_cdrom_channel; - - saveconfig(); - - resetpchard(); - - return D_O_K; - } - } - if (c == 2) - return D_O_K; - } - - return D_O_K; -} diff --git a/src/allegro-gui.c b/src/allegro-gui.c deleted file mode 100644 index 63b6ddef8..000000000 --- a/src/allegro-gui.c +++ /dev/null @@ -1,229 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "disc.h" -#include "ide.h" - -static int file_return(void) -{ - return D_CLOSE; -} - -static int file_exit(void) -{ - quited = 1; - return D_CLOSE; -} - -static int file_reset(void) -{ - resetpchard(); - return D_CLOSE; -} - -static int file_cad(void) -{ - resetpc_cad(); - return D_CLOSE; -} - - -static MENU file_menu[]= -{ - {"&Return", file_return, NULL, 0, NULL}, - {"&Hard Reset", file_reset, NULL, 0, NULL}, - {"&Ctrl+Alt+Del", file_cad, NULL, 0, NULL}, - {"E&xit", file_exit, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static int disc_load_a() -{ - char fn[260]; - int ret; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, discfns[0]); - ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize); - if (ret) - { - disc_close(0); - disc_load(0, fn); - saveconfig(); - } - return D_O_K; -} - -static int disc_load_b() -{ - char fn[260]; - int ret; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, discfns[1]); - ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize); - if (ret) - { - disc_close(1); - disc_load(1, fn); - saveconfig(); - } - return D_O_K; -} - -static int disc_eject_a() -{ - disc_close(0); - saveconfig(); - - return D_O_K; -} - -static int disc_eject_b() -{ - disc_close(1); - saveconfig(); - - return D_O_K; -} - -static MENU disc_menu[]= -{ - {"Load drive &A:...", disc_load_a, NULL, 0, NULL}, - {"Load drive &B:...", disc_load_b, NULL, 0, NULL}, - {"&Eject drive &A:", disc_eject_a, NULL, 0, NULL}, - {"Eject drive &B:", disc_eject_b, NULL, 0, NULL}, - {"&Configure hard discs...", disc_hdconf, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU cdrom_menu[]; - -static void cdrom_update() -{ - int c; - - for (c = 0; cdrom_menu[c].text; c++) - cdrom_menu[c].flags = 0; - - if (!cdrom_enabled) - cdrom_menu[0].flags = D_SELECTED; - else - cdrom_menu[1].flags = D_SELECTED; - - return D_O_K; -} - -static int cdrom_disabled() -{ - if (!cdrom_enabled) - return D_O_K; - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - atapi->exit(); - cdrom_enabled = 0; - saveconfig(); - resetpchard(); - cdrom_update(); - } - - return D_O_K; -} - -static int cdrom_empty() -{ - if (cdrom_enabled) - { - atapi->exit(); - cdrom_drive = -1; - cdrom_null_open(cdrom_drive); - return D_O_K; - } - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = -1; - cdrom_enabled = 1; - cdrom_null_open(cdrom_drive); - saveconfig(); - resetpchard(); - cdrom_update(); - } -} - -static int cdrom_dev() -{ - if (cdrom_enabled) - { - atapi->exit(); - cdrom_drive = 1; - ioctl_open(cdrom_drive); - return D_O_K; - } - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = 1; - cdrom_enabled = 1; - ioctl_open(cdrom_drive); - saveconfig(); - resetpchard(); - cdrom_update(); - } -} - -static MENU cdrom_menu[] = -{ - {"&Disabled", cdrom_disabled, NULL, 0, NULL}, - {"&Empty", cdrom_empty, NULL, 0, NULL}, - {"/dev/cdrom", cdrom_dev, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU settings_menu[]= -{ - {"&Configure...", settings_configure, NULL, 0, NULL}, - {"CD-ROM", NULL, cdrom_menu, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU main_menu[]= -{ - {"&File", NULL, file_menu, 0, NULL}, - {"&Disc", NULL, disc_menu, 0, NULL}, - {"&Settings", NULL, settings_menu, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static DIALOG main_windows_gui[]= -{ - {d_menu_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, main_menu, NULL, NULL}, - {d_yield_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, NULL, NULL, NULL}, - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -void gui_enter() -{ - DIALOG_PLAYER *dp; - int x = 1; - infocus = 0; - - dp = init_dialog(main_windows_gui, 0); - show_mouse(screen); - while (x && !(mouse_b & 2) && !key[KEY_ESC]) - { - x = update_dialog(dp); - } - show_mouse(NULL); - shutdown_dialog(dp); - - clear(screen); - clear_keybuf(); - - infocus = 1; - - device_force_redraw(); -} diff --git a/src/allegro-gui.h b/src/allegro-gui.h deleted file mode 100644 index 1ea830552..000000000 --- a/src/allegro-gui.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void gui_enter(); - -extern int quited; - -extern int romspresent[ROM_MAX]; -extern int gfx_present[GFX_MAX]; - -int disc_hdconf(); - -int settings_configure(); - -void deviceconfig_open(device_t *device); diff --git a/src/allegro-joystick.c b/src/allegro-joystick.c deleted file mode 100644 index ed03267f9..000000000 --- a/src/allegro-joystick.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-joystick.h" -#include "device.h" -#include "gameport.h" - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; - -int joysticks_present; - -void joystick_init() -{ - install_joystick(JOY_TYPE_AUTODETECT); - joysticks_present = num_joysticks; -} -void joystick_close() -{ -} -void joystick_poll() -{ - int c, d; - - poll_joystick(); - - for (c = 0; c < num_joysticks; c++) - { - plat_joystick_state[c].a[0] = joy[c].stick[0].axis[0].pos * 256; - plat_joystick_state[c].a[1] = joy[c].stick[0].axis[1].pos * 256; - for (d = 0; d < MAX_JOYSTICK_BUTTONS; d++) - plat_joystick_state[c].b[d] = joy[c].button[d].b; - } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (c < num_joysticks) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = plat_joystick_state[c].a[d]; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[c].b[d]; - } - else - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - } - } -} diff --git a/src/allegro-keyboard.c b/src/allegro-keyboard.c deleted file mode 100644 index a3e3c3a51..000000000 --- a/src/allegro-keyboard.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-keyboard.h" - -int recv_key[272]; -int rawinputkey[272]; - -static int key_convert[128] = -{ - -1, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* , A, B, C, D, E, F, G*/ - 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* H, I, J, K, L, M, N, O*/ - 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* P, Q, R, S, T, U, V, W*/ - 0x2d, 0x15, 0x2c, 0x0b, 0x02, 0x03, 0x04, 0x05, /* X, Y, Z, 0, 1, 2, 3, 4*/ - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x52, 0x4f, 0x50, /* 5, 6, 7, 8, 9, p0, p1, p2*/ - 0x51, 0x4b, 0x4c, 0x4d, 0x47, 0x48, 0x49, 0x3b, /* p3, p4, p5, p6, p7, p8, p9, F1*/ - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, /* F2, F3, F4, F5, F6, F7, F8, F9*/ - 0x44, 0x57, 0x58, 0x01, 0x29, 0x0c, 0x0d, 0x0e, /*F10, F11, F12, ESC, `ª, -_, =+, backspace*/ - 0x0f, 0x1a, 0x1b, 0x1c, 0x27, 0x28, 0x2b, 0x56, /*TAB, [{, ]}, ENT, ;:, '@, \|, #~*/ - 0x33, 0x34, 0x35, 0x39, 0xd2, 0xd3, 0xc7, 0xcf, /* ,<, .>, /?, SPC, INS, DEL, HOME, END*/ - 0xc9, 0xd1, 0xcb, 0xcd, 0xc8, 0xd0, 0xb5, 0x37, /*PGU, PGD, LFT, RHT, UP, DN, /, * */ - 0x4a, 0x4e, 0x53, 0x9c, 0xff, -1, -1, -1, /* p-, p+, pDL, pEN, psc, pse, abnt, yen*/ - -1, -1, -1, -1, -1, -1, -1, -1, /*kana, convert, noconvert, at, circumflex, colon2, kanji, pad equals*/ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 0x2a, 0x36, 0x1d, 0x9d, 0x38, /*, , lshift, rshift, lctrl, rctrl, alt*/ - 0xb8, 0xdb, 0xdc, 0xdd, 0x46, 0x45, 0x3a, -1 /*altgr, lwin, rwin, menu, scrlock, numlock, capslock*/ -}; - -void keyboard_init() -{ - install_keyboard(); -} - -void keyboard_close() -{ -} - -void keyboard_poll_host() -{ - int c; - - for (c = 0; c < 128; c++) - { - int key_idx = key_convert[c]; - if (key_idx == -1) - continue; - - if (key[c] != recv_key[key_idx]) - recv_key[key_idx] = key[c]; - } -} diff --git a/src/allegro-main.c b/src/allegro-main.c deleted file mode 100644 index 65bd43aea..000000000 --- a/src/allegro-main.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "cpu.h" -#include "model.h" -#include "nvr.h" -#include "video.h" - -#undef printf - -int mousecapture = 0; -int quited = 0; -int winsizex = -1, winsizey = -1; - -int romspresent[ROM_MAX]; -int gfx_present[GFX_MAX]; - -void updatewindowsize(int x, int y) -{ - if (x < 128) - x = 128; - if (y < 128) - y = 128; - if (winsizex != x || winsizey != y) - { - winsizex = x; - winsizey = y; - allegro_video_update_size(x, y); - } -} - -void startblit() -{ -} - -void endblit() -{ -} - -static int ticks = 0; -static void timer_rout() -{ - ticks++; -} - -uint64_t timer_freq; -uint64_t timer_read() -{ - return 0; -} - -int main(int argc, char *argv[]) -{ - int frames = 0; - int c, d; - allegro_init(); - allegro_video_init(); - install_timer(); - install_int_ex(timer_rout, BPS_TO_TIMER(100)); - install_int_ex(onesec, BPS_TO_TIMER(1)); - midi_init(); - - initpc(argc, argv); - - d = romset; - for (c = 0; c < ROM_MAX; c++) - { - romset = c; - romspresent[c] = loadbios(); - pclog("romset %i - %i\n", c, romspresent[c]); - } - - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - break; - } - if (c == ROM_MAX) - { - printf("No ROMs present!\nYou must have at least one romset to use 86Box."); - return 0; - } - - romset=d; - c=loadbios(); - - if (!c) - { - if (romset != -1) - printf("Configured romset not available.\nDefaulting to available romset."); - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - { - romset = c; - model = model_getmodel(romset); - saveconfig(); - resetpchard(); - break; - } - } - } - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); - - if (!video_card_available(video_old_to_new(gfxcard))) - { - if (gfxcard) printf("Configured video BIOS not available.\nDefaulting to available romset."); - for (c = GFX_MAX-1; c >= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - saveconfig(); - resetpchard(); - break; - } - } - } - - resetpchard(); - - ticks = 0; - while (!quited) - { - if (ticks) - { - ticks--; - runpc(); - frames++; - if (frames >= 200 && nvr_dosave) - { - frames = 0; - nvr_dosave = 0; - savenvr(); - } - } - else - rest(1); - - if (ticks > 10) - ticks = 0; - - if ((mouse_b & 1) && !mousecapture) - mousecapture = 1; - - if (((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_END]) || (mouse_b & 4)) - mousecapture = 0; - - if ((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_ALT] && key[KEY_PGDN]) - { - int old_winsizex = winsizex, old_winsizey = winsizey; - if (winsizex < 512 || winsizey < 350) - updatewindowsize(512, 350); - gui_enter(); - if (old_winsizex < 512 || old_winsizey < 350) - updatewindowsize(old_winsizex, old_winsizey); - ticks = 0; - } - } - - closepc(); - - midi_close(); - - return 0; -} - -END_OF_MAIN(); diff --git a/src/allegro-main.h b/src/allegro-main.h deleted file mode 100644 index 4498defd3..000000000 --- a/src/allegro-main.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define getr8 allegro_getr8 -#define setr8 allegro_setr8 -#define get_filename allegro_get_filename -#define append_filename allegro_append_filename -#define put_backslash allegro_put_backslash -#define get_extension allegro_get_extension -#define GFX_VGA allegro_GFX_VGA -#define MAX_JOYSTICKS allegro_MAX_JOYSTICKS - -#include - -#undef MAX_JOYSTICKS -#undef GFX_VGA -#undef getr8 -#undef setr8 -#undef get_filename -#undef append_filename -#undef put_backslash -#undef get_extension diff --git a/src/allegro-midi.c b/src/allegro-midi.c deleted file mode 100644 index 9178f9e35..000000000 --- a/src/allegro-midi.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "plat-midi.h" - -//#define USE_ALLEGRO_MIDI - -void midi_init() -{ -#ifdef USE_ALLEGRO_MIDI - install_sound(DIGI_NONE, MIDI_AUTODETECT, NULL); -#endif -} - -void midi_close() -{ -#ifdef USE_ALLEGRO_MIDI - remove_sound(); -#endif -} - -static int midi_cmd_pos, midi_len; -static uint8_t midi_command[3]; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 0}; - -void midi_write(uint8_t val) -{ - if (val & 0x80) - { - midi_cmd_pos = 0; - midi_len = midi_lengths[(val >> 4) & 7]; - midi_command[0] = midi_command[1] = midi_command[2] = 0; - } - - if (midi_len && midi_cmd_pos < 3) - { - midi_command[midi_cmd_pos] = val; - - midi_cmd_pos++; - -#ifdef USE_ALLEGRO_MIDI - if (midi_cmd_pos == midi_len) - midi_out(midi_command, midi_len); -#endif - } -} diff --git a/src/allegro-mouse.c b/src/allegro-mouse.c deleted file mode 100644 index 60f287361..000000000 --- a/src/allegro-mouse.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-mouse.h" - -int mouse_buttons; - -void mouse_init() -{ - install_mouse(); -} - -void mouse_close() -{ -} - -void mouse_poll_host() -{ - //poll_mouse(); - mouse_buttons = mouse_b; -} - -void mouse_get_mickeys(int *x, int *y) -{ - if (mousecapture) - { - get_mouse_mickeys(x, y); -// position_mouse(64, 64); - } - else - *x = *y = 0; -} - diff --git a/src/allegro-video.c b/src/allegro-video.c deleted file mode 100644 index a4897ffc6..000000000 --- a/src/allegro-video.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "video.h" - -#include "allegro-video.h" - -static PALETTE cgapal= -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - -static uint32_t pal_lookup[256]; - -static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void allegro_blit_memtoscreen_8(int x, int y, int w, int h); -static BITMAP *buffer32_vscale; -void allegro_video_init() -{ - int c; - - set_color_depth(32); - set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); - video_blit_memtoscreen = allegro_blit_memtoscreen; - video_blit_memtoscreen_8 = allegro_blit_memtoscreen_8; - - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); - - buffer32_vscale = create_bitmap(2048, 2048); -} - -void allegro_video_close() -{ - destroy_bitmap(buffer32_vscale); -} - -void allegro_video_update_size(int x, int y) -{ - if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, x, y, 0, 0)) - fatal("Failed to set gfx mode %i,%i : %s\n", x, y, allegro_error); -} - -static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - if (h < winsizey) - { - int yy; - - for (yy = y+y1; yy < y+y2; yy++) - { - if (yy >= 0) - { - memcpy(&((uint32_t *)buffer32_vscale->line[yy*2])[x], &((uint32_t *)buffer32->line[yy])[x], w*4); - memcpy(&((uint32_t *)buffer32_vscale->line[(yy*2)+1])[x], &((uint32_t *)buffer32->line[yy])[x], w*4); - } - } - - blit(buffer32_vscale, screen, x, (y+y1)*2, 0, y1, w, (y2-y1)*2); - } - else - blit(buffer32, screen, x, y+y1, 0, y1, w, y2-y1); -} - -static void allegro_blit_memtoscreen_8(int x, int y, int w, int h) -{ - int xx, yy; - int line_double = (winsizey > h) ? 1 : 0; - - if (y < 0) - { - h += y; - y = 0; - } - - for (yy = y; yy < y+h; yy++) - { - int dy = line_double ? yy*2 : yy; - if (dy < buffer->h) - { - if (line_double) - { - for (xx = x; xx < x+w; xx++) - { - ((uint32_t *)buffer32->line[dy])[xx] = - ((uint32_t *)buffer32->line[dy + 1])[xx] = pal_lookup[buffer->line[yy][xx]]; - } - } - else - { - for (xx = x; xx < x+w; xx++) - ((uint32_t *)buffer32->line[dy])[xx] = pal_lookup[buffer->line[yy][xx]]; - } - } - } - - if (readflash) - { - if (line_double) - rectfill(buffer32, x+SCREEN_W-40, y*2+8, SCREEN_W-8, y*2+14, makecol(255, 255, 255)); - else - rectfill(buffer32, x+SCREEN_W-40, y+8, SCREEN_W-8, y+14, makecol(255, 255, 255)); - readflash = 0; - } - - if (line_double) - blit(buffer32, screen, x, y*2, 0, 0, w, h*2); - else - blit(buffer32, screen, x, y, 0, 0, w, h); -} diff --git a/src/allegro-video.h b/src/allegro-video.h deleted file mode 100644 index bcd05b28d..000000000 --- a/src/allegro-video.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void allegro_video_init(); -void allegro_video_close(); -void allegro_video_update_size(int x, int y); diff --git a/src/amstrad.c b/src/amstrad.c index c1f0ef763..a6dacab9c 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -15,7 +15,7 @@ uint8_t amstrad_read(uint16_t port, void *priv) switch (port) { case 0x379: - return 7 | readdacfifo(); + return 7; case 0x37a: if (romset == ROM_PC1512) return 0x20; if (romset == ROM_PC200) return 0x80; diff --git a/src/bugger.c b/src/bugger.c index d9a79aafa..ce5ed03a9 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -44,7 +44,7 @@ * configuration register (CTRL_SPCFG bit set) but have to * remember that stuff first... * - * Version: @(#)bugger.c 1.0.3 2017/04/07 + * Version: @(#)bugger.c 1.0.4 2017/05/09 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -98,10 +98,8 @@ bug_setui(void) (bug_ledr&0x08)?'R':'r', (bug_ledr&0x04)?'R':'r', (bug_ledr&0x02)?'R':'r', (bug_ledr&0x01)?'R':'r'); -#if 0 /* Send formatted string to the UI. */ - set_bugui(bug_str); -#endif + status_settext(bug_str); } diff --git a/src/buslogic.h b/src/buslogic.h deleted file mode 100644 index c4b6805f0..000000000 --- a/src/buslogic.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef BUSLOGIC_H -# define BUSLOGIC_H - - -typedef struct { - uint8_t flags; /* local flags */ - uint8_t bid; /* board ID */ - char fwl, fwh; /* firmware info */ -} aha_info; -#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ - - -extern device_t aha1540b_device; -extern device_t aha1542cf_device; -extern device_t buslogic_device; -extern device_t buslogic_pci_device; - - -extern int buslogic_dev_present(uint8_t id, uint8_t lun); - -extern void aha154x_init(uint16_t, uint32_t, aha_info *); -extern uint8_t aha154x_shram(uint8_t); -extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); -extern uint8_t aha154x_memory(uint8_t); - - -#endif /*BUSLOGIC_H*/ diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp new file mode 100644 index 000000000..86f09e8c8 --- /dev/null +++ b/src/cdrom-dosbox.cpp @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom-dosbox.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0; + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + track.attr = 0;//sync with load iso + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/cdrom-dosbox.h b/src/cdrom-dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom-dosbox.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool IsMode2 (unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 000000000..1959a8328 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,1201 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +#include "config.h" +#include "cdrom-dosbox.h" +#include "cdrom.h" +#include "cdrom-image.h" +#include "cdrom-null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 0; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + } + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + uint8_t *q; + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + int lb; + + if (cdrom_image[id].image_is_iso) + { + if (starttrack > 1 && starttrack != 0xaa) + return -1; + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + if (starttrack <= 1) { + *q++ = 0; /* reserved */ + *q++ = 0x14; /* ADR, control */ + *q++ = 1; /* track number */ + *q++ = 0; /* reserved */ + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } else { + /* sector 0 */ + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + } + /* lead out track */ + *q++ = 0; /* reserved */ + *q++ = 0x16; /* ADR, control */ + *q++ = 0xaa; /* track number */ + *q++ = 0; /* reserved */ + lb = image_size(id) - 1; + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } else { + *q++ = lb >> 24; + *q++ = lb >> 16; + *q++ = lb >> 8; + *q++ = lb; + } + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + + if (len > maxlen) + { + len = maxlen; + } + + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + int len = 4; + int number; + TMSF tmsf; + unsigned char attr; + uint8_t *q; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + + if (maxlen < 12) + { + return maxlen; + } + return 12; + } + + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + if (maxlen < len) + { + return maxlen; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + uint8_t *q; + int lb; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* first track */ + *q++ = 0x00; /* disk type */ + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa1; + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* last track */ + *q++ = 0x00; + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa2; /* lead-out */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + lb = image_size(id) >> 11; + /* this is raw, must be msf */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } + else + { + *q++ = (lb >> 24) & 0xff; + *q++ = (lb >> 16) & 0xff; + *q++ = (lb >> 8) & 0xff; + *q++ = lb & 0xff; + } + + *q++ = 1; /* session number */ + *q++ = 0x14; /* ADR, control */ + *q++ = 0; /* track number */ + *q++ = 1; /* point */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + /* same here */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } + else + { + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + if (msf) + { + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + } + return len; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} + +void image_reset(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + + update_status_bar_icon_state(0x10 | id, 0); + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h new file mode 100644 index 000000000..415956e56 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,26 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +void update_status_bar_icon_state(int tag, int state); +extern void cdrom_set_null_handler(uint8_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */ diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 5ab4d09a3..98c7cc538 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -107,6 +107,11 @@ static int get_track_nr(uint8_t id, uint32_t pos) return 0; } + if (cdrom_ioctl[id].last_track_pos == pos) + { + return cdrom_ioctl[id].last_track_nr; + } + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) { uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + @@ -118,6 +123,9 @@ static int get_track_nr(uint8_t id, uint32_t pos) track = c; } } + cdrom_ioctl[id].last_track_pos = pos; + cdrom_ioctl[id].last_track_nr = track; + return track; } @@ -349,19 +357,35 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; unsigned long size; - int pos=0; + int pos = 0, track; + uint32_t cdpos, track_address, dat; + if (!cdrom_drives[id].host_drive) return 0; - - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(id); + + cdpos = cdrom[id].seek_pos; + + if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + { + memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); + memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + } + else + { + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); + ioctl_close(id); + memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); + memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); + memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); + memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); + cdrom_ioctl[id].last_subchannel_pos = cdpos; + } if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) { - uint32_t cdpos = cdrom[id].seek_pos; - int track = get_track_nr(id, cdpos); - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); + track = get_track_nr(id, cdpos); + track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); @@ -371,7 +395,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (msf) { - uint32_t dat = cdpos; + dat = cdpos; b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; b[pos + 1] = (uint8_t)dat; @@ -709,11 +733,19 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; UCHAR buf[16]; - ioctl_open(id, 0); + if (!cdrom_ioctl[id].capacity_read) + { + ioctl_open(id, 0); - SCSICommand(id, cdb, buf, &len, 1); + SCSICommand(id, cdb, buf, &len, 1); - memcpy(b, buf, len); + memcpy(cdrom_ioctl[id].rcbuf, buf, len); + cdrom_ioctl[id].capacity_read = 1; + } + else + { + memcpy(b, cdrom_ioctl[id].rcbuf, 16); + } ioctl_close(id); } @@ -1016,8 +1048,11 @@ int ioctl_open(uint8_t id, char d) if (!cdrom_ioctl[id].ioctl_inited) { cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; + update_status_bar_icon_state(0x10 | id, 0); } return 0; } @@ -1050,7 +1085,6 @@ static CDROM ioctl_cdrom= NULL, ioctl_getcurrentsubchannel, ioctl_pass_through, - ioctl_sector_data_type, NULL, ioctl_playaudio, ioctl_load, diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c deleted file mode 100644 index 7fc01b246..000000000 --- a/src/cdrom-iso.c +++ /dev/null @@ -1,630 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -/*ISO CD-ROM support*/ - -#include - -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-iso.h" - -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#include - -static CDROM iso_cdrom; - -int cdrom_iso_do_log = 0; - -void cdrom_iso_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_ISO_LOG - if (cdrom_iso_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void iso_close(uint8_t id); - -void iso_audio_callback(uint8_t id, int16_t *output, int len) -{ - memset(output, 0, len * 2); - return; -} - -void iso_audio_stop(uint8_t id) -{ - return; -} - -static int iso_ready(uint8_t id) -{ - if (strlen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - return 1; -} - -static int iso_medium_changed(uint8_t id) -{ - if (strlen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - return 0; -} - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - int pos=0; - int32_t temp; - if (strlen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - b[pos++]=0; - b[pos++]=0; - b[pos++]=0; - - temp = cdrom[id].seek_pos; - if (msf) - { - memset(&(b[pos]), 0, 8); - lba_to_msf(&(b[pos]), temp); - pos += 4; - lba_to_msf(&(b[pos]), temp); - pos += 4; - } - else - { - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } - - return 0x15; -} - -static void iso_eject(uint8_t id) -{ - return; -} - -static void iso_load(uint8_t id) -{ - return; -} - -static int iso_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 2; /* Always Mode 1 */ -} - -static void iso_readsector(uint8_t id, uint8_t *b, int sector) -{ - uint64_t file_pos = sector; - if (!cdrom_drives[id].host_drive) - { - return; - } - file_pos <<= 11; - memset(b, 0, 2856); - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); - fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); - fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); - fclose(cdrom_iso[id].iso_image); - - /* sync bytes */ - b[0] = 0; - memset(b + 1, 0xff, 10); - b[11] = 0; - b += 12; - lba_to_msf(b, sector); - b[3] = 1; /* mode 1 data */ - b += 4; - b += 2048; - memset(b, 0, 288); - b += 288; - memset(b, 0, 392); -} - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2352]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; - -static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - uint8_t *b; - uint8_t *temp_b; - int real_pos; - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) - { - real_pos = cdrom_lba_to_msf_accurate(sector); - } - else - { - real_pos = sector; - } - - memset(cdrom_sector_buffer.buffer, 0, 2856); - - if ((cdrom_sector_type == 1) || (cdrom_sector_type > 2)) - { - if (cdrom_sector_type == 1) - { - cdrom_iso_log("CD-ROM %i: Attempting to read an audio sector from an ISO\n", id); - } - if (cdrom_sector_type >= 2) - { - cdrom_iso_log("CD-ROM %i: Attempting to read a non-mode 1 data sector from an ISO\n", id); - } - return 0; - } - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_iso_log("CD-ROM %i: 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_iso_log("CD-ROM %i: Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_iso_log("CD-ROM %i: Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - iso_readsector(id, cdrom_sector_buffer.buffer, real_pos); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_iso_log("CD-ROM %i: Sync\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_iso_log("CD-ROM %i: Header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - cdrom_iso_log("CD-ROM %i: Sub-header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_iso_log("CD-ROM %i: User data\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) - { - cdrom_iso_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - cdrom_iso_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - cdrom_iso_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - -static int iso_readtoc(uint8_t id, unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single) -{ - uint8_t *q; - int len; - - if (start_track > 1 && start_track != 0xaa) - return -1; - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - if (start_track <= 1) { - *q++ = 0; /* reserved */ - *q++ = 0x14; /* ADR, control */ - *q++ = 1; /* track number */ - *q++ = 0; /* reserved */ - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } else { - /* sector 0 */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - } - /* lead out track */ - *q++ = 0; /* reserved */ - *q++ = 0x16; /* ADR, control */ - *q++ = 0xaa; /* track number */ - *q++ = 0; /* reserved */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } else { - *q++ = cdrom_iso[id].last_block >> 24; - *q++ = cdrom_iso[id].last_block >> 16; - *q++ = cdrom_iso[id].last_block >> 8; - *q++ = cdrom_iso[id].last_block; - } - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static int iso_readtoc_session(uint8_t id, unsigned char *buf, int msf, int maxlen) -{ - uint8_t *q; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - - if (maxlen < 12) - { - return maxlen; - } - return 12; -} - -static int iso_readtoc_raw(uint8_t id, unsigned char *buf, int msf, int maxlen) -{ - uint8_t *q; - int len; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* first track */ - *q++ = 0x00; /* disk type */ - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa1; - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* last track */ - *q++ = 0x00; - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa2; /* lead-out */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - /* this is raw, must be msf */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } - else - { - *q++ = (cdrom_iso[id].last_block >> 24) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 16) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 8) & 0xff; - *q++ = cdrom_iso[id].last_block & 0xff; - } - - *q++ = 1; /* session number */ - *q++ = 0x14; /* ADR, control */ - *q++ = 0; /* track number */ - *q++ = 1; /* point */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - /* same here */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } - else - { - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static uint32_t iso_size(uint8_t id) -{ - uint64_t iso_size; - - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); - fseeko64(cdrom_iso[id].iso_image, 0, SEEK_END); - iso_size = ftello64(cdrom_iso[id].iso_image); - iso_size >>= 11; - fclose(cdrom_iso[id].iso_image); - - return (uint32_t) (iso_size); -} - -static int iso_status(uint8_t id) -{ - if (!(iso_ready(id)) && (cdrom_drives[id].host_drive != 200)) return CD_STATUS_EMPTY; - - return CD_STATUS_DATA_ONLY; -} - -void iso_reset(uint8_t id) -{ -} - -int iso_open(uint8_t id, char *fn) -{ - struct stat64 st; - - if (strcmp(fn, cdrom_iso[id].iso_path) != 0) - { - cdrom_iso[id].iso_changed = 1; - } - /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (!cdrom_iso[id].iso_inited && (cdrom_drives[id].host_drive != 200)) cdrom_iso[id].iso_changed = 0; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - sprintf(cdrom_iso[id].iso_path, "%s", fn); - } - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); - cdrom_drives[id].handler = &iso_cdrom; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - if (!cdrom_iso[id].iso_inited) cdrom_iso[id].iso_inited = 1; - fclose(cdrom_iso[id].iso_image); - } - - stat64(cdrom_iso[id].iso_path, &st); - cdrom_iso[id].image_size = st.st_size; - - return 0; -} - -void iso_close(uint8_t id) -{ - if (cdrom_iso[id].iso_image) fclose(cdrom_iso[id].iso_image); - memset(cdrom_iso[id].iso_path, 0, 1024); -} - -static void iso_exit(uint8_t id) -{ - cdrom_iso[id].iso_inited = 0; -} - -static int iso_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - return 0; -} - -static int iso_media_type_id(uint8_t id) -{ - if (iso_size(id) <= 405000) - { - return 1; /* Data CD. */ - } - else - { - return 65; /* DVD. */ - } -} - -static CDROM iso_cdrom = -{ - iso_ready, - iso_medium_changed, - iso_media_type_id, - NULL, - NULL, - iso_readtoc, - iso_readtoc_session, - iso_readtoc_raw, - iso_getcurrentsubchannel, - NULL, - iso_sector_data_type, - iso_readsector_raw, - NULL, - iso_load, - iso_eject, - NULL, - NULL, - iso_size, - iso_status, - iso_is_track_audio, - NULL, - iso_exit -}; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h deleted file mode 100644 index c16ea0ebb..000000000 --- a/src/cdrom-iso.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_ISO_H -#define CDROM_ISO_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern int iso_open(uint8_t id, char *fn); -extern void iso_reset(uint8_t id); - -extern void iso_close(uint8_t id); - -#endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 9c52cc848..f7d117077 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -31,11 +31,6 @@ static void null_load(uint8_t id) { } -static int null_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 0; -} - static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { *len = 0; @@ -71,9 +66,11 @@ void cdrom_null_reset(uint8_t id) { } +void cdrom_set_null_handler(uint8_t id); + int cdrom_null_open(uint8_t id, char d) { - cdrom_drives[id].handler = &null_cdrom; + cdrom_set_null_handler(id); return 0; } @@ -100,28 +97,34 @@ static int null_media_type_id(uint8_t id) return 0x70; } +void cdrom_set_null_handler(uint8_t id) +{ + cdrom_drives[id].handler = &null_cdrom; + cdrom_drives[id].host_drive = 0; + update_status_bar_icon_state(0x10 | id, 1); +} + static CDROM null_cdrom = { - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, + null_ready, + null_medium_changed, + null_media_type_id, + NULL, + NULL, null_readtoc, null_readtoc_session, - null_readtoc_raw, + null_readtoc_raw, null_getcurrentsubchannel, null_pass_through, - null_sector_data_type, - null_readsector_raw, + null_readsector_raw, NULL, null_load, null_eject, NULL, NULL, null_size, - null_status, - null_is_track_audio, + null_status, + null_is_track_audio, NULL, null_exit }; diff --git a/src/cdrom.c b/src/cdrom.c index 8cf6e3174..8617e35af 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -978,16 +978,16 @@ void cdrom_mode_sense_load(uint8_t id) switch(id) { case 0: - f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"rb"); break; case 1: - f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"rb"); break; case 2: - f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"rb"); break; case 3: - f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"rb"); break; default: return; @@ -1006,16 +1006,16 @@ void cdrom_mode_sense_save(uint8_t id) switch(id) { case 0: - f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"wb"); break; case 1: - f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"wb"); break; case 2: - f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"wb"); break; case 3: - f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"wb"); break; default: return; @@ -2424,19 +2424,17 @@ void cdrom_command(uint8_t id, uint8_t *cdb) toc_format = (cdb[9] >> 6) & 3; } - len = cdb[8] + (cdb[7] << 8); - switch (toc_format) { case 0: /*Normal*/ - len = cdrom_drives[id].handler->readtoc(id, cdbufferb, cdb[6], msf, len, 0); + len = cdrom_drives[id].handler->readtoc(id, cdbufferb, cdb[6], msf, max_len, 0); break; case 1: /*Multi session*/ - len = cdrom_drives[id].handler->readtoc_session(id, cdbufferb, msf, len); + len = cdrom_drives[id].handler->readtoc_session(id, cdbufferb, msf, max_len); cdbufferb[0] = 0; cdbufferb[1] = 0xA; break; case 2: /*Raw*/ - len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, len); + len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, max_len); break; default: cdrom_invalid_field(id); @@ -2444,6 +2442,14 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } } + if (len > max_len) + { + len = max_len; + + cdbufferb[0] = ((len - 2) >> 8) & 0xff; + cdbufferb[1] = (len - 2) & 0xff; + } + cdrom_data_command_finish(id, len, len, len, 0); /* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); */ return; @@ -2893,8 +2899,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; } - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || - !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) + if ((cdrom_drive < 1) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { cdrom_illegal_mode(id); break; @@ -2954,7 +2959,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) alloc_length = 24; break; } - if (alloc_length < len) + if (!(cdb[2] & 0x40) || (cdb[3] == 0)) + { + len = 4; + } + else { len = alloc_length; } diff --git a/src/cdrom.h b/src/cdrom.h index eb5e4066e..a3a3a69a9 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -15,7 +15,7 @@ #define BUF_SIZE 32768 -#define CDROM_ISO 200 +#define CDROM_IMAGE 200 #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) @@ -32,7 +32,6 @@ typedef struct CDROM int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); - int (*sector_data_type)(uint8_t id, int sector, int ismsf); int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); void (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf); void (*load)(uint8_t id); @@ -170,18 +169,23 @@ extern void (*ide_bus_master_set_irq)(int channel); typedef struct { - uint32_t last_block; - uint64_t image_size; - int iso_inited; - char iso_path[1024]; - FILE* iso_image; - int iso_changed; + int image_is_iso; + uint32_t last_block; + uint32_t cdrom_capacity; + int image_inited; + wchar_t image_path[1024]; + FILE* image; + int image_changed; + + int cd_state; uint32_t cd_pos; uint32_t cd_end; -} cdrom_iso_t; + int16_t cd_buffer[BUF_SIZE]; + int cd_buflen; +} cdrom_image_t; -cdrom_iso_t cdrom_iso[CDROM_NUM]; +cdrom_image_t cdrom_image[CDROM_NUM]; typedef struct { @@ -195,6 +199,13 @@ typedef struct int16_t cd_buffer[BUF_SIZE]; int cd_buflen; int actual_requested_blocks; + int last_track_pos; + int last_track_nr; + int capacity_read; + uint8_t rcbuf[16]; + uint8_t sub_q_data_format[16]; + uint8_t sub_q_channel_data[256]; + int last_subchannel_pos; } cdrom_ioctl_t; void ioctl_close(uint8_t id); @@ -211,7 +222,17 @@ void cdrom_command(uint8_t id, uint8_t *cdb); void cdrom_phase_callback(uint8_t id); uint32_t cdrom_read(uint8_t channel, int length); void cdrom_write(uint8_t channel, uint32_t val, int length); + +#ifdef __cplusplus +extern "C" { +#endif + int cdrom_lba_to_msf_accurate(int lba); + +#ifdef __cplusplus +} +#endif + void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); diff --git a/src/config.c b/src/config.c index 1e22f6415..8b31042d3 100644 --- a/src/config.c +++ b/src/config.c @@ -2,14 +2,38 @@ see COPYING for more details */ #include +#include #include #include +#include + +#include "cdrom.h" #include "config.h" +#include "device.h" +#include "disc.h" +#include "fdc.h" +#include "fdd.h" #include "ibm.h" +#include "cpu/cpu.h" +#include "gameport.h" +#include "ide.h" +#include "hdd.h" +#include "model.h" +#include "mouse.h" +#include "network.h" +#include "nvr.h" +#include "plat-joystick.h" +#include "scsi.h" +#include "sound/snd_dbopl.h" +#include "sound/snd_opl.h" +#include "sound/sound.h" +#include "video/video.h" -char config_file_default[256]; -static char config_file[256]; +wchar_t config_file_default[256]; + +static wchar_t config_file[256]; + typedef struct list_t { @@ -33,6 +57,7 @@ typedef struct entry_t char name[256]; char data[256]; + wchar_t wdata[256]; } entry_t; #define list_add(new, head) \ @@ -46,7 +71,7 @@ typedef struct entry_t (new)->next = NULL; \ } -void config_dump() +void config_dump(void) { section_t *current_section; @@ -73,7 +98,7 @@ void config_dump() } } -void config_free() +void config_free(void) { section_t *current_section; current_section = (section_t *)config_head.next; @@ -98,9 +123,9 @@ void config_free() } } -void config_load(char *fn) +void config_load(wchar_t *fn) { - FILE *f = fopen(fn, "rt"); + FILE *f = _wfopen(fn, L"rt, ccs=UNICODE"); section_t *current_section; memset(&config_head, 0, sizeof(list_t)); @@ -115,32 +140,34 @@ void config_load(char *fn) while (1) { int c; - char buffer[256]; + wchar_t buffer[1024]; + int org_pos; - fgets(buffer, 255, f); + memset(buffer, 0, 2048); + fgetws(buffer, 255, f); if (feof(f)) break; c = 0; - while (buffer[c] == ' ') + while (buffer[c] == L' ') c++; - if (!buffer[c]) continue; + if (buffer[c] == L'\0') continue; - if (buffer[c] == '#') /*Comment*/ + if (buffer[c] == L'#') /*Comment*/ continue; - if (buffer[c] == '[') /*Section*/ + if (buffer[c] == L'[') /*Section*/ { section_t *new_section; char name[256]; int d = 0; c++; - while (buffer[c] != ']' && buffer[c]) - name[d++] = buffer[c++]; + while (buffer[c] != L']' && buffer[c]) + wctomb(&(name[d++]), buffer[c++]); - if (buffer[c] != ']') + if (buffer[c] != L']') continue; name[d] = 0; @@ -157,13 +184,13 @@ void config_load(char *fn) char name[256]; int d = 0, data_pos; - while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) - name[d++] = buffer[c++]; + while (buffer[c] != L'=' && buffer[c] != L' ' && buffer[c]) + wctomb(&(name[d++]), buffer[c++]); - if (!buffer[c]) continue; + if (buffer[c] == L'\0') continue; name[d] = 0; - while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) + while ((buffer[c] == L'=' || buffer[c] == L' ') && buffer[c]) c++; if (!buffer[c]) continue; @@ -171,15 +198,18 @@ void config_load(char *fn) data_pos = c; while (buffer[c]) { - if (buffer[c] == '\n') - buffer[c] = 0; + if (buffer[c] == L'\n') + buffer[c] = L'\0'; c++; } new_entry = malloc(sizeof(entry_t)); memset(new_entry, 0, sizeof(entry_t)); strncpy(new_entry->name, name, 256); - strncpy(new_entry->data, &buffer[data_pos], 256); + memcpy(new_entry->wdata, &buffer[data_pos], 512); + new_entry->wdata[255] = L'\0'; + wcstombs(new_entry->data, new_entry->wdata, 512); + new_entry->data[255] = '\0'; list_add(&new_entry->list, ¤t_section->entry_head); } } @@ -191,9 +221,9 @@ void config_load(char *fn) -void config_new() +void config_new(void) { - FILE *f = fopen(config_file, "wt"); + FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); fclose(f); } @@ -292,6 +322,24 @@ char *config_get_string(char *head, char *name, char *def) return entry->data; } +wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + return entry->wdata; +} + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -308,6 +356,7 @@ void config_set_int(char *head, char *name, int val) entry = create_entry(section, name); sprintf(entry->data, "%i", val); + mbstowcs(entry->wdata, entry->data, 512); } void config_set_string(char *head, char *name, char *val) @@ -326,6 +375,25 @@ void config_set_string(char *head, char *name, char *val) entry = create_entry(section, name); strncpy(entry->data, val, 256); + mbstowcs(entry->wdata, entry->data, 256); +} + +void config_set_wstring(char *head, char *name, wchar_t *val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + memcpy(entry->wdata, val, 512); } @@ -336,7 +404,19 @@ char *get_filename(char *s) { if (s[c] == '/' || s[c] == '\\') return &s[c+1]; - c--; + c--; + } + return s; +} + +wchar_t *get_filename_w(wchar_t *s) +{ + int c = wcslen(s) - 1; + while (c > 0) + { + if (s[c] == L'/' || s[c] == L'\\') + return &s[c+1]; + c--; } return s; } @@ -346,6 +426,11 @@ void append_filename(char *dest, char *s1, char *s2, int size) sprintf(dest, "%s%s", s1, s2); } +void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size) +{ + _swprintf(dest, L"%s%s", s1, s2); +} + void put_backslash(char *s) { int c = strlen(s) - 1; @@ -353,6 +438,13 @@ void put_backslash(char *s) s[c] = '/'; } +void put_backslash_w(wchar_t *s) +{ + int c = wcslen(s) - 1; + if (s[c] != L'/' && s[c] != L'\\') + s[c] = L'/'; +} + char *get_extension(char *s) { int c = strlen(s) - 1; @@ -369,9 +461,27 @@ char *get_extension(char *s) return &s[c+1]; } -void config_save(char *fn) +wchar_t *get_extension_w(wchar_t *s) { - FILE *f = fopen(fn, "wt"); + int c = wcslen(s) - 1; + + if (c <= 0) + return s; + + while (c && s[c] != L'.') + c--; + + if (!c) + return &s[wcslen(s)]; + + return &s[c+1]; +} + +static wchar_t wname[512]; + +void config_save(wchar_t *fn) +{ + FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); section_t *current_section; current_section = (section_t *)config_head.next; @@ -381,13 +491,24 @@ void config_save(char *fn) entry_t *current_entry; if (current_section->name[0]) - fprintf(f, "\n[%s]\n", current_section->name); + { + mbstowcs(wname, current_section->name, strlen(current_section->name) + 1); + fwprintf(f, L"\n[%ws]\n", wname); + } current_entry = (entry_t *)current_section->entry_head.next; while (current_entry) { - fprintf(f, "%s = %s\n", current_entry->name, current_entry->data); + mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); + if (current_entry->wdata[0] == L'\0') + { + fwprintf(f, L"%ws = \n", wname); + } + else + { + fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); + } current_entry = (entry_t *)current_entry->list.next; } @@ -397,3 +518,476 @@ void config_save(char *fn) fclose(f); } +void loadconfig(wchar_t *fn) +{ + int c, d; + char s[512]; + char *p; + wchar_t *wp, *wq; + char temps[512]; + + if (!fn) + config_load(config_file_default); + else + config_load(fn); + + GAMEBLASTER = !!config_get_int(NULL, "gameblaster", 0); + GUS = !!config_get_int(NULL, "gus", 0); + SSI2001 = !!config_get_int(NULL, "ssi2001", 0); + voodoo_enabled = !!config_get_int(NULL, "voodoo", 0); + + /* SCSI */ + p = (char *)config_get_string(NULL, "scsicard", ""); + if (p) + scsi_card_current = scsi_card_get_from_internal_name(p); + else + scsi_card_current = 0; + + /* Network */ + network_type = config_get_int(NULL, "net_type", -1); + p = (char *)config_get_string(NULL, "net_card", NULL); + network_card = (p) ? network_card_get_from_internal_name(p) : 0; + + p = (char *)config_get_string(NULL, "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; + + if (model >= model_count()) + model = model_count() - 1; + + romset = model_getromset(); + cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); + cpu = config_get_int(NULL, "cpu", 0); + cpu_use_dynarec = !!config_get_int(NULL, "cpu_use_dynarec", 0); + + cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); + + p = (char *)config_get_string(NULL, "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; + video_speed = config_get_int(NULL, "video_speed", 3); + p = (char *)config_get_string(NULL, "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; + + mem_size = config_get_int(NULL, "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + if (mem_size > 1048576) + { + mem_size = 1048576; + } + + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); + if (p) + fdd_set_type(c, fdd_get_from_internal_name(p)); + else + fdd_set_type(c, (c < 2) ? 2 : 0); + if (fdd_get_type(c) > 13) + { + fdd_set_type(c, 13); + } + + sprintf(temps, "fdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(discfns[c], wp, 512); + else { + memcpy(discfns[c], L"", 2); + discfns[c][0] = L'\0'; + } + printf("Floppy: %ws\n", discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!config_get_int(NULL, temps, 0); + } + + p = (char *)config_get_string(NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + ide_enable[c] = config_get_int(NULL, temps, 0); + sprintf(temps, "ide_%02i_irq", c + 1); + ide_irq[c] = config_get_int(NULL, temps, 8 + c); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + hdc[c].spt = config_get_int(NULL, temps, 0); + if (hdc[c].spt > 99) + { + hdc[c].spt = 99; + } + sprintf(temps, "hdd_%02i_heads", c + 1); + hdc[c].hpc = config_get_int(NULL, temps, 0); + if (hdc[c].hpc > 64) + { + hdc[c].hpc = 64; + } + sprintf(temps, "hdd_%02i_cylinders", c + 1); + hdc[c].tracks = config_get_int(NULL, temps, 0); + if (hdc[c].tracks > 266305) + { + hdc[c].tracks = 266305; + } + sprintf(temps, "hdd_%02i_bus_type", c + 1); + hdc[c].bus = config_get_int(NULL, temps, 0); + if (hdc[c].bus > 4) + { + hdc[c].bus = 4; + } + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + hdc[c].mfm_channel = config_get_int(NULL, temps, 0); + if (hdc[c].mfm_channel > 1) + { + hdc[c].mfm_channel = 1; + } + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + hdc[c].ide_channel = config_get_int(NULL, temps, 0); + if (hdc[c].ide_channel > 7) + { + hdc[c].ide_channel = 7; + } + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); + if (hdc[c].scsi_id > 15) + { + hdc[c].scsi_id = 15; + } + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + hdc[c].scsi_lun = config_get_int(NULL, temps, 0); + if (hdc[c].scsi_lun > 7) + { + hdc[c].scsi_lun = 7; + } + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(hdd_fn[c], wp, 512); + else { + memcpy(hdd_fn[c], L"", 2); + hdd_fn[c][0] = L'\0'; + } + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); + cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; + sprintf(temps, "cdrom_%02i_enabled", c + 1); + cdrom_drives[c].enabled = !!config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + cdrom_drives[c].sound_on = !!config_get_int(NULL, temps, 1); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); + if (cdrom_drives[c].bus_type > 1) + { + cdrom_drives[c].bus_type = 1; + } + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + cdrom_drives[c].atapi_dma = !!config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); + if (cdrom_drives[c].ide_channel > 7) + { + cdrom_drives[c].ide_channel = 7; + } + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); + if (cdrom_drives[c].scsi_device_id > 15) + { + cdrom_drives[c].scsi_device_id = 15; + } + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); + if (cdrom_drives[c].scsi_device_lun > 7) + { + cdrom_drives[c].scsi_device_lun = 7; + } + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + else { + memcpy(cdrom_image[c].image_path, L"", 2); + cdrom_image[c].image_path[0] = L'\0'; + } + } + + vid_resize = !!config_get_int(NULL, "vid_resize", 0); + vid_api = config_get_int(NULL, "vid_api", 0); + video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); + + force_43 = !!config_get_int(NULL, "force_43", 0); + scale = !!config_get_int(NULL, "scale", 1); + enable_overscan = !!config_get_int(NULL, "enable_overscan", 0); + + enable_sync = !!config_get_int(NULL, "enable_sync", 1); + opl3_type = !!config_get_int(NULL, "opl3_type", 1); + + window_w = config_get_int(NULL, "window_w", 0); + window_h = config_get_int(NULL, "window_h", 0); + window_x = config_get_int(NULL, "window_x", 0); + window_y = config_get_int(NULL, "window_y", 0); + window_remember = config_get_int(NULL, "window_remember", 0); + + joystick_type = config_get_int(NULL, "joystick_type", 0); + p = (char *)config_get_string(NULL, "mouse_type", ""); + if (p) + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; + + enable_external_fpu = !!config_get_int(NULL, "enable_external_fpu", 0); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); + } + } + } + + memset(nvr_path, 0, 2048); + wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); + if (wp) { + if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); + else + { + append_filename_w(nvr_path, pcempath, L"nvr", 511); + } + } + else append_filename_w(nvr_path, pcempath, L"nvr", 511); + + if (nvr_path[wcslen(nvr_path) - 1] != L'/') + { + if (nvr_path[wcslen(nvr_path) - 1] != L'\\') + { + nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path) + 1] = L'\0'; + } + } + + path_len = wcslen(nvr_path); + + serial_enabled[0] = !!config_get_int(NULL, "serial1_enabled", 1); + serial_enabled[1] = !!config_get_int(NULL, "serial2_enabled", 1); + lpt_enabled = !!config_get_int(NULL, "lpt_enabled", 1); + bugger_enabled = !!config_get_int(NULL, "bugger_enabled", 0); +} + +wchar_t temp_nvr_path[1024]; + +wchar_t *nvr_concat(wchar_t *to_concat) +{ + char *p; + + memset(temp_nvr_path, 0, 2048); + wcscpy(temp_nvr_path, nvr_path); + + p = (char *) temp_nvr_path; + p += (path_len * 2); + wchar_t *wp = (wchar_t *) p; + + wcscpy(wp, to_concat); + return temp_nvr_path; +} + +void saveconfig(void) +{ + int c, d; + + char temps[512]; + + config_set_int(NULL, "gameblaster", GAMEBLASTER); + config_set_int(NULL, "gus", GUS); + config_set_int(NULL, "ssi2001", SSI2001); + config_set_int(NULL, "voodoo", voodoo_enabled); + + config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + + config_set_string(NULL, "net_card", network_card_get_internal_name(network_card)); + config_set_int(NULL, "net_type", network_type); +#if 1 + config_set_int(NULL, "maclocal", ne2000_get_maclocal()); + config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci()); +#endif + + config_set_string(NULL, "model", model_get_internal_name()); + config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); + config_set_int(NULL, "cpu", cpu); + config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(NULL, "cpu_waitstates", cpu_waitstates); + + config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(NULL, "video_speed", video_speed); + config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); + config_set_int(NULL, "cpu_speed", cpuspeed); + config_set_int(NULL, "has_fpu", hasfpu); + + config_set_int(NULL, "mem_size", mem_size); + + memset(temps, 0, 512); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); + sprintf(temps, "fdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_set_int(NULL, temps, ui_writeprot[c]); + } + + config_set_string(NULL, "hdd_controller", hdd_controller_name); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + config_set_int(NULL, temps, ide_enable[c]); + sprintf(temps, "ide_%02i_irq", c + 1); + config_set_int(NULL, temps, ide_irq[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + config_set_int(NULL, temps, hdc[c].spt); + sprintf(temps, "hdd_%02i_heads", c + 1); + config_set_int(NULL, temps, hdc[c].hpc); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + config_set_int(NULL, temps, hdc[c].tracks); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + config_set_int(NULL, temps, hdc[c].bus); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + config_set_int(NULL, temps, hdc[c].mfm_channel); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, hdc[c].ide_channel); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_id); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_lun); + sprintf(temps, "hdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, hdd_fn[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].host_drive); + sprintf(temps, "cdrom_%02i_enabled", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].enabled); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].sound_on); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].bus_type); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].ide_channel); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_set_wstring(NULL, temps, cdrom_image[c].image_path); + } + + config_set_int(NULL, "vid_resize", vid_resize); + config_set_int(NULL, "vid_api", vid_api); + config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); + + config_set_int(NULL, "force_43", force_43); + config_set_int(NULL, "scale", scale); + config_set_int(NULL, "enable_overscan", enable_overscan); + + config_set_int(NULL, "enable_sync", enable_sync); + config_set_int(NULL, "opl3_type", opl3_type); + + config_set_int(NULL, "joystick_type", joystick_type); + config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); + + config_set_int(NULL, "enable_external_fpu", enable_external_fpu); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + char s[80]; + + sprintf(s, "joystick_%i_nr", c); + config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); + } + } + } + + config_set_int(NULL, "window_w", window_w); + config_set_int(NULL, "window_h", window_h); + config_set_int(NULL, "window_x", window_x); + config_set_int(NULL, "window_y", window_y); + config_set_int(NULL, "window_remember", window_remember); + + config_set_int(NULL, "serial1_enabled", serial_enabled[0]); + config_set_int(NULL, "serial2_enabled", serial_enabled[1]); + config_set_int(NULL, "lpt_enabled", lpt_enabled); + config_set_int(NULL, "bugger_enabled", bugger_enabled); + + config_save(config_file_default); +} diff --git a/src/config.h b/src/config.h index 55e091e52..766257f37 100644 --- a/src/config.h +++ b/src/config.h @@ -3,17 +3,35 @@ */ int config_get_int(char *head, char *name, int def); char *config_get_string(char *head, char *name, char *def); +wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); void config_set_int(char *head, char *name, int val); void config_set_string(char *head, char *name, char *val); +void config_set_wstring(char *head, char *name, wchar_t *val); char *get_filename(char *s); +wchar_t *get_filename_w(wchar_t *s); void append_filename(char *dest, char *s1, char *s2, int size); +void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); void put_backslash(char *s); +void put_backslash_w(wchar_t *s); char *get_extension(char *s); -void config_load(char *fn); -void config_save(char *fn); -void config_dump(); -void config_free(); +#ifdef __cplusplus +extern "C" { +#endif -extern char config_file_default[256]; +wchar_t *get_extension_w(wchar_t *s); + +#ifdef __cplusplus +} +#endif + +void config_load(wchar_t *fn); +void config_save(wchar_t *fn); +void config_dump(void); +void config_free(void); + +extern wchar_t config_file_default[256]; + +void loadconfig(wchar_t *fn); +void saveconfig(void); diff --git a/src/dac.c b/src/dac.c deleted file mode 100644 index 7aecf02f5..000000000 --- a/src/dac.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "dac.h" - -uint8_t dac,dac2; -uint8_t dacctrl; -int lptfifo; -uint8_t dssbuffer[16]; -int dssstart=0,dssend=0; -int dssmode=0; - -void writedac(uint16_t addr, uint8_t val) -{ - if (dssmode) dac2=val; - else dac=val; -} - -void writedacctrl(uint16_t addr, uint8_t val) -{ - if (dacctrl&8 && !(val&8) && (lptfifo!=16)) - { - dssbuffer[dssend++]=dac2; - dssend&=15; - lptfifo++; - } - dacctrl=val; -} - -uint8_t readdacfifo() -{ - if (lptfifo==16) return 0x40; - return 0; -} - -void pollss() -{ - if (lptfifo) - { - dac=dssbuffer[dssstart++]; - dssstart&=15; - lptfifo--; - } -} - -int16_t dacbuffer[SOUNDBUFLEN+20]; -int dacbufferpos=0; -void getdacsamp() -{ - if (dacbufferposSOUNDBUFLEN) dacbufferpos=SOUNDBUFLEN; - for (c=0;c + #include "ibm.h" #include "config.h" @@ -56,78 +59,79 @@ void (*fdc_indexpulse)();*/ static struct { - char *ext; - void (*load)(int drive, char *fn); + wchar_t *ext; + void (*load)(int drive, wchar_t *fn); void (*close)(int drive); int size; } loaders[]= { - {"001", img_load, img_close, -1}, - {"002", img_load, img_close, -1}, - {"003", img_load, img_close, -1}, - {"004", img_load, img_close, -1}, - {"005", img_load, img_close, -1}, - {"006", img_load, img_close, -1}, - {"007", img_load, img_close, -1}, - {"008", img_load, img_close, -1}, - {"009", img_load, img_close, -1}, - {"010", img_load, img_close, -1}, - {"12", img_load, img_close, -1}, - {"144", img_load, img_close, -1}, - {"360", img_load, img_close, -1}, - {"720", img_load, img_close, -1}, - {"86F", d86f_load, d86f_close, -1}, - {"BIN", img_load, img_close, -1}, - {"CQ", img_load, img_close, -1}, - {"CQM", img_load, img_close, -1}, - {"DSK", img_load, img_close, -1}, - {"FDI", fdi_load, fdi_close, -1}, - {"FDF", img_load, img_close, -1}, - {"FLP", img_load, img_close, -1}, - {"HDM", img_load, img_close, -1}, - {"IMA", img_load, img_close, -1}, - {"IMD", imd_load, imd_close, -1}, - {"IMG", img_load, img_close, -1}, - {"TD0", td0_load, td0_close, -1}, - {"VFD", img_load, img_close, -1}, - {"XDF", img_load, img_close, -1}, + {L"001", img_load, img_close, -1}, + {L"002", img_load, img_close, -1}, + {L"003", img_load, img_close, -1}, + {L"004", img_load, img_close, -1}, + {L"005", img_load, img_close, -1}, + {L"006", img_load, img_close, -1}, + {L"007", img_load, img_close, -1}, + {L"008", img_load, img_close, -1}, + {L"009", img_load, img_close, -1}, + {L"010", img_load, img_close, -1}, + {L"12", img_load, img_close, -1}, + {L"144", img_load, img_close, -1}, + {L"360", img_load, img_close, -1}, + {L"720", img_load, img_close, -1}, + {L"86F", d86f_load, d86f_close, -1}, + {L"BIN", img_load, img_close, -1}, + {L"CQ", img_load, img_close, -1}, + {L"CQM", img_load, img_close, -1}, + {L"DSK", img_load, img_close, -1}, + {L"FDI", fdi_load, fdi_close, -1}, + {L"FDF", img_load, img_close, -1}, + {L"FLP", img_load, img_close, -1}, + {L"HDM", img_load, img_close, -1}, + {L"IMA", img_load, img_close, -1}, + {L"IMD", imd_load, imd_close, -1}, + {L"IMG", img_load, img_close, -1}, + {L"TD0", td0_load, td0_close, -1}, + {L"VFD", img_load, img_close, -1}, + {L"XDF", img_load, img_close, -1}, {0,0,0} }; static int driveloaders[4]; -void disc_load(int drive, char *fn) +void disc_load(int drive, wchar_t *fn) { int c = 0, size; - char *p; + wchar_t *p; FILE *f; if (!fn) return; - p = get_extension(fn); + p = get_extension_w(fn); if (!p) return; - f = fopen(fn, "rb"); + f = _wfopen(fn, L"rb"); if (!f) return; fseek(f, -1, SEEK_END); size = ftell(f) + 1; fclose(f); while (loaders[c].ext) { - if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) + if (!_wcsicmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { driveloaders[drive] = c; loaders[c].load(drive, fn); drive_empty[drive] = 0; - strcpy(discfns[drive], fn); + memcpy(discfns[drive], fn, (wcslen(fn) << 1) + 2); fdd_forced_seek(real_drive(drive), 0); disc_changed[drive] = 1; return; } c++; } - pclog("Couldn't load %s %s\n",fn,p); + pclog_w(L"Couldn't load %s %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = 0; + discfns[drive][0] = L'\0'; + update_status_bar_icon_state(drive, 1); } void disc_close(int drive) @@ -135,7 +139,7 @@ void disc_close(int drive) if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = 0; + discfns[drive][0] = L'\0'; drives[drive].hole = NULL; drives[drive].poll = NULL; drives[drive].seek = NULL; @@ -146,6 +150,7 @@ void disc_close(int drive) drives[drive].format = NULL; drives[drive].byteperiod = NULL; drives[drive].stop = NULL; + update_status_bar_icon_state(drive, 1); } int disc_notfound=0; diff --git a/src/disc.h b/src/disc.h index 32bb601a0..4bf7a96cb 100644 --- a/src/disc.h +++ b/src/disc.h @@ -21,7 +21,7 @@ extern DRIVE drives[FDD_NUM]; extern int curdrive; -void disc_load(int drive, char *fn); +void disc_load(int drive, wchar_t *fn); void disc_new(int drive, char *fn); void disc_close(int drive); void disc_init(); diff --git a/src/disc_86f.c b/src/disc_86f.c index 83df71198..eca278532 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "lzf/lzf.h" @@ -229,7 +230,7 @@ struct __attribute__((__packed__)) uint32_t error_condition; int is_compressed; int id_found; - char original_file_name[2048]; + wchar_t original_file_name[2048]; uint8_t *filebuf; uint8_t *outbuf; uint32_t dma_over; @@ -724,6 +725,10 @@ int d86f_wrong_densel(int drive) { case 0: default: + if (fdd_is_dd(drive)) + { + return 0; + } if (fdd_get_densel(drive)) { return 1; @@ -734,6 +739,10 @@ int d86f_wrong_densel(int drive) } break; case 1: + if (fdd_is_dd(drive)) + { + return 1; + } if (fdd_get_densel(drive)) { return 0; @@ -751,6 +760,10 @@ int d86f_wrong_densel(int drive) } break; case 2: + if (fdd_is_dd(drive) || !fdd_is_ed(drive)) + { + return 1; + } if (fdd_get_densel(drive)) { return 0; @@ -1896,7 +1909,11 @@ void d86f_format_track(int drive, int side, int do_write) break; case FMT_SECTOR_DATA: max_len = dtl; - if (do_write) d86f_write_direct(drive, side, d86f[drive].fill, 0); + if (do_write) + { + d86f_write_direct(drive, side, d86f[drive].fill, 0); + d86f_handler[drive].write_data(drive, side, d86f[drive].datac++, d86f[drive].fill); + } d86f_calccrc(drive, d86f[drive].fill); break; case FMT_SECTOR_GAP3: @@ -2726,7 +2743,7 @@ void d86f_writeback(int drive) /* The image is compressed. */ /* Open the original, compressed file. */ - cf = fopen(d86f[drive].original_file_name, "wb"); + cf = _wfopen(d86f[drive].original_file_name, L"wb"); /* Write the header to the original file. */ fwrite(header, 1, header_size, cf); @@ -3006,11 +3023,11 @@ void d86f_common_handlers(int drive) drives[drive].stop = d86f_stop; } -void d86f_load(int drive, char *fn) +void d86f_load(int drive, wchar_t *fn) { uint32_t magic = 0; uint32_t len = 0; - char temp_file_name[2048]; + wchar_t temp_file_name[2048]; uint16_t temp = 0; int i = 0; FILE *tf; @@ -3018,12 +3035,15 @@ void d86f_load(int drive, char *fn) d86f_unregister(drive); writeprot[drive] = 0; - d86f[drive].f = fopen(fn, "rb+"); + d86f[drive].f = _wfopen(fn, L"rb+"); if (!d86f[drive].f) { - d86f[drive].f = fopen(fn, "rb"); + d86f[drive].f = _wfopen(fn, L"rb"); if (!d86f[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -3042,6 +3062,7 @@ void d86f_load(int drive, char *fn) { /* File is WAY too small, abort. */ fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3050,6 +3071,7 @@ void d86f_load(int drive, char *fn) /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3071,6 +3093,7 @@ void d86f_load(int drive, char *fn) d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -3086,6 +3109,7 @@ void d86f_load(int drive, char *fn) { /* File too small, abort. */ fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3107,26 +3131,27 @@ void d86f_load(int drive, char *fn) { d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } #endif if (d86f[drive].is_compressed) { - append_filename(temp_file_name, pcempath, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 511); - memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 13); - memcpy(d86f[drive].original_file_name, fn, strlen(fn) + 1); + memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 256); + memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2); fclose(d86f[drive].f); - d86f[drive].f = fopen(temp_file_name, "wb"); + d86f[drive].f = _wfopen(temp_file_name, L"wb"); if (!d86f[drive].f) { d86f_log("86F: Unable to create temporary decompressed file\n"); + update_status_bar_icon_state(drive, 1); return; } - tf = fopen(fn, "rb"); + tf = _wfopen(fn, L"rb"); for (i = 0; i < 8; i++) { @@ -3151,11 +3176,12 @@ void d86f_load(int drive, char *fn) if (!temp) { d86f_log("86F: Error decompressing file\n"); - remove(temp_file_name); + _wremove(temp_file_name); + update_status_bar_icon_state(drive, 1); return; } - d86f[drive].f = fopen(temp_file_name, "rb+"); + d86f[drive].f = _wfopen(temp_file_name, L"rb+"); } if (d86f[drive].disk_flags & 0x100) @@ -3165,8 +3191,9 @@ void d86f_load(int drive, char *fn) fclose(d86f[drive].f); if (d86f[drive].is_compressed) { - remove(temp_file_name); + _wremove(temp_file_name); } + update_status_bar_icon_state(drive, 1); return; } @@ -3177,8 +3204,9 @@ void d86f_load(int drive, char *fn) fclose(d86f[drive].f); if (d86f[drive].is_compressed) { - remove(temp_file_name); + _wremove(temp_file_name); } + update_status_bar_icon_state(drive, 1); return; } @@ -3194,11 +3222,11 @@ void d86f_load(int drive, char *fn) if (d86f[drive].is_compressed) { - d86f[drive].f = fopen(temp_file_name, "rb"); + d86f[drive].f = _wfopen(temp_file_name, L"rb"); } else { - d86f[drive].f = fopen(fn, "rb"); + d86f[drive].f = _wfopen(fn, L"rb"); } } @@ -3211,6 +3239,7 @@ void d86f_load(int drive, char *fn) /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3219,6 +3248,7 @@ void d86f_load(int drive, char *fn) /* File is 2-sided but has no track 0 side 1, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3294,14 +3324,12 @@ void d86f_init() void d86f_close(int drive) { - char temp_file_name[2048]; + wchar_t temp_file_name[2048]; - append_filename(temp_file_name, pcempath, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 511); - memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 13); + memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 26); if (d86f[drive].f) fclose(d86f[drive].f); if (d86f[drive].is_compressed) - remove(temp_file_name); - d86f[drive].f = NULL; + _wremove(temp_file_name); } diff --git a/src/disc_86f.h b/src/disc_86f.h index 45c5838d2..7efc9b3f5 100644 --- a/src/disc_86f.h +++ b/src/disc_86f.h @@ -2,7 +2,7 @@ see COPYING for more details */ void d86f_init(); -void d86f_load(int drive, char *fn); +void d86f_load(int drive, wchar_t *fn); void d86f_close(int drive); void d86f_seek(int drive, int track); int d86f_hole(int drive); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index 091524b20..bf8410e91 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -3,6 +3,7 @@ */ #include #include +#include #include "ibm.h" #include "disc.h" #include "disc_img.h" @@ -239,13 +240,17 @@ void d86f_register_fdi(int drive) d86f_handler[drive].check_crc = 1; } -void fdi_load(int drive, char *fn) +void fdi_load(int drive, wchar_t *fn) { char header[26]; writeprot[drive] = fwriteprot[drive] = 1; - fdi[drive].f = fopen(fn, "rb"); - if (!fdi[drive].f) return; + fdi[drive].f = _wfopen(fn, L"rb"); + if (!fdi[drive].f) + { + update_status_bar_icon_state(drive, 1); + return; + } d86f_unregister(drive); @@ -281,7 +286,6 @@ void fdi_close(int drive) fdi2raw_header_free(fdi[drive].h); if (fdi[drive].f) fclose(fdi[drive].f); - fdi[drive].f = NULL; } void fdi_seek(int drive, int track) diff --git a/src/disc_fdi.h b/src/disc_fdi.h index d26340fd0..781efac23 100644 --- a/src/disc_fdi.h +++ b/src/disc_fdi.h @@ -2,7 +2,7 @@ see COPYING for more details */ void fdi_init(); -void fdi_load(int drive, char *fn); +void fdi_load(int drive, wchar_t *fn); void fdi_close(int drive); void fdi_seek(int drive, int track); void fdi_readsector(int drive, int sector, int track, int side, int density, int sector_size); diff --git a/src/disc_imd.c b/src/disc_imd.c index c69a0b674..fcbed568d 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -8,6 +8,7 @@ #include "fdd.h" #include +#include typedef struct { @@ -49,7 +50,7 @@ void imd_init() void d86f_register_imd(int drive); -void imd_load(int drive, char *fn) +void imd_load(int drive, wchar_t *fn) { uint32_t magic = 0; uint32_t fsize = 0; @@ -73,12 +74,15 @@ void imd_load(int drive, char *fn) d86f_unregister(drive); writeprot[drive] = 0; - imd[drive].f = fopen(fn, "rb+"); + imd[drive].f = _wfopen(fn, L"rb+"); if (!imd[drive].f) { - imd[drive].f = fopen(fn, "rb"); + imd[drive].f = _wfopen(fn, L"rb"); if (!imd[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -93,6 +97,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: Not a valid ImageDisk image\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -113,6 +118,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: No ASCII EOF character\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -125,6 +131,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: File ends after ASCII EOF character\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -243,6 +250,7 @@ void imd_load(int drive, char *fn) /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } } @@ -281,7 +289,6 @@ void imd_close(int drive) } fclose(imd[drive].f); } - imd[drive].f = NULL; } int imd_track_is_xdf(int drive, int side, int track) diff --git a/src/disc_imd.h b/src/disc_imd.h index 03628b031..a132605d9 100644 --- a/src/disc_imd.h +++ b/src/disc_imd.h @@ -2,6 +2,6 @@ see COPYING for more details */ void imd_init(); -void imd_load(int drive, char *fn); +void imd_load(int drive, wchar_t *fn); void imd_close(int drive); void imd_seek(int drive, int track); diff --git a/src/disc_img.c b/src/disc_img.c index a9e60c880..0391820d0 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -2,8 +2,10 @@ see COPYING for more details */ #include +#include #include "ibm.h" +#include "config.h" #include "disc.h" #include "disc_img.h" #include "fdc.h" @@ -296,14 +298,14 @@ int first_byte_is_valid(uint8_t first_byte) double bit_rate_300; -char ext[4]; +wchar_t *ext; uint8_t first_byte, second_byte, third_byte, fourth_byte; /* This is hard-coded to 0 - if you really need to read those NT 3.1 Beta floppy images, change this to 1 and recompile the emulator. */ uint8_t fdf_suppress_final_byte = 0; -void img_load(int drive, char *fn) +void img_load(int drive, wchar_t *fn) { int size; uint16_t bpb_bps; @@ -324,20 +326,20 @@ void img_load(int drive, char *fn) uint16_t track_bytes = 0; uint8_t *literal; - ext[0] = fn[strlen(fn) - 3] | 0x60; - ext[1] = fn[strlen(fn) - 2] | 0x60; - ext[2] = fn[strlen(fn) - 1] | 0x60; - ext[3] = 0; + ext = get_extension_w(fn); d86f_unregister(drive); writeprot[drive] = 0; - img[drive].f = fopen(fn, "rb+"); + img[drive].f = _wfopen(fn, L"rb+"); if (!img[drive].f) { - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); if (!img[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -350,7 +352,7 @@ void img_load(int drive, char *fn) img[drive].interleave = img[drive].skew = 0; - if (strcmp(ext, "fdi") == 0) + if (_wcsicmp(ext, L"FDI") == 0) { /* This is a Japanese FDI image, so let's read the header */ pclog("img_load(): File is a Japanese FDI image...\n"); @@ -395,7 +397,7 @@ void img_load(int drive, char *fn) pclog("img_load(): File is a FDF image...\n"); fwriteprot[drive] = writeprot[drive] = 1; fclose(img[drive].f); - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); fdf = 1; @@ -580,7 +582,7 @@ void img_load(int drive, char *fn) pclog("img_load(): File is a CopyQM image...\n"); fwriteprot[drive] = writeprot[drive] = 1; fclose(img[drive].f); - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); fseek(img[drive].f, 0x03, SEEK_SET); fread(&bpb_bps, 1, 2, img[drive].f); @@ -734,6 +736,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } } @@ -795,6 +798,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -811,6 +815,7 @@ jump_if_fdf: { pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -845,8 +850,6 @@ void img_close(int drive) fclose(img[drive].f); if (img[drive].disk_data) free(img[drive].disk_data); - img[drive].f = NULL; - img[drive].disk_data = NULL; } #define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] diff --git a/src/disc_img.h b/src/disc_img.h index a98ba1a98..4cb82ea1f 100644 --- a/src/disc_img.h +++ b/src/disc_img.h @@ -2,6 +2,6 @@ see COPYING for more details */ void img_init(); -void img_load(int drive, char *fn); +void img_load(int drive, wchar_t *fn); void img_close(int drive); void img_seek(int drive, int track); diff --git a/src/disc_td0.c b/src/disc_td0.c index 5905527b9..c63a62dc5 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -14,6 +14,8 @@ * Edited and translated to English by Kenji RIKITAKE */ +#include + #include "ibm.h" #include "disc.h" #include "disc_td0.h" @@ -499,16 +501,17 @@ uint8_t imagebuf[4*1024*1024]; uint8_t processed_buf[5*1024*1024]; uint8_t header[12]; -void td0_load(int drive, char *fn) +void td0_load(int drive, wchar_t *fn) { int ret = 0; d86f_unregister(drive); writeprot[drive] = 1; - td0[drive].f = fopen(fn, "rb"); + td0[drive].f = _wfopen(fn, L"rb"); if (!td0[drive].f) { + update_status_bar_icon_state(drive, 1); return; } fwriteprot[drive] = writeprot[drive]; @@ -518,6 +521,7 @@ void td0_load(int drive, char *fn) { pclog("TD0: Not a valid Teledisk image\n"); fclose(td0[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -532,6 +536,7 @@ void td0_load(int drive, char *fn) { pclog("TD0: Failed to initialize\n"); fclose(td0[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -579,7 +584,6 @@ void td0_close(int drive) if (td0[drive].f) fclose(td0[drive].f); - td0[drive].f = NULL; } uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm) diff --git a/src/disc_td0.h b/src/disc_td0.h index 48226d77a..306c7be20 100644 --- a/src/disc_td0.h +++ b/src/disc_td0.h @@ -2,6 +2,6 @@ see COPYING for more details */ void td0_init(); -void td0_load(int drive, char *fn); +void td0_load(int drive, wchar_t *fn); void td0_close(int drive); void td0_seek(int drive, int track); diff --git a/src/dma.c b/src/dma.c index c1c039ffa..259401dee 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,16 +1,19 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ #include "ibm.h" - -#include "dma.h" -#include "io.h" +#include "cpu/x86.h" #include "mem.h" -#include "video.h" -#include "x86.h" +#include "io.h" +#include "dma.h" + static uint8_t dmaregs[16]; static uint8_t dma16regs[16]; static uint8_t dmapages[16]; -void dma_reset() + +void dma_reset(void) { int c; dma.wp = 0; @@ -447,30 +450,30 @@ uint8_t dma_page_read(uint16_t addr, void *priv) return dmapages[addr & 0xf]; } -void dma_init() +void dma_init(void) { io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); dma.is_ps2 = 0; } -void dma16_init() +void dma16_init(void) { io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_set() +void dma_alias_set(void) { io_sethandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_remove() +void dma_alias_remove(void) { io_removehandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_remove_piix() +void dma_alias_remove_piix(void) { io_removehandler(0x0090, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); io_removehandler(0x0094, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); diff --git a/src/dma.h b/src/dma.h index 3cf611ea2..515f02f87 100644 --- a/src/dma.h +++ b/src/dma.h @@ -1,29 +1,29 @@ /* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ -void dma_init(); -void dma16_init(); -void ps2_dma_init(); -void dma_reset(); +void dma_init(void); +void dma16_init(void); +void ps2_dma_init(void); +void dma_reset(void); int dma_mode(int channel); #define DMA_NODATA -1 #define DMA_OVER 0x10000 #define DMA_VERIFY 0x20000 -void readdma0(); -int readdma1(); -uint8_t readdma2(); -int readdma3(); +void readdma0(void); +int readdma1(void); +uint8_t readdma2(void); +int readdma3(void); void writedma2(uint8_t temp); int dma_channel_read(int channel); int dma_channel_write(int channel, uint16_t val); -void dma_alias_set(); -void dma_alias_remove(); -void dma_alias_remove_piix(); +void dma_alias_set(void); +void dma_alias_remove(void); +void dma_alias_remove_piix(void); void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize); -void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); \ No newline at end of file +void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); diff --git a/src/fdc.c b/src/fdc.c index 40f1c11f8..9e5b66cce 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -142,11 +142,11 @@ int discrate[4]; int discint; -int fdc_do_log = 1; +int fdc_do_log = 0; void fdc_log(const char *format, ...) { -// #ifdef ENABLE_FDC_LOG +#ifdef ENABLE_FDC_LOG if (fdc_do_log) { va_list ap; @@ -155,7 +155,7 @@ void fdc_log(const char *format, ...) va_end(ap); fflush(stdout); } -// #endif +#endif } void fdc_reset() @@ -429,6 +429,7 @@ int fdc_get_rwc(int drive) void fdc_update_rwc(int drive, int rwc) { + fdc_log("FDD %c: New RWC is %i\n", 0x41 + drive, rwc); fdc.rwc[drive] = rwc; fdc_rate(drive); } @@ -445,6 +446,7 @@ void fdc_update_boot_drive(int boot_drive) void fdc_update_densel_polarity(int densel_polarity) { + fdc_log("FDC: New DENSEL polarity is %i\n", densel_polarity); fdc.densel_polarity = densel_polarity; fdc_update_rates(); } @@ -456,12 +458,14 @@ uint8_t fdc_get_densel_polarity() void fdc_update_densel_force(int densel_force) { + fdc_log("FDC: New DENSEL force is %i\n", densel_force); fdc.densel_force = densel_force; fdc_update_rates(); } void fdc_update_drvrate(int drive, int drvrate) { + fdc_log("FDD %c: New drive rate is %i\n", 0x41 + drive, drvrate); fdc.drvrate[drive] = drvrate; fdc_rate(drive); } @@ -588,6 +592,7 @@ static void fdc_rate(int drive) { fdc_update_rate(drive); disc_set_rate(drive, fdc.drvrate[drive], fdc.rate); + fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc.drvrate[drive], fdc.rate, fdc_get_densel(drive), fdc.rwc[drive], fdc.densel_force); fdd_set_densel(fdc_get_densel(drive)); } @@ -1822,6 +1827,7 @@ void fdc_error(int st5, int st6) fdc.res[4]=0x40|(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.rw_drive; fdc.res[5]=st5; fdc.res[6]=st6; + fdc_log("FDC Error: %02X %02X %02X\n", fdc.res[4], fdc.res[5], fdc.res[6]); switch(discint) { case 0x02: diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 53b4f6b24..1b6904a1a 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -86,19 +86,19 @@ void set_serial1_addr() switch (fdc37c665_regs[2] & 3) { case 0: - serial1_set(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); break; case 1: - serial1_set(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); break; case 2: - serial1_set(com3_addr, 4); + serial_setup(1, com3_addr, 4); break; case 3: - serial1_set(com4_addr, 3); + serial_setup(1, com4_addr, 3); break; } } @@ -111,19 +111,19 @@ void set_serial2_addr() switch (fdc37c665_regs[2] & 0x30) { case 0: - serial2_set(0x3f8, 4); + serial_setup(2, SERIAL1_ADDR, SERIAL1_IRQ); break; case 1: - serial2_set(0x2f8, 3); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); break; case 2: - serial2_set(com3_addr, 4); + serial_setup(2, com3_addr, 4); break; case 3: - serial2_set(com4_addr, 3); + serial_setup(2, com4_addr, 3); break; } } @@ -186,7 +186,7 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) } if (valxor & 0x60) { - serial1_remove(); + serial_remove(1); set_com34_addr(); set_serial1_addr(); set_serial2_addr(); @@ -195,12 +195,12 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) case 2: if (valxor & 7) { - serial1_remove(); + serial_remove(1); set_serial1_addr(); } if (valxor & 0x70) { - serial2_remove(); + serial_remove(2); set_serial2_addr(); } break; @@ -254,11 +254,11 @@ void fdc37c665_reset(void) fdc_update_is_nsc(0); - serial1_remove(); - serial1_set(0x3f8, 4); + serial_remove(1); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial2_remove(); - serial2_set(0x2f8, 3); + serial_remove(2); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); lpt2_remove(); diff --git a/src/fdc37c669.c b/src/fdc37c669.c index 337b8cec1..605b79e17 100644 --- a/src/fdc37c669.c +++ b/src/fdc37c669.c @@ -170,13 +170,13 @@ process_value: case 2: if (valxor & 8) { - serial1_remove(); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + serial_remove(1); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } if (valxor & 0x80) { - serial2_remove(); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + serial_remove(2); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } break; case 3: @@ -224,29 +224,29 @@ process_value: case 0x24: if (valxor & 0xfe) { - serial1_remove(); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + serial_remove(1); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } break; case 0x25: if (valxor & 0xfe) { - serial2_remove(); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + serial_remove(2); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } break; case 0x28: if (valxor & 0xf) { - serial2_remove(); + serial_remove(2); if ((fdc37c669_regs[0x28] & 0xf) == 0) fdc37c669_regs[0x28] |= 0x3; - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } if (valxor & 0xf0) { - serial1_remove(); + serial_remove(1); if ((fdc37c669_regs[0x28] & 0xf0) == 0) fdc37c669_regs[0x28] |= 0x40; - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } break; } @@ -280,11 +280,11 @@ void fdc37c669_reset(void) fdc_update_is_nsc(0); - serial1_remove(); - serial1_set(0x3f8, 4); + serial_remove(1); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial2_remove(); - serial2_set(0x2f8, 3); + serial_remove(2); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); lpt2_remove(); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 13b8371bd..5b4057d1e 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -297,11 +297,11 @@ process_value: if (valxor) { if (!val) - serial1_remove(); + serial_remove(1); else { ld_port = make_port(4); - serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]); + serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]); } } break; @@ -311,7 +311,7 @@ process_value: if (valxor && fdc37c932fr_ld_regs[4][0x30]) { ld_port = make_port(4); - serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]); + serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]); } break; } @@ -325,11 +325,11 @@ process_value: if (valxor) { if (!val) - serial2_remove(); + serial_remove(2); else { ld_port = make_port(5); - serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]); + serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]); } } break; @@ -339,7 +339,7 @@ process_value: if (valxor && fdc37c932fr_ld_regs[5][0x30]) { ld_port = make_port(5); - serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]); + serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]); } break; } @@ -443,6 +443,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[4][0x61] = 0xf8; fdc37c932fr_ld_regs[4][0x70] = 4; fdc37c932fr_ld_regs[4][0xF0] = 3; + serial_setup(1, 0x3f8, fdc37c932fr_ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ fdc37c932fr_ld_regs[5][0x30] = 1; @@ -452,6 +453,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[5][0x74] = 4; fdc37c932fr_ld_regs[5][0xF1] = 2; fdc37c932fr_ld_regs[5][0xF2] = 3; + serial_setup(2, 0x2f8, fdc37c932fr_ld_regs[5][0x70]); /* Logical device 6: RTC */ fdc37c932fr_ld_regs[6][0x63] = 0x70; diff --git a/src/fdd.c b/src/fdd.c index d876552f6..35a2b6865 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -271,6 +271,11 @@ int fdd_is_525(int drive) return drive_types[fdd[drive].type].flags & FLAG_525; } +int fdd_is_dd(int drive) +{ + return (drive_types[fdd[drive].type].flags & 0x70) == 0x10; +} + int fdd_is_ed(int drive) { return drive_types[fdd[drive].type].flags & FLAG_HOLE2; diff --git a/src/fdd.h b/src/fdd.h index 11d9dee89..c4a18afbe 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -10,6 +10,7 @@ void fdd_set_densel(int densel); int fdd_can_read_medium(int drive); int fdd_doublestep_40(int drive); int fdd_is_525(int drive); +int fdd_is_dd(int drive); int fdd_is_ed(int drive); int fdd_is_double_sided(int drive); void fdd_set_head(int drive, int head); @@ -28,3 +29,6 @@ int fdd_get_densel(int drive); void fdd_setswap(int swap); char *fdd_getname(int type); + +char *fdd_get_internal_name(int type); +int fdd_get_from_internal_name(char *s); diff --git a/src/gameport.c b/src/gameport.c index 45e2cb8d8..b75e9f6ce 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -4,19 +4,21 @@ #include #include #include "ibm.h" +#include "cpu/cpu.h" #include "device.h" #include "io.h" -#include "plat-joystick.h" #include "timer.h" - +#include "plat-joystick.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" #include "joystick_sw_pad.h" #include "joystick_tm_fcs.h" + int joystick_type; + joystick_if_t joystick_none = { "No joystick", diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 4dfc0b4b6..707e0d1b6 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -796,14 +796,14 @@ static void esdi_mca_write(int port, uint8_t val, void *p) } } -static void loadhd(esdi_t *esdi, int d, const char *fn) +static void loadhd(esdi_t *esdi, int d, const wchar_t *fn) { esdi_drive_t *drive = &esdi->drives[d]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -811,7 +811,7 @@ static void loadhd(esdi_t *esdi, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", @@ -842,7 +842,7 @@ static void *esdi_init() esdi_t *esdi = malloc(sizeof(esdi_t)); memset(esdi, 0, sizeof(esdi_t)); - rom_init_interleaved(&esdi->bios_rom, "roms/90x8970.bin", "roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init_interleaved(&esdi->bios_rom, L"roms/90x8970.bin", L"roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&esdi->bios_rom.mapping); for (i = 0; i < HDC_NUM; i++) @@ -882,7 +882,7 @@ static void esdi_close(void *p) static int esdi_available() { - return rom_present("roms/90x8969.bin") && rom_present("roms/90x8970.bin"); + return rom_present(L"roms/90x8969.bin") && rom_present(L"roms/90x8970.bin"); } device_t hdd_esdi_device = diff --git a/src/headland.c b/src/headland.c index b100b85c8..62e6dd076 100644 --- a/src/headland.c +++ b/src/headland.c @@ -2,9 +2,9 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "cpu.h" #include "headland.h" diff --git a/src/ibm.h b/src/ibm.h index ffbc18593..44c9c1df6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -4,11 +4,12 @@ #include #include #include +#include #define printf pclog + /*Memory*/ uint8_t *ram; - uint32_t rammask; int readlookup[256],readlookupp[256]; @@ -24,34 +25,31 @@ extern int mmu_perm; #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -uint8_t readmembl(uint32_t addr); -void writemembl(uint32_t addr, uint8_t val); -uint8_t readmemb386l(uint32_t seg, uint32_t addr); -void writememb386l(uint32_t seg, uint32_t addr, uint8_t val); -uint16_t readmemwl(uint32_t seg, uint32_t addr); -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); -uint32_t readmemll(uint32_t seg, uint32_t addr); -void writememll(uint32_t seg, uint32_t addr, uint32_t val); -uint64_t readmemql(uint32_t seg, uint32_t addr); -void writememql(uint32_t seg, uint32_t addr, uint64_t val); +extern uint8_t readmembl(uint32_t addr); +extern void writemembl(uint32_t addr, uint8_t val); +extern uint8_t readmemb386l(uint32_t seg, uint32_t addr); +extern void writememb386l(uint32_t seg, uint32_t addr, uint8_t val); +extern uint16_t readmemwl(uint32_t seg, uint32_t addr); +extern void writememwl(uint32_t seg, uint32_t addr, uint16_t val); +extern uint32_t readmemll(uint32_t seg, uint32_t addr); +extern void writememll(uint32_t seg, uint32_t addr, uint32_t val); +extern uint64_t readmemql(uint32_t seg, uint32_t addr); +extern void writememql(uint32_t seg, uint32_t addr, uint64_t val); -uint8_t *getpccache(uint32_t a); - -uint32_t mmutranslatereal(uint32_t addr, int rw); - -void addreadlookup(uint32_t virt, uint32_t phys); -void addwritelookup(uint32_t virt, uint32_t phys); +extern uint8_t *getpccache(uint32_t a); +extern uint32_t mmutranslatereal(uint32_t addr, int rw); +extern void addreadlookup(uint32_t virt, uint32_t phys); +extern void addwritelookup(uint32_t virt, uint32_t phys); /*IO*/ -uint8_t inb(uint16_t port); -void outb(uint16_t port, uint8_t val); -uint16_t inw(uint16_t port); -void outw(uint16_t port, uint16_t val); -uint32_t inl(uint16_t port); -void outl(uint16_t port, uint32_t val); +extern uint8_t inb(uint16_t port); +extern void outb(uint16_t port, uint8_t val); +extern uint16_t inw(uint16_t port); +extern void outw(uint16_t port, uint16_t val); +extern uint32_t inl(uint16_t port); +extern void outl(uint16_t port, uint32_t val); -FILE *romfopen(char *fn, char *mode); extern int shadowbios,shadowbios_write; extern int mem_size; extern int readlnum,writelnum; @@ -163,6 +161,9 @@ struct } cpu_state; #define cycles cpu_state._cycles +#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm +#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod +#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -292,13 +293,8 @@ typedef struct PIT } PIT; PIT pit, pit2; -void setpitclock(float clock); - -float pit_timer0_freq(); - -#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm -#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod -#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg +extern void setpitclock(float clock); +extern float pit_timer0_freq(void); @@ -350,7 +346,7 @@ extern int pic_intpending; int disctime; -char discfns[4][256]; +wchar_t discfns[4][256]; int driveempty[4]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) @@ -551,18 +547,13 @@ int gated,speakval,speakon; #define SND_WSS 9 /*Windows Sound System*/ #define SND_PAS16 10 /*Pro Audio Spectrum 16*/ -char pcempath[512]; +wchar_t pcempath[512]; /*Hard disc*/ -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { FILE *f; uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ uint64_t tracks; @@ -575,17 +566,10 @@ typedef struct __attribute((__packed__)) uint8_t scsi_id; uint8_t scsi_lun; } hard_disk_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { /* Stuff for SCSI hard disks. */ uint8_t cdb[16]; uint8_t current_cdb[16]; @@ -619,9 +603,7 @@ typedef struct __attribute((__packed__)) uint64_t base; uint8_t hd_cdb[16]; } scsi_hard_disk_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) #define HDC_NUM 16 #define IDE_NUM 8 @@ -637,10 +619,10 @@ FILE *shdf[HDC_NUM]; uint64_t hdt[128][3]; uint64_t hdt_mfm[128][3]; -extern char hdd_fn[HDC_NUM][512]; +extern wchar_t hdd_fn[HDC_NUM][512]; -int image_is_hdi(const char *s); -int image_is_hdx(const char *s, int check_signature); +int image_is_hdi(const wchar_t *s); +int image_is_hdx(const wchar_t *s, int check_signature); /*Keyboard*/ int keybsenddelay; @@ -663,25 +645,22 @@ extern uint32_t SCSIGetCDChannel(int channel); extern int ui_writeprot[4]; -void pclog(const char *format, ...); + extern int nmi; extern int nmi_auto_clear; - extern float isa_timing, bus_timing; -uint64_t timer_read(); +extern uint64_t timer_read(void); extern uint64_t timer_freq; -void loadconfig(char *fn); - extern int infocus; -void onesec(); +extern void onesec(void); -void resetpc_cad(); +extern void resetpc_cad(void); extern int dump_on_exit; extern int start_in_fullscreen; @@ -700,14 +679,13 @@ extern uint64_t star; #define FPU_CW_Reserved_Bits (0xe0c0) -extern char nvr_path[1024]; +extern wchar_t nvr_path[1024]; extern int path_len; -char *nvr_concat(char *to_concat); +wchar_t *nvr_concat(wchar_t *to_concat); int mem_a20_state; -void fatal(const char *format, ...); #ifdef ENABLE_LOG_TOGGLES extern int buslogic_do_log; @@ -729,63 +707,72 @@ typedef struct PCI_RESET extern PCI_RESET pci_reset_handler; -uint8_t trc_read(uint16_t port, void *priv); -void trc_write(uint16_t port, uint8_t val, void *priv); -void trc_init(); +extern uint8_t trc_read(uint16_t port, void *priv); +extern void trc_write(uint16_t port, uint8_t val, void *priv); +extern void trc_init(void); extern int enable_xtide; extern int enable_external_fpu; +extern int serial_enabled[2]; +extern int lpt_enabled, bugger_enabled; + extern int invert_display; uint32_t svga_color_transform(uint32_t color); extern int scale; -/* Function prototypes. */ -void BuslogicSoftReset(); -int checkio(int port); -void closepc(); -void codegen_block_end(); -void codegen_reset(); -void cpu_set_edx(); -int divl(uint32_t val); -void dumpregs(); -void exec386(int cycs); -void exec386_dynarec(int cycs); -void execx86(int cycs); -void flushmmucache(); -void flushmmucache_cr3(); -int idivl(int32_t val); -void initpc(int argc, char *argv[]); -void loadcscall(uint16_t seg); -void loadcsjmp(uint16_t seg, uint32_t oxpc); -void mmu_invalidate(uint32_t addr); -void pclog(const char *format, ...); -void pmodeint(int num, int soft); -void pmoderetf(int is32, uint16_t off); -void pmodeiret(int is32); -void port_92_clear_reset(); -uint8_t readdacfifo(); -void refreshread(); -int rep386(int fv); -void resetmcr(); -void resetpchard(); -void resetreadlookup(); -void resetx86(); -void runpc(); -void saveconfig(); -void softresetx86(); -void speedchanged(); -void trc_reset(uint8_t val); -void update_status_bar_icon(int tag, int active); -void x86_int_sw(int num); -void x86gpf(char *s, uint16_t error); -void x86np(char *s, uint16_t error); -void x86ss(char *s, uint16_t error); -void x86ts(char *s, uint16_t error); -void x87_dumpregs(); -void x87_reset(); -extern int serial_enabled[2]; -extern int lpt_enabled, bugger_enabled; +/* Function prototypes. */ +extern int checkio(int port); +extern void closepc(void); +extern void codegen_block_end(void); +extern void codegen_reset(void); +extern void cpu_set_edx(void); +extern int divl(uint32_t val); +extern void dumpregs(int __force); +extern void exec386(int cycs); +extern void exec386_dynarec(int cycs); +extern void execx86(int cycs); +extern void flushmmucache(void); +extern void flushmmucache_cr3(void); +extern int idivl(int32_t val); +extern void initpc(int argc, wchar_t *argv[]); +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t oxpc); +extern void mmu_invalidate(uint32_t addr); +extern void pclog(const char *format, ...); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +extern void port_92_clear_reset(void); +extern uint8_t readdacfifo(void); +extern void refreshread(void); +extern int rep386(int fv); +extern void resetmcr(void); +extern void resetpchard(void); +extern void resetreadlookup(void); +extern void resetx86(void); +extern void runpc(void); +extern void saveconfig(void); +extern void softresetx86(void); +extern void speedchanged(void); +extern void trc_reset(uint8_t val); +extern void x86_int_sw(int num); +extern void x86gpf(char *s, uint16_t error); +extern void x86np(char *s, uint16_t error); +extern void x86ss(char *s, uint16_t error); +extern void x86ts(char *s, uint16_t error); +extern void x87_dumpregs(void); +extern void x87_reset(void); + +/* Platform functions. */ +extern void pclog(const char *format, ...); +extern void pclog_w(const wchar_t *format, ...); +extern void fatal(const char *format, ...); + +extern void update_status_bar_icon(int tag, int active); +extern void update_status_bar_icon_state(int tag, int state); +extern void status_settextw(wchar_t *wstr); +extern void status_settext(char *str); diff --git a/src/ide.c b/src/ide.c index 525534189..f6c2c3454 100644 --- a/src/ide.c +++ b/src/ide.c @@ -13,6 +13,7 @@ #include #include +#include #include "86box.h" #include "cdrom.h" @@ -95,7 +96,7 @@ IDE ide_drives[IDE_NUM]; IDE *ext_ide; -char hdd_fn[HDC_NUM][512]; +wchar_t hdd_fn[HDC_NUM][512]; int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); @@ -142,16 +143,19 @@ int ide_drive_is_cdrom(IDE *ide) } } -int image_is_hdi(const char *s) +static char as[512]; + +int image_is_hdi(const wchar_t *s) { int i, len; char ext[5] = { 0, 0, 0, 0, 0 }; - len = strlen(s); - if ((len < 4) || (s[0] == '.')) + wcstombs(as, s, (wcslen(s) << 1) + 2); + len = strlen(as); + if ((len < 4) || (as[0] == '.')) { return 0; } - memcpy(ext, s + len - 4, 4); + memcpy(ext, as + len - 4, 4); for (i = 0; i < 4; i++) { ext[i] = toupper(ext[i]); @@ -166,19 +170,20 @@ int image_is_hdi(const char *s) } } -int image_is_hdx(const char *s, int check_signature) +int image_is_hdx(const wchar_t *s, int check_signature) { int i, len; FILE *f; uint64_t filelen; uint64_t signature; char ext[5] = { 0, 0, 0, 0, 0 }; - len = strlen(s); - if ((len < 4) || (s[0] == '.')) + wcstombs(as, s, (wcslen(s) << 1) + 2); + len = strlen(as); + if ((len < 4) || (as[0] == '.')) { return 0; } - memcpy(ext, s + len - 4, 4); + memcpy(ext, as + len - 4, 4); for (i = 0; i < 4; i++) { ext[i] = toupper(ext[i]); @@ -187,7 +192,7 @@ int image_is_hdx(const char *s, int check_signature) { if (check_signature) { - f = fopen(s, "rb"); + f = _wfopen(s, L"rb"); if (!f) { return 0; @@ -377,7 +382,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (PCI && (ide->board < 2)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -391,7 +396,7 @@ static void ide_identify(IDE *ide) } ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ +#if 0 ide->buffer[53] = 1; ide->buffer[55] = ide->hpc; ide->buffer[56] = ide->spt; @@ -406,14 +411,16 @@ static void ide_identify(IDE *ide) full_size = ((uint64_t) ide->hpc) * ((uint64_t) ide->spt) * ((uint64_t) ide->buffer[54]); ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[58] = (full_size >> 16) & 0x0FFF; +#endif ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if (ide->buffer[49] & (1 << 9)) { ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16) & 0x0FFF; } - if (PCI && (ide->board < 2)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { + ide->buffer[52] = 2 << 8; /*DMA timing mode*/ ide->buffer[63] = 7; } ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ @@ -437,16 +444,16 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[73] = 6; - ide->buffer[74] = 9; - ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) { + ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] |= 0x100; /* DMA supported */ ide->buffer[63] = 7; + ide->buffer[73] = 6; + ide->buffer[74] = 9; + ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ } } @@ -494,7 +501,7 @@ static void ide_next_sector(IDE *ide) } } -static void loadhd(IDE *ide, int d, const char *fn) +static void loadhd(IDE *ide, int d, const wchar_t *fn) { uint32_t sector_size = 512; uint32_t zero = 0; @@ -511,7 +518,7 @@ static void loadhd(IDE *ide, int d, const char *fn) ide->type = IDE_NONE; return; } - ide->hdfile = fopen64(fn, "rb+"); + ide->hdfile = _wfopen(fn, L"rb+"); if (ide->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -519,7 +526,7 @@ static void loadhd(IDE *ide, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - ide->hdfile = fopen64(fn, "wb+"); + ide->hdfile = _wfopen(fn, L"wb+"); if (ide->hdfile == NULL) { ide->type = IDE_NONE; @@ -780,7 +787,7 @@ void resetide(void) c = 0; for (d = 0; d < HDC_NUM; d++) { - if ((hdc[d].bus == 2) && (hdc[d].ide_channel < IDE_NUM)) + if (((hdc[d].bus == 2) || (hdc[d].bus == 3)) && (hdc[d].ide_channel < IDE_NUM)) { pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); loadhd(&ide_drives[hdc[d].ide_channel], d, hdd_fn[d]); @@ -1406,7 +1413,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1729,7 +1736,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_READ_DMA: @@ -1763,12 +1770,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1806,7 +1813,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_WRITE: @@ -1829,12 +1836,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } return; @@ -1870,12 +1877,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1906,12 +1913,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } return; @@ -1928,7 +1935,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_FORMAT: @@ -1950,7 +1957,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon(0x21, 1); */ + /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: diff --git a/src/intel.c b/src/intel.c index 2eb47939b..01560852f 100644 --- a/src/intel.c +++ b/src/intel.c @@ -2,14 +2,14 @@ see COPYING for more details */ #include "ibm.h" -#include "cpu.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pit.h" #include "timer.h" - #include "intel.h" + uint8_t batman_brdconfig(uint16_t port, void *p) { switch (port) diff --git a/src/intel_flash.c b/src/intel_flash.c index 39d40ec7d..1ccb225a9 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "rom.h" #define FLASH_IS_BXB 2 #define FLASH_INVERT 1 @@ -34,7 +35,7 @@ typedef struct flash_t uint8_t array[131072]; } flash_t; -static char flash_path[1024]; +static wchar_t flash_path[1024]; static uint8_t flash_read(uint32_t addr, void *p) { @@ -150,7 +151,6 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) void *intel_flash_init(uint8_t type) { FILE *f; - char fpath[1024]; int i; flash_t *flash; flash = malloc(sizeof(flash_t)); @@ -159,74 +159,64 @@ void *intel_flash_init(uint8_t type) switch(romset) { case ROM_REVENGE: - strcpy(flash_path, "roms/revenge/"); + wcscpy(flash_path, L"revenge.bin"); break; case ROM_586MC1: - strcpy(flash_path, "roms/586mc1/"); + wcscpy(flash_path, L"586mc1.bin"); break; case ROM_PLATO: - strcpy(flash_path, "roms/plato/"); + wcscpy(flash_path, L"plato.bin"); break; case ROM_ENDEAVOR: - strcpy(flash_path, "roms/endeavor/"); + wcscpy(flash_path, L"endeavor.bin"); break; case ROM_MB500N: - strcpy(flash_path, "roms/mb500n/"); + wcscpy(flash_path, L"mb500n.bin"); break; -#if 0 - case ROM_POWERMATE_V: - strcpy(flash_path, "roms/powermate_v/"); - break; -#endif case ROM_P54TP4XE: - strcpy(flash_path, "roms/p54tp4xe/"); + wcscpy(flash_path, L"p54tp4xe.bin"); break; case ROM_AP53: - strcpy(flash_path, "roms/ap53/"); + wcscpy(flash_path, L"ap53.bin"); break; case ROM_P55T2S: - strcpy(flash_path, "roms/p55t2s/"); + wcscpy(flash_path, L"p55t2s.bin"); break; case ROM_ACERM3A: - strcpy(flash_path, "roms/acerm3a/"); + wcscpy(flash_path, L"acerm3a.bin"); break; case ROM_ACERV35N: - strcpy(flash_path, "roms/acerv35n/"); + wcscpy(flash_path, L"acerv35n.bin"); break; case ROM_430VX: - strcpy(flash_path, "roms/430vx/"); + wcscpy(flash_path, L"430vx.bin"); break; case ROM_P55VA: - strcpy(flash_path, "roms/p55va/"); + wcscpy(flash_path, L"p55va.bin"); break; case ROM_P55T2P4: - strcpy(flash_path, "roms/p55t2p4/"); + wcscpy(flash_path, L"p55t2p4.bin"); break; case ROM_P55TVP4: - strcpy(flash_path, "roms/p55tvp4/"); + wcscpy(flash_path, L"p55tvp4.bin"); break; case ROM_440FX: - strcpy(flash_path, "roms/440fx/"); + wcscpy(flash_path, L"440fx.bin"); break; -#if 0 - case ROM_MARL: - strcpy(flash_path, "roms/marl/"); - break; -#endif case ROM_THOR: - strcpy(flash_path, "roms/thor/"); + wcscpy(flash_path, L"thor.bin"); break; case ROM_MRTHOR: - strcpy(flash_path, "roms/mrthor/"); + wcscpy(flash_path, L"mrthor.bin"); break; case ROM_ZAPPA: - strcpy(flash_path, "roms/zappa/"); + wcscpy(flash_path, L"zappa.bin"); break; case ROM_S1668: - strcpy(flash_path, "roms/tpatx/"); + wcscpy(flash_path, L"tpatx.bin"); break; default: - fatal("intel_flash_init on unsupported ROM set %i\n", romset); + fatal("intel_flash_init on unsupported ROM set %i\n", romset); } flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; @@ -289,9 +279,7 @@ void *intel_flash_init(uint8_t type) flash->command = CMD_READ_ARRAY; flash->status = 0; - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "rb"); + f = nvrfopen(flash_path, L"rb"); if (f) { fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); @@ -331,11 +319,7 @@ void intel_flash_close(void *p) FILE *f; flash_t *flash = (flash_t *)p; - char fpath[1024]; - - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "wb"); + f = nvrfopen(flash_path, L"wb"); fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); diff --git a/src/io.c b/src/io.c index da9e3318a..ca9259e75 100644 --- a/src/io.c +++ b/src/io.c @@ -2,10 +2,8 @@ see COPYING for more details */ #include "ibm.h" -#include "ide.h" #include "io.h" -#include "video.h" -#include "cpu.h" + uint8_t (*port_inb[0x10000][2])(uint16_t addr, void *priv); uint16_t (*port_inw[0x10000][2])(uint16_t addr, void *priv); @@ -17,6 +15,7 @@ void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv); void *port_priv[0x10000][2]; + void io_init() { int c; diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index 6ec66001f..3765b43ca 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -7,13 +7,13 @@ #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_amstrad.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4cf084829..4e6c7f7e9 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -2,21 +2,20 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "disc.h" -#include "fdc.h" #include "io.h" #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "disc.h" +#include "fdc.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_at.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index 498640777..e031bafad 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -2,16 +2,16 @@ #include "ibm.h" #include "io.h" #include "mem.h" -#include "mouse.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "mouse.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_olim24.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -21,6 +21,7 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 + struct { int wantirq; diff --git a/src/keyboard_pcjr.c b/src/keyboard_pcjr.c index 38142dd14..a7005d77b 100644 --- a/src/keyboard_pcjr.c +++ b/src/keyboard_pcjr.c @@ -2,22 +2,21 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "nmi.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_sn76489.h" -#include "sound_speaker.h" #include "timer.h" - +#include "device.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" +#include "sound/snd_sn76489.h" #include "keyboard.h" #include "keyboard_pcjr.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 0541b2692..c4497f9b9 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -2,21 +2,20 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" -#include "tandy_eeprom.h" #include "timer.h" - +#include "device.h" +#include "tandy_eeprom.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_xt.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -26,6 +25,7 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 + struct { int blocked; diff --git a/src/lpt.c b/src/lpt.c index 1f0ad05c5..73cd3ce6d 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -4,7 +4,6 @@ #include "ibm.h" #include "io.h" -#include "dac.h" #include "lpt.h" static uint8_t lpt1_dat, lpt2_dat; @@ -15,11 +14,9 @@ void lpt1_write(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: - writedac(port, val); lpt1_dat = val; break; case 2: - writedacctrl(port, val); lpt1_ctrl = val; break; } @@ -30,8 +27,6 @@ uint8_t lpt1_read(uint16_t port, void *priv) { case 0: return lpt1_dat; - case 1: - return readdacfifo(); case 2: return lpt1_ctrl; } @@ -43,11 +38,9 @@ void lpt2_write(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: - writedac(port, val); lpt2_dat = val; break; case 2: - writedacctrl(port, val); lpt2_ctrl = val; break; } @@ -58,8 +51,6 @@ uint8_t lpt2_read(uint16_t port, void *priv) { case 0: return lpt2_dat; - case 1: - return readdacfifo(); case 2: return lpt2_ctrl; } diff --git a/src/mem.c b/src/mem.c index a48b6217d..b6651ad20 100644 --- a/src/mem.c +++ b/src/mem.c @@ -7,20 +7,19 @@ - pc2386 video BIOS is underdumped (16k instead of 24k) - c386sx16 BIOS fails checksum */ - #include #include #include "ibm.h" - +#include "cpu/cpu.h" +#include "cpu/x86_ops.h" +#include "cpu/x86.h" #include "config.h" #include "io.h" #include "mem.h" -#include "video.h" -#include "x86.h" -#include "cpu.h" #include "rom.h" -#include "x86_ops.h" -#include "codegen.h" +#include "cpu/codegen.h" +#include "video/video.h" + page_t *pages; page_t **page_lookup; @@ -68,7 +67,7 @@ uint32_t ram_mapped_addr[64]; static void mem_load_atide115_bios() { FILE *f; - f=romfopen("roms/ide_at_1_1_5.bin","rb"); + f=romfopen(L"roms/ide_at_1_1_5.bin",L"rb"); if (f) { @@ -83,8 +82,8 @@ int loadbios() FILE *f=NULL,*ff=NULL; int c; - loadfont("roms/mda.rom", 0); - loadfont("roms/wy700.rom", 3); + loadfont(L"roms/mda.rom", 0); + loadfont(L"roms/wy700.rom", 3); biosmask = 0xffff; @@ -98,8 +97,8 @@ int loadbios() switch (romset) { case ROM_PC1512: - f=romfopen("roms/pc1512/40043.v1","rb"); - ff=romfopen("roms/pc1512/40044.v1","rb"); + f=romfopen(L"roms/pc1512/40043.v1",L"rb"); + ff=romfopen(L"roms/pc1512/40044.v1",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -108,11 +107,11 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc1512/40078.ic127", 2); + loadfont(L"roms/pc1512/40078.ic127", 2); return 1; case ROM_PC1640: - f=romfopen("roms/pc1640/40044.v3","rb"); - ff=romfopen("roms/pc1640/40043.v3","rb"); + f=romfopen(L"roms/pc1640/40044.v3",L"rb"); + ff=romfopen(L"roms/pc1640/40043.v3",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -121,13 +120,13 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/pc1640/40100","rb"); + f=romfopen(L"roms/pc1640/40100",L"rb"); if (!f) break; fclose(f); return 1; case ROM_PC200: - f=romfopen("roms/pc200/pc20v2.1","rb"); - ff=romfopen("roms/pc200/pc20v2.0","rb"); + f=romfopen(L"roms/pc200/pc20v2.1",L"rb"); + ff=romfopen(L"roms/pc200/pc20v2.0",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -136,24 +135,24 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc200/40109.bin", 1); + loadfont(L"roms/pc200/40109.bin", 1); return 1; case ROM_TANDY: - f=romfopen("roms/tandy/tandy1t1.020","rb"); + f=romfopen(L"roms/tandy/tandy1t1.020",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_TANDY1000HX: - f = romfopen("roms/tandy1000hx/v020000.u12", "rb"); + f = romfopen(L"roms/tandy1000hx/v020000.u12", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; case ROM_TANDY1000SL2: - f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); - ff = romfopen("roms/tandy1000sl2/8079048.hu2","rb"); + f = romfopen(L"roms/tandy1000sl2/8079047.hu1" ,L"rb"); + ff = romfopen(L"roms/tandy1000sl2/8079048.hu2",L"rb"); if (!f || !ff) break; fseek(f, 0x30000/2, SEEK_SET); fseek(ff, 0x30000/2, SEEK_SET); @@ -165,20 +164,12 @@ int loadbios() fclose(ff); fclose(f); return 1; -/* case ROM_IBMPCJR: - f=fopen("pcjr/bios.rom","rb"); - fread(rom+0xE000,8192,1,f); - fclose(f); - f=fopen("pcjr/basic.rom","rb"); - fread(rom+0x6000,32768,1,f); - fclose(f); - break;*/ case ROM_IBMXT: - f=romfopen("roms/ibmxt/xt.rom","rb"); + f=romfopen(L"roms/ibmxt/xt.rom",L"rb"); if (!f) { - f = romfopen("roms/ibmxt/5000027.u19", "rb"); - ff = romfopen("roms/ibmxt/1501512.u18","rb"); + f = romfopen(L"roms/ibmxt/5000027.u19", L"rb"); + ff = romfopen(L"roms/ibmxt/1501512.u18", L"rb"); if (!f || !ff) break; fread(rom, 0x8000, 1, f); fread(rom + 0x8000, 0x8000, 1, ff); @@ -195,22 +186,22 @@ int loadbios() break; case ROM_IBMPCJR: - f = romfopen("roms/ibmpcjr/bios.rom","rb"); + f = romfopen(L"roms/ibmpcjr/bios.rom", L"rb"); if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_PORTABLE: - f=romfopen("roms/portable/Compaq Portable Plus 100666-001 Rev C u47.bin","rb"); + f=romfopen(L"roms/portable/Compaq Portable Plus 100666-001 Rev C u47.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_PORTABLEII: - f = romfopen("roms/portableii/62x0820.u27", "rb"); - ff =romfopen("roms/portableii/62x0821.u47", "rb"); + f = romfopen(L"roms/portableii/62x0820.u27", L"rb"); + ff =romfopen(L"roms/portableii/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -222,9 +213,9 @@ int loadbios() return 1; case ROM_PORTABLEIII: - case ROM_PORTABLEIII386: - f = romfopen("roms/portableiii/62x0820.u27", "rb"); - ff =romfopen("roms/portableiii/62x0821.u47", "rb"); + case ROM_PORTABLEIII386: + f = romfopen(L"roms/portableiii/62x0820.u27", L"rb"); + ff =romfopen(L"roms/portableiii/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -236,20 +227,20 @@ int loadbios() return 1; case ROM_GENXT: - f=romfopen("roms/genxt/pcxt.rom","rb"); + f=romfopen(L"roms/genxt/pcxt.rom",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_DTKXT: - f=romfopen("roms/dtk/DTK_ERSO_2.42_2764.bin","rb"); + f=romfopen(L"roms/dtk/DTK_ERSO_2.42_2764.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_OLIM24: - f = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); - ff = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_high.bin","rb"); + f = romfopen(L"roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,L"rb"); + ff = romfopen(L"roms/olivetti_m24/olivetti_m24_version_1.43_high.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x4000; c += 2) { @@ -261,8 +252,8 @@ int loadbios() return 1; case ROM_PC2086: - f = romfopen("roms/pc2086/40179.ic129" ,"rb"); - ff = romfopen("roms/pc2086/40180.ic132","rb"); + f = romfopen(L"roms/pc2086/40179.ic129" ,L"rb"); + ff = romfopen(L"roms/pc2086/40180.ic132",L"rb"); if (!f || !ff) break; pclog("Loading BIOS\n"); for (c = 0x0000; c < 0x4000; c += 2) @@ -273,32 +264,26 @@ int loadbios() pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); fclose(ff); fclose(f); - f = romfopen("roms/pc2086/40186.ic171", "rb"); + f = romfopen(L"roms/pc2086/40186.ic171", L"rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_PC3086: - f = romfopen("roms/pc3086/fc00.bin" ,"rb"); + f = romfopen(L"roms/pc3086/fc00.bin", L"rb"); if (!f) break; fread(rom, 0x4000, 1, f); fclose(f); - f = romfopen("roms/pc3086/c000.bin", "rb"); + f = romfopen(L"roms/pc3086/c000.bin", L"rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_IBMAT: -/* f=romfopen("roms/AMIC206.BIN","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - return 1;*/ - case ROM_IBMAT386: - f = romfopen("roms/ibmat/62x0820.u27", "rb"); - ff =romfopen("roms/ibmat/62x0821.u47", "rb"); + f = romfopen(L"roms/ibmat/62x0820.u27", L"rb"); + ff =romfopen(L"roms/ibmat/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -309,8 +294,8 @@ int loadbios() fclose(f); return 1; case ROM_CMDPC30: - f = romfopen("roms/cmdpc30/commodore pc 30 iii even.bin", "rb"); - ff = romfopen("roms/cmdpc30/commodore pc 30 iii odd.bin", "rb"); + f = romfopen(L"roms/cmdpc30/commodore pc 30 iii even.bin", L"rb"); + ff = romfopen(L"roms/cmdpc30/commodore pc 30 iii odd.bin", L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -321,112 +306,65 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; -#if 0 - case ROM_CMDPC60: - f = romfopen("roms/cmdpc60/cbm-pc60c-bios-lo-v1.36-390473-07.bin", "rb"); - ff = romfopen("roms/cmdpc60/cbm-pc60c-bios-hi-v1.36-390474-07.bin", "rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x20000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; -#endif - case ROM_DELL200: - f=romfopen("roms/dells200/dell0.bin","rb"); - ff=romfopen("roms/dells200/dell1.bin","rb"); - if (!f || !ff) break; - for (c=0x0000;c<0x10000;c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - return 1; -/* case ROM_IBMAT386: - f=romfopen("roms/at386/at386.bin","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - return 1;*/ case ROM_AMI386SX: - f=romfopen("roms/ami386/ami386.bin","rb"); + f=romfopen(L"roms/ami386/ami386.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("roms/ami386dx/OPT495SX.AMI","rb"); + f=romfopen(L"roms/ami386dx/OPT495SX.AMI",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("roms/mr386dx/OPT495SX.MR","rb"); + f=romfopen(L"roms/mr386dx/OPT495SX.MR",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; -#if 0 - case ROM_ACER386: - f=romfopen("roms/acer386/acer386.bin","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - rom[0xB0]=0xB0-0x51; - rom[0x40d4]=0x51; /*PUSH CX*/ - f=romfopen("roms/acer386/oti067.bin","rb"); - if (!f) break; - fclose(f); - return 1; -#endif - case ROM_AMI286: - f=romfopen("roms/ami286/amic206.bin","rb"); + f=romfopen(L"roms/ami286/amic206.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_AWARD286: - f=romfopen("roms/award286/award.bin","rb"); + f=romfopen(L"roms/award286/award.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; - case ROM_EUROPC: - f=romfopen("roms/europc/50145","rb"); + case ROM_EUROPC: + f=romfopen(L"roms/europc/50145",L"rb"); if (!f) break; fread(rom+0x8000,32768,1,f); fclose(f); return 1; case ROM_IBMPC: - f=romfopen("roms/ibmpc/pc102782.bin","rb"); + f=romfopen(L"roms/ibmpc/pc102782.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.f6","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ fread(rom+0x6000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.f8","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); if (!f) break; /*But if some of it is there, then all of it must be*/ fread(rom+0x8000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fa","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); if (!f) break; fread(rom+0xA000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fc","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); @@ -434,8 +372,8 @@ int loadbios() case ROM_MEGAPC: case ROM_MEGAPCDX: - f = romfopen("roms/megapc/41651-bios lo.u18", "rb"); - ff = romfopen("roms/megapc/211253-bios hi.u19", "rb"); + f = romfopen(L"roms/megapc/41651-bios lo.u18", L"rb"); + ff = romfopen(L"roms/megapc/211253-bios hi.u19", L"rb"); if (!f || !ff) break; fseek(f, 0x8000, SEEK_SET); fseek(ff, 0x8000, SEEK_SET); @@ -449,22 +387,21 @@ int loadbios() return 1; case ROM_AMI486: - f=romfopen("roms/ami486/ami486.BIN","rb"); + f=romfopen(L"roms/ami486/ami486.BIN",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_WIN486: - f=romfopen("roms/win486/ALI1429G.AMW","rb"); + f=romfopen(L"roms/win486/ALI1429G.AMW",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_SIS496: - /* f = romfopen("roms/sis496/SIS496-1.AWA", "rb"); */ - f = romfopen("roms/sis496/SIS496_3.AWA", "rb"); + f = romfopen(L"roms/sis496/SIS496_3.AWA", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -473,7 +410,7 @@ int loadbios() return 1; case ROM_430VX: - f = romfopen("roms/430vx/55XWUQ0E.BIN", "rb"); + f = romfopen(L"roms/430vx/55XWUQ0E.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -481,12 +418,12 @@ int loadbios() return 1; case ROM_REVENGE: - f = romfopen("roms/revenge/1009AF2_.BIO", "rb"); + f = romfopen(L"roms/revenge/1009AF2_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/revenge/1009AF2_.BI1", "rb"); + f = romfopen(L"roms/revenge/1009AF2_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xc000, 1, f); @@ -494,12 +431,12 @@ int loadbios() biosmask = 0x1ffff; return 1; case ROM_ENDEAVOR: - f = romfopen("roms/endeavor/1006CB0_.BIO", "rb"); + f = romfopen(L"roms/endeavor/1006CB0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/endeavor/1006CB0_.BI1", "rb"); + f = romfopen(L"roms/endeavor/1006CB0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xd000, 1, f); @@ -508,7 +445,7 @@ int loadbios() return 1; case ROM_IBMPS1_2011: - f = romfopen("roms/ibmps1es/f80000.bin", "rb"); + f = romfopen(L"roms/ibmps1es/f80000.bin", L"rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -518,7 +455,7 @@ int loadbios() case ROM_IBMPS1_2121: case ROM_IBMPS1_2121_ISA: - f = romfopen("roms/ibmps1_2121/fc0000.bin", "rb"); + f = romfopen(L"roms/ibmps1_2121/fc0000.bin", L"rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -531,8 +468,8 @@ int loadbios() return 1; case ROM_DESKPRO_386: - f=romfopen("roms/deskpro386/109592-005.U11.bin","rb"); - ff=romfopen("roms/deskpro386/109591-005.U13.bin","rb"); + f=romfopen(L"roms/deskpro386/109592-005.U11.bin",L"rb"); + ff=romfopen(L"roms/deskpro386/109591-005.U13.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -545,78 +482,63 @@ int loadbios() return 1; case ROM_AMIXT: - f = romfopen("roms/amixt/AMI_8088_BIOS_31JAN89.BIN", "rb"); + f = romfopen(L"roms/amixt/AMI_8088_BIOS_31JAN89.BIN", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_LTXT: - f = romfopen("roms/ltxt/27C64.bin", "rb"); + f = romfopen(L"roms/ltxt/27C64.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_LXT3: - f = romfopen("roms/lxt3/27C64D.bin", "rb"); + f = romfopen(L"roms/lxt3/27C64D.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ - f = romfopen("roms/spc4200p/U8.01", "rb"); + f = romfopen(L"roms/spc4200p/U8.01", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; case ROM_SUPER286TR: /*Hyundai Super-286TR*/ - f = romfopen("roms/super286tr/hyundai_award286.bin", "rb"); + f = romfopen(L"roms/super286tr/hyundai_award286.bin", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; -#if 0 - case ROM_PX386: /*Phoenix 80386 BIOS*/ - f=romfopen("roms/px386/3iip001l.bin","rb"); - ff=romfopen("roms/px386/3iip001h.bin","rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x10000; c += 2) - { - rom[c] = getc(f); - rom[c+1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; -#endif - case ROM_DTK386: /*Uses NEAT chipset*/ - f = romfopen("roms/dtk386/3cto001.bin", "rb"); + f = romfopen(L"roms/dtk386/3cto001.bin", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; case ROM_PXXT: - f = romfopen("roms/pxxt/000p001.bin", "rb"); + f = romfopen(L"roms/pxxt/000p001.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_JUKOPC: - f = romfopen("roms/jukopc/000o001.bin", "rb"); + f = romfopen(L"roms/jukopc/000o001.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_IBMPS2_M30_286: - f = romfopen("roms/ibmps2_m30_286/33f5381a.bin", "rb"); + f = romfopen(L"roms/ibmps2_m30_286/33f5381a.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -628,14 +550,14 @@ int loadbios() return 1; case ROM_DTK486: - f = romfopen("roms/dtk486/4siw005.bin", "rb"); + f = romfopen(L"roms/dtk486/4siw005.bin", L"rb"); if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_R418: - f = romfopen("roms/r418/r418i.bin", "rb"); + f = romfopen(L"roms/r418/r418i.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -644,7 +566,7 @@ int loadbios() return 1; case ROM_586MC1: - f = romfopen("roms/586mc1/IS.34", "rb"); + f = romfopen(L"roms/586mc1/IS.34", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -652,12 +574,12 @@ int loadbios() return 1; case ROM_PLATO: - f = romfopen("roms/plato/1016AX1_.BIO", "rb"); + f = romfopen(L"roms/plato/1016AX1_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/plato/1016AX1_.BI1", "rb"); + f = romfopen(L"roms/plato/1016AX1_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xd000, 1, f); @@ -666,7 +588,7 @@ int loadbios() return 1; case ROM_MB500N: - f = romfopen("roms/mb500n/031396S.BIN", "rb"); /* Works */ + f = romfopen(L"roms/mb500n/031396S.BIN", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -674,7 +596,7 @@ int loadbios() return 1; case ROM_AP53: - f = romfopen("roms/ap53/AP53R2C0.ROM", "rb"); /* Works */ + f = romfopen(L"roms/ap53/AP53R2C0.ROM", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -682,7 +604,7 @@ int loadbios() return 1; case ROM_P55T2S: - f = romfopen("roms/p55t2s/S6Y08T.ROM", "rb"); /* Works */ + f = romfopen(L"roms/p55t2s/S6Y08T.ROM", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -690,7 +612,7 @@ int loadbios() return 1; case ROM_P54TP4XE: - f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb"); + f = romfopen(L"roms/p54tp4xe/T15I0302.AWD", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -698,7 +620,7 @@ int loadbios() return 1; case ROM_ACERM3A: - f = romfopen("roms/acerm3a/r01-b3.bin", "rb"); + f = romfopen(L"roms/acerm3a/r01-b3.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -706,7 +628,7 @@ int loadbios() return 1; case ROM_ACERV35N: - f = romfopen("roms/acerv35n/V35ND1S1.BIN", "rb"); + f = romfopen(L"roms/acerv35n/V35ND1S1.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -714,7 +636,7 @@ int loadbios() return 1; case ROM_P55VA: - f = romfopen("roms/p55va/VA021297.BIN", "rb"); + f = romfopen(L"roms/p55va/VA021297.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -722,7 +644,7 @@ int loadbios() return 1; case ROM_P55T2P4: - f = romfopen("roms/p55t2p4/0207_J2.BIN", "rb"); + f = romfopen(L"roms/p55t2p4/0207_J2.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -730,7 +652,7 @@ int loadbios() return 1; case ROM_P55TVP4: - f = romfopen("roms/p55tvp4/TV5I0204.AWD", "rb"); + f = romfopen(L"roms/p55tvp4/TV5I0204.AWD", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -738,7 +660,7 @@ int loadbios() return 1; case ROM_440FX: - f = romfopen("roms/440fx/NTMAW501.BIN", "rb"); /* Working Tyan BIOS. */ + f = romfopen(L"roms/440fx/NTMAW501.BIN", L"rb"); /* Working Tyan BIOS. */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -746,7 +668,7 @@ int loadbios() return 1; case ROM_S1668: - f = romfopen("roms/tpatx/S1668P.ROM", "rb"); /* Working Tyan BIOS. */ + f = romfopen(L"roms/tpatx/S1668P.ROM", L"rb"); /* Working Tyan BIOS. */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -754,12 +676,12 @@ int loadbios() return 1; case ROM_THOR: - f = romfopen("roms/thor/1006CN0_.BIO", "rb"); + f = romfopen(L"roms/thor/1006CN0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/thor/1006CN0_.BI1", "rb"); + f = romfopen(L"roms/thor/1006CN0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0x10000, 1, f); @@ -768,7 +690,7 @@ int loadbios() return 1; case ROM_MRTHOR: - f = romfopen("roms/mrthor/MR_ATX.BIO", "rb"); + f = romfopen(L"roms/mrthor/MR_ATX.BIO", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -776,12 +698,12 @@ int loadbios() return 1; case ROM_ZAPPA: - f = romfopen("roms/zappa/1006BS0_.BIO", "rb"); + f = romfopen(L"roms/zappa/1006BS0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/zappa/1006BS0_.BI1", "rb"); + f = romfopen(L"roms/zappa/1006BS0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0x10000, 1, f); @@ -790,8 +712,8 @@ int loadbios() return 1; case ROM_IBMPS2_M50: - f=romfopen("roms/i8550021/90x7423.zm14","rb"); - ff=romfopen("roms/i8550021/90x7426.zm16","rb"); + f=romfopen(L"roms/i8550021/90x7423.zm14",L"rb"); + ff=romfopen(L"roms/i8550021/90x7426.zm16",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x10000; c += 2) { @@ -800,8 +722,8 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/i8550021/90x7420.zm13","rb"); - ff=romfopen("roms/i8550021/90x7429.zm18","rb"); + f=romfopen(L"roms/i8550021/90x7420.zm13",L"rb"); + ff=romfopen(L"roms/i8550021/90x7429.zm18",L"rb"); if (!f || !ff) break; for (c = 0x10000; c < 0x20000; c += 2) { @@ -814,8 +736,8 @@ int loadbios() return 1; case ROM_IBMPS2_M55SX: - f=romfopen("roms/i8555081/33f8146.zm41","rb"); - ff=romfopen("roms/i8555081/33f8145.zm40","rb"); + f=romfopen(L"roms/i8555081/33f8146.zm41",L"rb"); + ff=romfopen(L"roms/i8555081/33f8145.zm40",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { @@ -828,8 +750,8 @@ int loadbios() return 1; case ROM_IBMPS2_M80: - f=romfopen("roms/i8580111/15f6637.bin","rb"); - ff=romfopen("roms/i8580111/15f6639.bin","rb"); + f=romfopen(L"roms/i8580111/15f6637.bin",L"rb"); + ff=romfopen(L"roms/i8580111/15f6639.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { diff --git a/src/mem.h b/src/mem.h index 7e888e207..f4cef2a31 100644 --- a/src/mem.h +++ b/src/mem.h @@ -107,8 +107,6 @@ void mem_write_null(uint32_t addr, uint8_t val, void *p); void mem_write_nullw(uint32_t addr, uint16_t val, void *p); void mem_write_nulll(uint32_t addr, uint32_t val, void *p); -FILE *romfopen(char *fn, char *mode); - mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; diff --git a/src/mfm_at.c b/src/mfm_at.c index ebbcde2a9..c4c1be484 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -8,6 +8,7 @@ #include #include +#include #include "ibm.h" #include "device.h" @@ -159,14 +160,14 @@ static void mfm_next_sector(mfm_t *mfm) } } -static void loadhd(mfm_t *mfm, int c, int d, const char *fn) +static void loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) { mfm_drive_t *drive = &mfm->drives[c]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -174,7 +175,7 @@ static void loadhd(mfm_t *mfm, int c, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index eac421b0a..fde48c45d 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -763,14 +763,14 @@ static void xebec_callback(void *p) } } -static void loadhd(xebec_t *xebec, int d, const char *fn) +static void loadhd(xebec_t *xebec, int d, const wchar_t *fn) { mfm_drive_t *drive = &xebec->drives[d]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -778,7 +778,7 @@ static void loadhd(xebec_t *xebec, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", @@ -858,7 +858,7 @@ static void *xebec_init() xebec_set_switches(xebec); - rom_init(&xebec->bios_rom, "roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, L"roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); @@ -885,7 +885,7 @@ static void xebec_close(void *p) static int xebec_available() { - return rom_present("roms/ibm_xebec_62x0822_1985.bin"); + return rom_present(L"roms/ibm_xebec_62x0822_1985.bin"); } device_t mfm_xebec_device = @@ -923,7 +923,7 @@ static void *dtc_5150x_init() xebec->drives[1].cfg_cyl = xebec->drives[1].tracks; xebec->drives[1].cfg_hpc = xebec->drives[1].hpc; - rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, L"roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); @@ -933,7 +933,7 @@ static void *dtc_5150x_init() } static int dtc_5150x_available() { - return rom_present("roms/dtc_cxd21a.bin"); + return rom_present(L"roms/dtc_cxd21a.bin"); } device_t dtc_5150x_device = diff --git a/src/model.c b/src/model.c index f92f0ea92..5be1bab9c 100644 --- a/src/model.c +++ b/src/model.c @@ -3,16 +3,15 @@ */ #include #include - #include "ibm.h" -#include "cdrom.h" -#include "cpu.h" +#include "cpu/cpu.h" +#include "io.h" #include "mem.h" +#include "rom.h" #include "model.h" #include "mouse.h" #include "mouse_ps2.h" -#include "io.h" -#include "rom.h" +#include "cdrom.h" #include "acerm3a.h" #include "ali1429.h" @@ -64,14 +63,14 @@ #include "sis496.h" #include "sis85c471.h" #include "sio.h" -#include "sound_ps1.h" -#include "sound_pssj.h" -#include "sound_sn76489.h" +#include "sound/snd_ps1.h" +#include "sound/snd_pssj.h" +#include "sound/snd_sn76489.h" #include "tandy_eeprom.h" #include "tandy_rom.h" #include "um8669f.h" -#include "vid_pcjr.h" -#include "vid_tandy.h" +#include "video/vid_pcjr.h" +#include "video/vid_tandy.h" #include "w83877f.h" #include "wd76c10.h" #include "xtide.h" @@ -159,7 +158,6 @@ MODEL models[] = {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, @@ -276,11 +274,11 @@ void common_init() pit_init(); if (serial_enabled[0]) { - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); } if (serial_enabled[1]) { - serial2_init(0x2f8, 3); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); } } @@ -307,7 +305,7 @@ void pcjr_init() pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); if (serial_enabled[0]) { - serial1_init(0x2f8, 3); + serial_setup(1, 0x2f8, 3); } keyboard_pcjr_init(); device_add(&sn76489_device); diff --git a/src/mouse.c b/src/mouse.c index 9fb10ccf2..3e11903dc 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,40 +1,22 @@ #include "ibm.h" #include "mouse.h" #include "mouse_serial.h" -#ifdef INPORT_MOUSE -# include "mouse_inport.h" -#endif #include "mouse_ps2.h" #include "mouse_bus.h" #include "amstrad.h" #include "keyboard_olim24.h" -#ifndef INPORTMOUSE -static mouse_t mouse_notimp = { - "Microsoft InPort Mouse", - "msinport", - MOUSE_TYPE_INPORT, - NULL, NULL, NULL -}; -#endif - - static mouse_t *mouse_list[] = { &mouse_serial_microsoft, /* 0 Microsoft Serial Mouse */ -#ifdef INPORTMOUSE - &mouse_inport, /* 1 Microsoft InPort Bus Mouse */ -#else - &mouse_notimp, /* 1 (not implemented) */ -#endif - &mouse_ps2_2_button, /* 2 PS/2 Mouse 2-button */ + &mouse_ps2_2_button, /* 1 PS/2 Mouse 2-button */ + &mouse_intellimouse, /* 2 PS/2 Intellimouse 3-button */ &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ - &mouse_intellimouse, /* 4 PS/2 Intellimouse 3-button */ - &mouse_amstrad, /* 5 Amstrad PC System Mouse */ - &mouse_olim24, /* 6 Olivetti M24 System Mouse */ + &mouse_amstrad, /* 4 Amstrad PC System Mouse */ + &mouse_olim24, /* 5 Olivetti M24 System Mouse */ #if 0 - &mouse_msystems, /* 7 Mouse Systems */ - &mouse_genius, /* 8 Genius Bus Mouse */ + &mouse_msystems, /* 6 Mouse Systems */ + &mouse_genius, /* 7 Genius Bus Mouse */ #endif NULL }; @@ -44,14 +26,16 @@ static void *mouse_p; int mouse_type = 0; -void mouse_emu_init(void) +void +mouse_emu_init(void) { cur_mouse = mouse_list[mouse_type]; mouse_p = cur_mouse->init(); } -void mouse_emu_close(void) +void +mouse_emu_close(void) { if (cur_mouse) cur_mouse->close(mouse_p); @@ -59,14 +43,16 @@ void mouse_emu_close(void) } -void mouse_poll(int x, int y, int z, int b) +void +mouse_poll(int x, int y, int z, int b) { if (cur_mouse) cur_mouse->poll(x, y, z, b, mouse_p); } -char *mouse_get_name(int mouse) +char * +mouse_get_name(int mouse) { if (!mouse_list[mouse]) return(NULL); @@ -74,18 +60,19 @@ char *mouse_get_name(int mouse) } -char *mouse_get_internal_name(int mouse) +char * +mouse_get_internal_name(int mouse) { return(mouse_list[mouse]->internal_name); } -int mouse_get_from_internal_name(char *s) +int +mouse_get_from_internal_name(char *s) { int c = 0; - while (mouse_list[c] != NULL) - { + while (mouse_list[c] != NULL) { if (!strcmp(mouse_list[c]->internal_name, s)) return(c); c++; @@ -95,14 +82,16 @@ int mouse_get_from_internal_name(char *s) } -int mouse_get_type(int mouse) +int +mouse_get_type(int mouse) { return(mouse_list[mouse]->type); } /* Return number of MOUSE types we know about. */ -int mouse_get_ndev(void) +int +mouse_get_ndev(void) { return(sizeof(mouse_list)/sizeof(mouse_t *) - 1); } diff --git a/src/mouse.h b/src/mouse.h index 701d5de9a..4ae2d8d76 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -3,14 +3,13 @@ #define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ -#define MOUSE_TYPE_INPORT 1 /* Microsoft InPort Bus Mouse */ -#define MOUSE_TYPE_PS2 2 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2 1 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2_MS 2 /* Microsoft Intellimouse PS/2 */ #define MOUSE_TYPE_BUS 3 /* Logitech/ATI Bus Mouse */ -#define MOUSE_TYPE_PS2_MS 4 -#define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ -#define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ -#define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ -#define MOUSE_TYPE_GENIUS 8 /* Genius Bus Mouse */ +#define MOUSE_TYPE_AMSTRAD 4 /* Amstrad PC system mouse */ +#define MOUSE_TYPE_OLIM24 5 /* Olivetti M24 system mouse */ +#define MOUSE_TYPE_MSYSTEMS 6 /* Mouse Systems mouse */ +#define MOUSE_TYPE_GENIUS 7 /* Genius Bus Mouse */ #define MOUSE_TYPE_MASK 0x0f #define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */ diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 19ddb98cb..ca2c4f80a 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -8,16 +8,19 @@ * * Implementation of Bus Mouse devices. * - * These mice devices were made by both Microsoft (InPort) and - * Logitech. Sadly, they did not use the same I/O protocol, but - * they were close enough to fit into a single implementation. + * These devices were made by both Microsoft and Logitech. At + * first, Microsoft used the same protocol as Logitech, but did + * switch to their new protocol for their InPort interface. So, + * although alike enough to be handled in the same driver, they + * are not the same. * - * Although the Minix driver blindly took IRQ5, the board seems - * to be able to tell the driver what IRQ it is set for. When - * testing on MS-DOS (6.22), the 'mouse.exe' driver did not want - * to start, and only after disassembling it and inspecting the - * code it was discovered that driver actually does use the IRQ - * reporting feature. In a really, really weird way, too: it + * This code is based on my Minix driver for the Logitech(-mode) + * interface. Although that driver blindly took IRQ5, the board + * seems to be able to tell the driver what IRQ it is set for. + * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not + * want to start, and only after disassembling it and inspecting + * the code it was discovered that driver actually does use the + * IRQ reporting feature. In a really, really weird way, too: it * sets up the board, and then reads the CTRL register which is * supposed to return that IRQ value. Depending on whether or * not the FREEZE bit is set, it has to return either the two's @@ -29,10 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * NOTE: Still have to add the code for the MS InPort mouse, which - * is very similar. Almost done, but not ready for release. - * - * Version: @(#)mouse_bus.c 1.0.3 2017/04/22 + * Version: @(#)mouse_bus.c 1.0.4 2017/05/06 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -50,13 +50,11 @@ #define ENABLE_3BTN 1 /* enable 3-button mode */ -/* Register definitions (based on Logitech info.) */ +/* Register definitions for Logitech mode. */ #define LTMOUSE_DATA 0 /* DATA register */ #define LTMOUSE_MAGIC 1 /* signature magic register */ # define MAGIC_BYTE1 0xa5 /* most drivers use this */ # define MAGIC_BYTE2 0x5a /* some drivers use this */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0xad #define LTMOUSE_CTRL 2 /* CTRL register */ # define CTRL_FREEZE 0x80 /* do not sample when set */ # define CTRL_RD_Y_HI 0x60 /* plus FREEZE */ @@ -64,15 +62,25 @@ # define CTRL_RD_X_HI 0x20 /* plus FREEZE */ # define CTRL_RD_X_LO 0x00 /* plus FREEZE */ # define CTRL_RD_MASK 0x60 -# define CTRL_IDISABLE 0x10 -# define CTRL_IENABLE 0x00 -# define CTRL_DFLT (CTRL_IDISABLE) +# define CTRL_IDIS 0x10 +# define CTRL_IENB 0x00 +# define CTRL_DFLT (CTRL_IDIS) #define LTMOUSE_CONFIG 3 /* CONFIG register */ # define CONFIG_DFLT 0x91 /* 8255 controller config */ +/* Register definitions for Microsoft mode. */ #define MSMOUSE_CTRL 0 /* CTRL register */ +# define MSCTRL_RESET 0x80 +# define MSCTRL_MODE 0x07 +# define MSCTRL_RD_Y 0x02 +# define MSCTRL_RD_X 0x01 +# define MSCTRL_RD_BUT 0x00 #define MSMOUSE_DATA 1 /* DATA register */ +# define MSDATA_BASE 0x10 +# define MSDATA_IRQ 0x01 #define MSMOUSE_MAGIC 2 /* MAGIC register */ +# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ +# define MAGIC_MSBYTE2 0xad #define MSMOUSE_CONFIG 3 /* CONFIG register */ @@ -92,47 +100,62 @@ typedef struct { uint8_t but; } mouse_bus_t; #define MOUSE_ENABLED 0x80 /* device is enabled for use */ -#define MOUSE_LOGITECH 0x40 /* running as Logitech mode */ -#define MOUSE_CMDFLAG 0x01 /* next wr is a command (MS) */ +#define MOUSE_LOGITECH 0x40 /* running in Logitech mode */ +#define MOUSE_MICROSOFT 0x20 /* running in Microsoft mode */ -/* Handle a write to the control register. */ +/* Handle a WRITE to a Microsoft-mode register. */ static void -wctrl(mouse_bus_t *ms, uint8_t val) +ms_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { - uint8_t b = (ms->r_ctrl ^ val); +#if 1 + pclog("BUSMOUSE: ms_write(%d,%02x)\n", port, val); +#endif - if (b & CTRL_FREEZE) { - /* Hold the sampling while we do something. */ - if (! (val & CTRL_FREEZE)) { - /* Reset current state. */ - ms->x = ms->y = 0; - if (ms->but) /* allow one more POLL for button-release */ - ms->but = 0x80; - } + switch (port) { + case MSMOUSE_CTRL: /* [00] control register */ + if (val & MSCTRL_RESET) { + /* Reset the interface. */ + ms->r_magic = MAGIC_MSBYTE1; + ms->r_conf = 0x00; + } + + /* Save new register value. */ + ms->r_ctrl = val; + break; + + case MSMOUSE_DATA: /* [01] data register */ + if (ms->r_ctrl == MSCTRL_MODE) { + ms->r_conf = val; + } + break; + + case MSMOUSE_MAGIC: /* [02] magic data register */ + break; + + case MSMOUSE_CONFIG: /* [03] config register */ + ms->r_conf = val; + ms->flags &= ~MOUSE_MICROSOFT; + ms->flags |= MOUSE_LOGITECH; + break; + + default: + break; } - - if (b & CTRL_IDISABLE) { - /* Disable or enable interrupts. */ - /* (we don't do anything for that here..) */ - } - - /* Save new register value. */ - ms->r_ctrl = val; } -/* Handle a WRITE operation to one of our registers. */ +/* Handle a WRITE to a LOGITECH-mode register. */ static void -busmouse_write(uint16_t port, uint8_t val, void *priv) +lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { - mouse_bus_t *ms = (mouse_bus_t *)priv; + uint8_t b = (ms->r_ctrl ^ val); -#if 0 - pclog("BUSMOUSE: write(%d,%02x)\n", port-ms->port, val); +#if 1 + pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val); #endif - switch (port-ms->port) { + switch (port) { case LTMOUSE_DATA: /* [00] data register */ break; @@ -144,7 +167,24 @@ busmouse_write(uint16_t port, uint8_t val, void *priv) break; case LTMOUSE_CTRL: /* [02] control register */ - wctrl(ms, val); + if (b & CTRL_FREEZE) { + /* Hold the sampling while we do something. */ + if (! (val & CTRL_FREEZE)) { + /* Reset current state. */ + ms->x = ms->y = 0; + if (ms->but) + /* One more POLL for button-release. */ + ms->but = 0x80; + } + } + + if (b & CTRL_IDIS) { + /* Disable or enable interrupts. */ + /* (we don't do anything for that here..) */ + } + + /* Save new register value. */ + ms->r_ctrl = val; break; case LTMOUSE_CONFIG: /* [03] config register */ @@ -157,6 +197,20 @@ busmouse_write(uint16_t port, uint8_t val, void *priv) } +/* Handle a WRITE operation to one of our registers. */ +static void +bm_write(uint16_t port, uint8_t val, void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + + if (ms->flags & MOUSE_LOGITECH) + lt_write(ms, port - ms->port, val); + + if (ms->flags & MOUSE_MICROSOFT) + ms_write(ms, port - ms->port, val); +} + + /* Handle a READ from a Microsoft-mode register. */ static uint8_t ms_read(mouse_bus_t *ms, uint16_t port) @@ -194,8 +248,8 @@ ms_read(mouse_bus_t *ms, uint16_t port) break; } -#if 0 - pclog("BUSMOUSE: msread(%d): %02x\n", port, r); +#if 1 + pclog("BUSMOUSE: ms_read(%d): %02x\n", port, r); #endif return(r); @@ -285,7 +339,7 @@ lt_read(mouse_bus_t *ms, uint16_t port) * first value is assumed to be the 2's complement of the * actual IRQ value. * Next, it does this a second time, but now with the - * IDISABLE bit clear (so, interrupts enabled), which is + * IDIS bit clear (so, interrupts enabled), which is * our cue to return the regular (not complemented) value * to them. * @@ -297,10 +351,10 @@ lt_read(mouse_bus_t *ms, uint16_t port) */ if (ms->r_intr++ < 250) /* Still settling, return invalid data. */ - r = (ms->r_ctrl&CTRL_IDISABLE)?0xff:0x00; + r = (ms->r_ctrl&CTRL_IDIS)?0xff:0x00; else { /* OK, all good, return correct data. */ - r = (ms->r_ctrl&CTRL_IDISABLE)?-ms->irq:ms->irq; + r = (ms->r_ctrl&CTRL_IDIS)?-ms->irq:ms->irq; ms->r_intr = 0; } break; @@ -313,8 +367,8 @@ lt_read(mouse_bus_t *ms, uint16_t port) break; } -#if 0 - pclog("BUSMOUSE: ltread(%d): %02x\n", port, r); +#if 1 + pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r); #endif return(r); @@ -323,14 +377,15 @@ lt_read(mouse_bus_t *ms, uint16_t port) /* Handle a READ operation from one of our registers. */ static uint8_t -busmouse_read(uint16_t port, void *priv) +bm_read(uint16_t port, void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; uint8_t r; if (ms->flags & MOUSE_LOGITECH) r = lt_read(ms, port - ms->port); - else + + if (ms->flags & MOUSE_MICROSOFT) r = ms_read(ms, port - ms->port); return(r); @@ -339,14 +394,10 @@ busmouse_read(uint16_t port, void *priv) /* The emulator calls us with an update on the host mouse device. */ static uint8_t -busmouse_poll(int x, int y, int z, int b, void *priv) +bm_poll(int x, int y, int z, int b, void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; -#if 0 - pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b); -#endif - /* Return early if nothing to do. */ if (!x && !y && !z && (ms->but == b)) return(1); @@ -354,6 +405,10 @@ busmouse_poll(int x, int y, int z, int b, void *priv) if (!(ms->flags & MOUSE_ENABLED) || (ms->r_ctrl & CTRL_FREEZE)) return(0); +#if 0 + pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b); +#endif + /* Add the delta to our state. */ x += ms->x; if (x > 127) @@ -372,7 +427,7 @@ busmouse_poll(int x, int y, int z, int b, void *priv) ms->but = b; /* All set, generate an interrupt. */ - if (! (ms->r_ctrl & CTRL_IDISABLE)) + if (! (ms->r_ctrl & CTRL_IDIS)) picint(1 << ms->irq); return(0); @@ -381,14 +436,13 @@ busmouse_poll(int x, int y, int z, int b, void *priv) /* Release all resources held by the device. */ static void -busmouse_close(void *priv) +bm_close(void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; /* Release our I/O range. */ io_removehandler(ms->port, ms->portlen, - busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, - ms); + bm_read, NULL, NULL, bm_write, NULL, NULL, ms); free(ms); } @@ -396,7 +450,7 @@ busmouse_close(void *priv) /* Initialize the device for use by the user. */ static void * -busmouse_init(void) +bm_init(void) { mouse_bus_t *ms; @@ -417,17 +471,12 @@ busmouse_init(void) ms->r_conf = CONFIG_DFLT; ms->r_ctrl = CTRL_DFLT; - /* - * Technically this is not possible, but we fake that we - * did a power-up initialization with default config as - * set in the "conf" register. Emulators rock! --FvK - */ - ms->flags = MOUSE_ENABLED; + /* Initialize with Microsoft-mode being default. */ + ms->flags = (MOUSE_ENABLED | MOUSE_MICROSOFT); /* Request an I/O range. */ io_sethandler(ms->port, ms->portlen, - busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, - ms); + bm_read, NULL, NULL, bm_write, NULL, NULL, ms); /* Return our private data to the I/O layer. */ return(ms); @@ -438,7 +487,7 @@ mouse_t mouse_bus = { "Bus Mouse", "msbus", MOUSE_TYPE_BUS, - busmouse_init, - busmouse_close, - busmouse_poll + bm_init, + bm_close, + bm_poll }; diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 84e85a673..8afe9b3b3 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -1,12 +1,29 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Serial Mouse devices. + * + * Based on the 86Box Serial Mouse driver as a framework. + * + * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 + * + * Author: Fred N. van Kempen, + */ #include #include "ibm.h" -#include "mouse.h" -#include "pic.h" -#include "serial.h" #include "timer.h" +#include "serial.h" +#include "mouse.h" +#include "mouse_serial.h" typedef struct mouse_serial_t { + int port; int pos, delay; int oldb; @@ -14,16 +31,19 @@ typedef struct mouse_serial_t { } mouse_serial_t; +/* Callback from serial driver: RTS was toggled. */ static void -sermouse_rcr(SERIAL *serial, void *priv) +sermouse_callback(void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - + + /* Start a timer to wake us up in a little while. */ ms->pos = -1; ms->delay = 5000 * (1 << TIMER_SHIFT); } +/* Callback timer expired, now send our "mouse ID" to the serial port. */ static void sermouse_timer(void *priv) { @@ -32,6 +52,8 @@ sermouse_timer(void *priv) ms->delay = 0; if (ms->pos == -1) { ms->pos = 0; + + /* This identifies a two-button Microsoft Serial mouse. */ serial_write_fifo(ms->serial, 'M'); } } @@ -41,10 +63,7 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - SERIAL *sp = ms->serial; - uint8_t mousedat[3]; - - if (!(sp->ier & 1)) return(1); + uint8_t data[3]; if (!x && !y && b == ms->oldb) return(1); @@ -55,24 +74,21 @@ sermouse_poll(int x, int y, int z, int b, void *priv) if (y<-128) y = -128; /* Use Microsoft format. */ - mousedat[0] = 0x40; - mousedat[0] |= (((y>>6)&3)<<2); - mousedat[0] |= ((x>>6)&3); - if (b&1) mousedat[0] |= 0x20; - if (b&2) mousedat[0] |= 0x10; - mousedat[1] = x & 0x3F; - mousedat[2] = y & 0x3F; + data[0] = 0x40; + data[0] |= (((y>>6)&3)<<2); + data[0] |= ((x>>6)&3); + if (b&1) data[0] |= 0x20; + if (b&2) data[0] |= 0x10; + data[1] = x & 0x3F; + data[2] = y & 0x3F; - /* FIXME: we should check in serial_write_fifo, not here! --FvK */ - if (! (sp->mctrl & 0x10)) { + /* Send the packet to the bottom-half of the attached port. */ #if 0 - pclog("Serial data %02X %02X %02X\n", - mousedat[0], mousedat[1], mousedat[2]); + pclog("Mouse_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); #endif - serial_write_fifo(ms->serial, mousedat[0]); - serial_write_fifo(ms->serial, mousedat[1]); - serial_write_fifo(ms->serial, mousedat[2]); - } + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); return(0); } @@ -83,11 +99,10 @@ sermouse_init(void) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; /* Attach a serial port to the mouse. */ - ms->serial = &serial1; - serial1.rcr_callback = sermouse_rcr; - serial1.rcr_callback_p = ms; + ms->serial = serial_attach(ms->port, sermouse_callback, ms); timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); @@ -101,7 +116,7 @@ sermouse_close(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; /* Detach serial port from the mouse. */ - serial1.rcr_callback = NULL; + serial_attach(ms->port, NULL, NULL); free(ms); } diff --git a/src/mouse_serial.h b/src/mouse_serial.h index 94e744d44..f37b32da2 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -1 +1,27 @@ -extern mouse_t mouse_serial_microsoft; +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Serial Mouse devices. + * + * Definitions for the Serial Mouse driver. + * + * Version: @(#)mouse_serial.h 1.0.2 2017/05/06 + * + * Author: Fred N. van Kempen, + */ +#ifndef MOUSE_SERIAL_H +# define MOUSE_SERIAL_H + + +#define SERMOUSE_PORT 1 /* attach to Serial1 */ + + +extern mouse_t mouse_serial_microsoft; + + +#endif /*MOUSE_SERIAL_H*/ diff --git a/src/ne2000.c b/src/ne2000.c deleted file mode 100644 index 9bcad3036..000000000 --- a/src/ne2000.c +++ /dev/null @@ -1,2440 +0,0 @@ -/* Copyright holders: Peter Grehan, SA1988, Tenshi - see COPYING for more details -*/ -/* - $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $ -*/ -/* - Copyright (C) 2002 MandrakeSoft S.A. - - MandrakeSoft S.A. - 43, rue d'Aboukir - 75002 Paris - France - http://www.linux-mandrake.com/ - http://www.mandrakesoft.com/ -*/ - -/* Peter Grehan (grehan@iprg.nokia.com) coded all of this - NE2000/ether stuff. */ -#include -#include -#include -#include -#include - -#include "slirp/slirp.h" -#include "slirp/queue.h" -#include - -#include "ibm.h" -#include "device.h" -#include "disc_random.h" - -#include "config.h" -#include "nethandler.h" - -#include "io.h" -#include "mem.h" -#include "nethandler.h" -#include "rom.h" - -#include "ne2000.h" -#include "pci.h" -#include "pic.h" -#include "timer.h" - -/* THIS IS THE DEFAULT MAC ADDRESS .... so it wont place nice with multiple VMs. YET. */ -uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; - -#define NETBLOCKING 0 /* we won't block our pcap */ - -pcap_t *net_pcap; - -queueADT slirpq; -int net_slirp_inited=0; -int net_is_pcap=0; /* and pretend pcap is dead. */ -int fizz=0; -void slirp_tic(); - -#define BX_RESET_HARDWARE 0 -#define BX_RESET_SOFTWARE 1 - -/* Never completely fill the ne2k ring so that we never - hit the unclear completely full buffer condition. */ -#define BX_NE2K_NEVER_FULL_RING (1) - -#define BX_NE2K_MEMSIZ (32*1024) -#define BX_NE2K_MEMSTART (16*1024) -#define BX_NE2K_MEMEND (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ) - -uint8_t rtl8029as_eeprom[128]; - -typedef struct ne2000_t -{ - /* ne2k register state */ - - /* Page 0 */ - - /* Command Register - 00h read/write */ - struct CR_t - { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ - uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ - uint8_t pgsel; /* PS0,PS1 - Page select */ - } CR; - /* Interrupt Status Register - 07h read/write */ - struct ISR_t - { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet transmitted with no errors */ - int rx_err; /* RXE - packet received with 1 or more errors */ - int tx_err; /* TXE - packet tx'd " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ - } ISR; - /* Interrupt Mask Register - 0fh write */ - struct IMR_t - { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ - } IMR; - /* Data Configuration Register - 0eh write */ - struct DCR_t - { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx packets with remote DMA */ - uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ - } DCR; - /* Transmit Configuration Register - 0dh write */ - struct TCR_t - { - int crc_disable; /* CRC - inhibit tx CRC */ - uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ - uint8_t reserved; /* D5,D6,D7 - reserved */ - } TCR; - /* Transmit Status Register - 04h read */ - struct TSR_t - { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ - } TSR; - /* Receive Configuration Register - 0ch write */ - struct RCR_t - { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ - uint8_t reserved; /* D6,D7 - reserved */ - } RCR; - /* Receive Status Register - 0ch read */ - struct RSR_t - { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ - } RSR; - - uint16_t local_dma; /* 01,02h read ; current local DMA addr */ - uint8_t page_start; /* 01h write ; page start register */ - uint8_t page_stop; /* 02h write ; page stop register */ - uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ - uint8_t tx_page_start; /* 04h write ; transmit page start register */ - uint8_t num_coll; /* 05h read ; number-of-collisions register */ - uint16_t tx_bytes; /* 05,06h write ; transmit byte-count register */ - uint8_t fifo; /* 06h read ; FIFO */ - uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ - uint16_t remote_start; /* 08,09h write ; remote start address register */ - uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count register */ - uint8_t tallycnt_0; /* 0dh read ; tally counter 0 (frame align errors) */ - uint8_t tallycnt_1; /* 0eh read ; tally counter 1 (CRC errors) */ - uint8_t tallycnt_2; /* 0fh read ; tally counter 2 (missed pkt errors) */ - - /* Page 1 */ - - /* Command Register 00h (repeated) */ - - uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ - uint8_t curr_page; /* 07h read/write ; current page register */ - uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ - - /* Page 2 - diagnostic use only */ - - /* Command Register 00h (repeated) */ - - /* Page Start Register 01h read (repeated) - Page Stop Register 02h read (repeated) - Current Local DMA Address 01,02h write (repeated) - Transmit Page start address 04h read (repeated) - Receive Configuration Register 0ch read (repeated) - Transmit Configuration Register 0dh read (repeated) - Data Configuration Register 0eh read (repeated) - Interrupt Mask Register 0fh read (repeated) - */ - uint8_t rempkt_ptr; /* 03h read/write ; remote next-packet pointer */ - uint8_t localpkt_ptr; /* 05h read/write ; local next-packet pointer */ - uint16_t address_cnt; /* 06,07h read/write ; address counter */ - - /* Page 3 - should never be modified. */ - - /* Novell ASIC state */ - uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ - uint8_t mem[BX_NE2K_MEMSIZ]; /* on-chip packet memory */ - - /* ne2k internal state */ - uint32_t base_address; - int base_irq; - int tx_timer_index; - int tx_timer_active; - - rom_t bios_rom; - -} ne2000_t; - -int disable_netbios = 0; - -void ne2000_tx_event(void *p, uint32_t val); -uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len); -void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len); -void ne2000_rx_frame(void *p, const void *buf, int io_len); - -int ne2000_do_log = 0; - -void ne2000_log(const char *format, ...) -{ -#ifdef ENABLE_NE2000_LOG - if (ne2000_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -static uint8_t *ne2000_mac() -{ - if (network_card_current == 2) - { - return maclocal_pci; - } - else - { - return maclocal; - } -} - -void ne2000_generate_maclocal(int mac) -{ - maclocal[0] = 0x00; /* 00:00:1B (NE2000 ISA vendor prefix). */ - maclocal[1] = 0x00; - maclocal[2] = 0x1B; - - if (mac & 0xff000000) - { - /* Generating new MAC. */ - maclocal[3] = disc_random_generate(); - maclocal[4] = disc_random_generate(); - maclocal[5] = disc_random_generate(); - } - else - { - maclocal[3] = (mac >> 16) & 0xff; - maclocal[4] = (mac >> 8) & 0xff; - maclocal[5] = mac & 0xff; - } -} - -void ne2000_generate_maclocal_pci(int mac) -{ - maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal_pci[1] = 0x20; - maclocal_pci[2] = 0x18; - - if (mac & 0xff000000) - { - /* Generating new MAC. */ - maclocal_pci[3] = disc_random_generate(); - maclocal_pci[4] = disc_random_generate(); - maclocal_pci[5] = disc_random_generate(); - } - else - { - maclocal_pci[3] = (mac >> 16) & 0xff; - maclocal_pci[4] = (mac >> 8) & 0xff; - maclocal_pci[5] = mac & 0xff; - } -} - -int net2000_get_maclocal() -{ - int temp; - temp = (((int) maclocal[3]) << 16); - temp |= (((int) maclocal[4]) << 8); - temp |= ((int) maclocal[5]); - return temp; -} - -int net2000_get_maclocal_pci() -{ - int temp; - temp = (((int) maclocal_pci[3]) << 16); - temp |= (((int) maclocal_pci[4]) << 8); - temp |= ((int) maclocal_pci[5]); - return temp; -} - -static void ne2000_setirq(ne2000_t *ne2000, int irq) -{ - ne2000->base_irq = irq; -} - -/* reset - restore state to power-up, cancelling all i/o */ - -static void ne2000_reset(void *p, int reset) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - int i; - - ne2000_log("ne2000 reset\n"); - - /* Initialise the mac address area by doubling the physical address */ - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; - - /* ne2k signature */ - for (i = 12; i < 32; i++) - { - ne2000->macaddr[i] = 0x57; - } - - /* Zero out registers and memory */ - memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); - memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); - memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); - memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); - memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); - memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); - memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); - ne2000->tx_timer_active = 0; - ne2000->local_dma = 0; - ne2000->page_start = 0; - ne2000->page_stop = 0; - ne2000->bound_ptr = 0; - ne2000->tx_page_start = 0; - ne2000->num_coll = 0; - ne2000->tx_bytes = 0; - ne2000->fifo = 0; - ne2000->remote_dma = 0; - ne2000->remote_start = 0; - ne2000->remote_bytes = 0; - ne2000->tallycnt_0 = 0; - ne2000->tallycnt_1 = 0; - ne2000->tallycnt_2 = 0; - - ne2000->curr_page = 0; - - ne2000->rempkt_ptr = 0; - ne2000->localpkt_ptr = 0; - ne2000->address_cnt = 0; - - memset( & ne2000->mem, 0, sizeof(ne2000->mem)); - - /* Set power-up conditions */ - ne2000->CR.stop = 1; - ne2000->CR.rdma_cmd = 4; - ne2000->ISR.reset = 1; - ne2000->DCR.longaddr = 1; - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); -} - -#include "bswap.h" - -/* read_cr/write_cr - utility routines for handling reads/writes to - the Command Register */ - -uint32_t ne2000_read_cr(ne2000_t *ne2000) -{ - uint32_t val; - - val = (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); - ne2000_log("%s: read CR returns 0x%02x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); - return val; -} - -void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) -{ - ne2000_log("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); - - /* Validate remote-DMA */ - if ((value & 0x38) == 0x00) - { - ne2000_log("CR write - invalid rDMA value 0\n"); - value |= 0x20; /* dma_cmd == 4 is a safe default */ - } - - /* Check for s/w reset */ - if (value & 0x01) - { - ne2000->ISR.reset = 1; - ne2000->CR.stop = 1; - } else { - ne2000->CR.stop = 0; - } - - ne2000->CR.rdma_cmd = (value & 0x38) >> 3; - - /* If start command issued, the RST bit in the ISR */ - /* must be cleared */ - if ((value & 0x02) && !ne2000->CR.start) - { - ne2000->ISR.reset = 0; - } - - ne2000->CR.start = ((value & 0x02) == 0x02); - ne2000->CR.pgsel = (value & 0xc0) >> 6; - - /* Check for send-packet command */ - if (ne2000->CR.rdma_cmd == 3) - { - /* Set up DMA read from receive ring */ - ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; - ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); - ne2000_log("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); - } - - /* Check for start-tx */ - if ((value & 0x04) && ne2000->TCR.loop_cntl) - { - if (ne2000->TCR.loop_cntl != 1) - { - ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } - else - { - ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - } - } - else if (value & 0x04) - { - if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) - { - if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ - { - return; /* Solaris9 probe */ - } - ne2000_log("CR write - tx start, dev in reset\n"); - } - - if (ne2000->tx_bytes == 0) - { - ne2000_log("CR write - tx start, tx bytes == 0\n"); - } - - /* Send the packet to the system driver */ - ne2000->CR.tx_packet = 1; - if(!net_is_pcap) - { - slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - ne2000_log("ne2000 slirp sending packet\n"); - } - else if (net_is_pcap && (net_pcap != NULL)) - { - pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - ne2000_log("ne2000 pcap sending packet\n"); - } - - /* some more debug */ - if (ne2000->tx_timer_active) - { - ne2000_log("CR write, tx timer still active\n"); - } - - ne2000_tx_event(ne2000, value); - } - - /* Linux probes for an interrupt by setting up a remote-DMA read - of 0 bytes with remote-DMA completion interrupts enabled. - Detect this here */ - if (ne2000->CR.rdma_cmd == 0x01 && - ne2000->CR.start && - ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - if (network_card_current == 1) - { - picintc(1 << ne2000->base_irq); - } - } - } -} - -/* chipmem_read/chipmem_write - access the 64K private RAM. - The ne2000 memory is accessed through the data port of - the asic (offset 0) after setting up a remote-DMA transfer. - Both byte and word accesses are allowed. - The first 16 bytes contains the MAC address at even locations, - and there is 16K of buffer memory starting at 16K -*/ - -uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) -{ - uint32_t retval = 0; - - if ((io_len == 2) && (address & 0x1)) - { - ne2000_log("unaligned chipmem word read\n"); - } - - /* ROM'd MAC address */ - if ((address >=0) && (address <= 31)) - { - retval = ne2000->macaddr[address % 32]; - if ((io_len == 2) || (io_len == 4)) - { - retval |= (ne2000->macaddr[(address + 1) % 32] << 8); - } - if (io_len == 4) - { - retval |= (ne2000->macaddr[(address + 2) % 32] << 16); - retval |= (ne2000->macaddr[(address + 3) % 32] << 24); - } - return (retval); - } - - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - { - retval = ne2000->mem[address - BX_NE2K_MEMSTART]; - if ((io_len == 2) || (io_len == 4)) - { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); - } - if (io_len == 4) - { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); - } - return (retval); - } - - ne2000_log("out-of-bounds chipmem read, %04X\n", address); - - if (network_card_current == 1) - { - switch(io_len) - { - case 1: - return 0xff; - case 2: - return 0xffff; - } - } - else - { - return 0xff; - } - - return 0xffff; -} - -void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) -{ - if ((io_len == 2) && (address & 0x1)) - { - ne2000_log("unaligned chipmem word write\n"); - } - - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - { - ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; - if ((io_len == 2) || (io_len == 4)) - { - ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; - } - if (io_len == 4) - { - ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; - ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; - } - } - else - { - ne2000_log("out-of-bounds chipmem write, %04X\n", address); - } -} - -/* asic_read/asic_write - This is the high 16 bytes of i/o space - (the lower 16 bytes is for the DS8390). Only two locations - are used: offset 0, which is used for data transfer, and - offset 0xf, which is used to reset the device. - The data transfer port is used to as 'external' DMA to the - DS8390. The chip has to have the DMA registers set up, and - after that, insw/outsw instructions can be used to move - the appropriate number of bytes to/from the device. -*/ -uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) -{ - uint32_t retval = 0; - - switch (offset) - { - case 0x0: /* Data register */ - - /* A read remote-DMA command must have been issued, - and the source-address and length registers must - have been initialised. */ - - if (io_len > ne2000->remote_bytes) - { - ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); - } - - ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); - retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); - - /* The 8390 bumps the address and decreases the byte count - by the selected word size after every access, not by - the amount of data requested by the host (io_len). */ - - if (io_len == 4) - { - ne2000->remote_dma += io_len; - } - else - { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - - if (ne2000->remote_dma == ne2000->page_stop << 8) - { - ne2000->remote_dma = ne2000->page_start << 8; - } - - /* keep s.remote_bytes from underflowing */ - if (ne2000->remote_bytes > ne2000->DCR.wdsize) - { - if (io_len == 4) - { - ne2000->remote_bytes -= io_len; - } - else - { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - } - else - { - ne2000->remote_bytes = 0; - } - - /* If all bytes have been written, signal remote-DMA complete */ - if (ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - } - } - break; - - case 0xf: /* Reset register */ - ne2000_reset(ne2000, BX_RESET_SOFTWARE); - break; - - default: - ne2000_log("asic read invalid address %04x\n", (unsigned) offset); - break; - } - - return (retval); -} - -void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); - switch (offset) - { - case 0x0: /* Data register - see asic_read for a description */ - if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) - { - ne2000_log("dma write length %d on byte mode operation\n", io_len); - break; - } - if (ne2000->remote_bytes == 0) - { - ne2000_log("dma write, byte count 0\n"); - } - - ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); - if (io_len == 4) - { - ne2000->remote_dma += io_len; - } - else - { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - - if (ne2000->remote_dma == ne2000->page_stop << 8) - { - ne2000->remote_dma = ne2000->page_start << 8; - } - - if (io_len == 4) - { - ne2000->remote_bytes -= io_len; - } - else - { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - - if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) - { - ne2000->remote_bytes = 0; - } - - /* If all bytes have been written, signal remote-DMA complete */ - if (ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - } - } - break; - - case 0xf: /* Reset register */ - /* end of reset pulse */ - break; - - default: /* this is invalid, but happens under win95 device detection */ - ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); - break; - } -} - -/* page0_read/page0_write - These routines handle reads/writes to - the 'zeroth' page of the DS8390 register file */ - -uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) -{ - uint8_t value = 0; - - if (io_len > 1) - { - ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, io_len); /* encountered with win98 hardware probe */ - return value; - } - - switch (offset) - { - case 0x1: /* CLDA0 */ - value = (ne2000->local_dma & 0xff); - break; - - case 0x2: /* CLDA1 */ - value = (ne2000->local_dma >> 8); - break; - - case 0x3: /* BNRY */ - value = ne2000->bound_ptr; - break; - - case 0x4: /* TSR */ - value = ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); - break; - - case 0x5: /* NCR */ - value = ne2000->num_coll; - break; - - case 0x6: /* FIFO */ - /* reading FIFO is only valid in loopback mode */ - ne2000_log("reading FIFO not supported yet\n"); - value = ne2000->fifo; - break; - - case 0x7: /* ISR */ - value = ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - break; - - case 0x8: /* CRDA0 */ - value = (ne2000->remote_dma & 0xff); - break; - - case 0x9: /* CRDA1 */ - value = (ne2000->remote_dma >> 8); - break; - - case 0xa: /* reserved / RTL8029ID0 */ - if (network_card_current == 2) - { - value = 0x50; - } - else - { - ne2000_log("reserved read - page 0, 0xa\n"); - value = 0xff; - } - break; - - case 0xb: /* reserved / RTL8029ID1 */ - if (network_card_current == 2) - { - value = 0x43; - } - else - { - ne2000_log("reserved read - page 0, 0xb\n"); - value = 0xff; - } - break; - - case 0xc: /* RSR */ - value = ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); - break; - - case 0xd: /* CNTR0 */ - value = ne2000->tallycnt_0; - break; - - case 0xe: /* CNTR1 */ - value = ne2000->tallycnt_1; - break; - - case 0xf: /* CNTR2 */ - value = ne2000->tallycnt_2; - break; - - default: - ne2000_log("page 0 register 0x%02x out of range\n", offset); - break; - } - - ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); - return value; -} - -void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - uint8_t value2; - - /* It appears to be a common practice to use outw on page0 regs... */ - - /* break up outw into two outb's */ - if (io_len == 2) - { - ne2000_page0_write(ne2000, offset, (value & 0xff), 1); - if (offset < 0x0f) - { - ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); - } - return; - } - - ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); - - switch (offset) - { - case 0x1: /* PSTART */ - ne2000->page_start = value; - break; - - case 0x2: /* PSTOP */ - ne2000->page_stop = value; - break; - - case 0x3: /* BNRY */ - ne2000->bound_ptr = value; - break; - - case 0x4: /* TPSR */ - ne2000->tx_page_start = value; - break; - - case 0x5: /* TBCR0 */ - /* Clear out low byte and re-insert */ - ne2000->tx_bytes &= 0xff00; - ne2000->tx_bytes |= (value & 0xff); - break; - - case 0x6: /* TBCR1 */ - /* Clear out high byte and re-insert */ - ne2000->tx_bytes &= 0x00ff; - ne2000->tx_bytes |= ((value & 0xff) << 8); - break; - - case 0x7: /* ISR */ - value &= 0x7f; /* clear RST bit - status-only bit */ - /* All other values are cleared iff the ISR bit is 1 */ - ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); - ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); - ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); - ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); - ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); - ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value == 0) - { - picintc(1 << ne2000->base_irq); - } - break; - - case 0x8: /* RSAR0 */ - /* Clear out low byte and re-insert */ - ne2000->remote_start &= 0xff00; - ne2000->remote_start |= (value & 0xff); - ne2000->remote_dma = ne2000->remote_start; - break; - - case 0x9: /* RSAR1 */ - /* Clear out high byte and re-insert */ - ne2000->remote_start &= 0x00ff; - ne2000->remote_start |= ((value & 0xff) << 8); - ne2000->remote_dma = ne2000->remote_start; - break; - - case 0xa: /* RBCR0 */ - /* Clear out low byte and re-insert */ - ne2000->remote_bytes &= 0xff00; - ne2000->remote_bytes |= (value & 0xff); - break; - - case 0xb: /* RBCR1 */ - /* Clear out high byte and re-insert */ - ne2000->remote_bytes &= 0x00ff; - ne2000->remote_bytes |= ((value & 0xff) << 8); - break; - - case 0xc: /* RCR */ - /* Check if the reserved bits are set */ - if (value & 0xc0) - { - ne2000_log("RCR write, reserved bits set\n"); - } - - /* Set all other bit-fields */ - ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); - ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); - ne2000->RCR.broadcast = ((value & 0x04) == 0x04); - ne2000->RCR.multicast = ((value & 0x08) == 0x08); - ne2000->RCR.promisc = ((value & 0x10) == 0x10); - ne2000->RCR.monitor = ((value & 0x20) == 0x20); - - /* Monitor bit is a little suspicious... */ - if (value & 0x20) - { - ne2000_log("RCR write, monitor bit set!\n"); - } - break; - - case 0xd: /* TCR */ - /* Check reserved bits */ - if (value & 0xe0) - { - ne2000_log("TCR write, reserved bits set\n"); - } - - /* Test loop mode (not supported) */ - if (value & 0x06) - { - ne2000->TCR.loop_cntl = (value & 0x6) >> 1; - ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } - else - { - ne2000->TCR.loop_cntl = 0; - } - - /* Inhibit-CRC not supported. */ - if (value & 0x01) - { - ne2000_log("TCR write, inhibit-CRC not supported\n"); - } - - /* Auto-transmit disable very suspicious */ - if (value & 0x08) - { - ne2000_log("TCR write, auto transmit disable not supported\n"); - } - - /* Allow collision-offset to be set, although not used */ - ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); - break; - - case 0xe: /* DCR */ - /* the loopback mode is not suppported yet */ - if (!(value & 0x08)) - { - ne2000_log("DCR write, loopback mode selected\n"); - } - /* It is questionable to set longaddr and auto_rx, since they - aren't supported on the ne2000. Print a warning and continue */ - if (value & 0x04) - { - ne2000_log("DCR write - LAS set ???\n"); - } - if (value & 0x10) - { - ne2000_log("DCR write - AR set ???\n"); - } - - /* Set other values. */ - ne2000->DCR.wdsize = ((value & 0x01) == 0x01); - ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); /* illegal ? */ - ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); /* also illegal ? */ - ne2000->DCR.fifo_size = (value & 0x50) >> 5; - break; - - case 0xf: /* IMR */ - /* Check for reserved bit */ - if (value & 0x80) - { - ne2000_log("IMR write, reserved bit set\n"); - } - - /* Set other values */ - ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); - ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); - ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); - ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); - ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); - ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); - ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - value2 = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - if (((value & value2) & 0x7f) == 0) - { - picintc(1 << ne2000->base_irq); - } - else - { - picint(1 << ne2000->base_irq); - } - break; - - default: - ne2000_log("page 0 write, bad register 0x%02x\n", offset); - break; - } -} - -/* page1_read/page1_write - These routines handle reads/writes to - the first page of the DS8390 register file */ - -uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) -{ - ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); - - switch (offset) - { - case 0x1: /* PAR0-5 */ - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - return (ne2000->physaddr[offset - 1]); - - case 0x7: /* CURR */ - ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); - return (ne2000->curr_page); - - case 0x8: /* MAR0-7 */ - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - return (ne2000->mchash[offset - 8]); - - default: - ne2000_log("page 1 read register 0x%02x out of range\n", offset); - return 0; - } -} - -void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - - switch (offset) - { - case 0x1: /* PAR0-5 */ - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - ne2000->physaddr[offset - 1] = value; - if (offset == 6) - { - ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", ne2000->physaddr[0], ne2000->physaddr[1], ne2000->physaddr[2], ne2000->physaddr[3], ne2000->physaddr[4], ne2000->physaddr[5]); - } - break; - - case 0x7: /* CURR */ - ne2000->curr_page = value; - break; - - case 0x8: /* MAR0-7 */ - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000->mchash[offset - 8] = value; - break; - - default: - ne2000_log("page 1 write register 0x%02x out of range\n", offset); - break; - } -} - -/* page2_read/page2_write - These routines handle reads/writes to - the second page of the DS8390 register file */ - -uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) -{ - ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); - - switch (offset) - { - case 0x1: /* PSTART */ - return (ne2000->page_start); - - case 0x2: /* PSTOP */ - return (ne2000->page_stop); - - case 0x3: /* Remote Next-packet pointer */ - return (ne2000->rempkt_ptr); - - case 0x4: /* TPSR */ - return (ne2000->tx_page_start); - - case 0x5: /* Local Next-packet pointer */ - return (ne2000->localpkt_ptr); - - case 0x6: /* Address counter (upper) */ - return (ne2000->address_cnt >> 8); - - case 0x7: /* Address counter (lower) */ - return (ne2000->address_cnt & 0xff); - - case 0x8: /* Reserved */ - case 0x9: - case 0xa: - case 0xb: - ne2000_log("reserved read - page 2, register 0x%02x\n", offset); - return (0xff); - - case 0xc: /* RCR */ - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); - - case 0xd: /* TCR */ - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); - - case 0xe: /* DCR */ - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); - - case 0xf: /* IMR */ - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - - default: - ne2000_log("page 2 register 0x%02x out of range\n", offset); - break; - } - - return (0); -} - -void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - /* Maybe all writes here should be BX_PANIC()'d, since they - affect internal operation, but let them through for now - and print a warning. */ - ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - - switch (offset) - { - case 0x1: /* CLDA0 */ - /* Clear out low byte and re-insert */ - ne2000->local_dma &= 0xff00; - ne2000->local_dma |= (value & 0xff); - break; - - case 0x2: /* CLDA1 */ - /* Clear out high byte and re-insert */ - ne2000->local_dma &= 0x00ff; - ne2000->local_dma |= ((value & 0xff) << 8); - break; - - case 0x3: /* Remote Next-pkt pointer */ - ne2000->rempkt_ptr = value; - break; - - case 0x4: - ne2000_log("page 2 write to reserved register 0x04\n"); - break; - - case 0x5: /* Local Next-packet pointer */ - ne2000->localpkt_ptr = value; - break; - - case 0x6: /* Address counter (upper) */ - /* Clear out high byte and re-insert */ - ne2000->address_cnt &= 0x00ff; - ne2000->address_cnt |= ((value & 0xff) << 8); - break; - - case 0x7: /* Address counter (lower) */ - /* Clear out low byte and re-insert */ - ne2000->address_cnt &= 0xff00; - ne2000->address_cnt |= (value & 0xff); - break; - - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000_log("page 2 write to reserved register 0x%02x\n", offset); - break; - - default: - ne2000_log("page 2 write, illegal register 0x%02x\n", offset); - break; - } -} - -/* page3_read/page3_write - writes to this page are illegal */ - -uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) -{ - if (network_card_current == 2) - { - switch (offset) - { - case 0x3: /* CONFIG0 */ - return (0); - case 0x5: /* CONFIG2 */ - return (0x40); - case 0x6: /* CONFIG3 */ - return (0x40); - default: - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } - } - else - { - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } -} - -void ne2000_page3_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - ne2000_log("page 3 write register 0x%02x attempted\n", offset); - return; -} - -void ne2000_tx_event(void *p, uint32_t val) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - - ne2000_log("tx_timer\n"); - ne2000->CR.tx_packet = 0; - ne2000->TSR.tx_ok = 1; - ne2000->ISR.pkt_tx = 1; - /* Generate an interrupt if not masked */ - if (ne2000->IMR.tx_inte) - { - picint(1 << ne2000->base_irq); - } - ne2000->tx_timer_active = 0; -} - -/* read_handler/read - i/o 'catcher' function called from BOCHS - mainline when the CPU attempts a read in the i/o space registered - by this ne2000 instance */ - -uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) -{ - uint32_t retval = 0; - int offset = address - ne2000->base_address; - - ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); - - if (offset >= 0x10) - { - retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); - } - else if (offset == 0x00) - { - retval = ne2000_read_cr(ne2000); - } - else - { - switch (ne2000->CR.pgsel) - { - case 0x00: - retval = ne2000_page0_read(ne2000, offset, io_len); - break; - - case 0x01: - retval = ne2000_page1_read(ne2000, offset, io_len); - break; - - case 0x02: - retval = ne2000_page2_read(ne2000, offset, io_len); - break; - - case 0x03: - retval = ne2000_page3_read(ne2000, offset, io_len); - break; - - default: - ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - break; - } - } - - return (retval); -} - -void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) -{ - int offset = address - ne2000->base_address; - - ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); - - /* The high 16 bytes of i/o space are for the ne2000 asic - - the low 16 bytes are for the DS8390, with the current - page being selected by the PS0,PS1 registers in the - command register */ - - if (offset >= 0x10) - { - ne2000_asic_write(ne2000, offset - 0x10, value, io_len); - } - else if (offset == 0x00) - { - ne2000_write_cr(ne2000, value); - } - else - { - switch (ne2000->CR.pgsel) - { - case 0x00: - ne2000_page0_write(ne2000, offset, value, io_len); - break; - - case 0x01: - ne2000_page1_write(ne2000, offset, value, io_len); - break; - - case 0x02: - ne2000_page2_write(ne2000, offset, value, io_len); - break; - - case 0x03: - ne2000_page3_write(ne2000, offset, value, io_len); - break; - - default: - ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; - } - } -} - -/* - * mcast_index() - return the 6-bit index into the multicast - * table. Stolen unashamedly from FreeBSD's if_ed.c - */ -static int mcast_index(const void *dst) -{ -#define POLYNOMIAL 0x04c11db6 - unsigned long crc = 0xffffffffL; - int carry, i, j; - unsigned char b; - unsigned char *ep = (unsigned char *) dst; - - for (i = 6; --i >= 0;) - { - b = *ep++; - for (j = 8; --j >= 0;) - { - carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); - crc <<= 1; - b >>= 1; - if (carry) - { - crc = ((crc ^ POLYNOMIAL) | carry); - } - } - } - return (crc >> 26); -#undef POLYNOMIAL -} - -/* - * rx_frame() - called by the platform-specific code when an - * ethernet frame has been received. The destination address - * is tested to see if it should be accepted, and if the - * rx ring has enough room, it is copied into it and - * the receive process is updated - */ -void ne2000_rx_frame(void *p, const void *buf, int io_len) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - - int pages; - int avail; - int idx; - int nextpage; - uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *) buf; - uint8_t *startptr; - static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; - - if(io_len != 60) - { - ne2000_log("rx_frame with length %d\n", io_len); - } - - if ((ne2000->CR.stop != 0) || - (ne2000->page_start == 0)) - { - return; - } - - /* Add the pkt header + CRC to the length, and work - out how many 256-byte pages the frame would occupy */ - pages = (io_len + 4 + 4 + 255)/256; - - if (ne2000->curr_page < ne2000->bound_ptr) - { - avail = ne2000->bound_ptr - ne2000->curr_page; - } - else - { - avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->bound_ptr); - } - - /* Avoid getting into a buffer overflow condition by not attempting - to do partial receives. The emulation to handle this condition - seems particularly painful. */ - if ((avail < pages) -#if BX_NE2K_NEVER_FULL_RING - || (avail == pages) -#endif - ) - { - ne2000_log("no space\n"); - return; - } - - if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) - { - ne2000_log("rejected small packet, length %d\n", io_len); - return; - } - /* some computers don't care... */ - if (io_len < 60) - { - io_len=60; - } - - /* Do address filtering if not in promiscuous mode */ - if (! ne2000->RCR.promisc) - { - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (bcast_addr); - mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); - if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) - { - if (!ne2000->RCR.broadcast) - { - return; - } - } - else if (pktbuf[0] & 0x01) - { - if (! ne2000->RCR.multicast) - { - return; - } - idx = mcast_index(buf); - if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) - { - return; - } - } - else if (0 != memcmp(buf, ne2000->physaddr, 6)) - { - return; - } - } - else - { - ne2000_log("rx_frame promiscuous receive\n"); - } - - ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); - - nextpage = ne2000->curr_page + pages; - if (nextpage >= ne2000->page_stop) - { - nextpage -= ne2000->page_stop - ne2000->page_start; - } - - /* Setup packet header */ - pkthdr[0] = 0; /* rx status - old behavior - pkthdr[0] = 1; /* Probably better to set it all the time - rather than set it to 0, which is clearly wrong. */ - if (pktbuf[0] & 0x01) - { - pkthdr[0] |= 0x20; /* rx status += multicast packet */ - } - pkthdr[1] = nextpage; /* ptr to next packet */ - pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ - pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ - - /* copy into buffer, update curpage, and signal interrupt if config'd */ - startptr = & ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; - if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) - { - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, io_len); - ne2000->curr_page = nextpage; - } - else - { - int endbytes = (ne2000->page_stop - ne2000->curr_page) * 256; - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, endbytes - 4); - startptr = & ne2000->mem[ne2000->page_start * 256 - BX_NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); - ne2000->curr_page = nextpage; - } - - ne2000->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) - { - ne2000->RSR.rx_mbit = 1; - } - - ne2000->ISR.pkt_rx = 1; - - if (ne2000->IMR.rx_inte) - { - picint(1 << ne2000->base_irq); - } -} - -uint8_t ne2000_readb(uint16_t addr, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - return ne2000_read(ne2000, addr, 1); -} - -uint16_t ne2000_readw(uint16_t addr, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - if (ne2000->DCR.wdsize & 1) - { - return ne2000_read(ne2000, addr, 2); - } - else - { - return ne2000_read(ne2000, addr, 1); - } -} - -uint32_t ne2000_readl(uint16_t addr, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - return ne2000_read(ne2000, addr, 4); -} - -void ne2000_writeb(uint16_t addr, uint8_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_write(ne2000, addr, val, 1); -} - -void ne2000_writew(uint16_t addr, uint16_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - if (ne2000->DCR.wdsize & 1) - { - ne2000_write(ne2000, addr, val, 2); - } - else - { - ne2000_write(ne2000, addr, val, 1); - } -} - -void ne2000_writel(uint16_t addr, uint32_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_write(ne2000, addr, val, 4); -} - -void ne2000_poller(void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - struct queuepacket *qp; - const unsigned char *data; - struct pcap_pkthdr h; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; - - if (!net_is_pcap) - { - while(QueuePeek(slirpq) > 0) - { - qp=QueueDelete(slirpq); - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - free(qp); - return; - } - ne2000_rx_frame(ne2000,&qp->data,qp->len); - ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); - free(qp); - } - fizz++; - if (fizz>1200) - { - fizz=0;slirp_tic(); - } - } /* end slirp */ - else if (net_is_pcap && (net_pcap != NULL)) - { - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - return; - } - data=pcap_next(net_pcap,&h); - if(data==0x0) - { - return; - } - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (data+6); - mac_cmp16[0] = *(uint16_t *) (data+10); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (ne2000_mac()); - mac_cmp16[1] = *(uint16_t *) (ne2000_mac() + 4); - if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) - { - ne2000_rx_frame(ne2000,data,h.caplen); - } - } -} - -typedef union -{ - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; - -uint8_t ne2000_pci_regs[256]; - -bar_t ne2000_pci_bar[2]; - -uint32_t bios_addr = 0xD0000; -uint32_t old_base_addr = 0; - -uint32_t bios_size = 0; -uint32_t bios_mask = 0; - -void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) -{ - old_base_addr = addr; - if (network_card_current == 1) - { - io_sethandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - } - else - { - io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - } -} - -void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) -{ - if (network_card_current == 1) - { - io_removehandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - } - else - { - io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - } -} - -uint8_t ne2000_pci_read(int func, int addr, void *p) -{ - switch (addr) - { - case 0x00: - return 0xec; - case 0x01: - return 0x10; - - case 0x02: - return 0x29; - case 0x03: - return 0x80; - - case 0x2C: - return 0xF4; - case 0x2D: - return 0x1A; - case 0x2E: - return 0x00; - case 0x2F: - return 0x11; - - case 0x04: - return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return ne2000_pci_regs[0x05]; - - case 0x07: - return 2; - - case 0x08: - return 0; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - - case 0x0B: - return ne2000_pci_regs[0x0B]; - - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return ne2000_pci_bar[0].addr_regs[1]; - case 0x12: - return ne2000_pci_bar[0].addr_regs[2]; - case 0x13: - return ne2000_pci_bar[0].addr_regs[3]; - - case 0x30: - return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - case 0x31: - return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; - case 0x32: - return ne2000_pci_bar[1].addr_regs[2]; - case 0x33: - return ne2000_pci_bar[1].addr_regs[3]; - - case 0x3C: - return ne2000_pci_regs[0x3C]; - case 0x3D: - return ne2000_pci_regs[0x3D]; - } - return 0; -} - -void ne2000_update_bios(ne2000_t *ne2000) -{ - int reg_bios_enable; - - reg_bios_enable = 1; - - /* PCI BIOS stuff, just enable_disable. */ - if (!disable_netbios && reg_bios_enable) - { - mem_mapping_enable(&ne2000->bios_rom.mapping); - mem_mapping_set_addr(&ne2000->bios_rom.mapping, bios_addr, 0x10000); - ne2000_log("Network BIOS now at: %08X\n", bios_addr); - } - else - { - mem_mapping_disable(&ne2000->bios_rom.mapping); - if (network_card_current == 2) ne2000_pci_bar[1].addr = 0; - } -} - -void ne2000_pci_write(int func, int addr, uint8_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *) p; - - switch (addr) - { - case 0x04: - ne2000_io_remove(ne2000->base_address, ne2000); - if (val & PCI_COMMAND_IO) - { - ne2000_io_set(ne2000->base_address, ne2000); - } - ne2000_pci_regs[addr] = val; - break; - - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ - ne2000_io_remove(ne2000->base_address, ne2000); - /* Then let's set the PCI regs. */ - ne2000_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; - /* Log the new base. */ - ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); - /* We're done, so get out of the here. */ - if (val & PCI_COMMAND_IO) - { - ne2000_io_set(ne2000->base_address, ne2000); - } - return; - - case 0x30: case 0x31: case 0x32: case 0x33: - ne2000_pci_bar[1].addr_regs[addr & 3] = val; - ne2000_pci_bar[1].addr_regs[1] &= bios_mask; - bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; - ne2000_pci_bar[1].addr &= 0xffffe000; - ne2000_pci_bar[1].addr |= 0x1801; - ne2000_update_bios(ne2000); - return; - - /* Commented out until an APIC controller is emulated for the PIIX3, - otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ -#if 0 - case 0x3C: - ne2000_pci_regs[addr] = val; - if (val != 0xFF) - { - ne2000_log("NE2000 IRQ now: %i\n", val); - ne2000_setirq(ne2000, val); - } - return; -#endif - } -} - -void ne2000_rom_init(ne2000_t *ne2000, char *s) -{ - FILE *f = fopen(s, "rb"); - uint32_t temp; - if(!f) - { - disable_netbios = 1; - ne2000_update_bios(ne2000); - return; - } - fseek(f, 0, SEEK_END); - temp = ftell(f); - fclose(f); - bios_size = 0x10000; - if (temp <= 0x8000) - { - bios_size = 0x8000; - } - if (temp <= 0x4000) - { - bios_size = 0x4000; - } - if (temp <= 0x2000) - { - bios_size = 0x2000; - } - bios_mask = (bios_size >> 8) & 0xff; - bios_mask = (0x100 - bios_mask) & 0xff; - - rom_init(&ne2000->bios_rom, s, 0xd0000, bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); -} - -static char errbuf[32768]; - -void *ne2000_init() -{ - int rc; - int config_net_type; - int irq; - int pcap_device_available = 0; - int is_rtl8029as = 0; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); - memset(ne2000, 0, sizeof(ne2000_t)); - - if (PCI && (network_card_current == 2)) - { - is_rtl8029as = 1; - } - else - { - network_card_current = 1; - is_rtl8029as = 0; - } - - if (is_rtl8029as) - { - ne2000->base_address = 0x340; - } - else - { - ne2000->base_address = device_get_config_int("addr"); - } - - disable_netbios = device_get_config_int("disable_netbios"); - - irq = device_get_config_int("irq"); - ne2000_setirq(ne2000, irq); - - config_net_type = device_get_config_int("net_type"); - /* Network type is now specified in device config. */ - net_is_pcap = config_net_type ? 0 : 1; - if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) - { - net_is_pcap = 0; - pcap_device_available = 0; - } - else - { - pcap_device_available = 1; - } - ne2000_log("net_is_pcap = %i\n", net_is_pcap); - - if (is_rtl8029as) - { - pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); - } - - ne2000_io_set(ne2000->base_address, ne2000); - - memcpy(ne2000->physaddr, ne2000_mac(), 6); - - if (!disable_netbios) - { - ne2000_rom_init(ne2000, "roms/ne2000.rom"); - - if (is_rtl8029as) - { - mem_mapping_disable(&ne2000->bios_rom.mapping); - } - } - - if (is_rtl8029as) - { - ne2000_pci_regs[0x04] = 1; - ne2000_pci_regs[0x05] = 0; - - ne2000_pci_regs[0x07] = 2; - - /* Network controller. */ - ne2000_pci_regs[0x0B] = 2; - - ne2000_pci_bar[0].addr_regs[0] = 1; - - if (disable_netbios) - { - ne2000_pci_bar[1].addr = 0; - bios_addr = 0; - } - else - { - ne2000_pci_bar[1].addr = 0x000F8000; - ne2000_pci_bar[1].addr_regs[1] = bios_mask; - ne2000_pci_bar[1].addr |= 0x1801; - bios_addr = 0xD0000; - } - - ne2000_pci_regs[0x3C] = irq; - pclog("RTL8029AS IRQ: %i\n", ne2000_pci_regs[0x3C]); - ne2000_pci_regs[0x3D] = 1; - - memset(rtl8029as_eeprom, 0, 128); - rtl8029as_eeprom[0x76] = rtl8029as_eeprom[0x7A] = rtl8029as_eeprom[0x7E] = 0x29; - rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; - rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; - rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; - } - - ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); - - ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); - - /* need a switch statment for more network types. */ - if (!net_is_pcap) - { -initialize_slirp: - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if (!rc) - { - ne2000_log("ne2000 slirp initalized!\n"); - - net_slirp_inited = 1; - slirpq = QueueCreate(); - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else - { - net_slirp_inited = 0; - if (pcap_device_available) - { - net_is_pcap = 1; - goto initialize_pcap; - } - else - { - ne2000_log("Neither SLiRP nor PCap is available on your host, disabling network adapter...\n"); - free(ne2000); - network_card_current = 0; - resetpchard(); - return NULL; - } - } - } - else - { -initialize_pcap: - ne2000_log("ne2000 initalizing libpcap\n"); - - ne2000_log("ne2000 Pcap version [%s]\n",pcap_lib_version()); - - if((net_pcap=pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; - return(ne2000); /* YUCK!!! */ - } - - /* Time to check that we are in non-blocking mode. */ - rc=pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc = pcap_setnonblock(net_pcap,1,errbuf); - if (rc==0) - { /* no errors! */ - ne2000_log(".."); - rc=pcap_getnonblock(net_pcap,errbuf); - if(rc == 1) - { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else - { - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - } /* end set nonblock */ - else - { - ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if (net_is_pcap) - { - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5],\ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5]); - - /* I'm doing a MAC level filter so TCP/IP doesn't matter. */ - if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) - { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else - { - ne2000_log("..."); - if (pcap_setfilter(net_pcap, &fp) == -1) - { - ne2000_log("\nError installing pcap filter.\n"); - } /* end of set_filter failure */ - else - { - ne2000_log("...!\n"); - } - } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - } - else - { - pcap_device_available = 0; - goto initialize_slirp; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } /* end pcap setup */ - - ne2000_log("ne2000 is_pcap %d\n", net_is_pcap); - return ne2000; -} - -void ne2000_close(void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_io_remove(ne2000->base_address, ne2000); - free(ne2000); - - if(!net_is_pcap) - { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - ne2000_log("ne2000 exiting slirp\n"); - } - else if (net_is_pcap && (net_pcap != NULL)) - { - pcap_close(net_pcap); - ne2000_log("ne2000 closing pcap\n"); - } - ne2000_log("ne2000 close\n"); -} - -static device_config_t ne2000_config[] = -{ - { - "addr", "Address", CONFIG_SELECTION, "", 0x300, - { - { - "0x280", 0x280 - }, - { - "0x300", 0x300 - }, - { - "0x320", 0x320 - }, - { - "0x340", 0x340 - }, - { - "0x360", 0x360 - }, - { - "0x380", 0x380 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "net_type", "Network type", CONFIG_SELECTION, "", 0, - { - { - "PCap", 0 - }, - { - "SLiRP", 1 - }, - { - "" - } - }, - }, - { - "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } -}; - -static device_config_t rtl8029as_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "net_type", "Network type", CONFIG_SELECTION, "", 0, - { - { - "PCap", 0 - }, - { - "SLiRP", 1 - }, - { - "" - } - }, - }, - { - "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 - }, - { - "", "", -1 - } -}; - -device_t ne2000_device = -{ - "Novell NE2000", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - ne2000_config -}; - -device_t rtl8029as_device = -{ - "Realtek RTL8029AS", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - rtl8029as_config -}; - -/* SLIRP stuff */ -int slirp_can_output(void) -{ - return net_slirp_inited; -} - -void slirp_output (const unsigned char *pkt, int pkt_len) -{ - struct queuepacket *p; - p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); - p->len=pkt_len; - memcpy(p->data,pkt,pkt_len); - QueueEnter(slirpq,p); - ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); -} - -/* Instead of calling this and crashing some times - or experencing jitter, this is called by the - 60Hz clock which seems to do the job. */ -void slirp_tic() -{ - int ret2,nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int timeout; - nfds=-1; - - if(net_slirp_inited) - { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); /* this can crash */ - - if(timeout<0) - { - timeout=500; - } - - tv.tv_sec=0; - tv.tv_usec = timeout; /* basilisk default 10000 */ - - ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if(ret2>=0) - { - slirp_select_poll(&rfds, &wfds, &xfds); - } - } /* end if slirp inited */ -} diff --git a/src/ne2000.h b/src/ne2000.h deleted file mode 100644 index 218685e88..000000000 --- a/src/ne2000.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ -void ne2000_generate_maclocal(int mac); -void ne2000_generate_maclocal_pci(int mac); -int net2000_get_maclocal(); -int net2000_get_maclocal_pci(); - -extern device_t ne2000_device; -extern device_t rtl8029as_device; diff --git a/src/net_ne2000.c b/src/net_ne2000.c new file mode 100644 index 000000000..365cd2b75 --- /dev/null +++ b/src/net_ne2000.c @@ -0,0 +1,2179 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of an NE2000/RTL8029AS network controller. + * + * NOTE: Its still a mess, but we're getting there. The file will + * also implement an NE1000 for 8-bit ISA systems. + * + * Version: @(#)net_ne2000.c 1.0.3 2017/05/12 + * + * Authors: Fred N. van Kempen, + * Peter Grehan, grehan@iprg.nokia.com> + * SA1988, Tenshi + * + * Based on @(#)ne2k.cc v1.56.2.1 2004/02/02 22:37:22 cbothamy + * Portions Copyright (C) 2002 MandrakeSoft S.A. + */ +#include +#include +#include +#include +#include +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "pci.h" +#include "pic.h" +#include "device.h" +#include "config.h" +#include "disc_random.h" +#include "network.h" +#include "net_ne2000.h" +#include "bswap.h" +#ifdef WALTJE +# define ENABLE_NE2000_LOG 1 +#endif + + +/* For PCI. */ +typedef union { + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; + + +/* This stuff should go into the struct. --FvK */ +static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; +static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; +#if ENABLE_NE2000_LOG +static int nic_do_log = ENABLE_NE2000_LOG; +#else +static int nic_do_log = 0; +#endif + + +/* Never completely fill the ne2k ring so that we never + hit the unclear completely full buffer condition. */ +#define NE2K_NEVER_FULL_RING (1) + +#define NE2K_MEMSIZ (32*1024) +#define NE2K_MEMSTART (16*1024) +#define NE2K_MEMEND (NE2K_MEMSTART+NE2K_MEMSIZ) + + +typedef struct { + /* Page 0 */ + + /* Command Register - 00h read/write */ + struct CR_t { + int stop; /* STP - Software Reset command */ + int start; /* START - start the NIC */ + int tx_packet; /* TXP - initiate packet transmission */ + uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ + uint8_t pgsel; /* PS0,PS1 - Page select */ + } CR; + + /* Interrupt Status Register - 07h read/write */ + struct ISR_t { + int pkt_rx; /* PRX - packet received with no errors */ + int pkt_tx; /* PTX - packet txed with no errors */ + int rx_err; /* RXE - packet rxed with 1 or more errors */ + int tx_err; /* TXE - packet txed " " " " " */ + int overwrite; /* OVW - rx buffer resources exhausted */ + int cnt_oflow; /* CNT - network tally counter MSB's set */ + int rdma_done; /* RDC - remote DMA complete */ + int reset; /* RST - reset status */ + } ISR; + + /* Interrupt Mask Register - 0fh write */ + struct IMR_t { + int rx_inte; /* PRXE - packet rx interrupt enable */ + int tx_inte; /* PTXE - packet tx interrput enable */ + int rxerr_inte; /* RXEE - rx error interrupt enable */ + int txerr_inte; /* TXEE - tx error interrupt enable */ + int overw_inte; /* OVWE - overwrite warn int enable */ + int cofl_inte; /* CNTE - counter o'flow int enable */ + int rdma_inte; /* RDCE - remote DMA complete int enable */ + int reserved; /* D7 - reserved */ + } IMR; + + /* Data Configuration Register - 0eh write */ + struct DCR_t { + int wdsize; /* WTS - 8/16-bit select */ + int endian; /* BOS - byte-order select */ + int longaddr; /* LAS - long-address select */ + int loop; /* LS - loopback select */ + int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ + uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ + } DCR; + + /* Transmit Configuration Register - 0dh write */ + struct TCR_t { + int crc_disable; /* CRC - inhibit tx CRC */ + uint8_t loop_cntl; /* LB0,LB1 - loopback control */ + int ext_stoptx; /* ATD - allow tx disable by external mcast */ + int coll_prio; /* OFST - backoff algorithm select */ + uint8_t reserved; /* D5,D6,D7 - reserved */ + } TCR; + + /* Transmit Status Register - 04h read */ + struct TSR_t { + int tx_ok; /* PTX - tx complete without error */ + int reserved; /* D1 - reserved */ + int collided; /* COL - tx collided >= 1 times */ + int aborted; /* ABT - aborted due to excessive collisions */ + int no_carrier; /* CRS - carrier-sense lost */ + int fifo_ur; /* FU - FIFO underrun */ + int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + int ow_coll; /* OWC - out-of-window collision */ + } TSR; + + /* Receive Configuration Register - 0ch write */ + struct RCR_t { + int errors_ok; /* SEP - accept pkts with rx errors */ + int runts_ok; /* AR - accept < 64-byte runts */ + int broadcast; /* AB - accept eth broadcast address */ + int multicast; /* AM - check mcast hash array */ + int promisc; /* PRO - accept all packets */ + int monitor; /* MON - check pkts, but don't rx */ + uint8_t reserved; /* D6,D7 - reserved */ + } RCR; + + /* Receive Status Register - 0ch read */ + struct RSR_t { + int rx_ok; /* PRX - rx complete without error */ + int bad_crc; /* CRC - Bad CRC detected */ + int bad_falign; /* FAE - frame alignment error */ + int fifo_or; /* FO - FIFO overrun */ + int rx_missed; /* MPA - missed packet error */ + int rx_mbit; /* PHY - unicast or mcast/bcast address match */ + int rx_disabled; /* DIS - set when in monitor mode */ + int deferred; /* DFR - collision active */ + } RSR; + + uint16_t local_dma; /* 01,02h read ; current local DMA addr */ + uint8_t page_start; /* 01h write ; page start regr */ + uint8_t page_stop; /* 02h write ; page stop regr */ + uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ + uint8_t tx_page_start; /* 04h write ; transmit page start reg */ + uint8_t num_coll; /* 05h read ; number-of-collisions reg */ + uint16_t tx_bytes; /* 05,06h write ; transmit byte-count reg */ + uint8_t fifo; /* 06h read ; FIFO */ + uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ + uint16_t remote_start; /* 08,09h write ; remote start address reg */ + uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count reg */ + uint8_t tallycnt_0; /* 0dh read ; tally ctr 0 (frame align errs) */ + uint8_t tallycnt_1; /* 0eh read ; tally ctr 1 (CRC errors) */ + uint8_t tallycnt_2; /* 0fh read ; tally ctr 2 (missed pkt errs) */ + + /* Page 1 */ + + /* Command Register 00h (repeated) */ + + uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ + uint8_t curr_page; /* 07h read/write ; current page register */ + uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ + + /* Page 2 - diagnostic use only */ + + /* Command Register 00h (repeated) */ + + /* Page Start Register 01h read (repeated) + * Page Stop Register 02h read (repeated) + * Current Local DMA Address 01,02h write (repeated) + * Transmit Page start address 04h read (repeated) + * Receive Configuration Register 0ch read (repeated) + * Transmit Configuration Register 0dh read (repeated) + * Data Configuration Register 0eh read (repeated) + * Interrupt Mask Register 0fh read (repeated) + */ + uint8_t rempkt_ptr; /* 03h read/write ; rmt next-pkt ptr */ + uint8_t localpkt_ptr; /* 05h read/write ; lcl next-pkt ptr */ + uint16_t address_cnt; /* 06,07h read/write ; address cter */ + + /* Page 3 - should never be modified. */ + + /* Novell ASIC state */ + uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ + uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ + + int board; + int is_rtl8029as; + char name[32]; + uint32_t base_address; + int base_irq; + uint32_t bios_addr, + bios_size, + bios_mask; + bar_t pci_bar[2]; + int disable_netbios; + int tx_timer_index; + int tx_timer_active; + uint8_t pci_regs[256]; + uint8_t eeprom[128]; /* for RTL8029AS */ + rom_t bios_rom; +} nic_t; + + +static void nic_rx(void *, uint8_t *, int); +static void nic_tx(nic_t *, uint32_t); + + +static void +nelog(int lvl, const char *fmt, ...) +{ +#ifdef ENABLE_NE2000_LOG + va_list ap; + + if (nic_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + } +#endif +} +#define pclog nelog + + +/* reset - restore state to power-up, cancelling all i/o */ +static void +nic_reset(void *priv, int reset) +{ + nic_t *dev = (nic_t *)priv; + int i; + + pclog(1, "%s: reset\n", dev->name); + + /* Initialize the MAC address area by doubling the physical address */ + dev->macaddr[0] = dev->physaddr[0]; + dev->macaddr[1] = dev->physaddr[0]; + dev->macaddr[2] = dev->physaddr[1]; + dev->macaddr[3] = dev->physaddr[1]; + dev->macaddr[4] = dev->physaddr[2]; + dev->macaddr[5] = dev->physaddr[2]; + dev->macaddr[6] = dev->physaddr[3]; + dev->macaddr[7] = dev->physaddr[3]; + dev->macaddr[8] = dev->physaddr[4]; + dev->macaddr[9] = dev->physaddr[4]; + dev->macaddr[10] = dev->physaddr[5]; + dev->macaddr[11] = dev->physaddr[5]; + + /* ne2k signature */ + for (i = 12; i < 32; i++) { + dev->macaddr[i] = 0x57; + } + + /* Zero out registers and memory */ + memset(&dev->CR, 0x00, sizeof(dev->CR) ); + memset(&dev->ISR, 0x00, sizeof(dev->ISR)); + memset(&dev->IMR, 0x00, sizeof(dev->IMR)); + memset(&dev->DCR, 0x00, sizeof(dev->DCR)); + memset(&dev->TCR, 0x00, sizeof(dev->TCR)); + memset(&dev->TSR, 0x00, sizeof(dev->TSR)); + memset(&dev->RSR, 0x00, sizeof(dev->RSR)); + dev->tx_timer_active = 0; + dev->local_dma = 0; + dev->page_start = 0; + dev->page_stop = 0; + dev->bound_ptr = 0; + dev->tx_page_start = 0; + dev->num_coll = 0; + dev->tx_bytes = 0; + dev->fifo = 0; + dev->remote_dma = 0; + dev->remote_start = 0; + dev->remote_bytes = 0; + dev->tallycnt_0 = 0; + dev->tallycnt_1 = 0; + dev->tallycnt_2 = 0; + + dev->curr_page = 0; + + dev->rempkt_ptr = 0; + dev->localpkt_ptr = 0; + dev->address_cnt = 0; + + memset(&dev->mem, 0x00, sizeof(dev->mem)); + + /* Set power-up conditions */ + dev->CR.stop = 1; + dev->CR.rdma_cmd = 4; + dev->ISR.reset = 1; + dev->DCR.longaddr = 1; + + picint(1<base_irq); + picintc(1<base_irq); +} + + +/* chipmem_read/chipmem_write - access the 64K private RAM. + The ne2000 memory is accessed through the data port of + the asic (offset 0) after setting up a remote-DMA transfer. + Both byte and word accesses are allowed. + The first 16 bytes contains the MAC address at even locations, + and there is 16K of buffer memory starting at 16K +*/ +static uint32_t +chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) +{ + uint32_t retval = 0; + + if ((len == 2) && (addr & 0x1)) { + pclog(1, "%s: unaligned chipmem word read\n", dev->name); + } + + /* ROM'd MAC address */ + if ((addr >=0) && (addr <= 31)) { + retval = dev->macaddr[addr % 32]; + if ((len == 2) || (len == 4)) { + retval |= (dev->macaddr[(addr + 1) % 32] << 8); + } + if (len == 4) { + retval |= (dev->macaddr[(addr + 2) % 32] << 16); + retval |= (dev->macaddr[(addr + 3) % 32] << 24); + } + return(retval); + } + + if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { + retval = dev->mem[addr - NE2K_MEMSTART]; + if ((len == 2) || (len == 4)) { + retval |= (dev->mem[addr - NE2K_MEMSTART + 1] << 8); + } + if (len == 4) { + retval |= (dev->mem[addr - NE2K_MEMSTART + 2] << 16); + retval |= (dev->mem[addr - NE2K_MEMSTART + 3] << 24); + } + return(retval); + } + + pclog(1, "%s: out-of-bounds chipmem read, %04X\n", dev->name, addr); + + if (dev->is_rtl8029as) { + return(0xff); + } else { + switch(len) { + case 1: + return(0xff); + case 2: + return(0xffff); + } + } + + return(0xffff); +} + + +static void +chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) +{ + if ((len == 2) && (addr & 0x1)) { + pclog(1, "%s: unaligned chipmem word write\n", dev->name); + } + + if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { + dev->mem[addr-NE2K_MEMSTART] = val & 0xff; + if ((len == 2) || (len == 4)) { + dev->mem[addr-NE2K_MEMSTART+1] = val >> 8; + } + if (len == 4) { + dev->mem[addr-NE2K_MEMSTART+2] = val >> 16; + dev->mem[addr-NE2K_MEMSTART+3] = val >> 24; + } + } else { + pclog(1, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); + } +} + + +/* asic_read/asic_write - This is the high 16 bytes of i/o space + (the lower 16 bytes is for the DS8390). Only two locations + are used: offset 0, which is used for data transfer, and + offset 0xf, which is used to reset the device. + The data transfer port is used to as 'external' DMA to the + DS8390. The chip has to have the DMA registers set up, and + after that, insw/outsw instructions can be used to move + the appropriate number of bytes to/from the device. +*/ +static uint32_t +asic_read(nic_t *dev, uint32_t off, unsigned int len) +{ + uint32_t retval = 0; + + switch(off) { + case 0x00: /* Data register */ + /* A read remote-DMA command must have been issued, + and the source-address and length registers must + have been initialised. */ + if (len > dev->remote_bytes) { + pclog(1, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", + dev->name, len, dev->remote_bytes); + } + + pclog(2, "%s: DMA read: addr=%4x remote_bytes=%d\n", + dev->name, dev->remote_dma,dev->remote_bytes); + retval = chipmem_read(dev, dev->remote_dma, len); + + /* The 8390 bumps the address and decreases the byte count + by the selected word size after every access, not by + the amount of data requested by the host (io_len). */ + if (len == 4) { + dev->remote_dma += len; + } else { + dev->remote_dma += (dev->DCR.wdsize + 1); + } + + if (dev->remote_dma == dev->page_stop << 8) { + dev->remote_dma = dev->page_start << 8; + } + + /* keep s.remote_bytes from underflowing */ + if (dev->remote_bytes > dev->DCR.wdsize) { + if (len == 4) { + dev->remote_bytes -= len; + } else { + dev->remote_bytes -= (dev->DCR.wdsize + 1); + } + } else { + dev->remote_bytes = 0; + } + + /* If all bytes have been written, signal remote-DMA complete */ + if (dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); + } + } + break; + + case 0x0f: /* Reset register */ + nic_reset(dev, 1); + break; + + default: + pclog(1, "%s: ASIC read invalid address %04x\n", + dev->name, (unsigned)off); + break; + } + + return(retval); +} + + +static void +asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + pclog(2, "%s: asic write addr=0x%02x, value=0x%04x\n", + dev->name, (unsigned)off, (unsigned) val); + switch(off) { + case 0x00: /* Data register - see asic_read for a description */ + if ((len > 1) && (dev->DCR.wdsize == 0)) { + pclog(2, "%s: DMA write length %d on byte mode operation\n", + dev->name, len); + break; + } + if (dev->remote_bytes == 0) { + pclog(2, "%s: DMA write, byte count 0\n", dev->name); + } + + chipmem_write(dev, dev->remote_dma, val, len); + if (len == 4) { + dev->remote_dma += len; + } else { + dev->remote_dma += (dev->DCR.wdsize + 1); + } + + if (dev->remote_dma == dev->page_stop << 8) { + dev->remote_dma = dev->page_start << 8; + } + + if (len == 4) { + dev->remote_bytes -= len; + } else { + dev->remote_bytes -= (dev->DCR.wdsize + 1); + } + + if (dev->remote_bytes > NE2K_MEMSIZ) { + dev->remote_bytes = 0; + } + + /* If all bytes have been written, signal remote-DMA complete */ + if (dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); + } + } + break; + + case 0x0f: /* Reset register */ + /* end of reset pulse */ + break; + + default: /* this is invalid, but happens under win95 device detection */ + pclog(1, "%s: ASIC write invalid address %04x, ignoring\n", + dev->name, (unsigned)off); + break; + } +} + + +/* page0_read/page0_write - These routines handle reads/writes to + the 'zeroth' page of the DS8390 register file */ +static uint32_t +page0_read(nic_t *dev, uint32_t off, unsigned int len) +{ + uint8_t retval = 0; + + if (len > 1) { + /* encountered with win98 hardware probe */ + pclog(1, "%s: bad length! Page0 read from register 0x%02x, len=%u\n", + dev->name, off, len); + return(retval); + } + + switch(off) { + case 0x01: /* CLDA0 */ + retval = (dev->local_dma & 0xff); + break; + + case 0x02: /* CLDA1 */ + retval = (dev->local_dma >> 8); + break; + + case 0x03: /* BNRY */ + retval = dev->bound_ptr; + break; + + case 0x04: /* TSR */ + retval = ((dev->TSR.ow_coll << 7) | + (dev->TSR.cd_hbeat << 6) | + (dev->TSR.fifo_ur << 5) | + (dev->TSR.no_carrier << 4) | + (dev->TSR.aborted << 3) | + (dev->TSR.collided << 2) | + (dev->TSR.tx_ok)); + break; + + case 0x05: /* NCR */ + retval = dev->num_coll; + break; + + case 0x06: /* FIFO */ + /* reading FIFO is only valid in loopback mode */ + pclog(1, "%s: reading FIFO not supported yet\n", dev->name); + retval = dev->fifo; + break; + + case 0x07: /* ISR */ + retval = ((dev->ISR.reset << 7) | + (dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + break; + + case 0x08: /* CRDA0 */ + retval = (dev->remote_dma & 0xff); + break; + + case 0x09: /* CRDA1 */ + retval = (dev->remote_dma >> 8); + break; + + case 0x0a: /* reserved / RTL8029ID0 */ + if (dev->is_rtl8029as) { + retval = 0x50; + } else { + pclog(1, "%s: reserved Page0 read - 0x0a\n", dev->name); + retval = 0xff; + } + break; + + case 0x0b: /* reserved / RTL8029ID1 */ + if (dev->is_rtl8029as) { + retval = 0x43; + } else { + pclog(1, "%s: reserved Page0 read - 0x0b\n", dev->name); + retval = 0xff; + } + break; + + case 0x0c: /* RSR */ + retval = ((dev->RSR.deferred << 7) | + (dev->RSR.rx_disabled << 6) | + (dev->RSR.rx_mbit << 5) | + (dev->RSR.rx_missed << 4) | + (dev->RSR.fifo_or << 3) | + (dev->RSR.bad_falign << 2) | + (dev->RSR.bad_crc << 1) | + (dev->RSR.rx_ok)); + break; + + case 0x0d: /* CNTR0 */ + retval = dev->tallycnt_0; + break; + + case 0x0e: /* CNTR1 */ + retval = dev->tallycnt_1; + break; + + case 0x0f: /* CNTR2 */ + retval = dev->tallycnt_2; + break; + + default: + pclog(1, "%s: Page0 register 0x%02x out of range\n", + dev->name, off); + break; + } + + pclog(2, "%s: Page0 read from register 0x%02x, value=0x%02x\n", + dev->name, off, retval); + + return(retval); +} + + +static void +page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + uint8_t val2; + + /* It appears to be a common practice to use outw on page0 regs... */ + + /* break up outw into two outb's */ + if (len == 2) { + page0_write(dev, off, (val & 0xff), 1); + if (off < 0x0f) + page0_write(dev, off+1, ((val>>8)&0xff), 1); + return; + } + + pclog(2, "%s: Page0 write to register 0x%02x, value=0x%02x\n", + dev->name, off, val); + + switch(off) { + case 0x01: /* PSTART */ + dev->page_start = val; + break; + + case 0x02: /* PSTOP */ + dev->page_stop = val; + break; + + case 0x03: /* BNRY */ + dev->bound_ptr = val; + break; + + case 0x04: /* TPSR */ + dev->tx_page_start = val; + break; + + case 0x05: /* TBCR0 */ + /* Clear out low byte and re-insert */ + dev->tx_bytes &= 0xff00; + dev->tx_bytes |= (val & 0xff); + break; + + case 0x06: /* TBCR1 */ + /* Clear out high byte and re-insert */ + dev->tx_bytes &= 0x00ff; + dev->tx_bytes |= ((val & 0xff) << 8); + break; + + case 0x07: /* ISR */ + val &= 0x7f; /* clear RST bit - status-only bit */ + /* All other values are cleared iff the ISR bit is 1 */ + dev->ISR.pkt_rx &= ~((int)((val & 0x01) == 0x01)); + dev->ISR.pkt_tx &= ~((int)((val & 0x02) == 0x02)); + dev->ISR.rx_err &= ~((int)((val & 0x04) == 0x04)); + dev->ISR.tx_err &= ~((int)((val & 0x08) == 0x08)); + dev->ISR.overwrite &= ~((int)((val & 0x10) == 0x10)); + dev->ISR.cnt_oflow &= ~((int)((val & 0x20) == 0x20)); + dev->ISR.rdma_done &= ~((int)((val & 0x40) == 0x40)); + val = ((dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + val &= ((dev->IMR.rdma_inte << 6) | + (dev->IMR.cofl_inte << 5) | + (dev->IMR.overw_inte << 4) | + (dev->IMR.txerr_inte << 3) | + (dev->IMR.rxerr_inte << 2) | + (dev->IMR.tx_inte << 1) | + (dev->IMR.rx_inte)); + if (val == 0x00) { + picintc(1 << dev->base_irq); + } + break; + + case 0x08: /* RSAR0 */ + /* Clear out low byte and re-insert */ + dev->remote_start &= 0xff00; + dev->remote_start |= (val & 0xff); + dev->remote_dma = dev->remote_start; + break; + + case 0x09: /* RSAR1 */ + /* Clear out high byte and re-insert */ + dev->remote_start &= 0x00ff; + dev->remote_start |= ((val & 0xff) << 8); + dev->remote_dma = dev->remote_start; + break; + + case 0x0a: /* RBCR0 */ + /* Clear out low byte and re-insert */ + dev->remote_bytes &= 0xff00; + dev->remote_bytes |= (val & 0xff); + break; + + case 0x0b: /* RBCR1 */ + /* Clear out high byte and re-insert */ + dev->remote_bytes &= 0x00ff; + dev->remote_bytes |= ((val & 0xff) << 8); + break; + + case 0x0c: /* RCR */ + /* Check if the reserved bits are set */ + if (val & 0xc0) { + pclog(1, "%s: RCR write, reserved bits set\n", + dev->name); + } + + /* Set all other bit-fields */ + dev->RCR.errors_ok = ((val & 0x01) == 0x01); + dev->RCR.runts_ok = ((val & 0x02) == 0x02); + dev->RCR.broadcast = ((val & 0x04) == 0x04); + dev->RCR.multicast = ((val & 0x08) == 0x08); + dev->RCR.promisc = ((val & 0x10) == 0x10); + dev->RCR.monitor = ((val & 0x20) == 0x20); + + /* Monitor bit is a little suspicious... */ + if (val & 0x20) pclog(1, "%s: RCR write, monitor bit set!\n", + dev->name); + break; + + case 0x0d: /* TCR */ + /* Check reserved bits */ + if (val & 0xe0) pclog(1, "%s: TCR write, reserved bits set\n", + dev->name); + + /* Test loop mode (not supported) */ + if (val & 0x06) { + dev->TCR.loop_cntl = (val & 0x6) >> 1; + pclog(1, "%s: TCR write, loop mode %d not supported\n", + dev->name, dev->TCR.loop_cntl); + } else { + dev->TCR.loop_cntl = 0; + } + + /* Inhibit-CRC not supported. */ + if (val & 0x01) pclog(1, + "%s: TCR write, inhibit-CRC not supported\n",dev->name); + + /* Auto-transmit disable very suspicious */ + if (val & 0x08) pclog(1, + "%s: TCR write, auto transmit disable not supported\n", + dev->name); + + /* Allow collision-offset to be set, although not used */ + dev->TCR.coll_prio = ((val & 0x08) == 0x08); + break; + + case 0x0e: /* DCR */ + /* the loopback mode is not suppported yet */ + if (! (val & 0x08)) pclog(1, + "%s: DCR write, loopback mode selected\n", dev->name); + + /* It is questionable to set longaddr and auto_rx, since + * they are not supported on the NE2000. Print a warning + * and continue. */ + if (val & 0x04) + pclog(1, "%s: DCR write - LAS set ???\n", dev->name); + if (val & 0x10) + pclog(1, "%s: DCR write - AR set ???\n", dev->name); + + /* Set other values. */ + dev->DCR.wdsize = ((val & 0x01) == 0x01); + dev->DCR.endian = ((val & 0x02) == 0x02); + dev->DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ + dev->DCR.loop = ((val & 0x08) == 0x08); + dev->DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ + dev->DCR.fifo_size = (val & 0x50) >> 5; + break; + + case 0x0f: /* IMR */ + /* Check for reserved bit */ + if (val & 0x80) + pclog(1, "%s: IMR write, reserved bit set\n",dev->name); + + /* Set other values */ + dev->IMR.rx_inte = ((val & 0x01) == 0x01); + dev->IMR.tx_inte = ((val & 0x02) == 0x02); + dev->IMR.rxerr_inte = ((val & 0x04) == 0x04); + dev->IMR.txerr_inte = ((val & 0x08) == 0x08); + dev->IMR.overw_inte = ((val & 0x10) == 0x10); + dev->IMR.cofl_inte = ((val & 0x20) == 0x20); + dev->IMR.rdma_inte = ((val & 0x40) == 0x40); + val2 = ((dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + if (((val & val2) & 0x7f) == 0) { + picintc(1 << dev->base_irq); + } else { + picint(1 << dev->base_irq); + } + break; + + default: + pclog(1, "%s: Page0 write, bad register 0x%02x\n", + dev->name, off); + break; + } +} + + +/* page1_read/page1_write - These routines handle reads/writes to + the first page of the DS8390 register file */ +static uint32_t +page1_read(nic_t *dev, uint32_t off, unsigned int len) +{ + pclog(2, "%s: Page1 read from register 0x%02x, len=%u\n", + dev->name, off, len); + + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + return(dev->physaddr[off - 1]); + + case 0x07: /* CURR */ + pclog(2, "%s: returning current page: 0x%02x\n", + dev->name, (dev->curr_page)); + return(dev->curr_page); + + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + return(dev->mchash[off - 8]); + + default: + pclog(1, "%s: Page1 read register 0x%02x out of range\n", + dev->name, off); + return(0); + } +} + + +static void +page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + pclog(2, "%s: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", + dev->name, off, len, val); + + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + dev->physaddr[off - 1] = val; + if (off == 6) pclog(1, + "%s: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, + dev->physaddr[0], dev->physaddr[1], + dev->physaddr[2], dev->physaddr[3], + dev->physaddr[4], dev->physaddr[5]); + break; + + case 0x07: /* CURR */ + dev->curr_page = val; + break; + + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->mchash[off - 8] = val; + break; + + default: + pclog(1, "%s: Page1 write register 0x%02x out of range\n", + dev->name, off); + break; + } +} + + +/* page2_read/page2_write - These routines handle reads/writes to + the second page of the DS8390 register file */ +static uint32_t +page2_read(nic_t *dev, uint32_t off, unsigned int len) +{ + pclog(2, "%s: Page2 read from register 0x%02x, len=%u\n", + dev->name, off, len); + + switch(off) { + case 0x01: /* PSTART */ + return(dev->page_start); + + case 0x02: /* PSTOP */ + return(dev->page_stop); + + case 0x03: /* Remote Next-packet pointer */ + return(dev->rempkt_ptr); + + case 0x04: /* TPSR */ + return(dev->tx_page_start); + + case 0x05: /* Local Next-packet pointer */ + return(dev->localpkt_ptr); + + case 0x06: /* Address counter (upper) */ + return(dev->address_cnt >> 8); + + case 0x07: /* Address counter (lower) */ + return(dev->address_cnt & 0xff); + + case 0x08: /* Reserved */ + case 0x09: + case 0x0a: + case 0x0b: + pclog(1, "%s: reserved Page2 read - register 0x%02x\n", + dev->name, off); + return(0xff); + + case 0x0c: /* RCR */ + return ((dev->RCR.monitor << 5) | + (dev->RCR.promisc << 4) | + (dev->RCR.multicast << 3) | + (dev->RCR.broadcast << 2) | + (dev->RCR.runts_ok << 1) | + (dev->RCR.errors_ok)); + + case 0x0d: /* TCR */ + return ((dev->TCR.coll_prio << 4) | + (dev->TCR.ext_stoptx << 3) | + ((dev->TCR.loop_cntl & 0x3) << 1) | + (dev->TCR.crc_disable)); + + case 0x0e: /* DCR */ + return (((dev->DCR.fifo_size & 0x3) << 5) | + (dev->DCR.auto_rx << 4) | + (dev->DCR.loop << 3) | + (dev->DCR.longaddr << 2) | + (dev->DCR.endian << 1) | + (dev->DCR.wdsize)); + + case 0x0f: /* IMR */ + return ((dev->IMR.rdma_inte << 6) | + (dev->IMR.cofl_inte << 5) | + (dev->IMR.overw_inte << 4) | + (dev->IMR.txerr_inte << 3) | + (dev->IMR.rxerr_inte << 2) | + (dev->IMR.tx_inte << 1) | + (dev->IMR.rx_inte)); + + default: + pclog(1, "%s: Page2 register 0x%02x out of range\n", + dev->name, off); + break; + } + + return(0); +} + + +static void +page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +{ +/* Maybe all writes here should be BX_PANIC()'d, since they + affect internal operation, but let them through for now + and print a warning. */ + pclog(2, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", + dev->name, off, len, val); + switch(off) { + case 0x01: /* CLDA0 */ + /* Clear out low byte and re-insert */ + dev->local_dma &= 0xff00; + dev->local_dma |= (val & 0xff); + break; + + case 0x02: /* CLDA1 */ + /* Clear out high byte and re-insert */ + dev->local_dma &= 0x00ff; + dev->local_dma |= ((val & 0xff) << 8); + break; + + case 0x03: /* Remote Next-pkt pointer */ + dev->rempkt_ptr = val; + break; + + case 0x04: + pclog(1, "page 2 write to reserved register 0x04\n"); + break; + + case 0x05: /* Local Next-packet pointer */ + dev->localpkt_ptr = val; + break; + + case 0x06: /* Address counter (upper) */ + /* Clear out high byte and re-insert */ + dev->address_cnt &= 0x00ff; + dev->address_cnt |= ((val & 0xff) << 8); + break; + + case 0x07: /* Address counter (lower) */ + /* Clear out low byte and re-insert */ + dev->address_cnt &= 0xff00; + dev->address_cnt |= (val & 0xff); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + pclog(1, "%s: Page2 write to reserved register 0x%02x\n", + dev->name, off); + break; + + default: + pclog(1, "%s: Page2 write, illegal register 0x%02x\n", + dev->name, off); + break; + } +} + + +/* page3_read/page3_write - writes to this page are illegal */ +static uint32_t +page3_read(nic_t *dev, uint32_t off, unsigned int len) +{ + if (dev->is_rtl8029as) switch(off) { + case 0x3: /* CONFIG0 */ + return(0x00); + + case 0x5: /* CONFIG2 */ + return(0x40); + + case 0x6: /* CONFIG3 */ + return(0x40); + + default: + break; + } + + pclog(1, "%s: Page3 read register 0x%02x attempted\n", dev->name, off); + return(0x00); +} + + +static void +page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + pclog(1, "%s: Page3 write register 0x%02x attempted\n", dev->name, off); +} + + +/* read_cr/write_cr - utility routines for handling reads/writes to + the Command Register */ +static uint32_t +read_cr(nic_t *dev) +{ + uint32_t retval; + + retval = (((dev->CR.pgsel & 0x03) << 6) | + ((dev->CR.rdma_cmd & 0x07) << 3) | + (dev->CR.tx_packet << 2) | + (dev->CR.start << 1) | + (dev->CR.stop)); + pclog(2, "%s: read CR returns 0x%02x\n", dev->name, retval); + + return(retval); +} + + +static void +write_cr(nic_t *dev, uint32_t val) +{ + pclog(2, "%s: wrote 0x%02x to CR\n", dev->name, val); + + /* Validate remote-DMA */ + if ((val & 0x38) == 0x00) { + pclog(2, "%s: CR write - invalid rDMA value 0\n", dev->name); + val |= 0x20; /* dma_cmd == 4 is a safe default */ + } + + /* Check for s/w reset */ + if (val & 0x01) { + dev->ISR.reset = 1; + dev->CR.stop = 1; + } else { + dev->CR.stop = 0; + } + + dev->CR.rdma_cmd = (val & 0x38) >> 3; + + /* If start command issued, the RST bit in the ISR */ + /* must be cleared */ + if ((val & 0x02) && !dev->CR.start) { + dev->ISR.reset = 0; + } + + dev->CR.start = ((val & 0x02) == 0x02); + dev->CR.pgsel = (val & 0xc0) >> 6; + + /* Check for send-packet command */ + if (dev->CR.rdma_cmd == 3) { + /* Set up DMA read from receive ring */ + dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; + dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); + pclog(2, "%s: sending buffer #x%x length %d\n", + dev->name, dev->remote_start, dev->remote_bytes); + } + + /* Check for start-tx */ + if ((val & 0x04) && dev->TCR.loop_cntl) { + if (dev->TCR.loop_cntl != 1) { + pclog(1, "%s: loop mode %d not supported\n", + dev->name, dev->TCR.loop_cntl); + } else { + nic_rx(dev, + &dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], + dev->tx_bytes); + } + } else if (val & 0x04) { + if (dev->CR.stop || (!dev->CR.start && !dev->is_rtl8029as)) { + if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { + return; /* Solaris9 probe */ + } + pclog(1, "%s: CR write - tx start, dev in reset\n", dev->name); + } + + if (dev->tx_bytes == 0) + pclog(1, "%s: CR write - tx start, tx bytes == 0\n", dev->name); + + /* Send the packet to the system driver */ + dev->CR.tx_packet = 1; + network_tx(&dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], + dev->tx_bytes); + + /* some more debug */ + if (dev->tx_timer_active) + pclog(1, "%s: CR write, tx timer still active\n", dev->name); + + nic_tx(dev, val); + } + + /* Linux probes for an interrupt by setting up a remote-DMA read + * of 0 bytes with remote-DMA completion interrupts enabled. + * Detect this here */ + if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); + if (! dev->is_rtl8029as) { + picintc(1 << dev->base_irq); + } + } + } +} + + +static uint32_t +nic_read(nic_t *dev, uint32_t addr, unsigned len) +{ + uint32_t retval = 0; + int off = addr - dev->base_address; + + pclog(2, "%s: read addr %x, len %d\n", dev->name, addr, len); + + if (off >= 0x10) { + retval = asic_read(dev, off - 0x10, len); + } else if (off == 0x00) { + retval = read_cr(dev); + } else switch(dev->CR.pgsel) { + case 0x00: + retval = page0_read(dev, off, len); + break; + + case 0x01: + retval = page1_read(dev, off, len); + break; + + case 0x02: + retval = page2_read(dev, off, len); + break; + + case 0x03: + retval = page3_read(dev, off, len); + break; + + default: + pclog(1, "%s: unknown value of pgsel in read - %d\n", + dev->name, dev->CR.pgsel); + break; + } + + return(retval); +} + + +static uint8_t +nic_readb(uint16_t addr, void *priv) +{ + return(nic_read((nic_t *)priv, addr, 1)); +} + + +static uint16_t +nic_readw(uint16_t addr, void *priv) +{ + nic_t *dev = (nic_t *)priv; + + if (dev->DCR.wdsize & 1) + return(nic_read(dev, addr, 2)); + else + return(nic_read(dev, addr, 1)); +} + + +static uint32_t +nic_readl(uint16_t addr, void *priv) +{ + return(nic_read((nic_t *)priv, addr, 4)); +} + + +static void +nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) +{ + int off = addr - dev->base_address; + + pclog(2, "%s: write addr %x, value %x len %d\n", dev->name, addr, val, len); + + /* The high 16 bytes of i/o space are for the ne2000 asic - + the low 16 bytes are for the DS8390, with the current + page being selected by the PS0,PS1 registers in the + command register */ + if (off >= 0x10) { + asic_write(dev, off - 0x10, val, len); + } else if (off == 0x00) { + write_cr(dev, val); + } else switch(dev->CR.pgsel) { + case 0x00: + page0_write(dev, off, val, len); + break; + + case 0x01: + page1_write(dev, off, val, len); + break; + + case 0x02: + page2_write(dev, off, val, len); + break; + + case 0x03: + page3_write(dev, off, val, len); + break; + + default: + pclog(1, "%s: unknown value of pgsel in write - %d\n", + dev->name, dev->CR.pgsel); + break; + } +} + + +static void +nic_writeb(uint16_t addr, uint8_t val, void *priv) +{ + nic_write((nic_t *)priv, addr, val, 1); +} + + +static void +nic_writew(uint16_t addr, uint16_t val, void *priv) +{ + nic_t *dev = (nic_t *)priv; + + if (dev->DCR.wdsize & 1) + nic_write(dev, addr, val, 2); + else + nic_write(dev, addr, val, 1); +} + + +static void +nic_writel(uint16_t addr, uint32_t val, void *priv) +{ + nic_write((nic_t *)priv, addr, val, 4); +} + + +static void +nic_ioset(nic_t *dev, uint16_t addr) +{ + if (dev->is_rtl8029as) { + io_sethandler(addr, 16, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + io_sethandler(addr+16, 16, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + io_sethandler(addr+0x1f, 1, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + } else { + io_sethandler(addr, 16, + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); + io_sethandler(addr+16, 16, + nic_readb, nic_readw, NULL, + nic_writeb, nic_writew, NULL, dev); + io_sethandler(addr+0x1f, 1, + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); + } +} + + +static void +nic_ioremove(nic_t *dev, int16_t addr) +{ + if (dev->is_rtl8029as) { + io_removehandler(addr, 16, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + io_removehandler(addr+16, 16, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + io_removehandler(addr+0x1f, 1, + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); + } else { + io_removehandler(addr, 16, + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); + io_removehandler(addr+16, 16, + nic_readb, nic_readw, NULL, + nic_writeb, nic_writew, NULL, dev); + io_removehandler(addr+0x1f, 1, + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); + } +} + + +static void +nic_update_bios(nic_t *dev) +{ + int reg_bios_enable; + + reg_bios_enable = 1; + + /* PCI BIOS stuff, just enable_disable. */ + if (!dev->disable_netbios && reg_bios_enable) { + mem_mapping_enable(&dev->bios_rom.mapping); + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios_addr, 0x10000); + pclog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); + } else { + mem_mapping_disable(&dev->bios_rom.mapping); + if (dev->is_rtl8029as) + dev->pci_bar[1].addr = 0; + } +} + + +static uint8_t +nic_pci_read(int func, int addr, void *priv) +{ + nic_t *dev = (nic_t *)priv; + + switch(addr) { + case 0x00: + return 0xec; + case 0x01: + return 0x10; + + case 0x02: + return 0x29; + case 0x03: + return 0x80; + + case 0x2C: + return 0xF4; + case 0x2D: + return 0x1A; + case 0x2E: + return 0x00; + case 0x2F: + return 0x11; + + case 0x04: + return dev->pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return dev->pci_regs[0x05]; + + case 0x07: + return 2; + + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + + case 0x0B: + return dev->pci_regs[0x0B]; + + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return dev->pci_bar[0].addr_regs[1]; + case 0x12: + return dev->pci_bar[0].addr_regs[2]; + case 0x13: + return dev->pci_bar[0].addr_regs[3]; + + case 0x30: + return dev->pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; + case 0x32: + return dev->pci_bar[1].addr_regs[2]; + case 0x33: + return dev->pci_bar[1].addr_regs[3]; + + case 0x3C: + return dev->pci_regs[0x3C]; + case 0x3D: + return dev->pci_regs[0x3D]; + } + + return 0; +} + + +static void +nic_pci_write(int func, int addr, uint8_t val, void *priv) +{ + nic_t *dev = (nic_t *)priv; + + switch(addr) { + case 0x04: + nic_ioremove(dev, dev->base_address); + if (val & PCI_COMMAND_IO) { + nic_ioset(dev, dev->base_address); + } + dev->pci_regs[addr] = val; + break; + + case 0x10: + val &= 0xfc; + val |= 1; + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O, if old base was >= 0x280. */ + nic_ioremove(dev, dev->base_address); + + /* Then let's set the PCI regs. */ + dev->pci_bar[0].addr_regs[addr & 3] = val; + + /* Then let's calculate the new I/O base. */ + dev->base_address = dev->pci_bar[0].addr & 0xff00; + + /* Log the new base. */ + pclog(1, "%s: PCI: new I/O base is %04X\n", + dev->name, dev->base_address); + /* We're done, so get out of the here. */ + if (val & PCI_COMMAND_IO) + nic_ioset(dev, dev->base_address); + return; + + case 0x30: case 0x31: case 0x32: case 0x33: + dev->pci_bar[1].addr_regs[addr & 3] = val; + dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; + dev->bios_addr = dev->pci_bar[1].addr & 0xffffe000; + dev->pci_bar[1].addr &= 0xffffe000; + dev->pci_bar[1].addr |= 0x1801; + nic_update_bios(dev); + return; + +#if 0 + /* Commented out until an APIC controller is emulated for + * the PIIX3, otherwise the RTL-8029/AS will not get an IRQ + * on boards using the PIIX3. */ + case 0x3C: + dev->pci_regs[addr] = val; + if (val != 0xFF) { + pclog(1, "%s: IRQ now: %i\n", dev->name, val); + dev->base_irq = irq; + } + return; +#endif + } +} + + +static void +nic_tx(nic_t *dev, uint32_t val) +{ + dev->CR.tx_packet = 0; + dev->TSR.tx_ok = 1; + dev->ISR.pkt_tx = 1; + + /* Generate an interrupt if not masked */ + if (dev->IMR.tx_inte) + picint(1 << dev->base_irq); + dev->tx_timer_active = 0; +} + + +/* + * mcast_index() - return the 6-bit index into the multicast + * table. Stolen unashamedly from FreeBSD's if_ed.c + */ +static int +mcast_index(const void *dst) +{ +#define POLYNOMIAL 0x04c11db6 + unsigned long crc = 0xffffffffL; + int carry, i, j; + unsigned char b; + unsigned char *ep = (unsigned char *) dst; + + for (i = 6; --i >= 0;) + { + b = *ep++; + for (j = 8; --j >= 0;) + { + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); + crc <<= 1; + b >>= 1; + if (carry) + { + crc = ((crc ^ POLYNOMIAL) | carry); + } + } + } + return (crc >> 26); +#undef POLYNOMIAL +} + + +/* + * rx_frame() - called by the platform-specific code when an + * ethernet frame has been received. The destination address + * is tested to see if it should be accepted, and if the + * rx ring has enough room, it is copied into it and + * the receive process is updated + */ +static void +nic_rx(void *priv, uint8_t *buf, int io_len) +{ + static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + nic_t *dev = (nic_t *)priv; + int pages; + int avail; + int idx; + int nextpage; + uint8_t pkthdr[4]; + uint8_t *pktbuf = (uint8_t *) buf; + uint8_t *startptr; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; + + if (io_len != 60) + pclog(2, "%s: rx_frame with length %d\n", dev->name, io_len); + + if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; + + /* Add the pkt header + CRC to the length, and work + out how many 256-byte pages the frame would occupy */ + pages = (io_len + 4 + 4 + 255)/256; + if (dev->curr_page < dev->bound_ptr) { + avail = dev->bound_ptr - dev->curr_page; + } else { + avail = (dev->page_stop - dev->page_start) - (dev->curr_page - dev->bound_ptr); + } + + /* Avoid getting into a buffer overflow condition by not attempting + to do partial receives. The emulation to handle this condition + seems particularly painful. */ + if ((avail < pages) +#if NE2K_NEVER_FULL_RING + || (avail == pages) +#endif + ) { + pclog(1, "%s: no space\n", dev->name); + return; + } + + if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { + pclog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); + return; + } + + /* some computers don't care... */ + if (io_len < 60) { + io_len=60; + } + + /* Do address filtering if not in promiscuous mode */ + if (! dev->RCR.promisc) { + /* Received. */ + mac_cmp32[0] = *(uint32_t *) (buf); + mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); + + /* Local. */ + mac_cmp32[1] = *(uint32_t *) (bcast_addr); + mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); + if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { + if (! dev->RCR.broadcast) { + return; + } + } else if (pktbuf[0] & 0x01) { + if (! dev->RCR.multicast) { + return; + } + idx = mcast_index(buf); + if (!(dev->mchash[idx >> 3] & (1 << (idx & 0x7)))) { + return; + } + } else if (0 != memcmp(buf, dev->physaddr, 6)) { + return; + } + } else { + pclog(2, "%s: rx_frame promiscuous receive\n", dev->name); + } + + pclog(2, "%s: rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", + dev->name, io_len, + pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], + pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + + nextpage = dev->curr_page + pages; + if (nextpage >= dev->page_stop) { + nextpage -= dev->page_stop - dev->page_start; + } + + /* Setup packet header */ + pkthdr[0] = 0; /* rx status - old behavior + pkthdr[0] = 1; /* Probably better to set it all the time + rather than set it to 0, which is clearly wrong. */ + if (pktbuf[0] & 0x01) { + pkthdr[0] |= 0x20; /* rx status += multicast packet */ + } + pkthdr[1] = nextpage; /* ptr to next packet */ + pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ + pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ + + /* copy into buffer, update curpage, and signal interrupt if config'd */ + startptr = & dev->mem[dev->curr_page * 256 - NE2K_MEMSTART]; + if ((nextpage > dev->curr_page) || + ((dev->curr_page + pages) == dev->page_stop)) { + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, io_len); + dev->curr_page = nextpage; + } else { + int endbytes = (dev->page_stop - dev->curr_page) * 256; + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, endbytes - 4); + startptr = & dev->mem[dev->page_start * 256 - NE2K_MEMSTART]; + memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); + dev->curr_page = nextpage; + } + + dev->RSR.rx_ok = 1; + if (pktbuf[0] & 0x80) { + dev->RSR.rx_mbit = 1; + } + + dev->ISR.pkt_rx = 1; + + if (dev->IMR.rx_inte) + picint(1 << dev->base_irq); +} + + +static void +nic_rom_init(nic_t *dev, wchar_t *s) +{ + FILE *f = romfopen(s, L"rb"); + uint32_t temp; + + if (f != NULL) { + dev->disable_netbios = 1; + nic_update_bios(dev); + return; + } + fseek(f, 0, SEEK_END); + temp = ftell(f); + fclose(f); + dev->bios_size = 0x10000; + if (temp <= 0x8000) + dev->bios_size = 0x8000; + if (temp <= 0x4000) + dev->bios_size = 0x4000; + if (temp <= 0x2000) + dev->bios_size = 0x2000; + dev->bios_mask = (dev->bios_size >> 8) & 0xff; + dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; + +#if 1 + /* Shouldn't we use the configured address?? --FvK */ + rom_init(&dev->bios_rom, s, 0xd0000, + dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); +#else + rom_init(&dev->bios_rom, s, dev->bios_addr, + dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); +#endif +} + + +static void * +nic_init(int board) +{ + uint32_t mac; + uint8_t *ptr; + nic_t *dev; + + dev = malloc(sizeof(nic_t)); + memset(dev, 0x00, sizeof(nic_t)); + dev->board = board; + dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; + if (board == NE2K_RTL8029AS) + strcpy(dev->name, "RTL8029AS"); + else if (board == NE2K_NE1000) + strcpy(dev->name, "NE1000"); + else + strcpy(dev->name, "NE2000"); + + dev->base_irq = device_get_config_int("irq"); + dev->disable_netbios = device_get_config_int("disable_netbios"); + if (dev->is_rtl8029as) { + dev->base_address = 0x340; + mac = config_get_int(NULL, "maclocal_pci", -1); + } else { + dev->base_address = device_get_config_int("addr"); + mac = config_get_int(NULL, "maclocal", -1); + } + + /* Set up our MAC address. */ + if (dev->is_rtl8029as) { + maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + maclocal_pci[1] = 0x20; + maclocal_pci[2] = 0x18; + ptr = maclocal_pci; + } else { + maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + maclocal[1] = 0x00; + maclocal[2] = 0xD8; + ptr = maclocal; + } +pclog(1, "MAClocal: mac=%08lx\n", mac); + if (mac & 0xff000000) { + /* Generating new MAC. */ + ptr[3] = disc_random_generate(); + ptr[4] = disc_random_generate(); + ptr[5] = disc_random_generate(); + } else { + ptr[3] = (mac>>16) & 0xff; + ptr[4] = (mac>>8) & 0xff; + ptr[5] = mac & 0xff; + } + memcpy(dev->physaddr, ptr, 6); + + pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", + dev->name, dev->base_address, dev->base_irq, + dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], + dev->physaddr[3], dev->physaddr[4], dev->physaddr[5], + !dev->disable_netbios); + + if (network_attach(dev, dev->physaddr, nic_rx) < 0) { + pclog(1, "%s: unable to init platform network type %d\n", + dev->name, network_type); + free(dev); + return(NULL); + } + + if (dev->is_rtl8029as) + pci_add(nic_pci_read, nic_pci_write, dev); + nic_ioset(dev, dev->base_address); + + if (! dev->disable_netbios) { + nic_rom_init(dev, dev->is_rtl8029as ? L"roms/rtl8029as.rom" + : L"roms/ne2000.rom"); + if (dev->is_rtl8029as) + mem_mapping_disable(&dev->bios_rom.mapping); + } + + if (dev->is_rtl8029as) { + dev->pci_regs[0x04] = 1; + dev->pci_regs[0x05] = 0; + dev->pci_regs[0x07] = 2; + + /* Network controller. */ + dev->pci_regs[0x0B] = 2; + + dev->pci_bar[0].addr_regs[0] = 1; + + if (! dev->disable_netbios) { + dev->pci_bar[1].addr = 0; + dev->bios_addr = 0; + } else { + dev->pci_bar[1].addr = 0x000F8000; + dev->pci_bar[1].addr_regs[1] = dev->bios_mask; + dev->pci_bar[1].addr |= 0x1801; + dev->bios_addr = 0xD0000; + } + + dev->pci_regs[0x3C] = dev->base_irq; + pclog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); + dev->pci_regs[0x3D] = 1; + + memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); + dev->eeprom[0x76] = + dev->eeprom[0x7A] = + dev->eeprom[0x7E] = 0x29; + dev->eeprom[0x77] = + dev->eeprom[0x7B] = + dev->eeprom[0x7F] = 0x80; + dev->eeprom[0x78] = + dev->eeprom[0x7C] = 0x10; + dev->eeprom[0x79] = + dev->eeprom[0x7D] = 0xEC; + } + + nic_reset(dev, 0); + + pclog(1, "%s: %s init 0x%X %d\n", dev->name, + dev->is_rtl8029as?"PCI":"ISA", dev->base_address, dev->base_irq); + + return(dev); +} + + +static void +nic_close(void *priv) +{ + nic_t *dev = (nic_t *)priv; + + /* Make sure the platform layer is shut down. */ + network_close(); + + nic_ioremove(dev, dev->base_address); + + free(dev); + + pclog(1, "%s: closed\n", dev->name); +} + + +uint32_t +ne2000_get_maclocal(void) +{ + uint32_t temp; + + temp = (((int) maclocal[3]) << 16); + temp |= (((int) maclocal[4]) << 8); + temp |= ((int) maclocal[5]); + + return(temp); +} + + +uint32_t +ne2000_get_maclocal_pci(void) +{ + uint32_t temp; + + temp = (((int) maclocal_pci[3]) << 16); + temp |= (((int) maclocal_pci[4]) << 8); + temp |= ((int) maclocal_pci[5]); + + return(temp); +} + + +static void * +ne1000_init(void) +{ + return(nic_init(NE2K_NE1000)); +} + + +static void * +ne2000_init(void) +{ + return(nic_init(NE2K_NE2000)); +} + + +static void * +rtl8029as_init(void) +{ + return(nic_init(NE2K_RTL8029AS)); +} + + +static device_config_t ne1000_config[] = +{ + { + "addr", "Address", CONFIG_SELECTION, "", 0x300, + { + { + "0x280", 0x280 + }, + { + "0x300", 0x300 + }, + { + "0x320", 0x320 + }, + { + "0x340", 0x340 + }, + { + "0x360", 0x360 + }, + { + "0x380", 0x380 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "" + } + }, + }, + { + "net_type", "Network type", CONFIG_SELECTION, "", 0, + { + { + "PCap", 0 + }, + { + "SLiRP", 1 + }, + { + "" + } + }, + }, + { + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + }, + { + "", "", -1 + } +}; + +static device_config_t ne2000_config[] = +{ + { + "addr", "Address", CONFIG_SELECTION, "", 0x300, + { + { + "0x280", 0x280 + }, + { + "0x300", 0x300 + }, + { + "0x320", 0x320 + }, + { + "0x340", 0x340 + }, + { + "0x360", 0x360 + }, + { + "0x380", 0x380 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 10, + { + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "" + } + }, + }, + { + "net_type", "Network type", CONFIG_SELECTION, "", 0, + { + { + "PCap", 0 + }, + { + "SLiRP", 1 + }, + { + "" + } + }, + }, + { + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + }, + { + "", "", -1 + } +}; + +static device_config_t rtl8029as_config[] = +{ + { + "irq", "IRQ", CONFIG_SELECTION, "", 10, + { + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "" + } + }, + }, + { + "net_type", "Network type", CONFIG_SELECTION, "", 0, + { + { + "PCap", 0 + }, + { + "SLiRP", 1 + }, + { + "" + } + }, + }, + { + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + }, + { + "", "", -1 + } +}; + + + +device_t ne1000_device = { + "Novell NE1000", + 0, + ne1000_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + ne1000_config +}; + +device_t ne2000_device = { + "Novell NE2000", + 0, + ne2000_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + ne2000_config +}; + +device_t rtl8029as_device = { + "Realtek RTL8029AS", + 0, + rtl8029as_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + rtl8029as_config +}; diff --git a/src/net_ne2000.h b/src/net_ne2000.h new file mode 100644 index 000000000..4ff2fd0f6 --- /dev/null +++ b/src/net_ne2000.h @@ -0,0 +1,36 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the NE2000 ethernet controller. + * + * Version: @(#)net_ne2000.h 1.0.2 2017/05/11 + * + * Author: Fred N. van Kempen, + */ +#ifndef NET_NE2000_H +# define NET_NE2000_H + + +#define NE2K_NE1000 1 /* 8bit ISA NE1000 */ +#define NE2K_NE2000 2 /* 16bit ISA NE2000 */ +#define NE2K_RTL8029AS 3 /* 32bi PCI Realtek 8029AS */ + + +extern device_t ne1000_device; +extern device_t ne2000_device; +extern device_t rtl8029as_device; + + +extern void ne2000_generate_maclocal(uint32_t mac); +extern uint32_t ne2000_get_maclocal(void); + +extern void ne2000_generate_maclocal_pci(uint32_t mac); +extern uint32_t ne2000_get_maclocal_pci(void); + + +#endif /*NET_NE2000_H*/ diff --git a/src/net_pcap.c b/src/net_pcap.c new file mode 100644 index 000000000..f3db05131 --- /dev/null +++ b/src/net_pcap.c @@ -0,0 +1,221 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handle WinPcap library processing. + * + * Version: @(#)net_pcap.c 1.0.1 2017/05/11 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include +#include +#include +#include "ibm.h" +#include "config.h" +#include "thread.h" +#include "device.h" +#include "network.h" + + +static pcap_t *pcap; /* handle to WinPcap library */ +static thread_t *poll_tid; +static NETRXCB poll_rx; /* network RX function to call */ +static void *poll_arg; /* network RX function arg */ + + +/* Check if the interface has a packet for us. */ +static void +poll_thread(void *arg) +{ + const unsigned char *data; + uint8_t *mac = (uint8_t *)arg; + struct pcap_pkthdr h; + event_t *evt; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; + + pclog("PCAP: polling thread started, arg %08lx\n", arg); + + /* Create a waitable event. */ + evt = thread_create_event(); + pclog("PCAP: poll event is %08lx\n", evt); + + while (pcap != NULL) { + /* Wait for the next packet to arrive. */ + data = pcap_next(pcap, &h); + if (data != NULL) { + /* Received MAC. */ + mac_cmp32[0] = *(uint32_t *)(data+6); + mac_cmp16[0] = *(uint16_t *)(data+10); + + /* Local MAC. */ + mac_cmp32[1] = *(uint32_t *)mac; + mac_cmp16[1] = *(uint16_t *)(mac+4); + if ((mac_cmp32[0] != mac_cmp32[1]) || + (mac_cmp16[0] != mac_cmp16[1])) { + if (poll_rx != NULL) + poll_rx(poll_arg, (uint8_t *)data, h.caplen); + } else { + /* Mark as invalid packet. */ + data = NULL; + } + } + + /* If we did not get anything, wait a while. */ + if (data == NULL) + thread_wait_event(evt, 10); + } + + thread_destroy_event(evt); + poll_tid = NULL; + + pclog("PCAP: polling stopped.\n"); +} + + +/* Initialize WinPcap for us. */ +int +network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) +{ + char temp[PCAP_ERRBUF_SIZE]; + char filter_exp[255]; + struct bpf_program fp; + char *dev; + + /* Messy, but gets rid of a lot of useless info. */ + dev = (char *)pcap_lib_version(); + if (dev == NULL) { + /* Hmm, WinPcap doesn't seem to be alive.. */ + pclog("PCAP: WinPcap library not found, disabling network!\n"); + network_type = -1; + return(-1); + } + + /* OK, good for now.. */ + strcpy(temp, dev); + dev = strchr(temp, '('); + if (dev != NULL) *(dev-1) = '\0'; + pclog("Initializing WinPcap, version %s\n", temp); + + /* Get the value of our capture interface. */ + dev = config_get_string(NULL, "pcap_device", NULL); + if (dev == NULL) { + pclog(" No network device configured!\n"); + return(-1); + } + pclog(" Network interface: '%s'\n", dev); + + pcap = pcap_open_live(dev, /* interface name */ + 1518, /* maximum packet size */ + 1, /* promiscuous mode? */ + 10, /* timeout in msec */ + temp); /* error buffer */ + if (pcap == NULL) { + pclog("Unable to open WinPcap: %s!\n", temp); + return(-1); + } + + /* Create a MAC address based packet filter. */ + pclog("Building packet filter ..."); + sprintf(filter_exp, + "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + if (pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { + pclog("..."); + if (pcap_setfilter(pcap, &fp) == -1) { + pclog(" error installing filter!\n"); + } else { + pclog("!\nUsing filter\t[%s]\n", filter_exp); + } + } else { + pclog(" could not compile filter!\n"); + } + + /* Save the callback info. */ + poll_rx = func; + poll_arg = arg; + + pclog("PCAP: creating thread..\n"); + poll_tid = thread_create(poll_thread, mac); + + return(0); +} + + +/* Close up shop. */ +void +network_pcap_close(void) +{ + pcap_t *pc; + + if (pcap != NULL) { + pclog("Closing WinPcap\n"); + + /* Tell the polling thread to shut down. */ + pc = pcap; pcap = NULL; +#if 1 + /* Terminate the polling thread. */ + if (poll_tid != NULL) { + thread_kill(poll_tid); + poll_tid = NULL; + } +#else + /* Wait for the polling thread to shut down. */ + while (poll_tid != NULL) + ; +#endif + + /* OK, now shut down WinPcap itself. */ + pcap_close(pc); + } + poll_rx = NULL; + poll_arg = NULL; +} + + +/* Send a packet to the Pcap interface. */ +void +network_pcap_in(uint8_t *bufp, int len) +{ + if (pcap != NULL) + pcap_sendpacket(pcap, bufp, len); +} + + +/* Retrieve an easy-to-use list of devices. */ +int +network_devlist(netdev_t *list) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *devlist, *dev; + int i = 0; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs(&devlist, errbuf) == -1) { + pclog("NETWORK: error in pcap_findalldevs_ex: %s\n", errbuf); + return(-1); + } + + for (dev=devlist; dev!=NULL; dev=dev->next) { + strcpy(list->device, dev->name); + if (dev->description) + strcpy(list->description, dev->description); + else + memset(list->description, '\0', sizeof(list->description)); + list++; + i++; + } + + /* Release the memory. */ + pcap_freealldevs(devlist); + + return(i); +} diff --git a/src/net_slirp.c b/src/net_slirp.c new file mode 100644 index 000000000..43574eccf --- /dev/null +++ b/src/net_slirp.c @@ -0,0 +1,199 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handle SLiRP library processing. + * + * Version: @(#)net_slirp.c 1.0.1 2017/05/11 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include +#include +#include "slirp/slirp.h" +#include "slirp/queue.h" +#include "ibm.h" +#include "config.h" +#include "device.h" +#include "thread.h" +#include "network.h" + + +static queueADT slirpq; /* SLiRP library handle */ +static thread_t *poll_tid; +static NETRXCB poll_rx; /* network RX function to call */ +static void *poll_arg; /* network RX function arg */ +static int fizz; + + +/* Instead of calling this and crashing some times + or experencing jitter, this is called by the + 60Hz clock which seems to do the job. */ +static void +slirp_tic(void) +{ + int ret2,nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int tmo; + nfds=-1; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ + if (tmo < 0) { + tmo = 500; + } + + tv.tv_sec = 0; + tv.tv_usec = tmo; /* basilisk default 10000 */ + + ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); + if (ret2 >= 0) { + slirp_select_poll(&rfds, &wfds, &xfds); + } +} + + +/* Check if the interface has a packet for us. */ +static void +poll_thread(void *arg) +{ + uint8_t *mac = (uint8_t *)arg; + struct queuepacket *qp; + event_t *evt; + + pclog("SLiRP: polling thread started, arg %08lx\n", arg); + + /* Create a waitable event. */ + evt = thread_create_event(); + pclog("SLiRP: poll event is %08lx\n", evt); + + while (slirpq != NULL) { + if (++fizz > 1200) { + fizz = 0; + slirp_tic(); + } + + /* Wait for the next packet to arrive. */ + if (QueuePeek(slirpq) == 0) { + /* If we did not get anything, wait a while. */ + thread_wait_event(evt, 10); + continue; + } + + /* Grab a packet from the queue. */ + qp = QueueDelete(slirpq); + pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n", + QueuePeek(slirpq), qp->len, qp); + + if (poll_rx != NULL) + poll_rx(poll_arg, (uint8_t *)&qp->data, qp->len); + + /* Done with this one. */ + free(qp); + } + + thread_destroy_event(evt); + poll_tid = NULL; + + pclog("SLiRP: polling stopped.\n"); +} + + +/* Initialize SLiRP for us. */ +int +network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) +{ + int rc; + + pclog("Initializing SLiRP\n"); + + if (slirp_init() != 0) { + pclog("SLiRP could not be initialized!\n"); + return(-1); + } + + slirpq = QueueCreate(); + pclog(" Packet queue is at %08lx\n", &slirpq); + + fizz = 0; + + /* Save the callback info. */ + poll_rx = func; + poll_arg = arg; + + pclog("SLiRP: creating thread..\n"); + poll_tid = thread_create(poll_thread, mac); + + return(0); +} + + +void +network_slirp_close(void) +{ + queueADT sl; + + if (slirpq != NULL) { + pclog("Closing SLiRP\n"); + + /* Tell the polling thread to shut down. */ + sl = slirpq; slirpq = NULL; +#if 1 + /* Terminate the polling thread. */ + if (poll_tid != NULL) { + thread_kill(poll_tid); + poll_tid = NULL; + } +#else + /* Wait for the polling thread to shut down. */ + while (poll_tid != NULL) + ; +#endif + + /* OK, now shut down SLiRP itself. */ + QueueDestroy(sl); + slirp_exit(0); + } + + poll_rx = NULL; + poll_arg = NULL; +} + + +/* Send a packet to the SLiRP interface. */ +void +network_slirp_in(uint8_t *pkt, int pkt_len) +{ + if (slirpq != NULL) + slirp_input((const uint8_t *)pkt, pkt_len); +} + + +void +slirp_output(const uint8_t *pkt, int pkt_len) +{ + struct queuepacket *qp; + + if (slirpq != NULL) { + qp = (struct queuepacket *)malloc(sizeof(struct queuepacket)); + qp->len = pkt_len; + memcpy(qp->data, pkt, pkt_len); + QueueEnter(slirpq, qp); + } +} + + +int +slirp_can_output(void) +{ + return((slirpq != NULL)?1:0); +} diff --git a/src/nethandler.c b/src/nethandler.c deleted file mode 100644 index c399964c6..000000000 --- a/src/nethandler.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#include -#include -#include -#include -#include "nethandler.h" - -#include "ibm.h" -#include "device.h" - -#include "ne2000.h" -#include "timer.h" -#include "thread.h" - -int network_card_current = 0; -static int network_card_last = 0; - -typedef struct -{ - char name[64]; - char internal_name[32]; - device_t *device; -} NETWORK_CARD; - -static NETWORK_CARD network_cards[] = -{ - {"None", "none", NULL}, - {"Novell NE2000", "ne2k", &ne2000_device}, - {"Realtek RTL8029AS", "ne2kpci", &rtl8029as_device}, - {"", "", NULL} -}; - -int network_card_available(int card) -{ - if (network_cards[card].device) - return device_available(network_cards[card].device); - - return 1; -} - -char *network_card_getname(int card) -{ - return network_cards[card].name; -} - -device_t *network_card_getdevice(int card) -{ - return network_cards[card].device; -} - -int network_card_has_config(int card) -{ - if (!network_cards[card].device) - return 0; - return network_cards[card].device->config ? 1 : 0; -} - -char *network_card_get_internal_name(int card) -{ - return network_cards[card].internal_name; -} - -int network_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(network_cards[c].internal_name)) - { - if (!strcmp(network_cards[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -void network_card_init() -{ - if (network_cards[network_card_current].device) - device_add(network_cards[network_card_current].device); - network_card_last = network_card_current; -} - -static struct -{ - void (*poller)(void *p); - void *priv; -} vlan_handlers[8]; - -static int vlan_handlers_num; - -static int vlan_poller_time = 0; - -void vlan_handler(void (*poller)(void *p), void *p) -{ - vlan_handlers[vlan_handlers_num].poller = poller; - vlan_handlers[vlan_handlers_num].priv = p; - vlan_handlers_num++; -} - -static void network_thread(void *param) -{ - int c; - - for (c = 0; c < vlan_handlers_num; c++) - { - vlan_handlers[c].poller(vlan_handlers[c].priv); - } -} - -void vlan_poller(void *priv) -{ - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); - - if (vlan_handlers_num) - { - network_thread(priv); - } -} - -void vlan_reset() -{ - pclog("vlan_reset()\n"); - - if (network_card_current) - { - pclog("Adding timer...\n"); - - timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); - } - - vlan_handlers_num = 0; -} diff --git a/src/nethandler.h b/src/nethandler.h deleted file mode 100644 index 623dec93b..000000000 --- a/src/nethandler.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include - -void vlan_handler(void (*poller)(void *p), void *p); - -extern int network_card_current; - -int network_card_available(int card); -char *network_card_getname(int card); -struct device_t *network_card_getdevice(int card); -int network_card_has_config(int card); -char *network_card_get_internal_name(int card); -int network_card_get_from_internal_name(char *s); -void network_card_init(); -void vlan_reset(); - -void initpcap(); -void closepcap(); diff --git a/src/network.c b/src/network.c new file mode 100644 index 000000000..f79f91628 --- /dev/null +++ b/src/network.c @@ -0,0 +1,219 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the network module. + * + * NOTE The definition of the netcard_t is currently not optimal; + * it should be malloc'ed and then linked to the NETCARD def. + * Will be done later. + * + * Version: @(#)network.c 1.0.3 2017/05/12 + * + * Authors: Kotori, + * Fred N. van Kempen, + */ +#include +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "network.h" +#include "net_ne2000.h" + + +static netcard_t net_cards[] = { + { "None", "none", NULL, + NULL, NULL }, + { "Novell NE1000", "ne1k", &ne1000_device, + NULL, NULL }, + { "Novell NE2000", "ne2k", &ne2000_device, + NULL, NULL }, + { "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device, + NULL, NULL }, + { "", "", NULL, + NULL, NULL } +}; + + +int network_card; +int network_type; + + +/* + * Initialize the configured network cards. + * + * This function gets called only once, from the System + * Platform initialization code (currently in pc.c) to + * set our local stuff to a known state. + */ +void +network_init(void) +{ + network_card = 0; + network_type = -1; +} + + +/* + * Attach a network card to the system. + * + * This function is called by a hardware driver ("card") after it has + * finished initializing itself, to link itself to the platform support + * modules. + */ +int +network_attach(void *dev, uint8_t *mac, NETRXCB rx) +{ + int ret = -1; + + if (! network_card) return(ret); + + /* Save the card's callback info. */ + net_cards[network_card].private = dev; + net_cards[network_card].rx = rx; + + /* Start the platform module. */ + switch(network_type) { + case 0: + ret = network_pcap_setup(mac, rx, dev); + break; + + case 1: + ret = network_slirp_setup(mac, rx, dev); + break; + } + + return(ret); +} + + +/* Stop any network activity. */ +void +network_close(void) +{ + switch(network_type) { + case 0: + network_pcap_close(); + break; + + case 1: + network_slirp_close(); + break; + } + +} + + +/* + * Reset the network card(s). + * + * This function is called each time the system is reset, + * either a hard reset (including power-up) or a soft reset + * including C-A-D reset.) It is responsible for connecting + * everything together. + */ +void +network_reset(void) +{ + pclog("NETWORK: reset (type=%d, card=%d\n", network_type, network_card); + + /* Just in case.. */ + network_close(); + + /* If no active card, we're done. */ + if (!network_card || (network_type<0)) return; + + pclog("NETWORK: set up for %s, card=%s\n", + (network_type==1)?"SLiRP":"WinPcap", net_cards[network_card].name); + + pclog("NETWORK: reset (card=%d)\n", network_card); + /* Add the (new?) card to the I/O system. */ + if (net_cards[network_card].device) { + pclog("NETWORK: adding device '%s'\n", + net_cards[network_card].name); + device_add(net_cards[network_card].device); + } +} + + +/* Transmit a packet to one of the network providers. */ +void +network_tx(uint8_t *bufp, int len) +{ + switch(network_type) { + case 0: + network_pcap_in(bufp, len); + break; + + case 1: + network_slirp_in(bufp, len); + break; + } +} + + +/* UI */ +int +network_card_available(int card) +{ + if (net_cards[card].device) + return(device_available(net_cards[card].device)); + + return(1); +} + + +/* UI */ +char * +network_card_getname(int card) +{ + return(net_cards[card].name); +} + + +/* UI */ +device_t * +network_card_getdevice(int card) +{ + return(net_cards[card].device); +} + + +/* UI */ +int +network_card_has_config(int card) +{ + if (! net_cards[card].device) return(0); + + return(net_cards[card].device->config ? 1 : 0); +} + + +/* UI */ +char * +network_card_get_internal_name(int card) +{ + return(net_cards[card].internal_name); +} + + +/* UI */ +int +network_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(net_cards[c].internal_name)) { + if (! strcmp(net_cards[c].internal_name, s)) + return(c); + c++; + } + + return(0); +} diff --git a/src/network.h b/src/network.h new file mode 100644 index 000000000..ed971e9b7 --- /dev/null +++ b/src/network.h @@ -0,0 +1,74 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the network module. + * + * Version: @(#)network.h 1.0.3 2017/05/12 + * + * Authors: Kotori, + * Fred N. van Kempen, + */ +#ifndef NETWORK_H +# define NETWORK_H +# include + + +#define NE1000 1 +#define NE2000 2 +#define RTL8029AS 3 + + +typedef void (*NETRXCB)(void *, uint8_t *, int); + + +typedef struct { + char name[64]; + char internal_name[32]; + device_t *device; + void *private; + int (*poll)(void *); + NETRXCB rx; +} netcard_t; + +typedef struct { + char device[128]; + char description[128]; +} netdev_t; + + +/* Global variables. */ +extern int network_card; +extern int network_type; + + +/* Function prototypes. */ +extern void network_init(void); +extern int network_attach(void *, uint8_t *, NETRXCB); +extern void network_close(void); +extern void network_reset(void); +extern void network_tx(uint8_t *, int); + +extern int network_pcap_setup(uint8_t *, NETRXCB, void *); +extern void network_pcap_close(void); +extern void network_pcap_in(uint8_t *, int); +extern int network_devlist(netdev_t *); + +extern int network_slirp_setup(uint8_t *, NETRXCB, void *); +extern void network_slirp_close(void); +extern void network_slirp_in(uint8_t *, int); + +extern int network_devlist(netdev_t *); +extern int network_card_available(int); +extern char *network_card_getname(int); +extern int network_card_has_config(int); +extern char *network_card_get_internal_name(int); +extern int network_card_get_from_internal_name(char *); +extern struct device_t *network_card_getdevice(int); + + +#endif /*NETWORK_H*/ diff --git a/src/nvr.c b/src/nvr.c index 76c42e7d0..f3490260a 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -1,8 +1,10 @@ #include #include "ibm.h" #include "io.h" +#include "mem.h" #include "nvr.h" #include "pic.h" +#include "rom.h" #include "timer.h" #include "rtc.h" @@ -190,72 +192,59 @@ void loadnvr() oldromset=romset; switch (romset) { - case ROM_PC1512: f = romfopen(nvr_concat("pc1512.nvr"), "rb"); break; - case ROM_PC1640: f = romfopen(nvr_concat("pc1640.nvr"), "rb"); break; - case ROM_PC200: f = romfopen(nvr_concat("pc200.nvr"), "rb"); break; - case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "rb"); break; - case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "rb"); break; - case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "rb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "rb"); break; - case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "rb"); break; - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "rb"); break; - case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; - case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "rb"); break; - case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "rb"); break; - case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; - case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; - case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; - case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "rb"); nvrmask = 127; break; - case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; - case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; - case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "rb"); break; - /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; */ - case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break; - case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "rb"); nvrmask = 127; break; - case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "rb"); nvrmask = 127; break; - case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "rb"); nvrmask = 127; break; - case ROM_SIS496: f = romfopen(nvr_concat("sis496.nvr"), "rb"); nvrmask = 127; break; - case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "rb"); nvrmask = 127; break; - case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "rb"); nvrmask = 127; break; - case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "rb"); nvrmask = 127; break; - /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "rb"); nvrmask = 127; break; */ - case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "rb"); nvrmask = 127; break; - case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "rb"); nvrmask = 127; break; - case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "rb"); nvrmask = 127; break; - case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "rb"); nvrmask = 127; break; - case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "rb"); nvrmask = 127; break; - case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "rb"); nvrmask = 127; break; - case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break; - case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "rb"); nvrmask = 127; break; - case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break; - case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "rb"); nvrmask = 127; break; - case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break; - case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break; - case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "rb"); nvrmask = 127; break; + case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"rb"); break; + case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"rb"); break; + case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"rb"); break; + case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"rb"); break; + case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"rb"); break; + case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"rb"); break; + case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"rb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"rb"); break; + case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"rb"); nvrmask = 127; break; + case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"rb"); break; + case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"rb"); break; + case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"rb"); nvrmask = 127; break; + case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"rb"); nvrmask = 127; break; + case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"rb"); nvrmask = 127; break; + case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"rb"); nvrmask = 127; break; + case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"rb"); break; + case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"rb"); break; + case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"rb"); nvrmask = 127; break; + case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"rb"); nvrmask = 127; break; + case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"rb"); nvrmask = 127; break; + case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"rb"); nvrmask = 127; break; + case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"rb"); nvrmask = 127; break; + case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"rb"); nvrmask = 127; break; + case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"rb"); nvrmask = 127; break; + case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"rb"); nvrmask = 127; break; + case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"rb"); nvrmask = 127; break; + case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"rb"); nvrmask = 127; break; + case ROM_R418: f = nvrfopen(L"r418.nvr", L"rb"); nvrmask = 127; break; + case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"rb"); nvrmask = 127; break; + case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"rb"); nvrmask = 127; break; + case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"rb"); nvrmask = 127; break; + case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"rb"); nvrmask = 127; break; + case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"rb"); nvrmask = 127; break; + case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"rb"); nvrmask = 127; break; + case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"rb"); nvrmask = 127; break; + case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"rb"); nvrmask = 127; break; + case ROM_THOR: f = nvrfopen(L"thor.nvr", L"rb"); nvrmask = 127; break; + case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break; + case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break; + case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break; default: return; } if (!f) @@ -287,72 +276,59 @@ void savenvr() FILE *f; switch (oldromset) { - case ROM_PC1512: f = romfopen(nvr_concat("pc1512.nvr"), "wb"); break; - case ROM_PC1640: f = romfopen(nvr_concat("pc1640.nvr"), "wb"); break; - case ROM_PC200: f = romfopen(nvr_concat("pc200.nvr"), "wb"); break; - case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "wb"); break; - case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "wb"); break; - case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "wb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "wb"); break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "wb"); break; - case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "wb"); break; - case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "wb"); break; - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "wb"); break; - case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; - case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "wb"); break; - case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "wb"); break; - case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; - case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; - case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; - case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "wb"); break; - case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; - case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; - case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; - case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "wb"); break; - /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; */ - case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break; - case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "wb"); break; - case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break; - case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "wb"); break; - case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "wb"); break; - case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "wb"); break; - case ROM_SIS496: f = romfopen(nvr_concat("sis496.nvr"), "wb"); break; - case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "wb"); break; - case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "wb"); break; - case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "wb"); break; - /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "wb"); break; */ - case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "wb"); break; - case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "wb"); break; - case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "wb"); break; - case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "wb"); break; - case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "wb"); break; - case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "wb"); break; - case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "wb"); break; - case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "wb"); break; -#if 0 - case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break; -#endif - case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break; - case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "wb"); break; - case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "wb"); break; - case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break; - case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break; - case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "wb"); break; - case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "wb"); break; - case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "wb"); break; - case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "wb"); break; -#if 0 - case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "wb"); break; -#endif - case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break; - case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break; - case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "wb"); break; -#if 0 - case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "wb"); break; -#endif - case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "wb"); break; + case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"wb"); break; + case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"wb"); break; + case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"wb"); break; + case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"wb"); break; + case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"wb"); break; + case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"wb"); break; + case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"wb"); break; + case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"wb"); break; + case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"wb"); break; + case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"wb"); break; + case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"wb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"wb"); break; + case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"wb"); break; + case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"wb"); break; + case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"wb"); break; + case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"wb"); break; + case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"wb"); break; + case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"wb"); break; + case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"wb"); break; + case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"wb"); break; + case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"wb"); break; + case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"wb"); break; + case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"wb"); break; + case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"wb"); break; + case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"wb"); break; + case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"wb"); break; + case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"wb"); break; + case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"wb"); break; + case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"wb"); break; + case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"wb"); break; + case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"wb"); break; + case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"wb"); break; + case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"wb"); break; + case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"wb"); break; + case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"wb"); break; + case ROM_R418: f = nvrfopen(L"r418.nvr", L"wb"); break; + case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"wb"); break; + case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"wb"); break; + case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"wb"); break; + case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"wb"); break; + case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"wb"); break; + case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"wb"); break; + case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"wb"); break; + case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"wb"); break; + case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"wb"); break; + case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"wb"); break; + case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"wb"); break; + case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"wb"); break; + case ROM_THOR: f = nvrfopen(L"thor.nvr", L"wb"); break; + case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break; + case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break; + case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/opti495.c b/src/opti495.c index 2567782bd..9bf55d854 100644 --- a/src/opti495.c +++ b/src/opti495.c @@ -1,7 +1,7 @@ /*OPTi 82C495 emulation This is the chipset used in the AMI386 model*/ #include "ibm.h" -#include "cpu.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" diff --git a/src/pc.c b/src/pc.c index 2c9f891ad..3dd43745b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -4,19 +4,19 @@ #include #include #include - #include "86box.h" #include "ibm.h" +#include "mem.h" +#include "cpu/cpu.h" +#include "cpu/x86_ops.h" +#include "cpu/codegen.h" +#include "dma.h" +#include "nvr.h" +#include "pic.h" +#include "pit.h" +#include "timer.h" #include "device.h" -#ifndef __unix -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win.h" -#include "win-language.h" -#endif - #include "ali1429.h" #include "cdrom.h" #include "cdrom-ioctl.h" @@ -25,57 +25,55 @@ #include "disc_fdi.h" #include "disc_imd.h" #include "disc_img.h" -#include "disc_random.h" #include "disc_td0.h" -#include "mem.h" -#include "x86_ops.h" -#include "codegen.h" -#include "cdrom-iso.h" -#include "cdrom-null.h" +#include "disc_random.h" #include "config.h" -#include "cpu.h" -#include "dma.h" #include "fdc.h" #include "fdd.h" #include "gameport.h" -#include "sound_gus.h" -#include "ide.h" -#include "cdrom.h" -#include "scsi.h" -#include "keyboard.h" -#include "keyboard_at.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "ne2000.h" -#include "nethandler.h" -#include "nvr.h" -#include "pic.h" -#include "pit.h" #include "plat-joystick.h" #include "plat-midi.h" -#include "plat-mouse.h" -#include "plat-keyboard.h" -#include "serial.h" -#include "sound.h" -#include "sound_cms.h" -#include "sound_dbopl.h" -#include "sound_opl.h" -#include "sound_sb.h" -#include "sound_speaker.h" -#include "sound_ssi2001.h" -#include "timer.h" -#include "vid_voodoo.h" -#include "video.h" -#include "amstrad.h" #include "hdd.h" -#include "nethandler.h" -#define NE2000 1 -#define RTL8029AS 2 -uint8_t ethif; -int inum; +#include "ide.h" +#include "cdrom.h" +#include "cdrom-image.h" +#include "cdrom-null.h" +#include "scsi.h" +#include "keyboard.h" +#include "plat-keyboard.h" +#include "keyboard_at.h" +#include "model.h" +#include "mouse.h" +#include "plat-mouse.h" +#include "network.h" +#include "serial.h" +#include "sound/sound.h" +#include "sound/snd_cms.h" +#include "sound/snd_dbopl.h" +#include "sound/snd_opl.h" +#include "sound/snd_gus.h" +#include "sound/snd_sb.h" +#include "sound/snd_speaker.h" +#include "sound/snd_ssi2001.h" +#include "video/video.h" +#include "video/vid_voodoo.h" +#include "amstrad.h" +#ifdef WALTJE +# define UNICODE +# include "plat-dir.h" +#endif -char nvr_path[1024]; +#ifndef __unix +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "win.h" +#include "win-language.h" +#endif + + +wchar_t nvr_path[1024]; int path_len; int window_w, window_h, window_x, window_y, window_remember; @@ -103,6 +101,8 @@ int atfullspeed; void saveconfig(); int infocus; int mousecapture; + + void pclog(const char *format, ...) { #ifndef RELEASE_BUILD @@ -114,6 +114,17 @@ void pclog(const char *format, ...) #endif } +void pclog_w(const wchar_t *format, ...) +{ +#ifndef RELEASE_BUILD + va_list ap; + va_start(ap, format); + vwprintf(format, ap); + va_end(ap); + fflush(stdout); +#endif +} + #ifndef __unix #ifndef _LIBC # define __builtin_expect(expr, val) (expr) @@ -121,6 +132,7 @@ void pclog(const char *format, ...) #undef memmem + /* Return the first occurrence of NEEDLE in HAYSTACK. */ void *memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) { @@ -145,6 +157,7 @@ void *memmem (const void *haystack, size_t haystack_len, const void *needle, siz } #endif + void fatal(const char *format, ...) { char msg[1024]; @@ -175,8 +188,9 @@ void fatal(const char *format, ...) uint8_t cgastat; + int pollmouse_delay = 2; -void pollmouse() +void pollmouse(void) { int x, y, z; pollmouse_delay--; @@ -236,14 +250,14 @@ int updatestatus; int win_title_update=0; -void onesec() +void onesec(void) { fps=framecount; framecount=0; win_title_update=1; } -void pc_reset() +void pc_reset(void) { cpu_set(); resetx86(); @@ -259,68 +273,88 @@ void pc_reset() ali1429_reset(); } + + #undef printf -void initpc(int argc, char *argv[]) +void initpc(int argc, wchar_t *argv[]) { - char *p; - char *config_file = NULL; + wchar_t *p; + wchar_t *config_file = NULL; int c, i; FILE *ff; - get_executable_name(pcempath,511); - pclog("executable_name = %s\n", pcempath); - p=get_filename(pcempath); - *p=0; - pclog("path = %s\n", pcempath); + get_executable_name(pcempath, 511); + pclog("executable_name = %ws\n", pcempath); + p=get_filename_w(pcempath); + *p=L'\0'; + pclog("path = %ws\n", pcempath); for (c = 1; c < argc; c++) { - if (!strcasecmp(argv[c], "--help")) + if (!_wcsicmp(argv[c], L"--help")) { - printf("PCem command line options :\n\n"); + printf("Command line options :\n\n"); printf("--config file.cfg - use given config file as initial configuration\n"); printf("--dump - always dump memory on exit\n"); printf("--fullscreen - start in fullscreen mode\n"); exit(-1); } - else if (!strcasecmp(argv[c], "--config")) + else if (!_wcsicmp(argv[c], L"--config")) { if ((c+1) == argc) break; config_file = argv[c+1]; c++; } - else if (!strcasecmp(argv[c], "--dump")) + else if (!_wcsicmp(argv[c], L"--dump")) { dump_on_exit = 1; } - else if (!strcasecmp(argv[c], "--fullscreen")) + else if (!_wcsicmp(argv[c], L"--fullscreen")) { start_in_fullscreen = 1; } - else if (!strcasecmp(argv[c], "--test")) + else if (!_wcsicmp(argv[c], L"--test")) { /* some (undocumented) test function here.. */ +#ifdef WALTJE + DIR *dir; + struct direct *dp; + + dir = opendirw(pcempath); + if (dir != NULL) { + printf("Directory '%ws':\n", pcempath); + for (;;) { + dp = readdir(dir); + if (dp == NULL) break; + printf(">> '%ws'\n", dp->d_name); + } + closedir(dir); + } else { + printf("Could not open '%ws'..\n", pcempath); + } +#endif /* .. and then exit. */ exit(0); } } - keyboard_init(); + /* Initialize modules. */ + network_init(); mouse_init(); midi_init(); + serial_init(); + disc_random_init(); if (config_file == NULL) { - append_filename(config_file_default, pcempath, "86box.cfg", 511); + append_filename_w(config_file_default, pcempath, L"86box.cfg", 511); } else { - append_filename(config_file_default, pcempath, config_file, 511); + append_filename_w(config_file_default, pcempath, config_file, 511); } - disc_random_init(); - loadconfig(config_file); pclog("Config loaded\n"); if (config_file) @@ -357,17 +391,7 @@ void initpc(int argc, char *argv[]) { if (cdrom_drives[i].host_drive == 200) { - ff = fopen(cdrom_iso[i].iso_path, "rb"); - if (ff) - { - fclose(ff); - iso_open(i, cdrom_iso[i].iso_path); - } - else - { - cdrom_drives[i].host_drive = 0; - cdrom_null_open(i, cdrom_drives[i].host_drive); - } + image_open(i, cdrom_image[i].image_path); } else { @@ -406,7 +430,7 @@ void initpc(int argc, char *argv[]) { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -416,7 +440,7 @@ void initpc(int argc, char *argv[]) } } -void resetpc() +void resetpc(void) { pc_reset(); shadowbios=0; @@ -434,7 +458,7 @@ void pc_keyboard_send(uint8_t val) } } -void resetpc_cad() +void resetpc_cad(void) { pc_keyboard_send(29); /* Ctrl key pressed */ pc_keyboard_send(56); /* Alt key pressed */ @@ -446,7 +470,7 @@ void resetpc_cad() int suppress_overscan = 0; -void resetpchard() +void resetpchard(void) { int i = 0; @@ -467,11 +491,11 @@ void resetpchard() mem_resize(); fdc_init(); disc_reset(); - + model_init(); - mouse_emu_init(); video_init(); speaker_init(); + network_reset(); ide_ter_disable(); ide_qua_disable(); @@ -486,12 +510,6 @@ void resetpchard() ide_qua_init(); } - if (network_card_current != 0) - { - vlan_reset(); /* NETWORK */ - } - network_card_init(network_card_current); - for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type) @@ -503,7 +521,7 @@ void resetpchard() resetide(); scsi_card_init(); - sound_card_init(sound_card_current); + sound_card_init(); if (GUS) device_add(&gus_device); if (GAMEBLASTER) @@ -514,6 +532,7 @@ void resetpchard() device_add(&voodoo_device); hdd_controller_init(hdd_controller_name); pc_reset(); + mouse_emu_init(); loadnvr(); @@ -530,7 +549,7 @@ void resetpchard() { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -559,9 +578,12 @@ int serial_fifo_read, serial_fifo_write; int emu_fps = 0; -void runpc() +static WCHAR wmodel[2048]; +static WCHAR wcpu[2048]; + +void runpc(void) { - char s[200]; + wchar_t s[200]; int done=0; startblit(); @@ -583,7 +605,6 @@ void runpc() execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); } - keyboard_poll_host(); keyboard_process(); pollmouse(); if (joystick_type != 7) joystick_poll(); @@ -637,13 +658,15 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "86Box v%s - %i%% - %s - %s - %s", emulator_version, fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? "Press F12-F8 to release mouse" : "Press F12-F8 or middle button to release mouse")); + mbstowcs(wmodel, model_getname(), strlen(model_getname()) + 1); + mbstowcs(wcpu, models[model].cpu[cpu_manufacturer].cpus[cpu].name, strlen(models[model].cpu[cpu_manufacturer].cpus[cpu].name) + 1); + _swprintf(s, L"86Box v%s - %i%% - %s - %s - %s", emulator_version_w, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); set_window_title(s); } done++; } -void fullspeed() +void fullspeed(void) { cpuspeed2=cpuspeed; if (!atfullspeed) @@ -658,7 +681,7 @@ void fullspeed() nvr_recalc(); } -void speedchanged() +void speedchanged(void) { if (AT) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); @@ -667,7 +690,7 @@ void speedchanged() nvr_recalc(); } -void closepc() +void closepc(void) { int i = 0; for (i = 0; i < CDROM_NUM; i++) @@ -683,411 +706,5 @@ void closepc() closevideo(); device_close_all(); midi_close(); -} - -/*int main() -{ - initpc(); - while (!key[KEY_F11]) - { - runpc(); - } - closepc(); - return 0; -} - -END_OF_MAIN();*/ - -void loadconfig(char *fn) -{ - int c, d; - char s[512]; - char *p; - char temps[512]; - - if (!fn) - config_load(config_file_default); - else - config_load(fn); - - GAMEBLASTER = config_get_int(NULL, "gameblaster", 0); - GUS = config_get_int(NULL, "gus", 0); - SSI2001 = config_get_int(NULL, "ssi2001", 0); - voodoo_enabled = config_get_int(NULL, "voodoo", 0); - - /* SCSI */ - p = (char *)config_get_string(NULL, "scsicard", ""); - if (p) - scsi_card_current = scsi_card_get_from_internal_name(p); - else - scsi_card_current = 0; - - /* network */ - ethif = config_get_int(NULL, "netinterface", 1); - if (ethif >= inum) - inum = ethif + 1; - p = (char *)config_get_string(NULL, "netcard", ""); - if (p) - network_card_current = network_card_get_from_internal_name(p); - else - network_card_current = 0; - ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); - ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); - - p = (char *)config_get_string(NULL, "model", ""); - if (p) - model = model_get_model_from_internal_name(p); - else - model = 0; - - if (model >= model_count()) - model = model_count() - 1; - - romset = model_getromset(); - cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); - cpu = config_get_int(NULL, "cpu", 0); - cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0); - - cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); - - p = (char *)config_get_string(NULL, "gfxcard", ""); - if (p) - gfxcard = video_get_video_from_internal_name(p); - else - gfxcard = 0; - video_speed = config_get_int(NULL, "video_speed", 3); - p = (char *)config_get_string(NULL, "sndcard", ""); - if (p) - sound_card_current = sound_card_get_from_internal_name(p); - else - sound_card_current = 0; - - mem_size = config_get_int(NULL, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - fdd_set_type(c, config_get_int(NULL, temps, (c < 2) ? 2 : 0)); - sprintf(temps, "fdd_%02i_fn", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(discfns[c], p); - else strcpy(discfns[c], ""); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = config_get_int(NULL, temps, 0); - } - - p = (char *)config_get_string(NULL, "hdd_controller", ""); - if (p) - strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); - else - strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - ide_enable[c] = config_get_int(NULL, temps, 0); - sprintf(temps, "ide_%02i_irq", c + 1); - ide_irq[c] = config_get_int(NULL, temps, 8 + c); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - hdc[c].spt = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_heads", c + 1); - hdc[c].hpc = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - hdc[c].tracks = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - hdc[c].bus = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - hdc[c].scsi_lun = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_fn", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(hdd_fn[c], p); - else strcpy(hdd_fn[c], ""); - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); - cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; - sprintf(temps, "cdrom_%02i_enabled", c + 1); - cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(cdrom_iso[c].iso_path, p); - else strcpy(cdrom_iso[c].iso_path, ""); - } - - vid_resize = config_get_int(NULL, "vid_resize", 0); - vid_api = config_get_int(NULL, "vid_api", 0); - video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - - force_43 = config_get_int(NULL, "force_43", 0); - scale = config_get_int(NULL, "scale", 1); - enable_overscan = config_get_int(NULL, "enable_overscan", 0); - enable_flash = config_get_int(NULL, "enable_flash", 1); - - enable_sync = config_get_int(NULL, "enable_sync", 1); - opl3_type = config_get_int(NULL, "opl3_type", 1); - - window_w = config_get_int(NULL, "window_w", 0); - window_h = config_get_int(NULL, "window_h", 0); - window_x = config_get_int(NULL, "window_x", 0); - window_y = config_get_int(NULL, "window_y", 0); - window_remember = config_get_int(NULL, "window_remember", 0); - - joystick_type = config_get_int(NULL, "joystick_type", 0); - p = (char *)config_get_string(NULL, "mouse_type", ""); - if (p) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - enable_xtide = config_get_int(NULL, "enable_xtide", 1); - enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); - } - } - } - - memset(nvr_path, 0, 1024); - p = (char *)config_get_string(NULL, "nvr_path", "nvr"); - if (p) { - if (strlen(p) <= 992) strcpy(nvr_path, p); - else strcpy(nvr_path, "nvr"); - } - else strcpy(nvr_path, "nvr"); - - if (nvr_path[strlen(nvr_path)] != '/') - { - nvr_path[strlen(nvr_path)] = '/'; - } - - path_len = strlen(nvr_path); - - serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); - serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); - lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); - bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); -} - -char *nvr_concat(char *to_concat) -{ - memset(nvr_path + path_len, 0, 1024 - path_len); - strcpy(nvr_path + path_len, to_concat); - return nvr_path; -} - -void saveconfig() -{ - int c, d; - - char temps[512]; - - config_set_int(NULL, "gameblaster", GAMEBLASTER); - config_set_int(NULL, "gus", GUS); - config_set_int(NULL, "ssi2001", SSI2001); - config_set_int(NULL, "voodoo", voodoo_enabled); - - config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - - config_set_int(NULL, "netinterface", ethif); - config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); - config_set_int(NULL, "maclocal", net2000_get_maclocal()); - config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); - - config_set_string(NULL, "model", model_get_internal_name()); - config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); - config_set_int(NULL, "cpu", cpu); - config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(NULL, "cpu_waitstates", cpu_waitstates); - - config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(NULL, "video_speed", video_speed); - config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int(NULL, "cpu_speed", cpuspeed); - config_set_int(NULL, "has_fpu", hasfpu); - - config_set_int(NULL, "mem_size", mem_size); - - memset(temps, 0, 512); - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - config_set_int(NULL, temps, fdd_get_type(c)); - sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_string(NULL, temps, discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(NULL, temps, ui_writeprot[c]); - } - - config_set_string(NULL, "hdd_controller", hdd_controller_name); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - config_set_int(NULL, temps, ide_enable[c]); - sprintf(temps, "ide_%02i_irq", c + 1); - config_set_int(NULL, temps, ide_irq[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - config_set_int(NULL, temps, hdc[c].spt); - sprintf(temps, "hdd_%02i_heads", c + 1); - config_set_int(NULL, temps, hdc[c].hpc); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - config_set_int(NULL, temps, hdc[c].tracks); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - config_set_int(NULL, temps, hdc[c].bus); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(NULL, temps, hdc[c].mfm_channel); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, hdc[c].ide_channel); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_id); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_lun); - sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_string(NULL, temps, hdd_fn[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].host_drive); - sprintf(temps, "cdrom_%02i_enabled", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].enabled); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].sound_on); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].bus_type); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].ide_channel); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - config_set_string(NULL, temps, cdrom_iso[c].iso_path); - } - - config_set_int(NULL, "vid_resize", vid_resize); - config_set_int(NULL, "vid_api", vid_api); - config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); - - config_set_int(NULL, "force_43", force_43); - config_set_int(NULL, "scale", scale); - config_set_int(NULL, "enable_overscan", enable_overscan); - config_set_int(NULL, "enable_flash", enable_flash); - - config_set_int(NULL, "enable_sync", enable_sync); - config_set_int(NULL, "opl3_type", opl3_type); - - config_set_int(NULL, "joystick_type", joystick_type); - config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); - - config_set_int(NULL, "enable_xtide", enable_xtide); - config_set_int(NULL, "enable_external_fpu", enable_external_fpu); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - char s[80]; - - sprintf(s, "joystick_%i_nr", c); - config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); - } - } - } - - config_set_int(NULL, "window_w", window_w); - config_set_int(NULL, "window_h", window_h); - config_set_int(NULL, "window_x", window_x); - config_set_int(NULL, "window_y", window_y); - config_set_int(NULL, "window_remember", window_remember); - - config_set_int(NULL, "serial1_enabled", serial_enabled[0]); - config_set_int(NULL, "serial2_enabled", serial_enabled[1]); - config_set_int(NULL, "lpt_enabled", lpt_enabled); - config_set_int(NULL, "bugger_enabled", bugger_enabled); - - config_save(config_file_default); + network_close(); } diff --git a/src/pc87306.c b/src/pc87306.c index b62ea642c..c0a6bb7d1 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -89,24 +89,24 @@ void serial1_handler() temp = (pc87306_regs[1] >> 2) & 3; switch (temp) { - case 0: serial1_set(0x3f8, uart1_int()); break; - case 1: serial1_set(0x2f8, uart1_int()); break; + case 0: serial_setup(1, SERIAL1_ADDR, uart1_int()); break; + case 1: serial_setup(1, SERIAL2_ADDR, uart1_int()); break; case 2: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial1_set(0x3e8, uart1_int()); break; - case 1: serial1_set(0x338, uart1_int()); break; - case 2: serial1_set(0x2e8, uart1_int()); break; - case 3: serial1_set(0x220, uart1_int()); break; + case 0: serial_setup(1, 0x3e8, uart1_int()); break; + case 1: serial_setup(1, 0x338, uart1_int()); break; + case 2: serial_setup(1, 0x2e8, uart1_int()); break; + case 3: serial_setup(1, 0x220, uart1_int()); break; } break; case 3: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial1_set(0x2e8, uart1_int()); break; - case 1: serial1_set(0x238, uart1_int()); break; - case 2: serial1_set(0x2e0, uart1_int()); break; - case 3: serial1_set(0x228, uart1_int()); break; + case 0: serial_setup(1, 0x2e8, uart1_int()); break; + case 1: serial_setup(1, 0x238, uart1_int()); break; + case 2: serial_setup(1, 0x2e0, uart1_int()); break; + case 3: serial_setup(1, 0x228, uart1_int()); break; } break; } @@ -118,24 +118,24 @@ void serial2_handler() temp = (pc87306_regs[1] >> 4) & 3; switch (temp) { - case 0: serial2_set(0x3f8, uart2_int()); break; - case 1: serial2_set(0x2f8, uart2_int()); break; + case 0: serial_setup(2, SERIAL1_ADDR, uart2_int()); break; + case 1: serial_setup(2, SERIAL2_ADDR, uart2_int()); break; case 2: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial2_set(0x3e8, uart2_int()); break; - case 1: serial2_set(0x338, uart2_int()); break; - case 2: serial2_set(0x2e8, uart2_int()); break; - case 3: serial2_set(0x220, uart2_int()); break; + case 0: serial_setup(2, 0x3e8, uart2_int()); break; + case 1: serial_setup(2, 0x338, uart2_int()); break; + case 2: serial_setup(2, 0x2e8, uart2_int()); break; + case 3: serial_setup(2, 0x220, uart2_int()); break; } break; case 3: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial2_set(0x2e8, uart2_int()); break; - case 1: serial2_set(0x238, uart2_int()); break; - case 2: serial2_set(0x2e0, uart2_int()); break; - case 3: serial2_set(0x228, uart2_int()); break; + case 0: serial_setup(2, 0x2e8, uart2_int()); break; + case 1: serial_setup(2, 0x238, uart2_int()); break; + case 2: serial_setup(2, 0x2e0, uart2_int()); break; + case 3: serial_setup(2, 0x228, uart2_int()); break; } break; } @@ -206,7 +206,7 @@ process_value: if (valxor & 2) { - serial1_remove(); + serial_remove(1); if (val & 2) { serial1_handler(); @@ -214,7 +214,7 @@ process_value: } if (valxor & 4) { - serial2_remove(); + serial_remove(2); if (val & 4) { serial2_handler(); @@ -266,7 +266,7 @@ process_value: } else { - serial1_remove(); + serial_remove(1); } } @@ -278,7 +278,7 @@ process_value: } else { - serial2_remove(); + serial_remove(2); } } break; @@ -288,8 +288,8 @@ process_value: if (val & 1) { lpt1_remove(); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); fdc_remove(); } else @@ -448,8 +448,8 @@ void pc87306_reset(void) fdc_remove(); fdc_set_base(0x3f0, 0); fdd_swap = 0; - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); serial1_handler(); serial2_handler(); pc87306_gpio_init(); diff --git a/src/libwpcapdelay.a b/src/pcap/libwpcapdelay.a similarity index 100% rename from src/libwpcapdelay.a rename to src/pcap/libwpcapdelay.a diff --git a/src/pcap_if.c b/src/pcap_if.c new file mode 100644 index 000000000..588ee01e8 --- /dev/null +++ b/src/pcap_if.c @@ -0,0 +1,223 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Simple program to show usage of WinPcap. + * + * Based on the "libpcap" examples. + * + * Version: @(#)pcap_if.c 1.0.2 2017/05/09 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include +#include + + +typedef struct { + char device[128]; + char description[128]; +} dev_t; + + +/* Retrieve an easy-to-use list of devices. */ +static int +get_devlist(dev_t *list) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *devlist, *dev; + int i = 0; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs(&devlist, errbuf) == -1) { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + return(-1); + } + + for (dev=devlist; dev!=NULL; dev=dev->next) { + strcpy(list->device, dev->name); + if (dev->description) + strcpy(list->description, dev->description); + else + memset(list->description, '\0', sizeof(list->description)); + list++; + i++; + } + + /* Release the memory. */ + pcap_freealldevs(devlist); + + return(i); +} + + +/* Simple HEXDUMP routine for raw data. */ +static void +hex_dump(unsigned char *bufp, int len) +{ + char asci[20]; + unsigned char c; + long addr; + + addr = 0; + while (len-- > 0) { + c = bufp[addr]; + if ((addr % 16) == 0) + printf("%04x %02x", addr, c); + else + printf(" %02x", c); + asci[(addr & 15)] = (uint8_t)isprint(c) ? c : '.'; + if ((++addr % 16) == 0) { + asci[16] = '\0'; + printf(" | %s |\n", asci); + } + } + + if (addr % 16) { + while (addr % 16) { + printf(" "); + asci[(addr & 15)] = ' '; + addr++; + } + asci[16] = '\0'; + printf(" | %s |\n", asci); + } +} + + +/* Print a standard Ethernet MAC address. */ +static void +eth_praddr(unsigned char *ptr) +{ + printf("%02x:%02x:%02x:%02x:%02x:%02x", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); +} + + +/* Print a standard Ethernet header. */ +static int +eth_prhdr(unsigned char *ptr) +{ + unsigned short type; + + printf("Ethernet "); + eth_praddr(ptr+6); + printf(" > "); + eth_praddr(ptr); + type = (ptr[12] << 8) | ptr[13]; + printf(" type %04x\n", type); + + return(14); +} + + +/* Capture packets from the network, and print them. */ +static int +start_cap(char *dev) +{ + char temp[PCAP_ERRBUF_SIZE]; + struct pcap_pkthdr *hdr; + const unsigned char *pkt; + struct tm *ltime; + time_t now; + pcap_t *pcap; + int rc; + + /* Open the device for reading from it. */ + pcap = pcap_open_live(dev, + 1518, /* MTU */ + 1, /* promisc mode */ + 10, /* timeout */ + temp); + if (pcap == NULL) { + fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); + return(2); + } + + printf("Listening on '%s'..\n", dev); + for (;;) { + rc = pcap_next_ex(pcap, &hdr, &pkt); + if (rc < 0) break; + + /* Did we time out? */ + if (rc == 0) continue; + + /* Convert the timestamp to readable format. */ + now = hdr->ts.tv_sec; + ltime = localtime(&now); + strftime(temp, sizeof(temp), "%H:%M:%S", ltime); + + /* Process and print the packet. */ + printf("\n<< %s,%.6d len=%d\n", + temp, hdr->ts.tv_usec, hdr->len); + rc = eth_prhdr((unsigned char *)pkt); + hex_dump((unsigned char *)pkt+rc, hdr->len-rc); + } + + /* All done, close up. */ + pcap_close(pcap); + + return(0); +} + + +/* Show a list of available network interfaces. */ +static void +show_devs(dev_t *list, int num) +{ + int i; + + if (num > 0) { + printf("Available network interfaces:\n\n"); + + for (i=0; idevice); + if (list->description[0] != '\0') + printf(" (%s)\n", list->description); + else + printf(" (No description available)\n"); + list++; + printf("\n"); + } + } else { + printf("No interfaces found!\nMake sure WinPcap is installed.\n"); + } +} + + +int +main(int argc, char **argv) +{ + dev_t interfaces[32]; + dev_t *dev = interfaces; + int numdev, i; + + /* Get the list. */ + numdev = get_devlist(interfaces); + + if (argc == 1) { + /* No arguments, just show the list. */ + show_devs(interfaces, numdev); + + return(numdev); + } + + /* Assume argument to be the interface number to listen on. */ + i = atoi(argv[1]); + if (i < 0 || i > numdev) { + fprintf(stderr, "Invalid interface number %d !\n", i); + + return(1); + } + + /* Looks good, go and listen.. */ + i = start_cap(interfaces[i-1].device); + + return(i); +} diff --git a/src/pcap_if.rc b/src/pcap_if.rc new file mode 100644 index 000000000..57d78e657 --- /dev/null +++ b/src/pcap_if.rc @@ -0,0 +1,52 @@ +#ifdef _WIN32 +#include +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,2,0 + PRODUCTVERSION 1,0,2,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "IRC #SoftHistory\0" + VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" + VALUE "FileVersion", "1.0.2\0" + VALUE "InternalName", "pcap_if\0" + VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "pcap_if.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "WinPcap Test Tool\0" + VALUE "ProductVersion", "1.0.2\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/piix.c b/src/piix.c index 2cb81a739..04cf62418 100644 --- a/src/piix.c +++ b/src/piix.c @@ -674,5 +674,5 @@ void piix3_init(int card) dma_alias_set(); - pci_reset_handler.pci_set_reset = piix_reset; + pci_reset_handler.pci_set_reset = piix3_reset; } diff --git a/src/pit.c b/src/pit.c index e9e4cb090..b735656a5 100644 --- a/src/pit.c +++ b/src/pit.c @@ -5,17 +5,18 @@ #include #include "ibm.h" - -#include "cpu.h" -#include "device.h" +#include "cpu/cpu.h" #include "dma.h" #include "io.h" #include "pic.h" #include "pit.h" -#include "sound_speaker.h" +#include "device.h" #include "timer.h" -#include "video.h" #include "model.h" +#include "sound/snd_speaker.h" +#include "video/video.h" + + /*B0 to 40, two writes to 43, then two reads - value does not change!*/ /*B4 to 40, two writes to 43, then two reads - value _does_ change!*/ int displine; diff --git a/src/plat-dir.h b/src/plat-dir.h new file mode 100644 index 000000000..f9fbf2a9d --- /dev/null +++ b/src/plat-dir.h @@ -0,0 +1,76 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the platform OpenDir module. + * + * Version: @(#)plat-dir.h 1.0.1 2017/05/12 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_DIR_H +# define PLAT_DIR_H + + +#ifdef _MAX_FNAME +# define MAXNAMLEN _MAX_FNAME +#else +# define MAXNAMLEN 15 +#endif +# define MAXDIRLEN 127 + + +struct direct { + long d_ino; + unsigned short d_reclen; + unsigned short d_off; +#ifdef UNICODE + wchar_t d_name[MAXNAMLEN + 1]; +#else + char d_name[MAXNAMLEN + 1]; +#endif +}; +#define d_namlen d_reclen + + +typedef struct { + short flags; /* internal flags */ + short offset; /* offset of entry into dir */ + long handle; /* open handle to Win32 system */ + short sts; /* last known status code */ + char *dta; /* internal work data */ +#ifdef UNICODE + wchar_t dir[MAXDIRLEN+1]; /* open dir */ +#else + char dir[MAXDIRLEN+1]; /* open dir */ +#endif + struct direct dent; /* actual directory entry */ +} DIR; + + +/* Directory routine flags. */ +#define DIR_F_LOWER 0x0001 /* force to lowercase */ +#define DIR_F_SANE 0x0002 /* force this to sane path */ +#define DIR_F_ISROOT 0x0010 /* this is the root directory */ + + +/* Function prototypes. */ +#ifdef UNICODE +extern DIR *opendirw(const wchar_t *); +#else +extern DIR *opendir(const char *); +#endif +extern struct direct *readdir(DIR *); +extern long telldir(DIR *); +extern void seekdir(DIR *, long); +extern int closedir(DIR *); + +#define rewinddir(dirp) seekdir(dirp, 0L) + + +#endif /*PLAT_DIR_H*/ diff --git a/src/serial_bh.h b/src/plat-serial.h similarity index 85% rename from src/serial_bh.h rename to src/plat-serial.h index a3f42a1ba..e11737a89 100644 --- a/src/serial_bh.h +++ b/src/plat-serial.h @@ -8,17 +8,13 @@ * * Definitions for the Bottom Half of the SERIAL card. * - * Version: @(#)serial_bh.h 1.0.1 2017/04/14 + * Version: @(#)plat-serial.h 1.0.3 2017/05/06 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ -#ifndef SERIAL_BH_H -# define SERIAL_BH_H - - -#define BHTTY_PORT1 "COM2" /* port 1 connects to .. */ -#define BHTTY_PORT2 "COM4" /* port 2 connects to .. */ +#ifndef PLAT_SERIAL_H +# define PLAT_SERIAL_H typedef struct { @@ -50,4 +46,4 @@ extern int bhtty_write(BHTTY *, unsigned char); extern int bhtty_read(BHTTY *, unsigned char *, int); -#endif /*SERIAL_BH_H*/ +#endif /*PLAT_SERIAL_H*/ diff --git a/src/ps1.c b/src/ps1.c index a9f068bfd..d54df75af 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -74,9 +74,9 @@ void ps1_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -134,7 +134,7 @@ void ps1mb_init() if (!enable_xtide) { rom_init(&ps1_high_rom, - "roms/ibmps1es/f80000_shell.bin", + L"roms/ibmps1es/f80000_shell.bin", 0xf80000, 0x80000, 0x7ffff, @@ -142,8 +142,8 @@ void ps1mb_init() MEM_MAPPING_EXTERNAL); } /* rom_init_interleaved(&ps1_high_rom, - "roms/ibmps1es/ibm_1057757_24-05-90.bin", - "roms/ibmps1es/ibm_1057757_29-15-90.bin", + L"roms/ibmps1es/ibm_1057757_24-05-90.bin", + L"roms/ibmps1es/ibm_1057757_29-15-90.bin", 0xfc0000, 0x40000, 0x3ffff, @@ -155,8 +155,8 @@ void ps1mb_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); memset(&ps1_hd, 0, sizeof(ps1_hd)); } @@ -242,9 +242,9 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -287,7 +287,7 @@ void ps1mb_m2121_init() io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); rom_init(&ps1_high_rom, - "roms/ibmps1_2121/fc0000_shell.bin", + L"roms/ibmps1_2121/fc0000_shell.bin", 0xfc0000, 0x40000, 0x3ffff, @@ -299,8 +299,8 @@ void ps1mb_m2121_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); mem_remap_top_384k(); } diff --git a/src/ps2.c b/src/ps2.c index 1b5c4dc06..0f1e1a964 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -68,9 +68,9 @@ void ps2_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -131,8 +131,8 @@ void ps2board_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); memset(&ps2_hd, 0, sizeof(ps2_hd)); } diff --git a/src/ps2_mca.c b/src/ps2_mca.c index fd3201ac3..5af537b6e 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -1,15 +1,16 @@ #include "ibm.h" -#include "cpu.h" -#include "device.h" +#include "cpu/cpu.h" +#include "cpu/x86.h" #include "io.h" -#include "lpt.h" #include "mca.h" #include "mem.h" +#include "rom.h" +#include "device.h" +#include "lpt.h" #include "ps2_mca.h" #include "ps2_nvr.h" -#include "rom.h" #include "serial.h" -#include "x86.h" + static struct { @@ -191,16 +192,16 @@ static void model_50_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -247,16 +248,16 @@ static void model_55sx_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -323,16 +324,16 @@ static void model_80_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -555,8 +556,8 @@ static void ps2_mca_board_common_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); } void ps2_mca_board_model_50_init() diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c index 917b0e786..33661c813 100644 --- a/src/ps2_nvr.c +++ b/src/ps2_nvr.c @@ -2,6 +2,8 @@ #include "ibm.h" #include "device.h" #include "io.h" +#include "mem.h" +#include "rom.h" #include "ps2_nvr.h" typedef struct ps2_nvr_t @@ -56,7 +58,7 @@ static void *ps2_nvr_init() switch (romset) { - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"rb"); break; } if (f) { @@ -76,7 +78,7 @@ static void ps2_nvr_close(void *p) switch (romset) { - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"wb"); break; } if (f) { diff --git a/src/resource.h b/src/resource.h index 9bfe518b4..bc0d8da03 100644 --- a/src/resource.h +++ b/src/resource.h @@ -1,10 +1,9 @@ /* Copyright holders: Tenshi see COPYING for more details */ - /* {{NO_DEPENDENCIES}} Microsoft Developer Studio generated include file. - Used by pc_new2.rc + Used by 86Box.rc */ #define IDHDCONFIG 3 #define IDCDCONFIG 4 @@ -159,22 +158,22 @@ #define IDM_VID_INVERT 40079 #define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_ISO 40144 +#define IDM_CDROM_1_IMAGE 40144 #define IDM_CDROM_1_RELOAD 40160 #define IDM_CDROM_1_EMPTY 40176 #define IDM_CDROM_1_REAL 40192 #define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_ISO 40145 +#define IDM_CDROM_2_IMAGE 40145 #define IDM_CDROM_2_RELOAD 40161 #define IDM_CDROM_2_EMPTY 40177 #define IDM_CDROM_2_REAL 40193 #define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_ISO 40146 +#define IDM_CDROM_3_IMAGE 40146 #define IDM_CDROM_3_RELOAD 40162 #define IDM_CDROM_3_EMPTY 40178 #define IDM_CDROM_3_REAL 40194 #define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_ISO 40147 +#define IDM_CDROM_4_IMAGE 40147 #define IDM_CDROM_4_RELOAD 40163 #define IDM_CDROM_4_EMPTY 40179 #define IDM_CDROM_4_REAL 40195 @@ -195,27 +194,30 @@ #define IDM_IDE_QUA_IRQ15 44035 #ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG -#define IDM_LOG_BUSLOGIC 51200 -#endif -#ifdef ENABLE_CDROM_LOG -#define IDM_LOG_CDROM 51201 -#endif -#ifdef ENABLE_D86F_LOG -#define IDM_LOG_D86F 51202 -#endif -#ifdef ENABLE_FDC_LOG -#define IDM_LOG_FDC 51203 -#endif -#ifdef ENABLE_IDE_LOG -#define IDM_LOG_IDE 51204 -#endif -#ifdef ENABLE_NE2000_LOG -#define IDM_LOG_NE2000 51205 -#endif +# ifdef ENABLE_BUSLOGIC_LOG +# define IDM_LOG_BUSLOGIC 51200 +# endif +# ifdef ENABLE_CDROM_LOG +# define IDM_LOG_CDROM 51201 +# endif +# ifdef ENABLE_D86F_LOG +# define IDM_LOG_D86F 51202 +# endif +# ifdef ENABLE_FDC_LOG +# define IDM_LOG_FDC 51203 +# endif +# ifdef ENABLE_IDE_LOG +# define IDM_LOG_IDE 51204 +# endif +# ifdef ENABLE_NE2000_LOG +# define IDM_LOG_NE2000 51205 +# endif #endif #ifdef ENABLE_LOG_BREAKPOINT -#define IDM_LOG_BREAKPOINT 51206 +# define IDM_LOG_BREAKPOINT 51206 +#endif +#ifdef ENABLE_VRAM_DUMP +# define IDM_DUMP_VRAM 51207 #endif #define IDC_COMBO1 1000 @@ -413,13 +415,12 @@ #define IDC_STATIC 1792 /* Next default values for new objects */ - #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1055 -#define _APS_NEXT_SYMED_VALUE 101 -#endif +# ifndef APSTUDIO_READONLY_SYMBOLS +# define _APS_NO_MFC 1 +# define _APS_NEXT_RESOURCE_VALUE 110 +# define _APS_NEXT_COMMAND_VALUE 40002 +# define _APS_NEXT_CONTROL_VALUE 1055 +# define _APS_NEXT_SYMED_VALUE 101 +# endif #endif diff --git a/src/rom.c b/src/rom.c index 60475aac8..82299602d 100644 --- a/src/rom.c +++ b/src/rom.c @@ -9,25 +9,31 @@ #include "rom.h" -FILE *romfopen(char *fn, char *mode) +FILE *romfopen(wchar_t *fn, wchar_t *mode) { - char s[512]; - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - return fopen(s, mode); + wchar_t s[512]; + wcscpy(s, pcempath); + put_backslash_w(s); + wcscat(s, fn); + return _wfopen(s, mode); } -int rom_present(char *fn) +FILE *nvrfopen(wchar_t *fn, wchar_t *mode) +{ + return _wfopen(nvr_concat(fn), mode); +} + + +int rom_present(wchar_t *fn) { FILE *f; - char s[512]; + wchar_t s[512]; - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - f = fopen(s, "rb"); + wcscpy(s, pcempath); + put_backslash_w(s); + wcscat(s, fn); + f = _wfopen(s, L"rb"); if (f) { fclose(f); @@ -70,13 +76,13 @@ uint32_t rom_readl(uint32_t addr, void *p) } -int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f = romfopen(fn, "rb"); + FILE *f = romfopen(fn, L"rb"); if (!f) { - pclog("ROM image not found : %s\n", fn); + pclog("ROM image not found : %ws\n", fn); return -1; } @@ -101,20 +107,20 @@ int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int fil } -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, wchar_t *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f_low = romfopen(fn_low, "rb"); - FILE *f_high = romfopen(fn_high, "rb"); + FILE *f_low = romfopen(fn_low, L"rb"); + FILE *f_high = romfopen(fn_high, L"rb"); int c; if (!f_low || !f_high) { if (!f_low) - pclog("ROM image not found : %s\n", fn_low); + pclog("ROM image not found : %ws\n", fn_low); else fclose(f_low); if (!f_high) - pclog("ROM image not found : %s\n", fn_high); + pclog("ROM image not found : %ws\n", fn_high); else fclose(f_high); return -1; diff --git a/src/rom.h b/src/rom.h index d548ee8be..c4cea8f7c 100644 --- a/src/rom.h +++ b/src/rom.h @@ -1,8 +1,9 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -FILE *romfopen(char *fn, char *mode); -int rom_present(char *fn); +FILE *romfopen(wchar_t *fn, wchar_t *mode); +FILE *nvrfopen(wchar_t *fn, wchar_t *mode); +int rom_present(wchar_t *fn); typedef struct rom_t { @@ -11,5 +12,5 @@ typedef struct rom_t mem_mapping_t mapping; } rom_t; -int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, wchar_t *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); diff --git a/src/scsi.c b/src/scsi.c index 3dbefdf37..733e2a0a7 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -6,10 +6,11 @@ #include #include "86box.h" #include "ibm.h" +#include "timer.h" #include "device.h" #include "cdrom.h" #include "scsi.h" -#include "timer.h" +#include "scsi_aha154x.h" #include "scsi_buslogic.h" @@ -106,7 +107,7 @@ void SCSIReset(uint8_t id, uint8_t lun) if (hdc_id != 0xff) { scsi_hd_reset(cdrom_id); - SCSIDevices[id][lun].LunType = SCSI_HDD; + SCSIDevices[id][lun].LunType = SCSI_DISK; } else { if (cdrom_id != 0xff) { diff --git a/src/scsi.h b/src/scsi.h index ba0334f57..2c9280c29 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -1,17 +1,18 @@ /* Copyright holders: SA1988 see COPYING for more details */ -#ifndef __SCSI_H__ -#define __SCSI_H__ +#ifndef SCSI_H +#define SCSI_H -#include "timer.h" #define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) -/* SCSI Commands */ + +/* SCSI commands. */ #define GPCMD_TEST_UNIT_READY 0x00 #define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_FORMAT_UNIT 0x04 #define GPCMD_READ_6 0x08 #define GPCMD_WRITE_6 0x0a #define GPCMD_SEEK_6 0x0b @@ -207,7 +208,7 @@ extern int cd_status; extern int prev_status; #define SCSI_NONE 0 -#define SCSI_HDD 1 +#define SCSI_DISK 1 #define SCSI_CDROM 2 #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) @@ -265,4 +266,40 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l void scsi_hd_command(uint8_t id, uint8_t *cdb); void scsi_hd_callback(uint8_t id); -#endif \ No newline at end of file + +#pragma pack(push,1) +typedef struct { + uint8_t hi; + uint8_t mid; + uint8_t lo; +} addr24; +#pragma pack(pop) + +#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) +#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) + + +/* + * + * Scatter/Gather Segment List Definitions + * + * Adapter limits + */ +#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ + +#pragma pack(push,1) +typedef struct { + uint32_t Segment; + uint32_t SegmentPointer; +} SGE32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + addr24 Segment; + addr24 SegmentPointer; +} SGE; +#pragma pack(pop) + + +#endif diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index fd89a1cc5..615bd8675 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -6,24 +6,34 @@ * * This file is part of the 86Box distribution. * - * Implementation of several low-level support functions for - * the AHA-154x series of ISA Host Adapters made by Adaptec. - * These functions implement the support needed by the ROM BIOS - * of these cards. + * Implementation of the AHA-154x series of SCSI Host Adapters + * made by Adaptec, Inc. These controllers were designed for + * the ISA bus. * - * Version: @(#)aha154x.c 1.0.4 2017/04/21 + * NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go. * - * Author: Fred N. van Kempen, + * Version: @(#)scsi_aha154x.c 1.0.6 2017/05/06 + * + * Authors: Fred N. van Kempen, + * Original Buslogic version by SA1988. * Copyright 2017 Fred N. van Kempen. */ +#include #include #include #include +#include #include "ibm.h" +#include "io.h" #include "mem.h" #include "rom.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" #include "device.h" -#include "scsi_buslogic.h" +#include "cdrom.h" +#include "scsi.h" +#include "scsi_aha154x.h" #define AHA AHA154xCF /* set desired card type */ @@ -34,41 +44,41 @@ #if AHA == AHA154xB -# define ROMFILE "roms/adaptec/aha1540b310.bin" +# define ROMFILE L"roms/adaptec/aha1540b310.bin" # define AHA_BID 'A' /* AHA-154x B */ #endif #if AHA == AHA154xC -# define ROMFILE "roms/adaptec/aha1542c101.bin" -# define AHA_BID 'D' /* AHA-154x C */ -# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define ROMFILE L"roms/adaptec/aha1542c101.bin" +# define AHA_BID 'D' /* AHA-154x C */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif #if AHA == AHA154xCF -# define ROMFILE "roms/adaptec/aha1542cf201.bin" -# define AHA_BID 'E' /* AHA-154x CF */ -# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define ROMFILE L"roms/adaptec/aha1542cf201.bin" +# define AHA_BID 'E' /* AHA-154x CF */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif #if AHA == AHA154xCP -# define ROMFILE "roms/adaptec/aha1542cp102.bin" -# define AHA_BID 'F' /* AHA-154x CP */ -# define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define ROMFILE L"roms/adaptec/aha1542cp102.bin" +# define AHA_BID 'F' /* AHA-154x CP */ +# define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif -#define ROM_SIZE 16384 /* one ROM is 16K */ +#define ROM_SIZE 16384 /* one ROM is 16K */ /* EEPROM map and bit definitions. */ @@ -100,6 +110,61 @@ #define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ +/* + * Host Adapter I/O ports. + * + * READ Port x+0: STATUS + * WRITE Port x+0: CONTROL + * + * READ Port x+1: DATA + * WRITE Port x+1: COMMAND + * + * READ Port x+2: INTERRUPT STATUS + * WRITE Port x+2: (undefined?) + * + * R/W Port x+3: (undefined) + */ + +/* WRITE CONTROL commands. */ +#define CTRL_HRST 0x80 /* Hard reset */ +#define CTRL_SRST 0x40 /* Soft reset */ +#define CTRL_IRST 0x20 /* interrupt reset */ +#define CTRL_SCRST 0x10 /* SCSI bus reset */ + +/* READ STATUS. */ +#define STAT_STST 0x80 /* self-test in progress */ +#define STAT_DFAIL 0x40 /* internal diagnostic failure */ +#define STAT_INIT 0x20 /* mailbox initialization required */ +#define STAT_IDLE 0x10 /* HBA is idle */ +#define STAT_CDFULL 0x08 /* Command/Data output port is full */ +#define STAT_DFULL 0x04 /* Data input port is full */ +#define STAT_INVCMD 0x01 /* Invalid command */ + +/* READ/WRITE DATA. */ +#define CMD_NOP 0x00 /* No operation */ +#define CMD_MBINIT 0x01 /* mailbox initialization */ +#define CMD_START_SCSI 0x02 /* Start SCSI command */ +#define CMD_BIOS 0x03 /* Execute ROM BIOS command */ +#define CMD_INQUIRY 0x04 /* Adapter inquiry */ +#define CMD_EMBOI 0x05 /* enable Mailbox Out Interrupt */ +#define CMD_SELTIMEOUT 0x06 /* Set SEL timeout */ +#define CMD_BUSON_TIME 0x07 /* set bus-On time */ +#define CMD_BUSOFF_TIME 0x08 /* set bus-off time */ +#define CMD_DMASPEED 0x09 /* set ISA DMA speed */ +#define CMD_RETDEVS 0x0A /* return installed devices */ +#define CMD_RETCONF 0x0B /* return configuration data */ +#define CMD_TARGET 0x0C /* set HBA to target mode */ +#define CMD_RETSETUP 0x0D /* return setup data */ +#define CMD_ECHO 0x1F /* ECHO command data */ + +/* READ INTERRUPT STATUS. */ +#define INTR_ANY 0x80 /* any interrupt */ +#define INTR_SRCD 0x08 /* SCSI reset detected */ +#define INTR_HACC 0x04 /* HA command complete */ +#define INTR_MBOA 0x02 /* MBO empty */ +#define INTR_MBIF 0x01 /* MBI full */ + + static rom_t aha_bios; /* active ROM */ static uint8_t *aha_rom1; /* main BIOS */ static uint8_t *aha_rom2; /* SCSI-Select */ @@ -192,23 +257,23 @@ aha_patch(uint8_t *romptr, uint16_t ioaddr) /* Initialize AHA-154xNN-specific stuff. */ -void -aha154x_init(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) +static void +aha154x_bios(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) { uint32_t bios_size; uint32_t bios_addr; uint32_t bios_mask; - char *bios_path; + wchar_t *bios_path; uint32_t temp; FILE *f; /* Set BIOS load address. */ bios_addr = memaddr; bios_path = ROMFILE; - pclog("AHA154x: loading BIOS from '%s'\n", bios_path); + pclog_w(L"AHA154x: loading BIOS from '%s'\n", bios_path); /* Open the BIOS image file and make sure it exists. */ - if ((f = fopen(bios_path, "rb")) == NULL) { + if ((f = romfopen(bios_path, L"rb")) == NULL) { pclog("AHA154x: BIOS ROM not found!\n"); return; } @@ -335,7 +400,7 @@ again: /* Mess with the AHA-154xCF's Shadow RAM. */ -uint8_t +static uint8_t aha154x_shram(uint8_t cmd) { #ifdef ROM_SHRAM @@ -359,7 +424,7 @@ aha154x_shram(uint8_t cmd) } -uint8_t +static uint8_t aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) { uint8_t r = 0xff; @@ -387,7 +452,7 @@ aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) } -uint8_t +static uint8_t aha154x_memory(uint8_t cmd) { uint8_t r = 0xff; @@ -405,3 +470,1916 @@ aha154x_memory(uint8_t cmd) return(0); } + + +#define AHA_RESET_DURATION_NS UINT64_C(50000000) + + +/* + * Auto SCSI structure which is located in host adapter RAM + * and contains several configuration parameters. + */ +#pragma pack(push,1) +typedef struct { + uint8_t aInternalSignature[2]; + uint8_t cbInformation; + uint8_t aHostAdaptertype[6]; + uint8_t uReserved1; + uint8_t fFloppyEnabled :1, + fFloppySecondary :1, + fLevelSensitiveInterrupt:1, + uReserved2 :2, + uSystemRAMAreForBIOS :3; + uint8_t uDMAChannel :7, + fDMAAutoConfiguration :1, + uIrqChannel :7, + fIrqAutoConfiguration :1; + uint8_t uDMATransferRate; + uint8_t uSCSIId; + uint8_t fLowByteTerminated :1, + fParityCheckingEnabled :1, + fHighByteTerminated :1, + fNoisyCablingEnvironment:1, + fFastSyncNegotiation :1, + fBusResetEnabled :1, + fReserved3 :1, + fActiveNegotiationEna :1; + uint8_t uBusOnDelay; + uint8_t uBusOffDelay; + uint8_t fHostAdapterBIOSEnabled :1, + fBIOSRedirectionOfInt19 :1, + fExtendedTranslation :1, + fMapRemovableAsFixed :1, + fReserved4 :1, + fBIOSMoreThan2Drives :1, + fBIOSInterruptMode :1, + fFlopticalSupport :1; + uint16_t u16DeviceEnabledMask; + uint16_t u16WidePermittedMask; + uint16_t u16FastPermittedMask; + uint16_t u16SynchronousPermittedMask; + uint16_t u16DisconnectPermittedMask; + uint16_t u16SendStartUnitCommandMask; + uint16_t u16IgnoreInBIOSScanMask; + unsigned char uPCIInterruptPin : 2; + unsigned char uHostAdapterIoPortAddress : 2; + uint8_t fStrictRoundRobinMode : 1; + uint8_t fVesaBusSpeedGreaterThan33MHz : 1; + uint8_t fVesaBurstWrite : 1; + uint8_t fVesaBurstRead : 1; + uint16_t u16UltraPermittedMask; + uint32_t uReserved5; + uint8_t uReserved6; + uint8_t uAutoSCSIMaximumLUN; + uint8_t fReserved7 : 1; + uint8_t fSCAMDominant : 1; + uint8_t fSCAMenabled : 1; + uint8_t fSCAMLevel2 : 1; + unsigned char uReserved8 : 4; + uint8_t fInt13Extension : 1; + uint8_t fReserved9 : 1; + uint8_t fCDROMBoot : 1; + unsigned char uReserved10 : 5; + unsigned char uBootTargetId : 4; + unsigned char uBootChannel : 4; + uint8_t fForceBusDeviceScanningOrder : 1; + unsigned char uReserved11 : 7; + uint16_t u16NonTaggedToAlternateLunPermittedMask; + uint16_t u16RenegotiateSyncAfterCheckConditionMask; + uint8_t aReserved12[10]; + uint8_t aManufacturingDiagnostic[2]; + uint16_t u16Checksum; +} AutoSCSIRam; +#pragma pack(pop) + +/* The local RAM. */ +#pragma pack(push,1) +typedef union { + uint8_t u8View[256]; /* byte view */ + struct { /* structured view */ + uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ + AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ + } structured; +} HALocalRAM; +#pragma pack(pop) + +/* Structure for the INQUIRE_SETUP_INFORMATION reply. */ +#pragma pack(push,1) +typedef struct { + uint8_t uOffset :4, + uTransferPeriod :3, + fSynchronous :1; +} ReplyInquireSetupInformationSynchronousValue; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t fSynchronousInitiationEnabled :1, + fParityCheckingEnabled :1, + uReserved1 :6; + uint8_t uBusTransferRate; + uint8_t uPreemptTimeOnBus; + uint8_t uTimeOffBus; + uint8_t cMailbox; + addr24 MailboxAddress; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; + uint8_t uDisconnectPermittedId0To7; + uint8_t uSignature; + uint8_t uCharacterD; + uint8_t uHostBusType; + uint8_t uWideTransferPermittedId0To7; + uint8_t uWideTransfersActiveId0To7; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; + uint8_t uDisconnectPermittedId8To15; + uint8_t uReserved2; + uint8_t uWideTransferPermittedId8To15; + uint8_t uWideTransfersActiveId8To15; +} ReplyInquireSetupInformation; +#pragma pack(pop) + +/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ +#pragma pack(push,1) +typedef struct { + uint8_t uBusType; + uint8_t uBiosAddress; + uint16_t u16ScatterGatherLimit; + uint8_t cMailbox; + uint32_t uMailboxAddressBase; + uint8_t uReserved1 :2, + fFastEISA :1, + uReserved2 :3, + fLevelSensitiveInterrupt:1, + uReserved3 :1; + uint8_t aFirmwareRevision[3]; + uint8_t fHostWideSCSI :1, + fHostDifferentialSCSI :1, + fHostSupportsSCAM :1, + fHostUltraSCSI :1, + fHostSmartTermination :1, + uReserved4 :3; +} ReplyInquireExtendedSetupInformation; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct { + uint8_t Count; + addr24 Address; +} MailboxInit_t; +#pragma pack(pop) + + +/* + * Mailbox Definitions. + * + * Mailbox Out (MBO) command values. + */ +#define MBO_FREE 0x00 +#define MBO_START 0x01 +#define MBO_ABORT 0x02 + +/* Mailbox In (MBI) status values. */ +#define MBI_FREE 0x00 +#define MBI_SUCCESS 0x01 +#define MBI_ABORT 0x02 +#define MBI_NOT_FOUND 0x03 +#define MBI_ERROR 0x04 + + +#pragma pack(push,1) +typedef struct { + uint8_t CmdStatus; + addr24 CCBPointer; +} Mailbox_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint32_t CCBPointer; + union { + struct { + uint8_t Reserved[3]; + uint8_t ActionCode; + } out; + struct { + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved; + uint8_t CompletionCode; + } in; + } u; +} Mailbox32_t; +#pragma pack(pop) + + +/* + * + * CCB - SCSI Command Control Block + * + * The CCB is a superset of the CDB (Command Descriptor Block) + * and specifies detailed information about a SCSI command. + * + */ +/* Byte 0 Command Control Block Operation Code */ +#define SCSI_INITIATOR_COMMAND 0x00 +#define TARGET_MODE_COMMAND 0x01 +#define SCATTER_GATHER_COMMAND 0x02 +#define SCSI_INITIATOR_COMMAND_RES 0x03 +#define SCATTER_GATHER_COMMAND_RES 0x04 +#define BUS_RESET 0x81 + +/* Byte 1 Address and Direction Control */ +#define CCB_TARGET_ID_SHIFT 0x06 /* CCB Op Code = 00, 02 */ +#define CCB_INITIATOR_ID_SHIFT 0x06 /* CCB Op Code = 01 */ +#define CCB_DATA_XFER_IN 0x01 +#define CCB_DATA_XFER_OUT 0x02 +#define CCB_LUN_MASK 0x07 /* Logical Unit Number */ + +/* Byte 2 SCSI_Command_Length - Length of SCSI CDB + Byte 3 Request Sense Allocation Length */ +#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ +#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ + +/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ +/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ +/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ +/* Byte 13 Command Link ID - TBD (I don't know yet) */ +/* Byte 14 Host Status - Host Adapter status */ +#define CCB_COMPLETE 0x00 /* CCB completed without error */ +#define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */ +#define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */ +#define CCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ +#define CCB_DATA_OVER_UNDER_RUN 0x12 +#define CCB_UNEXPECTED_BUS_FREE 0x13 /* Trg dropped SCSI BSY */ +#define CCB_PHASE_SEQUENCE_FAIL 0x14 /* Trg bus phase sequence fail */ +#define CCB_BAD_MBO_COMMAND 0x15 /* MBO command not 0, 1 or 2 */ +#define CCB_INVALID_OP_CODE 0x16 /* CCB invalid operation code */ +#define CCB_BAD_LINKED_LUN 0x17 /* Linked CCB LUN diff from 1st */ +#define CCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ +#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */ +#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */ + +/* Byte 15 Target Status + + See scsi.h files for these statuses. + Bytes 16 and 17 Reserved (must be 0) + Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Reserved1 :3, + ControlByte :2, + TagQueued :1, + QueueTag :2; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint32_t DataLength; + uint32_t DataPointer; + uint8_t Reserved2[2]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Id; + uint8_t Lun :5, + LegacyTagEnable :1, + LegacyQueueTag :2; + uint8_t Cdb[12]; + uint8_t Reserved3[6]; + uint32_t SensePointer; +} CCB32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Lun :3, + ControlByte :2, + Id :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + addr24 DataLength; + addr24 DataPointer; + addr24 LinkPointer; + uint8_t LinkId; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved[2]; + uint8_t Cdb[12]; +} CCB; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Pad1 :3, + ControlByte :2, + Pad2 :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint8_t Pad3[10]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Pad4[2]; + uint8_t Cdb[12]; +} CCBC; +#pragma pack(pop) + +#pragma pack(push,1) +typedef union { + CCB32 new; + CCB old; + CCBC common; +} CCBU; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + CCBU CmdBlock; + uint8_t *RequestSenseBuffer; + uint32_t CCBPointer; + int Is24bit; + uint8_t TargetID; + uint8_t LUN; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t MailboxCompletionCode; +} Req_t; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct { + rom_t bios; + int UseLocalRAM; + int StrictRoundRobinMode; + int ExtendedLUNCCBFormat; + HALocalRAM LocalRAM; + Req_t Req; + uint8_t Status; + uint8_t Interrupt; + uint8_t Geometry; + uint8_t Control; + uint8_t Command; + uint8_t CmdBuf[53]; + uint8_t CmdParam; + uint8_t CmdParamLeft; + uint8_t DataBuf[64]; + uint16_t DataReply; + uint16_t DataReplyLeft; + uint32_t MailboxCount; + uint32_t MailboxOutAddr; + uint32_t MailboxOutPosCur; + uint32_t MailboxInAddr; + uint32_t MailboxInPosCur; + int Base; + int Irq; + int DmaChannel; + int IrqEnabled; + int Mbx24bit; + int MailboxOutInterrupts; + int MbiActive[256]; + int PendingInterrupt; + int Lock; + mem_mapping_t mmio_mapping; + aha_info aha; + int chip; +} aha_t; +#pragma pack(pop) + + +static int ResetCB = 0; +static int AHA_Callback = 0; +static int AHA_InOperation = 0; +static aha_t *ResetDev; + + +enum { + CHIP_AHA154XB, + CHIP_AHA154XCF +}; + + +#ifdef xWALTJE +int aha_do_log = 1; +# define ENABLE_AHA154X_LOG +#else +int aha_do_log = 0; +#endif + + +static void +aha_log(const char *format, ...) +{ +#ifdef ENABLE_AHA154X_LOG + va_list ap; + + if (aha_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog aha_log + + +static void +ClearIntr(aha_t *dev) +{ + dev->Interrupt = 0; + pclog("AHA154X: lowering IRQ %i (stat 0x%02x)\n", + dev->Irq, dev->Interrupt); + picintc(1 << dev->Irq); + if (dev->PendingInterrupt) { + dev->Interrupt = dev->PendingInterrupt; + pclog("AHA154X: Raising Interrupt 0x%02X (Pending)\n", dev->Interrupt); + if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { + if (dev->IrqEnabled) picint(1 << dev->Irq); + } + dev->PendingInterrupt = 0; + } +} + + +static void +RaiseIntr(aha_t *dev, uint8_t Interrupt) +{ + if (dev->Interrupt & INTR_HACC) { + pclog("Pending IRQ\n"); + dev->PendingInterrupt = Interrupt; + } else { + dev->Interrupt = Interrupt; + pclog("Raising IRQ %i\n", dev->Irq); + if (dev->IrqEnabled) + picint(1 << dev->Irq); + } +} + + +static void +LocalRAM(aha_t *dev) +{ + /* + * These values are mostly from what I think is right + * looking at the dmesg output from a Linux guest inside + * a VMware server VM. + * + * So they don't have to be right :) + */ + memset(dev->LocalRAM.u8View, 0, sizeof(HALocalRAM)); + dev->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; + dev->LocalRAM.structured.autoSCSIData.fParityCheckingEnabled = 1; + dev->LocalRAM.structured.autoSCSIData.fExtendedTranslation = 1; /* Same as in geometry register. */ + dev->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = UINT16_MAX; /* All enabled. Maybe mask out non present devices? */ + dev->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16SynchronousPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.fStrictRoundRobinMode = dev->StrictRoundRobinMode; + dev->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = UINT16_MAX; + /** @todo calculate checksum? */ +} + + +static void +aha_reset(aha_t *dev) +{ + AHA_Callback = 0; + ResetCB = 0; + dev->Status = STAT_IDLE | STAT_INIT; + dev->Geometry = 0x80; + dev->Command = 0xFF; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; + dev->IrqEnabled = 1; + dev->StrictRoundRobinMode = 0; + dev->ExtendedLUNCCBFormat = 0; + dev->MailboxOutPosCur = 0; + dev->MailboxInPosCur = 0; + dev->MailboxOutInterrupts = 0; + dev->PendingInterrupt = 0; + dev->Lock = 0; + AHA_InOperation = 0; + + ClearIntr(dev); + + LocalRAM(dev); +} + + +static void +aha_softreset(void) +{ + if (ResetDev != NULL) { + aha_reset(ResetDev); + } +} + + +static void +aha_reset_ctrl(aha_t *dev, uint8_t Reset) +{ + aha_reset(dev); + if (Reset) { + dev->Status |= STAT_STST; + dev->Status &= ~STAT_IDLE; + } + ResetCB = AHA_RESET_DURATION_NS * TIMER_USEC; +} + + +static void +aha_cmd_done(aha_t *dev) +{ + dev->DataReply = 0; + dev->Status |= STAT_IDLE; + + if ((dev->Command != 0x02) && (dev->Command != 0x82)) { + dev->Status &= ~STAT_DFULL; + dev->Interrupt = (INTR_ANY | INTR_HACC); + pclog("Raising IRQ %i\n", dev->Irq); + if (dev->IrqEnabled) + picint(1 << dev->Irq); + } + + dev->Command = 0xFF; + dev->CmdParam = 0; +} + + +static void +aha_mbi_setup(aha_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, + uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) +{ + Req_t *req = &dev->Req; + + req->CCBPointer = CCBPointer; + memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); + req->Is24bit = dev->Mbx24bit; + req->HostStatus = HostStatus; + req->TargetStatus = TargetStatus; + req->MailboxCompletionCode = mbcc; + + pclog("Mailbox in setup\n"); + + AHA_InOperation = 2; +} + + +static void +aha_mbi(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint32_t CCBPointer = req->CCBPointer; + CCBU *CmdBlock = &(req->CmdBlock); + uint8_t HostStatus = req->HostStatus; + uint8_t TargetStatus = req->TargetStatus; + uint8_t MailboxCompletionCode = req->MailboxCompletionCode; + Mailbox32_t Mailbox32; + Mailbox_t MailboxIn; + uint32_t Incoming; + + Mailbox32.CCBPointer = CCBPointer; + Mailbox32.u.in.HostStatus = HostStatus; + Mailbox32.u.in.TargetStatus = TargetStatus; + Mailbox32.u.in.CompletionCode = MailboxCompletionCode; + + Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * (dev->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + if (MailboxCompletionCode != MBI_NOT_FOUND) { + CmdBlock->common.HostStatus = HostStatus; + CmdBlock->common.TargetStatus = TargetStatus; + + /* Rewrite the CCB up to the CDB. */ + pclog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); + DMAPageWrite(CCBPointer, (char *)CmdBlock, offsetof(CCBC, Cdb)); + } else { + pclog("Mailbox not found!\n"); + } + + pclog("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); + + if (dev->Mbx24bit) { + MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; + U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); + pclog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); + + DMAPageWrite(Incoming, (char *)&MailboxIn, sizeof(Mailbox_t)); + pclog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); + } else { + pclog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); + + DMAPageWrite(Incoming, (char *)&Mailbox32, sizeof(Mailbox32_t)); + pclog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + } + + dev->MailboxInPosCur++; + if (dev->MailboxInPosCur >= dev->MailboxCount) + dev->MailboxInPosCur = 0; + + RaiseIntr(dev, INTR_MBIF | INTR_ANY); + + AHA_InOperation = 0; +} + + +static void +aha_rd_sge(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) +{ + uint32_t i; + SGE SGE24[MAX_SG_DESCRIPTORS]; + + if (Is24bit) { + DMAPageRead(SGList, (char *)&SGE24, Entries * sizeof(SGE)); + + for (i=0;iCmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + pclog("Data Buffer write: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { + if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || + req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { + uint32_t SGRead; + uint32_t ScatterEntry; + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t SGLeft = DataLength / SGEntryLength; + uint32_t SGAddrCurrent = DataPointer; + uint32_t DataToTransfer = 0; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer += SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + } + + SGAddrCurrent += SGRead * SGEntryLength; + } while (SGLeft > 0); + + pclog("Data to transfer (S/G) %d\n", DataToTransfer); + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both no read/write commands. */ + if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || + (req->CmdBlock.common.ControlByte == 0x00)) { + SGLeft = DataLength / SGEntryLength; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + + DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += SGRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + } while (SGLeft > 0); + } + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + uint32_t Address = DataPointer; + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + if (DataLength > 0) { + DMAPageRead(Address, + (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, + SCSIDevices[req->TargetID][req->LUN].InitLength); + } + } + } +} + + +static void +aha_buf_free(Req_t *req) +{ + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t DataPointer = 0; + uint32_t DataLength = 0; + uint32_t sg_buffer_pos = 0; + uint32_t SGRead; + uint32_t ScatterEntry; + uint32_t SGEntrySize; + uint32_t SGLeft; + uint32_t SGAddrCurrent; + uint32_t Address; + uint32_t Residual; + + if (req->Is24bit) { + DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + + if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { + pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n", + DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength); + } + + if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) { + DataLength = 0; + } + + pclog("Data Buffer read: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both read/write commands. */ + if ((DataLength > 0) && + ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || + (req->CmdBlock.common.ControlByte == 0x00))) { + if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + SGEntrySize = (req->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + SGLeft = DataLength / SGEntrySize; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(req->Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + uint32_t DataToTransfer; + + pclog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); + + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += (SGRead * SGEntrySize); + } while (SGLeft > 0); + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + Address = DataPointer; + + pclog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, DataLength); + } + } + + if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + /* Should be 0 when scatter/gather? */ + if (DataLength >= SCSIDevices[req->TargetID][req->LUN].InitLength) { + Residual = DataLength; + Residual -= SCSIDevices[req->TargetID][req->LUN].InitLength; + } else { + Residual = 0; + } + + if (req->Is24bit) { + U32_TO_ADDR(req->CmdBlock.old.DataLength, Residual); + pclog("24-bit Residual data length for reading: %d\n", + ADDR_TO_U32(req->CmdBlock.old.DataLength)); + } else { + req->CmdBlock.new.DataLength = Residual; + pclog("32-bit Residual data length for reading: %d\n", + req->CmdBlock.new.DataLength); + } + } +} + + +static uint8_t +aha_read(uint16_t port, void *priv) +{ + aha_t *dev = (aha_t *)priv; + uint8_t ret; + + switch (port & 3) { + case 0: + ret = dev->Status; + break; + + case 1: + if (dev->UseLocalRAM) + ret = dev->LocalRAM.u8View[dev->DataReply]; + else + ret = dev->DataBuf[dev->DataReply]; + if (dev->DataReplyLeft) { + dev->DataReply++; + dev->DataReplyLeft--; + if (! dev->DataReplyLeft) + aha_cmd_done(dev); + } + break; + + case 2: + ret = dev->Interrupt; + break; + + case 3: + ret = dev->Geometry; + break; + } + + if (port < 0x1000) { + pclog("AHA154X: Read Port 0x%02X, Returned Value %02X\n", port, ret); + } + + return(ret); +} + + +static uint16_t +aha_readw(uint16_t port, void *priv) +{ + return aha_read(port, priv); +} + + +static uint32_t +aha_readl(uint16_t port, void *priv) +{ + return aha_read(port, priv); +} + + +/* This is BS - we just need a 'dev_present' indication.. --FvK */ +static int +aha_dev_present(uint8_t id, uint8_t lun) +{ + if (lun > 7) return(0); + + if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); + + if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && + cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && + (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) return(1); + + return(0); +} + + +static void +aha_write(uint16_t port, uint8_t val, void *priv) +{ + int i = 0; + uint8_t j = 0; + aha_t *dev = (aha_t *)priv; + uint8_t max_id = 8; + uint8_t Offset; + MailboxInit_t *MailboxInit; + ReplyInquireSetupInformation *ReplyISI; + ReplyInquireExtendedSetupInformation *ReplyIESI; + int cCharsToTransfer; + + pclog("AHA154X: Write Port 0x%02X, Value %02X\n", port, val); + + switch (port & 3) { + case 0: + if ((val & CTRL_HRST) || (val & CTRL_SRST)) { + uint8_t Reset = !(val & CTRL_HRST); + aha_reset_ctrl(dev, Reset); + break; + } + + if (val & CTRL_IRST) { + ClearIntr(dev); + } + break; + + case 1: + /* Fast path for the mailbox execution command. */ + if (((val == 0x02) || (val == 0x82)) && + (dev->Command == 0xFF)) { + /* If there are no mailboxes configured, don't even try to do anything. */ + if (dev->MailboxCount) { + if (!AHA_Callback) { + AHA_Callback = 50 * SCSI_TIME; + } + } + return; + } + + if (dev->Command == 0xFF) { + dev->Command = val; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; + + dev->Status &= ~(STAT_INVCMD | STAT_IDLE); + pclog("AHA154X: Operation Code 0x%02X\n", val); + switch (dev->Command) { + case 0x01: + dev->CmdParamLeft = sizeof(MailboxInit_t); + break; + + case 0x03: /* Exec BIOS Command */ + dev->CmdParamLeft = 10; + break; + + case 0x25: + /* Same as 0x01 for AHA. */ + dev->CmdParamLeft = sizeof(MailboxInit_t); + break; + + case 0x05: + case 0x07: + case 0x08: + case 0x09: + case 0x0D: + case 0x1F: + case 0x21: + case 0x24: + dev->CmdParamLeft = 1; + break; + + case 0x06: + dev->CmdParamLeft = 4; + break; + + case 0x1C: + case 0x1D: + dev->CmdParamLeft = 3; + break; + + case 0x22: /* write EEPROM */ + dev->CmdParamLeft = 3+32; + break; + + case 0x23: /* read EEPROM */ + dev->CmdParamLeft = 3; + break; + + case 0x29: + dev->CmdParamLeft = 2; + break; + + case 0x91: + dev->CmdParamLeft = 2; + break; + } + } else { + dev->CmdBuf[dev->CmdParam] = val; + dev->CmdParam++; + dev->CmdParamLeft--; + } + + if (! dev->CmdParamLeft) { + pclog("Running Operation Code 0x%02X\n", dev->Command); + switch (dev->Command) { + case 0x00: + dev->DataReplyLeft = 0; + break; + + case 0x01: +aha_0x01: + { + dev->Mbx24bit = 1; + + MailboxInit = (MailboxInit_t *)dev->CmdBuf; + + dev->MailboxCount = MailboxInit->Count; + dev->MailboxOutAddr = ADDR_TO_U32(MailboxInit->Address); + dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); + + pclog("Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", dev->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", dev->MailboxInAddr); + pclog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); + + dev->Status &= ~STAT_INIT; + dev->DataReplyLeft = 0; + } + break; + + case 0x03: + dev->DataBuf[0] = 0x00; + dev->DataReplyLeft = 1; + break; + + case 0x04: + dev->DataBuf[0] = dev->aha.bid; + dev->DataBuf[1] = 0x30; + dev->DataBuf[2] = dev->aha.fwh; + dev->DataBuf[3] = dev->aha.fwl; + dev->DataReplyLeft = 4; + break; + + case 0x05: + if (dev->CmdBuf[0] <= 1) { + dev->MailboxOutInterrupts = dev->CmdBuf[0]; + pclog("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); + } else { + dev->Status |= STAT_INVCMD; + } + dev->DataReplyLeft = 0; + break; + + case 0x06: + dev->DataReplyLeft = 0; + break; + + case 0x07: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uBusOnDelay = dev->CmdBuf[0]; + pclog("Bus-on time: %d\n", dev->CmdBuf[0]); + break; + + case 0x08: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uBusOffDelay = dev->CmdBuf[0]; + pclog("Bus-off time: %d\n", dev->CmdBuf[0]); + break; + + case 0x09: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uDMATransferRate = dev->CmdBuf[0]; + pclog("DMA transfer rate: %02X\n", dev->CmdBuf[0]); + break; + + case 0x0A: + memset(dev->DataBuf, 0, 8); + for (i=0; i<7; i++) { + dev->DataBuf[i] = 0; + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + dev->DataBuf[i] |= (1<DataBuf[7] = 0; + dev->DataReplyLeft = 8; + break; + + case 0x0B: + dev->DataBuf[0] = (1<DmaChannel); + if (dev->Irq >= 8) + dev->DataBuf[1]=(1<<(dev->Irq-9)); + else + dev->DataBuf[1]=(1<Irq); + dev->DataBuf[2] = 7; /* HOST ID */ + dev->DataReplyLeft = 3; + break; + + case 0x0D: + { + dev->DataReplyLeft = dev->CmdBuf[0]; + + ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; + memset(ReplyISI, 0, sizeof(ReplyInquireSetupInformation)); + + ReplyISI->fSynchronousInitiationEnabled = 1; + ReplyISI->fParityCheckingEnabled = 1; + ReplyISI->cMailbox = dev->MailboxCount; + U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); + pclog("Return Setup Information: %d\n", dev->CmdBuf[0]); + } + break; + + case 0x1C: + { + uint32_t FIFOBuf; + addr24 Address; + + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + DMAPageRead(FIFOBuf, (char *)&dev->LocalRAM.u8View[64], 64); + } + break; + + case 0x1D: + { + uint32_t FIFOBuf; + addr24 Address; + + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + pclog("FIFO: Writing 64 bytes at %08X\n", FIFOBuf); + DMAPageWrite(FIFOBuf, (char *)&dev->LocalRAM.u8View[64], 64); + } + break; + + case 0x1F: + dev->DataBuf[0] = dev->CmdBuf[0]; + dev->DataReplyLeft = 1; + break; + + case 0x21: + if (dev->CmdParam == 1) + dev->CmdParamLeft = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + break; + + case 0x22: /* write EEPROM */ + /* Sent by CF BIOS. */ + dev->DataReplyLeft = + aha154x_eeprom(dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + &dev->CmdBuf[3]); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + + case 0x23: + dev->DataReplyLeft = + aha154x_eeprom(dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + dev->DataBuf); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + + case 0x24: + /* + * For AHA1542CF, this is the command + * to play with the Shadow RAM. BIOS + * gives us one argument (00,02,03) + * and expects a 0x04 back in the INTR + * register. --FvK + */ + dev->Interrupt = aha154x_shram(val); + break; + + case 0x25: + goto aha_0x01; + + case 0x26: /* AHA memory mapper */ + case 0x27: /* AHA memory mapper */ + dev->DataReplyLeft = + aha154x_memory(dev->Command); + break; + + case 0x28: + dev->DataBuf[0] = 0x08; + dev->DataBuf[1] = dev->Lock; + dev->DataReplyLeft = 2; + break; + + case 0x29: + if (dev->CmdBuf[1] == dev->Lock) { + if (dev->CmdBuf[0] & 1) { + dev->Lock = 1; + } else { + dev->Lock = 0; + } + } + dev->DataReplyLeft = 0; + break; + + case 0x2C: /* AHA-1542CP sends this */ + dev->DataBuf[0] = 0x00; + dev->DataReplyLeft = 1; + break; + + case 0x33: /* AHA-1542CP sends this */ + dev->DataBuf[0] = 0x00; + dev->DataBuf[1] = 0x00; + dev->DataBuf[2] = 0x00; + dev->DataBuf[3] = 0x00; + dev->DataReplyLeft = 256; + break; + + case 0x91: + Offset = dev->CmdBuf[0]; + dev->DataReplyLeft = dev->CmdBuf[1]; + + dev->UseLocalRAM = 1; + dev->DataReply = Offset; + break; + + default: + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } + } + + if (dev->DataReplyLeft) + dev->Status |= STAT_DFULL; + else if (!dev->CmdParamLeft) + aha_cmd_done(dev); + break; + + case 2: + break; + + case 3: + break; + } +} + + +static void +aha_writew(uint16_t Port, uint16_t Val, void *p) +{ + aha_write(Port, Val & 0xFF, p); +} + + +static void +aha_writeL(uint16_t Port, uint32_t Val, void *p) +{ + aha_write(Port, Val & 0xFF, p); +} + + +static uint8_t +ConvertSenseLength(uint8_t RequestSenseLength) +{ + pclog("Unconverted Request Sense length %i\n", RequestSenseLength); + + if (RequestSenseLength == 0) + RequestSenseLength = 14; + else if (RequestSenseLength == 1) + RequestSenseLength = 0; + + pclog("Request Sense length %i\n", RequestSenseLength); + + return(RequestSenseLength); +} + + +static void +SenseBufferFree(Req_t *req, int Copy, int is_hd) +{ + uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; + uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN]; + uint32_t SenseBufferAddress; + uint8_t temp_sense[256]; + + if (SenseLength && Copy) { + if (is_hd) + { + scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength); + } + else + { + cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); + } + + /* + * The sense address, in 32-bit mode, is located in the + * Sense Pointer of the CCB, but in 24-bit mode, it is + * located at the end of the Command Descriptor Block. + */ + if (req->Is24bit) { + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + offsetof(CCB, Cdb); + } else { + SenseBufferAddress = req->CmdBlock.new.SensePointer; + } + + pclog("Request Sense address: %02X\n", SenseBufferAddress); + + pclog("SenseBufferFree(): Writing %i bytes at %08X\n", + SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, (char *)temp_sense, SenseLength); + pclog("Sense data written to buffer: %02X %02X %02X\n", + temp_sense[2], temp_sense[12], temp_sense[13]); + } +} + + +static void +aha_disk_cmd(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t hdc_id; + uint8_t hd_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + hdc_id = scsi_hard_disks[Id][Lun]; + + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", + Id, Lun, hdc_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, shdc[hdc_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len); + } + + /* + * Since that field in the HDC struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + shdc[hdc_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + scsi_hd_command(hdc_id, temp_cdb); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + if (SCSIStatus == SCSI_STATUS_OK) { + hd_phase = scsi_hd_phase_to_scsi(hdc_id); + if (hd_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + scsi_hd_callback(hdc_id); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + /* Command second phase complete - call the callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", shdc[hdc_id].sense[2], shdc[hdc_id].sense[12], shdc[hdc_id].sense[13]); + + aha_buf_free(req); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 1); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void +aha_cdrom_cmd(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t cdrom_id; + uint8_t cdrom_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + cdrom_id = scsi_cdrom_drives[Id][Lun]; + + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", + Id, Lun, cdrom_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + /* + * Since that field in the CDROM struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + cdrom[cdrom_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + cdrom_command(cdrom_id, temp_cdb); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) { + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); + + aha_buf_free(req); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void +aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t last_id = 7; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&req->CmdBlock, sizeof(CCB32)); + + req->Is24bit = dev->Mbx24bit; + req->CCBPointer = CCBPointer; + req->TargetID = dev->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; + req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; + + Id = req->TargetID; + Lun = req->LUN; + if ((Id > last_id) || (Lun > 7)) { + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return; + } + + pclog("Scanning SCSI Target ID %i\n", Id); + + SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[Id][Lun].InitLength = 0; + + /* Do this here, so MODE SELECT data does not get lost in transit. */ + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + + aha_buf_alloc(req, req->Is24bit); + + if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { + pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun); + aha_buf_free(req); + SenseBufferFree(req, 0, 0); + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + } else { + pclog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); + + pclog("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); + pclog("CDB Length %i\n", req->CmdBlock.common.CdbLength); + pclog("CCB Opcode %x\n", req->CmdBlock.common.Opcode); + if (req->CmdBlock.common.ControlByte > 0x03) { + pclog("Invalid control byte: %02X\n", + req->CmdBlock.common.ControlByte); + } + + AHA_InOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1; + pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); + } +} + + +static void +aha_req_abort(aha_t *dev, uint32_t CCBPointer) +{ + CCBU CmdBlock; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&CmdBlock, sizeof(CCB32)); + + aha_mbi_setup(dev, CCBPointer, &CmdBlock, + 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); +} + + +static uint32_t +aha_mbo(aha_t *dev, Mailbox32_t *Mailbox32) +{ + Mailbox_t MailboxOut; + uint32_t Outgoing; + + if (dev->Mbx24bit) { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox_t)); + DMAPageRead(Outgoing, (char *)&MailboxOut, sizeof(Mailbox_t)); + + Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); + Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; + } else { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox32_t)); + + DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t)); + } + + return Outgoing; +} + + +static void +aha_mbo_adv(aha_t *dev) +{ + dev->MailboxOutPosCur = (dev->MailboxOutPosCur + 1) % dev->MailboxCount; +} + + +static void +aha_do_mail(aha_t *dev) +{ + Mailbox32_t mb32; + uint32_t Outgoing; + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + CodeOffset = dev->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + + if (! dev->StrictRoundRobinMode) { + uint8_t MailboxCur = dev->MailboxOutPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do { + /* Fetch mailbox from guest memory. */ + Outgoing = aha_mbo(dev, &mb32); + + /* Check the next mailbox. */ + aha_mbo_adv(dev); + } while ((mb32.u.out.ActionCode == MBO_FREE) && (MailboxCur != dev->MailboxOutPosCur)); + } else { + Outgoing = aha_mbo(dev, &mb32); + } + + if (mb32.u.out.ActionCode != MBO_FREE) { + /* We got the mailbox, mark it as free in the guest. */ + pclog("aha_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); + } + + if (dev->MailboxOutInterrupts) + RaiseIntr(dev, INTR_MBOA | INTR_ANY); + + /* Check if the mailbox is actually loaded. */ + if (mb32.u.out.ActionCode == MBO_FREE) { + return; + } + + if (mb32.u.out.ActionCode == MBO_START) { + pclog("Start Mailbox Command\n"); + aha_req_setup(dev, mb32.CCBPointer, &mb32); + } else if (mb32.u.out.ActionCode == MBO_ABORT) { + pclog("Abort Mailbox Command\n"); + aha_req_abort(dev, mb32.CCBPointer); + } else { + pclog("Invalid action code: %02X\n", mb32.u.out.ActionCode); + } + + /* Advance to the next mailbox. */ + if (dev->StrictRoundRobinMode) + aha_mbo_adv(dev); +} + + +static void +aha_reset_poll(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + dev->Status &= ~STAT_STST; + dev->Status |= STAT_IDLE; + + ResetCB = 0; +} + + +static void +aha_cmd_cb(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + if (AHA_InOperation == 0) { + if (dev->MailboxCount) { + aha_do_mail(dev); + } else { + AHA_Callback += 50 * SCSI_TIME; + return; + } + } else if (AHA_InOperation == 1) { + pclog("BusLogic Callback: Process CD-ROM request\n"); + aha_cdrom_cmd(dev); + if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) + { + /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ + AHA_Callback += 1000 * SCSI_TIME; + return; + } + } else if (AHA_InOperation == 2) { + pclog("BusLogic Callback: Send incoming mailbox\n"); + aha_mbi(dev); + } else if (AHA_InOperation == 0x11) { + pclog("BusLogic Callback: Process DISK request\n"); + aha_disk_cmd(dev); + } else { + fatal("Invalid BusLogic callback phase: %i\n", AHA_InOperation); + } + + AHA_Callback += 50 * SCSI_TIME; +} + + +static void * +aha_init(int chip, int has_bios) +{ + aha_t *dev; + int i = 0; + int j = 0; + uint32_t bios_addr = 0; + int bios = 0; + + dev = malloc(sizeof(aha_t)); + memset(dev, 0x00, sizeof(aha_t)); + + ResetDev = dev; + dev->chip = chip; + dev->Base = device_get_config_int("addr"); + dev->Irq = device_get_config_int("irq"); + dev->DmaChannel = device_get_config_int("dma"); + bios = device_get_config_int("bios"); + bios_addr = device_get_config_int("bios_addr"); + + if (dev->Base != 0) { + io_sethandler(dev->Base, 4, + aha_read, aha_readw, NULL, + aha_write, aha_writew, NULL, dev); + } + + pclog("Building SCSI hard disk map...\n"); + build_scsi_hd_map(); + pclog("Building SCSI CD-ROM map...\n"); + build_scsi_cdrom_map(); + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) { + if (scsi_hard_disks[i][j] != 0xff) { + SCSIDevices[i][j].LunType = SCSI_DISK; + } + } + } + + for (i=0; iBase); + + aha_reset_ctrl(dev, CTRL_HRST); + + if (bios) { + /* Perform AHA-154xNN-specific initialization. */ + aha154x_bios(dev->Base, bios_addr, &dev->aha); + } + + return(dev); +} + + +static void * +aha_154xB_init(void) +{ + return(aha_init(CHIP_AHA154XB, 0)); +} + + +static void * +aha_154xCF_init(void) +{ + return(aha_init(CHIP_AHA154XCF, 1)); +} + + +static void +aha_close(void *priv) +{ + aha_t *dev = (aha_t *)priv; + free(dev); + ResetDev = NULL; +} + + +static device_config_t aha_154XCF_config[] = { + { + "addr", "Address", CONFIG_SELECTION, "", 0x334, + { + { + "None", 0 + }, + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "bios", "Enable BIOS", CONFIG_BINARY, 0 + }, + { + "bios_addr", "BIOS Address", CONFIG_SELECTION, "", 0xd8000, + { + { + "C800H", 0xc8000 + }, + { + "D000H", 0xd0000 + }, + { + "D800H", 0xd8000 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + + +device_t aha1540b_device = { + "Adaptec AHA-1540B", + 0, + aha_154xB_init, + aha_close, + NULL, + NULL, + NULL, + NULL, + aha_154XCF_config +}; + +device_t aha1542cf_device = { + "Adaptec AHA-1542CF", + 0, + aha_154xCF_init, + aha_close, + NULL, + NULL, + NULL, + NULL, + aha_154XCF_config +}; diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h new file mode 100644 index 000000000..67734e070 --- /dev/null +++ b/src/scsi_aha154x.h @@ -0,0 +1,17 @@ +#ifndef SCSI_AHA154X_H +# define SCSI_AHA154X_H + + +typedef struct { + uint8_t flags; /* local flags */ + uint8_t bid; /* board ID */ + char fwl, fwh; /* firmware info */ +} aha_info; +#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ + + +extern device_t aha1540b_device; +extern device_t aha1542cf_device; + + +#endif /*SCSI_AHA154X_H*/ diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 9675cfe88..11a4d3d27 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1,13 +1,11 @@ /* Copyright holders: SA1988 see COPYING for more details */ -/*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ +/*Buslogic SCSI emulation*/ /* Emulated SCSI controllers: - 0 - Adaptec AHA-154xB ISA; - 1 - Adaptec AHA-154xCF ISA; - 2 - BusLogic BT-542B ISA; - 3 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ + 0 - BusLogic BT-542B ISA; + 1 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ #include #include @@ -15,7 +13,6 @@ #include #include #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "rom.h" @@ -23,6 +20,7 @@ #include "pic.h" #include "pci.h" #include "timer.h" +#include "device.h" #include "scsi.h" #include "cdrom.h" #include "scsi_buslogic.h" @@ -31,18 +29,6 @@ #define BUSLOGIC_RESET_DURATION_NS UINT64_C(50000000) -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - -#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) -#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) - - /* * Host Adapter I/O ports. * @@ -439,29 +425,6 @@ typedef union { #pragma pack(pop) -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -/* #define MAX_SG_DESCRIPTORS ((bl->chip >= CHIP_BUSLOGIC_ISA) ? 32 : 17) */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - #pragma pack(push,1) typedef struct { CCBU CmdBlock; @@ -473,7 +436,7 @@ typedef struct { uint8_t HostStatus; uint8_t TargetStatus; uint8_t MailboxCompletionCode; -} BuslogicRequests_t; +} Req_t; #pragma pack(pop) #pragma pack(push,1) @@ -483,7 +446,7 @@ typedef struct { int StrictRoundRobinMode; int ExtendedLUNCCBFormat; HALocalRAM LocalRAM; - BuslogicRequests_t BuslogicRequests; + Req_t Req; uint8_t Status; uint8_t Interrupt; uint8_t Geometry; @@ -512,30 +475,23 @@ typedef struct { int PendingInterrupt; int Lock; mem_mapping_t mmio_mapping; - aha_info aha; int chip; } Buslogic_t; #pragma pack(pop) -int scsi_model = 1; -int BuslogicResetCallback = 0; -int BuslogicCallback = 0; -int BuslogicInOperation = 0; +static int BuslogicResetCallback = 0; +static int BuslogicCallback = 0; +static int BuslogicInOperation = 0; static Buslogic_t *BuslogicResetDevice; -enum -{ - CHIP_AHA154XB, - CHIP_AHA154XCF, - CHIP_BUSLOGIC_ISA, - CHIP_BUSLOGIC_PCI +enum { + CHIP_BUSLOGIC_ISA, + CHIP_BUSLOGIC_PCI }; -static void BuslogicStartMailbox(Buslogic_t *Buslogic); - #ifdef WALTJE int buslogic_do_log = 1; # define ENABLE_BUSLOGIC_LOG @@ -544,7 +500,11 @@ int buslogic_do_log = 0; #endif -static void BuslogicLog(const char *format, ...) +static void BuslogicStartMailbox(Buslogic_t *); + + +static void +BuslogicLog(const char *format, ...) { #ifdef ENABLE_BUSLOGIC_LOG va_list ap; @@ -560,7 +520,8 @@ static void BuslogicLog(const char *format, ...) #define pclog BuslogicLog -static void BuslogicClearInterrupt(Buslogic_t *bl) +static void +BuslogicClearInterrupt(Buslogic_t *bl) { pclog("Buslogic: Lowering Interrupt 0x%02X\n", bl->Interrupt); bl->Interrupt = 0; @@ -577,7 +538,8 @@ static void BuslogicClearInterrupt(Buslogic_t *bl) } -static void BuslogicLocalRAM(Buslogic_t *bl) +static void +BuslogicLocalRAM(Buslogic_t *bl) { /* * These values are mostly from what I think is right @@ -601,7 +563,8 @@ static void BuslogicLocalRAM(Buslogic_t *bl) } -static void BuslogicReset(Buslogic_t *bl) +static void +BuslogicReset(Buslogic_t *bl) { BuslogicCallback = 0; BuslogicResetCallback = 0; @@ -626,7 +589,8 @@ static void BuslogicReset(Buslogic_t *bl) } -void BuslogicSoftReset(void) +static void +BuslogicSoftReset(void) { if (BuslogicResetDevice != NULL) { BuslogicReset(BuslogicResetDevice); @@ -634,7 +598,8 @@ void BuslogicSoftReset(void) } -static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) +static void +BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) { BuslogicReset(bl); if (Reset) { @@ -645,16 +610,13 @@ static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) } -static void BuslogicCommandComplete(Buslogic_t *bl) +static void +BuslogicCommandComplete(Buslogic_t *bl) { bl->DataReply = 0; bl->Status |= STAT_IDLE; -#ifdef WALTJE - if ((bl->Command != 0x02) && (bl->Command != 0x82)) { -#else if (bl->Command != 0x02) { -#endif bl->Status &= ~STAT_DFULL; bl->Interrupt = (INTR_ANY | INTR_HACC); pclog("Raising IRQ %i\n", bl->Irq); @@ -667,7 +629,8 @@ static void BuslogicCommandComplete(Buslogic_t *bl) } -static void BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) +static void +BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) { if (bl->Interrupt & INTR_HACC) { pclog("Pending IRQ\n"); @@ -681,12 +644,12 @@ static void BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) } -static void BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, - CCBU *CmdBlock, uint8_t HostStatus, - uint8_t TargetStatus, - uint8_t MailboxCompletionCode) +static void +BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, CCBU *CmdBlock, + uint8_t HostStatus, uint8_t TargetStatus, + uint8_t MailboxCompletionCode) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; req->CCBPointer = CCBPointer; memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); @@ -701,9 +664,10 @@ static void BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, } -static void BuslogicMailboxIn(Buslogic_t *bl) +static void +BuslogicMailboxIn(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint32_t CCBPointer = req->CCBPointer; CCBU *CmdBlock = &(req->CmdBlock); uint8_t HostStatus = req->HostStatus; @@ -758,7 +722,8 @@ static void BuslogicMailboxIn(Buslogic_t *bl) } -static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) +static void +BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) { uint32_t i; SGE SGE24[MAX_SG_DESCRIPTORS]; @@ -777,7 +742,8 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries } -void BuslogicDataBufferAllocate(BuslogicRequests_t *req, int Is24bit) +static void +BuslogicDataBufferAllocate(Req_t *req, int Is24bit) { uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; @@ -873,7 +839,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *req, int Is24bit) } -void BuslogicDataBufferFree(BuslogicRequests_t *req) +static void +BuslogicDataBufferFree(Req_t *req) { uint32_t DataPointer = 0; uint32_t DataLength = 0; @@ -974,7 +941,8 @@ void BuslogicDataBufferFree(BuslogicRequests_t *req) } -static uint8_t BuslogicRead(uint16_t Port, void *p) +static uint8_t +BuslogicRead(uint16_t Port, void *p) { Buslogic_t *bl = (Buslogic_t *)p; uint8_t Temp; @@ -1016,20 +984,22 @@ static uint8_t BuslogicRead(uint16_t Port, void *p) } -static uint16_t BuslogicReadW(uint16_t Port, void *p) +static uint16_t +BuslogicReadW(uint16_t Port, void *p) { return BuslogicRead(Port, p); } -static uint32_t BuslogicReadL(uint16_t Port, void *p) +static uint32_t +BuslogicReadL(uint16_t Port, void *p) { return BuslogicRead(Port, p); } /* This is BS - we just need a 'dev_present' indication.. --FvK */ -int +static int buslogic_dev_present(uint8_t id, uint8_t lun) { if (lun > 7) return(0); @@ -1046,7 +1016,8 @@ buslogic_dev_present(uint8_t id, uint8_t lun) static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); -static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) +static void +BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { int i = 0; uint8_t j = 0; @@ -1078,8 +1049,7 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 1: /* Fast path for the mailbox execution command. */ - if (((Val == 0x02) || (Val == 0x82)) && - (bl->Command == 0xFF)) { + if ((Val == 0x02) && (bl->Command == 0xFF)) { /* If there are no mailboxes configured, don't even try to do anything. */ if (bl->MailboxCount) { if (!BuslogicCallback) { @@ -1101,19 +1071,8 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) bl->CmdParamLeft = sizeof(MailboxInit_t); break; - case 0x03: /* Exec BIOS Command */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 10; - } - break; - case 0x25: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - /* Same as 0x01 for AHA. */ - bl->CmdParamLeft = sizeof(MailboxInit_t); - } else { bl->CmdParamLeft = 1; - } break; case 0x05: @@ -1136,36 +1095,19 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) bl->CmdParamLeft = 3; break; - case 0x22: /* write EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 3+32; - } - break; - - case 0x23: /* read EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 3; - } - break; - - case 0x29: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 0 : 2; - break; - case 0x8B: case 0x8D: case 0x8F: case 0x96: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + bl->CmdParamLeft = 1; break; case 0x81: - pclog("Command 0x81 on %s\n", (bl->chip >= CHIP_BUSLOGIC_ISA) ? "BusLogic" : "Adaptec"); - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? sizeof(MailboxInitExtended_t) : 0; + bl->CmdParamLeft = sizeof(MailboxInitExtended_t); break; case 0x8C: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + bl->CmdParamLeft = 1; break; case 0x91: @@ -1216,17 +1158,10 @@ aha_0x01: break; case 0x04: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { bl->DataBuf[0] = 0x41; bl->DataBuf[1] = 0x41; bl->DataBuf[2] = '5'; bl->DataBuf[3] = '0'; - } else { - bl->DataBuf[0] = bl->aha.bid; - bl->DataBuf[1] = 0x30; - bl->DataBuf[2] = bl->aha.fwh; - bl->DataBuf[3] = bl->aha.fwl; - } bl->DataReplyLeft = 4; break; @@ -1277,14 +1212,7 @@ aha_0x01: case 0x0B: bl->DataBuf[0] = (1 << bl->DmaChannel); - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[1] = (1<<(bl->Irq-9)); - } else { - if (bl->Irq >= 8) - bl->DataBuf[1]=(1<<(bl->Irq-9)); - else - bl->DataBuf[1]=(1<Irq); - } + bl->DataBuf[1] = (1<<(bl->Irq-9)); bl->DataBuf[2] = 7; /* HOST ID */ bl->DataReplyLeft = 3; break; @@ -1301,14 +1229,12 @@ aha_0x01: ReplyISI->cMailbox = bl->MailboxCount; U32_TO_ADDR(ReplyISI->MailboxAddress, bl->MailboxOutAddr); - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - ReplyISI->uSignature = 'B'; - /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too - * friendly with Adaptec hardware and upsetting the HBA state. - */ - ReplyISI->uCharacterD = 'D'; /* BusLogic model. */ - ReplyISI->uHostBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'F' : 'A'; /* ISA bus. */ - } + ReplyISI->uSignature = 'B'; + /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too + * friendly with Adaptec hardware and upsetting the HBA state. + */ + ReplyISI->uCharacterD = 'D'; /* BusLogic model. */ + ReplyISI->uHostBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'F' : 'A'; /* ISA bus. */ pclog("Return Setup Information: %d\n", bl->CmdBuf[0]); } @@ -1350,11 +1276,7 @@ aha_0x01: case 0x20: bl->DataReplyLeft = 0; - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - BuslogicResetControl(bl, 1); - } else { - bl->Status |= STAT_INVCMD; - } + BuslogicResetControl(bl, 1); break; case 0x21: @@ -1363,53 +1285,27 @@ aha_0x01: bl->DataReplyLeft = 0; break; - case 0x22: /* write EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - /* Sent by CF BIOS. */ - bl->DataReplyLeft = - aha154x_eeprom(bl->Command, - bl->CmdBuf[0], - bl->CmdBuf[1], - bl->CmdBuf[2], - &bl->CmdBuf[3]); - if (bl->DataReplyLeft == 0xff) { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - } else { - bl->Status |= STAT_INVCMD; - bl->DataReplyLeft = 0; - } - break; - case 0x23: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { memset(bl->DataBuf, 0, 8); for (i = 8; i < 16; i++) { +#if 1 /* FIXME: Kotori, check this! */ + bl->DataBuf[i-8] = 0; + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + bl->DataBuf[i-8] |= (1<DataBuf[i] = 0; for (i=0; j<8; j++) { if (SCSIDevices[i][j].LunType != SCSI_NONE) - bl->DataBuf[i] |= (1 << j); + bl->DataBuf[i] |= (1<DataReplyLeft = 8; - } else { - /* Sent by CF BIOS. */ - bl->DataReplyLeft = - aha154x_eeprom(bl->Command, - bl->CmdBuf[0], - bl->CmdBuf[1], - bl->CmdBuf[2], - bl->DataBuf); - if (bl->DataReplyLeft == 0xff) { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - } - break; + break; case 0x24: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { + { uint16_t TargetsPresentMask = 0; for (i=0; i<16; i++) { @@ -1421,135 +1317,46 @@ aha_0x01: bl->DataBuf[0] = TargetsPresentMask & 0xFF; bl->DataBuf[1] = TargetsPresentMask >> 8; bl->DataReplyLeft = 2; - } else { - /* - * For AHA1542CF, this is the command - * to play with the Shadow RAM. BIOS - * gives us one argument (00,02,03) - * and expects a 0x04 back in the INTR - * register. --FvK - */ - bl->Interrupt = aha154x_shram(Val); } break; - + case 0x25: - if ((bl->chip < CHIP_BUSLOGIC_ISA)) { - goto aha_0x01; - } else { if (bl->CmdBuf[0] == 0) bl->IrqEnabled = 0; else bl->IrqEnabled = 1; pclog("Lowering IRQ %i\n", bl->Irq); picintc(1 << bl->Irq); - } break; - case 0x26: /* AHA memory mapper */ - case 0x27: /* AHA memory mapper */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataReplyLeft = - aha154x_memory(bl->Command); - } else { - bl->Status |= STAT_INVCMD; - bl->DataReplyLeft = 0; - } - break; - - case 0x28: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x08; - bl->DataBuf[1] = bl->Lock; - bl->DataReplyLeft = 2; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x29: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - if (bl->CmdBuf[1] == bl->Lock) { - if (bl->CmdBuf[0] & 1) { - bl->Lock = 1; - } else { - bl->Lock = 0; - } - } - bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x2C: /* AHA-1542CP sends this */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x00; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x33: /* AHA-1542CP sends this */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x00; - bl->DataBuf[1] = 0x00; - bl->DataBuf[2] = 0x00; - bl->DataBuf[3] = 0x00; - bl->DataReplyLeft = 256; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - case 0x81: { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->Mbx24bit = 0; - - MailboxInitE = (MailboxInitExtended_t *)bl->CmdBuf; + bl->Mbx24bit = 0; - bl->MailboxCount = MailboxInitE->Count; - bl->MailboxOutAddr = MailboxInitE->Address; - bl->MailboxInAddr = MailboxInitE->Address + (bl->MailboxCount * sizeof(Mailbox32_t)); - - pclog("Buslogic Extended Initialize Mailbox Command\n"); - pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); - pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); - pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); - - bl->Status &= ~STAT_INIT; - bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + MailboxInitE = (MailboxInitExtended_t *)bl->CmdBuf; + + bl->MailboxCount = MailboxInitE->Count; + bl->MailboxOutAddr = MailboxInitE->Address; + bl->MailboxInAddr = MailboxInitE->Address + (bl->MailboxCount * sizeof(Mailbox32_t)); + + pclog("Buslogic Extended Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); + pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); + + bl->Status &= ~STAT_INIT; + bl->DataReplyLeft = 0; } break; case 0x84: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = '7'; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + bl->DataBuf[0] = '7'; + bl->DataReplyLeft = 1; break; case 0x85: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 'B'; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + bl->DataBuf[0] = 'B'; + bl->DataReplyLeft = 1; break; case 0x86: @@ -1592,64 +1399,47 @@ aha_0x01: case 0x8B: { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - /* The reply length is set by the guest and is found in the first byte of the command buffer. */ - bl->DataReplyLeft = bl->CmdBuf[0]; - memset(bl->DataBuf, 0, bl->DataReplyLeft); - if (bl->chip == CHIP_BUSLOGIC_PCI) { - aModelName[0] = '9'; - aModelName[1] = '5'; - aModelName[2] = '8'; - aModelName[3] = 'D'; - } - cCharsToTransfer = bl->DataReplyLeft <= sizeof(aModelName) - ? bl->DataReplyLeft - : sizeof(aModelName); - - for (i = 0; i < cCharsToTransfer; i++) - bl->DataBuf[i] = aModelName[i]; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; + /* The reply length is set by the guest and is found in the first byte of the command buffer. */ + bl->DataReplyLeft = bl->CmdBuf[0]; + memset(bl->DataBuf, 0, bl->DataReplyLeft); + if (bl->chip == CHIP_BUSLOGIC_PCI) { + aModelName[0] = '9'; + aModelName[1] = '5'; + aModelName[2] = '8'; + aModelName[3] = 'D'; } + cCharsToTransfer = bl->DataReplyLeft <= sizeof(aModelName) + ? bl->DataReplyLeft + : sizeof(aModelName); + + for (i = 0; i < cCharsToTransfer; i++) + bl->DataBuf[i] = aModelName[i]; } break; case 0x8C: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { bl->DataReplyLeft = bl->CmdBuf[0]; memset(bl->DataBuf, 0, bl->DataReplyLeft); - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; + break; case 0x8D: - { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataReplyLeft = bl->CmdBuf[0]; - ReplyIESI = (ReplyInquireExtendedSetupInformation *)bl->DataBuf; - memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); + bl->DataReplyLeft = bl->CmdBuf[0]; + ReplyIESI = (ReplyInquireExtendedSetupInformation *)bl->DataBuf; + memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); - ReplyIESI->uBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'E' : 'A'; /* ISA style */ - ReplyIESI->uBiosAddress = 0; - ReplyIESI->u16ScatterGatherLimit = 8192; - ReplyIESI->cMailbox = bl->MailboxCount; - ReplyIESI->uMailboxAddressBase = bl->MailboxOutAddr; - if (bl->chip == CHIP_BUSLOGIC_PCI) { - ReplyIESI->fLevelSensitiveInterrupt = 1; - ReplyIESI->fHostWideSCSI = 1; - ReplyIESI->fHostUltraSCSI = 1; - } - memcpy(ReplyIESI->aFirmwareRevision, "07B", sizeof(ReplyIESI->aFirmwareRevision)); - pclog("Return Extended Setup Information: %d\n", bl->CmdBuf[0]); - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; + ReplyIESI->uBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'E' : 'A'; /* ISA style */ + ReplyIESI->uBiosAddress = 0; + ReplyIESI->u16ScatterGatherLimit = 8192; + ReplyIESI->cMailbox = bl->MailboxCount; + ReplyIESI->uMailboxAddressBase = bl->MailboxOutAddr; + if (bl->chip == CHIP_BUSLOGIC_PCI) { + ReplyIESI->fLevelSensitiveInterrupt = 1; + ReplyIESI->fHostWideSCSI = 1; + ReplyIESI->fHostUltraSCSI = 1; } - } - break; + memcpy(ReplyIESI->aFirmwareRevision, "07B", sizeof(ReplyIESI->aFirmwareRevision)); + pclog("Return Extended Setup Information: %d\n", bl->CmdBuf[0]); + break; /* VirtualBox has these two modes implemented in reverse. According to the BusLogic datasheet: @@ -1658,28 +1448,21 @@ aha_0x01: 1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then processes it. */ case 0x8F: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { if (bl->CmdBuf[0] == 0) bl->StrictRoundRobinMode = 1; else if (bl->CmdBuf[0] == 1) bl->StrictRoundRobinMode = 0; bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - + break; + case 0x91: - { Offset = bl->CmdBuf[0]; bl->DataReplyLeft = bl->CmdBuf[1]; bl->UseLocalRAM = 1; bl->DataReply = Offset; - } - break; + break; case 0x95: if (bl->chip == CHIP_BUSLOGIC_PCI) { @@ -1734,18 +1517,13 @@ aha_0x01: break; case 0x96: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { if (bl->CmdBuf[0] == 0) bl->ExtendedLUNCCBFormat = 0; else if (bl->CmdBuf[0] == 1) bl->ExtendedLUNCCBFormat = 1; bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; + break; default: bl->DataReplyLeft = 0; @@ -1761,31 +1539,32 @@ aha_0x01: break; case 2: - if (bl->chip >= CHIP_BUSLOGIC_ISA) - bl->Interrupt = Val; /* For Buslogic */ + bl->Interrupt = Val; break; case 3: - if (bl->chip >= CHIP_BUSLOGIC_ISA) - bl->Geometry = Val; /* For Buslogic */ + bl->Geometry = Val; break; } } -static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) +static void +BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) { BuslogicWrite(Port, Val & 0xFF, p); } -static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) +static void +BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) { BuslogicWrite(Port, Val & 0xFF, p); } -static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) +static uint8_t +BuslogicConvertSenseLength(uint8_t RequestSenseLength) { pclog("Unconverted Request Sense length %i\n", RequestSenseLength); @@ -1800,7 +1579,8 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) } -static void BuslogicSenseBufferFree(BuslogicRequests_t *req, int Copy, int is_hd) +static void +BuslogicSenseBufferFree(Req_t *req, int Copy, int is_hd) { uint8_t SenseLength = BuslogicConvertSenseLength(req->CmdBlock.common.RequestSenseLength); uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; @@ -1841,9 +1621,10 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *req, int Copy, int is_hd } -static void BuslogicHDCommand(Buslogic_t *bl) +static void +BuslogicHDCommand(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t hdc_id; uint8_t hd_phase; @@ -1923,9 +1704,11 @@ static void BuslogicHDCommand(Buslogic_t *bl) } } -static void BuslogicCDROMCommand(Buslogic_t *bl) + +static void +BuslogicCDROMCommand(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t cdrom_id; uint8_t cdrom_phase; @@ -2006,9 +1789,10 @@ static void BuslogicCDROMCommand(Buslogic_t *bl) } -static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +static void +BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailbox32) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t last_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 15 : 7; @@ -2055,13 +1839,14 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbo req->CmdBlock.common.ControlByte); } - BuslogicInOperation = (SCSIDevices[Id][Lun].LunType == SCSI_HDD) ? 0x11 : 1; + BuslogicInOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1; pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); } } -static void BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) +static void +BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) { CCBU CmdBlock; @@ -2074,7 +1859,8 @@ static void BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) } -static uint32_t BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) +static uint32_t +BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) { Mailbox_t MailboxOut; uint32_t Outgoing; @@ -2095,13 +1881,15 @@ static uint32_t BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) } -static void BuslogicMailboxOutAdvance(Buslogic_t *bl) +static void +BuslogicMailboxOutAdvance(Buslogic_t *bl) { bl->MailboxOutPosCur = (bl->MailboxOutPosCur + 1) % bl->MailboxCount; } -static void BuslogicProcessMailbox(Buslogic_t *bl) +static void +BuslogicProcessMailbox(Buslogic_t *bl) { Mailbox32_t mb32; uint32_t Outgoing; @@ -2155,7 +1943,8 @@ static void BuslogicProcessMailbox(Buslogic_t *bl) } -void BuslogicResetPoll(void *p) +static void +BuslogicResetPoll(void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2166,7 +1955,8 @@ void BuslogicResetPoll(void *p) } -void BuslogicCommandCallback(void *p) +static void +BuslogicCommandCallback(void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2180,6 +1970,12 @@ void BuslogicCommandCallback(void *p) } else if (BuslogicInOperation == 1) { pclog("BusLogic Callback: Process CD-ROM request\n"); BuslogicCDROMCommand(bl); + if (bl->Req.CmdBlock.common.Cdb[0] == 0x42) + { + /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ + BuslogicCallback += 1000 * SCSI_TIME; + return; + } } else if (BuslogicInOperation == 2) { pclog("BusLogic Callback: Send incoming mailbox\n"); BuslogicMailboxIn(bl); @@ -2194,19 +1990,22 @@ void BuslogicCommandCallback(void *p) } -static uint8_t mem_read_null(uint32_t addr, void *priv) +static uint8_t +mem_read_null(uint32_t addr, void *priv) { return(0); } -static uint16_t mem_read_nullw(uint32_t addr, void *priv) +static uint16_t +mem_read_nullw(uint32_t addr, void *priv) { return(0); } -static uint32_t mem_read_nulll(uint32_t addr, void *priv) +static uint32_t +mem_read_nulll(uint32_t addr, void *priv) { return(0); } @@ -2222,7 +2021,8 @@ uint8_t buslogic_pci_regs[256]; bar_t buslogic_pci_bar[3]; -static uint8_t BuslogicPCIRead(int func, int addr, void *p) +static uint8_t +BuslogicPCIRead(int func, int addr, void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2291,7 +2091,8 @@ static uint8_t BuslogicPCIRead(int func, int addr, void *p) } -static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) +static void +BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2387,84 +2188,8 @@ static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } -void *AdaptecInit(int has_bios, int chip) -{ - Buslogic_t *bl; - int i = 0; - int j = 0; - uint32_t bios_addr = 0; - int bios = 0; - - bl = malloc(sizeof(Buslogic_t)); - memset(bl, 0x00, sizeof(Buslogic_t)); - - BuslogicResetDevice = bl; - bl->chip = chip; - bl->Base = device_get_config_int("addr"); - bl->PCIBase = 0; - bl->MMIOBase = 0; - bl->Irq = device_get_config_int("irq"); - bl->DmaChannel = device_get_config_int("dma"); - bios = device_get_config_int("bios"); - bios_addr = device_get_config_int("bios_addr"); - - if (bl->Base != 0) { - io_sethandler(bl->Base, 4, - BuslogicRead, BuslogicReadW, NULL, - BuslogicWrite, BuslogicWriteW, NULL, bl); - } - - pclog("Building SCSI hard disk map...\n"); - build_scsi_hd_map(); - pclog("Building SCSI CD-ROM map...\n"); - build_scsi_cdrom_map(); - - for (i=0; i<16; i++) { - for (j=0; j<8; j++) - { - if (scsi_hard_disks[i][j] != 0xff) - { - SCSIDevices[i][j].LunType = SCSI_HDD; - } - } - } - - for (i=0; iBase); - - BuslogicResetControl(bl, CTRL_HRST); - - if (bios) { - /* Perform AHA-154xNN-specific initialization. */ - aha154x_init(bl->Base, bios_addr, &bl->aha); - } - - return(bl); -} - -void *AHA_154xB_Init() -{ - return AdaptecInit(0, CHIP_AHA154XB); -} - -void *AHA_154xCF_Init() -{ - return AdaptecInit(1, CHIP_AHA154XCF); -} - - -void *BuslogicInit(int chip) +static void * +BuslogicInit(int chip) { Buslogic_t *bl; @@ -2509,7 +2234,7 @@ void *BuslogicInit(int chip) { if (scsi_hard_disks[i][j] != 0xff) { - SCSIDevices[i][j].LunType = SCSI_HDD; + SCSIDevices[i][j].LunType = SCSI_DISK; } } } @@ -2550,18 +2275,23 @@ void *BuslogicInit(int chip) return(bl); } -void *Buslogic_542B_Init() + +static void * +Buslogic_542B_Init(void) { return BuslogicInit(CHIP_BUSLOGIC_ISA); } -void *Buslogic_958D_Init() + +static void * +Buslogic_958D_Init(void) { return BuslogicInit(CHIP_BUSLOGIC_PCI); } -void BuslogicClose(void *p) +static void +BuslogicClose(void *p) { Buslogic_t *bl = (Buslogic_t *)p; free(bl); @@ -2569,107 +2299,7 @@ void BuslogicClose(void *p) } -static device_config_t AHA154XCF_Config[] = -{ - { - "addr", "Address", CONFIG_SELECTION, "", 0x334, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "bios", "Enable BIOS", CONFIG_BINARY, 0 - }, - { - "bios_addr", "BIOS Address", CONFIG_SELECTION, "", 0xd8000, - { - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -static device_config_t BuslogicConfig[] = -{ +static device_config_t BuslogicConfig[] = { { "addr", "Address", CONFIG_SELECTION, "", 0x334, { @@ -2747,35 +2377,9 @@ static device_config_t BuslogicConfig[] = } }; -device_t aha1540b_device = -{ - "Adaptec AHA-1540B", - 0, - AHA_154xB_Init, - BuslogicClose, - NULL, - NULL, - NULL, - NULL, - BuslogicConfig -}; -device_t aha1542cf_device = -{ - "Adaptec AHA-1542CF", - 0, - AHA_154xCF_Init, - BuslogicClose, - NULL, - NULL, - NULL, - NULL, - AHA154XCF_Config -}; - -device_t buslogic_device = -{ - "Buslogic BT-542B PCI", +device_t buslogic_device = { + "Buslogic BT-542B ISA", 0, Buslogic_542B_Init, BuslogicClose, @@ -2786,9 +2390,8 @@ device_t buslogic_device = BuslogicConfig }; -device_t buslogic_pci_device = -{ - "Buslogic BT-542B PCI", +device_t buslogic_pci_device = { + "Buslogic BT-958D PCI", 0, Buslogic_958D_Init, BuslogicClose, diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index c4b6805f0..c2d5dccc5 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -1,27 +1,9 @@ -#ifndef BUSLOGIC_H -# define BUSLOGIC_H +#ifndef SCSI_BUSLOGIC_H +# define SCSI_BUSLOGIC_H -typedef struct { - uint8_t flags; /* local flags */ - uint8_t bid; /* board ID */ - char fwl, fwh; /* firmware info */ -} aha_info; -#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ - - -extern device_t aha1540b_device; -extern device_t aha1542cf_device; extern device_t buslogic_device; extern device_t buslogic_pci_device; - - -extern int buslogic_dev_present(uint8_t id, uint8_t lun); - -extern void aha154x_init(uint16_t, uint32_t, aha_info *); -extern uint8_t aha154x_shram(uint8_t); -extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); -extern uint8_t aha154x_memory(uint8_t); - - -#endif /*BUSLOGIC_H*/ + + +#endif /*SCSI_BUSLOGIC_H*/ diff --git a/src/scsi_hd.c b/src/scsi_disk.c similarity index 98% rename from src/scsi_hd.c rename to src/scsi_disk.c index 1f2bd2788..31623fbed 100644 --- a/src/scsi_hd.c +++ b/src/scsi_disk.c @@ -65,7 +65,8 @@ uint8_t scsi_hd_command_flags[0x100] = IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ + 0, 0, 0, IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, IMPLEMENTED | CHECK_READY, /* 0x0A */ @@ -174,7 +175,7 @@ int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 3) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) + if ((hdc[i].bus == 4) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) { return i; } @@ -189,7 +190,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) uint64_t signature = 0xD778A82044445459ll; uint64_t full_size = 0; int c; - char *fn = hdd_fn[id]; + wchar_t *fn = hdd_fn[id]; shdc[id].base = 0; @@ -205,7 +206,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) scsi_hard_disks[scsi_id][scsi_lun] = 0xff; return; } - shdf[id] = fopen64(fn, "rb+"); + shdf[id] = _wfopen(fn, L"rb+"); if (shdf[id] == NULL) { /* Failed to open existing hard disk image */ @@ -213,7 +214,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) { /* Failed because it does not exist, so try to create new file */ - shdf[id] = fopen64(fn, "wb+"); + shdf[id] = _wfopen(fn, L"wb+"); if (shdf[id] == NULL) { scsi_hard_disks[scsi_id][scsi_lun] = 0xff; @@ -764,6 +765,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: + case GPCMD_FORMAT_UNIT: case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: @@ -850,11 +852,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x22, 1); + update_status_bar_icon(0x23, 1); } else { - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); } return; @@ -911,11 +913,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x22, 1); + update_status_bar_icon(0x23, 1); } else { - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); } return; @@ -1127,7 +1129,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1140,7 +1142,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1153,7 +1155,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); diff --git a/src/serial.c b/src/serial.c index 4eb78e821..a2b896321 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,295 +1,639 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of NS8250-series UART devices. + * + * The original IBM-PC design did not have any serial ports of + * any kind. Rather, these were offered as add-on devices, most + * likely because a) most people did not need one at the time, + * and, b) this way, IBM could make more money off them. + * + * So, for the PC, the offerings were for an IBM Asynchronous + * Communications Adapter, and, later, a model for synchronous + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. + * + * Of course, many system builders came up with similar boards, + * and even more boards were designed where several I/O functions + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. + * + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. + * + * Based on the 86Box serial port driver as a framework. + * + * Version: @(#)serial.c 1.0.5 2017/05/07 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ #include "ibm.h" #include "io.h" -#include "mouse.h" #include "pic.h" -#include "serial.h" #include "timer.h" +#include "serial.h" +#include "plat-serial.h" -enum -{ - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8 + +enum { + SERINT_LSR = 1, + SERINT_RECEIVE = 2, + SERINT_TRANSMIT = 4, + SERINT_MSR = 8 }; -SERIAL serial1, serial2; -void serial_reset() -{ - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} +/* IER register bits. */ +#define IER_RDAIE (0x01) +#define IER_THREIE (0x02) +#define IER_RXLSIE (0x04) +#define IER_MSIE (0x08) +#define IER_SLEEP (0x10) /* NS16750 */ +#define IER_LOWPOWER (0x20) /* NS16750 */ +#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ -void serial_update_ints(SERIAL *serial) +/* IIR register bits. */ +#define IIR_IP (0x01) +#define IIR_IID (0x0e) +# define IID_IDMDM (0x00) +# define IID_IDTX (0x02) +# define IID_IDRX (0x04) +# define IID_IDERR (0x06) +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) +# define IIR_FIFO64 (0x20) +# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOENB (0xc0) + +/* FCR register bits. */ +#define FCR_FCRFE (0x01) +#define FCR_RFR (0x02) +#define FCR_TFR (0x04) +#define FCR_SELDMA1 (0x08) +#define FCR_FENB64 (0x20) /* 16750 */ +#define FCR_RTLS (0xc0) +# define FCR_RTLS1 (0x00) +# define FCR_RTLS4 (0x40) +# define FCR_RTLS8 (0x80) +# define FCR_RTLS14 (0xc0) + +/* LCR register bits. */ +#define LCR_WLS (0x03) +# define WLS_BITS5 (0x00) +# define WLS_BITS6 (0x01) +# define WLS_BITS7 (0x02) +# define WLS_BITS8 (0x03) +#define LCR_SBS (0x04) +#define LCR_PE (0x08) +#define LCR_EP (0x10) +#define LCR_PS (0x20) +# define PAR_NONE (0x00) +# define PAR_EVEN (LCR_PE | LCR_EP) +# define PAR_ODD (LCR_PE) +# define PAR_MARK (LCR_PE | LCR_PS) +# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) +#define LCR_BC (0x40) +#define LCR_DLAB (0x80) + +/* MCR register bits. */ +#define MCR_DTR (0x01) +#define MCR_RTS (0x02) +#define MCR_OUT1 (0x04) /* 8250 */ +#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ +#define MCR_LMS (0x10) +#define MCR_AUTOFLOW (0x20) /* 16750 + +/* LSR register bits. */ +#define LSR_DR (0x01) +#define LSR_OE (0x02) +#define LSR_PE (0x04) +#define LSR_FE (0x08) +#define LSR_BI (0x10) +#define LSR_THRE (0x20) +#define LSR_TEMT (0x40) +#define LSR_RXFE (0x80) + +/* MSR register bits. */ +#define MSR_DCTS (0x01) +#define MSR_DDSR (0x02) +#define MSR_TERI (0x04) +#define MSR_DDCD (0x08) +#define MSR_CTS (0x10) +#define MSR_DSR (0x20) +#define MSR_RI (0x40) +#define MSR_DCD (0x80) +#define MSR_MASK (0x0f) + + +static SERIAL serial1, /* serial port 1 data */ + serial2; /* serial port 2 data */ + + +static void +update_ints(SERIAL *sp) { - int stat = 0; + int stat = 0; - serial->iir = 1; + sp->iir = IIR_IP; + if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { + /* Line Status interrupt. */ + stat = 1; + sp->iir = IID_IDERR; + } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { + /* Received Data available. */ + stat = 1; + sp->iir = IID_IDRX; + } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { + /* Transmit Data empty. */ + stat = 1; + sp->iir = IID_IDTX; + } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { + /* Modem Status interrupt. */ + stat = 1; + sp->iir = IID_IDMDM; + } - if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ - { - stat = 1; - serial->iir = 6; - } - else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ - { - stat = 1; - serial->iir = 4; - } - else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ - { - stat = 1; - serial->iir = 2; - } - else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ - { - stat = 1; - serial->iir = 0; - } - - if (stat && ((serial->mctrl & 8) || PCJR)) - picintlevel(1 << serial->irq); - else - picintc(1 << serial->irq); + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); } -void serial_write_fifo(SERIAL *serial, uint8_t dat) + +/* Fake interrupt generator, needed for Serial Mouse. */ +static void +serial_timer(void *priv) { - serial->fifo[serial->fifo_write] = dat; - serial->fifo_write = (serial->fifo_write + 1) & 0xFF; - if (!(serial->lsr & 1)) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + SERIAL *sp = (SERIAL *)priv; + + sp->receive_delay = 0; + + if (sp->fifo_read != sp->fifo_write) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } } -uint8_t serial_read_fifo(SERIAL *serial) + +/* Write data to the (input) FIFO. Used by MOUSE driver. */ +void +serial_write_fifo(SERIAL *sp, uint8_t dat) { - if (serial->fifo_read != serial->fifo_write) - { - serial->dat = serial->fifo[serial->fifo_read]; - serial->fifo_read = (serial->fifo_read + 1) & 0xFF; - } - return serial->dat; + /* Stuff data into FIFO. */ + sp->fifo[sp->fifo_write] = dat; + sp->fifo_write = (sp->fifo_write + 1) & 0xFF; + + if (! (sp->lsr & LSR_DR)) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } } -void serial_write(uint16_t addr, uint8_t val, void *p) + +static uint8_t +read_fifo(SERIAL *sp) { - SERIAL *serial = (SERIAL *)p; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - serial->dlab1 = val; - return; - } - serial->thr = val; - serial->lsr |= 0x20; - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - if (serial->mctrl & 0x10) - { - serial_write_fifo(serial, val); - } - break; - case 1: - if (serial->lcr & 0x80) - { - serial->dlab2 = val; - return; - } - serial->ier = val & 0xf; - serial_update_ints(serial); - break; - case 2: - serial->fcr = val; - break; - case 3: - serial->lcr = val; - break; - case 4: - if ((val & 2) && !(serial->mctrl & 2)) - { - if (serial->rcr_callback) - serial->rcr_callback(serial, serial->rcr_callback_p); - } - serial->mctrl = val; - if (val & 0x10) - { - uint8_t new_msr; - - new_msr = (val & 0x0c) << 4; - new_msr |= (val & 0x02) ? 0x10: 0; - new_msr |= (val & 0x01) ? 0x20: 0; - - if ((serial->msr ^ new_msr) & 0x10) - new_msr |= 0x01; - if ((serial->msr ^ new_msr) & 0x20) - new_msr |= 0x02; - if ((serial->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((serial->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - serial->msr = new_msr; - } - break; - case 5: - serial->lsr = val; - if (serial->lsr & 0x01) - serial->int_status |= SERIAL_INT_RECEIVE; - if (serial->lsr & 0x1e) - serial->int_status |= SERIAL_INT_LSR; - if (serial->lsr & 0x20) - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - break; - case 6: - serial->msr = val; - if (serial->msr & 0x0f) - serial->int_status |= SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - serial->scratch = val; - break; - } + if (sp->fifo_read != sp->fifo_write) { + sp->dat = sp->fifo[sp->fifo_read]; + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + } + + return(sp->dat); } -uint8_t serial_read(uint16_t addr, void *p) -{ - SERIAL *serial = (SERIAL *)p; - uint8_t temp = 0; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - temp = serial->dlab1; - break; - } - serial->lsr &= ~1; - serial->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(serial); - temp = serial_read_fifo(serial); - if (serial->fifo_read != serial->fifo_write) - serial->recieve_delay = 1000 * TIMER_USEC; - break; - case 1: - if (serial->lcr & 0x80) - temp = serial->dlab2; - else - temp = serial->ier; - break; - case 2: - temp = serial->iir; - if ((temp & 0xe) == 2) - { - serial->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - } - if (serial->fcr & 1) - temp |= 0xc0; - break; - case 3: - temp = serial->lcr; - break; - case 4: - temp = serial->mctrl; - break; - case 5: - if (serial->lsr & 0x20) - serial->lsr |= 0x40; - serial->lsr |= 0x20; - temp = serial->lsr; - if (serial->lsr & 0x1f) - serial->lsr &= ~0x1e; - serial->int_status &= ~SERIAL_INT_LSR; - serial_update_ints(serial); - break; - case 6: - temp = serial->msr; - serial->msr &= ~0x0f; - serial->int_status &= ~SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - temp = serial->scratch; - break; - } - return temp; +/* BHTTY WRITE COMPLETE handler. */ +static void +serial_wr_done(void *arg) +{ + SERIAL *sp = (SERIAL *)arg; + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } -void serial_recieve_callback(void *p) + +/* Handle a WRITE operation to one of our registers. */ +static void +serial_write(uint16_t addr, uint8_t val, void *priv) { - SERIAL *serial = (SERIAL *)p; - - serial->recieve_delay = 0; - - if (serial->fifo_read != serial->fifo_write) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + SERIAL *sp = (SERIAL *)priv; + uint8_t wl, sb, pa; + uint16_t baud; + long speed; + +#if 0 + pclog("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); +#endif + switch (addr & 0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab1 = val; + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ +#if 0 + bhtty_write((BHTTY *)sp->bh, + sp->thr, serial_wr_done, sp); +#else + bhtty_write((BHTTY *)sp->bh, sp->thr); + serial_wr_done(sp); +#endif + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) + serial_write_fifo(sp, val); + } + + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val); + } + break; + + case 1: /* IER / DLAB2 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab2 = val; + return; + } + sp->ier = (val & IER_MASK); + update_ints(sp); + break; + + case 2: /* FCR */ + sp->fcr = val; + break; + + case 3: /* LCR */ + if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { + /* We dropped DLAB, so handle baudrate. */ + baud = ((sp->dlab2<<8) | sp->dlab1); + if (baud > 0) { + speed = 115200UL/baud; +#if 0 + pclog("Serial%d: divisor %u, baudrate %ld\n", + sp->port, baud, speed); +#endif + if ((sp->bh != NULL) && (speed > 0)) + bhtty_speed((BHTTY *)sp->bh, speed); +#if 0 + } else { + pclog("Serial%d: divisor %u invalid!\n", + sp->port, baud); +#endif + } + } + wl = (val & LCR_WLS) + 5; /* databits */ + sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ + pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#if 0 + pclog("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#endif + if (sp->bh != NULL) + bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; + break; + + case 4: + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { + /* + * This is old code for use by the Serial Mouse + * driver. If the user toggles RTS, serial mice + * are expected to send an ID, to inform any + * enumerator there 'is' something. + */ + if (sp->rts_callback) { + sp->rts_callback(sp->rts_callback_p); +#if 0 + pclog("RTS raised; sending ID\n"); +#endif + } + } + + if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { + if (sp->bh != NULL) { + /* Linked, start reading from host port. */ + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); + } else { + /* Not linked, start RX timer. */ + timer_add(serial_timer, + &sp->receive_delay, + &sp->receive_delay, sp); +#if 0 + pclog("Serial%d: RX timer started!\n",sp->port); +#endif + } + } + sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ + uint8_t new_msr; + + /*FIXME: WTF does this do?? --FvK */ + new_msr = (val & 0x0c) << 4; + new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; + new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; + + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + sp->msr = new_msr; + } + break; + + case 5: + sp->lsr = val; + if (sp->lsr & LSR_DR) + sp->int_status |= SERINT_RECEIVE; + if (sp->lsr & 0x1e) + sp->int_status |= SERINT_LSR; + if (sp->lsr & LSR_THRE) + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + break; + + case 6: + sp->msr = val; + if (sp->msr & MSR_MASK) + sp->int_status |= SERINT_MSR; + update_ints(sp); + break; + + case 7: + sp->scratch = val; + break; + } } -uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; -int serial_irq[2] = { 4, 3 }; -/*Tandy might need COM1 at 2f8*/ -void serial1_init(uint16_t addr, int irq) +/* BHTTY READ COMPLETE handler. */ +static void +serial_rd_done(void *arg, int num) { - memset(&serial1, 0, sizeof(serial1)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial1.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_set(uint16_t addr, int irq) -{ - serial1_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_remove() -{ - io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + SERIAL *sp = (SERIAL *)arg; +#if 0 +pclog("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); +#endif + + /* Stuff the byte in the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + + /* Start up the next read from the real port. */ + if (sp->bh != NULL) + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); } -void serial2_init(uint16_t addr, int irq) + +/* Handle a READ operation from one of our registers. */ +static uint8_t +serial_read(uint16_t addr, void *priv) { - memset(&serial2, 0, sizeof(serial2)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial2.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); - serial_addr[1] = addr; - serial_irq[1] = irq; + SERIAL *sp = (SERIAL *)priv; + uint8_t ret = 0x00; + + switch (addr&0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + ret = sp->dlab1; + break; + } + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; + break; + + case 1: /* LCR / DLAB2 */ + if (sp->lcr & LCR_DLAB) + ret = sp->dlab2; + else + ret = sp->ier; + break; + + case 2: /* IIR */ + ret = sp->iir; + if ((ret & IIR_IID) == IID_IDTX) { + sp->int_status &= ~SERINT_TRANSMIT; + update_ints(sp); + } + if (sp->fcr & 0x01) { + ret |= 0xc0; + } + break; + + case 3: /* LCR */ + ret = sp->lcr; + break; + + case 4: /* MCR */ + ret = sp->mctrl; + break; + + case 5: /* LSR */ + if (sp->lsr & LSR_THRE) + sp->lsr |= LSR_TEMT; + sp->lsr |= LSR_THRE; + ret = sp->lsr; + if (sp->lsr & 0x1f) + sp->lsr &= ~0x1e; +#if 0 + sp->lsr |= (LSR_THRE | LSR_TEMT); +#endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + break; + + case 6: + ret = sp->msr; + sp->msr &= ~0x0f; + sp->int_status &= ~SERINT_MSR; + update_ints(sp); + break; + + case 7: + ret = sp->scratch; + break; + } + + return(ret); } -void serial2_set(uint16_t addr, int irq) + + +/* Set up a serial port for use. */ +void +serial_setup(int port, uint16_t addr, int irq) { - serial2_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial_addr[1] = addr; - serial_irq[1] = irq; + SERIAL *sp; + + pclog("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + /* Set up the basic info. */ + if (sp->addr != 0x0000) { + /* Unlink the previous handler. Just in case. */ + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + } + sp->addr = addr; + sp->irq = irq; + + /* Request an I/O range. */ + io_sethandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + +#if 1 + /* Do not disable here, it breaks the SIO chips. */ +#else + /* No DTR/RTS callback for now. */ + sp->rts_callback = NULL; +#endif } -void serial2_remove() + + +/* Release all resources held by a serial port. */ +void +serial_remove(int port) { - io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + SERIAL *sp; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + // FIXME: stop timer, if enabled! + +#if 1 + /* Do not disable here, it breaks the SIO chips. */ +#else + /* Remove any callbacks. */ + sp->rts_callback = NULL; +#endif + + /* Close the host device. */ + (void)serial_link(port, NULL); + + /* Release our I/O range. */ + if (sp->addr != 0x0000) { + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + } + sp->addr = 0x0000; + sp->irq = 0; +} + + +/* Initialize the serial ports. */ +void +serial_init(void) +{ + memset(&serial1, 0x00, sizeof(SERIAL)); + serial1.port = 1; + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + + memset(&serial2, 0x00, sizeof(SERIAL)); + serial2.port = 2; + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); +} + + +/* + * Reset the serial ports. + * + * This should be a per-port function. + */ +void +serial_reset(void) +{ + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial1.fifo_read = serial1.fifo_write = 0; + + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + + +/* Link a serial port to a host (serial) port. */ +int +serial_link(int port, char *arg) +{ + SERIAL *sp; + BHTTY *bh; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + if (arg != NULL) { + /* Make sure we're not already linked. */ + if (sp->bh != NULL) { + pclog("Serial%d already linked!\n", port); + return(-1); + } + + /* Request a port from the host system. */ + bh = bhtty_open(arg, 0); + if (bh == NULL) { + pclog("Serial%d unable to link to '%s' !\n", port, arg); + return(-1); + } + sp->bh = bh; + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = sp; + } else { + /* If we are linked, unlink it. */ + if (sp->bh != NULL) { + bhtty_close((BHTTY *)sp->bh); + sp->bh = NULL; + } + + } + + return(0); +} + + +/* Attach another device (MOUSE) to a serial port. */ +SERIAL * +serial_attach(int port, void *func, void *arg) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + /* Set up callback info. */ + sp->rts_callback = func; + sp->rts_callback_p = arg; + + return(sp); } diff --git a/src/serial.h b/src/serial.h index 96104068e..bf361a0b1 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,35 +1,64 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void serial1_init(uint16_t addr, int irq); -void serial2_init(uint16_t addr, int irq); -void serial1_set(uint16_t addr, int irq); -void serial2_set(uint16_t addr, int irq); -void serial1_remove(); -void serial2_remove(); -void serial_reset(); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the SERIAL card. + * + * Version: @(#)serial.h 1.0.3 2017/05/07 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef SERIAL_H +# define SERIAL_H -struct SERIAL; -typedef struct -{ - uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; - uint8_t dlab1,dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - int irq; +/* Default settings for the standard ports. */ +#define SERIAL1_ADDR 0x03f8 +#define SERIAL1_IRQ 4 +#define SERIAL2_ADDR 0x02f8 +#define SERIAL2_IRQ 3 - void (*rcr_callback)(struct SERIAL *serial, void *p); - void *rcr_callback_p; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int recieve_delay; + +typedef struct _serial_ { + int8_t port; /* port number (1,2,..) */ + int8_t irq; /* IRQ channel used */ + uint16_t addr; /* I/O address used */ + + uint8_t lsr, thr, mctrl, rcr, /* UART registers */ + iir, ier, lcr, msr; + uint8_t dlab1, dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + /* Data for the RTS-toggle callback. */ + void (*rts_callback)(void *); + void *rts_callback_p; + + uint8_t hold; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int receive_delay; + + void *bh; /* BottomHalf handler */ } SERIAL; -extern SERIAL serial1, serial2; -void serial_write_fifo(SERIAL *serial, uint8_t dat); +/* Functions. */ +extern void serial_init(void); +extern void serial_reset(void); +extern void serial_setup(int port, uint16_t addr, int irq); +extern void serial_remove(int port); +extern SERIAL *serial_attach(int, void *, void *); +extern int serial_link(int, char *); +extern void serial_write_fifo(SERIAL *, uint8_t); + + +#endif /*SERIAL_H*/ diff --git a/src/sio.c b/src/sio.c index a5303935e..9092e0c2e 100644 --- a/src/sio.c +++ b/src/sio.c @@ -7,10 +7,9 @@ word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer */ #include - #include "ibm.h" +#include "cpu/cpu.h" #include "cdrom.h" -#include "cpu.h" #include "disc.h" #include "dma.h" #include "fdc.h" diff --git a/src/sis85c471.c b/src/sis85c471.c index 5d12ae341..e7d5af86c 100644 --- a/src/sis85c471.c +++ b/src/sis85c471.c @@ -58,13 +58,13 @@ process_value: { if (val & 0x20) { - serial1_init(0x3f8, 4); - serial2_init(0x2f8, 3); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); } else { - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); } } diff --git a/src/slirp/ip_input.c b/src/slirp/ip_input.c index fb8f3fcf1..62fd5d202 100644 --- a/src/slirp/ip_input.c +++ b/src/slirp/ip_input.c @@ -37,7 +37,6 @@ * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ - #include "slirp.h" #include "ip_icmp.h" diff --git a/src/slirp/misc.c b/src/slirp/misc.c index b39a4d9a3..90bc2483e 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -82,6 +82,10 @@ inet_aton(cp, ia) } #endif + +extern void pclog(char *fmt, ...); + + /* * Get our IP address and put it in our_addr */ @@ -91,14 +95,14 @@ getouraddr() char buff[512]; struct hostent *he = NULL; #define ANCIENT - #ifdef ANCIENT +#ifdef ANCIENT if (gethostname(buff,500) == 0) he = gethostbyname(buff); if (he) our_addr = *(struct in_addr *)he->h_addr; if (our_addr.s_addr == 0) our_addr.s_addr = loopback_addr.s_addr; - #else +#else if (gethostname(buff,256) == 0) { struct addrinfo hints = { 0 }; @@ -113,8 +117,9 @@ getouraddr() } if (our_addr.s_addr == 0) our_addr.s_addr = loopback_addr.s_addr; - #endif - #undef ANCIENT +#endif +#undef ANCIENT + pclog(" Our IP address: %s (%s)\n", inet_ntoa(our_addr), buff); } //#if SIZEOF_CHAR_P == 8 diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c index 8725b8922..6a9670f12 100644 --- a/src/slirp/slirp.c +++ b/src/slirp/slirp.c @@ -1,22 +1,20 @@ #include "slirp.h" -/* host address */ -struct in_addr our_addr; -/* host dns address */ -struct in_addr dns_addr; -/* host loopback address */ -struct in_addr loopback_addr; -/* address for slirp virtual addresses */ -struct in_addr special_addr; -/* virtual address alias for host */ -struct in_addr alias_addr; +/* Our actual addresses. */ +char slirp_hostname[33]; +struct in_addr our_addr; /* host IP address */ +struct in_addr dns_addr; /* host DNS server */ +struct in_addr loopback_addr; /* host loopback address */ +/* Our SLiRP virtual addresses. */ +struct in_addr special_addr; /* virtual IP address */ +struct in_addr alias_addr; /* virtual address alias for host */ const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 + 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 /* virtual MAC address. */ }; -uint8_t client_ethaddr[6]; +uint8_t client_ethaddr[6]; /* guest's MAC address */ int do_slowtimo; int link_up; @@ -27,10 +25,12 @@ struct ex_list *exec_list; /* XXX: suppress those select globals */ fd_set *global_readfds, *global_writefds, *global_xfds; -char slirp_hostname[33]; + +extern void pclog(const char *, ...); +extern int config_get_int(char *, char *, int); + #ifdef _WIN32 - static int get_dns_addr(struct in_addr *pdns_addr) { FIXED_INFO *FixedInfo=NULL; @@ -62,16 +62,11 @@ static int get_dns_addr(struct in_addr *pdns_addr) pIPAddr = &(FixedInfo->DnsServerList); inet_aton(pIPAddr->IpAddress.String, &tmp_addr); *pdns_addr = tmp_addr; -#if 0 - printf( "DNS Servers:\n" ); - printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); - - pIPAddr = FixedInfo -> DnsServerList.Next; + printf( " DNS Servers:\n" ); while ( pIPAddr ) { - printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); + printf( " Address: %s\n", pIPAddr ->IpAddress.String ); pIPAddr = pIPAddr ->Next; } -#endif if (FixedInfo) { GlobalFree(FixedInfo); FixedInfo = NULL; @@ -117,9 +112,9 @@ static int get_dns_addr(struct in_addr *pdns_addr) return -1; return 0; } - #endif + #ifdef _WIN32 void slirp_cleanup(void) { @@ -127,13 +122,17 @@ void slirp_cleanup(void) } #endif -int slirp_init(void) + +int +slirp_init(void) { - struct in_addr myaddr; - int rc; - char* category = "SLiRP Port Forwarding"; - char key[32]; - int i = 0, udp, from, to; + char* category = "SLiRP Port Forwarding"; + char key[32]; + struct in_addr myaddr; + int i = 0, udp, from, to; + int rc; + + pclog("%s initializing..\n", category); #ifdef SLIRP_DEBUG // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); @@ -165,29 +164,28 @@ debug_init("slirplog.txt",DEBUG_DEFAULT); return -1; inet_aton(CTL_SPECIAL, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); - getouraddr(); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); + inet_aton(CTL_LOCAL, &myaddr); - inet_aton("10.0.2.15",&myaddr); + while (1) { + sprintf(key, "%d_udp", i); + udp = config_get_int(category, key, 0); + sprintf(key, "%d_from", i); + from = config_get_int(category, key, 0); + if (from < 1) + break; + sprintf(key, "%d_to", i); + to = config_get_int(category, key, from); - while (1) { - sprintf(key, "%d_udp", i); - udp = config_get_int(category, key, 0); - sprintf(key, "%d_from", i); - from = config_get_int(category, key, 0); - if (from < 1) - break; - sprintf(key, "%d_to", i); - to = config_get_int(category, key, from); + rc = slirp_redir(udp, from, myaddr, to); + if (rc == 0) + pclog("slirp redir %d -> %d successful\n", from, to); + else + pclog("slirp redir %d -> %d failed (%d)\n", from, to, rc); - rc = slirp_redir(udp, from, myaddr, to); - if (rc == 0) - pclog("slirp redir %d -> %d successful\n", from, to); - else - pclog("slirp redir %d -> %d failed (%d)\n", from, to, rc); - - i++; - } + i++; + } return 0; } @@ -464,7 +462,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) //winsock2.h:549:32: note: expected 'const char *' but argument is of type 'int *' //WINSOCK_API_LINKAGE int PASCAL send(SOCKET,const char*,int,int); JASON //ret = send(so->s, "a", 1, 0); WHY THE HELL WAS THIS HERE?! - ret = send(so->s, &ret, 0, 0); //This is what it should be. + ret = send(so->s, (char *)&ret, 0, 0); //This is what it should be. if (ret < 0) { /* XXXXX Must fix, zero bytes is a NOP */ if (errno == EAGAIN || errno == EWOULDBLOCK || @@ -510,7 +508,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) /* tcp_input will take care of it */ } else { - ret = send(so->s, &ret, 0,0); + ret = send(so->s, (char *)&ret, 0,0); if (ret < 0) { /* XXX */ if (errno == EAGAIN || errno == EWOULDBLOCK || diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index b7b077527..3f4efd0bd 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -328,8 +328,13 @@ extern int do_echo; # define insque_32 insque # define remque_32 remque #else - extern __inline void insque_32 _P((void *, void *)); - extern __inline void remque_32 _P((void *)); +# ifdef NEED_QUE32_INLINE +extern __inline void insque_32 _P((void *, void *)); +extern __inline void remque_32 _P((void *)); +# else +extern void insque_32 _P((void *, void *)); +extern void remque_32 _P((void *)); +# endif #endif #ifndef _WIN32 diff --git a/src/slirp/tcp_input.c b/src/slirp/tcp_input.c index 77006a2d7..97187788d 100644 --- a/src/slirp/tcp_input.c +++ b/src/slirp/tcp_input.c @@ -37,7 +37,6 @@ * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ - #include #include "slirp.h" #include "ip_icmp.h" diff --git a/src/slirp/udp.c b/src/slirp/udp.c index 318ac6400..fbeb3c340 100644 --- a/src/slirp/udp.c +++ b/src/slirp/udp.c @@ -150,6 +150,7 @@ udp_input(m, iphlen) goto bad; } +#ifdef NEED_TFTP /* * handle TFTP */ @@ -157,6 +158,7 @@ udp_input(m, iphlen) tftp_input(m); goto bad; } +#endif /* * Locate pcb for datagram. diff --git a/src/sound_mpu401_uart.c b/src/sound_mpu401_uart.c deleted file mode 100644 index 5d70b5427..000000000 --- a/src/sound_mpu401_uart.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "ibm.h" -#include "io.h" -#include "plat-midi.h" -#include "sound_mpu401_uart.h" - -enum -{ - STATUS_OUTPUT_NOT_READY = 0x40, - STATUS_INPUT_NOT_READY = 0x80 -}; - -static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) -{ - mpu401_uart_t *mpu = (mpu401_uart_t *)p; - - if (addr & 1) /*Command*/ - { - switch (val) - { - case 0xff: /*Reset*/ - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; - mpu->uart_mode = 0; - break; - - case 0x3f: /*Enter UART mode*/ - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; - mpu->uart_mode = 1; - break; - } - return; - } - - /*Data*/ - if (mpu->uart_mode) - midi_write(val); -} - -static uint8_t mpu401_uart_read(uint16_t addr, void *p) -{ - mpu401_uart_t *mpu = (mpu401_uart_t *)p; - - if (addr & 1) /*Status*/ - return mpu->status; - - /*Data*/ - mpu->status |= STATUS_INPUT_NOT_READY; - return mpu->rx_data; -} - -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr) -{ - mpu->status = STATUS_INPUT_NOT_READY; - mpu->uart_mode = 0; - - io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); -} diff --git a/src/sound_mpu401_uart.h b/src/sound_mpu401_uart.h deleted file mode 100644 index 893c53fc4..000000000 --- a/src/sound_mpu401_uart.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct mpu401_uart_t -{ - uint8_t status; - uint8_t rx_data; - - int uart_mode; -} mpu401_uart_t; - -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr); diff --git a/src/tandy_eeprom.c b/src/tandy_eeprom.c index 391b9c12f..8d1a9eff2 100644 --- a/src/tandy_eeprom.c +++ b/src/tandy_eeprom.c @@ -4,7 +4,9 @@ #include #include "ibm.h" #include "device.h" +#include "mem.h" #include "io.h" +#include "rom.h" #include "tandy_eeprom.h" typedef struct @@ -124,10 +126,10 @@ void *tandy_eeprom_init() switch (romset) { case ROM_TANDY1000HX: - f = romfopen(nvr_concat("tandy1000hx.bin"), "rb"); + f = nvrfopen(L"tandy1000hx.bin", L"rb"); break; case ROM_TANDY1000SL2: - f = romfopen(nvr_concat("tandy1000sl2.bin"), "rb"); + f = nvrfopen(L"tandy1000sl2.bin", L"rb"); break; } if (f) @@ -151,10 +153,10 @@ void tandy_eeprom_close(void *p) switch (eeprom->romset) { case ROM_TANDY1000HX: - f = romfopen(nvr_concat("tandy1000hx.bin"), "wb"); + f = nvrfopen(L"tandy1000hx.bin", L"wb"); break; case ROM_TANDY1000SL2: - f = romfopen(nvr_concat("tandy1000sl2.bin"), "wb"); + f = nvrfopen(L"tandy1000sl2.bin", L"wb"); break; } fwrite(eeprom->store, 128, 1, f); diff --git a/src/tandy_rom.c b/src/tandy_rom.c index fb4c6bdfd..a3b912c5f 100644 --- a/src/tandy_rom.c +++ b/src/tandy_rom.c @@ -6,6 +6,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "tandy_rom.h" static uint8_t *tandy_rom; @@ -52,8 +53,8 @@ void *tandy_rom_init() tandy_rom = malloc(0x80000); - f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); - ff = romfopen("roms/tandy1000sl2/8079048.hu2","rb"); + f = romfopen(L"roms/tandy1000sl2/8079047.hu1", L"rb"); + ff = romfopen(L"roms/tandy1000sl2/8079048.hu2", L"rb"); for (c = 0x0000; c < 0x80000; c += 2) { tandy_rom[c] = getc(f); diff --git a/src/timer.h b/src/timer.h index 50c83e55c..bdc77493b 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,6 @@ #ifndef _TIMER_H_ #define _TIMER_H_ -#include "cpu.h" extern int timer_start; @@ -40,11 +39,11 @@ extern int timer_start; timer_update_outstanding(); \ } while (0) -void timer_process(); -void timer_update_outstanding(); -void timer_reset(); -int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv); -void timer_set_callback(int timer, void (*callback)(void *priv)); +extern void timer_process(void); +extern void timer_update_outstanding(void); +extern void timer_reset(void); +extern int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv); +extern void timer_set_callback(int timer, void (*callback)(void *priv)); #define TIMER_ALWAYS_ENABLED &timer_one diff --git a/src/um8669f.c b/src/um8669f.c index a20b1589e..00433f24c 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -92,10 +92,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) temp |= 2; switch (temp) { - case 0: serial1_set(0x3f8, 4); break; - case 1: serial1_set(0x2f8, 4); break; - case 2: serial1_set(0x3e8, 4); break; - case 3: serial1_set(0x2e8, 4); break; + case 0: serial_setup(1, 0x3f8, 4); break; + case 1: serial_setup(1, 0x2f8, 4); break; + case 2: serial_setup(1, 0x3e8, 4); break; + case 3: serial_setup(1, 0x2e8, 4); break; } } @@ -106,10 +106,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) temp |= 2; switch (temp) { - case 0: serial2_set(0x3f8, 3); break; - case 1: serial2_set(0x2f8, 3); break; - case 2: serial2_set(0x3e8, 3); break; - case 3: serial2_set(0x2e8, 3); break; + case 0: serial_setup(2, 0x3f8, 3); break; + case 1: serial_setup(2, 0x2f8, 3); break; + case 2: serial_setup(2, 0x3e8, 3); break; + case 3: serial_setup(2, 0x2e8, 3); break; } } diff --git a/src/w83877f.c b/src/w83877f.c index ebb22513d..cb980df09 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -340,15 +340,15 @@ process_value: case 4: if (valxor & 0x10) { - serial2_remove(); - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + serial_remove(2); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } if (valxor & 0x20) { - serial1_remove(); + serial_remove(1); if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } if (valxor & 0x80) @@ -407,28 +407,28 @@ process_value: { if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } break; case 0x25: if (valxor & 0xfe) { - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } break; case 0x28: if (valxor & 0xf) { if ((w83877f_regs[0x28] & 0xf) == 0) w83877f_regs[0x28] |= 0x3; - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } if (valxor & 0xf0) { if ((w83877f_regs[0x28] & 0xf0) == 0) w83877f_regs[0x28] |= 0x40; if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } break; @@ -498,8 +498,8 @@ void w83877f_reset(void) disable_write = 0; fdc_update_drv2en(1); fdd_setswap(0); - serial1_set(0x3f8, 4); - serial2_set(0x2f8, 3); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); w83877f_remap(); w83877f_locked = 0; w83877f_rw_locked = 0; diff --git a/src/wd76c10.c b/src/wd76c10.c index 595a1d6f3..9644058ae 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -50,17 +50,17 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) switch ((val >> 5) & 7) { - case 1: serial1_set(0x3f8, 4); break; - case 2: serial1_set(0x2f8, 4); break; - case 3: serial1_set(0x3e8, 4); break; - case 4: serial1_set(0x2e8, 4); break; + case 1: serial_setup(1, 0x3f8, 4); break; + case 2: serial_setup(1, 0x2f8, 4); break; + case 3: serial_setup(1, 0x3e8, 4); break; + case 4: serial_setup(1, 0x2e8, 4); break; } switch ((val >> 1) & 7) { - case 1: serial2_set(0x3f8, 3); break; - case 2: serial2_set(0x2f8, 3); break; - case 3: serial2_set(0x3e8, 3); break; - case 4: serial2_set(0x2e8, 3); break; + case 1: serial_setup(2, 0x3f8, 3); break; + case 2: serial_setup(2, 0x2f8, 3); break; + case 3: serial_setup(2, 0x3e8, 3); break; + case 4: serial_setup(2, 0x2e8, 3); break; } break; diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index b3378e1e6..dff2e0d6f 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -3,28 +3,31 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP #include #include "86box.h" -#include "resource.h" -#include "video.h" +#include "video/video.h" #include "win-d3d-fs.h" #include "win.h" #include "win-cgapal.h" +#include "resource.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); -static void d3d_fs_init_objects(); -static void d3d_fs_close_objects(); +static void d3d_fs_init_objects(void); +static void d3d_fs_close_objects(void); static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); + static LPDIRECT3D9 d3d = NULL; static LPDIRECT3DDEVICE9 d3ddev = NULL; @@ -107,7 +110,7 @@ static CUSTOMVERTEX d3d_verts[] = {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; -void cgapal_rebuild() +void cgapal_rebuild(void) { int c; for (c = 0; c < 256; c++) @@ -133,7 +136,7 @@ void cgapal_rebuild() int d3d_fs_init(HWND h) { HRESULT hr; - char emulator_title[200]; + WCHAR emulator_title[200]; d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); @@ -142,7 +145,7 @@ int d3d_fs_init(HWND h) d3d_hwnd = h; - sprintf(emulator_title, "86Box v%s", emulator_version); + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); d3d_device_window = CreateWindowEx ( 0, szSubClassName, @@ -194,7 +197,7 @@ int d3d_fs_init(HWND h) return 1; } -static void d3d_fs_close_objects() +static void d3d_fs_close_objects(void) { if (d3dTexture) { @@ -208,7 +211,7 @@ static void d3d_fs_close_objects() } } -static void d3d_fs_init_objects() +static void d3d_fs_init_objects(void) { D3DLOCKED_RECT dr; RECT r; @@ -255,7 +258,7 @@ static void d3d_fs_init_objects() d3d_reset(); }*/ -void d3d_fs_reset() +void d3d_fs_reset(void) { HRESULT hr; @@ -290,7 +293,7 @@ void d3d_fs_reset() device_force_redraw(); } -void d3d_fs_close() +void d3d_fs_close(void) { if (d3dTexture) { @@ -393,7 +396,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), (uint32_t *) &(buffer32->line[yy + y][x]), w * 4); + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); @@ -570,7 +573,7 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) PostMessage(ghwnd, WM_RESETD3D, 0, 0); } -void d3d_fs_take_screenshot(char *fn) +void d3d_fs_take_screenshot(wchar_t *fn) { LPDIRECT3DSURFACE9 d3dSurface = NULL; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 561873c58..abfce0bfb 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -2,23 +2,26 @@ see COPYING for more details */ #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP #include #include "resource.h" #include "win-d3d.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); -extern "C" void video_blit_complete(); +extern "C" void device_force_redraw(void); +extern "C" void video_blit_complete(void); -void d3d_init_objects(); -void d3d_close_objects(); + +void d3d_init_objects(void); +void d3d_close_objects(void); void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); void d3d_blit_memtoscreen_8(int x, int y, int w, int h); @@ -91,7 +94,7 @@ int d3d_init(HWND h) return 1; } -void d3d_close_objects() +void d3d_close_objects(void) { if (d3dTexture) { @@ -105,7 +108,7 @@ void d3d_close_objects() } } -void d3d_init_objects() +void d3d_init_objects(void) { D3DLOCKED_RECT dr; RECT r; @@ -149,7 +152,7 @@ void d3d_resize(int x, int y) d3d_reset(); } -void d3d_reset() +void d3d_reset(void) { HRESULT hr; @@ -184,7 +187,7 @@ void d3d_reset() device_force_redraw(); } -void d3d_close() +void d3d_close(void) { if (d3dTexture) { @@ -380,7 +383,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); } -void d3d_take_screenshot(char *fn) +void d3d_take_screenshot(wchar_t *fn) { LPDIRECT3DSURFACE9 d3dSurface = NULL; diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 9c7bedbb0..9fc355c63 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -2,23 +2,25 @@ see COPYING for more details */ #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP #include "win-ddraw-fs.h" #include "win-ddraw-screenshot.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" int ddraw_fs_init(HWND h); -extern "C" void ddraw_fs_close(); +extern "C" void ddraw_fs_close(void); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); @@ -90,7 +92,7 @@ int ddraw_fs_init(HWND h) return 1; } -void ddraw_fs_close() +void ddraw_fs_close(void) { if (lpdds_back2) { @@ -201,7 +203,7 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h } for (yy = y1; yy < y2; yy++) { - if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), ((uint32_t *) &(((uint8_t *)buffer32->line[y + yy]))[x]), w * 4); + if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } video_blit_complete(); lpdds_back->Unlock(NULL); @@ -330,7 +332,7 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); } -void ddraw_fs_take_screenshot(char *fn) +void ddraw_fs_take_screenshot(wchar_t *fn) { ddraw_common_take_screenshot(fn, lpdds_back2); } diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc index 55c2ff730..e8a891fe9 100644 --- a/src/win-ddraw-screenshot.cc +++ b/src/win-ddraw-screenshot.cc @@ -3,19 +3,23 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP +#include "win.h" #include "win-ddraw-screenshot.h" -#include "video.h" +#include "win-language.h" +#include "video/video.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" void ddraw_init(HWND h); -extern "C" void ddraw_close(); +extern "C" void ddraw_close(void); HBITMAP hbitmap; @@ -64,7 +68,9 @@ void DoubleLines(uint8_t *dst, uint8_t *src) } } -void SaveBitmap(char *szFilename,HBITMAP hBitmap) +static WCHAR szMessage[2048]; + +void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; @@ -73,8 +79,6 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; - char szMessage[2048]; - do{ hdc=GetDC(NULL); @@ -103,10 +107,10 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); - if((fp = fopen(szFilename,"wb"))==NULL) + if((fp = _wfopen(szFilename,L"wb"))==NULL) { - sprintf(szMessage, "Unable to Create Bitmap File %s", szFilename); - MessageBox( NULL, szMessage, "Error", MB_OK|MB_ICONERROR); + _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); + msgbox_error_wstr(ghwnd, szMessage); break; } @@ -151,7 +155,7 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) if(fp) fclose(fp); } -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface) +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface) { xs = xsize; ys = ys2 = ysize; diff --git a/src/win-ddraw-screenshot.h b/src/win-ddraw-screenshot.h index 7c56e5f96..4739174a1 100644 --- a/src/win-ddraw-screenshot.h +++ b/src/win-ddraw-screenshot.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface); +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 347c6a752..509124205 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -3,23 +3,25 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP #include "win-ddraw.h" #include "win-ddraw-screenshot.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" int ddraw_init(HWND h); -extern "C" void ddraw_close(); +extern "C" void ddraw_close(void); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); @@ -95,7 +97,7 @@ int ddraw_init(HWND h) return 1; } -void ddraw_close() +void ddraw_close(void) { if (lpdds_back2) { @@ -310,7 +312,7 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) } } -void ddraw_take_screenshot(char *fn) +void ddraw_take_screenshot(wchar_t *fn) { ddraw_common_take_screenshot(fn, lpdds_back2); } diff --git a/src/win-keyboard.cc b/src/win-keyboard.cc deleted file mode 100644 index 16381cd4c..000000000 --- a/src/win-keyboard.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#include -#include -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "plat-keyboard.h" -#include "win.h" -#include "video.h" - -extern "C" int recv_key[272]; - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void keyboard_init(); -extern "C" void keyboard_close(); -extern "C" void keyboard_poll(); - -int recv_key[272]; - -void keyboard_init() -{ - atexit(keyboard_close); - - memset(recv_key, 0, sizeof(recv_key)); - pclog("Keyboard initialized!\n"); -} - -void keyboard_close() -{ -} - -void keyboard_poll_host() -{ -#if 0 - int c; - - for (c = 0; c < 272; c++) - recv_key[c] = rawinputkey[c]; - - if ((rawinputkey[0x1D] || rawinputkey[0x9D]) && - (rawinputkey[0x38] || rawinputkey[0xB8]) && - (rawinputkey[0x51] || rawinputkey[0xD1]) && - video_fullscreen) - leave_fullscreen(); - - if ((rawinputkey[0x1D] || rawinputkey[0x9D]) && -// (rawinputkey[0x38] || rawinputkey[0xB8]) && - (rawinputkey[0x57] || rawinputkey[0x57])) - { - pclog("Taking screenshot...\n"); - take_screenshot(); - } -#endif -} diff --git a/src/win-language.c b/src/win-language.c index 353fb1302..333729302 100644 --- a/src/win-language.c +++ b/src/win-language.c @@ -21,11 +21,12 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 148 +#define STRINGS_NUM 152 WCHAR lpResourceString[STRINGS_NUM][512]; char openfilestring[260]; +WCHAR wopenfilestring[260]; void win_language_set() { @@ -94,11 +95,21 @@ void msgbox_info(HWND hwndParent, int i) MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); } +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + void msgbox_error(HWND hwndParent, int i) { MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); } +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); +} + void msgbox_critical(HWND hwndParent, int i) { MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); @@ -116,27 +127,22 @@ void msgbox_fatal(HWND hwndParent, char *string) free(lptsTemp); } -int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) { OPENFILENAME ofn; /* common dialog box structure */ BOOL r; DWORD err; - WCHAR ufn[260]; - WCHAR uofs[260]; - - /* Convert file name to Unicode */ - mbstowcs(ufn, fn, strlen(fn) + 1); /* Initialize OPENFILENAME */ ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; - ofn.lpstrFile = uofs; + ofn.lpstrFile = wopenfilestring; /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not use the contents of szFile to initialize itself. */ - memcpy(ofn.lpstrFile, ufn, (wcslen(ufn) << 1) + 2); + memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); ofn.nMaxFile = 259; ofn.lpstrFilter = f; ofn.nFilterIndex = 1; @@ -163,7 +169,7 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) } if (r) { - wcstombs(openfilestring, uofs, 520); + wcstombs(openfilestring, wopenfilestring, 520); pclog("File dialog return true\n"); return 0; } @@ -173,6 +179,18 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) return 1; } +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +{ + WCHAR ufn[512]; + mbstowcs(ufn, fn, strlen(fn) + 1); + return file_dlg_w(hwnd, f, ufn, save); +} + +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) +{ + file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); +} + int file_dlg_st(HWND hwnd, int i, char *fn, int save) { file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); diff --git a/src/win-language.h b/src/win-language.h index 47fde8df8..113c16f44 100644 --- a/src/win-language.h +++ b/src/win-language.h @@ -1,12 +1,20 @@ +#ifdef __cplusplus +extern "C" { +#endif + int msgbox_reset(HWND hwndParent); int msgbox_reset_yn(HWND hwndParent); int msgbox_question(HWND hwndParent, int i); void msgbox_info(HWND hwndParent, int i); +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr); void msgbox_error(HWND hwndParent, int i); +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr); void msgbox_fatal(HWND hwndParent, char *string); void msgbox_critical(HWND hwndParent, int i); +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save); int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save); int file_dlg_st(HWND hwnd, int i, char *fn, int save); void win_language_load_common_strings(); @@ -17,3 +25,7 @@ void win_language_check(); LPTSTR win_language_get_string_from_id(int i); LPTSTR win_language_get_string_from_string(char *str); + +#ifdef __cplusplus +} +#endif diff --git a/src/win-midi.c b/src/win-midi.c index 8fa56c768..621510ab2 100644 --- a/src/win-midi.c +++ b/src/win-midi.c @@ -10,21 +10,33 @@ static int midi_id; static HMIDIOUT midi_out_device = NULL; +HANDLE m_event; + void midi_close(); void midi_init() { - MMRESULT hr; + MMRESULT hr = MMSYSERR_NOERROR; midi_id = config_get_int(NULL, "midi", 0); + m_event = CreateEvent(NULL, TRUE, TRUE, NULL); + +#if 0 hr = midiOutOpen(&midi_out_device, midi_id, 0, 0, CALLBACK_NULL); +#endif + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { printf("midiOutOpen error - %08X\n",hr); midi_id = 0; +#if 0 hr = midiOutOpen(&midi_out_device, midi_id, 0, 0, CALLBACK_NULL); +#endif + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { printf("midiOutOpen error - %08X\n",hr); return; @@ -41,6 +53,7 @@ void midi_close() midiOutReset(midi_out_device); midiOutClose(midi_out_device); midi_out_device = NULL; + CloseHandle(m_event); } } @@ -81,6 +94,7 @@ static void midi_send_sysex() midi_insysex = 0; } +#if 0 void midi_write(uint8_t val) { if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) @@ -111,3 +125,186 @@ void midi_write(uint8_t val) midiOutShortMsg(midi_out_device, midi_command); } } +#endif + +static uint8_t midi_rt_buf[1024] = { 0, 0, 0, 0 }; +static uint8_t midi_cmd_buf[1024] = { 0, 0, 0, 0 }; +static int midi_cmd_pos = 0; +static int midi_cmd_len = 0; +static uint8_t midi_status = 0; +static int midi_sysex_start = 0; +static int midi_sysex_delay = 0; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + +void PlayMsg(uint8_t *msg) +{ + midiOutShortMsg(midi_out_device, *(uint32_t *) msg); +} + +MIDIHDR m_hdr; + +void PlaySysex(uint8_t *sysex, unsigned int len) +{ + MMRESULT result; + + if (WaitForSingleObject(m_event, 2000) == WAIT_TIMEOUT) + { + pclog("Can't send MIDI message\n"); + return; + } + + midiOutUnprepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + m_hdr.lpData = (char *) sysex; + m_hdr.dwBufferLength = len; + m_hdr.dwBytesRecorded = len; + m_hdr.dwUser = 0; + + result = midiOutPrepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + if (result != MMSYSERR_NOERROR) return; + ResetEvent(m_event); + result = midiOutLongMsg(midi_out_device, &m_hdr, sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) + { + SetEvent(m_event); + return; + } +} + +#define SYSEX_SIZE 1024 +#define RAWBUF 1024 + +int GetTicks() +{ +} + +void midi_write(uint8_t val) +{ + /* Test for a realtime MIDI message */ + if (val >= 0xf8) + { + midi_rt_buf[0] = val; + PlayMsg(midi_rt_buf); + return; + } + + /* Test for a active sysex transfer */ + + if (midi_status == 0xf0) + { + if (!(val & 0x80)) + { + if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; + return; + } + else + { + midi_sysex_data[midi_pos++] = 0xf7; + + if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) + { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } + else + { + PlaySysex(midi_sysex_data, midi_pos); + if (midi_sysex_start) + { + if (midi_sysex_data[5] == 0x7f) + { + midi_sysex_delay = 290; /* All parameters reset */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) + { + midi_sysex_delay = 145; /* Viking Child */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) + { + midi_sysex_delay = 30; /* Dark Sun 1 */ + } + else + midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + + midi_sysex_start = GetTicks(); + } + } + } + } + + + if (val & 0x80) + { + midi_status = val; + midi_cmd_pos = 0; + midi_cmd_len = MIDI_evt_len[val]; + if (midi_status == 0xf0) + { + midi_sysex_data[0] = 0xf0; + midi_pos = 1; + } + } + + if (midi_cmd_len) + { + midi_cmd_buf[midi_cmd_pos++] = val; + if (midi_cmd_pos >= midi_cmd_len) + { + PlayMsg(midi_cmd_buf); + midi_cmd_pos = 1; + } + } +} + +void midi_reset() +{ + uint8_t buf[64], used; + + /* Flush buffers */ + midiOutReset(midi_out_device); + + /* GM1 reset */ + buf[0] = 0xf0; + buf[1] = 0x7e; + buf[2] = 0x7f; + buf[3] = 0x09; + buf[4] = 0x01; + buf[5] = 0xf7; + PlaySysex((uint8_t *) buf, 6); + + /* GS1 reset */ + buf[0] = 0xf0; + buf[1] = 0x41; + buf[2] = 0x10; + buf[3] = 0x42; + buf[4] = 0x12; + buf[5] = 0x40; + buf[6] = 0x00; + buf[7] = 0x7f; + buf[8] = 0x00; + buf[9] = 0x41; + buf[10] = 0xf7; + PlaySysex((uint8_t *) buf, 11); +} diff --git a/src/win-opendir.c b/src/win-opendir.c new file mode 100644 index 000000000..847265582 --- /dev/null +++ b/src/win-opendir.c @@ -0,0 +1,213 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation POSIX OpenDir(3) and friends for Win32 API. + * + * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 + * + * Version: @(#)win-opendir.c 1.0.1 2017/05/12 + * + * Author: Fred N. van Kempen, + * Copyright 1998-2007 MicroWalt Corporation + * Copyright 2017 Fred N. van Kempen + */ +#define UNICODE +#include +#include +#include +#include +#include +#include +#include "ibm.h" +#include "plat-dir.h" + + +#ifdef UNICODE +# define SUFFIX L"\\*" +# define FINDATA struct _wfinddata_t +# define FINDFIRST _wfindfirst +# define FINDNEXT _wfindnext +#else +# define SUFFIX "\\*" +# define FINDATA struct _finddata_t +# define FINDFIRST _findfirst +# define FINDNEXT _findnext +#endif + + +/* Open a directory. */ +DIR * +#ifdef UNICODE +opendirw(const wchar_t *name) +#else +opendir(const char *name) +#endif +{ + DIR *p; + + /* Create a new control structure. */ + p = (DIR *) malloc(sizeof(DIR)); + if (p == NULL) + return(NULL); + memset(p, 0x00, sizeof(DIR)); + p->flags = (DIR_F_LOWER | DIR_F_SANE); + p->offset = 0; + p->sts = 0; + + /* Create a work area. */ + p->dta = (char *)malloc(sizeof(FINDATA)); + if (p->dta == NULL) { + free(p); + return(NULL); + } + memset(p->dta, 0x00, sizeof(struct _finddata_t)); + + /* Add search filespec. */ +#ifdef UNICODE + wcscpy(p->dir, name); + wcscat(p->dir, SUFFIX); +#else + strcpy(p->dir, name); + strcat(p->dir, SUFFIX); +#endif + + /* Special case: flag if we are in the root directory. */ +#ifdef UNICODE + if (wcslen(p->dir) == 3) +#else + if (strlen(p->dir) == 3) +#endif + p->flags |= DIR_F_ISROOT; + + /* Start the searching by doing a FindFirst. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + free(p->dta); + free(p); + return(NULL); + } + + /* All OK. */ + return(p); +} + + +/* Close an open directory. */ +int +closedir(DIR *p) +{ + if (p == NULL) + return(0); + + _findclose(p->handle); + + if (p->dta != NULL) + free(p->dta); + free(p); + + return(0); +} + + +/* + * Read the next entry from a directory. + * Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS + * file systems do not have a root directory containing the UNIX- + * standard "." and ".." entries. Many applications do assume + * this anyway, so we simply fake these entries. + */ +struct direct * +readdir(DIR *p) +{ + FINDATA *ffp; + + if (p == NULL || p->sts == 1) + return(NULL); + + /* Format structure with current data. */ + ffp = (FINDATA *)p->dta; + p->dent.d_ino = 1L; + p->dent.d_off = p->offset++; + switch(p->offset) { + case 1: /* . */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L".", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ".", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 1; + break; + + case 2: /* .. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L"..", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, "..", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 2; + break; + + default: /* regular entry. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#endif + p->dent.d_reclen = (char) wcslen(p->dent.d_name); + } + + /* Read next entry. */ + p->sts = 0; + + /* Fake the "." and ".." entries here.. */ + if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2)) + return(&(p->dent)); + + /* Get the next entry if we did not fake the above. */ + if (FINDNEXT(p->handle, ffp) < 0) + p->sts = 1; + + return(&(p->dent)); +} + + +/* Report current position within the directory. */ +long +telldir(DIR *p) +{ + return(p->offset); +} + + +void +seekdir(DIR *p, long newpos) +{ + short pos; + + /* First off, rewind to start of directory. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + p->sts = 1; + return; + } + p->offset = 0; + p->sts = 0; + + /* If we are rewinding, that's all... */ + if (newpos == 0L) return; + + /* Nope.. read entries until we hit the right spot. */ + pos = (short) newpos; + while (p->offset != pos) { + p->offset++; + if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) { + p->sts = 1; + return; + } + } +} diff --git a/src/serial_bh.c b/src/win-serial.c similarity index 99% rename from src/serial_bh.c rename to src/win-serial.c index 23ec556e8..fb92b8bea 100644 --- a/src/serial_bh.c +++ b/src/win-serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)serial_bh.c 1.0.1 2017/04/14 + * Version: @(#)win-serial.c 1.0.2 2017/05/05 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -22,7 +22,7 @@ #include #include #define BHTTY_C -#include "serial_bh.h" +#include "plat-serial.h" extern void pclog(char *__fmt, ...); diff --git a/src/win-settings.c b/src/win-settings.c index 4790ce717..3e48e898d 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -8,35 +8,35 @@ #undef BITMAP #include - #include - -#include "nethandler.h" #include "ibm.h" -#include "ide.h" -#include "cdrom.h" -#include "cpu.h" +#include "mem.h" +#include "cpu/cpu.h" +#include "nvr.h" +#include "model.h" #include "device.h" -#include "scsi_buslogic.h" +#include "cdrom.h" #include "disc.h" #include "fdd.h" -#include "gameport.h" #include "hdd.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "nvr.h" -#include "resource.h" +#include "ide.h" #include "scsi.h" -#include "sound.h" -#include "sound_dbopl.h" -#include "video.h" -#include "vid_voodoo.h" +#include "scsi_buslogic.h" +#include "network.h" +#include "sound/sound.h" +#include "sound/snd_dbopl.h" +#include "video/video.h" +#include "video/vid_voodoo.h" +#include "gameport.h" +#include "mouse.h" #include "win.h" #include "win-language.h" +#include "resource.h" + #define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + /* Machine category */ int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; @@ -57,7 +57,7 @@ char temp_hdc_name[16]; /* Hard disks category */ hard_disk_t temp_hdc[HDC_NUM]; -char temp_hdd_fn[HDC_NUM][512]; +wchar_t temp_hdd_fn[HDC_NUM][512]; /* Removable devices category */ int temp_fdd_types[FDD_NUM]; @@ -109,7 +109,7 @@ static void win_settings_init() /* Peripherals category */ temp_scsi_card = scsi_card_current; - temp_net_card = network_card_current; + temp_net_card = network_card; strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); temp_ide_ter = ide_enable[2]; temp_ide_ter_irq = ide_irq[2]; @@ -124,7 +124,7 @@ static void win_settings_init() memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(temp_hdd_fn[i], hdd_fn[i], 512); + memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); } /* Removable devices category */ @@ -168,7 +168,7 @@ static int win_settings_changed() /* Peripherals category */ i = i || (scsi_card_current != temp_scsi_card); - i = i || (network_card_current != temp_net_card); + i = i || (network_card != temp_net_card); i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); i = i || (temp_ide_ter != ide_enable[2]); i = i || (temp_ide_ter_irq != ide_irq[2]); @@ -183,7 +183,7 @@ static int win_settings_changed() i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); for (j = 0; j < HDC_NUM; j++) { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 512); + i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); } /* Removable devices category */ @@ -259,7 +259,7 @@ static void win_settings_save() /* Peripherals category */ scsi_card_current = temp_scsi_card; - network_card_current = temp_net_card; + network_card = temp_net_card; strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); ide_enable[2] = temp_ide_ter; ide_irq[2] = temp_ide_ter_irq; @@ -274,7 +274,7 @@ static void win_settings_save() memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(hdd_fn[i], temp_hdd_fn[i], 512); + memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); } /* Removable devices category */ @@ -825,29 +825,26 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa default: str_id = 2139; break; - case 1: /* MS InPort Bus */ - str_id = 2177; - break; - case 2: /* PS2 2b */ - str_id = 2140; - break; - case 3: /* MS/logi bus 2b */ - str_id = 2161; - break; - case 4: /* PS2 intelli 3b */ + case 1: /* PS2 2b */ str_id = 2141; break; - case 5: /* Amstrad */ + case 2: /* PS2 intelli 3b */ str_id = 2142; break; - case 6: /* Olivetti M24 */ + case 3: /* MS/logi bus 2b */ str_id = 2143; break; - case 7: /* MouseSystems */ + case 4: /* Amstrad */ str_id = 2162; break; - case 8: /* Genius Bus */ - str_id = 2178; + case 5: /* Olivetti M24 */ + str_id = 2177; + break; + case 6: /* MouseSystems */ + str_id = 2140; + break; + case 7: /* Genius Bus */ + str_id = 2161; break; } @@ -1460,7 +1457,7 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); - for (i = 0; i < 6; i += 2) + for (i = 0; i < 8; i += 2) { hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); ImageList_AddIcon(hSmall, hiconItem); @@ -1474,29 +1471,25 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) int next_free_id = 0; +wchar_t ifn[HDC_NUM][512]; + static void normalize_hd_list() { hard_disk_t ihdc[HDC_NUM]; - char ifn[HDC_NUM][512]; int i, j; j = 0; memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memset(ifn[i], 0, 512); + memset(ifn[i], 0, 1024); } for (i = 0; i < HDC_NUM; i++) { - if ((temp_hdc[i].bus == 3) && (temp_hdc[i].scsi_id == 7)) - { - /* SCSI ID 7 is the host adapter, so any hard disk set to SCSI bus and ID 7 is to be treated as disabled and marked as such. */ - temp_hdc[i].bus = 0; - } if (temp_hdc[i].bus > 0) { memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 512); + memcpy(ifn[j], temp_hdd_fn[i], 1024); j++; } } @@ -1504,7 +1497,7 @@ static void normalize_hd_list() memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(temp_hdd_fn[i], ifn[i], 512); + memcpy(temp_hdd_fn[i], ifn[i], 1024); } } @@ -1542,9 +1535,9 @@ static void add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2166 + i)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); } h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); @@ -1625,7 +1618,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; - case 1: /* IDE */ + case 1: /* IDE (PIO-only) */ + case 2: /* IDE (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1635,7 +1629,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); break; - case 2: /* SCSI */ + case 3: /* SCSI */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1663,8 +1657,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) ShowWindow(h, SW_HIDE); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); + EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); } else { @@ -1684,7 +1677,8 @@ static void recalc_next_free_id(HWND hdlg) int i; int c_mfm = 0; - int c_ide = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; int c_scsi = 0; int enable_add = 0; @@ -1698,9 +1692,13 @@ static void recalc_next_free_id(HWND hdlg) } else if (temp_hdc[i].bus == 2) { - c_ide++; + c_ide_pio++; } else if (temp_hdc[i].bus == 3) + { + c_ide_dma++; + } + else if (temp_hdc[i].bus == 4) { c_scsi++; } @@ -1719,7 +1717,7 @@ static void recalc_next_free_id(HWND hdlg) enable_add = enable_add || (next_free_id >= 0); /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); /* pclog("Enable add: %i\n", enable_add); */ h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); @@ -1746,7 +1744,7 @@ static void recalc_next_free_id(HWND hdlg) h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - if ((c_mfm == 0) && (c_ide == 0) && (c_scsi == 0)) + if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) { EnableWindow(h, FALSE); } @@ -1775,9 +1773,12 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case 2: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } @@ -1786,8 +1787,7 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column } else if (column == 1) { - mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); - lvI.pszText = szText; + lvI.pszText = temp_hdd_fn[i]; lvI.iImage = 0; } else if (column == 2) @@ -1848,9 +1848,12 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case 2: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } @@ -1864,8 +1867,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 1; - mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); - lvI.pszText = szText; + lvI.pszText = temp_hdd_fn[i]; lvI.iItem = j; lvI.iImage = 0; @@ -1950,11 +1952,11 @@ static BOOL win_settings_hard_disks_init_columns(HWND hwndList) { case 0: /* Bus */ - lvc.cx = 85; + lvc.cx = 135; lvc.fmt = LVCFMT_LEFT; break; case 2: /* Cylinders */ - lvc.cx = 51; + lvc.cx = 41; lvc.fmt = LVCFMT_RIGHT; break; case 3: /* Heads */ @@ -1963,11 +1965,11 @@ static BOOL win_settings_hard_disks_init_columns(HWND hwndList) lvc.fmt = LVCFMT_RIGHT; break; case 1: /* File */ - lvc.cx = 180; + lvc.cx = 150; lvc.fmt = LVCFMT_LEFT; break; case 5: /* Size (MB) 8 */ - lvc.cx = 51; + lvc.cx = 41; lvc.fmt = LVCFMT_RIGHT; break; } @@ -2020,7 +2022,7 @@ int existing = 0; uint64_t selection = 127; uint64_t spt, hpc, tracks, size; -char hd_file_name[512]; +wchar_t hd_file_name[512]; static int hdconf_initialize_hdt_combo(HWND hdlg) { @@ -2090,6 +2092,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W case WM_INITDIALOG: memset(hd_file_name, 0, 512); + SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); + no_update = 1; spt = existing ? 0 : 17; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); @@ -2125,6 +2129,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W SendMessage(h, CB_SETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); no_update = 0; return TRUE; @@ -2132,7 +2138,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (LOWORD(wParam)) { case IDOK: - if (strlen(hd_file_name) == 0) + if (wcslen(hd_file_name) == 0) { msgbox_error(hwndParentDialog, 2056); return TRUE; @@ -2151,14 +2157,14 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - memset(temp_hdd_fn[next_free_id], 0, 512); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, strlen(hd_file_name) + 1); + memset(temp_hdd_fn[next_free_id], 0, 1024); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); sector_size = 512; - if (!existing && (strlen(hd_file_name) > 0)) + if (!existing && (wcslen(hd_file_name) > 0)) { - f = fopen(hd_file_name, "wb"); + f = _wfopen(hd_file_name, L"wb"); if (image_is_hdi(hd_file_name)) { @@ -2223,9 +2229,22 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return TRUE; case IDC_CFILE: - if (!file_dlg(hdlg, win_language_get_string_from_id(2172), "", !existing)) + if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) { - f = fopen(openfilestring, existing ? "rb" : "wb"); + if (!existing) + { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) + { + fclose(f); + if (msgbox_question(ghwnd, 2178) != IDYES) + { + return FALSE; + } + } + } + + f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); if (f == NULL) { msgbox_error(hwndParentDialog, existing ? 2060 : 2057); @@ -2233,7 +2252,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } if (existing) { - if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) + if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) { fseeko64(f, 0x10, SEEK_SET); fread(§or_size, 1, 4, f); @@ -2310,9 +2329,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - mbstowcs(szText, openfilestring, strlen(openfilestring) + 1); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) szText); - memcpy(hd_file_name, openfilestring, strlen(openfilestring) + 1); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); return TRUE; @@ -2630,7 +2648,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA return FALSE; case IDC_BUTTON_HDD_REMOVE: - strncpy(temp_hdd_fn[hdlv_current_sel], "", strlen("") + 1); + memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; diff --git a/src/win-status.c b/src/win-status.c index b907d6942..a39d38700 100644 --- a/src/win-status.c +++ b/src/win-status.c @@ -7,22 +7,24 @@ #undef BITMAP #include "ibm.h" +#include "mem.h" +#include "cpu/x86_ops.h" +#include "cpu/codegen.h" #include "device.h" -#include "video.h" #include "resource.h" #include "win.h" -#include "x86_ops.h" -#include "mem.h" -#include "codegen.h" + HWND status_hwnd; int status_is_open = 0; + extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; extern uint64_t main_time; static uint64_t status_time; + static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { char device_s[4096]; @@ -91,14 +93,3 @@ void status_open(HWND hwnd) status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); ShowWindow(status_hwnd, SW_SHOW); } - - -#if 0 -void -set_bugui(char *str) -{ - if (str == NULL) - str = "L:R GGGGGGGG-RRRRRRRR"; - SendMessage(status_hwnd, SB_SETTEXT, 2, (WPARAM)str); -} -#endif diff --git a/src/win-video.c b/src/win-video.c index dd6b3788f..15aec3785 100644 --- a/src/win-video.c +++ b/src/win-video.c @@ -4,11 +4,13 @@ #include #include #include -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + BITMAP *screen; + void hline(BITMAP *b, int x1, int y, int x2, uint32_t col) { if (y < 0 || y >= buffer->h) diff --git a/src/win.c b/src/win.c index 9c6695efa..4d7bc0631 100644 --- a/src/win.c +++ b/src/win.c @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#define UNICODE #define _WIN32_WINNT 0x0501 #define BITMAP WINDOWS_BITMAP #include @@ -9,9 +10,7 @@ #include #include - #include - #include #include #include @@ -23,29 +22,26 @@ #include "fdd.h" #include "hdd.h" #include "ibm.h" +#include "cpu/cpu.h" +#include "mem.h" +#include "rom.h" +#include "nvr.h" +#include "thread.h" +#include "config.h" +#include "model.h" #include "ide.h" +#include "cdrom.h" #include "cdrom-null.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" -#include "config.h" -#include "video.h" -#include "resource.h" -#include "cpu.h" -#include "cdrom.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "nethandler.h" -#include "nvr.h" -#include "sound.h" -#include "sound_dbopl.h" -#include "thread.h" -#include "rom.h" -#include "vid_ega.h" - +#include "cdrom-image.h" +#include "video/video.h" +#include "video/vid_ega.h" +#include "plat-keyboard.h" #include "plat-mouse.h" #include "plat-midi.h" -#include "plat-keyboard.h" +#include "mouse.h" +#include "sound/sound.h" +#include "sound/snd_dbopl.h" #include "win.h" #include "win-ddraw.h" @@ -53,6 +49,8 @@ #include "win-d3d.h" #include "win-d3d-fs.h" #include "win-language.h" +#include "resource.h" + #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 @@ -397,7 +395,7 @@ static void initmenu(void) { int i, c; HMENU m; - char s[32]; + WCHAR s[64]; for (i = 0; i < CDROM_NUM; i++) { @@ -407,22 +405,22 @@ static void initmenu(void) it's a CDROM */ for (c='A';c<='Z';c++) { - sprintf(s,"%c:\\",c); + _swprintf(s,L"%c:\\",c); if (GetDriveType(s)==DRIVE_CDROM) { - sprintf(s, "Host CD/DVD Drive (%c:)", c); + _swprintf(s, win_language_get_string_from_id(2076), c); AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); } } } } -void get_executable_name(char *s, int size) +void get_executable_name(WCHAR *s, int size) { GetModuleFileName(hinstance, s, size); } -void set_window_title(char *s) +void set_window_title(WCHAR *s) { if (video_fullscreen) return; @@ -478,8 +476,8 @@ UINT16 convert_scan_code(UINT16 scan_code) void get_registry_key_map() { - char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - char *valueName = "Scancode Map"; + WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + WCHAR *valueName = L"Scancode Map"; unsigned char buf[32768]; DWORD bufSize; HKEY hKey; @@ -522,24 +520,24 @@ void get_registry_key_map() } } -static char **argv; +static wchar_t **argv; static int argc; -static char *argbuf; +static wchar_t *argbuf; static void process_command_line() { - char *cmdline; + WCHAR *cmdline; int argc_max; int i, q; cmdline = GetCommandLine(); - i = strlen(cmdline) + 1; - argbuf = malloc(i); - memcpy(argbuf, cmdline, i); + i = wcslen(cmdline) + 1; + argbuf = malloc(i * 2); + memcpy(argbuf, cmdline, i * 2); argc = 0; argc_max = 64; - argv = malloc(sizeof(char *) * argc_max); + argv = malloc(sizeof(wchar_t *) * argc_max); if (!argv) { free(argbuf); @@ -551,12 +549,12 @@ static void process_command_line() /* parse commandline into argc/argv format */ while (argbuf[i]) { - while (argbuf[i] == ' ') + while (argbuf[i] == L' ') i++; if (argbuf[i]) { - if ((argbuf[i] == '\'') || (argbuf[i] == '"')) + if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) { q = argbuf[i++]; if (!argbuf[i]) @@ -570,7 +568,7 @@ static void process_command_line() if (argc >= argc_max) { argc_max += 64; - argv = realloc(argv, sizeof(char *) * argc_max); + argv = realloc(argv, sizeof(wchar_t *) * argc_max); if (!argv) { free(argbuf); @@ -578,7 +576,7 @@ static void process_command_line() } } - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != ' '))) + while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) i++; if (argbuf[i]) @@ -619,7 +617,7 @@ HANDLE hinstAcc; HICON LoadIconEx(PCTSTR pszIconName) { - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, 0); + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); } HICON LoadIconBig(PCTSTR pszIconName) @@ -724,9 +722,7 @@ void update_status_bar_icon(int tag, int active) sb_part_icons[found] &= ~257; sb_part_icons[found] |= sb_icon_flags[found]; - DestroyIcon(hIcon[found]); - hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); } } } @@ -759,65 +755,57 @@ void update_status_bar_icon_state(int tag, int state) sb_part_icons[found] &= ~257; sb_part_icons[found] |= sb_icon_flags[found]; - DestroyIcon(hIcon[found]); - hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); } } -char sbTips[24][512]; +WCHAR sbTips[24][512]; void create_floppy_tip(int part) { WCHAR *szText; - char ansi_text[2][512]; + WCHAR wtext[512]; int drive = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2179); - wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2185); - wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); - if (strlen(discfns[drive]) == 0) + + mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); + if (wcslen(discfns[drive]) == 0) { - sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); } else { - sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), discfns[drive]); + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); } } void create_cdrom_tip(int part) { WCHAR *szText; - char ansi_text[4][512]; + char ansi_text[3][512]; + WCHAR wtext[512]; int drive = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2180); - wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2185); - wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2186); - wcstombs(ansi_text[2], szText, (wcslen(szText) << 1) + 2); + if (cdrom_drives[drive].host_drive == 200) { - if (strlen(cdrom_iso[drive].iso_path) == 0) + if (wcslen(cdrom_image[drive].image_path) == 0) { - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - sprintf(sbTips[part], ansi_text[0], drive + 1, cdrom_iso[drive].iso_path); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); } } else if (cdrom_drives[drive].host_drive < 0x41) { - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - sprintf(ansi_text[3], ansi_text[2], cdrom_drives[drive].host_drive & ~0x20); - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[3]); + _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); } } @@ -826,8 +814,8 @@ void create_hd_tip(int part) WCHAR *szText; int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2182 + bus); - wcstombs(sbTips[part], szText, (wcslen(szText) << 1) + 2); + szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); + memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); } void update_tip(int meaning) @@ -866,7 +854,7 @@ void update_tip(int meaning) static int get_floppy_state(int id) { - return (strlen(discfns[id]) == 0) ? 1 : 0; + return (wcslen(discfns[id]) == 0) ? 1 : 0; } static int get_cd_state(int id) @@ -879,7 +867,7 @@ static int get_cd_state(int id) { if (cdrom_drives[id].host_drive == 0x200) { - return (strlen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; + return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; } else { @@ -888,6 +876,34 @@ static int get_cd_state(int id) } } +void status_settextw(wchar_t *wstr) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == 0x30) + { + part = i; + } + } + + if (part != -1) + { + SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); + } +} + +static wchar_t cwstr[512]; + +void status_settext(char *str) +{ + memset(cwstr, 0, 1024); + mbstowcs(cwstr, str, strlen(str) + 1); + status_settextw(cwstr); +} + void update_status_bar_panes(HWND hwnds) { int i, j, id; @@ -895,12 +911,14 @@ void update_status_bar_panes(HWND hwnds) int c_rll = 0; int c_mfm = 0; - int c_ide = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; int c_scsi = 0; c_mfm = count_hard_disks(1); - c_ide = count_hard_disks(2); - c_scsi = count_hard_disks(3); + c_ide_pio = count_hard_disks(2); + c_ide_dma = count_hard_disks(3); + c_scsi = count_hard_disks(4); sb_parts = 0; memset(sb_part_meanings, 0, 40); @@ -932,20 +950,27 @@ void update_status_bar_panes(HWND hwnds) sb_part_meanings[sb_parts] = 0x20; sb_parts++; } - if (c_ide && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = 0x21; sb_parts++; } - if (c_scsi) + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = 0x22; sb_parts++; } + if (c_scsi) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x23; + sb_parts++; + } if (sb_parts) { iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); @@ -962,7 +987,7 @@ void update_status_bar_panes(HWND hwnds) { case 0x00: /* Floppy */ - sb_icon_flags[i] = (strlen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; create_floppy_tip(i); break; @@ -977,7 +1002,7 @@ void update_status_bar_panes(HWND hwnds) { if (cdrom_drives[id].host_drive == 0x200) { - sb_icon_flags[i] = (strlen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; } else { @@ -1002,16 +1027,14 @@ void update_status_bar_panes(HWND hwnds) break; case 0x30: /* Status text */ - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "Hello from 86Box UX lab! :p"); + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); sb_part_icons[i] = -1; break; } if (sb_part_icons[i] != -1) { SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); - DestroyIcon(hIcon[i]); - hIcon[i] = LoadIconEx((PCTSTR) sb_part_icons[i]); - SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[i]); + SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ } @@ -1029,6 +1052,51 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) RECT rectDialog; int dw, dh; + for (i = 128; i < 136; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 144; i < 148; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 150; i < 154; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 160; i < 166; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 176; i < 184; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 384; i < 392; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 400; i < 404; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 406; i < 410; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 416; i < 422; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + GetWindowRect(hwndParent, &rectDialog); dw = rectDialog.right - rectDialog.left; dh = rectDialog.bottom - rectDialog.top; @@ -1078,6 +1146,8 @@ void win_menu_update() #endif } +int recv_key[272]; + int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, @@ -1088,10 +1158,12 @@ int WINAPI WinMain (HINSTANCE hThisInstance, MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ int c, d, e, bRet; - char emulator_title[200]; + WCHAR emulator_title[200]; LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ + memset(recv_key, 0, sizeof(recv_key)); + process_command_line(); win_language_load_common_strings(); @@ -1105,8 +1177,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCSTR) 100); + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); wincl.hCursor = NULL; wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ @@ -1126,7 +1198,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - sprintf(emulator_title, "86Box v%s", emulator_version); + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( @@ -1148,7 +1220,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, ShowWindow (hwnd, nFunsterStil); /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, "MainAccel"); + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); if (haccel == NULL) fatal("haccel is null\n"); @@ -1169,7 +1241,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, initpc(argc, argv); - hwndRender = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); @@ -1206,7 +1278,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (cdrom_drives[e].host_drive == 200) { - CheckMenuItem(smenu, IDM_CDROM_1_ISO + e, MF_CHECKED); + CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); } else if (cdrom_drives[e].host_drive >= 65) { @@ -1401,9 +1473,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, TerminateThread(mainthreadh,0); savenvr(); saveconfig(); - if (save_window_pos && window_remember) - saveconfig(); - closepc(); + closepc(); vid_apis[video_fullscreen][vid_api].close(); @@ -1454,7 +1524,7 @@ void cdrom_close(uint8_t id) ioctl_close(id); break; case 200: - iso_close(id); + image_close(id); break; } } @@ -1537,7 +1607,7 @@ void win_cdrom_eject(uint8_t id) } if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); } else { @@ -1564,7 +1634,7 @@ void win_cdrom_reload(uint8_t id) cdrom_close(id); if (cdrom_drives[id].prev_host_drive == 200) { - iso_open(id, cdrom_iso[id].iso_path); + image_open(id, cdrom_image[id].image_path); if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ @@ -1572,7 +1642,7 @@ void win_cdrom_reload(uint8_t id) } CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); } else { @@ -1622,7 +1692,7 @@ static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA void about_open(HWND hwnd) { - DialogBox(hinstance, (LPCSTR) ABOUTDLG, hwnd, about_dlgproc); + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -1833,14 +1903,21 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; #endif +#ifdef ENABLE_VRAM_DUMP + case IDM_DUMP_VRAM: + svga_dump_vram(); + break; +#endif + case IDM_CONFIG_LOAD: pause = 1; if (!file_dlg_st(hwnd, 2174, "", 0)) { if (msgbox_reset_yn(ghwnd) == IDYES) { - loadconfig(openfilestring); config_save(config_file_default); + loadconfig(wopenfilestring); + pclog_w(L"NVR path: %s\n", nvr_path); mem_resize(); loadbios(); resetpchard(); @@ -1852,7 +1929,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_SAVE: pause = 1; if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(openfilestring); + config_save(wopenfilestring); pause = 0; break; } @@ -2127,7 +2204,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR RECT rc; POINT pt; - char temp_iso_path[1024]; + WCHAR temp_image_path[1024]; int new_cdrom_drive; int cdrom_id = 0; int menu_sub_param = 0; @@ -2142,11 +2219,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { case IDM_DISC_1: case IDM_DISC_1_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[0], 0)) { disc_close(0); ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, openfilestring); + disc_load(0, wopenfilestring); update_status_bar_icon_state(0x00, 0); update_tip(0x00); saveconfig(); @@ -2154,11 +2231,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_2: case IDM_DISC_2_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[1], 0)) { disc_close(1); ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, openfilestring); + disc_load(1, wopenfilestring); update_status_bar_icon_state(0x01, 0); update_tip(0x01); saveconfig(); @@ -2166,11 +2243,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_3: case IDM_DISC_3_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[2], 0)) { disc_close(2); ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, openfilestring); + disc_load(2, wopenfilestring); update_status_bar_icon_state(0x02, 0); update_tip(0x02); saveconfig(); @@ -2178,11 +2255,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_4: case IDM_DISC_4_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[3], 0)) { disc_close(3); ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, openfilestring); + disc_load(3, wopenfilestring); update_status_bar_icon_state(0x03, 0); update_tip(0x03); saveconfig(); @@ -2244,24 +2321,24 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR win_cdrom_reload(cdrom_id); break; - case IDM_CDROM_1_ISO: - case IDM_CDROM_2_ISO: - case IDM_CDROM_3_ISO: - case IDM_CDROM_4_ISO: + case IDM_CDROM_1_IMAGE: + case IDM_CDROM_2_IMAGE: + case IDM_CDROM_3_IMAGE: + case IDM_CDROM_4_IMAGE: cdrom_id = LOWORD(wParam) & 3; hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) { cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - strcpy(temp_iso_path, openfilestring); - if ((strcmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) { - /* Switching from ISO to the same ISO. Do nothing. */ + /* Switching from image to the same image. Do nothing. */ break; } cdrom_drives[cdrom_id].handler->exit(cdrom_id); cdrom_close(cdrom_id); - iso_open(cdrom_id, temp_iso_path); + image_open(cdrom_id, temp_image_path); if (cdrom_drives[cdrom_id].enabled) { /* Signal disc change to the emulated machine. */ @@ -2273,8 +2350,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); update_tip(0x10 | cdrom_id); saveconfig(); } @@ -2307,10 +2383,9 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); } diff --git a/src/win.h b/src/win.h index 17316c27a..0e09db88f 100644 --- a/src/win.h +++ b/src/win.h @@ -9,9 +9,9 @@ extern int mousecapture; extern "C" { #endif -#define szClassName "86BoxMainWnd" -#define szSubClassName "86BoxSubWnd" -#define szStatusBarClassName "86BoxStatusBar" +#define szClassName L"86BoxMainWnd" +#define szSubClassName L"86BoxSubWnd" +#define szStatusBarClassName L"86BoxStatusBar" void leave_fullscreen(); @@ -28,12 +28,13 @@ void deviceconfig_open(HWND hwnd, struct device_t *device); void joystickconfig_open(HWND hwnd, int joy_nr, int type); extern char openfilestring[260]; +extern WCHAR wopenfilestring[260]; int getfile(HWND hwnd, char *f, char *fn); int getsfile(HWND hwnd, char *f, char *fn); -void get_executable_name(char *s, int size); -void set_window_title(char *s); +void get_executable_name(WCHAR *s, int size); +void set_window_title(WCHAR *s); void startblit(); void endblit(); diff --git a/src/xtide.c b/src/xtide.c index 587f1de02..ce827151b 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,20 +1,20 @@ #include - #include "ibm.h" - -#include "device.h" #include "io.h" -#include "ide.h" #include "mem.h" #include "rom.h" +#include "device.h" +#include "ide.h" #include "xtide.h" + typedef struct xtide_t { uint8_t data_high; rom_t bios_rom; } xtide_t; + static void xtide_write(uint16_t port, uint8_t val, void *p) { xtide_t *xtide = (xtide_t *)p; @@ -40,6 +40,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) } } + static uint8_t xtide_read(uint16_t port, void *p) { xtide_t *xtide = (xtide_t *)p; @@ -67,12 +68,13 @@ static uint8_t xtide_read(uint16_t port, void *p) } } -static void *xtide_init() + +static void *xtide_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); ide_pri_disable(); ide_sec_disable(); @@ -81,23 +83,25 @@ static void *xtide_init() return xtide; } -static void *xtide_at_init() + +static void *xtide_at_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; } -static void *xtide_ps2_init() + +static void *xtide_ps2_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); ide_pri_disable(); ide_sec_disable(); @@ -106,17 +110,19 @@ static void *xtide_ps2_init() return xtide; } -static void *xtide_at_ps2_init() + +static void *xtide_at_ps2_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; } + static void xtide_close(void *p) { xtide_t *xtide = (xtide_t *)p; @@ -124,26 +130,31 @@ static void xtide_close(void *p) free(xtide); } -static int xtide_available() + +static int xtide_available(void) { - return rom_present("roms/ide_xt.bin"); + return rom_present(L"roms/ide_xt.bin"); } -static int xtide_at_available() + +static int xtide_at_available(void) { - return rom_present("roms/ide_at.bin"); + return rom_present(L"roms/ide_at.bin"); } -static int xtide_ps2_available() + +static int xtide_ps2_available(void) { - return rom_present("roms/SIDE1V12.BIN"); + return rom_present(L"roms/SIDE1V12.BIN"); } -static int xtide_at_ps2_available() + +static int xtide_at_ps2_available(void) { - return rom_present("roms/ide_at_1_1_5.bin"); + return rom_present(L"roms/ide_at_1_1_5.bin"); } + device_t xtide_device = { "XTIDE",