
#include "ti83plus.inc"
#include "mirage.inc"
#include "keys.inc"

	.org $9d93
	.db $BB,$6D
	ret
	.db 1
Button:
	.db	%00000000,%00000000
	.db	%00000000,%01110000
	.db	%00000011,%00100000
	.db	%00000011,%00100000
	.db	%00000000,%00010100
	.db	%00000111,%10011100
	.db	%00000111,%10010100
	.db	%00000000,%00000000
	.db	%00011111,%11100000
	.db	%00011111,%11100000
	.db	%00000000,%00000000
	.db	%01111111,%11111000
	.db	%01111111,%11111000
	.db	%00000000,%00000000
	.db	%00000000,%00000000
Description:
	.db	"The Tower of Hanoi - TCPA",0

Pile1 = saferam1        ;Number of bricks, Size of bricks
Pile2 = Pile1+11
Pile3 = Pile2+11
Temp =  Pile3+11            ;Pile XCoord, which brick, which size
PP =	Temp+5			;Picked piece
From =	PP+1
NoM =	From+1			;Number of moves
Counter =	NoM+2
PXCoord =	Counter+1
XCoord =	PXCoord+1
YCoord =	XCoord+1

start:
		res appAutoScroll,(iy+appflags)

Message:
        ld hl,Pile1
        ld de,Pile1+1
        ld bc,50
        ld (hl),0
        ldir

        bcall(_clrlcdfull)
	bcall(_grbufclr)
	ld hl,Pic
	ld de,plotsscreen
	ld bc,96
	ldir

	set textwrite,(iy+sgrflags)

DispBlocks:
	ld hl,Author
	ld de,51*256+11
	call setvputs
	ld de,57*256+11
	call setvputs
	ld de,11*256+1
	call setvputs
	ld de,29*256+1
	call setvputs

	ld hl,plotsscreen+228			;$FD30
	ld d,h
	ld e,l
	ld a,%01111111
	ld (hl),a
	inc hl
	rlca
	ld (hl),a
	inc hl
	ex de,hl
	ld bc,10
	ldir

	ld de,plotsscreen+335			;$FDBF
	inc hl
	ld bc,12
	lddr

	ld hl,plotsscreen+240			;$FD40
	ld d,h
	ld e,l
	ld a,$80
	ld (hl),a
	inc hl
	rlca
	ld (hl),a
	inc hl
	ex de,hl
	ld bc,82
	ldir

	ld hl,plotsscreen+446			;$FE54
	ld d,h
	ld e,l
	ld a,%01111111
	ld (hl),a
	ld a,255
	inc hl
	ld (hl),a
	inc hl
	ld (hl),a
	inc hl
	ld a,%11111110
	ld (hl),a
	inc hl
	ex de,hl
	ld bc,4
	ldir

	ld hl,plotsscreen+574			;$FEFC
	ex de,hl
	ld bc,9
	lddr

	ld hl,plotsscreen+458			;$FE64
	ld d,h
	ld e,l
	ld a,%10000000
	ld (hl),a
	inc hl
	inc hl
	inc hl
	rlca
	ld (hl),a
	inc hl
	ex de,hl
	ld bc,4
	ldir

	ld hl,plotsscreen+456			;$FE60
	ld de,plotsscreen+468			;$FE70
	ld bc,94
	ldir

DispNumbers:
	ld hl,$14FB
	ld (penCol),hl
	ld c,2
	ld b,6
DNLoop
	ld a,(penCol)
	add a,12
	ld (penCol),a
	inc c
	ld a,c
	add a,'0'
	bcall(_vputmap)
	djnz DNLoop
	
	ld hl,39*256+20
	ld (penCol),hl
	ld hl,NormalTxt
	bcall(_vputs)
	ld a,(penCol)
	add a,7
	ld (penCol),a
	bcall(_vputs)


	ld a,(CMode)
	call BigInvert

	ld a,(Blocks)
	call Select

	call Stupid2

MessageLoop:
	call Stupid
MessageLoopB:
	call iFastCopy
MessageLoopC:
	bcall(_getcsc)
	cp G_LEFT
	jr z,DecNoB
	cp G_DOWN
	jr z,SelectMode
	cp G_CLEAR
	ret z
	cp G_MODE
	ret z
	cp G_ENTER
	jr z,StartGame
	cp G_RIGHT
	jr nz,MessageLoopC

IncNoB:
	ld a,(Blocks)
	cp 8
	jr z,MessageLoopB
	inc a
	ld (Blocks),a
	dec a
Common:
	call Select
	ld a,(Blocks)
	call Select
	jr MessageLoopB

DecNoB:
	ld a,(Blocks)
	cp 3
	jr z,MessageLoopB
	dec a
	ld (Blocks),a
	inc a
	jr Common

SelectMode:
	call Stupid
SelectModeLoop:
	call iFastCopy
SelectModeLoopB:
	bcall(_getcsc)
	;cp G_DOWN
	;jr z,StartGame
	cp G_ENTER
	jr z,StartGame
	cp G_RIGHT
	jr z,SetMode
	cp G_UP
	jr z,MessageLoop
	cp G_CLEAR
	ret z
	cp G_LEFT
	jr nz,SelectModeLoopB

SetMode:
	ld a,(CMode)
	call BigInvert
	ld a,(CMode)
	xor 1
	ld (CMode),a
	call BigInvert
	jr SelectModeLoop

StartGame
	ld a,(CMode)
	or a
	jr z,Begin
	jp Puzzle

Begin:
	bcall(_clrlcdfull)
	bcall(_grbufclr)

	ld hl,Pile1
	ld a,(Blocks)
    ld (hl),a
    inc hl
    ld b,a
Loop:
    ld (hl),a
    dec a
    inc hl
    djnz Loop
Loopend:
	ld a,-16
	ld (PXCoord),a
    call DrawFirst
        
Move:
	ld a,-16
	ld (PXCoord),a
	bcall(_getcsc)
	cp G_MODE
	jp z,EndRound
	cp G_YEDIT
	jr z,FromLeftRoutine
	cp G_ZOOM
	jr z,FromMiddleRoutine
	cp G_GRAPH
	jr nz,Move

FromRightRoutine:
	ld a,2
	jr FromRoutine

FromMiddleRoutine:
	ld a,1
	jr FromRoutine

FromLeftRoutine:
	xor a

FromRoutine:
	ld (From),a
	ld l,7
	ld b,a
	add a,a		;*2
	add a,a		;*4
	add a,b		;*5
	add a,3
	ld h,a
	sub 3
	sub b		;*4
	ld c,a
	add a,a		;*8
	add a,c		;*12
	sub b		;*11
	ld (curRow),hl
	ld e,a
	ld d,0
	ld hl,Pile1
	add hl,de
	ld a,6
	bcall(_putc)
	ld c,(hl)
	xor a
	cp c
	jr z,MoveNot
	dec (hl)
	ld b,0
	add hl,bc
	ld a,(hl)
	ld (PP),a
	xor a
	ld (hl),a
	jr To2
MoveNot:
	call DrawFirst
	jr Move

To2:
	bcall(_getcsc)
	cp G_MODE
	jp z,EndRound
	cp G_YEDIT
	jr z,ToLeftRoutine
	cp G_ZOOM
	jr z,ToMiddleRoutine
	cp G_GRAPH
	jr nz,To2

ToRightRoutine:
	ld a,2
	jr ToRoutine

ToMiddleRoutine:
	ld a,1
	jr ToRoutine

ToLeftRoutine:
	xor a

ToRoutine:
	ld b,a
	ld a,(From)
	cp b
	jr z,CouldntMove
	ld a,b
	add a,a		;*2
	add a,a		;*4
	ld c,a
	add a,a		;*8
	add a,c		;*12
	sub b		;*11
	ld e,a
	ld d,0
	ld hl,Pile1
	add hl,de
	ld d,h
	ld e,l
	ld c,(hl)
	xor a
	cp c
	jr nz,NotZ
	inc hl
NotZ:
	ld b,0
	add hl,bc
	ld b,(hl)
	xor a
	cp b
	jr z,Zero
	ld a,(PP)
	cp b
	jr nc,CouldntMove
Zero:
	ld h,d
	ld l,e
	inc (hl)
	ld c,(hl)
	ld b,0
	add hl,bc
	ld a,(PP)
	ld (hl),a
	ld hl,(NoM)
	inc hl
	ld (NoM),hl
	call DrawFirst

CheckDone:
	ld hl,Pile2
	ld a,(Blocks)
	ld b,(hl)
	cp b
	jr z,Done
	ld hl,Pile3
	ld a,(Blocks)
	ld b,(hl)
	cp b
	jr z,Done
	jp Move

CouldntMove:
	ld a,(From)
	ld b,a
	add a,a
	add a,b
	add a,a
	add a,a
	sub b
	ld e,a
	ld d,0
	ld hl,Pile1
	add hl,de
CMRoutine:
	inc (hl)
	ld c,(hl)
	ld b,0
	add hl,bc
	ld a,(PP)
	ld (hl),a
	call DrawFirst
	jp Move

Done:
	ld hl,$0001
	ld (curRow),hl
	ld hl,Congrats
	bcall(_puts)
Label:
	bcall(_getcsc)
	cp G_ENTER
	jr nz,Label
	jp Message

DrawFirst:
	bcall(_grbufclr)
        ld hl,Pile1-1
DrawPile1:
        ld a,0
        ld (Temp+1),a
        inc hl
        ld b,10
        ld a,(PXCoord)
        add a,32
        ld (PXCoord),a
DrawP1Loop:
        push bc
        ld a,(Temp+1)
        inc a
        ld (Temp+1),a
        inc hl
        ld a,(hl)
        push hl
        call CheckSize
        pop hl
        pop bc
        djnz DrawP1Loop
        ld a,(Counter)
        inc a
        ld (Counter),a
        cp 3
        jr nz,DrawPile1

Return:
	ld hl,(NoM)
	bcall(_setxxxxop2)
	bcall(_op2toop1)
	ld bc,0
	ld (pencol),bc
	ld a,3
	bcall(_dispop1a)
	xor a
	ld (Counter),a
	ld b,4
	ld hl,Temp
RetLoop:
	ld (hl),a
	inc hl
	djnz RetLoop
	jp iFastCopy

CheckSize:
        or a
        jr z,DrawPin

        ld (Temp+2),a
        ld a,(Temp+1)
		add a,a
		add a,a
        ld b,a
        ld a,63
        sub b
        ld (YCoord),a
        jp PutItOut

DrawPin:
        ld a,(PXCoord)
        dec a
        ld (XCoord),a
        ld a,(Temp+1)
		add a,a
		add a,a
        ld b,a
        ld a,63
        sub b
        ld (YCoord),a
        ld a,(YCoord)
        ld b,4
        sub b
        ld d,a
        ld (YCoord),a
        ld c,4
PinYLoop:        
        ld b,2
        ld a,(YCoord)
        dec a
        ld (YCoord),a
        ld a,(XCoord)
        ld e,a

PinXLoop:
        call PutPixel
        inc e
        djnz PinXLoop
        dec c
        jr nz,PinYLoop
        ret
        
PutItOut:
        ld a,(Temp+2)
        add a,a
        ld b,a
        ld a,(PXCoord)
        sub b
        ld e,a
        ld (XCoord),a
        ld a,(YCoord)
        ld b,8
        sub b
        ld d,a
        ld (YCoord),a
        push de
        ld a,(Temp+2)
		add a,a
		add a,a
        ld b,a
        ld c,3
YLoop:
        ld a,(YCoord)
        inc a
        ld (YCoord),a
        ld a,(Temp+2)
		add a,a
		add a,a
        ld b,a
        ld a,(XCoord)
        ld e,a

XLoop:
        call PutPixel
        inc e
        djnz XLoop
        dec c
        jr nz,YLoop
        pop de
        ret

PutPixel:
        push bc
	push de
        ld a,(YCoord)
        ld c,e
	ld e,a
	ld a,c
        call iGetPix
        or (hl)
        ld (hl),a
	pop de
        pop bc
        ret

Puzzle:
	ld a,(Blocks)
	ld b,a
PuzzleLoop:
	push bc
	ld b,3
	call iRandom
	pop bc
	ld e,a
	add a,a	;*2
	add a,e	;*3
	add a,a	;*6
	add a,a	;*12
	sub e	;*11
	ld e,a
	ld d,0
	ld hl,Pile1
	add hl,de
	inc (hl)
	ld e,(hl)
	add hl,de
	ld (hl),b	
	djnz PuzzleLoop
	jp Loopend

EndRound:
	bcall(_clrlcdfull)
	jp Message

Select:
	sub 3
	add a,a
	ld e,a
	ld d,0
	ld hl,plotsscreen+240			;228
	add hl,de
	ld de,11
	ld b,7					;9
Invert:
	ld a,(hl)
	xor %01111111	;cpl
	ld (hl),a
	inc hl
	ld a,(hl)
	xor %11111110	;cpl
	ld (hl),a
	add hl,de
	djnz Invert
	ret

BigInvert:
	add a,a
	add a,a
	add a,4
	ld e,a
	ld d,0
	ld hl,plotsscreen+454			;442
	add hl,de
	ld de,9
	ld b,9					;11
BInvert:
	ld a,(hl)
	xor %01111111	;cpl
	ld (hl),a
	inc hl
	ld a,(hl)
	cpl
	ld (hl),a
	inc hl
	ld a,(hl)
	cpl
	ld (hl),a
	inc hl
	ld a,(hl)
	xor %11111110	;cpl
	ld (hl),a
	add hl,de
	djnz BInvert
	ret

Stupid:
	ld hl,plotsscreen+132		;$FCB0
	call SelectWhat
Stupid2:
	ld hl,plotsscreen+348		;$FDD0
SelectWhat:
	ld de,8
	ld c,7
ThisLoop:
	ld b,4
SmthLoop:
	ld a,(hl)
	cpl
	ld (hl),a
	inc hl
	djnz SmthLoop
	add hl,de
	dec c
	jr nz,ThisLoop
	ret

Pic:
  .db %11111111,%11111111,%00010111,%11111100,%01111111,%11111111,%11111111,%11110110,%10111111,%11111110,%11111111,%11111111
  .db %11111111,%11111111,%10110111,%11111110,%11111111,%11111111,%11111111,%11101110,%10111111,%11111111,%11111111,%11111111
  .db %11111111,%11111111,%10110011,%10111110,%11101101,%01011011,%00111110,%11000110,%10110110,%01110110,%11111111,%11111111
  .db %11111111,%11111111,%10110101,%01011110,%11010101,%01010101,%01011101,%01101110,%00101010,%10101010,%11111111,%11111111
  .db %11111111,%11111111,%10110101,%00011110,%11010101,%01010001,%01011101,%01101110,%10110010,%10101010,%11111111,%11111111
  .db %11111111,%11111111,%10110101,%01111110,%11010110,%10110111,%01111101,%01101110,%10101010,%10101010,%11111111,%11111111
  .db %11111111,%11111111,%10110101,%01011110,%11010110,%10110101,%01111101,%01101110,%10101010,%10101010,%11111111,%11111111
  .db %11111111,%11111111,%10110101,%10111110,%11101110,%10111011,%01111110,%11101110,%10110010,%10110110,%11111111,%11111111

NormalTxt:	.db "Normal",0
PuzzleTxt:	.db "Puzzle",0

CMode:	.db 0
Blocks:	.db 3

Author:
	.db "Made by Andreas Finne",0
Email:
	.db "a_finne@hotmail.com",0

Numbertxt:	.db "Blocks:",0
Modetxt:	.db "Mode:",0

Congrats:	.db "Congratulations!",0

.end
