[org 100h]
[segment .text]

; puvodni graf. mod
; -----------------

		mov       AH, 0Fh               ; zjistim puvodni graf. mod
		int       10h
	        mov	  [grmod], AL	        ; ulozim ho
		mov       AX, 0013h		; nastavim 320x200x256
		int       10h



; ==============================================
; nacteni obrazku s pozadim
; ==============================================

; pokus o otevreni souboru
; ------------------------

		mov       AX, 3d00h		; budu otevirat jen pro cteni
		mov       DX, bgfile          
		int       21h
		jnc       _fileopen             ; podarilo se otevrit?
		ret                             ; ne, konec
_fileopen:      mov       BX, AX                ; ano, ulozim handle souboru

; cteni palety
; ------------

		mov       AX, 4200h		; nastavim sluzbu, v BX je ulozen handle
		xor       CX, CX
		mov       DX, 18                ; offset 18, tam zacina paleta
		int       21h

		push      DS			
		mov       AX, 0A000h		; paletu docasne ulozim do video RAM
		mov       DS, AX

		xor       DX, DX
		mov       AH, 3fh               ; nactu celou paletu do video RAM
		mov       CX, 768
		int       21h

		xor       AX, AX
		xor       SI, SI
		mov       CX, 256               ; 256 barev

_palnext:	mov       DX, 03c8h             ; port adres graf. karty
                mov       AL, AH                ; index barvy
		out       DX, AL
		inc       DX                    ; port data graf. karty
		inc       AH

                mov       AL, [DS:SI+2]         
		shr       AL, 2                 ; R slozka
		out       DX, AL
		push      AX                    ; ulozim AH (index barvy)
		lodsw                           ; nactu do AH G a do AL B slozku barvy
		push      AX                    ; ulozim AH (B)
		mov       AL, AH                
		shr       AL, 2
		out       DX, AL		; a odeslu G
                pop       AX                    ; obnovim AH (B)
		shr       AL, 2
		out       DX, AL                ; a odeslu
                inc       SI
                pop       AX                    ; obnovim AH (index barvy)
		loop      _palnext

; cteni obrazku na obrazovku
; --------------------------

		xor       DX, DX
		mov       AH, 3fh
		mov       CX, 64000
		int       21h
		mov       AH, 3eh		; a uzavreme soubor
		int       21h
		pop       DS                    ; a obnovime DS



; ==============================================
; nacteni obrazku k odhalovani
; ==============================================

; alokovani pameti
; ----------------

		mov       AX, CS		; alokuju pamet
		mov       ES, AX
		mov       AH, 4Ah
		mov       BX, 1672
		int       21h
		jnc       _alocpic              ; alokovano?
		ret                             ; ne, tak konec

_alocpic:       mov       AX, CS
		add       AX, 4096
		mov       [image], AX

; pokus o otevreni souboru
; ------------------------

		mov       AX, 3d00h		; budu otevirat jen pro cteni
		mov       DX, imgfile          
		int       21h
		jnc       _fileopen2            ; podarilo se otevrit?
		ret                             ; ne, konec

; cteni ze souboru
; ----------------

_fileopen2:     mov       BX, AX                ; ano, ulozim handle souboru
		mov       AX, 4200h		; nastavim sluzbu, v BX je ulozen handle
		xor       CX, CX
		mov       DX, 18+768            ; offset 18+768, tam zacina obrazek
		int       21h
		
		push 	DS
		mov 	AX, [image]
		mov 	DS, AX
		xor	DX, DX
		mov	AH, 3fh               	; nactu cely obrazek do image
		mov	CX, 26752
		int	21h

		mov	AH, 3eh			; a uzavreme soubor
		int	21h
		pop	DS                    	; a obnovime DS




; ==============================================
; nacteni obrazku s kostkami
; ==============================================

; alokovani pameti
; ----------------

		mov       AX, CS		; alokuju pamet
		mov       ES, AX
		mov       AH, 4Ah
		mov       BX, 512
		int       21h
		jnc       _aloccub              ; alokovano?
		ret                             ; ne, tak konec

_aloccub:       mov       AX, CS                ; jo, nastavim promenou stinram
		add       AX, 4096+26752
		mov       [cubes], AX

; pokus o otevreni souboru
; ------------------------

		mov       AX, 3d00h		; budu otevirat jen pro cteni
		mov       DX, cubfile          
		int       21h
		jnc       _fileopen3            ; podarilo se otevrit?
		ret                             ; ne, konec

; cteni ze souboru
; ----------------

_fileopen3:     mov       BX, AX                ; ano, ulozim handle souboru
		mov       AX, 4200h		; nastavim sluzbu, v BX je ulozen handle
		xor       CX, CX
		mov       DX, 18+768            ; offset 18+768, tam zacina obrazek
		int       21h
		
		push 	DS
		mov 	AX, [cubes]
		mov 	DS, AX
		xor	DX, DX
		mov	AH, 3fh               	; nactu cely obrazek do cubes
		mov	CX, 512
		int	21h

		mov	AH, 3eh			; a uzavreme soubor
		int	21h
		pop	DS                    	; a obnovime DS



; ==============================================
; nastaveni preruseni
; ==============================================

		xor	AX, AX
		mov	ES, AX			; ES nastavim na zacatek pameti s prerusenima
		mov	AX, CS			; ulozim si code segment
		mov	BX, _keyb		; vezmu svoji rutinu obsluhy preruseni
		cli
		xchg	[ES:9*4], BX		; IRQ1 - int9
		xchg	[ES:9*4+2], AX
		sti
		push	AX			; ulozim si novou i starou prerusovaci rutinu (offsety)
		push	BX
		push	ES


; ==============================================
; experimenty
; ==============================================

; smycka na vykresleni celeho image
; ---------------------------------

		mov	CX, 50
next:		mov	AL, CL
		call	_show_line
		loop	next

		mov	CX, 4

c_next:		mov	AL, CL
		mov	BL, CL
		mov	BH, CL
		call	_show_cube
		loop	c_next;

		mov	AX, 65535
		call	_show_score

		call	_kontrola
		jmp	_konec


; cekani na stisk
; ---------------

_kontrola:	xor	SI, SI
		add	SI, keytab
		mov	AL, [SI]
		xor	AH, AH
		call	_show_score

		cmp	AX, 1
                jnz	_kontrola		; jo tak budeme koncit
		ret



; ==============================================
; ukonceni programu
; ==============================================

; odhlaseni preruseni
; -------------------

_konec:		pop	ES
		pop	BX			; obnovim predchozi prerusovaci rutinu
		pop	AX
		cli
		xchg	[ES:9*4], BX		; IRQ1 - int9
		xchg	[ES:9*4+2], AX
		sti

; obnoveni grafiky
; ----------------

		xor       AH, AH                ; obnovime puvodni grafickej rezim
		mov       AL, [grmod]
		int       10h

		ret				; a ukoncime program



; ==============================================
; zobrazovani grafiky
; ==============================================

; zobrazeni AL-teho radku image
; -----------------------------

_show_line:	push	CX
		push	AX

		mov	CX, 0A000h
		mov	ES, CX			; segment grafiky

		xor	AH, AH
		mov	DI, AX
		shl	AX, 8			; 2^8 = 256
		shl	DI, 6			; 2^6 = 64
		add	AX, 2720		; + zakladni ofset do obrazovky - zacatek image
		add	DI, AX			; ES:DI - ukazatel do videoRAM

		pop	AX			; AL = radek
		mov	AH, 152			
		mul	AH			; x 152 = ofset v obrazku
		mov	SI, AX
		push	DS
		mov	CX, [image]
		mov	DS, CX			; DS:SI - ukazatel do image

		mov	CX, 152
		rep movsb			; kopiruj...
		pop	DS
		pop	CX
		ret		

; vykresleni kostky AL na souradnici BL, BH v poli
; ------------------------------------------------

_show_cube:	push	CX
		push	DX
		push	AX
		push	BX
		push	DS

		xor	AH, AH
		shl	AX, 6			; AX *= 64 za velikost kazde kostky
		mov	SI, AX
		mov	AX, [cubes]
		mov	DS, AX			; DS:SI - ukazatel do cubes
		
		mov	CX, 0A000h;
		mov	ES, CX
		mov	AX, 320
		mov	CX, BX
		shr	BX, 8
		mul	BX			; AX = 320 * BH
		and	CX, 255
		add	AX, CX			; AX = 320 * BH + BL
		shl	AX, 3			; AX = 8 * (320 * BH + BL)
		add	AX, 320*8+56		; dorovnat na spravnou pozici v obraze
		mov	DI, AX			; ES:DI - ukazatel do videoRAM

		mov	CX, 8
_next_line:	push	CX
		mov	CX, 8
		rep movsb			; kopirovani ctverecku 8x8 do obrazu
		add	DI, 320-8
		pop	CX
		loop	_next_line

		pop	DS
		pop	BX
		pop	AX
		pop	DX
		pop	CX
		ret

; vykresleni digitalniho cisla DL od ofsetu BX
; --------------------------------------------

_show_number:	push	AX
		push	BX
		push	DX
		push	CX
		push	DS

		mov	SI, nums
		add	SI, DX
		mov	DL, [SI]

		mov	CX, 0A000h
		mov	ES, CX

		mov	SI, 1			; vodorovne cary
		add	BX, 1			; horni vodorovna cara
		call	_shn_line
		add	BX, 5*320-4		; stredni vodorovna cara
		call	_shn_line
		add	BX, 5*320-4		; spodni vodorovna cara
		call	_shn_line

		mov	SI, 320			; svisle cary
		add	BX, 65536-9*320-5	; leva horni svisla cara
		call	_shn_line
		add	BX, 65536-4*320+5	; prava horni svisla cara
		call	_shn_line
		add	BX, 320-5		; leva dolni svisla cara
		call	_shn_line
		add	BX, 65536-4*320+5	; prava dolni svisla cara
		call	_shn_line

		pop	DS
		pop	CX
		pop	DX
		pop	BX
		pop	AX
		ret

_shn_line:	mov	CX, 4
		shr	DL, 1
		jc	_shn_next1
_shn_next0:	mov	[ES:BX], byte num0
		add	BX, SI
		loop	_shn_next0
		ret
_shn_next1:	mov	[ES:BX], byte num1
		add	BX, SI
		loop	_shn_next1
		ret

; vypsani score - vypsani AX
; --------------------------

_show_score:	push	AX
		mov	BX, 36844
		mov	CX, 5			; 5 cifer
_shs_next:	mov	SI, 10
		xor	DX, DX
		div	SI			; AX = AX div 10, DX = AX mod 10
_shs_rest:	call	_show_number
		add	BX, 65536-8
		cmp	AX, 0
		jne	_shs_loop_next
		mov	DX, 10
		loop	_shs_rest
		pop	AX
		sti
		ret
_shs_loop_next:	loop	_shs_next
		pop	AX
		ret



; ==============================================
; obsluha klavesnice
; ==============================================

; obsluha preruseni
; -----------------
; 1 - byla prave stisknuta
; 2 - byla prave uvolnena
		
_keyb:		push	AX			; ulozim si veci, se kteryma budu pracovat
		push	BX
		push	ES
		push	CX
		push	DS
		push	SI

		xor	AX, AX
		in	AL, 60h			; nactu port
		cmp	AL, 80h			; byla klavesa uvolnena?
		jb	_stisk			; nebyla
		xor	AL, 80h			; byla tak si zjistim klavesu
		mov	BH, 2			; vyberu barvu, kterou to budu barvit
		jmp	_uvolnena		; byla tak skocim
_stisk:		mov	BH, 1			; byla stisnuta tak vyberu barvu

_uvolnena:	cmp	AL, 4Bh			; LEFT?
		jne	_notleft
		mov	SI, 0
		jmp	_keystop
_notleft:	cmp	AL, 4Dh			; RIGHT?
		jne	_notright
		mov	SI, 1
		jmp	_keystop
_notright:	cmp	AL, 48h			; UP?
		jne	_notup
		mov	SI, 2
		jmp	_keystop
_notup:		cmp	AL, 50h			; DOWN?
		jne	_notdown
		mov	SI, 3
		jmp	_keystop
_notdown:	
		jmp	_keynothing

_keystop:	add	SI, keytab
		mov	[SI], BH

_keynothing:	mov	AL, 20h			; konec preruseni
		out	20h, AL

		pop	SI
		pop	DS
		pop	CX
		pop	ES
		pop	BX
		pop	AX
		iret




; ==============================================
; promenne
; ==============================================

grmod		db		0		; puvodni graficky mod
souradnice	dw		0		; souradnice kostky v poli (0..12, 0..23)
num1		equ		224		; aktivni barva cislice
num0		equ		32		; neaktivni barva cislice
nums		db		7Dh, 50h, 37h, 57h, 5Ah, 4Fh, 6Fh, 51h, 7Fh, 5Fh, 00h
						; kody cislic 0-9

keytab		db		0, 0, 0, 0, 0, 0, 0, 0
						; L, R, U, D, F1, F2, F3, F4

bgfile		db		'bg.tga', 0	; soubor s pozadim
imgfile		db		'image.tga', 0	; obrazek k odkryvani, 152x176
cubfile		db		'cubes.tga', 0	; obrazek s 8mi kostkami

image		resb		26752		; obrazek k odkryvani
cubes		resb		512		; obrazek s kostkami

; tvary kostek ve vsech 4ech otocenich
; ------------------------------------

kostka00	db		0, 1, 0, 0, 0, 1, 0, 0,	0, 1, 0, 0, 0, 1, 0, 0
kostka01	db		0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
kostka02	db		0, 1, 0, 0, 0, 1, 0, 0,	0, 1, 0, 0, 0, 1, 0, 0
kostka03	db		0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0

kostka10	db		0, 1, 1, 0, 0, 0, 1, 1,	0, 0, 0, 0, 0, 0, 0, 0
kostka11	db		0, 0, 0, 1, 0, 0, 1, 1,	0, 0, 1, 0, 0, 0, 0, 0
kostka12	db		0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
kostka13	db		0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0

kostka20	db		0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0
kostka21	db		0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
kostka22	db		0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
kostka23	db		0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0

kostka30	db		0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0
kostka31	db		0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
kostka32	db		0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0
kostka33	db		0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

