Programming:CPC Plus Vertical scroll
From CPCWiki - THE Amstrad CPC encyclopedia!
;; This example shows how to scroll the screen vertically using the ;; CPC+ "soft" hardware scroll. This scroll is smooth because it will scroll ;; a scanline at a time. ;; ;; This example will only work on the CPC+. ;; ;; The scroll is made by changing the start of the screen using the CRTC, ;; (which will scroll the screen vertically by the number of scanlines defined by register 9), ;; and a scan-line adjustment defined using the CPC+ "soft" hardware scroll register. ;; The location of this code is important. It must not be located ;; between &4000-&7fff. org &8000 nolist ;;---------------------------------------------------------------------- ;; 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 ;;---------------------------------------------------------------------- ;; install a interrupt handler ;; ;; We install our own interrupt handler for this reason: ;; - To stop the firmware interrupt from being executed, this will ;; ensure that our direct access to the hardware will not be interrupted ;; by the firmware, and that the values we write are not re-written by ;; the firmware. di ;; disable interrupts im 1 ;; set interrupt mode 1 (jump to &0038 when interrupt occurs) ld hl,&c9fb ;; EI:RET ld (&0038),hl ;; &0038 is executed ei ;;---------------------------------------------------------------------- ;; main loop .main_loop ;; wait for start of vsync. This test assumes that the start of the vsync ;; has not yet happened. ld b,&f5 .ml2 in a,(c) rra jr nc,ml2 ;; The vsync has just started, we can safely setup the scroll ;; without the display being effected. ;;----------------------------------------------------------------------- ;; update vertical scan-line scroll adjustment ;; page in ASIC ram ;; ASIC registers will be paged into memory range &4000-&7fff ld bc,&7fb8 out (c),c ;; get scan-line scroll adjustment ld a,(scanline_offset) ;; shift into bits required for writing to hardware add a,a add a,a add a,a add a,a ;; write to "soft" hardware scroll register of CPC+ ld (&6804),a ;; page out ASIC ram ld bc,&7fa0 out (c),c ;;----------------------------------------------------------------------- ;; update CRTC with scroll offset ld hl,(scroll_offset) ;; get scroll offset ld a,h or &30 ;; This defines the "base" of the screen in 16k units. ;; &00 -> screen uses &0000-&3fff ;; &10 -> screen uses &4000-&7fff ;; &20 -> screen uses &8000-&bfff ;; &30 -> screen uses &c000-&ffff ld h,a ld bc,&bc0c ;; select CRTC register 12 out (c),c inc b ;; B = &BD out (c),h ;; write to CRTC register 12 dec b inc c ;; BC = &BC0D out (c),c ;; select CRTC register 13 inc b out (c),l ;; write to CRTC register 13 ;;---------------------------------------------------------------------- ;; we need to wait long enough for the VSYNC signal to finish, so that the ;; test at the beginning of this loop will synchronise with the *start* of the ;; vsync. ;; this first HALT will catch the interrupt that occurs two scanlines from ;; the start of the VSYNC, the second will delay a furthur 52 scanlines. The maximum ;; duration for the VSYNC is 16 scanlines. halt halt ;; update the scroll ready for the next update of the display call scroll_up ;; loop jp main_loop ;;---------------------------------------------------------------------- ;; adjust scroll parameters to scroll the screen up ;; ;; Each CRTC character is 8 scanlines tall, therefore the CRTC scroll offset ;; will scroll the screen up by 8 scanlines at a time. ;; ;; We use the CPC+ "soft" hardware scroll to set the scanline offset within ;; each CRTC character. ;; ;; The CPC+ "soft" hardware scroll is updated for every scanlines. ;; The CRTC scroll offset is only updated once for every 8 scanlines. .scroll_up ;; get scanline offset ld a,(scanline_offset) inc a ;; ensure it is in range and &7 ;; store scanline offset ld (scanline_offset),a cp 0 ret nz ;; by now we have scrolled through 8 scanlines using the CPC+ "soft" hardware ;; scroll, now we need to update the screen start address ;; get the crtc scroll offset ld hl,(scroll_offset) ld bc,40 ;; this is the same as the value written to CRTC register 1 ;; and defines the width of the display in CRTC characters. add hl,bc ld a,h ;; ensure the scroll offset is in the range &300-&3ff and &3 ld h,a ;; store the crtc scroll offset ld (scroll_offset),hl ret ;;---------------------------------------------------------------------- ;; scroll offset of the screen to be written to CRTC register 12 and 13 ;; This value is defined in "CRTC" characters. .scroll_offset defw 0 ;;---------------------------------------------------------------------- ;; holds a number between 0 and 7 which is the scanline adjustment ;; for the scroll .scanline_offset defb 0 ;;---------------------------------------------------------------------- ;; 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