update, including support for ROM-in-builtin-flash

This commit is contained in:
Romain Dolbeau 2023-10-14 10:37:15 +02:00
parent b90dfb229e
commit d9535db3be
41 changed files with 46 additions and 5774 deletions

3
.gitmodules vendored
View File

@ -5,9 +5,6 @@
[submodule "nubus-to-ztex-gateware/VintageBusFPGA_Common"]
path = nubus-to-ztex-gateware/VintageBusFPGA_Common
url = git@github.com:rdolbeau/VintageBusFPGA_Common.git
[submodule "nubus-to-ztex-gateware/DeclROM/ns816-declrom"]
path = nubus-to-ztex-gateware/DeclROM/ns816-declrom
url = https://github.com/jaoswald/ns816-declrom
[submodule "nubus-to-ztex-gateware/hdl-util_hdmi"]
path = nubus-to-ztex-gateware/hdl-util_hdmi
url = https://github.com/hdl-util/hdmi

View File

@ -22,7 +22,9 @@ Directory 'nubus-to-ztex'
The (now obsolete) V1.0 custom board is a NuBus-compliant (I hope...) board, designed to receive a [ZTex USB-FPGA Module 2.13](https://www.ztex.de/usb-fpga-2/usb-fpga-2.13.e.html) as a daughterboard. The ZTex module contains the actual FPGA (Artix-7), some RAM, programming hardware, etc. The NuBus board contains level-shifters & drivers ICs to interface between the NuBus signals and the FPGA, a CPLD handling some level-shifting & the bus mastering arbitration, a serial header, two user Leds, 14 debug Leds tied to specific NuBus or CPLD/FPGA signals, a JTAG header, a USB micro-B connector, a VGA chip & connector, and a HDMI chip & connector. It supports every NuBus feature except the optional parity (i.e. it can do both slave and master modes). The V1.0 board is in commit 3f3371a. The CPLD solution works but is annoying as it requires older Xilinx software (ISE 14.7) and dedicated JTAG programmer to use.
The current board is V1.2. It drops the CPLD and VGA port. Bus arbitration is now done inside the FPGA. It gains a micro-sd slot, and a custom expansion connector that is based (and compatible with, with more signals) PMod. It supports the same accelerated HDMI framebuffer and RAM Disk. Optionally, The Declaration Rom can be stored in a Flash NOR chip connected ot the PMOd expansion connector (easier for working on embedded driver in the DeclRom).
The current board is V1.2. It drops the CPLD and VGA port. Bus arbitration is now done inside the FPGA. It gains a micro-sd slot, and a custom expansion connector that is based (and compatible with, with more signals) PMod. It supports the same accelerated HDMI framebuffer and RAM Disk. Optionally, The Declaration Rom can be stored in a Flash NOR chip connected ot the PMOd expansion connector (easier for working on embedded driver in the DeclRom). The ROM can alternately be stored in a sector of the config flash from the ZTex board.
The new (July 2023) [ZTex USB-FPGA Module 2.12](https://www.ztex.de/usb-fpga-2/usb-fpga-2.12.e.html) should be compatible with all *FPGA, but has not yet been tested.
The PCBs were designed with Kicad 5.1

View File

@ -11,3 +11,4 @@ blit.raw
blit.s
*.patch
OLD
nubusfpga_csr_*.h

View File

@ -1,11 +0,0 @@
vid_decl_rom.bin
vid_decl_rom.dir
vid_decl_rom.l
vid_decl_rom.o
vid_decl_rom.raw
vid_decl_rom.srec
*.bin
VidRom*
NuBusFPGADrvr*.s
NuBusFPGARAMDskDrvr*.s
*.o

View File

@ -1,56 +0,0 @@
.include "res.inc"
NuBusFPGAID = 0xC0
defMinorBase = 0 /* beginning */
defMinorLength = 0x800000 /* 8192 KiB */
Pages8s = 1
Pages4s = 1
Pages2s = 1
Pages1s = 1
Pages15s = 1
Pages24s = 1
defmBounds_Ls = 0
defmBounds_Ts = 0
defmBounds_Rs = HRES
defmBounds_Bs = VRES
defScrnRow = HRES
/* row bytes */
RB8s = HRES
RB4s = HRES/2
RB2s = HRES/4
RB1s = HRES/8
RB15s = HRES*2
RB24s = HRES*4
DrHwNuBusFPGA = 0xBEEF /* placeholder for GoboFB */
DrHwNuBusFPGADsk = 0xBEEE /* placeholder for RAM Dsk */
DrHwNuBusFPGAAudio = 0xBEED /* placeholder for Audio */
DrHwNuBusFPGASDCard = 0xBEEC /* placeholder for SD Card */
typeDrive = 0x1000 /* placeholder for RAM Dsk*/
typeAudio = 0x1001 /* placeholder for Audio*/
defmBaseOffset = 0 /* beginning, placeholder */
devVersion = 0 /* placeholder */
defmHRes = 0x480000 /* Horizontal Pixels/inch */
defmVRes = 0x480000 /* Vertical pixels/inch */
clutType = 0
directType = 2
defmPlaneBytes = 0 /* Offset from one plane to the next. */
SGammaResID = 0
ChunkyIndexed = 0
ChunkyDirect = 16
defVersion = 0 /* Version = 0 */

View File

@ -1,74 +0,0 @@
AS=/home/dolbeau/Retro68/build/toolchain/bin/m68k-apple-macos-as
CC=/home/dolbeau/Retro68/build/toolchain/bin/m68k-apple-macos-gcc
LD=/home/dolbeau/Retro68/build/toolchain/bin/m68k-apple-macos-ld
STRIP=/home/dolbeau/Retro68/build/toolchain/bin/m68k-apple-macos-strip
OBJCOPY=/home/dolbeau/Retro68/build/toolchain/bin/m68k-apple-macos-objcopy
HOSTCC=gcc
HOSTCFLAGS=-O2
ARCHFLAGS=-march=68020 -mcpu=68020
CFLAGS=-O2 -mpcrel
NS816DECLROMDIR=./ns816-declrom
NUBUS_CHECKSUM=${NS816DECLROMDIR}/nubus_checksum
PROCESS_ROM=${NS816DECLROMDIR}/process_rom
APPLEINCS=${NS816DECLROMDIR}/atrap.inc ${NS816DECLROMDIR}/declrom.inc ${NS816DECLROMDIR}/globals.inc
HRES=1920
VRES=1080
QEMU=no
ifeq ($(QEMU),yes)
CFLAGS+=-DQEMU
endif
CSRC_VIDEO=NuBusFPGADrvr_OpenClose.c NuBusFPGADrvr_Ctrl.c NuBusFPGADrvr_Status.c NuBusFPGAPrimaryInit_Primary.c NuBusFPGAPrimaryInit_RamInit.c NuBusFPGASecondaryInit_Secondary.c
CSRC_RAMDSK=NuBusFPGARAMDskDrvr_OpenClose.c NuBusFPGARAMDskDrvr_Ctrl.c NuBusFPGARAMDskDrvr_Prime.c NuBusFPGARAMDskDrvr_Status.c myrle.c
CSRC_SDCARD=NuBusFPGASDCardDrvr_OpenClose.c NuBusFPGASDCardDrvr_Ctrl.c NuBusFPGASDCardDrvr_Prime.c NuBusFPGASDCardDrvr_Status.c
CSRC=${CSRC_VIDEO} ${CSRC_RAMDSK} ${CSRC_SDCARD}
CSRC_ASM=${CSRC:.c=.s}
GEN_ASM=VidRomDef.s VidRomDir.s VidRomName.s VidRomRes.s VidRomRsrcDir.s
all: vid_decl_rom.bin
gen_mode: gen_mode.c
$(HOSTCC) -Wall ${HOSTCFLAGS} $^ -o $@
${GEN_ASM}: gen_mode
./gen_mode ${HRES} ${VRES}
$(NUBUS_CHECKSUM): ${NS816DECLROMDIR}/nubus_checksum.cc ${NS816DECLROMDIR}/nubus_crc.cc
g++ -std=c++11 $^ -lglog -lgflags -labsl_strings -o $@
vid_decl_rom.o: vid_decl_rom.s NuBusFPGADrvr.s NuBusFPGARAMDskDrvr.s ${APPLEINCS} DepVideo.inc ${GEN_ASM}
rm -f res.inc
echo -e "HRES=${HRES}\nVRES=${VRES}\n" | tee res.inc
${AS} ${ARCHFLAGS} -I${NS816DECLROMDIR} $< -o $@ -a > vid_decl_rom.l
myrle.o: myrle.c
${CC} ${ARCHFLAGS} ${CFLAGS} $< -c -o $@ -DSKIP_MAIN
dump_cpr.s: dump_cpr.c
${CC} ${ARCHFLAGS} ${CFLAGS} $< -S -o $@ -DSKIP_MAIN
sed -i -e 's/^\([^a-zA-Z0-9_]*\.globl.*\)/# --- \1/' $@
sed -i -e 's/\.\(L[0-9][0-9]*\)/.dump_cpr_\1/g' $@
%.o: %.c NuBusFPGADrvr.h
${CC} ${CFLAGS} $< -c -o $@ -DHRES=${HRES} -DVRES=${VRES}
vid_decl_rom.elf: linker.ld vid_decl_rom.o ${CSRC:.c=.o} # linker script must be first
${LD} -o $@ -T $^
vid_decl_rom.raw: vid_decl_rom.elf
${OBJCOPY} $^ $@ --input-target=elf32-m68k --output-target=binary
vid_decl_rom.bin: vid_decl_rom.raw $(NUBUS_CHECKSUM)
${NUBUS_CHECKSUM} --input_file $< --output_file $@ --output_size 32768
dd if=dump.cpr of=vid_decl_rom.bin bs=1 conv=notrunc
clean:
rm -f res.inc ${CSRC_ASM} *.o vid_decl_rom.srec vid_decl_rom.raw vid_decl_rom.dir vid_decl_rom.l VidRom*.s
append_romdir: append_romdir.c
${HOSTCC} $< -o $@

View File

@ -1,157 +0,0 @@
#ifndef __NUBUSFPGADRVR_H__
#define __NUBUSFPGADRVR_H__
#include <Files.h>
#include <Devices.h>
#include <Slots.h>
#include <MacErrors.h>
#include <MacMemory.h>
#include <Video.h>
#define GOBOFB_BASE 0x00900000
#define GOBOFB_ACCEL 0x00901000
#define GOBOFB_ACCEL_LE 0x00901800
//#define GOBOFB_REG_BASE 0x00900000
//#define GOBOFB_MEM_BASE 0x00000000 /* remapped to 0x8f800000 by HW */
#define GOBOFB_MODE 0x0
#define GOBOFB_VBL_MASK 0x4
#define GOBOFB_VIDEOCTRL 0x8
#define GOBOFB_INTR_CLEAR 0xc
#define GOBOFB_RESET 0x10
#define GOBOFB_LUT_ADDR 0x14
#define GOBOFB_LUT 0x18
#define GOBOFB_DEBUG 0x1c
//#define GOBOFB_CURSOR_LUT 0x20
//#define GOBOFB_CURSOR_XY 0x24
#define GOBOFB_HRES 0x40
#define GOBOFB_VRES 0x44
#define GOBOFB_HRES_START 0x48
#define GOBOFB_VRES_START 0x4C
#define GOBOFB_HRES_END 0x50
#define GOBOFB_VRES_END 0x54
//#define GOBOFB_MASK_BASE 0x80
//#define GOBOFB_BITS_BASE 0x100
#define GOBOFB_INTR_VBL 0x1
// for GOBOFB_MODE
#define GOBOFB_MODE_1BIT 0x0
#define GOBOFB_MODE_2BIT 0x1
#define GOBOFB_MODE_4BIT 0x2
#define GOBOFB_MODE_8BIT 0x3
#define GOBOFB_MODE_24BIT 0x10
#define GOBOFB_MODE_15BIT 0x11
#define u_int32_t volatile unsigned long
struct goblin_accel_regs {
u_int32_t reg_status; // 0
u_int32_t reg_cmd;
u_int32_t reg_r5_cmd;
u_int32_t resv0;
u_int32_t reg_width; // 4
u_int32_t reg_height;
u_int32_t reg_fgcolor;
u_int32_t resv2;
u_int32_t reg_bitblt_src_x; // 8
u_int32_t reg_bitblt_src_y;
u_int32_t reg_bitblt_dst_x;
u_int32_t reg_bitblt_dst_y;
u_int32_t reg_src_stride; // 12
u_int32_t reg_dst_stride;
u_int32_t reg_src_ptr; // 14
u_int32_t reg_dst_ptr;
};
// status
#define WORK_IN_PROGRESS_BIT 0
// cmd
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
#define DO_FILL_BIT 1 // hardwired in goblin_accel.py
#define DO_TEST_BIT 3 // hardwired in goblin_accel.py
struct MyGammaTbl {
short gVersion; /*gamma version number*/
short gType; /*gamma data type*/
short gFormulaSize; /*Formula data size*/
short gChanCnt; /*number of channels of data*/
short gDataCnt; /*number of values/channel*/
short gDataWidth; /*bits/corrected value (data packed to next larger byte size)*/
char gFormulaData[3][256]; /*data for formulas followed by gamma values*/
};
#define nativeVidMode ((unsigned char)0x80)
/* alternate resolution in 0x81...0x8f */
#define diskResource ((unsigned char)0x90)
struct NuBusFPGADriverGlobals {
AuxDCEPtr dce; // unused
SlotIntQElement *siqel;
//unsigned char shadowClut[768];
unsigned short hres[16]; /* HW max in 0 */
unsigned short vres[16]; /* HW max in 0 */
unsigned short curPage;
unsigned char maxMode;
unsigned char curMode; /* mode ; this is resolution (which can't be changed in 7.1 except via reboot ?) */
unsigned char curDepth; /* depth */
char gray;
char irqen;
char slot;
struct MyGammaTbl gamma;
};
typedef struct NuBusFPGADriverGlobals NuBusFPGADriverGlobals;
typedef struct NuBusFPGADriverGlobals *NuBusFPGADriverGlobalsPtr;
typedef struct NuBusFPGADriverGlobals **NuBusFPGADriverGlobalsHdl;
typedef struct NuBusFPGAPramRecord { /* slot parameter RAM record, derived from SPRAMRecord */
short boardID; /* Apple-defined card ID */
char vendorUse1; /* reserved for vendor use */ /* DCDMF3 p210 says reserved for system ... */
unsigned char mode; /* vendorUse2 */
unsigned char depth; /* vendorUse3 */
unsigned char page; /* vendorUse4 */
char vendorUse5; /* reserved for vendor use */
char vendorUse6; /* reserved for vendor use */
} NuBusFPGAPramRecord;
typedef struct NuBusFPGAPramRecord *NuBusFPGAPramRecordPtr;
static inline void write_reg(AuxDCEPtr dce, unsigned int reg, unsigned int val) {
*((volatile unsigned int*)(dce->dCtlDevBase+GOBOFB_BASE+reg)) = val;
}
static inline unsigned int read_reg(AuxDCEPtr dce, unsigned int reg) {
return *((volatile unsigned int*)(dce->dCtlDevBase+GOBOFB_BASE+reg));;
}
/* ASM */
extern SlotIntServiceProcPtr interruptRoutine;
/* ctrl */
void linearGamma(NuBusFPGADriverGlobalsPtr dStore) __attribute__ ((section (".text.fbdriver")));
OSErr changeIRQ(AuxDCEPtr dce, char en, OSErr err) __attribute__ ((section (".text.fbdriver")));
OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.fbdriver")));
OSErr reconfHW(AuxDCEPtr dce, unsigned char mode, unsigned char depth, unsigned short page) __attribute__ ((section (".text.fbdriver")));
OSErr updatePRAM(AuxDCEPtr dce, unsigned char mode, unsigned char depth, unsigned short page) __attribute__ ((section (".text.fbdriver")));
/* status */
OSErr cNuBusFPGAStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.fbdriver")));
/* open close */
OSErr cNuBusFPGAOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.fbdriver")));
OSErr cNuBusFPGAClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.fbdriver")));
/* primary init */
UInt32 Primary(SEBlock* block) __attribute__ ((section (".text.primary")));
int sdram_init(uint32_t a32) __attribute__ ((section (".text.primary")));
/* secondary init */
UInt32 Secondary(SEBlock* seblock) __attribute__ ((section (".text.secondary")));
#define Check32QDTrap 0xAB03
#if 0
static inline UInt32 revb(UInt32 d) {
return ((d&0xFFul)<<24) | ((d&0xFF00ul)<<8) | ((d&0xFF0000ul)>>8) | ((d&0xFF000000ul)>>24);
}
#else
#define revb(a) __builtin_bswap32(a)
#endif
#endif

View File

@ -1,23 +0,0 @@
NuBusFPGADrvr:
.word 0x4c00 /* 0x4c00: ctl, status, needsLock [Devices.a] */
.word 0
.word 0
.word 0
/* Entry point offset table */
/* we can directly call the C version if it has the right calling convention */
.word cNuBusFPGAOpen-NuBusFPGADrvr /* open routine */
.word NuBusFPGADrvr-NuBusFPGADrvr /* no prime */
.word cNuBusFPGACtl-NuBusFPGADrvr /* control */
.word cNuBusFPGAStatus-NuBusFPGADrvr /* status */
.word cNuBusFPGAClose-NuBusFPGADrvr /* close */
_NuBusFPGATitle:
.byte _NuBusFPGATitle_StringEnd-.-1 /* pascal string length */
.ascii ".NuBusFPGA_Drvr"
_NuBusFPGATitle_StringEnd:
.word 0 /* version number */
/* for entry points: */
/* A0 pointer to driver parameter block */
/* A1 pointer to driver device control entry */
ALIGN 2

View File

@ -1,513 +0,0 @@
#include "NuBusFPGADrvr.h"
void linearGamma(NuBusFPGADriverGlobalsPtr dStore) {
int i;
dStore->gamma.gVersion = 0;
dStore->gamma.gType = 0;
dStore->gamma.gFormulaSize = 0;
dStore->gamma.gChanCnt = 3;
dStore->gamma.gDataCnt = 256;
dStore->gamma.gDataWidth = 8;
for (i = 0 ; i < 256 ; i++) {
dStore->gamma.gFormulaData[0][i] = i;
dStore->gamma.gFormulaData[1][i] = i;
dStore->gamma.gFormulaData[2][i] = i;
}
}
OSErr changeIRQ(AuxDCEPtr dce, char en, OSErr err) {
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
char busMode = 1;
if (en != dStore->irqen) {
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0005); */
/* write_reg(dce, GOBOFB_DEBUG, en); */
if (en) {
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;
}
}
SwapMMUMode ( &busMode );
write_reg(dce, GOBOFB_VBL_MASK, en ? GOBOFB_INTR_VBL : 0);
SwapMMUMode ( &busMode );
dStore->irqen = en;
}
return noErr;
}
/*
7.1.1:
11 Debug: 0x00000003
2 Debug: 0x00000004
1 Debug: 0x00000005
4 Debug: 0x00000006
1 <EFBFBD>Debug: 0x00000002
7.5.3:
4 Debug: 0x00000002
12 Debug: 0x00000003
3 Debug: 0x00000004
5 Debug: 0x00000005
5 Debug: 0x00000006
5 Debug: 0x00000009
4 Debug: 0x0000000a
5 Debug: 0x00000010
1 <EFBFBD>Debug: 0x00000002
8.1:
5 Debug: 0x00000002
9 Debug: 0x00000003
1 Debug: 0x00000004
6 Debug: 0x00000005
6 Debug: 0x00000006
4 Debug: 0x00000009
5 Debug: 0x0000000a
4 Debug: 0x00000010
1 <EFBFBD>Debug: 0x00000002
*/
#pragma parameter __D0 cNuBusFPGACtl(__A0, __A1)
OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
short ret = -1;
char busMode = 1;
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0001); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
switch (pb->csCode)
{
case -1:
asm volatile(".word 0xfe16\n");
break;
case cscReset: /* 0x0 */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
dStore->curMode = nativeVidMode;
dStore->curDepth = kDepthMode1; /* 8-bit */
vPInfo->csMode = nativeVidMode;
vPInfo->csPage = 0;
vPInfo->csBaseAddr = 0;
ret = noErr;
}
break;
case cscKillIO: /* 0x1 */
asm volatile(".word 0xfe16\n");
ret = noErr;
break;
case cscSetMode: /* 0x2 */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
ret = reconfHW(dce, dStore->curMode, vPInfo->csMode, vPInfo->csPage);
if (ret == noErr)
vPInfo->csBaseAddr = (void*)(vPInfo->csPage * 1024 * 1024 * 4);
}
break;
case cscSetEntries: /* 0x3 */
if (1) {
VDSetEntryRecord **vdentry = (VDSetEntryRecord **)(long *)pb->csParam;
int csCount = (*vdentry)->csCount;
int csStart = (*vdentry)->csStart;
int i;
if (csCount <= 0) {
ret = noErr;
goto cscSetMode_done;
}
SwapMMUMode ( &busMode );
if (csStart < 0) {
for (i = 0 ; i <= csCount ; i++) {
unsigned char idx = ((*vdentry)->csTable[i].value & 0x0FF);
/* dStore->shadowClut[idx*3+0] = (*vdentry)->csTable[i].rgb.red; */
/* dStore->shadowClut[idx*3+1] = (*vdentry)->csTable[i].rgb.green; */
/* dStore->shadowClut[idx*3+2] = (*vdentry)->csTable[i].rgb.blue; */
write_reg(dce, GOBOFB_LUT_ADDR, 3 * idx);
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[0][(*vdentry)->csTable[i].rgb.red>>8 & 0xFF]);
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[1][(*vdentry)->csTable[i].rgb.green>>8 & 0xFF]);
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[2][(*vdentry)->csTable[i].rgb.blue>>8 & 0xFF]);
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.red); */
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.green); */
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.blue); */
}
} else {
write_reg(dce, GOBOFB_LUT_ADDR, 3 * (csStart & 0xFF));
for (i = 0 ; i <= csCount ; i++) {
/* dStore->shadowClut[(i+csStart)*3+0] = (*vdentry)->csTable[i].rgb.red; */
/* dStore->shadowClut[(i+csStart)*3+1] = (*vdentry)->csTable[i].rgb.green; */
/* dStore->shadowClut[(i+csStart)*3+2] = (*vdentry)->csTable[i].rgb.blue; */
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[0][(*vdentry)->csTable[i].rgb.red>>8 & 0xFF]);
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[1][(*vdentry)->csTable[i].rgb.green>>8 & 0xFF]);
write_reg(dce, GOBOFB_LUT, dStore->gamma.gFormulaData[2][(*vdentry)->csTable[i].rgb.blue>>8 & 0xFF]);
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.red); */
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.green); */
/* write_reg(dce, GOBOFB_LUT, (*vdentry)->csTable[i].rgb.blue); */
}
}
SwapMMUMode ( &busMode );
ret = noErr;
} else {
ret = noErr;
}
cscSetMode_done:
break;
case cscSetGamma: /* 0x4 */
{
VDGammaRecord *vdgamma = (VDGammaRecord *)*(long *)pb->csParam;
GammaTbl *gammaTbl = (GammaTbl*)vdgamma->csGTable;
int i;
if (gammaTbl == NULL) {
linearGamma(dStore);
} else {
ret = noErr;
if (gammaTbl->gDataWidth != 8)
ret = paramErr;
if (gammaTbl->gDataCnt != 256) // 8-bits
ret = paramErr;
if ((gammaTbl->gChanCnt != 1) && (gammaTbl->gChanCnt != 3))
ret = paramErr;
if ((gammaTbl->gType != 0) && (gammaTbl->gType != 0xFFFFBEEF))
ret = paramErr;
if (gammaTbl->gFormulaSize != 0)
ret = paramErr;
if (ret != noErr)
goto done;
dStore->gamma.gVersion = gammaTbl->gVersion;
dStore->gamma.gType = gammaTbl->gType;
dStore->gamma.gFormulaSize = gammaTbl->gFormulaSize;
dStore->gamma.gChanCnt = gammaTbl->gChanCnt;
dStore->gamma.gDataCnt = gammaTbl->gDataCnt;
dStore->gamma.gDataWidth = gammaTbl->gDataWidth;
int og, ob;
if (gammaTbl->gChanCnt == 1)
og = ob = 0;
else {
og = 256;
ob = 512;
}
for (i = 0 ; i < gammaTbl->gDataCnt ; i++) {
dStore->gamma.gFormulaData[0][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + 0];
dStore->gamma.gFormulaData[1][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + og];
dStore->gamma.gFormulaData[2][i] = ((unsigned char*)gammaTbl->gFormulaData)[i + ob];
}
}
ret = noErr;
}
break;
case cscGrayPage: /* 0x5 == cscGrayScreen */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
const uint8_t idx = dStore->curMode % 4; // checkme
UInt32 a32 = dce->dCtlDevBase;
UInt32 a32_l0, a32_l1;
UInt32 a32_4p0, a32_4p1;
const uint32_t wb = dStore->hres[0] >> idx;
unsigned short j, i;
short npage = (vPInfo->csMode == kDepthMode5) ? 1 : 2;
if (vPInfo->csPage >= npage) {
return paramErr;
goto done;
}
a32 += vPInfo->csPage * 1024 * 1024 * 4; /* fixme */
SwapMMUMode ( &busMode );
#if 0
if ((dStore->curMode != kDepthMode5) && (dStore->curMode != kDepthMode6)) {
/* grey the screen */
a32_l0 = a32;
a32_l1 = a32 + wb;
for (j = 0 ; j < dStore->vres[0] ; j+= 2) {
a32_4p0 = a32_l0;
a32_4p1 = a32_l1;
for (i = 0 ; i < wb ; i += 4) {
*((UInt32*)a32_4p0) = 0xFF00FF00;
*((UInt32*)a32_4p1) = 0x00FF00FF;
a32_4p0 += 4;
a32_4p1 += 4;
}
a32_l0 += 2*wb;
a32_l1 += 2*wb;
}
} else {
/* testing */
a32_l0 = a32;
a32_l1 = a32 + dStore->hres[0]*4;
for (j = 0 ; j < dStore->vres[0] ; j+= 2) {
a32_4p0 = a32_l0;
a32_4p1 = a32_l1;
for (i = 0 ; i < dStore->hres[0] ; i ++ ) {
*((UInt32*)a32_4p0) = (i&0xFF);//(i&0xFF) | (i&0xFF)<<8 | (i&0xff)<<24;
*((UInt32*)a32_4p1) = (i&0xFF)<<16;//(i&0xFF) | (i&0xFF)<<8 | (i&0xff)<<24;
a32_4p0 += 4;
a32_4p1 += 4;
}
a32_l0 += 2*dStore->hres[0]*4;
a32_l1 += 2*dStore->hres[0]*4;
}
}
#else
#define WAIT_FOR_HW_LE(accel_le) \
while (accel_le->reg_status & (1<<WORK_IN_PROGRESS_BIT))
const UInt32 fgcolor = 0; // FIXME: per-depth?
struct goblin_accel_regs* accel_le = (struct goblin_accel_regs*)(dce->dCtlDevBase+GOBOFB_ACCEL_LE);
WAIT_FOR_HW_LE(accel_le);
accel_le->reg_width = dStore->hres[dStore->curMode - nativeVidMode]; // pixels
accel_le->reg_height = dStore->vres[dStore->curMode - nativeVidMode];
accel_le->reg_bitblt_dst_x = 0; // pixels
accel_le->reg_bitblt_dst_y = 0;
accel_le->reg_dst_ptr = 0;
accel_le->reg_fgcolor = fgcolor;
accel_le->reg_cmd = (1<<DO_FILL_BIT);
WAIT_FOR_HW_LE(accel_le);
#undef WAIT_FOR_HW_LE
#endif
SwapMMUMode ( &busMode );
ret = noErr;
}
break;
case cscSetGray: /* 0x6 */
{
VDGrayRecord *vGInfo = (VDGrayRecord *)*(long *)pb->csParam;
dStore->gray = vGInfo->csMode;
ret = noErr;
}
break;
case cscSetInterrupt: /* 0x7 */
{
VDFlagRecord *vdflag = (VDFlagRecord *)*(long *)pb->csParam;
ret = changeIRQ(dce, 1 - vdflag->csMode, controlErr);
}
break;
case cscDirectSetEntries: /* 0x8 */
asm volatile(".word 0xfe16\n");
ret = controlErr;
break;
case cscSetDefaultMode: /* 0x9 */
{
VDDefMode *vddefm = (VDDefMode *)*(long *)pb->csParam;
ret = updatePRAM(dce, vddefm->csID, dStore->curDepth, 0);
}
break;
case cscSwitchMode: /* 0xa */
{
VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam;
ret = reconfHW(dce, vdswitch->csData, vdswitch->csMode, vdswitch->csPage);
if (ret == noErr)
vdswitch->csBaseAddr = (void*)(vdswitch->csPage * 1024 * 1024 * 4);
}
break;
/* cscSetSync */ /* 0xb */
/* 0xc ... 0xf : undefined */
case cscSavePreferredConfiguration: /* 0x10 */
{
VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam;
ret = updatePRAM(dce, vdswitch->csData, vdswitch->csMode, 0);
}
break;
/* 0x11 .. 0x15 : undefined */
/* cscSetHardwareCursor */ /* 0x16 */
/* cscDrawHardwareCursor */ /* 0x17 */
/* cscSetConvolution */ /* 0x18 */
/* cscSetPowerState */ /* 0x19 */
/* cscPrivateControlCall */ /* 0x1a */
/* 0x1b : undefined */
/* cscSetMultiConnect */ /* 0x1c */
/* cscSetClutBehavior */ /* 0x1d */
/* 0x1e : undefined */
/* cscSetDetailedTiming */ /* 0x1f */
/* 0x20 : undefined */
/* cscDoCommunication */ /* 0x21 */
/* cscProbeConnection */ /* 0x22 */
default: /* always return controlErr for unknown csCode */
asm volatile(".word 0xfe16\n");
ret = controlErr;
break;
}
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}
OSErr reconfHW(AuxDCEPtr dce, unsigned char mode, unsigned char depth, unsigned short page) {
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
const short npage = (depth == kDepthMode5) ? 1 : 2;
OSErr err = noErr;
char busMode = 1;
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0031); */
/* write_reg(dce, GOBOFB_DEBUG, mode); */
/* write_reg(dce, GOBOFB_DEBUG, depth); */
/* write_reg(dce, GOBOFB_DEBUG, page); */
if ((mode == dStore->curMode) &&
(depth == dStore->curDepth) &&
(page == dStore->curPage)) {
return noErr;
}
if (page >= npage)
return paramErr;
if ((mode < nativeVidMode) ||
(mode > dStore->maxMode))
return paramErr;
switch (depth) {
case kDepthMode1:
break;
case kDepthMode2:
break;
case kDepthMode3:
break;
case kDepthMode4:
break;
case kDepthMode5:
break;
case kDepthMode6:
break;
default:
return paramErr;
}
SwapMMUMode ( &busMode );
if (mode != dStore->curMode) {
unsigned short i;
for (i = nativeVidMode ; i <= dStore->maxMode ; i++) {
// disable spurious resources, enable only the right one
SpBlock spb;
spb.spParamData = (i != mode ? 1 : 0); /* disable/enable */
spb.spSlot = dStore->slot;
spb.spID = i;
spb.spExtDev = 0;
SetSRsrcState(&spb);
}
dce->dCtlSlotId = mode; // where is that explained ? cscSwitchMode is not in DCDMF3, and you should'nt do that anymore says PDCD...
UInt8 id = mode - nativeVidMode;
unsigned int ho = ((dStore->hres[0] - dStore->hres[id]) / 2);
unsigned int vo = ((dStore->vres[0] - dStore->vres[id]) / 2);
/* write_reg(dce, GOBOFB_VIDEOCTRL, 0); */
write_reg(dce, GOBOFB_HRES_START, __builtin_bswap32(ho));
write_reg(dce, GOBOFB_VRES_START, __builtin_bswap32(vo));
write_reg(dce, GOBOFB_HRES_END, __builtin_bswap32(ho + dStore->hres[id]));
write_reg(dce, GOBOFB_VRES_END, __builtin_bswap32(vo + dStore->vres[id]));
/* write_reg(dce, GOBOFB_VIDEOCTRL, 1); */
}
if (depth != dStore->curDepth) {
switch (depth) {
case kDepthMode1:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_8BIT);
break;
case kDepthMode2:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_4BIT);
break;
case kDepthMode3:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_2BIT);
break;
case kDepthMode4:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_1BIT);
break;
case kDepthMode5:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_24BIT);
break;
case kDepthMode6:
write_reg(dce, GOBOFB_MODE, GOBOFB_MODE_15BIT);
break;
default:
SwapMMUMode ( &busMode );
return paramErr;
}
}
dStore->curMode = mode;
dStore->curDepth = depth;
dStore->curPage = page; /* FIXME: HW */
SwapMMUMode ( &busMode );
return err;
}
OSErr updatePRAM(AuxDCEPtr dce, unsigned char mode, unsigned char depth, unsigned short page) {
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
const short npage = (depth == kDepthMode5) ? 1 : 2;
SpBlock spb;
NuBusFPGAPramRecord pram;
OSErr err;
if (page >= npage)
return paramErr;
if ((mode < nativeVidMode) ||
(mode > dStore->maxMode))
return paramErr;
switch (depth) {
case kDepthMode1:
break;
case kDepthMode2:
break;
case kDepthMode3:
break;
case kDepthMode4:
break;
case kDepthMode5:
break;
case kDepthMode6:
break;
default:
return paramErr;
}
spb.spSlot = dce->dCtlSlot;
spb.spResult = (UInt32)&pram;
err = SReadPRAMRec(&spb);
if (err == noErr) {
pram.mode = mode;
pram.depth = depth;
pram.page = page;
spb.spSlot = dce->dCtlSlot;
spb.spsPointer = &pram;
err = SPutPRAMRec(&spb);
}
return err;
}

View File

@ -1,208 +0,0 @@
#include "NuBusFPGADrvr.h"
#include "ROMDefs.h"
typedef void(*vblproto)(short);
/* how do I tell it to only modify D0 & A1 ? */
/* the ABI allows to modify D0-D2 & A0-A1 (caller save) */
/* currently this is clobbering A0 yet seems to work ... */
/* 'Devices' p1-37 says of interrupt handler "preserving all registers other than D0 through D3 and A0 through A3"
* but that for NuBus you see SIntInstall which says (2-70)
* "routine must preserve the contents of all registers except A1 and D0"
* yet the interrupt handler for the video card driver example in DCDMF3 p589 clobbers A0
*/
#pragma parameter __D0 fbIrq(__A1)
__attribute__ ((section (".text.fbdriver"))) short fbIrq(const long sqParameter) {
register unsigned long p_D1 asm("d1"), p_D2 asm("d2");
unsigned int irq;
short ret;
asm volatile("" : "+d" (p_D1), "+d" (p_D2));
ret = 0;
irq = (*((volatile unsigned int*)(sqParameter+GOBOFB_BASE+GOBOFB_INTR_CLEAR)));
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...
ret = 1;
}
asm volatile("" : : "d" (p_D1), "d" (p_D2));
return ret;
}
#pragma parameter __D0 cNuBusFPGAOpen(__A0, __A1)
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); */
if (dce->dCtlStorage == nil)
{
int i;
/* set up flags in the device control entry */
/* dce->dCtlFlags |= (dCtlEnableMask | dStatEnableMask | dWritEnableMask |
dReadEnableMask | dNeedLockMask | dRAMBasedMask ); */
/* initialize dCtlStorage */
ReserveMemSys(sizeof(NuBusFPGADriverGlobals));
dce->dCtlStorage = NewHandleSysClear(sizeof(NuBusFPGADriverGlobals));
if (dce->dCtlStorage == nil)
return(openErr);
HLock(dce->dCtlStorage);
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
/* (*dStore)->dce = dce; */
/* for (i = 0 ; i < 256 ; i++) { */
/* dStore->shadowClut[i*3+0] = i; */
/* dStore->shadowClut[i*3+1] = i; */
/* dStore->shadowClut[i*3+2] = i; */
/* } */
dStore->gray = 0;
dStore->irqen = 0;
dStore->slot = dce->dCtlSlot;
/* initialize DRAM controller */
//sdram_init(0xF0000000 | (((unsigned long)dStore->slot) << 24));
/* Get the HW setting for native resolution */
dStore->hres[0] = __builtin_bswap32((unsigned int)read_reg(dce, GOBOFB_HRES)); // fixme: endianness
dStore->vres[0] = __builtin_bswap32((unsigned int)read_reg(dce, GOBOFB_VRES)); // fixme: endianness
SlotIntQElement *siqel = (SlotIntQElement *)NewPtrSysClear(sizeof(SlotIntQElement));
if (siqel == NULL) {
return openErr;
}
siqel->sqType = sIQType;
siqel->sqPrio = 8;
//siqel->sqAddr = interruptRoutine;
/* not sure how to get the proper result in C... */
/* SlotIntServiceProcPtr sqAddr; */
/* asm("lea %%pc@(interruptRoutine),%0\n" : "=a"(sqAddr)); */
/* siqel->sqAddr = sqAddr; */
/* siqel->sqParm = (long)dce->dCtlDevBase; */
/* not sure how to get the proper result in C... */
/* ... from ~mac68k, you need option "-mpcrel", and it works */
/* SlotIntServiceProcPtr sqAddr; */
/* asm("lea %%pc@(fbIrq),%0\n" : "=a"(sqAddr)); */
siqel->sqAddr = fbIrq;
/* siqel->sqParm = (long)dce; */
siqel->sqParm = (long)dce->dCtlDevBase;
dStore->siqel = siqel;
dStore->curPage = 0;
dStore->curMode = nativeVidMode;
dStore->curDepth = kDepthMode1;
{
OSErr err = noErr;
SpBlock spb;
UInt8 max = nativeVidMode;
spb.spParamData = 1<<fall|1<<foneslot;
spb.spCategory = catDisplay;
spb.spCType = typeVideo;
spb.spDrvrSW = drSwApple;
spb.spDrvrHW = 0xBEEF;
spb.spTBMask = 0; /* match everything above */
spb.spSlot = dce->dCtlSlot;
spb.spID = nativeVidMode;
spb.spExtDev = 0;
err = SGetTypeSRsrc(&spb);
while ((err == noErr) &&
(spb.spSlot == dce->dCtlSlot) &&
(((UInt8)spb.spID) > (UInt8)0x80) &&
(((UInt8)spb.spID) < (UInt8)0x90)) {
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0020); */
/* write_reg(dce, GOBOFB_DEBUG, spb.spID); */
/* write_reg(dce, GOBOFB_DEBUG, err); */
if (((UInt8)spb.spID) == max) // should not happen
err = smNoMoresRsrcs;
if (((UInt8)spb.spID) > max)
max = spb.spID;
err = SGetTypeSRsrc(&spb);
}
dStore->maxMode = max;
}
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0000); */
/* write_reg(dce, GOBOFB_DEBUG, dStore->maxMode); */
{
OSErr err = noErr;
SpBlock spb;
/* check for resolution */
UInt8 id;
for (id = nativeVidMode; id <= dStore->maxMode ; id ++) {
/* try every resource, enabled or not */
spb.spParamData = 1<<fall; /* wants disabled */
spb.spCategory = catDisplay;
spb.spCType = typeVideo;
spb.spDrvrSW = drSwApple;
spb.spDrvrHW = 0xBEEF;
spb.spTBMask = 0;
spb.spSlot = dce->dCtlSlot;
spb.spID = id;
spb.spExtDev = 0;
err = SGetSRsrc(&spb);
if (err == noErr) {
spb.spID = kDepthMode1;
err = SFindStruct(&spb); /* that will give us the Parms block ... */
if (err == noErr) {
/* take the Parms pointer, add the offset to the Modes block and then skip the block size at the beginning to get the structure pointer ... */
const unsigned long offset = *(unsigned long*)spb.spsPointer & 0x00FFFFFF;
VPBlockPtr vpblock = (VPBlockPtr)(spb.spsPointer + offset + sizeof(long));
UInt8 idx = id - nativeVidMode;
dStore->hres[idx] = vpblock->vpBounds.right;
dStore->vres[idx] = vpblock->vpBounds.bottom;
}
}
}
}
linearGamma(dStore);
/* now check the content of PRAM */
if (0) {
SpBlock spb;
NuBusFPGAPramRecord pram;
OSErr err;
spb.spSlot = dce->dCtlSlot;
spb.spResult = (UInt32)&pram;
err = SReadPRAMRec(&spb);
if (err == noErr) {
err = reconfHW(dce, pram.mode, pram.depth, pram.page);
}
}
write_reg(dce, GOBOFB_VIDEOCTRL, 1);
ret = changeIRQ(dce, 1, openErr);
}
return noErr;
}
#pragma parameter __D0 cNuBusFPGAClose(__A0, __A1)
OSErr cNuBusFPGAClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0003); */
/* write_reg(dce, GOBOFB_DEBUG, 0x0000DEAD); */
asm(".word 0xfe16\n");
if (dce->dCtlStorage != nil)
{
ret = changeIRQ(dce, 0, openErr);
write_reg(dce, GOBOFB_VIDEOCTRL, 0);
DisposePtr((Ptr)(*(NuBusFPGADriverGlobalsHdl)dce->dCtlStorage)->siqel);
DisposeHandle(dce->dCtlStorage);
dce->dCtlStorage = nil;
}
return ret;
}

View File

@ -1,406 +0,0 @@
#include "NuBusFPGADrvr.h"
/*
7.1:
2 Debug: 0x00000009
1 <EFBFBD>Debug: 0x00000009
7.5.3:
6 Debug: 0x00000008
112 Debug: 0x0000000a
32 Debug: 0x0000000c
14 Debug: 0x0000000d
3 Debug: 0x0000000e
4 Debug: 0x00000010
2 Debug: 0x00000011
78 Debug: 0x00000012
1 Debug: 0x00000014
1 <EFBFBD>Debug: 0x0000000a
8.1:
9 Debug: 0x00000008
273 Debug: 0x0000000a
156 Debug: 0x0000000c
16 Debug: 0x0000000d
3 Debug: 0x00000010
3 Debug: 0x00000011
157 Debug: 0x00000012
1 Debug: 0x00000014
2 Debug: 0x00000018
10 Debug: 0x0000001c
1 <EFBFBD>Debug: 0x0000000c
*/
#pragma parameter __D0 cNuBusFPGAStatus(__A0, __A1)
OSErr cNuBusFPGAStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
NuBusFPGADriverGlobalsHdl dStoreHdl = (NuBusFPGADriverGlobalsHdl)dce->dCtlStorage;
NuBusFPGADriverGlobalsPtr dStore = *dStoreHdl;
short ret = -1;
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0002); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
#if 1
switch (pb->csCode)
{
case -1:
asm volatile(".word 0xfe16\n");
break;
case 0:
ret = statusErr;
break;
/* case 1: */
/* break; */
case cscGetMode: /* 2 */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
vPInfo->csMode = dStore->curDepth; /* checkme: PCI says depth, 7.5+ doesn't call anyway? */
vPInfo->csPage = dStore->curPage;
vPInfo->csBaseAddr = (Ptr)(dStore->curPage * 1024 * 1024 * 4); /* fixme */
ret = noErr;
}
break;
case cscGetEntries: /* 3 */
/* FIXME: TODO */
/* never called in >= 7.1 ? */
asm volatile(".word 0xfe16\n");
ret = noErr;
break;
case cscGetPageCnt: /* 4 == cscGetPages */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
if ((vPInfo->csMode != kDepthMode1) &&
(vPInfo->csMode != kDepthMode2) &&
(vPInfo->csMode != kDepthMode3) &&
(vPInfo->csMode != kDepthMode4) &&
(vPInfo->csMode != kDepthMode5) &&
(vPInfo->csMode != kDepthMode6)) {
ret = paramErr;
goto done;
}
vPInfo->csPage = (vPInfo->csMode == kDepthMode5) ? 1 : 2;
ret = noErr;
}
break;
case cscGetPageBase: /* 5 == cscGetBaseAddr */
{
VDPageInfo *vPInfo = (VDPageInfo *)*(long *)pb->csParam;
if ((vPInfo->csMode != kDepthMode1) &&
(vPInfo->csMode != kDepthMode2) &&
(vPInfo->csMode != kDepthMode3) &&
(vPInfo->csMode != kDepthMode4) &&
(vPInfo->csMode != kDepthMode5) &&
(vPInfo->csMode != kDepthMode6)) {
ret = paramErr;
goto done;
}
short npage = (vPInfo->csMode == kDepthMode5) ? 1 : 2;
if (vPInfo->csPage >= npage) {
ret = paramErr;
goto done;
}
vPInfo->csBaseAddr = (Ptr)(vPInfo->csPage * 1024 * 1024 * 4); /* fixme for > 2 pages ? */
ret = noErr;
}
asm volatile(".word 0xfe16\n");
ret = noErr;
break;
case cscGetGray: /* 6 */
{
VDGrayRecord *vGInfo = (VDGrayRecord *)*(long *)pb->csParam;
vGInfo->csMode = dStore->gray;
ret = noErr;
}
asm volatile(".word 0xfe16\n");
break;
case cscGetInterrupt: /* 7 */
asm volatile(".word 0xfe16\n");
{
VDFlagRecord *vdflag = (VDFlagRecord *)*(long *)pb->csParam;
vdflag->csMode = 1 - dStore->irqen;
ret = noErr;
}
break;
case cscGetGamma: /* 8 */
{
VDGammaRecord *vdgamma = (VDGammaRecord *)*(long *)pb->csParam;
vdgamma->csGTable = (Ptr)&dStore->gamma;
ret = noErr;
}
break;
case cscGetDefaultMode: /* 9 */
{ /* obsolete in PCI, not called >= 7.5 */
VDDefMode *vddefm = (VDDefMode *)*(long *)pb->csParam;
SpBlock spb;
NuBusFPGAPramRecord pram;
OSErr err;
spb.spSlot = dce->dCtlSlot;
spb.spResult = (UInt32)&pram;
ret = SReadPRAMRec(&spb);
if (ret == noErr) {
vddefm->csID = pram.mode;
}
}
break;
case cscGetCurMode: /* 0xa */
{
VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam;
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0022); */
/* write_reg(dce, GOBOFB_DEBUG, (unsigned int)dStore->curDepth); */
/* write_reg(dce, GOBOFB_DEBUG, (unsigned int)dStore->curMode); */
vdswitch->csMode = dStore->curDepth;
vdswitch->csData = dStore->curMode;
vdswitch->csPage = dStore->curPage;
vdswitch->csBaseAddr = (Ptr)(dStore->curPage * 1024 * 1024 * 4); /* fixme */
ret = noErr;
}
break;
case cscGetSync: /* 0xb */
asm volatile(".word 0xfe16\n");
ret = statusErr;
break;
case cscGetConnection: /* 0xc */
{
VDDisplayConnectInfoRec *vdconn = *(VDDisplayConnectInfoRec **)(long *)pb->csParam;
vdconn->csDisplayType = kGenericLCD;
vdconn->csConnectTaggedType = 0;
vdconn->csConnectTaggedData = 0;
vdconn->csConnectFlags = (1<<kTaggingInfoNonStandard) | (1<<kAllModesSafe) | (1<<kAllModesValid);
vdconn->csDisplayComponent = 0;
ret = noErr;
}
break;
case cscGetModeTiming: /* 0xd */
{
VDTimingInfoRec *vdtim = *(VDTimingInfoRec **)(long *)pb->csParam;
if (((((UInt8)vdtim->csTimingMode) < nativeVidMode) ||
(((UInt8)vdtim->csTimingMode) > dStore->maxMode)) &&
(vdtim->csTimingMode != kDisplayModeIDFindFirstResolution) &&
(vdtim->csTimingMode != kDisplayModeIDCurrent)) {
ret = paramErr;
goto done;
}
unsigned int mode = vdtim->csTimingMode;
if (mode == kDisplayModeIDFindFirstResolution)
mode = nativeVidMode;
if (mode == kDisplayModeIDCurrent)
mode = dStore->curMode;
switch (mode) {
case nativeVidMode:
vdtim->csTimingFormat = kDeclROMtables;
vdtim->csTimingData = 0;
vdtim->csTimingFlags = 1<<kModeValid | 1<<kModeSafe | 1<<kModeDefault;
break;
default:
vdtim->csTimingFormat = kDeclROMtables;//kDetailedTimingFormat;
vdtim->csTimingData = 0;
vdtim->csTimingFlags = 1<<kModeValid | 1<<kModeSafe;
break;
}
ret = noErr;
}
break;
case cscGetModeBaseAddress: /* 0xe */
/* undocumented ??? */
{
VDBaseAddressInfoRec *vdbase = *(VDBaseAddressInfoRec **)(long *)pb->csParam;
vdbase->csDevBase = 0;
ret = noErr;
}
ret = noErr;
break;
/* cscGetScanProc */ /* 0xf*/ /* undocumented ? could be called according to #mac68k */
case cscGetPreferredConfiguration: /* 0x10 */
{ /* fixme: NVRAM */
VDSwitchInfoRec *vdswitch = *(VDSwitchInfoRec **)(long *)pb->csParam;
vdswitch->csMode = kDepthMode1; //dStore->curDepth; /* fixme: prefered not current / default */
vdswitch->csData = nativeVidMode; //dStore->curMode;
ret = noErr;
SpBlock spb;
NuBusFPGAPramRecord pram;
OSErr err;
spb.spSlot = dce->dCtlSlot;
spb.spResult = (UInt32)&pram;
ret = SReadPRAMRec(&spb);
if (ret == noErr) {
vdswitch->csMode = pram.depth;
vdswitch->csData = pram.mode;
}
}
break;
case cscGetNextResolution: /* 0x11 */
{
VDResolutionInfoRec *vdres = *(VDResolutionInfoRec **)(long *)pb->csParam;
switch (vdres->csPreviousDisplayModeID)
{
default:
if ((((UInt8)vdres->csPreviousDisplayModeID) < nativeVidMode) ||
(((UInt8)vdres->csPreviousDisplayModeID) > dStore->maxMode)) {
ret = paramErr;
goto done;
}
if (((UInt8)vdres->csPreviousDisplayModeID) == dStore->maxMode)
vdres->csDisplayModeID = kDisplayModeIDNoMoreResolutions;
else
vdres->csDisplayModeID = ((UInt8)vdres->csPreviousDisplayModeID) + 1;
vdres->csHorizontalPixels = dStore->hres[((UInt8)vdres->csDisplayModeID) - nativeVidMode];
vdres->csVerticalLines = dStore->vres[((UInt8)vdres->csDisplayModeID) - nativeVidMode];
vdres->csRefreshRate = 60 << 16; /* Fixed(Point) 16+16 */
vdres->csMaxDepthMode = kDepthMode6;
break;
case kDisplayModeIDFindFirstResolution:
vdres->csDisplayModeID = nativeVidMode;
vdres->csHorizontalPixels = dStore->hres[0];
vdres->csVerticalLines = dStore->vres[0];
vdres->csRefreshRate = 60 << 16; /* Fixed(Point) 16+16 */
vdres->csMaxDepthMode = kDepthMode6;
break;
case kDisplayModeIDCurrent:
vdres->csDisplayModeID = dStore->curMode;
vdres->csHorizontalPixels = dStore->hres[dStore->curMode - nativeVidMode];
vdres->csVerticalLines = dStore->vres[dStore->curMode - nativeVidMode];
vdres->csRefreshRate = 60 << 16; /* Fixed(Point) 16+16 */
vdres->csMaxDepthMode = kDepthMode6;
break;
}
ret = noErr;
}
break;
case cscGetVideoParameters: /* 0x12 */
{
VDVideoParametersInfoRec *vdparam = *(VDVideoParametersInfoRec **)(long *)pb->csParam;
if (((((UInt8)vdparam->csDisplayModeID) < nativeVidMode) ||
(((UInt8)vdparam->csDisplayModeID) > dStore->maxMode)) &&
(vdparam->csDisplayModeID != kDisplayModeIDFindFirstResolution) &&
(vdparam->csDisplayModeID != kDisplayModeIDCurrent)) {
ret = paramErr;
goto done;
}
if ((vdparam->csDepthMode != kDepthMode1) &&
(vdparam->csDepthMode != kDepthMode2) &&
(vdparam->csDepthMode != kDepthMode3) &&
(vdparam->csDepthMode != kDepthMode4) &&
(vdparam->csDepthMode != kDepthMode5) &&
(vdparam->csDepthMode != kDepthMode6)) {
ret = paramErr;
goto done;
}
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0022); */
/* write_reg(dce, GOBOFB_DEBUG, (unsigned int)vdparam->csDisplayModeID); */
/* write_reg(dce, GOBOFB_DEBUG, (unsigned int)vdparam->csDepthMode); */
VPBlock* vpblock = vdparam->csVPBlockPtr;
unsigned char mode = vdparam->csDisplayModeID;
if (mode == kDisplayModeIDFindFirstResolution)
mode = nativeVidMode;
if (mode == kDisplayModeIDCurrent)
mode = dStore->curMode;
/* basically the same as the EBVParms ? */
vdparam->csPageCount = (vdparam->csDepthMode == kDepthMode5) ? 1 : 2;
vpblock->vpBaseOffset = 0;
vpblock->vpBounds.left = 0;
vpblock->vpBounds.top = 0;
vpblock->vpBounds.right = dStore->hres[mode - nativeVidMode];
vpblock->vpBounds.bottom = dStore->vres[mode - nativeVidMode];
vpblock->vpVersion = 0;
vpblock->vpPackType = 0;
vpblock->vpPackSize = 0;
vpblock->vpHRes = 0x480000;
vpblock->vpVRes = 0x480000;
vpblock->vpPixelType = chunky; // checkme?
if (vdparam->csDepthMode == kDepthMode1) {
vpblock->vpRowBytes = vpblock->vpBounds.right;
vdparam->csDeviceType = clutType;
vpblock->vpPixelSize = 8;
vpblock->vpCmpCount = 1;
vpblock->vpCmpSize = 8;
} else if (vdparam->csDepthMode == kDepthMode2) {
vpblock->vpRowBytes = vpblock->vpBounds.right/2;
vdparam->csDeviceType = clutType;
vpblock->vpPixelSize = 4;
vpblock->vpCmpCount = 1;
vpblock->vpCmpSize = 4;
} else if (vdparam->csDepthMode == kDepthMode3) {
vpblock->vpRowBytes = vpblock->vpBounds.right/4;
vdparam->csDeviceType = clutType;
vpblock->vpPixelSize = 2;
vpblock->vpCmpCount = 1;
vpblock->vpCmpSize = 2;
} else if (vdparam->csDepthMode == kDepthMode4) {
vpblock->vpRowBytes = vpblock->vpBounds.right/8;
vdparam->csDeviceType = clutType;
vpblock->vpPixelSize = 1;
vpblock->vpCmpCount = 1;
vpblock->vpCmpSize = 1;
} else if (vdparam->csDepthMode == kDepthMode5) {
vpblock->vpRowBytes = vpblock->vpBounds.right*4;
vdparam->csDeviceType = directType;
vpblock->vpPixelSize = 32;
vpblock->vpCmpCount = 3;
vpblock->vpCmpSize = 8;
} else if (vdparam->csDepthMode == kDepthMode6) {
vpblock->vpRowBytes = vpblock->vpBounds.right*2;
vdparam->csDeviceType = directType;
vpblock->vpPixelSize = 16;
vpblock->vpCmpCount = 3;
vpblock->vpCmpSize = 5;
}
vpblock->vpPlaneBytes = 0;
ret = noErr;
}
break;
/* 0x13 */ /* nothing */
case cscGetGammaInfoList: /* 0x14 */
ret = statusErr;
break;
case cscRetrieveGammaTable: /* 0x15 */
asm volatile(".word 0xfe16\n");
ret = statusErr;
break;
/* cscSupportsHardwareCursor */ /* 0x16 */ /* never called, unfortunately */
/* cscGetHardwareCursorDrawState */ /* 0x17 */ /* never called, unfortunately */
case cscGetConvolution: /* 0x18 */
ret = statusErr;
break;
/* cscGetPowerState */ /* 0x19 */
/* cscPrivateStatusCall */ /* 0x1a */
/* cscGetDDCBlock */ /* 0x1b */
case cscGetMultiConnect: /* 0x1c */
ret = statusErr;
break;
/* cscGetClutBehavior */ /* 0x1d */
/* cscGetTimingRanges */ /* 0x1e */
/* cscGetDetailedTiming */ /* 0x1f */
/* cscGetCommunicationInfo */ /* 0x20 */
default: /* always return statusErr for unknown csCode */
asm volatile(".word 0xfe16\n");
ret = statusErr;
break;
}
#endif
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}

View File

@ -1,157 +0,0 @@
#include "NuBusFPGADrvr.h"
#include "NuBusFPGARAMDskDrvr.h"
#include <Traps.h>
#include <ROMDefs.h>
#define PRIM_WRITEREG(reg, val) \
*((volatile UInt32*)(a32+GOBOFB_BASE+reg)) = (UInt32)val
#define PRIM_READREG(reg) \
(*((volatile UInt32*)(a32+GOBOFB_BASE+reg)))
#pragma parameter __D0 Primary(__A0)
UInt32 Primary(SEBlock* seblock) {
UInt32 a32 = 0xF0000000 | ((UInt32)seblock->seSlot << 24);
UInt32 a32_l0, a32_l1;
UInt32 a32_4p0, a32_4p1;
SpBlock spblock;
/* UInt8 pram[8]; */
OSErr err;
UInt16 i,j, hres, vres;
char busMode;
UniversalProcPtr qd32ptr, unimpptr;
busMode = 1;
SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ???
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 */
hres = __builtin_bswap32((UInt32)PRIM_READREG(GOBOFB_HRES)); // fixme: endianness
vres = __builtin_bswap32((UInt32)PRIM_READREG(GOBOFB_VRES)); // fixme: endianness
/* initialize DRAM controller */
#ifndef QEMU
sdram_init(a32);
#endif
/* grey the screen */
/* should switch to HW ? */
a32_l0 = a32;
a32_l1 = a32 + hres;
for (j = 0 ; j < vres ; j+= 2) {
a32_4p0 = a32_l0;
a32_4p1 = a32_l1;
for (i = 0 ; i < hres ; i += 4) {
*((UInt32*)a32_4p0) = 0xAAAAAAAA;
*((UInt32*)a32_4p1) = 0x55555555;
a32_4p0 += 4;
a32_4p1 += 4;
}
a32_l0 += 2*hres;
a32_l1 += 2*hres;
}
SwapMMUMode ( &busMode ); // restore
{ // disable non-default entries
SpBlock spb;
err = noErr;
do {
spb.spParamData = 1<<foneslot|1<<fnext;
spb.spCategory = catDisplay;
spb.spCType = typeVideo;
spb.spDrvrSW = drSwApple;
spb.spDrvrHW = 0xBEEF;
spb.spTBMask = 0; /* match everything above */
spb.spSlot = seblock->seSlot;
spb.spID = nativeVidMode; /* skip over the 'good' one; we can reset as SNextTypeSRsrc skips disabled */
spb.spExtDev = 0;
err = SNextTypeSRsrc(&spb);
if ((err == noErr) &&
(spb.spSlot == seblock->seSlot) &&
(((UInt8)spb.spID) > (UInt8)nativeVidMode) &&
(((UInt8)spb.spID) < (UInt8)diskResource)) {
spb.spParamData = 1; /* disable */
spb.spSlot = seblock->seSlot;
spb.spExtDev = 0;
SetSRsrcState(&spb);
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xBEEF000F); */
/* PRIM_WRITEREG(GOBOFB_DEBUG, spb.spID); */
}
} while (err == noErr);
}
#if 0
/* call SVersion to figure out if we have a recent SlotManager */
//spblock.spSlot = seblock->seSlot;
//spblock.spExtDev = 0;
err = SVersion(&spblock);
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (err) {
/* DCDMF3 p178: if error, old slot manager*/
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
/* PRIM_WRITEREG(GOBOFB_DEBUG, err);*/
} else {
/* DCDMF3 p178: new slot manager */
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0);*/
/* PRIM_WRITEREG(GOBOFB_DEBUG, spblock.spResult);*/
}
SwapMMUMode ( &busMode ); // restore
/* check for 32-bits QuickDraw */
qd32ptr = GetTrapAddress(Check32QDTrap);
unimpptr = GetTrapAddress(_Unimplemented);
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (qd32ptr == unimpptr) {
/* no 32QD */
PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);
PRIM_WRITEREG(GOBOFB_DEBUG, unimpptr);
} else {
/* yes 32QD */
PRIM_WRITEREG(GOBOFB_DEBUG, 0x00C0FFEE);
}
SwapMMUMode ( &busMode ); // restore
/* check the content of the PRAM */
spblock.spSlot = seblock->seSlot;
spblock.spResult = (UInt32)pram;
err = SReadPRAMRec(&spblock);
#if 0
PRIM_WRITEREG(GOBOFB_DEBUG, 0x88888888);
for (j = 0 ; j < 8 ; j++)
PRIM_WRITEREG(GOBOFB_DEBUG, (uint32_t)pram[j]);
PRIM_WRITEREG(GOBOFB_DEBUG, 0x88888888);
#endif
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (err) {
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
/* PRIM_WRITEREG(GOBOFB_DEBUG, err);*/
} else {
/* PRIM_WRITEREG(GOBOFB_DEBUG, 0xC0FFEE00);*/
/* for (i = 0 ; i < 8 ; i++) */
/* PRIM_WRITEREG(GOBOFB_DEBUG, pram[i]);*/
}
SwapMMUMode ( &busMode ); // restore
#endif
seblock->seStatus = 1;
return 0;
}
/* SDRAM INIT */

View File

@ -1,650 +0,0 @@
#include "NuBusFPGADrvr.h"
#define CONFIG_CSR_DATA_WIDTH 32
#include "../nubusfpga_csr_ddrphy.h"
#include "../nubusfpga_csr_sdram.h"
/* auto-generated sdram_phy.h + sc */
#define DFII_CONTROL_SEL 0x01
#define DFII_CONTROL_CKE 0x02
#define DFII_CONTROL_ODT 0x04
#define DFII_CONTROL_RESET_N 0x08
#define DFII_COMMAND_CS 0x01
#define DFII_COMMAND_WE 0x02
#define DFII_COMMAND_CAS 0x04
#define DFII_COMMAND_RAS 0x08
#define DFII_COMMAND_WRDATA 0x10
#define DFII_COMMAND_RDDATA 0x20
#define SDRAM_PHY_A7DDRPHY
#define SDRAM_PHY_XDR 2
#define SDRAM_PHY_DATABITS 16
#define SDRAM_PHY_PHASES 4
#define SDRAM_PHY_CL 6
#define SDRAM_PHY_CWL 5
#define SDRAM_PHY_CMD_LATENCY 0
#define SDRAM_PHY_RDPHASE 2
#define SDRAM_PHY_WRPHASE 3
#define SDRAM_PHY_WRITE_LATENCY_CALIBRATION_CAPABLE
#define SDRAM_PHY_READ_LEVELING_CAPABLE
#define SDRAM_PHY_MODULES SDRAM_PHY_DATABITS/8
#define SDRAM_PHY_DELAYS 32
#define SDRAM_PHY_BITSLIPS 8
__attribute__ ((section (".text.primary"))) static void cdelay(int i);
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_rst_delay (uint32_t a32, int module);
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_inc_delay (uint32_t a32, int module);
__attribute__ ((section (".text.primary"))) static inline void command_p0(uint32_t a32, int cmd)
{
sdram_dfii_pi0_command_write(a32, cmd);
sdram_dfii_pi0_command_issue_write(a32, 1);
}
__attribute__ ((section (".text.primary"))) static inline void command_p1(uint32_t a32, int cmd)
{
sdram_dfii_pi1_command_write(a32, cmd);
sdram_dfii_pi1_command_issue_write(a32, 1);
}
__attribute__ ((section (".text.primary"))) static inline void command_p2(uint32_t a32, int cmd)
{
sdram_dfii_pi2_command_write(a32, cmd);
sdram_dfii_pi2_command_issue_write(a32, 1);
}
__attribute__ ((section (".text.primary"))) static inline void command_p3(uint32_t a32, int cmd)
{
sdram_dfii_pi3_command_write(a32, cmd);
sdram_dfii_pi3_command_issue_write(a32, 1);
}
#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE
__attribute__ ((section (".text.primary"))) static inline unsigned long sdram_dfii_pix_wrdata_addr(int phase)
{
switch (phase) {
case 0: return CSR_SDRAM_DFII_PI0_WRDATA_ADDR;
case 1: return CSR_SDRAM_DFII_PI1_WRDATA_ADDR;
case 2: return CSR_SDRAM_DFII_PI2_WRDATA_ADDR;
case 3: return CSR_SDRAM_DFII_PI3_WRDATA_ADDR;
default: return 0;
}
}
__attribute__ ((section (".text.primary"))) static inline unsigned long sdram_dfii_pix_rddata_addr(int phase)
{
switch (phase) {
case 0: return CSR_SDRAM_DFII_PI0_RDDATA_ADDR;
case 1: return CSR_SDRAM_DFII_PI1_RDDATA_ADDR;
case 2: return CSR_SDRAM_DFII_PI2_RDDATA_ADDR;
case 3: return CSR_SDRAM_DFII_PI3_RDDATA_ADDR;
default: return 0;
}
}
#define DDRX_MR_WRLVL_ADDRESS 1
#define DDRX_MR_WRLVL_RESET 6
#define DDRX_MR_WRLVL_BIT 7
__attribute__ ((section (".text.primary"))) static inline void init_sequence(uint32_t a32)
{
/* Release reset */
sdram_dfii_pi0_address_write(a32, 0x0);
sdram_dfii_pi0_baddress_write(a32, 0);
sdram_dfii_control_write(a32, DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
cdelay(50000);
/* Bring CKE high */
sdram_dfii_pi0_address_write(a32, 0x0);
sdram_dfii_pi0_baddress_write(a32, 0);
sdram_dfii_control_write(a32, DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
cdelay(10000);
/* Load Mode Register 2, CWL=5 */
sdram_dfii_pi0_address_write(a32, 0x200);
sdram_dfii_pi0_baddress_write(a32, 2);
command_p0(a32, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
/* Load Mode Register 3 */
sdram_dfii_pi0_address_write(a32, 0x0);
sdram_dfii_pi0_baddress_write(a32, 3);
command_p0(a32, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
/* Load Mode Register 1 */
sdram_dfii_pi0_address_write(a32, 0x6);
sdram_dfii_pi0_baddress_write(a32, 1);
command_p0(a32, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
/* Load Mode Register 0, CL=6, BL=8 */
sdram_dfii_pi0_address_write(a32, 0x920);
sdram_dfii_pi0_baddress_write(a32, 0);
command_p0(a32, DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
cdelay(200);
/* ZQ Calibration */
sdram_dfii_pi0_address_write(a32, 0x400);
sdram_dfii_pi0_baddress_write(a32, 0);
command_p0(a32, DFII_COMMAND_WE|DFII_COMMAND_CS);
cdelay(200);
}
#include "nubusfpga_csr_common.h"
/* sdram.c from liblitedram, preprocessed for our case, + sc */
__attribute__ ((section (".text.primary"))) static inline unsigned long
lfsr (unsigned long bits, unsigned long prev)
{
/*static*/ const unsigned long long lfsr_taps[] = {
0x0L,
0x0L,
0x3L,
0x6L,
0xcL,
0x14L,
0x30L,
0x60L,
0xb8L,
0x110L,
0x240L,
0x500L,
0x829L,
0x100dL,
0x2015L,
0x6000L,
0xd008L,
0x12000L,
0x20400L,
0x40023L,
0x90000L,
0x140000L,
0x300000L,
0x420000L,
0xe10000L,
0x1200000L,
0x2000023L,
0x4000013L,
0x9000000L,
0x14000000L,
0x20000029L,
0x48000000L,
0x80200003L,
0x100080000L,
0x204000003L,
0x500000000L,
0x801000000L,
0x100000001fL,
0x2000000031L,
0x4400000000L,
0xa000140000L,
0x12000000000L,
0x300000c0000L,
0x63000000000L,
0xc0000030000L,
0x1b0000000000L,
0x300003000000L,
0x420000000000L,
0xc00000180000L,
0x1008000000000L,
0x3000000c00000L,
0x6000c00000000L,
0x9000000000000L,
0x18003000000000L,
0x30000000030000L,
0x40000040000000L,
0xc0000600000000L,
0x102000000000000L,
0x200004000000000L,
0x600003000000000L,
0xc00000000000000L,
0x1800300000000000L,
0x3000000000000030L,
0x6000000000000000L,
0x800000000000000dL
};
unsigned long lsb = prev & 1;
prev >>= 1;
prev ^= (-lsb) & lfsr_taps[bits];
return prev;
}
__attribute__ ((section (".text.primary")))
static void cdelay (int i)
{
//i >>= 2;
while (i > 0) {
__asm__ volatile ("");
i--;
}
}
__attribute__ ((section (".text.primary"))) static unsigned char
sdram_dfii_get_rdphase(uint32_t a32)
{
return ddrphy_rdphase_read(a32);
}
__attribute__ ((section (".text.primary"))) static unsigned char
sdram_dfii_get_wrphase(uint32_t a32)
{
return ddrphy_wrphase_read(a32);
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_pix_address_write(uint32_t a32, unsigned char phase, unsigned int value)
{
switch (phase) {
case 3:
sdram_dfii_pi3_address_write(a32, value);
break;
case 2:
sdram_dfii_pi2_address_write(a32, value);
break;
case 1:
sdram_dfii_pi1_address_write(a32, value);
break;
default:
sdram_dfii_pi0_address_write(a32, value);
}
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_pird_address_write(uint32_t a32, unsigned int value)
{
unsigned char rdphase = sdram_dfii_get_rdphase(a32);
sdram_dfii_pix_address_write(a32, rdphase, value);
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_piwr_address_write(uint32_t a32, unsigned int value)
{
unsigned char wrphase = sdram_dfii_get_wrphase(a32);
sdram_dfii_pix_address_write(a32, wrphase, value);
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_pix_baddress_write(uint32_t a32, unsigned char phase, unsigned int value)
{
switch (phase) {
case 3:
sdram_dfii_pi3_baddress_write(a32, value);
break;
case 2:
sdram_dfii_pi2_baddress_write(a32, value);
break;
case 1:
sdram_dfii_pi1_baddress_write(a32, value);
break;
default:
sdram_dfii_pi0_baddress_write(a32, value);
}
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_pird_baddress_write(uint32_t a32, unsigned int value)
{
unsigned char rdphase = sdram_dfii_get_rdphase(a32);
sdram_dfii_pix_baddress_write(a32, rdphase, value);
}
__attribute__ ((section (".text.primary"))) static void
sdram_dfii_piwr_baddress_write(uint32_t a32, unsigned int value)
{
unsigned char wrphase = sdram_dfii_get_wrphase(a32);
sdram_dfii_pix_baddress_write(a32, wrphase, value);
}
__attribute__ ((section (".text.primary"))) static void
command_px(uint32_t a32, unsigned char phase, unsigned int value)
{
switch (phase) {
case 3:
command_p3(a32, value);
break;
case 2:
command_p2(a32, value);
break;
case 1:
command_p1(a32, value);
break;
default:
command_p0(a32, value);
}
}
__attribute__ ((section (".text.primary"))) static void
command_prd(uint32_t a32, unsigned int value)
{
unsigned char rdphase = sdram_dfii_get_rdphase(a32);
command_px(a32, rdphase, value);
}
__attribute__ ((section (".text.primary"))) static void
command_pwr (uint32_t a32, unsigned int value)
{
unsigned char wrphase = sdram_dfii_get_wrphase(a32);
command_px(a32, wrphase, value);
}
__attribute__ ((section (".text.primary"))) static void
sdram_software_control_on(uint32_t a32)
{
unsigned int previous;
previous = sdram_dfii_control_read(a32);
if (previous != (0x02 | 0x04 | 0x08)) {
sdram_dfii_control_write(a32, (0x02 | 0x04 | 0x08));
}
}
__attribute__ ((section (".text.primary"))) static void
sdram_software_control_off(uint32_t a32)
{
unsigned int previous;
previous = sdram_dfii_control_read(a32);
if (previous != (0x01)) {
sdram_dfii_control_write(a32, (0x01));
}
}
__attribute__ ((section (".text.primary"))) static void
sdram_mode_register_write(uint32_t a32, char reg, int value)
{
sdram_dfii_pi0_address_write(a32, value);
sdram_dfii_pi0_baddress_write(a32, reg);
command_p0(a32, 0x08 | 0x04 | 0x02 | 0x01);
}
//typedef void (*delay_callback) (uint32_t a32, int module);
__attribute__ ((section (".text.primary"))) static void
sdram_activate_test_row(uint32_t a32)
{
sdram_dfii_pi0_address_write(a32, 0);
sdram_dfii_pi0_baddress_write(a32, 0);
command_p0(a32, 0x08 | 0x01);
cdelay (15);
}
__attribute__ ((section (".text.primary"))) static void
sdram_precharge_test_row(uint32_t a32)
{
sdram_dfii_pi0_address_write(a32, 0);
sdram_dfii_pi0_baddress_write(a32, 0);
command_p0(a32, 0x08 | 0x02 | 0x01);
cdelay (15);
}
__attribute__ ((section (".text.primary"))) static unsigned int
popcount (unsigned int x)
{
x -= ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003F;
}
__attribute__ ((section (".text.primary"))) static unsigned int
sdram_write_read_check_test_pattern (uint32_t a32, int module, unsigned int seed)
{
int p, i;
unsigned int errors;
unsigned int prv;
unsigned char tst[1 * 32 / 8];
unsigned char prs[4][1 * 32 / 8];
prv = seed;
for (p = 0; p < 4; p++) {
for (i = 0; i < 1 * 32 / 8; i++) {
prv = lfsr (32, prv);
prs[p][i] = prv;
}
}
sdram_activate_test_row(a32);
for (p = 0; p < 4; p++)
csr_wr_buf_uint8(a32, (sdram_dfii_pix_wrdata_addr (p)/* - CSR_SDRAM_BASE*/), prs[p], 1 * 32 / 8); /* cleanme */
sdram_dfii_piwr_address_write(a32, 0);
sdram_dfii_piwr_baddress_write(a32, 0);
command_pwr(a32, 0x04 | 0x02 | 0x01 | 0x10);
cdelay (15);
sdram_dfii_pird_address_write(a32, 0);
sdram_dfii_pird_baddress_write(a32, 0);
command_prd(a32, 0x04 | 0x01 | 0x20);
cdelay (15);
sdram_precharge_test_row(a32);
errors = 0;
for (p = 0; p < 4; p++) {
csr_rd_buf_uint8(a32, (sdram_dfii_pix_rddata_addr (p)/* - CSR_SDRAM_BASE*/), tst, 1 * 32 / 8); /* cleanme */
errors +=
popcount (prs[p][16 / 8 - 1 - module] ^ tst[16 / 8 - 1 - module]);
errors +=
popcount (prs[p][2 * 16 / 8 - 1 - module] ^
tst[2 * 16 / 8 - 1 - module]);
}
return errors;
}
__attribute__ ((section (".text.primary"))) static void
sdram_leveling_center_module (uint32_t a32, int module, int show_short, int show_long)
/* ,
delay_callback rst_delay,
delay_callback inc_delay) */
{
int i;
int show;
int working;
unsigned int errors;
int delay, delay_mid, delay_range;
int delay_min = -1, delay_max = -1;
delay = 0;
//rst_delay(a32, module);
sdram_read_leveling_rst_delay(a32, module);
while (1) {
errors = sdram_write_read_check_test_pattern(a32, module, 42);
errors += sdram_write_read_check_test_pattern(a32, module, 84);
working = errors == 0;
show = show_long;
if (working && delay_min < 0) {
delay_min = delay;
break;
}
delay++;
if (delay >= 32)
break;
//inc_delay(a32, module);
sdram_read_leveling_inc_delay(a32, module);
}
delay++;
//inc_delay(a32, module);
sdram_read_leveling_inc_delay(a32, module);
while (1) {
errors = sdram_write_read_check_test_pattern(a32, module, 42);
errors += sdram_write_read_check_test_pattern(a32, module, 84);
working = errors == 0;
show = show_long;
if (!working && delay_max < 0) {
delay_max = delay;
}
delay++;
if (delay >= 32)
break;
//inc_delay(a32, module);
sdram_read_leveling_inc_delay(a32, module);
}
if (delay_max < 0) {
delay_max = delay;
}
delay_mid = (delay_min + delay_max) / 2 % 32;
delay_range = (delay_max - delay_min) / 2;
//delay_mid = 25;
//rst_delay(a32, module);
sdram_read_leveling_rst_delay(a32, module);
cdelay (100);
for (i = 0; i < delay_mid; i++) {
//inc_delay(a32, module);
sdram_read_leveling_inc_delay(a32, module);
cdelay (100);
}
}
//__attribute__ ((section (".data.primary"))) int _sdram_write_leveling_bitslips[16];
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_rst_delay (uint32_t a32, int module)
{
ddrphy_dly_sel_write(a32, 1 << module);
ddrphy_rdly_dq_rst_write(a32, 1);
ddrphy_dly_sel_write(a32, 0);
}
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_inc_delay (uint32_t a32, int module)
{
ddrphy_dly_sel_write(a32, 1 << module);
ddrphy_rdly_dq_inc_write(a32, 1);
ddrphy_dly_sel_write(a32, 0);
}
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_rst_bitslip (uint32_t a32, char m)
{
ddrphy_dly_sel_write(a32, 1 << m);
ddrphy_rdly_dq_bitslip_rst_write(a32, 1);
ddrphy_dly_sel_write(a32, 0);
}
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling_inc_bitslip (uint32_t a32, char m)
{
ddrphy_dly_sel_write(a32, 1 << m);
ddrphy_rdly_dq_bitslip_write(a32, 1);
ddrphy_dly_sel_write(a32, 0);
}
__attribute__ ((section (".text.primary"))) static unsigned int
sdram_read_leveling_scan_module (uint32_t a32, int module, int bitslip, int show)
{
const unsigned int max_errors = 2 * (4 * 2 * 32);
int i;
unsigned int score;
unsigned int errors;
score = 0;
sdram_read_leveling_rst_delay(a32, module);
for (i = 0; i < 32; i++) {
int working;
int _show = show;
errors = sdram_write_read_check_test_pattern(a32, module, 42);
errors += sdram_write_read_check_test_pattern(a32, module, 84);
working = (errors == 0) ? 1 : 0;
score += (working * max_errors * 32) + (max_errors - errors);
sdram_read_leveling_inc_delay(a32, module);
}
return score;
}
__attribute__ ((section (".text.primary"))) static void
sdram_read_leveling(uint32_t a32)
{
int module;
int bitslip;
unsigned int score;
unsigned int best_score;
int best_bitslip;
for (module = 0; module < 16 / 8; module++) {
best_score = 0;
best_bitslip = 0;
sdram_read_leveling_rst_bitslip(a32, module);
for (bitslip = 0; bitslip < 8; bitslip++) {
score = sdram_read_leveling_scan_module(a32, module, bitslip, 1);
sdram_leveling_center_module(a32, module, 1, 0);
/*,
sdram_read_leveling_rst_delay,
sdram_read_leveling_inc_delay);*/
if (score > best_score) {
best_bitslip = bitslip;
best_score = score;
}
if (bitslip == 8 - 1)
break;
sdram_read_leveling_inc_bitslip(a32, module);
}
//best_bitslip = 1;
sdram_read_leveling_rst_bitslip(a32, module);
for (bitslip = 0; bitslip < best_bitslip; bitslip++)
sdram_read_leveling_inc_bitslip(a32, module);
sdram_leveling_center_module(a32, module, 1, 0);
/*,
sdram_read_leveling_rst_delay,
sdram_read_leveling_inc_delay);*/
}
}
__attribute__ ((section (".text.primary"))) static void
sdram_write_latency_calibration(uint32_t a32)
{
int i;
int module;
int bitslip;
unsigned int score;
unsigned int subscore;
unsigned int best_score;
int best_bitslip;
int _sdram_write_leveling_bitslips[16] = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
for (module = 0; module < 16 / 8; module++) {
best_score = 0;
best_bitslip = -1;
for (bitslip = 0; bitslip < 8; bitslip += 2) {
score = 0;
ddrphy_dly_sel_write(a32, 1 << module);
ddrphy_wdly_dq_bitslip_rst_write(a32, 1);
for (i = 0; i < bitslip; i++) {
ddrphy_wdly_dq_bitslip_write(a32, 1);
}
ddrphy_dly_sel_write(a32, 0);
score = 0;
sdram_read_leveling_rst_bitslip(a32, module);
for (i = 0; i < 8; i++) {
subscore = sdram_read_leveling_scan_module(a32, module, i, 0);
score = subscore > score ? subscore : score;
sdram_read_leveling_inc_bitslip(a32, module);
}
if (score > best_score) {
best_bitslip = bitslip;
best_score = score;
}
}
if (_sdram_write_leveling_bitslips[module] < 0)
bitslip = best_bitslip;
else
bitslip = _sdram_write_leveling_bitslips[module];
//bitslip = 0;
ddrphy_dly_sel_write(a32, 1 << module);
ddrphy_wdly_dq_bitslip_rst_write(a32, 1);
for (i = 0; i < bitslip; i++) {
ddrphy_wdly_dq_bitslip_write(a32, 1);
}
ddrphy_dly_sel_write(a32, 0);
}
}
__attribute__ ((section (".text.primary"))) static int
sdram_leveling(uint32_t a32)
{
int module;
sdram_software_control_on(a32);
for (module = 0; module < 16 / 8; module++) {
sdram_read_leveling_rst_delay(a32, module);
sdram_read_leveling_rst_bitslip(a32, module);
}
sdram_write_latency_calibration(a32);
sdram_read_leveling(a32);
sdram_software_control_off(a32);
return 1;
}
int
sdram_init(uint32_t a32) // // attribute in header file
{
ddrphy_rdphase_write(a32, 2);
ddrphy_wrphase_write(a32, 3);
sdram_software_control_on(a32);
ddrphy_rst_write(a32, 1);
cdelay (1000);
ddrphy_rst_write(a32, 0);
cdelay (1000);
init_sequence(a32);
sdram_leveling(a32);
sdram_software_control_off(a32);
return 1;
}

View File

@ -1,71 +0,0 @@
#ifndef __NUBUSFPGARAMDSKDRVR_H__
#define __NUBUSFPGARAMDSKDRVR_H__
#include <Files.h>
#include <Devices.h>
#include <Slots.h>
#include <MacErrors.h>
#include <MacMemory.h>
#include <Disks.h>
// #define ENABLE_DMA 1
#include "NuBusFPGADrvr.h"
typedef struct {
unsigned long blk_todo;
unsigned long blk_done;
unsigned long blk_offset;
unsigned long blk_doing;
void *ioBuffer;
int write;
} ram_dsk_op;
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;
#endif
};
#define DRIVE_SIZE_BYTES ((256ul-8ul)*1024ul*1024ul) // FIXME: mem size minus fb size
/* FIXME; should be auto-generated for CSR addresses... */
/* WARNING: 0x00100800 is the offset to GOBOFB_BASE !! */
#define DMA_BLK_SIZE (0x00100800 | 0x00)
#define DMA_BLK_BASE (0x00100800 | 0x04)
#define DMA_MEM_SIZE (0x00100800 | 0x08)
#define DMA_IRQ_CTL (0x00100800 | 0x0c)
#define DMA_BLK_ADDR (0x00100800 | 0x10)
#define DMA_DMA_ADDR (0x00100800 | 0x14)
#define DMA_BLK_CNT (0x00100800 | 0x18)
#define DMA_STATUS (0x00100800 | 0x2c)
#define DMA_STATUS_CHECK_BITS (0x01F)
#define DMA_IRQSTATUS (0x00100800 | 0x34)
/* ctrl */
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")));
uint32_t rledec(uint32_t* out, const uint32_t* in, const uint32_t len) __attribute__ ((section (".text.dskdriver")));;
#endif

View File

@ -1,23 +0,0 @@
NuBusFPGARAMDskDrvr:
.word 0x4f00 /* 0x4f00: ctl, status, read, write, needsLock [Devices.a] */
.word 0
.word 0
.word 0
/* Entry point offset table */
/* we can directly call the C version if it has the right calling convention */
.word cNuBusFPGARAMDskOpen - NuBusFPGARAMDskDrvr /* open routine */
.word cNuBusFPGARAMDskPrime - NuBusFPGARAMDskDrvr /* prime */
.word cNuBusFPGARAMDskCtl - NuBusFPGARAMDskDrvr /* control */
.word cNuBusFPGARAMDskStatus- NuBusFPGARAMDskDrvr /* status */
.word cNuBusFPGARAMDskClose - NuBusFPGARAMDskDrvr /* close */
_NuBusFPGARAMDskTitle:
.byte _NuBusFPGARAMDskTitle_StringEnd-.-1 /* pascal string length */
.ascii ".NuBusFPGARAMDsk_Drvr"
_NuBusFPGARAMDskTitle_StringEnd:
.word 0 /* version number */
/* for entry points: */
/* A0 pointer to driver parameter block */
/* A1 pointer to driver device control entry */
ALIGN 2

View File

@ -1,59 +0,0 @@
#include "NuBusFPGARAMDskDrvr.h"
#ifdef ENABLE_DMA
OSErr changeRAMDskIRQ(AuxDCEPtr dce, char en, OSErr err) {
struct RAMDrvContext *ctx = *(struct RAMDrvContext**)dce->dCtlStorage;
if (en != ctx->irqen) {
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0005); */
/* write_reg(dce, GOBOFB_DEBUG, en); */
if (en) {
if (SIntInstall(ctx->siqel, dce->dCtlSlot)) {
return err;
}
} else {
if (SIntRemove(ctx->siqel, dce->dCtlSlot)) {
return err;
}
}
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)
OSErr cNuBusFPGARAMDskCtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct RAMDrvContext *ctx;
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0002); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
ctx = *(struct RAMDrvContext**)dce->dCtlStorage;
if (ctx) {
switch (pb->csCode)
{
case kFormat:
ret = noErr;
break;
default:
ret = controlErr;
break;
}
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
goto done;
}
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}

View File

@ -1,185 +0,0 @@
#include "NuBusFPGARAMDskDrvr.h"
#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)
__attribute__ ((section (".text.dskdriver"))) static inline int dupAddDrive(unsigned long num, DrvQElPtr qEl) {
asm volatile(".word 0xA04E" : : "d" (num), "a" (qEl));
return num; // should cost nothing, num is already in D0
}
#include <ROMDefs.h>
#pragma parameter __D0 cNuBusFPGARAMDskOpen(__A0, __A1)
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;
char busMode;
char slot;
busMode = 1;
SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ???
if (dce->dCtlDevBase == 0) { // for some unknown reason, we get an empty dCtlDevBase...
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;
}
dce->dCtlDevBase = 0xF0000000ul | ((unsigned long)slot << 24);
}
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0000); */
/* write_reg(dce, GOBOFB_DEBUG, dce->dCtlSlot); */
if (dce->dCtlStorage == nil) {
DrvQElPtr dq;
for(dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
if (dq->dQDrive >= drvnum)
drvnum = dq->dQDrive+1;
}
ReserveMemSys(sizeof(struct RAMDrvContext));
dce->dCtlStorage = NewHandleSysClear(sizeof(struct RAMDrvContext));
if (dce->dCtlStorage == nil) {
ret = openErr;
goto done;
}
HLock(dce->dCtlStorage);
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 */
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
// MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
// write_reg(dce, GOBOFB_DEBUG, 0x0000DEAD);
// initialize to our empty volume
{
unsigned long *superslot = (unsigned long*)(((unsigned long)ctx->slot) << 28ul);
unsigned long *compressed = (unsigned long*)(dce->dCtlDevBase + 0x00FF8000ul);
unsigned long res;
res = rledec(superslot, compressed, 730); // FIXME: 730 = 2920/4 (compressed size in words)
}
// add the drive
//MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
dupAddDrive((dsptr->dQRefNum & 0xFFFF) | (drvnum << 16), (DrvQElPtr)&dsptr->qLink);
#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;
while ((1 << ctx->dma_blk_size_shift) < ctx->dma_blk_size) // fixme
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); */
{
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;
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
// auto-mount
{
ParamBlockRec pbr;
pbr.volumeParam.ioVRefNum = dsptr->dQDrive;
ret = PBMountVol(&pbr);
}
}
SwapMMUMode ( &busMode );
done:
return ret;
}
#pragma parameter __D0 cNuBusFPGARAMDskClose(__A0, __A1)
OSErr cNuBusFPGARAMDskClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct RAMDrvContext *ctx = *(struct RAMDrvContext**)dce->dCtlStorage;
/* dce->dCtlDevBase = 0xfc000000; */
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0001); */
if (dce->dCtlStorage) {
//DisposePtr((Ptr)ctx->siqel);
/* HUnlock(dce->dCtlStorage); */ /* not needed before DisposeHandle */
DisposeHandle(dce->dCtlStorage);
dce->dCtlStorage = NULL;
}
return ret;
}

View File

@ -1,350 +0,0 @@
#include "NuBusFPGARAMDskDrvr.h"
/* #include <DriverServices.h> */
__attribute__ ((section (".text.dskdriver"))) static inline void waitSome(unsigned long bound) {
unsigned long i;
for (i = 0 ; i < bound ; i++) {
asm volatile("nop");
}
}
// CLEANME: use the proper CSR accessor from nubusfpga_csr_exchange_with_mem.h
#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;
if (ctx->op.blk_doing > 65535) { // fixme: read HW max
ctx->op.blk_doing = 32768; // nice Po2
}
write_reg(dce, DMA_BLK_ADDR, revb(ctx->dma_blk_base + ctx->op.blk_offset));
write_reg(dce, DMA_DMA_ADDR, revb((uint32_t)(ctx->op.ioBuffer + (ctx->op.blk_done << ctx->dma_blk_size_shift))));
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;
OSErr ret = noErr;
max_count = 32 * ctx->op.blk_doing;
delay = (ctx->op.blk_doing >> 4);
if (delay > 65536)
delay = 65536;
waitSome(delay);
count = 0;
blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF;
status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS;
while (((blk_cnt != 0) ||
(status != 0)) &&
(count < max_count)) {
count ++;
waitSome(delay);
if (blk_cnt) blk_cnt = revb(read_reg(dce, DMA_BLK_CNT)) & 0xFFFF;
if (status) status = revb(read_reg(dce, DMA_STATUS)) & DMA_STATUS_CHECK_BITS;
}
if (blk_cnt || status) {
ret = ctx->op.write ? writErr : readErr;
}
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)
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); */
/* write_reg(dce, GOBOFB_DEBUG, pb->ioPosMode); */
/* write_reg(dce, GOBOFB_DEBUG, pb->ioReqCount); */
/* write_reg(dce, GOBOFB_DEBUG, pb->ioPosOffset); */
ctx = *(struct RAMDrvContext**)dce->dCtlStorage;
if (ctx) {
#ifdef ENABLE_DMA
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<<noQueueBit)))) {
ret = changeRAMDskIRQ(dce, 1, (pb->ioTrap & 0x00FF) == aWrCmd ? writErr : readErr);
if (ret != noErr) {
IODone((DCtlPtr)dce, ret);
goto done;
}
// 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
{
#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<<noQueueBit))) {
IODone((DCtlPtr)dce, ret);
}
goto done;
}
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
goto done;
}
done:
return ret;
}

View File

@ -1,30 +0,0 @@
#include "NuBusFPGARAMDskDrvr.h"
#pragma parameter __D0 cNuBusFPGARAMDskStatus(__A0, __A1)
OSErr cNuBusFPGARAMDskStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct RAMDrvContext *ctx;
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0004); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
ctx = *(struct RAMDrvContext**)dce->dCtlStorage;
if (ctx) {
switch (pb->csCode)
{
default:
ret = statusErr;
break;
}
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
goto done;
}
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}

View File

@ -1,119 +0,0 @@
#ifndef __NUBUSFPGARAMDSKDRVR_H__
#define __NUBUSFPGARAMDSKDRVR_H__
#include <Files.h>
#include <Devices.h>
#include <Slots.h>
#include <MacErrors.h>
#include <MacMemory.h>
#include <Disks.h>
#include "NuBusFPGADrvr.h"
struct SDCardContext {
DrvSts2 drvsts;
unsigned int dma_blk_size;
unsigned int dma_blk_size_mask;
unsigned int dma_blk_size_shift;
unsigned int dma_blk_per_sdblk;
unsigned int dma_blk_per_sdblk_lshift;
char slot;
char toto;
unsigned int max_rd_blk_len;
SlotIntQElement *siqel;
};
#include "nubusfpga_csr_common.h"
#include "../nubusfpga_csr_sdblock2mem.h"
#include "../nubusfpga_csr_sdcore.h"
//#include "../nubusfpga_csr_sdirq.h"
#include "../nubusfpga_csr_sdmem2block.h"
#include "../nubusfpga_csr_sdphy.h"
#include "../nubusfpga_csr_exchange_with_sd.h"
/* basically Litex BIOS code */
#ifndef CONFIG_CLOCK_FREQUENCY
#define CONFIG_CLOCK_FREQUENCY 100000000
#endif
#define CLKGEN_STATUS_BUSY 0x1
#define CLKGEN_STATUS_PROGDONE 0x2
#define CLKGEN_STATUS_LOCKED 0x4
#define SD_CMD_RESPONSE_SIZE 16
#define SD_OK 0
#define SD_CRCERROR 1
#define SD_TIMEOUT 2
#define SD_WRITEERROR 3
#define SD_SWITCH_CHECK 0
#define SD_SWITCH_SWITCH 1
#define SD_SPEED_SDR12 0
#define SD_SPEED_SDR25 1
#define SD_SPEED_SDR50 2
#define SD_SPEED_SDR104 3
#define SD_SPEED_DDR50 4
#define SD_DRIVER_STRENGTH_B 0
#define SD_DRIVER_STRENGTH_A 1
#define SD_DRIVER_STRENGTH_C 2
#define SD_DRIVER_STRENGTH_D 3
#define SD_GROUP_ACCESSMODE 0
#define SD_GROUP_COMMANDSYSTEM 1
#define SD_GROUP_DRIVERSTRENGTH 2
#define SD_GROUP_POWERLIMIT 3
#define SDCARD_STREAM_STATUS_OK 0b000
#define SDCARD_STREAM_STATUS_TIMEOUT 0b001
#define SDCARD_STREAM_STATUS_DATAACCEPTED 0b010
#define SDCARD_STREAM_STATUS_CRCERROR 0b101
#define SDCARD_STREAM_STATUS_WRITEERROR 0b110
#define SDCARD_CTRL_DATA_TRANSFER_NONE 0
#define SDCARD_CTRL_DATA_TRANSFER_READ 1
#define SDCARD_CTRL_DATA_TRANSFER_WRITE 2
#define SDCARD_CTRL_RESPONSE_NONE 0
#define SDCARD_CTRL_RESPONSE_SHORT 1
#define SDCARD_CTRL_RESPONSE_LONG 2
#define SDCARD_CTRL_RESPONSE_SHORT_BUSY 3
//#define SDCARD_DEBUG
//#define SDCARD_CMD23_SUPPORT /* SET_BLOCK_COUNT */
#define SDCARD_CMD18_SUPPORT /* READ_MULTIPLE_BLOCK */
#define SDCARD_CMD25_SUPPORT /* WRITE_MULTIPLE_BLOCK */
#ifndef SDCARD_CLK_FREQ_INIT
#define SDCARD_CLK_FREQ_INIT 400000
#endif
#ifndef SDCARD_CLK_FREQ
#define SDCARD_CLK_FREQ 25000000
//#define SDCARD_CLK_FREQ 12500000
#endif
/* ctrl */
OSErr cNuBusFPGASDCardCtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.sddriver")));
/* open, close */
OSErr cNuBusFPGASDCardOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.sddriver")));
OSErr cNuBusFPGASDCardClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.sddriver")));
void busy_wait(int d) __attribute__ ((section (".text.sddriver")));
void delay(int d) __attribute__ ((section (".text.sddriver")));
int sdcard_read(uint32_t sc, struct SDCardContext *ctx, uint32_t block, uint32_t count, uint8_t* buf) __attribute__ ((section (".text.sddriver")));
int sdcard_write(uint32_t sc, struct SDCardContext *ctx, uint32_t block, uint32_t count, uint8_t* buf) __attribute__ ((section (".text.sddriver")));
/* prime */
OSErr cNuBusFPGASDCardPrime(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.sddriver")));
void waitSome(unsigned long bound) __attribute__ ((section (".text.sddriver")));
/* status */
OSErr cNuBusFPGASDCardStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) __attribute__ ((section (".text.sddriver")));
uint32_t rledec(uint32_t* out, const uint32_t* in, const uint32_t len) __attribute__ ((section (".text.sddriver")));
#endif

View File

@ -1,23 +0,0 @@
NuBusFPGASDCardDrvr:
.word 0x4f00 /* 0x4f00: ctl, status, read, write, needsLock [Devices.a] */
.word 0
.word 0
.word 0
/* Entry point offset table */
/* we can directly call the C version if it has the right calling convention */
.word cNuBusFPGASDCardOpen - NuBusFPGASDCardDrvr /* open routine */
.word cNuBusFPGASDCardPrime - NuBusFPGASDCardDrvr /* prime */
.word cNuBusFPGASDCardCtl - NuBusFPGASDCardDrvr /* control */
.word cNuBusFPGASDCardStatus- NuBusFPGASDCardDrvr /* status */
.word cNuBusFPGASDCardClose - NuBusFPGASDCardDrvr /* close */
_NuBusFPGASDCardTitle:
.byte _NuBusFPGASDCardTitle_StringEnd-.-1 /* pascal string length */
.ascii ".NuBusFPGASDCard_Drvr"
_NuBusFPGASDCardTitle_StringEnd:
.word 0 /* version number */
/* for entry points: */
/* A0 pointer to driver parameter block */
/* A1 pointer to driver device control entry */
ALIGN 2

View File

@ -1,59 +0,0 @@
#include "NuBusFPGASDCardDrvr.h"
#if 0
OSErr changeSDCardIRQ(AuxDCEPtr dce, char en, OSErr err) {
struct SDCardContext *ctx = *(struct SDCardContext**)dce->dCtlStorage;
if (en != ctx->irqen) {
/* write_reg(dce, GOBOFB_DEBUG, 0xBEEF0005); */
/* write_reg(dce, GOBOFB_DEBUG, en); */
if (en) {
if (SIntInstall(ctx->siqel, dce->dCtlSlot)) {
return err;
}
} else {
if (SIntRemove(ctx->siqel, dce->dCtlSlot)) {
return err;
}
}
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 cNuBusFPGASDCardCtl(__A0, __A1)
OSErr cNuBusFPGASDCardCtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct SDCardContext *ctx;
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0002); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
ctx = *(struct SDCardContext**)dce->dCtlStorage;
if (ctx) {
switch (pb->csCode)
{
case kFormat:
ret = noErr;
break;
default:
ret = controlErr;
break;
}
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
goto done;
}
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}

View File

@ -1,873 +0,0 @@
#include "NuBusFPGASDCardDrvr.h"
#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)
__attribute__ ((section (".text.sddriver"))) static inline int dupAddDrive(unsigned long num, DrvQElPtr qEl) {
asm volatile(".word 0xA04E" : : "d" (num), "a" (qEl));
return num; // should cost nothing, num is already in D0
}
static int sdcard_init(struct SDCardContext* sdcc, uint32_t sc) __attribute__ ((section (".text.sddriver")));
#include <ROMDefs.h>
#pragma parameter __D0 cNuBusFPGASDCardOpen(__A0, __A1)
OSErr cNuBusFPGASDCardOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
DrvSts2 *dsptr; // pointer to the DrvSts2 in our context
int drvnum = 1;
struct SDCardContext *ctx;
OSErr ret = noErr;
char busMode;
char slot;
busMode = 1;
SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ???
if (dce->dCtlDevBase == 0) { // for some unknown reason, we get an empty dCtlDevBase...
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 = 0xbeec; // DrHwNuBusFPGADsk
mySpBlock.spTBMask = 0;
ret = SNextTypeSRsrc(&mySpBlock);
if (ret)
goto done;
slot = mySpBlock.spSlot;
} else {
slot = dce->dCtlSlot;
}
dce->dCtlDevBase = 0xF0000000ul | ((unsigned long)slot << 24);
}
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0000); */
/* write_reg(dce, GOBOFB_DEBUG, dce->dCtlSlot); */
if (dce->dCtlStorage == nil) {
DrvQElPtr dq;
for(dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
if (dq->dQDrive >= drvnum)
drvnum = dq->dQDrive+1;
}
ReserveMemSys(sizeof(struct SDCardContext));
dce->dCtlStorage = NewHandleSysClear(sizeof(struct SDCardContext));
if (dce->dCtlStorage == nil) {
ret = openErr;
goto done;
}
HLock(dce->dCtlStorage);
ctx = *(struct SDCardContext **)dce->dCtlStorage;
ctx->slot = slot;
ctx->toto = 0; // removeme
/* init the SDCard, this will also fill out dsptr->driveSize & dsptr->driveS1 */
if (!sdcard_init(ctx, dce->dCtlDevBase)) {
ret = openErr;
HUnlock(dce->dCtlStorage);
DisposeHandle(dce->dCtlStorage);
dce->dCtlStorage = NULL;
goto done;
}
ctx->dma_blk_size = exchange_with_sd_blk_size_read(dce->dCtlDevBase);
ctx->dma_blk_size_mask = ctx->dma_blk_size - 1; // size is Po2
ctx->dma_blk_size_shift = 0;
while ((1 << ctx->dma_blk_size_shift) < ctx->dma_blk_size) // fixme
ctx->dma_blk_size_shift++;
ctx->dma_blk_per_sdblk_lshift = 9 - ctx->dma_blk_size_shift;
ctx->dma_blk_per_sdblk = 1 << ctx->dma_blk_per_sdblk_lshift; // 512 / ctx->dma_blk_size
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 */
/* driveSize & driveS1 filled by sdcard_init */
//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
// MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
// write_reg(dce, GOBOFB_DEBUG, 0x0000DEAD);
// add the drive
//MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
dupAddDrive((dsptr->dQRefNum & 0xFFFF) | (drvnum << 16), (DrvQElPtr)&dsptr->qLink);
#if 0
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;
while ((1 << ctx->dma_blk_size_shift) < ctx->dma_blk_size) // fixme
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); */
{
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;
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
// auto-mount
if (0) {
ParamBlockRec pbr;
pbr.volumeParam.ioVRefNum = dsptr->dQDrive;
ret = PBMountVol(&pbr);
}
}
SwapMMUMode ( &busMode );
done:
return ret;
}
#pragma parameter __D0 cNuBusFPGASDCardClose(__A0, __A1)
OSErr cNuBusFPGASDCardClose(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct SDCardContext *ctx = *(struct SDCardContext**)dce->dCtlStorage;
/* dce->dCtlDevBase = 0xfc000000; */
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0001); */
if (dce->dCtlStorage) {
//DisposePtr((Ptr)ctx->siqel);
/* HUnlock(dce->dCtlStorage); */ /* not needed before DisposeHandle */
DisposeHandle(dce->dCtlStorage);
dce->dCtlStorage = NULL;
}
return ret;
}
/*-----------------------------------------------------------------------*/
/* Helpers */
/*-----------------------------------------------------------------------*/
#define max(x, y) (((x) > (y)) ? (x) : (y))
#define min(x, y) (((x) < (y)) ? (x) : (y))
/* In MacOS
Delay(unsigned long numTicks, unsigned long * finalTicks)
has ticks in 1/60th of a second or 16.6666 ms
*/
/* in NetBSD/sparc busy_wait is 1ms * d */
void busy_wait(int d) {
waitSome(d * 20000); // improveme
return;
}
/* in NetBSD/sparc delay is 1us * d */
void delay(int d) {
waitSome(d * 20); // improveme
return;
}
/*-----------------------------------------------------------------------*/
/* SDCard command helpers */
/*-----------------------------------------------------------------------*/
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_wait_cmd_done(uint32_t sc) {
unsigned int event;
#ifdef SDCARD_DEBUG
uint32_t r[SD_CMD_RESPONSE_SIZE/4];
#endif
for (;;) {
event = sdcore_cmd_event_read(sc);
#ifdef SDCARD_DEBUG
printf("cmdevt: %08x\n", event);
#endif
delay(10);
if (event & 0x1)
break;
}
#ifdef SDCARD_DEBUG
csr_rd_buf_uint32(sc, sc->sc_bhregs_sdcore + (CSR_SDCORE_CMD_RESPONSE_ADDR - CSR_SDCORE_BASE), r, SD_CMD_RESPONSE_SIZE/4);
printf("%08x %08x %08x %08x\n", r[0], r[1], r[2], r[3]);
#endif
if (event & 0x4)
return SD_TIMEOUT;
if (event & 0x8)
return SD_CRCERROR;
return SD_OK;
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_wait_data_done(uint32_t sc) {
unsigned int event;
for (;;) {
event = sdcore_data_event_read(sc);
#ifdef SDCARD_DEBUG
printf("dataevt: %08x\n", event);
#endif
if (event & 0x1)
break;
delay(10);
}
if (event & 0x4)
return SD_TIMEOUT;
else if (event & 0x8)
return SD_CRCERROR;
return SD_OK;
}
/*-----------------------------------------------------------------------*/
/* SDCard clocker functions */
/*-----------------------------------------------------------------------*/
/* round up to closest power-of-two */
__attribute__ ((section (".text.sddriver"))) static inline uint32_t pow2_round_up(uint32_t r) {
r--;
r |= r >> 1;
r |= r >> 2;
r |= r >> 4;
r |= r >> 8;
r |= r >> 16;
r++;
return r;
}
__attribute__ ((section (".text.sddriver"))) static inline void sdcard_set_clk_freq(uint32_t sc, uint32_t clk_freq, int show) {
uint32_t divider;
divider = clk_freq ? CONFIG_CLOCK_FREQUENCY/clk_freq : 256;
divider = pow2_round_up(divider);
divider = min(max(divider, 2), 256);
#ifdef SDCARD_DEBUG
show = 1;
#endif
if (show) {
/* this is the *effective* new clk_freq */
clk_freq = CONFIG_CLOCK_FREQUENCY/divider;
/*
printf("Setting SDCard clk freq to ");
if (clk_freq > 1000000)
printf("%d MHz\n", clk_freq/1000000);
else
printf("%d KHz\n", clk_freq/1000);
*/
}
sdphy_clocker_divider_write(sc, divider);
}
/*-----------------------------------------------------------------------*/
/* SDCard commands functions */
/*-----------------------------------------------------------------------*/
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_send_command(uint32_t sc, uint32_t arg, uint8_t cmd, uint8_t rsp) {
sdcore_cmd_argument_write(sc, arg);
sdcore_cmd_command_write(sc, (cmd << 8) | rsp);
sdcore_cmd_send_write(sc, 1);
return sdcard_wait_cmd_done(sc);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_go_idle(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("CMD0: GO_IDLE\n");
#endif
return sdcard_send_command(sc, 0, 0, SDCARD_CTRL_RESPONSE_NONE);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_send_ext_csd(uint32_t sc) {
uint32_t arg = 0x000001aa;
#ifdef SDCARD_DEBUG
printf("CMD8: SEND_EXT_CSD, arg: 0x%08x\n", arg);
#endif
return sdcard_send_command(sc, arg, 8, SDCARD_CTRL_RESPONSE_SHORT);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_app_cmd(uint32_t sc, uint16_t rca) {
#ifdef SDCARD_DEBUG
printf("CMD55: APP_CMD\n");
#endif
return sdcard_send_command(sc, rca << 16, 55, SDCARD_CTRL_RESPONSE_SHORT);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_app_send_op_cond(uint32_t sc, int hcs) {
uint32_t arg = 0x10ff8000;
if (hcs)
arg |= 0x60000000;
#ifdef SDCARD_DEBUG
printf("ACMD41: APP_SEND_OP_COND, arg: %08x\n", arg);
#endif
return sdcard_send_command(sc, arg, 41, SDCARD_CTRL_RESPONSE_SHORT_BUSY);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_all_send_cid(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("CMD2: ALL_SEND_CID\n");
#endif
return sdcard_send_command(sc, 0, 2, SDCARD_CTRL_RESPONSE_LONG);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_set_relative_address(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("CMD3: SET_RELATIVE_ADDRESS\n");
#endif
return sdcard_send_command(sc, 0, 3, SDCARD_CTRL_RESPONSE_SHORT);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_send_cid(uint32_t sc, uint16_t rca) {
#ifdef SDCARD_DEBUG
printf("CMD10: SEND_CID\n");
#endif
return sdcard_send_command(sc, rca << 16, 10, SDCARD_CTRL_RESPONSE_LONG);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_send_csd(uint32_t sc, uint16_t rca) {
#ifdef SDCARD_DEBUG
printf("CMD9: SEND_CSD\n");
#endif
return sdcard_send_command(sc, rca << 16, 9, SDCARD_CTRL_RESPONSE_LONG);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_select_card(uint32_t sc, uint16_t rca) {
#ifdef SDCARD_DEBUG
printf("CMD7: SELECT_CARD\n");
#endif
return sdcard_send_command(sc, rca << 16, 7, SDCARD_CTRL_RESPONSE_SHORT_BUSY);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_app_set_bus_width(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("ACMD6: SET_BUS_WIDTH\n");
#endif
return sdcard_send_command(sc, 2, 6, SDCARD_CTRL_RESPONSE_SHORT);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_switch(uint32_t sc, unsigned int mode, unsigned int group, unsigned int value) {
unsigned int arg;
arg = (mode << 31) | 0xffffff;
arg &= ~(0xf << (group * 4));
arg |= value << (group * 4);
//device_printf(sc->dk.sc_dev, "switch arg is 0x%08x\n", arg);
#ifdef SDCARD_DEBUG
printf("CMD6: SWITCH_FUNC\n");
#endif
sdcore_block_length_write(sc, 64);
sdcore_block_count_write(sc, 1);
while (sdcard_send_command(sc, arg, 6,
(SDCARD_CTRL_DATA_TRANSFER_READ << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return sdcard_wait_data_done(sc);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_app_send_scr(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("CMD51: APP_SEND_SCR\n");
#endif
sdcore_block_length_write(sc, 8);
sdcore_block_count_write(sc, 1);
while (sdcard_send_command(sc, 0, 51,
(SDCARD_CTRL_DATA_TRANSFER_READ << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return sdcard_wait_data_done(sc);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_app_set_blocklen(uint32_t sc, unsigned int blocklen) {
#ifdef SDCARD_DEBUG
printf("CMD16: SET_BLOCKLEN\n");
#endif
return sdcard_send_command(sc, blocklen, 16, SDCARD_CTRL_RESPONSE_SHORT);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_write_single_block(uint32_t sc, unsigned int blockaddr) {
#ifdef SDCARD_DEBUG
printf("CMD24: WRITE_SINGLE_BLOCK\n");
#endif
sdcore_block_length_write(sc, 512);
sdcore_block_count_write(sc, 1);
while (sdcard_send_command(sc, blockaddr, 24,
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return SD_OK;
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_write_multiple_block(uint32_t sc, unsigned int blockaddr, unsigned int blockcnt) {
#ifdef SDCARD_DEBUG
printf("CMD25: WRITE_MULTIPLE_BLOCK\n");
#endif
sdcore_block_length_write(sc, 512);
sdcore_block_count_write(sc, blockcnt);
while (sdcard_send_command(sc, blockaddr, 25,
(SDCARD_CTRL_DATA_TRANSFER_WRITE << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return SD_OK;
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_read_single_block(uint32_t sc, unsigned int blockaddr) {
#ifdef SDCARD_DEBUG
printf("CMD17: READ_SINGLE_BLOCK\n");
#endif
sdcore_block_length_write(sc, 512);
sdcore_block_count_write(sc, 1);
while (sdcard_send_command(sc, blockaddr, 17,
(SDCARD_CTRL_DATA_TRANSFER_READ << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return sdcard_wait_data_done(sc);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_read_multiple_block(uint32_t sc, unsigned int blockaddr, unsigned int blockcnt) {
#ifdef SDCARD_DEBUG
printf("CMD18: READ_MULTIPLE_BLOCK\n");
#endif
sdcore_block_length_write(sc, 512);
sdcore_block_count_write(sc, blockcnt);
while (sdcard_send_command(sc, blockaddr, 18,
(SDCARD_CTRL_DATA_TRANSFER_READ << 5) |
SDCARD_CTRL_RESPONSE_SHORT) != SD_OK);
return sdcard_wait_data_done(sc);
}
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_stop_transmission(uint32_t sc) {
#ifdef SDCARD_DEBUG
printf("CMD12: STOP_TRANSMISSION\n");
#endif
return sdcard_send_command(sc, 0, 12, SDCARD_CTRL_RESPONSE_SHORT_BUSY);
}
#if 0
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_send_status(uint32_t sc, uint16_t rca) {
#ifdef SDCARD_DEBUG
printf("CMD13: SEND_STATUS\n");
#endif
return sdcard_send_command(sc, rca << 16, 13, SDCARD_CTRL_RESPONSE_SHORT);
}
#endif
#if 0
__attribute__ ((section (".text.sddriver"))) static inline int sdcard_set_block_count(uint32_t sc, unsigned int blockcnt) {
#ifdef SDCARD_DEBUG
printf("CMD23: SET_BLOCK_COUNT\n");
#endif
return sdcard_send_command(sc, blockcnt, 23, SDCARD_CTRL_RESPONSE_SHORT);
}
#endif
__attribute__ ((section (".text.sddriver"))) static inline uint16_t sdcard_decode_rca(uint32_t sc) {
uint32_t r[SD_CMD_RESPONSE_SIZE/4];
csr_rd_buf_uint32(sc, CSR_SDCORE_CMD_RESPONSE_ADDR, r, SD_CMD_RESPONSE_SIZE/4);
return (r[3] >> 16) & 0xffff;
}
__attribute__ ((section (".text.sddriver"))) static inline void sdcard_decode_cid(uint32_t sc) {
uint32_t r[SD_CMD_RESPONSE_SIZE/4];
csr_rd_buf_uint32(sc, CSR_SDCORE_CMD_RESPONSE_ADDR, r, SD_CMD_RESPONSE_SIZE/4);
/* aprint_normal_dev(sc->dk.sc_dev, */
/* "CID Register: 0x%08x%08x%08x%08x " */
/* "Manufacturer ID: 0x%x " */
/* "Application ID 0x%x " */
/* "Product name: %c%c%c%c%c " */
/* "CRC: %02x " */
/* "Production date(m/yy): %d/%d " */
/* "PSN: %08x " */
/* "OID: %c%c\n", */
/* r[0], r[1], r[2], r[3], */
/* (r[0] >> 16) & 0xffff, */
/* r[0] & 0xffff, */
/* (r[1] >> 24) & 0xff, (r[1] >> 16) & 0xff, */
/* (r[1] >> 8) & 0xff, (r[1] >> 0) & 0xff, (r[2] >> 24) & 0xff, */
/* r[3] & 0xff, */
/* (r[3] >> 8) & 0x0f, (r[3] >> 12) & 0xff, */
/* (r[3] >> 24) | (r[2] << 8), */
/* (r[0] >> 16) & 0xff, (r[0] >> 8) & 0xff */
/* ); */
}
__attribute__ ((section (".text.sddriver"))) static inline void sdcard_decode_csd(struct SDCardContext* sdcc, uint32_t sc) {
uint32_t r[SD_CMD_RESPONSE_SIZE/4];
csr_rd_buf_uint32(sc, CSR_SDCORE_CMD_RESPONSE_ADDR, r, SD_CMD_RESPONSE_SIZE/4);
/* FIXME: only support CSR structure version 2.0 */
//sc->max_rd_blk_len = (1 << ((r[1] >> 16) & 0xf));
//sc->max_size_in_blk = ((r[2] >> 16) + ((r[1] & 0xff) << 16) + 1) * 512 * 2;
uint32_t max_size_in_blk = ((r[2] >> 16) + ((r[1] & 0xff) << 16) + 1) * 512 * 2; // weird spec in 512KiB unit
if (max_size_in_blk >= 4194304) // 2 GiB
max_size_in_blk = 4194303; // 2 GiB - 512 B
#define MAX_DSK_SIZE_MB 80
if (max_size_in_blk >= (MAX_DSK_SIZE_MB*(1048576/512))) // TEMPORARY FOR TESTING
max_size_in_blk = (MAX_DSK_SIZE_MB*(1048576/512)); // TEMPORARY FOR TESTING
sdcc->drvsts.driveSize = max_size_in_blk & 0x0000FFFF;
sdcc->drvsts.driveS1 = (max_size_in_blk & 0xFFFF0000) >> 16;
sdcc->max_rd_blk_len = (1 << ((r[1] >> 16) & 0xf)); // READ_BL_LEN ? should always be 9 ?
/* aprint_normal_dev(sc->dk.sc_dev, */
/* "CSD Register: 0x%08x%08x%08x%08x " */
/* "Max data transfer rate: %d MB/s " */
/* "Max read block length: %d bytes " */
/* "Device size: %d GiB (%d blocks)\n", */
/* r[0], r[1], r[2], r[3], */
/* (r[0] >> 24) & 0xff, */
/* sc->max_rd_blk_len, */
/* ((r[2] >> 16) + ((r[1] & 0xff) << 16) + 1) * 512 / (1024 * 1024), */
/* sc->max_size_in_blk */
/* ); */
}
/*-----------------------------------------------------------------------*/
/* SDCard user functions */
/*-----------------------------------------------------------------------*/
static int sdcard_init(struct SDCardContext* sdcc, uint32_t sc) {
uint16_t rca, timeout;
int res;
/* Set SD clk freq to Initialization frequency */
sdcard_set_clk_freq(sc, SDCARD_CLK_FREQ_INIT, 0);
busy_wait(1);
for (timeout=1000; timeout>0; timeout--) {
/* Set SDCard in SPI Mode (generate 80 dummy clocks) */
sdphy_init_initialize_write(sc, 1);
busy_wait(1);
/* Set SDCard in Idle state */
if (sdcard_go_idle(sc) == SD_OK)
break;
busy_wait(1);
}
if (timeout == 0) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard timeout (1)\n");
return 0;
}
/* Set SDCard voltages, only supported by ver2.00+ SDCards */
if ((res = sdcard_send_ext_csd(sc)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_send_ext_csd failed\n");
return 0;
}
/* Set SD clk freq to Operational frequency */
sdcard_set_clk_freq(sc, SDCARD_CLK_FREQ, 0);
busy_wait(1);
/* Set SDCard in Operational state */
for (timeout=1000; timeout>0; timeout--) {
sdcard_app_cmd(sc, 0);
if ((res = sdcard_app_send_op_cond(sc, 1)) != SD_OK)
break;
busy_wait(1);
}
if (timeout == 0) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard timeout (2)\n");
return 0;
}
/* Send identification */
if ((res = sdcard_all_send_cid(sc)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_all_send_cid failed (%d)\n", res);
return 0;
}
sdcard_decode_cid(sc);
/* Set Relative Card Address (RCA) */
if ((res = sdcard_set_relative_address(sc)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_set_relative_address failed (%d)\n", res);
return 0;
}
rca = sdcard_decode_rca(sc);
//device_printf(sc->dk.sc_dev, "rca is 0x%08x\n", rca);
/* Set CID */
if ((res = sdcard_send_cid(sc, rca)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_send_cid failed (%d)\n", res);
return 0;
}
#ifdef SDCARD_DEBUG
/* FIXME: add cid decoding (optional) */
#endif
/* Set CSD */
if ((res = sdcard_send_csd(sc, rca)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_send_csd failed (%d)\n", res);
return 0;
}
sdcard_decode_csd(sdcc, sc);
/* Select card */
if ((res = sdcard_select_card(sc, rca)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_select_card failed (%d)\n", res);
return 0;
}
/* Set bus width */
if ((res = sdcard_app_cmd(sc, rca)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_app_cmd failed (%d)\n", res);
return 0;
}
if((res = sdcard_app_set_bus_width(sc)) != SD_OK){
//aprint_error_dev(sc->dk.sc_dev, "sdcard_app_set_bus_width failed (%d)\n", res);
return 0;
}
/* Switch speed */
if ((res = sdcard_switch(sc, SD_SWITCH_SWITCH, SD_GROUP_ACCESSMODE, SD_SPEED_SDR25)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_switch failed (%d)\n", res);
return 0;
}
/* Send SCR */
/* FIXME: add scr decoding (optional) */
if ((res = sdcard_app_cmd(sc, rca)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_app_cmd failed (%d)\n", res);
return 0;
}
if ((res = sdcard_app_send_scr(sc)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_app_send_scr failed (%d)\n", res);
return 0;
}
/* Set block length */
if ((res = sdcard_app_set_blocklen(sc, 512)) != SD_OK) {
//aprint_error_dev(sc->dk.sc_dev, "sdcard_app_set_blocklen failed (%d)\n", res);
return 0;
}
return 1;
}
#if 1
__attribute__ ((section (".text.sddriver"))) static inline void do_copy_rev(uint32_t *src, uint32_t *dst, uint32_t size) {
uint32_t i;
for (i = 0 ; i < size/4 ; i++) {
dst[i] = revb(src[i]);
}
}
#endif
__attribute__ ((section (".text.sddriver"))) static inline OSErr start_dma_read(uint32_t sc, struct SDCardContext *ctx, uint32_t count, uint8_t* buf) {
unsigned int dma_blk_cnt = count << ctx->dma_blk_per_sdblk_lshift;
exchange_with_sd_blk_addr_write(sc, 0);
exchange_with_sd_dma_addr_write(sc, buf);
exchange_with_sd_blk_cnt_write(sc, dma_blk_cnt | 0x80000000); // MSb==1, read
return noErr;
}
__attribute__ ((section (".text.sddriver"))) static inline OSErr start_dma_write(uint32_t sc, struct SDCardContext *ctx, uint32_t count, uint8_t* buf) {
unsigned int dma_blk_cnt = count << ctx->dma_blk_per_sdblk_lshift;
exchange_with_sd_blk_addr_write(sc, 0);
exchange_with_sd_dma_addr_write(sc, buf);
exchange_with_sd_blk_cnt_write(sc, dma_blk_cnt); // MSb==0, write
return noErr;
}
#if 0
#define DMA_STATUS_CHECK_BITS (0x01F)
__attribute__ ((section (".text.sddriver"))) static inline OSErr wait_dma(uint32_t sc, uint32_t blk_count, OSErr err) {
unsigned long count, max_count, delay;
unsigned long blk_cnt, status;
OSErr ret = noErr;
max_count = 32 * blk_count;
delay = blk_count >> 2;
if (delay > 65536)
delay = 65536;
waitSome(delay);
count = 0;
blk_cnt = exchange_with_sd_blk_cnt_blk_cnt_read(sc);
status = exchange_with_sd_dma_status_read(sc) & DMA_STATUS_CHECK_BITS;
while (((blk_cnt != 0) ||
(status != 0)) &&
(count < max_count)) {
count ++;
waitSome(delay);
if (blk_cnt) blk_cnt = exchange_with_sd_blk_cnt_blk_cnt_read(sc);
if (status) status = exchange_with_sd_dma_status_read(sc) & DMA_STATUS_CHECK_BITS;
}
if (blk_cnt || status) {
ret = err;
}
return ret;
}
#endif
int sdcard_read(uint32_t sc, struct SDCardContext *ctx, uint32_t block, uint32_t count, uint8_t* buf) {
while (count) {
uint32_t nblocks;
//uint64_t buf_hw_addr = ((uint64_t)((uint32_t)buf));// << 32;
uint32_t buf_hw_addr = (uint32_t)buf; // TEMPORARY FOR TESTING
uint32_t stage_addr_dma = 0x80000000; // DDR // TEMPORARY FOR TESTING
uint32_t stage_addr_cpu = sc << 4; // superslot // TEMPORARY FOR TESTING
#ifdef SDCARD_CMD18_SUPPORT
nblocks = count;
if (nblocks > 16)
nblocks = 16;
#else
nblocks = 1;
#endif
#if 1
/* Initialize DMA Writer */
sdblock2mem_dma_enable_write(sc, 0);
/* sdblock2mem_dma_base_write takes an uint64_t */
////sdblock2mem_dma_base_write(sc, buf_hw_addr);
sdblock2mem_dma_base_write(sc, stage_addr_dma);
sdblock2mem_dma_length_write(sc, 512*nblocks);
sdblock2mem_dma_enable_write(sc, 1);
#else
start_dma_write(sc, ctx, nblocks, buf_hw_addr); // read from sdcard, write to memory
#endif
/* Read Block(s) from SDCard */
#ifdef SDCARD_CMD23_SUPPORT
sdcard_set_block_count(sc, nblocks);
#endif
if (nblocks > 1)
sdcard_read_multiple_block(sc, block, nblocks);
else
sdcard_read_single_block(sc, block);
#if 1
//int timeout = 64 * nblocks;
int timeout = 1024 * nblocks;
/* Wait for DMA Writer to complete */
while (((sdblock2mem_dma_done_read(sc) & 0x1) == 0) && timeout) {
//delay(2);
delay(20);
timeout --;
}
if ((sdblock2mem_dma_done_read(sc) & 0x1) == 0) {
/* device_printf(sc->dk.sc_dev, "%s: SD card timeout\n", __PRETTY_FUNCTION__); */
return 1;
}
#else
if (wait_dma(sc, nblocks, readErr) != noErr)
return 1;
#endif
/* Stop transmission (Only for multiple block reads) */
if (nblocks > 1)
sdcard_stop_transmission(sc);
BlockMoveData((void*)stage_addr_cpu, (void*)buf_hw_addr, 512*nblocks);
//do_copy_rev((void*)stage_addr_cpu, (void*)buf_hw_addr, 512*nblocks);
/* Update Block/Buffer/Count */
block += nblocks;
buf += 512*nblocks;
count -= nblocks;
}
return 0;
}
int sdcard_write(uint32_t sc, struct SDCardContext *ctx, uint32_t block, uint32_t count, uint8_t* buf) {
while (count) {
uint32_t nblocks;
//uint64_t buf_hw_addr = ((uint64_t)((uint32_t)buf));// << 32;
uint32_t buf_hw_addr = (uint32_t)buf; // TEMPORARY FOR TESTING
uint32_t stage_addr_dma = 0x80000000; // DDR // TEMPORARY FOR TESTING
uint32_t stage_addr_cpu = sc << 4; // superslot // TEMPORARY FOR TESTING
#ifdef SDCARD_CMD25_SUPPORT
nblocks = count;
if (nblocks > 16)
nblocks = 16;
#else
nblocks = 1;
#endif
BlockMoveData((void*)buf_hw_addr, (void*)stage_addr_cpu, 512*nblocks);
//do_copy_rev((void*)buf_hw_addr, (void*)stage_addr_cpu, 512*nblocks);
#if 1
/* Initialize DMA Reader */
sdmem2block_dma_enable_write(sc, 0);
/* sdblock2mem_dma_base_write takes an uint64_t */
////sdmem2block_dma_base_write(sc, buf_hw_addr);
sdmem2block_dma_base_write(sc, stage_addr_dma);
sdmem2block_dma_length_write(sc, 512*nblocks);
sdmem2block_dma_enable_write(sc, 1);
#else
start_dma_read(sc, ctx, nblocks, buf_hw_addr); // write to sdcard, read from memory
#endif
/* Write Block(s) to SDCard */
#ifdef SDCARD_CMD23_SUPPORT
sdcard_set_block_count(sc, nblocks);
#endif
if (nblocks > 1)
sdcard_write_multiple_block(sc, block, nblocks);
else
sdcard_write_single_block(sc, block);
/* Stop transmission (Only for multiple block writes) */
if (nblocks > 1)
sdcard_stop_transmission(sc);
#if 1
/* Wait for DMA Reader to complete */
//int timeout = 64 * nblocks;
int timeout = 1024 * nblocks;
while (((sdmem2block_dma_done_read(sc) & 0x1) == 0) && timeout) {
//delay(2);
delay(20);
timeout --;
}
if ((sdmem2block_dma_done_read(sc) & 0x1) == 0) {
/* device_printf(sc->dk.sc_dev, "%s: SD card timeout\n", __PRETTY_FUNCTION__); */
return 1;
}
#else
if (wait_dma(sc, nblocks, writErr) != noErr)
return 1;
#endif
/* Update Block/Buffer/Count */
block += nblocks;
buf += 512*nblocks;
count -= nblocks;
}
return 0;
}

View File

@ -1,111 +0,0 @@
#include "NuBusFPGASDCardDrvr.h"
/* #include <DriverServices.h> */
inline void waitSome(unsigned long bound) {
unsigned long i;
for (i = 0 ; i < bound ; i++) {
asm volatile("nop");
}
}
__attribute__ ((section (".text.sddriver"))) static OSErr doSync(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce, struct SDCardContext *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
if (abs_offset & 0x01FF) {
ret = paramErr;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x804) = abs_offset;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x808) = pb->ioReqCount;
goto done;
}
if (pb->ioReqCount & 0x01FF) {
ret = paramErr;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x804) = abs_offset;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x808) = pb->ioReqCount;
goto done;
}
if (sdcard_read(dce->dCtlDevBase, ctx, abs_offset >> 9, pb->ioReqCount >> 9, pb->ioBuffer)) {
ret = readErr;
goto done;
}
}
pb->ioActCount = pb->ioReqCount;
dce->dCtlPosition = abs_offset + pb->ioReqCount;
pb->ioPosOffset = dce->dCtlPosition;
} else if ((pb->ioTrap & 0x00FF) == aWrCmd) {
if (abs_offset & 0x01FF) {
ret = paramErr;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x804) = abs_offset;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x808) = pb->ioReqCount;
goto done;
}
if (pb->ioReqCount & 0x01FF) {
ret = paramErr;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x804) = abs_offset;
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x808) = pb->ioReqCount;
goto done;
}
if (sdcard_write(dce->dCtlDevBase, ctx, abs_offset >> 9, pb->ioReqCount >> 9, pb->ioBuffer)) {
ret = writErr;
goto done;
}
pb->ioActCount = pb->ioReqCount;
dce->dCtlPosition = abs_offset + pb->ioReqCount;
pb->ioPosOffset = dce->dCtlPosition;
} else {
ret = paramErr;
goto done;
}
done:
if (ret != noErr)
*(uint32_t*)(dce->dCtlDevBase | 0x00902000 | 0x800) = ret | (((pb->ioTrap & 0x00FF) == aRdCmd) ? 0x11000000 : 0x22000000);
return ret;
}
/* Devices 1-34 (p54) */
#pragma parameter __D0 cNuBusFPGASDCardPrime(__A0, __A1)
OSErr cNuBusFPGASDCardPrime(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce) {
OSErr ret = noErr;
struct SDCardContext *ctx;
unsigned long abs_offset = 0;
ctx = *(struct SDCardContext**)dce->dCtlStorage;
if (ctx) {
ret = doSync(pb, dce, ctx);
if (!(pb->ioTrap & (1<<noQueueBit))) {
IODone((DCtlPtr)dce, ret);
}
goto done;
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
goto done;
}
done:
return ret;
}

View File

@ -1,30 +0,0 @@
#include "NuBusFPGASDCardDrvr.h"
#pragma parameter __D0 cNuBusFPGASDCardStatus(__A0, __A1)
OSErr cNuBusFPGASDCardStatus(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
{
OSErr ret = noErr;
struct SDCardContext *ctx;
/* write_reg(dce, GOBOFB_DEBUG, 0xDEAD0004); */
/* write_reg(dce, GOBOFB_DEBUG, pb->csCode); */
ctx = *(struct SDCardContext**)dce->dCtlStorage;
if (ctx) {
switch (pb->csCode)
{
default:
ret = statusErr;
break;
}
} else {
ret = offLinErr; /* r/w requested for an off-line drive */
goto done;
}
done:
if (!(pb->ioTrap & (1<<noQueueBit)))
IODone((DCtlPtr)dce, ret);
return ret;
}

View File

@ -1,93 +0,0 @@
#include "NuBusFPGADrvr.h"
#include <Traps.h>
#define SECO_WRITEREG(reg, val) \
*((volatile UInt32*)(a32+GOBOFB_BASE+reg)) = (UInt32)val;
#pragma parameter __D0 Primary(__A0)
UInt32 Secondary(SEBlock* seblock) {
UInt32 a32 = 0xF0000000 | ((UInt32)seblock->seSlot << 24);
UInt32 a32_l0, a32_l1;
UInt32 a32_4p0, a32_4p1;
SpBlock spblock;
/* UInt8 pram[8]; */
OSErr err;
UInt16 i,j;
char busMode;
UniversalProcPtr qd32ptr, unimpptr;
busMode = 1;
/* call SVersion to figure out if we have a recent SlotManager */
#if 0
//spblock.spSlot = seblock->seSlot;
//spblock.spExtDev = 0;
err = SVersion(&spblock);
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (err) {
/* DCDMF3 p178: if error, old slot manager*/
/* SECO_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
/* SECO_WRITEREG(GOBOFB_DEBUG, err);*/
} else {
/* DCDMF3 p178: new slot manager */
/* SECO_WRITEREG(GOBOFB_DEBUG, 0);*/
/* SECO_WRITEREG(GOBOFB_DEBUG, spblock.spResult);*/
}
SwapMMUMode ( &busMode ); // restore
#endif
#if 1
/* check for 32-bits QuickDraw */
qd32ptr = GetTrapAddress(Check32QDTrap);
unimpptr = GetTrapAddress(_Unimplemented);
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (qd32ptr == unimpptr) {
/* no 32QD */
SECO_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);
SECO_WRITEREG(GOBOFB_DEBUG, unimpptr);
} else {
/* yes 32QD */
SECO_WRITEREG(GOBOFB_DEBUG, 0x00C0FFEE);
}
SwapMMUMode ( &busMode ); // restore
#endif
#if 0
/* check the content of the PRAM */
spblock.spSlot = seblock->seSlot;
spblock.spResult = (UInt32)pram;
err = SReadPRAMRec(&spblock);
#if 0
SECO_WRITEREG(GOBOFB_DEBUG, 0x88888888);
for (j = 0 ; j < 8 ; j++)
SECO_WRITEREG(GOBOFB_DEBUG, (uint32_t)pram[j]);
SECO_WRITEREG(GOBOFB_DEBUG, 0x88888888);
#endif
#endif
#if 0
busMode = 1;
SwapMMUMode ( &busMode ); // to32
if (err) {
/* SECO_WRITEREG(GOBOFB_DEBUG, 0xFFFFFFFF);*/
/* SECO_WRITEREG(GOBOFB_DEBUG, err);*/
} else {
/* SECO_WRITEREG(GOBOFB_DEBUG, 0xC0FFEE00);*/
/* for (i = 0 ; i < 8 ; i++) */
/* SECO_WRITEREG(GOBOFB_DEBUG, pram[i]);*/
}
SwapMMUMode ( &busMode ); // restore
#endif
seblock->seStatus = 1;
return 0;
}

View File

@ -1,197 +0,0 @@
appleFormat = 1
romRevision = 1
romRevRange = 9
testPattern = 1519594439L
sCodeRev = 2
sExec2 = 2
sCPU68000 = 1
sCPU68020 = 2
sCPU68030 = 3
sCPU68040 = 4
sMacOS68000 = 1
sMacOS68020 = 2
sMacOS68030 = 3
sMacOS68040 = 4
board = 0
displayVideoAppleTFB = 16843009L
displayVideoAppleGM = 16843010L
networkEtherNetApple3Com = 33620225L
testSimpleAppleAny = -2147417856L
endOfList = 255
defaultTO = 100
fOpenAtStart = 1
f32BitMode = 2
sRsrcType = 1
sRsrcName = 2
sRsrcIcon = 3
sRsrcDrvrDir = 4
sRsrcLoadDir = 5
sRsrcBootRec = 6
sRsrcFlags = 7
sRsrcHWDevId = 8
minorBaseOS = 10
majorBaseOS = 12
majorLength = 13
sRsrcTest = 14
sRsrccicn = 15
sRsrcicl8 = 16
sRsrcicl4 = 17
sDRVRDir = 16
sGammaDir = 64
sRsrcVidNames = 65
sRsrcDock = 80
sDiagRec = 85
sVidAuxParams = 123
sDebugger = 124
sVidAttributes = 125
fLCDScreen = 0
fBuiltInDisplay = 1
fDefaultColor = 2
fActiveBlack = 3
fDimMinAt1 = 4
fBuiltInDetach = 4
sVidParmDir = 126
sBkltParmDir = 140
sSuperDir = 254
/* = */
/* = */
catBoard = 0x0001
catTest = 0x0002
catDisplay = 0x0003
catNetwork = 0x0004
catScanner = 0x0008
catCPU = 0x000A
catIntBus = 0x000C
catProto = 0x0011
catDock = 0x0020
typeBoard = 0x0000
typeApple = 0x0001
typeVideo = 0x0001
typeEtherNet = 0x0001
typeStation = 0x0001
typeDesk = 0x0002
typeTravel = 0x0003
typeDSP = 0x0004
typeXPT = 0x000B
typeSIM = 0x000C
typeDebugger = 0x0100
type68000 = 0x0002
type68020 = 0x0003
type68030 = 0x0004
type68040 = 0x0005
type601 = 0x0025
type603 = 0x002E
typeAppleII = 0x0015
drSwMacCPU = 0
drSwAppleIIe = 0x0001
drSwApple = 1
drSwMacsBug = 0x0104
drSwDepewEngineering = 0x0101
drHwTFB = 1
drHw3Com = 1
drHwBSC = 3
drHwGemini = 1
drHwDeskBar = 1
drHwATT3210 = 0x0001
drHwBootBug = 0x0100
drHwMicroDock = 0x0100
drHwSTB3 = 0x0002
drHwSTB = drHwSTB3
drHwRBV = 0x0018
drHwElsie = 0x001A
drHwTim = 0x001B
drHwDAFB = 0x001C
drHwGSC = 0x001E
drHwDAFBPDS = 0x001F
drHWVSC = 0x0020
drHwApollo = 0x0021
drHwSonora = 0x0022
drHwReserved2 = 0x0023
drHwColumbia = 0x0024
drHwCivic = 0x0025
drHwBrazil = 0x0026
drHWPBLCD = 0x0027
drHWCSC = 0x0028
drHwJET = 0x0029
drHWMEMCjr = 0x002A
drHwHPV = 0x002C
drHwPlanaria = 0x002D
drHwValkyrie = 0x002E
drHwKeystone = 0x002F
drHWATI = 0x0055
drHwGammaFormula = 0x0056
drHwSonic = 0x0110
drHwMace = 0x0114
drHwDblExp = 0x0001
MIIBoardId = 0x0010
ciVidBoardID = 0x001F
CX16VidBoardID = 0x0020
MIIxBoardId = 0x0021
SE30BoardID = 0x0022
MIIcxBoardId = 0x0023
MIIfxBoardId = 0x0024
EricksonBoardID = 0x0028
ElsieBoardID = 0x0029
TIMBoardID = 0x002A
EclipseBoardID = 0x002B
SpikeBoardID = 0x0033
DBLiteBoardID = 0x0035
ZydecoBrdID = 0x0036
ApolloBoardID = 0x0038
PDMBrdID = 0x0039
VailBoardID = 0x003A
WombatBrdID = 0x003B
ColumbiaBrdID = 0x003C
CycloneBrdID = 0x003D
CompanionBrdID = 0x003E
DartanianBoardID = 0x0040
DartExtVidBoardID = 0x0046
HookBoardID = 0x0047
EscherBoardID = 0x004A
POBoardID = 0x004D
TempestBrdID = 0x0050
BlackBirdBdID = 0x0058
BBExtVidBdID = 0x0059
YeagerBoardID = 0x005A
BBEtherNetBdID = 0x005E
TELLBoardID = 0x0065
MalcolmBoardID = 0x065E
AJBoardID = 0x065F
M2BoardID = 0x0660
OmegaBoardID = 0x0661
TNTBoardID = 0x0670
HooperBoardID = 0x06CD
BoardIDDblExp = 0x002F
DAFBPDSBoardID = 0x0037
MonetBoardID = 0x0048
SacSONIC16BoardID = 0x004E
SacSONIC32BoardID = 0x004F
drHWMacII = 0x0001
drHwMacIIx = 0x0002
drHWSE30 = 0x0003
drHwMacIIcx = 0x0004
drHWMacIIfx = 0x0005
drHWF19 = 0x0005
sBlockTransferInfo = 20
sMaxLockedTransferCount = 21
boardId = 32
pRAMInitData = 33
primaryInit = 34
timeOutConst = 35
vendorInfo = 36
boardFlags = 37
secondaryInit = 38
MajRAMSp = 129
MinROMSp = 130
vendorId = 1
serialNum = 2
revLevel = 3
partNum = 4
date = 5
testByte = 32
testWord = 33
testLong = 34
testString = 35
mBlockTransferInfo = 5
mMaxLockedTransferCount = 6

View File

@ -1,358 +0,0 @@
mBaseOffset = 1 /*IdofmBaseOffset.*/
mRowBytes = 2 /*VideosResourceparameterId's*/
mBounds = 3 /*VideosResourceparameterId's*/
mVersion = 4 /*VideosResourceparameterId's*/
mHRes = 5 /*VideosResourceparameterId's*/
mVRes = 6 /*VideosResourceparameterId's*/
mPixelType = 7 /*VideosResourceparameterId's*/
mPixelSize = 8 /*VideosResourceparameterId's*/
mCmpCount = 9 /*VideosResourceparameterId's*/
mCmpSize = 10 /*VideosResourceparameterId's*/
mPlaneBytes = 11 /*VideosResourceparameterId's*/
mVertRefRate = 14 /*VideosResourceparameterId's*/
mVidParams = 1 /*Videoparameterblockid.*/
mTable = 2 /*Offsettothetable.*/
mPageCnt = 3 /*Numberofpages*/
mDevType = 4 /*DeviceType*/
oneBitMode = 128 /*IdofOneBitModeParameterlist.*/
twoBitMode = 129 /*IdofTwoBitModeParameterlist.*/
fourBitMode = 130 /*IdofFourBitModeParameterlist.*/
eightBitMode = 131/*IdofEightBitModeParameterlist.*/
sixteenBitMode = 132 /*IdofSixteenBitModeParameterlist.*/
thirtyTwoBitMode = 133 /*IdofThirtyTwoBitModeParameterlist.*/
firstVidMode = 128 /*Thenew,betterwaytodotheabove.*/
secondVidMode = 129 /*QuickDrawonlysupportssixvideo*/
thirdVidMode = 130 /*atthistime.*/
fourthVidMode = 131
fifthVidMode = 132
sixthVidMode = 133
spGammaDir = 64
spVidNamesDir = 65
/* kDeclROMtables = FOUR_CHAR_CODE('decl') */
/* kDetailedTimingFormat = FOUR_CHAR_CODE('arba') */ /*Timingisadetailedtiming*/
kDDCBlockSize = 128
kDDCBlockTypeEDID = 0/*EDIDblocktype.*/
kDDCForceReadBit = 0 /*ForceanewreadoftheEDID.*/
kDDCForceReadMask = (1<<kDDCForceReadBit)/*MaskforkddcForceReadBit.*/
timingInvalid_SM_T24 = 8 /*WorkaroundbuginSMThunder24card.*/
timingApple_FixedRateLCD = 42 /*Lumpallfixed-rateLCDsintoonecategory.*/
timingApple_512x384_60hz = 130 /*512x384(60Hz)Rubiktiming.*/
timingApple_560x384_60hz = 135 /*560x384(60Hz)Rubik-560timing.*/
timingApple_640x480_67hz = 140 /*640x480(67Hz)HRtiming.*/
timingApple_640x400_67hz = 145 /*640x400(67Hz)HR-400timing.*/
timingVESA_640x480_60hz = 150 /*640x480(60Hz)VGAtiming.*/
timingVESA_640x480_72hz = 152 /*640x480(72Hz)VGAtiming.*/
timingVESA_640x480_75hz = 154 /*640x480(75Hz)VGAtiming.*/
timingVESA_640x480_85hz = 158 /*640x480(85Hz)VGAtiming.*/
timingGTF_640x480_120hz = 159 /*640x480(120Hz)VESAGeneralizedTimingFormula*/
timingApple_640x870_75hz = 160 /*640x870(75Hz)FPDtiming.*/
timingApple_640x818_75hz = 165 /*640x818(75Hz)FPD-818timing.*/
timingApple_832x624_75hz = 170 /*832x624(75Hz)GoldFishtiming.*/
timingVESA_800x600_56hz = 180 /*800x600(56Hz)SVGAtiming.*/
timingVESA_800x600_60hz = 182 /*800x600(60Hz)SVGAtiming.*/
timingVESA_800x600_72hz = 184 /*800x600(72Hz)SVGAtiming.*/
timingVESA_800x600_75hz = 186 /*800x600(75Hz)SVGAtiming.*/
timingVESA_800x600_85hz = 188 /*800x600(85Hz)SVGAtiming.*/
timingVESA_1024x768_60hz = 190 /*1024x768(60Hz)VESA1K-60Hztiming.*/
timingVESA_1024x768_70hz = 200 /*1024x768(70Hz)VESA1K-70Hztiming.*/
timingVESA_1024x768_75hz = 204 /*1024x768(75Hz)VESA1K-75Hztiming(verysimilarto
timingVESA_1024x768_85hz = 208 /*1024x768(85Hz)VESAtiming.*/
timingApple_1024x768_75hz = 210 /*1024x768(75Hz)Apple19"RGB.*/
timingApple_1152x870_75hz = 220 /*1152x870(75Hz)Apple21"RGB.*/
timingAppleNTSC_ST = 230 /*512x384(60Hz,interlaced,non-convolved).*/
timingAppleNTSC_FF = 232 /*640x480(60Hz,interlaced,non-convolved).*/
timingAppleNTSC_STconv = 234 /*512x384(60Hz,interlaced,convolved).*/
timingAppleNTSC_FFconv = 236 /*640x480(60Hz,interlaced,convolved).*/
timingApplePAL_ST = 238 /*640x480(50Hz,interlaced,non-convolved).*/
timingApplePAL_FF = 240 /*768x576(50Hz,interlaced,non-convolved).*/
timingApplePAL_STconv = 242 /*640x480(50Hz,interlaced,convolved).*/
timingApplePAL_FFconv = 244 /*768x576(50Hz,interlaced,convolved).*/
timingVESA_1280x960_75hz = 250 /*1280x960(75Hz)*/
timingVESA_1280x960_60hz = 252 /*1280x960(60Hz)*/
timingVESA_1280x960_85hz = 254 /*1280x960(85Hz)*/
timingVESA_1280x1024_60hz = 260 /*1280x1024(60Hz)*/
timingVESA_1280x1024_75hz = 262 /*1280x1024(75Hz)*/
timingVESA_1280x1024_85hz = 268 /*1280x1024(85Hz)*/
timingVESA_1600x1200_60hz = 280 /*1600x1200(60Hz)VESAtiming.*/
timingVESA_1600x1200_65hz = 282 /*1600x1200(65Hz)VESAtiming.*/
timingVESA_1600x1200_70hz = 284 /*1600x1200(70Hz)VESAtiming.*/
timingVESA_1600x1200_75hz = 286 /*1600x1200(75Hz)VESAtiming(pixelclockis189.2
timingVESA_1600x1200_80hz = 288 /*1600x1200(80Hz)VESAtiming(pixelclockis216>?
timingVESA_1600x1200_85hz = 289 /*1600x1200(85Hz)VESAtiming(pixelclockis229.5
timingVESA_1792x1344_60hz = 296 /*1792x1344(60Hz)VESAtiming(204.75Mhzdotclock).
timingVESA_1792x1344_75hz = 298 /*1792x1344(75Hz)VESAtiming(261.75Mhzdotclock).
timingVESA_1856x1392_60hz = 300 /*1856x1392(60Hz)VESAtiming(218.25Mhzdotclock).
timingVESA_1856x1392_75hz = 302 /*1856x1392(75Hz)VESAtiming(288Mhzdotclock).
timingVESA_1920x1440_60hz = 304 /*1920x1440(60Hz)VESAtiming(234Mhzdotclock).
timingVESA_1920x1440_75hz = 306 /*1920x1440(75Hz)VESAtiming(297Mhzdotclock).
timingSMPTE240M_60hz = 400 /*60HzV,33.75KHzH,interlacedtiming,16:9aspect,typical
timingFilmRate_48hz = 410 /*48HzV,25.20KHzH,non-interlacedtiming,typicalresolutionof
timingSony_1600x1024_76hz = 500 /*1600x1024(76Hz)Sonytiming(pixelclockis170.447
timingSony_1920x1080_60hz = 510 /*1920x1080(60Hz)Sonytiming(pixelclockis159.84
timingSony_1920x1080_72hz = 520 /*1920x1080(72Hz)Sonytiming(pixelclockis216.023
timingSony_1920x1200_76hz = 540 /*1900x1200(76Hz)Sonytiming(pixelclockis243.20
timingApple_0x0_0hz_Offline = 550/*Indicatesthatthistimingwilltakethedisplayoff-line
timingApple12 = timingApple_512x384_60hz
timingApple12x = timingApple_560x384_60hz
timingApple13 = timingApple_640x480_67hz
timingApple13x = timingApple_640x400_67hz
timingAppleVGA = timingVESA_640x480_60hz
timingApple15 = timingApple_640x870_75hz
timingApple15x = timingApple_640x818_75hz
timingApple16 = timingApple_832x624_75hz
timingAppleSVGA = timingVESA_800x600_56hz
timingApple1Ka = timingVESA_1024x768_60hz
timingApple1Kb = timingVESA_1024x768_70hz
timingApple19 = timingApple_1024x768_75hz
timingApple21 = timingApple_1152x870_75hz
timingSony_1900x1200_74hz = 530 /*1900x1200(74Hz)Sonytiming(pixelclockis236.25
timingSony_1900x1200_76hz = timingSony_1920x1200_76hz/*1900x1200(76Hz)Sonytiming(pixelclockis245.48
kAllModesValid = 0 /*Allmodesnottrimmedbyprimaryinitaregood
kAllModesSafe = 1 /*Allmodesnottrimmedbyprimaryinitareknow
kReportsTagging = 2 /*Candetecttaggeddisplays(toidentifysmartmonitors)*/
kHasDirectConnection = 3 /*Trueimpliesthatdrivercantalkdirectlytodevice
kUncertainConnection = 5 /*Theremaynotbeadisplay(nosenselines?).
kTaggingInfoNonStandard = 6 /*SetwhencsConnectTaggedType/csConnectTaggedDataarenon-standard(i.e.,nottheApple
kReportsDDCConnection = 7 /*Cardcandoddc(setkHasDirectConnect&&kHasDDCConnectif
kHasDDCConnection = 8 /*Cardhasddcconnectnow.*/
kConnectionInactive = 9 /*SetwhentheconnectionisNOTcurrentlyactive(generally
kDependentConnection = 10 /*SetwhensomeascpectofTHISconnectiondependson
kBuiltInConnection = 11 /*SetwhenconnectionisKNOWNtobebuilt-in(this
kOverrideConnection = 12 /*Setwhenthereportedconnectionisnotthetrue
kFastCheckForDDC = 13 /*Setwhenall3aretrue:1)sensecodes
kReportsHotPlugging = 14/*Detectsandreportshotplugggingonconnector(viaVSL
kPanelConnect = 2 /*Forusewithfixed-in-placeLCDpanels.*/
kPanelTFTConnect = 2 /*AliasforkPanelConnect*/
kFixedModeCRTConnect = 3 /*Forusewithfixed-mode(i.e.,verylimitedrange)displays.
kMultiModeCRT1Connect = 4 /*320x200maybe,12"maybe,13"(default),16"certain,19"
kMultiModeCRT2Connect = 5 /*320x200maybe,12"maybe,13"certain,16"(default),19"
kMultiModeCRT3Connect = 6 /*320x200maybe,12"maybe,13"certain,16"certain,19"
kMultiModeCRT4Connect = 7 /*Expansiontolargemultimode(notyetused)*/
kModelessConnect = 8 /*Expansiontomodelessmodel(notyetused)*/
kFullPageConnect = 9 /*640x818(toget8bppin512Kcase)and640x870
kVGAConnect = 10 /*640x480VGAdefault--questioneverythingelse*/
kNTSCConnect = 11 /*NTSCST(default),FF,STconv,FFconv*/
kPALConnect = 12 /*PALST(default),FF,STconv,FFconv*/
kHRConnect = 13 /*Straight-6connect--640x480and640x400(toget8bpp
kMonoTwoPageConnect = 15 /*1152x870Applecolortwo-pagedisplay*/
kColorTwoPageConnect = 16 /*1152x870AppleB&Wtwo-pagedisplay*/
kColor16Connect = 17 /*832x624AppleB&Wtwo-pagedisplay*/
kColor19Connect = 18 /*1024x768AppleB&Wtwo-pagedisplay*/
kGenericCRT = 19 /*IndicatesnothingexceptthatconnectionisCRTinnature.
kGenericLCD = 20 /*IndicatesnothingexceptthatconnectionisLCDinnature.
kDDCConnect = 21 /*DDCconnection,alwayssetkHasDDCConnection*/
kNoConnect = 22/*Nodisplayisconnected-loadsensingorsimilar
kModeValid = 0 /*SaysthatthismodeshouldNOTbetrimmed.*/
kModeSafe = 1 /*Thismodedoesnotneedconfirmation*/
kModeDefault = 2 /*Thisisthedefaultmodeforthistypeof
kModeShowNow = 3 /*Thismodeshouldalwaysbeshown(eventhoughit
kModeNotResize = 4 /*Thismodeshouldnotbeusedtoresizethe
kModeRequiresPan = 5 /*Thismodehasmorepixelsthanareactuallydisplayed
kModeInterlaced = 6 /*Thismodeisinterlaced(singlepixellineslookbad).
kModeShowNever = 7 /*Thismodeshouldnotbeshownintheuser
kModeSimulscan = 8 /*Indicatesthatmorethanonedisplayconnectioncanbe
kModeNotPreset = 9 /*Indicatesthatthetimingisnotafactorypreset
kModeBuiltIn = 10 /*Indicatesthatthedisplaymodeisforthebuilt-in
kModeStretched = 11/*Indicatesthatthedisplaymodewillbestretched/distortedto
kDepthDependent = 0/*Saysthatthisdepthmodemaycausedependentchanges
kResolutionHasMultipleDepthSizes = 0/*SaysthatthismodehasdifferentcsHorizontalPixels csVerticalLinesat
kAVPowerOff = 0 /*Powerfullyoff*/
kAVPowerStandby = 1
kAVPowerSuspend = 2
kAVPowerOn = 3
kHardwareSleep = 128
kHardwareWake = 129
kHardwareWakeFromSuspend = 130
kHardwareWakeToDoze = 131
kHardwareWakeToDozeFromSuspend = 132
cscReset = 0
cscKillIO = 1
cscSetMode = 2
cscSetEntries = 3
cscSetGamma = 4
cscGrayPage = 5
cscGrayScreen = 5
cscSetGray = 6
cscSetInterrupt = 7
cscDirectSetEntries = 8
cscSetDefaultMode = 9
cscSwitchMode = 10 /*TakesaVDSwitchInfoPtr*/
cscSetSync = 11 /*TakesaVDSyncInfoPtr*/
cscSavePreferredConfiguration = 16 /*TakesaVDSwitchInfoPtr*/
cscSetHardwareCursor = 22 /*TakesaVDSetHardwareCursorPtr*/
cscDrawHardwareCursor = 23 /*TakesaVDDrawHardwareCursorPtr*/
cscSetConvolution = 24 /*TakesaVDConvolutionInfoPtr*/
cscSetPowerState = 25 /*TakesaVDPowerStatePtr*/
cscPrivateControlCall = 26 /*TakesaVDPrivateSelectorDataPtr*/
cscSetMultiConnect = 28 /*TakesaVDMultiConnectInfoPtr*/
cscSetClutBehavior = 29 /*TakesaVDClutBehavior*/
cscSetDetailedTiming = 31 /*TakesaVDDetailedTimingPtr*/
cscDoCommunication = 33 /*TakesaVDCommunicationPtr*/
cscProbeConnection = 34 /*Takesnilpointer(maygenerateakFBConnectInterruptServiceTypeserviceinterrupt)*/
cscUnusedCall = 127/*Thiscallusedtoexpendthescrnresource.Its
cscGetMode = 2
cscGetEntries = 3
cscGetPageCnt = 4
cscGetPages = 4 /*ThisiswhatC&D2callsit.*/
cscGetPageBase = 5
cscGetBaseAddr = 5 /*ThisiswhatC&D2callsit.*/
cscGetGray = 6
cscGetInterrupt = 7
cscGetGamma = 8
cscGetDefaultMode = 9
cscGetCurMode = 10 /*TakesaVDSwitchInfoPtr*/
cscGetSync = 11 /*TakesaVDSyncInfoPtr*/
cscGetConnection = 12 /*Returninformationabouttheconnectiontothedisplay*/
cscGetModeTiming = 13 /*Returntiminginfoforamode*/
cscGetModeBaseAddress = 14 /*Returnbaseaddressinformationaboutaparticularmode*/
cscGetScanProc = 15 /*QuickTimescanchasingroutine*/
cscGetPreferredConfiguration = 16 /*TakesaVDSwitchInfoPtr*/
cscGetNextResolution = 17 /*TakesaVDResolutionInfoPtr*/
cscGetVideoParameters = 18 /*TakesaVDVideoParametersInfoPtr*/
cscGetGammaInfoList = 20 /*TakesaVDGetGammaListPtr*/
cscRetrieveGammaTable = 21 /*TakesaVDRetrieveGammaPtr*/
cscSupportsHardwareCursor = 22 /*TakesaVDSupportsHardwareCursorPtr*/
cscGetHardwareCursorDrawState = 23 /*TakesaVDHardwareCursorDrawStatePtr*/
cscGetConvolution = 24 /*TakesaVDConvolutionInfoPtr*/
cscGetPowerState = 25 /*TakesaVDPowerStatePtr*/
cscPrivateStatusCall = 26 /*TakesaVDPrivateSelectorDataPtr*/
cscGetDDCBlock = 27 /*TakesaVDDDCBlockPtr*/
cscGetMultiConnect = 28 /*TakesaVDMultiConnectInfoPtr*/
cscGetClutBehavior = 29 /*TakesaVDClutBehaviorPtr*/
cscGetTimingRanges = 30 /*TakesaVDDisplayTimingRangePtr*/
cscGetDetailedTiming = 31 /*TakesaVDDetailedTimingPtr*/
cscGetCommunicationInfo = 32/*TakesaVDCommunicationInfoPtr*/
kDisableHorizontalSyncBit = 0
kDisableVerticalSyncBit = 1
kDisableCompositeSyncBit = 2
kEnableSyncOnBlue = 3
kEnableSyncOnGreen = 4
kEnableSyncOnRed = 5
kNoSeparateSyncControlBit = 6
kTriStateSyncBit = 7
kHorizontalSyncMask = 0x01
kVerticalSyncMask = 0x02
kCompositeSyncMask = 0x04
kDPMSSyncMask = 0x07
kTriStateSyncMask = 0x80
kSyncOnBlueMask = 0x08
kSyncOnGreenMask = 0x10
kSyncOnRedMask = 0x20
kSyncOnMask = 0x38
kDPMSSyncOn = 0
kDPMSSyncStandby = 1
kDPMSSyncSuspend = 2
kDPMSSyncOff = 7
kConvolved = 0
kLiveVideoPassThru = 1
kConvolvedMask = 0x01
kLiveVideoPassThruMask = 0x02
kRSCZero = 0
kRSCOne = 1
kRSCTwo = 2
kRSCThree = 3
kRSCFour = 4
kRSCFive = 5
kRSCSix = 6
kRSCSeven = 7
kESCZero21Inch = 0x00 /*21"RGB*/
kESCOnePortraitMono = 0x14 /*PortraitMonochrome*/
kESCTwo12Inch = 0x21 /*12"RGB*/
kESCThree21InchRadius = 0x31 /*21"RGB(Radius)*/
kESCThree21InchMonoRadius = 0x34 /*21"Monochrome(Radius)*/
kESCThree21InchMono = 0x35 /*21"Monochrome*/
kESCFourNTSC = 0x0A /*NTSC*/
kESCFivePortrait = 0x1E /*PortraitRGB*/
kESCSixMSB1 = 0x03 /*MultiScanBand-1(12"thru1Six")*/
kESCSixMSB2 = 0x0B /*MultiScanBand-2(13"thru19")*/
kESCSixMSB3 = 0x23 /*MultiScanBand-3(13"thru21")*/
kESCSixStandard = 0x2B /*13"/14"RGBor12"Monochrome*/
kESCSevenPAL = 0x00 /*PAL*/
kESCSevenNTSC = 0x14 /*NTSC*/
kESCSevenVGA = 0x17 /*VGA*/
kESCSeven16Inch = 0x2D /*16"RGB(GoldFish)*/
kESCSevenPALAlternate = 0x30 /*PAL(Alternate)*/
kESCSevenDDC = 0x3E /*DDCdisplay*/
kESCSevenNoDisplay = 0x3F/*Nodisplayconnected*/
kDepthMode1 = 128
kDepthMode2 = 129
kDepthMode3 = 130
kDepthMode4 = 131
kDepthMode5 = 132
kDepthMode6 = 133
kFirstDepthMode = 128 /*Theseconstantsareobsolete,andjustincluded*/
kSecondDepthMode = 129 /*forclientsthathaveconvertedtotheabove*/
kThirdDepthMode = 130 /*kDepthModeXXXconstants.*/
kFourthDepthMode = 131
kFifthDepthMode = 132
kSixthDepthMode = 133
kDisplayModeIDCurrent = 0x00 /*ReferencetheCurrentDisplayModeID*/
kDisplayModeIDInvalid = 0xFFFFFFFF /*AbogusDisplayModeIDinallcases*/
kDisplayModeIDFindFirstResolution = 0xFFFFFFFE /*UsedincscGetNextResolutiontoresetiterator*/
kDisplayModeIDNoMoreResolutions = 0xFFFFFFFD /*UsedincscGetNextResolutiontoindicateEndOfList*/
kDisplayModeIDFindFirstProgrammable = 0xFFFFFFFC /*UsedincscGetNextResolutiontofindunusedprogrammabletiming*/
kDisplayModeIDBootProgrammable = 0xFFFFFFFB /*ThisistheIDgivenatboottimeby
kDisplayModeIDReservedBase = 0x80000000/*Lowest(unsigned)DisplayModeIDreservedbyApple*/
kGammaTableIDFindFirst = 0xFFFFFFFE /*GetthefirstgammatableID*/
kGammaTableIDNoMoreTables = 0xFFFFFFFD /*Usedtoindicateendoflist*/
kGammaTableIDSpecific = 0x00/*Returntheinfoforthegiventableid*/
kActivateConnection = (0<<kConnectionInactive) /*Usedforactivatingaconnection(csConnectFlagsvalue).*/
kDeactivateConnection = (1<<kConnectionInactive)/*Usedfordeactivatingaconnection(csConnectFlagsvalue.)*/
kVideoDefaultBus = 0
kVideoBusTypeInvalid = 0
kVideoBusTypeI2C = 1
kVideoNoTransactionType = 0 /*Notransaction*/
kVideoSimpleI2CType = 1 /*SimpleI2Cmessage*/
kVideoDDCciReplyType = 2/*DDC/cimessage(withimbeddedlength)*/
kVideoReplyMicroSecDelayMask = (1<<0)/*Ifset thedrivershoulddelaycsMinReplyDelay
kSyncInterlaceMask = (1<<7)
kSyncAnalogCompositeMask = 0
kSyncAnalogCompositeSerrateMask = (1<<2)
kSyncAnalogCompositeRGBSyncMask = (1<<1)
kSyncAnalogBipolarMask = (1<<3)
kSyncAnalogBipolarSerrateMask = (1<<2)
kSyncAnalogBipolarSRGBSyncMask = (1<<1)
kSyncDigitalCompositeMask = (1<<4)
kSyncDigitalCompositeSerrateMask = (1<<2)
kSyncDigitalCompositeMatchHSyncMask = (1<<2)
kSyncDigitalSeperateMask = (1<<4)+(1<<3)
kSyncDigitalVSyncPositiveMask = (1<<2)
kSyncDigitalHSyncPositiveMask = (1<<1)
kDMSModeReady = 0 /*DisplayModeIDisconfiguredandready*/
kDMSModeNotReady = 1 /*DisplayModeIDisisbeingprogrammed*/
kDMSModeFree = 2/*DisplayModeIDisnotassociatedwithatiming*/
kTimingChangeRestrictedErr = -10930
kVideoI2CReplyPendingErr = -10931
kVideoI2CTransactionErr = -10932
kVideoI2CBusyErr = -10933
kVideoI2CTransactionTypeErr = -10934
kVideoBufferSizeErr = -10935
kRangeSupportsSignal_0700_0300_Bit = 0
kRangeSupportsSignal_0714_0286_Bit = 1
kRangeSupportsSignal_1000_0400_Bit = 2
kRangeSupportsSignal_0700_0000_Bit = 3
kRangeSupportsSignal_0700_0300_Mask = (1<<kRangeSupportsSignal_0700_0300_Bit)
kRangeSupportsSignal_0714_0286_Mask = (1<<kRangeSupportsSignal_0714_0286_Bit)
kRangeSupportsSignal_1000_0400_Mask = (1<<kRangeSupportsSignal_1000_0400_Bit)
kRangeSupportsSignal_0700_0000_Mask = (1<<kRangeSupportsSignal_0700_0000_Bit)
kDigitalSignalBit = 0 /*Donotset.MacOSdoesnotcurrentlysupport
kAnalogSetupExpectedBit = 1 /*Analogdisplays-displayexpectsablank-to-blacksetupor
kDigitalSignalMask = (1<<kDigitalSignalBit)
kAnalogSetupExpectedMask = (1<<kAnalogSetupExpectedBit)
kAnalogSignalLevel_0700_0300 = 0
kAnalogSignalLevel_0714_0286 = 1
kAnalogSignalLevel_1000_0400 = 2
kAnalogSignalLevel_0700_0000 = 3
kRangeSupportsSeperateSyncsBit = 0
kRangeSupportsSyncOnGreenBit = 1
kRangeSupportsCompositeSyncBit = 2
kRangeSupportsVSyncSerrationBit = 3
kRangeSupportsSeperateSyncsMask = (1<<kRangeSupportsSeperateSyncsBit)
kRangeSupportsSyncOnGreenMask = (1<<kRangeSupportsSyncOnGreenBit)
kRangeSupportsCompositeSyncMask = (1<<kRangeSupportsCompositeSyncBit)
kRangeSupportsVSyncSerrationMask = (1<<kRangeSupportsVSyncSerrationBit)
kSyncPositivePolarityBit = 0 /*Digitalseparatesyncpolarityforanaloginterfaces(0=>
kSyncPositivePolarityMask = (1<<kSyncPositivePolarityBit)
kSetClutAtSetEntries = 0 /*SetEntriesbehavioristoupdateclutduringSetEntriescall*/
kSetClutAtVBL = 1/*SetEntriesbehavioristoupateclutatnextvbl*/

View File

@ -1,282 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
struct one_res {
const unsigned short hres;
const unsigned short vres;
const unsigned char native_only;
};
#define NUM_RES 16
#if 1
static struct one_res res_db[NUM_RES] = {
{ 1920, 1080, 0 },
{ 1680, 1050, 0 }, // should be unsuitable
{ 1600, 900, 1 }, // freaks out my monitor on 1920x1080, it thinks it's 1680x1050...
{ 1440, 900, 0 },
{ 1280, 1024, 0 },
{ 1280, 960, 0 },
{ 1280, 800, 0 },
{ 1152, 870, 0 },
{ 1152, 864, 0 },
{ 1024, 768, 0 },
{ 832, 624, 0 },
{ 800, 600, 0 },
{ 768, 576, 0 },
{ 640, 480, 0 },
{ 512, 384, 0 },
{ 0, 0, 0 }
};
#else
static struct one_res res_db[NUM_RES] = {
{ 1920, 1080, 0 },
{ 1600, 900, 1 },
/* { 640, 480, 0 }, */
{ 0, 0, 0}
};
#endif
int main(int argc, char **argv) {
unsigned short maxhres = 1920, maxvres = 1080;
const int depthdb[6] = { 8, 4, 2, 1, 32, 16 };
int enabled[NUM_RES];
int i, j;
unsigned char id;
for (i = 0 ; i < NUM_RES ; i++) {
enabled[i] = 0;
}
if (argc == 3) {
maxhres = atoi(argv[1]);
maxvres = atoi(argv[2]);
}
fprintf(stderr, "Resolution: %hu x %hu\n", maxhres, maxvres);
id = 0x80;
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) && (id < 0x90); i++) { // 0x90 is the ram disk
char filename[512];
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
FILE *fd;
if ((hres * vres) % 128) // unsuitable, safety net
continue;
if (res_db[i].native_only && ((hres != maxhres) || (vres != maxvres)))
continue;
if ((hres > maxhres) || (vres > maxvres))
continue;
snprintf(filename, 512, "VidRomRes_%hux%hu.s", hres, vres);
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
enabled[i] = 1;
id ++;
for (j = 0 ; j < 6 ; j++) {
char modename[128];
const unsigned short depth = depthdb[j];
const unsigned short rowBytes = (hres * depth) / 8;
snprintf(modename, 128, "R%hux%huD%d", hres, vres, depth);
fprintf(fd, "\tALIGN 2\n");
fprintf(fd, "_%sModes: /* id 0x%02x */\n", modename, id-1);
fprintf(fd, "\tOSLstEntry\tmVidParams,_%sParms\t/* offset to vid parameters */\n", modename);
fprintf(fd, "\tDatLstEntry\tmPageCnt,%d\t/* number of video pages */\n", (depth == 32) ? 1 : 2);
fprintf(fd, "\tDatLstEntry\tmDevType,%s\t/* device type */\n", depth <= 8 ? "clutType" : "directType");
fprintf(fd, "\t.long\tEndOfList\t/* end of list */\n");
fprintf(fd, "_%sParms:\n", modename);
fprintf(fd, "\t.long\t_End%sParms-_%sParms\t/* physical block size */\n", modename, modename);
fprintf(fd, "\t.long\t0\t/* QuickDraw base offset ; vpBaseOffset */\n"); // defmBaseOffset
fprintf(fd, "\t.word\t%hu\t/* physRowBytes ; vpRowBytes */\n", rowBytes);
fprintf(fd, "\t.word\t0,0,%hu,%hu\t/* vpBounds */\n", vres, hres);
fprintf(fd, "\t.word\tdefVersion\t/* bmVersion ; vpVersion */\n");
fprintf(fd, "\t.word\t0\t/* packType not used ; vpPackType */\n");
fprintf(fd, "\t.long\t0\t/* packSize not used ; vpPackSize */\n");
fprintf(fd, "\t.long\tdefmHRes\t/* bmHRes */\n");
fprintf(fd, "\t.long\tdefmVRes\t/* bmVRes */\n");
fprintf(fd, "\t.word\t%s\t/* bmPixelType */\n", depth <= 8 ? "ChunkyIndexed" : "ChunkyDirect");
fprintf(fd, "\t.word\t%d\t/* bmPixelSize */\n", depth);
fprintf(fd, "\t.word\t%d\t/* bmCmpCount */\n", depth <= 8 ? 1 : 3);
fprintf(fd, "\t.word\t%d\t/* bmCmpSize */\n", depth <= 8 ? depth : (depth == 32 ? 8 : 5));
fprintf(fd, "\t.long\t0\t/* bmPlaneBytes */\n"); // defmPlaneBytes
fprintf(fd, "_End%sParms:\n\n",modename);
}
fclose(fd);
}
{
char filename[512];
FILE *fd;
id = 0x80;
snprintf(filename, 512, "VidRomRes.s");
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
fprintf(fd, ".include \"VidRomRes_%hux%hu.s\"\n", hres, vres);
}
}
fclose(fd);
}
{
char filename[512];
FILE *fd;
snprintf(filename, 512, "VidRomName.s");
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
fprintf(fd, "\tALIGN 2\n");
fprintf(fd, "_VModeName:\n");
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
fprintf(fd, "\tOSLstEntry\tsRsrc_GoboFB_R%hux%hu,_ScreenNameGoboFB_R%hux%hu\n", hres, vres, hres, vres);
}
}
fprintf(fd, "\tDatLstEntry endOfList, 0\n");
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
int native = (hres == maxhres) && (vres == maxvres);
fprintf(fd, "\tALIGN 2\n");
fprintf(fd, "_ScreenNameGoboFB_R%hux%hu:\n", hres, vres);
fprintf(fd, "\t.long\t_ScreenNameGoboFB_R%hux%huEnd - _ScreenNameGoboFB_R%hux%hu\n", hres, vres, hres, vres);
fprintf(fd, "\t.word\t0\n");
fprintf(fd, "\t.string\t\"GoblinFB %hux%hu%s\\0\"\n", hres, vres, native ? " (N)": "");
fprintf(fd, "_ScreenNameGoboFB_R%hux%huEnd:\n", hres, vres);
}
}
fclose(fd);
}
{
char filename[512];
FILE *fd;
snprintf(filename, 512, "VidRomDir_%hux%hu.s", maxhres, maxvres);
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
int native = (hres == maxhres) && (vres == maxvres);
fprintf(fd, "\tALIGN 2\n");
fprintf(fd, "_sRsrc_GoboFB_R%hux%hu:\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tsRsrcType,_GoboFBType\t/* video type descriptor */\n");
fprintf(fd, "\tOSLstEntry\tsRsrcName,_GoboFBName\t/* offset to driver name string */\n");
fprintf(fd, "\tOSLstEntry\tsRsrcDrvrDir,_GoboFBDrvrDir /* offset to driver directory */\n");
fprintf(fd, "\tDatLstEntry\tsRsrcFlags,%d\t/* force 32 bits mode & open (native) - or not (others)*/\n", native ? 6 : 0);
fprintf(fd, "\tDatLstEntry\tsRsrcHWDevId,1\t/* hardware device ID */\n");
fprintf(fd, "\tOSLstEntry\tMinorBaseOS,_MinorBase\t/* offset to frame buffer array */\n");
fprintf(fd, "\tOSLstEntry\tMinorLength,_MinorLength\t/* offset to frame buffer length */\n");
fprintf(fd, "\t/* OSLstEntry\tsGammaDir,_GammaDirS\t/* directory for 640x480 monitor */\n");
fprintf(fd, "/* Parameters */\n");
fprintf(fd, "\tOSLstEntry\tfirstVidMode,_R%hux%huD8Modes\t/* offset to 8 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tsecondVidMode,_R%hux%huD4Modes\t/* offset to 4 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tthirdVidMode,_R%hux%huD2Modes\t/* offset to 2 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tfourthVidMode,_R%hux%huD1Modes\t/* offset to 1 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tfifthVidMode,_R%hux%huD32Modes\t/* offset to 24/32 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\tOSLstEntry\tsixthVidMode,_R%hux%huD16Modes\t/* offset to 15/16 Bit Mode parms */\n", hres, vres);
fprintf(fd, "\t.long EndOfList\t/* end of list */\n\n");
}
}
fclose(fd);
}
{
char filename[512];
FILE *fd;
unsigned char id = 0x80;
snprintf(filename, 512, "VidRomDir.s");
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
fprintf(fd, "\t.include \"VidRomDir_%hux%hu.s\"\n", maxhres, maxvres);
fclose(fd);
}
{
char filename[512];
FILE *fd;
unsigned char id = 0x80;
snprintf(filename, 512, "VidRomDef.s");
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
fprintf(fd, "sRsrc_GoboFB_R%hux%hu = 0x%02hhx\n", hres, vres, id++);
}
}
fclose(fd);
}
{
char filename[512];
FILE *fd;
snprintf(filename, 512, "VidRomRsrcDir.s");
fd = fopen(filename, "w");
if (fd == NULL) {
fprintf(stderr, "Generating '%s' failed.\n", filename);
return -1;
}
fprintf(fd, "_sRsrcDir:\n");
fprintf(fd, "\tOSLstEntry\tsRsrc_Board,_sRsrc_Board\t/* board sRsrc List */\n");
for (i = 0 ; (res_db[i].hres != 0) && (res_db[i].vres != 0) ; i++) {
const unsigned short hres = res_db[i].hres;
const unsigned short vres = res_db[i].vres;
if (enabled[i]) {
fprintf(fd, "\tOSLstEntry\tsRsrc_GoboFB_R%hux%hu,_sRsrc_GoboFB_R%hux%hu/* video sRsrc List */\n", hres, vres, hres, vres);
}
}
//fprintf(fd, "\tOSLstEntry\tsRsrc_RAMDsk,_sRsrc_RAMDsk\n");
fprintf(fd, "\tOSLstEntry\tsRsrc_SDCard,_sRsrc_SDCard\n");
fprintf(fd, "\tOSLstEntry\tsRsrc_HDMIAudio,_sRsrc_HDMIAudio\n");
fprintf(fd, "\tDatLstEntry endOfList, 0\n");
fclose(fd);
}
return 0;
}

View File

@ -1,50 +0,0 @@
OUTPUT_FORMAT("elf32-m68k");
ENTRY(DeclROMDir);
SECTIONS {
.text : {
/* first the resource dir & related */
*(.text.begin)
*(.text .sdata .sdata.* .data .data.* .rodata .rodata.*)
/* then various sections for the various bits of codes */
PROVIDE(_sPInitRec = .);
PROVIDE(entry_sPInitRec = (0x22000000 | ((_sPInitRec - _sRsrc_Board - 12) & 0xFFFFFF))); /* fixme; offset 12 hardwired */
*(.text.primary_init)
*(.text.primary)
PROVIDE(_EndsPInitRec = .);
PROVIDE(size_sPInitRec = _EndsPInitRec - _sPInitRec);
PROVIDE(_sSInitRec = .);
PROVIDE(entry_sSInitRec = (0x24000000 | ((_sSInitRec - _sRsrc_Board - 20) & 0xFFFFFF))); /* fixme; offset 20 hardwired */
*(.text.secondary_init)
*(.text.secondary)
PROVIDE(_EndsSInitRec = .);
PROVIDE(size_sSInitRec = _EndsSInitRec - _sSInitRec);
PROVIDE(_GoboFBDrvrMacOS68020 = .);
PROVIDE(entry_GoboFBDrvrMacOS68020 = (0x02000000 | ((_GoboFBDrvrMacOS68020 - _GoboFBDrvrDir) & 0xFFFFFF)));
*(.text.fbdriver_init)
*(.text.fbdriver)
PROVIDE(_GoboFBEnd020Drvr = .);
PROVIDE(_RAMDskDrvrMacOS68020 = .);
PROVIDE(entry_RAMDskDrvrMacOS68020 = (0x02000000 | ((_RAMDskDrvrMacOS68020 - _RAMDskDrvrDir) & 0xFFFFFF)));
*(.text.dskdriver_init)
*(.text.dskdriver)
PROVIDE(_RAMDskEnd020Drvr = .);
PROVIDE(_SDCardDrvrMacOS68020 = .);
PROVIDE(entry_SDCardDrvrMacOS68020 = (0x02000000 | ((_SDCardDrvrMacOS68020 - _SDCardDrvrDir) & 0xFFFFFF)));
*(.text.sddriver_init)
*(.text.sddriver)
PROVIDE(_SDCardEnd020Drvr = .);
/* and at the end the ROM block, missing only the CRC */
. = ALIGN(4);
*(.romblock)
PROVIDE(ROMSize = .);
PROVIDE(RsrcDirOffset = ((0-.)+20) & 0xFFFFFF);
}
/DISCARD/ : { *(*) }
}

View File

@ -1,151 +0,0 @@
#include <stdint.h>
//#include <stdio.h>
#include "NuBusFPGARAMDskDrvr.h"
#ifndef SKIP_MAIN
uint32_t rleenc(uint32_t* out, const uint32_t* in, const uint32_t len) {
uint32_t i = 0, j = 0, p = 0, ib, k;
int32_t c = 0;
p = in[0];
for (i = 1 ; i < len ; i++) {
if (c == 0) { // just started
if (in[i] == p) { // repeat
c++;
} else { // non-repeat
p = in[i];
c--;
ib = i - 1;
}
} else if (c > 0) { // in-repeat
if (in[i] == p) { // keep repeating
c++;
} else { // exit repeat
out[j++] = __builtin_bswap32(c); // write result
out[j++] = p;
p = in[i]; // restart
c = 0;
}
} else { // c < 0
if (in[i] == p) { // exit non-repeat
out[j++] = __builtin_bswap32(c+1); // write result, removing previous
for (k = 0 ; k < (-c) ; k++)
out[j++] = in[ib+k];
p = in[i]; // restart
c = 1; // this and previous
} else { // non-repeat
p = in[i];
c--;
}
}
}
out[j++] = __builtin_bswap32(c);
out[j++] = p;
return j;
}
#endif
uint32_t rledec(uint32_t* out, const uint32_t* in, const uint32_t len) {
uint32_t i = 0, j = 0, k = 0, chk = 0, ib;
for (i = 0 ; i < len ; ) {
#ifndef __m68k__
int32_t c = (int32_t)__builtin_bswap32(in[i]);
#else
int32_t c = (int32_t)(in[i]);
#endif
if (c >= 0) {
chk += (1 + c);
if (c < 300000) { // !!!!!!!!!!!!!!!!!!!!!!!!!!
for (k = 0 ; k < (c + 1) ; k++)
out[j++] = in[i+1];
} else { // do a small subset at the beginning and end instead of the full range and assume this is padding otherwise
for (k = 0 ; k < 4 ; k++)
out[j+k] = in[i+1];
for (k = c-3 ; k < (c + 1) ; k++)
out[j+k] = in[i+1];
j += c+1;
}
i += 2;
} else {
chk += (1 + -c);
for (k = 0 ; k < (1 + -c) ; k++)
out[j++] = in[i+1+k];
i += 2 + -c;
}
//fprintf(stderr, "%u: %u <> %u (%d, 0x%08x)\n", i, j, chk, c, in[i+1]);
}
return j;
}
#ifndef SKIP_MAIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
int main(int argc, char** argv) {
int fd;
uint32_t len, k;
uint32_t *bufa, *bufb;
FILE* f;
bufa = calloc(sizeof(uint32_t), 256*1024*1024/sizeof(uint32_t));
bufb = calloc(sizeof(uint32_t), 256*1024*1024/sizeof(uint32_t));
fd = open("dump.raw", O_RDONLY);
len = read(fd, bufa, 248*1024*1024ull) / 4;
close(fd);
printf("File : %d bytes\n", len*4);
len = rleenc(bufb, bufa, len);
printf("Compressed : %d bytes\n", len*4);
/* for (k = 0 ; k < len ; k++) */
/* bufb[k] = __builtin_bswap32(bufb[k]); */
fd = open("dump.cpr", O_WRONLY | O_CREAT, S_IRWXU);
/* len = */write (fd, bufb, len*4);
close(fd);
/* for (k = 0 ; k < len ; k++) */
/* bufb[k] = __builtin_bswap32(bufb[k]); */
f = fopen("dump_cpr.c", "w");
/* fprintf(f, "unsigned char* compressed[%d] = {\n", len*4); */
/* for (k = 0 ; k < len*4 ; k++) { */
/* fprintf(f, "0x%02x%s", ((unsigned char*)bufb)[k], */
/* k == (len*4-1) ? "};" : (k%16 == 15 ? ",\n" : ",") */
/* ); */
/* } */
fprintf(f, "unsigned long* compressed[%d] = {\n", len);
for (k = 0 ; k < len ; k++) {
fprintf(f, "0x%08x%s", bufb[k],
k == (len-1) ? "};" : (k%8 == 7 ? ",\n" : ",")
);
}
fclose(f);
len = rledec(bufa, bufb, len);
printf("Uncompressed : %d bytes\n", len*4);
fd = open("dump.ucp", O_WRONLY | O_CREAT, S_IRWXU);
len = write (fd, bufa, len*4);
close(fd);
return 0;
}
#endif

@ -1 +0,0 @@
Subproject commit 618242763e1cda7da667e875c322f66c9b3afe96

View File

@ -1,214 +0,0 @@
#ifndef __NUBUSFPGA_CSR_COMMON_H__
#define __NUBUSFPGA_CSR_COMMON_H__
/* from hw/common.h, +a32 */
#define CONFIG_CSR_DATA_WIDTH 32
/* CSR data width (subreg. width) in bytes, for direct comparson to sizeof() */
#define CSR_DW_BYTES (CONFIG_CSR_DATA_WIDTH/8)
#define CSR_OFFSET_BYTES 4
/* Number of subregs required for various total byte sizes, by subreg width:
* NOTE: 1, 2, 4, and 8 bytes represent uint[8|16|32|64]_t C types; However,
* CSRs of intermediate byte sizes (24, 40, 48, and 56) are NOT padded
* (with extra unallocated subregisters) to the next valid C type!
* +-----+-----------------+
* | csr | bytes |
* | _dw | 1 2 3 4 5 6 7 8 |
* | |-----=---=-=-=---|
* | 1 | 1 2 3 4 5 6 7 8 |
* | 2 | 1 1 2 2 3 3 4 4 |
* | 4 | 1 1 1 1 2 2 2 2 |
* | 8 | 1 1 1 1 1 1 1 1 |
* +-----+-----------------+ */
static inline int num_subregs(int csr_bytes)
{
return (csr_bytes - 1) / CSR_DW_BYTES + 1;
}
/* Read a CSR of size 'csr_bytes' located at address 'a'. */
static inline uint64_t _csr_rd(uint32_t a32, unsigned long a, int csr_bytes)
{
uint64_t r = __builtin_bswap32(*((uint32_t*)(a32 + a)));
for (int i = 1; i < num_subregs(csr_bytes); i++) {
r <<= CONFIG_CSR_DATA_WIDTH;
a += CSR_OFFSET_BYTES;
r |= __builtin_bswap32(*((uint32_t*)(a32 + a)));
}
return r;
}
/* Write value 'v' to a CSR of size 'csr_bytes' located at address 'a'. */
static inline void _csr_wr(uint32_t a32, unsigned long a, uint64_t v, int csr_bytes)
{
int ns = num_subregs(csr_bytes);
for (int i = 0; i < ns; i++) {
*((uint32_t*)(a32 + a)) = __builtin_bswap32(v >> (CONFIG_CSR_DATA_WIDTH * (ns - 1 - i)));
a += CSR_OFFSET_BYTES;
}
}
// FIXME: - should we provide 24, 40, 48, and 56 bit csr_[rd|wr] methods?
static inline uint8_t csr_rd_uint8(uint32_t a32, unsigned long a)
{
return _csr_rd(a32, a, sizeof(uint8_t));
}
static inline void csr_wr_uint8(uint32_t a32, uint8_t v, unsigned long a)
{
_csr_wr(a32, a, v, sizeof(uint8_t));
}
static inline uint16_t csr_rd_uint16(uint32_t a32, unsigned long a)
{
return _csr_rd(a32, a, sizeof(uint16_t));
}
static inline void csr_wr_uint16(uint32_t a32, uint16_t v, unsigned long a)
{
_csr_wr(a32, a, v, sizeof(uint16_t));
}
static inline uint32_t csr_rd_uint32(uint32_t a32, unsigned long a)
{
return _csr_rd(a32, a, sizeof(uint32_t));
}
static inline void csr_wr_uint32(uint32_t a32, uint32_t v, unsigned long a)
{
_csr_wr(a32, a, v, sizeof(uint32_t));
}
static inline uint64_t csr_rd_uint64(uint32_t a32, unsigned long a)
{
return _csr_rd(a32, a, sizeof(uint64_t));
}
static inline void csr_wr_uint64(uint32_t a32, uint64_t v, unsigned long a)
{
_csr_wr(a32, a, v, sizeof(uint64_t));
}
/* Read a CSR located at address 'a' into an array 'buf' of 'cnt' elements.
*
* NOTE: Since CSR_DW_BYTES is a constant here, we might be tempted to further
* optimize things by leaving out one or the other of the if() branches below,
* depending on each unsigned type width;
* However, this code is also meant to serve as a reference for how CSRs are
* to be manipulated by other programs (e.g., an OS kernel), which may benefit
* from dynamically handling multiple possible CSR subregister data widths
* (e.g., by passing a value in through the Device Tree).
* Ultimately, if CSR_DW_BYTES is indeed a constant, the compiler should be
* able to determine on its own whether it can automatically optimize away one
* of the if() branches! */
#define _csr_rd_buf(a32, a, buf, cnt) \
{ \
int i, j, nsubs, n_sub_elem; \
uint64_t r; \
if (sizeof(buf[0]) >= CSR_DW_BYTES) { \
/* one or more subregisters per element */ \
for (i = 0; i < cnt; i++) { \
buf[i] = _csr_rd(a32, a, sizeof(buf[0])); \
a += CSR_OFFSET_BYTES * num_subregs(sizeof(buf[0])); \
} \
} else { \
/* multiple elements per subregister (2, 4, or 8) */ \
nsubs = num_subregs(sizeof(buf[0]) * cnt); \
n_sub_elem = CSR_DW_BYTES / sizeof(buf[0]); \
for (i = 0; i < nsubs; i++) { \
r = __builtin_bswap32(*(uint32_t*)(a32 + a)); \
for (j = n_sub_elem - 1; j >= 0; j--) { \
if (i * n_sub_elem + j < cnt) \
buf[i * n_sub_elem + j] = r; \
r >>= sizeof(buf[0]) * 8; \
} \
a += CSR_OFFSET_BYTES; \
} \
} \
}
/* Write an array 'buf' of 'cnt' elements to a CSR located at address 'a'.
*
* NOTE: The same optimization considerations apply here as with _csr_rd_buf()
* above.
*/
#define _csr_wr_buf(a32, a, buf, cnt) \
{ \
int i, j, nsubs, n_sub_elem; \
uint64_t v; \
if (sizeof(buf[0]) >= CSR_DW_BYTES) { \
/* one or more subregisters per element */ \
for (i = 0; i < cnt; i++) { \
_csr_wr(a32, a, buf[i], sizeof(buf[0])); \
a += CSR_OFFSET_BYTES * num_subregs(sizeof(buf[0])); \
} \
} else { \
/* multiple elements per subregister (2, 4, or 8) */ \
nsubs = num_subregs(sizeof(buf[0]) * cnt); \
n_sub_elem = CSR_DW_BYTES / sizeof(buf[0]); \
for (i = 0; i < nsubs; i++) { \
v = buf[i * n_sub_elem + 0]; \
for (j = 1; j < n_sub_elem; j++) { \
if (i * n_sub_elem + j == cnt) \
break; \
v <<= sizeof(buf[0]) * 8; \
v |= buf[i * n_sub_elem + j]; \
} \
*((uint32_t*)(a32 + a)) = __builtin_bswap32(v); \
a += CSR_OFFSET_BYTES; \
} \
} \
}
static inline void csr_rd_buf_uint8(uint32_t a32, unsigned long a, uint8_t *buf, int cnt)
{
_csr_rd_buf(a32, a, buf, cnt);
}
static inline void csr_wr_buf_uint8(uint32_t a32, unsigned long a,
const uint8_t *buf, int cnt)
{
_csr_wr_buf(a32, a, buf, cnt);
}
static inline void csr_rd_buf_uint16(uint32_t a32, unsigned long a, uint16_t *buf, int cnt)
{
_csr_rd_buf(a32, a, buf, cnt);
}
static inline void csr_wr_buf_uint16(uint32_t a32, unsigned long a,
const uint16_t *buf, int cnt)
{
_csr_wr_buf(a32, a, buf, cnt);
}
static inline void csr_rd_buf_uint32(uint32_t a32, unsigned long a, uint32_t *buf, int cnt)
{
_csr_rd_buf(a32, a, buf, cnt);
}
static inline void csr_wr_buf_uint32(uint32_t a32, unsigned long a,
const uint32_t *buf, int cnt)
{
_csr_wr_buf(a32, a, buf, cnt);
}
/* NOTE: the macros' "else" branch is unreachable, no need to be warned
* about a >= 64bit left shift! */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
static inline void csr_rd_buf_uint64(uint32_t a32, unsigned long a, uint64_t *buf, int cnt)
{
_csr_rd_buf(a32, a, buf, cnt);
}
static inline void csr_wr_buf_uint64(uint32_t a32, unsigned long a,
const uint64_t *buf, int cnt)
{
_csr_wr_buf(a32, a, buf, cnt);
}
#pragma GCC diagnostic pop
#endif // __NUBUSFPGA_CSR_COMMON_H__

View File

@ -1,228 +0,0 @@
.include "atrap.inc"
.include "globals.inc"
.include "declrom.inc"
.include "ROMDefs.inc"
.include "Video.inc"
.include "DepVideo.inc"
sRsrc_Board = 1 /* board sResource (>0 & <128) */
.include "VidRomDef.s"
sRsrc_RAMDsk = 0x90 /* functional sResources */
sRsrc_SDCard = 0x91 /* functional sResources */
sRsrc_HDMIAudio = 0xA0 /* functional sResources */
.global DeclROMDir
.section .text.begin
.include "VidRomRsrcDir.s"
.global _sRsrc_Board
_sRsrc_Board:
OSLstEntry sRsrcType,_BoardType /* offset to board descriptor */
OSLstEntry sRsrcName,_BoardName /* offset to name of board */
DatLstEntry boardId,NuBusFPGAID /* board ID # (assigned by DTS) */
/* OSLstEntry primaryInit,_sPInitRec */ /* offset to PrimaryInit exec blk */
.long entry_sPInitRec
OSLstEntry vendorInfo,_VendorInfo /* offset to vendor info record */
/* OSLstEntry secondaryInit,_sSInitRec */ /* offset to SecondaryInit block */
.long entry_sSInitRec
OSLstEntry sRsrcVidNames, _VModeName /* video name directory */
.long EndOfList
_BoardType:
.short catBoard /* board sResource */
.short typeBoard
.short 0
.short 0
_BoardName:
.string "NuBusFPGA GoboFB\0" /* name of board */
ALIGN 2
/* _VidICON ; optional icon, not needed */
/* _sVidNameDir ; optional name(s), not needed */
.section .text.primary_init
/* _sPInitRec: */
/* .long _EndsPInitRec-_sPInitRec */ /* physical block size */
.long size_sPInitRec
.byte sExec2 /* Code revision (Primary init) */
.byte sCPU68020 /* CPU type is 68020 */
.short 0 /* Reserved */
.long Primary-. /* Offset to C code. */
ALIGN 2
/* _EndsPInitRec: */
.section .text.secondary_init
/* _sSInitRec: */
/* .long _EndsSInitRec-_sSInitRec */ /* physical block size */
.long size_sSInitRec
.byte sExec2 /* Code revision (Primary init) */
.byte sCPU68020 /* CPU type is 68020 */
.short 0 /* Reserved */
.long Secondary-. /* Offset to C code. */
ALIGN 2
/* _EndsSInitRec: */
.section .text.begin
ALIGN 2
_VendorInfo:
OSLstEntry vendorId,_VendorId /* offset to vendor ID */
OSLstEntry serialNum,_SerialNum /* offset to revision */
OSLstEntry revLevel,_RevLevel /* offset to revision */
OSLstEntry partNum,_PartNum /* offset to part number record */
OSLstEntry date,_Date /* offset to ROM build date */
.long EndOfList
_VendorId:
.string "Romain Dolbeau\0" /* vendor ID */
_SerialNum:
.string "0000000001\0" /* serial number */
_RevLevel:
.string "NuBusFPGA V1.0\0" /* revision level */
_PartNum:
.string "Part Number\0" /* part number */
_Date:
.string "&SysDate" /* date */
.include "VidRomName.s" /* contains _VidName */
.include "VidRomDir.s"
ALIGN 2
_GoboFBType:
.short catDisplay /* <Category> */
.short typeVideo /* <Type> */
.short drSwApple /* <DrvrSw> */
.short DrHwNuBusFPGA /* <DrvrHw> */
_GoboFBName:
.string "GoboFB_NuBusFPGA" /* video driver name */
_MinorBase:
.long defMinorBase /* frame buffer offset */
_MinorLength:
.long defMinorLength /* frame buffer length */
ALIGN 2
.section .text.begin
.global _GoboFBDrvrDir
_GoboFBDrvrDir:
/* OSLstEntry sMacOS68020,_GoboFBDrvrMacOS68020 */ /* driver directory for Mac OS */
.long entry_GoboFBDrvrMacOS68020
.long EndOfList
ALIGN 2
.section .text.fbdriver_init
/* _GoboFBDrvrMacOS68020: */ /* supplied by linker script */
.long _GoboFBEnd020Drvr-. /* physical block size */
.include "NuBusFPGADrvr.s" /* driver code */
/* _GoboFBEnd020Drvr: */ /* supplied by linker script */
.section .text.begin
.include "VidRomRes.s"
/* ////////////////////////////////////////////// RAM DISK */
.section .text.begin
ALIGN 2
_sRsrc_RAMDsk:
OSLstEntry sRsrcType,_RAMDskType /* video type descriptor */
OSLstEntry sRsrcName,_RAMDskName /* offset to driver name string */
OSLstEntry sRsrcDrvrDir,_RAMDskDrvrDir /* offset to driver directory */
DatLstEntry sRsrcFlags,6 /* force 32 bits mode & open */
DatLstEntry sRsrcHWDevId,2 /* hardware device ID */
.long EndOfList /* end of list */
ALIGN 2
_RAMDskType:
.short catProto /* <Category> */
.short typeDrive /* custom */ /* <Type> */
.short drSwApple /* <DrvrSw> */
.short DrHwNuBusFPGADsk /* <DrvrHw> */
_RAMDskName:
.string "RAMDsk_NuBusFPGA" /* video driver name */
ALIGN 2
.section .text.begin
.global _RAMDskDrvrDir
_RAMDskDrvrDir:
/* OSLstEntry sMacOS68020,_RAMDskDrvrMacOS68020 */ /* driver directory for Mac OS */
.long entry_RAMDskDrvrMacOS68020
.long EndOfList
ALIGN 2
.section .text.dskdriver_init
/* _RAMDskDrvrMacOS68020: */ /* supplied by linker script */
.long _RAMDskEnd020Drvr-. /* physical block size */
.include "NuBusFPGARAMDskDrvr.s" /* driver code */
/* _RAMDskEnd020Drvr: */ /* supplied by linker script */
/* ////////////////////////////////////////////// SDCARD */
.section .text.begin
ALIGN 2
_sRsrc_SDCard:
OSLstEntry sRsrcType,_SDCardType /* video type descriptor */
OSLstEntry sRsrcName,_SDCardName /* offset to driver name string */
OSLstEntry sRsrcDrvrDir,_SDCardDrvrDir /* offset to driver directory */
DatLstEntry sRsrcFlags,6 /* force 32 bits mode & open */
DatLstEntry sRsrcHWDevId,2 /* hardware device ID */
.long EndOfList /* end of list */
ALIGN 2
_SDCardType:
.short catProto /* <Category> */
.short typeDrive /* custom */ /* <Type> */
.short drSwApple /* <DrvrSw> */
.short DrHwNuBusFPGASDCard /* <DrvrHw> */
_SDCardName:
.string "SDCard_NuBusFPGA" /* video driver name */
ALIGN 2
.section .text.begin
.global _SDCardDrvrDir
_SDCardDrvrDir:
/* OSLstEntry sMacOS68020,_SDCardDrvrMacOS68020 */ /* driver directory for Mac OS */
.long entry_SDCardDrvrMacOS68020
.long EndOfList
ALIGN 2
.section .text.sddriver_init
/* _SDCardDrvrMacOS68020: */ /* supplied by linker script */
.long _SDCardEnd020Drvr-. /* physical block size */
.include "NuBusFPGASDCardDrvr.s" /* driver code */
/* _SDCardEnd020Drvr: */ /* supplied by linker script */
/* ////////////////////////////////////////////// HDMI AUDIO */
.section .text.begin
ALIGN 2
_sRsrc_HDMIAudio:
OSLstEntry sRsrcType,_HDMIAudioType /* video type descriptor */
.long EndOfList /* end of list */
ALIGN 2
_HDMIAudioType:
.short catProto /* <Category> */
.short typeAudio /* custom */ /* <Type> */
.short drSwApple /* <DrvrSw> */
.short DrHwNuBusFPGAAudio /* <DrvrHw> */
/* Declaration ROM directory at end */
.section .romblock
ALIGN 2
DeclROMDir:
.long RsrcDirOffset /* supplied by linker script, replace OSLstEntry 0, _sRsrcDir */
DeclROMCRC:
.long ROMSize /* supplied by linker script */
.long 0 /* crc TBComputed after the fact */
.byte 1 /* Revision Level */
.byte appleFormat /* Apple Format */
.long testPattern /* magic TestPattern */
.byte 0 /* reserved */
.byte 0x0F /* byte lane marker */
DeclRomEnd:
.end

@ -1 +1 @@
Subproject commit 9e350c5962f1dc8f43091a3f44a7c1f8071d2bff
Subproject commit bd8d1da000db1c705581670c5307219e46f3f3fc

View File

@ -2,7 +2,7 @@
source /opt/Xilinx/Vivado/2020.1/settings64.sh
export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2020.1/lib/lnx64.o/SuSE
python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.2 --sys-clk-freq 100e6 --goblin --goblin-res 1920x1080@60Hz --hdmi --sdcard --flash # --ethernet
python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.2 --sys-clk-freq 100e6 --goblin --goblin-res 1920x1080@60Hz --hdmi --sdcard --config-flash # --ethernet # --flash
#python3 nubus_to_fpga_soc.py --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.2 --sys-clk-freq 100e6
@ -12,6 +12,8 @@ python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --var
grep -A10 'Design Timing Summary' build/ztex213_nubus_V1_2/gateware/ztex213_nubus_V1_2_timing.rpt
grep '^\$\$' build_V1_2.log
###
# For 16 MiB Flash NOR (W25Q128.V):

@ -1 +1 @@
Subproject commit 01c18e4cbba4aeb5cebecc71cd9bb14ae7bf49b3
Subproject commit 3200da4fc98af3504e63e89d2af8b3fa5d98d03d

View File

@ -201,7 +201,7 @@ class NuBusFPGA(SoCCore): # Add SDCard --------------------------------------
self.sdphy = SDPHY(sdcard_pads, self.platform.device, self.clk_freq, cmd_timeout=10e-1, data_timeout=10e-1)
self.sdcore = SDCore(self.sdphy)
def __init__(self, variant, version, sys_clk_freq, goblin, hdmi, goblin_res, sdcard, flash, ethernet, **kwargs):
def __init__(self, variant, version, sys_clk_freq, goblin, hdmi, goblin_res, sdcard, flash, config_flash, ethernet, **kwargs):
print(f"Building NuBusFPGA for board version {version}")
kwargs["cpu_type"] = "None"
@ -275,9 +275,11 @@ class NuBusFPGA(SoCCore): # Add SDCard --------------------------------------
"csr" : 0xF0A00000, # CSR
"pingmaster": 0xF0B00000,
"ethmac": 0xF0C00000,
#"spiflash": 0xF0D00000, # testing
#"spiflash": 0xF0D00000, # testing
#"config_spiflash": 0xF0D00000, # testing
"rom": 0xF0FF8000, # ROM at the end (32 KiB of it ATM)
"spiflash": 0xF0FF8000, # FIXME currently the flash is in the ROM spot, limited to 32 KiB
"config_spiflash": 0xF0FF8000, # FIXME currently the flash is in the ROM spot, limited to 32 KiB
#"END OF SLOT SPACE": 0xF0FFFFFF,
}
self.mem_map.update(wb_mem_map)
@ -300,7 +302,7 @@ class NuBusFPGA(SoCCore): # Add SDCard --------------------------------------
#print(fix_line)
platform.add_platform_command(fix_line)
if (not flash):
if ((not flash) and (not config_flash)): # so ROM is builtin
rom_file = "rom_{}.bin".format(version.replace(".", "_"))
rom_data = soc_core.get_mem_data(filename_or_regions=rom_file, endianness="little") # "big"
# rom = Array(rom_data)
@ -309,6 +311,7 @@ class NuBusFPGA(SoCCore): # Add SDCard --------------------------------------
# print(hex(rom[i]))
#print("\n****************************************\n")
self.add_ram("rom", origin=self.mem_map["rom"], size=2**15, contents=rom_data, mode="r") ## 32 KiB, must match mmap
print("$$$$$ ROM must be pre-existing for integration in the bitstream, double-check the ROM file is current for this configuration $$$$$\n");
if (flash):
from litespi.modules.generated_modules import W25Q128JV
@ -318,8 +321,22 @@ class NuBusFPGA(SoCCore): # Add SDCard --------------------------------------
module=W25Q128JV(Codes.READ_1_1_4),
region_size = 0x00008000, # 32 KiB
with_mmap=True, with_master=False)
print("$$$$$ ROM must be put in the external Flash NOR $$$$$\n");
if (config_flash):
sector = 40
from litespi.modules.generated_modules import S25FL128S
from litespi.opcodes import SpiNorFlashOpCodes as Codes
self.add_spi_flash(name="config_spiflash",
mode="1x",
clk_freq = sys_clk_freq/4, # Fixme; PHY freq ?
module=S25FL128S(Codes.READ_1_1_1),
region_size = 0x00008000, # 32 KiB,
region_offset = (sector * 65536),
with_mmap=True, with_master=False)
print(f"$$$$$ ROM must be put in the config Flash at sector {sector} $$$$$\n");
#from wb_test import WA2D
#self.submodules.wa2d = WA2D(self.platform)
#self.bus.add_slave("WA2D", self.wa2d.bus, SoCRegion(origin=0x00C00000, size=0x00400000, cached=False))
@ -576,7 +593,8 @@ def main():
parser.add_argument("--hdmi", action="store_true", help="The framebuffer uses HDMI (default to VGA, required for V1.2)")
parser.add_argument("--goblin-res", default="640x480@60Hz", help="Specify the goblin resolution")
parser.add_argument("--sdcard", action="store_true", help="add a sdcard controller (V1.2 only)")
parser.add_argument("--flash", action="store_true", help="add a Flash device [V1.2+FLASHTEMP PMod]")
parser.add_argument("--flash", action="store_true", help="add a Flash device [V1.2+FLASHTEMP PMod] and configure the ROM to it")
parser.add_argument("--config-flash", action="store_true", help="Configure the ROM to the internal Flash used for FPGA config")
parser.add_argument("--ethernet", action="store_true", help="Add Ethernet (V1.2 w/ custom PMod only)")
builder_args(parser)
vivado_build_args(parser)
@ -601,6 +619,10 @@ def main():
if ((not args.hdmi) and (args.version == "V1.2")):
print(" ***** ERROR ***** : VGA not supported on V1.2\n");
assert(False)
if (args.config_flash and args.flash):
print(" ***** ERROR ***** : ROM-in-Flash can only use config OR PMod, not both\n");
assert(False)
soc = NuBusFPGA(**soc_core_argdict(args),
variant=args.variant,
@ -611,6 +633,7 @@ def main():
goblin_res=args.goblin_res,
sdcard=args.sdcard,
flash=args.flash,
config_flash=args.config_flash,
ethernet=args.ethernet)
version_for_filename = args.version.replace(".", "_")

View File

@ -52,6 +52,13 @@ _io = [
Subsignal("reset_n", Pins("J5"), IOStandard("SSTL135")),
Misc("SLEW=FAST"),
),
("config_spiflash", 0,
Subsignal("cs_n", Pins("L13")),
# Subsignal("clk", Pins("E9")), # 'E9' isn't a user pin, access clock via STARTUPE2 primitive, disabling the pads should do it in LiteSPIClkGen ?
Subsignal("mosi", Pins("K17")),
Subsignal("miso", Pins("K18")),
IOStandard("LVCMOS33"),
),
]
# NuBusFPGA I/O
@ -258,6 +265,8 @@ class Platform(XilinxPlatform):
def __init__(self, variant="ztex2.13a", version="V1.0"):
device = {
"ztex2.12a": "xc7a15tcsg324-1", #untested, too small?
"ztex2.12b": "xc7a35tcsg324-1", #untested
"ztex2.13a": "xc7a35tcsg324-1",
"ztex2.13b": "xc7a50tcsg324-1", #untested
"ztex2.13b2": "xc7a50tcsg324-1", #untested