* 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
- Move code for deferred isr buffer building to separate function .deferred_isr_run in file deferred_isr.s
- Introduce function .deferred_isr_reset to write shadow regs as first (VBL) buffer entry
- Add new subroutine .deferred_isr_reset_and_init that runs .deferred_isr_reset and .deferred_isr_run twice
- Drain buffer when DISPLAY_OFF is called, by making sure a single NMI execution happens before screen is turned off in vblank
- Change DISPLAY_OFF to write only DISPLAY_OFF flag and PPUMASK, but leave shadow_PPU_MASK unchanged
- Call .deferred_isr_reset_and_init in DISPLAY_ON when display changes from off to on
- Make DISPLAY_ON run run VBL / LCD handlers to reinitialize buffers when display switches from off to on
- Change early-out in NMI handler to rely on DISPLAY_OFF flag instead of shadow_PPUMASK
- Remove mentioned of manual-draining caveat in docs, as it no longer applies
- Add minor size/speed optimization of frame counter increment in NMI, to prevent branch penalties / incorrect system detection
* 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
- Define new constant .MAX_DEFERRED_ISR_CALLS as .MAX_LCD_ISR_CALLS+1
- Refactor vsync function for double-buffering, and have it flip the read index at completion
- Refactor .do_lcd_ppu_reg_writes, and rename to .do_hblank_writes
- Remove scroll glitch mitigation in .do_hblank_writes, as no longer needed
- Redefine __lcd_isr_ arrays sizes as 2*.MAX_DEFERRED_ISR_CALLS
- remove redundant ZP variable __crt0_disableNMI, as no longer needed
- TAB -> space conversion
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