CRAM addresses?

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
AmateurSegaDev
Interested
Posts: 11
Joined: Sun Feb 27, 2022 3:27 am

CRAM addresses?

Post by AmateurSegaDev » Sun Jun 05, 2022 5:14 am

Hello everyone!

I'm trying to dip my toes into some in-line assembly (in SGDK) to try to change a specific color during a horizontal interrupt. This is my current simple code:

Code: Select all

asm volatile (
       "move.l #0xc0000000, 0xc00004.l;"  //Prepare VDP to write to.
       "move.w #0x007E, 0xc00000.l;" //Write Orange (0B, 7G, ER) into CRAM slot 0.  I don't know how "c00000" addresses palette 0, color 0, nor do I understand how I can just move a word into a longword space?
       );
I thought I had seen a memory map of the CRAM addresses, but perhaps I am mistaken (is this dependent on the mode of the VDP? If so, does SGDK use mode 1?). I've seen examples of loading palette data on Plutidev, but am not quite following on how the addressing works for the individual palette colors.

I apologize in advance for my ignorance (this is my first attempt at assembly) and thank you in advance to any replies.

AmateurSegaDev
Interested
Posts: 11
Joined: Sun Feb 27, 2022 3:27 am

Re: CRAM addresses?

Post by AmateurSegaDev » Sun Jun 05, 2022 11:11 pm

Ah, I see now that sequential writes will increment the color being written. Is there a way to jump to a specified color directly?

Mask of Destiny
Very interested
Posts: 608
Joined: Thu Nov 30, 2006 6:30 am

Re: CRAM addresses?

Post by Mask of Destiny » Tue Jun 07, 2022 7:34 am

AmateurSegaDev wrote:
Sun Jun 05, 2022 5:14 am
I don't know how "c00000" addresses palette 0, color 0
So the VDP contains an internal address pointer and a separate register called CD which stores which type of RAM you want to access and whether you want to read or write it. The 32-bit command word you write to the control port sets both of these registers. The top 2 bits of the command word set the bottom 2 bits of CD, the next 14-bits set the low 14-bits of the address, then there's a bunch of unused bits, 4 more CD bits, another unused bit and 3 more address bits. So the whole thing looks like CCAAAAAA AAAAAAAA 00000000 CCCC0AAA where C is a CD bit and A is an address bit. So C0000000 sets CD to 3 (write to CRAM) and address to 0. Since CRAM is word wide, the second entry for palette 0 is at address 2. The command word for that would be C0020000. The first entry of palette 1 is at address 0x20 and the command word for that would be C0200000.
AmateurSegaDev wrote:
Sun Jun 05, 2022 5:14 am
nor do I understand how I can just move a word into a longword space?
The .l here refers to the use of absolute long addressing mode instead of absolute short, not the size of the data being written. Absolute short addressing mode produces smaller instructions and is a bit faster, but can only address the bottom and top 32 KiB of address space (so the first 32 KiB of ROM and the last 32 KiB of RAM).

AmateurSegaDev
Interested
Posts: 11
Joined: Sun Feb 27, 2022 3:27 am

Re: CRAM addresses?

Post by AmateurSegaDev » Tue Jun 07, 2022 9:14 pm

Ah, okay. Thank you so much for the detailed explanation!

I was still tripped up a little by palettes being split in two, but I got it sorted out. For anyone in the future searching for this, here are examples:

Code: Select all

"move.l #0xc0000000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 0, Color 0.
"move.l #0xc0020000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 0, Color 1.
"move.l #0xc00F0000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 0, Color 7.
"move.l #0xc0100000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 0, Color 8
"move.l #0xc0200000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 1, Color 0.
"move.l #0xc07F0000, 0xc00004.l;"  //Instruct VDP Control Port (address 0xc00004) to write to CRAM: Pallet 3, Color 15.
  
"move.w #0x007E, 0xc00000.l;" //Write an Orange color into CRAM by sending Blue (0), Green (7), Red (E) into the VDP Data port (address 0xc00000).

Post Reply