This commit is contained in:
Zane Kaminski 2021-03-15 13:40:59 -04:00
parent fdbc92725a
commit 686fac229e
10 changed files with 7378 additions and 6582 deletions

1808
Docs.sch

File diff suppressed because it is too large Load Diff

37
Documentation/Flash Map Normal file
View File

@ -0,0 +1,37 @@
GR8RAM/LibraryCard flash memory map
-----------------------------
FF FFFF | |
.. .... | reserved (12 MB) |
40 0000 | |
-----------------------------
3F FFFF | |
.. .... | firmware 3 (1 MB) |
30 0000 | |
-----------------------------
2F FFFF | |
.. .... | firmware 2 (1 MB) |
20 0000 | |
-----------------------------
1F FFFF | |
.. .... | firmware 1 (1 MB) |
10 0000 | |
-----------------------------
0F FFFF | |
.. .... | firmware 0 (1 MB) |
00 0000 | |
-----------------------------
Firmware area map (X == 0, 1, 2, or 3)
-----------------------------
XF FFFF | |
.. .... | reserved (510 kB) |
X8 0800 | |
-----------------------------
X8 07FF | |
.. .... | IOSEL area (2 kB) |
X8 0000 | |
-----------------------------
X7 FFFF | |
.. .... | 256x IOSTRB area (512 kB) |
X0 0000 | |
-----------------------------

View File

@ -0,0 +1,140 @@
Init sequence
Init State SDRAM Flash Other
--------------------------------------------------------------------------------
$000000-$0FFFBF Wait for Vcc Wait for Vcc
$000000 NOP CKE /CS hi, CLK lo
...
$0FFF90 NOP CKE /CS hi, CLK lo InitActv <= ~BODf
....
$0FFFA0 NOP CKE /CS lo, CLK lo
...
$0FFFAF NOP CKE /CS lo, CLK lo
$0FFFB0-$0FFFBF Init: Precharge Send read cmd ($03)
$0FFFB0 PC all CLK lo, MOSI 0 (b7)
$0FFFB1 NOP CKE CLK hi
$0FFFB2 NOP CKE CLK lo, MOSI 0 (b6)
$0FFFB3 NOP CKE CLK hi
$0FFFB4 NOP CKE CLK lo, MOSI 0 (b5)
$0FFFB5 NOP CKE CLK hi
$0FFFB6 NOP CKE CLK lo, MOSI 0 (b4)
$0FFFB7 NOP CKE CLK hi
$0FFFB8 NOP CKE CLK lo, MOSI 0 (b3)
$0FFFB9 NOP CKE CLK hi
$0FFFBA NOP CKE CLK lo, MOSI 0 (b2)
$0FFFBB NOP CKE CLK hi
$0FFFBC NOP CKE CLK lo, MOSI 1 (b1)
$0FFFBD NOP CKE CLK hi
$0FFFBE NOP CKE CLK lo, MOSI 1 (b0)
$0FFFBF NOP CKE CLK hi
$0FFFC0-$0FFFEF Init: mode & ref Send address ($000000)
$0FFFC0 Load mode CLK lo, MOSI 0 (b23)
$0FFFC1 NOP CKE CLK hi
$0FFFC2 NOP CKE CLK lo, MOSI 0 (b22)
$0FFFC3 NOP CKE CLK hi
$0FFFC4 AREF CLK lo, MOSI Firmware[1] (b21)
$0FFFC5 NOP CKE CLK hi
$0FFFC6 NOP CKE CLK lo, MOSI Firmware[0] (b20)
$0FFFC7 NOP CKE CLK hi
$0FFFC8 NOP CKE CLK lo, MOSI 0 (b19)
$0FFFC9 NOP CKE CLK hi
$0FFFCA NOP CKE CLK lo, MOSI 0 (b18)
$0FFFCB NOP CKE CLK hi
$0FFFCC AREF CLK lo, MOSI 0 (b17)
$0FFFCD NOP CKE CLK hi
$0FFFCE NOP CKE CLK lo, MOSI 0 (b16)
$0FFFCF NOP CKE CLK hi
$0FFFD0 NOP CKE CLK lo, MOSI 0 (b15)
$0FFFD1 NOP CKE CLK hi
$0FFFD2 NOP CKE CLK lo, MOSI 0 (b14)
$0FFFD3 NOP CKE CLK hi
$0FFFD4 AREF CLK lo, MOSI 0 (b13)
$0FFFD5 NOP CKE CLK hi
$0FFFD6 NOP CKE CLK lo, MOSI 0 (b12)
$0FFFD7 NOP CKE CLK hi
$0FFFD8 NOP CKE CLK lo, MOSI 0 (b11)
$0FFFD9 NOP CKE CLK hi
$0FFFDA NOP CKE CLK lo, MOSI 0 (b10)
$0FFFDB NOP CKE CLK hi
$0FFFDC AREF CLK lo, MOSI 0 (b9)
$0FFFDD NOP CKE CLK hi
$0FFFDE NOP CKE CLK lo, MOSI 0 (b8)
$0FFFDF NOP CKE CLK hi
$0FFFE0 NOP CKE CLK lo, MOSI 0 (b7)
$0FFFE1 NOP CKE CLK hi
$0FFFE2 NOP CKE CLK lo, MOSI 0 (b6)
$0FFFE3 NOP CKE CLK hi
$0FFFE4 AREF CLK lo, MOSI 0 (b5)
$0FFFE5 NOP CKE CLK hi
$0FFFE6 NOP CKE CLK lo, MOSI 0 (b4)
$0FFFE7 NOP CKE CLK hi
$0FFFE8 NOP CKE CLK lo, MOSI 0 (b3)
$0FFFE9 NOP CKE CLK hi
$0FFFEA NOP CKE CLK lo, MOSI 0 (b2)
$0FFFEB NOP CKE CLK hi
$0FFFEC AREF CLK lo, MOSI 0 (b1)
$0FFFED NOP CKE CLK hi
$0FFFEE NOP CKE CLK lo, MOSI 0 (b0)
$0FFFEF NOP CKE CLK hi
$0FFFF0-$0FFFFF Init: mode & ref 8 dummy clocks
$0FFFF0 NOP CKE CLK lo, MOSIOE 0
$0FFFF1 NOP CKE CLK hi
$0FFFF2 NOP CKE CLK lo
$0FFFF3 NOP CKE CLK hi
$0FFFF4 AREF CLK lo
$0FFFF5 NOP CKE CLK hi
$0FFFF6 NOP CKE CLK lo
$0FFFF7 NOP CKE CLK hi
$0FFFF8 NOP CKE CLK lo
$0FFFF9 NOP CKE CLK hi
$0FFFFA NOP CKE CLK lo
$0FFFFB NOP CKE CLK hi
$0FFFFC AREF CLK lo
$0FFFFD NOP CKE CLK hi
$0FFFFE NOP CKE CLK lo
$0FFFFF NOP CKE CLK hi
Write ROM data Shift in read data
$100000 NOP CKE CLK lo
$100001 NOP CKE CLK hi, get b7:6 of $000000
$100002 NOP CKE CLK lo
$100003 NOP CKE CLK hi, get b5:4 of $000000
$100004 AREF CLK lo
$100005 NOP CKE CLK hi, get b3:2 of $000000
$100006 ACT CLK lo
$100007 NOP CKE CLK hi, get b1:0 of $000000
$100008 WR AP CLK lo
$100009 NOP CKE CLK hi, get b7:6 of $000001
$10000A NOP CKE CLK lo
$10000B NOP CKE CLK hi, get b5:4 of $000001
$10000C AREF CLK lo
$10000D NOP CKE CLK hi, get b3:2 of $000001
$10000E ACT CLK lo
$10000F NOP CKE CLK hi, get b1:0 of $000001
...
$507FF0 WR AP CLK lo
$503FF1 NOP CKE CLK hi, get b7:6 of $0807FE
$503FF2 NOP CKE CLK lo
$503FF3 NOP CKE CLK hi, get b5:4 of $0807FE
$503FF4 AREF CLK lo
$503FF5 NOP CKE CLK hi, get b3:2 of $0807FE
$503FF6 ACT CLK lo
$503FF7 NOP CKE CLK hi, get b1:0 of $0807FE
$503FF8 WR AP CLK lo
$503FF9 NOP CKE CLK hi, get b7:6 of $0807FF
$503FFA NOP CKE CLK lo
$503FFB NOP CKE CLK hi, get b5:4 of $0807FF
$503FFC AREF CLK lo
$503FFD NOP CKE CLK hi, get b3:2 of $0807FF
$503FFE ACT CLK lo
$503FFF NOP CKE CLK hi, get b1:0 of $0807FF
$504000 WR AP CLK lo, /CS hi
$504001 NOP CKE CLK lo
...
$50400F NOP CKE CLK lo
$504010 NOP CKE SDRAMActv <= InitActv && ~InitInterrupted
...
$5F5E0F flip 1hz, wrap

View File

@ -1,106 +0,0 @@
Addr Slinky GR8RAM
0 RAMAddrL RAMAddrL
1 RAMAddrM RAMAddrM
2 RAMAddrH RAMAddrH
3 Data Data
4 AppleAddrL (TimerDMAEN)
5 AppleAddrH (TimerDMAEN)
6 DMALengthL (TimerDMAEN)
7 DMALengthH (TimerDMAEN)
8 Magic (reads 0x57, write command sequence)
9 Ctl (TimerDMAEN)
A Readout
B
C
D
E BankH (ExtBankEN)
F Bank BankL
Magic commands
Set readout
4 tick bytes
config byte
Write hidden control register
Write IRQ period H
Write IRQ period L
Hidden control register
(1) Enable timer & dma
(1) enable extended bank
(2) reserved
(1) DR shift data bit
(1) write '1' to shift bit into DR
(1) write '1' to erase settings
(1) write '1' to program settings
Control register (TimerDMAEN)
(1) Timer IRQ enabled
(1) Timer IRQ flag
(1) reserved
(1) INTout
(1) DMA Compare result
(1) RAMAddrHH
(2) DMA command (always reads 00)
00 = no operation
01 = read
10 = write
11 = compare
Configuration Bits
(1) Config word valid
1 = invalid
0 = valid
(1) Slinky/RamFactor
1 = RamFactor
0 = Slinky
(2) Driver number (BankCX) (0-3)
(3) Capacity (invert bottom bit, then decode to get mask)
111 = 011111 = 08192 kB
110 = 111111 = 16384 kB
101 = 000111 = 02048 kB
100 = 001111 = 04096 kB
011 = 000001 = 00512 kB
010 = 000011 = 01024 kB
001 = 000000 = 00256 kB
000 = reserved
Flash Memory Map (2 MB)
-----------------------------
3FF | |
... | GS/OS Recovery (1.5 MB) |
200 | |
-----------------------------
1FF | |
... | ProDOS Recovery (256 kB) |
180 | |
-----------------------------
07F | |
... | Driver 3 (64 kB) |
060 | |
-----------------------------
05F | |
... | Driver 2 (64 kB) |
040 | |
-----------------------------
03F | |
... | Driver 1 (64 kB) |
020 | |
-----------------------------
01F | |
... | Driver 0 (64 kB) |
000 | |
|----------------------------
SDRAM Memory Map (32 MB)
1FFFFFF:1800000 RAMWorks copy
17FFFFF:17F0000 64 kB main RAM copy
17EFFFF:17E0000 64 kB driver (32 2048 byte banks)
17DFFFF:1010000 Shared Memory (8064 kB)
0FFFFFF:0800000 Extended RamFactor
07FFFFF:0000000 8 MB RamFactor

View File

@ -1,30 +1,44 @@
GR8RAM/LibraryCard Slinky memory map
GR8RAM/LibraryCard Slinky RAM memory map
-----------------------------
1 FF FFFF | |
. .. .... | LibCrd Sect. Cache (8 MB) |
. .. .... | LibCrd sect. cache (8 MB) |
1 80 0000 | |
-----------------------------
1 7F FFFF | |
. .. .... | reserved (6 MB) |
1 20 0000 | |
-----------------------------
1 1F FFFF | |
. .. .... | LibCrd registers (1 MB) |
1 70 0000 | |
-----------------------------
1 6F FFFF | |
. .. .... | reserved (5.9375 MB) |
1 11 0000 | |
-----------------------------
1 10 FFFF | |
. .. .... | RAM shadow (64 kB) |
1 10 0000 | |
-----------------------------
1 0F FFFF | |
. .. .... | 256x IOSTRB area (512 kB) |
1 08 0000 | |
-----------------------------
1 07 FFFF | |
. .. .... | 256x IOSEL area (512 kB) |
. .. .... | firmware (1 MB) |
1 00 0000 | |
-----------------------------
0 FF 0000 | |
. .. .... | RAMFactor Memory (16 MB) |
0 FF FFFF | |
. .. .... | RAMFactor RAM (16 MB) |
0 00 0000 | |
-----------------------------
Firmware area map (X == 0, 1, 2, or 3)
-----------------------------
1 0F FFFF | |
. .. .... | reserved (510 kB) |
1 08 0800 | |
-----------------------------
1 08 07FF | |
. .. .... | IOSEL area (2 kB) |
1 08 0000 | |
-----------------------------
1 07 FFFF | |
. .. .... | 256x IOSTRB area (512 kB) |
1 00 0000 | |
-----------------------------
Library Card register space
-----------------------------
@ -33,18 +47,18 @@ Library Card register space
1 74 0000 | |
-----------------------------
1 73 FFFF | |
. .. .... | Response B (64 kB) |
. .. .... | response B (64 kB) |
1 73 0000 | |
-----------------------------
1 72 FFFF | |
. .. .... | Command B (64 kB) |
. .. .... | command B (64 kB) |
1 72 0000 | |
-----------------------------
1 71 FFFF | |
. .. .... | Response A (64 kB) |
. .. .... | response A (64 kB) |
1 71 0000 | |
-----------------------------
1 70 FFFF | |
. .. .... | Command A (64 kB) |
. .. .... | command A (64 kB) |
1 70 0000 | |
-----------------------------

45
Documentation/Registers Normal file
View File

@ -0,0 +1,45 @@
Addr Slinky GR8RAM TimeMachine
$0 RAddrL RAddrL RAddrL
$1 RAddrM RAddrM RAddrM
$2 RAddrH RAddrH RAddrH
$3 RData RData RData
$4 DMAAddrL
$5 DMAAddrH
$6
$7
$8
$9
$A
$B
$C
$D Readin/out Readin/out
$E Command Command
$F Bank Bank Bank
GR8RAM commands
CmdNum Description Argument
$00 SetReadinout RiNum/RoNum
$EF CFGPrgmEN don't care
$EE CFGEraseEN don't care
GR8RAM Readin
RiNum Description Data
$10 SPI flash { MOSI(1), X(6), CS(1) }
$11 SPI flash + clk pulse { MOSI(1), X(6), CS(1) }
$13 CFG flash + clk pulse { CFGDin(1), X(7) }
$20 Mode { RF/nSlinky(1), X(4), Size(3) }
$21 RAddrHH { X(7), RAddr[24](1) }
GR8RAM Readout
RoNum Description
$00 Magic $C1
$01 Card ID $00
$10 SPI flash { MISO(1), X(7) }
$20 Mode { RF/nSlinky(1), X(4), Size(3) }
TimeMachine commands
$XX DMA into Apple RAM Length
$XX DMA into Slinky RAM Length
$XX DMA into Apple RAM Length-256
$XX DMA into Slinky RAM Length-256

7
Documentation/Settings Normal file
View File

@ -0,0 +1,7 @@
GR8RAM Settings (not applicable to Library Card!)
Settings[15] SetValid (1 = invalid, 0 = valid)
Settings[14] SetFW[1] (1 = RAMFactor, 0 = Slinky)
Settings[13] SetFW[0]
Settings[12] SetLim8M
Settings[11:0] Reserved

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ Comment3 ""
Comment4 ""
$EndDescr
$Sheet
S 500 600 500 150
S 750 650 500 150
U 5D4D21A0
F0 "Docs" 50
F1 "Docs.sch" 50
@ -2497,18 +2497,6 @@ F 4 "C7955" H 3800 1050 50 0001 C CNN "LCSC Part"
$EndComp
Text Label 900 6550 2 50 ~ 0
FD2
$Comp
L Device:R_Small R19
U 1 1 5FFDC1D7
P 8300 5000
F 0 "R19" V 8250 5000 50 0000 C BNN
F 1 "1k" V 8350 5000 50 0000 C TNN
F 2 "stdpads:R_0603" H 8300 5000 50 0001 C CNN
F 3 "~" H 8300 5000 50 0001 C CNN
F 4 "C21190" H 8300 5000 50 0001 C CNN "LCSC Part"
1 8300 5000
0 1 1 0
$EndComp
Connection ~ 7800 5000
Wire Wire Line
7400 4650 7400 4700
@ -2541,10 +2529,10 @@ L Device:R_Small R18
U 1 1 617DE3BC
P 7050 4750
F 0 "R18" H 7100 4800 50 0000 L CNN
F 1 "22k" H 7100 4700 50 0000 L CNN
F 1 "100k" H 7100 4700 50 0000 L CNN
F 2 "stdpads:R_0603" H 7050 4750 50 0001 C CNN
F 3 "~" H 7050 4750 50 0001 C CNN
F 4 "C31850" H 7050 4750 50 0001 C CNN "LCSC Part"
F 4 "C25803" H 7050 4750 50 0001 C CNN "LCSC Part"
1 7050 4750
1 0 0 -1
$EndComp
@ -3357,18 +3345,6 @@ F 4 "C23253" H 4200 1300 50 0001 C CNN "LCSC Part"
1 4200 1300
1 0 0 -1
$EndComp
$Comp
L Device:C_Small C39
U 1 1 5FFA952A
P 4750 1300
F 0 "C39" H 4842 1346 50 0000 L CNN
F 1 "1n" H 4842 1255 50 0000 L CNN
F 2 "stdpads:C_0603" H 4750 1300 50 0001 C CNN
F 3 "~" H 4750 1300 50 0001 C CNN
F 4 "C1588" H 4750 1300 50 0001 C CNN "LCSC Part"
1 4750 1300
1 0 0 -1
$EndComp
Wire Wire Line
4100 1150 4750 1150
Wire Wire Line
@ -3414,18 +3390,6 @@ Wire Wire Line
Connection ~ 4350 1450
Wire Wire Line
4350 1200 4350 950
$Comp
L Device:C_Small C38
U 1 1 5FB5B1B9
P 4350 1300
F 0 "C38" H 4442 1346 50 0000 L CNN
F 1 "22n" H 4442 1255 50 0000 L CNN
F 2 "stdpads:C_0603" H 4350 1300 50 0001 C CNN
F 3 "~" H 4350 1300 50 0001 C CNN
F 4 "C21122" H 4350 1300 50 0001 C CNN "LCSC Part"
1 4350 1300
1 0 0 -1
$EndComp
Wire Wire Line
4350 1450 4350 1400
$Comp
@ -3473,23 +3437,6 @@ Text Notes 5000 1150 2 50 ~ 0
Wire Wire Line
3300 1050 3500 1050
$Comp
L Device:C_Small C41
U 1 1 5FF9336A
P 7050 5200
F 0 "C41" H 7142 5246 50 0000 L CNN
F 1 "22n" H 7142 5155 50 0000 L CNN
F 2 "stdpads:C_0603" H 7050 5200 50 0001 C CNN
F 3 "~" H 7050 5200 50 0001 C CNN
F 4 "C21122" H 7050 5200 50 0001 C CNN "LCSC Part"
1 7050 5200
1 0 0 -1
$EndComp
Wire Wire Line
6750 5300 7050 5300
Wire Wire Line
7050 5300 7400 5300
Connection ~ 7050 5300
$Comp
L Device:R_Small R31
U 1 1 60BD9796
P 1700 6550
@ -3906,16 +3853,6 @@ Wire Wire Line
3400 4350 4150 4350
Wire Wire Line
3400 4250 4150 4250
Wire Bus Line
600 3750 600 4650
Wire Bus Line
1800 4650 1800 5450
Wire Bus Line
3300 1950 3300 4550
Wire Bus Line
3300 4850 3300 5550
Wire Bus Line
1800 2350 1800 4250
$Comp
L Device:C_Small C2
U 1 1 5E8640BA
@ -4002,4 +3939,84 @@ F 4 "C15850" H 3700 5900 50 0001 C CNN "LCSC Part"
1 3700 5900
1 0 0 -1
$EndComp
Wire Wire Line
5050 900 4750 900
Connection ~ 5050 900
$Comp
L Device:C_Small C38
U 1 1 5FB5B1B9
P 4350 1300
F 0 "C38" H 4442 1346 50 0000 L CNN
F 1 "22n" H 4442 1255 50 0000 L CNN
F 2 "stdpads:C_0603" H 4350 1300 50 0001 C CNN
F 3 "~" H 4350 1300 50 0001 C CNN
F 4 "C21122" H 4350 1300 50 0001 C CNN "LCSC Part"
1 4350 1300
1 0 0 -1
$EndComp
Wire Wire Line
6750 5300 7050 5300
$Comp
L Device:C_Small C41
U 1 1 6070D634
P 7050 5200
F 0 "C41" H 7100 5250 50 0000 L CNN
F 1 "2u2" H 7100 5150 50 0000 L CNN
F 2 "stdpads:C_0603" H 7050 5200 50 0001 C CNN
F 3 "~" H 7050 5200 50 0001 C CNN
F 4 "C23630" H 7050 5200 50 0001 C CNN "LCSC Part"
1 7050 5200
1 0 0 -1
$EndComp
Connection ~ 7050 5300
Wire Wire Line
7050 5300 7400 5300
$Comp
L Device:C_Small C39
U 1 1 604926F4
P 4750 1300
F 0 "C39" H 4800 1350 50 0000 L CNN
F 1 "2u2" H 4800 1250 50 0000 L CNN
F 2 "stdpads:C_0603" H 4750 1300 50 0001 C CNN
F 3 "~" H 4750 1300 50 0001 C CNN
F 4 "C23630" H 4750 1300 50 0001 C CNN "LCSC Part"
1 4750 1300
1 0 0 -1
$EndComp
$Comp
L Device:C_Small C17
U 1 1 60492089
P 4750 800
F 0 "C17" H 4800 850 50 0000 L CNN
F 1 "2u2" H 4800 750 50 0000 L CNN
F 2 "stdpads:C_0603" H 4750 800 50 0001 C CNN
F 3 "~" H 4750 800 50 0001 C CNN
F 4 "C23630" H 4750 800 50 0001 C CNN "LCSC Part"
1 4750 800
1 0 0 -1
$EndComp
Text GLabel 4750 700 0 50 Input ~ 0
Vin
$Comp
L Device:R_Small R19
U 1 1 5FFDC1D7
P 8300 5000
F 0 "R19" V 8250 5000 50 0000 C BNN
F 1 "33k" V 8350 5000 50 0000 C TNN
F 2 "stdpads:R_0603" H 8300 5000 50 0001 C CNN
F 3 "~" H 8300 5000 50 0001 C CNN
F 4 "C4216" H 8300 5000 50 0001 C CNN "LCSC Part"
1 8300 5000
0 1 1 0
$EndComp
Wire Bus Line
3300 4850 3300 5550
Wire Bus Line
600 3750 600 4650
Wire Bus Line
1800 4650 1800 5450
Wire Bus Line
1800 2350 1800 4250
Wire Bus Line
3300 1950 3300 4550
$EndSCHEMATC

513
cpld/GR8RAM.v Normal file
View File

@ -0,0 +1,513 @@
module GR8RAM(C25M, PHI0, nPBOD, nBOD, nRES,
nIOSEL, nDEVSEL, nIOSTRB,
RA, nWE, nWEout, Adir,
RD, Ddir,
DMAin, DMAout, INTin, INTout,
nDMA, nRDY, nNMI, nIRQ, nINH, nRESout
SBA, SA, nRCS, nRAS, nCAS, nSWE, DQML, DQMH, RCKE, SD,
nFCS, FCK, MISO, MOSI);
/* Clock signals */
/* Outputs: C25M, PHI0r1, PHI0r2, */
input C25M, PHI0;
reg PHI0r0, PHI0r1, PHI0r2;
always @(negedge C25M) begin PHI0r0 <= PHI0; end
always @(posedge C25M) begin PHI0r1 <= PHI0r0; PHI0r2 <= PHI0r1; end
/* Reset/brown-out detect synchronized inputs */
/* Outputs: nRESr, nPBODr, nBODf */
input nRES, nPBOD, nBOD;
reg nRESr0, nRESr;
reg nPBODr0, nPBODr;
reg nBODr0, nBODr, nBODf0, nBODf;
always @(posedge C25M) begin
// Double-synchronize nBOD, nPBOD, nRES
nPBODr0 <= nPBOD; nBODr0 <= nBOD; nRESr0 <= nRES;
nPBODr <= nPBODr0; nBODr <= nBODr0; nRESr <= nRESr0;
// Filter nBODr to get nBODf. Output hi when hi for $5E0F-$10000 cycles
if (LS[15:0]==16'h5E0F) begin // When LS low-order is $5E0F
nBODf0 <= nBODr; // "Precharge" nBODf0
nBODf <= nBODf0; // "Evaluate" computed nBODf0 into nBODf
end else if (nBODr2) begin // Else AND nBODf0 with nBODr
nBODf0 <= nBODf0 && nBODr;
end
end
/* Long state counter: counts from 0 to $5F5E0F (6,249,999) *
* CSec: 1/2 Hz clock */
/* Outputs: LS, CSec */
reg [22:0] LS = 0;
reg [1:0] CSec = 0;
reg LSEN = 0;
always @(posedge C25M) begin
// Allow LS to fully count once nBODf active
if (nBODf) LSEN <= 1;
// LS rolls over at 24'h5F5E0F or at 16'h5E0F when LSEN is 0
if ((LS[22:16]==7'h5F || ~LSEN) && LS[15:0]==16'h5E0F) LS <= 0;
else LS <= LS+1;
// Flip 1/2 Hz clocks when LS==23'h5F5E0F
if (LS[22:0]==23'h5F5E0F) CSec <= CSec+1;
end
/* Init state */
output reg nRESout = 0;
reg InitActv = 0;
reg InitIntr = 0;
reg SDRAMActv = 0;
always @(posedge C25M) begin
if (~nBODf) begin
nRESout <= 0;
InitActv <= 0;
InitIntr <= 1;
end else if (LS[22:0]==23'h0FFF10) begin
InitActv <= ~AppleActive;
InitIntr <= 0;
end else if (LS[22:0]==23'h504010) begin
nRESout <= InitActv && ~InitIntr;
InitActv <= 0;
SDRAMActv <= InitActv && ~InitIntr;
end
end
/* Apple IO area select signals */
/* Outputs: DEVSELr */
input nIOSEL, nDEVSEL, nIOSTRB;
reg DEVSELr0, DEVSELr;
always @(negedge C25M) begin DEVSELr0 <= ~nDEVSEL; end
always @(posedge C25M) begin DEVSELr <= DEVSELr0; end
/* DMA/IRQ daisy chain */
input DMAin, INTin;
output DMAout = DMAin;
output INTout = INTin;
/* Apple open-drain outputs */
output nDMA = 1;
output nRDY = 1;
output nNMI = 1;
output nIRQ = ~(TIRQEN && TIRQMask);
output nINH = 1;
/* Apple address bus */
/* Outputs: RAr1, nWEr1 */
input [15:0] RA;
input nWE;
output RAdir = 1;
output nWEout = 1;
reg [15:0] RAr0; reg nWEr0;
reg [15:0] RAcur; reg nWEcur;
always @(negedge C25M) begin RAr0 <= RA; nWEr0 <= nWE; end
always @(posedge C25M) begin
if (S==0 && PHI0r1 && ~PHI0r2) begin
RAcur[15:0] <= RAr0[15:0];
nWEcur <= nWEr0;
end
end
/* Apple select signals */
/* Outputs: ROMSpecRD, RAMSpecSEL, RAMSpecRD, RAMSpecWR, RAMSEL */
wire ROMSpecRD = RAcur[15:12]==4'hC && RAcur[11:8]!=4'h0 && nWEcur;
wire RAMSpecSEL = RAcur[15:12]==4'hC && RAcur[11:8]==4'h0 && RAcur[7] && RAcur[7:4]!=4'h8 && RAcur[3:0]==4'h3;
wire RAMSpecRD = RAMSpecSEL && nWEcur;
wire RAMSpecWR = RAMSpecSEL && ~nWEcur;
reg RAMSEL = 0;
wire RAMWR = RAMSEL && ~nWEcur;
always @(posedge C25M) begin
if (S==5) RAMSEL <= RAMSpecSEL && DEVSELr;
else if (S==0) RAMSEL <= 0;
end
/* Apple data bus */
inout [7:0] RD = RDdir ? 8'bZ : RDout[7:0];
reg [7:0] RDout;
reg RDOE = 0;
output RDdir = ~((~nDEVSEL || ~nIOSEL || (~nIOSTRB && IOEN)) &&
PHI0 && PHI0r2 && nWE && RDOE && ~BODf);
/* Slinky address registers */
reg [24:0] Addr;
wire AddrHSpecSEL = RAcur[3:0]==4'h2;
wire AddrMSpecSEL = RAcur[3:0]==4'h1;
wire AddrLSpecSEL = RAcur[3:0]==4'h0;
always @(posedge C25M) begin
if (~nRESr) begin
Addr[24] <= 1'b0;
Addr[23:20] <= SetFW[1] ? 4'h0 : 4'hF;
Addr[19:0] <= 20'h00000;
end else if (S==7 && DEVSELr) begin
if (AddrHSpecSEL || AddrMSpecSEL || AddrLSpecSEL) begin
Addr[24] <= 1'b0;
end
if (AddrHSpecSEL) begin
Addr[23:16] <= { SetFW[1] ? RD[7:4] : 4'hF, RD[3:0] };
end else if ((RAMSEL && Addr[15:0]==16'hFFFF) ||
(AddrMSpecSEL && Addr[15] && ~RD[7]) ||
(AddrLSpecSEL && Addr[7] && ~RD[7] && Addr[15:8]==8'hFF)) begin
Addr[23:16] <= Addr[23:16]+1;
end
if (AddrMSpecSEL) begin
Addr[15:8] <= RD[7:0];
end else if ((RAMSEL && Addr[7:0]==8'hFF) ||
(AddrLSpecSEL && Addr[7] && ~RD[7])) begin
Addr[15:8] <= Addr[15:8]+1;
end
if (AddrLSpecSEL) begin
Addr[7:0] <= RD[7:0];
end else if (RAMSEL) begin
Addr[7:0] <= Addr[7:0]+1;
end
end
end
/* SPI flash */
output reg nFCS = 1;
output reg FCK = 0;
output reg MOSI = MOSIOE ? MOSIout : 1'bZ;
reg MOSIOE = 0;
reg MOSIout;
input MISO;
/* SPI flash control */
always @(posedge C25M) begin
if (InitActv) begin
// Pulse clock from init states $0FFFC0 to $907FFF
if (LS[22:0]>=23'h0FFFC0 && LS[22:0]<=23'h907FFF) FCK <= LS[0];
end else FCK <= 0;
// Flash /CS enabled from init states $0FFFB0 to s$90800F
if (LS[22:0]>=23'h0FFFB0 && LS[22:0]<=23'h90800F) nFCS <= 0;
end else nFCS <= 1;
// Send command $3B (read) (MSB first)
if (LS[22:0]==23'h0FFFB0 || LS[22:0]==23'h0FFFB1) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFB2 || LS[22:0]==23'h0FFFB3) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFB4 || LS[22:0]==23'h0FFFB5) MOSIout <= 1;
else if (LS[22:0]==23'h0FFFB6 || LS[22:0]==23'h0FFFB7) MOSIout <= 1;
else if (LS[22:0]==23'h0FFFB8 || LS[22:0]==23'h0FFFB9) MOSIout <= 1;
else if (LS[22:0]==23'h0FFFBA || LS[22:0]==23'h0FFFBB) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFBC || LS[22:0]==23'h0FFFBD) MOSIout <= 1;
else if (LS[22:0]==23'h0FFFBE || LS[22:0]==23'h0FFFBF) MOSIout <= 1;
// Send 24-bit address (MSB first)
else if (LS[22:0]==23'h0FFFC0 || LS[22:0]==23'h0FFFC1) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFC2 || LS[22:0]==23'h0FFFC3) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFC4 || LS[22:0]==23'h0FFFC5) MOSIout <= SetFW[1];
else if (LS[22:0]==23'h0FFFC6 || LS[22:0]==23'h0FFFC7) MOSIout <= SetFW[0];
else if (LS[22:0]==23'h0FFFC8 || LS[22:0]==23'h0FFFC9) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFCA || LS[22:0]==23'h0FFFCB) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFCC || LS[22:0]==23'h0FFFCD) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFCE || LS[22:0]==23'h0FFFCF) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFD0 || LS[22:0]==23'h0FFFD1) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFD2 || LS[22:0]==23'h0FFFD3) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFD4 || LS[22:0]==23'h0FFFD5) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFD6 || LS[22:0]==23'h0FFFD7) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFD8 || LS[22:0]==23'h0FFFD9) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFDA || LS[22:0]==23'h0FFFDB) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFDC || LS[22:0]==23'h0FFFDD) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFDE || LS[22:0]==23'h0FFFDF) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFE0 || LS[22:0]==23'h0FFFE1) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFE2 || LS[22:0]==23'h0FFFE3) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFE4 || LS[22:0]==23'h0FFFE5) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFE6 || LS[22:0]==23'h0FFFE7) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFE8 || LS[22:0]==23'h0FFFE9) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFEA || LS[22:0]==23'h0FFFEB) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFEC || LS[22:0]==23'h0FFFED) MOSIout <= 0;
else if (LS[22:0]==23'h0FFFEE || LS[22:0]==23'h0FFFEF) MOSIout <= 0;
else MOSIout <= 0;
MOSIOE <= LS[22:0]<23'h0FFFF0;
end else if (AppleActive) begin
//TODO: control these with Apple II
nFCS <= 1;
FCK <= 0;
MOSIout <= 0;
MOSIOE <= 0;
//TODO? sample nMenu when MOSI not outputting?
end
end
/* SDRAM address/command */
output reg [1:0] SBA;
output reg [12:0] SA;
output reg RCKE = 1;
output reg nRCS = 1;
output reg nRAS = 1;
output reg nCAS = 1;
output reg nSWE = 1;
output reg DQMH = 1;
output reg DQML = 1;
/* SDRAM data bus */
inout [7:0] SD = SDOE ? WRD[7:0] : 8'bZ;
reg [7:0] WRD;
reg SDOE = 0;
always @(posedge C25M) begin
// Shift { MISO, MOSI } in when InitActv. When ready, synchronize RD
if (InitActv) if (LS[1]) WRD[7:0] <= { MISO, MOSI, WRD[5:0] };
end else WRD[7:0] <= RD[7:0];
// Output data on SDRAM data bus only during init and when writing
SDOE <= InitActv || (RAMSEL && nWEcur && S==6);
end
/* State counters */
reg [2:0] S = 0;
always @(posedge C25M) begin
if ( ~InitActv && SDRAMActv && S==0 && PHI0r1 && ~PHI0r2 && nRESr && nBODf) S <= 1;
else if (S==0) S <= 0;
else S <= S+1;
end
/* Refresh state */
reg RefReady = 0;
reg RefDone = 0;
always @(posedge C25M) begin
// Ready to refresh when init inactive, SDRAM active, S0 and refresh not already done
RefReady <= ~InitActv && SDRAMActv && S==0 && ~RefDone;
if (LS[6:0]==7'h00) RefDone <= 0; // Reset RefDone every 128 C25M cycles (5.12 us)
else if (~InitActv && SDRAMActv && S==0 && ~RefDone && RefReady && ~(PHI0r1 && ~PHI0r2)) RefDone <= 1;
end
/* SDRAM control */
always @(posedge C25M) begin
if (S==0 && InitActv) begin
if (LS[22:0]==23'h000000) begin
end
end else if (S==0 && ~SDRAMActv) begin
// NOP CKE
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else if (S==0 && PHI0r1 && ~PHI0r2) begin
// NOP CKE
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else if (S==0 && ~RefDone) begin
// NOP CKE
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else if (S==0 && RefReady) begin
// AREF
RCKE <= 1'b1;
nRCS <= 1'b0;
nRAS <= 1'b0;
nCAS <= 1'b0;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else if (S==0) begin
// NOP CKD
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else if (S==4'h1) begin
if (ROMSpecRD || RAMSpecRD) begin
// ACT
RCKE <= 1'b1;
nRCS <= 1'b0;
nRAS <= 1'b0;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
if (RAMSpecRD) begin
RBA[1] <= Addr[24];
RBA[0] <= Addr[23] & ~SetLim8M;
RA[12:0] <= Addr[22:10];
end else begin
RBA[1] <= 1'b1;
RBA[0] <= 1'b0;
RA[12:10] <= 3'b000;
if (RAcur[11]) begin // IOSTRB
RA[9] <= 1'b0;
RA[8:1] <= Bank[7:0];
RA[0] <= RAcur[10];
end else begin // IOSEL
RA[9] <= 1'b1;
RA[8:1] <= 8'h00;
RA[0] <= RAcur[10];
end
end
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (S==4'h2) begin
if (ROMSpecRD || RAMSpecRD) begin
// RD auto-PC
RCKE <= 1'b1;
nRCS <= 1'b0;
nRAS <= 1'b1;
nCAS <= 1'b0;
nSWE <= 1'b1;
A[12:11] <= 1'b0; // don't care
A[10] <= 1'b1; // auto-precharge
A[9] <= 1'b0; // don't care
if (RAMSpecRD) begin
RBA[1] <= Addr[24];
RBA[0] <= Addr[23];
RA[8:0] <= Addr[9:1];
DQMH <= ~Addr[0];
DQML <= Addr[0];
end else /* ROMSpecRD */ begin
RBA[1] <= 1'b1;
RBA[0] <= 1'b0;
RA[8:0] <= RAcur[9:1];
DQMH <= ~RAcur[0];
DQML <= RAcur[0];
end
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (S==4'h3) begin
if (ROMSpecRD || RAMSpecRD) begin
// NOP cken
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (S==4'h4) begin
if (RAMSpecWR) begin
// NOP cken
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (S==4'h5) begin
if (RAMSpecWR && DEVSELr) begin
// ACT
RCKE <= 1'b1;
nRCS <= 1'b0;
nRAS <= 1'b0;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
BA[1] <= Addr[24];
BA[0] <= Addr[23];
A[12:0] <= Addr[22:10];
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (s==4'h6) begin
if (RAMWR) begin
// WR auto-PC
RCKE <= 1'b1;
nRCS <= 1'b0;
nRAS <= 1'b1;
nCAS <= 1'b0;
nSWE <= 1'b0;
BA[1] <= Addr[24];
BA[0] <= Addr[23];
A[12:11] <= 1'b0; // don't care
A[10] <= 1'b1; // auto-precharge
A[9:0] <= Addr[9:0];
DQMH <= ~Addr[10];
DQML <= Addr[10];
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end else if (S==4'h7) begin
if (RAMSpecWR) begin
// NOP cken
RCKE <= 1'b1;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end else begin
// NOP ckdis
RCKE <= 1'b0;
nRCS <= 1'b1;
nRAS <= 1'b1;
nCAS <= 1'b1;
nSWE <= 1'b1;
DQMH <= 1'b1;
DQML <= 1'b1;
end
end
end
endmodule