6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 3:17 pm

All times are UTC




Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Tue Nov 19, 2024 9:45 pm 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
(Although full-fat BBC Basic is 16k, there are certainly ways of trimming off some bytes, for example to make room for a mini-MOS and still fitting in 16k. See the topic Heresy! Hacking chunks out of 6502 Basic ROMs over on stardot.)

Once you've got solid state storage, you can load an application such as Basic into RAM at boot time for no real penalty.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 20, 2024 12:18 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
DRG wrote:
My (ultimate) ambition would to be to run BBC Basic on my 65C02 SBC...

That would be a worthwhile goal—as 8-bit interpreters go, it was significantly better than the Micro-Soft equivalent.

Quote:
Ah, yes. WinCUPL, 22V10s and positive/negative logic - nothing there to bamboozle an electronics tyro, no? So, I already was aware of the concept of active low chip select logic and that was my intention in writing my GAL code i.e. for the pin to output a logic low for the device for the appropriate memory address. However, I wasn't aware that the way one writes the code can make a difference to the code - I assumed anything equivalent would be assembled into identical code in the GAL for example...
Code:
Pin 1 = !WE
WE = CLK & !RW

and

Pin 1 = WE
!WE = CLK & !RW
...would be the same.

The two approaches seem the same. However, the second rendition when compiled into a JEDEC file, will be implemented with “double negative” logic on the right-hand side of the equation, effectively:

Code:
WE = !(CLK & !RW)

Declaring WE as active-low, as in your first equation, uses no extra logic—it merely “connects” an inverter in between the internal gates that implement the logic and the output pin.  In the realm of a GAL, that inverter costs nothing in terms of logic resources and has negligible effect on prop time.

Quote:
Taking on board some earlier comments, I will also remove my zero page VIA and settle for a more conventional memory map.

Good choice, in my opinion.  Rarely does mapping I/O hardware into page zero gain anything.  Device drivers tend to spend much more time manipulating data, pointers, indices, etc., than touching hardware.  It is the pointers and indices that should be in zero page.

Quote:
Finally, "increases PT usage" - at the risk of looking silly, what's PT?

Product Term.  In the realm of programmable logic, a product term is a resource, i.e., internal gate, that is able to implement a logic expression. The term comes from Boolean algebra, in which a product term is effectively a logic expression, e.g., A AND B, which would be written as A ∧ B in Boolean notation.

A limited number of PTs are available per pin in a GAL.  If you try to create too complex an equation for an output, or if the way the equation is written can’t be sufficiently minimized, the compiler will stop and report too many product terms, or something similar, when it tries to compile the equation.  Using inverted logic for address decoding that ultimately drives what is supposed to be an active-low output complicates the minimization process, possibly leading to a design that won’t compile.

See the attached CUPL manual, which among other things, mentions why inverted logic is not recommended.

Attachment:
File comment: CUPL Reference Manual
cupl_reference.pdf [814.53 KiB]
Downloaded 6 times

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


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 21, 2024 7:18 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
I think I have taken into account what advice has been posted in this thread and attempted to write my WinCUPL file so to not have any double-negative or inverted logic. I want all chip selects to be active-low. My cupl code is based on my understanding that the command RAM = Address:[000x..BFFx] will set the variable RAM to a logical 1 if the current address falls in the range 0000 - BFFF. I want the RAM CS to be zero if this is the case, so use the "!" prefix to negate to a 0.

48K RAM, 16K ROM.

It compiles with zero errors or warnings. Here it is for comment...

Code:
Device          p22v10;


/* Pin Map
       --------
CLK   |1     24| Vcc
RW    |2     23| WEB
A15   |3     22| OEB
A14   |4     21| RAM_CSB
A13   |5     20| ROM_CSB
A12   |6     19| IO_0_CSB
A11   |7     18| IO_1_CSB
A10   |8     17| IO_2_CSB
A9    |9     16| IO_3_CSB
A8    |10    15| A4
A7    |11    14| A5
Gnd   |12    13| A6
       --------
*/

/*
   =======================================
   Inputs:  All are signals from the 65C02
   =======================================
*/
Pin 1        =  CLK;
Pin 2        =  RW;
Pin [3..11]  =  [A15..7];
Pin [13..15] =  [A6..4];


/*
   =================================================
   Outputs:  define outputs - all are positive logic
   =================================================
*/
Pin 23 = WEB;        /* to RAM and ROM chips */
Pin 22 = OEB;        /* to RAM and ROM chips */
Pin 21 = RAM_CSB;    /* to RAM /CS pin */
Pin 20 = ROM_CSB;    /* to ROM /CS pin */
Pin 19 = IO_0_CSB;   /* to IO_0 CS pin */
Pin 18 = IO_1_CSB;   /* to IO_1 CS pin */
Pin 17 = IO_2_CSB;   /* to IO_2 CS pin */
Pin 16 = IO_3_CSB;   /* to IO_3 CS pin */


/*
   ===============
   Local variables
   ===============
 */

FIELD Address = [A15..4];

RAM      = Address:[000x..BFFx];
ROM0     = Address:[C00x..FDFx];
IO_0     = Address:[FE0x..FE0x];
IO_1     = Address:[FE1x..FE1x];
IO_2     = Address:[FE2x..FE2x];
IO_3     = Address:[FE3x..FE3x];
ROM1     = Address:[FF0x..FFFx];

/*
   ===============
   Logic equations
   ===============
 */
WEB      = !(CLK & !RW);
OEB      = !(CLK & RW);
RAM_CSB  = !RAM;
ROM_CSB  = !(ROM0 # ROM1);
IO_0_CSB = !IO_0;
IO_1_CSB = !IO_1;
IO_2_CSB = !IO_2;
IO_3_CSB = !IO_3;

Dave.


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 3:09 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
DRG wrote:
My cupl code is based on my understanding that the command RAM = Address:[000x..BFFx] will set the variable RAM to a logical 1 if the current address falls in the range 0000 - BFFF.

Basically, that is correct, but in logic design, think in terms of “true” or “false”, not “1” or “0”.

Quote:
I want the RAM CS to be zero if this is the case, so use the "!" prefix to negate to a 0.

No, sir.  When you define a pin that is active-low, you negate its definition, not the equation that drives it.  By negating the pin definition, the effect will be pin goes low when expression is true.  That uses fewer PTs than does inverting the equation.

Code:
Pin 21 = RAM_CSB;

RAM      = Address:[000x..BFFx];

RAM_CSB  = !RAM;

The above is inefficient and in addition to wasting PTs by inverting the RAM expression, wastes PTs with unnecessary address decoding granularity.  In the address range assigned to RAM, only bits 15-12 are relevant, since the highest possible RAM address will be $BFFF and the lowest possible address will be $0000.  Knowing that, and also desiring to reduce clutter in the CUPL source file, I’d do it thusly:

Code:
Pin 21 = !RAM_CSB; /* define this pin as active-low output */

RAM_CSB = Address:[0xxx..Bxxx]; /* select RAM if address is below $C000 */

In the above, I define the RAM_CSB output as active-low and use the address field evaluation to directly control the RAM chip select—no intermediate variable needed.  The resulting equation is positive logic and the fact that RAM_CSB is defined as active-low means it will be high when Address:[0xxx..Bxxx] evaluates false.  Conversely, RAM_CSB will be low when Address:[0xxx..Bxxx] evaluates true.

Intermediate variables only become useful when the same expression is used in multiple equations.  The Address:[000x..BFFx] evaluation is only used once in your design, so there is no value in assigning it to an intermediate variable.

Quote:
It compiles with zero errors or warnings.

I loaded your code into WinCUPL and tried to compile it.  Compilation failed with an excessive product terms diagnostic for the ROM chip select output equation.  Here’s the verbatim diagnostic:

    The number of product terms needed to implement the logic expression for the given variable exceeds the capacity of the output pin for which it was declared.

Have you left something out?

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


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 9:24 am 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
Thanks so much for that input, BDD - that's taught me quite a bit.

I have reworked it as below and, again, it compiles without errors or warnings. This time I have also attached the PLD file so it's easier to verify. Are there compiler specific setting that need to be made in WinCUPL? - I have not changed the default ones that it was installed with.
Code:
Name            DRG65C02 Address Decoder;
Partno          DRG65C02;
Revision        02;
Date            22/11/2024;
Designer        DRG;
Company         ;
Location        Edenfield, Lancs. UK;
Assembly        None;
Device          p22v10;


/* Pin Map
       --------
CLK   |1     24| Vcc
RW    |2     23| WEB
A15   |3     22| OEB
A14   |4     21| RAM_CSB
A13   |5     20| ROM_CSB
A12   |6     19| IO_0_CSB
A11   |7     18| IO_1_CSB
A10   |8     17| IO_2_CSB
A9    |9     16| IO_3_CSB
A8    |10    15| A4
A7    |11    14| A5
Gnd   |12    13| A6
       --------
*/

/*
   =======================================
   Inputs:  All are signals from the 65C02
   =======================================
*/
Pin 1        =  CLK;
Pin 2        =  RW;
Pin [3..11]  =  [A15..7];
Pin [13..15] =  [A6..4];


/*
   =================================================
   Outputs:  define outputs - all are positive logic
   =================================================
*/
Pin 23 = !WEB;        /* to RAM and ROM chips */
Pin 22 = !OEB;        /* to RAM and ROM chips */
Pin 21 = !RAM_CSB;    /* to RAM /CS pin */
Pin 20 = !ROM_CSB;    /* to ROM /CS pin */
Pin 19 = !IO_0_CSB;   /* to IO_0 CS pin */
Pin 18 = !IO_1_CSB;   /* to IO_1 CS pin */
Pin 17 = !IO_2_CSB;   /* to IO_2 CS pin */
Pin 16 = !IO_3_CSB;   /* to IO_3 CS pin */


/*
   ===============
   Local variables
   ===============
 */

FIELD Address = [A15..4];

ROM0     = Address:[C0xx..FDxx];
ROM1     = Address:[FFxx..FFxx];

/*
   ===============
   Logic equations
   ===============
 */
WEB      = CLK & !RW;
OEB      = CLK & RW;
RAM_CSB  = Address:[0xxx..Bxxx];
ROM_CSB  = ROM0 # ROM1;
IO_0_CSB = Address:[FE0x..FE0x];
IO_1_CSB = Address:[FE1x..FE1x];
IO_2_CSB = Address:[FE2x..FE2x];
IO_3_CSB = Address:[FE3x..FE3x];


Attachments:
65C02_V2.PLD.txt [1.81 KiB]
Downloaded 2 times
Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 5:59 pm 
Offline

Joined: Sun Feb 22, 2004 9:01 pm
Posts: 109
BigEd wrote:
(Although full-fat BBC Basic is 16k, there are certainly ways of trimming off some bytes, for example to make room for a mini-MOS and still fitting in 16k. See the topic Heresy! Hacking chunks out of 6502 Basic ROMs over on stardot.)

Yes, and C0Basic is BBC BASIC assembled at &C000 with just enough cut out to leave just over 700 bytes free at the top of memory for a miniture MOS.

Here are examples with a mini-MOS for the BenEater and Grant Searle SBCs.

_________________
--
JGH - http://mdfs.net


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 7:16 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
Since inexpensive RAM and ROM are 64K or bigger, it makes sense to copy contents of ROM into RAM at reset and switch out ROM, so you wind up with a RAM only system. An inexpensive fast 45nS ROM is W27C512 and an inexpensive fast RAM is W24512.
Bill


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 7:35 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 41
plasmo wrote:
Since inexpensive RAM and ROM are 64K or bigger, it makes sense to copy contents of ROM into RAM at reset and switch out ROM, so you wind up with a RAM only system. An inexpensive fast 45nS ROM is W27C512 and an inexpensive fast RAM is W24512.
Bill

Is this what is referred to as a "ROMless" system? What is used to copy from ROM to RAM? Wouldn't it require 16 address lines, 8 data lines and some control lnes too to switch between RAM/ROM? Also, the 65C02 would have to be held in reset with the bus disconnected? I think I've seen RDY and BE used like this. I've never really seen what is used to do the copying though as approaching 30 I/O pins would be required.
I like the idea but think that is too advanced for me at the moment.


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 8:08 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
A true ROM-less design uses DMA to fill RAM or boot strap from serial/parallel/IDE. It can be fairly complicated, although PROG65 boots from FT245 and only has 2 TTL logic. Most of my 6502 designs have small ROM in either CPLD or 22V10 to load system RAM and then page out the small ROM. I do have couple designs that have traditional ROM. Here is one that’s a very simple 6502 design (no glue logic) that boots from ROM, copy to RAM and page out ROM.

https://www.retrobrewcomputers.org/doku ... 6502r1home
Bill

PS, here is a rather long discussion about it on 6502.org viewtopic.php?f=4&t=6455


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 8:23 pm 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
Why is it advantageous to copy ROM content to RAM and then page out ROM for an all-RAM system?

I can think of a couple of possible reasons
- the ROM is slower, or the slightly more complex decode is slower, and so once the all-RAM setup is in place the clock speed can be increased
- once the software has been copied from ROM to RAM it's possible to patch it, or for it to include some self-patching code.

Is there another reason?


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 8:47 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 986
Location: Potsdam, DE
In 8080/8085/Z80 systems (Yes! Heresy!) there is often a need to use the restart vectors at 0x00, 0x08, 0x10... 0x38 for different purposes in a running program - for example, MS basic and CP/M used the vectors for completely different things. But irrespective, the reset vector is always 0x00, so ideally you want ROM there - at least to start.

Once your initial reset is complete, if you've changed from ROM to RAM, you can change the vectors at will. So you might arrange things such that the reset switches in the ROM at 0x0000 to perform the reset; code then sequentially reads the ROM and writes back to the same address; hidden magic ensures that the RAM is written (obviously the ROM can't be!) and once that's complete a switch selects RAM for reading rather than ROM.

A similar system (and need) might be envisaged for maximum flexibility from a 6502 system, but in this case the reset and interrupt vectors are at the top of memory rather than the bottom.

Note that this doesn't require any change in data or address lines; only read/write, chip select, and output enable need some thought.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 9:31 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8509
Location: Midwestern USA
DRG wrote:
Thanks so much for that input, BDD - that's taught me quite a bit.

I have reworked it as below and, again, it compiles without errors or warnings. This time I have also attached the PLD file so it's easier to verify. Are there compiler specific setting that need to be made in WinCUPL? - I have not changed the default ones that it was installed with.

My bad! :oops:  When I copied and pasted your original code into WinCUPL, I forgot to set the correct optimization/minimization.  After doing so, the code compiled okay.

As for your revisions, please see attached.  I slightly revised your revisions, especially with regards to the ROM chip-select equation.  Also, assuming you are using the ATF22V10C, the device mnemonic for that part is g22v10, not p22v10.  The latter is for compiling to make the 22V10C look like its ancestral PAL device.  Since this is a new design, no reason to do so.  Refer to page 9, section 10, of the Atmel data sheet for more info.

Attachment:
File comment: Modified SPLD Source File
65c02_v2.pld.txt [2.3 KiB]
Downloaded 5 times

BTW, just an opinion, but I think your address decoding is excessively granular.  As you have it, a total of 16 I/O devices can fit into the I/O page ($FExx).  However, such an arrangement is physically impossible with a 22V10, due to insufficient output-capable pins.

I would reduce the granularity by two bits (get rid of A4 and A5), which will give you two more pins for other purposes. Such a change would allocate enough decoded address space in the I/O page for the four I/O devices you have, and give you the option of using one of the freed-up pins to enable a wait-state when ROM or slow I/O is selected.

plasmo wrote:
Since inexpensive RAM and ROM are 64K or bigger, it makes sense to copy contents of ROM into RAM at reset and switch out ROM, so you wind up with a RAM only system.

The other pin could be used to control ROM/RAM shadowing, similar to what Bill (plasmo) mentions.  A trivial change to the logic would make it possible for a write to the ROM address space to “bleed through” into RAM (although having I/O where you have it, smack dab in the middle of ROM address space, complicates things).  That way, your reset code could copy ROM into (shadow) RAM, and then switch off the ROM.  With that done, there would be no need for a wait-state to access the firmware.  Your non-wait-stated Ø2 clock “ceiling” would be determined by the speed of the RAM you use—SRAM down to 10ns is available.  Since the GAL is generating the /RD and /WD signals, it would also be trivial to arrange for shadow RAM write-protection once ROM has been switched out.

————————————————————————————————————
Edit: I originally posted the wrong copy of the PLD file.  The correct version is attached.

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


Last edited by BigDumbDinosaur on Sat Nov 23, 2024 8:57 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 22, 2024 9:33 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8545
Location: Southern California
BigEd wrote:
Why is it advantageous to copy ROM content to RAM and then page out ROM for an all-RAM system?

I can think of a couple of possible reasons
- the ROM is slower, or the slightly more complex decode is slower, and so once the all-RAM setup is in place the clock speed can be increased
- once the software has been copied from ROM to RAM it's possible to patch it, or for it to include some self-patching code.

Is there another reason?

A reason I find attractive is that you don't have to dedicate any more of the memory map to ROM material than you really need to, and the rest (minus I/O) can be used for RAM, without needing it to be any nice, round numbers, or needing to hardwire it into the address decoding.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 23, 2024 12:56 am 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
Many good reasons for RAM-only system have already being mentioned in last few posts. Other reasons for RAM-only are interrupt vectors can be changed, and updated ROM software can be patched/tested without reprogramming ROM.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: Paganini and 37 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: