I have read Garth Wilson's resources at least 3 times now. Each time I take more in as I am better prepared to absorb concepts that I was blind to on the previous readings. I note that Garth (as do others) hint that beginners get too hooked-up on wringing every byte out of the 64k on offer and many posts refer to some beginner decoding solutions being too granular in their approach. I've though more on this as to what approach I should take and here I open up my inexperienced thoughts. I suppose it will always be a trade off between what is possible versus what is practical.
Taking the extremes first, conceptually, I expect that the finest granularity would be individual byte mapping of the available 64k address space. In my mind, I think that you could do this with a 64k x 8 bit ROM as the address decoder. The 16 address lines would allow an individual 8 bit number to be placed on the 8 data pins of the ROM - those numbers being any of the 8 following values (based on active low logic) to select a device...
Code: Select all
11111110, 11111101, 11111011, 11110111, 11101111, 11011111, 10111111, 01111111I make no claims to the viability of this as I fully acknowledge my ignorance around the CPU/ROM timings but would suspect it possible at low operating frequencies simply given ROM access typically being around 70ns and a 1 MHz 6502 providing a 1000ns between cycles.
The other extreme (other than an all RAM or all ROM configuration) is the split which would just use A15 on the address line. This has a granularity of 32K. However, it would be slightly boring with no input/output functionality!
In general, my understanding is that granularity is defined by 2^bits where "bits" refers to the number of address lines in the decoding solution. For my design, I am looking at using A15-A10. 6 bits, so a granularity of 1024 bytes (2^6). To me, this means I can divide my memory map up in 1K "chunks". Using WinCupl, I produced the necessary logic for A15-A10 and allows a simpler version of the Daryl Rictor address decoding idea using a GAL as I have a couple of these already.
Code: Select all
RAM = ADDRESS:['h'0000..5FFF]; /* 24K RAM */
CS1 = ADDRESS:['h'6000..63FF]; /* IO */
CS2 = ADDRESS:['h'6400..67FF]; /* IO */
CS3 = ADDRESS:['h'6800..6BFF]; /* IO */
CS4 = ADDRESS:['h'6C00..6FFF]; /* IO */
ROM = ADDRESS:['h'8000..FFFF]; /* 32K ROM */Code: Select all
5C00 -> _RAM = 0 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
6000 -> _RAM = 1 _CS1 = 0 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
6400 -> _RAM = 1 _CS1 = 1 _CS2 = 0 _CS3 = 1 _CS4 = 1 _ROM = 1
6800 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 0 _CS4 = 1 _ROM = 1
6C00 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 0 _ROM = 1
7000 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
7400 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
7800 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
7C00 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 1
8000 -> _RAM = 1 _CS1 = 1 _CS2 = 1 _CS3 = 1 _CS4 = 1 _ROM = 0 Code: Select all
"(A13 and A14) or A15", # _RAM
"A15 or not(A14) or not (A13) or A12 or A11 or A10", # _CS1
"A15 or not(A14) or not (A13) or A12 or A11 or not(A10)", # _CS2
"A15 or not(A14) or not (A13) or A12 or not(A11) or A10", # _CS3
"A15 or not(A14) or not (A13) or A12 or not(A11) or not(A10)", # _CS4
"not(A15)" # _ROMI appreciate that, with the same kit, I could already implement Daryl's solution (using A15-A4) but I like working things out for myself and I hope this post could add to the knowledge base for those like me starting from scratch in the world of 6502 systems design.