CLSLayer2DMA
Quote from Mikele on 27th December 2018, 5:23 pmAnother method to clear Layer2 screen. This time by using DMA.
sub CLSLayer2DMAFast(dest as uinteger, color as ubyte, length as uinteger)
asm
push hl
push ix; first part
ld e,3
ld a,1
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
; second part
ld e,2
;ld a,1
;add a,$40
ld a,$41
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
;third part
ld e,1
;ld a,1
;add a,$80
ld a,$81
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
; DMAFill (0, col, 64*256); exit part
ld e,1
ld bc, LAYER2_ACCESS_PORT
ld a,2
out (c),ajp EndDMAFill2
DMAFill2:
di
ld (FillValue2),a
ld (DMACDest2),de
ld (DMACLength2),bc
ld hl,DMACCode2
ld b,DMACCode_Len2
ld c,Z80_DMA_PORT_DATAGEAR ;ZXN_DMA_PORT
otir
ei
retFillValue2:
db 0
DMACCode2:
db DMA_DISABLEdb %01111101
DMACSource2:
dw FillValue2
DMACLength2:
dw 0
db %00100100,%00010000,%10101101 ; %00010000
DMACDest2:
dw 0
db DMA_LOAD,DMA_ENABLE
DMACCode_Len2 equ $-DMACCode2EndDMAFill2:
pop ix
pop hlend asm
end sub
Still I don't know how to clear screen with a proper timing so short blink is visible during the operation.
You can test it with modified standard Boriel example:
#include <nextlib.bas>
5 DIM x, y as ubyte
7 DIM s as UInteger
8 dim color1 as ubyte
9 border 0
10 cls: CLSLayer2DMAFast(0, 0, 64*256): LET x=128: LET y=87: LET s=1: randomize 1 : randomize : let color1=rnd*255
20 LET s=s+1: IF x>0 AND x<255 AND y>0 AND y<175 THEN Plot256(x,y,color1): END IF
22 IF s=2048 THEN pause 1: randomize : CLSLayer2DMAFast(0, 0, 64*256): LET x=128: LET y=87: LET s=1:RANDOMIZE 1: RANDOMIZE rnd*50: Randomize: let color1=rnd*255: END IF
25 ON RND * 4 GOTO 30, 40, 50, 6030 LET x=x+2: color1=color1+1:GO TO 20
40 LET x=x-2: color1=color1-1:GO TO 20
50 LET y=y+2: color1=color1+1:GO TO 20
60 LET y=y-2: color1=color1-1:GO TO 20SUB Plot256(x as ubyte, y as ubyte, color as ubyte)
SUB CLSLayer2DMAFast(dest as uinteger, color as ubyte, length as uinteger)https://www.youtube.com/watch?v=ofgWFYswmIY
To have it working you need to add to the first part of nextlib.bas library (the very first "asm" part) these definitions:
Z80_DMA_PORT_DATAGEAR equ $6b
Z80_DMA_PORT_MB02 equ $0bDMA_RESET equ $c3
DMA_RESET_PORT_A_TIMING equ $c7
DMA_RESET_PORT_B_TIMING equ $cb
DMA_LOAD equ $cf
DMA_CONTINUE equ $d3
DMA_DISABLE_INTERUPTS equ $af
DMA_ENABLE_INTERUPTS equ $ab
DMA_RESET_DISABLE_INTERUPTS equ $a3
DMA_ENABLE_AFTER_RETI equ $b7
DMA_READ_STATUS_BYTE equ $bf
DMA_REINIT_STATUS_BYTE equ $8b
DMA_START_READ_SEQUENCE equ $a7
DMA_FORCE_READY equ $b3
DMA_DISABLE equ $83
DMA_ENABLE equ $87
DMA_WRITE_REGISTER_COMMAND equ $bb
Another method to clear Layer2 screen. This time by using DMA.
sub CLSLayer2DMAFast(dest as uinteger, color as ubyte, length as uinteger)
asm
push hl
push ix; first part
ld e,3
ld a,1
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
; second part
ld e,2
;ld a,1
;add a,$40
ld a,$41
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
;third part
ld e,1
;ld a,1
;add a,$80
ld a,$81
ld bc, LAYER2_ACCESS_PORT
out (c),ald a, (IX+7)
LD e, (IX+4)
LD d, (IX+5)
LD c, (IX+8)
LD b, (IX+9)call DMAFill2
; DMAFill (0, col, 64*256); exit part
ld e,1
ld bc, LAYER2_ACCESS_PORT
ld a,2
out (c),ajp EndDMAFill2
DMAFill2:
di
ld (FillValue2),a
ld (DMACDest2),de
ld (DMACLength2),bc
ld hl,DMACCode2
ld b,DMACCode_Len2
ld c,Z80_DMA_PORT_DATAGEAR ;ZXN_DMA_PORT
otir
ei
retFillValue2:
db 0
DMACCode2:
db DMA_DISABLEdb %01111101
DMACSource2:
dw FillValue2
DMACLength2:
dw 0
db %00100100,%00010000,%10101101 ; %00010000
DMACDest2:
dw 0
db DMA_LOAD,DMA_ENABLE
DMACCode_Len2 equ $-DMACCode2EndDMAFill2:
pop ix
pop hlend asm
end sub
Still I don't know how to clear screen with a proper timing so short blink is visible during the operation.
You can test it with modified standard Boriel example:
#include <nextlib.bas>
5 DIM x, y as ubyte
7 DIM s as UInteger
8 dim color1 as ubyte
9 border 0
10 cls: CLSLayer2DMAFast(0, 0, 64*256): LET x=128: LET y=87: LET s=1: randomize 1 : randomize : let color1=rnd*255
20 LET s=s+1: IF x>0 AND x<255 AND y>0 AND y<175 THEN Plot256(x,y,color1): END IF
22 IF s=2048 THEN pause 1: randomize : CLSLayer2DMAFast(0, 0, 64*256): LET x=128: LET y=87: LET s=1:RANDOMIZE 1: RANDOMIZE rnd*50: Randomize: let color1=rnd*255: END IF
25 ON RND * 4 GOTO 30, 40, 50, 6030 LET x=x+2: color1=color1+1:GO TO 20
40 LET x=x-2: color1=color1-1:GO TO 20
50 LET y=y+2: color1=color1+1:GO TO 20
60 LET y=y-2: color1=color1-1:GO TO 20SUB Plot256(x as ubyte, y as ubyte, color as ubyte)
SUB CLSLayer2DMAFast(dest as uinteger, color as ubyte, length as uinteger)
https://www.youtube.com/watch?v=ofgWFYswmIY
To have it working you need to add to the first part of nextlib.bas library (the very first "asm" part) these definitions:
Z80_DMA_PORT_DATAGEAR equ $6b
Z80_DMA_PORT_MB02 equ $0bDMA_RESET equ $c3
DMA_RESET_PORT_A_TIMING equ $c7
DMA_RESET_PORT_B_TIMING equ $cb
DMA_LOAD equ $cf
DMA_CONTINUE equ $d3
DMA_DISABLE_INTERUPTS equ $af
DMA_ENABLE_INTERUPTS equ $ab
DMA_RESET_DISABLE_INTERUPTS equ $a3
DMA_ENABLE_AFTER_RETI equ $b7
DMA_READ_STATUS_BYTE equ $bf
DMA_REINIT_STATUS_BYTE equ $8b
DMA_START_READ_SEQUENCE equ $a7
DMA_FORCE_READY equ $b3
DMA_DISABLE equ $83
DMA_ENABLE equ $87
DMA_WRITE_REGISTER_COMMAND equ $bb