;; Pixel by pixel scrolling 

org &8000
nolist

scr_set_mode equ &bc0e
txt_output equ &bb5a
km_read_char equ &bb09

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

ld a,2
call scr_set_mode

ld bc,24*80
ld d,' '
l2:
inc d
ld a,d
cp &7f
jr nz,no_char_reset
ld d,' '
no_char_reset:
ld a,d
call txt_output
dec bc
ld a,b
or c
jr nz,l2

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

loop1:
ld b,&f5
l1:
in a,(c)
rra
jr nc,l1

call set_scroll

call check_keys


halt
halt
halt
jp loop1

set_scroll:
di
;; enable asic ram
ld bc,&7fb8
out (c),c
;; write scroll values to asic ram
ld a,(hscroll)
ld c,a
ld a,(vscroll)
add a,a
add a,a
add a,a
add a,a
or c
or &80			;; mask right side
ld (&6804),a

;; disable asic ram
ld bc,&7fa0
out (c),c

;; write crtc values
ld bc,&bc0c
out (c),c
ld hl,(scrl2)
inc b
out (c),h
ld bc,&bc0d
out (c),c
inc b
out (c),l
ei
ret


;; check if a key has been pressed and perform action if it has
check_keys:
call km_read_char
ret nc
;; A = ascii char of key pressed
;; we check for both upper and lower case chars
cp '8'
jp z,scroll_up
cp '2'
jp z,scroll_down
cp '4'
jp z,scroll_left
cp '6'
jp z,scroll_right
cp '7'
jp z,scroll_up_left
cp '9'
jp z,scroll_up_right
cp '1'
jp z,scroll_down_left
cp '3'
jp z,scroll_down_right

ret


scroll_down_right:
call scroll_down
call scroll_right
ret


scroll_down_left:
call scroll_down
call scroll_left
ret


scroll_up_left:
call scroll_up
call scroll_left
ret

scroll_up_right:
call scroll_up
call scroll_right
ret


scroll_left:
ld a,(hscroll)

;;add a,1					;; mode 2
;;add a,2					;; mode 1
sub 4					;; mode 0
jp p,scroll_right2
and &f
ld (hscroll),a

ld hl,(scrl2)
inc hl
ld a,h
and &3
or &30
ld h,a
ld (scrl2),hl
ret
scroll_right2:
and &f
ld (hscroll),a
ret


scroll_right:
ld a,(hscroll)
;;sub a,1					;; mode 2
;;sub a,2					;; mode 1
add a,4					;; mode 0
cp 16
jp c,scroll_left2
and &f
ld (hscroll),a
ld hl,(scrl2)
dec hl
ld a,h
and &3
or &30
ld h,a
ld (scrl2),hl
ret
scroll_left2:
and &f
ld (hscroll),a
ret

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

;; update these seperate of display
scroll_up:
ld a,(vscroll)
inc a
and &7
ld (vscroll),a
or a
ret nz

ld hl,(scrl2)
ld bc,40
add hl,bc
ld a,h
and &3
or &30
ld h,a
ld (scrl2),hl
ret

;; update these seperate of display
scroll_down:
ld a,(vscroll)
dec a
and &7
ld (vscroll),a
cp &7
ret nz

ld hl,(scrl2)
or a
ld bc,40
sbc hl,bc
ld a,h
and &3
or &30
ld h,a
ld (scrl2),hl
ret

vscroll:
defb 0

hscroll:
defb 0

scrl2:
defw &3000


;;----------------------------------------------------------
;; 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