* 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
- Move TIM ISR emulation to dedicated function .tim_emulation and dedicated file timer_isr.s
- Make TIM ISR emulation save entirety of ALL_REGTEMPS_BEGIN to ALL_REGTEMPS_END
- Improve emulation to allow average TIM rate to be faster compared to vblank rate
- Add support for consistent average TIM rate on PAL, for a less system-dependent timer
- Add support for different base dividers defined by GB-like TAC_REG variable
- Add defines values for "vblank parity mode" to global.s and nes.h
- Update crt0 init code to set TMA_REG to vblank parity mode correctly for PAL/Dendy
- Update documentation, describing the improved GB TIM emulation and vblank parity mode
- Update cross-platform IRQ example to better showcase the emulation
* NES: Make sure TIM ISR handlers are thread-safe
- Backup and restore REGTEMP area when calling TIM ISR in vblank
- Update irq example to use #pragma nooverlay for tim handler
- Add warning and explanation about having to use #pragma for TIM handlers in NES section of docs
- Add @anchor to docs, and a code example for #pragma nooverlay
- Update irq.c with `#pragma nooverlay` only being applied if NINTENDO_NES is defined
- Add more detailed comment of `#pragma nooverlay` in irq.c
- Add reference to docs in gb.h
- Add similar reference to nes.h
NES: Align coordinates and scanline counting in LCD ISR implementation with GB, add SCX / SCY / LYC defines
- Change definition of _lcd_scanline to be -1 less than current, aligning with GB LYC register
- Change definition of _bkg_scroll_y to match GB's SCY, being relative to current scanline
- Refactor do_hblank_writes, delay_fractional and delay_to_scanline subroutines in crt0
- Add "#define LYC_REG" and "#define LY_REG" as aliases of _lcd_scanline
- Add #defines for SCX and SCY to alias _bkg_scroll_x / _bkg_scroll_y shadow variables
- Change text scroller example to use LYC_REG / SCX / SCY instead of _lcd_scanline / move_bkg, remove redundant #ifdefs
- Add subtle shake in y direction to text scroller example, to check that GB / NES coordinates match
- Update "From Game Boy to NES" section's descriptions of LCD handlers
- Update "Migrating to new GBDK versions" with a short description of bkg_scroll_y changing from absolute to relative Y coordinates for 4.4.0
MegaDuck: Updated on duck laptop IO commands, expose a few vars
- Printer command labeled and some query commands for the init result
- Run cart command labeled
- Add add_TIM / remove_TIM functions to nes.h
- Refactor implementation in lcd.s to support add_TIM / remove_TIM
- Add TMA_REG / TIMA_REG / TAC_REG vars to emulate GB hardware timer register
- Add call to TIM function at end of NMI handler in crt0.s, and make it use TMA_REG / TIMA_REG vars
- Add implementation for set_interrupts in lcd.s, replacing JMP instruction with RTS when disabled
- Enable NES target in examples/cross-platform/irq and replace delay(1000) call with 60 vsyncs
- Update examples/cross-platform/scroller and examples/cross-platform/irq to use set_interrupts
- Update documentation to describe use-cases and limitations of TIM handler
Adds a mention to the docs that HIDE_BKG and SHOW_BKG do not work while running in CGB mode, the relevant bit instead overrides all background/window priority over the sprite layer, see Pandocs 4.4
* Copy gbdk-lib/include/gb/bcd.h to gbdk-lib/include/nes/bcd.h
* Add bcd asm implementation in libc/asm/mos6502/bcd.s
* Update bcd.h to accept NES target
* Update examples/cross-platform/bcd to build for nes
* Refactor .delay_to_lcd_scanline to not use Y register. Remove outdated comments.
* Move .jmp_to_LCD_isr call to vsync routine, and have it copy shadow PPU register values to a buffer
* Add MAX_LCD_ISR_CALLS define to limit the deferred PPU register write buffer size
* Add .do_lcd_ppu_reg_writes for writing buffer aligned to hblank, and calls to .delay_to_lcd_scanline
* Make .do_lcd_ppu_reg_write restore Y-scroll for start-of-frame after every update, to mitigate glitches in lag frames
* Have LCD at scanline#0 be treated as a special-case, where VBL shadow values are replaced without adding to the buffer
* Re-introduce variable to skip NMI as __crt0_disableNMI, and set it in vsync during buffer building
Update text_scroller example:
* Fix NES-version of code to do multiple splits like the other platforms do
* Fill nametable with '*' to make splits more visible
* TODO: Find out why fill_bkg_rect isn't working on GB
* Name change for consistency with other platforms: _system_bits -> _SYSTEM
* Add _SYSTEM extern to msx.h and sms.h
* Make all platforms have SYSTEM_60HZ and 0x00 and SYSTEM_50HZ as 0x01
* Make _SYSTEM have uint8_t type instead of UBYTE
* Add new zeropage variable _system_bits to indicate NTSC/PAL/Dendy system
* Modify init code to detect NTSC/PAL/Dendy via cycle counting, storing result in _system_bits
* Modify fake-LCD-ISR delays in NMI handler to accommodate PAL timings
Cross-platform:
* Change existing SYSTEM_NTSC / SYSTEM_PAL defines in sms.h to SYSTEM_60HZ / SYSTEM_50HZ, and copy them to gb.h / nes.h / msx.h
* Add new cross-platform function get_system for all ports, to query whether running on a 60Hz or 50Hz system
* Add minimal cross-platform display_system example to exercise get_system