mirror of
https://github.com/rdolbeau/VintageBusFPGA_Common.git
synced 2026-04-13 23:33:43 +00:00
move DeclRom from NuBusFPGA to common
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "DeclROM/ns816-declrom"]
|
||||
path = DeclROM/ns816-declrom
|
||||
url = https://github.com/jaoswald/ns816-declrom
|
||||
11
DeclROM/.gitignore
vendored
Normal file
11
DeclROM/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
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
|
||||
56
DeclROM/DepVideo.inc
Normal file
56
DeclROM/DepVideo.inc
Normal file
@@ -0,0 +1,56 @@
|
||||
.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 */
|
||||
89
DeclROM/Makefile
Normal file
89
DeclROM/Makefile
Normal file
@@ -0,0 +1,89 @@
|
||||
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
|
||||
FEATURES=
|
||||
|
||||
TARGET=NUBUSFPGA
|
||||
|
||||
ifeq (${TARGET},NUBUSFPGA)
|
||||
FEATURES+=-DNUBUSFPGA -DENABLE_RAMDSK -DENABLE_SDCARD -DENABLE_HDMIAUDIO
|
||||
endif
|
||||
ifeq (${TARGET},IISIFPGA)
|
||||
FEATURES+=--DIISIFPGA DENABLE_HDMIAUDIO
|
||||
endif
|
||||
ifeq (${TARGET},QUADRAFPGA)
|
||||
FEATURES+=-DQUADRAFPGA -DENABLE_HDMIAUDIO
|
||||
endif
|
||||
|
||||
CFLAGS+=${FEATURES}
|
||||
|
||||
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 $@
|
||||
157
DeclROM/NuBusFPGADrvr.h
Normal file
157
DeclROM/NuBusFPGADrvr.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#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
|
||||
|
||||
23
DeclROM/NuBusFPGADrvr.s
Normal file
23
DeclROM/NuBusFPGADrvr.s
Normal file
@@ -0,0 +1,23 @@
|
||||
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
|
||||
513
DeclROM/NuBusFPGADrvr_Ctrl.c
Normal file
513
DeclROM/NuBusFPGADrvr_Ctrl.c
Normal file
@@ -0,0 +1,513 @@
|
||||
#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 <20>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 <20>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 <20>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;
|
||||
}
|
||||
208
DeclROM/NuBusFPGADrvr_OpenClose.c
Normal file
208
DeclROM/NuBusFPGADrvr_OpenClose.c
Normal file
@@ -0,0 +1,208 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
406
DeclROM/NuBusFPGADrvr_Status.c
Normal file
406
DeclROM/NuBusFPGADrvr_Status.c
Normal file
@@ -0,0 +1,406 @@
|
||||
#include "NuBusFPGADrvr.h"
|
||||
|
||||
/*
|
||||
7.1:
|
||||
2 Debug: 0x00000009
|
||||
1 <20>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 <20>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 <20>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;
|
||||
}
|
||||
157
DeclROM/NuBusFPGAPrimaryInit_Primary.c
Normal file
157
DeclROM/NuBusFPGAPrimaryInit_Primary.c
Normal file
@@ -0,0 +1,157 @@
|
||||
#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 */
|
||||
|
||||
660
DeclROM/NuBusFPGAPrimaryInit_RamInit.c
Normal file
660
DeclROM/NuBusFPGAPrimaryInit_RamInit.c
Normal file
@@ -0,0 +1,660 @@
|
||||
#include "NuBusFPGADrvr.h"
|
||||
|
||||
#define CONFIG_CSR_DATA_WIDTH 32
|
||||
|
||||
#if defined(NUBUSFPGA)
|
||||
#include "../nubusfpga_csr_ddrphy.h"
|
||||
#include "../nubusfpga_csr_sdram.h"
|
||||
#elif defined(IISIFPGA)
|
||||
#include "../IIsifpga_csr_ddrphy.h"
|
||||
#include "../IIsifpga_csr_sdram.h"
|
||||
#elif defined(QUADRAFPGA)
|
||||
#include "../quadrafpga_csr_ddrphy.h"
|
||||
#include "../quadrafpga_csr_sdram.h"
|
||||
#else
|
||||
#error "no board defined"
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
}
|
||||
74
DeclROM/NuBusFPGARAMDskDrvr.h
Normal file
74
DeclROM/NuBusFPGARAMDskDrvr.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef __NUBUSFPGARAMDSKDRVR_H__
|
||||
#define __NUBUSFPGARAMDSKDRVR_H__
|
||||
|
||||
#include <Files.h>
|
||||
#include <Devices.h>
|
||||
#include <Slots.h>
|
||||
#include <MacErrors.h>
|
||||
#include <MacMemory.h>
|
||||
#include <Disks.h>
|
||||
|
||||
// noy yest supported on PDS variants
|
||||
#if defined(NUBUSFPGA)
|
||||
// #define ENABLE_DMA 1
|
||||
#endif
|
||||
|
||||
#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
|
||||
23
DeclROM/NuBusFPGARAMDskDrvr.s
Normal file
23
DeclROM/NuBusFPGARAMDskDrvr.s
Normal file
@@ -0,0 +1,23 @@
|
||||
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
|
||||
59
DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c
Normal file
59
DeclROM/NuBusFPGARAMDskDrvr_Ctrl.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#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;
|
||||
}
|
||||
185
DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c
Normal file
185
DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c
Normal file
@@ -0,0 +1,185 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
350
DeclROM/NuBusFPGARAMDskDrvr_Prime.c
Normal file
350
DeclROM/NuBusFPGARAMDskDrvr_Prime.c
Normal file
@@ -0,0 +1,350 @@
|
||||
#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;
|
||||
}
|
||||
30
DeclROM/NuBusFPGARAMDskDrvr_Status.c
Normal file
30
DeclROM/NuBusFPGARAMDskDrvr_Status.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#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;
|
||||
}
|
||||
137
DeclROM/NuBusFPGASDCardDrvr.h
Normal file
137
DeclROM/NuBusFPGASDCardDrvr.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#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"
|
||||
|
||||
#if defined(NUBUSFPGA)
|
||||
#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"
|
||||
#elif defined(IISIFPGA)
|
||||
#include "../IIsifpga_csr_sdblock2mem.h"
|
||||
#include "../IIsifpga_csr_sdcore.h"
|
||||
//#include "../IIsifpga_csr_sdirq.h"
|
||||
#include "../IIsifpga_csr_sdmem2block.h"
|
||||
#include "../IIsifpga_csr_sdphy.h"
|
||||
#include "../IIsifpga_csr_exchange_with_sd.h"
|
||||
#elif defined(QUADRAFPGA)
|
||||
#include "../quadrafpga_csr_sdblock2mem.h"
|
||||
#include "../quadrafpga_csr_sdcore.h"
|
||||
//#include "../quadrafpga_csr_sdirq.h"
|
||||
#include "../quadrafpga_csr_sdmem2block.h"
|
||||
#include "../quadrafpga_csr_sdphy.h"
|
||||
#include "../quadrafpga_csr_exchange_with_sd.h"
|
||||
#else
|
||||
#error "no board defined"
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
23
DeclROM/NuBusFPGASDCardDrvr.s
Normal file
23
DeclROM/NuBusFPGASDCardDrvr.s
Normal file
@@ -0,0 +1,23 @@
|
||||
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
|
||||
59
DeclROM/NuBusFPGASDCardDrvr_Ctrl.c
Normal file
59
DeclROM/NuBusFPGASDCardDrvr_Ctrl.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#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;
|
||||
}
|
||||
878
DeclROM/NuBusFPGASDCardDrvr_OpenClose.c
Normal file
878
DeclROM/NuBusFPGASDCardDrvr_OpenClose.c
Normal file
@@ -0,0 +1,878 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
#if 0
|
||||
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
|
||||
#endif
|
||||
|
||||
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 1
|
||||
__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 // VIRTUAL NEEDS TO GO THROUGH MemoryManager
|
||||
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
|
||||
|
||||
if (nblocks > 1)
|
||||
sdcard_stop_transmission(sc);
|
||||
|
||||
/* Update Block/Buffer/Count */
|
||||
block += nblocks;
|
||||
buf += 512*nblocks;
|
||||
count -= nblocks;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
111
DeclROM/NuBusFPGASDCardDrvr_Prime.c
Normal file
111
DeclROM/NuBusFPGASDCardDrvr_Prime.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
30
DeclROM/NuBusFPGASDCardDrvr_Status.c
Normal file
30
DeclROM/NuBusFPGASDCardDrvr_Status.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#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;
|
||||
}
|
||||
93
DeclROM/NuBusFPGASecondaryInit_Secondary.c
Normal file
93
DeclROM/NuBusFPGASecondaryInit_Secondary.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
197
DeclROM/ROMDefs.inc
Normal file
197
DeclROM/ROMDefs.inc
Normal file
@@ -0,0 +1,197 @@
|
||||
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
|
||||
|
||||
358
DeclROM/Video.inc
Normal file
358
DeclROM/Video.inc
Normal file
@@ -0,0 +1,358 @@
|
||||
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*/
|
||||
|
||||
BIN
DeclROM/dump.cpr
Executable file
BIN
DeclROM/dump.cpr
Executable file
Binary file not shown.
288
DeclROM/gen_mode.c
Normal file
288
DeclROM/gen_mode.c
Normal file
@@ -0,0 +1,288 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_RAMDSK
|
||||
fprintf(fd, "\tOSLstEntry\tsRsrc_RAMDsk,_sRsrc_RAMDsk\n");
|
||||
#endif
|
||||
#ifdef ENABLE_SDCARD
|
||||
fprintf(fd, "\tOSLstEntry\tsRsrc_SDCard,_sRsrc_SDCard\n");
|
||||
#endif
|
||||
#ifdef ENABLE_HDMIAUDIO
|
||||
fprintf(fd, "\tOSLstEntry\tsRsrc_HDMIAudio,_sRsrc_HDMIAudio\n");
|
||||
#endif
|
||||
fprintf(fd, "\tDatLstEntry endOfList, 0\n");
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
50
DeclROM/linker.ld
Normal file
50
DeclROM/linker.ld
Normal file
@@ -0,0 +1,50 @@
|
||||
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/ : { *(*) }
|
||||
}
|
||||
151
DeclROM/myrle.c
Normal file
151
DeclROM/myrle.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#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
DeclROM/ns816-declrom
Submodule
1
DeclROM/ns816-declrom
Submodule
Submodule DeclROM/ns816-declrom added at 618242763e
214
DeclROM/nubusfpga_csr_common.h
Normal file
214
DeclROM/nubusfpga_csr_common.h
Normal file
@@ -0,0 +1,214 @@
|
||||
#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__
|
||||
228
DeclROM/vid_decl_rom.s
Normal file
228
DeclROM/vid_decl_rom.s
Normal file
@@ -0,0 +1,228 @@
|
||||
.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
|
||||
Reference in New Issue
Block a user