; *************************************************************
; * col40.asm - демонстрация режима 40x24 тайла 6x8           *
; *************************************************************

#include "simple_lib.inc"

start		call initGraphicMode	; инициализируем графический режим
		pc <- repeat

repeat		
		r0 <- 0		; чет
		call draw_pattern
		;psw = psw | CPU_HALT
		
		r0 <- 1		; нечет
		call draw_pattern
		;psw = psw | CPU_HALT

		pc <- repeat	; повторяем процедуру с самого начала
		
		; r0 - на входе, первый тайл для отрисовки
draw_pattern	r1 <- 0		; текущая колонка
		r2 <- 0		; текущая строка
.loop
		call draw_tile
		r0 = 1 - r0	; меняем номер тайла из 0 в 1 и обратно
		r1 <- r1 + 1	; продвигаем колонку
		void = r1 - 40	; сравниваем с 40
		jnz .loop
		r1 <- 0
		r2 <- r2 + 1	; продвигаем строку
		void = r2 - 24	; сравниваем с 24
		jnz .loop
		ret
		
		; r0 - номер тайла для отрисовки
		; r1 - колонка X
		; r2 - строка Y
draw_tile		
		[ sp ] <- r0	; сохраним все регистры которые портим
		[ sp ] <- r1
		[ sp ] <- r2
		[ sp ] <- r3
		[ sp ] <- r4
		
		r3 = r1 + index_table	; ищем в таблице опорный индекс I
		r3 <- [ r3 ]		; r3 = I
		r3 = r3 + bitmapBase		; r3 = bitmapBase + I
		r4 <- r2			; r4 = Y
		r4 <= r4 >> 7		; эквивалентно << 9, т.е. *= 512
		r3 = r3 + r4		; r3 = bitmapBase + I + 512 * Y
		r4 <- 8			; счетчик цикла
		r0 <= r0 >> 12		; эквивалентно << 4, т.е. *= 16, настраиваемся на паттерн тайла
		void = r1 & 1		; тестируем нулевой бит колонки (чёт или нечет?)
		jz .draw_left
.draw_right	
		r0 = sprites_right + r0	; r0 - указатель на спрайт, а в r3 - указатель в видеопамять
.right_loop
		r2 = [ r3 ] & $FF00		; считываем из видеопамяти половинку слова
		[ r3 ] = r2 | [ r0 ]		; записываем в память половинку наложенную на остаток
		r0 <- r0 + 1
		r3 <- r3 + 1
		[ r3 ] <- [ r0 ]		; второе слово перегоняем целиком
		r0 <- r0 + 1
		r3 = r3 + 63		; переходим к следующему сканлайну
		r4 <= r4 - 1
		jnz .right_loop		; повторяем раз
		pc <- .end
.draw_left
		r0 = sprites_left + r0	; r0 - указатель на спрайт, а в r3 - указатель в видеопамять
.left_loop
		[ r3 ] <- [ r0 ]		; первое слово перегоняем целиком
		r0 <- r0 + 1
		r3 <- r3 + 1
		r2 = [ r3 ] & $00FF		; считываем из видеопамяти половинку слова
		[ r3 ] = r2 | [ r0 ]		; записываем в память половинку наложенную на остаток
		r0 <- r0 + 1
		r3 = r3 + 63		; переходим к следующему сканлайну
		r4 <= r4 - 1
		jnz .left_loop		; повторяем раз
		
.end
		r4 <- [ sp ]
		r3 <- [ sp ]
		r2 <- [ sp ]
		r1 <- [ sp ]
		r0 <- [ sp ]
		ret
		
index_table	
		dw ( 3 * 0 / 2 )
		dw ( 3 * 1 / 2 )
		dw ( 3 * 2 / 2 )
		dw ( 3 * 3 / 2 )
		dw ( 3 * 4 / 2 )
		dw ( 3 * 5 / 2 )
		dw ( 3 * 6 / 2 )
		dw ( 3 * 7 / 2 )
		dw ( 3 * 8 / 2 )
		dw ( 3 * 9 / 2 )
		dw ( 3 * 10 / 2 )
		dw ( 3 * 11 / 2 )
		dw ( 3 * 12 / 2 )
		dw ( 3 * 13 / 2 )
		dw ( 3 * 14 / 2 )
		dw ( 3 * 15 / 2 )
		dw ( 3 * 16 / 2 )
		dw ( 3 * 17 / 2 )
		dw ( 3 * 18 / 2 )
		dw ( 3 * 19 / 2 )
		dw ( 3 * 20 / 2 )
		dw ( 3 * 21 / 2 )
		dw ( 3 * 22 / 2 )
		dw ( 3 * 23 / 2 )
		dw ( 3 * 24 / 2 )
		dw ( 3 * 25 / 2 )
		dw ( 3 * 26 / 2 )
		dw ( 3 * 27 / 2 )
		dw ( 3 * 28 / 2 )
		dw ( 3 * 29 / 2 )
		dw ( 3 * 30 / 2 )
		dw ( 3 * 31 / 2 )
		dw ( 3 * 32 / 2 )
		dw ( 3 * 33 / 2 )
		dw ( 3 * 34 / 2 )
		dw ( 3 * 35 / 2 )
		dw ( 3 * 36 / 2 )
		dw ( 3 * 37 / 2 )
		dw ( 3 * 38 / 2 )
		dw ( 3 * 39 / 2 )
		
sprites_left
		dw $C0C0 $C000
		dw $0C0C $0C00
		dw $C0C0 $C000
		dw $0C0C $0C00
		dw $C0C0 $C000
		dw $0C0C $0C00
		dw $C0C0 $C000
		dw $0C0C $0C00

		dw $CCCC $CC00
		dw $C000 $0C00
		dw $C000 $0C00
		dw $C000 $0C00
		dw $C000 $0C00
		dw $C000 $0C00
		dw $C000 $0C00
		dw $CCCC $CC00

sprites_right	
		dw $00C0 $C0C0
		dw $000C $0C0C
		dw $00C0 $C0C0
		dw $000C $0C0C
		dw $00C0 $C0C0
		dw $000C $0C0C
		dw $00C0 $C0C0
		dw $000C $0C0C

		dw $00CC $CCCC
		dw $00C0 $000C
		dw $00C0 $000C
		dw $00C0 $000C
		dw $00C0 $000C
		dw $00C0 $000C
		dw $00C0 $000C
		dw $00CC $CCCC
				