First steps...
Re: First steps...
Preliminary Address Space...
Range Banks Purpose
0000-0FFF 0 Zero Page, OS stack space
0000-0FFF 1-FF Application stack space
1000-1FFF 0 OS kernel buffers
2000-2FFF 0 OS kernel system calls
1000-2FFF 1-FF Application RAM
3000-DFFF 0-FF OS/Application RAM
E000-EFFF Shared I/O Space
F000-F7FF Shared Shared ROM, Bank switch routines (For Position-Independent application bank allocation/code jumping*)
F800-FFDF 0-FF Generic ROM
FFE0-FFFF 0 Vector Table
FFE0-FFFF 1-FF Generic ROM
"Shared" means that portion of the address space is mirrored in all banks (one copy). Otherwise, assume each bank has a unique copy of that portion of the address space reserved for the described purpose.
This is meant to be forwards-compatible. No chance in hell I'm implementing a full OS now. Only bank 0 and 1 are meaningful for now... the latter just for a checkerboard test, as BDD suggested, to test my bank logic. *But if anyone knows how create a bank-independent program loader and bank-independent '816 applications, I'm all ears. When we get to this point, I'll probably use a 7400-series MMU for virtual memory.
Range Banks Purpose
0000-0FFF 0 Zero Page, OS stack space
0000-0FFF 1-FF Application stack space
1000-1FFF 0 OS kernel buffers
2000-2FFF 0 OS kernel system calls
1000-2FFF 1-FF Application RAM
3000-DFFF 0-FF OS/Application RAM
E000-EFFF Shared I/O Space
F000-F7FF Shared Shared ROM, Bank switch routines (For Position-Independent application bank allocation/code jumping*)
F800-FFDF 0-FF Generic ROM
FFE0-FFFF 0 Vector Table
FFE0-FFFF 1-FF Generic ROM
"Shared" means that portion of the address space is mirrored in all banks (one copy). Otherwise, assume each bank has a unique copy of that portion of the address space reserved for the described purpose.
This is meant to be forwards-compatible. No chance in hell I'm implementing a full OS now. Only bank 0 and 1 are meaningful for now... the latter just for a checkerboard test, as BDD suggested, to test my bank logic. *But if anyone knows how create a bank-independent program loader and bank-independent '816 applications, I'm all ears. When we get to this point, I'll probably use a 7400-series MMU for virtual memory.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First steps...
cr1901 wrote:
Preliminary Address Space...
"Shared" means that portion of the address space is mirrored in all banks (one copy). Otherwise, assume each bank has a unique copy of that portion of the address space reserved for the described purpose.
Code: Select all
Range Banks Purpose
0000-0FFF 0 Zero Page, OS stack space
0000-0FFF 1-FF Application stack space
1000-1FFF 0 OS kernel buffers
2000-2FFF 0 OS kernel system calls
1000-2FFF 1-FF Application RAM
3000-DFFF 0-FF OS/Application RAM
E000-EFFF Shared I/O Space
F000-F7FF Shared Shared ROM, Bank switch routines (For Position-Independent application bank allocation/code jumping*)
F800-FFDF 0-FF Generic ROM
FFE0-FFFF 0 Vector Table
FFE0-FFFF 1-FF Generic ROMQuote:
Code: Select all
0000-0FFF 1-FF Application stack spaceMirroring ROM in every bank will prevent you from treating RAM above $00FFFF as flat space. While programs officially can't overlap banks, data certainly can, as indexing will span from one bank to the next. So I wouldn't be inclined to throw away that possibility.
Also, if you decide you want to run this system at 20 MHz, you are going to have to wait-state ROM accesses. That will add to the complication of ROM being in every bank.
Quote:
This is meant to be forwards-compatible. No chance in hell I'm implementing a full OS now. Only bank 0 and 1 are meaningful for now... the latter just for a checkerboard test, as BDD suggested, to test my bank logic. *But if anyone knows how create a bank-independent program loader and bank-independent '816 applications, I'm all ears.
Quote:
When we get to this point, I'll probably use a 7400-series MMU for virtual memory.
Last edited by BigDumbDinosaur on Tue May 27, 2014 4:14 am, edited 1 time in total.
x86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
If you use wire-wrap or programmable logic so it's not too big a deal to change things after the bulk of the project is built up, it should give more flexibility than a PC board and 74-family logic would. (Remember there are PLCC sockets, even for WW.) Some things you may just have to learn from experience; but do try to avoid painting yourself into corners such that a change of mind requires starting over. Actually, on early projects, ideas seem to develop faster than you can build, which has a tendency of keeping one from finishing anything; so I recommend starting simple but with the possibility of expansion left open.
I would encourage leaving at least some banks as contiguous, free RAM for large data arrays so you don't have the pain of dealing with interruptions in such arrays. If you need a lot of RAM, it will probably be for data, not so much for program space. You'll give yourself a lot more freedom if you don't commit to chopping up RAM in a particular inflexible way.
I would encourage leaving at least some banks as contiguous, free RAM for large data arrays so you don't have the pain of dealing with interruptions in such arrays. If you need a lot of RAM, it will probably be for data, not so much for program space. You'll give yourself a lot more freedom if you don't commit to chopping up RAM in a particular inflexible way.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: First steps...
BigDumbDinosaur wrote:
Just my curmudgeonly opinion, but it's much too complicated. You're "micromanaging" memory allocation and will pay for it in complex (i.e., slow) glue logic. If you're going to go to that much trouble then you might as well apportion all RAM into pages (not 65xx pages) and set up hardware memory protection.
BigDumbDinosaur wrote:
4KB is a lot of stack space, probably much more than you'll likely need. Also, what about the application's direct page?
BigDumbDinosaur wrote:
Mirroring ROM in every bank will prevent you from treating RAM above $00FFFF as flat space. While programs officially can't overlap banks, data certainly can, as indexing will span from one bank to the next. So I wouldn't be inclined to throw away that possibility.
BigDumbDinosaur wrote:
Also, if you decide you want to run this system at 20 MHz, you are going to have to wait-state ROM accesses. That will add to the complication of ROM being in every bank.
BigDumbDinosaur wrote:
Bank-independent applications? You already have that. If you load a program at $xx1000, for example (where $xx is any bank), it will run regardless of what $xx is. Relative branches, JMPs and JSRs are bounded by the bank in PB. Only JML and JSL can take you out of a bank, and I don't recommend their use in the ordinary course of events. I recommend that OS calls be via software interrupts so applications don't have to know about specific addresses.
Then HOW do you handle the case where a task/application requires more than 64kB of code in a manner where the application doesn't care which banks to which its code segments are loaded? Using an already-existing EXE format isn't a problem for me (when we get to this point), but I have trouble visualizing how to load programs > 64kB in a position-independent manner.
BigDumbDinosaur wrote:
I don't sound negative or discouraging, but exactly what 7400-series MMU would you use that could stay with the 65C816 at any speed above a couple of MHz? Are you thinking about the 74LS610? This sounds like a job for programmable logic.
Again, this was all for future use. But I'll tone it back for starting out.
Last edited by cr1901 on Tue May 27, 2014 3:36 am, edited 1 time in total.
Re: First steps...
GARTHWILSON wrote:
If you need a lot of RAM, it will probably be for data, not so much for program space. You'll give yourself a lot more freedom if you don't commit to chopping up RAM in a particular inflexible way.
And how do I handle the case where a program has > 64kB of code without hardcoding bank numbers? Perhaps I could implement that as an OS service to "switch banks", instead of using the JSL/JML instructions directly in application/task code.
GARTHWILSON wrote:
Actually, on early projects, ideas seem to develop faster than you can build, which has a tendency of keeping one from finishing anything; so I recommend starting simple but with the possibility of expansion left open.
So what's left is:
- reset circuit
- clock circuit
- power supply (I'll probably cheat and use a bench supply for now)
- three TTL chips
For the three TTL chips- one TTL latch to hold the bank, one TTL bidirectional hiz transceiver to attach/detach the '816 from the data bus, and one TTL chip to expand the VIA's I/O capabilities. Garth, I seem to recall you mentioning that the VIA can support more I/O devices with simple glue logic, but the post where you mention this escapes me. Do you know by any chance what I am referring to?
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
cr1901 wrote:
what about I/O being mirrored throughout each bank?
Quote:
Or perhaps you're implying to split up code and data as much as possible without going full Harvard Architecture, and make the most-accessed banks have access to the mirrored address spaces.
Quote:
And how do I handle the case where a program has > 64kB of code without hardcoding bank numbers?
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
cr1901 wrote:
Garth, I seem to recall you mentioning that the VIA can support more I/O devices with simple glue logic, but the post where you mention this escapes me. Do you know by any chance what I am referring to?
http://wilsonminesco.com/6502primer/ExpBusIntrfc.html
http://wilsonminesco.com/6502primer/IO_ICs.html
http://wilsonminesco.com/6502primer/potpourri.html
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First steps...
cr1901 wrote:
BigDumbDinosaur wrote:
4KB is a lot of stack space, probably much more than you'll likely need. Also, what about the application's direct page?
Quote:
BigDumbDinosaur wrote:
Mirroring ROM in every bank will prevent you from treating RAM above $00FFFF as flat space. While programs officially can't overlap banks, data certainly can, as indexing will span from one bank to the next. So I wouldn't be inclined to throw away that possibility.
Quote:
BigDumbDinosaur wrote:
Also, if you decide you want to run this system at 20 MHz, you are going to have to wait-state ROM accesses. That will add to the complication of ROM being in every bank.
Quote:
BigDumbDinosaur wrote:
Bank-independent applications? You already have that. If you load a program at $xx1000, for example (where $xx is any bank), it will run regardless of what $xx is. Relative branches, JMPs and JSRs are bounded by the bank in PB. Only JML and JSL can take you out of a bank, and I don't recommend their use in the ordinary course of events. I recommend that OS calls be via software interrupts so applications don't have to know about specific addresses.
Quote:
Then HOW do you handle the case where a task/application requires more than 64kB of code in a manner where the application doesn't care which banks to which its code segments are loaded? Using an already-existing EXE format isn't a problem for me (when we get to this point), but I have trouble visualizing how to load programs > 64kB in a position-independent manner.
Quote:
BigDumbDinosaur wrote:
I don't sound negative or discouraging, but exactly what 7400-series MMU would you use that could stay with the 65C816 at any speed above a couple of MHz? Are you thinking about the 74LS610? This sounds like a job for programmable logic.
Quote:
So what's left is:

For the three TTL chips- one TTL latch to hold the bank...
- reset circuit
- clock circuit
- power supply (I'll probably cheat and use a bench supply for now)
- three TTL chips
For the three TTL chips- one TTL latch to hold the bank...
Quote:
...one TTL bidirectional hiz transceiver to attach/detach the '816 from the data bus...
Quote:
...and one TTL chip to expand the VIA's I/O capabilities.
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First steps...
P.S. If I were building this, I'd set up a memory map thusly:
The HMU could be some registers in a PLD that would allow you to map out one or both segments of ROM and expose the RAM underneath. Writing to a ROM address would bleed through to RAM.
Code: Select all
000000-00BFFF RAM
00C000-00CFFF Lo ROM
00D000-00D7FF I/O
00D800-00DEFF Reserved
00DF00-00DFFF HMU (hardware management unit, aka MMU)
00E000-00FFFF Hi ROM
010000-xxFFFF contiguous RAMx86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
I didn't really think about the 4KB for stack space before; but I will comment now that 16 pages for stack space may be a lot more than you'll ever need. You probably won't need even a quarter of a page for any task. (If you use Pascal, I'll have to eat my words.
) The amount you give to each task is variable in one-byte increments; ie, it does not have to be multiples of 256 (or any other number). You could just as easily give a task 75 bytes' space as 64 or 256. 4KB at a quarter of a page each would be 64 tasks.
The same goes for direct-page space. It does not have to start on a page boundary, although if it does, certain instructions will take one less clock to execute. So there again, you could give each task only slightly more direct-page space than it needs, whether that's 30 bytes or 230.
The same goes for direct-page space. It does not have to start on a page boundary, although if it does, certain instructions will take one less clock to execute. So there again, you could give each task only slightly more direct-page space than it needs, whether that's 30 bytes or 230.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: First steps...
BigDumbDinosaur wrote:
P.S. If I were building this, I'd set up a memory map thusly:
The HMU could be some registers in a PLD that would allow you to map out one or both segments of ROM and expose the RAM underneath. Writing to a ROM address would bleed through to RAM.
Code: Select all
000000-00BFFF RAM
00C000-00CFFF Lo ROM
00D000-00D7FF I/O
00D800-00DEFF Reserved
00DF00-00DFFF HMU (hardware management unit, aka MMU)
00E000-00FFFF Hi ROM
010000-xxFFFF contiguous RAMAdditionally, I could reserve part of the HMU for virtual-memory like features in addition to mapping out ROM and RAM (assigning pages to the contiguous RAM, etc), should I choose to go that route. The ABORT pin seems like it could use some love
Okay, not that it excuses me not doing my research, but my experience with the '816 is with the SNES. The SNES doesn't seem to use the COP interrupt, at least for anything I've looked at. So of course I told myself "I'll review COP later." Guess how that turned out
Some clarification- I thought the 7400 series MMUs accomplished similar goals to, say, the Motorola 68451- just being a lot simpler to set up. There's even a page on 6502.org detailing the discrete equivalent of the 74ls610. I don't think of an MMU as simply a bank switcher/swapper.
... I'll start at 8MHz, and work my way up. I'll probably also include a single-instruction mode as well... that's as simple as waiting for VDA/VPA to both be asserted I believe.
I know my code is not likely to exceed 64kB for a task, but just for the sake of discussion... what WOULD you guys do in that case to make the resultant executable position-independent if the code size exceeded 64kB? Semi-related: Didn't someone create an EXE format just for the 65xx series? The DOS MZ/Linux ELF formats, for example keeps a list of offsets that must be patched before running the program (though in the case of the former, those are segment markups, not linear addresses
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
What bothers me most about requiring long addressing for I/O is that it's missing TSB, TRB, BIT, INC, and DEC. The indirect and indexed longs have less application in I/O, so I don't see them as an issue. Fortunately I myself don't really anticipate having code outside bank 0, only data, so it's not a problem. If I can put I/O in the first page (or two or four) of bank 0, and have all the rest to be RAM, and pre-load a part of RAM (in memory space which would otherwise be ROM) before releasing the processor from reset, it makes thing pretty simple (read: low propagation delays in the address decoding), and leaves a lot of flexibility, with nearly all of bank 0 being RAM. Even the interrupt vectors can be modified by the program. I know that wouldn't be suitable for a multitasking desktop-type computer though, which might be what you have in mind. Maybe you could write to a bit that would switch I/O in and out of a small part of every page, part that would otherwise be RAM.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: First steps...
cr1901 wrote:
I'll probably do some variation on that. One issue I see is when an application needs direct I/O port access- with this scheme, all I/O writes will be long (I can't envision creating an ISR just for writing bytes to the VIA or ACIA registers). This issue was also brought up when I proposed using a bank solely for I/O.
Code: Select all
phb ;protect current data bank
lda #$00 ;bank $00
pha
plb ;set new bankCode: Select all
plb ;restore old data bankQuote:
Additionally, I could reserve part of the HMU for virtual-memory like features in addition to mapping out ROM and RAM (assigning pages to the contiguous RAM, etc), should I choose to go that route. The ABORT pin seems like it could use some love
.
Quote:
Okay, not that it excuses me not doing my research, but my experience with the '816 is with the SNES. The SNES doesn't seem to use the COP interrupt, at least for anything I've looked at. So of course I told myself "I'll review COP later." Guess how that turned out
. Ditto with not knowing that the Stack Pointer is automapped to bank 0: xx:0000-xx:1fff is mirrored RAM in all banks except 7f on the SNES, and 1fff is a good initial SP.
I'm sure you're familiar with direct page indirect addressing, e.g., LDA ($12),Y. I don't know if you also know that the 65C816 has a 24 bit version of that, e.g., LDA [$12],Y. The value stored at $12 is a 24 bit address in little endian format, with the bank value being at $14. This addressing mode is the key to treating RAM as flat data space. With the index registers set to 16 bits, you can access 64KB of data at a time by merely indexing .Y as you go. If .Y wraps then you would increment the bank byte. For example:
Code: Select all
;access a large range of RAM
;
rep #%00010000 ;16 bit index registers
sep #%00100000 ;8 bit accumulator
lda #$04 ;starting bank
ldx #$0100 ;starting address in bank
stx $12 ;set starting address
sta $14 ;set starting bank...
;
; The above sets the effective address to $040100.
;
ldy #$0000 ;this is 16 bit load
;
loop lda [$12],y ;read from RAM
...process the byte...
sta [$12],y ;write to RAM
iny ;next location
bne loop ;loop over 64K locations
;
inc $14 ;next bank
bra loop ;effective address now $050000Quote:
Some clarification- I thought the 7400 series MMUs accomplished similar goals to, say, the Motorola 68451- just being a lot simpler to set up. There's even a page on 6502.org detailing the discrete equivalent of the 74ls610. I don't think of an MMU as simply a bank switcher/swapper.
Quote:
... I'll start at 8MHz, and work my way up. I'll probably also include a single-instruction mode as well... that's as simple as waiting for VDA/VPA to both be asserted I believe.
Quote:
I know my code is not likely to exceed 64kB for a task, but just for the sake of discussion... what WOULD you guys do in that case to make the resultant executable position-independent if the code size exceeded 64kB?
Quote:
Semi-related: Didn't someone create an EXE format just for the 65xx series? The DOS MZ/Linux ELF formats, for example keeps a list of offsets that must be patched before running the program (though in the case of the former, those are segment markups, not linear addresses
).
GARTHWILSON wrote:
What bothers me most about requiring long addressing for I/O is that it's missing TSB, TRB, BIT, INC, and DEC.
Last edited by BigDumbDinosaur on Tue May 27, 2014 11:57 pm, edited 1 time in total.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: First steps...
BigDumbDinosaur wrote:
This is where pushing DB to the stack and temporarily loading it with bank $00 (or wherever the I/O hardware is located) helps out. In any 65C816 system with more than 64K, you are going to have to either use long addressing or be prepared to tinker with DB. It's unavoidable.
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: First steps...
I suspect that doing 24-bit addressing would be more efficient than constantly changing data banks when transferring data from I/O to memory or vice-versa. However, my '816 experience is limited to the '802 which is an '816 that goes into a 6502 socket, so it has a lot of '816 benefits but there's no operation outside of bank 0.
I think that if it spans two or more banks, it shouldn't be any problem if they're always in the same order (probably consecutive).
Quote:
I know my code is not likely to exceed 64kB for a task, but just for the sake of discussion... what WOULD you guys do in that case to make the resultant executable position-independent if the code size exceeded 64kB?
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?