6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 4:01 pm

All times are UTC




Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Re: RAM banking
PostPosted: Sat May 06, 2023 5:55 am 
Online

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 983
Location: Potsdam, DE
A thing to bear in mind with the 574 is that if you want to be able to set bits independently, you either need to maintain a RAM copy of the current state to OR/AND against, or you need to arrange a way to read the current output.

If you're just writing a byte then there's no issue, of course.

(There's a nice approach in some STM32s (though not all, and it can bit you if you're not careful) where there is a control register which sets matching bits; another which clears matching bits, and a third which both sets and clears. Handy.)

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sat May 06, 2023 2:19 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
cjs wrote:
how about adding a second PIA to the system? Since you've already got a VIA with timers and all that, the second one could be just a 6821/6520 PIA
I agree this will, as you say, give a readable port for memory mapping and also a spare port for other stuff. But rather than a 6520 I'd be inclined to put in a 6522, despite the extra capabilities that (presently) simply seem like overkill.

barnacle wrote:
A thing to bear in mind with the 574 is that if you want to be able to set bits independently, you either need to maintain a RAM copy of the current state to OR/AND against, or you need to arrange a way to read the current output.
On an existing Z80 SBC of mine, I managed to retrofit the readback capability! :mrgreen: But if I had the whole thing to do over again it would probably have been better to eschew the ad hoc creativity and simply include a read/writeable peripheral IC. :roll:

-- Jeff


Attachments:
pins 1 to 10.jpg
pins 1 to 10.jpg [ 35.69 KiB | Viewed 6664 times ]
pins 11 to 20.jpg
pins 11 to 20.jpg [ 34.28 KiB | Viewed 6664 times ]

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sat May 06, 2023 3:40 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Thanks for all the replies!

GARTHWILSON wrote:
The higher resistances do not increase the capacitance, but will make it take longer to charge up whatever capacitance there is on the line. The time constant is the amount of time it will take to charge it to 1-1/e of the final voltage excursion, about 63%; so if you really started from 0V, and the resistors pull up to 5V, that's 3.16V, more than high enough to be considered a valid '1' in TTL levels, but not high enough to be a solid '1' for a CMOS device that wants 70% of VDD. The time constant is the capacitance times the resistance. The concept is illustrated in Figure 2 of my 6502 interrupts primer. The link gets you to the right section of the page; then scroll down to the first diagram below the cartoon of the drug-store photo counter. Suppose you had 15pF on the line, which includes the input capacitance of the SRAM's address line, the capacitance of the 574's output when it's turned off, the traces, and maybe sockets; then suppose you have 10K pull-ups. 15pF x 10K = 150ns, probably too long. 3.3K, and if you can get down to even 10pF, gives you 33ns.[/color]


This explains a lot! Clearly, I had wrong understanding of how this works.

Martin A wrote:
If you need to drive the address lines, rather than using pull ups, you could add a 74xx157.


Today I learned! Every time I have a challenge, there's always a 74' chip that I've missed which solves the problem in an elegant fashion. :)

fachat wrote:
You mention to keep stack and zeropage for the system and bank in loadable programs above $1000.

Did you consider that your programs also need stack and zeropage? How are you going to share this area?

André


Hey - I read a lot of your articles @ 6502.org, so I'd like to say huge THANKS for your work! My entire banking & context switching thing was inspired by your work.

Actually, I was planning to use only software stack in my loadable programs (since almost all of them are written in C), so entire zeropage would be used by kernel only.
However, now that you've asked this, I think there's a big flaw in my design... Namely, sp/tmp*/ptr*/regbank stuff that's used by software stack resides in zeropage, so there will be conflicts between stacks of different programs...
I might need to re-think my entire design. :D

cjs wrote:
So, this is going to sound crazy, and maybe it's never been done before, but how about adding a second PIA to the system? Since you've already got a VIA with timers and all that, the second one could be just a 6821/6520 PIA, giving you a port for your memory mapping and another spare port for more stuff. And it now lets you read your current bank configuration.

(Actually, come to think of it, perhaps there was some company out there who regularly used two 652x PIA-style chips in their computers, but I can't think off-hand who it might be. :-))


GARTHWILSON wrote:
You can multiplex gobs of things on a single VIA, as I show about 40% of the way down the 6502 primer's I/O ICs page. But if all you need is a single, cheap, small, 8-bit output port, you could use something like a 74xx574 octal D-type edge-triggered flip-flop.


That's a good idea. I actually thought of this, however I had several issues with this:
- 6522 is still rather bulky
- It felt too simple and I was feeling like doing a bit of over-engineering. :)
- I'm trying to reserve my VIA for I/O only to make things simpler, since even with simple bit-banging & a shift register things get hairy real fast!
The downside is that my entire VIA can only handle 4004 LCD, uSD card (SPI mode), PS/2 keyboard, and an I2C bus, with only 2 free pins to spare. However, the coding is much easier, since all devices are directly connected to VIA without intermediate glue logic.

Anyway - I need to seriously re-think my design, since I'll probably need to bank a part of zeropage (26 bytes of CC65 variables) as well. :D

Another tricky thing is that during syscalls, I might need to switch to kernel's bank, since part of my kernel is also written in C...

/Andrew

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sat Jul 22, 2023 6:09 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
I decided to return to this idea and try implementing simple preemptive multitasking by having paged RAM.

It would be very easy to do with a VIA (and I'm still planning to use VIA's timer for context switching), but I want to have a separate 8-bit "register" to hold active bank, and also to be able to read its value. I'm going to use AS6C4008, so I'll get 16x 32KB banks.

Here's what I came up with as a "cheap" read-write register:

Attachment:
rw_banking.jpg
rw_banking.jpg [ 195.38 KiB | Viewed 6306 times ]


I couldn't think of a way to do this with less than 2 chips (+ logic gates), but I may be wrong. Maybe there is a better way. Finally, I'm not sure if the above contraption is going to work (although it seems to when simulated). Any thoughts are welcome.

EDIT: Okay, turns out all chip selects can be handled by a single NAND. :D So now I'm down to 3 chips total - '273, '244, and '00.

Attachment:
rw_banking2.jpg
rw_banking2.jpg [ 188.93 KiB | Viewed 6302 times ]


EDIT 2: André - as you mentioned about zeropage etc, I gave it some thought and my new plan is to bank entire visible RAM and make first bank a "kernel" page (zerobank, if you will), and banks 1 to 15 will be for individual "processes".
So each process (as well as the kernel itself) will have their own zeropage, stack, and RAM.
When a system call is performed (basically, any call of kernel's public routines), kernel will then decide whether it needs to bank to its own bank or stay in program bank.
E. g. for `open`, kernel will use program's bank to read file name, but then use its own bank to store file descriptor information.
For `exec`, it will use program's bank to read file name and then use a new bank to store cmdline, initialize stack, etc.
For `memcpy`, it can stay inside program's bank.
Basically, I'm treating bank register as something like CS register in x86.

Finally, system calls will use a lot of sei/cli instructions to ensure that context switching does not happen during critical kernel operation. And most importantly, all system calls that switch from program bank to kernel bank will reactivate program bank before return to ensure that we're returning to the right PC in stack.

Another benefit is that with banking I won't need to write relocatable code.

Of course, it's all just a theory for now. And my `rom.cfg` is probably going to look like a mess with lots of overlapping segments. :D I'll be happy to hear your thoughts, especially considering your impressive work on GeckOS!

EDIT 3: I think the biggest bottleneck in my case is that I'll need to waste some cycles or even an entire register to keep track of "previous" bank number in cases when a syscall needs to, say, copy some data between banks and not get lost in multiple stacks. I'm starting to think that it might be worth sharing a small segment of RAM (say, 256 bytes at the end of RAM region - $7F00-$7FFF), i. e. making this little page non-bankable. Or I could make it 1K or more and call it a "shared memory" so that it can be used for more powerful primitives like pipes or mutexes.
(My dream is to use all of this to build a POSIX-like shell for 6502 with job control, piping, and subshells.)

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Last edited by and3rson on Sat Jul 22, 2023 7:23 pm, edited 17 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sat Jul 22, 2023 6:18 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
It would be easier if you didn't allow reading the register. You can cater for that by having a separate RAM location that code had to update just before changing the hardware register (which is what Acorn did in the BBC Model B, though they provided a readable register in the later Master models) or you can have the hardware register overlay/shadow a RAM address, so that writing the RAM address also writes the hardware register.


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 7:51 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
Is /banken qualified with phi2? Otherwise it stays valid for too long, and the CPU has taken the data off the bus already
IIRC the 273 latches the data in at rising edge of CP. So you should make sure CP is only low when phi2 is high.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 10:58 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
Good you found the '273 because of its reset capability.

is your /BANKEN qualified with phi2? The '273 latches the value at the rising edge of its clock input, this needs to be at the same time as phi2 going high, otherwise the data might already be lost. You can easily add phi2 to the first stage NAND that you currently use as inverter, to achieve that.

What you need to do is to provide the ability, from kernel mode, to read (and sometimes write) data from (into) the user process. For example reading a file name to open a file is more efficient if the filesystem process can read it from some mapped user space. (you could transfer the name etc using a byte-based protocol with a kernel call per byte, but that is highly inefficient.) Also for reading and writing mass data (like loading a file) the kernel should be able to read from or write to user space.

In GeckOS I have a call buffer per process at a fixed address, that is either shared (in systems without MMU, and protected via a Semaphore), or where the data is in fact copied over into kernel space (system with MMU) with a specific routine (look for PCBUF resp. SYSBUF if I remember correctly). File data transfer is current byte-wise which I think is highly inefficient. I have designed a new interface with block transfers and flexible call buffers, but not yet managed to implemented it.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 12:29 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
gfoot wrote:
It would be easier if you didn't allow reading the register. You can cater for that by having a separate RAM location that code had to update just before changing the hardware register (which is what Acorn did in the BBC Model B, though they provided a readable register in the later Master models) or you can have the hardware register overlay/shadow a RAM address, so that writing the RAM address also writes the hardware register.


It would be easier, but not necessarily better. Esp. if you do multitasking sometimes it is just easier reading from a register and save the value when another task is started, and restore it from there when coming back. That is not necessarily the case with the banking register though.
For example, in the 8x96 Commodore PET, they had a banking register "under" the ROM at $fff0. It was only writable. So this works, but depending on the purpose of the register you may want to re-think that.

Here you have to check with your software design if you could spare some storage (a byte) for the current bank if you can just read the value from the register when going from user space to kernel.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 2:18 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
As long as the forum issue is not fixed (a couple of posts disappearing between page 1 and 2) you may want to use this link that shows the missing posts (thanks to @Ed for providing it) viewtopic.php?f=4&t=7591&start=11

Edit: fixed link

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 5:08 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
fachat wrote:
Good you found the '273 because of its reset capability.
[...]
Is /banken qualified with phi2? Otherwise it stays valid for too long, and the CPU has taken the data off the bus already
IIRC the 273 latches the data in at rising edge of CP. So you should make sure CP is only low when phi2 is high.


Yep, it is: I have used /RD & /WD signals (qualified with Ф2) as inputs in my latest design, since I already have them in my SBC. I also happened to have just enough spare '14 gates for this task:

Attachment:
rw_banking3.jpg
rw_banking3.jpg [ 101.46 KiB | Viewed 4882 times ]


gfoot wrote:
It would be easier if you didn't allow reading the register. You can cater for that by having a separate RAM location that code had to update just before changing the hardware register (which is what Acorn did in the BBC Model B, though they provided a readable register in the later Master models) or you can have the hardware register overlay/shadow a RAM address, so that writing the RAM address also writes the hardware register.


While I agree that it would eliminate the need in '244, I still prefer to use it for two reasons: it gives me satisfaction to do hardware solution for this and it also eliminates the need to track a copy of last written value in RAM.

fachat wrote:
What you need to do is to provide the ability, from kernel mode, to read (and sometimes write) data from (into) the user process. For example reading a file name to open a file is more efficient if the filesystem process can read it from some mapped user space. (you could transfer the name etc using a byte-based protocol with a kernel call per byte, but that is highly inefficient.) Also for reading and writing mass data (like loading a file) the kernel should be able to read from or write to user space.


Yeah, it seems like it would be nice to have an ability to map different regions of multiple banks at once, especially when there's a need to copy data between processes, or work with kernel & user-space data simultaneously.
Another option I can think of is to use "swap" memory for this purpose, e. g. during some syscall, a kernel would copy data from bank 1 into this area, then switch to bank 2 and copy the data there.
But I think most of this copying can be minimized if all program-related data (file descriptors, buffers, etc) is to be stored in program bank. In other words - make kernel use program banks as much as possible, and use kernel's own bank only for metadata (process list, etc). This way each program will "own" most of its data locally. There are some complications though: a program should never touch those kernel-managed data regions of its bank, and mutate them only via syscalls. And, of course, copying data between banks will be very slow.

André - would you mind providing some link or code for your call buffer feature? It sounds interesting and I'm really interested in understanding how it works. Is it just a shared region of memory to be used by multiple processes to transfer data between banks, or something more complex?

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 5:46 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 589
Location: Michigan, USA
and3rson wrote:
Yeah, it seems like it would be nice to have an ability to map different regions of multiple banks at once, especially when there's a need to copy data between processes, or work with kernel & user-space data simultaneously.

I was looking at the 74HC670 4-bit Register File IC some years back for the ability to map different segments into 64K address space. I had seen the '670 used in projects by the RC2014 Z80 crowd. Could something like that be useful in your project? *drawing below was for an '1802 project which uses separate address space for I/O...

Good luck on your project.


Attachments:
K8LH MMU excerpt.png
K8LH MMU excerpt.png [ 236.39 KiB | Viewed 4878 times ]
Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 6:19 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Michael wrote:
I was looking at the 74HC670 4-bit Register File IC some years back for the ability to map different segments into 64K address space. I had seen the '670 used in projects by the RC2014 Z80 crowd. Could something like that be useful in your project? *drawing below was for an '1802 project which uses separate address space for I/O...


'670 looks cool - I think I saw your picture earlier, but failed to realize the convenience of it! I also saw something similar in André's articles about MMU, though seems like it was '610.

I think I could wire my A11-A14 to inputs (D0-D3) and use its outputs (Q0-Q3) as A15-A18 for RAM. For writing the file however, I think I'll need to use '157, since new values will come from data bus. Something like this:

Code:
             +------+      +------+
A11-A14 ---> |      |      |      |
             | '157 | ---> | '670 | ---> A15-A18 (RAM)
D0-D3   ---> |      |      |      |
             +------+      +------+


As a result, I'll have 16x 32KB banks in RAM, each divided into 16x 2KB regions that can be mapped individually.

Since it seems that '670 doesn't have a reset input, the kernel would be responsible for initializing it on boot.

EDIT: I think I messed up a bit: '670 is a 4-word file, not 16-word... So I can only have 4x 8KB regions mapped individually, not 16:

Code:
             +--------+                +--------+
D4-D5   ---> | A      |                | '670   |
             |      Y | -------------> | Wa, Wb |
A13-A14 ---> | B      |                |        | ---> RAM
             |  '157  |       D0-D3 -> | D      |
             |        |                |        |
REG/WR\ ---> | ~A/B   |     REG/WR\ -> | ~Gw    |
             +--------+                +--------+

'157 selects D4-D5 when REG/WR\ asserted, A13-A14 otherwise.
'670 latches D0-D3 to word from '157 when REG/WR\ is asserted, otherwise it selects RAM bank.

To map Xth 8-KB segment to bank Y:

D5..D4  = X (0..3)
D3..D0  = Y (0..15)
REG/WR\ = asserted

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 8:16 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
I can't remember whether I already posted this, I thought I had but can't see it, so sorry if it's repeating, but in my experiment with this sort of thing I put some normal static RAM between the PID register and the high address lines of my main memory so that each process had its own page table. Processes used a system call to request pages to be mapped, and the supervisor (PID=0) can map any pages it likes for itself including those already used by other PIDs, so it can read memory of other processes if necessary.

In the prototype I only used 32K of main memory, so not many address lines were used, but it would scale up well to larger RAM modules - or the high bits in the page table could reflect executability and other protection states. At some point you might want 16 data bits in the page table. I probably copied most of these ideas from Andre's system.

Attachment:
5530451601220609552.png
5530451601220609552.png [ 79.71 KiB | Viewed 4849 times ]


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 8:21 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
@gfoot how do you set the pagetable values? Wouldn't it require some registers visible to the CPU? That seems to be missing or I haven't understood how it works

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
 Post subject: Re: RAM banking
PostPosted: Sun Jul 23, 2023 8:49 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
fachat wrote:
@gfoot how do you set the pagetable values? Wouldn't it require some registers visible to the CPU? That seems to be missing or I haven't understood how it works

For the supervisor process I think it was memory-mapped, with user processes using a syscall to request maps be set up for them.

On the hardware side I think ideally you'd use some transceivers or multiplexers to control the buses to the pagetable RAM, but I didn't get that far, this prototype was very hacky and I seem to remember I cut a lot of corners on that bit. It's no harder than the way video RAM is shared between the CPU and GPU though - you just need to make the address decoding swap things around when you're writing to the pagetable.


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

All times are UTC


Who is online

Users browsing this forum: barnacle and 29 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: