Page 1 of 1

Apple II Like Memory Mapping

Posted: Wed Feb 03, 2021 10:09 pm
by cbmeeks
So I'm working on a design that I would like to somewhat mimic the memory mapping of an Apple II.
The requirement is to only use TTL parts and no PLD's.

Basically:

Code: Select all

RAM: 0000 - BFFF
IO:    C000 - CFFF
ROM: D000 - FFFF
That's not technically accurate because I need the interrupt vectors starting at $FFFA.
So I've been scratching my brain on coming up with logic that would allow the very top to be RAM as well. Then it occurred to me that's not really smart.

Instead, why not just "hard code" a RAM address, say $B000 (or any RAM) into the actual ROM. For example, the RESET Vector would have $00B0 at $FFFC in ROM. Then I could change the actual reset location at position $B000. Basically a jump table. Do it for the other locations too. I think the one drawback would be for high-speed IRQ's. The IRQ would always involve a JMP to address $B002 (or whatever).

So my question is, is this a good practice for such a system? I realize this is trivial to some of you but I really wanted something different than the "standard" 32KiB RAM based on A15. :-)

Opinions and advice welcomed!

Thanks.

Re: Apple II Like Memory Mapping

Posted: Wed Feb 03, 2021 10:54 pm
by Martin A
A quick look at the BBC micro MOS1.2 vectors

NMI is vectored directly to RAM (at 0D00)
RESET is dealt with in the ROM
IRQ/BRK has both rom code and vectors in RAM

Which sort of makes sense, the NMI is the priority interrupt that has the minimum latency. Reset gets the system to a guaranteed state. The IRQ gets to the the heavy lifting, so speed isn't quite as vital and it saves the need for any trickery overlaying the vectors with ram.

Re: Apple II Like Memory Mapping

Posted: Wed Feb 03, 2021 11:49 pm
by BigDumbDinosaur
cbmeeks wrote:
So I'm working on a design that I would like to somewhat mimic the memory mapping of an Apple II.
The requirement is to only use TTL parts and no PLD's.

Basically:

Code: Select all

RAM: 0000 - BFFF
IO:  C000 - CFFF
ROM: D000 - FFFF
That is exactly the memory map for my POC V1.2 design, which is achieved solely with 74AC logic. See below for the 65C02 equivalent.
Glue Logic
Glue Logic
Quote:
That's not technically accurate because I need the interrupt vectors starting at $FFFA. So I've been scratching my brain on coming up with logic that would allow the very top to be RAM as well. Then it occurred to me that's not really smart.
Put the front ends of the interrupt handlers in ROM and arrange for them to jump through RAM vectors. Trying to expose a little bit of RAM as you want would result in a very convoluted and slow glue logic, and for what gain?

Quote:
Instead, why not just "hard code" a RAM address, say $B000 (or any RAM) into the actual ROM. For example, the RESET Vector would have $00B0 at $FFFC in ROM.

Well, you'd have a bit of a problem at power-on, because the reset routine needs to be instantly available at that time. There would be no code in RAM at power-on. While you could download an image of the reset handler from ROM into RAM and then jump to it, I don't know what you would expect to gain.

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 12:41 am
by jds
It depends how many gate delays are acceptable, assuming this is not a high speed system then we could implement it relatively simply.

First let's look at how this is split up. The RAM is 48k. This could be implemented with 3 16k SRAMs, or 1 64k SRAM with 16k wasted (or possibly banked with extra logic). It would save a lot of space to go with the 64k RAM. If we went with the 3 chips then we'd need further address decoding. At the other extreme it would be possible to decode all 4k blocks and use 4k RAM's, but that's a lot of chips so wouldn't do that. I think the Apple II probably decoded down to 4k blocks, at that time they didn't have the option of one bigger chip.

The IO range is 4k, a small area that increases the address bits needed for decoding. And ROM is 12k, which doesn't fit a single chip nicely. Again, today it's probably easier to use a 16k ROM and waste 4k.

And since we know we know the smallest decode range is on 4k boundaries, we can decode this with A15-A12.

It's always nice to use any extra chip selects if they are available, but this mainly is useful on IO chips, so I'll ignore that for now.

The decode equations are:

/RAM_CS = PHI0 . !(A15 . A14). ; When PHI2 is high and not when both A15 and A14 are high
/IO_CS = A15 . A14 . !A13 . !A12 ; A15 and A14 are high and A13 and A12 are low
/ROM_CS = A15 . A14 . !(!A13 . !A12) ; A15-A14 high and A13, A12 are not both 0

So now it becomes a process of logic minimisation (unless we just cheat use these equations in a PAL).

The equations converted into gates as they are look like this:

RAM_CS = NAND(PHI1, NAND(A15, A14))
IO_CS = NAND(A15, A14, NOT(A13), NOT(A12))
ROM_CS = NAND(A15, A14, NAND(NOT(A13), NOT(A12)))

We'd need 2 quad input NAND gates, 2 2 input NAND gate, and two inverters. So let's look at 74 series chips and any simplifications or substitutions we can make to save a chip.

74LS18 2 x 4 input AND, fully used.
74LS04 6 inverters, using 2, so we might be able to find a way to save another chip by using more of these.
74LS00 4 x 2 input NAND gate, we use 2, so two spares.

I miscounted here on the first try and thought we could reuse 2 NANDs to replace the inverters, but then we're a NAND short, so looks like we still need the inverter chip. We only need 2 (or even 1) inverter, but the others may be usable elsewhere in the circuit.

People may come up with tricks to minimise this further, and I'd definitely check it before use, I didn't have a lot of time to work on this.

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 12:58 am
by floobydust
I guess I'll add my $0.02 as well... so in addition to the current responses, here's some thoughts:

- Exactly what is the plan for the system? Emulate an Apple II, hence mimic the memory map?
- Clock speed, planned I/O devices?
- A limit on ROM or able to add (ROM) to the open address ranges for specific uses?
- Adapter slots or everything built onto a single board?

As Martin noted, the IRQ vector is also shared with the BRK instruction. If you plan on using the BRK instruction for entering a Monitor or something else, you'll need to manage it separately from the IRQ routine.

I'd also ask if there's a need to mimic the Apple II memory map, or is it just a nice idea... point being, how much I/O space do you think you'll need? Unlike the old days (or early days) memory is pretty cheap, so why not load it up with your desired mix of RAM/ROM and keep the I/O space to what you need with some future (limited) expansion in mind.

If you're looking to maximize RAM space, then park your I/O devices up high in the address range and have a lesser amount of ROM at the top. The other option is to use a microcontroller to front end the CPU (keep it in RESET state), load RAM with the appropriate code and then let the CPU boot from it.

Again... just throwing out some thoughts...

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 9:02 am
by drogon
cbmeeks wrote:
So I'm working on a design that I would like to somewhat mimic the memory mapping of an Apple II.
The requirement is to only use TTL parts and no PLD's.

Basically:

Code: Select all

RAM: 0000 - BFFF
IO:    C000 - CFFF
ROM: D000 - FFFF
That's not technically accurate because I need the interrupt vectors starting at $FFFA.
So I've been scratching my brain on coming up with logic that would allow the very top to be RAM as well. Then it occurred to me that's not really smart.
My Ruby is all RAM. The 'trick' is getting the bootstrap code which includes the hardware vectors into the top 256 bytes of RAM before the 65xx comes out of reset. I do this by brute-force of having an ATmega take over the memory system.

There is also someone here (can't find the link now, sorry) who is SPI booting a 6502 IIRC.
Quote:
Instead, why not just "hard code" a RAM address, say $B000 (or any RAM) into the actual ROM. For example, the RESET Vector would have $00B0 at $FFFC in ROM. Then I could change the actual reset location at position $B000. Basically a jump table. Do it for the other locations too. I think the one drawback would be for high-speed IRQ's. The IRQ would always involve a JMP to address $B002 (or whatever).

So my question is, is this a good practice for such a system? I realize this is trivial to some of you but I really wanted something different than the "standard" 32KiB RAM based on A15. :-)

Opinions and advice welcomed!
It's your system, so ...

In Ruby I have the vectors pointing to the OS 'ROM' (Lives in $C000 through $FFFF, IO is at $FExx), the IRQ code first checks for the on-board IRQ sources (BRK and 2 from the VIA), then jumps () to handle off-board sources - the OS has to populate the indirect JMP location before IRQs are enabled - then you live in the hope that memory isn't corrupted - more important for me as the OS lives totally in RAM anyway, however so-far so good.

Don't forget BRK in a 6502, or an '816 running in emulation mode. the BBC Micro also has an indirection for BRK, so languages (e.g. BASIC) can install their own BRK handler - typically in the Beeb, reporting errors is done by BRK, byte-code, ASCII string, 0.

-Gordon

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 1:43 pm
by cbmeeks
Thanks everyone for your responses.
BigDumbDinosaur wrote:
Well, you'd have a bit of a problem at power-on, because the reset routine needs to be instantly available at that time. There would be no code in RAM at power-on. While you could download an image of the reset handler from ROM into RAM and then jump to it, I don't know what you would expect to gain.
I didn't think about what happens at power-on. I'll have to think that through some more. I can put a custom ROM into my SBC and run some tests.
jds wrote:
It depends how many gate delays are acceptable, assuming this is not a high speed system then we could implement it relatively simply.
Goal is around 2 - 4MHz.
jds wrote:
First let's look at how this is split up. The RAM is 48k. This could be implemented with 3 16k SRAMs, or 1 64k SRAM with 16k wasted
I would probably go with one chip to save board space and just waste the extra RAM. Assuming I don't do a 180 and change my mind on using a PLD or not (still on the fence).
jds wrote:
The IO range is 4k, a small area that increases the address bits needed for decoding. And ROM is 12k, which doesn't fit a single chip nicely. Again, today it's probably easier to use a 16k ROM and waste 4k.........
Thanks for the details! I will have to study that some more. Well, the 12KiB of ROM was mainly because the Apple II used smaller ROM's at the time and by the time the Apple II Plus came out, it was a 48KiB machine with 12KiB of ROM and 4KiB of I/O. Giving it a clean 64KiB space. Well, that's not counting the language cards that banked extra RAM and was eventually included in the Apple IIe.
floobydust wrote:
I guess I'll add my $0.02 as well... so in addition to the current responses, here's some thoughts:

- Exactly what is the plan for the system? Emulate an Apple II, hence mimic the memory map?
- Clock speed, planned I/O devices?
I am designing my third SBC that I hope to improve on my last one. I'm taking "inspiration" from the Apple II, VIC-20 and TI-99/4a. My computer would be a competitor to those systems back in the day (minus a little cheating with SRAM and larger ROM/RAM).
I'm not looking to emulate anything. Well, not really. In my last SBC, I had a decoding logic that mapped the four slots in a similar way the Apple II did. I hope to do the same in this one.

But the real reason is I just like that memory map. And I figured it's a little more difficult than my last SBC and having a mapping system like that would give me some challenge.

Clock speed will hopefully be in the 2 - 4 MHz. But I will be interfacing to some vintage chips so if that becomes a problem, I won't have any issue with running it at 1 MHz.
floobydust wrote:
- A limit on ROM or able to add (ROM) to the open address ranges for specific uses?
- Adapter slots or everything built onto a single board?
Yes, I hope to have some adapter slots. My last SBC had four. I hope to do between 2-8 on this one. Depending on how large the board gets. And I loved the way the Apple II had the slots mapped. It wasn't dynamic, but accessing code on ROM (via a slot) and even being able to boot off a slot was pretty slick for 1977. BTW, I live in the 70's and 80's....lol
floobydust wrote:
I'd also ask if there's a need to mimic the Apple II memory map, or is it just a nice idea... point being, how much I/O space do you think you'll need?
Well, I'm not going to need a ton. I plan on putting some VIA's and ACIA on-board with a few slots. So probably 8 or less but haven't sorted the details yet.

As far as the Apple II memory map, it's just a nice idea for me. I just like it. But I won't fight it for months if that's what it comes to. My goal for this computer isn't emulating anything. It's having fun so if it stops being fun, I will move on and change things. :-)
drogon wrote:
My Ruby is all RAM. The 'trick' is getting the bootstrap code which includes the hardware vectors into the top 256 bytes of RAM before the 65xx comes out of reset. I do this by brute-force of having an ATmega take over the memory system.
I thought about that as well. Like I said, I'm on the fence about PLD's or not (a single ATF1504 would make things so much easier).
In a way, I guess the closest computer I can think of that did something similar was the C64 (and maybe C16/Plus4). There you could pretty much disable the entire ROM and get nearly 100% of all RAM. Obviously, they needed custom chips for that.

Well, you guys have given me a lot to think about. I may beg/borrow/steal some ideas from here if you don't mind.

I will keep you all posted!

Thanks!

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 2:59 pm
by plasmo
cbmeeks wrote:
I thought about that as well. Like I said, I'm on the fence about PLD's or not (a single ATF1504 would make things so much easier).
Thanks!
My observation as a 2-month-old newbie on this forum is ATF1504 is under utilized. It is relegated to glorified address decoder when it is capable of so much more. Generic processor+RAM+ROM+CPLD can have great deal of capabilities still untapped, IMHO.
Bill

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 7:02 pm
by Windfall
plasmo wrote:
My observation as a 2-month-old newbie on this forum is ATF1504 is under utilized. It is relegated to glorified address decoder when it is capable of so much more. Generic processor+RAM+ROM+CPLD can have great deal of capabilities still untapped, IMHO.
Like this perhaps (http://www.zeridajh.org/hardware/reco6502/snapshots.htm) ? (Unless I'm not aware of some of your game rules).

I've personally never used an EPM7064 (basically the same, apparently, as an ATF1504) as just a 'glorified address decoder'. Just doing address decoding would waste a lot of cells, even in an EPM7032 ...

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 7:39 pm
by floobydust
plasmo wrote:
My observation as a 2-month-old newbie on this forum is ATF1504 is under utilized. It is relegated to glorified address decoder when it is capable of so much more. Generic processor+RAM+ROM+CPLD can have great deal of capabilities still untapped, IMHO.
Bill
I can't speak for others on this one, but I'm relatively new to using a (C)PLD, having implemented my first 3+ years ago, an ATF22V10 followed by an ATF16V8 last year. I'd certainly agree that the ATF150x CPLDs are more capable, but for myself, I'm looking to use them as a single "glue logic" solution. So, address decoding, memory and I/O read and write signals, control lines for latches, etc. and likely some wait-state generation where needed for slower I/O devices. My experience with them is minimal, so I'm learning as I go along with them.

For my next SBC project, it will be based on my current SBC (the second one in the past 7 years) to further integrate more into a pocket-sized PCB. Certain elements just make sense for me... i.e., a (D)UART for terminal access. The next SBC will use a NXP 28L92, which also gives me a timer/counter (jiffy clock) and some GPIO pins. A larger RAM (128KB), 32KB EEPROM along with a hardware RTC and IDE/CF storage. This is where I'll move over to mostly surface mounted devices as well. I'm looking at the ATF1502 for the glue logic... but I need to do more work on that one first.

Beyond that, sorry for hijacking the thread a bit... back to our normal station and programming...

Re: Apple II Like Memory Mapping

Posted: Thu Feb 04, 2021 8:51 pm
by jds
Another advantage of a CPLD is that you can implement bank switching without too much effort.

I've used the ATF1504/8 a little bit, and have a board waiting now for parts to arrive that makes good use of one. The ATF150x series is still in production if that is important to you, but the EPM7xxx series has some advantages for me. They are pin compatible but slightly different internally. I program them in verilog, which is more difficult for the ATF parts, what they suggest now is that you use Quartus II and select the matching EPM part, then run a program called POF2JED and then program the chip. POF2JED is a windows executable, and so is the Atmel programmer. That's a problem for me as I don't have windows, so the whole programming process is quite complex. Alternatively you can use Quartus II to do everything for the EPM parts.

And the Atmel programmer is quite expensive (but I do have one), whereas the EPM parts can be programmed with readily available and cheap programmers.

So I'm going to try out an EPM7064 hopefully very soon, I'll let you know how it goes. My board will take either chip, so I could swap back if needed, but I don't see any reason why I would need to.

Re: Apple II Like Memory Mapping

Posted: Tue Feb 16, 2021 3:29 pm
by Sheep64
plasmo on Thu 4 Feb 2021 wrote:
ATF1504 is under utilized. It is relegated to glorified address decoder when it is capable of so much more.
I strongly agree. When it is not used in a stateless form, it is typically used as an address latch or shift register. I'd be very interested to see address decode with one or more privilege bits and applications which require more state.

Re: Apple II Like Memory Mapping

Posted: Sun Mar 28, 2021 4:03 pm
by handyandy
I found this interesting:

http://redskulldc.50megs.com/Flashrom/Flashrom.html

While the circuit is used to access a flash rom drive on an Apple II(+, e, gs), it could be also used to implement softswitches to modify a memory map, read/write access...

Cheers,
Andy

Re: Apple II Like Memory Mapping

Posted: Sun May 09, 2021 12:52 pm
by Sheep64
I've been thinking about your memory map. It can be implemented with one 74HC138, one 74HC139, one AND gate and BigDumbDinosaur's preferred technique for read and write strobes. The second half of the 74HC139 may be used to divide the I/O segment into four pieces. Alternatively, it may be allocated to dual core bank switching.