module PCMCIA
title 'PCMCIA Interface'

"This is a module for a PCMCIA Interface on the PC Card.
"It integrates all the sub functions as grouped below.
"The macro is designed to be generic, it can be modified 
"to suit the application. 

"A 16-bit I/O interface is implemented, with 8-bit I/O functions 
"commented-out, choose appropriate I/O function.
"Comments at appropriate places help modification.
"'_' at the end of the signal name indicates active low.

DECLARATIONS
"---------------------------------------- INPUTS ----------------------"
    [AD7..AD0]    PIN;
    REG           PIN;
    OEn           PIN;
    CE1n          PIN;
    CE2n          PIN;
    wen_pgmn      PIN;
    IORDn         PIN;
    IOWRn         PIN;

"---------------------------------------- OUTPUTS ----------------------"
    wp__iois16    PIN ISTYPE 'COM';
    IORn          PIN ISTYPE 'COM';
    IOWn          PIN ISTYPE 'COM';
    INPACKn       PIN ISTYPE 'COM';

    AMCSn         PIN ISTYPE 'COM';
    AMOEn         PIN ISTYPE 'COM';
    AMWEn         PIN ISTYPE 'COM';

    CMCSEn        PIN ISTYPE 'COM';   "controls even byte of 16-bit word
    CMCSOn        PIN ISTYPE 'COM';   "controls odd byte of 16-bit word
    CMOEn         PIN ISTYPE 'COM';
    CMWEn         PIN ISTYPE 'COM';

    IOCSEn        PIN ISTYPE 'COM';
    IOCSOn        PIN ISTYPE 'COM';

    [D7..D0]      pin istype 'COM';    "BIDIR

    selreg1_      node ISTYPE 'COM';
    selreg2_      node ISTYPE 'COM';
    selreg3_      node ISTYPE 'COM';
    selreg0_      node ISTYPE 'COM';
    sel, muxen    node istype 'COM';

    [o_p07..o_p00]    node ISTYPE 'COM';
    [o_p17..o_p10]    node ISTYPE 'COM';
    [o_p27..o_p20]    node ISTYPE 'COM';
    [o_p37..o_p30]    node ISTYPE 'COM';

    [reg0_7..reg0_0]  node ISTYPE 'REG';
    [reg1_7..reg1_0]  node ISTYPE 'REG';
    [reg2_7..reg2_0]  node ISTYPE 'REG';
    [reg3_7..reg3_0]  node ISTYPE 'REG';

"---------------------------------------- GROUPS -----------------"
D_bus = [D7..D0];
reg0_bus = [ reg0_0..reg0_7 ];
reg1_bus = [ reg1_0..reg1_7 ];
reg2_bus = [ reg2_0..reg2_7 ];
reg3_bus = [ reg3_0..reg3_7 ];

X = .X.;

EQUATIONS
"------------------------------------------------------------"

"Attribute Memory Handler"    
"This macro generates control signals for attribute memory.
"Locations 0100H, 0102H, 0104H and 0106H are reserved
"for Card Configuration registers.

AMCSn = !(!REG & !CE1n & (!AD0 & CE2n # !CE2n));
AMOEn = !(!REG & !OEn & wen_pgmn);
AMWEn = !(!REG & !wen_pgmn & OEn);

"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"Common  Memory Handler"
"This macro decodes address and control signals
"and generates CS and OE and WE signals for Common Memory.
"Common Memory is 16-bits. The High Byte and the Low Byte can
"be accesses individually.
"CMCSE selects even addresses and CMCSO selects odd addresses

CMCSEn = !(REG & !CE1n & ((CE2n & !AD0) # !CE2n));
CMCSOn = !( (CE2n & !CE1n & AD0 & REG) # (!CE2n & !CE1n & REG) # (!CE2n & CE1n & REG));
CMOEn =  !( REG & !OEn & wen_pgmn);
CMWEn  = !( REG & OEn & !wen_pgmn);

"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"Remove comments on io8 and comment-out io16 
"to make macro for 8-bit I_O 
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"io8, 8-Bit Input / Output Handler"
"Generates control signals for 8-bit IO
"INPACK is asserted when IO address is valid and
"is selected for reading.
"IOIS16 is negated.
"The bus-controller handles
"even and odd bytes individually for byte access 

"IORn = !(!REG & CE2n & (!CE1n)  & (!IORDn) & IOWRn);
"IOWn = !(!REG & CE2n & !CE1n & IORDn & !IOWRn);
"INPACKn = IORn & IOWn;
"wp__iois16 = 1;


"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"io16, 16-Bit Input / Output Handler"
"Generates control signals for 16-bit IO.
"INPACK is asserted when IO address is valid and
"is selected for reading.
"IOIS16 is asserted when IO transfer is attempted.
"The bus-controller handles even and odd bytes 
"individually for byte access in 16-bit controller.


IORn = !(!REG & !IORDn & IOWRn &((!CE1n & !AD0) # (CE1n & !CE2n)) );
IOWn = !(!REG & !IOWRn & IORDn &((!CE1n & !AD0) # (CE1n & !CE2n)) );
INPACKn = IORn & IOWn;
wp__iois16 = !(!REG & ((!IORDn) # (IORDn & !IOWRn)));

IOCSEn = !( (!IORDn # !IOWRn) & !REG & !CE1n & ((CE2n & !AD0) # (CE2n & !AD0)));
IOCSOn = !( (!IORDn # !IOWRn) & !REG & ((!CE2n & !CE1n & !AD0) # (!CE2n & CE1n ) # 
    (CE2n & !CE1n & AD0)));


"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"Card Configuration Registers"
"Four card configuration registers are assumed.
"Card Configuration registers are located at 10H, 12H, 14H & 16H.
"In case of I/O cards these registers contain card configurable characteristics 
"like I/O address space, power requirements, and interrupt request.
"The addresses are decoded assuming 256 ROM. Modify address lines AD appropriately


"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"Registers of CCRs ;     
"Four card configuration registers are assumed.
"Card Configuration registers are located at 10H, 12H, 14H & 16H.
"In case of I/O cards these registers contain card configurable
"characteristics like I/O address space, power requirements, and 
"interrupt request.
"The addresses are decoded assuming 8K ROM. Modify AD appropriately.

TRUTH_TABLE
([REG, AD7..AD0] -> [selreg0_, selreg1_, selreg2_, selreg3_])
[0, 0,0,0,1,0,0,0,0] -> [0, 1, 1, 1];
[0, 0,0,0,1,0,0,1,0] -> [1, 0, 1, 1];
[0, 0,0,0,1,0,1,0,0] -> [1, 1, 0, 1];
[0, 0,0,0,1,0,1,1,0] -> [1, 1, 1, 0];

[X, X,X,X,X,X,X,X,1] -> [1, 1, 1, 1];
[X, X,X,X,X,1,X,X,X] -> [1, 1, 1, 1];
[X, X,X,X,0,X,X,X,X] -> [1, 1, 1, 1];
[X, X,X,1,X,X,X,X,X] -> [1, 1, 1, 1];
[X, X,1,X,X,X,X,X,X] -> [1, 1, 1, 1];
[X, 1,X,X,X,X,X,X,X] -> [1, 1, 1, 1];
[1, X,X,X,X,X,X,X,X] -> [1, 1, 1, 1];
"END TABLE
equations

reg0_bus.D = ( !selreg0_ & D_bus ) # ( reg0_bus.FB & selreg0_ );
reg1_bus.D = ( !selreg1_ & D_bus ) # ( reg1_bus.FB & selreg1_ );
reg2_bus.D = ( !selreg2_ & D_bus ) # ( reg2_bus.FB & selreg2_ );
reg3_bus.D = ( !selreg3_ & D_bus ) # ( reg3_bus.FB & selreg3_ );

reg0_bus.CLK  = !wen_pgmn;
reg1_bus.CLK  = !wen_pgmn;
reg2_bus.CLK  = !wen_pgmn;
reg3_bus.CLK  = !wen_pgmn;

[o_p07..o_p00] = reg0_bus.q;
[o_p17..o_p10] = reg1_bus.q;
[o_p27..o_p20] = reg2_bus.q;
[o_p37..o_p30] = reg3_bus.q;

"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
"Multiplexer     
"Four card configuration registers are assumed. This submacro muxes the
"the 4 registers.
"Card Configuration registers are located at 10H, 12H, 14H & 16H.
"In case of I/O cards these registers contain card configurable
"characteristics like I/O address space, power requirements, and 
"interrupt request.
"The addresses are decoded assuming 8K ROM. Modify AD appropriately.

TRUTH_TABLE
([REG, AD7..AD0] -> [sel])
[0, 0,0,0,1,0,0,0,0] -> [1];
[0, 0,0,0,1,0,0,1,0] -> [1];
[0, 0,0,0,1,0,1,0,0] -> [1];
[0, 0,0,0,1,0,1,1,0] -> [1];

[X, X,X,X,X,X,X,X,1] -> [0];
[X, X,X,X,X,1,X,X,X] -> [0];
[X, X,X,X,0,X,X,X,X] -> [0];
[X, X,X,1,X,X,X,X,X] -> [0];
[X, X,1,X,X,X,X,X,X] -> [0];
[X, 1,X,X,X,X,X,X,X] -> [0];
[1, X,X,X,X,X,X,X,X] -> [0];

"END TABLE
equations

muxen = !(sel & !OEn);

D0 = (
  ((!AD1 & !AD2) & o_p00)
# (( AD1 & !AD2) & o_p10)
# ((!AD1 &  AD2) & o_p20)
# (( AD1 &  AD2) & o_p30)
) & muxen;

D1 = (
  ((!AD1 & !AD2) & o_p01)
# (( AD1 & !AD2) & o_p11)
# ((!AD1 &  AD2) & o_p21)
# (( AD1 &  AD2) & o_p31)
) & muxen;

D2 = (
  ((!AD1 & !AD2) & o_p02)
# (( AD1 & !AD2) & o_p12)
# ((!AD1 &  AD2) & o_p22)
# (( AD1 &  AD2) & o_p32)
) & muxen;

D3 = (
  ((!AD1 & !AD2) & o_p03)
# (( AD1 & !AD2) & o_p13)
# ((!AD1 &  AD2) & o_p23)
# (( AD1 &  AD2) & o_p33)
) & muxen;

D4 = (
  ((!AD1 & !AD2) & o_p04)
# (( AD1 & !AD2) & o_p14)
# ((!AD1 &  AD2) & o_p24)
# (( AD1 &  AD2) & o_p34)
) & muxen;

D5 = (
  ((!AD1 & !AD2) & o_p05)
# (( AD1 & !AD2) & o_p15)
# ((!AD1 &  AD2) & o_p25)
# (( AD1 &  AD2) & o_p35)
) & muxen;

D6 = (
  ((!AD1 & !AD2) & o_p06)
# (( AD1 & !AD2) & o_p16)
# ((!AD1 &  AD2) & o_p26)
# (( AD1 &  AD2) & o_p36)
) & muxen;

D7 = (
  ((!AD1 & !AD2) & o_p07)
# (( AD1 & !AD2) & o_p17)
# ((!AD1 &  AD2) & o_p27)
# (( AD1 &  AD2) & o_p37)
) & muxen;
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"

END


