ProDOS HDD Driver modified to support returning
the volume size in the X/Y registers. New command line option to force a size for autoexpanding use.
This commit is contained in:
parent
7497aa9923
commit
b0dc4fd407
Binary file not shown.
|
@ -55,6 +55,8 @@ 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:
|
||||
|
@ -280,7 +282,12 @@ GetSlotInX
|
|||
; 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
|
||||
|
||||
|
@ -309,11 +316,21 @@ cmdproc
|
|||
|
||||
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
|
||||
|
||||
;======================================
|
||||
|
||||
; 33 unused bytes
|
||||
; 18 unused bytes
|
||||
|
||||
!zone data
|
||||
|
||||
|
@ -330,12 +347,12 @@ done
|
|||
; $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 $FC)
|
||||
; datablock. This starts near the end of the firmware (at offset $FB)
|
||||
;; data
|
||||
@checkCsFC
|
||||
*= $00FC ; org $00FC
|
||||
!warn "CsFC padding = ", * - @checkCsFC
|
||||
|
||||
!word $7fff ; how many blocks are on the device.
|
||||
@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)
|
||||
|
|
|
@ -68,6 +68,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>
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -37,6 +37,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Registry.h"
|
||||
#include "SaveState.h"
|
||||
#include "YamlHelper.h"
|
||||
#include "CmdLine.h"
|
||||
|
||||
#include "Debugger/Debug.h"
|
||||
#include "../resource/resource.h"
|
||||
|
@ -53,6 +54,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 +78,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.
|
||||
|
@ -657,19 +662,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)(GetImageSizeInBlocks(pHDD->m_imagehandle) & 0x00ff);
|
||||
else
|
||||
r = 0;
|
||||
break;
|
||||
case 0xa:
|
||||
if (pHDD->m_imageloaded)
|
||||
r = (BYTE)((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 +711,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 +748,16 @@ BYTE __stdcall HarddiskInterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, B
|
|||
return r;
|
||||
}
|
||||
|
||||
UINT HarddiskInterfaceCard::GetImageSizeInBlocks(ImageInfo* const pImageInfo)
|
||||
{
|
||||
if (g_cmdLine.uHarddiskNumBlocks != 0)
|
||||
return g_cmdLine.uHarddiskNumBlocks;
|
||||
UINT numberOfBlocks = (pImageInfo ? pImageInfo->uImageSize : 0) / HD_BLOCK_SIZE;
|
||||
if (numberOfBlocks > kHarddiskMaxNumBlocks)
|
||||
numberOfBlocks = kHarddiskMaxNumBlocks;
|
||||
return numberOfBlocks;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void HarddiskInterfaceCard::UpdateLightStatus(HardDiskDrive* pHDD)
|
||||
|
|
|
@ -34,6 +34,8 @@ enum HardDrive_e
|
|||
NUM_HARDDISKS
|
||||
};
|
||||
|
||||
const UINT kHarddiskMaxNumBlocks = 0xffff; // Maximum number of blocks we can report.
|
||||
|
||||
class HardDiskDrive
|
||||
{
|
||||
public:
|
||||
|
@ -117,7 +119,7 @@ private:
|
|||
const std::string& DiskGetBaseName(const int iDrive);
|
||||
bool SelectImage(const int drive, LPCSTR pszFilename);
|
||||
void UpdateLightStatus(HardDiskDrive* pHDD);
|
||||
|
||||
static UINT GetImageSizeInBlocks(ImageInfo* const pImageInfo);
|
||||
void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit);
|
||||
|
||||
|
|
Loading…
Reference in New Issue