Difference between revisions of "Programming:CPC Plus Horizontal scroll"
From CPCWiki - THE Amstrad CPC encyclopedia!
m (credit box) |
|||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | <div style="border: 1px solid rgb(228, 222, 222); margin: 0px 0px 5px; padding: 0.5em 1em; background-color: rgb(249, 249, 249);"> | |
+ | <center> | ||
+ | |||
+ | '''''This article originally came from Kevin Thackers' archive at [http://www.cpctech.org.uk http://www.cpctech.org.uk].''''' </center></div> | ||
<pre> | <pre> | ||
Line 195: | Line 198: | ||
defb &ff,&00,&ff,&77,&b3,&51,&a8,&d4,&62,&39,&9c,&46,&2b,&15,&8a,&cd,&ee | defb &ff,&00,&ff,&77,&b3,&51,&a8,&d4,&62,&39,&9c,&46,&2b,&15,&8a,&cd,&ee | ||
</pre> | </pre> | ||
+ | |||
+ | User Fano has this to say: | ||
+ | There seems to have an error in "CPC Plus Horizontal scroll".It doesn't work properly on winape.Could you test it on a real CPC+ to be sure ? | ||
+ | |||
+ | I just wrote a little fix in case of (ln142-156) | ||
+ | |||
+ | <pre> | ||
+ | The horizontal pixel scroll offset is updated for every pixel. | ||
+ | ;; The CRTC scroll offset is updated for every CRTC character (every 16 pixels in mode 2 | ||
+ | ;; OR every 8 pixels in mode 1 OR every 4 pixels in mode 0). | ||
+ | |||
+ | scroll_speed EQU 2 ;; increments for pixel scrolling: | ||
+ | ;; 1 for mode 2 | ||
+ | ;; 2 for mode 1 | ||
+ | ;; 4 for mode 0 | ||
+ | |||
+ | |||
+ | .scroll_right | ||
+ | ;; get horizontal pixel scroll offset | ||
+ | ld a,(horz_pixel_offset) | ||
+ | sub scroll_speed | ||
+ | and &f | ||
+ | ld (horz_pixel_offset),a | ||
+ | cp 16-scroll_speed | ||
+ | ret nz</pre> | ||
+ | |||
+ | [[Category:CPC Plus]] | ||
+ | [[Category:Programming]] |
Latest revision as of 02:54, 27 January 2009
;; This example shows how to scroll the screen horizonatally using the ;; CPC+ "soft" hardware scroll. This scroll is smooth because it will scroll ;; a pixel 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,(horz_pixel_offset) ;; bits 3..0 define the horizontal pixel scroll offset ;; bits 6..4 define the vertical scanline scroll offset ;; 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_right ;; loop jp main_loop ;;---------------------------------------------------------------------- ;; adjust scroll parameters to scroll the screen right ;; ;; Each CRTC character is 2 bytes. ;; ;; In mode 0 there are 2 pixels per byte, there are 4 pixels for each CRTC character. ;; In mode 1 there are 4 pixels per byte, there are 8 pixels for each CRTC character. ;; In mode 2 there are 8 pixels per byte, there are 16 pixels for each CRTC character. ;; ;; The horizontal pixel scroll offset is defined for mode 2 resolution. ;; Pixels in mode 1 are twice the width of mode 2 pixels. ;; Pixels in mode 0 are four times the width of mode 2 pixels. ;; ;; The horizontal pixel scroll offset is updated for every pixel. ;; The CRTC scroll offset is updated for every CRTC character (every 16 pixels in mode 2 ;; OR every 8 pixels in mode 1 OR every 4 pixels in mode 0). .scroll_right ;; get horizontal pixel scroll offset ld a,(horz_pixel_offset) sub 1 ;; increments for pixel scrolling: ;; 1 for mode 2 ;; 2 for mode 1 ;; 4 for mode 0 and &f ld (horz_pixel_offset),a cp 0 ret nz ;; by now we have scrolled through: ;; - 16 pixels in mode 2 ;; - 8 pixels in mode 1 ;; - 4 pixels in mode 0 ;; get the crtc scroll offset ld hl,(scroll_offset) inc hl ;; update offset 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 15 which is the pixel offset ;; for the scroll .horz_pixel_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
User Fano has this to say: There seems to have an error in "CPC Plus Horizontal scroll".It doesn't work properly on winape.Could you test it on a real CPC+ to be sure ?
I just wrote a little fix in case of (ln142-156)
The horizontal pixel scroll offset is updated for every pixel. ;; The CRTC scroll offset is updated for every CRTC character (every 16 pixels in mode 2 ;; OR every 8 pixels in mode 1 OR every 4 pixels in mode 0). scroll_speed EQU 2 ;; increments for pixel scrolling: ;; 1 for mode 2 ;; 2 for mode 1 ;; 4 for mode 0 .scroll_right ;; get horizontal pixel scroll offset ld a,(horz_pixel_offset) sub scroll_speed and &f ld (horz_pixel_offset),a cp 16-scroll_speed ret nz