User:Fiskbit

From NESdev Wiki
Revision as of 09:58, 8 September 2021 by Fiskbit (talk | contribs) (PPU behavior. MMC3 scanline counter behavior. TV-NET info. FAM-NET controller.)
Jump to navigationJump to search

I'll be staging information here before finding a place to move it to on the wiki.

CPU / APU

Behavior

  • When the CPU comes out of reset, it is random whether it is aligned on the first or second half of an APU cycle (and thus random whether it begins on a GET or PUT cycle).
  • The state of the CPU's OUT pins is only updated when transitioning from a GET to PUT cycle. Thus, changes to OUT state lasting only 1 cycle (such as when toggled with an INC instruction) may be missed by the joypad device. This can be used to determine CPU/APU alignment, but poses a problem for expansion port devices that use OUT bits to signal when to snoop the data bus.
  • Readable APU registers ($4015 and, if modded, the test registers) drive the internal CPU bus, but not the external CPU bus, so they do not affect external open bus state. Therefore, a dummy read from one of these registers on the cycle before a read from external open bus (such as by using page crossing on an indexed read) will not change the external open bus value.
  • The CPU clock divider is not affected by reset. Therefore, resetting the CPU does not change CPU/PPU sub-cycle alignment.

APU register reads

The CPU has an internal address bus onto which separate 6502, OAM DMA, and DMC DMA buses are multiplexed. APU registers can only be read when bits [15:5] of the 6502 address bus match the $4000-$401F range. When they match during a read, bits [4:0] of the internal CPU address bus will be checked for a matching register. If those bits are $16 or $17, the relevant joypad is clocked, and if they are $15 or the CPU test pin is asserted, the internal data bus is isolated from the external data bus (preventing the register read from affecting external open bus) and fed from any matching APU register.

Some unexpected edge cases result from this. Whether APU registers can be read depends on whether the 6502 address bus is in the APU register range, so if it is not, then OAM DMA from the $4000-40FF page will be unable to read them and will not clock joypads. However, if it is in that range when DMA occurs (because the CPU is currently executing from or reading from this range), then any DMA from an address with bits [4:0] matching a readable register or with the test pin asserted will trigger a register read, either overriding the value that would normally be read by the DMA or, in the case of non-test joypad reads, potentially causing a bus conflict.

This has relevance to real workloads. If a joypad register is read at the same time as a DMC DMA from an address matching an APU register, the DMA will perform a register read, possibly with a bus conflict. Though not yet tested, this should also be able to cause an additional joypad clock, at least for the other joypad (as it is unknown whether additional same-joypad reads are ignored if on consecutive cycles). Thus, an audible glitch may occur if using the repeated-read method of avoiding joypad bit deletion.

Revision differences

Letterless

  • 4-cycle DMA glitches do not occur.
  • When DMA collides with a joypad read, one extra read occurs on each halt. Behavior is not yet fully understood.

PPU

Behavior

OAM

  • Writes to OAM during rendering are ignored.
  • Disabling rendering outside of vblank can cause OAM to be corrupted when rendering next begins. If the disable write occurs approximately in the ranges of dots 0-125 or 254-318, then 2 sprite tiles (1 row) will be corrupted with the value of row 0 when rendering is next enabled. If the disable write occurs in the range 126-253 and rendering is enabled again outside of vblank, then corruption can occur on some CPU/PPU alignments, though this corruption is poorly understood. Dots 319-340 appear safe. Note that these values may not be exact to the dot.
  • Signal reflection from a cartridge on the CPU data lines can cause OAM to corrupt. Cartridges with long or thin traces should include 30-100 ohm termination resistors in-series on these lines to suppress signal reflection. This issue has been observed on the FDS, PowerPak, and original Everdrive N8. https://forums.nesdev.org/viewtopic.php?p=232140#p232140

Fetching

  • During rendering, dot 0 of each scanline performs the first half of a low BG tile byte fetch. This means the address is placed on the bus and thus visible to the cartridge, but the read is never performed. This behavior is critical for MMC3 scanline counting when background uses the $1000 table and sprites use the $0000 table, such as in Wario's Woods. Note that all 2-dot fetches are scheduled by the preceding dot, so when dot 340 is skipped as happens at the start of every odd frame, dot 0 simply completes 340's fetch rather than starting this half-fetch.
  • The "garbage" fetches during sprite tile fetching and the end of the scanline are all nametable fetches; attribute fetches are replaced with nametable fetches in these ranges. The addresses of these fetches are all based on v, as with normal fetches.
  • Writing to v on the first dot of a fetch can result in the low 8 bits being latched from the old v and the high 6 bits coming from the new v, resulting in a fetch from the wrong location. This can happen naturally at dot 258, where the low bits latch on dot 257 before the horizontal component of v is updated and the high bits on 258 after the update. Note that this applies to all fetches, but should only result in mixed addresses on nametable and attribute table fetches.

Palettes

  • On revisions that support reading from palette RAM, doing so via the PPUDATA register at the same time as forced greyscale, as seen in the NTSC border at dot 326, disables forced greyscale for that dot, presumably to prevent the greyscale from clearing the low 4 bits of the value. Greyscale is actually forced everywhere outside of draw range, but can only be seen at the start of the border.
  • Reads from palette RAM do not set bits 7-6, so these will return PPU open bus.
  • The background palette hack ignores bit 14 of v.
  • When rendering ends at the end of scanline 239, if the value left in v from rendering points into palette RAM, the NTSC border on scanlines 240-241 will automatically display the color pointed to by v (the "background palette hack"). This can be seen in the first corridor of Metal Storm.
  • The auto-increment behavior when writing to $2007 is delayed 1 dot after the write becomes effective. This means writing to palette RAM will show the newly-written color for 1 dot before advancing to the next color.
  • Disabling rendering mid-screen appears to be capable of corrupting palette RAM, but the specifics are not yet entirely known. The corrupted entry appears to depend on the value of v. https://forums.nesdev.org/viewtopic.php?f=2&t=23209

Miscellaneous

  • The PPU clock divider is affected by reset. Therefore, resetting the PPU changes the CPU/PPU sub-cycle alignment.

Revision differences

2C02A

  • Writes to $2001 disrupt rendering similar to toggling it off and on.
  • PPU bus write timing differs from later revisions in a way that causes glitches on the Everdrive Pro. (Normal cartridges seem unaffected.)

Mappers

MMC3

  • The scanline counter clocks when A12 rises after at least 3 M2 clocks with A12 low.
  • The scanline counter behavior can depend on the aborted fetch performed by the PPU on the idle dot.
  • Writing to $C001, clocking the counter, and writing to $C001 again will cause the counter to be OR'ed with value $80 on the next clock and neither decremented nor reloaded.

TV-NET

MC-1200

$5000-57FF: CPU/PPU RAM
$6000-6007: Registers (mirrored across $6000-6FFF)
$7000-7FFF: Cartridge PRG-RAM
$8000-FFFF: Modem/cartridge ROM

$6006 appears to control what is mapped into the $5000-57FF window. Observed writes are 4 before writing to what appears to be 1 KB of special graphics memory (MMC5-style ExRAM?) at $5000 and 3 after, and 5 to map in CHR-RAM, which is 32 KB and can be banked using $6002 in 1 KB amounts (unknown if bit 0 ignored).

When booted without a cartridge inserted, modem ROM is loaded at $8000-FFFF, with unique data at $8000-CFFF and the same 4 KB mirrored across $D000-FFFF. When booted with a cartridge, $8000-DFFF are replaced with cartridge ROM, and $7000-7FFF contains PRG-RAM. $6002 being 0 appears to signal that a cartridge is inserted. With a cartridge inserted, $8000-8001 is a pointer to a validation signature that must match a NULL-terminated string at $F223, and $8004-8005 is a pointer to the cartridge entrypoint. The JRA-PAT 3.00 cartridge (blue/green/yellow label) has been found to contain a 256 KB ROM and 32 KB battery-backed RAM. Bankswapping is not yet understood.

Contents of $8000-FFFF on letterless, A, and B revision modems have been found to be the same. Included is the string "ROM VERSION A1.0-06.15", suggesting the remaining ROM contents are likely also the same.

Controllers

MC-1200 controller

Covered on the forums here. Japanese is naively translated with a dictionary. Uses 3 shift registers; every button can be pressed simultaneously. Strobes with $4016.0.

$4016.1
0  - P/T switch (1 if T)
1  - 終了 (Shuuryou / End)
2  - F3
3  - (Always 1)
4  - F1
5  - F2
6  - F4
7  - F5
8  - 1
9  - 4
10 - 7
11 - (Always 1)
12 - 2
13 - 3
14 - 5
15 - 6
16 - *
17 - Left
18 - 実行 (Jikkou / Run)
19 - Right
20 - 8
21 - 9
22 - 0
23 - .

24+ - (Always 1)

MC-4800 controller

Included with the TV-NET Rank 2, this controller offers the same functionality as the base TV-NET controller plus 8 additional buttons. Strobes with $4016.0.

$4016.1
0  - P/T switch (1 if T)
1  - • / 実行 (Jikkou / Run)
2  - 後退 (Koutai / Backspace) / F3
3  - (Always 1)
4  - F1
5  - 番組 (Bangumi / Program) / F2
6  - 印字 (Inji / Typing?) / F4
7  - 取消 (Toke / Cancel) / F5
8  - 1
9  - 4
10 - 7
11 - (Always 1)
12 - 2
13 - 3
14 - 5
15 - 6
16 - *
17 - Left
18 - # / 実行 (Jikkou / Run)
19 - Right
20 - 8
21 - 9
22 - 0
23 - ,
24 - 入力 (Nyuuryoku / Input)
25 - Up
26 - Down
27 - 文字 (Moji / Character)
28 - 機能 (Kinou / Function)
29 - 切替 (Kika / Exchange) / F6
30 - 再送 (Saisou / Resend) / F7
31 - 停再 (Tomasai? / Stop again?) / F8

FAM-NET keyboard

This controller is equivalent to a Famicom keyboard with only 16 keys. The mapping to Famicom keyboard keys is described below. Note that this information is based on a FAM-NET I controller, but the controller bundled with the FAM-NET II is believed to be the same device.

LINE - F1
←    - ←
•    - .
EB   - F7
0    - 0
1    - 1
2    - 2
3    - 3
4    - 4
5    - 5
6    - 6
7    - 7
8    - 8
9    - 9
*    - space
#    - RETURN

Super Famicom NTT data keypad

0  - B
1  - Y
2  - 前ページ (Mae peeji / Previous page)
3  - 次ページ (Ji peeji / Next page)
4  - Up
5  - Down
6  - Left
7  - Right
8  - A
9  - X
10 - L
11 - R
12 - (Always 0)
13 - (Always 1)
14 - (Always 0)
15 - (Always 0)
16 - 0
17 - 1
18 - 2
19 - 3
20 - 4
21 - 5
22 - 6
23 - 7
24 - 8
25 - 9
26 - *
27 - #
28 - .
29 - C
30 - (Always 0)
31 - 通信終了 (Tsuushin shuuryou / End communication)