diff --git a/vcs/humans.c02 b/vcs/humans.c02 index c7b29b7..66fd489 100644 --- a/vcs/humans.c02 +++ b/vcs/humans.c02 @@ -4,6 +4,7 @@ #include //TIA and RIOT Registers #include //VCS Program Stub #include //VCS Library Routines +#include //Two Player Score Kernel #include //Two Line Game Kernel //TIA Register Bit Masks @@ -15,7 +16,7 @@ #define P0DIFF = $40 //Player 0 Difficulty //Constants Required by k2line.h02 -#define KNLLNS = 96 //Kernal Lines (Scanlines/2) +#define KNLLNS = 90 //Kernal Lines (Scanlines/2) #define P0HGHT = 10 //Player 0 Height #define P1HGHT = 10 //Player 1 Height @@ -33,17 +34,17 @@ void setup() { /* Vertical Blank Code */ void vrtblk() { + scrprp(); //Prepare Score For Display posobj(0,0); //Set P0 X-Position - p0prep(191, &human); //Set P0 Y-Position & Graphics Pointer + p0prep(179, &human); //Set P0 Y-Position & Graphics Pointer posobj(8,1); //Set P1 X-Position - p1prep(191, &human); //Set P1 Y-Position & Graphics Pointer - //VDELP0 = (SWCHB & #P0DIFF) ? #SET : #CLEAR; - //VDELP1 = (SWCHB & #P1DIFF) ? #SET : #CLEAR; + p1prep(179, &human); //Set P1 Y-Position & Graphics Pointer } /* Execute Kernel Code */ void kernel() { - dsplns(); //Display Playfield and Objects + scrdsp(); //Display Scores + dsplns(); //Display Playfield and Objects } /* Execute Overscan Code */ diff --git a/vcs/include/k2line.a02 b/vcs/include/k2line.a02 index 8868717..6a47b1f 100644 --- a/vcs/include/k2line.a02 +++ b/vcs/include/k2line.a02 @@ -81,6 +81,8 @@ P1PREP: CLC ;Add 1 to Y-Position ;Uses: KNLLNS, P0HGHT, P1HGHT, P0PTRL, P1PTRL ;Affects: A,X,Y,C,N,Z DSPLNS: LDY #KNLLNS ; - Number of Kernal Lines (Scanlines / 2) + LDA #1 ; - Reflect Playfield + STA CTRLPF ; - Set Playfield Control Register LDA #P1HGHT-1 ; - Preset GRP1 if Player 1 on Top Line DCP P1DRAW ; BCS DSPLN0 ; diff --git a/vcs/include/score2.a02 b/vcs/include/score2.a02 new file mode 100644 index 0000000..b209931 --- /dev/null +++ b/vcs/include/score2.a02 @@ -0,0 +1,77 @@ +;Atari 2600 Two Player Score Kernel + +;Score Routine Variables +SCORE0 EQU $E8 ;Player One Score +SCORE1 EQU $E9 ;Player Two Score +SC0ONE EQU $EA ;One Score Ones Digit Offset +SC1ONE EQU $EB ;Player Ten Score Ones Digit Offset +SC0TEN EQU $EC ;Player One Score Ones Digit Offset +SC1TEN EQU $ED ;Player Ten Score Ones Digit Offset +SC0GFX EQU $EE ;Player One Score Graphics Data +SC1GFX EQU $EF ;Player Two Score Graphics Data + + +;Prep Scores For Diplay +SCRPRP: LDX #1 ;Offset into SCORE0/SCORE1 +SCRPRL: LDA SCORE0,X ;Get SCORE1 (First Pass) or SCORE0 (Second Pass) + AND #$0F ;Remove Tens Digit + STA TEMP0 ;And Save It + ASL ;Multiply By 4 + ASL ;(Carry will be Clear because of AND/ASL) + ADC TEMP0 ;Add To Original Value for Multiply by 5 + STA SC0ONE,X ;Store in SC0ONE (First Pass) or SC1ONE (Second Pass) + LDA SCORE0,X ;Get SCORE1 (First Pass) or SCORE0 (Second Pass) + AND #$F0 ;Remove Ones Digit + LSR ;Divide by 4 + LSR ; + STA TEMP0 ;And Save It + LSR ;Divide by 4 Again + LSR ;(Leaving Carry Clear) + ADC TEMP0 ;Add Saved Value, Resulting in Digit / 16 * 5 + STA SC0TEN,X ;Store in SC0TEN (First Pass) or SC1TEN (Second Pass) + DEX ;Point to SCORE 1 + BPL SCRPRL ;AND Loop if >0 + RTS ;Return + +;Display Score Kernel - Uses 12 Lines Total +SCRDSP: LDA #2 ; - Use Player Colors + STA CTRLPF ; - Set Playfield Control Register + LDX #5 ; 43 - cycle after looping +SCRDSL: LDY SC0TEN ; 3 46 - get the tens digit offset for the Score + LDA DGTGFX,Y ; 5 51 - use it to load the digit graphics + AND #$F0 ; 2 53 - remove the graphics for the ones digit + STA SC0GFX ; 3 56 - AND save it + LDY SC0ONE ; 3 59 - get the ones digit offset for the Score + LDA DGTGFX,Y ; 5 64 - use it to load the digit graphics + AND #$0F ; 2 66 - remove the graphics for the tens digit + ORA SC0GFX ; 3 69 - merge with the tens digit graphics + STA SC0GFX ; 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 SC1TEN ; 3 6 - get the left digit offset for the Timer + LDA DGTGFX,Y ; 5 11 - use it to load the digit graphics + AND #$F0 ; 2 13 - remove the graphics for the ones digit + STA SC1GFX ; 3 16 - AND save it + LDY SC1ONE ; 3 19 - get the ones digit offset for the Timer + LDA DGTGFX,Y ; 5 24 - use it to load the digit graphics + AND #$0F ; 2 26 - remove the graphics for the tens digit + ORA SC1GFX ; 3 29 - merge with the tens digit graphics + STA SC1GFX ; 3 32 - AND save it + JSR SCRDSR ;12 44 - waste 12 cycles + STA PF1 ; 3 47 - @39-54, update playfield for Timer display + LDY SC0GFX ; 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 SC0TEN ; 5 8 - advance for the next line of graphic data + INC SC1TEN ; 5 13 - advance for the next line of graphic data + INC SC0ONE ; 5 18 - advance for the next line of graphic data + INC SC1ONE ; 5 23 - advance for the next line of graphic data + JSR SCRDSR ;12 35 - waste 12 cycles + DEX ; 2 37 - decrease the loop counter + STA PF1 ; 3 40 - @39-54, update playfield for the Timer display + BNE SCRDSL ; 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 +SCRDSR: RTS ; 6 12 - Return + diff --git a/vcs/include/score2.h02 b/vcs/include/score2.h02 new file mode 100644 index 0000000..a4424ea --- /dev/null +++ b/vcs/include/score2.h02 @@ -0,0 +1,13 @@ +/* Atari 2600 Two-Player Score Kernel */ + +char score1; //Player One Score +char score2; //Player Two Score + +char sc1one; //Player One Score Ones Digit Offset +char sc1ten; //Player One Score Ones Digit Offset +char sc2one; //Player Ten Score Ones Digit Offset +char sc2ten; //Player Ten Score Ones Digit Offset + +char sc1gfx; //Player One Score Graphics Data +char sc2gfx; //Player Two Score Graphics Data +