Sprite Early Clock Bit

By Chilly Willy

Expert (97)

Chilly Willy's picture

22-10-2022, 01:33

Has anyone here successfully programmed their sprites in Z80 Assembly using the 9918/28 where the sprites went off the left side of the screen without a hitch?

If so, please point me to examples.

CW

Login or register to post comments

By SjaaQ

Champion (369)

SjaaQ's picture

22-10-2022, 09:56

f_displayPointer:	PROC
;Draws the spritepointer
;Called by the interrupt handler
;Disables interrupts
	;ld	ix,v_spriteAttr
	ld	hl,(v_hid_POS)
	ld	de,(v_pointer_POS)
	call	mt_rst20
	ret	z
	ld	(v_pointer_POS),hl

	ld	a,(v_pointer_Sprite)
	ld	d,a
	ld	e,1
	ld	a,15
	ex	af,af'
	ld	a,(v_hid_POS+0)	;X
	ld	bc,256*218+q_vdp98	;Y-HIDE,	vdp
left:
	ld	hl,32-5		;X	offset
	cp	128+32
	jr	c,draw
right:
	ld	hl,-5
draw:
	add	a,l		;add	offset
	ld	h,a		;X
	ld	a,(v_hid_POS+1)	;Y
	ld	l,a		;Y
	push	de
;	xor	a
	ld	de,q_vdp_spriteAttribute
	call	f_setVramAddressWrite
	pop	de

	ld	a,(v_hid_POS+0)	;X
	cp	128+32
	call	c,show	;Y
	call	c,shiftOn
	call	nc,hide

	out	(c),h	;X
	nop
	nop
	nop
	out	(c),d	;ID
	nop
	nop
	nop
	out	(c),e	;1
	nop
	nop
	nop
	call	c,show	;Y
	call	nc,hide

	out	(c),h	;X
	inc	d
	inc	d
	inc	d
	inc	d
	out	(c),d	;ID
	ex	af,af'
	nop
	nop
	nop
	out	(c),a	;15
	ex	af,af'

	call	nc,show	;Y
	call	c,hide
	call	c,shiftOff
	out	(c),h	;X
	inc	d
	inc	d
	inc	d
	inc	d
	out	(c),d	;ID
	nop
	nop
	nop
	out	(c),e	;1
	nop
	nop
	nop
	call	nc,show	;Y
	call	c,hide
	nop
	nop
	nop
	out	(c),h	;X
	inc	d
	inc	d
	inc	d
	inc	d
	out	(c),d	;ID
	ex	af,af'
	nop
	nop
	nop
	out	(c),a	;15
	ex	af,af'

	ld	a,216	;EOF
	out	(c),a
	ret
show:
	out	(c),l
	nop
	nop
	nop
	ret
hide:
	out	(c),b
	nop
	nop
	nop
	ret
shiftOn:
	set	7,e
	ex	af,af'
	set	7,a
	ex	af,af'
	ret
shiftOff:
	res	7,e
	ex	af,af'
	res	7,a
	ex	af,af'
	ret
	ENDP

Taken from the NOP Modplayer GUI (MSX1). I has a sprite defined with and without the EC bit set. When I cross X = 128 I put the one of them in the border and swap it out with the other one (and fix the display position).

By thegeps

Paragon (1153)

thegeps's picture

22-10-2022, 23:54

Used them in all of my games. It isn't too hard to implement ecb use. Simply check x coordinate and when ecb has to be set add 128 to the color on sat related address. When doing so the sprite will be moved 32 pixel to the right, so you need to accordingly adjust the sprite x coordinate (also for collison check, if done by coordinates comparison)

By Chilly Willy

Expert (97)

Chilly Willy's picture

23-10-2022, 20:30

everyone gets thumbs up for all your help

By thegeps

Paragon (1153)

thegeps's picture

25-10-2022, 18:33

here's how I manage ecb in Shadow of the Pig:

        ld     hl,ramsat                        ;an aligned table 128 bytes long to manage sprites attributes in RAM
check_enemy1:
	ld	a,(enemy1_on_screen)    ;check if first bat is on screen 
	and	a
	jp	z,check_enemy2             ;if not check for next enemy
	ld	l,25                                ;point to bat x coordinate (this is like "ld hl, ramsat+25")
	ld	a,(bat1_speed)               ;load speed value in register a
	add	a,(hl)                             ;add it to current x coordinate (it is a negative value, bats fly to left)
	and	a                                   ;check if the value obtained is equal to 0 
	jp	nz,set_enemy1_x           ;if no jump to update the bat x coordinate
	ld	l,27                               ;if we reached the 0 value point to bat color byte (ramsat+27)
	ld	a,(hl)                             ;put it in register a
	and	%10000000                     ;check if ecb is already set
	jp	nz,reset_enemy1           ;if so then we have completed the path and bat can be removed, jump there
	ld	(hl),129                         ;else we have reached the left border of the screen and we need to set ecb for smooth
                                                    ;exit to left. 129=128 (ecb set)+1 (black color)
	ld	l,25                               ;point again to 1st bat x coordinate
	ld	a,32                              ;set register a value as 32 (to "fix" sprite's x coordinate, as you know when ecb is set
                                                    ;the sprite is moved 32 pixels to the left so putting it at 32 it seens to "normal "0 x
                                                    ;coordinate" but can be moved under the border)
	jp	set_enemy1_x               ;jump to write this value in our table
reset_enemy1:
	ld	(hl),1                            ;here we reset the sprite setting color as black (we jumped here from ecb check so hl
                                                    ;already points to 1st bat color byte
	xor	a                                  ;reset enemy on screen variable (so we will know to do nothing on this object)
	ld	(enemy1_on_screen),a
	ld	l,24                              ;ld hl,ramsat+24 (y coordinate)
	ld	(hl),209                        ;sprite out of screen
	jp	check_enemy2              ;go to next bat
set_enemy1_x:
	ld	(hl),a                            ;finally write our just obtained/fixed x coordinate in our table
	inc	l                                   ;point to next byte (bat shape)
	ld	a,(hl)                            ;its value in register a
	add	a,4                                ;add 4 to reach next animation frame value
	cp	136                               ;check if we reached the last (well the one after the last) animation frame value
	jp	nz,update_enemy1_anim   ;if no go and write obtained value
	ld	a,112                            ;else set first animation frame value
update_enemy1_anim:
	ld	(hl),a                            ;write shape value
check_enemy2:                             ;next enemy

hope this will help Smile
edit: sorry for bad comments' text alignement, but I copied the cody (that it isn't commented yet) and commented it here inserting spaces by hand