/* Atari VCS Color Bars Program */ #pragma origin $F800 //2k Cartridge #include //TIA and RIOT Registers #include //Initialize VCS zeropage char clrbkg; //Color Background zeropage char clrofs; //Color Offset zeropage char clrmsk; //Color/B&W Mask zeropage char score; //Two Digit BCD Score zeropage char timer; //Two Digit BDC Timer zeropage char scrone; //Offset into Ones Digit zeropage char tmrone; zeropage char scrten; //Offset into Tens Digit zeropage char tmrten; zeropage char scrgfx; //Score Graphics Data zeropage char tmrgfx; //Score Timer Graphics zeropage char temp; //Scratch Variable /* Generate Ones Digit Offset */ char ofsone() { temp = A & $0F; temp++; A<<; A<<; return A + temp; } /* Generate Tens Digit Offset */ char ofsten() { A = A & $F0; A>>; A>>; temp = A; temp++; A>>; A>>; return A + temp; } /* Prepare Score and Timer for Display */ void prepst() { scrone = ofsone(score); scrten = ofsten(score); tmrone = ofsone(timer); tmrten = ofsten(timer); } /* Display Score and Timer */ void dispst() { X = 5; //5 lines in digit } ScoreLoop: ; 43 - cycle after bpl ScoreLoop ldy DigitTens ; 3 46 - get the tens digit offset for the Score lda DigitGfx,y ; 5 51 - use it to load the digit graphics and #$F0 ; 2 53 - remove the graphics for the ones digit sta ScoreGfx ; 3 56 - and save it ldy DigitOnes ; 3 59 - get the ones digit offset for the Score lda DigitGfx,y ; 5 64 - use it to load the digit graphics and #$0F ; 2 66 - remove the graphics for the tens digit ora ScoreGfx ; 3 69 - merge with the tens digit graphics sta ScoreGfx ; 3 72 - and save it sta WSYNC ; 3 75 - wait for end of scanline ;--------------------------------------- sta PF1 ; 3 3 - @66-28, update playfield for Score dislay ldy DigitTens+1 ; 3 6 - get the left digit offset for the Timer lda DigitGfx,y ; 5 11 - use it to load the digit graphics and #$F0 ; 2 13 - remove the graphics for the ones digit sta TimerGfx ; 3 16 - and save it ldy DigitOnes+1 ; 3 19 - get the ones digit offset for the Timer lda DigitGfx,y ; 5 24 - use it to load the digit graphics and #$0F ; 2 26 - remove the graphics for the tens digit ora TimerGfx ; 3 29 - merge with the tens digit graphics sta TimerGfx ; 3 32 - and save it jsr Sleep12 ;12 44 - waste some cycles sta PF1 ; 3 47 - @39-54, update playfield for Timer display ldy ScoreGfx ; 3 50 - preload for next scanline sta WSYNC ; 3 53 - wait for end of scanline ;--------------------------------------- sty PF1 ; 3 3 - @66-28, update playfield for the Score display inc DigitTens ; 5 8 - advance for the next line of graphic data inc DigitTens+1 ; 5 13 - advance for the next line of graphic data inc DigitOnes ; 5 18 - advance for the next line of graphic data inc DigitOnes+1 ; 5 23 - advance for the next line of graphic data jsr Sleep12 ;12 35 - waste some cycles dex ; 2 37 - decrease the loop counter sta PF1 ; 3 40 - @39-54, update playfield for the Timer display bne ScoreLoop ; 2 42 - (3 43) if dex != 0 then branch to ScoreLoop sta WSYNC ; 3 45 - wait for end of scanline ;--------------------------------------- stx PF1 ; 3 3 - x = 0, so this blanks out playfield sta WSYNC ; 3 6 - wait for end of scanline /* Generate Vertical Sync Signal */ void vtsync() { X=49; //49*64 Cycles (37 Scanlines) A=2; //Set Bit 2 (D1) WSYNC=A; //Wait for end of Scanline VSYNC=A; //Turn On Vertical Sync TIM64T=X; //Set Timer WSYNC=A; //Wait 2 More Scanlines WSYNC=A; A=0; //Clear Bit 2 (D1) WSYNC=A; //Wait for End of 3rd Scanline VSYNC=A; //Turn Off Vertical Sync return; } /* Execute Vertical Blank Code */ void vtblnk() { clrmsk = (SWCHB & 8) ? $FF : $0F; if (SWCHB & 64) clrofs--; else clrofs++; A=0; //Clear All Bits return; } /* Execute Kernel Code */ void kernel() { do WSYNC=A; while(INTIM); VBLANK=0; //Turn Off Vertical Blank X=192; //Draw 192 Scanlines do { clrbkg = X; if (!SWCHB & 128) clrbkg<<; A = clrbkg + clrofs & clrmsk; //Set Background Color WSYNC = A; //Wait for end of Scanline COLUBK = A; //Set Background Color X--; } while (X); return; } /* Execute Overscan Code */ void ovrscn() { WSYNC=A; //Wait for end of Scanline A=2; //Set Bit 2 (D1) VBLANK=A; //Turn On Vertical Blank TIM64T = 32; //Delay 32*64 Cycles (27 Scanlines) do { WSYNC=A; //Wait for end of Scanline } while(INTIM); return; } irqbrk: //Code to Execute when BRK Instruction is Encountered main: //Start of Program Code vtsync(); //Generate Vertical Sync Signal vtblnk(); //Generate Vertical Blank Signal kernel(); //Execute Kernal Code ovrscn(); //Execute Overscan Code goto main; #include //Finalization Code