Supercat 2600

Saturday, May 14, 2011

 

Easy Banking

The "Easy Banking" scheme is a memory-control design which allows the user to access up to 24K-30K of ROM and 6K of RAM (6K of ROM is copied to RAM on startup and is inaccessible thereafter) without any bank-switching instructions. There are a few restrictions on memory layout, but the memory access will be far smoother than with any other banking system.

The cartridge memory space is divided into sixteen 2K regions. Eight of these are called "code banks", and the other eight are "data banks". Code is only allowed to run in code banks, or in RIOT RAM from $0880-$08FF. The behavior of running code from any other address is unspecified. Data may be accessed from within the current running code bank, or from any data bank. The effect of accessing data from a code bank other than the current one, or accessing data from a code bank when running from RIOT RAM at $08xx, is unspecified.

One of the code banks will access the first 2K of RAM, which is on startup pre-loaded with ROM from $4000-$47FF; the other seven will access ROM from $0800-$3FFF. To jump from one bank to another, all one needs to to is use a JMP or JSR to the proper address, or do an RTS with the proper address on the stack. The only restriction is that target of a JMP or JSR instruction must not be a multiple of 2K away from either either last byte of the JMP or JSR instruction, nor the first byte of the next instruction, unless the target address is in the same bank as the JMP/JSR instruction itself. An RTS may be located anywhere except at the very last byte of a code area, and is allowed to return to any valid code location.

The first three data banks will access 6K of RAM, which is pre-loaded with ROM from $4000-$57FF. The remaining five data banks will access ROM from $5800 to $7FFF.

The RAM at $1000-$17FF, $3000-$37FF, and $5000-$57FF may be written using STA, STX, STY, or SAX instructions, using any supported addressing mode. The effect of other instructions is unspecified. Data written to RAM at $1000-$17FF will also appear 2K higher in the RAM code bank from $1800-$1FFF. Note that writing to addresses $1800-$1FFF is not supported; one must write to addresses $1000-$17FF.

**CODE ADDRESSES**
6507 Address ROM Address
1800-1FFF 4000-47FF+
3800-3FFF 0800-0FFF
5800-5FFF 1000-17FF
7800-7FFF 1800-1FFF
9800-9FFF 2000-27FF
B800-BFFF 2800-2FFF
D800-DFFF 3000-37FF
E800-FFFF 3800-3FFF

**DATA ADDRESSES**
6507 Address ROM Address
1000-17FF* 4000-47FF+
3000-37FF* 4800-4FFF+
5000-57FF* 5000-47FF+
7000-77FF 5800-4FFF
9000-97FF 6000-47FF
B000-B7FF 6800-4FFF
D000-D7FF 7000-47FF
F000-F7FF 7800-4FFF

(*) Address is writable
(+) Address is RAM which is initialized from ROM

Thursday, October 7, 2010

 

JX10, fetcher mode

NOTE: Not quite up to date with latest changes in Stella

In fetcher mode, the cartridge will dynamically generate 6502 code to implement a specialized instruction set. Every instruction will be 16 bits, and will take 2 to 4 cycles to execute. Instructions will be assigned 4-5 character mnemonics to distinguish them from 6507 opcodes. Opcodes ending with "+" may have an "L" or "J" suffix to specify that they should do "Loop-test" or "Jump-loop" (see below) in addition to their normal function.

The JX10 Fetcher itself keeps three pieces of state information, all of them addresses: the next JX10 instruction, the fetcher group 0 table, the and fetcher group 1 table. All other state is manged by performing read-modify-write operations on the data in the fetcher tables, or memory pointed at by such data; any of these latter changes will be directly visible to the target application.

REST+3 cyclesJMP $1010
This instruction takes 3 cycles to execute. A REST instruction must be done at least once every 4,000 cycles or the Atari may malfunction. It translates into JMP $1010.
QUIT addr(EXITS)JMP addr
Generates an "JMP a" instruction and returns to normal code execution.
LIMA value
LIMX value
LIMY value
2 cyclesLDA #value
LDX #value
LDY #value
Load A, X, or Y with an 8-bit immediate value
LDFA group,fetcher,inc
LDFX group,fetcher,inc
LDFY group,fetcher,inc
2 cyclesLDA #data
LDX #data
LDY #data
Load A, X, or Y from fetcher #f of group #g and increment it by i. (lda #imm, etc.)
SDRA+ addr
SDRX+ addr
SDRY+ addr
SDRQ+ addr
3 cyclesSTA addr
STX addr
STY addr
SAX addr
Store A, X, Y, or (A&X) to specified TIA address
SSDA+ addr
SSDX+ addr
SSDY+ addr
SSDQ+ addr
4 cyclesSTA.w addr
STX.w addr
STY.w addr
SAX.w addr
As above, but takes 4 cycles.
SDFR group,fetcher,inc3 cyclesSTA addr
STX addr
STY addr
SAX addr
Get a byte from fetcher #f or group #g, increment it by i, generate a STA, STX, STY, or SAX instruction. Use top two bits of fetched value to select instruction; remaining 6 bits for address.
SSFR group,fetcher,inc4 cyclesSTA.w addr
STX.w addr
STY.w addr
SAX.w addr
As above, but takes 4 cycles (sta abs, etc.)
TSTS addr,g,f3 cyclesBIT addr
Read specified address and store the result to RAM pointed at by the specified fetcher (single-increment mode only). Useful for collision detection.
TSTI addr,group,fetcher3 cyclesBIT addr
Read the specified address and increment the upper byte of the indicated fetcher if bit 7 is set, and/or the lower byte if bit 6 is set. Useful for paddles.


The system has two fetcher-pointers. To perform a fetch-retrieval (e.g. for "LDFA") the system selects one of the pointers using the "g" bit. It then performs the following logic:

addr1 = ptr + f*2
addr2 = memw[addr1]
dat = mem[addr2]
generate opcode from dat
if i<>max then
addr2 += i
else
addr3 = memw[addr1+2]
dat = mem[addr3], and update flags
if dat was zero
addr3++
else
dat--
mem[addr3]=dat
endif
if addr3 is odd then addr2++
endif
memw[addr1] = addr2

Loop-test and Jump-loop behavior:

dat = mem[fetchptr0-4]
if dat=0
fetchptr0 = memw[fetchptr0 - 2]
fetchptr1 = memw[fetchptr0-8] ' Use new value of fp0
virtpc = memw[fetchotr0-6]
else
dat--
memw[fetchptr0-4] = dat
dat = mem[fetchptr1-4]
if dat=0
fetchptr1 = memw[fetchptr1 - 2]
else
dat--
memw[fetchptr1-4] = dat
endif
if (is jump-loop instruction)
virtpc = memw[fetchptr1-6]
endif
endif

Monday, October 4, 2010

 

JX10, preliminary

JX10 Banking

Notes

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$1HXXRAM $1HXX
Bank 1$3HXXROM $0HXX
Bank 2$5HXXROM $1LXX
Bank 3$7HXXROM $1HXX
Bank 4$9HXXROM $2LXX
Bank 5$BHXXROM $2HXX
Bank 6$DHXXROM $3LXX
Bank 7$FHXXROM $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:


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-$V0FFZero-page trigger (used to determine bank for (ZP,X) and (ZP),Y address
$V100-$V1FFStack trigger (used to determine bank for JSR or RTS address)
$V280-$V2FFRIOT registers (no banking action)
$V400-$V4FFSet LSB of banking address (MSB unaffected)
$V500-$V5FFSet MSB of banking address (LSB unaffected)
$V600-$V601Set bank mode (values below)
$V700-$v71FMap bank to RAM at $0000-$1F00 (LSB cleared)
$V880-$V8FFExecutable RIOT RAM
$V900-$V97FMap bank to ROM at $0000-$7F00 (LSB cleared)
$VC00-$VCFFAdd $0000-$00FF to bank address
$VD00-$VDFFSubtract $0000-$00FF from bank address
$VE00-$VE1FAdd $0000-$1F00 to bank address
$VE40-$VE5FSubtract $0000-$1F00 from bank address

Banking modes (more will follow):

0Access ROM (read-only; writes forbidden)
1Access 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.

Archives

October 2010   May 2011  

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]