First sprite test

Talk about programming CreatiVision (except games programming). Projects of homebrew hardware are also welcome.
Post Reply
User avatar
carlsson
Posts: 515
Joined: Fri Jun 13, 2008 7:39 am
Location: Västerås, Sweden

First sprite test

Post by carlsson » Wed Jan 02, 2013 10:56 pm

Tonight I felt like wrestling the bull, so I took a closer look at Kurt's Titanic/Frogger demo and some VDP resources. My goal was to display a sprite on screen. Actually it didn't take me more than about one hour to get going, based on my previous 6502 coding skillz... :P

It is highly recommended to study Kurt's source code to understand what is going on, and of course also to study one of the VDP references to figure out how the chip is set up. I realize I still have a lot to learn and study, but this is at least a start.

Code: Select all

; Simple Creativision sprite test program

; The memory addresses and pointers are based on information in
; the Titanic/Frogger demo by Kurt Woloch. You are referred to
; the source code of that demo for additional information about those.

; Assemble with DASM using flags -f3

#processor 6502

VDP_Status_Write = $3001
VDP_Data_Write = $3000
VDP_Data_Read = $2000
VDP_Status_Read = $2001
Sound_Write = $1002
Sound_Status = $1003

BIOS_Sound_Write = $FE77
BIOS_Interrupt_Return = $FF52 
BIOS_Interrupt_Handler = $FF3F 
BIOS_VDP_Regwrite = $FE1F 
BIOS_VDP_Regsetup = $F84B 

  org $A000

Start:
  sei
          
; clear RAM
  ldx #0
  txa
cl$:
  sta 0,x
  sta $0100,x
  sta $0200,x
  sta $0300,x
  dex
  bne cl$

; now draw graphics

  ; set up the VDP to write to address $0800 (sprite generator table)
  lda #$00   ; LSB of $0800
  sta VDP_Status_Write
  lda #$48   ; MSB of $0800 + command 'write address'
  sta VDP_Status_Write

  ldx #31
csp$:
  lda sprgfx,x
  sta VDP_Data_Write
  dex
  bpl csp$

; now try to display sprite (sprite attribute table = $1300)

  lda #$00
  sta VDP_Status_Write
  lda #$53  ; $13 + $40
  sta VDP_Status_Write

  lda #70 ; Y=70
  sta VDP_Data_Write
  lda #0 ; X=0
  sta $0300
  sta VDP_Data_Write
  lda #$00 ; sprite pattern 0
  sta VDP_Data_Write
  lda #$06 ; dark red
  sta VDP_Data_Write

  cli
loop:
  jmp loop

Internal_Interrupt_Handler:
  ldx $0300
  lda #$01 ; jump directly to the X column of SA table
  sta VDP_Status_Write
  lda #$53
  sta VDP_Status_Write
  stx VDP_Data_Write
  inx
  stx $0300
  jmp BIOS_Interrupt_Return

; Some sprite graphics data. In 16x16 mode, it seems the the right column
; is defined first, followed by the left column. Both columns are however
; defined from bottom to top, not from top to bottom???
; ....**** ........
; ....**** ........
; ....**** ........
; ....**** *******.
; ....**** *******.
; ....**** *******.
; ******** ********
; .******* ********
; ..****** ********
; ..****** *******.
; ...*..** *****...
; .......* ****....
; .......* ***.....
; ........ ***.....
; ........ .***....
; ........ ........

sprgfx:
  .byte 0,112,224,224,240,248,254,255,255,255,254,254,254,0,0,0
  .byte 0,0,0,1,1,19,63,63,127,255,15,15,15,15,15,15

  ; BIOS expects a vector to the cartridge's interrupt routine
  org $BFEA
  .word Internal_Interrupt_Handler

  ; VDP vectors, same as in Crazy Chicky (Screen Mode 0)
  org $BFF0
  .byte $00  ; VDP 0: External video off, M2=0
  .byte $E2  ; VDP 1: 16K mode, Screen active, Generate interrupts
             ;        M1=0, M3=0, Sprites = 16x16 unmagnified
  .byte $04  ; VDP 2: Pattern Name Table = 04 * $400 = $1000
  .byte $4E  ; VDP 3: Color Table Address =    0001 0011 1000 0000 = $1380
  .byte $00  ; VDP 4: Pattern Generator Table = $0000
  .byte $26  ; VDP 5: Sprite Attribute Table = 0001 0011 0000 0000 = $1300
  .byte $01  ; VDP 6: Sprite Generator Table = 0000 1000 0000 0000 = $0800
  .byte $01  ; VDP 7: TC=1 (transparent color), BD=0 (black backdrop)

  ; $0000 Pattern generator table = character definitions (2048 bytes)
  ; $0800 Sprite generator table = sprite definitions (2048 bytes)
  ; $1000 Pattern name table = screen memory (32x24 = 768 bytes)
  ; $1300 Sprite attribute table (128 bytes)
  ; $1380 Color table address (32x28 = 896 bytes?)

  ; BIOS vectors
  org $BFFC
  .word Start
  .word BIOS_Interrupt_Handler
When you assemble the above program, a very crude 16x16 version of state of Texas, USA will float across the screen. The choice of graphic symbol should be quite obvious if you think about it...
You do not have the required permissions to view the files attached to this post.
User avatar
carlsson
Posts: 515
Joined: Fri Jun 13, 2008 7:39 am
Location: Västerås, Sweden

Re: First sprite test

Post by carlsson » Wed Jan 02, 2013 11:41 pm

Small errata that doesn't show in the test program: the color table in mode 0 of course is 32 bytes, and the total possible 256 characters are split into sets of 8 characters each, just like in Basic. That is one part that is really hard for me to understand, but it'll come to me eventually. :roll:

Another errata is the reason why the sprite data needs to be stored upside down, right column first is my loop is indexed backwards, but the VDP data is written forwards. I'm used to STA nnnn,x where it wouldn't show up but in this case it should've becomed obvious if I thought twice. Forward loops it is then, at the cost of an extra CPX instruction...
User avatar
carlsson
Posts: 515
Joined: Fri Jun 13, 2008 7:39 am
Location: Västerås, Sweden

Re: First sprite test

Post by carlsson » Thu Jan 03, 2013 11:42 pm

On the second day, He created a font and drew some characters. He saw they were diagonal and light yellow, and that concluded the second day. 8-)

Yes, that is a VIC-20 font. I believe the "plot" subroutine I wrote can be useful for plotting characters on the screen. The routine is only supposed to be used for rows 0-23 and columns 0-31.

Of course I haven't tried to READ anything from the VDP yet, nor checked its status register for sprite collissions and so on. That is an exercise for later.
SPRITETEST.zip
You do not have the required permissions to view the files attached to this post.
Post Reply