#define MAX_BRIGHTNESS 255U
#define SETW(what, val) what = val
#define SET(what, val) what = val
#define GET(what) what
void cDelay (unsigned int units)
{
volatile unsigned int i;
for (i = 0; i < units; i++) {
asm ("nop");
}
}
static void cstrcpy (char *dest, char *src)
{
char c;
do {
c = *src++;
*dest++ = c;
}
while (c != '\0');
}
static int random (void)
{
static unsigned long rseed;
return (int) (rseed = (rseed * 2053UL) + 13849UL);
}
#ifdef NEVER
// this is quite a "C" optimized version of print_sync
// it is actually FASTER than
// the "not very optimized" assembler include!
// (-O3 and no_frame_pointer)
void
draw_synced_list_c (signed char *u, signed int y, signed int x,
unsigned int scaleMove, unsigned int scaleList)
{
#define ZERO_DELAY 5
do {
// resync / startsync
VIA_shift_reg = 0; // all output is BLANK
//asm ( "clra" );
//asm ( "sta 0xd00a");
// move to zero
VIA_cntl = (int) 0xcc; // zero the integrators
VIA_port_a = 0; // reset integrator offset
VIA_port_b = (int) 0 b10000010;
VIA_t1_cnt_lo = scaleMove;
// delay, till beam is at zero
// volatile - otherwise delay loop does not work with -O
for (volatile signed int b = ZERO_DELAY; b > 0; b--) ;
VIA_port_b = (int) 0 b10000011;
// move to "location"
VIA_port_a = y; // y pos to dac
VIA_cntl = (int) 0xce; // disable zero, disable all blank
VIA_port_b = 0; // mux enable, dac to -> integrator y (and x)
//VIA_shift_reg = 0; // all output is BLANK
//asm ( "clra" );
//asm ( "sta 0xd00a");
VIA_port_b = 1; // mux disable, dac only to x
VIA_port_a = x; // dac -> x
VIA_t1_cnt_hi = 0; // start timer
// this can be done before the wait loop
// since it only fills the latch, not the actual timer!
VIA_t1_cnt_lo = scaleList;
u += 3;
// moving test for yx== 0 into the move delay
if ((*(u - 2) != 0) || (*(u - 1) != 0))
{
while ((VIA_int_flags & 0x40) == 0) ; // wait till timer finishes
// internal moveTo
VIA_port_a = *(u - 2); // y pos to dac
VIA_cntl = (int) 0xce; // disable zero, disable all blank
VIA_port_b = 0; // mux enable, dac to -> integrator y (and x)
//VIA_shift_reg = 0; // all output is BLANK
//asm ( "clra" );
//asm ( "sta 0xd00a");
VIA_port_b = 1; // mux disable, dac only to x
VIA_port_a = *(u - 1); // dac -> x
VIA_t1_cnt_hi = 0; // start timer
while ((VIA_int_flags & 0x40) == 0) ; // wait till timer finishes
}
else
{
while ((VIA_int_flags & 0x40) == 0) ; // wait till timer finishes
}
while (1)
{
if (*u < 0) // draw line
{
// draw a vector
VIA_port_a = *(1 + u); // y pos to dac
VIA_port_b = 0; // mux enable, dac to -> integrator y (and x)
VIA_port_b = 1; // mux disable, dac only to x
VIA_port_a = *(2 + u); // dac -> x
VIA_t1_cnt_hi = 0; // start timer
VIA_shift_reg = (int) 0xff; // draw complete line
while ((VIA_int_flags & 0x40) == 0) ; // wait till timer
// finishes
VIA_shift_reg = 0; // all output is BLANK
//asm ( "clra" );
//asm ( "sta 0xd00a");
}
else if (*u == 0) // moveTo
{
if ((*(u + 1) != 0) || (*(u + 2) != 0))
{
// internal moveTo
VIA_port_a = *(1 + u); // y pos to dac
VIA_cntl = (int) 0xce; // disable zero, disable all blank
VIA_port_b = 0; // mux enable, dac to -> integrator y (and x)
//VIA_shift_reg = 0; // all output is BLANK
//asm ( "clra" );
//asm ( "sta 0xd00a");
VIA_port_b = 1; // mux disable, dac only to x
VIA_port_a = *(2 + u); // dac -> x
VIA_t1_cnt_hi = 0; // start timer
while ((VIA_int_flags & 0x40) == 0) ; // wait till timer
// finishes
}
}
else
{
break;
}
u += 3;
}
}
while (*u != 2);
}
#endif /* */
static void cMov_Draw_VLc_a (signed char *vList)
{
register int count = *(vList) - 1; // count in list
SET (dp_VIA_port_a, *(1 + vList)); // y pos to dac
SET (dp_VIA_cntl, 0xce); // disable zero, disable all blank
SET (dp_VIA_port_b, 0); // mux enable, dac to -> integrator y (and x)
SET (dp_VIA_port_b, 1); // mux disable, dac only to x
SET (dp_VIA_port_a, *(2 + vList)); // dac -> x
SET (dp_VIA_t1_cnt_hi, 0); // start timer
vList += 3;
while ((GET (dp_VIA_int_flags) & 0x40) == 0) ; // wait till timer
// finishes
// This will have to be modified until you get reading to work...
do {
SET (dp_VIA_port_a, *(vList)); // first y coordinate to dac
SET (dp_VIA_port_b, 0); // mux enable, dac to -> integrator y (and x)
SET (dp_VIA_port_b, 1); // mux disable, dac only to x
SET (dp_VIA_port_a, *(vList + 1)); // dac -> x
SET (dp_VIA_shift_reg, 0xff); // full "unblank" output
SET (dp_VIA_t1_cnt_hi, 0); // start timer
vList += 2;
while ((GET (dp_VIA_int_flags) & 0x40) == 0) ; // wait till timer
// finishes
SET (dp_VIA_shift_reg, 0); // output full blank
}
while (--count >= 0); // loop thru all vectors
}
static void cMoveto_d (signed int y, signed int x)
{
dp_VIA_port_a = y; // y pos to dac
dp_VIA_cntl = 0xce; // disable zero, disable all blank
dp_VIA_port_b = 0; // mux enable, dac to -> integrator y (and x)
dp_VIA_shift_reg = 0; // all output is BLANK
dp_VIA_port_b++; // mux disable, dac only to x
dp_VIA_port_a = x; // dac -> x
dp_VIA_t1_cnt_hi = 0; // start timer
while ((dp_VIA_int_flags & 0x40) == 0) ; // wait till timer finishes
}
static void cIntensity_a (unsigned int i)
{
Vec_Brightness = (int) i;
SET (dp_VIA_port_a, (int) i); // Store intensity in D/A
SET (dp_VIA_port_b, 5); // mux disabled channel 2
SET (dp_VIA_port_b, 4); // mux enable
SET (dp_VIA_port_b, 1); // turn off mux
}
static void cDraw_VLp (signed int *list)
{
do
{
dp_VIA_port_a = *(list + 1); // Send Y to A/D
dp_VIA_port_b = 0; // Enable mux dac goes to y and x integrators
dp_VIA_port_b++; // disable mux
dp_VIA_port_a = *(list + 2); // send x to A/D
dp_VIA_t1_cnt_hi = 0; // start timer (and movement)
dp_VIA_shift_reg = (unsigned int) *list; // *list; // shift reg =
// pattern byte
list = list + 3;
while ((dp_VIA_int_flags & 0x40) == 0) ; // wait till timer finishes
dp_VIA_shift_reg = (int) 0x00; // swithc light off
}
while (((signed int) (*list)) <= 0);
}
static void cReset0Ref ()
{
SET (dp_VIA_cntl, 0xcc); // enable zero, enable all blank
// reset integrators
SET (dp_VIA_port_a, 0); // dac = 0
SET (dp_VIA_port_b, 3); // mux=1, disable mux
SET (dp_VIA_port_b, 2); // mux=1, enable mux
SET (dp_VIA_port_b, 2); // delay
SET (dp_VIA_port_b, 1); // disable mux
}
// The 'No BIOS' raster text printing is not working yet, and we are currently
// using the bios print_str - however it seems to be working for now...
#define Char_Table 0xF9F4L
#define Char_Table_End 0xFBD4L
void cPrint_Str (register void *volatile text)
{
Vec_Str_Ptr = text;
register int *charTable = (int *) (Char_Table - 0x20); // Point to
// start of
// chargen
// bitmaps
dp_VIA_aux_cntl = 0x18;
dp_VIA_port_a = 0; // Clear D/A output
dp_VIA_port_b = (int) 0x83; // ramp off/on set mux to channel 1
register int letter;
while (1) {
dp_VIA_port_b--; // Enable mux
dp_VIA_port_b++; // Disable mux
dp_VIA_port_b = (int) 0x81; // Disable RAMP, set mux to channel
// 0, disable mux
dp_VIA_port_b = (int) 0x80; // Enable mux
dp_VIA_port_b++; // Disable mux
dp_VIA_port_a = Vec_Text_Width; // Get text width -> Send it to the
// D/A
dp_VIA_port_b = 0x01; // enable RAMP, disable mux
goto overStep;
stepBack:
dp_VIA_shift_reg = (unsigned int) *(charTable + letter);
overStep:
letter = (int) *(((unsigned int *) text++));
if (letter > 0)
goto stepBack;
dp_VIA_port_b = (int) 0x81; // disable mux, disable ramp
dp_VIA_port_a = -dp_VIA_port_a;
dp_VIA_port_b = 0x01; // enable RAMP, disable mux
if (((unsigned long) charTable) == (Char_Table_End - 0x20L))
break;
charTable += 0x50;
register volatile unsigned int size = (unsigned int) (((unsigned long) text) - ((unsigned long) Vec_Str_Ptr));
size -= 2;
size = size << 1;
while (size-- > 0) ;
dp_VIA_port_b = (int) 0x81; // disable RAMP, disable mux
dp_VIA_port_a = Vec_Text_Height;
dp_VIA_port_b--; // Enable mux
dp_VIA_port_b = (int) 0x81; // disable RAMP, disable mux
dp_VIA_port_a = 0;
dp_VIA_port_b = 0x01; // enable RAMP, disable mux
dp_VIA_port_b = (int) 0x81; // disable RAMP, disable mux
dp_VIA_port_b = 0x03; // ENABLE RAMP ...
}
dp_VIA_aux_cntl = 0x98;
cReset0Ref ();
}
#define scale(x) do { dp_VIA_t1_cnt_lo = (x); } while(0)
__attribute__ ((interrupt)) static void draw_graphics (void)
{
int *vec;
int row;
if ((dp_VIA_int_flags & 0x20) == 0) {
// for anything except the t2 timer we want to rti immediately.
return;
}
Vec_Loop_Count++;
dp_VIA_t2 = Vec_Rfrsh;
dp_VIA_t1_cnt_lo = (unsigned int) 255;
cMoveto_d (127, 127);
dp_VIA_cntl = 0xcc; // enable zero, enable all blank
cMoveto_d (-128, -128);
dp_VIA_cntl = 0xcc; // enable zero, enable all blank
dp_VIA_port_a = 0; // dac = 0
dp_VIA_port_b = 3; // mux=1, disable mux
dp_VIA_port_b = 2; // mux=1, enable mux
dp_VIA_port_b = 2; // delay
dp_VIA_port_b = 1; // disable mux
// graphics executed here.
dp_VIA_aux_cntl = 0x98;
Reset0Ref ();
Print_Str_d (0, -70, DEMO);
// BOUNCER
cIntensity_a (MAX_BRIGHTNESS / 4); /* set intensity of vector beam... */
for (int i = 0; i < 7; i++) {
scale (0x50);
cDelay (1);
SET (VIA_cntl, 0xCE);
cMov_Draw_VLc_a ((void *) BouncerTitle[i]);
SET (VIA_cntl, 0xCC);
}
vec = (int *) vector;
for (row = 0; row < ASTEROIDS; row++) {
cReset0Ref ();
scale (0x58);
cMoveto_d (y[row], x[row]);
scale (0x04);
cDraw_VLp (vec);
vec += 3 * 8 + 1;
}
}
#define IRQBASE 0xCBF8
unsigned long volatile *const IRQ = (unsigned long *) (IRQBASE + 1);
unsigned int volatile *const IRQ_INST = (unsigned int *) IRQBASE;
static int init (void);
static int loop (void);
int main (void)
{
unsigned long frame;
*IRQ_INST = (unsigned int) 0x7e; // JMP ... this is actually code!,
// first a JMP instruction
*IRQ = (unsigned long) &draw_graphics; // to Address
(void) init ();
// ensure timer is sensible to start with
dp_VIA_t2 = Vec_Rfrsh;
dp_VIA_int_enable |= 0x20;
asm ("andcc #0xef"); // enable IRQ with 6809
frame = Vec_Loop_Count = 0L;
for (;;) {
// Only display once every 1/50s in interrupt routine
while (frame == Vec_Loop_Count) /* wait */
;
frame = Vec_Loop_Count;
(void) loop ();
} return 1; // cold reset - NOT REACHED
}