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.
What I meant was the data flow would come via IRQs, not register setup. You can always change the active data bank with:
Code:
phb ;protect current data bank
lda #$00 ;bank $00
pha
plb ;set new bank
Later on when your code has finished tinkering with the I/O hardware:
Code:
plb ;restore old data bank
Setting the data bank in this way eliminates having to use 24 bit instructions, and also gives you the use of some instructions that have no 24 bit counterparts (e.g., TRB).
Quote:
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
.
Use of ABORT is somewhat challenging, as there are strict timing deadlines involved. However, it's there to be used, such as for memory protection, correcting page faults, etc.
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.
Unfortunately, the SNES was not a true 65C816 implementation and definitely not a model of a general purpose computer. As you are no longer working within the constraints of the SNES architecture you can rig up your system with flat address space and can use that space as you see fit (e.g., large data arrays, as Garth suggests).
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:
;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 $050000
Quote:
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.
The MC68451 is a sophisticated device that goes well beyond what a 74LS610 can do. That said, the '610 is LS logic, and you really shouldn't be using LS hardware in this application.
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.
Right.
VDA && VPA is the equivalent of SYNC being high on the 65C02, indicating an opcode fetch is in progress.
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?
I've never given it any thought. The largest program I ever developed in assembly language worked out to about 18K total, code and data. That is a huge program by 65xx standards.
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
).
André Fachat, whose page you earlier linked, developed a relocating format for 65xx executables.
GARTHWILSON wrote:
What bothers me most about requiring long addressing for I/O is that it's missing TSB, TRB, BIT, INC, and DEC.
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.