Add missing docs
This commit is contained in:
27
files/docs/snes/yoshi/READ.ME
Normal file
27
files/docs/snes/yoshi/READ.ME
Normal file
@@ -0,0 +1,27 @@
|
||||
*****************************************************************************
|
||||
SNES Documentation v2.30: Written by Yoshi
|
||||
*****************************************************************************
|
||||
Previous version: v2.21
|
||||
The follow files are included (or should be!) in this archive:
|
||||
[* = Updated since previous version]
|
||||
|
||||
* snes.0.............Introduction
|
||||
* snes.1.............SNES Register section
|
||||
* snes.2.............SNES Colour section
|
||||
* snes.3.............SNES Graphics section
|
||||
* snes.4.............SNES Screen-mode section
|
||||
* snes.5.............SNES OAM/Sprite section
|
||||
* snes.6.............Super Magicomm disk registers
|
||||
-=NEW=- snes.7.............SNES Memory map
|
||||
-=NEW=- snes.8.............Those boring credits/thank-yous/hellos! :-)
|
||||
sound.doc..........SPC-700 (sound) documentation by Antitrack
|
||||
sprite.doc.........OBJ/OAM documentation
|
||||
-=NEW=- test.lzh...........Mini "demo" by yours-truly. Comes with source,
|
||||
music, graphics, and the SMC file.
|
||||
-=NEW=- sid-spc.src........C64 sound emulator documentation/code by Antitrack
|
||||
*****************************************************************************
|
||||
All sections are formatted using whitespaces vs. actual tab characters. This
|
||||
is due to the fact that some people have their tabs set to 4 or 5 spaces
|
||||
rather than the vi-standard of 8.
|
||||
|
||||
'sound.doc', 'sprite.doc', and 'sid-spc.src' are not formatted this way.
|
||||
1072
files/docs/snes/yoshi/SID-SPC.SRC
Normal file
1072
files/docs/snes/yoshi/SID-SPC.SRC
Normal file
File diff suppressed because it is too large
Load Diff
70
files/docs/snes/yoshi/SNES.0
Normal file
70
files/docs/snes/yoshi/SNES.0
Normal file
@@ -0,0 +1,70 @@
|
||||
_________________ _________________ _________________ _________________
|
||||
| || || || |
|
||||
| || || || |
|
||||
| __________|| || _________|| ___________|
|
||||
| | | || / |
|
||||
| || | || / | |
|
||||
__________ || | || ___/_____ ___________ |
|
||||
| || | || || |
|
||||
| || | || || |
|
||||
|_________________||________|________||_________________||_________________|
|
||||
****************************************************************************
|
||||
SNES Documentation v2.30: Written by Yoshi
|
||||
****************************************************************************
|
||||
Well, seems like you're interested in the SNES programming world.
|
||||
|
||||
First off, learn 65c816 assembly. This document will probably be
|
||||
WAY over your head if you don't even understand basic opcodes. I
|
||||
don't plan on adding a "how.to.code.in.65c816" section to this
|
||||
document, *EVER*. Learn it yourself. I can help you with it, but
|
||||
you need to learn the basics yourself. It's worth it in the long-
|
||||
run, trust me.
|
||||
|
||||
This document currently covers more than ANY other document i've
|
||||
ever seen: No, i'm not bragging. I'm stating a fact. I'm proud to be
|
||||
the one to release this information, too. I feel everyone has the
|
||||
right to know about all of this, especially if they're interested in
|
||||
getting a career in the SNES-world.
|
||||
|
||||
If you have any information to send me, such as typo comments, or
|
||||
information which is "wrong" or *NEW* information, do so! I'm always
|
||||
updating this thing: the more the better. It's looking great so
|
||||
far, and I plan on keeping the rate-of-progress steady.
|
||||
|
||||
For more information about moi, read on! :-)
|
||||
****************************************************************************
|
||||
I'm 17 years old; brown hair, blue/grey eyes. 5 foot 10 inches
|
||||
tall (175cm), 145 pounds (62.25kg). I am currently in my 5th
|
||||
year of high school (I failed my senior year), attending Corvallis
|
||||
High School in Corvallis, Oregon.
|
||||
|
||||
I'm currently without a job, but i'd love to do development work
|
||||
in a CS-related job, ESPECIALLY SNES-related. I'm available! :-)
|
||||
|
||||
In my spare time, I enjoy writing stories (books, if you must know.
|
||||
I love writing, so...), SNES documentation (ha ha ha), programming
|
||||
(in just about anything and everything), biking, sleeping, sketch-
|
||||
ing, and IRCing. You can *ALWAYS* find me on IRC at just about ANY
|
||||
time of the day. Leave me a /MSG -info note (which is sent to me
|
||||
via EMail, FYI), and i'll get it when I log in to check my mail.
|
||||
|
||||
As of January 24th, 1995, I will be 18 years old. I'm not employed
|
||||
(vs. unemployed, where you've actually HAD a job). Dunno what'll
|
||||
happen to me. Maybe i'll die. Who knows. I hope to move in with
|
||||
a good friend of mine, but i'm too chicken to ask. I'd rather be
|
||||
out on the street w/out foot than be told "No you can't" - it's a
|
||||
huge flaw in my philosophy... Sorry.
|
||||
|
||||
You can reach via the following ways:
|
||||
InterNET: yoshi@CSOS.ORST.EDU (fast, and is preferred)
|
||||
yoshi@drift.winternet.com
|
||||
IRC: Yoshi
|
||||
Phone: 1+ 503-753-2431
|
||||
SnailMail: Jeremy Chadwick
|
||||
33811 Twin Maple Lane
|
||||
Corvallis, OR 97333
|
||||
USA
|
||||
****************************************************************************
|
||||
|
||||
December 28th, 1994
|
||||
- Yoshi
|
||||
606
files/docs/snes/yoshi/SNES.1
Normal file
606
files/docs/snes/yoshi/SNES.1
Normal file
@@ -0,0 +1,606 @@
|
||||
----------------------------------------------------------------------------
|
||||
|rwd2?|Address|Title & Explanation |
|
||||
||||||-----------------------------------------------------------------------|
|
||||
|||||| |
|
||||
||||||__ ?: Don't know what the statistics on this register are |
|
||||
|||||____ 2: 2 byte (1 word) length register |
|
||||
||||_____ d: Double-byte write required when writing to this register |
|
||||
|||______ w: Writable register |
|
||||
||_______ r: Readable register |
|
||||
| |
|
||||
|Words in brackets ( [] ) are the official "names" of the registers |
|
||||
|Words in braces ( {} ) are different from the "real" SNES manual |
|
||||
|Bits define 1 as "ON/ENABLE" and 0 as "OFF/DISABLE," unless otherwise stated|
|
||||
|Registers without any bits/defined-data can be assumed to be 8 bits in size |
|
||||
|and should only be read once. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|NOTE! I have renamed all occurances of "Plane {x}" to "BG{x+1}." This means |
|
||||
|stuff like "Plane 2" is now referred to as "BG3" - This is how it is done |
|
||||
|(so i'm told) in the official SNES documentation, so for compatibility and |
|
||||
|comprehension, i've renamed everything. |
|
||||
| |
|
||||
|I have also renamed "Sprites" to "OBJ", "objects," or "OAM" for the same |
|
||||
|reason that I renamed "Plane" to "BG." |
|
||||
|----------------------------------------------------------------------------|
|
||||
|rwd2?|Address|Title & Explanation |
|
||||
|----------------------------------------------------------------------------|
|
||||
| w |$2100 |Screen display register [INIDISP] |
|
||||
| | |x000bbbb x: 0 = Screen on. |
|
||||
| | | 1 = Screen off. |
|
||||
| | | bbbb: Brightness ($0-$F). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2101 |OAM size register [OBSEL] |
|
||||
| | |sssnnbbb s: 000 = 8x8 or 16x16. |
|
||||
| | | 001 = 8x8 or 32x32. |
|
||||
| | | 010 = 8x8 or 64x64. |
|
||||
| | | 011 = 16x16 or 32x32. |
|
||||
| | | 100 = 16x16 or 64x64. |
|
||||
| | | 101 = 32x32 or 64x64. |
|
||||
| | | n: Name selection (upper 4k word addr). |
|
||||
| | | b: Base selection (8k word seg. addr). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$2102 |OAM address register [OAMADDL/OAMADDH] |
|
||||
| | |aaaaaaaa r000000m a: OAM address. |
|
||||
| | | r: OAM priority rotation. |
|
||||
| | | m: OAM address MSB. |
|
||||
| | | |
|
||||
| | | |
|
||||
| wd |$2104 |OAM data register [OAMDATA] |
|
||||
| | |???????? ???????? |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2105 |Screen mode register [BGMODE] |
|
||||
| | |abcdefff a: BG4 tile size (0=8x8, 1=16x16). |
|
||||
| | | b: BG3 tile size (0=8x8, 1=16x16). |
|
||||
| | | c: BG2 tile size (0=8x8, 1=16x16). |
|
||||
| | | d: BG1 tile size (0=8x8, 1=16x16). |
|
||||
| | | e: Highest priority for BG3 in MODE 1. |
|
||||
| | | f: MODE definition. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2106 |Screen pixelation register [MOSAIC] |
|
||||
| | |xxxxabcd x: Pixel size (0=Smallest, $F=Largest). |
|
||||
| | | a: Affect BG4. |
|
||||
| | | b: Affect BG3. |
|
||||
| | | c: Affect BG2. |
|
||||
| | | d: Affect BG1. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2107 |BG1 VRAM location register [BG1SC] |
|
||||
| | |xxxxxxab x: Base address |
|
||||
| | | ab: SC size |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2108 |BG2 VRAM location register [BG2SC] -| |
|
||||
| w |$2109 |BG3 VRAM location register [BG3SC] |- Same as $2107. |
|
||||
| w |$210A |BG4 VRAM location register [BG4SC] -| |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$210B |BG1 & BG2 VRAM location register [BG12NBA] |
|
||||
| | |aaaabbbb a: Base address for BG2. |
|
||||
| | | b: Base address for BG1. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$210C |BG3 & BG4 VRAM location register [BG34NBA] |
|
||||
| | |aaaabbbb a: Base address for BG4. |
|
||||
| | | b: Base address for BG3. |
|
||||
| | | |
|
||||
| | | |
|
||||
| wd |$210D |BG1 horizontal scroll register [BG1HOFS] |
|
||||
| | |mmmmmaaa aaaaaaaa a: Horizontal offset. |
|
||||
| | | m: Only set with MODE 7. |
|
||||
| | | |
|
||||
| | |This is an intruiging register. Like the types define, it has |
|
||||
| | |to be written to twice: The first byte holds the first 8 bits,|
|
||||
| | |and the second byte holds the last 3 bits. This makes a total |
|
||||
| | |of 11 bits for information. This only proves true for MODes |
|
||||
| | |0 to 6. MODE 7 uses 13 bits instead of 11. As long as you're |
|
||||
| | |not in MODE 7, you can store $00 in the 2nd byte for a smooth |
|
||||
| | |scrolling background. |
|
||||
| | | |
|
||||
| | | |
|
||||
| wd |$210E |BG1 vertical scroll register [BG1VOFS] -| |
|
||||
| wd |$210F |BG2 horizontal scroll register [BG2HOFS] | |
|
||||
| wd |$2110 |BG3 vertical scroll register [BG2VOFS] | |
|
||||
| wd |$2111 |BG3 horizontal scroll register [BG3HOFS] |- Same as $210D. |
|
||||
| wd |$2112 |BG3 vertical scroll register [BG3VOFS] | |
|
||||
| wd |$2113 |BG4 horizontal scroll register [BG4HOFS] | |
|
||||
| wd |$2114 |BG4 vertical scroll register [BG4VOFS] -| |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2115 |Video port control [VMAIN] |
|
||||
| | |i000abcd i: 0 = Addr-inc after writing to $2118 |
|
||||
| | | or reading from $2139. |
|
||||
| | | 1 = Addr-inc after writing to $2119 |
|
||||
| | | or reading from $213A. |
|
||||
| | | ab: Full graphic (see table below). |
|
||||
| | | cd: SC increment (see table below). |
|
||||
| | |abcd|Result |
|
||||
| | |----|---------------------------------------------------------|
|
||||
| | |0100|Increment by 8 for 32 times (2-bit formation). |
|
||||
| | |1000|Increment by 8 for 64 times (4-bit formation). |
|
||||
| | |1100|Increment by 8 for 128 times (8-bit formation). |
|
||||
| | |0000|Address increments 1x1. |
|
||||
| | |0001|Address increments 32x32. |
|
||||
| | |0010|Address increments 64x64. |
|
||||
| | |0011|Address increments 128x128. |
|
||||
| | |----|---------------------------------------------------------|
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$2116 |Video port address [VMADDL/VMADDH] |
|
||||
| | |???????? ???????? |
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$2118 |Video port data [VMDATAL/VMDATAH] |
|
||||
| | |???????? ???????? |
|
||||
| | | |
|
||||
| | |According to bit 7 of $2115, the data can be stored as: |
|
||||
| | | |
|
||||
| | |Bit 7|Register |Result |
|
||||
| | |-----|---------------------------|----------------------------|
|
||||
| | | 0 |Write to $2118 only. |Lower 8-bits written then |
|
||||
| | | | |address is increased. |
|
||||
| | | 0 |Write to $2119 then $2118. |Address increased when both |
|
||||
| | | | |are written to (in order). |
|
||||
| | | 1 |Write to $2119 only. |Upper 8-bits written, then |
|
||||
| | | | |address is increased. |
|
||||
| | | 1 |Write to $2118 then $2119. |Address increased when both |
|
||||
| | | | |are written to (in order). |
|
||||
| | |-----|---------------------------|----------------------------|
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$211A |MODE7 settings register [M7SEL] |
|
||||
| | |ab0000yx ab: (see table below). |
|
||||
| | | y: Vertical screen flip (1=flip). |
|
||||
| | | x: Horizontal screen flip (1=flip). |
|
||||
| | | |
|
||||
| | |ab|Result |
|
||||
| | |--|-----------------------------------------------------------|
|
||||
| | |00|Screen repetition if outside of screen area. |
|
||||
| | |10|Character 0x00 repetition if outside of screen area. |
|
||||
| | |11|Outside of screen area is back-drop screen in 1 colour. |
|
||||
| | |--|-----------------------------------------------------------|
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$211B |COS (COSINE) rotate angle / X Expansion [M7A] |
|
||||
| w |$211C |SIN (SIN) rotate angle / X Expansion [M7B] |
|
||||
| w |$211D |SIN (SIN) rotate angle / Y Expansion [M7C] |
|
||||
| w |$211E |COS (COSINE) rotate angle / Y Expansion [M7D] |
|
||||
| wd |$211F |Center position X (13-bit data only) [M7X] |
|
||||
| wd |$2120 |Center position Y (13-bit data only) [M7Y] |
|
||||
| | | |
|
||||
| | |MODE 7 formulae for rotation/enlargement/reduction: |
|
||||
| | | |
|
||||
| | |X2 = AB * X1-X0 + X0 |
|
||||
| | |Y2 = CD * Y1-Y0 + Y0 |
|
||||
| | | |
|
||||
| | |A = COS(GAMMA)*(1/ALPHA) B = SIN(GAMMA)*(1/ALPHA) |
|
||||
| | |C = SIN(GAMMA)*(1/BETA) D = COS(GAMMA)*(1/BETA) |
|
||||
| | | |
|
||||
| | | GAMMA: Rotation angle. |
|
||||
| | | ALPHA: Reduction rates for X (horizontal). |
|
||||
| | | BETA: Reduction rates for Y (vertical). |
|
||||
| | |X0 & Y0: Center coordinate. |
|
||||
| | |X1 & Y1: Display coordinate. |
|
||||
| | |X2 & Y2: Coordinate before calculation. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2121 |Colour # (or pallete) selection register [CGADD] |
|
||||
| | |xxxxxxxx x: Address (color #). |
|
||||
| | | |
|
||||
| | | |
|
||||
| wd |$2122 |Colour data register [CGDATA] |
|
||||
| | |xxxxxxxx x: Value of colour. |
|
||||
| | | |
|
||||
| | |SNES colour is 15 bit; 5 bits for red, green, and blue. The |
|
||||
| | |order isn't RGB though: It's BGR (RGB reversed!). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2123 |Window mask settings register [W12SEL] |
|
||||
| | |abcdefgh a: Disable/enable BG2 Window 2. |
|
||||
| | | b: BG2 Window 2 I/O (0=IN). |
|
||||
| | | c: Disable/enable BG2 Window 1. |
|
||||
| | | d: BG2 Window 1 I/O (0=IN). |
|
||||
| | | e: Disable/enable BG1 Window 2. |
|
||||
| | | f: BG1 Window 2 I/O (0=IN). |
|
||||
| | | g: Disable/enable BG1 Window 1. |
|
||||
| | | h: BG1 Window 1 I/O (0=IN). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2124 |Window mask settings register [W34SEL] |
|
||||
| | |abcdefgh a: Disable/enable BG4 Window 2. |
|
||||
| | | b: BG4 Window 2 I/O (0=IN). |
|
||||
| | | c: Disable/enable BG4 Window 1. |
|
||||
| | | d: BG4 Window 1 I/O (0=IN). |
|
||||
| | | e: Disable/enable BG3 Window 2. |
|
||||
| | | f: BG3 Window 2 I/O (0=IN). |
|
||||
| | | g: Disable/enable BG3 Window 1. |
|
||||
| | | h: BG3 Window 1 I/O (0=IN). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2125 |Window mask settings register [WOBJSEL] |
|
||||
| | |abcdefgh a: Disable/enable colour Window 2. |
|
||||
| | | b: Colour Window 2 I/O (0=IN). |
|
||||
| | | c: Disable/enable colour Window 1. |
|
||||
| | | d: Colour Window 1 I/O (0=IN). |
|
||||
| | | e: Disable/enable OBJ Window 2. |
|
||||
| | | f: OBJ Window 2 I/O (0=IN). |
|
||||
| | | g: Disable/enable OBJ Window 1. |
|
||||
| | | h: OBJ Window 1 I/O (0=IN). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2126 |Window 1 left position register [WH0] |
|
||||
| | |aaaaaaaa a: Position. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2127 |Window 1 right position register [WH1] -| |
|
||||
| w |$2128 |Window 2 left position register [WH2] |- Same as $2126. |
|
||||
| w |$2129 |Window 2 right position register [WH3] -| |
|
||||
| | | |
|
||||
| | |I may have the Window numbers reversed; as in, $2126 may be |
|
||||
| | |for Window 2, not Window 1; $2127 may be for Window 2, not |
|
||||
| | |Window 1... and so on... |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$212A |Mask logic settings for Window 1 & 2 per screen [WBGLOG] |
|
||||
| | |aabbccdd a: BG4 parms -| |
|
||||
| | | b: BG3 parms |- See table in $212B. |
|
||||
| | | c: BG2 parms | |
|
||||
| | | d: BG1 parms -| |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$212B |Mask logic settings for Colour Windows & OBJ Windows [WOBJLOG]|
|
||||
| | |0000aabb a: Colour Window parms (see table below)|
|
||||
| | | b: OBJ Window parms (see table below). |
|
||||
| | | |
|
||||
| | |Hi-bit|Lo-bit|Logic |
|
||||
| | |------|------|------------------------------------------------|
|
||||
| | | 0 | 0 |OR |
|
||||
| | | 0 | 1 |AND |
|
||||
| | | 1 | 0 |XOR |
|
||||
| | | 1 | 1 |XNOR |
|
||||
| | |------|------|------------------------------------------------|
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$212C |Main screen designation [TM] |
|
||||
| | |000abcde a: OBJ/OAM disable/enable. |
|
||||
| | | b: Disable/enable BG4. |
|
||||
| | | c: Disable/enable BG3. |
|
||||
| | | d: Disable/enable BG2. |
|
||||
| | | e: Disable/enable BG1. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$212D |Sub-screen designation [TD] |
|
||||
| | |*** Same as $212C, but for the sub-screens, not the main. |
|
||||
| | | |
|
||||
| | |Remember: When screen addition/subtraction is enabled, the |
|
||||
| | |sub screen is added/subtracted against the main screen. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$212E |Window mask main screen designation register [TMW] |
|
||||
| | |*** Same as $212C, but for window-masks. |
|
||||
| | | |
|
||||
| w |$212F |Window mask sub screen designation register [TSW] |
|
||||
| | |*** Same as $212E, but for the sub screen. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2130 |Fixed color addition or screen addition register [CGWSEL] |
|
||||
| | |abcd00ef ab: Main (see table below). |
|
||||
| | | cd: Sub (see table below). |
|
||||
| | | e: 0 = Enable +/- for fixed colour. |
|
||||
| | | 1 = Enable +/- for sub screen. |
|
||||
| | | f: Colour & char-data = direct color |
|
||||
| | | data (MODE 3, 4 & 7 only). |
|
||||
| | | |
|
||||
| | |ab|Result |
|
||||
| | |--|-----------------------------------------------------------|
|
||||
| | |00|All the time. |
|
||||
| | |01|Inside window only. |
|
||||
| | |10|Outside window only. |
|
||||
| | |11|All the time. |
|
||||
| | |--|-----------------------------------------------------------|
|
||||
| | | |
|
||||
| w |$2131 |Addition/subtraction for screens, BGs, & OBJs [CGADSUB] |
|
||||
| | |mrgsabcd m: 0 = Enable + colour-data mode. |
|
||||
| | | 1 = Enable - colour-data mode. |
|
||||
| | | r: See below for more info. |
|
||||
| | | g: Affect back-area. |
|
||||
| | | s: Affect OBJs. |
|
||||
| | | a: Affect BG4. |
|
||||
| | | b: Affect BG3. |
|
||||
| | | c: Affect BG2. |
|
||||
| | | d: Affect BG1. |
|
||||
| | | |
|
||||
| | |*** 'r' is some sort-of "1/2 of colour data" on/off bit. When |
|
||||
| | | the colour constant +/- or screen +/- is performed, desig-|
|
||||
| | | nate whether the RGB result in the +/- area should be 1/2 |
|
||||
| | | or not; the back-area is not affected. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2132 |Fixed colour data for fixed colour +/- [COLDATA] |
|
||||
| | |bgrdddddd b: Set to change blue. |
|
||||
| | | g: Set to change green. |
|
||||
| | | r: Set to change red. |
|
||||
| | | d: Set colour constant data for +/-. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$2133 |Screen mode/video select register [SETINI] |
|
||||
| | |sn00pvshi |
|
||||
| | | s: Super-impose SFX graphics over ex- |
|
||||
| | | ternal video (usually 0). |
|
||||
| | | n: External mode (screen expand). When |
|
||||
| | | sing MODE 7, enable. |
|
||||
| | | p: 0 = 256 resolution. |
|
||||
| | | 1 = 512 sub screen resolution. |
|
||||
| | | v: 0 = 224 vertical resolution. |
|
||||
| | | 1 = 239 vertical resolution. |
|
||||
| | | s: See below for more info. |
|
||||
| | | i: 0 = No interlace. |
|
||||
| | | 1 = Interlaced display. |
|
||||
| | | |
|
||||
| | |*** When in interlace mode, select either the 1-dot per line |
|
||||
| | | mode or the 1-dot repeated every 2-lines mode. If '1' is |
|
||||
| | | set in this bit, the OBJ seems to be reduced vertically |
|
||||
| | | by 1/2. |
|
||||
| | | |
|
||||
| | |*** Interlaced mode is used in the SNES test cartridge. It |
|
||||
| | | does flicker, but it gives a FULL 480 vertical resolution.|
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$2134 |Multiplication result register (low) [MPYL] |
|
||||
|r |$2135 |Multiplication result register (middle) [MPYM] |
|
||||
|r |$2136 |Multiplication result register (high) [MPYH] |
|
||||
| | |*** Result is 8 bits long for $2134, $2135, and $2136. |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$2137 |Software latch for horizontal/vertical counter [SLHV] |
|
||||
| | |aaaaaaaa a: Result. |
|
||||
| | | |
|
||||
| | |The counter value at the point when $2137 is read can be |
|
||||
| | |latched. Data read is meaningless. |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$2138 |Read data from OAM {OAMDATAREAD} |
|
||||
|r 2 |$2139 |Read data from VRAM {VMDATALREAD/VMDATAHREAD} |
|
||||
|r |$213B |Read data from CG-RAM (colour) {CGDATAREAD} |
|
||||
|r d |$213C |Horizontal scanline location [OPHCT] |
|
||||
|r d |$213D |Vertical scanline location [OPVCT] |
|
||||
| | |*** Registers $213C and $213D are 9-bits in length. |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$213E |PPU status flag & version number [STAT77] |
|
||||
| | |trm0vvvv t: Time over (see below). |
|
||||
| | | r: Range over (see below). |
|
||||
| | | m: Master/slave mode select. Usually 0. |
|
||||
| | | v: Version # ($5C77 (???)). |
|
||||
| | | |
|
||||
| | |*** Range: When the quantity of the OBJ (size is non-relevant)|
|
||||
| | | becomes 33 pieces or more, '1' is set. |
|
||||
| | | Time: When the quantity of the OBJ which is converted to |
|
||||
| | | 8x8 is 35 pieces or more, '1' will be set. |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$213F |PPU status flag & version number [STAT78] |
|
||||
| | |fl0mvvvv f: Field # scanned in int. mode (0=1st).|
|
||||
| | | l: Set if external signal (light pen, |
|
||||
| | | etc.) is installed/applied. |
|
||||
| | | m: NTSC/PAL mode (0=NTSC, 1=PAL). |
|
||||
| | | v: Version # ($5C78 (???)). |
|
||||
| | | |
|
||||
| | | |
|
||||
|rw |$2140 |[APUI00] -| |
|
||||
|rw |$2141 |[APUI01] |- Audio registers. See sound.doc and sid-spc.src. |
|
||||
|rw |$2142 |[APUI02] | |
|
||||
|rw |$2143 |[APUI03] -| |
|
||||
| | | |
|
||||
| | | |
|
||||
|rw |$2180 |Read/write WRAM register [WMDATA] |
|
||||
|rw |$2181 |WRAM data register (low byte) [WMADDL] |
|
||||
|rw |$2182 |WRAM data register (middle byte) [WMADDM] |
|
||||
|rw |$2183 |WRAM data register (high byte) [WMADDH] |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$4200 |Counter enable [NMITIMEN] |
|
||||
| | |a0yx000b a: NMI/VBlank interrupt. |
|
||||
| | | y: Vertical counter. |
|
||||
| | | x: Horizontal counter. |
|
||||
| | | b: Joypad read-enable. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$4201 |Programmable I/O port (out-port) [WRIO] |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$4202 |Multiplicand 'A' [WRMPYA] |
|
||||
| w |$4203 |Multiplier 'B' [WRMPYB] |
|
||||
| | |*** Absolute multiplication used when using the two above reg-|
|
||||
| | | isters. Formulae is: 'A (8-bit) * B (8-bit) = C (16-bit)'.|
|
||||
| | | Result can be read from $4216. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$4204 |Dividend C [WRDIVL/WRDIVH] |
|
||||
| w |$4205 |Divisor B [WRDIVB] |
|
||||
| | |*** Absolute division used when using the two above registers.|
|
||||
| | | Formulae is 'C (16-bit) / B (8-bit) = A (16-bit)'. |
|
||||
| | | Result can be read from $4214, and the remainder read from|
|
||||
| | | $4216. |
|
||||
| | |*** Operation will start when $4205 is set, and will be com- |
|
||||
| | | pleted after 16 machine cycles. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$4207 |Video horizontal IRQ beam position/pointer [HTIMEL/HTIMEH] |
|
||||
| | |0000000x xxxxxxxx x: Beam position. |
|
||||
| | | |
|
||||
| | |Valid values for x range from 0 to 339, due to overscan. The |
|
||||
| | |timer is reset every scanline, so unless it's disabled, you'll|
|
||||
| | |receive an interrupt every time the beam hits the value given.|
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$4209 |Video vertical IRQ beam position/pointer [VTIMEL/VTIMEH] |
|
||||
| | |0000000y yyyyyyyy y: Beam position. |
|
||||
| | | |
|
||||
| | |Same as $4207, but valid values for y are 0 to 261 (based from|
|
||||
| | |overscan at the top of the screen). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$420B |DMA enable register [MDMAEN] |
|
||||
| | |abcdefgh a: DMA channel #7. |
|
||||
| | | b: DMA channel #6. |
|
||||
| | | c: DMA channel #5. |
|
||||
| | | d: DMA channel #4. |
|
||||
| | | e: DMA channel #3. |
|
||||
| | | f: DMA channel #2. |
|
||||
| | | g: DMA channel #1. |
|
||||
| | | h: DMA channel #0. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$420C |HDMA enable register. |
|
||||
| | |*** Same as $420B, virtually. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$420D |Cycle speed register [MEMSEL] |
|
||||
| | |0000000x x: 0 = Normal (2.68MHz). |
|
||||
| | | 1 = Fast (3.58MHz). |
|
||||
| | | |
|
||||
| | |Note that using the fast mode requires 120ns or faster EPROMs.|
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$4210 |NMI register [RDNMI] |
|
||||
| | |x000vvvv x: Disable/enable NMI. |
|
||||
| | | v: Version # ($5A22 (???)) |
|
||||
| | | |
|
||||
| | |Bit 7 can be reset to 0 by reading this register. |
|
||||
| | | |
|
||||
| | | |
|
||||
|rw |$4211 |Video IRQ register [TIMEUP] |
|
||||
| | |i0000000 i: 0 = IRQ is not enabled. |
|
||||
| | | 1 = IRQ is enabled. |
|
||||
| | | |
|
||||
| | |This location MUST be read to clear a horizontal or vertical |
|
||||
| | |raster interrupt. It's all relative to $4200. If the horiz- |
|
||||
| | |ontal timer interrupt (bit 4, $4200) is set then the interrupt|
|
||||
| | |will be generated according to the position in $4207. Same |
|
||||
| | |thing is for vertical timing (bit 5, $4200) but the position |
|
||||
| | |will be read from $4209, not $4207. |
|
||||
| | | |
|
||||
| | | |
|
||||
|rw |$4212 |Status register [HVBJOY] |
|
||||
| | |xy00000a x: 0 = Not in VBlank state. |
|
||||
| | | 1 = In VBlank state. |
|
||||
| | | y: 0 = Not in HBlank state. |
|
||||
| | | 1 = In HBlank state. |
|
||||
| | | a: 0 = Joypad not ready. |
|
||||
| | | 1 = Joypad ready. |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$4213 |Programmable I/O port (in-port) [RDIO] |
|
||||
| | | |
|
||||
| | | |
|
||||
|r 2 |$4214 |Quotient of divide result [RDDIVL/RDDIVH] |
|
||||
| | | |
|
||||
| | | |
|
||||
|r 2 |$4216 |Multiplication or divide result [RDMPYL/RDMPYH] |
|
||||
| | | |
|
||||
| | | |
|
||||
|r |$4218 |Joypad #1 status register [JOY1L] |
|
||||
| | |abcd0000 a: A button (1=pressed). |
|
||||
| | | b: X button (1=pressed). |
|
||||
| | | c: Top-Left (1=pressed). |
|
||||
| | | d: Top-Rght (1=pressed). |
|
||||
| | | |
|
||||
|r |$4219 |Joypad #1 status register [JOY1H] |
|
||||
| | |abcdefgh a: B button (1=pressed). |
|
||||
| | | b: Y button (1=pressed). |
|
||||
| | | c: Select (1=pressed). |
|
||||
| | | d: Start (1=pressed). |
|
||||
| | | e: Up (1=pressed). |
|
||||
| | | f: Down (1=pressed). |
|
||||
| | | g: Left (1=pressed). |
|
||||
| | | h: Right (1=pressed). |
|
||||
| | | |
|
||||
|r |$421A |Joypad #2 status register [JOY2L] -| |
|
||||
|r |$421B |Joypad #2 status register [JOY2H] | |
|
||||
|r |$421C |Joypad #3 status register [JOY3L] |- Same as $4218 & $4219. |
|
||||
|r |$421D |Joypad #3 status register [JOY3H] | |
|
||||
|r |$421E |Joypad #4 status register [JOY4L] | |
|
||||
|r |$421F |Joypad #4 status register [JOY4H] -| |
|
||||
| | |*** Joypad registers can be read w/ a 16-bit accum/X/Y and |
|
||||
| | | both the high and low bytes will received valid data. |
|
||||
| | | |
|
||||
| | | |
|
||||
|----------------------------------------------------------------------------|
|
||||
|The following data is for DMA-transfers. 'x' represents the DMA channel #, |
|
||||
|which ranges from 0 to 7. So, the following would represent each section: |
|
||||
|DMA #0: $4300-$4305. |
|
||||
|DMA #1: $4310-$4315. |
|
||||
|.................... |
|
||||
|DMA #7: $4370-$4375. |
|
||||
|----------------------------------------------------------------------------|
|
||||
| w |$43x0 |DMA Control register [DMAPX] |
|
||||
| | |vh0cbaaa v: 0 = CPU memory -> PPU. |
|
||||
| | | 1 = PPU -> CPU memory. |
|
||||
| | | h: For HDMA only: |
|
||||
| | | 0 = Absolute addressing. |
|
||||
| | | 1 = Indirect addressing. |
|
||||
| | | c: 0 = Auto address inc/decrement. |
|
||||
| | | 1 = Fixed address (for VRAM, etc.). |
|
||||
| | | b: 0 = Automatic increment. |
|
||||
| | | 1 = Automatic decrement. |
|
||||
| | | a: Transfer type:
|
||||
| | | 000 = 1 address write twice: LH. |
|
||||
| | | 001 = 2 addresses: LH. |
|
||||
| | | 010 = 1 address write once. |
|
||||
| | | 011 = 2 addresses write twice: LLHH |
|
||||
| | | 100 = 4 addresses: LHLH |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$43x1 |DMA Destination register [BBADX] |
|
||||
| | |xxxxxxxx x: Low-byte address. |
|
||||
| | | |
|
||||
| | |*** The upper-byte address is assumed to be $21, making your |
|
||||
| | | access addresses $2100 to $21FF. |
|
||||
| | | |
|
||||
| | | |
|
||||
| w 2 |$43x2 |Source address [A1TXL/A1TXH] |
|
||||
| w |$43x4 |Source bank address [A1BX] |
|
||||
| w 2 |$43x5 |DMA transfer size & HDMA address register [DASXL/DASXH] |
|
||||
| | |*** When using DMA, $43x5 defines the # of bytes to be trans- |
|
||||
| | | ferred via DMA itself. When using HDMA, $43x5 defines the |
|
||||
| | | data address ($43x5 = low byte, $43x6 = hi byte). |
|
||||
| | | |
|
||||
| | | |
|
||||
| w |$43xA |Number of lines for HDMA transfer [NTRLX] |
|
||||
| | |cxxxxxxx c: Continue (0=yes, 1=no (???)). |
|
||||
| | | x: # of lines to transfer. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|Additional information follows. |
|
||||
|Most of the following information is for SMC files, and where the header |
|
||||
|info is kept in memory, etc. etc. etc... |
|
||||
|----------------------------------------------------------------------------|
|
||||
|rw |$FEED |UNDOCUMENTED REGISTER: Felon's banana register [FBNANACNT] |
|
||||
| | |rcnnnnnn r: Ripe bit (0=ripe, 1=rotten). |
|
||||
| | | c: Colour bit (0=yellow, 1=green). |
|
||||
| | | n: Number of bananas. |
|
||||
| | | |
|
||||
| | |*** This register counts the number of bananas Felon currently|
|
||||
| | | has in his possession... (Who the hell is Felon?!). |
|
||||
| | | |
|
||||
| | |*** According to numerous sources, this register can be used |
|
||||
| | | to calculate pi to the 5-billionth digit in 20 clock |
|
||||
| | | cycles. The number of cycles corresponds to Felon's age, |
|
||||
| | | increasing by 1 every 365 days (1 year). It is increased |
|
||||
| | | by 2 every leap year. |
|
||||
| | | |
|
||||
| | | |
|
||||
|rw |$FFC0 |Cartridge title. |
|
||||
|rw |$FFD6 |ROM/RAM information on cart. |
|
||||
|rw |$FFD7 |ROM size. |
|
||||
|rw |$FFD8 |RAM size. |
|
||||
|rw |$FFD9 |Developer ID code. |
|
||||
|rw |$FFDB |Version number. |
|
||||
|rw |$FFDC |Checksum complement. |
|
||||
|rw |$FFDE |Checksum. |
|
||||
|rw |$FFEA |NMI vector/VBL interrupt. |
|
||||
|rw |$FFEC |Reset vector. |
|
||||
----------------------------------------------------------------------------
|
||||
21
files/docs/snes/yoshi/SNES.2
Normal file
21
files/docs/snes/yoshi/SNES.2
Normal file
@@ -0,0 +1,21 @@
|
||||
----------------------------------------------------------------------------
|
||||
|The SNES has some interesting colour characteristics. The colour, theoret- |
|
||||
|ically is 15 bit; each RGB value (Red, Green, and Blue) has 5 bits for each |
|
||||
|colour. |
|
||||
| |
|
||||
|When it comes to putting the colour data into $2122, the format (in binary) |
|
||||
|is the following: |
|
||||
| b: Blue ?bbbbbgg gggrrrrr |
|
||||
| g: Green |
|
||||
| r: Red |
|
||||
| ?: The infamous bit-of-confusion. :-) |
|
||||
| |
|
||||
|A quick colour chart could be the following: |
|
||||
| $7FFF [0111 1111 1111 1111]: White. |
|
||||
| $001F [0000 0000 0001 1111]: Red. |
|
||||
| $03E0 [0000 0011 1110 0000]: Green. |
|
||||
| $7C00 [0111 1100 0000 0000]: Blue. |
|
||||
| $7C1F [0111 1100 0001 1111]: Purple. |
|
||||
| $7FE0 [0111 1111 1110 0000]: Aqua. |
|
||||
| $03FF [0000 0011 1111 1111]: Yellow. |
|
||||
----------------------------------------------------------------------------
|
||||
89
files/docs/snes/yoshi/SNES.3
Normal file
89
files/docs/snes/yoshi/SNES.3
Normal file
@@ -0,0 +1,89 @@
|
||||
----------------------------------------------------------------------------
|
||||
|For those of you who don't know how the SNES does do it's graphics, it |
|
||||
|uses tiles (surprise surprise!). |
|
||||
| |
|
||||
|There are different MODEs on the SNES; the most famous being MODE 7. |
|
||||
|Most people think that $2106 (Screen Pixelation: Look in SNES.1 for an ex- |
|
||||
|planation on this register) is MODE 7. *** THIS IS NOT MODE 7!!! ***. |
|
||||
|So, the next time the pixels get really "big" (almost making them look like |
|
||||
|look like IBM-clone 320x200x256 MODE 13h graphics), and your friend says |
|
||||
|"WOW! MODE 7 is really awesome," punch him/her in the nose for me. Just |
|
||||
|joking. :-) |
|
||||
| |
|
||||
|I'll be explaining MODE 1. I know how MODE 7 works, but since i've never |
|
||||
|used it, don't plan on me explaining it in the near future. Sorry to those |
|
||||
|who were looking for a MODE 7 document. Look elsewhere... |
|
||||
| |
|
||||
|MODE # of BGs MaxColour/Tile Palettes Colours |
|
||||
|----------------------------------------------------------------------------|
|
||||
|0 4 4 8 32 |
|
||||
|1 3 16/16/4 8 128 |
|
||||
| |
|
||||
|MODE 0 is good for geometric shapes (if you were going to rotate a wire- |
|
||||
|frame cube, or something like that), basic star scrolls, or a very 'bland' |
|
||||
|text scroller... it's pretty cool and doesn't take up much space. |
|
||||
| |
|
||||
|I'm going to explain MODE 1, since MODE 0 is the same thing but with less |
|
||||
|bitplanes. :-) |
|
||||
| |
|
||||
|MODE 1 is really best for things; detailed star scrolls, text scrollers, |
|
||||
|geometric shapes, and filled objects. It's the most common used MODE in the |
|
||||
|the professional SNES programming world. |
|
||||
| |
|
||||
|You need to "setup the plane" to tell it what tile goes where. If you want |
|
||||
|demo-code, check out 'test.asm' in 'test.lzh'. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|So, lets assume we have a character (a 8x8 tile) which we want to work with |
|
||||
|to figure out the SNES's colour scheme: |
|
||||
| |
|
||||
|TestCHR1 dcb $00,$00,$00,$00,$00,$00,$00,$00 ; '@' |
|
||||
|TestCHR2 dcb $00,$3C,$4E,$5E,$5E,$40,$3C,$00 ; '@' |
|
||||
| |
|
||||
|You're probably wondering how the two lines above turn into actual graphic |
|
||||
|data on your monitor or television set. Very simple. Consider each byte |
|
||||
|(each new $xx statement) a new pixel line. Tile size is 8x8. |
|
||||
| |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 This is TestCHR1 |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 |
|
||||
| %00000000 = $00 |
|
||||
| |
|
||||
| %00000000 = $00 |
|
||||
| %00111100 = $3C This is TestCHR2 |
|
||||
| %01001110 = $4E |
|
||||
| %01011110 = $5E |
|
||||
| %01011110 = $5E |
|
||||
| %01000000 = $40 |
|
||||
| %00111100 = $3C |
|
||||
| %00000000 = $00 |
|
||||
| |
|
||||
|The at-symbol ('@') is visible in TestCHR2. Now you're probably wondering |
|
||||
|"Well, that tells me how to define a pixel on and off; what about the colour|
|
||||
|itself!" Once again, very simple, but a tad more complex: |
|
||||
| |
|
||||
|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 color #0; eg.: |
|
||||
| 0000 = Color #0 |
|
||||
| ||||___________Bitplane 0 |
|
||||
| |||__________Bitplane 1 |
|
||||
| ||_________Bitplane 2 |
|
||||
| |________Bitplane 3 |
|
||||
| |
|
||||
|So, now, think about a 0 for bitplane 0, a 1 for bitplane 1 and 2, and a 0 |
|
||||
|for bitplane 3: |
|
||||
| 0110 = Color #6 |
|
||||
| ||||___________Bitplane 0 |
|
||||
| |||__________Bitplane 1 |
|
||||
| |_________Bitplane 2 |
|
||||
| |________Bitplane 3 |
|
||||
| |
|
||||
|Keep in mind, this is the best explanation i've ever seen done about SNES |
|
||||
|pixel color definition. Until I see better, I'd have to say this is the |
|
||||
|best it's gonna get. |
|
||||
|The result above gives you the color # per pixel; it's interesting. It's an |
|
||||
|"overlay" method, so-to-speak, not to confuse this w/ main and sub-screens. |
|
||||
----------------------------------------------------------------------------
|
||||
23
files/docs/snes/yoshi/SNES.4
Normal file
23
files/docs/snes/yoshi/SNES.4
Normal file
@@ -0,0 +1,23 @@
|
||||
----------------------------------------------------------------------------
|
||||
|MODE # of BGs MaxColour/Tile Palettes Colours |
|
||||
|----------------------------------------------------------------------------|
|
||||
|0 4 4 8 32 |
|
||||
|1 3 16/16/4 8 128 |
|
||||
|2 ? ??? ? ??? |
|
||||
|3 2 256 & 16 1 & 8 256 & 32 |
|
||||
|4 2 256 & 4 1 & 8 256 & 32 |
|
||||
|5 ? ??? ? ??? |
|
||||
|6 ? 16 8 128 (Interlaced mode) |
|
||||
|7 ? 256 1 256 |
|
||||
|----------------------------------------------------------------------------|
|
||||
|Parms which have question marks ("?") mean that I don't know their stats. |
|
||||
|Any information would be greatly appreciated! I have personally tested some |
|
||||
|of the MODEs (MODE 0, 1, and 3), but none of the rest. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|MODE 1's "16/16/4" means you can have 16 colours per tile on BG1 and BG2, |
|
||||
|but on BG3 you can only have 4. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|MODE 3 can have 256 colours on the first plane, but only 16 on the second. |
|
||||
|MODE 4 isn't the exact same as MODE 3 (as v2.20 of my document stated), but |
|
||||
|i'm waiting for someone to tell me the differences... |
|
||||
----------------------------------------------------------------------------
|
||||
48
files/docs/snes/yoshi/SNES.5
Normal file
48
files/docs/snes/yoshi/SNES.5
Normal file
@@ -0,0 +1,48 @@
|
||||
----------------------------------------------------------------------------
|
||||
|The OBJs use a lookup table that contains info on their X and Y position on |
|
||||
|the screen, their size, if they're flipped vertically or horizontally, their|
|
||||
|colour, and the actual data. |
|
||||
| |
|
||||
|The format you need to make the table is as follows: |
|
||||
| |
|
||||
| |
|
||||
|Spr. # Size Offset Explanation |
|
||||
|----------------------------------------------------------------------------|
|
||||
| 0 Byte 0 xxxxxxxx x: X-location. |
|
||||
| Byte 1 yyyyyyyy y: Y-location. |
|
||||
| Byte 2 abcdeeeC a: Vertical flip. |
|
||||
| b: Horizontal flip. |
|
||||
| c: Playfield priority. |
|
||||
| d: Playfield priority. |
|
||||
| e: Pallete #. |
|
||||
| Byte 3 CCCCCCCC C: Character data. |
|
||||
| |
|
||||
| 1 Byte 4 xxxxxxxx x: X-location. |
|
||||
| Byte 5 yyyyyyyy y: Y-location. |
|
||||
| Byte 6 abcdeeeC a: Vertical flip. |
|
||||
| b: Horizontal flip. |
|
||||
| c: Playfield priority. |
|
||||
| d: Playfield priority. |
|
||||
| e: Pallete #. |
|
||||
| Byte 7 CCCCCCCC C: Character data. |
|
||||
|...and so on... |
|
||||
|----------------------------------------------------------------------------|
|
||||
|Continue this table all the way down to OBJ #127 (out of 128). Don't think |
|
||||
|you're finished quite yet: There is one more table of data required. |
|
||||
| |
|
||||
|2 bits are defined for each OBJ (eg. byte #0 holds the info for OBJ 0, 1, 2,|
|
||||
|and 3; byte #1 holds the info for OBJ 4, 5, 6, and 7). Therefore, 128/4 is |
|
||||
|32 bytes of data for the following table: |
|
||||
| ab |
|
||||
| ||____Size toggle bit. |
|
||||
| |_____MSB of X-position bit. |
|
||||
| |
|
||||
|So, the 4 bytes/sprites + the block are put into the OAM table by consec- |
|
||||
|utive writes to the OAM data register. You first should set the OAM address |
|
||||
|to $0000, then shove your data into it. |
|
||||
| |
|
||||
|If you don't set the block after the OAM as well, the results are bad. All |
|
||||
|the data for the MSB stuff wouldn't be defined correctly, which would result|
|
||||
|in your entire OBJ table being wacko. Have atleast some 0's there or a table|
|
||||
|which you really want to use in the long run. |
|
||||
----------------------------------------------------------------------------
|
||||
19
files/docs/snes/yoshi/SNES.6
Normal file
19
files/docs/snes/yoshi/SNES.6
Normal file
@@ -0,0 +1,19 @@
|
||||
----------------------------------------------------------------------------
|
||||
|I have never used an actual Super MagiComm before, and I would strongly re- |
|
||||
|commend not using these unless you know what each one does for sure. If you |
|
||||
|decide to write any sort-of operating system for the SNES, please do get in |
|
||||
|touch with me. |
|
||||
| |
|
||||
|The below registers i've never tested, or had tested. If you end up killing |
|
||||
|your console unit because of this, I TAKE NO RESPONSIBILITY. |
|
||||
| |
|
||||
|Location Value returned when read Value input when written |
|
||||
|----------------------------------------------------------------------------|
|
||||
|$C000: Input Register |
|
||||
|$C002: Digital Output Register |
|
||||
|$C004: Main Status Register |
|
||||
|$C005: Data Register Data Register |
|
||||
|$C007: Digital Input Register Disk Control Register |
|
||||
|$C008: Parallel Data Parallel Data |
|
||||
|$C009: Parallel Status |
|
||||
----------------------------------------------------------------------------
|
||||
15
files/docs/snes/yoshi/SNES.7
Normal file
15
files/docs/snes/yoshi/SNES.7
Normal file
@@ -0,0 +1,15 @@
|
||||
----------------------------------------------------------------------------
|
||||
|Here's a really basic memory map of the SNES's memory. Thanks to Geggin of |
|
||||
|Censor for supplying this. Reminder: this is a memory map in MODE 20. |
|
||||
|----------------------------------------------------------------------------|
|
||||
|Bank |Address |Description |
|
||||
|-------|--------------|-----------------------------------------------------|
|
||||
|$00-$3F|$0000-$1FFF |Scratchpad RAM. Set D-reg here if you'd like (I do) |
|
||||
| |$2000-$5FFF |Reserved (PPU, DMA) |
|
||||
| |$6000-$7FFF |Expand (???) |
|
||||
| |$8000-$FFFF |ROM (for code, graphics, etc.) |
|
||||
|$70 |$0000-$7FFF |SRAM (BRAM) - Battery RAM |
|
||||
|$7E |$0000-$1FFF |Scratchpad RAM (same as bank $00 to $3F) |
|
||||
| |$2000-$FFFF |RAM (for music, or whatever) |
|
||||
|$7F |$0000-$FFFF |RAM (for whatever) |
|
||||
----------------------------------------------------------------------------
|
||||
22
files/docs/snes/yoshi/SNES.8
Normal file
22
files/docs/snes/yoshi/SNES.8
Normal file
@@ -0,0 +1,22 @@
|
||||
I'd like to thank the following people:
|
||||
|
||||
Jeremy Gordon: Thanks for supplying me your sprite documentation. I
|
||||
don't think this doc. would be complete without it!
|
||||
Also for 65816 v2.0! Excellent assembler.
|
||||
AntiTrack: Thanks for the source! Next time, i'll ask! (grin)
|
||||
Toshi: I know you can't say much due to your job, but I
|
||||
really appreciate all the moral support you've given
|
||||
me. I wish I could show you how much it means to me.
|
||||
minus: Work on TRASM some more! Fix' dem bugs! :-)
|
||||
Jehu: Keep in touch. Get back to me about the job!
|
||||
Clay C.: Without you, who knows where i'd be.
|
||||
Troy_: I appreciate the logos!
|
||||
Geggin of Censor: Thanks for the memory map!
|
||||
D. Messiah of PiR: ...for all the EMail, long talks, 'n all that jazz.
|
||||
You're like a brother to me.
|
||||
|
||||
Hellos and "HEY! You're important too!"s go out to:
|
||||
|
||||
III_Demon, JackRippr, Amos, Norm, Hardware, Skywalkr, KingPhish,
|
||||
felon, AntiTrack, IRSMan, sendog, SHORYUKEN, _grazzt, RuGalz, and
|
||||
all the rest of the #SNES and famidev-gang.
|
||||
450
files/docs/snes/yoshi/SOUND.DOC
Normal file
450
files/docs/snes/yoshi/SOUND.DOC
Normal file
@@ -0,0 +1,450 @@
|
||||
From PARADIS@htu.tu-graz.ac.at Fri Mar 25 08:41:08 1994
|
||||
|
||||
The Bloody SPC-700
|
||||
------------------
|
||||
|
||||
|
||||
A try to stumble into the inner secret of a nasty chip.
|
||||
|
||||
By Antitrack exclusively for the FAMIDEV development group.
|
||||
|
||||
|
||||
Chapter 1:
|
||||
----------
|
||||
|
||||
|
||||
FACTS
|
||||
|
||||
* The SPC 700 is a very stupid sound chip with about the worst
|
||||
handling
|
||||
that you have seen in your lifetime.
|
||||
|
||||
* This chip is a co processor. He has a quite large instruction set
|
||||
(contrary to the Amiga's COPPER, who has a very small one) and 64KB
|
||||
RAM
|
||||
memory, of which you can use atleast 32KB. (or so)
|
||||
|
||||
* All program and data that is supposed to be run by this chip must
|
||||
be'
|
||||
moved to the SPC's own ram with a small loop that pokes each byte of
|
||||
your SPC assembler program and (e.g. sample-)data into four memory
|
||||
locations : $2140 - $2143. They are your only chance to communicate
|
||||
with
|
||||
the SPC.
|
||||
|
||||
* These four memory locations have different meanings for read and
|
||||
write;
|
||||
if you read (LDA) $2140, you get the data from memory loc. 00f4 (or
|
||||
so)
|
||||
of the sound chip.
|
||||
|
||||
* On power-on, the SPC 700 jumps (much like the main processor) to a
|
||||
very
|
||||
small ROM area that resides from $ffc0 to $ffff inside the SPC.
|
||||
(This chip REALLY follows the black box principle, eh...) This
|
||||
program
|
||||
at $ffc0 is waiting to get the data in the right format on his
|
||||
input ports
|
||||
at $00f4/5/6/7 , which are $2140/1/2/3 from the 65c816's (e.g.
|
||||
your's )
|
||||
point of view.
|
||||
|
||||
* Your main program will therefore have to follow the SPC's
|
||||
conditions and
|
||||
poke all the program and data for the SPC into 2140/1/2/3 in a
|
||||
special
|
||||
order.
|
||||
|
||||
* When transmission is completed, you will also have transmitted the
|
||||
start
|
||||
address of your SPC code, and the SPC will start to execute your
|
||||
program
|
||||
there.
|
||||
|
||||
|
||||
|
||||
--------------------QUESTIONS.
|
||||
|
||||
|
||||
Q: How do I move my program and data to the SPC then, what format do
|
||||
I have
|
||||
to use?
|
||||
|
||||
|
||||
A: First, your SPC data/code has to be moved from ROM to the extra
|
||||
RAM at
|
||||
e.g. $7f0000 . Dont ask me why it has to be in RAM, probably it doesnt
|
||||
but all the existing routines that send data to the SPC do something
|
||||
like
|
||||
that.
|
||||
|
||||
Your data/code has to be in groups which I will call "chunks". A
|
||||
valid chunk
|
||||
looks like that:
|
||||
|
||||
first word: number of bytes to transmit to SPC -+
|
||||
sec. word : start address where to move data to the SPC | one chunk
|
||||
byte 4-???? : your data/code -+
|
||||
|
||||
You can have as many chunks as you want to , but the last chunk must
|
||||
be like
|
||||
that:
|
||||
|
||||
first word : $0000
|
||||
second word: Start address of your code.
|
||||
|
||||
|
||||
Q: So if you are right, this means: After I transmitted all my code
|
||||
and
|
||||
data, and my own SPC code takes over the control, I might encounter
|
||||
problems
|
||||
if my SPC program has to communicate with the outer world (the
|
||||
65c816).
|
||||
What if the main program wants to change sounds? What if a background
|
||||
melody
|
||||
shall always play on two voices, and extra two voices will be used for
|
||||
sound effects whenever the player sprite e.g. picks up an object?
|
||||
|
||||
A: That is sure a point. Your own code will have to look at memory
|
||||
locations
|
||||
$00f4/00f5/00f6/00f7 , because they are the only accessible from
|
||||
outside
|
||||
at $2140/1/2/3. The easiest way would be: As soon as any of $f4-$f7
|
||||
change,
|
||||
jump into the Boot ROM at $ffc0 (?) so the SPC is executing his
|
||||
receive
|
||||
routine again. Then you *probably* can send another SPC chunk with new
|
||||
sound and code to the SPC....
|
||||
|
||||
Q: This only helps if a complete new tune is to be played, this
|
||||
doesnt help
|
||||
if a melody using two voices shall still remain....
|
||||
|
||||
A: Thats true. The best approach is to send own command bytes to the
|
||||
SPC and
|
||||
your SPC code has to check out $f4-$f7 constantly and react to it.....
|
||||
A command byte like $00 could mean: sound off,
|
||||
$01 : play tune 1
|
||||
.
|
||||
.
|
||||
.
|
||||
$0f : play tune $0f
|
||||
$10 : play jingle (fx) 01
|
||||
.
|
||||
.
|
||||
.
|
||||
$ff : jump to $ffc0 (??) the receive
|
||||
ROM routine
|
||||
|
||||
|
||||
|
||||
Q: is there another approach?
|
||||
|
||||
A: Yes there is. As you probably know, all important addresses of the
|
||||
SPC 700 reside inside its own RAM's zeropage:
|
||||
|
||||
Address / register / usage
|
||||
0000 Volume left
|
||||
0001 Volume right
|
||||
0002 Pitch low
|
||||
0003 Pitch high (The total 14 bits of pitch
|
||||
height)
|
||||
0004 SRCN Designates source number from 0-
|
||||
255
|
||||
0005 ADSR 1
|
||||
0006 ADSR 2
|
||||
0007 GAIN Envelope can be freely designated by
|
||||
your code
|
||||
0008 ENVX Present val of envelope with DSP
|
||||
rewrites
|
||||
0009 VALX Present wave height val
|
||||
|
||||
(and so on...)
|
||||
|
||||
Your approach would be to move only sample data there, and/or (lots
|
||||
of) very
|
||||
small chunks of data with a target address in the zeropage, and a
|
||||
starting
|
||||
address of e.g. $ffc0. The small chunks would access zeropage
|
||||
addresses e.g.
|
||||
for the volume etc and thus result in tones; if this is done every
|
||||
frame
|
||||
you might end up with a music player quite similar to the C64 styled
|
||||
ones.
|
||||
|
||||
|
||||
Q: So anyway, in what format exactly do I have to move data to the
|
||||
SPC?
|
||||
|
||||
A: I have the following source code for you, but let me explain it a
|
||||
bit
|
||||
BEFORE you start to dig into it.
|
||||
|
||||
I've already mentioned the general "chunk" format. The loop does the
|
||||
following:
|
||||
|
||||
|
||||
- move ram destination address to $2142/3 (akku: 16 bit)
|
||||
- move either #$00 or #$01 into 2141, this depends if you have more
|
||||
than $0100
|
||||
bytes of data for the SPC;
|
||||
|
||||
- first time (first chunk you transmit): move constant #$cc into 2140
|
||||
|
||||
- loop: poke each byte that you want to be transmitted into 2140
|
||||
(word)
|
||||
the higher 7-15 bits of your accu-word contain the number of bytes
|
||||
already
|
||||
moved (e.g. 00 on the start)
|
||||
|
||||
- cmp $2140 with this number of bytes already moved (lower 8 bits of
|
||||
this
|
||||
number only!) and wait if its not equal.
|
||||
|
||||
- until the loop is over.
|
||||
|
||||
- for the next chunk header this is repeated, but not #$cc is moved
|
||||
into
|
||||
2140 but "nn" (lobyte of number of bytes moved) +3 or +6 if it was
|
||||
00 when
|
||||
+3 was used.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
move #$0400 to 2142 /word access
|
||||
|
||||
move #$01 to 2141
|
||||
move #$cc to 2140
|
||||
|
||||
move "gg00" to 2140 where "gg" is the first real code/data
|
||||
byte for
|
||||
the SPC
|
||||
|
||||
wait till 2140 is #$00
|
||||
|
||||
move hh01 to 2140 where "hh" is the second byte of code or
|
||||
data for SPC
|
||||
|
||||
wait till 2140 is #$01
|
||||
|
||||
move ii02 to 2140 where "ii" is the 3rd byte of data for the
|
||||
SPC....
|
||||
|
||||
wait till 2140 is #$02
|
||||
|
||||
|
||||
lets say "ii" was the last byte. Now we add #$04 (3+carry) to
|
||||
#$02
|
||||
(#$02 being the number-1 of how many bytes we moved to the
|
||||
SPC), we
|
||||
will push it onto the stack), now :
|
||||
|
||||
fetch the next header , poke target RAM address into $2142
|
||||
(word)
|
||||
poke 00 or 01 into 2141 depending of how many bytes to send,
|
||||
poke #$06 into 2140 (06 : number of bytes sent from last chunk-
|
||||
1 + 3 )
|
||||
|
||||
|
||||
I think I got this scheme pretty much right this time. Now, is PLEASE
|
||||
someone
|
||||
going to donate their home-brewed SPC dis/assemblers to me? Oh pretty
|
||||
please,
|
||||
I hate silent SNES's ! :)
|
||||
|
||||
|
||||
Source code follows, reassembled from a PAN/Baseline demo "xmas wish
|
||||
92/93":
|
||||
----------------------------------------------------------------------
|
||||
------
|
||||
|
||||
|
||||
; entry to the code starts here
|
||||
|
||||
|
||||
SEP #$30 ; x y a set to 8 bit length
|
||||
LDA #$FF ; ff into audio0w (write)
|
||||
STA $2140
|
||||
REP #$10 ; x,y: 16 bit length
|
||||
LDX #$7FFF
|
||||
l0DB5B LDA $018000,X ; move rom music data to ram at $7f0000
|
||||
STA $7F0000,X
|
||||
LDA $028000,X ; move rom music data to ram at $7f0000
|
||||
STA $7F8000,X
|
||||
DEX
|
||||
BPL l0DB5B
|
||||
LDA #$80 ; screen on , probably not important at all
|
||||
STA $2100
|
||||
LDA #$00 ; 00fd/00fe/00ff point to the data that is
|
||||
now
|
||||
STA $00FD ; in ram at $7f0000
|
||||
LDA #$00
|
||||
STA $00FE
|
||||
LDA #$7F
|
||||
STA $00FF
|
||||
STZ $4200 ; disable nmi and timer h/v count
|
||||
SEI ; disable irq
|
||||
|
||||
JSR l0DBCD ; unknown sub routine, labeled "RESTART"
|
||||
by PAN/ATX
|
||||
|
||||
SEP #$30 ; all regs 8 bit
|
||||
l0DB8B LDA $2140 ; wait for reply from sound chip ?
|
||||
BNE l0DB8B
|
||||
LDA #$E0 ; audio3w ?
|
||||
STA $2143
|
||||
LDA #$FF ; send data to sound chip ?
|
||||
STA $2142 ; $ffe0 this could be an address within the
|
||||
; sound chip ROM between $ffc0 and $ffff
|
||||
in the
|
||||
; ROM mask.......
|
||||
LDA #$01 ; send data to sound chip ?
|
||||
STA $2141
|
||||
LDA #$01 ; send data to sound chip ?
|
||||
STA $2140
|
||||
|
||||
l0DBA4 LDA $2140 ; wait for reply from sound chip ?
|
||||
CMP #$01 ; what a fuck of a protocol .... :(
|
||||
BNE l0DBA4
|
||||
|
||||
l0DBAB LDA $2140 ; wait again for reply from soundchip ?
|
||||
CMP #$55
|
||||
BNE l0DBAB
|
||||
|
||||
LDA $0207 ; aha ... move $0207 to sound chip ?
|
||||
STA $2141 ; probably sound number selector
|
||||
LDA #$07
|
||||
STA $2140 ; send data to sound chip
|
||||
l0DBBD LDA $2140 ; wait until sound chip accepted data?
|
||||
CMP #$07
|
||||
BNE l0DBBD
|
||||
l0DBC4 LDA $2140 ; wait for reply ?
|
||||
CMP #$55
|
||||
BNE l0DBC4
|
||||
CLI
|
||||
RTS
|
||||
|
||||
l0DBCD PHP ; labeled "RESTART" by pan/ATX
|
||||
JSR l0DBD8 ;
|
||||
PLP
|
||||
LDA #$00 ; 00 into audio0w
|
||||
STA $2140
|
||||
RTS
|
||||
|
||||
l0DBD8 PHP
|
||||
REP #$30 ; a,x,y 16 bit regs
|
||||
LDY #$0000 ; needed first time at lda [$fd],y :
|
||||
pointer to ram
|
||||
LDA #$BBAA
|
||||
l0DBE1 CMP $2140 ; wait for sound chip $2140/2141 ?
|
||||
BNE l0DBE1
|
||||
SEP #$20 ; akku 8 bit
|
||||
LDA #$CC
|
||||
BRA l0DC12 ; oh well, another mystery :-)
|
||||
|
||||
|
||||
; jump here if overflow is set e.g. if more than $0100 data to move
|
||||
l0DBEC LDA [$FD],Y ; get data from ram pointer
|
||||
INY ; the accumulator is about to get "xx00"
|
||||
where
|
||||
XBA ; /"xx" is the byte from [fd],y (first
|
||||
data byte)
|
||||
LDA #$00 ; /and resides into bit 15-7 of accu,
|
||||
and 00 is
|
||||
BRA l0DBFF ; /#$00 (8bit number of bytes already
|
||||
sent)
|
||||
|
||||
|
||||
l0DBF4 XBA ; accu is now "nn??" ?? is old data from
|
||||
last loop
|
||||
LDA [$FD],Y ; accu is now "nnxx" with xx the newest
|
||||
data byte
|
||||
INY ; /for
|
||||
the SPC!
|
||||
XBA ; accu is now "xxnn"
|
||||
l0DBF9 CMP $2140 ; wait for sound chip to reply with "nn" !!
|
||||
BNE l0DBF9
|
||||
INC A ; increment number of bytes that were
|
||||
sent...
|
||||
; accu is now "xxnn" with newest val for
|
||||
nn:=nn+1
|
||||
|
||||
l0DBFF REP #$20 ; akku 16 bit
|
||||
STA $2140 ; poke "xxnn" to soundchip. xx is actual
|
||||
data,
|
||||
SEP #$20 ; akku 8 bit ! nn is the 8-bit cutted
|
||||
number of bytes
|
||||
DEX ! which were already sent!!
|
||||
BNE l0DBF4 ; as many times as xreg says...
|
||||
|
||||
|
||||
l0DC09 CMP $2140 ; byte "nn" will be replied from the SPC if
|
||||
data
|
||||
BNE l0DC09 ; received correctly!
|
||||
l0DC0E ADC #$03 ; compare accu with #$fb ADC WILL ADD #$04
|
||||
COZ
|
||||
; CARRY IS ALWAYS SET AFTER THE CMP!!!
|
||||
ATTENTION!
|
||||
BEQ l0DC0E ; if accu was $fb then accu := $03 . (what
|
||||
for?)
|
||||
|
||||
l0DC12 PHA ; push value accu+$04 to stack (or
|
||||
beginning: #$cc)
|
||||
REP #$20 ; accu = 16 bit
|
||||
LDA [$FD],Y ; get ram data 2 bytes
|
||||
INY ; point to next word
|
||||
INY
|
||||
TAX ; x:=a : number of bytes to transmit
|
||||
LDA [$FD],Y ; get ram data
|
||||
INY
|
||||
INY
|
||||
STA $2142 ; audio2w : possibly the dest. area in the
|
||||
spc700
|
||||
SEP #$20 ; accu 8 bit
|
||||
CPX #$0100 ; set carry if first ram data was >= 0100
|
||||
lda #$00 ;
|
||||
ROL ;
|
||||
STA $2141 ; if ram data >= 0100, poke "1" into reg 1
|
||||
otherw 0
|
||||
ADC #$7F ; SET OVERFLOW FLAG IF X>=$0100 !!!! (nice
|
||||
trick!)
|
||||
PLA
|
||||
STA $2140 ; $cc in the first case , nn+4 on all later
|
||||
cases
|
||||
|
||||
l0DC32 CMP $2140 ; wait for snd chip reply
|
||||
BNE l0DC32
|
||||
BVS l0DBEC ; if there were more than $0100 data for the
|
||||
spc's RAM
|
||||
; move them where they R supposed to belong
|
||||
to!
|
||||
PLP
|
||||
RTS
|
||||
|
||||
|
||||
PLA
|
||||
STA $2140 ; same shit, never been jumped into
|
||||
l0DC3F CMP $2140
|
||||
BNE l0DC3F
|
||||
BVS l0DBF9
|
||||
PLP
|
||||
RTS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; also lets look at 7f0000: the first few bytes at 7f0000 are:
|
||||
|
||||
7f0000: b7 0e 00 04 20 cd cf bd e8 00 5d af c8 f0 d0 fb 5d d5 00 01
|
||||
d5 00 02
|
||||
|
||||
b7 0e should be number of bytes to transmit, 0400 the destination
|
||||
inside the
|
||||
spc....
|
||||
at this point I really need an SPC dis/assembler..... :(((
|
||||
|
||||
Okay well my first source was incompetent, sure thing. But I think I
|
||||
could
|
||||
solve a lot of questions meanwhile.
|
||||
201
files/docs/snes/yoshi/SPRITE.DOC
Normal file
201
files/docs/snes/yoshi/SPRITE.DOC
Normal file
@@ -0,0 +1,201 @@
|
||||
SPRITE DOC
|
||||
------------------------------------------------------------
|
||||
|
||||
if you haven't already obtained "yoshi doc", get it and read it before you
|
||||
read this doc....
|
||||
|
||||
|
||||
Part I - the bitplane representation of a 16 color 8x8 pixel tile
|
||||
-----------------------------------------------------------------
|
||||
|
||||
sprites are made of tiles, in particular 4-bitplane tiles, 4-bitplane
|
||||
tiles, means that the tiles are made of 4-bit color values, so this means
|
||||
that the tiles can have a maximum of 16 colors.
|
||||
|
||||
in many graphics formats, this type of data would be stored as follows
|
||||
(assuming a 8 pixel by 8 pixel tile)
|
||||
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
$2 $0 $6 $1 $f $e $1
|
||||
$a $2 $2 $2 $6 $7 $0
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
$1 $0 $2 $8 $2 $4 $5
|
||||
|
||||
where each hex number represents a color, so pixel (0,0) would be color
|
||||
number "1", and pixel (4,2) would be color "6"....this is <not> the case
|
||||
on the super nintendo....for reasons having to do with the implementation
|
||||
of the graphics engine, the super nintendo represents its image data in
|
||||
the "bitplane" format, assuming and 8 pixel by 8 pixel tile with 16
|
||||
colors, this data would have four bitplanes (0-3) of monochrome, binary
|
||||
image data:
|
||||
|
||||
|
||||
0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 1
|
||||
0 0 0 0 0 0 0 0 1 2
|
||||
0 0 0 0 0 0 0 0 1 2 3
|
||||
0 0 0 0 0 0 0 0 1 2 3
|
||||
0 0 0 0 0 0 0 0 1 2 3
|
||||
0 0 0 0 0 0 0 0 1 2 3
|
||||
0 0 0 0 0 0 0 0 1 2 3
|
||||
1 1 1 1 1 1 1 1 2 3
|
||||
2 2 2 2 2 2 2 2 3
|
||||
3 3 3 3 3 3 3 3
|
||||
|
||||
|
||||
four monochrome 8x8 pixel images stacked on top of each other. if you
|
||||
wanted pixel (4,2) to have the color "6" you would have to put a "1" in
|
||||
bitplane one, and a "1" in bitplane two, with the bitplane zero and three
|
||||
having "0"'s. this is because the binary representation of "6" is "0110".
|
||||
|
||||
ok, so it is obviously possible to store each monochrome bitplane in 8
|
||||
bytes, each byte representing a row in the bitplane. so a single tile
|
||||
takes up 32 bytes (8 bytes per row * 8 rows * 4 bitplanes) of memory.
|
||||
|
||||
|
||||
Part II - the way tiles are stored in vram for sprite data
|
||||
---------------------------------------------------------
|
||||
|
||||
in vram you store a tile 16 bits at a time as follows:
|
||||
|
||||
<-------2 bytes at a time------>
|
||||
<--1 byte wide-><--1 byte wide->
|
||||
|
||||
[plane 0, row 0][plane 1, row 0]
|
||||
[plane 0, row 1][plane 1, row 1]
|
||||
[plane 0, row 2][plane 1, row 2]
|
||||
..
|
||||
..
|
||||
..
|
||||
[plane 0, row 7][plane 1, row 7]
|
||||
[plane 2, row 0][plane 2, row 0]
|
||||
[plane 2, row 1][plane 2, row 1]
|
||||
[plane 2, row 2][plane 2, row 2]
|
||||
..
|
||||
..
|
||||
..
|
||||
[plane 2, row 7][plane 2, row 7]
|
||||
|
||||
|
||||
the super nintendo can have two different sizes of sprite on the screen
|
||||
at one time, you can choose from the following combinations:
|
||||
|
||||
[value] [sprite size 0][sprite size 1]
|
||||
000 8x8 pixel 16x16 pixel
|
||||
001 8x8 pixel 32x32 pixel
|
||||
010 8x8 pixel 64x64 pixel
|
||||
011 16x16 pixel 32x32 pixel
|
||||
100 16x16 pixel 64x64 pixel
|
||||
101 32x32 pixel 64x64 pixel
|
||||
|
||||
it is set in the upper three bits of address $2101....so to use 8x8 pixel
|
||||
sprites, and 32x32 pixel sprites, you would load $2101 with the value
|
||||
"001xxxxx" (where x is don't care)
|
||||
|
||||
the lower five bits of address $2101 are also very important, these bits
|
||||
tell the super nintendo where in vram your sprites are located. the
|
||||
lowest three bits are the "name base", and the fourth and fifth bits are the
|
||||
"name". the "name" bits specify the upper 4k word of the sprite address,
|
||||
and the "name base" specfies the offset. so if put you tile data in vram
|
||||
$0000 you would set these bits all to zero.
|
||||
|
||||
suppose you want to have four 32 pixel by 32 pixel sprites; each would be
|
||||
composed of 16 tiles, each tile is numbered, tiles $0-$3f
|
||||
|
||||
[sprite 0]
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 a b
|
||||
c d e f
|
||||
|
||||
..
|
||||
..
|
||||
|
||||
[sprite 3]
|
||||
30 31 32 33
|
||||
34 35 36 37
|
||||
38 39 3a 3b
|
||||
3c 3d 3e 3f
|
||||
|
||||
in vram, these tiles, $0 through tile $3f would be store in an interlaced
|
||||
fashion as follows:
|
||||
|
||||
|
||||
$0 $1 $2 $3 $10 $11 $12 $13 $20 $21 $22 $23 $30 $31 $32 $33
|
||||
$4 $5 $6 $7 $14 $15 $16 $17 $24 $25 $26 $27 $34 $35 $36 $37
|
||||
|
||||
do you see the pattern? you must store the first row (four tiles) of each
|
||||
sprite, and then the second row, then the third, etc....
|
||||
|
||||
if you were dealing with 8x8 sprites, you would have to store the first
|
||||
row of 16 sprites, then the second row of the 16 sprites, etc....
|
||||
|
||||
if you were dealing with 16x16 sprites, you have to store the first row
|
||||
of 8 sprites, then the second, then the third, etc...
|
||||
|
||||
with 64x64, yep, you guessed it, the first row of two sprites, then the
|
||||
second row, etc....
|
||||
|
||||
|
||||
|
||||
Part III - setting up the OAM table for your sprites
|
||||
-----------------------------------------------------
|
||||
|
||||
for each sprite in the sprite table (maximum of 128 sprites, numbered 0-127)
|
||||
you must have four bytes of information, the first byte is the low 8 bits of
|
||||
the horizontal position of the sprite, the second byte is the vertical
|
||||
position of the sprite, the third byte is the "address" of the sprite...
|
||||
it is not the actual vram address, it is the tile number, that is to say,
|
||||
the physical vram address of the sprite can be obtained by the following:
|
||||
multiply the sprite "address" by 32 (because each tile is 32 bytes) and add it
|
||||
to the starting vram address that you set in the $2101 register.
|
||||
this tile number points to the first tile in the sprite...the snes expects the
|
||||
rest of tiles to follow in the order described in the previous section...
|
||||
the next byte containes the 9th bit of the tile "address" and a few attributes
|
||||
|
||||
bit 0 = 9th bit
|
||||
bit 1-3 = palette number
|
||||
bit 4,5 = playfield priority
|
||||
bit 6 = horizontal flip
|
||||
bit 7 = horizonal flip
|
||||
|
||||
the palette number is not a 4 bit number, so obviously, you can only choose
|
||||
between 8 of the 16 palettes....if you set these bits to all 0, you will be
|
||||
selecting the eigth palette (palette 7), if you set them to "001" it is the
|
||||
ninth palette etc...it was trial and error, and some <serious> frustration
|
||||
before i figured this one out :)
|
||||
|
||||
to set these bytes in the OAM table, you must first setup the OAM "address"
|
||||
on the 16 bit register $2102 (and $2103). again this is not a real address,
|
||||
you use the 7 lowest bits of this address to select which sprite you
|
||||
would like to set the data for (sprite 0 to sprite 127)
|
||||
|
||||
then you can write the four bytes discussed above to the register $2104, its
|
||||
like the color register, auto incrementing...
|
||||
|
||||
so....what are all the other bits for??? (the remaining 9) well, i know about
|
||||
only two others, the highest bit (bit 15) is a sprite priority bit, it is
|
||||
basically the bit you set to "turn on" the sprite, and keep it being redrawn
|
||||
on the screen...its a little more than this, but thats all i know about its
|
||||
behavior. so when you setup your table, (and periodically throughout the
|
||||
sprites' display lifecycle) you must set this bit high....(for any sprite being
|
||||
displayed)
|
||||
|
||||
there is another small table (32 bytes) that you must load into the OAM, these
|
||||
consist of two bits for every sprite, one of the bits being the 9th horizontal
|
||||
position bit, and the other is the size select bit (remember we can pick from
|
||||
two different size sprites on the screen at once) the first bit is the
|
||||
most significant horizontal location, and the second is the size toggle
|
||||
bit...
|
||||
|
||||
to write this table the OAM, you must set the 9th bit of the "address" in $2103
|
||||
to one....then write the bytes, again it is an auto incrementing register
|
||||
|
||||
make sure that you have enabled the sprites to be on a particular plane (see
|
||||
the yoshi doc, on $212C....and make sure that you have set your palette
|
||||
correctly (remember sprite palette 0 is the 8th palette!!!)
|
||||
|
||||
good luck....
|
||||
Reference in New Issue
Block a user