Which of these is faster?

Page 1/3
| 2 | 3

By albs_br

Master (147)

albs_br's picture

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.

Login or register to post comments

By Grauw

Ascended (9340)

Grauw's picture

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.

By albs_br

Master (147)

albs_br's picture

20-09-2020, 19:09

768 bytes, all the names table.

By PingPong

Prophet (3555)

PingPong's picture

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 ????

By santiontanon

Paragon (1092)

santiontanon's picture

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.

By albs_br

Master (147)

albs_br's picture

21-09-2020, 05:46

Any code sample? 2 times faster is a lot.

By salutte

Expert (108)

salutte's picture

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

By gdx

Prophet (3748)

gdx's picture

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

By santiontanon

Paragon (1092)

santiontanon's picture

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

By theNestruo

Master (198)

theNestruo's picture

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!)

By albs_br

Master (147)

albs_br's picture

21-09-2020, 19:58

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

Page 1/3
| 2 | 3