How to use assembly for graphics in BASIC

Started by zmaster18, November 21, 2015, 08:06:31 pm

Previous topic - Next topic

zmaster18

Lately I was wondering 2 things:

1. Can you use assembly to display BG tiles on the edges of the screen in BASIC? Each edge of the screen has a margin the width of 2 8pixel tiles. Can you use assembly to places tiles in this margin?

2. Can you use assembly to move sprites around faster than the built-in commands? I made a little demo today of a ball bouncing inside of rectangle made of blocks. The animation isn't that fast because of the calculations it makes to determine if there is a wall. Maybe doing the calculations in assembly would save time?

P

1. Should be possible.
You write graphic data you want to use to the nametable VRAM address (nametable 0 (or SCREEN 0 in Family BASIC) is between $2000-$23BF and nametable 1 (SCREEN 1) is between $2400-$27BF), where you write it within $2000-$23BF decides where it will show up on screen. VRAM addresses are PPU addresses so you can't write to them directly (you only have access to CPU addresses as a programmer). Instead you send commands to the PPU via certain pins connected between the CPU and PPU. These pins (or ports) are used by writing to CPU register $2006 and $2007. $2006 sets the VRAM address the PPU is pointing at, and $2007 sets the data to be drawn on screen. First you set the VRAM address you want to use (in our case the nametable address $2000-$23BF) by first writing the high byte of the VRAM address and then the low byte to $2006. Then you write the graphic data you want to draw on the screen to $2007.

For instance if we want to write "5" in the middle of SCREEN 0, we first write $21 and then $CC to $2006, this sets the VRAM address the PPU is pointing at to $21CC (which I believe is somewhere in the middle of the screen) and then you write $35 (the CHR code for "5") to $2007. Before doing this though we can also read $2002 since doing that resets what byte in sequence $2006 is expecting.
It's done like this:

  lda $2002 ;reset high/low latch for $2006

;Now set the VRAM address the PPU should be pointing at:
  lda #$21
  sta $2006 ;set high byte of VRAM address
  lda #$CC
  sta $2006 ;set low byte of VRAM address

;Now the VRAM address is set, it's time to write the CHR data:
  lda #$35 (ASCII for "5")
  sta $2007 ;write the data to draw on screen


I also tried using POKE on $2006 and $2007 but the screen froze (CTR+D saved me though)!


2. I'm not sure what parts of things can be made faster in assembly, but doing the whole movement routine in assembly should be much faster.

zmaster18

I tried doing something like this and it did something different every time it was run.


10 CLS
11 POKE &H2006,32
12 POKE &H2006,0
13 POKE &H2007,35


Usually it prints nothing, but sometimes I'll get a character I,J,K or #. It does print inside the margin though! :)

P

What happens if you insert a PEEK &H2002 before your code?

zmaster18

I get  SN ERROR. If I do A=PEEK(&H2002) nothing changes. The peek statement must have a variable assigned to it.