Which of these is faster?

Pagina 1/3
| 2 | 3

Door albs_br

Master (145)

afbeelding van albs_br

20-09-2020, 17:48

Which of these is faster?

- Read one byte from VRAM with BIOS_RDVRM, increment it and save with BIOS_WRTVRM. Increment HL to next byte. Loop 768 times (all names table).

OR

- Make the operation on a buffer located at RAM, then copy all 768 bytes to VRAM with BIOS_LDIRVM ?

My guess is that the second method is faster.

Aangemeld of registreer om reacties te plaatsen

Van Grauw

Ascended (9334)

afbeelding van Grauw

20-09-2020, 18:55

Generally speaking, yes that's correct, the second is much faster.

Of course it depends on how many bytes you modify.

Van albs_br

Master (145)

afbeelding van albs_br

20-09-2020, 19:09

768 bytes, all the names table.

Van PingPong

Prophet (3554)

afbeelding van PingPong

20-09-2020, 20:12

Writing or reading a byte from vram in random access mode could take more than 80 t states
The same operation on main ram could be on the order of 8 t states. ( ld a, (hl))

If you write to vram in a sequential manner, however the difference is not so much, writing a byte takes from 23 to 30-40 t states, comparable to the same instruction of ram , the ldir that take 23 t states.

So do your math ????

Van santiontanon

Paragon (1092)

afbeelding van santiontanon

20-09-2020, 22:41

If you want to copy all 768, LDIRVM will be significantly faster. That being said, LDIRVM is rather slow... it uses 2x the amount of time that it'd take if you write a custom optimized routine to copy the data from RAM to VRAM.

Van albs_br

Master (145)

afbeelding van albs_br

21-09-2020, 05:46

Any code sample? 2 times faster is a lot.

Van salutte

Expert (107)

afbeelding van salutte

21-09-2020, 07:52

Top speed depends on the VDP used, sprite usage, blank screen, etc... Grauw's page is very informative!
http://map.grauw.nl/articles/vdp_tut.php

With sprites enabled, the maximum rate that you can write to the MSX1 VDP memory is one byte each 29 t cycles. And the optimal loop that takes exactly 29 t-cycles per byte is:

OutiToVram:
    outi
    jp nz,OutiToVram

However, just after the v-sync interrupt triggers you are in blank screen, the VDP is basically idle at that point, so you can write to VRAM much faster, check the "Unrolling OTIRs and such" section from:
http://map.grauw.nl/articles/fast_loops.php

Van gdx

Prophet (3730)

afbeelding van gdx

21-09-2020, 10:29

If you want something faster than the BIOS for MSX1:

; RAM to VRAM transfer (LDIRVM IO for MSX1)

;Input: HL = source address in RAM
;       DE = destination address in VRAM (0-3FFFh)
;       BC = number of bytes to transfer

VDP_DW	equ	00007h	; VDP write port


ldirvmIO:
	push	bc

	ld	a,(VDP_DW)	;Incompatible under DOS.
	ld	c,a
	inc	c

	di
	out	(c),e		;bits 0 to 7 of VRAM address
	ld	a,d
	and	03fh		;set bits 8 to 13
	or	040h		;set bit 6 for write to the VRAM
	out	(c),a		;bits 8-13 of VRAM address
	ei
	dec	c
	pop	de		;DE = number of bytes to transfert
ldirvm1:
	dec	de
	ld	a,d
	outi
	or	e
	jr	nz,ldirvm1
	ret

Van santiontanon

Paragon (1092)

afbeelding van santiontanon

21-09-2020, 17:11

As mentioned above, if you are copying just after the v-sync interrupt, you can do it faster. But for general copies, I use this routine, which is a drop-in replacement of LDIRVM (but about 2x faster) and still calls "SETWRT" for maximum compatibility:

;-----------------------------------------------
; hl: source data
; de: target address in the VDP
; bc: amount to copy
fast_LDIRVM:
    ex de,hl    ; this is wasteful, but it's to maintain the order of parameters of the original LDIRVM...
                ; For things that require real speed, this function should not be used anyway, and you should use specialized loops
    push de
    push bc
    call SETWRT
    pop bc
    pop hl
copy_to_VDP:
    ld e,b
    ld a,c
    or a
    jr z,copy_to_VDP_lsb_0
    inc e
copy_to_VDP_lsb_0:
    ld b,c
    ; get the VDP write register:
    ld a,(VDP.DW)
    ld c,a
    ld a,e
copy_to_VDP_loop2:
copy_to_VDP_loop:
    outi
    jp nz,copy_to_VDP_loop
    dec a
    jp nz,copy_to_VDP_loop2
    ret

Van theNestruo

Master (192)

afbeelding van theNestruo

21-09-2020, 18:11

As source RAM address, target VRAM address, and size are previously known...

; LDIRVM the NAMTBL buffer
FAST_LDIRVM_NAMTBL:
; Sets the VRAM pointer
	ld	hl, NAMTBL
	call	SETWRT
; Initializes the OUTI loop
	ld	hl, namtbl_buffer
	ld	a, [VDP_DW]
	ld	b, 0 ; (ensures 256 bytes for the first bank)
	ld	c, a
; Uses 3x256 = 768 OUTIs to blit the NAMTBL buffer
.LOOP0:
	outi
	jp	nz, .LOOP0
.LOOP1:
	outi
	jp	nz, .LOOP1
.LOOP2:
	outi
	jp	nz, .LOOP2
	ret

(Note: this code has not been tested!)

Van albs_br

Master (145)

afbeelding van albs_br

21-09-2020, 19:58

Thanks for the codes, santiontanon and gdx. I will give a try later.

Pagina 1/3
| 2 | 3