copying the memory block from VRAM to WRAM

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

copying the memory block from VRAM to WRAM

Post by sdm »

After a break I went back to learning 65816 SNES assembler.

I have a problem with the code to copy 2048-Bytes from VRAM $ 6000.W ($C000.B) to WRAM at address $ 00x0000 using classic loop (no DMA).
Is reading VRAM also autoincrement?

Code: Select all


	STZ $2181		; Set WRAM address to $000000.
	STZ $2182
	STZ $2183

	PHB

	REP #$20
	.ACCU 16		; .INDEX 16 sill.

	LDA #$80		; Set VRAM transfer mode to word-access, increment by 1.
	STA $2115

	LDA $6000		; WORD VRAM address.
	STA $2116		; $2116/7.

	LDY #$07FF		; -1.
	LDX #$0000

loop:

	LDA $2118
	STA $0000,x

	INX
;	INX

	DEY
	bne loop

	SEP #$20
	.ACCU 8
	PLB

Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: copying the memory block from VRAM to WRAM

Post by Oziphantom »

Code: Select all

STZ $2181		; Set WRAM address to $000000.
	STZ $2182
	STZ $2183

	PHB

	REP #$20
	.ACCU 16		; .INDEX 16 sill.

	LDA #$80		; Set VRAM transfer mode to word-access, increment by 1.
	STA $2115

	LDA #$6000		; WORD VRAM address. CHANGED LINE 
	STA $2116		; $2116/7.

	LDY #$07FF		; -1.
	LDX #$0000

loop:

	LDA $2118
	STA $0000,x

	INX
	INX  ; YES YOU WANT THIS

	DEY
	bpl loop ; THIS NEEDS TO ALSO COUNT 0, so -1 BPL or -0 BNE choose one

	SEP #$20
	.ACCU 8
	PLB
	
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: copying the memory block from VRAM to WRAM

Post by sdm »

doesn't work
UnDisbeliever
Posts: 124
Joined: Mon Mar 02, 2015 1:11 am
Location: Australia (PAL)
Contact:

Re: copying the memory block from VRAM to WRAM

Post by UnDisbeliever »

sdm wrote: Mon Nov 07, 2022 2:28 am Is reading VRAM also autoincrement?
VMDATAREAD does autoincrement (depending on the state of VMAIN), however the autoincrement (and VRAM-chip read by the PPU) occurs after VMDATAREAD outputs the vram_latch value.

In practice this requires you to preform a dummy read if you are preforming multiple VMDATAREAD reads. Otherwise first two VMDATAREAD reads will contain the same value (and there is an off-by-one or off-by-two in the read data).

Code: Select all

    VMMAIN = 0x80

    VMADD = 0x6000

    word0 = VMDATAREAD    // word0 = data at VRAM word address 0x6000
    word1 = VMDATAREAD    // word1 = data at VRAM word address 0x6000
    word2 = VMDATAREAD    // word2 = data at VRAM word address 0x6001
    word3 = VMDATAREAD    // word3 = data at VRAM word address 0x6002
Secondly, VMADD, VMDATAREAD and VMDATA will only preform the VRAM-chip reads/writes if the PPU is in force-blank (screen-disabled) or vertical-blank. VMDATAREAD will output invalid values if read outside of the force-blank/vertical-vblank[1]


(untested code).

Code: Select all

; 8 bit A
; 16 bit Index
; DB access registers
; DP = 0

    ; force blank
    lda   #INIDISP.force
    sta   INIDISP
    
    lda   #VMAIN.incrementMode.high | VMAIN.increment.by1
    sta   VMAIN

    ; vram word address
    ldx   #$6000
    stx   VMADD

    ; dummy read
    ldx   VMDATAREAD

    rep   #$30
; a16
; i16

    ; x = destination address
    ; y = number of words remaining
    ldx    #$0000
    ldy    #2048 / 2

    Loop:
        lda   VMDATAREAD
        sta   $7e0000,x

        inx
        inx

        dey
        bne   Loop

    sep   #20
; a8

---

[1]: I can't remember what the invalid value is. Higan says it always outputs 0, but I don't have a source for it and haven't written a test rom for VMDATAREAD yet.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: copying the memory block from VRAM to WRAM

Post by Oziphantom »

yeah for a loop this long you will need to force blank, it will take frames. Are you force blanking while this loop is called? If so how does it fail?
Post Reply