http://tinyvga.com/avr-isa-vga gives an example of driving an ISA bus from an Atmega. They mux the 8 data pins with the bottom 8 address pins on the microcontroller. The code looks like:
(Licensed under the GPL):
ADDRESS_HIGH &= 0x0F; // AddressHigh 4 bit and Reset is low
DDRA = 0xFF; // ADDRESS_LOW is output
ADDRESS_LOW = add%256; // Place the A0..A7 bit to BUS low
ADDRESS_MID = add/256; // Place the A8..A15 bit to BUS mid
ADDRESS_LATCH_ENABLE = 1; // Latch the value
ADDRESS_LATCH_ENABLE = 0;
ADDRESS_LOW = val; // Place the data to BUS low
IO_WRITE = 0; // Write to addressed io port
_NOP();
while(!IO_CH_READY);
ADDRESS_LOW = val; // Place the data to BUS low (@thejpster - this is spurious?)
IO_WRITE = 1;
_NOP();
DDRA = 0x00; // ADDRESS_LOW is input
PORTA = 0xFF;
A memory write looks like:
ADDRESS_HIGH = (addr>>16)&0xF0 ; // AddressHigh
DDRA = 0xFF; // ADDRESS_LOW is output
ADDRESS_LOW = addr&0xFF; // Place the A0..A7 bit to BUS low
ADDRESS_LATCH_ENABLE = 1; // Latch the value
ADDRESS_MID = (addr>>8)&0xFF; // Place the A8..A15 bit to BUS mid
ADDRESS_LATCH_ENABLE = 0;
ADDRESS_LOW = val; // Place the data to BUS low
MEMORY_WRITE = 0; // Write to addressed io port
ADMUX=0;
while(!IO_CH_READY);
ADDRESS_LOW = val; // Place the data to BUS low
MEMORY_WRITE = 1;
DDRA = 0x00; // ADDRESS_LOW is input
Seems nice and simple. It's asynchronous, like a parallel port - you write to the bus, strobe the correct line, then poll for an acknowledgement from the device.
http://tinyvga.com/avr-isa-vga gives an example of driving an ISA bus from an Atmega. They mux the 8 data pins with the bottom 8 address pins on the microcontroller. The code looks like:
(Licensed under the GPL):
A memory write looks like:
Seems nice and simple. It's asynchronous, like a parallel port - you write to the bus, strobe the correct line, then poll for an acknowledgement from the device.