2022-06-07 21:05:08 +00:00
# include "NuBusFPGARAMDskDrvr.h"
2022-10-05 21:46:28 +00:00
# include <Disks.h>
/* FYI, missing in library with Retro68 */
/* void AddDrive(short drvrRefNum, short drvNum, DrvQElPtr qEl); */
/* re-implement with Retro68 features */
/* drVNum to high-order bits of num, drvrRefNum in low-order */
/* not sure how to do "parameter" without output ? */
# pragma parameter __D0 AddDrive(__D0, __A0)
2022-10-06 21:28:07 +00:00
__attribute__ ( ( section ( " .text.dskdriver " ) ) ) static inline int dupAddDrive ( unsigned long num , DrvQElPtr qEl ) {
2022-10-05 21:46:28 +00:00
asm volatile ( " .word 0xA04E " : : " d " ( num ) , " a " ( qEl ) ) ;
return num ; // should cost nothing, num is already in D0
}
2022-06-07 21:05:08 +00:00
2022-06-26 10:31:43 +00:00
# include <ROMDefs.h>
2022-10-05 21:46:28 +00:00
# pragma parameter __D0 cNuBusFPGARAMDskOpen(__A0, __A1)
2022-06-07 21:05:08 +00:00
OSErr cNuBusFPGARAMDskOpen ( IOParamPtr pb , /* DCtlPtr */ AuxDCEPtr dce )
{
DrvSts2 * dsptr ; // pointer to the DrvSts2 in our context
int drvnum = 1 ;
struct RAMDrvContext * ctx ;
OSErr ret = noErr ;
2022-06-24 21:37:18 +00:00
char busMode ;
2022-06-26 10:31:43 +00:00
char slot ;
2022-06-24 21:37:18 +00:00
busMode = 1 ;
SwapMMUMode ( & busMode ) ; // to32 // this likely won't work on older MacII ???
2022-06-07 21:05:08 +00:00
2022-06-26 10:31:43 +00:00
if ( dce - > dCtlDevBase = = 0 ) { // for some unknown reason, we get an empty dCtlDevBase...
2022-07-14 07:33:15 +00:00
if ( ( dce - > dCtlSlot > 0xE ) | | ( dce - > dCtlSlot < 0x9 ) ) { // safety net
SpBlock mySpBlock ;
SInfoRecord mySInfoRecord ;
mySpBlock . spResult = ( long ) & mySInfoRecord ;
mySpBlock . spSlot = 0x9 ; // start at first
mySpBlock . spID = 0 ;
mySpBlock . spExtDev = 0 ;
mySpBlock . spCategory = catProto ;
mySpBlock . spCType = 0x1000 ; // typeDrive;
mySpBlock . spDrvrSW = drSwApple ;
mySpBlock . spDrvrHW = 0xbeee ; // DrHwNuBusFPGADsk
mySpBlock . spTBMask = 0 ;
ret = SNextTypeSRsrc ( & mySpBlock ) ;
if ( ret )
goto done ;
slot = mySpBlock . spSlot ;
} else {
slot = dce - > dCtlSlot ;
}
2022-06-26 10:31:43 +00:00
dce - > dCtlDevBase = 0xF0000000ul | ( ( unsigned long ) slot < < 24 ) ;
}
2022-06-07 21:05:08 +00:00
2022-06-26 10:31:43 +00:00
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0000); */
2022-07-14 07:33:15 +00:00
/* write_reg(dce, GOBOFB_DEBUG, dce->dCtlSlot); */
2022-06-07 21:05:08 +00:00
if ( dce - > dCtlStorage = = nil ) {
2022-06-24 21:37:18 +00:00
DrvQElPtr dq ;
2022-06-07 21:05:08 +00:00
for ( dq = ( DrvQElPtr ) ( GetDrvQHdr ( ) ) - > qHead ; dq ; dq = ( DrvQElPtr ) dq - > qLink ) {
if ( dq - > dQDrive > = drvnum )
drvnum = dq - > dQDrive + 1 ;
}
2022-06-24 21:37:18 +00:00
ReserveMemSys ( sizeof ( struct RAMDrvContext ) ) ;
2022-06-07 21:05:08 +00:00
dce - > dCtlStorage = NewHandleSysClear ( sizeof ( struct RAMDrvContext ) ) ;
if ( dce - > dCtlStorage = = nil ) {
ret = openErr ;
goto done ;
}
HLock ( dce - > dCtlStorage ) ;
ctx = * ( struct RAMDrvContext * * ) dce - > dCtlStorage ;
2022-06-26 10:31:43 +00:00
ctx - > slot = slot ;
2022-10-08 16:23:01 +00:00
// disable IRQ for now
write_reg ( dce , DMA_IRQ_CTL , revb ( 0x2 ) ) ; // 0x1 would enable irq, 0x2 is auto-clear so we make sure there's no spurious IRQ pending ; should be already done by Pirmary
2022-06-07 21:05:08 +00:00
dsptr = & ctx - > drvsts ;
// dsptr->track /* current track */
dsptr - > writeProt = 0 ; /* bit 7 = 1 if volume is locked */
dsptr - > diskInPlace = 8 ; /* disk in drive */
// dsptr->installed /* drive installed */
// dsptr->sides /* -1 for 2-sided, 0 for 1-sided */
// dsptr->QLink /* next queue entry */
dsptr - > qType = 1 ; /* 1 for HD20 */ /* Files 2-85 (p173) : 1 to enable S1 */
dsptr - > dQDrive = drvnum ; /* drive number */
dsptr - > dQRefNum = dce - > dCtlRefNum ; /* driver reference number */
// dsptr->dQFSID /* file system ID */
dsptr - > driveSize = ( ( DRIVE_SIZE_BYTES / 512ul ) & 0x0000FFFFul ) ; /* (no comments in Disks.h) */
dsptr - > driveS1 = ( ( DRIVE_SIZE_BYTES / 512ul ) & 0xFFFF0000ul ) > > 16 ; /* */
// dsptr->driveType
// dsptr->driveManf
// dsptr->driveChar
// dsptr->driveMisc
2022-06-12 11:45:41 +00:00
// MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
// write_reg(dce, GOBOFB_DEBUG, 0x0000DEAD);
2022-06-26 10:31:43 +00:00
// initialize to our empty volume
2022-06-12 11:45:41 +00:00
{
2022-06-26 10:31:43 +00:00
unsigned long * superslot = ( unsigned long * ) ( ( ( unsigned long ) ctx - > slot ) < < 28ul ) ;
unsigned long * compressed = ( unsigned long * ) ( dce - > dCtlDevBase + 0x00FF8000ul ) ;
2022-06-12 11:45:41 +00:00
unsigned long res ;
2022-06-24 21:37:18 +00:00
res = rledec ( superslot , compressed , 730 ) ; // FIXME: 730 = 2920/4 (compressed size in words)
2022-06-12 11:45:41 +00:00
}
2022-06-26 10:31:43 +00:00
// add the drive
2022-10-05 21:46:28 +00:00
//MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
dupAddDrive ( ( dsptr - > dQRefNum & 0xFFFF ) | ( drvnum < < 16 ) , ( DrvQElPtr ) & dsptr - > qLink ) ;
2022-07-23 10:53:30 +00:00
# ifdef ENABLE_DMA
ctx - > dma_blk_size = revb ( read_reg ( dce , DMA_BLK_SIZE ) ) ;
ctx - > dma_blk_size_mask = ctx - > dma_blk_size - 1 ; // size is Po2
ctx - > dma_blk_size_shift = 0 ;
2022-10-05 20:19:48 +00:00
while ( ( 1 < < ctx - > dma_blk_size_shift ) < ctx - > dma_blk_size ) // fixme
2022-07-23 10:53:30 +00:00
ctx - > dma_blk_size_shift + + ;
ctx - > dma_blk_base = revb ( read_reg ( dce , DMA_BLK_BASE ) ) ;
ctx - > dma_mem_size = revb ( read_reg ( dce , DMA_MEM_SIZE ) ) ;
/* write_reg(dce, GOBOFB_DEBUG, 0xD1580002); */
/* write_reg(dce, GOBOFB_DEBUG, ctx->dma_blk_size); */
/* write_reg(dce, GOBOFB_DEBUG, ctx->dma_blk_size_mask); */
/* write_reg(dce, GOBOFB_DEBUG, ctx->dma_blk_size_shift); */
/* write_reg(dce, GOBOFB_DEBUG, ctx->dma_blk_base); */
/* write_reg(dce, GOBOFB_DEBUG, ctx->dma_mem_size); */
2022-10-08 08:39:18 +00:00
2022-10-08 16:23:01 +00:00
{
2022-10-08 08:39:18 +00:00
SlotIntQElement * siqel = ( SlotIntQElement * ) NewPtrSysClear ( sizeof ( SlotIntQElement ) ) ;
if ( siqel = = NULL ) {
return openErr ;
}
siqel - > sqType = sIQType ;
siqel - > sqPrio = 7 ;
siqel - > sqAddr = dskIrq ;
siqel - > sqParm = ( long ) dce ;
ctx - > siqel = siqel ;
ctx - > irqen = 0 ;
2022-10-08 16:23:01 +00:00
ctx - > op . blk_todo = 0 ;
ctx - > op . blk_done = 0 ;
ctx - > op . blk_offset = 0 ;
ctx - > op . blk_doing = 0 ;
ctx - > op . ioBuffer = 0 ;
ctx - > op . write = 0 ;
2022-10-08 08:39:18 +00:00
}
2022-07-23 10:53:30 +00:00
# endif
2022-06-26 10:31:43 +00:00
// auto-mount
{
ParamBlockRec pbr ;
pbr . volumeParam . ioVRefNum = dsptr - > dQDrive ;
ret = PBMountVol ( & pbr ) ;
}
2022-06-07 21:05:08 +00:00
}
2022-06-12 11:45:41 +00:00
2022-06-24 21:37:18 +00:00
SwapMMUMode ( & busMode ) ;
2022-06-07 21:05:08 +00:00
done :
return ret ;
}
2022-10-05 21:46:28 +00:00
# pragma parameter __D0 cNuBusFPGARAMDskClose(__A0, __A1)
2022-06-07 21:05:08 +00:00
OSErr cNuBusFPGARAMDskClose ( IOParamPtr pb , /* DCtlPtr */ AuxDCEPtr dce )
{
OSErr ret = noErr ;
2022-10-08 08:39:18 +00:00
struct RAMDrvContext * ctx = * ( struct RAMDrvContext * * ) dce - > dCtlStorage ;
2022-06-07 21:05:08 +00:00
2022-06-26 10:31:43 +00:00
/* dce->dCtlDevBase = 0xfc000000; */
2022-06-07 21:05:08 +00:00
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0001); */
if ( dce - > dCtlStorage ) {
2022-10-08 08:39:18 +00:00
//DisposePtr((Ptr)ctx->siqel);
2022-09-20 06:39:35 +00:00
/* HUnlock(dce->dCtlStorage); */ /* not needed before DisposeHandle */
2022-06-07 21:05:08 +00:00
DisposeHandle ( dce - > dCtlStorage ) ;
dce - > dCtlStorage = NULL ;
}
return ret ;
}