]> git.ozlabs.org Git - minimigmac.git/blob - fpga/addr_decode.v
Add GPL v2
[minimigmac.git] / fpga / addr_decode.v
1 `timescale 1ns / 100ps
2
3 /* Mac Plus address space
4  *
5  * - 000000  RAM (or ROM when overlay enabled)
6  * 
7  * - 400000  ROM
8  *      WARNING: The ROM does a fun test to decide whether SCSI is availble
9  *               or not (MacPlus vs. Mac512KE ?). It basically tests if
10  *               (0x420000) == (0x440000) and if it -is- then it assumes
11  *               SCSI is -not- there. So we must not "replicate" the ROM
12  *               in our address decoding. 
13  * 
14  * 
15  * - 580000  SCSI
16  *   580drn
17  *      ||\
18  *      |\ \ b0000=Rd b0001=Wr
19  *      | \- reg (b0000...b0111)
20  *      \----b00d0 where d=dack
21  *  (repeated to 5fffff)
22  *
23  * - 600000  RAM copy when overlay enabled (max 2M)
24  *           (should we just always decode that ?)
25  * - 800000
26  * 
27  * - 9FFFF7  ?? SCC Reset ? (*)
28  * 
29  * - 9FFFF8  SCC Rd (LDS=read UDS=write)
30  * - BFFFF9  SCC Wr
31  *     +0 Ch B control
32  *     +2 Ch A control
33  *     +4 Ch B data
34  *     +6 Ch B data
35  * 
36  * - DFE1FF  IWM
37  *
38  *      + 0000 = DFE1FF = ph0L   : CA0 = 0
39  *      + 0200 = DFE3FF = ph0H   : CA0 = 1
40  *      + 0400 = DFE5FF = ph1L   : CA1 = 0
41  *      + 0600 = DFE7FF = ph1H   : CA1 = 1
42  *      + 0800 = DFE9FF = ph2L   : CA2 = 0
43  *      + 0A00 = DFEBFF = ph2H   : CA2 = 1
44  *      + 0C00 = DFEDFF = ph3L   : LSTRB = 0
45  *      + 0E00 = DFEFFF = ph3H   : LSTRB = 1
46  *      + 1000 = DFF1FF = mtrOff : ENABLE = 0
47  *      + 1200 = DFF3FF = mtrOn  : ENABLE = 1
48  *      + 1400 = DFF5FF = intDrv : SELECT = 0
49  *      + 1600 = DFF7FF = extDrv : SELECT = 1
50  *      + 1800 = DFF9FF = q6L    : Q6 = 0
51  *      + 1A00 = DFFBFF = q6H    : Q6 = 1
52  *      + 1C00 = DFFDFF = q7L    : Q7 = 0
53  *      + 1E00 = DFFFFF = q7H    : Q7 = 1
54  * 
55  * - EFE1FE  VIA
56  *   Ex[xxxr][rrr1]xx - rrrr is RS3..RS0
57  * 
58  *    Port A (reg 0x1 or 0xf)
59  *     0x07  O Sound volume
60  *     0x08  O 1=Main snd buf 0=Alt snd buf
61  *     0x10  O 1=ROM overlay (pullup, so set at boot)
62  *     0x20  O Disk SEL line
63  *     0x40  O 1=Main video 0=Alt video
64  *     0x80  I SCC WReq
65  * 
66  *    Port B (reg 0x0)
67  *     0x01 IO RTC data
68  *     0x02  O RTC clock
69  *     0x04  O RTC enable
70  *     0x08  I Mouse switch
71  *     0x10  I Mouse X2
72  *     0x20  I Mouse Y2
73  *     0x40  I HBlank
74  *     0x80  O 1=Sound disable 0=Enable
75  * 
76  * - F00000  PhaseRead (according FDiasm) (*)
77  *
78  * - F80000  Expansion ROM
79  * 
80  * - FFFFF?  Autovector interrupt sim (we only check for top 6 bits 1)
81  *
82  * I am not certain how that "phase" setting works. Essentially we just
83  * return all 1's and the ROM seems happy enough. What happens is that
84  * very early at boot, the ROM does:
85  * 
86  *     movem.w (0xf0000000), d0-d2
87  * 
88  * Loading thus the 3 half words from f0000000, f0000002 and f0000004
89  * into d0, d1 and d2 respectively.
90  * 
91  * It then does a byte read of 9ffff7 which I believe resets the SCC.
92  * 
93  * It then extracts the low order bit of the 3 reads above, adds them
94  * up, substracts one, and check if the results is 0 or -1 (ie check
95  * if at least 2 of those reads had bit 0 set).
96  * 
97  * If yes, it then does a "phase adjust" by reading a word from 9ffff8,
98  * and that's about it.
99  */
100
101 /*
102  * Combinational address decoder, returns a chip select for each
103  * device. Handles the special casing of the ROM overlay and major
104  * devices.
105  * 
106  * Returns cs_nack for a non-existing address region
107  * 
108  * We are quite lax with decoding to save logic, I haven't verified
109  * how "precise" a real macplus is but I haven't been anal at beeing
110  * as lax as possible neither...
111  */
112 module addr_decode(addr, req, rom_ovl,
113                    cs_ram, cs_rom, cs_scsi, cs_scc, cs_iwm, cs_via,
114                    cs_ivec, cs_nack);
115         input [23:1]    addr;
116         input           req;    
117         input           rom_ovl;
118         output reg      cs_ram;
119         output reg      cs_rom;
120         output reg      cs_scsi;
121         output reg      cs_scc;
122         output reg      cs_iwm;
123         output reg      cs_via;
124         output reg      cs_ivec;
125         output reg      cs_nack;
126
127         always@(addr or req or rom_ovl) begin
128                 cs_ram = 0;
129                 cs_rom = 0;
130                 cs_scsi = 0;
131                 cs_scc = 0;
132                 cs_iwm = 0;
133                 cs_via = 0;
134                 cs_ivec = 0;            
135                 cs_nack = 0;
136
137                 casez({req,addr[23:18],rom_ovl})
138                         8'b100????0: cs_ram = 1;
139                         8'b100????1: cs_rom = 1;
140                         8'b1010000?: cs_rom = 1;
141                         8'b101011??: cs_scsi = 1;
142                         8'b1011????: cs_ram = 1; /* only ovl=1 ? */
143                         8'b110?1???: cs_scc = 1;
144                         8'b11101???: cs_iwm = 1;
145                         8'b11110???: cs_via = 1;
146                         8'b1111111?: cs_ivec =1;                                
147                         default: cs_nack = req;
148                 endcase
149         end
150 endmodule
151
152         
153                         
154