#include #define DATA_DDR DDRD #define DATA_OUT PORTD #define DATA_IN PIND #asm .equ DATA_OUT = 0x12 ; x12 = PORTD #endasm #asm .def REG_LC = r18 .def REG_HALF = r19 .def REG_VIDPOSL = r20 .def REG_VIDPOSH = r21 .def REG_MEMPOSRL = r22 .def REG_MEMPOSRH = r23 .def REG_VIDDISPL = r28 .def REG_VIDDISPH = r29 .def REG_TMP1 = r24 .def REG_TMP2 = r25 .def REG_TMP3 = r16 .def REG_TMP4 = r17 ; 26 and 27 are our X register, used for array accesses #endasm #asm ; Z must be loaded with unpacked line address before this can be used .macro DISP_MEM ld REG_TMP1,Z+ ; 2 cycles out DATA_OUT, REG_TMP1 ; 1 cycle .endm .macro DISP_WAIT ; 18 clock ticks DISP_MEM nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop .endm .macro DISP_WAIT5 DISP_WAIT DISP_WAIT DISP_WAIT DISP_WAIT DISP_WAIT .endm .macro DISP_WAIT10 DISP_WAIT5 DISP_WAIT5 .endm #endasm #asm .macro DATA_OUT_EQUALS LDI REG_TMP1,@0 OUT DATA_OUT,REG_TMP1 .endm #endasm #asm .macro LOAD_LINE ; set up Z register with location of line ldi r30, low(_next_line) ;1 ldi r31, high(_next_line) ;1 .endm ; Z must be loaded with unpacked line address before this can be used ; Y must be loaded with current packed memory before this can be used .macro UNPACK_MEM ; 10 clock ticks ;unpack current byte to 2 bytes ld REG_TMP1,Y+ ; 2 cycles mov REG_TMP2, REG_TMP1 ; 1 andi REG_TMP2, 0xf0 ; 1 st Z+,REG_TMP2 ; 2 cycles swap REG_TMP1 ; 1 andi REG_TMP1, 0xf0 ; 1 st Z+,REG_TMP1 ; 2 cycles .endm ; Y must be loaded with current packed memory before this can be used .macro CHECK_VIDOVERFLOW ; 13 ;check for overflow ldi REG_TMP3, low(_vidbuf) ;1 ldi REG_TMP4, high(_vidbuf);1 ldi REG_TMP1, low(800) ; 1 ldi REG_TMP2, high(800) ;1 add REG_TMP3, REG_TMP1 ; 1 adc REG_TMP4, REG_TMP2 ;1 cp r28, REG_TMP3 ;1 cpc r29, REG_TMP4 ;1 ;out 0xc, r28 brne PC+3 ;1 if false, 2 if true ldi r28, low(_vidbuf) ;1 ldi r29, high(_vidbuf) ;1 breq PC+3 ;1 if false, 2 if true nop ;1 nop ;1 .endm #endasm #asm .macro LOAD_VIDBUFFER ; set up Y register with location of vbuffer ldi r28, low(_vidbuf) ;1 ldi r29, high(_vidbuf) ;1 .endm #endasm #define WAIT_500 \ WAIT_100 \ WAIT_100 \ WAIT_100 \ WAIT_100 \ WAIT_100 #define WAIT_100 \ WAIT_50 \ WAIT_50 #define WAIT_50 \ WAIT_10 \ WAIT_10 \ WAIT_10 \ WAIT_10 \ WAIT_10 #define WAIT_20 \ WAIT_10 \ WAIT_10 #define WAIT_10 \ WAIT_5 \ WAIT_5 #define WAIT_5 \ WAIT_2 \ WAIT_2 \ WAIT_1 #define WAIT_2 \ WAIT_1 \ WAIT_1 #define WAIT_1 \ #asm("nop"); char next_line[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80 }; char vidbuf[] = { 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x4B, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x4B, 0x5A, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x69, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x69, 0x69, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x69, 0x69, 0x78, 0x0F, 0x0F, 0x1E, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x69, 0x78, 0x78, 0x0F, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x69, 0x78, 0x78, 0x87, 0x0F, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x78, 0x87, 0x0F, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x78, 0x87, 0x87, 0x0F, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0x0F, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0x96, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0x96, 0xA5, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0x96, 0xA5, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0x96, 0xA5, 0xA5, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x3C, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0xA5, 0xA5, 0xB4, 0x0F, 0x1E, 0x1E, 0x2D, 0x2D, 0x3C, 0x4B, 0x4B, 0x5A, 0x5A, 0x69, 0x69, 0x78, 0x87, 0x87, 0x96, 0x96, 0xA5, 0xB4, 0xB4, 0x0F, 0x1E, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x69, 0x69, 0x78, 0x78, 0x87, 0x96, 0x96, 0xA5, 0xA5, 0xB4, 0xC3, 0x0F, 0x1E, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x4B, 0x5A, 0x69, 0x69, 0x78, 0x87, 0x87, 0x96, 0x96, 0xA5, 0xB4, 0xB4, 0xC3, 0x0F, 0x1E, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x5A, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x87, 0x96, 0xA5, 0xA5, 0xB4, 0xC3, 0xC3, 0x0F, 0x1E, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x5A, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x96, 0x96, 0xA5, 0xB4, 0xB4, 0xC3, 0xD2, 0x0F, 0x1E, 0x2D, 0x2D, 0x3C, 0x4B, 0x4B, 0x5A, 0x69, 0x69, 0x78, 0x87, 0x87, 0x96, 0xA5, 0xA5, 0xB4, 0xC3, 0xC3, 0xD2, 0x0F, 0x1E, 0x2D, 0x2D, 0x3C, 0x4B, 0x4B, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x96, 0x96, 0xA5, 0xB4, 0xB4, 0xC3, 0xD2, 0xE1, 0x0F, 0x1E, 0x2D, 0x2D, 0x3C, 0x4B, 0x5A, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x96, 0xA5, 0xA5, 0xB4, 0xC3, 0xC3, 0xD2, 0xE1, 0x0F, 0x1E, 0x2D, 0x2D, 0x3C, 0x4B, 0x5A, 0x5A, 0x69, 0x78, 0x87, 0x87, 0x96, 0xA5, 0xB4, 0xB4, 0xC3, 0xD2, 0xE1, 0xE1, 0x0F, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x5A, 0x69, 0x69, 0x78, 0x87, 0x96, 0x96, 0xA5, 0xB4, 0xC3, 0xC3, 0xD2, 0xE1, 0xF0, 0x0F, 0x1E, 0x2D, 0x3C, 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x78, 0x87, 0x96, 0xA5, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xE1, 0xF0, 0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xC3, 0xD2, 0xE1, 0xF0, 0xF0}; /*#define NEXT_MEM \ if(PORTX.Y == Z){ \ PORTB = (unsigned char)((cur_mem_pos & 0xff00) >> 8); \ PORTC = (unsigned char)(cur_mem_pos & 0x00ff); \ cur_mem_pos = (cur_mem_pos >= END_LOWRES) ? BEGIN_LOWRES : cur_mem_pos++; \ if(vid_ext == 800) vid_ext = 0; \ vidbuf[vid_ext++] = PINA; \ }*/ #asm .macro NEXT_MEM ; NEED TO ADD SYNCHRONIZATION IN ; output addresses NEED TO CHECK PORT NUMBERS out 0x18, REG_MEMPOSRH out 0x19, REG_MEMPOSRL ; reset position if at end, otherwise increment NEED TO CHECK ADDRESS NUMBERS cpi REG_MEMPOSRL, 0x00 cpc REG_MEMPOSRH, 0x20 brsh PC+2 rjmp PC+2 ; NEED TO SET THIS .endm .macro NEXT_MEM_GEN MOVW R30,R4 ANDI R30,LOW(0xFF00) MOV R30,R31 LDI R31,0 OUT 0x18,R30 MOVW R30,R4 ANDI R31,HIGH(0xFF) OUT 0x15,R30 LDI R30,LOW(10240) LDI R31,HIGH(10240) CP R4,R30 CPC R5,R31 BRSH PC+3 JMP _0x3 LDI R30,LOW(8192) LDI R31,HIGH(8192) RJMP _0x4 _0x3: MOVW R30,R4 ADIW R30,1 MOVW R4,R30 SBIW R30,1 _0x4: _0x5: MOVW R4,R30 LDI R30,LOW(800) LDI R31,HIGH(800) CP R30,R6 CPC R31,R7 BREQ PC+3 JMP _0x6 CLR R6 CLR R7 _0x6: MOVW R30,R6 ADIW R30,1 MOVW R6,R30 SBIW R30,1 SUBI R30,LOW(-_vidbuf) SBCI R31,HIGH(-_vidbuf) MOVW R26,R30 IN R30,0x19 ST X,R30 .endm #endasm unsigned char color = 0x00; // problem with bad sync is that the vertical sync should have 10 black lines before and 10 lines after it, with sync // arbitrary length (determines height) void main(){ #asm("cli"); // interrupts must be OFF DATA_DDR = 0xff; //DATA_OUT = 0x00; // 4-7 = data, 3 = vsync, 2 = hsync #asm("DATA_OUT_EQUALS 0x00"); // set up memory ports and read lines #asm("LOAD_VIDBUFFER"); #asm("ldi REG_HALF, 0"); #asm("LOAD_LINE"); #asm("UNPACK_MEM"); // 10 each #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("START:"); #asm("ldi REG_LC, 0"); //DATA_OUT = 0b00000100; // SBI, 2 cycles #asm("DATA_OUT_EQUALS 0x04"); WAIT_2 // this counts as part of horizontal sync time //#asm("LOAD_LINE"); // 2 // this counts as part of horizontal sync time #asm("NORMAL:"); //color += 0x10; WAIT_2 // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) /*WAIT_50 WAIT_10 WAIT_10*/ #asm("UNPACK_MEM"); // 10 each #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); WAIT_10 //WAIT_2 //DATA_OUT = 0b00000000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x00"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); #asm("UNPACK_MEM"); /* WAIT_50 WAIT_10 WAIT_10*/ //WAIT_2 //WAIT_2 //WAIT_50 WAIT_10 WAIT_20 WAIT_1 #asm("CHECK_VIDOVERFLOW"); //WAIT_2 // data for 720 clock ticks (45 us) #asm("LOAD_LINE"); // 2 in color burst #asm("DISP_MEM"); // 3 in color burst WAIT_10 WAIT_5 #asm("DISP_WAIT5"); // 90 #asm("DISP_WAIT"); // 18 #asm("DISP_WAIT"); // 18 #asm("DISP_WAIT"); // 18 #asm("DISP_WAIT10"); // 180 #asm("DISP_WAIT10"); // 180 #asm("DISP_WAIT10"); // 180 #asm("DISP_MEM"); // 3 WAIT_10 #asm("LOAD_LINE"); // 2 WAIT_5 WAIT_1 //DATA_OUT = 0b00000000; // set black level for front porch using last clock ticks of data region #asm("DATA_OUT_EQUALS 0x00"); // front porch for 73 clock ticks (4.5625 us) WAIT_2 #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); // 10 #asm("UNPACK_MEM"); // 10 /* WAIT_50 WAIT_10 WAIT_5*/// WAIT_2 WAIT_1 // total 8 clock ticks in either branch, using time from the front porch #asm("subi REG_LC, -1"); // 1 #asm("cpi REG_LC, 240"); // 1 #asm("brne NORMALMID"); // 1 if false, 2 if true #asm("breq BLACK1MID"); // 1 if false, 2 if true #asm("NORMALMID:"); WAIT_2 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); #asm("rjmp NORMAL"); // 2, counts as horizontal sync time #asm("BLACK1MID:"); // this code should be the same as the code below black1 WAIT_2 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); #asm("rjmp BLACK1"); // 2, counts as horizontal sync time // black lines before vertical sync #asm("BLACK1:"); // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) WAIT_50 WAIT_10 WAIT_10 WAIT_2 //DATA_OUT = 0b00000000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x00"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data WAIT_50 WAIT_10 WAIT_10 WAIT_2 WAIT_2 WAIT_50 WAIT_2 // data for 720 clock ticks (45 us) //DATA_OUT = 0b00000000; // 2 clock ticks in color burst region #asm("DATA_OUT_EQUALS 0x00"); WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_50 WAIT_10 WAIT_10 // front porch for 73 clock ticks (4.5625 us) WAIT_50 WAIT_10 WAIT_5 // total 8 clock ticks in either branch, using time from the front porch #asm("subi REG_LC, -1"); // 1 #asm("cpi REG_LC, 3"); // 1 #asm("brne BLACK1MID2"); // 1 if false, 2 if true #asm("breq INVMID"); // 1 if false, 2 if true #asm("BLACK1MID2:"); WAIT_2 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); #asm("rjmp BLACK1"); // 2, counts as horizontal sync time #asm("INVMID:"); #asm("ldi REG_LC, 0"); // 1 //DATA_OUT = 0b00001100; // 2 #asm("DATA_OUT_EQUALS 0x0C"); WAIT_2 // part of horizontal sync time #asm("INVERTED:"); // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) WAIT_50 WAIT_10 WAIT_10 WAIT_2 //DATA_OUT = 0b00001000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x08"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data WAIT_50 WAIT_10 WAIT_10 WAIT_5 WAIT_1 WAIT_50 WAIT_2 // data for 720 clock ticks (45 us) WAIT_500 WAIT_100 WAIT_100 WAIT_10 WAIT_10 // front porch for 73 clock ticks (4.5625 us) WAIT_50 WAIT_10 WAIT_10 WAIT_1 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); WAIT_2 // counts as horizontal sync time // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) WAIT_50 WAIT_10 WAIT_10 WAIT_2 //DATA_OUT = 0b00001000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x08"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data WAIT_50 WAIT_10 WAIT_10 WAIT_5 WAIT_1 WAIT_50 WAIT_2 // data for 720 clock ticks (45 us) WAIT_500 WAIT_100 WAIT_100 WAIT_10 WAIT_10 // front porch for 73 clock ticks (4.5625 us) WAIT_50 WAIT_10 WAIT_10 WAIT_1 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); WAIT_2 // counts as horizontal sync time // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) WAIT_50 WAIT_10 WAIT_10 WAIT_2 //DATA_OUT = 0b00001000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x08"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data WAIT_50 WAIT_10 WAIT_10 WAIT_5 WAIT_1 WAIT_50 WAIT_2 // data for 720 clock ticks (45 us) WAIT_500 WAIT_100 WAIT_100 WAIT_10 WAIT_10 // front porch for 73 clock ticks (4.5625 us) WAIT_50 WAIT_10 WAIT_10 WAIT_1 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); WAIT_2 // counts as horizontal sync time // black lines after vertical sync #asm("BLACK2:"); // horizontal sync for 76 clock ticks (4.75 us, close to 4.7 us) WAIT_50 WAIT_10 WAIT_10 WAIT_2 //DATA_OUT = 0b00000000; // CBI, 2 cycles #asm("DATA_OUT_EQUALS 0x00"); // color burst (back porch) for 76 clock ticks (4.75 us, close to 4.7 us) + 52 clock ticks for 3.25 stolen from data WAIT_50 WAIT_10 WAIT_10 WAIT_50 WAIT_2 WAIT_2 WAIT_2 // data for 720 clock ticks (45 us) //DATA_OUT = 0b00000000; // 2 clock ticks in color burst region #asm("DATA_OUT_EQUALS 0x00"); WAIT_500 WAIT_100 WAIT_100 WAIT_10 WAIT_10 // front porch for 73 clock ticks (4.5625 us) WAIT_50 WAIT_10 WAIT_5 // total 8 clock ticks in either branch, using time from the front porch #asm("subi REG_LC, -1"); // 1 #asm("cpi REG_LC, 14"); // 1 #asm("brne BLACK2MID2"); // 1 if false, 2 if true #asm("breq STARTMID"); // 1 if false, 2 if true #asm("BLACK2MID2:"); WAIT_2 //DATA_OUT = 0b00000100; // 2 #asm("DATA_OUT_EQUALS 0x04"); #asm("rjmp BLACK2"); // 2, counts as horizontal sync time #asm("STARTMID:"); #asm("jmp START"); // 3 (+3 at START) }