Skip to content
This repository was archived by the owner on Jun 29, 2025. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <malloc.h>
#include <string.h>
#include "libdragon.h"
#include "regsinternal.h"

/**
* @defgroup display Display Subsystem
Expand Down Expand Up @@ -172,6 +173,7 @@ static const uint32_t * const reg_values[] = {
pal_512p, ntsc_512p, mpal_512p,
pal_640p, ntsc_640p, mpal_640p,
};

/** @brief Video buffer pointers */
static void *buffer[NUM_BUFFERS];
/** @brief Currently active bit depth */
Expand All @@ -180,11 +182,14 @@ uint32_t __bitdepth;
uint32_t __width;
/** @brief Currently active video height (calculated) */
uint32_t __height;
/** @brief values to switch between in high res mode. Depends on TV type.*/
uint32_t __v_limits_values[2];
/** @brief Number of active buffers */
uint32_t __buffers = NUM_BUFFERS;
/** @brief Pointer to uncached 16-bit aligned version of buffers */
void *__safe_buffer[NUM_BUFFERS];


/** @brief Currently displayed buffer */
static int now_showing = -1;

Expand Down Expand Up @@ -233,6 +238,7 @@ static void __write_dram_register( void const * const dram_val )
MEMORY_BARRIER();
}


/**
* @brief Interrupt handler for vertical blank
*
Expand All @@ -251,6 +257,26 @@ static void __display_callback()
}
}

static bool _v_limits_switch;
/**
* @brief Interrupt handler for vertical blank
*
* If there is another frame to display, display the frame
* Also ensure the right sets of scan-lines is being displayed in high-res mode.
*/
static void __display_callback_highres_mode()
{

// Each time the VI_interrupt fires, switch between drawing odd and even numbered scanlines to achieve high-res mode.
VI_regs_t* vi_registers = (VI_regs_t*) REGISTER_BASE;

_v_limits_switch = !_v_limits_switch;
vi_registers->v_limits = __v_limits_values[_v_limits_switch];
MEMORY_BARRIER();

__display_callback();
}

/**
* @brief Initialize the display to a particular resolution and bit depth
*
Expand All @@ -277,6 +303,21 @@ void display_init( resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma
/* Can't have the video interrupt happening here */
disable_interrupts();

switch(tv_type) {
// PAL
case 0:
__v_limits_values[0] = 0x005f0239;
__v_limits_values[1] = 0x005d0237;
break;
// NTSC
case 1:
// MPAL
case 2:
__v_limits_values[0] = 0x002301fd;
__v_limits_values[1] = 0x002501ff;
break;
}

/* Ensure that buffering is either double or twiple */
if( num_buffers != 2 && num_buffers != 3 )
{
Expand Down Expand Up @@ -427,7 +468,12 @@ void display_init( resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma
enable_interrupts();

/* Set which line to call back on in order to flip screens */
register_VI_handler( __display_callback );
if (__height == 480) {
register_VI_handler( __display_callback_highres_mode );
} else {
register_VI_handler( __display_callback );
}

set_VI_interrupt( 1, 0x200 );
}

Expand Down