; Applix ; 1616 ; U15 ; Timing logic ; Keith ; Date: ; 2026-05-22 1st draft ; 2026-06-10 First compilation after considering ; observed behaviour of original PAL chip ; ; Status: UNTESTED! ; chip 1616_U51 PAL16R8 chip 1616_U51 GAL16V8 clk = 1 /Q0 = 2 ; 15 MHz /RAMSEL = 3 /DISPEN = 4 /AS = 5 /UDS = 6 /LDS = 7 RNW = 8 /RESET = 9 /OE = 11 ; <-- OE = GND ; Outputs /Q1 = 19 ; /7.5 MHz is CPU CLK /Q2 = 18 ; /3.75 MHz /CCLK = 17 ; /1.875 MHz is CCLK on CRTC, B on the multiplexers. /DTACKR = 16 ; /RAS = 15 ; /RAS /CASU = 14 ; /CAS for bits D15...8 /CASL = 13 ; /CAS for bits D7...0 /LP = 12 ; /LPULSE @define reading "RNW" @define writing "/RNW" @define phase_0 "/Q2*/Q1*/Q0" @define phase_1 "/Q2*/Q1*Q0" @define phase_2 "/Q2*Q1*/Q0" @define phase_3 "/Q2*Q1*Q0" @define phase_4 "Q2*/Q1*/Q0" @define phase_5 "Q2*/Q1*Q0" @define phase_6 "Q2*Q1*/Q0" @define phase_7 "Q2*Q1*Q0" @define phase_1_3_5_7 "/Q0" @define phase_0_2_4_6 "Q0" @define phase_3_2_6_7 "Q1" @define phase_0_or_1 "/Q2*/Q1" @define phase_2_or_3 "/Q2*Q1" @define phase_6_or_7 "Q2*Q1" @define phase_4_to_7 "Q2" @define vdu_window "/CCLK" @define cpu_window "CCLK" ; ; Uncomment this line if you want to disable /CAS ; during reset active. ; ;@define running "/RESET" ; ; or this if you want the original PAL chip behaviour: ; @define running "VCC" ; ; RAS is 5 cycles ; @define RAS_begin "phase_4_to_7" @define RAS_end "phase_0" ; ; CAS is 4 cycles, but 5 cycles for CPU reading. ; @define CAS_begin "phase_6_or_7" @define CAS_end "phase_0_or_1" @define CAS_extra "phase_2" ; ; DTACK CPU timing. ; @define DTACK_begin "cpu_window" @define DTACK_end "vdu_window*phase_2_or_3" ; ; Nested macros resolved directly to eliminate space/nesting limits ; ; @define RAS_begin "Q2" ; @define RAS_end "/Q2*/Q1*/Q0" ; @define CAS_begin "Q2*Q1" ; @define CAS_end "/Q2*/Q1" ; @define CAS_extra "/Q2*Q1*/Q0" ; @define DTACK_begin "CCLK" ; @define DTACK_end "/CCLK*/Q2*Q1"; ; ; ; equations ; have to come AFTER the @defines! ; ; ; Q1.D = Q1 * /Q0 + /Q1 * Q0; Q2.D = Q2 * /Q1 + Q2 * /Q0 + /Q2 * Q1 * Q0; ; ; Q2,1,0 behave just like a synchronous binary counter. ; ; They control the waveform timing of DRAM signals. ; ; One waveform for video, another for the processor. ; ; The character clock is half the rate of Q2, but slightly slewed. ; ; ; CCLK toggles only after phase_1 ; CCLK.D = /CCLK * phase_1 + CCLK * phase_1_3_5_7 + CCLK * phase_3_2_6_7 + CCLK * phase_4_to_7; ; ; LP active during the falling edge of the video window. ; LP.D = vdu_window * phase_0_or_1; ; ; RAS always driven in the video time window, ; whether accessing vided data ; or refreshing DRAM. ; ; It is active if the CPU is addressing RAM and AS is asserted. ; ; RAS.D = vdu_window * RAS_begin + vdu_window * RAS_end + cpu_window * RAS_begin * RAMSEL * AS + cpu_window * RAS_end * RAMSEL * AS; ; ; CASU and CASL are asserted during video data accesses, ; or CPU accesses. ; They last slightly longer for the CPU reading, ; perhaps to give the CPU a bit extra time ; to read the data before they disappear. ; CASU.D = vdu_window * CAS_begin * DISPEN + vdu_window * CAS_end * DISPEN + cpu_window * CAS_begin * RAMSEL * UDS + cpu_window * CAS_end * RAMSEL * UDS + cpu_window * CAS_extra * RAMSEL * UDS * reading; CASL.D = vdu_window * CAS_begin * DISPEN + vdu_window * CAS_end * DISPEN + cpu_window * CAS_begin * RAMSEL * LDS + cpu_window * CAS_end * RAMSEL * LDS + cpu_window * CAS_extra * RAMSEL * LDS * reading; ; ; DTACKR (DTACK from RAM) to the CPU is asserted ; during the cpu time window and ; slightly longer into the video time window. ; DTACKR.D = DTACK_begin * RAMSEL * LDS + DTACK_end * RAMSEL * LDS + DTACK_begin * RAMSEL * UDS + DTACK_end * RAMSEL * UDS;