-
Notifications
You must be signed in to change notification settings - Fork 3
/
addrController_top.v
217 lines (184 loc) · 6.7 KB
/
addrController_top.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
module addrController_top(
// clocks:
input clk,
output clk8, // 8.125 MHz CPU clock
output clk8_en_p,
output clk8_en_n,
output clk16_en_p,
output clk16_en_n,
// system config:
input turbo, // 0 = normal, 1 = faster
input [1:0] configROMSize, // 0 = 64K ROM, 1 = 128K ROM, 2 = 256K ROM
input [1:0] configRAMSize, // 0 = 128K, 1 = 512K, 2 = 1MB, 3 = 4MB RAM
// 68000 CPU memory interface:
input [23:0] cpuAddr,
input _cpuUDS,
input _cpuLDS,
input _cpuRW,
input _cpuAS,
// RAM/ROM:
output [21:0] memoryAddr,
output _memoryUDS,
output _memoryLDS,
output _romOE,
output _ramOE,
output _ramWE,
output videoBusControl,
output dioBusControl,
output cpuBusControl,
output memoryLatch,
// peripherals:
output selectSCSI,
output selectSCC,
output selectIWM,
output selectVIA,
output selectRAM,
output selectROM,
output selectSEOverlay,
// video:
output hsync,
output vsync,
output _hblank,
output _vblank,
output loadPixels,
input vid_alt,
input snd_alt,
output loadSound,
// misc
input memoryOverlayOn,
// interface to read dsk image from ram
input [21:0] dskReadAddrInt,
output dskReadAckInt,
input [21:0] dskReadAddrExt,
output dskReadAckExt
);
// -------------- audio engine (may be moved into seperate module) ---------------
assign loadSound = sndReadAck;
localparam SIZE = 20'd135408; // 168*806 clk8 events per frame
localparam STEP = 20'd5920; // one step every 16*370 clk8 events
reg [21:0] audioAddr;
reg [19:0] snd_div;
reg sndReadAckD;
always @(posedge clk)
if (clk8_en_n) sndReadAckD <= sndReadAck;
reg vblankD, vblankD2;
always @(posedge clk) begin
if(clk8_en_p && sndReadAckD) begin
vblankD <= _vblank;
vblankD2 <= vblankD;
// falling adge of _vblank = begin of vblank phase
if(vblankD2 && !vblankD) begin
audioAddr <= snd_alt?22'h3FA100:22'h3FFD00;
snd_div <= 20'd0;
end else begin
if(snd_div >= SIZE-1) begin
snd_div <= snd_div - SIZE + STEP;
audioAddr <= audioAddr + 22'd2;
end else
snd_div <= snd_div + STEP;
end
end
end
assign dioBusControl = extraBusControl;
// interleaved RAM access for CPU and video
reg [1:0] busCycle;
reg [1:0] busPhase;
reg [1:0] extra_slot_count;
always @(posedge clk) begin
busPhase <= busPhase + 1'd1;
if (busPhase == 2'b11)
busCycle <= busCycle + 2'd1;
end
assign memoryLatch = busPhase == 2'd3;
assign clk8 = !busPhase[1];
assign clk8_en_p = busPhase == 2'b11;
assign clk8_en_n = busPhase == 2'b01;
assign clk16_en_p = !busPhase[0];
assign clk16_en_n = busPhase[0];
reg extra_slot_advance;
always @(posedge clk)
if (clk8_en_n) extra_slot_advance <= (busCycle == 2'b11);
// allocate memory slots in the extra cycle
always @(posedge clk) begin
if(clk8_en_p && extra_slot_advance) begin
extra_slot_count <= extra_slot_count + 2'd1;
end
end
// video controls memory bus during the first clock of the four-clock cycle
assign videoBusControl = (busCycle == 2'b00);
// cpu controls memory bus during the second and fourth clock of the four-clock cycle
assign cpuBusControl = (busCycle == 2'b01) || (busCycle == 2'b11);
// IWM/audio gets 3rd cycle
wire extraBusControl = (busCycle == 2'b10);
// interconnects
wire [21:0] videoAddr;
// RAM/ROM control signals
wire videoControlActive = _hblank;
wire extraRomRead = dskReadAckInt || dskReadAckExt;
assign _romOE = ~(extraRomRead || (cpuBusControl && selectROM && _cpuRW));
wire extraRamRead = sndReadAck;
assign _ramOE = ~((videoBusControl && videoControlActive) || (extraRamRead) ||
(cpuBusControl && selectRAM && _cpuRW));
assign _ramWE = ~(cpuBusControl && selectRAM && !_cpuRW);
assign _memoryUDS = cpuBusControl ? _cpuUDS : 1'b0;
assign _memoryLDS = cpuBusControl ? _cpuLDS : 1'b0;
wire [21:0] addrMux = sndReadAck ? audioAddr : videoBusControl ? videoAddr : cpuAddr[21:0];
wire [21:0] macAddr;
assign macAddr[15:0] = addrMux[15:0];
// video and sound always addresses ram
wire ram_access = (cpuBusControl && selectRAM) || videoBusControl || sndReadAck;
wire rom_access = (cpuBusControl && selectROM);
// simulate smaller RAM/ROM sizes
assign macAddr[16] = rom_access && configROMSize == 2'b00 ? 1'b0 : // force A16 to 0 for 64K ROM access
addrMux[16];
assign macAddr[17] = ram_access && configRAMSize == 2'b00 ? 1'b0 : // force A17 to 0 for 128K RAM access
rom_access && configROMSize == 2'b01 ? 1'b0 : // force A17 to 0 for 128K ROM access
rom_access && configROMSize == 2'b00 ? 1'b1 : // force A17 to 1 for 64K ROM access (64K ROM image is at $20000)
addrMux[17];
assign macAddr[18] = ram_access && configRAMSize == 2'b00 ? 1'b0 : // force A18 to 0 for 128K RAM access
rom_access && configROMSize != 2'b11 ? 1'b0 : // force A18 to 0 for 64K/128K/256K ROM access
addrMux[18];
assign macAddr[19] = ram_access && configRAMSize[1] == 1'b0 ? 1'b0 : // force A19 to 0 for 128K or 512K RAM access
rom_access ? 1'b0 : // force A19 to 0 for ROM access
addrMux[19];
assign macAddr[20] = ram_access && configRAMSize != 2'b11 ? 1'b0 : // force A20 to 0 for all but 4MB RAM access
rom_access ? 1'b0 : // force A20 to 0 for ROM access
addrMux[20];
assign macAddr[21] = ram_access && configRAMSize != 2'b11 ? 1'b0 : // force A21 to 0 for all but 4MB RAM access
rom_access ? 1'b0 : // force A21 to 0 for ROM access
addrMux[21];
// floppy emulation gets extra slots 0 and 1
assign dskReadAckInt = (extraBusControl == 1'b1) && (extra_slot_count == 0);
assign dskReadAckExt = (extraBusControl == 1'b1) && (extra_slot_count == 1);
// audio gets extra slot 2
assign sndReadAck = (extraBusControl == 1'b1) && (extra_slot_count == 2);
assign memoryAddr =
dskReadAckInt ? dskReadAddrInt + 22'h100000: // first dsk image at 1MB
dskReadAckExt ? dskReadAddrExt + 22'h200000: // second dsk image at 2MB
macAddr;
// address decoding
addrDecoder ad(
.configROMSize(configROMSize),
.address(cpuAddr),
._cpuAS(_cpuAS),
.memoryOverlayOn(memoryOverlayOn),
.selectRAM(selectRAM),
.selectROM(selectROM),
.selectSCSI(selectSCSI),
.selectSCC(selectSCC),
.selectIWM(selectIWM),
.selectVIA(selectVIA),
.selectSEOverlay(selectSEOverlay));
// video
videoTimer vt(
.clk(clk),
.clk_en(clk8_en_p),
.busCycle(busCycle),
.vid_alt(vid_alt),
.videoAddr(videoAddr),
.hsync(hsync),
.vsync(vsync),
._hblank(_hblank),
._vblank(_vblank),
.loadPixels(loadPixels));
endmodule