    // FIXME: OS/9 MMU doesn't work


module superpet (
    input MHZ16,
    output LED,
    input WREN,         // input from write protect switch
    input nRES,         // daughter board reset generated by U3C (74HCT11)
    input nERES,        // /RESET from CBM motherboard
    output GRW,         // generated R/W for Flash and RAM
    input RW,           // R/W from 6502 and 6809
    input TSC,          // CPU select: 0=6809, 1=6502
    output reg PROG,    // system latch[0]: output to CPU select switch
    output reg WRPRG,   // system latch[1]: output to write protect switch
    output reg uDIAG,   // system latch[3]: output to DIAG line
    output nOE,         // Output Enable to Flash and RAM
    output nROMCS,      // /CS for Flash
    output nRAMCS,      // /CS for RAM
    output reg uQ,      // clock signals for 6809E
    output reg uE,
    input PHI0,         // PHI0 (1 MHz) from Motherboard
    output PHI2,        // PHI2 to CBM motherboard
    output nFIRQ,       // 6809E /FIRQ, used by SuperPET OS/9 MMU
    output ERW,         // R/W to CBM motherboard
    output CSACIA,      // 6551 chip select, active high
    input BA,           // 6809E BA
    input BS,           // 6809E BS
    inout  [7:0] D,     // internal data bus on daughter board
    inout  [7:0] ED,    // data bus to/from CBM motherboard
    input [15:0] A,     // address bus
    output EA15,        // A15 to CBM motherboard
    output MA12,        // extended address lines
    output MA13,
    output MA14,
    output MA15,
    output MA16,
    output reg MA17,
    output reg MA18
    );


    // ===== System Reset ============================================
    always @ (negedge nERES)
    begin
        MA17 <= 1;      // 128 KB RAM chips have high active CS2 there
        MA18 <= 0;
    end

    assign MA16 = nRAMCS ? TSC   : bankswitch[4];
    assign MA15 = nRAMCS ? A[15] : bankswitch[3];
    assign MA14 = nRAMCS ? A[14] : bankswitch[2];
    assign MA13 = nRAMCS ? A[13] : bankswitch[1];
    assign MA12 = nRAMCS ? A[12] : bankswitch[0];

    // ===== Clock Generation ========================================
    reg [4:0] clk;
    reg [1:3] resync;
    reg rise;

    always @ (posedge MHZ16)
    begin
        rise <= resync[2] & !resync[3];
        // fall <= resync[3] & !resync[2];
        resync <= {PHI0 , resync[1:2]};
        if (rise) begin
            clk <= 0;
            uQ <= 0;
        end else begin
            clk = clk + 1'b1;
            if (clk ==  8) uQ <= 1;
            if (clk ==  4) uE <= 0;
            if (clk == 12) uE <= 1;
        end

        ED2D <= ED;
        D2ED <= D;

    end
    assign PHI2 = PHI0 ;    // 1 MHz PHI2 to CBM motherboard

    // ===== Temporary Assignments ===================================

    wire A_9XXX;
    wire IO_AREA;
    wire ONBOARD;
    wire OUR_IO;
    wire MEMWR;
    wire MEMRD;
    wire OS9SEL;

    assign EA15 = ONBOARD ? 0 : A[15];
    assign ERW  = ONBOARD ? 1 : RW;

    assign GRW = !MEMWR;    // TODO: implement R/W protection

    assign nOE = !MEMRD;    // Output Enable to Flash and RAM


    assign A_9XXX = A[15:12] == 9;

    assign nRAMCS = !(
        ( TSC & A_9XXX & !RAMROM) ||                // 6502 active
        (!TSC & A_9XXX));                           // 6809 active

    assign nROMCS = !(
        ( TSC & !IO_AREA & (A[15:12] == 4'hA)) ||   // 6502 active
        (!TSC & !IO_AREA & (A[15:12] >= 4'hA))      // 6809 active
        );


    // ===== Pass data trough CPLD ===================================

    reg [7:0] ED2D;
    reg [7:0] D2ED;

    assign IO_AREA = (A >= 16'hE800) & (A <= 16'hEFFF);
    assign OUR_IO  = (A >= 16'hEFE0) & (A <= 16'hEFFF);
    assign ONBOARD = OUR_IO | !nRAMCS | !nROMCS;
    assign D  = ( RW & !ONBOARD & !CSACIA) ? ED2D : 8'bZ;
    assign ED = (!RW & !ONBOARD & !CSACIA) ? D2ED : 8'bZ;

    // ===== Bank switch latch $EFFC - $EFFD =========================
    reg [7:0] bankswitch;

    assign MEMWR = ~RW & uE;
    assign MEMRD =  RW & uE;

    // nFIRQ is used by SuperPET OS/9 MMU to switch back to PET memory map
    always @(negedge MEMWR or negedge nRES or negedge nFIRQ)
    begin
        if (nRES == 0 || nFIRQ == 0) begin
            bankswitch <= 8'b0;
        end else if (A[15:1] == 15'b111011111111110) begin
            bankswitch <= D;
        end
    end


    // ===== System latch $EFF8 - $EFFB ==============================
    always @(negedge MEMWR or negedge nERES)
    begin
        if (nERES == 0) begin
            PROG  <= 0;     // system latch[0]: to CPU select switch
            WRPRG <= 0;     // system latch[1]: to write protect switch
            uDIAG <= 0;     // system latch[3]: to DIAG line
        end else if (bankswitch[7] & A[15:2] == 14'b11101111111110) begin
            PROG  <= D[0];
            WRPRG <= D[1];
            uDIAG <= D[3];
        end
    end

    // ===== RAM/ROM selection $EFFE - $EFFF =========================
    reg RAMROM;
    always @(negedge MEMWR or negedge nERES)
    begin
        if (nERES == 0) begin
            RAMROM <= 0;
        end else if (A[15:1] == 15'b111011111111111) begin
            RAMROM <= D[0];
        end
    end


    // ===== ACIA chip select $EFF0 - $EFF3 ==========================
    assign CSACIA = A[15:2] == 14'b11101111111100;

    // ===== SuperPET OS/9 MMU =======================================
    assign nFIRQ = bankswitch[5] | BS | ~BA; // bankswitch[5] = 1 --> /FIRQ disabled
    assign OS9SEL = ~bankswitch[6] | BA;



    assign LED = TSC;

endmodule




// vim: noai:ts=4:sw=4:et
