Jump to content
IGNORED

Atari 8bit bank switching


Recommended Posts

I'm trying to cut a 32K program into 2 16K banks to run on the A8 platform. I'm afraid I am at a total loss of how to set up and then to tell the 6502 ASM program which of two 16K banks to point to! Here's some questions:

 

 

 

.ORG $4000	 ; beginning of the 1st 16 Bank, right? 
lda #$00 
sta $20
sta $30 
jsr Bank-1-Do-Stuff	  ;still running in 1st 16K bank....
;  
jsr Bank-2-subroutine
; 
...
.ORG ????			  ; how do you use ORG to setup the 2 banks? 
Bank-2-subroutine
lda ...
rts					   ;end of bank 2 ROM

 

Question1: Before the jsr Bank-2-subroutine, don't I need to access some register/memory location? Literally what statement(s) go before and after the bank switch jsr? Is it user-defined?

 

Question2: How do you use .ORG to arrange the 2 16K banks? I am only familiar with a normal 32K ROM size , on the Atari 5200, which is $4000-$BFFF.

 

Any help?

Link to comment
Share on other sites

I assume you're talking 130XE here.

 

PORTB ($D301) controls bank selecting. When you store a value there to change the configuration, the change is instant.

 

Having two code sections with the same .ORG should be fine with one exception: if you're assembling to RAM, you'll likely overwrite the first block of code with subsequent ones.

 

Assembling to a binary-load file also has the same consideration.

 

When the program is loading, you would want to change PORTB such that each block of code destined for $4000 goes to its proper bank.

 

You could do it two ways:

 

1. Have a hard-coded section with .ORG $D301 followed by a .BYTE which forces PORTB to the appropriate value.

2. Have a section of code which gets called through the Binary Load INIT vector ($2E2) which switches the appropriate bank in so that subsequent data gets loaded into the correct bank.

 

Alternatively to all of that, you might want to have the code/data destined for each bank of extended memory in seperate source files. Of course, the disadvantage to that would be that label references would be lost for code/data outside of that particular area.

Link to comment
Share on other sites

Here's a lift from the AtariWinPlus emulator Help about the different cart types and how to use them, below.

 

Megacart format is the closest fit if you want 16K banks rather than 8K. I think you'll find Sunmark can make a real physical Megacart if you need, and I believe Bryan has some experience making XEGS carts.

 

Note that 16K cart address starts at $8000, rather than $4000 as with the 5200 ($4000 tends to be used for extra RAM banks which is what Rybags is explaining about)

 

I can tell you how to assemble carts with ATasm, but don't know how to with other assemblers. What one are you using - is it DASM? If so, then the 2600 guys will know how to do that - may be the REORG statement you need?

 

Cartridge images are dumps of ROMs used in real cartridges.

 

The following table lists currently supported cartridge types:

 

 

Id Machine Size Name

1 800/XL/XE 8 Standard 8 KB cartridge

2 800/XL/XE 16 Standard 16 KB cartridge

3 800/XL/XE 16 OSS '034M' 16 KB cartridge

4 5200 32 Standard 32 KB 5200 cartridge

5 800/XL/XE 32 DB 32 KB cartridge

6 5200 16 Two chip 16 KB 5200 cartridge

7 5200 40 Bounty Bob Strikes Back 40 KB 5200 cartridge

8 800/XL/XE 64 64 KB Williams cartridge

9 800/XL/XE 64 Express 64 KB cartridge

10 800/XL/XE 64 Diamond 64 KB cartridge

11 800/XL/XE 64 SpartaDos X 64 KB cartridge

12 800/XL/XE 32 XEGS 32 KB cartridge

13 800/XL/XE 64 XEGS 64 KB cartridge

14 800/XL/XE 128 XEGS 128 KB cartridge

15 800/XL/XE 16 OSS 'M091' 16 KB cartridge

16 5200 16 One chip 16 KB 5200 cartridge

17 800/XL/XE 128 Atrax 128 KB cartridge

18 800/XL/XE 40 Bounty Bob Strikes Back 40 KB cartridge

19 5200 8 Standard 8 KB 5200 cartridge

20 5200 4 Standard 4 KB 5200 cartridge

21 800 8 Right slot 8 KB cartridge

22 800/XL/XE 32 32 KB Williams cartridge

23 800/XL/XE 256 XEGS 256 KB cartridge

24 800/XL/XE 512 XEGS 512 KB cartridge

25 800/XL/XE 1024 XEGS 1 MB cartridge

26 800/XL/XE 16 MegaCart 16 KB cartridge

27 800/XL/XE 32 MegaCart 32 KB cartridge

28 800/XL/XE 64 MegaCart 64 KB cartridge

29 800/XL/XE 128 MegaCart 128 KB cartridge

30 800/XL/XE 256 MegaCart 256 KB cartridge

31 800/XL/XE 512 MegaCart 512 KB cartridge

32 800/XL/XE 1024 MegaCart 1 MB cartridge

33 800/XL/XE 32 Switchable XEGS 32 KB cartridge

34 800/XL/XE 64 Switchable XEGS 64 KB cartridge

35 800/XL/XE 128 Switchable XEGS 128 KB cartridge

36 800/XL/XE 256 Switchable XEGS 256 KB cartridge

37 800/XL/XE 512 Switchable XEGS 512 KB cartridge

38 800/XL/XE 1024 Switchable XEGS 1 MB cartridge

39 800/XL/XE 8 Phoenix 8 KB cartridge

40 800/XL/XE 16 Blizzard 16 KB cartridge

41 800/XL/XE 128 Atarimax 128 KB flash cartridge

42 800/XL/XE 1024 Atarimax 1024 KB flash cartridge

There are two formats of cartridge images: raw and CART.

 

The raw dump contains no information of how to handle the cartridge, thus you are prompted to choose its type each time you attach a raw cartridge. There is no special extension for raw cartridges, but most common are ROM and BIN (recommended is ROM).

 

The CART file (with CAR extension) contains information about cartridge type, so it can be attached without prompting you for the type. Additionally the CART format can be identified, because it contains the ‘CART’ signature at the beginning of the file.

 

Details of cartridge types

 

Type 1: Standard 8 KB cartridge

Standard 8 KB cartridge, that occupies 8 KB of address space between $A000 and $BFFF.

 

Type 2: Standard 16 KB cartridge

Standard 16 KB cartridge, that occupies 16 KB of address space between $8000 and $BFFF.

 

Type 3: OSS '034M' 16 KB cartridge

There are two types of OSS cartridges. Both are 16 KB and occupy 8 KB of address space between $A000 and $BFFF. The cartridge memory is divided into 4 banks, 4 KB each. One bank ('main') is always mapped to $B000-$BFFF. The other 3 banks are mapped to $A000-$AFFF. The current bank is selected by accessing a byte in $D500-$D5FF. Only 4 lowest bits of address are significant.

 

The '034M' scheme is the more complicated one. The main bank is D. An access to:

 

· $D5x0 or $D5x1 selects bank A.

 

· $D5x3 or $D5x7 selects bank B.

 

· $D5x4 or $D5x5 selects bank C.

 

· $D5x2 or $D5x6 is not useful. It disables ROM (there're $FF bytes in $A000-$AFFF).

 

· $D5x8-$D5xF disables whole cartridge (enables computer's memory in address space between $A000 and $BFFF).

 

Type 4: Standard 32 KB 5200 cartridge

 

Standard 32 KB cartridge for Atari 5200, that occupies 32 KB of address space between $4000 and $BFFF.

 

Type 5: DB 32 KB cartridge

 

A 32 KB bank-switched cartridge. There are 4 banks. Bank D is mapped to $A000-$BFFF. Bank in $8000-$9FFF is selected by an access to $D500-$D5FF. Two lowest bits of address select bank A, B, C or D.

 

Type 6: Two chip 16 KB 5200 cartridge

 

In Atari 5200 there's 32 KB of address space reserved for the cartridge ($4000-$BFFF). A two chip 16 KB cartridge is mapped that way:

 

· First 8 KB are mapped into lower 16 KB. Since an address line is not connected, $4000-$5FFF and $6000-$7FFF contain same data, which is first half of the cartridge image.

 

· Similarly, second 8 KB are mapped into upper 16 KB.

 

Type 7: Bounty Bob Strikes Back 40 KB 5200 cartridge

 

The cartridge with "Bounty Bob Strikes Back" game uses very strange bank switching method:

 

· Four 4 KB banks (A,B,C,D) are mapped into $4000-$4FFF. An access to $4FF6 selects bank A, $4FF7 - bank B, $4FF8 - bank C, $4FF9 - bank D.

 

· Four 4 KB banks (E,F,G,H) are mapped into $5000-$5FFF. An access to $5FF6 selects bank E, $5FF7 - bank F, $5FF8 - bank G, $5FF9 - bank H.

 

· The remaining 8 KB is mapped to upper 16 KB of cartridge address space in Atari 5200. That is, $8000-$9FFF and $A000-$BFFF contain same data.

 

Type 8: 64 KB Williams cartridge

 

The cartridge has 8 banks mapped to $A000-$BFFF. An access to $D500 selects bank A, $D501 - bank B, etc. An access to $D508-$D50F disables the cartridge.

 

Type 9: Express 64 KB cartridge

 

The cartridge has 8 banks mapped to $A000-$BFFF. An access to $D577 selects bank A, $D576 - bank B, etc. An access to $D578-$D57F disables the cartridge.

 

Type 10: Diamond 64 KB cartridge

 

The cartridge has 8 banks mapped to $A000-$BFFF. An access to $D5D7 selects bank A, $D5D6 - bank B, etc. An access to $D5D8-$D5DF disables the cartridge.

 

Type 11: SpartaDOS X 64 KB cartridge

 

The cartridge has 8 banks mapped to $A000-$BFFF. An access to $D5E7 selects bank A, $D5E6 - bank B, etc. An access to $D5E8-$D5EF disables the cartridge.

 

Type 12: XEGS 32 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 4 banks, 8 KB each. Bank D (the last one) is always mapped to $A000-$BFFF. Two lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 13: XEGS 64 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 8 banks, 8 KB each. Bank H (the last one) is always mapped to $A000-$BFFF. Three lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 14: XEGS 128 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 16 banks, 8 KB each. Bank P (the last one) is always mapped to $A000-$BFFF. Four lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 15: OSS 'M091' 16 KB cartridge

 

This is the simpler one of OSS schemes. It uses only A0 and A3 address lines:

 

· A3=0, A0=0 - $A000-$AFFF: bank B, $B000-$BFFF: bank A

 

· A3=0, A0=1 - $A000-$AFFF: bank D, $B000-$BFFF: bank A

 

· A3=1, A0=0 - disable cartridge

 

· A3=1, A0=1 - $A000-$AFFF: bank C, $B000-$BFFF: bank A

 

Type 16: One chip 16 KB 5200 cartridge

 

16 KB cartridge for Atari 5200, that occupies 16 KB of address space between $8000 and $BFFF.

 

Type 17: Atrax 128 KB cartridge

 

This bank-switched cartridge occupies 8 KB of address space between $A000 and $BFFF. The cartridge memory is divided into 16 banks, 8 KB each. If a byte written to $D500-$D5FF has highest bit set, the cartridge is disabled. Otherwise four lowest bits select the bank mapped to $A000-$BFFF.

 

Type 18: Bounty Bob Strikes Back 40 KB cartridge

 

The cartridge with "Bounty Bob Strikes Back" game uses very strange bank switching method:

 

· Four 4 KB banks (A,B,C,D) are mapped into $8000-$8FFF. An access to $8FF6 selects bank A, $8FF7 - bank B, $8FF8 - bank C, $8FF9 - bank D.

 

· Four 4 KB banks (E,F,G,H) are mapped into $9000-$9FFF. An access to $9FF6 selects bank E, $9FF7 - bank F, $9FF8 - bank G, $9FF9 - bank H.

 

· The remaining 8 KB is mapped to $A000-$BFFF.

 

Type 19: Standard 8 KB 5200 cartridge

 

Standard 8 KB cartridge for Atari 5200, mapped into $8000-$9FFF and $A000-$BFFF.

 

Type 20: Standard 4 KB 5200 cartridge

 

Standard 4 KB cartridge for Atari 5200, mapped into $8000-$8FFF, $9000-$9FFF, $A000-$AFFF and $B000-$BFFF.

 

Type 21: Right slot 8 KB cartridge

 

8 KB cartridge for Atari 800, mapped into $8000-$9FFF. Atari 800 was the only 8-bit Atari with a Right Cartridge slot, in addition to the Left Cartridge slot as present on all 8-bit Ataris.

 

Type 22: 32 KB Williams cartridge

 

The cartridge has 4 banks mapped to $A000-$BFFF. An access to $D500 selects bank A, $D501 - bank B, etc. An access to $D508-$D50F disables the cartridge.

 

Type 23: XEGS 256 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 32 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Five lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 24: XEGS 512 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 64 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Six lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 25: XEGS 1 MB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 128 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Seven lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF.

 

Type 26: MegaCart 16 KB cartridge

 

A 16 KB cartridge, that occupies 16 KB of address space between $8000 and $BFFF, and can be disabled by writing a byte with bit 7 set to $D500-$D5FF.

 

Type 27: MegaCart 32 KB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Bit 0 selects one of two available banks, bit 7 disables the cartridge.

 

Type 28: MegaCart 64 KB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Bits 0 and 1 select one of four available banks, bit 7 disables the cartridge.

 

Type 29: MegaCart 128 KB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Bits 0,1,2 select one of 8 available banks, bit 7 disables the cartridge.

 

Type 30: MegaCart 256 KB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Four lowest bits select one of 16 available banks, bit 7 disables the cartridge.

 

Type 31: MegaCart 512 KB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Five lowest bits select one of 32 available banks, bit 7 disables the cartridge.

 

Type 32: MegaCart 1 MB cartridge

 

A bank-switched cartridge that occupies 16 KB of address space between $8000 and $BFFF. It is controlled by a byte written to $D500-$D5FF. Six lowest bits select one of 64 available banks, bit 7 disables the cartridge.

 

Type 33: Switchable XEGS 32 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 4 banks, 8 KB each. Bank D (the last one) is always mapped to $A000-$BFFF. Two lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 34: Switchable XEGS 64 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 8 banks, 8 KB each. Bank H (the last one) is always mapped to $A000-$BFFF. Three lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 35: Switchable XEGS 128 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 16 banks, 8 KB each. Bank P (the last one) is always mapped to $A000-$BFFF. Four lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 36: Switchable XEGS 256 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 32 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Five lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 37: Switchable XEGS 512 KB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 64 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Six lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 38: Switchable XEGS 1 MB cartridge

 

This bank-switched cartridge occupies 16 KB of address space between $8000 and $BFFF. The cartridge memory is divided into 128 banks, 8 KB each. The last bank is always mapped to $A000-$BFFF. Seven lowest bits of a byte written to $D500-$D5FF select the bank mapped to $8000-$BFFF, bit 7 disables the cartridge.

 

Type 39: Phoenix 8 KB cartridge

 

An 8 KB cartridge, that occupies 8 KB of address space between $A000 and $BFFF, and can be disabled by an access to $D500-$D5FF.

 

Type 40: Blizzard 16 KB cartridge

 

A 16 KB cartridge, that occupies 16 KB of address space between $8000 and $BFFF, and can be disabled by an access to $D500-$D5FF.

 

Type 41: Atarimax 128 KB flash cartridge

 

This bank-switched cartridge occupies 8 KB of address space between $A000 and $BFFF. The cartridge memory is divided into 16 banks, 8 KB each. The 4 lowest bits of the address written to $D500-$D50F select the bank mapped to $A000-$BFFF. Writing to $D510-$D51F disables the cartridge and any write to $D520-$D5FF is ignored.

 

Type 42: Atarimax 1024 KB flash cartridge

 

This bank-switched cartridge occupies 8 KB of address space between $A000 and $BFFF. The cartridge memory is divided into 128 banks, 8 KB each. The seven lowest bits of the address written to $D500-$D57F select the bank mapped to $A000-$BFFF, bit 7 disables the cartridge.

 

Usage

 

Use File/Attach cartridge (Alt+C) to run the program on a cartridge.

 

As soon as you manage to run a raw cartridge image, you can convert it to the CART format for easier use (

Misc/Convert/ROM to CART).

 

Remember to detach a cartridge (File/Detach cartridge or the ROM Image Selections dialog box) before using software from disk images. Most Atari software does not work if a cartridge is installed in computer.

 

See also

 

ROM Image Selections dialog box

 

Supported file formats

Edited by Sheddy
Link to comment
Share on other sites

I'm trying to cut a 32K program into 2 16K banks to run on the A8 platform. I'm afraid I am at a total loss of how to set up and then to tell the 6502 ASM program which of two 16K banks to point to! Here's some questions:

 

 

 

.ORG $4000	; beginning of the 1st 16 Bank, right? 
lda #$00 
sta $20
sta $30 
jsr Bank-1-Do-Stuff	 ;still running in 1st 16K bank....
;  
jsr Bank-2-subroutine
; 
...
.ORG ????			 ; how do you use ORG to setup the 2 banks? 
Bank-2-subroutine
lda ...
rts					  ;end of bank 2 ROM

 

Question1: Before the jsr Bank-2-subroutine, don't I need to access some register/memory location? Literally what statement(s) go before and after the bank switch jsr? Is it user-defined?

It depends on the banking scheme for the cartridge. Which type of cart will you be using, normal XE game system type that Beef Drop and Castle Crisis use (using boards Bryan created)>? You will need to do the bank switch before the JSR. The code that is doing the bank switch and JSR must be in the part of the cart memory that is fixed and will not go away (it will bank switch immediately and then the JSR instruction will be gone). Also, be sure you put the bank to whatever you need to after the JSR. You can also always put little stubs in the main non-switching part that do the bank switch, a JSR, restore the bank and return. I cheated with beef drop though since all I do is have a little routine at startup that copies 16K of the code in the extra banks below the cart itself, then I never have to worry about bankswitching in game. This method will require the user to have 32K of RAM instead of 16 though, but it is really fast to implement.

 

 

Question2: How do you use .ORG to arrange the 2 16K banks? I am only familiar with a normal 32K ROM size , on the Atari 5200, which is $4000-$BFFF.

This would be dependent on the assembler. Most assemblers have ways of specifying where in the image will go separate from what address the code will be run from. With the CC65 assembler you handle all of the through linker config files. With Atari Macro Assembler you have ORG and LOC?. I am not really familiar with other assemblers but I am sure someone else will chime in.

Any help?
Link to comment
Share on other sites

For XE style banking the address to store to is $D500. Here is some snipped out code from beef drop. This code, and the startup code needs to be in the fixed bank (last bank). Call CartCopyData shortly after startup. Doing something like this will require 32K ram and limit your program to 32K ROM but all you need to add something like this and assemble the whole program to be ORGd at $4000

 

zptr1 = $80
zptr2 = $82

CopyCartData:
lda #$FC	 ;select first bank
	sta $D500
	lda #>$4000
	jsr CopyOneBank
	lda #$FD	 ;select second bank
	sta $D500
	lda #>$6000
	jsr CopyOneBank
	lda #$FE	;select main bank
	sta $D500
rts
CopyOneBank:
	sta zptr2+1
	lda #0
	sta zptr2
	lda #<$8000
	sta zptr1
	lda #>$8000
	sta zptr1+1
	ldx #>$2000
	ldy #0
@ccd:   lda (zptr1),y
	sta (zptr2),y
	iny
	bne @ccd
	inc zptr1+1
	inc zptr2+1
	dex
	bne @ccd
			rts

Edited by kenfused
Link to comment
Share on other sites

When you say "XE style banking" -- is that what Beef Drop and Castle Crisis used?. In other words, you take your 32K which I assume you made on 5200 first, and copy it all to 32K of RAM and run it from there? Bryan mentioned this method a while ago to me, I cannot seem to locate his email anymore, but I thought that it required Bryan's special PCB's -- is that true, or not?

Link to comment
Share on other sites

To simplify your programming, it would probably be best to have jump tables for your commonly called routines.

 

If the cart is of the type which has one fixed bank and one switchable, then simply put it in the fixed bank.

 

If it's a cart with only one bank which is switched, then it would be best to have it copied to RAM.

Link to comment
Share on other sites

When you say "XE style banking" -- is that what Beef Drop and Castle Crisis used?. In other words, you take your 32K which I assume you made on 5200 first, and copy it all to 32K of RAM and run it from there? Bryan mentioned this method a while ago to me, I cannot seem to locate his email anymore, but I thought that it required Bryan's special PCB's -- is that true, or not?

Yes, Beef Drop uses the board Bryan created for Castle Crisis. I think it is the same as some XE Game System cartridges (it will run in Atari800WinPlus if you pick XEGS option).

 

My source code has some conditional compilation logic so I can build both versions from the same source code (different values for equates for POKEY, GTIA, and some of the OS vectors; different joystick routines, different text on screen, etc).

Edited by kenfused
Link to comment
Share on other sites

With an A8 XE cartridge, you have 2 banks: 8000-9FFF & A000-BFFF. They are both 8K wide. The 8000-9FFF area can be changed, but not the other half. If you're simply going to require 32K of RAM and copy out the contents, then it's easy. Place all your set-up code in the fixed bank, and add a copy routine to copy 2 of the 8K banks into RAM from 4000-7FFF. Then select the 3rd bank for 8000-9FFF, and the last bank is fixed at A000-BFFF. Viola! 32K ready to go and you never switch another bank.

 

If you want to support 16K machines, the idea is that you put certain things in the fixed bank so they're always there and then switch the other bank around as you use different routines. Castle Crisis manages everything from the DLI handler. On certain lines it switches banks and runs specific routines, then switches back.

 

The #IFNDEF a5200 lines show you where the A8 version has to do a bank-switch that the 5200 version does not.

 

;Warlords XL NMI code...
;2003 Bryan Edewaard

;All interrupts are DLI (NMI) type and therefore they all enter here.

dli

;Stage 1
;This part is 12 cycles
;(After all, we are doing 48 bytes/line with all DMA on.)

pha	   ;(3) Push A
txa	   ;A=X

sta WSYNC   ;(4) Wait until end of line

;Stage 2: End of line
;The idea here is to make Antic generate 7-line characters by
;fudging VSCROL between lines.
;VSCROL must not be changed until 2 more CPU cycles have passed or
;Antic gets confused.


ldx #01	   ;new VSCROL value (and our 2 cycles)
stx VSCROL   ;Cut off the top line of this row

;Set up the new Character Set

ldx tmpchr   ;Get next chset value
stx CHBASE   ;Set up new character set

pha	   ;Push X
txa	   ;A = tmpchr

#IFDEF showdli
sta COLBK
#ENDIF

#IFDEF tracking
ldx #$80
stx test
#ENDIF

;Set up 2nd VSCROL value

ldx #06	   ;Change VSCROL after the new line starts
stx VSCROL   ;(Chop off the bottom line of the next row)

;Look for special bits in the CHBASE value (those ignored by the hardware)

lsr a	   ;tmpchr bit 0 -> C
bcs dli_mid   ;C=1 means mid screen

;On most DLI's we end up here.
;Set up for next DLI

dli_exit
ldx dlicount   ;What DLI is this?
bne dli_exit2	;Unless last one (VBL), exit
jmp dli_last   ;End of screen

;We end up here if not the last DLI
dli_exit2

lda chbastab,x   ;Get the next CHBASE value
sta tmpchr   ;Save it

dec dlicount   ;Update counter

#IFDEF showdli
lda #BLACK
sta COLBK
#ENDIF

pla	   ;Pull X
tax

pla	   ;Pull A

rti	   ;Return from DLI

;**********************************************
;Mid-screen duties
;If CHBASE bit 0 is set, we test bit 1 as well.
;**********************************************
dli_mid	
lsr a	   ;tmpchr bit 1 -> C
bcs dli_mid2

;Carry clear (tmpchr b1=0) means perform mid-screen duties

cld

lda hscroll   ;Move hscroll into HSCROL
sta HSCROL
lda vscroll   ;Move vscroll into VSCROL
sta VSCROL

;New PF colors

lda c_dragyel   ;Change the color palette around
sta COLPF1
lda c_white   ;Char bit 7 now selects White...
sta COLPF2
lda c_dragred   ;or red (text or dragon).
sta COLPF3

;Save Y on stack

tya	   ;Copy Y to A
pha	   ;Save Y on stack

;*******************************
;Perform Middle-Of-Screen updates

#IFNDEF a5200
;Put us in the bank that has these routines
lda #BANK0
sta BANKSW
#ENDIF

;Draw Scores
jsr drawscore

;Draw Explosions
jsr explode

#IFNDEF a5200
;Put us back in the normal bank
lda #BANK2
sta BANKSW
#ENDIF


;*******************************

;Pull Y off stack

pla	   ;Get Y off stack
tay	   ;Copy A to Y

jmp dli_exit

;Carry set (tmpchr b1=1) means set up bottom half of screen.
dli_mid2

;Change the castle colors
lda c_white
sta COLPF1
lda qcolor0
sta COLPF2
lda qcolor1
sta COLPF3
lda #$02
sta HSCROL   ;Make sure HSCROL is right

;Check to see if attract graphics are on the screen

ldx hscopy
bpl dli_exit   ;If hscopy b7 not set, skip this part

lda c_white   ;c_white
sta COLPM3

txa
and #$40   ;Which high score is displayed?
bne dli_1pcolor

;Team shields
ldx twinner1
lda qcolor0,x
sta COLPM1

ldx twinner2
lda qcolor0,x
sta COLPM2

lda #122
sta HPOSP1
sta HPOSP3

lda #128
sta HPOSP2

lda #129
sta HPOSM3
lda #$40
sta SIZEM

jmp dli_exit

;dli_scoltab
;.db	PURPLE, BLUE, GREEN, RED

dli_1pcolor

ldx pwinner
lda qcolor0,x
sta COLPM1

lda #BLACK
sta COLPM2

lda #125
sta HPOSP1
sta HPOSP3
sta HPOSP2

jmp dli_exit

;**********************************************
;End-of-screen (VBLANK) duties
;**********************************************

dli_last

;Last DLI!
;Entering VBlank code. Set up for next screen	

cld

lda #13	   ;Set up new DLI counter
sta dlicount

;Setup PF colors for next screen

lda qcolor2
sta COLPF2
lda qcolor3
sta COLPF3
lda c_orange
sta COLPM0
sta COLPM1
sta COLPM2
sta COLPM3
lda c_gray
sta COLPF0
lda c_white
sta COLPF1

lda #00
sta SIZEM


;1st, make sure the previous iteration completed

;	lda loopfl   ;Get the Loop Flag
;	beq dli_flagok   ;Did we finish?
;.db 02
;	jmp dli_vblend   ;Do nothing this iteration.
;	jmp begin

dli_flagok
inc loopfl   ;Set loopfl

lda gamemode
cmp #07	   ;Pause?
beq dli_timend

inc time1   ;Increment timer 1
bne dli_timend   ;Did we hit 0?
inc time2   ;Increment timer 2
bpl dli_timend   ;Less than $80?
lda #$80   ;Stop timer 2 at $80
sta time2
dli_timend

;Don't run the game loop if we're flushing the queue.

lda flush   ;Are we flushing the background tasks?
beq dli_flushoff;nope.. skip this
lda gqix   ;Get the game index
cmp bqix   ;Has the background index caught up?
beq dli_flushok   ;yes. Continue
jmp dli_vblend   ;no. Return to the background task loop

dli_flushok
lda #0
sta flush   ;Turn off FLUSH

dli_flushoff	

;Save Y on stack

tya	   ;Copy Y to A
pha	   ;Save Y on stack

;Choose the fast or slow DLIST.
ldy #LSB(dlist1);Enable the mid-section

lda gamemode   ;Are we in a game?
bpl dli_dlist1   ;No, keep this setting			

lda dragphase   ;Yes, in a game... is the dragon on?
bmi dli_dlist1   ;Yes, keep this setting

ldy #LSB(dlist2);Game with no dragon, turn off the middle
dli_dlist1
sty DLISTL

;Reset the scroll variables
lda #$07
sta vscroll   ;If nothing else modifies this, use 7
lda #$02
sta hscroll

;*******************************
;Perform Bottom-Of-Screen updates (VBlank)

#IFNDEF a5200
;Put us in the bank that has these routines
lda #BANK0
sta BANKSW
#ENDIF

;Inputs Update (debug: purple)
jsr inputs

#IFNDEF a5200
;Put us in the bank that has these routines
lda #BANK1
sta BANKSW
#ENDIF

;Draw Players - includes cleanup (debug: aqua)
jsr players

;Draw Shields (debug: blue)
jsr shields

#IFNDEF a5200
;Put us in the bank that has these routines
lda #BANK0
sta BANKSW
#ENDIF

;Sound Updates
jsr sounds

;Look for a change in Scores
jsr scorecheck

;Dragon Update
jsr dragon

#IFNDEF a5200
;Put us back in the normal bank
lda #BANK2
sta BANKSW
#ENDIF

#IFDEF showdli
lda #BLACK
sta COLBK
#ENDIF

;Game Update
jsr game

;*******************************

;Pull Y off the stack

pla	   ;Pull Y
tay

;On the way out...

#IFDEF cputime
lda #BLACK
sta COLBK
#ENDIF

dli_vblend

pla	   ;Pull X
tax

pla	   ;Pull A
dec loopfl   ;Set loopfl back to 0

rti	   ;Return from VBlank activities

;Character set address table
;Low 2 bits are used as flags (so &FC).
chbastab
.db	$08, $08, $2C, $28, $24, $20, $1C, $1F, $A1, $18, $18, $14, $10, $0C


;

Link to comment
Share on other sites

Two things I'd like to add...

 

1) I just noticed that I commented out a small section of code in CC and never put it back. It was designed to make the game stop for one refresh if the game update logic ever took more than 1 screen to finish. Fortunately, in all my testing it always maintained 60fps and I've never had that happen. The worst case scenario is when you have 3 AI players and a lot of fireballs for them to track. The db 02 was in there to make Atari800Win crash if it ever happened (invalid opcode). Maybe I took it out intentionally... can't remember.

 

2) Some pseudo-code for the bankswitching:

 

A 32K XE cartridge will look like this:

 

bank 0 = EPROM 0000-1FFF

bank 1 = EPROM 2000-3FFF

bank 2 = EPROM 4000-5FFF

bank 3 = EPROM 6000-7FFF

 

You won't need to select bank 3 because it's fixed at A000-BFFF. All banks will appear at 8000-9FFF if selected. You'll probably want to set the Diagnostic Cart flag, so the OS jumps right into the game rather than initializing (I've written a version of the 5200's OS that can be compiled in if you need the same features). Your initializing code should be placed in the last 8K of the EPROM and should:

 

Set bank 0

Copy 8000-9FFF to 4000-5FFF

Set bank 1

Copy 8000-9FFF to 6000-7FFF

Set bank 2 (so now 8000-9FFF is bank 2, and A000-BFFF is bank 3)

 

Then you can jump to anywhere you want.

 

Note, if you don't set the cartridge to diagnostic, then the OS will look for an 8K cartridge in the 8000-9FFF region and it becomes important for the last few bytes of each bank to be formatted properly (because you never know which one is initially selected at power-up). If you set the diagnostic flag, you don't have this problem.

 

If you decide to bank it in real time for a 16K system remember that code in a bank can access anything in the same bank or anything in the fixed bank, but nothing else. Also, you have to remember that if Antic is reading a character set from the cartridge, you'll get garbage if you switch it out during active parts of the screen (I try to put character sets and interrupt code in the fixed bank). Also, the code in the first three 8K banks will have to be assembled with an $8000 .org since that's where it runs from (tricky!).

 

-Bry

Edited by Bryan
Link to comment
Share on other sites

  • 4 years later...

The 5200 64k method uses a poke to $bff8 for bank 1 and $bff9 for bank 2. This switches the whole 32k rom out. I'm trying to find a method to switch to a second bank thats only purpose is to store level data, copy that data to ram then return to the first bank. any ideas?

Link to comment
Share on other sites

So you're making your own cart ?

 

If that's the case then you can employ any method you want. You just have to build the logic to handle it.

 

Switching the Rom out completely on the 5200 seems weird - normally there's nothing under there so why would it be needed? Unless the hardware was designed to allow a Static Ram chip to be included on the board.

Link to comment
Share on other sites

The 5200 64k method uses a poke to $bff8 for bank 1 and $bff9 for bank 2. This switches the whole 32k rom out. I'm trying to find a method to switch to a second bank thats only purpose is to store level data, copy that data to ram then return to the first bank. any ideas?

 

Should be pretty easy:

 

Call code in low RAM (that you copied there previously from your bank1), that:

 

1. selects the second cartridge bank

2. copies the level data you want into RAM (don't overwrite your level copy code!)

3. select the first cartridge bank again

4. jump back into code in the cartridge ROM

Link to comment
Share on other sites

I need an emulator that I can test on. The $bff8/$bff9 method is what is supported by jum and dan boris's 5200 emulator. It works when the two .bins are merged, but they have to be extremely similar which seems to negate the purpose. Your ram solution would work but I need something I can test it with on the pc. Right now I just get a blank screen. I can send some roms and info if someone can help me out. john@meanhamster.com

Link to comment
Share on other sites

  • 10 years later...

I'm a beginner and a bit confused on this topic. 😐
Could I get step by step information on how to configure the code to receive, for example, a CART TYPE 23 - 800/XL/XE 256 XEGS 256 KB cartridge?
The example shows how to define higher Banks of this Cartridge and how to switch the Bank.

 

Sample code 16KB - I would like to make a larger one, e.g. 128/256KB:

 

    OPT O+ H- F+ C- ?+

CART_CRC = $001F70E7
CART_TYPE = 2							; Standard 16 KB cartridge.
; CART_TYPE = 23						; 800/XL/XE 256 XEGS 256 KB cartridge.

    .BYTE 'CART'
    .BYTE [CART_TYPE >> 24] & $FF
    .BYTE [CART_TYPE >> 16] & $FF
    .BYTE [CART_TYPE >> 8] & $FF
    .BYTE [CART_TYPE >> 0] & $FF
    .BYTE [CART_CRC >> 24] & $FF
    .BYTE [CART_CRC >> 16] & $FF
    .BYTE [CART_CRC >> 8] & $FF
    .BYTE [CART_CRC >> 0] & $FF
    .BYTE $00
    .BYTE $00
    .BYTE $00
    .BYTE $00

;#########################

SDMCTL = $022F
SDLSTL = $0230                ; Display List starting address.
CHBAS  = $02f4                ; CHaRacter Base Register.
COLOR0 = $02c4                ; Color for %01.
COLOR1 = $02c5                ; Color for %10.
COLOR2 = $02c6                ; Color for %11 (Normal).
COLOR3 = $02c7                ; Color for %11 (Inverse).
COLOR4 = $02c8                ; Color for %00 (BGR).

Charset = $3C00                ; CHaRacter Set.
Screen = $4000                ; Screen Buffer.
Blank8 = $70                ; 8 Blank Lines.
LMS = $40                ; Load Memory Scan.
JVB = $41                ; Jump while VBlank.

Antic2 = 2                ; Antic mode 2.
Antic5 = 5                ; Antic mode 5.

Gray_Medium = $06
Gray_Light = $0A
Green = $c2
Brown = $22
Black = $00

;#########################

    ORG $8000

;#########################

Start:

    LDA #%00100001
    STA SDMCTL

    MWA #DList SDLSTL

    MVA #>Charset CHBAS

    LDX #$00

Loop:

    MVA Chars,x Charset+8,x            ; Set-Up CHaRacter Set.
    INX
    CPX #16
    BNE Loop
                        ; Change Colors.
    mva #Gray_Medium COLOR0            ; %01.
    mva #Gray_Light COLOR1            ; %10.
    mva #green COLOR2            ; %11.
    mva #brown COLOR3            ; %11 (Inverse).
    mva #black COLOR4            ; %00.

	LDY #$00

Loop2:

	MVA Scene,y Screen,y
	MVA Scene+32,y Screen+32,y
	MVA Scene+64,y Screen+64,y
	MVA Scene+96,y Screen+96,y
	MVA Scene+128,y Screen+128,y
	MVA Scene+160,y Screen+160,y
	MVA Scene+192,y Screen+192,y
	MVA Scene+224,y Screen+224,y
	MVA Scene+256,y Screen+256,y
	MVA Scene+288,y Screen+288,y
	MVA Scene+320,y Screen+320,y
	MVA Scene+352,y Screen+352,y

	INY
	CPY #32
	BNE Loop2

    JMP *                    ; Forever Loop.

DList:                

    .BYTE Blank8, Blank8, Blank8
    .BYTE Antic5 + LMS, <Screen, >Screen
    .BYTE Antic5, Antic5, Antic5, Antic5, Antic5, Antic5
    .BYTE Antic5, Antic5, Antic5, Antic5, Antic5
    .BYTE JVB, <DList, >DList

Scene:

	.BYTE 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2
	.BYTE 1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,1,2
	.BYTE 1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2
	.BYTE 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2

Chars:

    .BYTE %10101010
    .BYTE %10100101
    .BYTE %01010101
    .BYTE %00000000
    .BYTE %01010010
    .BYTE %01010010
    .BYTE %01010010
    .BYTE %00000000
    
    .BYTE %01001010
    .BYTE %01001010
    .BYTE %00001001
    .BYTE %00000000
    .BYTE %10101001
    .BYTE %10010101
    .BYTE %01010101
    .BYTE %00000000

    ORG $BFFA

    .WORD $FFFF
    .BYTE $00
    .BYTE %00000000
    .WORD Start

	end

 

main.car

Link to comment
Share on other sites

On 3/30/2012 at 7:27 PM, ziggystar said:

I need an emulator that I can test on. The $bff8/$bff9 method is what is supported by jum and dan boris's 5200 emulator. It works when the two .bins are merged, but they have to be extremely similar which seems to negate the purpose. Your ram solution would work but I need something I can test it with on the pc. Right now I just get a blank screen. I can send some roms and info if someone can help me out. john@meanhamster.com

ALTIRRA!!!!!!!!!!!!!

Altirra, an 8-bit Atari computer emulator - virtualdub.org

Link to comment
Share on other sites

  • 8 months later...
1 hour ago, rcamp48 said:

How do you switch banks witjhin Altirra?

Exactly the same way you do on real hardware, just depends on which memory emulation you are using.

 

I generally use U1M with SDX which is the same config as my real hardware, so PortB bank switching.

 

Link to comment
Share on other sites

In Altirra, at least for PORTB banking, I've been manually changing the banks for debugging purposes.  So, if I want to inspect a bank, I set Altirra in debugging mode and have the memory window open.  Then, I can go to $D301 and type in a new bank byte.  The memory will change in the $4000-$7FFF range and display the bank.

Link to comment
Share on other sites

3 hours ago, reifsnyderb said:

In Altirra, at least for PORTB banking, I've been manually changing the banks for debugging purposes.  So, if I want to inspect a bank, I set Altirra in debugging mode and have the memory window open.  Then, I can go to $D301 and type in a new bank byte.  The memory will change in the $4000-$7FFF range and display the bank.

You can just use the syntax $xx'yyyy where xx is the PORTB value and yyyy is the window address in $4000-7FFF, e.g. $8F'4000. For some cartridge types, the analogous syntax t:$xx'yyyy also works for $xx being the banking data or address value and $yyyy being the window address in $8000-BFFF.

 

  • Like 3
Link to comment
Share on other sites

4 hours ago, phaeron said:

You can just use the syntax $xx'yyyy where xx is the PORTB value and yyyy is the window address in $4000-7FFF, e.g. $8F'4000. For some cartridge types, the analogous syntax t:$xx'yyyy also works for $xx being the banking data or address value and $yyyy being the window address in $8000-BFFF.

 

OK what I was looing to do was use bank switching in Basic XE for ForemXE Pro, is all of the carts memory already being used? 

Russ

 

Link to comment
Share on other sites

BASIC XE handles bank switching for you but only in the normal 130 XE range, Please refer to the BASIC XE manual and forum threads that discuss BASIC XE memory management. It's not really what this thread is about or discussing. You will find it better to keep within those other threads as the scope is a bit different.

Edited by _The Doctor__
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...