diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_Ctrl.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_Ctrl.c index a08c225..3b42e7c 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_Ctrl.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_Ctrl.c @@ -27,6 +27,9 @@ OSErr changeIRQ(AuxDCEPtr dce, char en, OSErr err) { if (SIntInstall(dStore->siqel, dce->dCtlSlot)) { return err; } + write_reg(dce, GOBOFB_DEBUG, 0x88888888); + write_reg(dce, GOBOFB_DEBUG, dStore->siqel); + write_reg(dce, GOBOFB_DEBUG, dStore->siqel->sqLink); } else { if (SIntRemove(dStore->siqel, dce->dCtlSlot)) { return err; diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_OpenClose.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_OpenClose.c index f33e3fe..2943f5e 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_OpenClose.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGADrvr_OpenClose.c @@ -20,7 +20,7 @@ __attribute__ ((section (".text.fbdriver"))) short fbIrq(const long sqParameter) asm volatile("" : "+d" (p_D1), "+d" (p_D2)); ret = 0; irq = (*((volatile unsigned int*)(sqParameter+GOBOFB_BASE+GOBOFB_INTR_CLEAR))); - if (irq) { + if (irq & 1) { vblproto myVbl = *(vblproto**)0x0d28; *((volatile unsigned int*)(sqParameter+GOBOFB_BASE+GOBOFB_INTR_CLEAR)) = 0; myVbl((sqParameter>>24)&0xf); // cleaner to use dStore->slot ? but require more code... @@ -34,8 +34,8 @@ __attribute__ ((section (".text.fbdriver"))) short fbIrq(const long sqParameter) OSErr cNuBusFPGAOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) { OSErr ret = noErr; - write_reg(dce, GOBOFB_DEBUG, 0xBEEF0000); - write_reg(dce, GOBOFB_DEBUG, (unsigned long)dce->dCtlDevBase); + /* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0000); */ + /* write_reg(dce, GOBOFB_DEBUG, (unsigned long)dce->dCtlDevBase); */ if (dce->dCtlStorage == nil) { diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c index 67d664a..d28ec71 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGAPrimaryInit_Primary.c @@ -1,4 +1,5 @@ #include "NuBusFPGADrvr.h" +#include "NuBusFPGARAMDskDrvr.h" #include #include @@ -23,10 +24,11 @@ UInt32 Primary(SEBlock* seblock) { busMode = 1; SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ??? - PRIM_WRITEREG(GOBOFB_VBL_MASK, 0);// disable interrupts + PRIM_WRITEREG(GOBOFB_VBL_MASK, 0);// disable interrupts on FB + PRIM_WRITEREG(DMA_IRQ_CTL, revb(0x2));// disable/clear interrupts on DSK - PRIM_WRITEREG(GOBOFB_DEBUG, 0x87654321);// trace - PRIM_WRITEREG(GOBOFB_DEBUG, busMode);// trace + /* PRIM_WRITEREG(GOBOFB_DEBUG, 0x87654321);// trace */ + /* PRIM_WRITEREG(GOBOFB_DEBUG, busMode);// trace */ hres = __builtin_bswap32((UInt32)PRIM_READREG(GOBOFB_HRES)); // fixme: endianness vres = __builtin_bswap32((UInt32)PRIM_READREG(GOBOFB_VRES)); // fixme: endianness diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr.h b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr.h index 4cd2dd3..714eb79 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr.h +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr.h @@ -12,7 +12,6 @@ #include "NuBusFPGADrvr.h" -#ifdef ENABLE_DMA typedef struct { unsigned long blk_todo; unsigned long blk_done; @@ -21,26 +20,24 @@ typedef struct { void *ioBuffer; int write; } ram_dsk_op; -#endif struct RAMDrvContext { DrvSts2 drvsts; + ram_dsk_op op; char slot; #ifdef ENABLE_DMA + char irqen; unsigned int dma_blk_size; unsigned int dma_blk_size_mask; unsigned int dma_blk_size_shift; unsigned long dma_blk_base; unsigned long dma_mem_size; SlotIntQElement *siqel; - ram_dsk_op op; - char irqen; #endif }; #define DRIVE_SIZE_BYTES ((256ul-8ul)*1024ul*1024ul) // FIXME: mem size minus fb size -#ifdef ENABLE_DMA /* FIXME; should be auto-generated for CSR addresses... */ /* WARNING: 0x00100800 is the offset to GOBOFB_BASE !! */ #define DMA_BLK_SIZE (0x00100800 | 0x00) @@ -56,15 +53,15 @@ struct RAMDrvContext { #define DMA_IRQSTATUS (0x00100800 | 0x34) -#endif /* ctrl */ -OSErr changeRAMdskIRQ(AuxDCEPtr dce, char en, OSErr err) __attribute__ ((section (".text.dskdriver"))); +OSErr changeRAMDskIRQ(AuxDCEPtr dce, char en, OSErr err) __attribute__ ((section (".text.dskdriver"))); OSErr cNuBusFPGARAMDskCtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.dskdriver"))); /* open, close */ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.dskdriver"))); OSErr cNuBusFPGARAMDskClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.dskdriver"))); /* prime */ +short dskIrq(const long sqParameter) __attribute__ ((section (".text.dskdriver"))); OSErr cNuBusFPGARAMDskPrime(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.dskdriver"))); /* status */ OSErr cNuBusFPGARAMDskStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.dskdriver"))); diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c index 804eb6a..de2f4a6 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c @@ -1,7 +1,6 @@ #include "NuBusFPGARAMDskDrvr.h" - - +#ifdef ENABLE_DMA OSErr changeRAMDskIRQ(AuxDCEPtr dce, char en, OSErr err) { struct RAMDrvContext *ctx = *(struct RAMDrvContext**)dce->dCtlStorage; @@ -19,11 +18,12 @@ OSErr changeRAMDskIRQ(AuxDCEPtr dce, char en, OSErr err) { } } - write_reg(dce, DMA_IRQ_CTL, en ? 0x3 : 0x2); // 0x2: always clear pending interrupt + write_reg(dce, DMA_IRQ_CTL, en ? revb(0x3) : revb(0x2)); // 0x2: always clear pending interrupt ctx->irqen = en; } return noErr; } +#endif #pragma parameter __D0 cNuBusFPGARAMDskCtl(__A0, __A1) diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c index c2deb56..6c7d75a 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c @@ -14,32 +14,6 @@ __attribute__ ((section (".text.dskdriver"))) static inline int dupAddDrive(unsi return num; // should cost nothing, num is already in D0 } - -/* see the comment for the FB irq */ -#pragma parameter __D0 dskIrq(__A1) -__attribute__ ((section (".text.dskdriver"))) short dskIrq(const long sqParameter) { - register unsigned long p_D1 asm("d1"), p_D2 asm("d2"); - AuxDCEPtr dce; - struct RAMDrvContext *ctx; - unsigned int irq; - short ret; - asm volatile("" : "+d" (p_D1), "+d" (p_D2)); - dce = (AuxDCEPtr)sqParameter; - ctx = *(struct RAMDrvContext**)dce->dCtlStorage; - ret = 0; - irq = revb(*((volatile unsigned int*)(sqParameter+GOBOFB_BASE+DMA_IRQSTATUS))); - *((volatile unsigned int*)(sqParameter+GOBOFB_BASE+GOBOFB_DEBUG)) = 0x11111111; - *((volatile unsigned int*)(sqParameter+GOBOFB_BASE+GOBOFB_DEBUG)) = irq; - if (irq & 1) { - unsigned int irqctrl = revb(*((volatile unsigned int*)(sqParameter+GOBOFB_BASE+DMA_IRQ_CTL))); - irqctrl |= 0x2; // irq clear - *((volatile unsigned int*)(sqParameter+GOBOFB_BASE+DMA_IRQ_CTL)) = revb(irqctrl); - ret = 1; - } - asm volatile("" : : "d" (p_D1), "d" (p_D2)); - return ret; -} - #include #pragma parameter __D0 cNuBusFPGARAMDskOpen(__A0, __A1) @@ -100,6 +74,9 @@ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) ctx = *(struct RAMDrvContext **)dce->dCtlStorage; ctx->slot = slot; + + // 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 dsptr = &ctx->drvsts; // dsptr->track /* current track */ @@ -150,15 +127,12 @@ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) /* write_reg(dce, GOBOFB_DEBUG, ctx->dma_blk_base); */ /* write_reg(dce, GOBOFB_DEBUG, ctx->dma_mem_size); */ - if (1) { + { SlotIntQElement *siqel = (SlotIntQElement *)NewPtrSysClear(sizeof(SlotIntQElement)); if (siqel == NULL) { return openErr; } - - // disable IRQ for now - write_reg(dce, DMA_IRQ_CTL, 0x2); // 0x1 would enable irq, 0x2 is auto-clear so we make sure there's no spurious IRQ pending siqel->sqType = sIQType; siqel->sqPrio = 7; @@ -166,8 +140,13 @@ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) siqel->sqParm = (long)dce; ctx->siqel = siqel; ctx->irqen = 0; - write_reg(dce, GOBOFB_DEBUG, siqel); - write_reg(dce, GOBOFB_DEBUG, ctx); + + 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; } #endif diff --git a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Prime.c b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Prime.c index 14ad501..eb41c7e 100644 --- a/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Prime.c +++ b/nubus-to-ztex-gateware/DeclROM/NuBusFPGARAMDskDrvr_Prime.c @@ -9,6 +9,7 @@ __attribute__ ((section (".text.dskdriver"))) static inline void waitSome(unsign } } +#ifdef ENABLE_DMA __attribute__ ((section (".text.dskdriver"))) static void startOneOp(struct RAMDrvContext *ctx, const AuxDCEPtr dce) { if (ctx->op.blk_todo > 0) { ctx->op.blk_doing = ctx->op.blk_todo; @@ -17,13 +18,15 @@ __attribute__ ((section (".text.dskdriver"))) static void startOneOp(struct RAMD } write_reg(dce, DMA_BLK_ADDR, revb(ctx->dma_blk_base + ctx->op.blk_offset)); write_reg(dce, DMA_DMA_ADDR, revb(ctx->op.ioBuffer + (ctx->op.blk_done << ctx->dma_blk_size_shift))); - write_reg(dce, DMA_BLK_CNT, revb((ctx->op.write ? 0x80000000ul : 0x00000000ul) | ctx->op.blk_doing)); ctx->op.blk_done += ctx->op.blk_doing; ctx->op.blk_todo -= ctx->op.blk_doing; ctx->op.blk_offset += ctx->op.blk_doing; + write_reg(dce, DMA_BLK_CNT, revb((ctx->op.write ? 0x80000000ul : 0x00000000ul) | ctx->op.blk_doing)); } } +#endif +#ifdef ENABLE_DMA __attribute__ ((section (".text.dskdriver"))) static OSErr waitForHW(struct RAMDrvContext *ctx, const AuxDCEPtr dce) { unsigned long count, max_count, delay; unsigned long blk_cnt, status; @@ -49,6 +52,227 @@ __attribute__ ((section (".text.dskdriver"))) static OSErr waitForHW(struct RAMD } return ret; } +#endif + +#ifdef ENABLE_DMA +/* see the comment for the FB irq */ +#pragma parameter __D0 dskIrq(__A1) +__attribute__ ((section (".text.dskdriver"))) short dskIrq(const long sqParameter) { + register unsigned long p_D1 asm("d1"), p_D2 asm("d2"); + AuxDCEPtr dce; + struct RAMDrvContext *ctx; + unsigned int irq; + short ret; + asm volatile("" : "+d" (p_D1), "+d" (p_D2)); + dce = (AuxDCEPtr)sqParameter; + ctx = *(struct RAMDrvContext**)dce->dCtlStorage; + ret = 0; + irq = revb(read_reg(dce, DMA_IRQSTATUS)); + if (irq & 1) { + unsigned int irqctrl = revb(read_reg(dce, DMA_IRQ_CTL)); + irqctrl |= 0x2; // irq clear + write_reg(dce, DMA_IRQ_CTL, revb(irqctrl)); + if (ctx->op.blk_todo > 0) { + startOneOp(ctx, dce); + } else { + if (ctx->op.blk_doing > 0) { + ctx->op.blk_doing = 0; // reset just in case + IODone((DCtlPtr)dce, noErr); + } + } + ret = 1; + } + asm volatile("" : : "d" (p_D1), "d" (p_D2)); + return ret; +} +#endif + +#ifdef ENABLE_DMA +__attribute__ ((section (".text.dskdriver"))) static OSErr doAsync(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce, struct RAMDrvContext *ctx) { + OSErr ret = noErr; + + unsigned char* superslot = (unsigned char*)(((unsigned long)ctx->slot) << 28ul); + unsigned long abs_offset = 0; + /* IOParamPtr: Devices 1-53 (p73) */ + /* **** WHERE **** */ + switch(pb->ioPosMode & 0x000F) { // ignore rdVerify + case fsAtMark: + abs_offset = dce->dCtlPosition; + break; + case fsFromStart: + abs_offset = pb->ioPosOffset; + break; + case fsFromMark: + abs_offset = dce->dCtlPosition + pb->ioPosOffset; + break; + default: + break; + } + /* **** WHAT **** */ + /* Devices 1-33 (p53) */ + if ((pb->ioTrap & 0x00FF) == aRdCmd) { + if(!(pb->ioPosMode & 0x40)) { // rdVerify, let's ignore it for now + unsigned long blk_cnt, status; + blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; + status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; + if ((blk_cnt == 0) && (status == 0)) { + ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; + ctx->op.blk_done = 0; + ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; + ctx->op.ioBuffer = pb->ioBuffer; + ctx->op.write = 0; + /* should we do it now ? */ + pb->ioActCount = pb->ioReqCount; + dce->dCtlPosition = abs_offset + pb->ioReqCount; + pb->ioPosOffset = dce->dCtlPosition; + if (ctx->op.blk_todo > 0) { + startOneOp(ctx, dce); + goto done; + } + } + if (blk_cnt || status) { + ret = readErr; + goto done; + } + } + } else if ((pb->ioTrap & 0x00FF) == aWrCmd) { + unsigned long blk_cnt, status; + blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; + status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; + if ((blk_cnt == 0) && (status == 0)) { + ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; + ctx->op.blk_done = 0; + ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; + ctx->op.ioBuffer = pb->ioBuffer; + ctx->op.write = 1; + /* should we do it now ? */ + pb->ioActCount = pb->ioReqCount; + dce->dCtlPosition = abs_offset + pb->ioReqCount; + pb->ioPosOffset = dce->dCtlPosition; + if (ctx->op.blk_todo > 0) { + startOneOp(ctx, dce); + goto done; + } + } + if (blk_cnt || status) { + ret = writErr; + goto done; + } + } else { + ret = paramErr; + goto done; + } + + done: + return ret; +} +#endif // ENABLE_DMA + +__attribute__ ((section (".text.dskdriver"))) static OSErr doSync(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce, struct RAMDrvContext *ctx) { + OSErr ret = noErr; + + unsigned char* superslot = (unsigned char*)(((unsigned long)ctx->slot) << 28ul); + unsigned long abs_offset = 0; + /* IOParamPtr: Devices 1-53 (p73) */ + /* **** WHERE **** */ + switch(pb->ioPosMode & 0x000F) { // ignore rdVerify + case fsAtMark: + abs_offset = dce->dCtlPosition; + break; + case fsFromStart: + abs_offset = pb->ioPosOffset; + break; + case fsFromMark: + abs_offset = dce->dCtlPosition + pb->ioPosOffset; + break; + default: + break; + } + /* **** WHAT **** */ + /* Devices 1-33 (p53) */ + if ((pb->ioTrap & 0x00FF) == aRdCmd) { + if(!(pb->ioPosMode & 0x40)) { // rdVerify, let's ignore it for now +#ifdef ENABLE_DMA + /* write_reg(dce, GOBOFB_DEBUG, 0xD1580000); */ + /* write_reg(dce, GOBOFB_DEBUG, (unsigned long)pb->ioBuffer); */ + /* write_reg(dce, GOBOFB_DEBUG, pb->ioReqCount); */ + if ((((unsigned long)pb->ioBuffer & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)pb->ioReqCount & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)abs_offset & ctx->dma_blk_size_mask) == 0)) { + unsigned long blk_cnt, status; + blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; + status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; + if ((blk_cnt == 0) && (status == 0)) { + ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; + ctx->op.blk_done = 0; + ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; + ctx->op.ioBuffer = pb->ioBuffer; + ctx->op.write = 0; + while (ctx->op.blk_todo > 0) { + startOneOp(ctx, dce); + ret = waitForHW(ctx, dce); + if (ret != noErr) + goto done; + } + } + if (blk_cnt || status) { + ret = readErr; + goto done; + } + } else +#endif + { + BlockMoveData((superslot + abs_offset), pb->ioBuffer, pb->ioReqCount); + } + } + pb->ioActCount = pb->ioReqCount; + dce->dCtlPosition = abs_offset + pb->ioReqCount; + pb->ioPosOffset = dce->dCtlPosition; + } else if ((pb->ioTrap & 0x00FF) == aWrCmd) { +#ifdef ENABLE_DMA + /* write_reg(dce, GOBOFB_DEBUG, 0xD1580001); */ + /* write_reg(dce, GOBOFB_DEBUG, (unsigned long)pb->ioBuffer); */ + /* write_reg(dce, GOBOFB_DEBUG, pb->ioReqCount); */ + if ((((unsigned long)pb->ioBuffer & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)pb->ioReqCount & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)abs_offset & ctx->dma_blk_size_mask) == 0)) { + unsigned long blk_cnt, status; + blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; + status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; + if ((blk_cnt == 0) && (status == 0)) { + ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; + ctx->op.blk_done = 0; + ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; + ctx->op.ioBuffer = pb->ioBuffer; + ctx->op.write = 1; + while (ctx->op.blk_todo > 0) { + startOneOp(ctx, dce); + ret = waitForHW(ctx, dce); + if (ret != noErr) + goto done; + } + } + if (blk_cnt || status) { + ret = writErr; + goto done; + } + } else +#endif + { + BlockMoveData(pb->ioBuffer, (superslot + abs_offset), pb->ioReqCount); + } + pb->ioActCount = pb->ioReqCount; + dce->dCtlPosition = abs_offset + pb->ioReqCount; + pb->ioPosOffset = dce->dCtlPosition; + } else { + ret = paramErr; + goto done; + } + + done: + ctx->op.blk_doing = 0; + return ret; +} /* Devices 1-34 (p54) */ #pragma parameter __D0 cNuBusFPGARAMDskPrime(__A0, __A1) @@ -56,6 +280,22 @@ OSErr cNuBusFPGARAMDskPrime(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) { OSErr ret = noErr; struct RAMDrvContext *ctx; + unsigned long abs_offset = 0; + /* IOParamPtr: Devices 1-53 (p73) */ + /* **** WHERE **** */ + switch(pb->ioPosMode & 0x000F) { // ignore rdVerify + case fsAtMark: + abs_offset = dce->dCtlPosition; + break; + case fsFromStart: + abs_offset = pb->ioPosOffset; + break; + case fsFromMark: + abs_offset = dce->dCtlPosition + pb->ioPosOffset; + break; + default: + break; + } /* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0003); */ /* write_reg(dce, GOBOFB_DEBUG, pb->ioTrap); */ @@ -66,111 +306,43 @@ OSErr cNuBusFPGARAMDskPrime(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) ctx = *(struct RAMDrvContext**)dce->dCtlStorage; if (ctx) { - unsigned char* superslot = (unsigned char*)(((unsigned long)ctx->slot) << 28ul); - unsigned long abs_offset = 0; - /* IOParamPtr: Devices 1-53 (p73) */ - /* **** WHERE **** */ - switch(pb->ioPosMode & 0x000F) { // ignore rdVerify - case fsAtMark: - abs_offset = dce->dCtlPosition; - break; - case fsFromStart: - abs_offset = pb->ioPosOffset; - break; - case fsFromMark: - abs_offset = dce->dCtlPosition + pb->ioPosOffset; - break; - default: - break; - } - /* **** WHAT **** */ - /* Devices 1-33 (p53) */ - if ((pb->ioTrap & 0x00FF) == aRdCmd) { - if(!(pb->ioPosMode & 0x40)) { // rdVerify, let's ignore it for now #ifdef ENABLE_DMA - /* write_reg(dce, GOBOFB_DEBUG, 0xD1580000); */ - /* write_reg(dce, GOBOFB_DEBUG, (unsigned long)pb->ioBuffer); */ - /* write_reg(dce, GOBOFB_DEBUG, pb->ioReqCount); */ - if ((((unsigned long)pb->ioBuffer & ctx->dma_blk_size_mask) == 0) && - (((unsigned long)pb->ioReqCount & ctx->dma_blk_size_mask) == 0) && - (((unsigned long)abs_offset & ctx->dma_blk_size_mask) == 0)) { - unsigned long blk_cnt, status; - blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; - status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; - if ((blk_cnt == 0) && (status == 0)) { - ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; - ctx->op.blk_done = 0; - ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; - ctx->op.ioBuffer = pb->ioBuffer; - ctx->op.write = 0; - while (ctx->op.blk_todo > 0) { - startOneOp(ctx, dce); - ret = waitForHW(ctx, dce); - if (ret != noErr) - goto done; - } - } - if (blk_cnt || status) { - ret = readErr; - goto done; - } - } else -#endif - { - BlockMoveData((superslot + abs_offset), pb->ioBuffer, pb->ioReqCount); - } + if ((((unsigned long)pb->ioBuffer & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)pb->ioReqCount & ctx->dma_blk_size_mask) == 0) && + (((unsigned long)abs_offset & ctx->dma_blk_size_mask) == 0) && + (!(pb->ioTrap & (1<ioTrap & 0x00FF) == aWrCmd ? writErr : readErr); + if (ret != noErr) { + IODone((DCtlPtr)dce, ret); + goto done; } - pb->ioActCount = pb->ioReqCount; - dce->dCtlPosition = abs_offset + pb->ioReqCount; - pb->ioPosOffset = dce->dCtlPosition; - } else if ((pb->ioTrap & 0x00FF) == aWrCmd) { -#ifdef ENABLE_DMA - /* write_reg(dce, GOBOFB_DEBUG, 0xD1580001); */ - /* write_reg(dce, GOBOFB_DEBUG, (unsigned long)pb->ioBuffer); */ - /* write_reg(dce, GOBOFB_DEBUG, pb->ioReqCount); */ - if ((((unsigned long)pb->ioBuffer & ctx->dma_blk_size_mask) == 0) && - (((unsigned long)pb->ioReqCount & ctx->dma_blk_size_mask) == 0) && - (((unsigned long)abs_offset & ctx->dma_blk_size_mask) == 0)) { - unsigned long blk_cnt, status; - blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF; - status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS; - if ((blk_cnt == 0) && (status == 0)) { - ctx->op.blk_todo = pb->ioReqCount >> ctx->dma_blk_size_shift; - ctx->op.blk_done = 0; - ctx->op.blk_offset = abs_offset >> ctx->dma_blk_size_shift; - ctx->op.ioBuffer = pb->ioBuffer; - ctx->op.write = 1; - while (ctx->op.blk_todo > 0) { - startOneOp(ctx, dce); - ret = waitForHW(ctx, dce); - if (ret != noErr) - goto done; - } - } - if (blk_cnt || status) { - ret = writErr; - goto done; - } - } else + // DMA-ifiable & queuable, go async + ret = doAsync(pb, dce, ctx); + // no IODone if ongoing, done at interrupt time + if (ret != noErr) + IODone((DCtlPtr)dce, ret); + goto done; + } else #endif - { - BlockMoveData(pb->ioBuffer, (superslot + abs_offset), pb->ioReqCount); - } - pb->ioActCount = pb->ioReqCount; - dce->dCtlPosition = abs_offset + pb->ioReqCount; - pb->ioPosOffset = dce->dCtlPosition; - } else { - ret = paramErr; + { +#ifdef ENABLE_DMA + ret = changeRAMDskIRQ(dce, 0, (pb->ioTrap & 0x00FF) == aWrCmd ? writErr : readErr); +#endif + if (ret) + goto done; + ret = doSync(pb, dce, ctx); + if (!(pb->ioTrap & (1<ioTrap & (1<ioTrap & (1<