JX10 Banking
Notes
- Hexadecimal constants are preceded by a dollarsign. Within a hex constant, "L" means any digit 0-7, "H" means any digit 8-F, "J" means any odd digit, "N" means any even digit, and "X" means any digit.
- Certain operations are explicitly described as "forbidden". The effect of forbidden operations may vary between different versions of the ARM code; it is recommended that emulation stop if code performs a forbidden operation.
- There is going to be a "super-fetcher" mode, details TBD, which behaves totally differently from what's described here; any emulator design must be able to switch between normal mode and super-fetcher mode.
Atari Programming
There are eight code banks, distinguished by bits 13-15 of the address. Cartridge code execution is only permited at an address of $JHXX, and RIOT RAM code execution is only permitted at $V8HX. Except as provided below, any JMP, JSR, or RTS will cause a bank switch to the bank specified by the top three bits:
Bank 0 | $1HXX | RAM $1HXX
|
Bank 1 | $3HXX | ROM $0HXX
|
Bank 2 | $5HXX | ROM $1LXX
|
Bank 3 | $7HXX | ROM $1HXX
|
Bank 4 | $9HXX | ROM $2LXX
|
Bank 5 | $BHXX | ROM $2HXX
|
Bank 6 | $DHXX | ROM $3LXX
|
Bank 7 | $FHXX | ROM $3HXX
|
Jumping into RIOT RAM will also trigger a bank switch based upon the upper address bits (e.g. a jump to $08HX will switch to bank 0, $28HX will switch to bank 1, etc.)
Restrictions:
- A JMP or JSR instruction which starts at address N must not jump to an address that is a multiple of 8K bytes from N+2 or N+3, except that a JMP instruction may target the next address in sequence in the same bank.
- Any data fetches from $JHXX must be in the same bank as the code performing them (this restriction applies even when code is running from RIOT RAM; e.g., if RIOT RAM is entered via "JMP $4880", it may may access ROM at $5800-$5FFF, but may not access $1800-$1FFF, $3800-$3FFF, etc.
There are eight switchable data-banking areas, located at $JLXX (i.e. $1000-$17FF, $3000-$37FF, etc.) Each zone is controlled via various hot-spots at $V200-$VF7F. The $1000-$17FF zone is controlled by various hot-spots at $0200-$0F7F, the $3000-$37FF zone is controlled by hot-spots at $2200-$2F7F, etc. Hot-spots are as follows. Note that access to any addresses in the range $V200-$VFFF other than those listed below is forbidden (future functions will likely be added).
Hot-spots (more will follow):
$V000-$V0FF | Zero-page trigger (used to determine bank for (ZP,X) and (ZP),Y address
|
$V100-$V1FF | Stack trigger (used to determine bank for JSR or RTS address)
|
$V280-$V2FF | RIOT registers (no banking action)
|
$V400-$V4FF | Set LSB of banking address (MSB unaffected)
|
$V500-$V5FF | Set MSB of banking address (LSB unaffected)
|
$V600-$V601 | Set bank mode (values below)
|
$V700-$v71F | Map bank to RAM at $0000-$1F00 (LSB cleared)
|
$V880-$V8FF | Executable RIOT RAM
|
$V900-$V97F | Map bank to ROM at $0000-$7F00 (LSB cleared)
|
$VC00-$VCFF | Add $0000-$00FF to bank address
|
$VD00-$VDFF | Subtract $0000-$00FF from bank address
|
$VE00-$VE1F | Add $0000-$1F00 to bank address
|
$VE40-$VE5F | Subtract $0000-$1F00 from bank address
|
Banking modes (more will follow):
0 | Access ROM (read-only; writes forbidden)
|
1 | Access RAM (reads or ST* instructions; read-modify-write forbidden)
|
Implementation Notes
The implementation needs to keep track of the address and mode for each of the eight code banks. It also needs to keep a 16-bit variable called
"LastCodeAddr" and a 32-bit variable called "RecentCode".
Addresses are divided into a few groups. Note that most of the hot-spots are treated similarly; for simplicity, they are simply called "hot-spot" below. All addresses given are physical 13-bit address-bus addresses. An emulator may check upper bits to ensure they are as expected.
- $0000-$00FF
- Wait until address is seen greater than $01FF. Then set RecentCode to ((RecentCode shl 8) or data)
- $0100-$01FF
- If RecentCode[15..8] is $60, set RecentCode to $00004C00 and clear LastCodeAddr. If RecentCode[15..8] is $20, set RecentCode to $0000004C (leave RecentAddr alone). If neither condition applies, clear RecentCode. In any case, wait until address is seen greater than $01FF and handle RecentCode as with $00XX.
- General hot-spot
- Use RecentCode[7..5] to select a one of eight banks, and apply hot-spot behavior to that bank.
- $0880-$08FF
- Banking behavior is like $1800-$1FFF.
- $1000-$17FF
- Use RecentCode[7..5] to select one of eight banks, and treat according to that bank mode. If RAM, if RecentCode[23-16] is $80-$9F, handle as a write; otherwise handle as a read.
- $1800-$1FFF
- If address does matches LastCodeAddr or LastCodeAddr+1, set RecentCode to ((RecentCode shl 8) or data). Otherwise, if RecentCode[23..16] is 0x4C, set code bank based on RecentCode[7..5]; if address hadn't matched, clear RecentCode.
Super-Fetcher mode (preview)
In super-fetcher mode, all addresses $JXXX will be treated identically. The cartridge will maintain its own program counter, and execute two-byte super-instructions. Each super-instruction will generate the data for one or more bus cycles. Some typical super-instructions would be "Load accomulator from fetcher 19", "Store X in COLUP1", and "stuff a 6507 'JMP $1000' instruction. Note that disassembly via normal means will be totally meaningless.
Post a Comment