;Checkers v1.0
;By Sam Heald

	.nolist		
	#include "ion.inc"
	.list		

#ifdef TI83P		
	.org progstart-2
	.db $BB,$6D
TEXT_MEM  = $8508
TEXT_MEM2 = $8A3A

#else		
	.org progstart

TEXT_MEM  = $80c9
TEXT_MEM2 = $858f

#endif		
	xor a	
	jr nc,StartTheProgram

ProgDesc: .db "Checkers 8X v1.2",0

xpos   = TEXT_MEM
ypos   = TEXT_MEM+1
anim_counter = TEXT_MEM+2
hxpos = TEXT_MEM+3
hypos = TEXT_MEM+4
hflag = TEXT_MEM+5
bpos = TEXT_MEM+6
turn = TEXT_MEM+8
selected = TEXT_MEM+9
jflag = TEXT_MEM+11
game = TEXT_MEM+12 
color = TEXT_MEM+13
temp = TEXT_MEM+14
lcounter  = TEXT_MEM+15      ; WORD
curspos = TEXT_MEM+17
boardflip = TEXT_MEM+18
hrflag = TEXT_MEM+25
Viables = TEXT_MEM+39 ;20 bytes ;2 for loc, 1 for flag, 2 for loc of jumped piece

Board = TEXT_MEM+60 ;64 bytes
BoardEnd = Board+56 ;last row

StartTheProgram:
 res 1,(iy+13)
 call display_ttl_scr
 set 1,(iy+13)
 ret

display_ttl_scr:
	res 3,(iy+5)
	   ld a,(toggle)
         or a
         ld hl,t_yes
         call nz,nope
         ld bc,3
 	   ld de,toggle_text
 	   ldir

	bcall(_clrlcdf)
         ld       de,0
         ld       hl,ProgDesc
	   call DTX

         ld       de,$0814
	   ld hl,Title
         call DMX

         ld       de,$0F1E
         call DMX

         ld       de,$2006
         call DMX

         ld       d,$28
         call DMX

         ld       d,$30
         call DMX

intro_loop:
       ld       hl,curspos                 ; Redraw arrow
       ld       a,(hl)
       cp 255
       jr       c,duh
       ld       a,2
duh:
       cp       3
       jr       c,position_ok
       xor a
position_ok:
         ld       (hl),a

 LD a,(curspos)
 add a,4
 ld d,$00
 ld e,a
 ld a,5
 call DCX

       bcall(_getk)  ; Read and process keystrokees

no__cheat:
         ld       hl,curspos
         cp       $0f
         ret z
         cp       $09
         jr       z,selectedop
         cp       $04
         jr       nz,no_up
         call ClearArrow
         dec      (hl)

no_up:   cp       $01
         jr       nz,intro_loop
         call ClearArrow
         inc      (hl)
         jr       intro_loop

selectedop:
         ld       a,(curspos)
         or       a
         jr       z,toggleflip
         dec      a
         jr       z,regular
Link:
 ld a,1
 jr ContG

regular:
 xor a
ContG:
 ld (game),a
 call start
 jp display_ttl_scr

nope:
 ld hl,t_no
 ret

toggleflip:
         ld       hl,toggle
         ld       a,(hl)
         or       a
         jr       z,toggle_no
	   ld       (hl),0
	   jr toggle_set
toggle_no:
         ld       (hl),1
toggle_set:
         jp       display_ttl_scr


ClearArrow:
 ld a,(curspos)
 add a,4
 ld e,a
 ld d,$00
 ld a,32
DCX:
 ld (currow),de
 bcall(_putc)
 ret

start:
 ld hl,Board2
 ld de,Board
 ld bc,64
 ldir

 ld hl,Board
 ld (bpos),hl

 xor a
 ld (ypos),a
 ld (xpos),a
 ld (hflag),a
 ld (jflag),a
 inc a
 ld (boardflip),a ;1 = reg , 2 = flipped
 inc a
 ld (turn),a   ;initialize variables

 ld a,(game)
 or a
 jr z,NewSquare  ;Same calc

 bcall(_clrlcdf)
 ld de,$0303
 ld hl,WaitTxt
 call DTX

 xor a
 ld (hrflag),a
 call ReceiveByte
 or a
 jr nz,NoWait	       ; If byte gotten, the other calc was waiting
 ld a,1
 call SendByte        ; Else wait until the other calc responds
 ld a,2
NoWait:
 ld (color),a
 ld (hrflag),a  ;anything but zero
 xor a
 ld (toggle),a
NewSquare:
 ld hl,GRAPH_MEM
 ld (hl),0
 ld de,GRAPH_MEM+1
 ld bc,767
 ldir

 call JFLAGS
 call DrawBoard
 call DrawSideBar
 call DrawHigh
 call CheckWinner
 ld a,1
 ld (anim_counter),a

MainLoop:
 call DrawCursor
 ld a,(game)
 or a
 jr z,SameCalc

 ld a,(turn)
 ld b,a
 ld a,(color)
 cp b
 jr z,SameCalc ;Your turn you control

 call ReceiveByte
 jr SameCalc2

SameCalc:
 ei
 halt
 bcall(_getk)
 push af
 ld a,(game)
 or a
 jr z,NoSend
 pop af
 ld (TEXT_MEM+20),a
 call SendByte  ;Send what you did
 ei
 halt
 ld a,(TEXT_MEM+20)
 push af
NoSend:
 pop af
SameCalc2:
 cp $04
 jr z,MoveUp
 cp $02
 jr z,MoveLeft
 cp $03
 jr z,MoveRight
 cp $01
 jr z,MoveDown
 cp $36
 jr z,MovePiece
 cp $30
 jp z,EndJump
 cp $38
 call z,PauseG
 cp $0f
 jp nz,MainLoop
 ret

MoveUp:
 ld a,(ypos)
 or a
 jp z,MainLoop
 add a,-8
 ld (ypos),a
 ld hl,(bpos)
 ld de,-8
 add hl,de
 ld (bpos),hl
 jp NewSquare 

MoveRight:
 ld a,(xpos)
 cp 56
 jp z,MainLoop
 add a,8
 ld (xpos),a

 ld hl,(bpos)
 inc hl
 ld (bpos),hl

 jp NewSquare

MoveLeft:
 ld a,(xpos)
 or a
 jp z,MainLoop
 add a,-8
 ld (xpos),a
 ld hl,(bpos)
 dec hl
 ld (bpos),hl
 jp NewSquare

MoveDown:
 ld a,(ypos)
 cp 56
 jp z,MainLoop
 add a,8
 ld (ypos),a
 ld hl,(bpos)
 ld de,8
 add hl,de
 ld (bpos),hl
 jp NewSquare

MovePiece:
 ld a,(hflag)
 or a
 jp z,Hilight

 ld de,(selected)
 ld hl,(bpos)
 bcall(_cphlde)
 jr z,SamePiece

 call CheckViables
 jp c,NewSquare

 ld hl,(bpos)
 ld de,(selected)
 ld a,(de)
 ld (hl),a
 xor a            
 ld (de),a

 call CheckSquares

 ld a,(jflag)
 or a
 jp nz,Hilight
EndJump2:
 xor a
 ld (hflag),a
 ld (jflag),a
 ld a,(turn)
 xor 3
 ld (turn),a
 ld a,(toggle)
 or a
 jr nz,NEW ;1 = no switch
 ld a,(boardflip)
 xor 3
 ld (boardflip),a  ;Switched
 ld hl,Board+63
 ld de,TEXT_MEM2
 ld b,64
Cloop:
 ld a,(hl)
 ld (de),a
 inc de
 dec hl
 djnz Cloop
 ld hl,TEXT_MEM2
 ld de,Board
 ld bc,64
 ldir

NEW:
 jp NewSquare

EndJump:
 ld a,(jflag)
 or a
 jp z,MainLoop
 jr EndJump2


SamePiece:
 ld a,(jflag)
 or a
 jr nz,NEW
 xor a            
 ld (hflag),a
 jp NewSquare

CheckViables:
 ld de,(bpos)
 ld hl,Viables
 ld b,4
Checker:
 push hl
 call LD_HL_MHL
 bcall(_cphlde)
 pop hl
 inc hl
 inc hl
 jr z,testSquare  ;no carry flag set = good square
 inc hl
 inc hl
 inc hl
 djnz Checker
WrongSquare:
 scf
 ret


JumpOnly:
 ld a,(hl)
 cp 2
 jr nz,WrongSquare
 jr DoJump

testSquare:
 ld a,(jflag)
 or a
 jr nz,JumpOnly
 ld a,(hl)
 or a
 jr z,WrongSquare
 cp 1
 ret z ;Good Square
DoJump:
 inc hl
 call LD_HL_MHL
 xor a
 ld (hl),a
 inc a
 ld (jflag),a
 ret ;Good Square

Hilight:
 ld a,(turn)
 ld b,a
 ld hl,(bpos)
 ld a,(hl)
 cp b
 jp z,GoodPiece
 inc b
 inc b
 cp b
 jp nz,NewSquare
GoodPiece:
 ld a,(xpos)
 ld (hxpos),a
 ld a,(ypos)
 ld (hypos),a
 ld hl,(bpos)
 ld (selected),hl
 ld d,(hl)
 call WriteViables  
 ld a,1
 ld (hflag),a
 jp NewSquare

Switch:
 ld a,d
 xor 3
 ld d,a
 ret

PauseG:
 ld a,(game)
 or a
 ret nz
 RES 4, (IY $09)     ; Turn off 'ON' flag
 DI                  ; disable interrupts
 LD  A, 01           ; bit 3 = lcd status
 OUT ($03), A        ; bit 0 = ON-interrupt status
 EI                  ; enable interrupts
 HALT                ; wait for ON (that's the only interrupt)
 ret


WriteViables:
 ld a,(turn)
 ld b,a  ;b = turn
 xor 3
 ld c,a  ;c = other guy
 add a,2
 ld e,a

 ld a,d
 cp 3
 jr z,CheckBoth
 cp 4
 jr z,CheckBoth 

 ld a,(turn)
 ld d,a
 ld a,(boardflip)
 cp 2 ;2 equals flipped
 call z,Switch
 ld a,d
 cp 2
 jr z,checktop

checkbottom:
 push hl
 ld de,7
 add hl,de
 ld ix,Next3
 ld a,(hl)
 cp b
 jp z,SetNo
 push bc
 inc b
 inc b 
 cp b
 pop bc
 jp z,SetNo
 cp c
 jp z,CheckJump
 push bc
 inc c
 inc c 
 cp c
 pop bc 
 jp z,CheckJump
 or a
 call z,PlainGood
Next3:
 ld (Viables+10),de
 ld (Viables+12),a
 ld (Viables+13),hl
 pop hl
 push hl
 ld de,9
 add hl,de
 ld ix,Next4
 ld a,(hl)
 cp b
 jr z,SetNo
 push bc
 inc b
 inc b 
 cp b
 pop bc
 jr z,SetNo
 cp c
 jr z,CheckJump
 push bc
 inc c
 inc c 
 cp c
 pop bc
 jr z,CheckJump
 or a
 call z,PlainGood
Next4:
 ld (Viables+15),de
 ld (Viables+17),a
 ld (Viables+18),hl
 pop hl
 ret

CheckBoth:
 call checkbottom

checktop:
 push hl
 ld de,-9
 add hl,de
 ld ix,Next1
 ld a,(hl)
 cp b
 jr z,SetNo
 push bc
 inc b
 inc b 
 cp b
 pop bc
 jr z,SetNo
 cp c
 jr z,CheckJump
 push bc
 inc c
 inc c 
 cp c
 pop bc
 jr z,CheckJump
 or a
 call z,PlainGood
Next1:
 ld (Viables),de
 ld (Viables+2),a
 ld (Viables+3),hl
 pop hl
 ld de,-7
 add hl,de
 ld ix,Next2
 ld a,(hl)
 cp b
 jr z,SetNo
 inc b
 inc b
 cp b
 jr z,SetNo
 cp c
 jr z,CheckJump
 inc c
 inc c 
 cp c
 jr z,CheckJump
 or a
 call z,PlainGood
Next2:
 ld (Viables+5),de
 ld (Viables+7),a
 ld (Viables+8),hl
 ret

SetNo:
 xor a
 ex de,hl
 jp (ix)
 
PlainGood:
 ld a,1
 ex de,hl
 ret

CheckJump:
 add hl,de ;add DE to HL again
 ld a,(hl)
 or a
 jr z,jumpgood
 xor a
 jp (ix)

jumpgood:
 push hl
 ld a,2
 sbc hl,de
 pop de
 jp (ix)



DrawCursor:
 ld a,(anim_counter)
 dec a
 ld (anim_counter),a
 ret nz
 ld a,30
 ld (anim_counter),a

 ld a,(xpos)
 ld b,a
 ld a,(ypos)
 ld c,a
 ld hl,Space
 call PutSprite
 bcall(_copygbuf)
 ret

DrawHigh:
 ld a,(hflag)
 or a
 ret z
 ld a,(hxpos)
 ld b,a
 ld a,(hypos)
 ld c,a
 ld hl,HiLite
 call PutSprite
 ret

DrawSideBar:
 ld hl,SideBar
 ld de,GRAPH_MEM+8
 ld a,7
ll:
 ld bc,4
 ldir

 inc de
 inc de
 inc de
 inc de
 inc de
 inc de
 inc de
 inc de

 dec a
 jr nz,ll

 set 7,(iy+$14)
 ld d,$0A
 ld a,(turn)
 cp 2
 jr z,BTurn
 ld e,$45
 ld hl,WhiteTurn
 call DMX
 ld de,$1048
P2:
 call DMX
P:
 res 7,(iy+$14)
 ret

BTurn:
 ld e,$42
 set 3,(iy+5)
 ld hl,BlackTurn
 call DMX
 ld d,$10
 call DMX
 res 3,(iy+5)
 jr P


DrawBoard:
 ld hl,Board
 ld c,0  ;y coord
 ld e,8  ;8 horizontal rows
DrawLoop:
 ld b,0
 ld d,8  ;8 vertical collumns
DrawLoop2:
 push hl
 push bc
 push de
 ld a,(hl)
 cp 9
 jr z,Done21
 or a
 jr z,DrawSpace
 dec a
 jr z,DrawWhite
 dec a 
 jr z,DrawBlack
 dec a
 jr z,DrawWhiteK
DrawBlackK:
 ld hl,BlackK
 jr DoneThisOne

DrawBlack:
 ld hl,Black
DoneThisOne:
 call PutSprite
Done21:
 pop de
 pop bc
 pop hl

 inc hl

 ld a,b
 add a,8 ;move over
 ld b,a

 ld a,d
 dec a
 dec d
 jr nz,DrawLoop2

 ld a,c
 add a,8
 ld c,a

 ld a,e
 dec a
 dec e
 jr nz,DrawLoop
 ret


DrawSpace:
 ld hl,Space
 jr DoneThisOne

DrawWhite:
 ld hl,White
 jr DoneThisOne

DrawWhiteK:
 ld hl,WhiteK
 jr DoneThisOne



CheckWinner:
 ld a,2
CheckWin:
 ld hl,Board
 ld b,64
CheckWin2:
 ld c,(hl)
 cp c
 jr z,Done1
 inc a
 inc a
 cp c
 jr z,Done2
 dec a
 dec a
 inc hl
 djnz CheckWin2

 cp 1
 jr z,OneWin
TwoWin:
 ld hl,TWin
FlashWinner:
 push hl
 bcall(_getk)
 pop hl
 cp $09
 jr z,Quit
 ld a,(iy+5)
 xor 8
 ld (iy+5),a
 push hl
 bcall(_copygbuf)
 pop hl
 ld de,$0303
 push hl
 call DTX
 pop hl
 ei
 ld b,20
FlashWait:
 halt
 djnz FlashWait
 jr FlashWinner

Quit:
 inc sp
 inc sp
 ret

OneWin:
 ld hl,OWin
 jr FlashWinner 

Done2:
 dec a
 dec a
Done1:
 dec a
 jr nz,CheckWin
 ret

Flipped:
 ld hl,Board
 ret
Flipped2:
 ld hl,BoardEnd
 ret

CheckSquares:
 ld hl,Board
 ld a,(boardflip)
 cp 2
 call z,Flipped2
 ld b,8
CheckB:
 ld a,(hl)
 cp 2
 call z,NewBK
 inc hl
 djnz CheckB
 ld hl,BoardEnd
 ld a,(boardflip)
 cp 2
 call z,Flipped
 ld b,8
CheckW:
 ld a,(hl)
 cp 1
 call z,NewWK
 inc hl
 djnz CheckW
 ret

NewWK:
 ld (hl),3
 ret

NewBK:
 ld (hl),4
 ret


PutSprite:
	ld      DE, GRAPH_MEM
convdone:
	ld      A, 63
	sub     C
	ld      C, A
	push    HL
	call    FIND_PIXEL
	add     HL, DE
	ex      DE, HL
	pop     HL
	ld      B, 8
	ld      C, 8
	push    HL
	pop     IX
	ex      DE, HL
PS_NewRow:
	push    BC
	ld      D, (IX)
	inc     IX
	push    AF
	push    HL
PS_NewCol:
	rl      D
	ld      E, A
	jr      nc, PS_NextPixel
	xor     (HL)
	ld      (HL), A
PS_NextPixel:
	ld      A, E
	rrca
	jr      nc, PS_SameByte
	inc     HL
PS_SameByte:
	djnz    PS_NewCol
	pop     HL
	pop     AF
	ld      DE, 12
	add     HL, DE
	pop     BC
	dec     C
	jr      nz, PS_NewRow
      ret

JFLAGS:
 ld a,(jflag)
 or a
 ret z
JJ
 set 7,(iy+$14)
 ld hl,Alpha
 ld de,$2346
 call DMX
 ld d,$29
 inc e
 inc e
 call DMX
 dec e
 ld d,$2F
 jp P2

DMX:
 ld (pencol),de
 bcall(_vputs)
 ret

DTX:
 ld (currow),de
 bcall(_puts)
 ret

WaitTxt:
 .db "Waiting...",0

Title:
 .db "Programmed by:",0
 .db "Sam Heald",0
 .db "Board Flipping - "
toggle_text:
 .db "YES",0
 .db "Two Players - 1 calculator",0
 .db "Two Players - 2 calculator",0

t_yes:
 .db "YES",0
t_no:
 .db "NO ",0

toggle:
 .db 0


Alpha:
 .db "ALPHA",0
 .db "ends",0
 .db "move",0

WhiteTurn:
 .db "White's",0
 .db 0
WT:
 .db "Turn",0
BlackTurn:
 .db "  Black's  ",0
 .db 0
BT:
 .db "      Turn      ",0
OWin:
 .db "Black Wins",0
TWin:
 .db "White Wins",0

Board2:
 .db 9,1,9,1,9,1,9,1
 .db 1,9,1,9,1,9,1,9
 .db 9,1,9,1,9,1,9,1
 .db 0,9,0,9,0,9,0,9
 .db 9,0,9,0,9,0,9,0
 .db 2,9,2,9,2,9,2,9
 .db 9,2,9,2,9,2,9,2
 .db 2,9,2,9,2,9,2,9

Space:
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111
 .db %11111111

HiLite:
 .db %11111111
 .db %10000001
 .db %10000001
 .db %10000001
 .db %10000001
 .db %10000001
 .db %10000001
 .db %11111111

White:
 .db %11111111
 .db %11100111
 .db %11000011
 .db %10000001
 .db %10000001
 .db %11000011
 .db %11100111
 .db %11111111

Black:
 .db %11111111
 .db %11100111
 .db %11011011
 .db %10111101
 .db %10111101
 .db %11011011
 .db %11100111
 .db %11111111

WhiteK:
 .db %11111111
 .db %10100101
 .db %11000011
 .db %10000001
 .db %10000001
 .db %11000011
 .db %10100101
 .db %11111111

BlackK:
 .db %11111111
 .db %10100101
 .db %11011011
 .db %10111101
 .db %10111101
 .db %11011011
 .db %10100101
 .db %11111111

SideBar:
 .db %01111111,%11111111,%11111111,%11111111
 .db %01100101,%11111111,%10111111,%11111111
 .db %01011100,%11101110,%10111101,%10101001
 .db %01011101,%01010101,%10101010,%10011011
 .db %01011101,%01001101,%10011001,%10111101
 .db %01100101,%01100110,%10101100,%10111001
 .db %01111111,%11111111,%11111111,%11111111

LD_HL_MHL:
 push de
 ld e,(hl)
 inc hl
 ld d,(hl)
 pop hl
 ex de,hl
 ret

;-------------------------------------------------------------------------------
;FIND_PIXEL Routine, by Patrick Davidson [From Zkart3d 82]
;-------------------------------------------------------------------------------
FIND_PIXEL_DATA:
         .db      128,64,32,16,8,4,2,1
FIND_PIXEL:
         push     bc
	   push     de
         ld       a,b
         and      7
         ld       hl,FIND_PIXEL_DATA
         ld       e,a
         ld       d,0
         add      hl,de
         ld       e,(hl)            ; E = pixel mask
         ld       a,63
         sub      c
         ld       c,a
         add      a,a
         add      a,c               ; A = 3 * Y
         ld       l,a
         ld       h,0
         add      hl,hl
         add      hl,hl             ; HL = 12 * Y
         ld       a,b
         ld       b,0
         rrca
         rrca
         rrca
         and      15
         ld       c,a
         add      hl,bc
         ld       a,e               ; A = pixel mask
         pop      de
         pop      bc
         ret

#ifdef TI83P
.include "linkrout.h"

#else
.include "link83.h"
#endif

.end


