C64 / ATARI - Cartridge Memory Mapper Bank Switching

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
Post Reply
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

Does anyone here have experience programming C64 / ATARI 8-Bit? I would like to embrace a larger type of cartridge than the standard, maximum 16KB.

For the C64, we have CART LO $8000-9FFF and CART HI $A000-BFFF / $E000-FFFF. Similarly in ATARI $8000-BFFF / $A000-BFFF.

What are the popular C64/ATARI Mappers to get e.g. 128/256KB CARTRIDGE size? And how BANK switching works in this case.

I use MADS in ATARI and 64TASS in C64.

On C64 "OCEAN TYPE 1" is interesting - Up to 512KB (64x8KB BANK). The question is how to define higher BANKS in 64TASS to make everything work properly:
https://codebase64.org/doku.php?id=base ... ean_type_1

Trying to define e.g. additional two Bank $8000-BFFF compilation still gives me a 16KB ROM instead of 32KB. I can't find anywhere how to define all this in 64TASS :/

Code: Select all

;------------------

* = $8000				; $8000-9FFF.

	; Code

* = $9FFF
	.BYTE 0

;------------------

* = $8000				; $8000-9FFF (EXTENDED BANK).

	; Code

* = $9FFF
	.BYTE 0

;------------------

* = $8000				; $8000-9FFF (EXTENDED BANK).

	; Code

* = $9FFF
	.BYTE 0

;------------------

* = $A000				; $A000-BFFF.

	; Code

* = $BFFF
	.BYTE 0

Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

well you hit to jackpot, as I'm a well known C64 dev who uses 64tass ;D

Ocean cart is great but these days go GMod2 ( 512K of 8K banks ) or EasyFlash ( 1M of 16K banks ) as your targets. GMod2 is basically Ocean compatible but also has EEPROM save file, while EasyFlash lets you erase and flash a bank to save.

to make a crt for GMod2 or Ocean as they have the same layout you do this.

Code: Select all

* = $0000
.logical $8000
; bank 0 here 
.cwarn * >= $A000, "bank overflow"
.here
.align 8192 ; make sure you fill the whole 8K 

.logical $8000
; bank 1 here 
.cwarn * >= $A000, "bank overflow"
.here
.align 8192 ; make sure you fill the whole 8K 

.logical $8000
; bank 2 here 
.cwarn * >= $A000, "bank overflow"
.here
.align 8192 ; make sure you fill the whole 8K 

until you have all the banks you want, probably best to put your code into Sections, and then you can [tt].dsection bank00[/tt] to include the code. You could also just [tt].include[/tt] if you want to put each bank in its own file. 
 
you need to assemble with the -b -X
b tells it to make a binary output which skips the PRG header. -X CAPITAL X not small x, tells it to expand the memory map size to long, 24bit address size so it can make an output file that is upto 16MB. Note the PC is still only 16bits, so you can't do * = $38000 as the PC is still locked to 16 bits.

that will give you a binary file of which you can use the VICE Cartconv to make into a valid CRT file.
for Ocean you want cartconv -p -t ocean -i "your.bin" -o "your.crt" for gmod2 cartconv -p -t gmod2 -i "your.bin" -o "your.crt"

EF3 uses the same layout but it is 8K Lo 8K Hi, next bank. so as above just make the align 16,384 and the warn being >= $c000
however the EF3 boots into Ulitmax mode so the first upper 8K of bank 0 starts to $E000 not $A000 which you will need to handle for the RESET vector portion at least.
For code example and Cart boot examples see https://codebase64.org/doku.php?id=base:thirdparty

Atari 8bit can't help you, I'm a Commodore man.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

Thanks. But I still need help to figure it out...
Ocean in 512KB mode (Terminator2) only uses $8000-9FFF and 64 Banks of 8KB ? Space A000-BFFF is not used at all?
However, in the 256KB mode, Ocean has the ability to switch $8000 and $A000 separately, but max 16 8KB Banks per "Slot"?


If I wanted to create Ocean 256KB, Bank $A000 would be defined as follows: ?

Code: Select all


.logical $A000

; bank 16 here

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $A000

; bank 17 here

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $A000

; bank 18 here

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $A000

; bank 19 here

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

I need to figure it all out because I'm in a terrible mess and I don't quite know yet:

Sample code 16KB, without Banks/Mapper:

Code: Select all


* = $8000

	.WORD ColdStart						; ColdStart vector.
	.WORD WarmStart						; WarmStart vector.
	.BYTE $C3,$C2,$CD,$38,$30				; "CBM8O" Autostart string.

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

Screen		= $0400

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

ColdStart:

	SEI

	STX $D016
	JSR $FDA3     						; Prepare IRQ.
	JSR $FD50       					; Init Memory. Rewrite this routine to speed up boot process.
	JSR $FD15       					; Init I/O.
	JSR $FF5B         					; Init Video.

	CLI             					; Disable Interrupts.

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

WarmStart:

	JSR Load_TileMap

	LDA #$02
	STA $D800				;  Color RAM $D800-$DBE7.
	LDA #$01
	STA $D801				;  Color RAM $D800-$DBE7.
	LDA #$00
	STA $D802				;  Color RAM $D800-$DBE7.

	LDA #$08				; #bordercolor
	STA $D020
	LDA #$06				; #backgroundcolor
	STA $D021

;-------

	LDA #%11111111
	STA $D015				; Sprite Enable Registers.

	LDA #%00000111
	STA $D017				; Sprite Vertical Expansion
	STA $D01D				; Sprite Horizontal Expansion

	LDA #%11111010
	STA $D01C				; Sprite Multicolor Registers.

;-------

	LDA #%10000000				; 128x64= $2000
	STA $7F8

	LDA #%10000001				; Sprite1 - 129x64=$2040.
	STA $7F9

	LDA #%10000010				; Sprite2 - 130x64=$2080.
	STA $7FA

;-------

	LDA #$04		; // sprite multicolor 1
	STA $D025
	LDA #$07		; // sprite multicolor 2
	STA $D026

	LDA #$00		; SPRITE0 KOLOR.
	STA $D027
	LDA #$01		; SPRITE1 KOLOR.
	STA $D028
	LDA #$03		; SPRITE2 KOLOR.
	STA $D029
	LDA #$01		; SPRITE3 KOLOR.
	STA $D02A
	LDA #$01		; SPRITE4 KOLOR.
	STA $D02B
	LDA #$01		; SPRITE5 KOLOR.
	STA $D02C
	LDA #$01		; SPRITE6 KOLOR.
	STA $D02D
	LDA #$01		; SPRITE7 KOLOR.
	STA $D02E

	lda #$80
	sta $D000
	sta $D001

	lda #$40
	sta $D002
	sta $D003

	lda #$C0
	sta $D004
	sta $D005

	JSR LoadSprite0
	JSR LoadSprite1
	JSR LoadSprite2

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

Forever:

	LDA #$FB						; Your Clear raster line to make stuff.
Wait:
	CMP $D012
	BNE Wait

;-------

	JMP Forever

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

LoadSprite0:

	LDY #$00

LoadSprite0_Loop:

	LDA Sprite0,y
	STA $2000,y

	INY
	CPY #64
	BNE LoadSprite0_Loop

	RTS

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

LoadSprite1:

	LDY #$00

LoadSprite1_Loop:

	LDA Sprite1,y
	STA $2040,y

	INY
	CPY #64
	BNE LoadSprite1_Loop

	RTS

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

LoadSprite2:

	LDY #$00

LoadSprite2_Loop:

	LDA Sprite1,y		; laduje sprite1 aby miec to samo do testow co sprite1
	STA $2080,y

	INY
	CPY #64
	BNE LoadSprite2_Loop

	RTS

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

Sprite0:							; Narysowany na stronie "https://www.spritemate.com/".

	.byte %11111110,%00000111,%11110000
	.byte %11111111,%10001111,%11110000
	.byte %11110000,%11001000,%11110000
	.byte %01100000,%01111000,%01110000
	.byte %00100010,%00011000,%00010000
	.byte %00110000,%00001100,%00100000
	.byte %00011110,%00000100,%00100000
	.byte %00111111,%00000001,%01111000
	.byte %01000000,%00000000,%01101110
	.byte %11000000,%00111100,%11000011
	.byte %10000100,%01111100,%10000011
	.byte %11000000,%01111100,%00000011
	.byte %11000000,%01111000,%01000111
	.byte %11100000,%00110000,%00000111
	.byte %11110000,%00000110,%00011110
	.byte %01111100,%00000011,%11111100
	.byte %00111111,%10000011,%10000000
	.byte %00000011,%00010011,%10000000
	.byte %00000011,%00000111,%00000000
	.byte %00000001,%00011111,%00000000
	.byte %00000001,%11111110,%00000000

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

Sprite1:							; / multicolor / color: $00.

	.BYTE %00000010,%10101010,%10000000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00001110,%01101001,%10110000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000010,%10101010,%10000000
	.BYTE %00000000,%11101011,%00000000
	.BYTE %11101010,%10101010,%10101011
	.BYTE %10100000,%11101011,%00001010
	.BYTE %10000010,%10101010,%10000010
	.BYTE %10001110,%10010110,%10110010
	.BYTE %10001010,%10101010,%10100010
	.BYTE %10001010,%11010111,%10100010
	.BYTE %11001010,%10101010,%10100011
	.BYTE %00001010,%10010110,%10100000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000011,%10101010,%11000000
	.BYTE %00000000,%10111110,%00000000
	.BYTE %00000011,%10000010,%11000000
	.BYTE %00110010,%10000010,%10001100
	.BYTE %00101110,%11000011,%10111000
	.BYTE %00101010,%00000000,%10101000

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

sprite2:

	.BYTE %00000000,%00000000,%00000000
	.BYTE %00000010,%00000000,%00000000
	.BYTE %00011001,%00000000,%10011000
	.BYTE %00100100,%10000001,%00100100
	.BYTE %01001010,%01000001,%01010010
	.BYTE %01001010,%01000001,%01010010
	.BYTE %00100100,%01000001,%00100100
	.BYTE %00011000,%01000001,%00011000
	.BYTE %00000000,%00100001,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00100000,%00111100,%00001000
	.BYTE %00100000,%00000000,%00000100
	.BYTE %01000000,%00000000,%00000100
	.BYTE %01000000,%00000000,%10000100
	.BYTE %00100001,%00010000,%10011000
	.BYTE %00011001,%00010011,%11100000
	.BYTE %00000111,%11111100,%00000000
	.BYTE %00000000,%00000000,%00000000

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

Load_TileMap:

	LDY #$00

Load_TileMap_Loop:

	LDA TileMap,y
	STA Screen,y

	LDA TileMap+250,y
	STA Screen+250,y

	LDA TileMap+500,y
	STA Screen+500,y

	LDA TileMap+750,y
	STA Screen+750,y

	INY
	CPY #250
	BNE Load_TileMap_Loop

	RTS

;################
	
TileMap:

	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35

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

* = $BFFF
	.BYTE 0

And this is the code with the addition of OCEAN, it compiles, but it's probably wrong and I'd like to correct it... :

Code: Select all


;* = $0000			; do nothing ?

.logical $8000

; bank 0 here

* = $8000

	.WORD ColdStart				; ColdStart vector.
	.WORD WarmStart				; WarmStart vector.
	.BYTE $C3,$C2,$CD,$38,$30		; "CBM8O" Autostart string.

;------------------

Screen		= $0400

;------------------

ColdStart:

	SEI

	STX $D016
	JSR $FDA3     				; Prepare IRQ.
	JSR $FD50       			; Init Memory. Rewrite this routine to speed up boot process.
	JSR $FD15       			; Init I/O.
	JSR $FF5B         			; Init Video.

	CLI             			; Disable Interrupts.

;------------------

WarmStart:

	JSR Load_TileMap

	LDA #$02
	STA $D800				;  Color RAM $D800-$DBE7.
	LDA #$01
	STA $D801				;  Color RAM $D800-$DBE7.
	LDA #$00
	STA $D802				;  Color RAM $D800-$DBE7.

	LDA #$08				; #bordercolor
	STA $D020
	LDA #$06				; #backgroundcolor
	STA $D021

;-------

	LDA #%11111111
	STA $D015				; Sprite Enable Registers.

	LDA #%00000111
	STA $D017				; Sprite Vertical Expansion
	STA $D01D				; Sprite Horizontal Expansion

	LDA #%11111010
	STA $D01C				; Sprite Multicolor Registers.

;-------

	LDA #%10000000				; 128x64= $2000
	STA $7F8

	LDA #%10000001				; Sprite1 czyli 129x64=$2040.
	STA $7F9

	LDA #%10000010				; Sprite2 czyli 130x64=$2080.
	STA $7FA

;-------

	LDA #$04		; // sprite multicolor 1
	STA $D025
	LDA #$07		; // sprite multicolor 2
	STA $D026

	LDA #$00		; SPRITE0 KOLOR.
	STA $D027
	LDA #$01		; SPRITE1 KOLOR.
	STA $D028
	LDA #$03		; SPRITE2 KOLOR.
	STA $D029
	LDA #$01		; SPRITE3 KOLOR.
	STA $D02A
	LDA #$01		; SPRITE4 KOLOR.
	STA $D02B
	LDA #$01		; SPRITE5 KOLOR.
	STA $D02C
	LDA #$01		; SPRITE6 KOLOR.
	STA $D02D
	LDA #$01		; SPRITE7 KOLOR.
	STA $D02E

	lda #$80
	sta $D000
	sta $D001

	lda #$40
	sta $D002
	sta $D003

	lda #$C0
	sta $D004
	sta $D005

	JSR LoadSprite0
	JSR LoadSprite1
	JSR LoadSprite2

;------------------

Forever:

	LDA #$FB						; Your Clear raster line to make stuff.
Wait:
	CMP $D012
	BNE Wait

;-------

	JMP Forever

;------------------

LoadSprite0:

	LDY #$00

LoadSprite0_Loop:

	LDA Sprite0,y
	STA $2000,y

	INY
	CPY #64
	BNE LoadSprite0_Loop

	RTS

;------------------

LoadSprite1:

	LDY #$00

LoadSprite1_Loop:

	LDA Sprite1,y
	STA $2040,y

	INY
	CPY #64
	BNE LoadSprite1_Loop

	RTS

;------------------

LoadSprite2:

	LDY #$00

LoadSprite2_Loop:

	LDA Sprite1,y		; laduje sprite1 aby miec to samo do testow co sprite1
	STA $2080,y

	INY
	CPY #64
	BNE LoadSprite2_Loop

	RTS

;------------------

Sprite0:							; Narysowany na stronie "https://www.spritemate.com/".

	.byte %11111110,%00000111,%11110000
	.byte %11111111,%10001111,%11110000
	.byte %11110000,%11001000,%11110000
	.byte %01100000,%01111000,%01110000
	.byte %00100010,%00011000,%00010000
	.byte %00110000,%00001100,%00100000
	.byte %00011110,%00000100,%00100000
	.byte %00111111,%00000001,%01111000
	.byte %01000000,%00000000,%01101110
	.byte %11000000,%00111100,%11000011
	.byte %10000100,%01111100,%10000011
	.byte %11000000,%01111100,%00000011
	.byte %11000000,%01111000,%01000111
	.byte %11100000,%00110000,%00000111
	.byte %11110000,%00000110,%00011110
	.byte %01111100,%00000011,%11111100
	.byte %00111111,%10000011,%10000000
	.byte %00000011,%00010011,%10000000
	.byte %00000011,%00000111,%00000000
	.byte %00000001,%00011111,%00000000
	.byte %00000001,%11111110,%00000000

;------------------

Sprite1:							; / multicolor / color: $00.

	.BYTE %00000010,%10101010,%10000000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00001110,%01101001,%10110000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000010,%10101010,%10000000
	.BYTE %00000000,%11101011,%00000000
	.BYTE %11101010,%10101010,%10101011
	.BYTE %10100000,%11101011,%00001010
	.BYTE %10000010,%10101010,%10000010
	.BYTE %10001110,%10010110,%10110010
	.BYTE %10001010,%10101010,%10100010
	.BYTE %10001010,%11010111,%10100010
	.BYTE %11001010,%10101010,%10100011
	.BYTE %00001010,%10010110,%10100000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000011,%10101010,%11000000
	.BYTE %00000000,%10111110,%00000000
	.BYTE %00000011,%10000010,%11000000
	.BYTE %00110010,%10000010,%10001100
	.BYTE %00101110,%11000011,%10111000
	.BYTE %00101010,%00000000,%10101000

;------------------

sprite2:

	.BYTE %00000000,%00000000,%00000000
	.BYTE %00000010,%00000000,%00000000
	.BYTE %00011001,%00000000,%10011000
	.BYTE %00100100,%10000001,%00100100
	.BYTE %01001010,%01000001,%01010010
	.BYTE %01001010,%01000001,%01010010
	.BYTE %00100100,%01000001,%00100100
	.BYTE %00011000,%01000001,%00011000
	.BYTE %00000000,%00100001,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00100000,%00111100,%00001000
	.BYTE %00100000,%00000000,%00000100
	.BYTE %01000000,%00000000,%00000100
	.BYTE %01000000,%00000000,%10000100
	.BYTE %00100001,%00010000,%10011000
	.BYTE %00011001,%00010011,%11100000
	.BYTE %00000111,%11111100,%00000000
	.BYTE %00000000,%00000000,%00000000

;------------------

Load_TileMap:

	LDY #$00

Load_TileMap_Loop:

	LDA TileMap,y
	STA Screen,y

	LDA TileMap+250,y
	STA Screen+250,y

	LDA TileMap+500,y
	STA Screen+500,y

	LDA TileMap+750,y
	STA Screen+750,y

	INY
	CPY #250
	BNE Load_TileMap_Loop

	RTS

;------------------
	
TileMap:

	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35

;------------------

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 1 here 

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 2 here

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 3 here

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $8000

; bank 4 here
 
.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

* = $A000

; a000 code

* = $BFFF
	.BYTE 0

Attachments
helloworld_ocean.zip
(926 Bytes) Downloaded 31 times
helloworld_normal16k.zip
(682 Bytes) Downloaded 31 times
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

well to make a 256K cart you need to have a 256K file or at least on over 128K. You make a 48K file which it somehow made into a 128K crt.
but it is 16 banks of 8K that start at 8000 and then 16 banks of 8K that start at A000.
Also don't set the * to be $8000 that will cause you lots of pain.
you also need to have something in a bank for the align to work for example
if you are at $2000 in the file and you say align $2000, we $2000 is a clean divisor of $2000 so it already is algined to something that is a a multiple of $2000 so it puts nothing. So I add a .byte 0 to every bank. thus you do

Code: Select all

2000 .byte 0
2001 algin $2000 
which then forces it to go to $4000

here is a 256K ocean 1 skeleton file for you

Code: Select all

* = $0000			; not needed but best to be explicit

.logical $8000

; bank 0 here

	.WORD ColdStart				; ColdStart vector.
	.WORD WarmStart				; WarmStart vector.
	.BYTE $C3,$C2,$CD,$38,$30		; "CBM8O" Autostart string.

;------------------

Screen		= $0400

;------------------

ColdStart:

	SEI

	STX $D016
	JSR $FDA3     				; Prepare IRQ.
	JSR $FD50       			; Init Memory. Rewrite this routine to speed up boot process.
	JSR $FD15       			; Init I/O.
	JSR $FF5B         			; Init Video.

	CLI             			; Disable Interrupts.

;------------------

WarmStart:

	JSR Load_TileMap

	LDA #$02
	STA $D800				;  Color RAM $D800-$DBE7.
	LDA #$01
	STA $D801				;  Color RAM $D800-$DBE7.
	LDA #$00
	STA $D802				;  Color RAM $D800-$DBE7.

	LDA #$08				; #bordercolor
	STA $D020
	LDA #$06				; #backgroundcolor
	STA $D021

;-------

	LDA #%11111111
	STA $D015				; Sprite Enable Registers.

	LDA #%00000111
	STA $D017				; Sprite Vertical Expansion
	STA $D01D				; Sprite Horizontal Expansion

	LDA #%11111010
	STA $D01C				; Sprite Multicolor Registers.

;-------

	LDA #%10000000				; 128x64= $2000
	STA $7F8

	LDA #%10000001				; Sprite1 czyli 129x64=$2040.
	STA $7F9

	LDA #%10000010				; Sprite2 czyli 130x64=$2080.
	STA $7FA

;-------

	LDA #$04		; // sprite multicolor 1
	STA $D025
	LDA #$07		; // sprite multicolor 2
	STA $D026

	LDA #$00		; SPRITE0 KOLOR.
	STA $D027
	LDA #$01		; SPRITE1 KOLOR.
	STA $D028
	LDA #$03		; SPRITE2 KOLOR.
	STA $D029
	LDA #$01		; SPRITE3 KOLOR.
	STA $D02A
	LDA #$01		; SPRITE4 KOLOR.
	STA $D02B
	LDA #$01		; SPRITE5 KOLOR.
	STA $D02C
	LDA #$01		; SPRITE6 KOLOR.
	STA $D02D
	LDA #$01		; SPRITE7 KOLOR.
	STA $D02E

	lda #$80
	sta $D000
	sta $D001

	lda #$40
	sta $D002
	sta $D003

	lda #$C0
	sta $D004
	sta $D005

	JSR LoadSprite0
	JSR LoadSprite1
	JSR LoadSprite2

;------------------

Forever:

	LDA #$FB						; Your Clear raster line to make stuff.
Wait:
	CMP $D012
	BNE Wait

;-------

	JMP Forever

;------------------

LoadSprite0:

	LDY #$00

LoadSprite0_Loop:

	LDA Sprite0,y
	STA $2000,y

	INY
	CPY #64
	BNE LoadSprite0_Loop

	RTS

;------------------

LoadSprite1:

	LDY #$00

LoadSprite1_Loop:

	LDA Sprite1,y
	STA $2040,y

	INY
	CPY #64
	BNE LoadSprite1_Loop

	RTS

;------------------

LoadSprite2:

	LDY #$00

LoadSprite2_Loop:

	LDA Sprite1,y		; laduje sprite1 aby miec to samo do testow co sprite1
	STA $2080,y

	INY
	CPY #64
	BNE LoadSprite2_Loop

	RTS

;------------------

Sprite0:							; Narysowany na stronie "https://www.spritemate.com/".

	.byte %11111110,%00000111,%11110000
	.byte %11111111,%10001111,%11110000
	.byte %11110000,%11001000,%11110000
	.byte %01100000,%01111000,%01110000
	.byte %00100010,%00011000,%00010000
	.byte %00110000,%00001100,%00100000
	.byte %00011110,%00000100,%00100000
	.byte %00111111,%00000001,%01111000
	.byte %01000000,%00000000,%01101110
	.byte %11000000,%00111100,%11000011
	.byte %10000100,%01111100,%10000011
	.byte %11000000,%01111100,%00000011
	.byte %11000000,%01111000,%01000111
	.byte %11100000,%00110000,%00000111
	.byte %11110000,%00000110,%00011110
	.byte %01111100,%00000011,%11111100
	.byte %00111111,%10000011,%10000000
	.byte %00000011,%00010011,%10000000
	.byte %00000011,%00000111,%00000000
	.byte %00000001,%00011111,%00000000
	.byte %00000001,%11111110,%00000000

;------------------

Sprite1:							; / multicolor / color: $00.

	.BYTE %00000010,%10101010,%10000000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00001110,%01101001,%10110000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000010,%10101010,%10000000
	.BYTE %00000000,%11101011,%00000000
	.BYTE %11101010,%10101010,%10101011
	.BYTE %10100000,%11101011,%00001010
	.BYTE %10000010,%10101010,%10000010
	.BYTE %10001110,%10010110,%10110010
	.BYTE %10001010,%10101010,%10100010
	.BYTE %10001010,%11010111,%10100010
	.BYTE %11001010,%10101010,%10100011
	.BYTE %00001010,%10010110,%10100000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000011,%10101010,%11000000
	.BYTE %00000000,%10111110,%00000000
	.BYTE %00000011,%10000010,%11000000
	.BYTE %00110010,%10000010,%10001100
	.BYTE %00101110,%11000011,%10111000
	.BYTE %00101010,%00000000,%10101000

;------------------

sprite2:

	.BYTE %00000000,%00000000,%00000000
	.BYTE %00000010,%00000000,%00000000
	.BYTE %00011001,%00000000,%10011000
	.BYTE %00100100,%10000001,%00100100
	.BYTE %01001010,%01000001,%01010010
	.BYTE %01001010,%01000001,%01010010
	.BYTE %00100100,%01000001,%00100100
	.BYTE %00011000,%01000001,%00011000
	.BYTE %00000000,%00100001,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00100000,%00111100,%00001000
	.BYTE %00100000,%00000000,%00000100
	.BYTE %01000000,%00000000,%00000100
	.BYTE %01000000,%00000000,%10000100
	.BYTE %00100001,%00010000,%10011000
	.BYTE %00011001,%00010011,%11100000
	.BYTE %00000111,%11111100,%00000000
	.BYTE %00000000,%00000000,%00000000

;------------------

Load_TileMap:

	LDY #$00

Load_TileMap_Loop:

	LDA TileMap,y
	STA Screen,y

	LDA TileMap+250,y
	STA Screen+250,y

	LDA TileMap+500,y
	STA Screen+500,y

	LDA TileMap+750,y
	STA Screen+750,y

	INY
	CPY #250
	BNE Load_TileMap_Loop

	RTS

;------------------
	
TileMap:

	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35

;------------------

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 1 here 
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 2 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 3 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $8000

; bank 4 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 5 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 6 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 7 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 8 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 9 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 10 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 11 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 12 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 13 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 14 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 15 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $A000

; bank 16 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 17 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 18 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 19 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 20 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 21 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 22 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 23 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 24 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 25 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 26 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 27 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 28 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 29 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 30 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $A000

; bank 31 here
.byte 0

.cwarn * >= $C000, "bank overflow"
* = $BFFF
.byte 0
.here
This will give you this memory map when you assemble

Code: Select all

Memory range:      $0000-$05a2   $05a3
Memory range:      $2000-$2000   $0001
Memory range:      $4000-$4000   $0001
Memory range:      $6000-$6000   $0001
Memory range:      $8000-$8000   $0001
Memory range:      $a000-$a000   $0001
Memory range:      $c000-$c000   $0001
Memory range:      $e000-$e000   $0001
Memory range:     $10000-$10000  $0001
Memory range:     $12000-$12000  $0001
Memory range:     $14000-$14000  $0001
Memory range:     $16000-$16000  $0001
Memory range:     $18000-$18000  $0001
Memory range:     $1a000-$1a000  $0001
Memory range:     $1c000-$1c000  $0001
Memory range:     $1e000-$1e000  $0001
Memory range:     $20000-$20000  $0001
Memory range:     $22000-$22000  $0001
Memory range:     $24000-$24000  $0001
Memory range:     $26000-$26000  $0001
Memory range:     $28000-$28000  $0001
Memory range:     $2a000-$2a000  $0001
Memory range:     $2c000-$2c000  $0001
Memory range:     $2e000-$2e000  $0001
Memory range:     $30000-$30000  $0001
Memory range:     $32000-$32000  $0001
Memory range:     $34000-$34000  $0001
Memory range:     $36000-$36000  $0001
Memory range:     $38000-$38000  $0001
Memory range:     $3a000-$3a000  $0001
Memory range:     $3c000-$3c000  $0001
Memory range:     $3e000-$3e000  $0001
Memory range:     $3ffff-$3ffff  $0001
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

Thanks a lot! :)


I understand that changing to skeleton 512 is setting 64 banks $8000 only: ?

Code: Select all

* = $0000			; not needed but best to be explicit

.logical $8000

; bank 0 here

	.WORD ColdStart				; ColdStart vector.
	.WORD WarmStart				; WarmStart vector.
	.BYTE $C3,$C2,$CD,$38,$30		; "CBM8O" Autostart string.

;------------------

Screen		= $0400

;------------------

ColdStart:

	SEI

	STX $D016
	JSR $FDA3     				; Prepare IRQ.
	JSR $FD50       			; Init Memory. Rewrite this routine to speed up boot process.
	JSR $FD15       			; Init I/O.
	JSR $FF5B         			; Init Video.

	CLI             			; Disable Interrupts.

;------------------

WarmStart:

	JSR Load_TileMap

	LDA #$02
	STA $D800				;  Color RAM $D800-$DBE7.
	LDA #$01
	STA $D801				;  Color RAM $D800-$DBE7.
	LDA #$00
	STA $D802				;  Color RAM $D800-$DBE7.

	LDA #$08				; #bordercolor
	STA $D020
	LDA #$06				; #backgroundcolor
	STA $D021

;-------

	LDA #%11111111
	STA $D015				; Sprite Enable Registers.

	LDA #%00000111
	STA $D017				; Sprite Vertical Expansion
	STA $D01D				; Sprite Horizontal Expansion

	LDA #%11111010
	STA $D01C				; Sprite Multicolor Registers.

;-------

	LDA #%10000000				; 128x64= $2000
	STA $7F8

	LDA #%10000001				; Sprite1 czyli 129x64=$2040.
	STA $7F9

	LDA #%10000010				; Sprite2 czyli 130x64=$2080.
	STA $7FA

;-------

	LDA #$04		; // sprite multicolor 1
	STA $D025
	LDA #$07		; // sprite multicolor 2
	STA $D026

	LDA #$00		; SPRITE0 KOLOR.
	STA $D027
	LDA #$01		; SPRITE1 KOLOR.
	STA $D028
	LDA #$03		; SPRITE2 KOLOR.
	STA $D029
	LDA #$01		; SPRITE3 KOLOR.
	STA $D02A
	LDA #$01		; SPRITE4 KOLOR.
	STA $D02B
	LDA #$01		; SPRITE5 KOLOR.
	STA $D02C
	LDA #$01		; SPRITE6 KOLOR.
	STA $D02D
	LDA #$01		; SPRITE7 KOLOR.
	STA $D02E

	lda #$80
	sta $D000
	sta $D001

	lda #$40
	sta $D002
	sta $D003

	lda #$C0
	sta $D004
	sta $D005

	JSR LoadSprite0
	JSR LoadSprite1
	JSR LoadSprite2

;------------------

Forever:

	LDA #$FB						; Your Clear raster line to make stuff.
Wait:
	CMP $D012
	BNE Wait

;-------

	JMP Forever

;------------------

LoadSprite0:

	LDY #$00

LoadSprite0_Loop:

	LDA Sprite0,y
	STA $2000,y

	INY
	CPY #64
	BNE LoadSprite0_Loop

	RTS

;------------------

LoadSprite1:

	LDY #$00

LoadSprite1_Loop:

	LDA Sprite1,y
	STA $2040,y

	INY
	CPY #64
	BNE LoadSprite1_Loop

	RTS

;------------------

LoadSprite2:

	LDY #$00

LoadSprite2_Loop:

	LDA Sprite1,y		; laduje sprite1 aby miec to samo do testow co sprite1
	STA $2080,y

	INY
	CPY #64
	BNE LoadSprite2_Loop

	RTS

;------------------

Sprite0:							; Narysowany na stronie "https://www.spritemate.com/".

	.byte %11111110,%00000111,%11110000
	.byte %11111111,%10001111,%11110000
	.byte %11110000,%11001000,%11110000
	.byte %01100000,%01111000,%01110000
	.byte %00100010,%00011000,%00010000
	.byte %00110000,%00001100,%00100000
	.byte %00011110,%00000100,%00100000
	.byte %00111111,%00000001,%01111000
	.byte %01000000,%00000000,%01101110
	.byte %11000000,%00111100,%11000011
	.byte %10000100,%01111100,%10000011
	.byte %11000000,%01111100,%00000011
	.byte %11000000,%01111000,%01000111
	.byte %11100000,%00110000,%00000111
	.byte %11110000,%00000110,%00011110
	.byte %01111100,%00000011,%11111100
	.byte %00111111,%10000011,%10000000
	.byte %00000011,%00010011,%10000000
	.byte %00000011,%00000111,%00000000
	.byte %00000001,%00011111,%00000000
	.byte %00000001,%11111110,%00000000

;------------------

Sprite1:							; / multicolor / color: $00.

	.BYTE %00000010,%10101010,%10000000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00001110,%01101001,%10110000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000010,%10101010,%10000000
	.BYTE %00000000,%11101011,%00000000
	.BYTE %11101010,%10101010,%10101011
	.BYTE %10100000,%11101011,%00001010
	.BYTE %10000010,%10101010,%10000010
	.BYTE %10001110,%10010110,%10110010
	.BYTE %10001010,%10101010,%10100010
	.BYTE %10001010,%11010111,%10100010
	.BYTE %11001010,%10101010,%10100011
	.BYTE %00001010,%10010110,%10100000
	.BYTE %00001110,%10101010,%10110000
	.BYTE %00000011,%10101010,%11000000
	.BYTE %00000000,%10111110,%00000000
	.BYTE %00000011,%10000010,%11000000
	.BYTE %00110010,%10000010,%10001100
	.BYTE %00101110,%11000011,%10111000
	.BYTE %00101010,%00000000,%10101000

;------------------

sprite2:

	.BYTE %00000000,%00000000,%00000000
	.BYTE %00000010,%00000000,%00000000
	.BYTE %00011001,%00000000,%10011000
	.BYTE %00100100,%10000001,%00100100
	.BYTE %01001010,%01000001,%01010010
	.BYTE %01001010,%01000001,%01010010
	.BYTE %00100100,%01000001,%00100100
	.BYTE %00011000,%01000001,%00011000
	.BYTE %00000000,%00100001,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00000000,%00100010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00010000,%01000010,%00000000
	.BYTE %00100000,%00111100,%00001000
	.BYTE %00100000,%00000000,%00000100
	.BYTE %01000000,%00000000,%00000100
	.BYTE %01000000,%00000000,%10000100
	.BYTE %00100001,%00010000,%10011000
	.BYTE %00011001,%00010011,%11100000
	.BYTE %00000111,%11111100,%00000000
	.BYTE %00000000,%00000000,%00000000

;------------------

Load_TileMap:

	LDY #$00

Load_TileMap_Loop:

	LDA TileMap,y
	STA Screen,y

	LDA TileMap+250,y
	STA Screen+250,y

	LDA TileMap+500,y
	STA Screen+500,y

	LDA TileMap+750,y
	STA Screen+750,y

	INY
	CPY #250
	BNE Load_TileMap_Loop

	RTS

;------------------
	
TileMap:

	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,35,32,32,32,35,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,32,32,32,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,35,35,35,35,35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,35,32,32,32,32,32,32,32,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35
	.BYTE 35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35

;------------------

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 1 here 
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 2 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;------------------

.logical $8000

; bank 3 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $8000

; bank 4 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 5 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 6 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 7 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 8 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 9 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 10 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 11 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 12 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 13 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 14 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 15 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

;-------------------

.logical $8000

; bank 16 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 17 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 18 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 19 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 20 here
.byte 0

.cwarn * >= $C000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 21 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 22 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 23 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 24 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 25 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 26 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 27 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 28 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 29 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 30 here
.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

;----------------------------

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 31 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 60 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 61 here

.byte 0

.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 62 here

.byte 0
.cwarn * >= $A000, "bank overflow"
.here
.align 8192				; make sure you fill the whole 8K.

.logical $8000

; bank 63 here

.byte 0
.cwarn * >= $A000, "bank overflow"

* = $9FFF
.byte 0
.here


By the way, I will ask about some simplest methods of obtaining sounds from SID. Unfortunately, I tried in various ways to write different values to the SID Registers to get some sounds, but nothing really worked out - I understand it's not as easy as with 2A03, where you can write a few random values to it to get SFX?
Last edited by sdm on Fri Dec 30, 2022 6:12 am, edited 2 times in total.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

Yes, for 512K all banks are $8000 logical.

The SID is a lot more complex than the 2A03, as you have different waveforms per voice, ADSR and filters to deal with.
So to get a noise you will want to set a frequency and a waveform and set the gate bit to 1 to start making sound I.e start the AD part of the ADSR curve.

the Commodore 64 users Guide has basic samples for the SID, but if you are programming the C64 you should get hold a Commodore 64 Programmers Reference Guide which has a whole chapter dedicated to the SID as well a full complete details of every other aspect of the machine. It really is the "Bible" for C64 dev. There are also extensive books on each topic available here https://commodore.bombjack.org/commodore/books.htm
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

Ocean 256KB has BANK0 $8000-9FFF physically visible, but which Bank $A000-BFFF is physically visible in this range? BANK16 and BANK 31 $A000 the code is not visible right away (I thought one of them was visible right away) - I need to somehow set the default visibility of some bank under $A000?
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

that is very odd, the cart image is set as 16K, however the contents are mirrored. I.e A000 shows exactly the same as 8000. This as far as I can tell is an error and I have raised it as a bug with the team, you can follow along here https://sourceforge.net/p/vice-emu/bugs/1795/
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

i.e. always A000 is a mirror of 8000? I thought you could switch both addresses independently.

example:

LDA #15 ; Switch $8000-9FFF to Bank #15
STA $DE00

LDA #16 ; Switch $A000-BFFF to Bank #16
STA $DE00

right?

- writing 00-15 to $DE00 select $8000-9FFF bank?
- writing 16-31 ro $DE00 select $A000-BFFF bank?

In general, 512KiB type switches the entire physical address $8000-9FFF at once - how to work with it then? There is no fixed bank, do you need to create a temporary fixed bank? Because I understand it works similarly to NES AOROM where the entire physical 32kb bank is switched and you have to create a temporary "fixed" bank.

Or maybe some other simple 128/256KB mapper?
Preferably one that has the ability to independently switch 8000 / A000 or one of them as FIXED 8KB and one as SWAPPABLE 8KB as on the NES.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

in sizes other than 256K yes, but for the 256K you should get Bank 0 at $8000 and Bank 16 at $a000.

No, you only have 1 bank register at DE00 and it will set both banks to be that value with the upper bank +16 so

lda #15
sta $de00 ; $8000-9FFF is bank 15, and $A000-BFFF is bank 31

I'm not sure what would happen if you write 16 in the 256 case, however I would expect it to wrap around to 0 again so
lda #16
sta $de00 ; $8000-9FFF is bank 0, and $A000-BFFF is bank 16
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

So it's possible the problem is the fault of the emulator?

So there is no mapper in C64 that allows you to switch both 8KB independently? ($8000 and $A000) ?

By the way, my first C64 production - Simple Pac-Man 'like Game: (No SFX because I can't program SID yet).
Attachments
pak-men.zip
(5.17 KiB) Downloaded 38 times
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by Oziphantom »

This is a case of there are 4 games in the whole world that use this format, and the implementation supports those 4.
What VICE does is mirrors the same data to $8000 and $A000, this as far as I can understand is wrong. However the way the carts are used, as a super fast disk, and the instructions mean. They can set bank 16 and access it at $a000, the mirror does not break this idea. While I would expect bank 0 to be visible at $8000 and not bank 16. It doesn't matter as the games when loading won't actually ever touch the other bank while using the banks, and hence it just works for the 4 examples that need to use it.

I believer the Action Replay 5 and 6 cartridges do have some form of split banking it might be 4K splits. But those are very custom to do a custom job cart and not something you should try and make a game in. Basically when you do ROMH And ROML you treat it as 16K banks which is far nicer and there is no real need to have a split bank. It is a lot of extra cost on an already expensive cart for very little gain.

Looking good for a first C64 game. Are you cycling though the 4 split sprites when you eat a ghost or are you doing some plexing?
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: C64 / ATARI - Cartridge Memory Mapper Bank Switching

Post by sdm »

It's a bit odd that there are so few mappers that independently allow $8000/$A000 switching. The C64 has this capability, the ATARI doesn't.
Oziphantom wrote: Fri Dec 30, 2022 10:55 pm Are you cycling though the 4 split sprites when you eat a ghost or are you doing some plexing?
It's the same one Sprite, but interlaced/flickered into 4 frames - it's in a different place in each frame.
Post Reply