Skip to content

(VERA 0.8) Registers $9F23 and $9F24 (and $9F25)

Stephen Horn edited this page Mar 22, 2020 · 1 revision

This page refers to the VERA 0.8 and needs to be updated for emulator versions r37 and later.

Registers $9F23 and $9F24 (and $9F25)

Reading and writing memory on the VERA is very straightforward: Write the low, middle, and high bytes of the VRAM address to registers $9F20, $9F21, and $9F22, respectively, with your automatic address increment value set in the upper 4 bits of register $9F22. Then read or write data on register $9F23.

Take this simple "HELLO WORLD" for example:

BASIC

10 REM "HELLO WORLD"
20 DATA 8,5,12,12,15,$60,23,15,18,12,4
30 POKE$9F20,0 : POKE$9F21,8 : POKE$9F22,$20
40 REM PRINT HELLO WORLD TO SCREEN
50 FOR X=1 TO 11 : READ A : POKE$9F23,A : NEXT

6502

hello: 
    !byte $08, $05, $0C, $0C, $0F, $60, $17, $0F, $12, $0C, $04 ; "HELLO WORLD"

print_hello:
    stz $9F20
    stz $9F21
    lda #$20
    sta $9F22
    ldy #0
loop:
    lda hello,y
    sta $9F23
    iny
    cpy #11
    bne loop
    rts

$9F23 is VERA_DATA0 in the VERA Programmer's Reference, and $9F20-$9F22 set the VRAM address for VERA_DATA0.

But what about VERA_DATA1, on $9F24?

$9F25 selects which VERA_DATA register we're talking about on $9F20-$9F22

To configure the VRAM address on $9F24, first write $01 to $9F25. Now, the VRAM address in $9F20-$9F22 refers to VERA_DATA1 on $9F24. Write the low, middle, and high bytes of the VRAM address, just as if we were setting the VRAM address for $9F23. Then read or write data on register $9F24:

BASIC

10 REM "HELLO WORLD"
20 DATA 8,5,12,12,15,$60,23,15,18,12,4
30 POKE$9F25,1
40 POKE$9F20,0 : POKE$9F21,8 : POKE$9F22,$20
50 REM PRINT HELLO WORLD TO SCREEN
60 FOR X=1 TO 11 : READ A : POKE$9F24,A : NEXT

6502

hello: 
    !byte $08, $05, $0C, $0C, $0F, $60, $17, $0F, $12, $0C, $04 ; "HELLO WORLD"

print_hello:
    lda #1
    sta $9F25
    stz $9F20
    stz $9F21
    lda #$20
    sta $9F22
    ldy #0
loop:
    lda hello,y
    sta $9F24
    iny
    cpy #11
    bne loop
    rts

(See notes.)

If we were to try, we would discover we can still read or write data on $9F23 - its configuration has remained untouched, and it will continue to behave as it did before setting up $9F24. To go back to configuring $9F23, simply write $00 to $9F25. At this point, $9F24 will continue to behave as we had configured it, while we can change the configuration of $9F23.

But why?

This is generally useful anytime you want to read or write data at some location in VRAM and then continue reading or writing where you had previously left off. For instance, your program might normally use VERA_DATA0 to read and write, and reserve VERA_DATA1 for use during interrupts.

In some special cases, you may wish to rapidly copy a block of data from one location in VRAM to another, such as if you need to copy sprite data in a game because one enemy type has left the screen and you're compacting VRAM so that adding new enemy types at the end of used memory can be done quickly. In this case, you might setup VERA_DATA0 to point to the VRAM you want to copy from, setup VERA_DATA1 to point to the VRAM you want to copy to, and then repeatedly read VERA_DATA0 and write to VERA_DATA1 for how many bytes need to be copied.

$9F25's Other Purpose

While we're on the subject, $9F25 can perform one other task. If you write $80 to $9F25, the VERA will restore all of its internal settings to their defaults, including (or perhaps most notably) the color palette.

Notes

If you ran that second example program, you might've noticed that it did some "interesting" things to your display that the first BASIC program did not. This is because the kernal makes use of VERA_DATA1 for its normal operation. SCREEN 2 should return your console to normal.