git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

commit ade8bc1f68cfeb49682373d6cef85b8f0a47ffdc
parent c24ddf3ad7c3fc25f407356bc78303f7270068e0
Author: Toxa <56631470+untoxa@users.noreply.github.com>
Date:   Mon, 29 Apr 2024 09:07:21 +0300

Merge pull request #649 from michel-iwaniec/nes_add_pal_support-v3

NES: Add PAL support
Diffstat:
Agbdk-lib/examples/cross-platform/display_system/src/display_system.c53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/include/gb/gb.h10++++++++++
Mgbdk-lib/include/msx/msx.h11+++++++++++
Mgbdk-lib/include/nes/nes.h17+++++++++++++++++
Mgbdk-lib/include/sms/sms.h13++++++++++---
Mgbdk-lib/libc/targets/mos6502/nes/crt0.s103++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mgbdk-lib/libc/targets/mos6502/nes/global.s2+-
Mgbdk-lib/libc/targets/z80/gg/global.s4++--
Mgbdk-lib/libc/targets/z80/msxdos/global.s4++--
Mgbdk-lib/libc/targets/z80/sms/global.s4++--
10 files changed, 192 insertions(+), 29 deletions(-)

diff --git a/gbdk-lib/examples/cross-platform/display_system/src/display_system.c b/gbdk-lib/examples/cross-platform/display_system/src/display_system.c @@ -0,0 +1,53 @@ +/* + display_system.c + + Displays the system gbdk is running on. + + This will report one of these three: + * 60 Hz + * 50 Hz + * 50 Hz, Dendy-like (only applicable gbdk-nes port) + +*/ + +#include <stdio.h> +#include <gbdk/platform.h> +#include <gbdk/font.h> +#include <gbdk/console.h> + +const char* get_system_name(uint8_t system) +{ + switch(system) + { + case SYSTEM_60HZ: + return "60 Hz"; + case SYSTEM_50HZ: +#if defined(NINTENDO_NES) + // For gbdk-nes, we can also inspect the bits in _SYSTEM to more specifically + // report the console as a Dendy-like Famiclone instead of an official PAL NES. + // This distinction is rarely useful as both run on 50Hz, but can be a + // useful feature for running this detection program on unknown hardware. + if((_SYSTEM & 0xC0) == SYSTEM_BITS_DENDY) + return "50 Hz (Dendy-like)"; + else + return "50 Hz"; +#else + return "50 Hz"; +#endif + default: + return "Unknown"; + } +} + +void main(void) +{ + font_t ibm_font; + uint8_t system = get_system(); + // Init font system and load font + font_init(); + ibm_font = font_load(font_ibm); + DISPLAY_ON; + gotoxy(4, 4); + printf("System: %s", get_system_name(system)); + vsync(); +} diff --git a/gbdk-lib/include/gb/gb.h b/gbdk-lib/include/gb/gb.h @@ -24,6 +24,9 @@ #undef MSX #endif +#define SYSTEM_60HZ 0x00 +#define SYSTEM_50HZ 0x01 + #if defined(__TARGET_ap) #define ANALOGUEPOCKET #elif defined(__TARGET_gb) @@ -410,6 +413,13 @@ void mode(uint8_t m); */ uint8_t get_mode(void) PRESERVES_REGS(b, c, d, e, h, l); +/** Returns the system gbdk is running on. + +*/ +inline uint8_t get_system(void) { + return SYSTEM_60HZ; +} + /** GB CPU type @see DMG_TYPE, MGB_TYPE, CGB_TYPE, cpu_fast(), cpu_slow(), _is_GBA diff --git a/gbdk-lib/include/msx/msx.h b/gbdk-lib/include/msx/msx.h @@ -28,6 +28,10 @@ #define MSXDOS #endif +extern const uint8_t _SYSTEM; + +#define SYSTEM_60HZ 0x00 +#define SYSTEM_50HZ 0x01 #define VBK_REG VDP_ATTR_SHIFT @@ -112,6 +116,13 @@ void mode(uint8_t m) OLDCALL; */ uint8_t get_mode(void) OLDCALL; +/** Returns the system gbdk is running on. + +*/ +inline uint8_t get_system(void) { + return _SYSTEM; +} + /* Interrupt flags */ /** Disable calling of interrupt service routines */ diff --git a/gbdk-lib/include/nes/nes.h b/gbdk-lib/include/nes/nes.h @@ -25,6 +25,13 @@ #undef MSX #endif +#define SYSTEM_BITS_NTSC 0x00 +#define SYSTEM_BITS_PAL 0x40 +#define SYSTEM_BITS_DENDY 0x80 +extern const uint8_t _SYSTEM; + +#define SYSTEM_60HZ 0x00 +#define SYSTEM_50HZ 0x01 #define RGB(r,g,b) RGB_TO_NES(((r) | ((g) << 2) | ((b) << 4))) #define RGB8(r,g,b) RGB_TO_NES((((r) >> 6) | (((g) >> 6) << 2) | (((b) >> 6) << 4))) @@ -255,6 +262,16 @@ void mode(uint8_t m) NO_OVERLAY_LOCALS; */ uint8_t get_mode(void) NO_OVERLAY_LOCALS; +/** Returns the system gbdk is running on. + +*/ +inline uint8_t get_system(void) { + if(_SYSTEM == SYSTEM_BITS_NTSC) + return SYSTEM_60HZ; + else + return SYSTEM_50HZ; +} + /** Global Time Counter in VBL periods (60Hz) Increments once per Frame diff --git a/gbdk-lib/include/sms/sms.h b/gbdk-lib/include/sms/sms.h @@ -33,10 +33,10 @@ extern const UBYTE _BIOS; -extern const UBYTE _SYSTEM; +extern const uint8_t _SYSTEM; -#define SYSTEM_PAL 0x00 -#define SYSTEM_NTSC 0x01 +#define SYSTEM_60HZ 0x00 +#define SYSTEM_50HZ 0x01 #define VBK_REG VDP_ATTR_SHIFT @@ -121,6 +121,13 @@ void mode(uint8_t m) OLDCALL; */ uint8_t get_mode(void) OLDCALL; +/** Returns the system gbdk is running on. + +*/ +inline uint8_t get_system(void) { + return _SYSTEM; +} + /* Interrupt flags */ /** Disable calling of interrupt service routines */ diff --git a/gbdk-lib/libc/targets/mos6502/nes/crt0.s b/gbdk-lib/libc/targets/mos6502/nes/crt0.s @@ -72,6 +72,7 @@ _bkg_scroll_y:: .ds 1 _attribute_row_dirty:: .ds 1 _attribute_column_dirty:: .ds 1 .crt0_forced_blanking:: .ds 1 +__SYSTEM:: .ds 1 .define __crt0_NMITEMP "___SDCC_m6502_ret4" @@ -177,21 +178,36 @@ ProcessDrawList: .delay_to_lcd_scanline:: lda #0 sta *.acc - ldy #(19-5) + ldy #(19-5) nop nop bne 2$ 1$: - ldy #19 + ldy #15 2$: dey - bne 2$ ; -> 2 + 18*5 + 4 = 91 cycles - lda *.acc + bne 2$ ; -> 2 + 14*5 + 4 = 76 cycles + + nop + nop ; -> 4 cycles + + lda #144 ; Initialize A with PAL fractional cycle count + ; +7 cycles for NTSC scanlines + bit *__SYSTEM + bvs 3$ + lda #171 ; NTSC fractional cycle count + nop + nop + nop +3$: ; -> 15 NTSC cycles / 8 PAL cycles + ; Add fractional cycles and branch on carry clc - adc #85 - bcc 3$ -3$: - sta *.acc ; -> 12.666 cycles + adc *.acc + sta *.acc + bcs 4$ +4$: + sta *.acc ; -> 13.666 NTSC cycles / 13.5625 PAL cycles + dex bne 1$ ; -> 5 cycles rts @@ -238,12 +254,22 @@ __crt0_NMI: lda *0x00 dex bne 1$ + ; Do additional delay of 5186 cycles if running on a PAL system, and -5*7 + 2 = -33 for alignment + ; This is to compensate for the longer vblank period of 7459 vs NTSC's 2273 + bit *__SYSTEM + bvc 2$ + nop + ldy #5 + ldx #(14-7) +3$: + dex + bne 3$ + dey + bne 3$ +2$: ; ...then delay for desired number of scanlines ldx *__lcd_scanline jsr .delay_to_lcd_scanline - ; Additional alignment - nop - nop ; Call the handler jsr .jmp_to_LCD_isr __crt0_NMI_skip: @@ -306,11 +332,42 @@ __crt0_setPalette: bne 1$ rts -__crt0_waitPPU: -__crt0_waitPPU_loop: + +.macro CRT0_WAIT_PPU ?.loop +.loop: lda PPUSTATUS - bpl __crt0_waitPPU_loop - rts + bpl .loop +.endm + +; +; Detects system. After execution, A contains the following values: +; +; 0: NTSC NES/Famicom +; 1: PAL NES +; 2: Dendy-like Famiclone +; +.macro CRT0_WAIT_PPU_AND_DETECT_SYSTEM ?.loop, ?.end_of_loop, ?.end + ldx #0 + ldy #0 +; 256 iterations of the inner loop (X) takes 256 * (4 + 2 + 2 + 3) - 1 = 2816 cycles +; 1 iteration of the outer loop takes 2816 + 2 + 3 = 2821 cycles +; And different systems will have the following contents in Y: +; NTSC: 29780 / 2821 = 10 +; PAL: 33247 / 2821 = 11 +; Dendy: 35464 / 2821 = 12 +.loop: + bit PPUSTATUS + bmi .end_of_loop + inx + bne .loop + iny + bne .loop +.end_of_loop: + tya + sec + sbc #10 +.end: +.endm .macro CRT0_CLEAR_RAM ldx #0x00 @@ -366,11 +423,19 @@ __crt0_RESET_bankSwitchValue: ; Disable NMIs and rendering sta PPUCTRL sta PPUMASK - ; Wait for PPU warm-up - jsr __crt0_waitPPU - jsr __crt0_waitPPU - ; Clear RAM and VRAM + ; Clear RAM CRT0_CLEAR_RAM + ; Wait for PPU warm-up / detect system + bit PPUSTATUS + CRT0_WAIT_PPU + CRT0_WAIT_PPU_AND_DETECT_SYSTEM + ; Store system in upper two bits of __SYSTEM, to allow bit instruction to quickly test for PAL + clc + ror + ror + ror + sta *__SYSTEM + ; Clear VRAM jsr __crt0_clearVRAM ; Hide sprites in shadow OAM, and perform OAM DMA ldx #0 diff --git a/gbdk-lib/libc/targets/mos6502/nes/global.s b/gbdk-lib/libc/targets/mos6502/nes/global.s @@ -1,7 +1,7 @@ ;; Transfer buffer (lower half of hardware stack) __vram_transfer_buffer = 0x100 ;; Number of 8-cycles available each frame for transfer buffer - VRAM_DELAY_CYCLES_X8 = 174 + VRAM_DELAY_CYCLES_X8 = 172 ;; Keypad .UP = 0x08 diff --git a/gbdk-lib/libc/targets/z80/gg/global.s b/gbdk-lib/libc/targets/z80/gg/global.s @@ -225,8 +225,8 @@ .BIOS = 0xC000 - .SYSTEM_PAL = 0x00 - .SYSTEM_NTSC = 0x01 + .SYSTEM_NTSC = 0x00 + .SYSTEM_PAL = 0x01 .CPU_CLOCK = 3579545 diff --git a/gbdk-lib/libc/targets/z80/msxdos/global.s b/gbdk-lib/libc/targets/z80/msxdos/global.s @@ -287,8 +287,8 @@ .MAP_FRAME2 = 0xfffe .MAP_FRAME3 = 0xffff - .SYSTEM_PAL = 0x00 - .SYSTEM_NTSC = 0x01 + .SYSTEM_NTSC = 0x00 + .SYSTEM_PAL = 0x01 .CPU_CLOCK = 3579545 diff --git a/gbdk-lib/libc/targets/z80/sms/global.s b/gbdk-lib/libc/targets/z80/sms/global.s @@ -227,8 +227,8 @@ .BIOS = 0xC000 - .SYSTEM_PAL = 0x00 - .SYSTEM_NTSC = 0x01 + .SYSTEM_NTSC = 0x00 + .SYSTEM_PAL = 0x01 .CPU_CLOCK = 3579545

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.