1IF !__CPU_GBZ80__ & !__CPU_INTEL__ 2 SECTION code_graphics 3 PUBLIC scroll_left 4 5 EXTERN pixeladdress 6 EXTERN leftbitmask, rightbitmask 7 8; 9; $Id: lftscrol.asm,v 1.6 2016-04-13 21:09:09 dom Exp $ 10; 11 12; *********************************************************************** 13; 14; Scroll specified graphics area leftward horisontally 15; 16; Design & programming by Gunther Strube, Copyright (C) InterLogic 1995 17; 18; IN: HL = (x,y) 19; BC = (width,heigth) 20; A = scroll distance, 1 to 8 pixels. 21; 22; Variables on stack; ix pointer to base of variables: 23; (ix+0) scroll distance 24; (ix+1) y 25; (ix+2) height 26; (ix+3,4) adr0 27; (ix+5,6) adr1 28; (ix+7) bitmask0 bitmask for leftmost byte of pixel row 29; (ix+8) bitmask1 bitmask for rightmost byte of pixel row 30; (ix+9) rowbytes number of bytes in pixel row to scroll 31; (ix+10) lastbyte 32; 33; OUT: None. (graphics area is scrolled) 34; 35; Registers changed after return: 36; ......../IXIY same 37; AFBCDEHL/.... different 38; 39.scroll_left push ix 40 push iy 41 ld de,0 42 ex de,hl 43 add hl,sp 44 ex de,hl 45 ld ix,-11 46 add ix,sp ; ix points at base of variables 47 ld sp,ix ; local variable area created 48 push de ; remember pointer to original ix, iy 49 50 ld (ix+0),a ; remember scroll distance 51 ld (ix+1),l ; remember y 52 ld (ix+2),c ; remember height 53 push bc 54 call pixeladdress ; adr0, bitpos0 = PixelAddress(x,y) 55 ld (ix+3),e 56 ld (ix+4),d 57 call leftbitmask 58 ld (ix+7),a ; bitmask0 = LeftBitMask(bitpos0) 59 pop bc 60 ld a,h 61 add a,b 62 dec a 63 ld h,a 64 push de 65 call pixeladdress ; adr1, bitpos1 = PixelAddress(x+width-1,y) 66 ld (ix+5),e 67 ld (ix+6),d 68 call rightbitmask 69 ld (ix+8),a ; bitmask1 = LeftBitMask(bitpos0) 70 pop hl 71 ex de,hl 72 cp a 73 sbc hl,de ; (adr1-adr0) 74 srl l 75 srl l 76 srl l 77 ld (ix+9),l ; rowbytes = (adr1-adr0) div 8, no. of bytes in row 78 ; 0 means that scroll area is within same address 79 ; FOR h = 1 TO height 80.scroll_l_height ld iy,0 ; offset=0 81 ld e,(ix+3) 82 ld d,(ix+4) ; DE = adr0 83 ld a,(de) ; byte = (adr0) 84 ld h,a 85 ld l,0 86 xor a 87 cp (ix+9) ; if rowbytes = 0 88 jr nz, scrollrow_left ; scroll area is within one byte... 89 ld b,(ix+0) 90 call scrollleft ; byte = Scrollleft(byte,0,scrolldist) 91 ld b,h 92 ld l,(ix+7) 93 ld a,l 94 cpl ; NOT bitmask0 95 and b 96 ld b,a ; byte = byte AND (NOT bitmask0) 97 ld h,(ix+8) 98 ld a,h 99 cpl ; NOT bitmask1 100 and b ; byte = byte AND (NOT bitmask1) 101 ld b,a 102 ld a,(de) 103 and l 104 ld l,a ; byte0 = (adr0) AND bitmask0 105 ld a,(de) 106 and h ; byte1 = (adr0) AND bitmask1 107 or b ; byte = byte OR byte1 108 or l ; byte = byte OR byte0 109 ld (de),a ; (adr0) = byte 110 jr leftscroll_nextrow 111.scrollrow_left ; else 112 push de ; scroll area is defined as row of bytes 113 ld e,(ix+5) 114 ld d,(ix+6) 115 ld a,(de) 116 ld (ix+10),a ; lastbyte = (adr1) 117 ld b,a 118 ld a,(ix+8) ; bitmask1 119 cpl 120 and b ; (adr1) = (adr1) AND (NOT bitmask1) 121 ld (de),a ; - preserve only bits within scroll area 122 pop de ; - the other bits are restored after scroll 123 push iy 124 add iy,de 125 ld l,(iy+8) ; (adr0+8) 126 pop iy 127 128 ld b,(ix+0) 129 call scrollleft ; byte = Scrollleft(byte,(adr0+8),scrolldist) 130 ld b,h 131 ld a,(ix+7) 132 cpl ; NOT bitmask0 133 and b 134 ld b,a ; byte = byte AND (NOT bitmask0) 135 ld c,(ix+7) ; bitmask0 136 ld a,(de) ; byte0 = (adr0) 137 and c ; byte0 = byte0 AND bitmask0 138 or b 139 ld (de),a ; (adr0) = byte0 OR byte 140 ld bc,8 141 add iy,bc ; offset += 8 142 ld b,(ix+9) ; r = rowbytes 143 144.scroll_row_left_loop dec b ; while ( --r != 0 ) 145 jr z, endrow_left 146 push bc 147 push iy ; DE = adr0 148 add iy,de ; adr0+offset 149 ld b,(ix+0) ; scrolldist 150 ld h,(iy+0) ; (adr0+offset) 151 ld l,(iy+8) ; (adr0+offset+8) 152 call scrollleft ; byte = Scrollleft( (adr0+offset),(adr0+offset+8),scrolldist) 153 ld (iy+0),h ; (adr0+offset) = byte 154 pop iy 155 ld bc,8 156 add iy,bc ; offset += 8 157 pop bc 158 jr scroll_row_left_loop 159 160.endrow_left ld e,(ix+5) 161 ld d,(ix+6) ; adr1, addr of last byte in row to scroll 162 ld a,(de) ; byte = (adr1) 163 ld h,a 164 ld l,0 165 ld b,(ix+0) 166 call scrollleft ; byte = Scrollleft( (adr1),0,scrolldist) 167 ld a,(ix+8) 168 and (ix+10) ; lastbyte = lastbyte AND bitmask1 : clear scroll area 169 or h ; mask in what has been scrolled, the rest is outside scroll area. 170 ld (de),a ; (adr1) = byte OR lastbyte, last byte of row completed. 171 ; endif 172 173.leftscroll_nextrow inc (ix+1) ; inc y 174 ld a,(ix+1) 175 and @00000111 ; if y MOD 8 <> 0 176 jr z, leftscroll_newline 177.inc_l_row inc (ix+3) ; inc adr0 178 inc (ix+5) ; inc adr1 179 jr leftscroll_next_h 180 ; else 181.leftscroll_newline ld a,(ix+3) 182 add a,256-7 183 ld (ix+3),a 184 inc (ix+4) ; adr0 += 256 185 ld a,(ix+5) 186 add a,256-7 187 ld (ix+5),a 188 inc (ix+6) ; adr1 += 256 189 190.leftscroll_next_h dec (ix+2) ; END FOR h 191 jp nz, scroll_l_height 192 193.end_scroll_left pop hl 194 ld sp,hl ; pointer to original ix, iy 195 pop iy 196 pop ix 197 ret 198 199 200; ************************************************************************ 201; 202; Scroll bytes left, b1 into b0, total of B pixels 203; 204; IN: H = b0 205; L = b1 206; B = scroll distance, 1 to 8 pixels. 207; 208; OUT: H = scrolled byte 209; 210.scrollleft add hl,hl 211 djnz scrollleft 212 ret 213ENDIF 214