$PAGINATE
$title(Arnold 5 test)
$subtitle(Test of the Sprite Colour Palette)
$copyright(Copyright (c) 1989, 1990, Amstrad plc.)
$pagewidth=131

        PUBLIC  SpritePaletteTest     ;called indirectly from TESTPACK
                                      ; out of MainMenuTable

        EXTERN  SetCursorPos            ;SUPPORT
        EXTERN  PrintStringHL           ;SUPPORT
        EXTERN  PrintAHex               ;SUPPORT
        EXTERN  KeyboardReadNoDelay     ;SUPPORT
        EXTERN  UnlockArn5              ;SUPPORT
        EXTERN  RelockArn5              ;SUPPORT

        EXTERN  .SpritePalMess          ;MESSAGES
        EXTERN  .SpritePalDefinitions   ;MESSAGES

        include "equates.inc"

        DEFSEG  TestCode, CLASS=CODE

        SEG     TestCode

;=================
SpritePaletteTest:
;=================
;
; This could be a real goody !, The idea is as follows:
;
; The screen is cleared (it doesn't matter which MODE it's in cos the
; sprites are mode indepedent).
;
; Sprite 0 and 1 are defined as two squares of 8 colour areas:
;
; 4000: 0000000011111111        4100: 2222222233333333
; 4010: 0000000011111111        4110: 2222222233333333
; 4020: 0000000011111111        4120: 2222222233333333
; 4030: 0000000011111111        4130: 2222222233333333
; 4040: 4444444455555555        4140: 6666666677777777
; 4050: 4444444455555555        4150: 6666666677777777
; 4060: 4444444455555555        4160: 6666666677777777
; 4070: 4444444455555555        4170: 6666666677777777
; 4080: 8888888899999999        4180: AAAAAAAABBBBBBBB
; 4090: 8888888899999999        4190: AAAAAAAABBBBBBBB
; 40A0: 8888888899999999        41A0: AAAAAAAABBBBBBBB
; 40B0: 8888888899999999        41B0: AAAAAAAABBBBBBBB
; 40C0: CCCCCCCCDDDDDDDD        41C0: EEEEEEEEFFFFFFFF
; 40D0: CCCCCCCCDDDDDDDD        41D0: EEEEEEEEFFFFFFFF
; 40E0: CCCCCCCCDDDDDDDD        41E0: EEEEEEEEFFFFFFFF
; 40F0: CCCCCCCCDDDDDDDD        41F0: EEEEEEEEFFFFFFFF
;
; They will always be positioned adjacent to one another with the magnification
; set to full (00Fh) so that they are twice as tall as wide. Together they will
; make a single square 32x16 showing the 16 colors.
;
; They are started in the top left and as they are moved up, down, left and
; right the sprite palette entries are varied so that the sprites change color
; as they are moved around the screen.
;

        ld      de,01400h
        call    SetCursorPos

        ld      hl,.SpritePalMess
        ld      b,1
        call    PrintStringHL

        call    UnlockArn5

        ld      hl,0
        ld      (6400h),hl              ;make background black

        ld      hl,.SpritePalDefinitions
        ld      de,._.SpriteData        ;where the sprites live
        ld      bc,0100h                ;enough for 2 sprites
_SpriteDefineLoop:
        ld      a,(hl)                  ;data is packed as 2 nybbles
        push    af
        and     0F0h                    ;get upper nybble
        srl     a
        srl     a
        srl     a
        srl     a                       ;move to lower nybble
        ld      (de),a                  ;set left pixel
        inc     de
        pop     af
        and     00Fh
        ld      (de),a                  ;then right
        inc     de
        inc     hl
        dec     bc
        ld      a,b
        or      c
        jr      nz,_SpriteDefineLoop

        ld      a,0Fh
        ld      (6004h),a               ;sprites to max mag.
        ld      (600Ch),a               ;and makes them appear

        ld      hl,256
        ld      (6000h),hl              ;sprite 0 X to (256,??)
        ld      hl,320
        ld      (6008h),hl              ;sprite 1 X to left of sprite 0

        ld      hl,48
        ld      (6002h),hl              ;sprite 0 Y to (??,48) (256,48)
        ld      (600Ah),hl              ;sprite 1 Y to (??,48) (320,48)

;
; The green part of the sprite palette entries are fixed to levels 1..16
;
        ld      hl,6423h                ;sprite color palette (green entry)
        ld      b,15
_SpritSetGreens:
        ld      a,16
        sub     b                       ;make 15..0 int0 1..16
        ld      (hl),a
        inc     hl
        inc     hl                      ;step on a word
        djnz    _SpritSetGreens

;
; The R and B parts are set as a function of the current X and Y
;
        call    _SpritSetPal

_SpritPalWaitKey:
        call    KeyboardReadNoDelay

        ld      b,200
_SpritSmallDelay:
        djnz    _SpritSmallDelay

        cp      66                      ;is it ESC = END
        jp      z,_SpritPalEndTest
        cp      76                      ;Joy 0 fire = END
        jp      z,_SpritPalEndTest
        cp      0                       ;keyboard up
        jr      z,_SpritUp
        cp      72                      ;Joystick up
        jr      z,_SpritUp
        cp      2                       ;keyboard down
        jr      z,_SpritDown
        cp      73                      ;joystick down
        jr      z,_SpritDOwn
        cp      1                       ;keyboard right
        jr      z,_SpritRight
        cp      75                      ;joystick right
        jr      z,_SpritRight
        cp      8                       ;keyboard left
        jr      z,_SpritLeft
        cp      74                      ;joystick left
        jr      z,_SpritLeft

        jr      _SpritPalWaitKey

_SpritUp:
        ld      hl,(6002h)              ;get sprite 0 Y
        ld      a,h
        or      l                       ;are we at scan 0 already ?
        jr      z,_SpritNoUp
        dec     hl
        ld      (6002h),hl              ;set new sprite 0 Y
        ld      (600Ah),hl              ;same for sprite 1
        call    _SpritSetPal
_SpritNoUp:
        jp      _SpritPalWaitKey

_SpritDown:
        ld      hl,(6002h)              ;sprite 0 Y
        ld      bc,-127
        add     hl,bc                   ;test if reached 200 yet
        ld      a,h
        or      l
        jr      z,_SpritNoDown
        ld      hl,(6002h)
        inc     hl
        ld      (6002h),hl
        ld      (600Ah),hl
        call    _SpritSetPal
_SpritNoDown:
        jp      _SpritPalWaitKey

_SpritLeft:
        ld      hl,(6000h)              ;sprite 0 X
        ld      a,h
        or      l
        jr      z,_SpritNoLeft
        dec     hl
        ld      (6000h),hl
        ld      bc,64
        add     hl,bc
        ld      (6008h),hl
        call    _SpritSetPal
_SpritNoLeft:
        jp      _SpritPalWaitKey

_SpritRight:
        ld      hl,(6000h)
        ld      bc,-511
        add     hl,bc
        ld      a,h
        or      l
        jr      z,_SpritNoRight
        ld      hl,(6000h)
        inc     hl
        ld      (6000h),hl
        ld      bc,64
        add     hl,bc
        ld      (6008h),hl
        call    _SpritSetPal
_SpritNoRight:
        jp      _SpritPalWaitKey


;============
_SpritSetPal:
;============
;
; Sprite 0s current X/Y location is used to program the sprite color palette
;
        ld      hl,(6000h)              ;get sprite 0 X posn.. Want this/32
                                        ;so *8 then take top byte.
        add     hl,hl
        add     hl,hl
        add     hl,hl
        ld      e,h                     ;bottom 4bits this is the blue value
        ld      a,(6002h)               ;now get Y coord
        sla     a                       ;bits 6-3 to 7-4
        and     0F0h                    ;clear bottom 4 bits
        ld      d,a                     ;save that for a sec.
        ld      a,e                     ;get blue byte
        and     00Fh                    ;just get bottom 4 bits
        or      d                       ;then add in red value at top
        ld      hl,6422h
        ld      b,15
_SpritSetRandB:
        ld      (hl),a
        inc     hl
        inc     hl
        djnz    _SpritSetRandB

        ld      de,1625h
        call    SetCursorPos

        ld      a,(6422h)               ;get red and blue
        and     00Fh                    ;just get blue bit
        call    PrintAHex

        ld      de,1725h
        call    SetCursorPos

        ld      a,(6422h)               ;get red and blue
        and     0F0h                    ;just get red bit
        srl     a
        srl     a
        srl     a
        srl     a                       ;move to lower nybble
        call    PrintAHex

        ret

;----------------
_SpritPalEndTest:
;----------------
;
        ld      a,0
        ld      (6004h),a               ;switch off sprite 0
        ld      (600Ch),a               ;switch off sprite 1

        call    RelockArn5

        ld      bc,7F00h
        out     (c),c                   ;point at PEN 0 palette entry

        ld      c,44h
        out     (c),c                   ;make back BLUE again

        ret

        END

