2016-07-04 18:30:25 +02:00
|
|
|
//---
|
|
|
|
//
|
|
|
|
// gint core/drawing module: gray
|
|
|
|
//
|
|
|
|
// Runs the gray engine and handles drawing for the dual-buffer system.
|
|
|
|
//
|
|
|
|
//---
|
|
|
|
|
2016-05-05 11:49:05 +02:00
|
|
|
#include <gray.h>
|
|
|
|
#include <screen.h>
|
2016-05-20 22:04:15 +02:00
|
|
|
#include <timer.h>
|
2016-07-25 22:38:47 +02:00
|
|
|
#include <mpu.h>
|
2017-07-05 21:38:12 +02:00
|
|
|
#include <stdlib.h>
|
2016-05-05 11:49:05 +02:00
|
|
|
|
2017-04-19 19:57:31 +02:00
|
|
|
// Additional video rams used by the gray engine.
|
2017-07-05 21:38:12 +02:00
|
|
|
#ifdef GINT_STATIC_GRAY
|
|
|
|
static uint32_t internals_vrams[3][256];
|
|
|
|
#endif
|
2017-03-26 18:38:32 +02:00
|
|
|
static uint32_t *vrams[4];
|
2016-05-05 11:49:05 +02:00
|
|
|
|
2017-04-19 19:57:31 +02:00
|
|
|
// Current vram set (0 or 1), delays of the light and dark frames respectively.
|
2016-05-05 11:49:05 +02:00
|
|
|
static int current = 0;
|
2016-05-20 22:04:15 +02:00
|
|
|
static int delays[2];
|
|
|
|
|
2017-04-19 19:57:31 +02:00
|
|
|
// Is the engine currently running?
|
2016-07-04 18:30:25 +02:00
|
|
|
static int runs = 0;
|
|
|
|
|
2017-04-19 19:57:31 +02:00
|
|
|
// Hardware timer used to run the engine.
|
2017-03-01 11:07:28 +01:00
|
|
|
static timer_t *gray_timer = NULL;
|
2016-05-05 11:49:05 +02:00
|
|
|
|
2016-07-04 18:30:25 +02:00
|
|
|
|
|
|
|
|
2017-02-25 19:02:07 +01:00
|
|
|
//---
|
|
|
|
// Interrupt control and initialization.
|
|
|
|
//---
|
|
|
|
|
2017-07-05 21:38:12 +02:00
|
|
|
/* gray_interrupt() -- switch buffers and update the screen */
|
2017-02-25 19:02:07 +01:00
|
|
|
void gray_interrupt(void)
|
|
|
|
{
|
2017-03-01 11:07:28 +01:00
|
|
|
htimer_reload(timer_gray, delays[(~current) & 1]);
|
|
|
|
|
2017-02-25 19:02:07 +01:00
|
|
|
screen_display(vrams[current]);
|
|
|
|
current ^= 1;
|
|
|
|
}
|
|
|
|
|
2017-07-05 21:38:12 +02:00
|
|
|
/* gray_init() -- setup the video ram buffers and timer delays */
|
|
|
|
__attribute__((constructor)) static void gray_init(void)
|
2017-02-25 19:02:07 +01:00
|
|
|
{
|
2017-03-26 18:38:32 +02:00
|
|
|
vrams[0] = display_getLocalVRAM();
|
2017-07-05 21:38:12 +02:00
|
|
|
#ifdef GINT_STATIC_GRAY
|
2017-03-26 18:38:32 +02:00
|
|
|
vrams[1] = internal_vrams[0];
|
|
|
|
vrams[2] = internal_vrams[1];
|
|
|
|
vrams[3] = internal_vrams[2];
|
2017-07-05 21:38:12 +02:00
|
|
|
#else
|
|
|
|
vrams[1] = NULL;
|
|
|
|
vrams[2] = NULL;
|
|
|
|
vrams[3] = NULL;
|
|
|
|
#endif
|
2017-02-25 19:02:07 +01:00
|
|
|
delays[0] = 912;
|
|
|
|
delays[1] = 1343;
|
|
|
|
}
|
|
|
|
|
2017-07-05 21:38:12 +02:00
|
|
|
/* gray_quit() -- Free the gray engine's heap-allocated video rams */
|
|
|
|
__attribute__((destructor)) static void gray_quit(void)
|
|
|
|
{
|
|
|
|
#ifndef GINT_STATIC_GRAY
|
|
|
|
free(vrams[1]);
|
|
|
|
free(vrams[2]);
|
|
|
|
free(vrams[3]);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-02-25 19:02:07 +01:00
|
|
|
|
|
|
|
|
2016-07-04 18:30:25 +02:00
|
|
|
//---
|
|
|
|
// Engine control.
|
|
|
|
//---
|
|
|
|
|
2016-05-05 11:49:05 +02:00
|
|
|
/*
|
|
|
|
gray_start()
|
|
|
|
Starts the gray engine. The control of the screen is transferred to the
|
|
|
|
gray engine.
|
|
|
|
*/
|
|
|
|
void gray_start(void)
|
|
|
|
{
|
2017-07-05 21:38:12 +02:00
|
|
|
#ifndef GINT_STATIC_GRAY
|
|
|
|
for(int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!vrams[i]) vrams[i] = malloc(1024);
|
|
|
|
/* Don't continue if any of the buffer is missing */
|
|
|
|
if(!vrams[i]) return;
|
|
|
|
}
|
|
|
|
#endif
|
2016-07-14 21:10:51 +02:00
|
|
|
if(runs) return;
|
|
|
|
|
2017-03-01 11:07:28 +01:00
|
|
|
gray_timer = htimer_setup(timer_gray, delays[0], timer_Po_64, 0);
|
|
|
|
timer_attach(gray_timer, gray_interrupt, NULL);
|
|
|
|
timer_start(gray_timer);
|
|
|
|
|
2016-07-14 21:10:51 +02:00
|
|
|
current &= 1;
|
2016-07-04 18:30:25 +02:00
|
|
|
runs = 1;
|
2016-05-05 11:49:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
gray_stop()
|
|
|
|
Stops the gray engine. The monochrome display system takes control of
|
|
|
|
the video ram.
|
|
|
|
*/
|
|
|
|
void gray_stop(void)
|
|
|
|
{
|
2017-03-01 11:07:28 +01:00
|
|
|
timer_stop(gray_timer);
|
2016-07-04 18:30:25 +02:00
|
|
|
runs = 0;
|
|
|
|
|
2017-04-19 19:57:31 +02:00
|
|
|
/* TODO This may not be very wise considering the fact that the user
|
|
|
|
may have specified another monochrome vram address. This raises again
|
|
|
|
the idea of a parameter stack. */
|
2016-05-05 11:49:05 +02:00
|
|
|
display_useVRAM(display_getLocalVRAM());
|
|
|
|
}
|
|
|
|
|
2016-07-06 11:28:51 +02:00
|
|
|
/*
|
|
|
|
gray_setDelays()
|
|
|
|
Changes the gray engine delays.
|
|
|
|
*/
|
|
|
|
void gray_setDelays(int light, int dark)
|
|
|
|
{
|
|
|
|
delays[0] = light;
|
|
|
|
delays[1] = dark;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Engine information.
|
|
|
|
//---
|
|
|
|
|
|
|
|
/*
|
|
|
|
gray_runs()
|
|
|
|
Returns 1 if the gray engine is running, 0 otherwise.
|
|
|
|
*/
|
|
|
|
inline int gray_runs(void)
|
|
|
|
{
|
|
|
|
return runs;
|
|
|
|
}
|
|
|
|
|
2016-05-05 11:49:05 +02:00
|
|
|
/*
|
|
|
|
gray_lightVRAM()
|
|
|
|
Returns the module's gray vram address.
|
|
|
|
*/
|
2017-03-26 18:38:32 +02:00
|
|
|
uint32_t *gray_lightVRAM(void)
|
2016-05-05 11:49:05 +02:00
|
|
|
{
|
2017-03-26 18:38:32 +02:00
|
|
|
return vrams[~current & 2];
|
2016-05-05 11:49:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
gray_lightVRAM()
|
|
|
|
Returns the module's dark vram address.
|
|
|
|
*/
|
2017-03-26 18:38:32 +02:00
|
|
|
uint32_t *gray_darkVRAM(void)
|
2016-05-05 11:49:05 +02:00
|
|
|
{
|
2017-03-26 18:38:32 +02:00
|
|
|
return vrams[(~current & 2) | 1];
|
2016-05-05 11:49:05 +02:00
|
|
|
}
|
|
|
|
|
2017-07-01 16:07:14 +02:00
|
|
|
/*
|
|
|
|
gray_currentVRAM()
|
|
|
|
Returns the currently displayed video ram (if the engine runs). Used
|
|
|
|
internally, but has no interest for the user. You don't want to draw to
|
|
|
|
this vram.
|
|
|
|
*/
|
|
|
|
uint32_t *gray_currentVRAM(void)
|
|
|
|
{
|
|
|
|
return vrams[current ^ 1];
|
|
|
|
}
|
|
|
|
|
2016-05-20 22:04:15 +02:00
|
|
|
/*
|
|
|
|
gray_getDelays()
|
2016-07-04 18:30:25 +02:00
|
|
|
Returns the gray engine delays. Pointers are not set if NULL.
|
2016-05-20 22:04:15 +02:00
|
|
|
*/
|
|
|
|
void gray_getDelays(int *light, int *dark)
|
|
|
|
{
|
|
|
|
if(light) *light = delays[0];
|
|
|
|
if(dark) *dark = delays[1];
|
|
|
|
}
|
|
|
|
|
2016-07-06 11:28:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
// Drawing.
|
|
|
|
//---
|
|
|
|
|
2016-05-20 22:04:15 +02:00
|
|
|
/*
|
2016-07-06 11:28:51 +02:00
|
|
|
gupdate()
|
|
|
|
Swaps the vram buffer sets.
|
2016-05-20 22:04:15 +02:00
|
|
|
*/
|
2016-07-06 11:28:51 +02:00
|
|
|
inline void gupdate(void)
|
2016-05-20 22:04:15 +02:00
|
|
|
{
|
2016-07-06 11:28:51 +02:00
|
|
|
current ^= 2;
|
2016-05-20 22:04:15 +02:00
|
|
|
}
|