// source code for the mega16 or mega32. This processor will read the sync pulses on // the ELM304, and then update a counter when it is time to display pixels. This counter // will point directly to an address on the 32K memory chips. // DO NOT CHANGE ANY OF THIS UNLESS YOU KNOW WHAT YOU ARE DOING. // IT MAY BE POSSIBLE TO HAVE THIS CHIP DO SMALL TASKS, DURING THE DOWN TIME // BUT THE CODE SHOULD NOT BE ALTERED UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING #include //#include #define DISPLAY_ON PIND.7 #define DISPLAY_READY PIND.6 #define MEM_OE PORTD.5 #define DAC_ACTIVE PORTD.4 // global variables // Display variables register unsigned int pixelAddress @4; unsigned char i, displayFlag, repeatFlag, firstDisplay; #asm ; Port definitions ; ***** I/O REGISTER DEFINITIONS ***************************************** ; NOTE: ; Definitions marked "MEMORY MAPPED"are extended I/O ports ; and cannot be used with IN/OUT instructions .equ PORTA = 0x1b .equ DDRA = 0x1a .equ PINA = 0x19 .equ PORTB = 0x18 .equ DDRB = 0x17 .equ PINB = 0x16 .equ PORTC = 0x15 .equ DDRC = 0x14 .equ PINC = 0x13 .equ PORTD = 0x12 .equ DDRD = 0x11 .equ PIND = 0x10 ; ***** CPU REGISTER DEFINITIONS ***************************************** .def XH = r27 .def XL = r26 .def YH = r29 .def YL = r28 .def ZH = r31 .def ZL = r30 #endasm interrupt [EXT_INT0] void ext_int0(void) { unsigned char timer1 = 0; while (timer1<11) // wait for back porch to finish { timer1++; } if (DISPLAY_ON == 1) { // check if mega128 is done with sram if (DISPLAY_READY == 1 && firstDisplay == 0) // added this check so it will not start displaying halfway through a frame { // set display flag displayFlag = 1; PORTD.1 = 0; } else { displayFlag = 0; firstDisplay = 1; } //////////////////////////// //******Display Code******// //////////////////////////// if (displayFlag == 1) { // turn on Memory output MEM_OE = 0; // set ports for output DDRA = 0xFF; DDRC = 0xFF; DAC_ACTIVE = 0; // ON #asm .MACRO singlePixel out PORTA, r4 inc r4 nop ;nop .ENDMACRO .MACRO fivePixels singlePixel singlePixel singlePixel singlePixel singlePixel .ENDMACRO .MACRO fiftyPixels fivePixels fivePixels fivePixels fivePixels fivePixels fivePixels fivePixels fivePixels fivePixels fivePixels .ENDMACRO .MACRO Two55Pixels fiftyPixels fiftyPixels fiftyPixels fiftyPixels fiftyPixels fivePixels .ENDMACRO out PORTC, r5 ; go to correct line in memory Two55Pixels ; push out pixels by incrementing PORTA inc r5 ; go to next line in memory clr r4 ; reset pixel count #endasm if (repeatFlag == 0) { repeatFlag = 1; #asm dec r5 #endasm } else repeatFlag = 0; // Turn off mem_oe MEM_OE = 1; DAC_ACTIVE = 1; // OFF // Set ports in high-Z state DDRA = 0x00; DDRC = 0x00; PORTA = 0x00; PORTC = 0x00; } } else // WHITE_ON == 0 { // Tell the mega128 display is done PORTD.1 = 1; // restart pixel count pixelAddress = 0; firstDisplay = 0; } } void initialize(void) { pixelAddress = 0; //turn off memory output MEM_OE = 1; // PortA Low address DDRA = 0x00; // PortC high address DDRC = 0x00; // PortD will be used to take in the sync pulses, the external interrupt on bit2 is active // also used to test for incoming stuff from mega128 and v2 on the elm304 // also, pin 5 is used for MEM_OE // also pin 4 used to turn DAC on and off DDRD = 0b00110010; PORTD = 0b00110000; /*****Interrupts and Timers*****/ // Set Timer0 Control Register, no prescaler TCCR0 = 0x01; // Set interrupt 0 to register on rising edge (horizontal sync is a falling edge, followed by a rising edge) // Idle sleep mode also set MCUCR = 0b00000011; // Enable external interrupt 0 to seach for sync pulses. GICR = 0b01000000; } void main(void) { initialize(); #asm sei #endasm while(1) { #asm sleep #endasm } }