Jump to content
IGNORED

VBI doesn't quite work


Recommended Posts

Does this code look as if it should work during the vertical blank interrupt? I want to use the VBI time to cycle through some character animation and right now the x-register works but the y-register doesn't. The strange part is that if I separate the code and run it as it's own program then it works fine.

 

I don't think it's necessary (though correct me if I'm wrong) to save the x, y, and accumulator on the stack, but I did to be safe. I also have some DLIs running too.

 

My feeling is that somewhere in the main body of the code is a bug but, just in case I'm missing something obvious, I've posted it below.

 

Thanks!

 

Avram

 

;vbi routine
*=$9000	
pha
txa
pha
tay
pha

dec vbi_timr	; vbi timer
lda vbi_timr
bne vbi_exit
lda #10		
sta vbi_timr	; reset timer

; begin main VBI routine
ldy #16		; number of chars to change, x8
ldx vbi_char 
cpx #80
bne char_anim
;character animate reset
lda #0
sta vbi_char
char_anim 	
lda $7000,x	;read frame
sta $6020,x	;copy to character set
inx		
dey
bne char_anim	

clc
lda vbi_char
adc #16
sta vbi_char
vbi_exit
pla
tay
pla
tax
pla
jmp $E462	;exit VBI

;vbi set-up
vbi_test
ldy #$0		; lo-byte of vbi routine
ldx #$90	; hi-byte of vbi routine
lda #7		; deferred vector
jsr $E45C	; go to SETVBV
rts

Link to comment
Share on other sites

So, this copies from $7000,x to $6020,x 16 times. This won't copy anything new, since the index is the same for source and destination. It will always copy:

 

$7000->6020

$7001->6021

$7002->6022

...

$7050->6070 (80 decimal is 50 hex)

...

... and it will keep going until vbi_char=#80 on entry into the routine, doing 16 bytes per VBL.

 

 

Don't you want to copy different information to the destination table each time? And oh wait, you do an exact compare with #80 but #80 isn't divisible by 16. maybe you mean #$80 (128). A quick way to test for 128 or more is to test for minus.

 

I'd need to know more about the data being moved. And you're right, a deferred VBLANK routine doesn't need to push anything.

 

If you're trying to update two characters at $6020 using 8 frames at $7000, then this is probably what you want:

 

; begin main VBI routine
       ldy #15         ; number of bytes to change -1 (two characters)
       ldx vbi_char    ; get index into table
       bpl char_anim   ; at the end of the table?
;character animate reset
       ldx #0          ; yes, reset index
char_anim       
       lda $7000,x     ; read frame
       sta $6020,y     ; copy to character set
       inx             ; next byte to read
       dey             ; write from offset 15 to 0 (copies upside down, though)
       bpl char_anim   ; if Y wrapped from 0 to FF, we're done.

       stx vbi_char    ; whatever X is, save it for next time

Edited by Bryan
Link to comment
Share on other sites

Hi Brian

 

I'm attempting to cycle through 4 different frames of two antic #4 characters (16 bytes per vbi visit) so it creates some simple animation.

 

It could be I've bungled up the code but I think that using char_anim lets me jump around my data, so that I'm reading from $7000 + 0/16/32/48/64 (80 is the flag to reset back to zero and loop the animation).

 

Avram

 

*edit* Just saw your extra code there Bryan. I'll give that a shot and see how it works.

Edited by Avram
Link to comment
Share on other sites

Hi Brian

 

I'm attempting to cycle through 4 different frames of two antic #4 characters (16 bytes per vbi visit) so it creates some simple animation.

 

It could be I've bungled up the code but I think that using char_anim lets me jump around my data, so that I'm reading from $7000 + 0/16/32/48/64 (80 is the flag to reset back to zero and loop the animation).

 

Avram

 

*edit* Just saw your extra code there Bryan. I'll give that a shot and see how it works.

 

Okay, 4 frames at $7000, $7010, $7020 and $7030 ($703F is the last byte used). Since vbi_char appears to be your X index storage place, we'll need to test it for $40(64)

 

; begin main VBI routine
       ldy #15         ; number of bytes to change -1 (two characters)
       ldx vbi_char    ; get index into table
       cpx #64         ; are we at the end of the table 
       bne char_anim   ; nope, copy from current index
;character animate reset
       ldx #0          ; yes, reset index
char_anim       
       lda $7000,x     ; read frame
       sta $6020,y     ; copy to character set
       inx             ; next byte to read
       dey             ; write from offset 15 to 0 (copies data upside down, though)
       bpl char_anim   ; if Y wrapped from 0 to FF, we're done.

       stx vbi_char    ; whatever X is, save it for next time
                       ; (due to the post-increment, X will be at the start of the next frame)

 

Here's another take on it which reverses the frame order, but doesn't copy the data upside-down since X and Y are both decremented:

 

; begin main VBI routine
       ldy #15         ; number of bytes to change -1 (two characters)
       ldx vbi_char    ; get index into table
       bne char_anim   ; index is okay (not 0)
;character animate reset
       ldx #64         ; otherwise, reset index
char_anim       
       dex             ; pre-decrement X
       lda $7000,x     ; read frame
       sta $6020,y     ; copy to character set
       dey             ; write from offset 15 to 0
       bpl char_anim   ; if Y wrapped from 0 to FF, we're done.

       stx vbi_char    ; whatever X is, save it for next time
              

 

in both cases, vbi_char should be initialized to 0 at startup.

Edited by Bryan
Link to comment
Share on other sites

Does this code look as if it should work during the vertical blank interrupt? I want to use the VBI time to cycle through some character animation and right now the x-register works but the y-register doesn't. The strange part is that if I separate the code and run it as it's own program then it works fine.

 

I don't think it's necessary (though correct me if I'm wrong) to save the x, y, and accumulator on the stack, but I did to be safe. I also have some DLIs running too.

 

My feeling is that somewhere in the main body of the code is a bug but, just in case I'm missing something obvious, I've posted it below.

 

Thanks!

 

Avram

 

;vbi routine
*=$9000	
pha
txa
pha
tay  ;THIS SHOULD BE TYA - the accumulator holds X at this point, and you then put that in y
pha

;SNIP

See the note above - you have a tay when you needed a tya.

Link to comment
Share on other sites

 

See the note above - you have a tay when you needed a tya.

 

It wouldn't be my code if there weren't any stupid mistakes in it.

 

Cool, glad you got it working.

 

It just takes a while to 'think' in 6502. After a while, you'll be building various structures from memory, and remembering all the little tricks. I wish I had more time for it nowadays.

Edited by Bryan
Link to comment
Share on other sites

One more thing. I don't think I'll need to but if I have more than 256 bytes of character data to move is there an easy way to modify the routine to make it so?

Sure. Make more than one data table (one for the 1st char, and one for the 2nd) and do 8 passes through the loop rather than 16. This gives you twice the data with the same index range. Dividing your data into more and more separate tables can give you a lot of indexing ability with 8-bits.

 

This method doubles the number of frames to 8 using the same maximum index (64) and an additional data table at $7040.

 

; begin main VBI routine
       ldy #7          ; number of bytes to change /2 -1 (two characters)
       ldx vbi_char    ; get index into table
       cpx #64         ; are we at the end of the table 
       bne char_anim   ; nope, copy from current index
;character animate reset
       ldx #0          ; yes, reset index
char_anim       
       lda $7000,x     ; read frame from table 1
       sta $6020,y     ; copy into character 1
       lda $7040,x     ; read frame from table 2 
       sta $6028,y     ; copy into character 2
       inx             ; next byte to read
       dey             ; write from offset 7 to 0 (copies data upside down, though)
       bpl char_anim   ; if Y wrapped from 0 to FF, we're done.

       stx vbi_char    ; whatever X is, save it for next time
                       ; (due to the post-increment, X will be at the start of the next frame)

Edited by Bryan
Link to comment
Share on other sites

You're welcome. I've had situations where I separated a character sets into 8 tables, one for each byte. That way, I had a table of 256 byte 1's, 256 byte 2's etc... Then I could retrieve any of 256 characters with an index:

 


   ;X = the character to read
   ;$4000 is the destination character

   lda char_table0,x
   sta $4000
   lda char_table1,x
   sta $4001
   lda char_table2,x
   sta $4002
   lda char_table3,x
   sta $4003
   lda char_table4,x
   sta $4004
   lda char_table5,x
   sta $4005
   lda char_table6,x
   sta $4006
   lda char_table7,x
   sta $4007

 

Here a simple technique to put one of 256 characters into one of 32 character set positions. Pick the destination char with Y (char_num*8 ):

 


   ;X = the character to read
   ;Y = destination char position
   ;$4000 is the first char position

   ldx source_char
   lda dest_char
   asl a
   asl a
   asl a                ;*8
   tay

   lda char_table0,x
   sta $4000,y
   lda char_table1,x
   sta $4001,y
   lda char_table2,x
   sta $4002,y
   lda char_table3,x
   sta $4003,y
   lda char_table4,x
   sta $4004,y
   lda char_table5,x
   sta $4005,y
   lda char_table6,x
   sta $4006,y
   lda char_table7,x
   sta $4007,y

 

Of course, you can get much fancier with zero-page pointers.

Edited by Bryan
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...