video_int.h


//-----------video----------------
//cycles = 63.625 * 16 Note NTSC is 63.55
//but this line duration makes each frame exactly 1/60 sec
//which is nice for keeping a realtime clock
#define lineTime 1018
#define width 126
#define ScreenTop 30
#define ScreenBot 230
extern char syncON, syncOFF;
int LineCount;

#pragma warn-
interrupt [TIM1_COMPA] void t1_cmpA(void)
{
  //start the Horizontal sync pulse
  PORTD = syncON;
  //update the curent scanline number
  LineCount ++ ;
  //begin inverted (Vertical) synch after line 247
  if (LineCount==248)
  {
    syncON = 0b00100000;
    syncOFF = 0;
  }
  //back to regular sync after line 250
  if (LineCount==251)
  {
    syncON = 0;
    syncOFF = 0b00100000;
  }
  //start new frame after line 262
  if (LineCount==263)
  {
     LineCount = 1;
  }

  delay_us(2);
  PORTD = syncOFF;


  if (LineCount=ScreenTop)
  {
       //compute byte index for beginning of the next line
       //left-shift 4 would be individual lines
       // <<3 means line-double the pixels
       //The 0xfff8 truncates the odd line bit
       //i=(LineCount-ScreenTop)<<3 & 0xfff8; //

       #asm
       push r16
       lds   r12, _LineCount
       lds   r13, _Linecount+1
       ldi   r16, 30
       sub  r12, r16
       ldi  r16,0
       sbc  r13, r16
       lsl  r12
       rol  r13
       lsl  r12
       rol  r13
       lsl  r12
       rol  r13
       mov  r16,r12
       andi r16,0xf0
       mov  r12,r16
       pop r16
       #endasm

       //load 16 registers with screen info
       #asm
       push r14
       push r15
       push r16
       push r17
       push r18
       push r19
       push r26
       push r27

       ldi  r26,low(_screen)   ;base address of screen
       ldi  r27,high(_screen)
       add  r26,r12            ;offset into screen (add i)
       adc  r27,r13
       ld   r4,x+   	       ;load 16 registers and inc pointer
       ld   r5,x+
       ld   r6,x+
       ld   r7,x+
       ld   r8,x+
       ld   r9,x+
       ld   r10,x+
       ld   r11,x+
       ld   r12,x+
       ld   r13,x+
       ld   r14,x+
       ld   r15,x+
       ld   r16,x+
       ld   r17,x+
       ld   r18,x+
       ld   r19,x

	  pop  r27
       pop  r26

       #endasm

       delay_us(4);  //adjust to center image on screen to work with 64 cycles
        // delay_us(1);  //16cycles plus 4 above was added to recenter the image
		  //might have to adjust

       //blast 16 bytes to the screen
       #asm
       ;but first a macro to make the code shorter
       ;the macro takes a register number as a parameter
       ;and dumps its bits serially to portD.6
       ;the nop can be eliminated to make the display narrower
       .macro videobits ;regnum
        BST  @0,7
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,6
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,5
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,4
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,3
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,2
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,1
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30

	BST  @0,0
	IN   R30,0x12
	BLD  R30,6
	nop
	OUT  0x12,R30
       .endm

	videobits r4 ;video line -- byte 1
        videobits r5 ;byte 2
        videobits r6 ;byte 3
        videobits r7 ;byte 4
        videobits r8 ;byte 5
        videobits r9 ;byte 6
        videobits r10 ;byte 7
        videobits r11 ;byte 8
        videobits r12 ;byte 9
        videobits r13 ;byte 10
        videobits r14 ;byte 11
        videobits r15 ;byte 12
        videobits r16 ;byte 13
        videobits r17 ;byte 14
        videobits r18 ;byte 15
        videobits r19 ;byte 16
	clt   ;clear video after the last pixel on the line
	IN   R30,0x12
	BLD  R30,6
	OUT  0x12,R30

       pop r19
       pop r18
       pop r17
       pop r16
       pop r15
       pop r14
       #endasm
   }
}
#pragma warn+