mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-11-22 01:31:33 +00:00
157 lines
5.1 KiB
Plaintext
157 lines
5.1 KiB
Plaintext
/* Atari VCS Color Bars Program */
|
|
|
|
#pragma origin $F800 //2k Cartridge
|
|
#include <vcshead.h02> //TIA and RIOT Registers
|
|
#include <vcsinit.h02> //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 <vcsfoot.h02> //Finalization Code
|
|
|
|
|