132 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
CopyRange:
 | 
						|
  ; hl is source
 | 
						|
  ; de is destination
 | 
						|
  ; bc is length to copy
 | 
						|
  ld a, b 
 | 
						|
  or a, c
 | 
						|
  ret z
 | 
						|
.loop
 | 
						|
  ld a, [hl+]
 | 
						|
  ld [de], a
 | 
						|
  inc de
 | 
						|
  dec bc
 | 
						|
  ld a, b
 | 
						|
  or a, c ; check if bc is zero
 | 
						|
  jr nz, .loop
 | 
						|
  
 | 
						|
  ret
 | 
						|
 | 
						|
CopyRangeBy8s:
 | 
						|
  ; hl is source
 | 
						|
  ; de is destination
 | 
						|
  ; bc is length to copy
 | 
						|
  ld a, b 
 | 
						|
  or a, c
 | 
						|
  ret z
 | 
						|
.loop
 | 
						|
  rept 8
 | 
						|
    ld a, [hl+]
 | 
						|
    ld [de], a
 | 
						|
    inc de
 | 
						|
    dec bc
 | 
						|
  endr
 | 
						|
  ld a, b
 | 
						|
  or a, c ; check if bc is zero
 | 
						|
  jr nz, .loop
 | 
						|
  
 | 
						|
  ret
 | 
						|
 | 
						|
CopyOneTileData:
 | 
						|
  di
 | 
						|
  rept 16
 | 
						|
    ld a, [hl+]
 | 
						|
    ld [de], a 
 | 
						|
    inc de
 | 
						|
  endr
 | 
						|
  reti
 | 
						|
 | 
						|
CopyRangeOfTilesButRotated:
 | 
						|
  ld a, b
 | 
						|
  or a, c
 | 
						|
  ret z
 | 
						|
.loop
 | 
						|
  push bc ; save bc so we can use it in the loop
 | 
						|
  
 | 
						|
  ; add 15 to e, we're writing to the destination in reverse order
 | 
						|
  ld a, e
 | 
						|
  add a, 16
 | 
						|
  ld e, a 
 | 
						|
  ld a, d
 | 
						|
  adc a, 0
 | 
						|
  ld d, a 
 | 
						|
  
 | 
						|
  rept 8 ; copy 8 tiles
 | 
						|
    dec de
 | 
						|
    dec de ; step back two bytes (one tile) 
 | 
						|
    
 | 
						|
    
 | 
						|
    ; copy half the tile (one byte)
 | 
						|
    ld a, [hl+]
 | 
						|
    call ReverseBits ; reverse the order of a
 | 
						|
    ld [de], a 
 | 
						|
    inc de ; step forward because we want to preserve the order of each pair
 | 
						|
    
 | 
						|
    ; copy the second half of the tile (one byte)
 | 
						|
    ld a, [hl+]
 | 
						|
    call ReverseBits
 | 
						|
    ld [de], a 
 | 
						|
    dec de ; step backwards to be ready for the next pair
 | 
						|
    
 | 
						|
  endr
 | 
						|
  
 | 
						|
  pop bc ; restore bc to be the count to copy, and decrement it by 16
 | 
						|
  ld a, c 
 | 
						|
  sub a, 16
 | 
						|
  ld c, a 
 | 
						|
  ld a, b 
 | 
						|
  sbc a, 0
 | 
						|
  ld b, a 
 | 
						|
  
 | 
						|
  ; add 16 to properly increment the destination to be for the next tile
 | 
						|
  ld a, e 
 | 
						|
  add a, 16
 | 
						|
  ld e, a 
 | 
						|
  ld a, d 
 | 
						|
  adc a, 0
 | 
						|
  ld d, a 
 | 
						|
  
 | 
						|
  ld a, b
 | 
						|
  or a, c
 | 
						|
  jp nz, .loop
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
ReverseBits: ; overwrites bc and a, and reverses the bits of a. thanks to https://stackoverflow.com/a/2602885 for the algo 
 | 
						|
  swap a ; swap high nibble with low nibble
 | 
						|
  
 | 
						|
  ; swap 0b11001100 with 0b00110011
 | 
						|
  ld b, a 
 | 
						|
  and a, 0b11001100 ; select upper half of nibbles
 | 
						|
  srl a ; swap the upper half to the lower half
 | 
						|
  srl a
 | 
						|
  ld c, a ; c now holds the upper half and lower half swapped
 | 
						|
  ld a, b ; get back the whole byte
 | 
						|
  and a, 0b00110011 ; select lower halves of nibbles
 | 
						|
  sla a 
 | 
						|
  sla a ; swap the lower half to the upper half
 | 
						|
  or a, c 
 | 
						|
  
 | 
						|
  ; swap 0b10101010 with 0b01010101
 | 
						|
  ld b, a 
 | 
						|
  and a, 0b10101010
 | 
						|
  srl a 
 | 
						|
  ld c, a 
 | 
						|
  ld a, b
 | 
						|
  and a, 0b01010101
 | 
						|
  sla a 
 | 
						|
  or a, c
 | 
						|
  
 | 
						|
  ret
 | 
						|
  
 | 
						|
 
 |