📄 qsnesdoc.html
字号:
windowing, the appropriate bits in <A HREF="#Reg212E">registers $212E and
$212F</A> must be set in addition to the bits in these registers.
<P><A NAME="Reg2125"></A><B><FONT FACE="Lucida Console">Register $2125:
Window mask settings #2 (1b/W)</FONT></B>
<P><TT>ccccssss c: Settings for "color windows" s: Settings
for sprite windows</TT>
<P><TT>Both of these sets of four bits are formatted the same as <A HREF="#Reg2123">registers
$2123 and $2124</A>.</TT>
<P>This is like the last set of registers except it is for sprites and
"color windows". I don't know what color windows are; won't someone
explain it?
<P><A NAME="Reg2126"></A><B><FONT FACE="Lucida Console">Register $2126
to $2129: Window position designations (4*1b/W)</FONT></B>
<P><TT>$2126 Window 1 left position</TT>
<BR><TT>$2127 Window 1 right position</TT>
<BR><TT>$2128 Window 2 left position</TT>
<BR><TT>$2129 Window 2 right position</TT>
<P><TT>For each of these bytes:</TT>
<BR><TT>xxxxxxxx x: pixel position of window left or right position.</TT>
<P>These regs simply tell the range of the window. The window range
is inclusive, so if clipping is IN, and the window range is from pixels
3 to 6, all four pixels will be clipped rather than just pixels 4 and 5.
If clipping is out, however, clipping will be from pixels 0 to 2 and 7
to 255 inclusive.
<P><A NAME="Reg212A"></A><B><FONT FACE="Lucida Console">Register $212A
and $212B: Mask Logic settings (2*1B/W)</FONT></B>
<P><TT>
Parameters for:</TT>
<BR><TT>$212A 44332211 4: BG4 3: BG3 2: BG2
1: BG1</TT>
<BR><TT>$212B ????ccss c: Color windows s:
Sprites</TT>
<P><TT>Each of the two bits for each BG and sprites determines the mask
logic as follows:</TT>
<P><TT>00 OR 10 XOR</TT>
<BR><TT>01 AND 11 XNOR</TT>
<P>Apparently, these registers apply only for BGs and sprites that have
both windows enabled at the same time. If only one window is enabled,
these bits should be ignored. I'm not sure whether the logic is applied
to the visible regions or the clipped regions. For example, if pixels
10-20 and 50-60 are clipped, I don't know whether OR or AND would be used
to clip both regions and which would clip neither.
<P><A NAME="Reg212E"></A><B><FONT FACE="Lucida Console">Register $212E
and $212F: Window designation (2*1b/W)</FONT></B>
<P><TT>$212E Main-screen window designation</TT>
<BR><TT>$212F Sub-screen window designation</TT>
<BR><TT>For each of these:</TT>
<BR><TT>---sdcba s: sprites enable d: BG4 enable c: BG3
enable</TT>
<BR><TT>
b: BG2 enable a: BG1 enable</TT>
<P>These registers are formatted the same as the visibility designation
<A HREF="#Reg212C">registers $212C and $212D</A>. A bit must be set
in both $212C and $212E or $212D or $212E in order for windows to be enabled
for that layer (BG or sprites).
<BR>
<CENTER><A NAME="RegCounter"></A><FONT SIZE=+2>Counter/IRQ/NMI Registers</FONT></CENTER>
<CENTER> </CENTER>
<P><A NAME="Reg2137"></A><B><FONT FACE="Lucida Console">Register $2137:
Software latch for h/v counter (1b/R)</FONT></B>
<P>This register does not return a useful value. Apparently, though,
you have to read from this register before attempting to read $213C or
$213D.
<P><A NAME="Reg213C"></A><B><FONT FACE="Lucida Console">Register $213C
& $213D: Horizontal/Vertical scan location (Db/R)</FONT></B>
<PRE>For each of the registers:
-------l llllllll l: scanline number ($213C) or horizontal position ($213D)
* vertical range is 0 to 261, 0=top of screen (values over 0-223/0-238 are in the vblank)
* horizontal range is from 0 to 339, 0=far-left of screen.</PRE>
This register tells where exactly on the screen the SNES is sending data
to the TV. For the horizontal counter, apparently, zSNES always alternates
between sending a strange value (most often 8) and 1, respectively, in
register $213C, but only after $2137 has been read once. For the
vertical counter, the low byte of the scanline is sent, followed by the
high byte, and afterwards nothing but zeros (until $2137 is read again.)
One doc suggests register $213F is related to this register, but I don't
know how so.
<P><A NAME="Reg4200"></A><B><FONT FACE="Lucida Console">Register $4200:
Counter Enable (1b/W)</FONT></B>
<PRE>n-vh---j n: NMI Interrupt enable v: vertical counter enable
h: horizontal counter enable j: joypad enable</PRE>
n and j must be set to enable NMI interrupts and the joypad. Not
sure of the exact effects of bits 4 and 5, but they probably must be set
to enable IRQ interrupts.
<P><A NAME="Reg4207"></A><A NAME="Reg4209"></A><B><FONT FACE="Lucida Console">Register
$4207/$4208 & $4209/$420A: Horizontal/Vertical IRQ trigger counters
(2*2b/W)</FONT></B>
<PRE>For each register:
???????l llllllll l: location to trigger IRQ</PRE>
When IRQs are enabled and the PPU starts drawing at the specified location,
an IRQ is generated. Horizontal IRQs are rarely used, because of
the high frequency (every scanline) of the interrupts.
<P><A NAME="Reg4210"></A><B><FONT FACE="Lucida Console">Register $4210:
NMI Register (1b/R)</FONT></B>
<PRE>n---vvvv n: nmi flag v: version number</PRE>
The full behavior of these bits is not known (at least, I don't know).
Yoshi doc lists "$5A22" for the v bits, whatever that means. Mario
World reads this register at the beginning of its NMI procedure and then
discards the value read. zSNES apparently returns a 1 in the n bit
when NMIs are enabled AND a vblank is in progress.
<P><A NAME="Reg4211"></A><B><FONT FACE="Lucida Console">Register $4211:
IRQ Register (1b/RW?)</FONT></B>
<PRE>i------- i: irq flag</PRE>
The full behavior of these bits is not known (at least, I don't know),
so take this description with a big grain of salt. If bits 4/5 of
<A HREF="#Reg4200">register $4200</A> are set, then as soon as the H/V
counter timer becomes the count value set in <A HREF="#Reg4207">registers
$4207 to $420A</A>, then an IRQ will be "applied" (unless the CPU interrupt
flag is enabled. If this is the case, then the interrupt will be
called as soon as the flag is cleared.) The IRQ routine must immediately
use SEI to prevent recursive calling, then read from this register to "un-apply"
the interrupt. The first read will return 1 in the i bit, then subsequent
reads will return 0. What happens to this register when bits 4/5
of <A HREF="#Reg4200">register $4200</A> are <I>not</I> set is unclear.
Some SNES programs use a loop to read this register (in emu's, often getting
stuck in this loop) but why a loop is used is unknown.
<P><A NAME="Reg4212"></A><B><FONT FACE="Lucida Console">Register $4212:
Status register IRQ Register (1b/RW?)</FONT></B>
<PRE>vh-----j v: whether in vblank state h: whether in hblank state
j: whether joypad is ready to be read</PRE>
This register is pretty simple; it returns whether in a vertical/horizontal
blank period (1=yes) and whether the joypad is ready to be read from registers
$4218 to $421F. The horizontal blank time lasts from "pixels" 256
to 339. (Not really pixels, since nothing is being drawn.) In zSNES,
<I>apparently</I>, the joypad becomes ready to be read once every frame,
and more specifically, scanline 227 (might not be a constant.) How
this bit gets cleared to 0, however, is unknown.
<P>A loop in the "leftover" demo suggests that the joypad bit is backwards;
that is, a value of 1 indicates the joypad is <I>not</I> ready. I
think some other demos suggest the opposite is true, though. Interestingly
enough, the demos still work regardless of their treatment of the bit.
Hmmm...
<CENTER> </CENTER>
<CENTER><A NAME="RegJoypad"></A><FONT SIZE=+2>Joypad Registers</FONT></CENTER>
<P><A NAME="Reg4218"></A><B><FONT FACE="Lucida Console">Register $4218
to $421F: Joypad registers(2*1b/R)</FONT></B>
<P><TT>$4218/$4219 Joypad 1 data</TT>
<BR><TT>$421A/$421B Joypad 2 data</TT>
<BR><TT>$421C/$421D Joypad 3 data</TT>
<BR><TT>$421E/$421F Joypad 4 data</TT>
<P><TT>The two registers for each joypad contain the following:</TT>
<P><TT>Low Byte B: B button Y: Y button
S: Select button T: Start button</TT>
<BR><TT>BYSTudlr u: Up d: Down l: Left
r: Right</TT>
<BR><TT>High Byte A: A button X: X button
L: Top-left button R: Top-right button</TT>
<BR><TT>AXLR????</TT>
<P>This is the easy way to read the joypad. Simply set bit 0 of <A HREF="#Reg4200">register
$4200</A>, and the SNES will automatically read the state of all the buttons
(probably once every frame) into these registers. These registers
may be read more than once; that is, reading these registers does not destroy
their values. It is best to wait for bit 0 of <A HREF="#Reg4212">register
$4212</A> to be set (set or cleared? I'm not sure) before reading
from these registers.
<P>Although there are only two joypad ports, two extra joypads can be accessed
through $421C-$421F using a multitap device.
<P><A NAME="Reg4016"></A><B><FONT FACE="Lucida Console">Registers $4016/$4217:
Old-style Joypad registers (2*1B/R/W)</FONT></B>
<P><TT>On read: $4016 is for Player 1; $4017 is for Player
2.</TT>
<BR><TT>???????b b: button state</TT>
<BR><TT>On write:</TT>
<BR><TT>???????? ?: strobe activation value</TT>
<P>These are called the "old-style" joypad registers because they are used
like the NES used them. First of all, to use these registers, bit
0 of $4200 must be clear (I suppose to prevent conflict between the SNES's
automatic read mechanism and the manual method.) If this bit is set,
then these registers simply return whether the joypad is connected (0=Not
connected.) Based on what commercial games do, it may be neccessary
to write a 0 before this function works.
<P>To use the old-style reading method, bit 0 of register $4200 must be
clear (probably to prevent conflict between the manual reading and the
SNES' automatic reading.) Like on the NES, two values should be written
before reading starts: a 1 followed by a 0. This "activates a strobe
in the joypad circuitry." Apparently, but not for certain, it is
only necessary to do this with $4016; that is, writing to one register
resets both joypads. Once the writing is done, each read from each register
will return the state of one button, in the following order:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -