From 2cbecdda6860f22a887493a9b766d82d5558b613 Mon Sep 17 00:00:00 2001 From: Peter Ibbotson Date: Tue, 6 Feb 2024 21:32:30 +0000 Subject: [PATCH] ProDOS HDD Controller firmware returns volume size in Y:X for STATUS command (PR #1272) * New command line option to force a size for autoexpanding use. * New HDD Controller firmware uses a separate v2 name and folder. * Harddisk.cpp now loads HDD Controller firmware v2 by default. * Save-state for 'Generic HDD' bumped to v4 --- firmware/HDDv2/build.bat | 11 ++ firmware/HDDv2/hddrvr-v2.a65 | 358 +++++++++++++++++++++++++++++++++++ firmware/HDDv2/hddrvr-v2.bin | Bin 0 -> 256 bytes help/CommandLine.html | 2 + resource/Applewin.rc | 1 + resource/Hddrvr-v2.bin | Bin 0 -> 256 bytes resource/resource.h | 1 + source/CmdLine.cpp | 12 ++ source/CmdLine.h | 2 + source/Harddisk.cpp | 39 +++- source/Harddisk.h | 6 +- source/Windows/AppleWin.cpp | 2 + 12 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 firmware/HDDv2/build.bat create mode 100644 firmware/HDDv2/hddrvr-v2.a65 create mode 100644 firmware/HDDv2/hddrvr-v2.bin create mode 100644 resource/Hddrvr-v2.bin diff --git a/firmware/HDDv2/build.bat b/firmware/HDDv2/build.bat new file mode 100644 index 00000000..31e8c654 --- /dev/null +++ b/firmware/HDDv2/build.bat @@ -0,0 +1,11 @@ +@REM ACME only ever returns 0! +acme.exe hddrvr-v2.a65 +@IF %ERRORLEVEL% NEQ 0 goto error + +copy hddrvr-v2.bin ..\..\resource +@goto end + +:error +@echo "ACME failed" + +:end diff --git a/firmware/HDDv2/hddrvr-v2.a65 b/firmware/HDDv2/hddrvr-v2.a65 new file mode 100644 index 00000000..3d42341e --- /dev/null +++ b/firmware/HDDv2/hddrvr-v2.a65 @@ -0,0 +1,358 @@ +;AppleWin : An Apple //e emulator for Windows +; +;Copyright (C) 1994-1996, Michael O'Brien +;Copyright (C) 1999-2001, Oliver Schmidt +;Copyright (C) 2002-2005, Tom Charlesworth +;Copyright (C) 2006-2012, Tom Charlesworth, Michael Pohoreski +; +;AppleWin 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. +; +;AppleWin 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 AppleWin; if not, write to the Free Software +;Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +; + +; Description: Firmware for harddisk card +; +; Author: Copyright (c) 2005, Robert Hoem +; + +; Modified by Tom Charlesworth: +; . Updated so it can be assembled by ACME 0.97 +; . Fixed so that ProDOS entrypoint is $c70a (26 Dev 2007) (Bug #12723) +; . Modified to support Apple Oasis' entrypoint: $c761 (8 Sept 2012) (Feature #5557) +; . Added support for SmartPort entrypoint (20 Oct 2012) +; - EG. "Prince of Persia (Original 3.5 floppy for IIc+).2mg" +; . GH#370 (Robert Hoem, 27 Oct 2016): +; . Added a check against open-apple during boot to route boot to slot 6 +; . This happens after the first two blocks are loaded from the HD. +; . GH#319: SmartPort return address wrong when crossing page +; . GH#996: Make code slot-independent (so HDD controller card can go into any slot) +; . Moved the 512-byte block read into AppleWin's HDD emulation (to mirror the block write command) +; TODO: +; . Remove support for Entrypoint_Cs46 (old AppleWin) & Entrypoint_Cs61 (Apple Oasis) +; - provide a utility to convert these to use Entrypoint_ProDOS +; . Check SmartPort: Is it OK to trash Y and $42,..,$47 ? +; + +!cpu 6502 ; Compatible with all Apple2's +!to "hddrvr-v2.bin", plain +!sl "hddrvr-v2.labels" + +; constants +hd_execute = $c080 +hd_status = $c081 ; b7=busy, b0=error +hd_command = $c082 +hd_unitnum = $c083 +hd_memblock = $c084 +hd_diskblock = $c086 +;hd_nextbyte = $c088 ; legacy read-only port (still supported by AppleWin) +hd_imgsizelo = $c089 +hd_imgsizehi = $c08a + +; Notes on accesses to I/O registers: +; . ROR ABS16,X and ROL ABS16,X - only used for $C081+s*$10 STATUS register: +; 6502: double read (old data), write (old data), write (new data). The writes are harmless as writes to STATUS are ignored. +; 65C02: double read (old data), write (new data). The write is harmless as writes to STATUS are ignored. +; . STA ABS16,X does a false-read. This is harmless for writable I/O registers, since the false-read has no side effect. + +command = $42 +unitnum = $43 +memblock = $44 +diskblock = $46 + +slot6 = $C600 +OS = $0801 +BUTTON0 = $C061 + +;====================================== + +!zone code + +*= $0000 ; org $0000 - position-independent code, so doesn't matter (but the other fixed org positions need to be on the same page) + +; The Autoboot rom will call this. +; This is also the entry point for such things as IN#7 and PR#7 + +start + +; Autoboot and ProDOS look at the following few opcodes to detect block devices +; NB. $Cn07 should be $00 for a SmartPort Interface, but changing this means that it won't autoboot on ][, ][+ and unenhanced IIe. +; . ref: http://www.1000bit.it/support/manuali/apple/technotes/udsk/tn.udsk.2.html + lda #$20 + lda #$00 + lda #$03 + lda #$3C + bne Bootstrap + +Entrypoint_ProDOS ; $Cn0A - ProDOS entrypoint + sec + bcs Entrypoint + +Entrypoint_SmartPort ; $Cn0D - SmartPort entrypoint + clc + +Entrypoint ; $Cn0E - entrypoint? + bcs GetSlotInX ; C=1: GetSlotInX -> cmdproc + + ; C=0: fall through to SmartPort... + +;====================================== + +; TODO: Is it OK to trash Y and $42,..,$47 ? +; Pre: C=0, X = Slot# << 4 +SmartPort ; SmartPort -> GetSlotInX -> cmdproc + pla + sta $46 + adc #3 ; Pre: C=0, Post: C=0 or 1 + tay + pla + sta $47 ; ($46) = &cmd_hdr + adc #0 + pha + tya + pha ; (sp).w += 3 + + ldy #1 + lda ($46),y ; cmd + sta $42 + iny + + lda ($46),y ; param_l + sta $45 + iny + lda ($46),y ; param_h + sta $46 + + ldy #1 ; skip paramLength (assume it's #$03) + lda ($45),y ; unit + sta $43 + iny + + lda ($45),y ; memblock_l + sta $44 + iny + lda ($45),y ; memblock_h + pha + iny + + lda ($45),y ; diskblock_l + pha + iny + + bne SmartPort2 + +;====================================== +; 2 unused bytes + +@checkCs46 +*= $0046 ; org $0046 +!warn "Cs46 padding = ", * - @checkCs46 + +Entrypoint_Cs46 ; Old f/w 'cmdproc' entrypoint + ; Keep this for any DOSMaster HDD images created with old AppleWin HDD f/w. + ; DOSMaster hardcodes the entrypoint addr into its bootstrapping code: + ; - So DOSMaster images are tied to the HDD's controller's f/w + sec + bcs Entrypoint ; or directly to GetSlotInX + +;====================================== + +Bootstrap +; Lets check to see if there's an image ready +; Slot n, disk 1 + clc + bcc GetSlotInX ; Post: X = Slot# << 4 +Bootstrap2 + lda #$00 + sta hd_unitnum,x ; b7=0 => disk 1 + sta hd_command,x + lda hd_execute,x + ror hd_status,x ; Post: C=0 or 1 + bcc hdboot + +; no image ready, boot diskette image instead +BootSlot6 + jmp slot6 + +;====================================== +; 2 unused bytes + +@checkCs61 +*= $0061 ; org $0061 +!warn "Cs61 padding = ", * - @checkCs61 + +Entrypoint_Cs61 ; Apple Oasis HDD controller entrypoint + ; Keep this for any DOSMaster HDD images created with Apple Oasis HDD f/w. + ; DOSMaster hardcodes the entrypoint addr into its bootstrapping code: + ; - So DOSMaster images are tied to the HDD's controller's f/w + sec + bcs Entrypoint ; or directly to GetSlotInX + +;====================================== + +; image ready. Lets boot from it. +; we want to load block 1 from disk 1 to $800 then jump there +; Pre: X = Slot# << 4 +; C = 0 +hdboot + lda #$0 + sta unitnum ; b7=0 => disk 1 + sta memblock + sta diskblock + sta diskblock+1 + lda #$8 + sta memblock+1 + lda #$1 + sta command + bne cmdproc +hdboot2 + bcs BootSlot6 + + bit BUTTON0 ; button 0 pressed? + bmi BootSlot6 + +; Pre: X = Slot# << 4 + jmp OS + +;====================================== + +SmartPort2 + lda ($45),y ; diskblock_h + sta $47 + + pla + sta $46 + pla + sta $45 + + sec + ; fall through... + +;====================================== + +; Pre: +; C=0 => via Bootstrap +; C=1 => via Entrypoint / SmartPort2 +; Post: +; X = Slot# << 4 +GetSlotInX + php + sei ; disable ints, in case an int handler races our $0000/RTS and stack accesses! + + ; NB. need RAM that's guaranteed to be both read & writeable: + ; . can't use $0200-$BFFF, due to eg. RAMRD=0/RAMWRT=1 combination + ; . can't use LC as ROM might be enabled. + ; So use ZP (specifically $0000) as whatever the state of ALTZP, both read & write will be to the same physical memory location. + lda $00 ; save $00 + ldx #$60 ; opcode RTS + stx $00 + jsr $0000 ; RTS immediately (NB. can't use $FF58, since LC RAM may be switched in) + sta $00 ; restore $00 + tsx + lda $0100,x ; $Cn + asl + asl + asl + asl + tax ; X=$n0 + + plp ; + restore int status + bcc Bootstrap2 + ; otherwise fall through for Entrypoint / SmartPort... + +;-------------------------------------- + +; entry point for ProDOS' block driver +; simple really. Copy the command from $42..$47 +; to our I/O ports then execute command + +; Pre: +; C=0 => via Bootstrap (hdboot) +; C=1 => via GetSlotInX (eg. Entrypoint / SmartPort2) +; X = Slot# << 4 +; Post: +; C = hd_status.b0 +; A = result of hd_execute +; Read or write command +; X = Slot# << 4 +; Y = command +; Status command +; X = low byte of disk size +; Y = high byte of disk size +cmdproc + php + + lda command + sta hd_command,x + lda unitnum + sta hd_unitnum,x + lda memblock + sta hd_memblock,x + lda memblock+1 + sta hd_memblock+1,x + lda diskblock + sta hd_diskblock,x + lda diskblock+1 + sta hd_diskblock+1,x + lda hd_execute,x ; A = result of hd_execute (NB. instantaneous 512 byte r/w!) + +- rol hd_status,x ; b7=busy doing DMA? + bcs - + + plp ; restore C from start of cmdproc + bcs done + ror hd_status,x ; Post: C=0 or 1 + lda #0 + beq hdboot2 + +done + ror hd_status,x ; Post: C=0 or 1 + ldy command ; Was it status + beq size ; yes, fill in the values + rts ; no, go home + +size + pha ; Save result + ldy hd_imgsizehi,x ; Get high byte of size + lda hd_imgsizelo,x ; Get low byte of size + tax ; Transfer into X + pla ; Get back status call result + rts + +;====================================== + +; 18 unused bytes + +!zone data + +; $CsFE = status bits (BAP p7-14) +; 7 = medium is removable +; 6 = device is interruptable +; 5-4 = number of volumes (0..3 means 1..4) +; 3 = device supports Format call +; 2 = device can be written to +; 1 = device can be read from (must be 1) +; 0 = device status can be read (must be 1) + +; $C7 = Removable, Interruptable, #Volumes=1, Supports write/read/status +; $D7 = Removable, Interruptable, #Volumes=2, Supports write/read/status +; $BF = Removable, Interruptable, #Volumes=4, Supports format/write/read/status (KEGS / IIGS) + +; datablock. This starts near the end of the firmware (at offset $FB) +;; data +@checkCsFB +*= $00FB ; org $00FB +!warn "CsFB padding = ", * - @checkCsFB + !byte $00 ; Smart port ID Type byte + !word $0000 ; how many blocks are on the device. Zero means use status call + !byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc) + !byte 7&D+&O>&nEeTcB7Z@@y;7Tl^#8CgyO#37vNSP_xD zfI4PlV&Mt8v*0lEOa3g&()ZJlfO>S+PNJX&;j%(28%^|z-Nj<8bw2#H>6Y=}hU9&e1*;}_^pSf*UI9_r18HFP$COF*7 UdW;XM$lq?b*>PPK@LxXrziU%yH~;_u literal 0 HcmV?d00001 diff --git a/help/CommandLine.html b/help/CommandLine.html index be4383ea..abd3fad5 100644 --- a/help/CommandLine.html +++ b/help/CommandLine.html @@ -69,6 +69,8 @@ Insert a hard disk controller card into slot 5 or 7.

-d1-disconnected, -d2-disconnected
Disconnect drive-1 and/or drive-2 from the Disk II controller card in slot 6.

+ -harddisknumblocks <number of ProDOS blocks>
+ Set the number of blocks returned by a ProDOS status call. Use -harddisknumblocks 32767 to have the same autoexpanding behavior as older AppleWin versions.

-no-nsc
Remove the No-Slot clock (NSC).

-r <number of pages>
diff --git a/resource/Applewin.rc b/resource/Applewin.rc index 046ed933..59130c26 100644 --- a/resource/Applewin.rc +++ b/resource/Applewin.rc @@ -332,6 +332,7 @@ IDR_DISK2_13SECTOR_FW FIRMWARE "Disk2-13sector.rom" IDR_DISK2_16SECTOR_FW FIRMWARE "Disk2.rom" IDR_SSC_FW FIRMWARE "SSC.rom" IDR_HDDRVR_FW FIRMWARE "Hddrvr.bin" +IDR_HDDRVR_V2_FW FIRMWARE "Hddrvr-v2.bin" IDR_PRINTDRVR_FW FIRMWARE "Parallel.rom" IDR_MOCKINGBOARD_D_FW FIRMWARE "Mockingboard-D.rom" IDR_MOUSEINTERFACE_FW FIRMWARE "MouseInterface.rom" diff --git a/resource/Hddrvr-v2.bin b/resource/Hddrvr-v2.bin new file mode 100644 index 0000000000000000000000000000000000000000..21f68edb0d673c9cbf78c66566fb5a9318d25d87 GIT binary patch literal 256 zcmZvVu};H442FH`z^PBrv112>7&D+&O>&nEeTcB7Z@@y;7Tl^#8CgyO#37vNSP_xD zfI4PlV&Mt8v*0lEOa3g&()ZJlfO>S+PNJX&;j%(28%^|z-Nj<8bw2#H>6Y=}hU9&e1*;}_^pSf*UI9_r18HFP$COF*7 UdW;XM$lq?b*>PPK@LxXrziU%yH~;_u literal 0 HcmV?d00001 diff --git a/resource/resource.h b/resource/resource.h index cbe032fc..aa1e4d45 100644 --- a/resource/resource.h +++ b/resource/resource.h @@ -52,6 +52,7 @@ #define IDR_APPLE2_JPLUS_VIDEO_ROM 152 #define IDR_BASE_64A_ROM 153 #define IDR_BASE64A_VIDEO_ROM 154 +#define IDR_HDDRVR_V2_FW 155 #define IDC_KEYB_BUFFER_ENABLE 1005 #define IDC_SAVESTATE 1006 #define IDC_SAVESTATE_ON_EXIT 1007 diff --git a/source/CmdLine.cpp b/source/CmdLine.cpp index 6d02dc75..e1a399cc 100644 --- a/source/CmdLine.cpp +++ b/source/CmdLine.cpp @@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "SoundCore.h" #include "SNESMAX.h" #include "Interface.h" +#include "Harddisk.h" CmdLine g_cmdLine; std::string g_sConfigFile; // INI file to use instead of Registry @@ -246,6 +247,17 @@ bool ProcessCmdLine(LPSTR lpCmdLine) LogFileOutput("Unsupported arg: %s\n", lpCmdLine); } } + else if (strcmp(lpCmdLine, "-harddisknumblocks") == 0) // number of blocks to report for ProDOS + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + g_cmdLine.uHarddiskNumBlocks = atoi(lpCmdLine); + if (g_cmdLine.uHarddiskNumBlocks > kHarddiskMaxNumBlocks) + g_cmdLine.uHarddiskNumBlocks = kHarddiskMaxNumBlocks; + else + if (g_cmdLine.uHarddiskNumBlocks < 0) + g_cmdLine.uHarddiskNumBlocks = 0; + } else if (strcmp(lpCmdLine, "-load-state") == 0) { lpCmdLine = GetCurrArg(lpNextArg); diff --git a/source/CmdLine.h b/source/CmdLine.h index 98b4b2d0..a5f45651 100644 --- a/source/CmdLine.h +++ b/source/CmdLine.h @@ -36,6 +36,7 @@ struct CmdLine noDisk2StepperDefer = false; szSnapshotName = NULL; szScreenshotFilename = NULL; + uHarddiskNumBlocks = 0; uRamWorksExPages = 0; uSaturnBanks = 0; newVideoType = -1; @@ -82,6 +83,7 @@ struct CmdLine LPCSTR szImageName_drive[NUM_SLOTS][NUM_DRIVES]; bool driveConnected[NUM_SLOTS][NUM_DRIVES]; LPCSTR szImageName_harddisk[NUM_SLOTS][NUM_HARDDISKS]; + UINT uHarddiskNumBlocks; LPSTR szSnapshotName; LPSTR szScreenshotFilename; UINT uRamWorksExPages; diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index a076ade3..0a0ddc57 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -53,6 +53,8 @@ Memory map (for slot 7): C0F6 (r/w) LOW BYTE OF BLOCK NUMBER C0F7 (r/w) HIGH BYTE OF BLOCK NUMBER C0F8 (r) NEXT BYTE (legacy read-only port - still supported) + C0F9 (r) LOW BYTE OF DISK IMAGE SIZE IN BLOCKS + C0FA (r) HIGHT BYTE OF DISK IMAGE SIZE IN BLOCKS Firmware notes: . ROR ABS16,X and ROL ABS16,X - only used for $C081+s*$10 STATUS register: @@ -75,6 +77,8 @@ Overview bytes, in a linear fashion. The internal formatting and meaning of each block to be decided by the Apple's operating system (ProDOS). To create an empty .HDV file, just create a 0 byte file. + Use the -harddisknumblocks n command line option to set the disk size + returned by ProDOS status calls. 2. Emulation code There are 4 commands ProDOS will send to a block device. @@ -162,7 +166,7 @@ void HarddiskInterfaceCard::InitializeIO(LPBYTE pCxRomPeripheral) { const DWORD HARDDISK_FW_SIZE = APPLE_SLOT_SIZE; - BYTE* pData = GetFrame().GetResource(IDR_HDDRVR_FW, "FIRMWARE", HARDDISK_FW_SIZE); + BYTE* pData = GetFrame().GetResource(IDR_HDDRVR_V2_FW, "FIRMWARE", HARDDISK_FW_SIZE); if (pData == NULL) return; @@ -657,19 +661,31 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY r = (BYTE)(pHDD->m_memblock & 0x00FF); break; case 0x5: - r = (BYTE)(pHDD->m_memblock & 0xFF00 >> 8); + r = (BYTE)((pHDD->m_memblock & 0xFF00) >> 8); break; case 0x6: r = (BYTE)(pHDD->m_diskblock & 0x00FF); break; case 0x7: - r = (BYTE)(pHDD->m_diskblock & 0xFF00 >> 8); + r = (BYTE)((pHDD->m_diskblock & 0xFF00) >> 8); break; case 0x8: // Legacy: continue to support this I/O port for old HDD firmware r = pHDD->m_buf[pHDD->m_buf_ptr]; if (pHDD->m_buf_ptr < sizeof(pHDD->m_buf)-1) pHDD->m_buf_ptr++; break; + case 0x9: + if (pHDD->m_imageloaded) + r = (BYTE)(pCard->GetImageSizeInBlocks(pHDD->m_imagehandle) & 0x00ff); + else + r = 0; + break; + case 0xa: + if (pHDD->m_imageloaded) + r = (BYTE)((pCard->GetImageSizeInBlocks(pHDD->m_imagehandle) & 0xff00) >> 8); + else + r = 0; + break; default: pHDD->m_status_next = DISK_STATUS_OFF; r = IO_Null(pc, addr, bWrite, d, nExecutedCycles); @@ -694,7 +710,9 @@ BYTE __stdcall HarddiskInterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, B case 0x0: // r/o: status case 0x1: // r/o: execute case 0x8: // r/o: legacy next-data port - // Writing to these 3 read-only registers is a no-op. + case 0x9: // r/o: low byte of image size + case 0xa: // r/o: high byte of image size + // Writing to these 5 read-only registers is a no-op. // NB. Don't change m_status_next, as UpdateLightStatus() has a huge performance cost! // Firmware has a busy-wait loop doing "rol hd_status,x" // - this RMW opcode does an IORead() then an IOWrite(), and the loop iterates ~100 times! @@ -729,6 +747,16 @@ BYTE __stdcall HarddiskInterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, B return r; } +UINT HarddiskInterfaceCard::GetImageSizeInBlocks(ImageInfo* const pImageInfo) +{ + if (m_userNumBlocks != 0) + return m_userNumBlocks; + UINT numberOfBlocks = (pImageInfo ? pImageInfo->uImageSize : 0) / HD_BLOCK_SIZE; + if (numberOfBlocks > kHarddiskMaxNumBlocks) + numberOfBlocks = kHarddiskMaxNumBlocks; + return numberOfBlocks; +} + //=========================================================================== void HarddiskInterfaceCard::UpdateLightStatus(HardDiskDrive* pHDD) @@ -766,7 +794,8 @@ bool HarddiskInterfaceCard::ImageSwap(void) // 2: Updated $C7nn firmware to fix GH#319 // 3: Updated $Csnn firmware to fix GH#996 (now slot-independent code) // Added: Not Busy Cycle -static const UINT kUNIT_VERSION = 3; +// 4: Updated $Csnn firmware to fix GH#1264 +static const UINT kUNIT_VERSION = 4; #define SS_YAML_VALUE_CARD_HDD "Generic HDD" diff --git a/source/Harddisk.h b/source/Harddisk.h index cca84e2e..048f0051 100644 --- a/source/Harddisk.h +++ b/source/Harddisk.h @@ -34,6 +34,8 @@ enum HardDrive_e NUM_HARDDISKS }; +const UINT kHarddiskMaxNumBlocks = 0xffff; // Maximum number of blocks we can report. + class HardDiskDrive { public: @@ -98,6 +100,7 @@ public: void Unplug(const int iDrive); bool IsDriveUnplugged(const int iDrive); void LoadLastDiskImage(const int iDrive); + void SetUserNumBlocks(UINT numBlocks) { m_userNumBlocks = numBlocks; } void GetLightStatus(Disk_Status_e* pDisk1Status); bool ImageSwap(void); @@ -117,7 +120,7 @@ private: const std::string& DiskGetBaseName(const int iDrive); bool SelectImage(const int drive, LPCSTR pszFilename); void UpdateLightStatus(HardDiskDrive* pHDD); - + UINT GetImageSizeInBlocks(ImageInfo* const pImageInfo); void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit); bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit); @@ -126,6 +129,7 @@ private: BYTE m_unitNum; // b7=unit BYTE m_command; UINT64 m_notBusyCycle; + UINT m_userNumBlocks; bool m_saveDiskImage; // Save the DiskImage name to Registry diff --git a/source/Windows/AppleWin.cpp b/source/Windows/AppleWin.cpp index 22592b5c..ba902b86 100644 --- a/source/Windows/AppleWin.cpp +++ b/source/Windows/AppleWin.cpp @@ -802,6 +802,8 @@ static void RepeatInitialization(void) { if (GetCardMgr().QuerySlot(i) == CT_Disk2 && g_cmdLine.slotInfo[i].isDiskII13) dynamic_cast(GetCardMgr().GetRef(i)).SetFirmware13Sector(); + if (GetCardMgr().QuerySlot(i) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(i)).SetUserNumBlocks(g_cmdLine.uHarddiskNumBlocks); } // Create window after inserting/removing VidHD card (as it affects width & height)