While segmenting memory lets you do things you can't do with bank switching, it is still (IMO) a horrible kludge.
As pointed out by Jeff, the 65C816 memory scheme is not segmentation like what Intel 8088/8086 programmers deal with. Also as pointed out by Jeff and Garth, one can "seamlessly" index across 64KB (bank) boundaries or use
[<dp>] addressing to read or write anywhere in the contiguous memory space. It's entirely possible to never touch DB (data bank register) and use 24 bit addresses or DP indirect addressing to cover the full range of memory.
The one real advantage to setting DB to a working bank is that all addressing can be reduced to 16 bits, which is slightly faster than 24 bits. It's a judgment call that one develops from experience.
...can you specify a full address as an immediate value, or do you have to load the segment register separately, does the segment register roll over on index register overflow etc.
There is no "segment register." There is DB, the data bank register, and PB the program bank register. PB matters when the '816 is fetching an opcode or an operand. DB matters when the '816 is fetching or storing anything other than an opcode or operand and 16 bit addressing is in use. DB, as I mentioned, can be "ignored" by using 24 bit addressing, by indexing across a 64KB boundary or both. A short code example explains the "both" scenario, which is the most flexible of the three possibilities:
Code: Select all
sep #%00110000 ;8 bit registers
ldx #<$00fffe ;LSB of a 16 bit address
ldy #>$00fffe ;MSB of a 16 bit address
lda #^$00fffe ;BSB ($00)
stx dpptr ;set up 24 bit...
sty dpptr+1 ;address in...
sta dpptr+2 ;direct page
lda #$ab ;set DB to bank $AB...
pha ;which will be...
plb ;the default bank
rep #%00010000 ;16 bit index registers
ldy #0000 ;16 bit index value
lda [dpptr],y ;reads from $00FFFE, not $ABFFFE
ldy #0002 ;new 16 bit index value
sta [dpptr],y ;writes to $010000, not to $AC0000
Note that the last instruction, while indexing into bank $01, does not affect DB at all. The programmer can set a new bank for read/write access by writing a different value into DPPTR+2 and not touch DB.
As Garth mentioned, all direct page and stack accesses are in bank $00, regardless of the value in DB. Also, when the '816 handles an interrupt it pushes PB, along with PC and SR, and then loads PB with $00, which means the front ends of all five interrupt service routines must be in bank $00. However, the ISRs can execute in some other bank by using JML to go to the non-bank $00 address.
It's not at all complicated.
In summary, I prefer the simplicity of bank switching against something that works but feels almost as cumbersome as bank switching.
Bank switching is inherently not simple for the eight bit assembly language programmer because a bank is of necessity some fraction of the 16 bit address space supported by the MPU. The '816 makes it easier to touch the entire address space because no specialized logic is required.