#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 }