;; This example shows how
;; to cut sprites where a panel is displayed.
;; Panel is displayed using Plus split screen
;;
;; sprites are cut by writing a mag value that disables them
org &8000

start:
;;--------------------------------------------------
;; STEP 1 - Unlock CPC+ additional features
;; unlock asic to gain access to asic registers

di
ld b,&bc
ld hl,sequence
ld e,17
seq:
ld a,(hl)
out (c),a
inc hl
dec e
jr nz,seq
ei

;; put something where main screen will be
ld hl,&c000
ld e,l
ld d,h
inc de
ld (hl),&aa
ld bc,&3fff
ldir

;; put something where split will be
ld hl,&4000
ld e,l
ld d,h
inc de
ld (hl),&ff
ld bc,&3fff
ldir


;;--------------------------------------------------
;; STEP 2 - Setup sprite pixel data
;;
;; The ASIC has internal "RAM" used to store the sprite pixel
;; data. If you want to change the pixel data for a sprite
;; then you need to copy new data into the internal "RAM".

;; page-in asic registers to &4000-&7fff
ld bc,&7fb8
out (c),c

;; write same pixel data to all sprites
ld b,16
ld hl,sprite_pixel_data

;; address of sprite 0 pixel data
;; sprite 0 pixel data is in the range &4000-&4100
ld de,&4000

;; In this loop, HL will be preserved.
;; B will count down for each sprite
;; DE will increase for each sprite
write_gfx:
push hl
push bc
;; length of pixel data for a single sprite (16x16 = 256)
ld bc,&100
ldir
pop bc
pop hl
djnz write_gfx

;;--------------------------------------------------
;; STEP 3 - Setup sprite palette
;;
;; The sprites use a single 15 entry sprite palette.
;; pen 0 is ALWAYS transparent.
;;
;; The sprite palette is different to the screen palette.

;; copy colours into ASIC sprite palette registers
ld hl,sprite_colours
ld de,&6422
ld bc,15*2
ldir

;;--------------------------------------------------
;; STEP 4 - Setup sprite properties
;;
;; Each sprite has properties which define the x,y coordinates 
;; and x,y magnification.

di
im 1							;; interrupt mode 1
ld a,&c3
ld hl,interrupt1				;; this changes as we execute interrupts
ld (&0038),a
ld (&0039),hl

;; set initial raster interrupt line; this will change
ld a,200
ld (&6800),a

;; set screen split at line 200; this is static
ld a,200
ld (&6801),a

;; screen split address; this is static
;; uses CRTC style memory addresses
ld hl,&1000
ld a,h
ld (&6802),a
ld a,l
ld (&6803),a

;; move screen up so we have space for panel
ld bc,&bc07
out (c),c
ld bc,&bd00+35
out (c),c

;; make space for panel (8 lines greater than normal screen)
ld bc,&bc06
out (c),c
ld bc,&bd00+25+8
out (c),c

ei

;; setup sprite x coordinates
ld hl,&6000	;; sprite 0 register location (+0 for X)
ld de,0		;; initial x coordinate
ld bc,16	 ;; x coordinate increment
ld a,16			;; number of sprites to setup
set_x:
push af
;; write x
ld (hl),e
inc l
ld (hl),d
;; add to get to next sprite info
ld a,l
add a,7
ld l,a
;; update x coordinate
ex de,hl
add hl,bc
ex de,hl
pop af
dec a
jr nz,set_x

ld hl,&6002	;; sprite 0 register location (+2 for Y)
ld de,100		;; initial y coordinate
ld bc,16	 ;; y coordinate increment
ld a,16			;; number of sprites to setup
set_y:
push af
;; write y
ld (hl),e
inc l
ld (hl),d
;; add to get to next sprite info
ld a,l
add a,7
ld l,a
;; update y coordinate
ex de,hl
add hl,bc
ex de,hl
pop af
dec a
jr nz,set_y

;; we have interrupts running so we loop to see them happening.
loop:
jp loop

;;--------------------------------------------------

;; this interrupt occurs at screen split location
interrupt1:
push af
push bc
push hl

;; disable all sprites to cut them at the position of the panel
call disable_sprites

;; next raster interrupt after panel
ld a,250
ld (&6800),a

;; interrupt handler
ld hl,interrupt2
ld (&0039),hl
pop hl
pop bc
pop af
ei
reti

;;--------------------------------------------------

interrupt2:
push af
push bc
push hl
;; restore sprite enables
call enable_sprites
;; where panel is
ld a,200
ld (&6800),a
;; back to interrupt 1 again
ld hl,interrupt1
ld (&0039),hl
pop hl
pop bc
pop af
ei
reti




;;--------------------------------------------------

enable_sprites:
ld c,%0101			;; x1 in X, x1 in Y, mode 2 resolution
jr en_dis_sprites

;;--------------------------------------------------

disable_sprites:
ld c,0				;; disable
jr en_dis_sprites

;;--------------------------------------------------

en_dis_sprites:
ld hl,&6004		;; mag for sprite 0
ld b,16
es1:
ld (hl),c		;; write value into mag
ld a,l			;; update pointer for next sprite mag
add a,8
ld l,a
djnz es1
ret

;;--------------------------------------------------
;; - there is two bytes per colour.
;; - these are stored in a form that can be written direct 
;; to the CPC+ colour palette registers (i.e. xGRB)
;; - pen 0 is always transparent and doesn't have a entry
;; in the CPC+ palette

sprite_colours:
defw &0111			;; colour for sprite pen 1
defw &0222			;; colour for sprite pen 2
defw &0333			;; colour for sprite pen 3
defw &0444			;; colour for sprite pen 4
defw &0555			;; colour for sprite pen 5
defw &0666			;; colour for sprite pen 6
defw &0777			;; colour for sprite pen 7
defw &0888			;; colour for sprite pen 8
defw &0999			;; colour for sprite pen 9
defw &0aaa			;; colour for sprite pen 10
defw &0bbb			;; colour for sprite pen 11
defw &0ccc			;; colour for sprite pen 12
defw &0ddd			;; colour for sprite pen 13
defw &0eee			;; colour for sprite pen 14
defw &0fff			;; colour for sprite pen 15

;;---------------------------------------------
;; - there is one pixel per byte (bits 3..0 of each byte define the palette index for this pixel)
;; - these bytes are stored in a form that can be written direct to the ASIC
;; sprite pixel data
sprite_pixel_data:
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 0
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 1
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 2
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 3
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 4
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 5
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 6
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 7
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 8
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 9
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 10
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 11
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 12
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 13
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 14
defb &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a,&0b,&0c,&0d,&0e,&0f,&01		;; line 15

;;----------------------------------------------------------
;; this is the sequence to unlock the ASIC extra features
sequence:
defb &ff,&00,&ff,&77,&b3,&51,&a8,&d4,&62,&39,&9c,&46,&2b,&15,&8a,&cd,&ee

end start