I was a bit premature in declaring the DRAM controller for Mackerel-30 complete. It was minimally functional as an 8-bit wide memory, but failed for any multi-byte or offset bus cycles. Implementing these wider memory cycles correctly requires some additional logic in the controller to correctly select the CAS lines for all possible bus cycle types.
On 72-pin SIMMs, there are four RAS lines and four CAS lines. Asserting a pair of RAS lines (0,2 or 1,3) selects between the two "sides" of the SIMM in the case of double-sided SIMMs (Note: these sides refer to how the DRAM chips are wired electrically, not necessarily how they are physically soldered to the PCB). Each of the CAS lines acts like a byte-select pin for the four bytes in the 32-bit wide SIMM. The trick to getting the correct bytes from DRAM onto the data bus requires decoding the SIZ0, SIZ1, A0, and A1 pins from the CPU into the right combination of CAS signals for the SIMM.
Fortunately, the MC68030 datasheet covers all of this in detail.
These two tables show how the SIZ0 and SIZ1 pins can be used to determine the requested bus width and how the A0 and A1 pins are used to set an offset if the request is not long word-aligned.
This huge table displays all possible combinations of bus width and offset and shows where the data is expected to be in each case. Since the DRAM always acts as a 32-bit wide memory, each of the entries in the Long-Word Port column map to a combination of CAS lines. For example, if the CPU requests a 16-bit word with an offset of 1 (row 6), the second and third bytes of the DRAM need to be read, so the CAS pattern is 0110 (active high).
The easiest way to translate this information into Verilog for the DRAM controller is with a case statement:
wire [3:0] CYCLE_TYPE = {SIZ1, SIZ0, ADDR[1], ADDR[0]};
reg [3:0] CAS; // active high
always @(*) begin
case (CYCLE_TYPE)
// CYCLE TYPE <= CAS[3:0]
// byte
4'b0100: CAS <= 4'b1000;
4'b0101: CAS <= 4'b0100;
4'b0110: CAS <= 4'b0010;
4'b0111: CAS <= 4'b0001;
// word
4'b1000: CAS <= 4'b1100;
4'b1001: CAS <= 4'b0110;
4'b1010: CAS <= 4'b0011;
4'b1011: CAS <= 4'b0001;
// 3-byte
4'b1100: CAS <= 4'b1110;
4'b1101: CAS <= 4'b0111;
4'b1110: CAS <= 4'b0011;
4'b1111: CAS <= 4'b0001;
// long word
4'b0000: CAS <= 4'b1111;
4'b0001: CAS <= 4'b0111;
4'b0010: CAS <= 4'b0011;
4'b0011: CAS <= 4'b0001;
default: CAS <= 4'b1111;
endcase
end
With the DRAM now handling different cycle types correctly, I set up address decoding to handle 64 or 128 MB SIMMs. The SIMM bank is selected based on the A26 line. If A26 is 0, RAS0 and RAS2 will be asserted, if A26 is 1, RAS1 and RAS3 will be asserted instead. This allows support for either a 64 or 128 MB SIMM, only the addressable size of the DRAM will change: 0x4000000 or 0x8000000 respectively. Smaller single-sided SIMMs (4 and 16 MB) should also work without modification, but other sizes of double-sided SIMMs would require modification to this address decoding scheme to be fully mapped, but who doesn't want as much RAM as possible anyway!?
To wrap up this DRAM improvement, I revamped the memory test code in the bootloader. There are now two ways to test memory: a simple 8-bit read and write test and a new 32-bit test that can cover the entire 128 MB memory space. The 32-bit test takes a start address and a size and writes the 32-bit address value to the memory at that same address, e.g. it will write the long-word 0xC0000000 to the memory at address 0xC0000000. This not only tests that the read and write is working for 32-bit cycles, but it makes it easy to check for incorrect or duplicate mapping across a whole range of memory. Each long-word of DRAM should contain its own address as its value at the end of the test. Running this test with the 128 MB SIMM installed shows that the entire memory space is accessible and uniquely mapped.
Does Mackerel-30 actually need 128 MB of RAM? Probably not, but I'm pretty happy that it's working all the same.
Verilog implementation of the DRAM controller: https://github.com/crmaykish/mackerel-68k/blob/master/pld/mackerel-30/dram_controller/dram_controller.v
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
As long as we're going into "comparable to a PC of the era" territory and if you like a challenge then you might try seeing if you can get Mac OS 8.1 to boot on it. You have the right CPU for the job and they have a qemu port that it will run on without modifications, meaning that it could provide what information you require to get it functional. I think the biggest problem would be graphics. However, even with basic graphics, that would put open up a large games library.
Are you sure? yes | no
That's an interesting idea. I have almost zero Mac experience so it would take some research. My plan for Mackerel-30 doesn't include any kind of graphics support, but I'd like to explore that for Mackerel-40. Maybe I can dig into Mac OS at that point.
Are you sure? yes | no
128 MB of EDO RAM in a PC?! Clearly, you're a rich man in 1995.
Are you sure? yes | no
Right? Slightly less impressive 30 years later. Now I just need something to take advantage of all this RAM.
Are you sure? yes | no