6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Apr 29, 2024 5:23 pm

All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Apr 15, 2024 7:16 pm 
Offline

Joined: Tue Feb 07, 2023 12:27 pm
Posts: 19
I want to expand the RAM with additional 64kB blocks.
It's not too complicated, but I would like the additional 64kB blocks to contain only RAM. I/O access would be optional. $0000-$ffff. In such a system, access to the MMU would be difficult. To solve this problem, I came up with several methods. The condition is that this should not be difficult using simple GAL systems. The system would detect access to the location in two consecutive instruction cycles $FFFF and $0000, which would not be too complicated. Each time $ffff is read, 8 bits of DATA will be written, and if address $0000 is read in the next cycle, the BANK register will be updated with the stored data, otherwise the stored data would be ignored
Theoretically, I could use many different commands to change the bank.
For example
Code:
         $1fffe 80  ;illegal 2byte NOP
         $1fffe 05
         $50000 ....NEXT CODE

other
Code:
           $1fffc CLC
           $1fffd BCC
           $1fffe $0F
           $1ffff $05
           $5000d ....NEXT CODE


I wonder if such a system would work properly.


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 15, 2024 8:47 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8155
Location: Midwestern USA
I have an idea as well: use a 65C816.  :wink:  You can access as much RAM as you want (or can afford :D) without the gyrations you are describing.  As a bonus, the 816 gives you new and powerful instructions, as well as new and powerful addressing modes for the already-familiar 65C02 instructions.

Incidentally, opcode $80 is not “illegal” with the 65C02.  It is the BRA instruction.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 15, 2024 9:22 pm 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 293
Gregorio is clearly talking about the NMOS 6502, where opcode $80 is a two byte two cycle NOP. And very clearly not talking about the 65816. I'm guessing the target is in the retrocomputing world, where even the 65C02 introduces unacceptable incompatibilities.

In that context, it's an interesting problem. How do you extend an existing system without breaking any of the software that runs on it - and if the system is something like the C64, that software often exploits every documented and undocumented feature it can. This looks like the start of a good solution. Code that wraps from $ffff to $0000 is very rare. You could harden it further by requiring a read of $80 from $fffe before the read from $ffff (or a branch opcode two cycles before, to allow the second example). It introduces a very small incompatibility, but one that I doubt would ever come up in practice.

The main problem I see with it is how do you access data in one bank from code running in another? Those examples show how to jump to code in another bank, but not how to get that code in there in the first place.

Interrupts are an annoyance, but not a road-block. I've been thinking about another way to extend the NMOS 6502 without losing compatibility, and haven't come up with a solution better than "interrupt vectors and handlers have to be duplicated in every bank".


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 15, 2024 9:41 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8155
Location: Midwestern USA
John West wrote:
Gregorio is clearly talking about the NMOS 6502...

Obviously, it wasn’t clear to me.  More than a few posters on this site use “6502” when referring to the 65C02.

Quote:
And very clearly not talking about the 65816.

Agreed.  I mentioned it because of the desire to access large swatches of RAM...it’s much easier with the 816.

Quote:
I'm guessing the target is in the retrocomputing world...

It could be, but if so, more specificity should be used to clearly describe the target environment when making these sorts of posts.

BTW, anything involving a 6502/65C02/65C816 would be, by definition, “retrocomputing.”  :D  All of those MPUs are ancient designs—the newest of the bunch, the 816, is closing in on 40 years old.

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 5:55 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Nice idea Gregorio! I think there are many clever ways of squeezing some extra signalling out of the instruction stream - Jeff here has tried a few and explained them previously. No doubt he'll be along shortly.

I'm with John though - switching out the entire 64k space makes for simple hardware but adds some difficulty to the software. But probably there are ingenious ways forward. Switching in 32k or 16k chunks makes the software, in some ways, easier. But it does break up the address space. So, a series of tradeoffs, as ever!


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 7:15 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 664
Location: Potsdam, DE
It strikes me that you're likely going to have to deal with it in (64k) pages anyway: while your code can now execute across a page boundary, you can't jump between pages, and you can't access data in one page from another. Which is why the 8086 came up with the offset registers...

And your assembler/compiler would need some thought to consider code around those boundaries; in most cases you're not going to be executing code from the interrupt/reset vectors, I suspect.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 8:56 am 
Offline

Joined: Tue Feb 07, 2023 12:27 pm
Posts: 19
Thank you all for your replies.
I've already built a similar system where I switched 64kB RAM banks and had access to I/O and ROM in each bank. So basically it was the same system, repeated several times and everything worked as it should. There I had additional memory in the I/O area, where the MMU was also located. with the difference that I replaced the BANKS with a program contained in the additional memory in I/O. Thanks to this, I could run any program in any BANK. Moving from task to task only required saving the processor registers on its own STACK before exiting the task and the S address.
returning to the task looked like this:
Code:
          LDA #BANK
          STA MMU
          LDX $02
          TXS
          RTI
         

Of course, I intend to keep these configurations and what I am writing about is only an option for a larger project.
Generally, the system is to be based on AppleIIplus and is to work similarly to the solution in AppleIIe (c), and what I am writing about is only an additional option.
I am also considering the possibility that moving to another bank will involve access to I/O registers with access to the MMU. However, at this stage this is only one of the proposals to be considered.
This is not the only possibility of transferring data between banks that can be used in this system, but for now I would like to focus on it, I may have to make corrections or, for example, give up this option.


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 11:01 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Oh, that's great that you're building on something which worked.

I would be inclined to use the SYNC signal, which (other than when an interrupt is handled) allows detection of the opcode fetch. (Checking all 16 address bits for FFFF seems quite expensive.) With SYNC, you can detect ordinary opcodes, or undocumented opcodes.


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 11:42 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 664
Location: Potsdam, DE
Hmm... got me thinking... since you can always identify an instruction fetch from a generic memory read, I wonder if you could use that to read program information from one bank and data from a different? Not sure how you'd cope with e.g. the stack or immediate values, though.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 11:50 am 
Offline

Joined: Tue Feb 07, 2023 12:27 pm
Posts: 19
I was thinking about the SYNC signal, it would provide many possibilities, but in the Apple II it is only available on the processor, which would require a direct connection to the processor, and I would like to avoid such a situation.
I want the system to be easy to install. When it comes to detecting 0000 and FFFF, one XOR gate and 2 D, and I already have that in my free resources on board with GAL :D


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 16, 2024 2:46 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
Fair enough if comparing 16 bits of address is cheap and if sync is inconvenient.

I’m wondering if you could get away with a plain EA NOP at FFFF and destination bank at 0000. The NOP will perform a dummy read of the “operand” and in the third cycle the new bank could (just about) be in place for the next instruction fetch.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 17, 2024 10:23 am 
Offline

Joined: Tue Feb 07, 2023 12:27 pm
Posts: 19
Thank you BigEd, the SYNC idea, although I initially rejected it, now seems very good to me.
I want to use additional 2 byte NOPs for BANK and RAMconfig reg settings. single byte.
The idea is that changing BANK will not immediately switch the memory to the next BANK, The transition to the next RAM BANK will occur after the $1A codec.
After NOP $3A will work so that only the first write will be toaditional RAM.
Thanks to this, I will have do not have an MMU in I/O.
The transition to the next RAM BANK will occur after the $1A .

Code:
 
;Write to differentBANK
       $80 02
       $3A
       STA BANKxxxxx
       STA 00xxxx
       $3A
       STX BANKxxx1 
;change BANK
00xxxx      $80 BANK
00xxx2      $1A
BANKxxx3 ....


Last edited by gregorio on Wed Apr 17, 2024 7:10 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 17, 2024 3:01 pm 
Offline

Joined: Wed Jan 03, 2007 3:53 pm
Posts: 51
Location: Sunny So Cal
barnacle wrote:
Hmm... got me thinking... since you can always identify an instruction fetch from a generic memory read, I wonder if you could use that to read program information from one bank and data from a different? Not sure how you'd cope with e.g. the stack or immediate values, though.


The 6509 says hi. It has separate registers for the code segment and the data segment (for lack of better terms). The data segment was only involved with indirect indexed Y instructions, so stack was still fixed in its usual location.

_________________
Machine room: http://www.floodgap.com/etc/machines.html


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 17, 2024 4:01 pm 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
Note that this specific approach does require a NMOS 6502 ... $80 in a 65C02 is "BRA".

One approach is to use a legal read operation that there is no reason to do, and to encode the BANK operation as a side-effect of that operation. For example, "LDA $FFFF,X". Detect the LDA abs,X opcode, detect the read of two consecutive $FF bytes, the BANK operation is in the ADL address lines for the following read. Simply ignore the value that happens to be read in the operation as the side-effect does its job.

If you have a 512KB SRAM, you could have two tri-state latches one with /LATCH1_OE=a7 and another with /LATCH2_OE=NOT(A7), and you have Q0-Q2 of each latch tied to A8-A10, so each 32KB RAM window requires 3 bits to set, so you need 6 bits to set both.

Setting the bits from A0-A5 means that if the bank setup in X has been generated on the fly with BANKLO:=(a0-a2) and BANKHI:=(a3-a5), ,the operation is "INX : LDA $FFFF,X", to correct for the fact that ADL=(X-1) when performing the read.


Top
 Profile  
Reply with quote  
PostPosted: Sat Apr 20, 2024 3:16 pm 
Offline

Joined: Tue Feb 07, 2023 12:27 pm
Posts: 19
In my opinion, the "LDA $FFFF,X" solution has a disadvantage because it changes the FLAG 6502 register.
In turn, the 6509 processor has a configuration register $00 $01 every 64kB, which creates holes in my memory.
I have selected several codes that can be used on both the 6502 and 6502C systems
$82 $C2 $E2, these fit me best. Then 44, 54, d4, f4
and $DC, $FC
I found information https://llx.com/Neil/a2/opcodes.html#insc02 that the code $5c with data $bb,$aa works differently than other combinations,
"the behavior of 01011100 (5C) is strange: '5C bb aa' after fetching three bytes accesses FFbb and then spends four cycles accessing FFFF


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 12 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:  
cron