idk
This commit is contained in:
parent
51d01f815f
commit
ef6286d674
|
@ -1,3 +1,4 @@
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
obj/
|
obj/
|
||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/settings.json
|
||||||
|
|
54
Makefile
54
Makefile
|
@ -5,12 +5,12 @@ LD=$(PREFIX)-ld
|
||||||
OBJCOPY=$(PREFIX)-objcopy
|
OBJCOPY=$(PREFIX)-objcopy
|
||||||
OBJDUMP=$(PREFIX)-objdump
|
OBJDUMP=$(PREFIX)-objdump
|
||||||
|
|
||||||
all: bin/ROMBUS.bin obj/rombus.s obj/driver.s obj/driver_abs.sym
|
all: bin/ROMBUS_8M.bin obj/rombus.s obj/driver.s obj/driver_abs.sym
|
||||||
|
|
||||||
obj:
|
obj:
|
||||||
mkdir $@
|
mkdir -p $@
|
||||||
bin:
|
bin:
|
||||||
mkdir $@
|
mkdir -p $@
|
||||||
|
|
||||||
|
|
||||||
obj/entry.o: entry.s obj
|
obj/entry.o: entry.s obj
|
||||||
|
@ -20,14 +20,38 @@ obj/entry_rel.sym: obj obj/entry.o
|
||||||
$(OBJDUMP) -t obj/entry.o > $@
|
$(OBJDUMP) -t obj/entry.o > $@
|
||||||
|
|
||||||
|
|
||||||
|
obj/spi.o: spi.c obj
|
||||||
|
$(CC) -Wall -march=68020 -c -Os $< -o $@
|
||||||
|
obj/spi_hal.o: spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_rx8.o: spi_rx8.s spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_rx16.o: spi_rx16.s spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_tx8.o: spi_tx8.s spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_tx16.o: spi_tx16.s spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_rxtx8.o: spi_rxtx8.s spi_hal.s spi_hal_common.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
obj/spi_delay.o: spi_delay.s obj
|
||||||
|
$(AS) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
obj/rombus.o: rombus.c obj
|
obj/rombus.o: rombus.c obj
|
||||||
$(CC) -Wall -march=68030 -c -Os $< -o $@
|
$(CC) -Wall -march=68020 -c -Os $< -o $@
|
||||||
|
|
||||||
obj/rombus.s: obj obj/rombus.o
|
obj/rombus.s: obj obj/rombus.o
|
||||||
$(OBJDUMP) -d obj/rombus.o > $@
|
$(OBJDUMP) -d obj/rombus.o > $@
|
||||||
|
|
||||||
obj/driver.o: obj obj/entry.o obj/rombus.o
|
obj/driver.o: obj obj/entry.o obj/rombus.o obj/spi.o obj/spi_hal.o \
|
||||||
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rombus.o
|
obj/spi_rx8.o obj/spi_rx16.o \
|
||||||
|
obj/spi_tx8.o obj/spi_tx16.o \
|
||||||
|
obj/spi_rxtx8.o
|
||||||
|
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rombus.o obj/spi.o obj/spi_hal.o \
|
||||||
|
obj/spi_rx8.o obj/spi_rx16.o \
|
||||||
|
obj/spi_tx8.o obj/spi_tx16.o \
|
||||||
|
obj/spi_rxtx8.o
|
||||||
|
|
||||||
obj/driver.s: obj obj/driver.o
|
obj/driver.s: obj obj/driver.o
|
||||||
$(OBJDUMP) -d obj/driver.o > $@
|
$(OBJDUMP) -d obj/driver.o > $@
|
||||||
|
@ -35,11 +59,11 @@ obj/driver.s: obj obj/driver.o
|
||||||
obj/driver_abs.sym: obj obj/driver.o
|
obj/driver_abs.sym: obj obj/driver.o
|
||||||
$(OBJDUMP) -t obj/driver.o > $@
|
$(OBJDUMP) -t obj/driver.o > $@
|
||||||
|
|
||||||
|
|
||||||
bin/driver.bin: bin obj/driver.o
|
bin/driver.bin: bin obj/driver.o
|
||||||
$(OBJCOPY) -O binary obj/driver.o $@
|
$(OBJCOPY) -O binary obj/driver.o $@
|
||||||
|
|
||||||
bin/baserom_romdisk_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_abs.sym obj/entry_rel.sym
|
|
||||||
|
bin/baserom_rombus_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_abs.sym obj/entry_rel.sym
|
||||||
cp roms/baserom.bin $@ # Copy base rom
|
cp roms/baserom.bin $@ # Copy base rom
|
||||||
# Patch driver
|
# Patch driver
|
||||||
dd if=bin/driver.bin of=$@ bs=1 seek=335248 skip=32 conv=notrunc # Copy driver code
|
dd if=bin/driver.bin of=$@ bs=1 seek=335248 skip=32 conv=notrunc # Copy driver code
|
||||||
|
@ -51,23 +75,19 @@ bin/baserom_romdisk_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_
|
||||||
cat obj/entry_rel.sym | grep "[0-9]\s*DStatus" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335230 count=2 conv=notrunc
|
cat obj/entry_rel.sym | grep "[0-9]\s*DStatus" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335230 count=2 conv=notrunc
|
||||||
cat obj/entry_rel.sym | grep "[0-9]\s*DClose" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335232 count=2 conv=notrunc
|
cat obj/entry_rel.sym | grep "[0-9]\s*DClose" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335232 count=2 conv=notrunc
|
||||||
|
|
||||||
bin/baserom_romdisk_noramtest.bin: bin bin/baserom_romdisk_ramtest.bin
|
bin/baserom_rombus_noramtest.bin: bin bin/baserom_rombus_ramtest.bin
|
||||||
cp bin/baserom_romdisk_ramtest.bin $@ # Copy base rom
|
cp bin/baserom_rombus_ramtest.bin $@ # Copy base rom
|
||||||
# Disable RAM test
|
# Disable RAM test
|
||||||
printf '\x4E\xD6' | dd of=$@ bs=1 seek=288736 count=2 conv=notrunc
|
printf '\x4E\xD6' | dd of=$@ bs=1 seek=288736 count=2 conv=notrunc
|
||||||
printf '\x4E\xD6' | dd of=$@ bs=1 seek=289016 count=2 conv=notrunc
|
printf '\x4E\xD6' | dd of=$@ bs=1 seek=289016 count=2 conv=notrunc
|
||||||
|
|
||||||
|
|
||||||
bin/ROMBUS.bin: bin bin/baserom_romdisk_noramtest.bin disks/RDisk7M5.dsk
|
bin/ROMBUS_8M.bin: bin bin/baserom_rombus_noramtest.bin disks/RDisk.dsk
|
||||||
# Copy base rom with ROM disk driver
|
# Copy base rom with ROM disk driver
|
||||||
cp bin/baserom_romdisk_noramtest.bin $@
|
cp bin/baserom_rombus_noramtest.bin $@
|
||||||
# Patch ROM disk driver parameter table
|
|
||||||
printf '\x00\x01\x2A\x29' | dd of=$@ bs=1 seek=335260 count=4 conv=notrunc # Patch CDR patch offset
|
|
||||||
printf '\x40\x89\x2A\x14' | dd of=$@ bs=1 seek=335268 count=4 conv=notrunc # Patch CDR name address
|
|
||||||
printf '\x44' | dd of=$@ bs=1 seek=335273 count=1 conv=notrunc # Patch CDR disable byte
|
|
||||||
printf '\x00\x78\x00\x00' | dd of=$@ bs=1 seek=335276 count=4 conv=notrunc # Patch ROM disk size
|
printf '\x00\x78\x00\x00' | dd of=$@ bs=1 seek=335276 count=4 conv=notrunc # Patch ROM disk size
|
||||||
# Copy ROM disk image
|
# Copy ROM disk image
|
||||||
dd if=disks/RDisk7M5.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
dd if=disks/RDisk.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/driver.bin
BIN
bin/driver.bin
Binary file not shown.
22
entry.s
22
entry.s
|
@ -8,13 +8,27 @@
|
||||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||||
|
|
||||||
SDiskSig:
|
RDiskSig:
|
||||||
.ascii "\5SDisk\0"
|
.ascii "\5RDisk\0"
|
||||||
|
.align 4
|
||||||
|
RDiskDBGDisPos:
|
||||||
|
dc.l 0x00000031
|
||||||
|
RDiskCDRDisPos:
|
||||||
|
dc.l 0xFFFFFFFF
|
||||||
|
RDiskDBGNameAddr:
|
||||||
|
dc.l 0x4088002A
|
||||||
|
RDiskCDRNameAddr:
|
||||||
|
dc.l 0x00000000
|
||||||
|
RDiskDBGDisByte:
|
||||||
|
dc.b 0x44
|
||||||
|
RDiskCDRDisByte:
|
||||||
|
dc.b 0x44
|
||||||
|
RDiskRAMRequired:
|
||||||
|
.ascii "16"
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
RDiskSize:
|
RDiskSize:
|
||||||
dc.l 0x00780000
|
dc.l 0x00780000
|
||||||
SDiskSize:
|
|
||||||
dc.l 0x80000000
|
|
||||||
|
|
||||||
DOpen:
|
DOpen:
|
||||||
movem.l %A0-%A1, -(%SP)
|
movem.l %A0-%A1, -(%SP)
|
||||||
|
|
89
old/Makefile
89
old/Makefile
|
@ -1,89 +0,0 @@
|
||||||
# path to RETRO68
|
|
||||||
RETRO68=~/Retro68-build/toolchain
|
|
||||||
|
|
||||||
PREFIX=$(RETRO68)/bin/m68k-apple-macos
|
|
||||||
AS=$(PREFIX)-as
|
|
||||||
CC=$(PREFIX)-gcc
|
|
||||||
LD=$(PREFIX)-ld
|
|
||||||
OBJCOPY=$(PREFIX)-objcopy
|
|
||||||
OBJDUMP=$(PREFIX)-objdump
|
|
||||||
CFLAGS=-march=68030 -c -Os
|
|
||||||
|
|
||||||
all: bin/rom16M_swap.bin obj/rdisk7M5.s obj/driver7M5.s obj/entry_rel.sym obj/driver_abs.sym
|
|
||||||
|
|
||||||
obj:
|
|
||||||
mkdir obj
|
|
||||||
|
|
||||||
bin:
|
|
||||||
mkdir bin
|
|
||||||
|
|
||||||
|
|
||||||
obj/entry.o: entry.s obj
|
|
||||||
$(AS) $< -o $@
|
|
||||||
|
|
||||||
obj/entry_rel.sym: obj obj/entry.o
|
|
||||||
$(OBJDUMP) -t obj/entry.o > $@
|
|
||||||
|
|
||||||
|
|
||||||
obj/rdisk7M5.o: rdisk.c obj
|
|
||||||
$(CC) -Wall -DRDiskSize=7864320 $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
obj/rdisk7M5.s: obj obj/rdisk7M5.o
|
|
||||||
$(OBJDUMP) -d obj/rdisk7M5.o > $@
|
|
||||||
|
|
||||||
|
|
||||||
obj/spi.o: spi.c obj
|
|
||||||
$(CC) -Wall $(CFLAGS) $< -o $@
|
|
||||||
|
|
||||||
obj/spi.s: obj obj/spi.o
|
|
||||||
$(OBJDUMP) -d obj/spi.o > $@
|
|
||||||
|
|
||||||
|
|
||||||
obj/sdmmc.o: sdmmc.c obj
|
|
||||||
$(CC) -Wall $(CFLAGS) -Os $< -o $@
|
|
||||||
|
|
||||||
obj/sdmmc.s: obj obj/sdmmc.o
|
|
||||||
$(OBJDUMP) -d obj/sdmmc.o > $@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
obj/driver7M5.o: obj obj/entry.o obj/rdisk7M5.o
|
|
||||||
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rdisk7M5.o obj/spi.o obj/sdmmc.o
|
|
||||||
|
|
||||||
obj/driver7M5.s: obj obj/driver7M5.o
|
|
||||||
$(OBJDUMP) -d obj/driver7M5.o > $@
|
|
||||||
|
|
||||||
obj/driver_abs.sym: obj obj/driver7M5.o
|
|
||||||
$(OBJDUMP) -t obj/driver7M5.o > $@
|
|
||||||
|
|
||||||
|
|
||||||
bin/driver7M5.bin: bin obj/driver7M5.o
|
|
||||||
$(OBJCOPY) -O binary obj/driver7M5.o $@
|
|
||||||
|
|
||||||
bin/rom8M.bin: bin baserom.bin RDisk7M5.dsk bin bin/driver7M5.bin obj/driver_abs.sym obj/entry_rel.sym
|
|
||||||
cp baserom.bin $@ # Copy base rom
|
|
||||||
# Patch driver
|
|
||||||
dd if=bin/driver7M5.bin of=$@ bs=1 seek=335248 skip=32 conv=notrunc # Copy driver code
|
|
||||||
printf '\x78' | dd of=$@ bs=1 seek=335168 count=1 conv=notrunc # Set resource flags
|
|
||||||
printf '\x4F' | dd of=$@ bs=1 seek=335216 count=1 conv=notrunc # Set driver flags
|
|
||||||
cat obj/entry_rel.sym | grep "DOpen" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335224 count=2 conv=notrunc
|
|
||||||
cat obj/entry_rel.sym | grep "DPrime" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335226 count=2 conv=notrunc
|
|
||||||
cat obj/entry_rel.sym | grep "DControl" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335228 count=2 conv=notrunc
|
|
||||||
cat obj/entry_rel.sym | grep "DStatus" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335230 count=2 conv=notrunc
|
|
||||||
cat obj/entry_rel.sym | grep "DClose" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335232 count=2 conv=notrunc
|
|
||||||
dd if=RDisk7M5.dsk of=$@ bs=1024 seek=512 count=7680 conv=notrunc # copy disk image
|
|
||||||
|
|
||||||
bin/rom8M_swap.bin: bin bin/rom8M.bin
|
|
||||||
dd if=bin/rom8M.bin of=$@ conv=swab # swap bytes
|
|
||||||
|
|
||||||
bin/iisi_swap.bin: bin iisi.bin
|
|
||||||
dd if=iisi.bin of=$@ conv=swab # swap bytes
|
|
||||||
|
|
||||||
bin/rom16M_swap.bin: bin/iisi_swap.bin bin/rom8M_swap.bin
|
|
||||||
cat bin/rom8M_swap.bin > $@
|
|
||||||
cat bin/iisi_swap.bin >> $@
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -fr bin obj
|
|
BIN
old/baserom.bin
BIN
old/baserom.bin
Binary file not shown.
84
old/entry.s
84
old/entry.s
|
@ -1,84 +0,0 @@
|
||||||
.EQU killCode, 1
|
|
||||||
.EQU noQueueBit, 9
|
|
||||||
.EQU kioTrap, 6
|
|
||||||
.EQU kioResult, 16
|
|
||||||
.EQU kcsCode, 26
|
|
||||||
.EQU JIODone, 0x08FC
|
|
||||||
.GLOBAL RDiskSig
|
|
||||||
.GLOBAL RDiskDBGNamePos
|
|
||||||
.GLOBAL RDiskDBGDisPos
|
|
||||||
.GLOBAL RDiskDBGDisByte
|
|
||||||
.GLOBAL RDiskCDRNamePos
|
|
||||||
.GLOBAL RDiskCDRDisPos
|
|
||||||
.GLOBAL RDiskCDRDisByte
|
|
||||||
|
|
||||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
|
||||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
|
||||||
|
|
||||||
RDiskSig:
|
|
||||||
.ascii "\5RDisk\0"
|
|
||||||
.align 4
|
|
||||||
RDiskDBGDisPos:
|
|
||||||
dc.l 0x00000031
|
|
||||||
RDiskCDRDisPos:
|
|
||||||
dc.l 0x00012CAF
|
|
||||||
RDiskDBGNameAddr:
|
|
||||||
dc.l 0x4088002A
|
|
||||||
RDiskCDRNameAddr:
|
|
||||||
dc.l 0x40892C96
|
|
||||||
RDiskDBGDisByte:
|
|
||||||
dc.b 0x44
|
|
||||||
RDiskCDRDisByte:
|
|
||||||
dc.b 0x44
|
|
||||||
RDiskRAMRequired:
|
|
||||||
.ascii "16"
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
DOpen:
|
|
||||||
movem.l %A0-%A1, -(%SP)
|
|
||||||
bsr RDOpen
|
|
||||||
movem.l (%SP)+, %A0-%A1
|
|
||||||
rts
|
|
||||||
|
|
||||||
DClose:
|
|
||||||
movem.l %A0-%A1, -(%SP)
|
|
||||||
bsr RDClose
|
|
||||||
movem.l (%SP)+, %A0-%A1
|
|
||||||
rts
|
|
||||||
|
|
||||||
DPrime:
|
|
||||||
movem.l %A0-%A1, -(%SP)
|
|
||||||
bsr RDPrime
|
|
||||||
movem.l (%SP)+, %A0-%A1
|
|
||||||
bra.b IOReturn
|
|
||||||
|
|
||||||
DControl:
|
|
||||||
movem.l %A0-%A1, -(%SP)
|
|
||||||
bsr RDCtl
|
|
||||||
movem.l (%SP)+, %A0-%A1
|
|
||||||
cmpi.w #killCode, kcsCode(%A0)
|
|
||||||
bne.b IOReturn
|
|
||||||
rts
|
|
||||||
|
|
||||||
DStatus:
|
|
||||||
movem.l %A0-%A1, -(%SP)
|
|
||||||
bsr RDStat
|
|
||||||
movem.l (%SP)+, %A0-%A1
|
|
||||||
|
|
||||||
IOReturn:
|
|
||||||
move.w kioTrap(%A0), %D1
|
|
||||||
btst #noQueueBit, %D1
|
|
||||||
beq.b Queued
|
|
||||||
|
|
||||||
NotQueued:
|
|
||||||
tst.w %D0
|
|
||||||
ble.b ImmedRTS
|
|
||||||
clr.w %D0
|
|
||||||
|
|
||||||
ImmedRTS:
|
|
||||||
move.w %D0, kioResult(%A0)
|
|
||||||
rts
|
|
||||||
|
|
||||||
Queued:
|
|
||||||
move.l JIODone, -(%SP)
|
|
||||||
rts
|
|
361
old/rombus.c
361
old/rombus.c
|
@ -1,361 +0,0 @@
|
||||||
#include <Memory.h>
|
|
||||||
#include <Devices.h>
|
|
||||||
#include <Files.h>
|
|
||||||
#include <Disks.h>
|
|
||||||
#include <Errors.h>
|
|
||||||
#include <Events.h>
|
|
||||||
#include <OSUtils.h>
|
|
||||||
|
|
||||||
#include "rdisk.h"
|
|
||||||
|
|
||||||
// Decode keyboard/PRAM settings
|
|
||||||
static void RDDecodeSettings(Ptr recoveryEN, Ptr unmountEN, Ptr mountEN) {
|
|
||||||
// Read PRAM
|
|
||||||
char legacy_startup;
|
|
||||||
RBReadXPRAM(1, 4, &legacy_startup);
|
|
||||||
|
|
||||||
// Decode settings: boot from recovery, unmount (don't boot), mount (after boot)
|
|
||||||
if (RBIsRPressed()) { // R boots from ROM recovery
|
|
||||||
*recoveryEN = 1; // Enable recovery partition
|
|
||||||
*unmountEN = 0; // Unmount SD so we don't boot from it
|
|
||||||
*mountEN = 1; // Mount SD later
|
|
||||||
} else {
|
|
||||||
*recoveryEN = 0; // Disable recovery partition
|
|
||||||
if (legacy_startup & 0x10) { // Boot from SD disk
|
|
||||||
*unmountEN = 0; // Don't unmount so we boot from this drive
|
|
||||||
*mountEN = 0; // No need to mount later since we are boot disk
|
|
||||||
} else if (legacy_startup & 0x20) { // Mount SD disk under other boot volume
|
|
||||||
*unmountEN = 1; // Unmount to not boot from our disk
|
|
||||||
*mountEN = 1; // Mount in accRun
|
|
||||||
} else {
|
|
||||||
*unmountEN = 1; // Unmount
|
|
||||||
*mountEN = 0; // Don't mount again
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to 32-bit mode and copy
|
|
||||||
#pragma parameter C24(__A0, __A1, __D0)
|
|
||||||
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
|
||||||
signed char mode = true32b;
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
BlockMove(sourcePtr, destPtr, byteCount);
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to 32-bit mode and get
|
|
||||||
#pragma parameter __D0 G24(__A2)
|
|
||||||
char __attribute__ ((noinline)) G24(Ptr pos) {
|
|
||||||
long ret;
|
|
||||||
signed char mode = true32b;
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
ret = *pos; // Peek
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to 32-bit mode and set
|
|
||||||
#pragma parameter S24(__A2, __D3)
|
|
||||||
void __attribute__ ((noinline)) S24(Ptr pos, char patch) {
|
|
||||||
signed char mode = true32b;
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
*pos = patch; // Poke
|
|
||||||
SwapMMUMode(&mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out the first available drive number >= 5
|
|
||||||
static int RBFindDrvNum() {
|
|
||||||
DrvQElPtr dq;
|
|
||||||
int drvNum = 5;
|
|
||||||
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
|
||||||
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
|
||||||
}
|
|
||||||
return drvNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RBOpenRDisk(RDiskStorage_t *c) {
|
|
||||||
int drvNum;
|
|
||||||
|
|
||||||
// Find first available drive number for ROM recovery
|
|
||||||
drvNum = RBFindDrvNum();
|
|
||||||
|
|
||||||
// Set ROM recovery drive status
|
|
||||||
//c->rStatus.track = 0;
|
|
||||||
c->rStatus.writeProt = -1; // nonzero is write protected
|
|
||||||
c->rStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
c->rStatus.installed = 1; // drive installed
|
|
||||||
//c->rStatus.sides = 0;
|
|
||||||
//c->rStatus.qType = 1;
|
|
||||||
c->rStatus.dQDrive = drvNum;
|
|
||||||
//c->rStatus.dQFSID = 0;
|
|
||||||
c->rStatus.dQRefNum = d->dCtlRefNum;
|
|
||||||
c->rStatus.driveSize = RDiskSize / 512;
|
|
||||||
//c->rStatus.driveS1 = (RDiskSize / 512) >> 16;
|
|
||||||
|
|
||||||
// Decompress icon
|
|
||||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
|
||||||
char *src = &RDiskIconCompressed[0];
|
|
||||||
char *dst = &c->rIcon[0];
|
|
||||||
UnpackBits(&src, &dst, RDISK_ICON_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add RDisk to drive queue and return
|
|
||||||
RDiskAddDrive(c->rStatus.dQRefNum, drvNum, (DrvQElPtr)&c->rStatus.qLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RBOpenSDisk(RDiskStorage_t *c) {
|
|
||||||
int drvNum;
|
|
||||||
|
|
||||||
// Find first available drive number for SD disk
|
|
||||||
drvNum = RBFindDrvNum();
|
|
||||||
|
|
||||||
// Set SD disk drive status
|
|
||||||
//c->rStatus.track = 0;
|
|
||||||
c->rStatus.writeProt = 0; // 0 is writable
|
|
||||||
c->rStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
c->rStatus.installed = 1; // drive installed
|
|
||||||
//c->rStatus.sides = 0;
|
|
||||||
c->rStatus.qType = 1;
|
|
||||||
c->rStatus.dQDrive = drvNum;
|
|
||||||
//c->rStatus.dQFSID = 0;
|
|
||||||
c->rStatus.dQRefNum = d->dCtlRefNum;
|
|
||||||
c->rStatus.driveSize = SDiskSize / 512;
|
|
||||||
c->rStatus.driveS1 = (SDiskSize / 512) >> 16;
|
|
||||||
|
|
||||||
// Decompress icon
|
|
||||||
#ifdef SDISK_COMPRESS_ICON_ENABLE
|
|
||||||
char *src = &SDiskIconCompressed[0];
|
|
||||||
char *dst = &c->sIcon[0];
|
|
||||||
UnpackBits(&src, &dst, SDISK_ICON_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add SDisk to drive queue and return
|
|
||||||
RDiskAddDrive(c->rstatus.dQRefNum, drvNum, (DrvQElPtr)&c->sStatus.qLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBOpen(__A0, __A1)
|
|
||||||
OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
|
||||||
RDiskStorage_t *c;
|
|
||||||
char legacy_startup;
|
|
||||||
|
|
||||||
// Do nothing if already opened
|
|
||||||
if (d->dCtlStorage) { return noErr; }
|
|
||||||
|
|
||||||
// Do nothing if inhibited
|
|
||||||
RBReadXPRAM(1, 4, &legacy_startup);
|
|
||||||
if (legacy_startup & 0x40) { return noErr; }
|
|
||||||
|
|
||||||
// Allocate storage struct
|
|
||||||
d->dCtlStorage = NewHandleSysClear(sizeof(RDiskStorage_t));
|
|
||||||
if (!d->dCtlStorage) { return openErr; }
|
|
||||||
|
|
||||||
// Lock our storage struct and get master pointer
|
|
||||||
HLock(d->dCtlStorage);
|
|
||||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
|
||||||
|
|
||||||
// Create RDisk and SDisk entries in drive queue, then return
|
|
||||||
RBOpenRDisk(c);
|
|
||||||
RBOpenSDisk(c);
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init is called at beginning of first prime (read/write) call
|
|
||||||
static void RBInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
|
||||||
char recoveryEN, unmountEN, mountEN;
|
|
||||||
// Mark init done
|
|
||||||
c->initialized = 1;
|
|
||||||
// Decode settings
|
|
||||||
RDDecodeSettings(&recoveryEN, &unmountEN, &mountEN);
|
|
||||||
|
|
||||||
// Unmount if not booting from ROM disk
|
|
||||||
if (!recoveryEN) { c->rStatus.diskInPlace = 0; }
|
|
||||||
|
|
||||||
// Unmount if not booting from ROM disk
|
|
||||||
if (unmountEN) { c->SStatus.diskInPlace = 0; }
|
|
||||||
|
|
||||||
// If mount enabled, enable accRun to post disk inserted event later
|
|
||||||
if (mountEN) {
|
|
||||||
d->dCtlDelay = 150; // Set accRun delay (150 ticks is 2.5 sec.)
|
|
||||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSErr RDPrime(IOParamPtr p, DCtlPtr d) {
|
|
||||||
// Get pointer to correct position in ROM disk buffer
|
|
||||||
Ptr disk = RDiskBuf + d->dCtlPosition;
|
|
||||||
|
|
||||||
// Return disk offline error if virtual disk not inserted
|
|
||||||
if (!c->rStatus.diskInPlace) { return offLinErr; }
|
|
||||||
|
|
||||||
// Bounds checking
|
|
||||||
if (d->dCtlPosition >= RDiskSize || p->ioReqCount >= RDiskSize ||
|
|
||||||
d->dCtlPosition + p->ioReqCount >= RDiskSize) { return paramErr; }
|
|
||||||
|
|
||||||
// Service read or write request
|
|
||||||
cmd = p->ioTrap & 0x00FF;
|
|
||||||
if (cmd == aRdCmd) {
|
|
||||||
if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); }
|
|
||||||
else { copy24(disk, StripAddress(p->ioBuffer), p->ioReqCount); }
|
|
||||||
} else if (cmd == aWrCmd) { return wPrErr;
|
|
||||||
} else { return noErr; } //FIXME: Fail if cmd isn't read or write?
|
|
||||||
|
|
||||||
// Update count and position/offset, then return
|
|
||||||
d->dCtlPosition += p->ioReqCount;
|
|
||||||
p->ioActCount = p->ioReqCount;
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSErr SDPrime(IOParamPtr p, DCtlPtr d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBPrime(__A0, __A1)
|
|
||||||
OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
|
||||||
RDiskStorage_t *c;
|
|
||||||
char cmd;
|
|
||||||
|
|
||||||
// Return disk offline error if dCtlStorage null
|
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
|
||||||
// Dereference dCtlStorage to get pointer to our context
|
|
||||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
|
||||||
|
|
||||||
// Initialize if this is the first prime call
|
|
||||||
if (!c->initialized) { RBInit(p, d, c); }
|
|
||||||
|
|
||||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
|
||||||
return SDPrime(p, d, c);
|
|
||||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
|
||||||
return RDPrime(p, d, c);
|
|
||||||
} else { return nsvErr; }
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSErr RDCtl(CntrlParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
|
||||||
// Handle control request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kFormat: return controlErr;
|
|
||||||
case kVerify:
|
|
||||||
if (!c->rStatus.diskInPlace) { return controlErr; }
|
|
||||||
return noErr;
|
|
||||||
case kEject:
|
|
||||||
// "Reinsert" disk if ejected illegally
|
|
||||||
if (c->rStatus.diskInPlace) {
|
|
||||||
PostEvent(diskEvt, c->status.dQDrive);
|
|
||||||
}
|
|
||||||
return controlErr; // Eject not allowed so return error
|
|
||||||
case kDriveIcon: case kMediaIcon: // Get icon
|
|
||||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
|
||||||
*(Ptr*)p->csParam = (Ptr)c->rIcon;
|
|
||||||
#else
|
|
||||||
*(Ptr*)p->csParam = (Ptr)RDiskIcon;
|
|
||||||
#endif
|
|
||||||
return noErr;
|
|
||||||
case kDriveInfo:
|
|
||||||
// high word (bytes 2 & 3) clear
|
|
||||||
// byte 1 = primary + fixed media + internal
|
|
||||||
// byte 0 = drive type (0x11 is ROM disk)
|
|
||||||
*(long*)p->csParam = 0x00000411;
|
|
||||||
return noErr;
|
|
||||||
case 24: // Return SCSI partition size
|
|
||||||
*(long*)p->csParam = RDiskSize / 512;
|
|
||||||
return noErr;
|
|
||||||
default: return controlErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSErr SDCtl(CntrlParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
|
||||||
// Handle control request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kFormat:
|
|
||||||
// FIXME: implement SD format
|
|
||||||
return controlErr;
|
|
||||||
case kVerify:
|
|
||||||
// FIXME: implement SD verify
|
|
||||||
return noErr;
|
|
||||||
case kEject:
|
|
||||||
// "Reinsert" disk if ejected illegally
|
|
||||||
if (c->sStatus.diskInPlace) {
|
|
||||||
PostEvent(diskEvt, c->sStatus.dQDrive);
|
|
||||||
}
|
|
||||||
return controlErr; // Eject not allowed so return error
|
|
||||||
case kDriveIcon: case kMediaIcon: // Get icon
|
|
||||||
#ifdef SDISK_COMPRESS_ICON_ENABLE
|
|
||||||
*(Ptr*)p->csParam = (Ptr)c->sIcon;
|
|
||||||
#else
|
|
||||||
*(Ptr*)p->csParam = (Ptr)SDiskIcon;
|
|
||||||
#endif
|
|
||||||
return noErr;
|
|
||||||
case kDriveInfo:
|
|
||||||
// high word (bytes 2 & 3) clear
|
|
||||||
// byte 1 = primary + fixed media + internal
|
|
||||||
// byte 0 = drive type (0x01 is unspecified drive)
|
|
||||||
*(long*)p->csParam = 0x00000401;
|
|
||||||
return noErr;
|
|
||||||
case 24: // Return SCSI partition size
|
|
||||||
*(long*)p->csParam = SDiskSize / 512;
|
|
||||||
return noErr;
|
|
||||||
default: return controlErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBCtl(__A0, __A1)
|
|
||||||
OSErr RBCtl(CntrlParamPtr p, DCtlPtr d) {
|
|
||||||
RDiskStorage_t *c;
|
|
||||||
// Fail if dCtlStorage null
|
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
|
||||||
// Dereference dCtlStorage to get pointer to our context
|
|
||||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
|
||||||
// Handle control request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case killCode:
|
|
||||||
return noErr;
|
|
||||||
case accRun:
|
|
||||||
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
|
||||||
c->sStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
PostEvent(diskEvt, c->sStatus.dQDrive); // Post disk inserted event
|
|
||||||
return noErr;
|
|
||||||
case 2351: // Post-boot
|
|
||||||
c->initialized = 1; // Skip initialization
|
|
||||||
d->dCtlDelay = 30; // Set accRun delay (30 ticks is 0.5 sec.)
|
|
||||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, dispatch to correct drive
|
|
||||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
|
||||||
return SDCtl(p, d, c);
|
|
||||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
|
||||||
return RDCtl(p, d, c);
|
|
||||||
} else { return nsvErr; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBStat(__A0, __A1)
|
|
||||||
OSErr RBStat(CntrlParamPtr p, DCtlPtr d) {
|
|
||||||
RDiskStorage_t *c;
|
|
||||||
// Fail if dCtlStorage null
|
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
|
||||||
// Dereference dCtlStorage to get pointer to our context
|
|
||||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
|
||||||
// Handle status request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kDriveStatus:
|
|
||||||
// Otherwise, copy correct drive status
|
|
||||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
|
||||||
BlockMove(&c->sStatus, &p->csParam, sizeof(DrvSts2));
|
|
||||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
|
||||||
BlockMove(&c->rStatus, &p->csParam, sizeof(DrvSts2));
|
|
||||||
} else { return nsvErr; }
|
|
||||||
return noErr;
|
|
||||||
default: return statusErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBClose(__A0, __A1)
|
|
||||||
OSErr RBClose(IOParamPtr p, DCtlPtr d) {
|
|
||||||
// If dCtlStorage not null, dispose of it
|
|
||||||
if (!d->dCtlStorage) { return noErr; }
|
|
||||||
//RDiskStorage_t *c = *(RDiskStorage_t**)d->dCtlStorage;
|
|
||||||
HUnlock(d->dCtlStorage);
|
|
||||||
DisposeHandle(d->dCtlStorage);
|
|
||||||
d->dCtlStorage = NULL;
|
|
||||||
return noErr;
|
|
||||||
}
|
|
179
old/rombus.h
179
old/rombus.h
|
@ -1,179 +0,0 @@
|
||||||
#ifndef ROMBUS_H
|
|
||||||
#define ROMBUS_H
|
|
||||||
|
|
||||||
#define RDiskBuf ((char*)0x408C0000)
|
|
||||||
#define SDiskSize (0x80000000L)
|
|
||||||
#define BufPtr ((Ptr*)0x10C)
|
|
||||||
#define MemTop ((Ptr*)0x108)
|
|
||||||
#define MMU32bit ((char*)0xCB2)
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBReadXPRAM(__D0, __D1, __A0)
|
|
||||||
OSErr RBReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
|
||||||
|
|
||||||
#pragma parameter __D0 RBAddDrive(__D1, __D0, __A0)
|
|
||||||
OSErr RBAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
|
||||||
|
|
||||||
static inline char RBIsRPressed() { return *((char*)0x175) & 0x80; }
|
|
||||||
|
|
||||||
typedef struct RBStorage_s {
|
|
||||||
DrvSts2 sStatus;
|
|
||||||
DrvSts2 rStatus;
|
|
||||||
char initialized;
|
|
||||||
} RBStorage_t;
|
|
||||||
|
|
||||||
typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long);
|
|
||||||
#define copy24(s, d, b) { RDiskCopy_t f = C24; f(s, d, b); }
|
|
||||||
|
|
||||||
typedef char (*RDiskPeek_t)(Ptr);
|
|
||||||
#define peek24(a, d) { RDiskPeek_t f = G24; d = f(a); }
|
|
||||||
|
|
||||||
typedef void (*RDiskPoke_t)(Ptr, char);
|
|
||||||
#define poke24(a, d) { RDiskPoke_t f = S24; f(a, d); }
|
|
||||||
|
|
||||||
#define RDISK_ICON_SIZE (285)
|
|
||||||
const char RDiskIcon[RDISK_ICON_SIZE] = {
|
|
||||||
// Icon
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
|
||||||
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
// Mask
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
|
||||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
|
||||||
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SDISK_ICON_SIZE (283)
|
|
||||||
const char const SDiskIcon[SDISK_ICON_SIZE] = {
|
|
||||||
// Icon
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000001, 0b00000001, 0b10000000, 0b11010000,
|
|
||||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
|
||||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
|
||||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
|
||||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
|
||||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
|
||||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000100, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001110, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00000100, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
// Mask
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
25, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
|
||||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
|
||||||
'R', 'O', 'M', 'B', 'U', 'S', 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
220
old/sdmmc.c
220
old/sdmmc.c
|
@ -1,220 +0,0 @@
|
||||||
#include "sdmmc.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Module Private Functions
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define INIT_PORT() init_port() /* Initialize MMC control port (CS/CLK/DI:output, DO:input) */
|
|
||||||
#define DLY_US(n) dly_us(n) /* Delay n microseconds */
|
|
||||||
#define FORWARD(d) forward(d) /* Data in-time processing function (depends on the project) */
|
|
||||||
|
|
||||||
/* Definitions for MMC/SDC command */
|
|
||||||
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
|
|
||||||
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
|
|
||||||
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
|
|
||||||
#define CMD8 (0x40+8) /* SEND_IF_COND */
|
|
||||||
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
|
|
||||||
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
|
|
||||||
#define CMD24 (0x40+24) /* WRITE_BLOCK */
|
|
||||||
#define CMD55 (0x40+55) /* APP_CMD */
|
|
||||||
#define CMD58 (0x40+58) /* READ_OCR */
|
|
||||||
|
|
||||||
/* Card type flags (CardType) */
|
|
||||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
|
||||||
#define CT_SD1 0x02 /* SD ver 1 */
|
|
||||||
#define CT_SD2 0x04 /* SD ver 2 */
|
|
||||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
|
||||||
#define CT_BLOCK 0x08 /* Block addressing */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char CardType; /* 0:MMC, 1:SDv1, 2:SDv2, 3:Block addressing */
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Send a command packet to MMC */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
static char send_cmd(char cmd, long arg)
|
|
||||||
{
|
|
||||||
char n, res;
|
|
||||||
|
|
||||||
if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
|
|
||||||
cmd &= 0x7F;
|
|
||||||
res = send_cmd(CMD55, 0);
|
|
||||||
if (res > 1) return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Select the card */
|
|
||||||
CS_H(); spi_rx();
|
|
||||||
CS_L(); spi_rx();
|
|
||||||
|
|
||||||
/* Send a command packet */
|
|
||||||
spi_tx(cmd); /* Start + Command index */
|
|
||||||
s((BYTE)(arg >> 24)); /* Argument[31..24] */
|
|
||||||
spi_tx((BYTE)(arg >> 16)); /* Argument[23..16] */
|
|
||||||
spi_tx((BYTE)(arg >> 8)); /* Argument[15..8] */
|
|
||||||
spi_tx((BYTE)arg); /* Argument[7..0] */
|
|
||||||
n = 0x01; /* Dummy CRC + Stop */
|
|
||||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
|
|
||||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
|
|
||||||
spi_tx(n);
|
|
||||||
|
|
||||||
/* Receive a command response */
|
|
||||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
|
||||||
do {
|
|
||||||
res = spi_rx();
|
|
||||||
} while ((res & 0x80) && --n);
|
|
||||||
|
|
||||||
return res; /* Return with the response value */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Public Functions
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
sdstatus_t sdmmc_init()
|
|
||||||
{
|
|
||||||
char n, cmd, ty, buf[4];
|
|
||||||
uint tmr;
|
|
||||||
|
|
||||||
CS_H();
|
|
||||||
spi_skip(10); /* Dummy clocks */
|
|
||||||
|
|
||||||
ty = 0;
|
|
||||||
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
|
|
||||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */
|
|
||||||
for (n = 0; n < 4; n++) buf[n] = spi_rx(); /* Get trailing return value of R7 resp */
|
|
||||||
if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
|
||||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */
|
|
||||||
if (send_cmd(ACMD41, 1UL << 30) == 0) break;
|
|
||||||
DLY_US(1000);
|
|
||||||
}
|
|
||||||
if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
|
||||||
for (n = 0; n < 4; n++) buf[n] = spi_rx();
|
|
||||||
ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { /* SDv1 or MMCv3 */
|
|
||||||
if (send_cmd(ACMD41, 0) <= 1) {
|
|
||||||
ty = CT_SD1; cmd = ACMD41; /* SDv1 */
|
|
||||||
} else {
|
|
||||||
ty = CT_MMC; cmd = CMD1; /* MMCv3 */
|
|
||||||
}
|
|
||||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */
|
|
||||||
if (send_cmd(cmd, 0) == 0) break;
|
|
||||||
DLY_US(1000);
|
|
||||||
}
|
|
||||||
if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
|
|
||||||
ty = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CardType = ty;
|
|
||||||
release_spi();
|
|
||||||
|
|
||||||
return ty ? 0 : STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read partial sector */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
sdresult_t sdmmc_readp(Ptr buf, long sector, uint offset, uint count)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
char d;
|
|
||||||
uint bc, tmr;
|
|
||||||
|
|
||||||
|
|
||||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
|
||||||
|
|
||||||
res = RES_ERROR;
|
|
||||||
if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */
|
|
||||||
|
|
||||||
tmr = 1000;
|
|
||||||
do { /* Wait for data packet in timeout of 100ms */
|
|
||||||
DLY_US(100);
|
|
||||||
d = spi_rx();
|
|
||||||
} while (d == 0xFF && --tmr);
|
|
||||||
|
|
||||||
if (d == 0xFE) { /* A data packet arrived */
|
|
||||||
bc = 514 - offset - count;
|
|
||||||
|
|
||||||
/* Skip leading bytes */
|
|
||||||
if (offset) spi_skip(offset);
|
|
||||||
|
|
||||||
/* Receive a part of the sector */
|
|
||||||
if (buff) { /* Store data to the memory */
|
|
||||||
do
|
|
||||||
*buff++ = spi_rx();
|
|
||||||
while (--count);
|
|
||||||
} else { /* Forward data to the outgoing stream */
|
|
||||||
do {
|
|
||||||
d = spi_rx();
|
|
||||||
FORWARD(d);
|
|
||||||
} while (--count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip trailing bytes and CRC */
|
|
||||||
spi_skip(bc);
|
|
||||||
|
|
||||||
res = RES_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
release_spi();
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write partial sector */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
sdresult_t sdmmc_writep(const Ptr buf, long sc)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
UINT bc, tmr;
|
|
||||||
static UINT wc;
|
|
||||||
|
|
||||||
res = RES_ERROR;
|
|
||||||
|
|
||||||
if (buff) { /* Send data bytes */
|
|
||||||
bc = (UINT)sc;
|
|
||||||
while (bc && wc) { /* Send data bytes to the card */
|
|
||||||
spi_tx(*buff++);
|
|
||||||
wc--; bc--;
|
|
||||||
}
|
|
||||||
res = RES_OK;
|
|
||||||
} else {
|
|
||||||
if (sc) { /* Initiate sector write transaction */
|
|
||||||
if (!(CardType & CT_BLOCK)) sc *= 512; /* Convert to byte address if needed */
|
|
||||||
if (send_cmd(CMD24, sc) == 0) { /* WRITE_SINGLE_BLOCK */
|
|
||||||
spi_tx(0xFF); spi_tx(0xFE); /* Data block header */
|
|
||||||
wc = 512; /* Set byte counter */
|
|
||||||
res = RES_OK;
|
|
||||||
}
|
|
||||||
} else { /* Finalize sector write transaction */
|
|
||||||
bc = wc + 2;
|
|
||||||
while (bc--) spi_tx(0); /* Fill left bytes and CRC with zeros */
|
|
||||||
if ((spi_rx() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */
|
|
||||||
for (tmr = 10000; spi_rx() != 0xFF && tmr; tmr--) /* Wait for ready (max 1000ms) */
|
|
||||||
DLY_US(100);
|
|
||||||
if (tmr) res = RES_OK;
|
|
||||||
}
|
|
||||||
release_spi();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
29
old/sdmmc.h
29
old/sdmmc.h
|
@ -1,29 +0,0 @@
|
||||||
#ifndef SDMMC_H
|
|
||||||
#define SDMMC_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Status of Disk Functions */
|
|
||||||
typedef char sdstatus_t;
|
|
||||||
|
|
||||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
|
||||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
|
||||||
|
|
||||||
|
|
||||||
/* Results of Disk Functions */
|
|
||||||
typedef enum sdmmc_result_e {
|
|
||||||
RES_OK = 0, /* 0: Function succeeded */
|
|
||||||
RES_ERROR, /* 1: Disk error */
|
|
||||||
RES_NOTRDY, /* 2: Not ready */
|
|
||||||
RES_PARERR /* 3: Invalid parameter */
|
|
||||||
} sdresult_t;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
|
||||||
/* Prototypes for disk control functions */
|
|
||||||
/*---------------------------------------*/
|
|
||||||
sdstatus_t sdmmc_init();
|
|
||||||
sdresult_t sdmmc_readp(Ptr buf, long sector, uint offset, uint count);
|
|
||||||
sdresult_t sdmmc_writep(const Ptr buf, long sc);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
164
old/spi.c
164
old/spi.c
|
@ -1,164 +0,0 @@
|
||||||
#include "spi.h"
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* Platform dependent macros and functions needed to be modified */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
#define CS_H() bset(P0) /* Set MMC CS "high" */
|
|
||||||
#define CS_L() bclr(P0) /* Set MMC CS "low" */
|
|
||||||
#define CK_H() bset(P1) /* Set MMC SCLK "high" */
|
|
||||||
#define CK_L() bclr(P1) /* Set MMC SCLK "low" */
|
|
||||||
#define DI_H() bset(P2) /* Set MMC DI "high" */
|
|
||||||
#define DI_L() bclr(P2) /* Set MMC DI "low" */
|
|
||||||
#define DO btest(P3) /* Test MMC DO (high:true, low:false) */
|
|
||||||
|
|
||||||
|
|
||||||
// Command listing
|
|
||||||
/* T16: Transfer 16-bit
|
|
||||||
* First, the 16-bit value encoded in the address bits A[17:2] is latched.
|
|
||||||
* The data output mux is set to the current RXR and the cycle completes.
|
|
||||||
* Shortly after /AS rises, the SPI transfer engine begins
|
|
||||||
* transferring the latched value.
|
|
||||||
*/
|
|
||||||
/* T16S: Transfer 16-bit Swapped
|
|
||||||
* Same as T16L but read data is byte-swapped.
|
|
||||||
*/
|
|
||||||
/* MERT: Measure Elapsed time and Reset Timer
|
|
||||||
* The elapsed time since the last MERT command is returned in D[31:24]
|
|
||||||
* and the timer is reset.
|
|
||||||
*/
|
|
||||||
/* SKIP1: Skip Clocks with MOSI "1"
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* SKIP0: Skip Clocks with MOSI "0"
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* T8S: Transfer 8-bit Swapped
|
|
||||||
* Same as T8 but read data is byte-swapped.
|
|
||||||
*/
|
|
||||||
/* T8: Transfer 8-bit
|
|
||||||
* First, the 8-bit value encoded in the address bits A[9:2] is latched.
|
|
||||||
* The data output mux is set to the current RXR and the cycle completes.
|
|
||||||
* Shortly after /AS rises, the SPI transfer engine begins
|
|
||||||
* transferring the latched value.
|
|
||||||
*/
|
|
||||||
/* WRC: Write Command
|
|
||||||
* The command encoded in address bits A[9:2] is sent to the command target
|
|
||||||
* corresponding to the address bits A[15:10].
|
|
||||||
* Command targets:
|
|
||||||
* $00 - Set bitbang
|
|
||||||
* A[2] - SCS value
|
|
||||||
*/
|
|
||||||
/* RDRXR: Read Receive Data Register
|
|
||||||
* The the current RXR is returned in D[31:16] and the cycle completes.
|
|
||||||
*/
|
|
||||||
/* RDRXRS: Read Receive Data Register Swapped
|
|
||||||
* Same as RDRXR but read data is byte-swapped.
|
|
||||||
*/
|
|
||||||
/* MAGIC: Write Command
|
|
||||||
* Write sequence $FF $00 $55 $AA $C1 $AD
|
|
||||||
* to enable registers at $40890000-$4097FFFF.
|
|
||||||
* Write anything else to disable them.
|
|
||||||
* Always reads 0xC1AD
|
|
||||||
*/
|
|
||||||
|
|
||||||
// SPI controller address map:
|
|
||||||
// 40940000-4097FFFF (256 kB, D[31:16]) T16S. Write transfer data in A[17:2].
|
|
||||||
// 40900000-4093FFFF (256 kB, D[31:16]) T16. Write transfer data in A[17:2].
|
|
||||||
// 408C0000-408FFFFF (320 kB) reserved
|
|
||||||
// 408A0000-408AFFFF ( 64 kB, D[31:24]) WRC. Write port address in A[15:10] and data in A[9:2].
|
|
||||||
// 40891C00-4089FFFF ( 55 kB) reserved
|
|
||||||
// 40892000-408923FF ( 1 kB, D[31:24]) MERT.
|
|
||||||
// 40891C00-40891FFF ( 1 kB) SKIP1. Write bytes to skip in A[9:2].
|
|
||||||
// 40891800-40891BFF ( 1 kB) SKIP0. Write bytes to skip in A[9:2].
|
|
||||||
// 40891400-408917FF ( 1 kB, D[31:16]) T8S. Write transfer data in A[9:2].
|
|
||||||
// 40891000-408913FF ( 1 kB, D[31:16]) T8. Write transfer data in A[9:2].
|
|
||||||
// 40890C00-40890FFF ( 1 kB, D[31:16]) RDRXRS.
|
|
||||||
// 40890800-40890BFF ( 1 kB, D[31:16]) RDRXR.
|
|
||||||
// 40890400-408907FF ( 1 kB) reserved
|
|
||||||
// 40890000-408903FF ( 1 kB, D[31:24]) MAGIC. Write magic numbers in A[9:2].
|
|
||||||
// 40880000-408FFFFF ( 64 kB, D[31:00]) ROMBUS driver data
|
|
||||||
|
|
||||||
#define RB_T16S(x) (*(volatile int*) (0x40940000 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_T16(x) (*(volatile int*) (0x40900000 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_RDS(a) (*(volatile char*) (0x408B0000 + ((a && 0x003F)<<10)) )
|
|
||||||
#define RB_WRC(a,d) (*(volatile char*) (0x408A0000 + ((a && 0x003F)<<10)
|
|
||||||
+ ((d && 0x00FF)<<02)) )
|
|
||||||
#define RB_MERT(x) (*(volatile char*) (0x40892000 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_SKIP1(n) (*(volatile char*) (0x40891C00 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_SKIP0(n) (*(volatile char*) (0x40891800 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_T8S(x) (*(volatile int*) (0x40891400 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_T8(x) (*(volatile int*) (0x40891000 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_RDRXRS (*(volatile int*) (0x40890C00 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_RDRXR (*(volatile int*) (0x40890800 + ((x && 0xFFFF)<<02)) )
|
|
||||||
#define RB_WRMOSI(x) (*(volatile char*) (0x40890400 + ((x && 0x0001)<<02)) )
|
|
||||||
#define RB_MAGIC(x) (*(volatile char*) (0x40890000 + ((x && 0xFFFF)<<02)) )
|
|
||||||
|
|
||||||
#define SPI_GET_MISO(d) (d & 1)
|
|
||||||
|
|
||||||
void spi_select() {
|
|
||||||
ret = *SPI_CMD_SEL0;
|
|
||||||
ret = *SPI_CMD_SEL1;
|
|
||||||
ret = *SPI_CMD_SEL2;
|
|
||||||
ret = *SPI_CMD_SEL3;
|
|
||||||
}
|
|
||||||
void spi_deselect() {
|
|
||||||
ret = *SPI_CMD_DES0;
|
|
||||||
ret = *SPI_CMD_DES1;
|
|
||||||
ret = *SPI_CMD_DES2;
|
|
||||||
ret = *SPI_CMD_DES3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spi_tx_slow(char d) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
*SPI_CMD_BBA((0 & 0x02) | (d & 0x01));
|
|
||||||
*SPI_CMD_BBA((1 & 0x02) | (d & 0x01));
|
|
||||||
d >>= 1;
|
|
||||||
}
|
|
||||||
*SPI_CMD_BBA((0 & 0x02) | (0 & 0x01));
|
|
||||||
}
|
|
||||||
|
|
||||||
char spi_rx_slow() {
|
|
||||||
char ret = 0;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
|
||||||
*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01));
|
|
||||||
ret = (ret << 1) + (*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01)) & 1);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spi_skip_slow(int n) {
|
|
||||||
while (n-- > 0) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
|
||||||
*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
|
||||||
}
|
|
||||||
|
|
||||||
void spi_tx_8(char d) {
|
|
||||||
*SPI_CMD_SH8(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
char spi_rx_8() {
|
|
||||||
*SPI_CMD_SH8(0xFF);
|
|
||||||
return *SPI_CMD_RD & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spi_tx_16(int d) {
|
|
||||||
*SPI_CMD_SH16(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
int spi_rx_16() {
|
|
||||||
*SPI_CMD_SH16(0xFFFF);
|
|
||||||
return *SPI_CMD_RD & 0xFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spi_skip(int n) {
|
|
||||||
while (n-- > 0) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
*SPI_CMD_SH8(0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
17
old/spi.h
17
old/spi.h
|
@ -1,17 +0,0 @@
|
||||||
#ifndef SPI_H
|
|
||||||
#define SPI_H
|
|
||||||
|
|
||||||
void spi_select();
|
|
||||||
void spi_deselect();
|
|
||||||
|
|
||||||
void spi_tx_slow(char d);
|
|
||||||
char spi_rx_slow();
|
|
||||||
void spi_skip_slow(int n);
|
|
||||||
|
|
||||||
void spi_tx_8(char d);
|
|
||||||
char spi_rx_8();
|
|
||||||
void spi_tx_16(int d);
|
|
||||||
int spi_rx_16();
|
|
||||||
void spi_skip(int n);
|
|
||||||
|
|
||||||
#endif
|
|
11
old/xfer.h
11
old/xfer.h
|
@ -1,11 +0,0 @@
|
||||||
#ifndef RDISK_H
|
|
||||||
#define RDISK_H
|
|
||||||
|
|
||||||
#pragma parameter xfer_s_256(__A0, __A1)
|
|
||||||
void xfer_s_256(Ptr srcreg, Ptr destmem);
|
|
||||||
|
|
||||||
#pragma parameter xfer_s(__D0, __A0, __A1)
|
|
||||||
void xfer_s(uint8_t numBytes, Ptr srcreg, Ptr destmem);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
34
old/xfer.s
34
old/xfer.s
|
@ -1,34 +0,0 @@
|
||||||
.macro xfer_in from, to
|
|
||||||
move.w (%A0), (%A1)+
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
.if \to-\from
|
|
||||||
xfer_in "(\from+1)"
|
|
||||||
.else
|
|
||||||
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
|
|
||||||
;pragma parameter xfer_s_256(__A0, __A1)
|
|
||||||
;void xfer_s_256(Ptr srcreg, Ptr destmem);
|
|
||||||
xfer_256:
|
|
||||||
movem.l %D0/%A1-%A2, -(%SP)
|
|
||||||
xfer_256_loop:
|
|
||||||
xfer_s_in 0, 255
|
|
||||||
xfer_256_end:
|
|
||||||
movem.l (%SP)+, %D0/%A1-%A2
|
|
||||||
|
|
||||||
|
|
||||||
;pragma parameter xfer_s(__D0, __A0, __A1)
|
|
||||||
;void xfer_s(uint8_t numBytes, Ptr srcreg, Ptr destmem);
|
|
||||||
xfer:
|
|
||||||
movem.l %D0/%A1-%A2, -(%SP)
|
|
||||||
andi.l #0xFF, %D0
|
|
||||||
subi.l #256, %D0
|
|
||||||
neg.l %D0
|
|
||||||
lsl.l #2, %D0
|
|
||||||
addi.l #xfer_256, %D0
|
|
||||||
movea.l %D0, %A2
|
|
||||||
jmp %A2
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef _PRIV_SYSCALL_H
|
||||||
|
#define _PRIV_SYSCALL_H
|
||||||
|
|
||||||
|
#include <Disks.h>
|
||||||
|
#include <OSUtils.h>
|
||||||
|
|
||||||
|
#pragma parameter __D0 PSReadXPRAM(__D0, __D1, __A0)
|
||||||
|
OSErr PSReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
||||||
|
|
||||||
|
#pragma parameter __D0 PSAddDrive(__D1, __D0, __A0)
|
||||||
|
OSErr PSAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
||||||
|
|
||||||
|
// Figure out the first available drive number >= 5
|
||||||
|
static int PSFindDrvNum() {
|
||||||
|
DrvQElPtr dq;
|
||||||
|
int drvNum = 5;
|
||||||
|
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
||||||
|
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
||||||
|
}
|
||||||
|
return drvNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
100
rdisk.c
100
rdisk.c
|
@ -1,100 +0,0 @@
|
||||||
#include <Memory.h>
|
|
||||||
#include <Devices.h>
|
|
||||||
#include <Files.h>
|
|
||||||
#include <Disks.h>
|
|
||||||
#include <Errors.h>
|
|
||||||
#include <Events.h>
|
|
||||||
#include <OSUtils.h>
|
|
||||||
#include <Quickdraw.h>
|
|
||||||
|
|
||||||
#include "rombus.h"
|
|
||||||
#include "rdisk.h"
|
|
||||||
|
|
||||||
OSErr RDOpen(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Find first available drive number for ROM drive
|
|
||||||
drvNum = RBFindDrvNum();
|
|
||||||
// Set ROM drive status
|
|
||||||
c->rdStatus.track = 0;
|
|
||||||
c->rdStatus.writeProt = -1; // nonzero is write protected
|
|
||||||
c->rdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
c->rdStatus.installed = 1; // drive installed
|
|
||||||
c->rdStatus.sides = 0;
|
|
||||||
c->rdStatus.qType = 0;
|
|
||||||
c->rdStatus.dQDrive = drvNum;
|
|
||||||
c->rdStatus.dQFSID = 0;
|
|
||||||
c->rdStatus.dQRefNum = d->dCtlRefNum;
|
|
||||||
c->rdStatus.driveSize = RDiskSize / 512;
|
|
||||||
//c->rdStatus.driveS1 = (RDiskSize / 512) >> 16;
|
|
||||||
// Decompress ROM disk icon
|
|
||||||
src = &RDiskIconCompressed[0];
|
|
||||||
dst = &c->rdIcon[0];
|
|
||||||
UnpackBits(&src, &dst, RDISK_ICON_SIZE);
|
|
||||||
// Add ROM disk to drive queue and return
|
|
||||||
return RBAddDrive(c->rdStatus.dQRefNum, c->rdStatus.dQDrive, (DrvQElPtr)&c->rdStatus.qLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr RDPrime(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Return disk offline error if virtual disk not inserted
|
|
||||||
if (!c->rdStatus.diskInPlace) { return offLinErr; }
|
|
||||||
|
|
||||||
// Get pointer to ROM disk buffer
|
|
||||||
disk = RDiskBuf + d->dCtlPosition;
|
|
||||||
// Bounds checking
|
|
||||||
if (d->dCtlPosition >= RDiskSize || p->ioReqCount >= RDiskSize ||
|
|
||||||
d->dCtlPosition + p->ioReqCount >= RDiskSize) { return paramErr; }
|
|
||||||
|
|
||||||
// Service read or write request
|
|
||||||
cmd = p->ioTrap & 0x00FF;
|
|
||||||
if (cmd == aRdCmd) { // Read
|
|
||||||
// Read from disk into buffer.
|
|
||||||
if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); }
|
|
||||||
else { copy24(disk, StripAddress(p->ioBuffer), p->ioReqCount); }
|
|
||||||
} else if (cmd == aWrCmd) { return wPrErr;
|
|
||||||
} else { return noErr; } //FIXME: Fail if cmd isn't read or write?
|
|
||||||
|
|
||||||
// Update count and 1position/offset, then return
|
|
||||||
d->dCtlPosition += p->ioReqCount;
|
|
||||||
p->ioActCount = p->ioReqCount;
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr RDCtl(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Handle control request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kFormat: return controlErr;
|
|
||||||
case kVerify:
|
|
||||||
if (!c->rdStatus.diskInPlace) { return controlErr; }
|
|
||||||
return noErr;
|
|
||||||
case kEject:
|
|
||||||
// "Reinsert" disk if ejected illegally
|
|
||||||
if (c->rdStatus.diskInPlace) {
|
|
||||||
PostEvent(diskEvt, c->rdStatus.dQDrive);
|
|
||||||
}
|
|
||||||
return controlErr; // Eject not allowed so return error
|
|
||||||
case kDriveIcon: case kMediaIcon: // Get icon
|
|
||||||
*(Ptr*)p->csParam = (Ptr)c->rdIcon;
|
|
||||||
return noErr;
|
|
||||||
case kDriveInfo:
|
|
||||||
// high word (bytes 2 & 3) clear
|
|
||||||
// byte 1 = primary + fixed media + internal
|
|
||||||
// byte 0 = drive type (0x10 is RAM disk) / (0x11 is ROM disk)
|
|
||||||
*(long*)p->csParam = 0x00000411;
|
|
||||||
return noErr;
|
|
||||||
case 24: // Return SCSI partition size
|
|
||||||
*(long*)p->csParam = RDiskSize / 512;
|
|
||||||
return noErr;
|
|
||||||
default: return controlErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr RDStat(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Handle status request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kDriveStatus:
|
|
||||||
BlockMove(&c->rdStatus, &p->csParam, sizeof(DrvSts2));
|
|
||||||
return noErr;
|
|
||||||
default: return statusErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RDClose(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c) { }
|
|
101
rdisk.h
101
rdisk.h
|
@ -1,101 +0,0 @@
|
||||||
#ifndef RDISK_H
|
|
||||||
#define RDISK_H
|
|
||||||
|
|
||||||
#include "rombus.h"
|
|
||||||
|
|
||||||
#define RDiskBuf ((char*)0x40880000)
|
|
||||||
#define RDiskSize (*(const unsigned long*)0x40851D98)
|
|
||||||
|
|
||||||
OSErr RDOpen(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr RDInit(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr RDPrime(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr RDCtl(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr RDStat(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr RDClose(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
|
|
||||||
#define RDISK_ICON_SIZE (285)
|
|
||||||
#define RDISK_COMPRESSED_ICON_SIZE (87)
|
|
||||||
const char RDiskIconCompressed[RDISK_COMPRESSED_ICON_SIZE] = {
|
|
||||||
PackBits_Repeat(76), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Repeat(4), 0b11111111, /*
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(36),
|
|
||||||
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
|
||||||
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
|
||||||
PackBits_Repeat(12), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
|
|
||||||
PackBits_Repeat(76), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Repeat(32), 0b11111111, /*
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(1), 0b01111111,
|
|
||||||
PackBits_Repeat(3), 0b11111111, /*
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(1), 0b01111111,
|
|
||||||
PackBits_Repeat(3), 0b11111111, /*
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Repeat(12), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Literal(29),
|
|
||||||
27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
|
||||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
|
||||||
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
276
rombus.c
276
rombus.c
|
@ -5,53 +5,71 @@
|
||||||
#include <Errors.h>
|
#include <Errors.h>
|
||||||
#include <Events.h>
|
#include <Events.h>
|
||||||
#include <OSUtils.h>
|
#include <OSUtils.h>
|
||||||
#include <Quickdraw.h>
|
|
||||||
|
|
||||||
#include "rombus.h"
|
#include "rombus.h"
|
||||||
#include "rdisk.h"
|
#include "spi.h"
|
||||||
#include "sdisk.h"
|
#include "priv_syscall.h"
|
||||||
|
|
||||||
// Decode keyboard/PRAM settings
|
// Decode keyboard settings
|
||||||
static void RBDecodeSettings(Ptr unmountROM, Ptr unmountSD, Ptr mountSD) {
|
static void RBDecodeKeySettings(RBStorage_t *c) {
|
||||||
// Sample R, S, X keys repeatedly
|
// Sample R, S, X keys repeatedly
|
||||||
char r = 0, s = 0, x = 0;
|
char r = 0, s = 0, x = 0;
|
||||||
long tmax = TickCount() + 60;
|
long tmax = TickCount() + 60;
|
||||||
for (long i = 0; i < 1000000; i++) {
|
for (long i = 0; i < 1000000; i++) {
|
||||||
r |= RBIsRPressed();
|
r |= IsRPressed();
|
||||||
s |= RBIsSPressed();
|
s |= IsSPressed();
|
||||||
x |= RBIsXPressed();
|
x |= IsXPressed();
|
||||||
if (r || s || x) { break; }
|
if (r || s || x) { break; }
|
||||||
if (TickCount() > tmax) { break; }
|
if (TickCount() > tmax) { break; }
|
||||||
}
|
}
|
||||||
|
// Decode settings
|
||||||
// Read PRAM
|
if (x) { // Unmount everything
|
||||||
char legacy_startup;
|
c->unmountROMEN = 1;
|
||||||
RBReadXPRAM(1, 4, &legacy_startup);
|
c->unmountSDEN = 1;
|
||||||
|
c->mountROMEN = 0;
|
||||||
// Decode settings: unmount (don't boot), mount (after boot), RAM disk
|
c->mountSDEN = 0;
|
||||||
if (x) { // X disables SD
|
} else if (s) { // Boot from SD, don't mount ROM
|
||||||
*unmountROM = 1; // Unmount ROM disk volume
|
c->unmountROMEN = 1;
|
||||||
*unmountSD = 1; // Unmount SD volume
|
c->unmountSDEN = 0;
|
||||||
*mountSD = 0; // Don't mount SD later
|
c->mountROMEN = 1;
|
||||||
} else if (r) { // R boots from ROM disk and mount SD later
|
c->mountSDEN = 0;
|
||||||
*unmountROM = 0; // Don't unmount so we boot from ROM
|
} else if (r) { // Boot from ROM, mount SD
|
||||||
*unmountSD = 1; // Unmount SD volume so we don't boot from it
|
c->unmountROMEN = 0;
|
||||||
*mountSD = 1; // Mount SD later
|
c->unmountSDEN = 1;
|
||||||
} else if (s) { // S boots from SD
|
c->mountROMEN = 0;
|
||||||
*unmountROM = 1; // Unmount ROM disk volume so we don't boot from it
|
c->mountSDEN = 1;
|
||||||
*unmountSD = 0; // Don't unmount so we boot from SD
|
|
||||||
*mountSD = 0; // No need to mount SD later since already mounted
|
|
||||||
} else if (legacy_startup & 0x04) { // Boot from SD
|
|
||||||
*unmountROM = 1; // Unmount ROM disk volume so we don't boot from it
|
|
||||||
*unmountSD = 0; // Don't unmount so we boot from SD
|
|
||||||
*mountSD = 0; // No need to mount later since already mounted
|
|
||||||
} else {
|
|
||||||
*unmountROM = !(legacy_startup & 0x01); // Unmount ROM disk if saved in PRAM
|
|
||||||
*unmountSD = 1; // Unmount SD volume so we don't boot from it
|
|
||||||
*mountSD = !(legacy_startup & 0x08); // Mount SD later if setting
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode PRAM settings
|
||||||
|
static OSErr RBDecodePRAMSettings(RBStorage_t *c) {
|
||||||
|
// Read PRAM
|
||||||
|
char legacy_startup, legacy_ram;
|
||||||
|
PSReadXPRAM(1, 4, &legacy_startup);
|
||||||
|
PSReadXPRAM(1, 5, &legacy_ram);
|
||||||
|
|
||||||
|
// Decoded settings
|
||||||
|
const char opt_disable = legacy_startup & (1<<7);
|
||||||
|
const char opt_boot_sd = legacy_startup & (1<<2);
|
||||||
|
const char opt_boot_rom = legacy_startup & (1<<0);
|
||||||
|
const char opt_mount_sd = legacy_startup & (1<<3);
|
||||||
|
const char opt_mount_rom = legacy_startup & (1<<4);
|
||||||
|
|
||||||
|
// Old settings for ROM SIMM (not used here)
|
||||||
|
//const char opt_old_mount_rom = !(legacy_startup & (1<<1));
|
||||||
|
//const char opt_old_ram = legacy_ram & (1<<0);
|
||||||
|
|
||||||
|
// Set based on decoded settings
|
||||||
|
if (opt_disable) { return -1; }
|
||||||
|
else {
|
||||||
|
c->unmountROMEN = !opt_boot_rom;
|
||||||
|
c->unmountSDEN = !opt_boot_sd;
|
||||||
|
c->mountROMEN = opt_mount_rom && !opt_boot_rom;
|
||||||
|
c->mountSDEN = opt_mount_sd && !opt_boot_sd;
|
||||||
|
}
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
// Switch to 32-bit mode and copy
|
// Switch to 32-bit mode and copy
|
||||||
#pragma parameter C24(__A0, __A1, __D0)
|
#pragma parameter C24(__A0, __A1, __D0)
|
||||||
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
||||||
|
@ -61,31 +79,24 @@ void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long by
|
||||||
SwapMMUMode(&mode);
|
SwapMMUMode(&mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out the first available drive number >= 5
|
#pragma parameter __D0 RBClose(__A0, __A1)
|
||||||
static int RBFindDrvNum() {
|
OSErr RBClose(IOParamPtr p, DCtlPtr d) {
|
||||||
DrvQElPtr dq;
|
// If dCtlStorage not null, dispose of it
|
||||||
int drvNum = 5;
|
if (!d->dCtlStorage) { return noErr; }
|
||||||
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
HUnlock(d->dCtlStorage);
|
||||||
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
DisposeHandle(d->dCtlStorage);
|
||||||
}
|
d->dCtlStorage = NULL;
|
||||||
return drvNum;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma parameter __D0 RBOpen(__A0, __A1)
|
#pragma parameter __D0 RBOpen(__A0, __A1)
|
||||||
OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
||||||
int drvNum;
|
int drvNum;
|
||||||
RBStorage_t *c;
|
RBStorage_t *c;
|
||||||
char legacy_startup;
|
|
||||||
char *src, *dst;
|
|
||||||
OSErr ret;
|
|
||||||
|
|
||||||
// Do nothing if already opened
|
// Do nothing if already opened
|
||||||
if (d->dCtlStorage) { return noErr; }
|
if (d->dCtlStorage) { return noErr; }
|
||||||
|
|
||||||
// Do nothing if inhibited
|
|
||||||
RBReadXPRAM(1, 4, &legacy_startup);
|
|
||||||
if (legacy_startup & 0x80) { return noErr; }
|
|
||||||
|
|
||||||
// Allocate storage struct
|
// Allocate storage struct
|
||||||
d->dCtlStorage = NewHandleSysClear(sizeof(RBStorage_t));
|
d->dCtlStorage = NewHandleSysClear(sizeof(RBStorage_t));
|
||||||
if (!d->dCtlStorage) { return openErr; }
|
if (!d->dCtlStorage) { return openErr; }
|
||||||
|
@ -94,36 +105,67 @@ OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
||||||
HLock(d->dCtlStorage);
|
HLock(d->dCtlStorage);
|
||||||
c = *(RBStorage_t**)d->dCtlStorage;
|
c = *(RBStorage_t**)d->dCtlStorage;
|
||||||
|
|
||||||
// Populate both drives' DrvSts and add each to drive queue
|
// Do nothing if inhibited
|
||||||
if (ret = RDOpen(p, d ,c) != noErr) { return ret; }
|
if (RBDecodePRAMSettings(c) != noErr) {
|
||||||
if (ret = SDOpen(p, d ,c) != noErr) { return ret; }
|
RBClose(p, d);
|
||||||
|
return openErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iff mount enabled, enable accRun to post disk inserted event later
|
||||||
|
if (c->mountROMEN || c->mountSDEN) { d->dCtlFlags |= dNeedTimeMask; }
|
||||||
|
else { d->dCtlFlags &= ~dNeedTimeMask; }
|
||||||
|
|
||||||
|
// Set accRun delay
|
||||||
|
d->dCtlDelay = 150; // (150 ticks is 2.5 sec.)
|
||||||
|
|
||||||
|
// Find first available drive number
|
||||||
|
drvNum = PSFindDrvNum();
|
||||||
|
|
||||||
|
//TODO: set c->sdSize
|
||||||
|
|
||||||
|
// Set drive status
|
||||||
|
c->sdStatus.track = 0;
|
||||||
|
c->sdStatus.writeProt = 0; // nonzero is write protected
|
||||||
|
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||||
|
c->sdStatus.installed = 1; // drive installed
|
||||||
|
c->sdStatus.sides = 0;
|
||||||
|
c->sdStatus.qType = 1;
|
||||||
|
c->sdStatus.dQDrive = drvNum;
|
||||||
|
c->sdStatus.dQFSID = 0;
|
||||||
|
c->sdStatus.dQRefNum = d->dCtlRefNum;
|
||||||
|
c->sdStatus.driveSize = c->sdSize / 512;
|
||||||
|
c->sdStatus.driveS1 = (c->sdSize / 512) >> 16;
|
||||||
|
|
||||||
|
// Decompress icon
|
||||||
|
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||||
|
char *src = &SDIconCompressed[0];
|
||||||
|
char *dst = &c->sd[0];
|
||||||
|
UnpackBits(&src, &dst, RB_ICON_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add drive to drive queue and return
|
||||||
|
PSAddDrive(c->sdStatus.dQRefNum, drvNum, (DrvQElPtr)&c->sdStatus.qLink);
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init is called at beginning of first prime (read/write) call
|
// Init is called at beginning of first prime (read/write) call
|
||||||
static void RBInit(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
static void RBBootInit(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
||||||
char unmountROM, unmountSD;
|
|
||||||
// Mark init done
|
// Mark init done
|
||||||
c->initialized = 1;
|
c->initialized = 1;
|
||||||
// Decode settings
|
|
||||||
RBDecodeSettings(&unmountROM, &c->mountROM, &unmountSD, &c->mountSD);
|
|
||||||
|
|
||||||
// Unmount if requested
|
// Decode key settings
|
||||||
if (unmountROM) { c->rdStatus.diskInPlace = 0; }
|
RBDecodeKeySettings(c);
|
||||||
if (unmountSD) { c->sdStatus.diskInPlace = 0; }
|
|
||||||
|
|
||||||
// If mount enabled, enable accRun to post disk inserted event later
|
// Unmount if not booting from ROM disk
|
||||||
if (c->mountROM || c->mountSD) {
|
if (c->unmountSDEN) { c->sdStatus.diskInPlace = 0; }
|
||||||
d->dCtlDelay = 150; // Set accRun delay (150 ticks is 2.5 sec.)
|
|
||||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
// Iff mount disabled, disable accRun
|
||||||
}
|
if (!c->mountSDEN || !c->mountROMEN) { d->dCtlFlags &= ~dNeedTimeMask; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma parameter __D0 RBPrime(__A0, __A1)
|
#pragma parameter __D0 RBPrime(__A0, __A1)
|
||||||
OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
||||||
RBStorage_t *c;
|
RBStorage_t *c;
|
||||||
char cmd;
|
|
||||||
Ptr disk;
|
|
||||||
|
|
||||||
// Return disk offline error if dCtlStorage null
|
// Return disk offline error if dCtlStorage null
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
if (!d->dCtlStorage) { return notOpenErr; }
|
||||||
|
@ -131,13 +173,17 @@ OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
||||||
c = *(RBStorage_t**)d->dCtlStorage;
|
c = *(RBStorage_t**)d->dCtlStorage;
|
||||||
|
|
||||||
// Initialize if this is the first prime call
|
// Initialize if this is the first prime call
|
||||||
if (!c->initialized) { RBInit(p, d, c); }
|
if (!c->initialized) { RBBootInit(p, d, c); }
|
||||||
|
|
||||||
switch (p->ioVRefNum) {
|
// Return disk offline error if virtual disk not inserted
|
||||||
case c->rdStatus.dQDrive: return RDPrime(p, d, c);
|
if (!c->sdStatus.diskInPlace) { return offLinErr; }
|
||||||
case c->sdStatus.dQDrive: return SDPrime(p, d, c);
|
|
||||||
default: return statusErr;
|
//TODO: Read/write
|
||||||
}
|
|
||||||
|
// Update count and position/offset, then return
|
||||||
|
d->dCtlPosition += p->ioReqCount;
|
||||||
|
p->ioActCount = p->ioReqCount;
|
||||||
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma parameter __D0 RBCtl(__A0, __A1)
|
#pragma parameter __D0 RBCtl(__A0, __A1)
|
||||||
|
@ -147,60 +193,60 @@ OSErr RBCtl(CntrlParamPtr p, DCtlPtr d) {
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
if (!d->dCtlStorage) { return notOpenErr; }
|
||||||
// Dereference dCtlStorage to get pointer to our context
|
// Dereference dCtlStorage to get pointer to our context
|
||||||
c = *(RBStorage_t**)d->dCtlStorage;
|
c = *(RBStorage_t**)d->dCtlStorage;
|
||||||
// Handle control request csCodes common to both volumes
|
// Handle control request based on csCode
|
||||||
switch (p->csCode) {
|
switch (p->csCode) {
|
||||||
case killCode: return noErr;
|
case kFormat:
|
||||||
case accRun:
|
if (!c->sdStatus.diskInPlace || c->sdStatus.writeProt) {
|
||||||
if (c->mountSD) { // Request to mount SD disk
|
return controlErr;
|
||||||
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
PostEvent(diskEvt, c->sdStatus.dQDrive); // Post disk inserted event
|
|
||||||
return noErr;
|
|
||||||
} else if (c->mountROM) { // Request to mount ROM disk
|
|
||||||
c->rdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
PostEvent(diskEvt, c->rdStatus.dQDrive); // Post disk inserted event
|
|
||||||
return noErr;
|
|
||||||
} else { // Nothing to mount
|
|
||||||
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
|
||||||
return noErr;
|
|
||||||
}
|
}
|
||||||
case 2351: // Post-boot
|
//TODO: Format
|
||||||
c->initialized = 1; // Skip initialization
|
|
||||||
d->dCtlDelay = 30; // Set accRun delay (30 ticks is 0.5 sec.)
|
|
||||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
case kVerify:
|
||||||
// Dispatch based on volume reference number
|
if (!c->sdStatus.diskInPlace) { return controlErr; }
|
||||||
switch (p->ioVRefNum) {
|
return noErr;
|
||||||
case c->rdStatus.dQDrive: return RDCtl(p, d, c);
|
case accRun:
|
||||||
case c->sdStatus.dQDrive: return SDCtl(p, d, c);
|
c->initialized = 1; // Mark init done
|
||||||
|
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||||
|
PostEvent(diskEvt, c->sdStatus.dQDrive); // Post disk inserted event
|
||||||
|
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
||||||
|
return noErr;
|
||||||
|
case kDriveIcon: case kMediaIcon: // Get icon
|
||||||
|
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||||
|
*(Ptr*)p->csParam = (Ptr)c->sd;
|
||||||
|
#else
|
||||||
|
*(Ptr*)p->csParam = (Ptr)RDiskIcon;
|
||||||
|
#endif
|
||||||
|
return noErr;
|
||||||
|
case kDriveInfo:
|
||||||
|
// high word (bytes 2 & 3) clear
|
||||||
|
// byte 1 = primary + fixed media + internal
|
||||||
|
// byte 0 = drive type (0x10 is RAM disk) / (0x11 is ROM disk)
|
||||||
|
if (c->sdStatus.writeProt) { *(long*)p->csParam = 0x00000400; }
|
||||||
|
else { *(long*)p->csParam = 0x00000400; }
|
||||||
|
return noErr;
|
||||||
|
case 24: // Return SCSI partition size
|
||||||
|
*(long*)p->csParam = c->sdSize / 512;
|
||||||
|
return noErr;
|
||||||
|
case killCode: return noErr;
|
||||||
|
case kEject:
|
||||||
|
// "Reinsert" disk if ejected illegally
|
||||||
|
if (c->sdStatus.diskInPlace) {
|
||||||
|
PostEvent(diskEvt, c->sdStatus.dQDrive);
|
||||||
|
}
|
||||||
|
return controlErr; // Eject not allowed so return error
|
||||||
default: return controlErr;
|
default: return controlErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma parameter __D0 RBStat(__A0, __A1)
|
#pragma parameter __D0 RBStat(__A0, __A1)
|
||||||
OSErr RBStat(CntrlParamPtr p, DCtlPtr d) {
|
OSErr RBStat(CntrlParamPtr p, DCtlPtr d) {
|
||||||
RBStorage_t *c;
|
|
||||||
// Fail if dCtlStorage null
|
// Fail if dCtlStorage null
|
||||||
if (!d->dCtlStorage) { return notOpenErr; }
|
if (!d->dCtlStorage) { return notOpenErr; }
|
||||||
// Dereference dCtlStorage to get pointer to our context
|
// Handle status request based on csCode
|
||||||
c = *(RBStorage_t**)d->dCtlStorage;
|
switch (p->csCode) {
|
||||||
// Dispatch based on volume reference number
|
case kDriveStatus:
|
||||||
switch (p->ioVRefNum) {
|
BlockMove(*d->dCtlStorage, &p->csParam, sizeof(DrvSts2));
|
||||||
case c->rdStatus.dQDrive: return RDStat(p, d, c);
|
return noErr;
|
||||||
case c->sdStatus.dQDrive: return SDStat(p, d, c);
|
|
||||||
default: return statusErr;
|
default: return statusErr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma parameter __D0 RBClose(__A0, __A1)
|
|
||||||
OSErr RBClose(IOParamPtr p, DCtlPtr d) {
|
|
||||||
// If dCtlStorage not null, dispose of it
|
|
||||||
if (!d->dCtlStorage) { return noErr; }
|
|
||||||
RBStorage_t *c = *(RBStorage_t**)d->dCtlStorage;
|
|
||||||
RDClose(p, d, c);
|
|
||||||
SDClose(p, d, c);
|
|
||||||
HUnlock(d->dCtlStorage);
|
|
||||||
DisposeHandle(d->dCtlStorage);
|
|
||||||
d->dCtlStorage = NULL;
|
|
||||||
return noErr;
|
|
||||||
}
|
|
||||||
|
|
207
rombus.h
207
rombus.h
|
@ -1,36 +1,201 @@
|
||||||
#ifndef ROMBUS_H
|
#ifndef _RDISK_H
|
||||||
#define ROMBUS_H
|
#define _RDISK_H
|
||||||
|
|
||||||
#define BufPtr ((Ptr*)0x10C)
|
#define RDiskBuf ((char*)0x40880000)
|
||||||
#define MemTop ((Ptr*)0x108)
|
|
||||||
#define MMU32bit ((char*)0xCB2)
|
#define MMU32bit ((char*)0xCB2)
|
||||||
|
|
||||||
#pragma parameter __D0 RBReadXPRAM(__D0, __D1, __A0)
|
#define RDiskDBGDisPos (*(const unsigned long*)0x40851D98)
|
||||||
OSErr RBReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
#define RDiskCDRDisPos (*(const unsigned long*)0x40851D9C)
|
||||||
|
#define RDiskDBGDisByte (*(const char*)0x40851DA8)
|
||||||
|
#define RDiskCDRDisByte (*(const char*)0x40851DA9)
|
||||||
|
#define RDiskSize (*(const unsigned long*)0x40851DAC)
|
||||||
|
|
||||||
#pragma parameter __D0 RBAddDrive(__D1, __D0, __A0)
|
#define RB_COMPRESS_ICON_ENABLE
|
||||||
OSErr RBAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
|
||||||
|
|
||||||
static inline char RBIsSPressed() { return *((volatile char*)0x174) & 0x02; }
|
static inline char IsRPressed() { return *((volatile char*)0x175) & 0x80; }
|
||||||
static inline char RBIsXPressed() { return *((volatile char*)0x174) & 0x80; }
|
static inline char IsSPressed() { return *((volatile char*)0x174) & 0x02; }
|
||||||
static inline char RBIsRPressed() { return *((volatile char*)0x175) & 0x80; }
|
static inline char IsXPressed() { return *((volatile char*)0x174) & 0x80; }
|
||||||
|
|
||||||
#define RDISK_ICON_SIZE (285)
|
#define RB_ICON_SIZE (285)
|
||||||
#define SDISK_ICON_SIZE (285)
|
typedef struct RDiskStorage_s {
|
||||||
typedef struct RBStorage_s {
|
|
||||||
DrvSts2 rdStatus;
|
|
||||||
DrvSts2 sdStatus;
|
DrvSts2 sdStatus;
|
||||||
|
long long sdSize;
|
||||||
|
|
||||||
char initialized;
|
char initialized;
|
||||||
char mountROM;
|
|
||||||
char mountSD;
|
char unmountSDEN;
|
||||||
char rdIcon[RDISK_ICON_SIZE+8];
|
char mountSDEN;
|
||||||
char sdIcon[SDISK_ICON_SIZE+8];
|
char unmountROMEN;
|
||||||
|
char mountROMEN;
|
||||||
|
|
||||||
|
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||||
|
char sd[RB_ICON_SIZE+8];
|
||||||
|
#endif
|
||||||
} RBStorage_t;
|
} RBStorage_t;
|
||||||
|
|
||||||
typedef void (*RBCopy_t)(Ptr, Ptr, unsigned long);
|
typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long);
|
||||||
#define copy24(s, d, b) { RBCopy_t f = C24; f(s, d, b); }
|
#define copy24(s, d, b) { RDiskCopy_t f = C24; f(s, d, b); }
|
||||||
|
|
||||||
#define PackBits_Repeat(count) (-1 * (count - 1))
|
#define PackBits_Repeat(count) (-1 * (count - 1))
|
||||||
#define PackBits_Literal(count) (count - 1)
|
#define PackBits_Literal(count) (count - 1)
|
||||||
|
|
||||||
|
#define RDISK_COMPRESSED_ICON_SIZE (87)
|
||||||
|
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||||
|
#include <Quickdraw.h>
|
||||||
|
const char SDIconCompressed[RDISK_COMPRESSED_ICON_SIZE] = {
|
||||||
|
PackBits_Repeat(76), 0b00000000, /*
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
||||||
|
PackBits_Repeat(4), 0b11111111, /*
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
||||||
|
PackBits_Literal(36),
|
||||||
|
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
||||||
|
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||||
|
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
||||||
|
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
||||||
|
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
||||||
|
PackBits_Repeat(12), 0b00000000, /*
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
||||||
|
|
||||||
|
PackBits_Repeat(76), 0b00000000, /*
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
||||||
|
PackBits_Repeat(32), 0b11111111, /*
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
||||||
|
PackBits_Literal(1), 0b01111111,
|
||||||
|
PackBits_Repeat(3), 0b11111111, /*
|
||||||
|
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
||||||
|
PackBits_Literal(1), 0b01111111,
|
||||||
|
PackBits_Repeat(3), 0b11111111, /*
|
||||||
|
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
||||||
|
PackBits_Repeat(12), 0b00000000, /*
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
||||||
|
PackBits_Literal(29),
|
||||||
|
27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
||||||
|
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
||||||
|
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const char RDiskIcon[RB_ICON_SIZE] = {
|
||||||
|
// Icon
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
||||||
|
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||||
|
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||||
|
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
||||||
|
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
||||||
|
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
// Mask
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||||
|
27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
||||||
|
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
||||||
|
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
99
sdisk.c
99
sdisk.c
|
@ -1,99 +0,0 @@
|
||||||
#include <Memory.h>
|
|
||||||
#include <Devices.h>
|
|
||||||
#include <Files.h>
|
|
||||||
#include <Disks.h>
|
|
||||||
#include <Errors.h>
|
|
||||||
#include <Events.h>
|
|
||||||
#include <OSUtils.h>
|
|
||||||
#include <Quickdraw.h>
|
|
||||||
|
|
||||||
#include "rombus.h"
|
|
||||||
#include "sdisk.h"
|
|
||||||
|
|
||||||
static char SPI_SetCS(char cs) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SPI_TX8(char d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static char SPI_RX8(char d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SPI_TX8_Slow(char d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static char SPI_RX8_Slow(char d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr SDOpen(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Find first available drive number for SD drive
|
|
||||||
drvNum = RBFindDrvNum();
|
|
||||||
// Set SD drive status
|
|
||||||
c->sdStatus.track = 0;
|
|
||||||
c->sdStatus.writeProt = 0; // zero is writable
|
|
||||||
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
|
||||||
c->sdStatus.installed = 1; // drive installed
|
|
||||||
c->sdStatus.sides = 0;
|
|
||||||
c->sdStatus.qType = 1;
|
|
||||||
c->sdStatus.dQDrive = drvNum;
|
|
||||||
c->sdStatus.dQFSID = 0;
|
|
||||||
c->sdStatus.dQRefNum = d->dCtlRefNum;
|
|
||||||
c->sdStatus.driveSize = SDiskSize / 512;
|
|
||||||
c->sdStatus.driveS1 = (SDiskSize / 512) >> 16;
|
|
||||||
// Decompress SD disk icon
|
|
||||||
src = &SDiskIconCompressed[0];
|
|
||||||
dst = &c->sdIcon[0];
|
|
||||||
UnpackBits(&src, &dst, SDISK_ICON_SIZE);
|
|
||||||
// Add SD disk to drive queue and return
|
|
||||||
return RBAddDrive(c->sdStatus.dQRefNum, c->sdStatus.dQDrive, (DrvQElPtr)&c->sdStatus.qLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr SDPrime(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
return controlErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr SDCtl(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Handle control request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kFormat: return controlErr;
|
|
||||||
case kVerify:
|
|
||||||
if (!c->sdStatus.diskInPlace) { return controlErr; }
|
|
||||||
return noErr;
|
|
||||||
case kEject:
|
|
||||||
// "Reinsert" disk if ejected illegally
|
|
||||||
if (c->sdStatus.diskInPlace) {
|
|
||||||
PostEvent(diskEvt, c->sdStatus.dQDrive);
|
|
||||||
}
|
|
||||||
return controlErr; // Eject not allowed so return error
|
|
||||||
case kDriveIcon: case kMediaIcon: // Get icon
|
|
||||||
*(Ptr*)p->csParam = (Ptr)c->sdIcon;
|
|
||||||
return noErr;
|
|
||||||
case kDriveInfo:
|
|
||||||
// high word (bytes 2 & 3) clear
|
|
||||||
// byte 1 = primary + fixed media + internal
|
|
||||||
// byte 0 = drive type (0x00 is ??)
|
|
||||||
*(long*)p->csParam = 0x00000400;
|
|
||||||
return noErr;
|
|
||||||
case 24: // Return SCSI partition size
|
|
||||||
*(long*)p->csParam = SDiskSize / 512;
|
|
||||||
return noErr;
|
|
||||||
default: return controlErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OSErr SDStat(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
|
||||||
// Handle status request based on csCode
|
|
||||||
switch (p->csCode) {
|
|
||||||
case kDriveStatus:
|
|
||||||
BlockMove(&c->sdStatus, &p->csParam, sizeof(DrvSts2));
|
|
||||||
return noErr;
|
|
||||||
default: return statusErr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDClose(IOParamPtr p, DCtlPtr d, RBStorage_t *c) { }
|
|
100
sdisk.h
100
sdisk.h
|
@ -1,100 +0,0 @@
|
||||||
#ifndef SDISK_H
|
|
||||||
#define SDISK_H
|
|
||||||
|
|
||||||
#include "rombus.h"
|
|
||||||
|
|
||||||
#define SDiskSize (*(const unsigned long*)0x40851D9C)
|
|
||||||
|
|
||||||
OSErr SDOpen(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr SDInit(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr SDPrime(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr SDCtl(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr SDStat(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
OSErr SDClose(CntrlParamPtr p, DCtlPtr d, RBStorage_t *c);
|
|
||||||
|
|
||||||
#define SDISK_ICON_SIZE (285)
|
|
||||||
#define SDISK_COMPRESSED_ICON_SIZE (86)
|
|
||||||
const char SDiskIconCompressed[SDISK_COMPRESSED_ICON_SIZE] = {
|
|
||||||
PackBits_Repeat(76), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Repeat(4), 0b11111111, /*
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(36),
|
|
||||||
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
|
||||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
|
||||||
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
|
||||||
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
|
||||||
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
|
||||||
PackBits_Repeat(12), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
|
|
||||||
PackBits_Repeat(76), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Repeat(32), 0b11111111, /*
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
|
||||||
0b11111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(1), 0b01111111,
|
|
||||||
PackBits_Repeat(3), 0b11111111, /*
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Literal(1), 0b01111111,
|
|
||||||
PackBits_Repeat(3), 0b11111111, /*
|
|
||||||
0b01111111, 0b11111111, 0b11111111, 0b11111111, */
|
|
||||||
PackBits_Repeat(12), 0b00000000, /*
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
|
||||||
0b00000000, 0b00000000, 0b00000000, 0b00000000, */
|
|
||||||
PackBits_Literal(29),
|
|
||||||
26, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
|
||||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
|
||||||
'S', 'D', ' ', 'D', 'i', 's', 'k', 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include "spi.h"
|
||||||
|
#include "spi_hal.h"
|
||||||
|
|
||||||
|
static int _search_lt(char *buf, int stride, int threshold) {
|
||||||
|
for (int i = 1; i < 256; i++) {
|
||||||
|
if (buf[i * stride] < threshold) { return 1; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _spi_hal_rx8_nops, _spi_hal_tx8_nops;
|
||||||
|
int _spi_hal_rx16_nops, _spi_hal_tx16_nops;
|
||||||
|
int _spi_hal_rxtx8_nops;
|
||||||
|
|
||||||
|
short *_spi_reg_rx16;
|
||||||
|
char *_spi_reg_tx16;
|
||||||
|
short *_spi_reg_rd16;
|
||||||
|
|
||||||
|
int spi_init(int swap) {
|
||||||
|
short buf16[256];
|
||||||
|
char *buf8 = (char*)&buf16;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
spi_hal_rx8(SPI_REG_TIMER8, buf8, 256, i);
|
||||||
|
_spi_hal_rx8_nops = i;
|
||||||
|
_spi_hal_tx8_nops = i > 0 ? i - 1 : 0;
|
||||||
|
if (!_search_lt(buf8, 1, 8)) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
spi_hal_rx16(SPI_REG_TIMER16, buf16, 256, i);
|
||||||
|
_spi_hal_rx16_nops = i;
|
||||||
|
_spi_hal_tx16_nops = i > 0 ? i - 1 : 0;
|
||||||
|
if (!_search_lt(buf8, 2, 8)) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
spi_hal_rxtx8(SPI_REG_EMPTY, SPI_REG_TIMER16, buf8, buf8, 256, i);
|
||||||
|
_spi_hal_rxtx8_nops = i;
|
||||||
|
if (!_search_lt(buf8, 1, 8)) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
_spi_reg_rx16 = swap ? SPI_REG_RX16S : SPI_REG_RX16;
|
||||||
|
_spi_reg_tx16 = swap ? SPI_REG_TX16S : SPI_REG_TX16;
|
||||||
|
_spi_reg_rd16 = swap ? SPI_REG_RD16S : SPI_REG_RD16;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_cs(int cs) {
|
||||||
|
if (cs) { SPI_REG_CSR_SET_CS(); }
|
||||||
|
else { SPI_REG_CSR_CLR_CS(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
char spi_txrx8_slow(char txd) {
|
||||||
|
char rxd = 0;
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
spi_delay(64);
|
||||||
|
SPI_REG_CSR_CLR_SCK();
|
||||||
|
spi_delay(64);
|
||||||
|
SPI_REG_SET_MOSI((txd >> i) & 1);
|
||||||
|
rxd = (rxd << 1) | SPI_REG_CSR_GET_MISO();
|
||||||
|
SPI_REG_CSR_SET_SCK();
|
||||||
|
}
|
||||||
|
spi_delay(64);
|
||||||
|
SPI_REG_CSR_CLR_SCK();
|
||||||
|
return rxd;
|
||||||
|
}
|
||||||
|
|
||||||
|
char spi_txrx8(char txd) {
|
||||||
|
spi_hal_tx8(SPI_REG_TX8, &txd, 1, _spi_hal_tx8_nops);
|
||||||
|
return *SPI_REG_RD8;
|
||||||
|
}
|
||||||
|
|
||||||
|
char spi_rxtx8(char txd) {
|
||||||
|
char rxd = *SPI_REG_RD8;
|
||||||
|
spi_hal_tx8(SPI_REG_TX8, &txd, 1, _spi_hal_tx8_nops);
|
||||||
|
return rxd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UNROLL_LENGTH 5
|
||||||
|
|
||||||
|
void spi_rx(char txd, char *rxb, unsigned int length) {
|
||||||
|
if (length == 0) { return; } // Return if length 0
|
||||||
|
|
||||||
|
// Word-align rx pointer by transferring 0/1 bytes
|
||||||
|
if ((int)rxb & 1) {
|
||||||
|
*(rxb++) = spi_rxtx8(txd);
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set tx pattern
|
||||||
|
reg_write16(SPI_REG_ST16, smear8to32(txd));
|
||||||
|
|
||||||
|
// Transfer all but 0-65 bytes
|
||||||
|
for (int i = length >> (UNROLL_LENGTH +1); i > 0; i--) {
|
||||||
|
// Transfer 2^UNROLL_LENGTH words (2 * 2^UNROLL_LENGTH bytes)
|
||||||
|
spi_hal_rx16(_spi_reg_rx16, rxb, UNROLL_LENGTH, _spi_hal_rx16_nops);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer remaining 1-32 words (2-64 bytes)
|
||||||
|
spi_hal_rx16(_spi_reg_rx16, rxb, length >> 1, _spi_hal_rx16_nops);
|
||||||
|
|
||||||
|
// Transfer remaining byte if any
|
||||||
|
if (length & 1) { *(rxb++) = spi_rxtx8(txd); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_tx(char *txb, unsigned int length) {
|
||||||
|
if (length == 0) { return; } // Return if length 0
|
||||||
|
|
||||||
|
// Word-align tx pointer by transferring 0/1 bytes
|
||||||
|
if ((int)txb & 1) {
|
||||||
|
spi_rxtx8(*(txb++));
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer all but 0-65 bytes
|
||||||
|
for (; length > UNROLL_LENGTH; length -= UNROLL_LENGTH) {
|
||||||
|
spi_hal_tx16(_spi_reg_tx16, txb, UNROLL_LENGTH, _spi_hal_tx16_nops);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer remaining 1-32 words (2-64 bytes)
|
||||||
|
spi_hal_tx16(_spi_reg_tx16, txb, length >> 1, _spi_hal_tx16_nops);
|
||||||
|
|
||||||
|
// Transfer remaining byte if any
|
||||||
|
if (length & 1) { spi_rxtx8(*(txb++)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
char spi_rd8() { return *SPI_REG_RD8; }
|
||||||
|
short spi_rd16() { return *_spi_reg_rd16; }
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef _SPI_H
|
||||||
|
#define _SPI_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int spi_init();
|
||||||
|
|
||||||
|
void spi_cs(int cs);
|
||||||
|
|
||||||
|
char spi_txrx8_slow(char txd);
|
||||||
|
char spi_txrx8(char txd);
|
||||||
|
char spi_rxtx8(char txd);
|
||||||
|
|
||||||
|
void spi_tx(char *txb, unsigned int length);
|
||||||
|
void spi_rx(char txd, char *rxb, unsigned int length);
|
||||||
|
|
||||||
|
char spi_rd8();
|
||||||
|
short spi_rd16();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef _SPI_HAL_H
|
||||||
|
#define _SPI_HAL_H
|
||||||
|
|
||||||
|
#pragma parameter spi_delay(__D0)
|
||||||
|
extern void spi_delay(char iterations);
|
||||||
|
|
||||||
|
#pragma parameter _reg_write8(__A0, __D0, __D1)
|
||||||
|
extern void _reg_write8(void *addr, char data, int tmp);
|
||||||
|
static inline void reg_write8(void *addr, char data) { _reg_write8(addr, data, 0); }
|
||||||
|
|
||||||
|
#pragma parameter _reg_write16(__A0, __D0, __D1)
|
||||||
|
extern void _reg_write16(void *addr, short data, int tmp);
|
||||||
|
static inline void reg_write16(void *addr, short data) { _reg_write16(addr, data, 0); }
|
||||||
|
|
||||||
|
#pragma parameter __D0 smear8to32(__D0)
|
||||||
|
extern long smear8to32(char data);
|
||||||
|
|
||||||
|
// Read transfer registers
|
||||||
|
#define SPI_REG_RX8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||||
|
#define SPI_REG_RX16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||||
|
#define SPI_REG_RX16S ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||||
|
#define SPI_REG_RD8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||||
|
#define SPI_REG_RD16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||||
|
#define SPI_REG_RD16S ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||||
|
#define SPI_REG_TIMER8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||||
|
#define SPI_REG_TIMER16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||||
|
// Write transfer registers
|
||||||
|
#define SPI_REG_TX8 ((char*) 0x00000000) // A[07:00]==arg
|
||||||
|
#define SPI_REG_TX16 ((char*) 0x00000000) // A[15:00]==arg
|
||||||
|
#define SPI_REG_TX16S ((char*) 0x00000000) // A[05:00]==arg
|
||||||
|
#define SPI_REG_ST16 ((char*) 0x00000000) // A[15:00]==arg
|
||||||
|
#define SPI_REG_EMPTY ((char*) 0x00000000)
|
||||||
|
// Control/status register (read/write)
|
||||||
|
#define SPI_REG_RD_CSR ((char*) 0x00000000)
|
||||||
|
#define SPI_REG_WR_CSR ((char*) 0x00000000)
|
||||||
|
#define SPI_REG_CSR_BIT_nDET (0)
|
||||||
|
#define SPI_REG_CSR_GET_nDET() ((*SPI_REG_RD_CSR>>SPI_REG_CSR_BIT_nDET) & 1)
|
||||||
|
#define SPI_REG_CSR_BIT_MISO (1)
|
||||||
|
#define SPI_REG_CSR_GET_MISO() ((*SPI_REG_RD_CSR>>SPI_REG_CSR_BIT_MISO) & 1)
|
||||||
|
#define SPI_REG_CSR_BIT_SCK (2)
|
||||||
|
#define SPI_REG_CSR_SET_SCK() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR | (1<<SPI_REG_CSR_BIT_SCK))
|
||||||
|
#define SPI_REG_CSR_CLR_SCK() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR & ~(1<<SPI_REG_CSR_BIT_SCK))
|
||||||
|
#define SPI_REG_CSR_BIT_CS (3)
|
||||||
|
#define SPI_REG_CSR_SET_CS() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR | (1<<SPI_REG_CSR_BIT_CS))
|
||||||
|
#define SPI_REG_CSR_CLR_CS() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR & ~(1<<SPI_REG_CSR_BIT_CS))
|
||||||
|
|
||||||
|
#define SPI_REG_SET_MOSI(x) reg_write16(SPI_REG_ST16, x ? 0xFFFF : 0x0000)
|
||||||
|
|
||||||
|
#pragma parameter _spi_hal_rx8(__A0, __A2, __A4, __D0, __D1, __D2)
|
||||||
|
extern void _spi_hal_rx8(void *reg, void *rx, void *tmp, int length, int nops, int tmp2);
|
||||||
|
static inline void spi_hal_rx8(void *reg, void *rx, int length, int nops) {
|
||||||
|
_spi_hal_rx8(reg, rx, 0, length, nops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma parameter _spi_hal_rx16(__A0, __A2, __A4, __D0, __D1, __D2)
|
||||||
|
extern void _spi_hal_rx16(void *reg, void *rx, void *tmp, int length, int nops, int tmp2);
|
||||||
|
static inline void spi_hal_rx16(void *reg, void *rx, int length, int nops) {
|
||||||
|
_spi_hal_rx16(reg, rx, 0, length, nops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma parameter _spi_hal_tx8(__A0, __A3, __A4, __D0, __D1, __D2)
|
||||||
|
extern void _spi_hal_tx8(void *reg, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||||
|
static inline void spi_hal_tx8(void *reg, void *tx, int length, int nops) {
|
||||||
|
_spi_hal_tx8(reg, tx, 0, length, nops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma parameter _spi_hal_tx16(__A0, __A3, __A4, __D0, __D1, __D2)
|
||||||
|
extern void _spi_hal_tx16(void *reg, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||||
|
static inline void spi_hal_tx16(void *reg, void *tx, int length, int nops) {
|
||||||
|
_spi_hal_tx16(reg, tx, 0, length, nops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma parameter _spi_hal_rxtx8(__A0, __A1, __A2, __A3, __A4, __D0, __D1, __D2)
|
||||||
|
extern void _spi_hal_rxtx8(void *reg, void *read, void *rx, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||||
|
static inline void spi_hal_rxtx8(void *reg, void *read, void *rx, void *tx, int length, int nops) {
|
||||||
|
_spi_hal_rxtx8(reg, read, rx, tx, 0, length, nops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,49 @@
|
||||||
|
.global spi_delay
|
||||||
|
.global _reg_write16
|
||||||
|
.global _reg_write8
|
||||||
|
.global smear8to32
|
||||||
|
|
||||||
|
* delay calling convention
|
||||||
|
* D0 - iterations
|
||||||
|
|
||||||
|
spi_delay:
|
||||||
|
subq.w #1, %D0
|
||||||
|
bne.b spi_delay
|
||||||
|
rts
|
||||||
|
|
||||||
|
* reg_write calling convention
|
||||||
|
* A0 - address
|
||||||
|
* D0 - data (clobbered)
|
||||||
|
* D1 - clobbered
|
||||||
|
|
||||||
|
_reg_write8:
|
||||||
|
move.l %A0, %D1
|
||||||
|
andi.l #0xFFFFFF00, %D1
|
||||||
|
andi.l #0x000000FF, %D0
|
||||||
|
or %D1, %D0
|
||||||
|
movea %D0, %A0
|
||||||
|
move.l (%A0), %D0
|
||||||
|
rts
|
||||||
|
|
||||||
|
_reg_write16:
|
||||||
|
move.l %A0, %D1
|
||||||
|
andi.l #0xFFFF0000, %D1
|
||||||
|
andi.l #0x0000FFFF, %D0
|
||||||
|
or %D1, %D0
|
||||||
|
movea %D0, %A0
|
||||||
|
move.l (%A0), %D0
|
||||||
|
rts
|
||||||
|
|
||||||
|
* smear8to32 calling convention
|
||||||
|
* D0 - data in/out
|
||||||
|
|
||||||
|
smear8to32:
|
||||||
|
andi.l #0xFF, %D0
|
||||||
|
move.l %D0, %D1
|
||||||
|
lsl.w #8, %D1
|
||||||
|
or.w %D1, %D0
|
||||||
|
lsl.w #8, %D1
|
||||||
|
or.w %D1, %D0
|
||||||
|
lsl.w #8, %D1
|
||||||
|
or.w %D1, %D0
|
||||||
|
rts
|
|
@ -0,0 +1,98 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
* D2 - clobbered (save SR)
|
||||||
|
* D3 - clobbered (save CACR)
|
||||||
|
|
||||||
|
.macro spi_call table, maxnops
|
||||||
|
* Limit %D0 (length) to 1-256
|
||||||
|
subq.w #1, %D0
|
||||||
|
andi.l #0xFF, %D0
|
||||||
|
addq.w #1, %D0
|
||||||
|
|
||||||
|
* Limit %D1 (nops) based on maxnops
|
||||||
|
.if \maxnops == 1
|
||||||
|
andi.l #1, %D1
|
||||||
|
.elseif \maxnops == 3
|
||||||
|
andi.l #3, %D1
|
||||||
|
.elseif \maxnops == 7
|
||||||
|
andi.l #7, %D1
|
||||||
|
.elseif \maxnops == 15
|
||||||
|
andi.l #15, %D1
|
||||||
|
.elseif \maxnops != 0
|
||||||
|
.error
|
||||||
|
.endif
|
||||||
|
|
||||||
|
* Convert length to offset
|
||||||
|
* %D0 = -%D0 (-length)
|
||||||
|
neg.l %D0
|
||||||
|
* %D0 = %D0 + 256 (-length + 256)
|
||||||
|
add.l #256, %D0
|
||||||
|
|
||||||
|
.if \maxnops != 0
|
||||||
|
* Combine nops with offset to get lookup table index
|
||||||
|
* %D1 = %D1 * 4 * 256 (nops * 256)
|
||||||
|
lsl.l #8, %D1
|
||||||
|
* %D0 = %D0 + %D1 (offset + nops*256)
|
||||||
|
or.l %D1, %D0
|
||||||
|
.endif
|
||||||
|
|
||||||
|
* Get index of entry point from lookup table
|
||||||
|
* %D0 = table[%D0] (table[4*(length+nops*256)])
|
||||||
|
move.l (\table - ., %PC, %D0.w : 4), %D0
|
||||||
|
|
||||||
|
* Save status register and disable interrupts
|
||||||
|
move.w %SR, %D2
|
||||||
|
ori.w #0x0700, %SR
|
||||||
|
|
||||||
|
* Save CACR in %D3
|
||||||
|
movec %CACR, %D3
|
||||||
|
|
||||||
|
* Copy CACR to %D1
|
||||||
|
move.l %D3, %D1
|
||||||
|
* Clear CACR bits:
|
||||||
|
* DE ('040 enable data cache) (31)
|
||||||
|
* WA ('030 write allocate) (13)
|
||||||
|
* DBE ('030 data burst enable) (12)
|
||||||
|
* CD ('030 clear data cache) (11)
|
||||||
|
* CED ('030 clear entry in data cache) (10)
|
||||||
|
* FD ('030 freeze data cache) (9)
|
||||||
|
* ED ('030 enable data cache) (8)
|
||||||
|
andi.l #0x7FFFC0FF, %D1
|
||||||
|
* Set '030 CACR bits:
|
||||||
|
* FD (freeze data cache) (9)
|
||||||
|
ori.w #0x0200, %D1
|
||||||
|
* Move back into CACR
|
||||||
|
movec.l %D1, %CACR
|
||||||
|
|
||||||
|
* Jump to entry point
|
||||||
|
* (table + table[length*4 + nops*4*256])
|
||||||
|
jmp (\table - ., %PC, %D0.l)
|
||||||
|
|
||||||
|
* Return statement for use with parameter checking
|
||||||
|
ret: rts
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro lookup_table base, nbase, stride, n
|
||||||
|
dc.l \nbase - \base
|
||||||
|
dc.l \nbase + \stride - \base
|
||||||
|
dc.l \nbase + \stride+\stride - \base
|
||||||
|
dc.l \nbase + \stride+\stride+\stride - \base
|
||||||
|
.if \n > 0
|
||||||
|
lookup_table \base, \nbase + \stride+\stride+\stride+\stride, \stride, \n-4
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro unroll_table macro, nops, n
|
||||||
|
.rept \n
|
||||||
|
\macro \nops
|
||||||
|
.endr
|
||||||
|
move.w %D2, %SR
|
||||||
|
movec.l %D3, %CACR
|
||||||
|
rts
|
||||||
|
.endm
|
|
@ -0,0 +1,73 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
|
||||||
|
.global _spi_hal_rx16
|
||||||
|
|
||||||
|
.include "spi_hal_common.s"
|
||||||
|
|
||||||
|
.macro _spi_hal_rx16_iteration nops
|
||||||
|
move.w (%A0), (%A2)+
|
||||||
|
.rept \nops
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16:
|
||||||
|
spi_call _spi_hal_rx16_lookup, 15
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_lookup:
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_0, 2, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_1, 4, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_2, 6, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_3, 8, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_4, 10, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_5, 12, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_6, 14, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_7, 16, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_8, 18, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_9, 20, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_10, 22, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_11, 24, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_12, 26, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_13, 28, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_14, 30, 256
|
||||||
|
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_15, 32, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_0: unroll_table _spi_hal_rx16_iteration, 0, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_1: unroll_table _spi_hal_rx16_iteration, 1, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_2: unroll_table _spi_hal_rx16_iteration, 2, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_3: unroll_table _spi_hal_rx16_iteration, 3, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_4: unroll_table _spi_hal_rx16_iteration, 4, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_5: unroll_table _spi_hal_rx16_iteration, 5, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_6: unroll_table _spi_hal_rx16_iteration, 6, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_7: unroll_table _spi_hal_rx16_iteration, 7, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_8: unroll_table _spi_hal_rx16_iteration, 8, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_9: unroll_table _spi_hal_rx16_iteration, 9, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_10: unroll_table _spi_hal_rx16_iteration, 10, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_11: unroll_table _spi_hal_rx16_iteration, 11, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_12: unroll_table _spi_hal_rx16_iteration, 12, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_13: unroll_table _spi_hal_rx16_iteration, 13, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_14: unroll_table _spi_hal_rx16_iteration, 14, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx16_table_15: unroll_table _spi_hal_rx16_iteration, 15, 256
|
|
@ -0,0 +1,49 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
|
||||||
|
.global _spi_hal_rx8
|
||||||
|
|
||||||
|
.include "spi_hal_common.s"
|
||||||
|
|
||||||
|
.macro _spi_hal_rx8_iteration nops
|
||||||
|
move.b (%A0), (%A2)+
|
||||||
|
.rept \nops
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8:
|
||||||
|
spi_call _spi_hal_rx8_lookup, 7
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_lookup:
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_0, 2, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_1, 4, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_2, 6, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_3, 8, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_4, 10, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_5, 12, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_6, 14, 256
|
||||||
|
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_7, 16, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_0: unroll_table _spi_hal_rx8_iteration, 0, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_1: unroll_table _spi_hal_rx8_iteration, 1, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_2: unroll_table _spi_hal_rx8_iteration, 2, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_3: unroll_table _spi_hal_rx8_iteration, 3, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_4: unroll_table _spi_hal_rx8_iteration, 4, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_5: unroll_table _spi_hal_rx8_iteration, 5, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_6: unroll_table _spi_hal_rx8_iteration, 6, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rx8_table_7: unroll_table _spi_hal_rx8_iteration, 7, 256
|
|
@ -0,0 +1,62 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
|
||||||
|
* spi single calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* D0 - data
|
||||||
|
* D1 - clobbered
|
||||||
|
|
||||||
|
.global _spi_hal_rxtx8
|
||||||
|
.global _spi_hal_rxtx8single
|
||||||
|
|
||||||
|
.include "spi_hal_common.s"
|
||||||
|
|
||||||
|
.macro _spi_hal_rxtx8_iteration nops
|
||||||
|
move.b (%A1), (%A2)+
|
||||||
|
move.b (%A3)+, %D1
|
||||||
|
move.b (%A0, %D1.W), %D1
|
||||||
|
.rept \nops
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8:
|
||||||
|
spi_call _spi_hal_rxtx8_lookup, 7
|
||||||
|
_spi_hal_rxtx8_single:
|
||||||
|
move.b (%A1), %D0
|
||||||
|
move.b (%A0, %D1.W), %D1
|
||||||
|
rts
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_lookup:
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_0, 8, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_1, 10, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_2, 12, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_3, 14, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_4, 16, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_5, 18, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_6, 20, 256
|
||||||
|
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_7, 22, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_0: unroll_table _spi_hal_rxtx8_iteration, 0, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_1: unroll_table _spi_hal_rxtx8_iteration, 1, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_2: unroll_table _spi_hal_rxtx8_iteration, 2, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_3: unroll_table _spi_hal_rxtx8_iteration, 3, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_4: unroll_table _spi_hal_rxtx8_iteration, 4, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_5: unroll_table _spi_hal_rxtx8_iteration, 5, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_6: unroll_table _spi_hal_rxtx8_iteration, 6, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_rxtx8_table_7: unroll_table _spi_hal_rxtx8_iteration, 7, 256
|
|
@ -0,0 +1,74 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
|
||||||
|
.global _spi_hal_tx16
|
||||||
|
|
||||||
|
.include "spi_hal_common.s"
|
||||||
|
|
||||||
|
.macro _spi_hal_tx16_iteration nops
|
||||||
|
move.w (%A3)+, %D1
|
||||||
|
move.b (%A0, %D1.W), %D1
|
||||||
|
.rept \nops
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16:
|
||||||
|
spi_call _spi_hal_tx16_lookup, 15
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_lookup:
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_0, 6, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_1, 8, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_2, 10, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_3, 12, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_4, 14, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_5, 16, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_6, 18, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_7, 20, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_8, 22, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_9, 24, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_10, 26, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_11, 28, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_12, 30, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_13, 32, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_14, 34, 256
|
||||||
|
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_15, 36, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_0: unroll_table _spi_hal_tx16_iteration, 0, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_1: unroll_table _spi_hal_tx16_iteration, 1, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_2: unroll_table _spi_hal_tx16_iteration, 2, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_3: unroll_table _spi_hal_tx16_iteration, 3, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_4: unroll_table _spi_hal_tx16_iteration, 4, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_5: unroll_table _spi_hal_tx16_iteration, 5, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_6: unroll_table _spi_hal_tx16_iteration, 6, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_7: unroll_table _spi_hal_tx16_iteration, 7, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_8: unroll_table _spi_hal_tx16_iteration, 8, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_9: unroll_table _spi_hal_tx16_iteration, 9, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_10: unroll_table _spi_hal_tx16_iteration, 10, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_11: unroll_table _spi_hal_tx16_iteration, 11, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_12: unroll_table _spi_hal_tx16_iteration, 12, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_13: unroll_table _spi_hal_tx16_iteration, 13, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_14: unroll_table _spi_hal_tx16_iteration, 14, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx16_table_15: unroll_table _spi_hal_tx16_iteration, 15, 256
|
|
@ -0,0 +1,50 @@
|
||||||
|
* spi calling convention
|
||||||
|
* A0 - ROM register
|
||||||
|
* A1 - readback address
|
||||||
|
* A2 - RX buffer
|
||||||
|
* A3 - TX buffer
|
||||||
|
* A4 - clobbered
|
||||||
|
* D0 - length (clobbered)
|
||||||
|
* D1 - nops (clobbered)
|
||||||
|
|
||||||
|
.global _spi_hal_tx8
|
||||||
|
|
||||||
|
.include "spi_hal_common.s"
|
||||||
|
|
||||||
|
.macro _spi_hal_tx8_iteration nops
|
||||||
|
move.b (%A3)+, %D1
|
||||||
|
move.b (%A0, %D1.W), %D1
|
||||||
|
.rept \nops
|
||||||
|
nop
|
||||||
|
.endr
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8:
|
||||||
|
spi_call _spi_hal_tx8_lookup, 7
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_lookup:
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_0, 6, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_1, 8, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_2, 10, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_3, 12, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_4, 14, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_5, 16, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_6, 18, 256
|
||||||
|
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_7, 20, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_0: unroll_table _spi_hal_tx8_iteration, 0, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_1: unroll_table _spi_hal_tx8_iteration, 1, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_2: unroll_table _spi_hal_tx8_iteration, 2, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_3: unroll_table _spi_hal_tx8_iteration, 3, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_4: unroll_table _spi_hal_tx8_iteration, 4, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_5: unroll_table _spi_hal_tx8_iteration, 5, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_6: unroll_table _spi_hal_tx8_iteration, 6, 256
|
||||||
|
.align 16
|
||||||
|
_spi_hal_tx8_table_7: unroll_table _spi_hal_tx8_iteration, 7, 256
|
Loading…
Reference in New Issue