mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-01-02 19:29:27 +00:00
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
This commit is contained in:
parent
001f04c706
commit
2cbecdda68
11
firmware/HDDv2/build.bat
Normal file
11
firmware/HDDv2/build.bat
Normal file
@ -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
|
358
firmware/HDDv2/hddrvr-v2.a65
Normal file
358
firmware/HDDv2/hddrvr-v2.a65
Normal file
@ -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 <Entrypoint_ProDOS ; entry point offset for ProDOS (must be $0a)
|
BIN
firmware/HDDv2/hddrvr-v2.bin
Normal file
BIN
firmware/HDDv2/hddrvr-v2.bin
Normal file
Binary file not shown.
@ -69,6 +69,8 @@
|
||||
Insert a hard disk controller card into slot 5 or 7.<br><br>
|
||||
-d1-disconnected, -d2-disconnected<br>
|
||||
Disconnect drive-1 and/or drive-2 from the Disk II controller card in slot 6.<br><br>
|
||||
-harddisknumblocks <number of ProDOS blocks><br>
|
||||
Set the number of blocks returned by a ProDOS status call. Use -harddisknumblocks 32767 to have the same autoexpanding behavior as older AppleWin versions.<br><br>
|
||||
-no-nsc<br>
|
||||
Remove the No-Slot clock (NSC).<br><br>
|
||||
-r <number of pages><br>
|
||||
|
@ -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"
|
||||
|
BIN
resource/Hddrvr-v2.bin
Normal file
BIN
resource/Hddrvr-v2.bin
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -802,6 +802,8 @@ static void RepeatInitialization(void)
|
||||
{
|
||||
if (GetCardMgr().QuerySlot(i) == CT_Disk2 && g_cmdLine.slotInfo[i].isDiskII13)
|
||||
dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(i)).SetFirmware13Sector();
|
||||
if (GetCardMgr().QuerySlot(i) == CT_GenericHDD)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(i)).SetUserNumBlocks(g_cmdLine.uHarddiskNumBlocks);
|
||||
}
|
||||
|
||||
// Create window after inserting/removing VidHD card (as it affects width & height)
|
||||
|
Loading…
Reference in New Issue
Block a user