Jump to content
IGNORED

I think I miscounted something...


Uzumaki

Recommended Posts

I was trying to do a color cycling fuji logo taking up most of the screen. It'd get used to fill in the blank spot of my multicarts. Should be neater than duplicating games or leaving it blank.

 

But unless I miscounted something, Stella reports 210 scanlines displayed but I only counted 192. Where did the 18 extra lines sneak in from??? :? Attached the asm file and bin for you to look at (PS ignore where I noted 32 data lines, it should be 23.)

 

			processor 6502 
			include "vcs.h" 
			include "macro.h" 

;variables

Color_Start = $80; Playfield Color (Color of the 1st Line)
Color = $81; Temp Var Address
PFData2 = #%00000000

			SEG 
			ORG $F000 
Reset 

	SEI
	CLD	
	LDX #$FF
	TXS
	LDA #0
Clear_Mem
	STA 0,X
	DEX
	BNE Clear_Mem			
	
	STA Color_Start; Init Playfield Color
			LDA #1
			STA CTRLPF; Mirrored Playfiels
			LDA #$00
			STA COLUBK; Set Background to Black

Start_Frame 

; Start VSYNC

			LDA #2 
			STA VSYNC 

			STA WSYNC 
			STA WSYNC 
			STA WSYNC; 3 Scanlines of VSYNC 

			LDA #0 
			STA VSYNC; End VSYNC		 

; 37 Scanlines of Vertical Blank... 
	   
   		LDX 37
Vertical_Blank  STA WSYNC 
	DEX
			BNE Vertical_Blank 
			
			LDA #0 
			STA VBLANK; Enable TIA Output
							
;Start Drawing Playfield 	
	  
	LDX Color_Start
	STX Color	
	STX COLUPF  
; Draw Top Border		
	LDY #4; 4 Lines to Draw (4 scans)
	LDA #PFData2
	STA PF0
	  STA PF1
	  STA PF2
DrawBorder1   	   
	STA WSYNC   
	DEX
	STX COLUPF  
			DEY
			BNE DrawBorder1 
			
; Draw Fuji
	STX Color
	LDX #$17; Init Index
Draw_Fuji		
	LDA PF1FujiData-1,x
	STA PF1
	LDA PF2FujiData-1,x
	STA PF2
	LDY #$07; 8 Lines repeated per data line
	TXA; Save Index
	LDX Color
Draw_Fuji_Line
	STA WSYNC
	DEX
	STX COLUPF  
	DEY
	BNE Draw_Fuji_Line
	STX Color; Save Color Index
	TAX; Restore Index
	DEX
	BNE Draw_Fuji ; 32 data lines * 8 = 184 scanlines here

;184 + 4 = 188 scanlines here, ok so far

; Draw Bottom Border		
	LDY #4; 4 Lines to Draw
	LDA #PFData2
	STA PF0
	  STA PF1
	  STA PF2
Draw_Border2   			
	STA WSYNC   
	DEX
	STX COLUPF			 
			DEY
			BNE Draw_Border2

; 188 + 4 more scanlines = 192 allowed in visible display
			
; Makes Colors to Scroll Up					
			LDX Color_Start
	DEX
			STX Color_Start

;overscan and vbanking	 	

	LDA #%01000010 ; Disable VIA Output
			STA VBLANK		   

; 30 scanlines of overscan... 

			LDX #30 
Overscan		STA WSYNC 
			DEX 
			BNE Overscan 

	JMP Start_Frame; Build Next Frame


PF1FujiData
	.byte #%11111000;
	.byte #%11111110;
	.byte #%01111111;
	.byte #%00001111;
	.byte #%00000111;
	.byte #%00000011;
	.byte #%00000001;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000; 23 * 8 = 184 lines
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;	
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000 ;

PF2FujiData
	.byte #%11000000;
	.byte #%11000000;
	.byte #%11000000;
	.byte #%11000001;
	.byte #%11000011;
	.byte #%11000011;
	.byte #%11000111;
	.byte #%11001111;
	.byte #%11001111;
	.byte #%11011110; 23 * 8 = 184
	.byte #%11011100;
	.byte #%11011100;
	.byte #%11011100;
	.byte #%11011000;
	.byte #%11011000;	
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000 ;

		ORG $FFFA 

; Interrupt Vectors 

		.word Reset		 ; NMI 
		.word Reset		 ; RESET 
		.word Reset		 ; IRQ 

	  END 

fujiscreen.bin

fuji.txt

Edited by Uzumaki
Link to comment
Share on other sites

VBLANK loop is missing the # ...

 

Adjusted the original code for missing # in 37 loops, still showing 210 lines in final output.

 

Any other?? Those extra lines may be OK on some TVs but many will probably roll due to having too many scanlines total.

I'm getting 239 lines, both before and after adding the # to fix the vblank loop. And as Thomas said, it should be 262, so you're actually short 23 lines. This is what I count:

 

vsync -- 3 lines

vblnk -- 37 lines

brdr1 -- 4 lines

dfuji -- 161 lines (23 x 7)

brdr2 -- 4 lines

oscan -- 30 lines

TOTAL -- 239 lines

 

The problem is right here, in the section where you draw the fuji:

 

  LDY #$07	 ; 8 Lines repeated per data line

This is actually doing it 7 times, not 8 times, because you're using BNE after you DEY. So you need to change that to LDY #$08. Or you can leave it at LDY #$07, but change the other line to BPL after you DEY.

 

By the way, nice color-cycling fuji! :)

 

MR

Link to comment
Share on other sites

I would like to tweak this part:

; Makes Colors to Scroll Up					
			LDX Color_Start
	DEX
			STX Color_Start

 

so they change depending on the difficulty switches. If I change DEX to INX, the color scroll down instead of up. And if I put 2 DEX or 2 INX, the color scrolls faster. But I haven't figured how to read difficulty switches or do the if-then-else version in ASM. Any help?

Link to comment
Share on other sites

I would like to tweak this part:

; Makes Colors to Scroll Up					
			LDX Color_Start
	DEX
			STX Color_Start

 

so they change depending on the difficulty switches. If I change DEX to INX, the color scroll down instead of up. And if I put 2 DEX or 2 INX, the color scrolls faster. But I haven't figured how to read difficulty switches or do the if-then-else version in ASM. Any help?

You read the console switches all at once at SWCHB, and they're arranged like this:

 

bit 7 = right (player 1) difficulty -- A=1, B=0

bit 6 = left (player 0) difficulty -- A=1, B=0

bit 5 = not used

bit 4 = not used

bit 3 = TV type -- Color=1, B&W=0

bit 2 = not used

bit 1 = game select -- Up=1, Pressed=0

bit 0 = game reset -- Up=1, Pressed=0

 

If the difficulty switches are the only ones you want to read, then all you have to do is use the BIT command on SWCHB, which will set the sign and overflow flags to match bits 7 and 6 (respectively) of the address you're checking. Then you can use the BMI, BPL, BVS, and/or BVC commands as appropriate, e.g.:

 

  LDX Color
Draw_Fuji_Line
  STA WSYNC
  DEX
  BIT SWCHB	 ; test the difficulty switches
  BVS Store_PF_Color  ; If Left Difficulty = A then DEX, else INX
  INX
  INX
Store_PF_Color
  STX COLUPF

In this example, the left difficulty switch is used to control the direction of the color cycling. Since the state of the left difficulty switch is stored in bit 6 of SWCHB, the BIT SWCHB command will set the overflow flag to match the left difficulty setting. If the switch is up (set to A), then bit 6 will be 1, so the overflow flag will be set. If the switch is down (set to B), then bit 6 will be 0, so the overflow flag will be cleared.

 

Coding an IF...THEN...ELSE situation can be a little bit tricky, but only because of the way you need to branch or jump around, and also because the exact structure of the code might vary depending on what you're trying to do, coupled with any timing or memory considerations. The generic structure would be something like the following:

 

  LDA Variable_A
  CMP #5
  BNE Else_Variable_A_Is_Not_5
  LDA This_Color
  STA COLUBK
  JMP End_If_Variable_A_Is_5
Else_Variable_A_Is_Not_5
  LDA That_Color
  STA COLUBK
End_If_Variable_A_Is_5
 ; on to the next bit of code

The example above is equivalent to

 

  if A = 5 then
		COLUBK = This_Color
  else
		COLUBK = That_Color
  endif

Note that I used BNE to branch over the THEN portion to the ELSE portion, and then I coded the THEN portion. After the THEN portion was done, I used JMP to jump over the ELSE portion to the ENDIF portion, and then I coded the ELSE portion.

 

I deliberately made the code a little bit redundant by including STA COLUBK in both the THEN and ELSE portions, to show how the easiest-to-write code might not be the best code. Since the THEN and ELSE portions both end with STA COLUBK, it would be better to move that statement to the very end, because it saves 2 bytes:

 

  LDA Variable_A
  CMP #5
  BNE Else_Variable_A_Is_Not_5
  LDA This_Color
  JMP End_If_Variable_A_Is_5
Else_Variable_A_Is_Not_5
  LDA That_Color
End_If_Variable_A_Is_5
  STA COLUBK
 ; on to the next bit of code

However, the code could be further improved by removing the JMP, as follows:

 

  LDX This_Color
  LDA Variable_A
  CMP #5
  BEQ End_If_Variable_A_Is_5
  LDX That_Color
End_If_Variable_A_Is_5
  STX COLUBK
 ; on to the next bit of code

In this version, we go ahead and load X with the color we want to use when Variable_A is 5, and then if Variable_A does equal 5 we use BEQ to skip over the ELSE portion. In the ELSE portion, we load X with the color we want to use when Variable_A is *not* 5. By doing it this way, we can eliminate the JMP at the end of the THEN portion, which skips over the ELSE portion.

 

Sometimes you can replace the JMP with a branch command, if you're sure the branch command will always be taken. For example, if I know that This_Color is *not* equal to 0, then I could have used BNE instead of JMP after the LDA This_Color statement.

 

However, another factor to consider is how long the THEN and ELSE portions are, because if they're too long then you'll need to use JMP instead of a branch command.

 

And of course the general construction of the IF is another factor-- e.g., if you're coding a >, <, >=, or <= situation, you might need to use two branches consecutively. I always have to look that stuff up to be sure, so I can't give an example right now.

 

Anyway, in the code I added to your fuji program, first I use DEX to decrement the color. Then I test the left difficulty switch. If it's set to A, I skip ahead to store the color. Otherwise, I use INX twice to increment the color (the first INX counteracts the DEX, and the second INX increments the color).

 

MR

Link to comment
Share on other sites

Here's another version that uses both difficulty switches:

 

  LDX Color
Draw_Fuji_Line
  STA WSYNC
  BIT SWCHB
  BPL Increment_Color
  DEX
  BVC Store_PF_Color
  DEX
  BVS Store_PF_Color
Increment_Color
  INX
  BVC Store_PF_Color
  INX
Store_PF_Color
  STX COLUPF

I'll leave it to you to figure out exactly what it's doing, but the left difficulty switch controls whether the color changes by 1 or 2, and the right difficulty switch controls whether the color is incremented or decremented.

 

MR

 

post-7456-1163347708_thumb.jpg post-7456-1163347742_thumb.jpg post-7456-1163347727_thumb.jpg post-7456-1163347757_thumb.jpg

Link to comment
Share on other sites

OK I think I got the B&W switch part done. Now I need to discard color info if switch is down (bit 3 reads 0) As I understand the color chart, left 4 bits are used for color and right 3 (4) bits for lumina and can be ignored. Since black is zero, the right 4 bits can change to 0000.

 

Still an ASM noob though. Try this code: (directly below Draw_Fuji_Line route, Color_Mask is set to %1000)

		LDA SWCHB	 ; read the console switches
	AND #Color_Mask; mask to get B/W switch value
	BNE Color_On  ; skip B&W if switch is set to color
	LDX ????; discard color value (black is %0000xxxx) but leave luma as is
Color_On

 

One: how do I correctly discard color data but leave lumina alone? and 2: variable A is being used at the same time and if I use A, it messes up and the fuji logo doesn't get past the first line. X is being used for color/luma and Y is for the 8 step loop to get 8 scan lines per "pixel"

Edited by Uzumaki
Link to comment
Share on other sites

OK I think I got the B&W switch part done. Now I need to discard color info if switch is down (bit 3 reads 0) As I understand the color chart, left 4 bits are used for color and right 3 (4) bits for lumina and can be ignored. Since black is zero, the right 4 bits can change to 0000.

 

Still an ASM noob though. Try this code: (directly below Draw_Fuji_Line route, Color_Mask is set to %1000)

		LDA SWCHB	; read the console switches
	AND #Color_Mask; mask to get B/W switch value
	BNE Color_On ; skip B&W if switch is set to color
	LDX ????; discard color value (black is %0000xxxx) but leave luma as is
Color_On

 

One: how do I correctly discard color data but leave lumina alone? and 2: variable A is being used at the same time and if I use A, it messes up and the fuji logo doesn't get past the first line. X is being used for color/luma and Y is for the 8 step loop to get 8 scan lines per "pixel"

First of all, you can use BIT SWCHB to check bit 7, bit 6, and one other bit, all at the same time, so you can check both difficulty switches and the TV type switch in one fell swoop! :) (Actually, you can check for a specific value, not just one other bit, but in this case you'd be interested only in bit 3.)

 

  LDA #%00001000  ; the bit(s) you want to check-- in this case, bit 3
  BIT SWCHB  ; this sets three flags at once-- sign, overflow, and zero (see below)
;	 BMI Right_Difficulty_A  ; this would branch somewhere if the right difficulty is set to A
;	 BPL Right_Difficulty_B  ; this would branch somewhere if the right difficulty is set to B
;	 BVS Left_Difficulty_A  ; this would branch somewhere if the left difficulty is set to A
;	 BVC Left_Difficulty_B  ; this would branch somewhere if the left difficulty is set to B
;	 BNE TV_Type_Color  ; this would branch somewhere if the TV type is set to color
;	 BEQ TV_Type_B&W  ; this would branch somewhere if the TV type is set to B&W

The BIT command will do a bitwise AND between the value in the accumulator and the value in the address that's being tested, and set the zero flag appropriately. Thus, if you do LDA #%00001000, and then do BIT SWCHB, the zero flag will be set to 0 if SWCHB AND #%00001000 is 0 (i.e., if bit 3 of SWCHB is 0), or the zero flag will be set to 1 if SWCHB AND #%00001000 is any non-zero value (i.e., if bit 3 of SWCHB is 1).

 

At the same time, the overflow flag will be set to match the value in bit 6 of SWCHB, and the sign flag will be set to match the value in bit 7 of SWCHB.

 

Note that if you do anything with the accumulator, you'll lose whatever value was already stored in it, so you won't be able to use TXA and TAX to store and restore the playfield graphics index. Instead, you'll need to add another variable, such as INDEX = $82:

 

INDEX = $82
  LDX #$17  ; Init Index
Draw_Fuji
  LDA PF1FujiData-1,x
  STA PF1
  LDA PF2FujiData-1,x
  STA PF2
  LDY #$08  ; 8 Lines repeated per data line
  STX Index  ; Save Index
  LDX Color
Draw_Fuji_Line
  STA WSYNC
  LDA #%00001000
  BIT SWCHB
  BEQ Store_PF_Color
  DEX
Store_PF_Color
  STX COLUPF
  DEY
  BNE Draw_Fuji_Line
  STX Color  ; Save Color Index
  LDX Index  ; Restore Index
  DEX
  BNE Draw_Fuji  ; 32 data lines * 8 = 184 scanlines here

In the variation shown above, the color will be decremented from one scan line to the next only if the TV type switch is set to color; otherwise, the fuji will be a solid color all up and down the screen (but will flash and cycle through the colors as the initial color is decremented from one frame to the next).

 

Second, the lower 4 bits-- or lo nybble-- is the luminance value, and the higher 4 bits-- or hi nybble-- is the hue value, so if you want to ignore the hue value and use just the luminance value, you would mask out the hi nybble and keep the lo nybble, as follows:

 

  TXA
  AND #%00001111
  TAX
  STX COLUPF

However, adding this to the other code isn't so easy, for two reasons. First, you're storing the color in COLUPF in three places-- where you set the color for the topmost scan lines, where you have the loop to draw the fuji, and where you set the color for the bottom of the fuji-- so you'll need to check the TV type switch in all three places. And second, if you check the TV type switch at the same time as the two difficulty switches (as shown previously), you'll lose the value of the zero flag as soon as you start incrementing or decrementing the X register, so that you means you'll need to check for the TV type switch separately, anyway. Thus, your final code might be as follows:

 

			processor 6502
			include "vcs.h"
			include "macro.h"

;variables

Color_Start = $80; Playfield Color (Color of the 1st Line)
Color = $81	; Temp Var Address
Index = $82	; Temp Var Address
PFData2 = #%00000000

			SEG 
			ORG $F000 
Reset 

	SEI
	CLD	
	LDX #$FF
	TXS
	LDA #0
Clear_Mem
	STA 0,X
	DEX
	BNE Clear_Mem			
	
	STA Color_Start; Init Playfield Color
	LDA #1
	STA CTRLPF; Mirrored Playfiels
	LDA #$00
	STA COLUBK; Set Background to Black

Start_Frame 

; Start VSYNC

	LDA #2 
	STA VSYNC 

	STA WSYNC 
	STA WSYNC 
	STA WSYNC	; 3 Scanlines of VSYNC 

	LDA #0 
	STA VSYNC; End VSYNC		 

; 37 Scanlines of Vertical Blank... 
	   
	LDX #37
Vertical_Blank  STA WSYNC 
	DEX
	BNE Vertical_Blank 

	LDA #0 
	STA VBLANK ; Enable TIA Output

;Start Drawing Playfield 	

	LDX Color_Start
	STX Color	
	STX COLUPF  
; Draw Top Border		
	LDY #4	; 4 Lines to Draw (4 scans)
	LDA #PFData2
	STA PF0
	  STA PF1
	  STA PF2
DrawBorder1
	STA WSYNC   
	DEX
	LDA #%00001000
	AND SWCHB
	BNE Store_Border1_Color
	TXA
	AND #%00001111
	TAX
Store_Border1_Color
	STX COLUPF  
	DEY
	BNE DrawBorder1

; Draw Fuji
	STX Color
	LDX #$17; Init Index
Draw_Fuji		
	LDA PF1FujiData-1,x
	STA PF1
	LDA PF2FujiData-1,x
	STA PF2
	LDY #$08; 8 Lines repeated per data line
	STX Index; Save Index
	LDX Color
Draw_Fuji_Line
	BIT SWCHB
	BPL Increment_Color
	DEX
	BVC Check_Color
	DEX
	BVS Check_Color
Increment_Color
	INX
	BVC Check_Color
	INX
Check_Color
	LDA #%00001000
	AND SWCHB
	BNE Store_Fuji_Color
	TXA
	AND #%00001111
	TAX
Store_Fuji_Color
	STA WSYNC
	STX COLUPF  
	DEY
	BNE Draw_Fuji_Line
	STX Color; Save Color Index
	LDX Index; Restore Index
	DEX
	BNE Draw_Fuji  ; 32 data lines * 8 = 184 scanlines here

;184 + 4 = 188 scanlines here, ok so far

; Draw Bottom Border		
	LDY #4	; 4 Lines to Draw
	LDA #PFData2
	STA PF0
	  STA PF1
	  STA PF2
Draw_Border2   			
	STA WSYNC   
	DEX
	LDA #%00001000
	AND SWCHB
	BNE Store_Border2_Color
	TXA
	AND #%00001111
	TAX
Store_Border2_Color
	STX COLUPF			 
	DEY
	BNE Draw_Border2

; 188 + 4 more scanlines = 192 allowed in visible display
			
; Makes Colors to Scroll Up					
	LDX Color_Start
	DEX
	STX Color_Start

;overscan and vbanking	 	

	LDA #%01000010 	; Disable VIA Output
	STA VBLANK		   

; 30 scanlines of overscan... 

	LDX #30 
Overscan
	STA WSYNC 
	DEX 
	BNE Overscan 

	JMP Start_Frame ; Build Next Frame


PF1FujiData
	.byte #%11111000;
	.byte #%11111110;
	.byte #%01111111;
	.byte #%00001111;
	.byte #%00000111;
	.byte #%00000011;
	.byte #%00000001;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000; 23 * 8 = 184 lines
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;	
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000;
	.byte #%00000000  ;

PF2FujiData
	.byte #%11000000;
	.byte #%11000000;
	.byte #%11000000;
	.byte #%11000001;
	.byte #%11000011;
	.byte #%11000011;
	.byte #%11000111;
	.byte #%11001111;
	.byte #%11001111;
	.byte #%11011110; 23 * 8 = 184
	.byte #%11011100;
	.byte #%11011100;
	.byte #%11011100;
	.byte #%11011000;
	.byte #%11011000;	
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000;
	.byte #%11011000  ;

		ORG $FFFA 

; Interrupt Vectors 

		.word Reset		  ; NMI 
		.word Reset		  ; RESET 
		.word Reset		  ; IRQ 

	  END

MR

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...