build log 5 - unorthodoxy exemplified

A project log for hexahedron

An open-source minimalist 68030 based VMEbus computer

Jason WesterveltJason Westervelt 12/14/2021 at 05:581 Comment

currently programming the PLDs for the system. while doing so, i started thinking about how i wanted to handle the memory-mapped IO, and how to remap peripherals.  sure, i COULD do it old style and use jumpers to set a comparison address on a 74F521, but that seems entirely too pedestrian for this project.  i like the idea of setting things in BIOS, interactively...

...the problem is, HOW?

seems like there are plenty of motherboards that I have owned, even back in the 80386 era, that were jumperless and permitted changing the base IO address of serial and parallel ports.  i never really looked into how this was accomplished.  this isn't really something that is easily searched for either, and no magic combination of search terms led me down a path to illumination.

so, i decided to get creative...

hexahedron will boot up with ROM at 0x00000000, but this can cause issues with linux, issues which have workarounds, but issues where remapping the base IO of ROM will be useful.  the ROM that i have on hand is a 4megabit (512KB) HN27C4096CC-12, an aesthetically pleasing piece of silicon for sure.  the idea is to have a 74F521 attached to 8 lines of the address bus for each peripheral (RAM, ROM, serial0, serial1, parallel, etc).  instead of front loading these with jumpers to set the identity address, i will be using 74LS164 shift registers... shift registers and a microcontroller.

the microcontroller i have on hand is an ATMEGA328P.  it will have it's own 74F521 and 74LS164 as well.  it will have one line running out to gate each of the 74F521 outputs, except for ROM, which will be on its own dedicated pin which will be asserted (LOW) at power-on.  at power-on, each of the 74LS164s should have their outputs = 0x0000,  but only ROM will be enabled so the CPU will start reading from ROM as it loads BIOS.  meanwhile, the microcontroller will run through its own internal program, reading the base IO address stored in EEPROM for itself and each peripheral.  by default, the MCU will have 0x80000 as its base address, residing just above the ROM. it will then serially clock in data to its own shift register so it will match on 0x80000, and then it will proceed to do the same for the other peripherals.  once they are all set, the MCU enables output on the non-ROM ID comparators.

the CPU will then contact the MCU at 0x80000 and request the peripheral base IO addresses stored in its EEPROM to  update its own state.  at this point, the user is free to remap the base IO address for anything by sending commands to the MCU, eventually disabling the ROM and remapping RAM to 0x00000000 should the need arise.

at this point, some people are either facepalming over my overcomplication of matters, or amazed by this implementation.  maybe i'm doing something that is actually sane.  i don't know, but i have to try it at this point.   feel free to chime in if you have insight as to how jumperless motherboards actually work on commercial gear.   


Jason Westervelt wrote 12/25/2021 at 19:18 point

it turns out that i cannot use this method with just a microcontroller, some shift registers, and 8-bit identity comparators.

the idea was to use an 8-bit identity comparator for board select, ensuring that the upper 8 address lines were low, which would put the address in the first 8MB of address space. i would use that to enable the other identity comparators that were handling ROM/RAM/peripheral decoding, and each of those comparators would be set from a microcontroller feeding an 8-bit shift register that would set one of the two identity values.  the other identity is where the problem comes in.  normally, this would be fed from the address bus, however these will match on exact values, not ranges.  so while this method would work just fine for a peripheral with a single IO address, it would not work for mapping ROM, RAM, video, or anything requiring a range like a parallel port.  i would need to find a way to pull the insignificant bits high or low so that they could match the other identity set by the shift register...

this is particularly frustrating because i have no idea how "modern" motherboards handle the address decoding.  it isn't something that is easily searched for online either... i'm sitting here with an old 80486 motherboard that has BIOS-configurable IO ranges, and i'll be damned if i can figure out how it is done.  considering the speed at which the address has to be decoded, i'm at a bit of a loss.

the only solution i see at this point is to throw one of my 10ns SRAM modules at the problem... and just fill that with the memory map, and have its data lines feeding the various chip enables.  

  Are you sure? yes | no