Uzumaki Posted November 11, 2006 Share Posted November 11, 2006 (edited) 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 November 11, 2006 by Uzumaki Quote Link to comment Share on other sites More sharing options...
Cybergoth Posted November 11, 2006 Share Posted November 11, 2006 VBLANK loop is missing the # ... Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 11, 2006 Author Share Posted November 11, 2006 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. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted November 11, 2006 Share Posted November 11, 2006 It should display 262 lines (~192 visible). Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted November 11, 2006 Share Posted November 11, 2006 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 Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 12, 2006 Author Share Posted November 12, 2006 Ok thanks for the help =) Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 12, 2006 Author Share Posted November 12, 2006 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? Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted November 12, 2006 Share Posted November 12, 2006 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 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted November 12, 2006 Share Posted November 12, 2006 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 Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 13, 2006 Author Share Posted November 13, 2006 (edited) Thanks a lot!! Now let see if I can figure from the examples and from info at Sea's post to make color/BW switch select color and greyscale mode. Edited November 13, 2006 by Uzumaki Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 13, 2006 Author Share Posted November 13, 2006 (edited) 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 November 13, 2006 by Uzumaki Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted November 13, 2006 Share Posted November 13, 2006 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 Quote Link to comment Share on other sites More sharing options...
Uzumaki Posted November 13, 2006 Author Share Posted November 13, 2006 I understand now. I think I'll stick with Batari for more advanced stuff. Thanks a lot for your time =) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.