=-=-= SNES Documentation v1.3: Written by Yoshi of Digital Exodus. =-=-= 1) Memory Map. i) "Main" memory map. ii) Additional info. 2) SNES Color explaination. 3) SNES DMA Memory Map and explaination. 4) SNES Graphics (tiles) explaination. 5) SNES Screen mode definitions. 6) SNES OAM/Sprite explaination. 7) Magicom Disk registers and Memory controller locations. 69) About the author... FF) Greetings, Thanx, etc... =-=-= 1) Memory Map. i) "Main" memory map. ----------- Just so you know... the R and/or W's on the left side before the memory location mean [R]eadable and/or [W]riteable. I don't know what happens if you try to read from the write-only registers: I think you get bogus data, but that's about it. ----------- W |$2100: Screen display register. x000bbbb x: 0 = Screen on. 1 = Screen off. bbbb: 0-$F = Brightness of screen. *** If you increment $2100 so the register goes up to $xF (x being whatever), you can make the screen "fade in". Make -SURE- you do this only during the VBlank period! If you don't, the screen goes totally wacko! The 'GS programmers like myself call it "Syncing to the VBL". ----------- W |$2101: OAM (Sprite) sizes. sssnnbbb s: Size. n: Name selection (upper 4k word address). b: Base selection (8k word segment address). *** The sizes are defined as follows: 000: 8x8 or 16x16 001: 8x8 or 32x32 *** I've never used this register, nor sprites. Check Section 6 for information which was not done by me: If you understand it better than I do, good deal. ----------- W |$2102: Address of OAM (Sprites). ???????? | ???????? *** This register i've never used. All I know is that it's a -WORD- in length, not a byte. ----------- W |$2104: Data for OAM (Sprites). ???????? *** I've never used this register. It's like $210D: You have to store a value in it twice. ----------- W |$2105: Screen mode. abcdfeee a: Plane 3 tile size. b: Plane 2 tile size. c: Plane 1 tile size. d: Plane 0 tile size. 0 = 8x8 tiles. 1 = 16x16 tiles. e: MODE definition. f: Make Plane 2 take highest priority. ----------- W |$2106: Screen pixelation (aka. MOSAIC) register. xxxxabcd x: 0-$F = Pixel size. a: Affect plane 3. b: Affect plane 2. c: Affect plane 1. d: Affect plane 0. *** Just like $2100, this only works during VBlank. I recommend you setup what planes you want to affect at the start of the program, then to make them change, do the following: LDA #$03 ; Affect planes 0 and 1. STA TempReg1 STA $2106 JSR WaitVBlank LDA TempReg1 Loop STA $2106 CLC ADC #$10 CMP #$F3 BNE Loop ----------- W |$2107: Plane 0 VRAM location register. xxxxxxab x: Address of VRAM location. ab: Virtual screen size selection. *** The virtual screen size dealy goes like this: 32x32 to 32x64 to 64x32 to 64x64. Visually, you only see 32x32(x25) at once unless you change the ACTUAL screen size. *** The way I use this register is pretty simple. Lets say the VRAM is in $2000... Therefore, we'd go like this: LDA #$20 STA $2107 ----------- W |$2108: Plane 1 VRAM location register. W |$2109: Plane 2 VRAM location register. W |$210A: Plane 3 VRAM location register. *** All of these follow the same definition as $2107. ----------- W |$210B: Tile VRAM location register. aaaabbbb a: Location of tiles for Plane 1. b: Location of tiles for Plane 0. *** The way you use this register is fairly neat. Since you only have a nybble to work with (which ranges from $0-F only) your Tile location can only be $0000 to $F000. You can't have an address such as $5F91 or $1C4A which holds your tile data. You just can't have it. :-) ----------- W |$210C: Tile VRAM location register. ccccdddd c: Location of tiles for Plane 3. d: Location of tiles for Plane 2. *** Same stats for $210B go for this one; 'cept the plane registers are different. ----------- W |$210D: Plane 0 X-scroll register. *** This register is really funky. You have to write to it twice in a row (each piece of data being 1 byte). The register is setup as the following: - You store the first 8 bits (the first byte) which ranges from $00 to $FF. After you store this value, you have to store the next 3 bits in the same register. *** The following code demonstrates how to move plane 0 left: LDA Plane0X DEC STA Plane0X STA $210D STZ $210D If you make that into a loop by itself, the result is the plane keeps scrolling left forever; it even wraps around back to the start. *** Note: I've been told this is a nasty way to do it because MODE 7 uses 13 bits of the above, while the rest use 10. I'm not taking care of the MSB. :-( ----------- W |$210E: Plane 0 Y-Scroll register. W |$210F: Plane 1 X-Scroll register. W |$2110: Plane 1 Y-Scroll register. W |$2111: Plane 2 X-Scroll register. W |$2112: Plane 2 Y-Scroll register. W |$2113: Plane 3 X-Scroll register. W |$2114: Plane 3 Y-Scroll register. *** All of these follow the same definition as $210D. ----------- W |$2115: Video port control. *** If you store the following listed values in this register, the following happens: $80: H/L increment which determines if the address will be incremented after it reads/writes to/from $2118 and $2139, or $2119 and $213A. W |$2116: Video port address. *** 16 bit VRAM address. $2117: Video port address (continued, due to 16 bits). W |$2118: Video port data. *** Data register for writing VRAM data. $2119: Video port data. *** Same as above. ----------- W |$211A: MODE 7 Information register. xy????ab a: Horizontal or Vertical flip. b: Horizontal or Vertical flip. x: Landscape repeat type. y: Landscape repeat type. *** I have not the SLIGHTEST idea what the hell the original author means by this. If someone can explain it, tell me. ----------- W |$211B: COS (COSIN) rotate angle / X Expansion. W |$211C: SIN (SIN) rotate angle / X Expansion. W |$211D: SIN (SIN) rotate angle / Y Expansion. W |$211E: COS (COSIN) rotate angle / Y Expansion. W |$211F: 13 bit address for the center of Rotate X. W |$2120: 13 bit address for the center of Rotate Y. *** All above things i've never used, nor do I have any explainations on them. Use them at your own risk, or until I get info on 'em. *** $211F and $2120 are like $210D: You have to write a byte to them twice. ----------- W |$2121: Color # (or pallete) selection register. xxxxxxxx x: Color # ($00-$FF). *** This register is probably one of the most simple registers I know of to use. You simply store the # of the color you want to modify before writing to $2122. This register is autoincrementing, so you don't have to "LDA #$01, STA $2121, LDA #$02, STA $2121, LDA #$03..." and so on... Code is as follows: STZ $2121 ; Start at color 0. STZ $2122 ; Color #0 = 00 00 STZ $2122 LDA #$FF ; Color #1 = 7F FF (white). STA $2122 LDA #$7F STA $2122 LDA #$1F ; Color #2 = 00 1F (red). STA $2122 STZ $2122 ----------- W |$2122: Color data register. xxxxxxxx x: Value of color. *** Color on the SNES is trippy; it's 15 bit. Check Section 2 on how the SNES colors are setup. Some example code I listed for $2121... Anyways, this register is like $210D (plane X-scroll) and those types: You have to store the value in it twice. For instance: If you wanted the color white (which is $7FFF in SNES-color), you would have to do the following: LDA [whatever color #] STA $2121 LDA #$FF ; We first store the "lower half" STA $2122 LDA #$7F ; Then the upper... STA $2122 It's really not that hard, but it'll take some getting used to :-) Remember, check Section 2 on how the SNES does it's color, and for tile-setup, check Section 4. ----------- W |$212C: Playfield/Sprite-enable register. abcdefgh a: Plane 3 enable (for Sprites). b: Plane 2 enable (for Sprites). c: Plane 1 enable (for Sprites). d: Plane 0 enable (for Sprites). e: Enable plane 3. f: Enable plane 2. g: Enable plane 1. h: Enable plane 0. *** This register allows you to enable which planes you want to put sprites on (to move or etc.) and to scroll, or other neato things. If you wanna use all 4 planes, but no sprites, shove $0F into this register. If you want to use all the planes, but want sprites on planes 1 and 3, you would shove $AF into this register. It's very easy to do. ----------- W |$2133: Screen mode register. ????ab?c a: Interlace Y. b: Overscan. c: Interlace X. *** To be blatently honest, I have -NO IDEA- what this register does; I don't understand what Corsair & Dax meant by Interlace and Overscan. If someone can explain this register to me, i'd be very grateful :-). ----------- R |$2139: VRAM port data (reading). $213A: " " ----------- ?? |$2140 *** These are the audio registers. 'never used 'em. ?? |$2141 Try shoving data into them; who knows, if you get ?? |$2142 music sometime, then you know you're on the right ?? |$2143 track. :-) ----------- ?? |$4200: Counter Enable. ??yx???a a: Joypad-read Enable (1 = Readable). x: Horizontal Counter Enable. y: Vertical Counter Enable. ----------- ?? |$4201: 8 bit parallel data. *** This is the expansion bus for the Famicom. ----------- RW |$420B: DMA enable register. abcdefgh a: DMA #7. b: DMA #6. c: DMA #5. d: DMA #4. e: DMA #3. f: DMA #2. g: DMA #1. h: DMA #0. *** I've personally never used DMA for anything. I hope someone out there has, and can tell me how to use it. :-) ----------- ?? |$420D: Memory select. ???????x x: Fast/Normal ROM flip. 0 = Normal. 1 = Fast. ----------- R |$4210: VBL register. x??????? x: VBlank period 1 = On. 0 = Off. *** This is probably the most important register you should work with. Without it, you die, and other things happen. :-) The following routine allows you to sync to the VBL/wait for the VBL to pass by so you can do your work: - LDA $4210 AND #$80 BEQ - LDA $4210 From a programmers' standpoint, the following code should do the EXACT SAME as the above, but faster. NOTE thou, that it doesn't. I think the timing is off, that's why it doesn't work right. But, here-goes: - LDA $4210 BPL - LDA $4210 ----------- ?? |$4211: ?????. x??????? x: IRQ Enable flag (1: Enabled). *** I don't even know the DESCRIPTION of the reg- ister! :-) ----------- RW |$4212: Joypad-ready register. ???????x x: Ready-state bit (1: Ready). *** I'm not sure how this register is setup; all I know is how to use it. Code is as follows: PadLoop LDA $4212 AND #$01 BNE PadLoop This waits for the joypad to become ready to read. ----------- RW |$4218: Joypad #0 register (1 out of 2). abcd0000 a: 0 = A button not pressed. 1 = A button pressed. b: 0 = X button not pressed. 1 = X button pressed. c: 0 = Top-left button not pressed. 1 = Top-left button pressed. d: 0 = Top-right button not pressed. 1 = Top-right button pressed. *** These are self-explainitory. To find out the status of each bit, just AND #$ for that bit... The code for checking is the following: LDA $4218 AND #$80 ; Is the A button pressed? BNE YesA ; Button pressed (bit is 1). LDA $4218 AND #$40 ; Is button X pressed? BNE YesX ; Button pressed (bit is 1). LDA $4218 AND #$10 ; Is the top-right button pressed? BNE YesTopR ; Button pressed (bit is 1). ...and so on. It's very simple. *** Note: The Corsair & Dax document was -WRONG-. It took me a good hour or two to find this out, so I decided i'd better write down the CORRECT way to do things). ----------- RW |$4219: Joypad #0 register (2 out of 2). abcdefgh a: 0 = B button not pressed. 1 = B button pressed. b: 0 = Y button not pressed. 1 = Y button pressed. c: 0 = Select button not pressed. 1 = Select button pressed. d: 0 = Start button not pressed. 1 = Start button pressed. e: 0 = Up not pressed. 1 = Up pressed. f: 0 = Down not pressed. 1 = Down pressed. g: 0 = Left not pressed. 1 = Left pressed. h: 0 = Right not pressed. 1 = Right pressed. *** Same as $4218... Some demo code follows: LDA $4219 AND #$80 ; Is the B button pressed? BNE YesB ; Button pressed (bit is 1). LDA $4219 AND #$04 ; Is Down pressed? BNE YesDown ; Button pressed (bit is 1). LDA $4219 AND #$02 ; Is Left pressed? BNE YesLeft ; Button pressed (bit is 1). ----------- RW |$421A: Joypad #1 register (1 out of 2). RW |$421B: Joypad #1 register (2 out of 2). RW |$421C: Joypad #2 register (1 out of 2). RW |$421D: Joypad #2 register (2 out of 2). RW |$421E: Joypad #3 register (2 out of 2). RW |$421F: Joypad #3 register (2 out of 2). *** Setup is the same as $4218 and $4219. =-=-= 1) Memory Map ii) Additional info. ----------- RW |$FFC0: Cartridge title. RW |$FFD6: ROM/RAM Info on cart.. RW |$FFD7: ROM Size. RW |$FFD8: RAM Size. RW |$FFD9: Maker ID Code. RW |$FFDB: Version #. RW |$FFDC: Checksum complement. RW |$FFDE: Checksum. RW |$FFEA: NMI vector/VBL Interrupt. RW |$FFEC: Reset vector. *** With SMC (Magicom) files the offset is $7e00 less than above. *** I've never actually used this information before: This could be SMC header only; but then why would there be memory locations for such? Strange. I'll leave the information I put in up to SNESASM v1.05. I use the psuedo-ops NAM, VER, and other things. =-=-= 2) SNES Color explaination. ----------- Oh BOY! So you're interested in finding out how the SNES does it's color (via $2122), right? Well here ya go... The SNES has a strange way of doing color (atleast that i've seen in my lifetime). Color is 15 bit; each "RGB" value (red, green, and blue) has 5 bits a piece. When it comes to putting data into $2122, the format (in binary) is the following (I put them into each byte): 0bbbbbgg gggrrrrr | |_ Someone needs to tell me what this bit -REALLY- is. I've just been told to set it to 0... We guess that the Japanese didn't like the idea of putting them in the "standard" order of R, G, then B: but instead wanted them in alphabetical order. Silly! :-). The way -I- do my color conversions is on a calculator... Just plug in the bits you want to set in binary, then let the calc. convert it into hexadecimal. It's pretty easy; or you can be a Studly Programmer (hehehe) and do it in your head. A quick color chart: $7FFF: White (0111 1111 1111 1111) $001F: Red (0000 0000 0001 1111) $03E0: Green (0000 0011 1110 0000) $7C00: Blue (0111 1100 0000 0000) $7C1F: Purple (0111 1100 0001 1111) $7FE0: Aqua (0111 1111 1110 0000) $03FF: Yellow (0000 0011 1111 1111); Well there you have it. It's pretty simple after you get the hang of it; when using the SNES, you get REALLY good with binary math: You'll find this out after working with the machine for awhile. =-=-= 3) DMA Memory Map and explaination. ----------- ?? |$43x0: DMA Control register (??? Not sure ???). W |$43x1: DMA Destination register. $18 = Video Port access. $22 = Color pallete access. *** This gives access to only some of the video chip. registers. Hell if I know which ones. ----------- W |$43x2: Source address. *** THIS REGISTER IS A WORD IN LENGTH *** *** The document I have says: "lo-hi 16 lowest bits". Who knows... ----------- W |$43x4: Source bank address. *** The document I have says: "8 highest bits". ----------- W |$43x5: Transfer size register. *** Same as above: "lo-hi". ----------- All the "x"s represent the DMA # (ranging from 0 to 7). DMA #0: $4300-$4305. DMA #1: $4310-$4315. ...... DMA #7: $4370-$4375. =-=-= 4) SNES Graphics (tiles) explaination. ----------- This is probably the most requested section of the document for people whom are starting out on the SNES and want to learn just how in the hell the SNES -DOES- do it's graphics. There's so much to explain!!! The SNES does it's graphics in tiles (surprise surprise!). There are different MODEs on the SNES; the most famous being is MODE 7. Alas: Most people think using $2106 is MODE 7 ($2106 is for screen pixelation: Where the pixels get "larger". Look in Section 1 for an explaination of this register). *** THIS IS NOT MODE 7!!! ***. So the next time the pixels get really "big" (almost making them look like IBM PC 320x200x256 mode :-)), and your friend says "WOW! MODE 7 is COOL," punch 'em in the nose for me. Just kidding. Also, another thing I should mention: Bitplanes are NOT THE SAME AS PLANES. Planes are like "screens." You can scroll a plane, but not a bitplane. Bitplanes are put ONTO a plane, which can be scrolled any direction. I'll be explaining MODE 1. MODE 7 is too tough for me to explain, since you end up losing colors and other screwy things... Check Section-5 for a mode-# list. MODE #/Playfields MaxColor/Tile Palettes Colors --------------------------------------------------------------------------- 0 4 4 8 16 1 3 16/16/4 (HUH?) 8 128 MODE 0 is good for geometric shapes (if you were going to rotate a wireframe cube), basic star scrolls, or a very "bland" text scroller. Let's start with MODE 1. MODE 1 is best for really basic things: Star scrollers, text scrolls, geometric (non detailed) art, or line drawings; it's only 16 colors/bitplane, and there's only 4 bitplanes to play with. What you need is 4 bitplanes of data. You don't -HAVE- to use 4 bitplanes... You can use 1 bitplane if you want, but you only get 16 colors (NO!!! :-)). You also need a plane map: You can't just have the predefined graphics data and thats it: You have to "setup the plane" to tell it what tile goes where. For demonstration purposes, i'll use code to explain it. ----------- The "lda #$0000" "tcd" transfers the DP location pointer to where the scratchpad RAM is. This makes things go much faster, because DP is always faster than normal RAM (yay for DP!!!) The other part puts where the location of the data in the binary/image is into two DP locations: font and font2. font equ $00 ; Direct page equates. font2 equ font+1 sei phk plb clc xce rep #$30 lda #$0000 tcd lda #charset sta font lda #charset2 sta font2 ----------- The following code tells the SNES where the actual data is in VRAM memory. lda #$10 ; Plane 0 text @ VRAM $1000. sta $2107 lda #$02 ; Tiles for Plane 0 @ VRAM $2000. sta $210b ----------- The following code actually MOVES the data in the binary/image into the SNES's VRAM. sep #$20 ldx #$2000 ; This puts the data sent thru $2118 and ; $2119 into VRAM $2000. stx $2116 ldy #$0000 - lda (font),y ; Get bitplane 0 data (font) sta $2118 ; ... and store it in bitplane 0. lda (font2),y ; Get bitplane 1 data (font2) sta $2119 ; ... and store it in bitplane 1... stz $2118 ; I don't want to use bitplane 2 and 3, stz $2119 ; so I store zeros here. You could put ; more font data in there if you wanted. iny cpy #$0200 bne - ldx #$1000 ; This puts the data sent thru $2118 and stx $2116 ; $2119 into VRAM $1000. ldx #$0000 - lda TEXT,x ; Get the character from TEXT... and #$3f ; AND #$3F because we only want the first ; 64 characters in the font. sta $2118 ; stz $2119 ; Check near the end of this Section for ; an explaination on what the actual bits ; do instead of just storing 0 there all ; the time. inx cpx #$0400 bne - ----------- Here's the actual data names (charset, charset2, and TEXT). My new source has them in dcb % statements to make the font more readable: The first time I did this, I had to convert the binary stuff I wrote on paper into hex, then put them into decent hex statements in an orderly fashion. charset dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'@' dcb $00,$3c,$66,$7e,$66,$66,$66,$00 ;'A' dcb $00,$7c,$66,$7c,$66,$66,$7c,$00 ;'B' dcb $00,$3c,$66,$60,$60,$66,$3c,$00 ;'C' dcb $00,$78,$6c,$66,$66,$6c,$78,$00 ;'D' dcb $00,$7e,$60,$78,$60,$60,$7e,$00 ;'E' dcb $00,$7e,$60,$78,$60,$60,$60,$00 ;'F' dcb $00,$3c,$66,$60,$6e,$66,$3c,$00 ;'G' dcb $00,$66,$66,$7e,$66,$66,$66,$00 ;'H' dcb $00,$3c,$18,$18,$18,$18,$3c,$00 ;'I' dcb $00,$1e,$0c,$0c,$0c,$6c,$38,$00 ;'J' dcb $00,$6c,$78,$70,$78,$6c,$66,$00 ;'K' dcb $00,$60,$60,$60,$60,$60,$7e,$00 ;'L' dcb $00,$63,$77,$7f,$6b,$63,$63,$00 ;'M' dcb $00,$66,$76,$7e,$7e,$6e,$66,$00 ;'N' dcb $00,$3c,$66,$66,$66,$66,$3c,$00 ;'O' dcb $00,$7c,$66,$66,$7c,$60,$60,$00 ;'P' dcb $00,$3c,$66,$66,$66,$3c,$0e,$00 ;'Q' dcb $00,$7c,$66,$66,$7c,$6c,$66,$00 ;'R' dcb $00,$3e,$60,$3c,$06,$66,$3c,$00 ;'S' dcb $00,$7e,$18,$18,$18,$18,$18,$00 ;'T' dcb $00,$66,$66,$66,$66,$66,$3c,$00 ;'U' dcb $00,$66,$66,$66,$66,$3c,$18,$00 ;'V' dcb $00,$63,$63,$6b,$7f,$77,$63,$00 ;'W' dcb $00,$66,$3c,$18,$3c,$66,$66,$00 ;'X' dcb $00,$66,$66,$3c,$18,$18,$18,$00 ;'Y' dcb $00,$7e,$0c,$18,$30,$60,$7e,$00 ;'Z' dcb $08,$00,$00,$00,$00,$00,$00,$00 ;'[' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'\' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;']' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'^' dcb $00,$08,$00,$00,$00,$00,$00,$00 ;'_' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;' ' dcb $00,$7E,$7E,$3C,$18,$00,$18,$00 ;'!' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'"' dcb $80,$80,$80,$80,$80,$80,$80,$80 ;'#' dcb $FC,$FE,$FF,$F7,$F7,$FF,$FE,$FC ;'$' dcb $3E,$42,$4E,$5C,$5C,$4E,$42,$3E ;'%' dcb $00,$00,$00,$00,$00,$00,$00,$01 ;'&' dcb $00,$00,$00,$07,$00,$00,$00,$00 ;''' dcb $00,$04,$08,$08,$08,$08,$04,$00 ;'(' dcb $00,$20,$10,$10,$10,$10,$20,$00 ;')' dcb $08,$08,$08,$F8,$08,$08,$08,$08 ;'*' dcb $10,$10,$10,$1F,$10,$10,$10,$10 ;'+' dcb $10,$10,$20,$C0,$00,$00,$00,$00 ;',' dcb $00,$00,$00,$FF,$00,$00,$00,$00 ;'-' dcb $00,$00,$00,$00,$00,$18,$18,$00 ;'.' dcb $00,$00,$00,$FF,$80,$80,$80,$80 ;'/' dcb $00,$3c,$66,$6e,$76,$66,$3c,$00 ;'0' dcb $00,$18,$38,$18,$18,$18,$7e,$00 ;'1' dcb $00,$7c,$06,$0c,$30,$60,$7e,$00 ;'2' dcb $00,$7e,$06,$1c,$06,$66,$3c,$00 ;'3' dcb $00,$0e,$1e,$36,$7f,$06,$06,$00 ;'4' dcb $00,$7e,$60,$7c,$06,$66,$3c,$00 ;'5' dcb $00,$3e,$60,$7c,$66,$66,$3c,$00 ;'6' dcb $00,$7e,$06,$0c,$0c,$0c,$0c,$00 ;'7' dcb $00,$3c,$66,$3c,$66,$66,$3c,$00 ;'8' dcb $00,$3c,$66,$3e,$06,$66,$3c,$00 ;'9' dcb $00,$00,$00,$03,$04,$08,$08,$08 ;':' dcb $00,$80,$80,$F0,$80,$80,$00,$00 ;';' dcb $80,$80,$80,$FF,$00,$00,$00,$00 ;'<' dcb $00,$00,$00,$C0,$20,$10,$10,$10 ;'=' dcb $08,$08,$04,$03,$00,$00,$00,$00 ;'>' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'?' charset2 dcb $00,$3C,$4E,$5E,$5E,$40,$3C,$00 ;'@' dcb $00,$3c,$66,$7e,$66,$66,$66,$00 ;'A' dcb $00,$7c,$66,$7c,$66,$66,$7c,$00 ;'B' dcb $00,$3c,$66,$60,$60,$66,$3c,$00 ;'C' dcb $00,$78,$6c,$66,$66,$6c,$78,$00 ;'D' dcb $00,$7e,$60,$78,$60,$60,$7e,$00 ;'E' dcb $00,$7e,$60,$78,$60,$60,$60,$00 ;'F' dcb $00,$3c,$66,$60,$6e,$66,$3c,$00 ;'G' dcb $00,$66,$66,$7e,$66,$66,$66,$00 ;'H' dcb $00,$3c,$18,$18,$18,$18,$3c,$00 ;'I' dcb $00,$1e,$0c,$0c,$0c,$6c,$38,$00 ;'J' dcb $00,$6c,$78,$70,$78,$6c,$66,$00 ;'K' dcb $00,$60,$60,$60,$60,$60,$7e,$00 ;'L' dcb $00,$63,$77,$7f,$6b,$63,$63,$00 ;'M' dcb $00,$66,$76,$7e,$7e,$6e,$66,$00 ;'N' dcb $00,$3c,$66,$66,$66,$66,$3c,$00 ;'O' dcb $00,$7c,$66,$66,$7c,$60,$60,$00 ;'P' dcb $00,$3c,$66,$66,$66,$3c,$0e,$00 ;'Q' dcb $00,$7c,$66,$66,$7c,$6c,$66,$00 ;'R' dcb $00,$3e,$60,$3c,$06,$66,$3c,$00 ;'S' dcb $00,$7e,$18,$18,$18,$18,$18,$00 ;'T' dcb $00,$66,$66,$66,$66,$66,$3c,$00 ;'U' dcb $00,$66,$66,$66,$66,$3c,$18,$00 ;'V' dcb $00,$63,$63,$6b,$7f,$77,$63,$00 ;'W' dcb $00,$66,$3c,$18,$3c,$66,$66,$00 ;'X' dcb $00,$66,$66,$3c,$18,$18,$18,$00 ;'Y' dcb $00,$7e,$0c,$18,$30,$60,$7e,$00 ;'Z' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'[' dcb $09,$09,$00,$00,$00,$00,$00,$00 ;'\' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;']' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'^' dcb $00,$08,$00,$00,$00,$00,$00,$00 ;'_' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;' ' dcb $00,$7E,$7E,$3C,$18,$00,$18,$00 ;'!' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'"' dcb $80,$80,$80,$80,$80,$80,$80,$80 ;'#' dcb $FC,$FE,$FF,$F7,$F7,$FF,$FE,$FC ;'$' dcb $3E,$42,$4E,$5C,$5C,$4E,$42,$3E ;'%' dcb $00,$00,$00,$00,$00,$00,$00,$01 ;'&' dcb $00,$00,$00,$07,$00,$00,$00,$00 ;''' dcb $00,$04,$08,$08,$08,$08,$04,$00 ;'(' dcb $00,$20,$10,$10,$10,$10,$20,$00 ;')' dcb $08,$08,$08,$F8,$08,$08,$08,$08 ;'*' dcb $10,$10,$10,$1F,$10,$10,$10,$10 ;'+' dcb $10,$10,$20,$C0,$00,$00,$00,$00 ;',' dcb $00,$00,$00,$FF,$00,$00,$00,$00 ;'-' dcb $00,$00,$00,$00,$00,$18,$18,$00 ;'.' dcb $00,$00,$00,$FF,$80,$80,$80,$80 ;'/' dcb $00,$3c,$66,$6e,$76,$66,$3c,$00 ;'0' dcb $00,$18,$38,$18,$18,$18,$7e,$00 ;'1' dcb $00,$7c,$06,$0c,$30,$60,$7e,$00 ;'2' dcb $00,$7e,$06,$1c,$06,$66,$3c,$00 ;'3' dcb $00,$0e,$1e,$36,$7f,$06,$06,$00 ;'4' dcb $00,$7e,$60,$7c,$06,$66,$3c,$00 ;'5' dcb $00,$3e,$60,$7c,$66,$66,$3c,$00 ;'6' dcb $00,$7e,$06,$0c,$0c,$0c,$0c,$00 ;'7' dcb $00,$3c,$66,$3c,$66,$66,$3c,$00 ;'8' dcb $00,$3c,$66,$3e,$06,$66,$3c,$00 ;'9' dcb $00,$00,$00,$03,$04,$08,$08,$08 ;':' dcb $00,$80,$80,$F0,$80,$80,$00,$00 ;';' dcb $80,$80,$80,$FF,$00,$00,$00,$00 ;'<' dcb $00,$00,$00,$C0,$20,$10,$10,$10 ;'=' dcb $08,$08,$04,$03,$00,$00,$00,$00 ;'>' dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'?' TEXT dcb " THIS IS YOUR ENTIRE SCREEN " dcb " HERE... IF YOU REMOVE ONE OF " dcb " THE LINES WHICH IS BLANK, THE " dcb " SCREEN ENDS UP BEING FUNKY " dcb " DOWN AT THE BOTTOM OF THE " dcb " SCREEN. " dcb " " dcb " SO MAKE SURE YOU ALWAYS LEAVE " dcb " ALL OF THIS TEXT THINGS IN! " dcb " " dcb " " dcb " " dcb " YOSHI THE DINO " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb " " dcb "********************************" dcb " " dcb " " ----------- Well there's some code for those whom want to rip it :-). I hope I haven't confused you yet: If I have, go back and re-read the code. I've been working with the SNES for awhile, so I under- stand a little more than a beginner. You're probably wondering how the heck the following line ends up being an "@" on your TV, or whatever you have your SNES hooked up to. Lets look at charset and charset2. charset dcb $00,$00,$00,$00,$00,$00,$00,$00 ;'@' charset2 dcb $00,$3C,$4E,$5E,$5E,$40,$3C,$00 ;'@' Convert charsets hex-statements into binary. Consider each new "$xx" statement a new pixel line. Tile size is 8x8. 00000000 = $00 00000000 = $00 00000000 = $00 00000000 = $00 00000000 = $00 00000000 = $00 00000000 = $00 00000000 = $00 Convert charset2s hex-statements into binary. 00000000 = $00 00111100 = $3C 01001110 = $4E 01011110 = $5E 01011110 = $5E 01000000 = $40 00111100 = $3C 00000000 = $00 *NOW* do you see the at-symbol? (and yes, I -DID- draw all of the font by hand. It took me HOURS, but I did it). You're probably now asking: "Well, that tells me how to define where a pixel IS: but how do I define it's color?" This is the fun part. It's sort-of hard to explain: If you have a 0 for bitplane 0, a 0 for bitplane 1, a 0 for bitplane 2, and a 0 for bitplane 3, you get the color 0. i.e.: 0000 = Color #0 ||||___________Bitplane 0 |||__________Bitplane 1 ||_________Bitplane 2 |________Bitplane 3 So, think about a 0 for bitplane 0, a 1 for bitplane 1 & 2 and a 0 for bitplane 3. i.e.: 0110 = Color #6 ||||___________Bitplane 0 |||__________Bitplane 1 ||_________Bitplane 2 |________Bitplane 3 This is probably the best explaination i've ever seen done about SNES pixel-color definition, so don't plan on seeing one any better anytime soon :-). Anyway, the result above gives you the color # per pixel; it's fairly interesting... it's like an "overlay" type of method. I mentioned in the source above that you should check near the end of the Section for info on why I "stz $2119". Well, here's why: The bits in the tile-data are fairly "silly": The tile "character" itself is 10 bits, while the other 6 are "fun bits," as I call them. Here's the explaination: yx?cccNN | NNNNNNNN y: Flip the tile vertically. x: Flip the tile horiztonally. ?: Dunno! Set it to 1 and find out. c: Pallete # (0-7). N: Character itself. So, I STZ there: Yes, I leave the top bits "unset," which means you could get messed up data, but as far as I have checked, the SNES has "clear memory" when you start it up: So the bits I don't zero-out should be zeros anyways! :-) If you want to set them, feel free to do so! The results of flipping Y and X are sortof fun to play with. "To read this scrolly, you must stand on your head" :-) =-=-= 5) SNES Screen mode definitions. ----------- MODE # of bitplanes Colors per plane Palletes Max. # of colors --------------------------------------------------------------------------- 0 2 4 8 32 1 4 16 8 128 2 ? ??? ? ??? 3 8 256 1 256 4 ? ??? ? ??? 5 ? ??? ? ??? 6 ? 16 8 128 (Interlaced mode) 7 ? 256 1 256 (Yes, MODE 7) --------------------------------------------------------------------------- The parms which have "?" or "???" mean I don't know what they REALLY are: I got a document which explained them, but it was bogus: It said a 16 color mode had -1- bitplane. Weird... I'm not even sure about MODE 6. But, we know what MODE 7 is, even if I'm not sure how many bitplanes it DOES use (the doc says 1, I say 8). I've tested MODE 0 and 1 myself. MODE 3 I might test in the future, but i've never had the desire to draw up 8 bitplanes of data by hand ( I don't have a SNES-graphics-generator for the PC! :-( ). =-=-= 6) SNES OAM/Sprite explaination. ----------- The sprites use a lookup table that contains info on their X and Y position on the screen, their size, if they're flipped horizontally or vertically, their color, and the actual character. The format you need to make the table in is as follows: Size Address/Offset Explaination --------------------------------------------------------------------------- *** SPRITE 0 *** BYTE 0 xxxxxxxx x: X location. BYTE 1 yyyyyyyy y: Y location. WORD 2+3 abcdeeex | xxxxxxxx a: Vertical flip. b: Horizontal flip. c: Playfield priority. d: Playfield priority. e: Pallete #. x: Character #. *** SPRITE 0 *** BYTE 4 xxxxxxxx x: X location. BYTE 5 yyyyyyyy y: Y location. ....... and so on ....... --------------------------------------------------------------------------- Continue this table all the way down to sprite #127 (the 128th sprite). Don't think you're