Es preferible usar los comandos de VRAM
Mi forma de hacerlo es con una rutina que lee un buffer de datos que tengo en RAM que seteo con los datos que necesita y luego lanzo la rutina que carga esos datos a la VRAM y ejecuto el comando.
Te pongo la rutina y un ejemplo.
Esta es la rutina para hacer comandos a la VRAM:
; //////////////////////////////////////
; ///////// _VDPCMD ///////////////////
; //////////////////////////////////////
; Ejecuta un comando al VDP con datos ordenados en puntero HL
; HL = Puntero de datos de comando
; ( SXL, SXH, SYL, SYH, DXL, DXH, DYL,DYH,
; INCXL,INCXH,INCYL,INCYH, COLO, ARG, CMD)
; Toca : BC,HL
_VDPCMD:
; Bucle de espera a bit CE
call WAIT_CE
ld A,20h ; Comando comença al Reg 20h
out [099h],A
ld A,80h+11h ; Reg 11h Ini. per enviar bytes seguits a Reg Seguits
out [099h],A
ld B,15
ld C,09Bh ; Port VDP per indirecte
@@LOOP:
outi
ld A,B
cp 0
jp nz,@@LOOP
; Bucle de espera a bit CE
call WAIT_CE
ret
; //////////////////////////////////////
; ///////// WAIT_CE ///////////////////
; //////////////////////////////////////
; Espera a que el bit 0 del R2 de Status estigui a 0 per començar o acabar _VDPCOM
WAIT_CE:
ld A,02h
out [099h],A
ld A,80h+0Fh ; Llegim el Reg 02h posant 2 a Reg 0Fh
out [099h],A
in A,[099h]
and 1
jp nz,WAIT_CE
; Abans de marxar recoloquem el REG STATUS 0 a Reg 0Fh
ld A,00h
out [099h],A
ld A,80h+0Fh
out [099h],A
ret
Y en RAM tengo este array de datos declarado. Verás que está comentado lo que significa cada byte:
VDPCOMDATA: .ds 15 ; 0: Source XL
; 1: Source XH [Normal a cero si SCR 5]
; 2: Source YL
; 3: Source YH [Page 0-3]
; 4: Destiny XL
; 5: Destiny XH [Normal a cero si SCR 5]
; 6: Destiny YL
; 7: Destiny YH [Page 0-3]
; 8: Width XL
; 9: Width XH [Normal a cero si SCR5]
;10: Height YL
;11: Height YH [Normal a cero si SCR5]
;12: Color Register
;13: Arguments [Habitual 000000-EQ-MAJ = 00h para VRAM<->VRAM]
;14: Comando a ejecutar
; HighSpeed CMD: (Que conozco)
; 000h: Stop
; 0D0h: Copy Rectangle VRAM->VRAM
Y esto es lo que haría en el código del juego si quiero copiar cachos de pantalla.
ld IX,VDPCOMDATA
ld [IX+0],
;....( setear todos los valores que corresponden [desde IX+0 a IX+14] con lo que quiero hacer, coordenadas y tamaños)...
ld [IX+14],0D0h ;CMD 0D0h HMMM Copy Rectangle
; Lanzar el comando
ld HL,VDPCOMDATA ; Envio CMD a la VRAM
; Aqui realiza los push que necesites guardar (ojo que el siguiente CALL toca registros)
call _VDPCMD
; Recupera datos anteriores con POP si hiciera falta.
Mirate :
http://problemkaputt.de/portar.htm#vdpregisters20h2ehmsx2videocommandregistersPara entender un poco que hace cada dato que se envia a los registros.
Te recomiendo tambien la lectura del PDF yamaha_v9938_MSX2.pdf en la página 54 hacia delante. Especialmente la página 62 que es el comando que te interesa de copiar de VRAM a VRAM
http://www.textfiles.com/bitsavers/pdf/yamaha/Yamaha_V9938_MSX-Video_Technical_Data_Book_Aug85.pdf