<div dir="auto"><p dir="ltr">Wow, many thanks! You&#39;re much better at me than this. I&#39;ve been opening up the PALs, in fact here&#39;s a quick cute experiment with AI:<br>
<a href="https://docs.google.com/document/d/1Iyer7eJRi2jGZQePto-YRO8U6GWU5KA0uFywxfltUe8/edit?usp=drivesdk" target="_blank" rel="noreferrer">https://docs.google.com/document/d/1Iyer7eJRi2jGZQePto-YRO8U6GWU5KA0uFywxfltUe8/edit?usp=drivesdk</a></p><p dir="ltr">I&#39;ll go through more details tonight after work, but you covered most of what I&#39;ve gotten to so far. The 3/60 can neither use bigger than 1Mb sticks, nor less. At some point I want to look at how the 3/80 deals with RAM. Since you also need a newer boot ROM to support 4mb sticks on it, leads me to believe there&#39;s a software controlled mapping around holes or stitching into a contiguous space that would be nice to learn from.</p><p dir="ltr">The TOWAY system and interleaving is pretty confusing, wondering too if it was done for refresh speed or to save some signals - can&#39;t see it be a giant advantage in either case.</p><p dir="ltr">There are 2 paths here really - trying to get in 4mb 30pin SIMMS which we can do within the current mechanical constraints (chips, slots and rough traces). I&#39;ve forced the signals on top and bottom on purpose and have made some patches already, so we can change a few things around and edit the PAL logic. There is space for one more address line (2 address bits) on U906 row/column multiplexer and if we&#39;re not worrying about TOWAY, should be easier.</p><p dir="ltr">The second path is to move to 72 pin SIMMs. Since it requires new layout, we can do substantially more. Using the original board layout as a testbed, I can try to consolidate 4x8 into 32 just with patching in a 72 pin holder so the RAS-based vs. CAS-based selection analysis helps.</p><p dir="ltr">Then we can combine the two methods and get 4x8x32 for example. Whatever design we end up with though, it will only support one SIMM size.</p></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 29, 2025, 07:46 Romain Dolbeau &lt;<a href="mailto:romain@dolbeau.org" target="_blank" rel="noreferrer">romain@dolbeau.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Le jeu. 29 mai 2025 à 15:04, Romain Dolbeau &lt;<a href="mailto:romain@dolbeau.org" rel="noreferrer noreferrer" target="_blank">romain@dolbeau.org</a>&gt; a écrit :<br>
&gt; In any case, it means all<br>
&gt; of that logic would need to be understood and rewritten to change from<br>
&gt; select-by-RAS to select-by-CAS :-(<br>
<br>
Might not be that bad; the current logic seems a bit complex, but it&#39;s<br>
just because PAL language is terrible.<br>
See below for a rough automatic translation from EQN to Verilog.<br>
<br>
Basically, the current logic, if we ignore TWOWAY and SEL0/SEL1 is<br>
* use A[2..21] (20 bits) to access a set of 1 MiB SIMM, so a block of 4 MiB<br>
* use A0/A1/SIZ0/SIZ1 (as per the 68k bus specifications) to pick<br>
bytes, and use the 4 RAS signal to enable/disable them<br>
* use A[22..27] to pick which set of SIMM to actually use through the<br>
CAS signals.<br>
(TWOWAY just semantically swap A2 and A22).<br>
<br>
That last bullet imply you could use 256 MiB (2^6 * 4 MiB), but the<br>
upper three bits (A25-A27) are only used to disable the CAS, and A24<br>
is only used 2/3 - so you really get only 6 * 4 MiB, for 24MiB total.<br>
There&#39;s no hardware to support smaller/larger SIMM that I can see.<br>
<br>
So assuming a similar restriction of &quot;fixed size SIMM&quot;, it should be<br>
possible to hardwire for e.g. 16 MiB 72-pins SIMMs by similar logic:<br>
<br>
* use A[2..23] (22 bits) to access a single 16 MiB SIMM, so a block of 16 MiB<br>
* use A0/A1/SIZ0/SIZ1 to pick bytes, and use the 4 CAS signal to<br>
enable/disable them (CAS not RAS here!)<br>
* use A[22..27] to pick which set of SIMM to actually use through one<br>
RAS signal per SIMM<br>
(and then maybe support TWOWAY again to interleave pair of SIMMs)<br>
<br>
Essentially the same logic as now, but swapping the populated/address<br>
check with the bus-sizing check for CAS and RAS. It should be possible<br>
to get 16 (one simm) to 64 MiB of RAM (four simm) that way, provided<br>
the PROM can be fixed to report it (or even more, but that would<br>
require a lot of SIMMs or the use of larger, less common SIMMs).<br>
<br>
Of course the real problem would be that the refresh logic might also<br>
need updating...<br>
<br>
<br>
The current RAS logic:<br>
<br>
module PAL16L8_x1578-01 (<br>
    input    i_SIZ0,<br>
    input    i_SIZ1,<br>
    input    i_A0,<br>
    input    i_A1,<br>
    input    i_SEL0n,<br>
    input    i_SEL1,<br>
    input    i_WRITEn,<br>
    input    i_R_ACKn,<br>
    input    i_M_PDn,<br>
    output    o_RE13n,<br>
    output    o_RE12n,<br>
    output    o_RE11n,<br>
    output    o_RE10n,<br>
    output    o_RE03n,<br>
    output    o_RE02n,<br>
    output    o_RE01n,<br>
    output    o_RE00n<br>
);<br>
    assign o_RE00n    = (~i_M_PDn) ? (i_R_ACKn &amp; (i_SEL0n | ~i_WRITEn)<br>
&amp; (~i_A0 | ~i_A1 | i_SEL0n) &amp; (~i_SIZ1 | ~i_A1 | i_SEL0n) &amp; (i_SIZ1 |<br>
i_SIZ0 | i_SEL0n) &amp; (~i_SIZ1 | ~i_SIZ0 | ~i_A0 | i_SEL0n)) : &#39;bZ;<br>
    assign o_RE01n    = (~i_M_PDn) ? (i_R_ACKn &amp; (i_SEL0n | ~i_WRITEn)<br>
&amp; (i_A0 | ~i_A1 | i_SEL0n) &amp; (~i_SIZ1 | ~i_A0 | i_A1 | i_SEL0n) &amp;<br>
(i_SIZ1 | i_SIZ0 | i_A1 | i_SEL0n) &amp; (~i_SIZ1 | ~i_SIZ0 | i_A1 |<br>
i_SEL0n)) : &#39;bZ;<br>
    assign o_RE02n    = (~i_M_PDn) ? (i_R_ACKn &amp; (i_SEL0n | ~i_WRITEn)<br>
&amp; (~i_A0 | i_A1 | i_SEL0n) &amp; (i_SIZ0 | i_A1 | i_SEL0n) &amp; (~i_SIZ1 |<br>
i_A1 | i_SEL0n)) : &#39;bZ;<br>
    assign o_RE03n    = (~i_M_PDn) ? (i_R_ACKn &amp; (i_SEL0n | ~i_WRITEn)<br>
&amp; (i_A0 | i_A1 | i_SEL0n)) : &#39;bZ;<br>
    assign o_RE10n    = (~i_M_PDn) ? (i_R_ACKn &amp; (~i_SEL1 | ~i_WRITEn)<br>
&amp; (~i_A0 | ~i_A1 | ~i_SEL1) &amp; (~i_SIZ1 | ~i_A1 | ~i_SEL1) &amp; (i_SIZ1 |<br>
i_SIZ0 | ~i_SEL1) &amp; (~i_SIZ1 | ~i_SIZ0 | ~i_A0 | ~i_SEL1)) : &#39;bZ;<br>
    assign o_RE11n    = (~i_M_PDn) ? (i_R_ACKn &amp; (~i_SEL1 | ~i_WRITEn)<br>
&amp; (i_A0 | ~i_A1 | ~i_SEL1) &amp; (~i_SIZ1 | ~i_A0 | i_A1 | ~i_SEL1) &amp;<br>
(i_SIZ1 | i_SIZ0 | i_A1 | ~i_SEL1) &amp; (~i_SIZ1 | ~i_SIZ0 | i_A1 |<br>
~i_SEL1)) : &#39;bZ;<br>
    assign o_RE12n    = (~i_M_PDn) ? (i_R_ACKn &amp; (~i_SEL1 | ~i_WRITEn)<br>
&amp; (~i_A0 | i_A1 | ~i_SEL1) &amp; (i_SIZ0 | i_A1 | ~i_SEL1) &amp; (~i_SIZ1 |<br>
i_A1 | ~i_SEL1)) : &#39;bZ;<br>
    assign o_RE13n    = (~i_M_PDn) ? (i_R_ACKn &amp; (~i_SEL1 | ~i_WRITEn)<br>
&amp; (i_A0 | i_A1 | ~i_SEL1)) : &#39;bZ;<br>
endmodule // PAL16L8_x1578-01<br>
<br>
The current CAS logic (I think S0n...S5n is just whether a bank of 4<br>
SIMMs is populated)<br>
<br>
module PAL20L8_x1585-01 (<br>
    input    i_M_S0n,<br>
    input    i_M_S1n,<br>
    input    i_M_S2n,<br>
    input    i_M_S3n,<br>
    input    i_M_S4n,<br>
    input    i_M_S5n,<br>
    input    i_PA02_22,<br>
    input    i_PA23,<br>
    input    i_PA24,<br>
    input    i_PA25,<br>
    input    i_PA26,<br>
    input    i_PA27,<br>
    input    i_M_ACKn,<br>
    output    o_CEn,<br>
    output    o_TWOWAYn,<br>
    output    o_CAS5n,<br>
    output    o_CAS4n,<br>
    output    o_CA3n,<br>
    output    o_CAS2n,<br>
    output    o_CAS1n,<br>
    output    o_CAS0n,<br>
    input    i_M_PDn<br>
);<br>
    assign o_CAS0n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S0n | i_PA02_22<br>
| i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_CAS1n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S1n | ~i_PA02_22<br>
| i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_CAS2n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S2n | i_PA02_22<br>
| ~i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_CA3n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S3n | ~i_PA02_22<br>
| ~i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_CAS4n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S4n | i_PA02_22<br>
| i_PA23 | ~i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_CAS5n    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S5n | ~i_PA02_22<br>
| i_PA23 | ~i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
    assign o_TWOWAYn    = (~i_M_PDn) ? ((i_M_S1n | i_M_S0n | i_M_S2n |<br>
i_M_S3n | i_M_S4n | i_M_S5n) &amp; (i_M_S1n | i_M_S0n | i_M_S2n | i_M_S3n<br>
| ~i_M_S4n | ~i_M_S5n) &amp; (i_M_S1n | i_M_S0n | ~i_M_S2n | ~i_M_S3n |<br>
~i_M_S4n | ~i_M_S5n)) : &#39;bZ;<br>
    assign o_CEn    = (~i_M_PDn) ? (i_M_ACKn &amp; (i_M_S0n | i_PA02_22 |<br>
i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27) &amp; (i_M_S1n | ~i_PA02_22 |<br>
i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27) &amp; (i_M_S4n | i_PA02_22 |<br>
i_PA23 | ~i_PA24 | i_PA25 | i_PA26 | i_PA27) &amp; (i_M_S5n | ~i_PA02_22 |<br>
i_PA23 | ~i_PA24 | i_PA25 | i_PA26 | i_PA27) &amp; (i_M_S2n | i_PA02_22 |<br>
~i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27) &amp; (i_M_S3n | ~i_PA02_22 |<br>
~i_PA23 | i_PA24 | i_PA25 | i_PA26 | i_PA27)) : &#39;bZ;<br>
endmodule // PAL20L8_x1585-01<br>
<br>
<br>
-- <br>
Romain Dolbeau<br>
</blockquote></div>