How to design a proper memory map for an 8-bit microprocessor?  - Page 1
Forum section: electronics / general

author: ali6x944
author_rank: Frequent Contributor
timestamp: June 21, 2018, 01:52:31 pm
content: hi everyone,during the last month, I have been working on the NSC800 project and I had hit a brick wall, if I want something more out of the micro I need to step out of the blinking LEDs stage to adding memory and peripherals, however I have no experience in designing memory maps and addressing them properly. I have previously tried to adapt simple minimalistic computers made by Grant Searle for the Z80 but without any success...so How to design a proper memory map for an 8-bit microprocessor that would keep everything simple and neat?I also have a hand full of questions to ask you about:1) do I need to make ROM at the beginning of the memory space?2) does interrupts need to be addressed to the ROM memory space?3) which is better in organising memory, pages or arbitrary assigning of memory space?4) if I use a GDC like the NEC uPD7220AD or intel 82720, do I need to include the memory for the GDC as addressable memory for the NSC800 even though the processor can't address it directly -or at least this is what I think-?5)for peripherals in the minimalistic computers made by Grant Searle he uses the z80's /IORQ and /MREQ to choose the the things he whats to address and he treats them as two separate 64k banks - see:http://searle.hostei.com/grant/z80/SimpleZ80.html - is it possible to do the same with a dual function pin on the NSC800 or similarly in the intel 8085?6) if I have certain programmable I/O in my computer, say a UART chip or a PIA or keyboard interface chip or even the GDC it self, do I need a special address for the chip or can I use RAM? if I have to use a special address for the chip how to choose it properly?7)if an I/O chip has its own separate memory does I need to treat it as a totally independent system, thus designing its own memory map?8)which is the best option regarding addressing, using chips or glue logic?I also have a couple of ROM boot related questions:1) what comes first in ROM, front end setup or back end setup? I/O setup or OS setup?2)is it possible to create a C ROM?3)is it possible to create a mix language ROM?sorry for the monstrous amount of questions but again newbies need a good healthy dose of questions to grow and become something I guess?thanks a lot for all your effort and time

author: dave j
author_rank: Regular Contributor
timestamp: June 21, 2018, 04:52:42 pm
content: Quote from: ali6x944 on June 21, 2018, 01:52:31 pmMy advice would be to look into how the various 8 bit microcomputers from the 1980s did it - there's lots of documentation about. From that period I'm mainly familiar with the BBC Micro but other machines did similar things.QuoteThe processor needs to load code from its start address at reset so the short answer is yes. Youcouldimplement something to delay startup at power on and insert code into RAM but that would be making things needlessly complicated.QuoteIt's easiest that way. Youcouldmake the first instructions your processor executes initialise interrupt vectors held in RAM but that's making needlessly complicated. You can always have your ROM interrupt routines redirect through RAM if you want the flexibility - the BBC Micro does this a lot.QuoteWhich ever is easiest to implement in hardware (so pages).QuoteYou don't need to make the GDC's memory accessible to the processor. You could map it if you wanted to also access it from your processor for some reason but you'd need to provide a mechanism to stop the processor and GDC from accessing the memory at the same time. (This includes when the only thing the GDC is doing is refreshing the display.QuoteI'm not very familiar with those processors so I can't say for definite but probably.QuoteYes. You need to check a portion of the address bus to see when it matches the addresses used by your peripherals. Seethis schematic of the BBC Microand look for IC22 and IC24 - they do the address decoding for the peripherals.QuoteThat will probably be dictated by the I/O chip.QuoteThat question is a bit vague but look at how the 8bit micros from the 1980s did it.

author: David Hess
author_rank: Super Contributor
timestamp: June 21, 2018, 09:33:02 pm
content: I work from the high bits of the address bus toward the chip select signals. For instance a '138 3-to-8 decoder divides the entire address space into 8 parts. Then one of those address spaces can be divided into 8 sections again with another '138.

author: nctnico
author_rank: Super Contributor
timestamp: June 21, 2018, 09:48:39 pm
content: Quote from: David Hess on June 21, 2018, 09:33:02 pmThat is how I used to do that as well. A very long time ago... Be careful though that each sub-selection adds extra delay which eats into the access time of the memory device.

author: NivagSwerdna
author_rank: Super Contributor
timestamp: June 21, 2018, 10:43:37 pm
content: Too many questions... but....Quote from: ali6x944 on June 21, 2018, 01:52:31 pmYour chosen processor has a reset vector at 0000 so you will probably need a ROM to map into that space. (Note: You do not necessarily have to decode the whole address bus so it could actually end up mapped to a number of addresses but it is a requirement that you have a vector at 0000.Quote from: ali6x944 on June 21, 2018, 01:52:31 pmGiven that you need a reset vector at 0000 probably suggests these also need to be ROM but it might be worthwhile to have a ROM based routine then JMP to an address that is RAM based for flexibility.Quote from: ali6x944 on June 21, 2018, 01:52:31 pmYou will need chip select logic and the simplest way will be to divide into regions.

author: David Hess
author_rank: Super Contributor
timestamp: June 22, 2018, 12:25:51 am
content: Quote from: nctnico on June 21, 2018, 09:48:39 pmThese old systems were pretty slow leaving lots time for decoding and modern implementations have memory with 25 to 50 nanosecond access times and faster logic like AS, FAST, AC, or ACT making things much easier.Decoding with '138s can be done in parallel with some cleverness. There are other decoding options like using an EPROM but access times are slower. After the era of TTL logic, PLDs were very commonly used for this type of decoding and they are both fast and dense.74138 3-to-8 5 to 45 nanoseconds74139 2-to-4 5 to 45 nanosecondsPLDs 5 to 15 nanoseconds

author: obiwanjacobi
author_rank: Super Contributor
timestamp: June 22, 2018, 09:25:42 am
content: Sounds like you're taking on too much at the same time.Start with adding some memory and then some simple (uart) io and build from there. Ignore interrupts for now.When you make the steps smaller, you will be able to ask more specific questions and we'll be able to give you a more concrete answer.A quick glance at the data sheet brings back Z80 memories.The external pins are different using the address latch most notable.Try to wrap your head around interfacing a single static memory (any size) chip to this CPU, draw the schematic and post it.

author: westfw
author_rank: Super Contributor
timestamp: June 22, 2018, 11:43:29 am
content: QuoteAn "ideal" z80-like system has 64k of RAM in the memory address space and a separate IO space.QuoteExecution begins at 0 after reset, but various things (notably CP/M) want RAM at low memory locations. General purpose microcomputers (ie that ran CP/M) would use some sort of logic to "temporarily" change the address decoding logic at reset, so that ROM could be (normally) in high memory. (The very start of the ROM would "jp REALROMLOC" and then reset the address decode logic. Or copy itself to RAM, jump to the copied code, and reset the address decode logic.)QuoteZ80 has several interrupt modes. One allows an interrupt controller to place arbitrary instructions on the bus, a 2nd uses a vector table that can be anywhere in memory, and the 3rd jumps to 0x38.QuoteTraditionally, you decode the upper address bits to figure out which "bank" of memory to use. I guess that's "pages." It made lots of sense when a "bank" of memory was 1k to 32k. Now that RAM chips are likely to be 64k or more, you might end up doing something more like decoding "holes" in the address space to insert other types of memory.QuoteI don't know anything about GDCs.QuoteThe NSC800 is supposed to be Z80 compatible, but the 8085 (and 8080) only has 256 bytes in the IORQ address space."memory mapped IO" was a thing for a while (and required in CPUs like 6800, 6502, etc, that didn't have separate IO address spaces), but got traded off with the desire for more memory. 8080 code will still only address 256 IO locations.QuoteYou have to decode the IO address space finely enough to fit all your peripherals in the 256 bytes, and coarsely enough to fit all the addresses that the IO chip uses. 8080-era peripherals tend to use "few" addresses compared to modern peripherals.QuoteIt depends on the IO chip.QuoteIt depends on the size of the system. If you're NOT doing a general purpose computer, decoding the upper address bits into banks and putting one device in each bank was pretty popular. For a 32k RAM/32k ROM system, that usually means just putting A15 into the CS of one chip, and into CS/ of the other (most RAM/PROM chips have both positive and negative logic chip selects.) Using the 74138 on the upper three bits (as other have suggested) gives you 8 8k banks. GALs or other programmable logic let you do more complex decoding (put in the upper 8 bits, get out sepate chip selects for 56k of RAM, 4k of ROM, and 8 memory-mapped peripherals of 512bytes each, plus the logic to do the special reset-mapping (on a 22v10)QuoteDoesn't really matter. Review CP/M's "BIOS" concept, where the OS expects certain services from the ROM (or other user-provided SW)QuoteMaybe. Depends on your C compiler.

author: David Hess
author_rank: Super Contributor
timestamp: June 22, 2018, 11:52:47 pm
content: Quote from: westfw on June 22, 2018, 11:43:29 amI do not know how the CP/M systems I used handled this. The one I remember was S-100 and had 1k of ROM starting at 63k which was always present in address space but must have been doing something more.My favorite way is to decode reads and writes separately without fudging addresses so initially the read from the interrupt vector comes from ROM which then proceeds to copy as needed into RAM and then swaps reads from ROM to RAM.

author: daybyter
author_rank: Frequent Contributor
timestamp: June 23, 2018, 03:56:30 am
content: Many CPU's have 0 as a nop opcode. If ram is empty, they just execute nop's until there is a rom.

author: westfw
author_rank: Super Contributor
timestamp: June 23, 2018, 04:30:27 am
content: QuoteIt's not hard to have your ROM enable be (<ROMaddressDecode>|<resetting>) and the RAM enable be (<RAMaddressDecode>& !<resetting>) where "resetting" is a bit from a SR FlipFlop.One example I found is here:https://k1.spdns.de/Develop/Hardware/K1-Bus%20Z80%20CPU%20board%20with%20SRAM/Some boards may have used discreet logic to force certain instructions onto the bus at reset instead. For instance, you could simply force NOP (0) onto the bus until the address increments up to the point where there is ROM.QuoteOTOH, note that RAM is not "empty"; at power-on, you should assume that its contents are random values!

author: ali6x944
author_rank: Frequent Contributor
timestamp: June 29, 2018, 10:37:54 am
content: Quote from: dave j on June 21, 2018, 04:52:42 pmI have looked up the bbc micro's memory map and I was a bit confused, because the there isn't any ROM in the first memory location that can be used to facilitate a load to RAM so how does it do it?Quote from: daybyter on June 23, 2018, 03:56:30 amI guess the bbc micro does that because ram is in the bottom of the stackQuote from: David HessI looked at the datasheet of the NSC800 and I saw in page 9 the table of signals or states that are active for each condition and I was thinking of using that to get larger RAM and ROM and I/O space.the mechanics of the circuit will be simple, so I was thinking one of these small ROMs or simple combination logic to drive it SEE THE TABLE BELLOW.Quote from: NivagSwerdna on June 21, 2018, 10:43:37 pmIs PAL better to use in this case?Quote from: obiwanjacobi on June 22, 2018, 09:25:42 amwell RAM should be interfaced in memory read/write cycles while ROM in Opcode fetches according to the table..also it has a really similar address latch enable to the intel 8085 making the latch pretty straightforward to configure.also the NSC800 is identical to the z80 and many processors of the time that it has a 265 I/O device access limit which is kinda useful?I really don't understand how these I/O devices are accessed, from what I understand a value need to be loaded to them for the cpu to access them...Quote from: westfw on June 23, 2018, 04:30:27 amdidn't understand the CP/M part

author: stevelup
author_rank: Regular Contributor
timestamp: June 29, 2018, 03:20:11 pm
content: Quote from: ali6x944 on June 29, 2018, 10:37:54 amhttp://wiki.itmuseum.in.ua/images/8/8b/Acorn_BBCSMOct85_Sec1.pdfYou can lose yourself in this for days...!

author: SiliconWizard
author_rank: Super Contributor
timestamp: June 29, 2018, 04:07:23 pm
content: Quote from: ali6x944 on June 29, 2018, 10:37:54 amThis is because, contrary to some other CPUs from the same era, the 6502's reset routine is actually not located at the 0000 address.See:http://wilsonminesco.com/6502primer/MemMapReqs.html

author: obiwanjacobi
author_rank: Super Contributor
timestamp: July 02, 2018, 07:45:08 am
content: Forget CMP - that only complicates things for now.First you need to understand the basic interfacing of memory before you can solve that problem.Like the Z80 the NSC800 has a bunch of restart vectors at the lower (address) part of the memory.Look at the data sheet (search for 'restart address' or 'vector') and you'll see vectors for (software) RST0 to RST38. The external reset/interrupt lines also have their vector addresses. /NMI at address 0x66 is the highest.It is simplest if you put these into ROM. So ROM starts at address 0x0000 and goes up from there - depending on how big a chip you're using.Lets say 16k. You'll need (the lower) 14 address bits (A0-A13) to access all bytes in that rom.In order to make the ROM chip active at the correct time you need to check if address bits A14-A15 are zero. If they are not zero that means some other (higher) memory is being accessed and the ROM chips should not be active. This is where chips like the 74x138 come in, they make it easy to do that address decoding.Also, the rom should only become active when the /RD signal is active (low). Usually a ROM chip has several CE inputs you can use to directly connect these signals to. Note that the S0 and S1 signals are ignored here, you do not need them.A small complication of this processor is that it does not expose the address but as a whole. You have to latch in the lower 8 bits. So you need something like a 74x373 or 74x573 to hold onto that lower address part while the rest of the interfacing takes place.See 9.2 (datasheet) where the signals and timing involved in op-code fetch are displayed. The Address Latch Enable is the signal that tells you you have to grab the lower 8 address bits. (the /WAIT and /REFRESH signals can be ignored - assuming you have a fast enough ROM chip - check the timings).I do not know if you have any output logic (UART/Display?) but at this point you should be able to write a 'hello world' program, burn it into the ROM chip and run it - assuming you have an assembler or compiler that will make a binary image of the code for you, which you can then program the ROM chip with.Hope it helps.

author: TomS_
author_rank: Frequent Contributor
timestamp: July 06, 2018, 01:04:10 pm
content: Chipping in my $0.02 here ..Define "proper". "Proper" to me is what ever the application needs. That might be something as simple as using A15 and an inverter to switch two halves of the address space between ROM and RAM. Maybe it is using a 74x138 to break the address space in to n parts. There are Z80 computer designs out there that use all kinds of techniques to extend the available memory to hundreds of KB or even low MB using various tricks and paging.I think it really depends what you are trying to do as to what is appropriate for your memory map. There isnt any "one size fits all" because some sizes are different - IMO.In response to your question #1, Z80 starts executing from address 0, so in theory it is necessary to place your ROM at the beginning of the address space. But have a look at the PRO-LOG 7804 Z80 processor card manual - its from the golden age where full schematics and operating theory were provided. They have a neat little trick to have a 4KB ROM mapped to address Fxxx at reset, which can later be switched out to some other area of the address space.The PRO-LOG processor cards have served as a little inspiration for myself. In a Z80 design of my own, I used a 74x138 to divide the address space in to 8 chunks. I then provided means to disable ROM and RAM sockets so that I can re-map it in some other scheme elsewhere in the system if 8KB per ROM/RAM wasnt going to be sufficient. Give yourself options I think is another way to look at it.

author: ali6x944
author_rank: Frequent Contributor
timestamp: July 08, 2018, 06:22:33 am
content: Quote from: obiwanjacobi on July 02, 2018, 07:45:08 amI found this in page 31:Quoteso these restart vectors and the interrupt vectors must all be contained in the initial 8K or 16K ROM page(s)...Quote from: obiwanjacobi on July 02, 2018, 07:45:08 amI have a couple of questions regarding this quote:1)Is it possible to get full 64K ROM bank AND 64K RAM bank with the full I/O bank using a 74x138?2)in my previous post I said that I was thinking of using small ROMs to address the memory, Is it possible to use the method I described to get a full 64K ROM bank AND 64K RAM bank with the full I/O bank?Quote from: obiwanjacobi on July 02, 2018, 07:45:08 amI do have multiple I/O devices, I have a D71055C PIA and uPD7220AD GDC and MC68B50P UART and P8279 Keyboard interface...for the compiler I think I can use a z80 compilers,the NSC800 has the same instruction set...for the 'hello world' program should I put a BASIC ROM and then a basic program in ROM or should it be in RAM.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: July 08, 2018, 06:50:25 am
content: Quote from: ali6x944 on July 08, 2018, 06:22:33 amAll these vectors reside in the first 256 bytes of the address space (100h). How big you ROM is does not matter (assuming it is larger than 256 bytes). The word 'page' is usually used in this context to indicate a system-defined size of memory that usually can be activated or deactivated (sometimes even at different addresses) in a bank-switching scenario. You do not want to start there. First get the basic thing working and understand how/why it works. Then you have the knowledge to expand on the design.Quote from: ali6x944 on July 08, 2018, 06:22:33 amDon't go there yet unless you have the basic scenario running. The question indicates to me that you do not yet fully understand how this is working. I am not here to give that to you - you would learn very little. I am trying to make you understand the underlying principles. With those, you can come up with the solution yourself and understand better what other designs are doing.Making a more complex memory addressing design, not only complicates the hardware, but also the software.Quote from: ali6x944 on July 08, 2018, 06:22:33 amNo BASIC. I don't know what it takes to set that up correctly (IO). I was thinking about writing some assembler or C code.I had a similar test for my Z80 project:Code:defcIO_ADDRESS=$??org $0000start:ld hl, TextSourceloop:ld a, (hl)cp a, 0jr z, endout (IO_ADDRESS), ainc hljr loopend:haltTextSource:defm "Hello World!", 0

author: ali6x944
author_rank: Frequent Contributor
timestamp: July 13, 2018, 06:57:12 am
content: I saw this:http://www.8085projects.info/Examples-of-IO-Interfacing-Page4.htmlis this what can run the code.