mirror of
https://github.com/gbdk-2020/gbdk-2020.git
synced 2026-03-05 23:14:44 +01:00
* NES: Add support for various tilemap layout (mirroring) configurations - Introduce platform configuration, mainly to define tilemap layout NES_TILEMAP_[F|H|V|S] in platform_cfg.s + Add NES_TILEMAP_S|H|V|F setting for tilemap layout, and hard-code to NES_TILEMAP_S for now + Add NES_LOMEM setting to enable current default of using part of stack instead of BSS for attribute shadow buffer + Edit Makefile to copy platform_cfg.s (if it exists) to platform directory after build - Updates to attribute shadow buffer and dirty bits: + Add NUM_NT define for number of nametables used by a layout, and AT_SHADOW_WIDTH/_HEIGHT to denote the variable dimensions + Add convenience defines NT_2W / NT_2H to quickly test whether tilemap layout is two screens wide / high + Define _attribute_shadow and _attribute_row/_column_dirty in terms of NUM_NT + Update flush_attributes to support all layouts + Update get_bkg_xy_addr / set_bkg_tile_xy to support all layouts + Update set_bkg_attribute_xy[_nes16x16] to support all layouts + Update set_bkg_attributes[_nes16x16] to support all layouts, and correctly wrap to next AT in both directions + Update set_bkg_submap_attributes[_nes16x16] to support all layouts + Update set_bkg_submap to support all layouts, and contain common inner subroutine .set_bkg_common + Replace set_bkg_tiles with simpler implementation calling .set_bkg_common, and correctly wraps to next NT in both directions + Add set_bkg_based_tiles / set_bkg_based_submap implementations using the new common subroutine - Updates to C include files: + Define DEVICE_SCREEN_BUFFER_WIDTH/_HEIGHT based on NES_TILEMAP_ setting, doubling high-level size of WIDTH / HEIGHT conditionally + Add typedefs scroll_x_t / scroll_y_t as uint8_t or uint16_t based on NES_TILEMAP_ setting + Make move_bkg use scroll_x/y_t typedefs, set 9th scroll bit in shadow_PPUCTRL where needed, and compensate for 239->0 y wrapping - Updates to examples: + Update large_map example to use platform-agnostic settings for scroll wrapping and offset + Update rle_map to use a uint16_t for scroll position, to support NES_TILEMAP_H and NES_TILEMAP_F settings
101 lines
2.9 KiB
C
101 lines
2.9 KiB
C
/** @file nes/hardware.h
|
|
Defines that let the NES hardware registers be accessed
|
|
from C.
|
|
*/
|
|
#ifndef _HARDWARE_H
|
|
#define _HARDWARE_H
|
|
|
|
#include <types.h>
|
|
|
|
#define __SHADOW_REG extern volatile uint8_t
|
|
#define __REG(addr) volatile __at (addr) uint8_t
|
|
|
|
__REG(0x2000) PPUCTRL;
|
|
#define PPUCTRL_NMI 0b10000000
|
|
#define PPUCTRL_SPR_8X8 0b00000000
|
|
#define PPUCTRL_SPR_8X16 0b00100000
|
|
#define PPUCTRL_BG_CHR 0b00010000
|
|
#define PPUCTRL_SPR_CHR 0b00001000
|
|
#define PPUCTRL_INC32 0b00000100
|
|
__SHADOW_REG shadow_PPUCTRL;
|
|
|
|
__REG(0x2001) PPUMASK;
|
|
#define PPUMASK_BLUE 0b10000000
|
|
#define PPUMASK_RED 0b01000000
|
|
#define PPUMASK_GREEN 0b00100000
|
|
#define PPUMASK_SHOW_SPR 0b00010000
|
|
#define PPUMASK_SHOW_BG 0b00001000
|
|
#define PPUMASK_SHOW_SPR_LC 0b00000100
|
|
#define PPUMASK_SHOW_BG_LC 0b00000010
|
|
#define PPUMASK_MONOCHROME 0b00000001
|
|
__SHADOW_REG shadow_PPUMASK;
|
|
|
|
__REG(0x2002) PPUSTATUS;
|
|
__REG(0x2003) OAMADDR;
|
|
__REG(0x2004) OAMDATA;
|
|
__REG(0x2005) PPUSCROLL;
|
|
__REG(0x2006) PPUADDR;
|
|
__REG(0x2007) PPUDATA;
|
|
__REG(0x4014) OAMDMA;
|
|
|
|
#define DEVICE_SCREEN_X_OFFSET 0
|
|
#define DEVICE_SCREEN_Y_OFFSET 0
|
|
#define DEVICE_SCREEN_WIDTH 32
|
|
#define DEVICE_SCREEN_HEIGHT 30
|
|
|
|
#if defined(NES_TILEMAP_F)
|
|
// Full tilemap
|
|
#define DEVICE_SCREEN_BUFFER_WIDTH 64
|
|
#define DEVICE_SCREEN_BUFFER_HEIGHT 60
|
|
typedef uint16_t scroll_x_t;
|
|
typedef uint16_t scroll_y_t;
|
|
#elif defined(NES_TILEMAP_H)
|
|
// Horizontally arranged tilemap
|
|
#define DEVICE_SCREEN_BUFFER_WIDTH 64
|
|
#define DEVICE_SCREEN_BUFFER_HEIGHT 30
|
|
typedef uint16_t scroll_x_t;
|
|
typedef uint8_t scroll_y_t;
|
|
#elif defined(NES_TILEMAP_V)
|
|
// Vertically arranged tilemap
|
|
#define DEVICE_SCREEN_BUFFER_WIDTH 32
|
|
#define DEVICE_SCREEN_BUFFER_HEIGHT 60
|
|
typedef uint8_t scroll_x_t;
|
|
typedef uint16_t scroll_y_t;
|
|
#else
|
|
// Single-screen tilemap
|
|
#define DEVICE_SCREEN_BUFFER_WIDTH 32
|
|
#define DEVICE_SCREEN_BUFFER_HEIGHT 30
|
|
typedef uint8_t scroll_x_t;
|
|
typedef uint8_t scroll_y_t;
|
|
#endif
|
|
|
|
#define DEVICE_SCREEN_MAP_ENTRY_SIZE 1
|
|
#define DEVICE_SPRITE_PX_OFFSET_X 0
|
|
#define DEVICE_SPRITE_PX_OFFSET_Y -1
|
|
#define DEVICE_WINDOW_PX_OFFSET_X 0
|
|
#define DEVICE_WINDOW_PX_OFFSET_Y 0
|
|
#define DEVICE_SCREEN_PX_WIDTH (DEVICE_SCREEN_WIDTH * 8)
|
|
#define DEVICE_SCREEN_PX_HEIGHT (DEVICE_SCREEN_HEIGHT * 8)
|
|
|
|
// Scrolling coordinates (will be written to PPUSCROLL at end-of-vblank by NMI handler)
|
|
__SHADOW_REG bkg_scroll_x;
|
|
__SHADOW_REG bkg_scroll_y;
|
|
// LCD scanline - a software-driven version of GB's incrasing 'LY' scanline counter
|
|
__SHADOW_REG _lcd_scanline;
|
|
|
|
extern volatile UBYTE TIMA_REG;
|
|
extern volatile UBYTE TMA_REG;
|
|
extern volatile UBYTE TAC_REG;
|
|
|
|
// Compatibility defines for GB LY / LYC registers, to allow easier LCD ISR porting
|
|
#define SCY_REG bkg_scroll_y /**< Scroll Y */
|
|
#define rSCY SCY_REG
|
|
#define SCX_REG bkg_scroll_x /**< Scroll X */
|
|
#define rSCX SCX_REG
|
|
#define LY_REG _lcd_scanline /**< LCDC Y-coordinate */
|
|
#define rLY LY_REG
|
|
#define LYC_REG _lcd_scanline /**< LY compare */
|
|
#define rLYC LYC_REG
|
|
|
|
#endif
|