6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Jun 16, 2024 6:52 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Wed Feb 03, 2021 10:09 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
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:
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.

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 03, 2021 10:54 pm 
Offline

Joined: Sat Jan 02, 2016 10:22 am
Posts: 197
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.


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 03, 2021 11:49 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8214
Location: Midwestern USA
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:
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.

Attachment:
File comment: Glue Logic
mapping_65c02.gif
mapping_65c02.gif [ 42.15 KiB | Viewed 2007 times ]

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.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 12:41 am 
Offline

Joined: Thu Mar 10, 2016 4:33 am
Posts: 170
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.


Attachments:
Decode.png
Decode.png [ 165 KiB | Viewed 2004 times ]
Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 12:58 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1378
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...

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 9:02 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1435
Location: Scotland
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:
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

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 1:43 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
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!

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 2:59 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1080
Location: Albuquerque NM USA
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


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 7:02 pm 
Offline
User avatar

Joined: Sun Nov 27, 2011 12:03 pm
Posts: 229
Location: Amsterdam, Netherlands
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 ...


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 7:39 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1378
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...

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 04, 2021 8:51 pm 
Offline

Joined: Thu Mar 10, 2016 4:33 am
Posts: 170
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 16, 2021 3:29 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
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.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 28, 2021 4:03 pm 
Offline

Joined: Mon Sep 14, 2015 8:50 pm
Posts: 110
Location: Virginia USA
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


Top
 Profile  
Reply with quote  
PostPosted: Sun May 09, 2021 12:52 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
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.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 24 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: