;Chris Otto     Andy Boyd

;Chess Logic
 

;;***************************************

;;***** Final Project on 8515 *************

;;***************************************

;Fully interrupt driven

;Strings can come from flash or RAM.
 
 

.include "c:\users\ca\4414def.inc"
 
 

.device AT90S8515
 

.def save =r1  ;saves the SREG in ISRs

.def reload =r2  ;timer 0 interval

.def lcdstat =r3
.def key  =r4

.def tstartrow =r5
.def tstartcol =r6
.def tendrow   =r7
.def tendcol   =r8
 

.def temp =r16 ;temporary register

.def charcnt =r17 ;a counter to use in message

.def savSREG =r15 ;save the status register

.def TXbusy =r19 ;transmit busy flag

.def RXchar =r20 ;a received character

.def TXflash =r21 ;text to be sent is in flash if <>0

.def TXram =r22 ;recieved counter
.def timeout =r23
.def temp2 =r24
.def butnum =r25 ;input number in hex
.def temp3 =r26
 

;-------------------------------------------------
;tic tac toe registers
;-------------------------------------------------
.def Xreg1 =r27
.def Xreg2 =r28
.def Yreg1 =r29
.def Yreg2 =r30
.def currentmove=r20
 
 

;-------------------------------------------------
;Chess Registers
;-------------------------------------------------
.def startrow=r27
.def endrow =r28
.def startcol=r29
.def endcol =r18
.def type =r10
.def color =r11
.def whoturn =r17
.def valid =r12
 
 
 

;***** Other equates

.equ lcdrs =PD6  ;LCD rs pin connected to PD6

.equ lcdrw =PD5  ;LCD r/w pin connected to PD5

.equ lcde =PD4  ;LCD e pin connected to PD4

.equ baud96 =25 ;9600 baud constant for 4Mhz crystal

.equ white ='w'
.equ black ='b'

.equ pawn ='P'

.equ rook ='R'

.equ knight ='K'
.equ bishop ='B'
.equ king ='U'
.equ queen ='Q'
 
 

;**************************************

.dseg
 
 

;define variable strings to be tranmitted from RAM

board: .byte 3 ;board counter
tic0: .byte 2 ;boardnumber
tic1: .byte 6 ;first tic row + a zero terminate
tic2: .byte 6 ;second tic row + a zero terminate
tic3: .byte 6 ;third tic row + a zero terminate

chess1: .byte 26 ;1 row chess
chess2: .byte 26 ;2 row chess
chess3: .byte 26 ;3 row chess
chess4: .byte 30 ;4 row chess
chess5: .byte 30 ;5 row chess
chess6: .byte 30 ;6 row chess
chess7: .byte 30 ;7 row chess
chess8: .byte 30 ;8 chess
 
 

;**************************************

.cseg
 
 

.org $0000

 rjmp  RESET ;reset entry vector

 reti

 reti

 reti

 reti

 reti

 reti

 rjmp t0int

 reti

 rjmp RXdone ;UART receive done

 rjmp TXempty ;UART buffer empty

 rjmp  TXdone ;UART transmit done

 reti
 
 

;define fixed strings to be tranmitted from flash- zero terminated

ticln: .db "-----", 0x00
chln: .db "--------------------------", 0x00
colln: .db " | 1| 2| 3| 4| 5| 6| 7| 8", 0x00

crlf: .db 0x0d, 0x0a, 0x00 ;carrage return/line feed

;The following table is used to convert raw button-press high/low

;values to a sequence number. Invalid codes caused by multiple

;button presses are ignored.

keytbl: .db 0b11101110, 0b11101101, 0b11101011, 0b11100111

 .db 0b11011110, 0b11011101, 0b11011011, 0b11010111

 .db 0b10111110, 0b10111101, 0b10111011, 0b10110111

 .db 0b01111110, 0b01111101, 0b01111011, 0b01110111
 

asciikey:
 .db "123A456B789C*0#D"

welcome:
 .db "A-Tic B-Chess",0x00
invalid:
 .db "Not a valid move-",0x00
xmove: .db "X make a move",0x00

ymove: .db "O make a move",0x00
wmoverow:
 .db "white-row: ",0x00
bmoverow:
 .db "black-row: ",0x00

movecol:
 .db " column: ",0x00
endpoint1:
 .db " where to-row: ",0x00
endpoint2:
 .db " column: ",0x00
cats: .db "Tie - Cats Game",0x00
xwin: .db "X WINS!", 0x00
ywin: .db "O WINS!", 0x00
 
 

RESET: ldi temp, LOW(RAMEND) ;setup stack pointer

 out  SPL, temp

 ldi temp, HIGH(RAMEND)

 out SPH, temp
 
 

 ser Temp
 out DDRB, Temp
 ldi Temp,0x00
 out PortB, Temp
 

        ;set up timer 0 for 1 mSec ticks
 
 
        ldi     Temp, 3         ;prescale timer by 64
        out     TCCR0, Temp
        ldi     temp,256-62   ;preload timer since
        out     TCNT0, temp   ;62.5 x (64x.25) microSec = 1.0 mSec.
 ldi Temp, 0b00000010
 out     TIMSK, Temp
 

 ;initial conditions

 

 clr TXbusy  ;start out not busy on TX
 
 
 

 ;setup UART -- enable TXempty & RXdone int, and RX, TX pins

 ldi  temp, 0b10111000

 out  UCR, temp

 ;set baud rate to 9600

 ldi temp, baud96

 out UBRR, temp
 

 ;intialize text pointer BEFORE turning on interrupts
 ;because RESET causes the TX empty flag to be SET
 ldi ZL, LOW(ticln<<1) ;do shift to convert word-addr to byte
 ldi  ZH, HIGH(ticln<<1)

 
 
 

;---------------------------------------------------------------------------------------
;initial tic-tac-toe board and chess board
;---------------------------------------------------------------------------------------
.include "c:\users\ca\initial.asm"
 
 sei

 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

;----------------------------------------------------------------------------------------
;this is where we start
;----------------------------------------------------------------------------------------
 
Begin:
 ldi ZL, LOW(welcome<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(welcome<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 
choose: rcall getkey
 ldi timeout, 255
 rcall delay
 ldi timeout, 255
 rcall delay
 cpi RXchar,'A'
 breq TicTacToeinit
 cpi RXchar,'B'
 breq Chessinit
 rjmp choose

TicTacToeinit:
Chessinit:
 clr startrow
 clr endrow
 clr startcol
 clr endcol
 clr color
 clr type
 rcall PrCheBd
 rjmp whiteturn ;whiteturn
 
;-------------------------------------------------------------
;Chess Logic
;-------------------------------------------------------------

whiteturn:
 ;setup ptr for <white's move> string
 ldi ZL, LOW(wmoverow<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(wmoverow<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay

 rcall getkey
 mov startrow, RXchar
 out UDR,startrow
 subi startrow,0x30
 
 
 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay

 ldi ZL, LOW(movecol<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(movecol<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 rcall getkey
 mov startcol,RXchar
 out UDR,startcol
 subi startcol,0x30
 
 ldi whoturn,white
 clr valid
 rcall lookup
 ldi temp,0x00
 cp valid,temp
 brne wnotvalid
 
midw: ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 out UDR,color
 ldi timeout,30
 rcall delay
 out UDR,type
 ldi timeout,30
 rcall delay

 ldi ZL, LOW(endpoint1<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(endpoint1<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 
 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay
 

 rcall getkey
 mov endrow,RXchar
 out UDR,endrow
 subi endrow,0x30

 ldi ZL, LOW(endpoint2<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(endpoint2<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay
 

 rcall getkey
 mov endcol,RXchar
 out UDR,endcol
 subi endcol,0x30

 clr valid
 rcall chsval
 ldi temp,0x00
 cp valid,temp
 brne wnotvalid

 rcall CheBdUpdate

 rcall PrCheBd

 rjmp blackturn

wnotvalid:
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi ZL, LOW(invalid<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(invalid<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 ldi timeout,255
 rcall delay

 ldi temp,25
 cp valid,temp
 breq midwturn
 rjmp whiteturn

midwturn:rjmp midw

blackturn:
 ;setup ptr for <white's move> string
 ldi ZL, LOW(bmoverow<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(bmoverow<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 rcall getkey
 mov startrow, RXchar
 out UDR,startrow
 subi startrow,0x30
 
 
 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay

 ldi ZL, LOW(movecol<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(movecol<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay
 
 rcall getkey
 mov startcol,RXchar
 out UDR,startcol
 subi startcol,0x30
 
 ldi whoturn,black
 clr valid
 rcall lookup
 ldi temp,0x00
 cp valid,temp
 brne bnotvalid
 
midb: ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 out UDR,color
 ldi timeout,30
 rcall delay
 out UDR,type
 ldi timeout,30
 rcall delay

 ldi ZL, LOW(endpoint1<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(endpoint1<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 
 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay
 

 rcall getkey
 mov endrow,RXchar
 out UDR,endrow
 subi endrow,0x30

 ldi ZL, LOW(endpoint2<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(endpoint2<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi timeout,255
 rcall  delay
 ldi timeout,255
 rcall  delay
 

 rcall getkey
 mov endcol,RXchar
 out UDR,endcol
 subi endcol,0x30
 
 clr valid
 rcall chsval
 ldi temp,0x00
 cp valid,temp
 brne bnotvalid
 
 rcall CheBdUpdate
 rcall PrCheBd
 rjmp whiteturn

bnotvalid:
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ldi ZL, LOW(invalid<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(invalid<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 ldi timeout,255
 rcall delay
 
 ldi temp,25
 cp valid,temp
 breq midbturn
 rjmp blackturn
midbturn:rjmp midb

lookup: cpi startrow,8
 breq sr8
 cpi startrow,7
 breq sr7
 cpi startrow,6
 breq sr6
 cpi startrow,5
 breq sr5
 cpi startrow,4
 breq sr4
 cpi startrow,3
 breq sr3
 cpi startrow,2
 breq sr2
 cpi startrow,1
 breq sr1
 ldi temp,1
 mov  valid,temp
 ret
sr8: ldi ZL,LOW(chess8)
 ldi ZH,HIGH(chess8)
 rjmp getpiece
sr7: ldi ZL,LOW(chess7)
 ldi ZH,HIGH(chess7)
 rjmp getpiece
sr6: ldi ZL,LOW(chess6)
 ldi ZH,HIGH(chess6)
 rjmp getpiece
sr5: ldi ZL,LOW(chess5)
 ldi ZH,HIGH(chess5)
 rjmp getpiece
sr4: ldi ZL,LOW(chess4)
 ldi ZH,HIGH(chess4)
 rjmp getpiece
sr3: ldi ZL,LOW(chess3)
 ldi ZH,HIGH(chess3)
 rjmp getpiece
sr2: ldi ZL,LOW(chess2)
 ldi ZH,HIGH(chess2)
 rjmp getpiece
sr1: ldi ZL,LOW(chess1)
 ldi ZH,HIGH(chess1)
 rjmp getpiece
getpiece:
 subi startcol,1
 clr temp
 add temp,startcol
 add temp,startcol
 add temp,startcol
 subi startcol,-1
 ld temp2,z  ;get rid of first two stored terms
 st z+,temp2
 ld temp2,z
 st z+,temp2
notyet: cpi temp,0
 breq here
 ld temp2,z
 st z+,temp2
 dec temp
 rjmp notyet
here: ld color,z
 cp color,whoturn
 breq notdifcol
 ldi temp,1
 mov valid,temp
 ret
notdifcol:
 ldi temp,0x20
 st z+,temp
 ld type,z
 st z,temp
 ret

CheBdUpdate:
;add piece to new line
 cpi endrow,8
 breq sr28
 cpi endrow,7
 breq sr27
 cpi endrow,6
 breq sr26
 cpi endrow,5
 breq sr25
 cpi endrow,4
 breq sr24
 cpi endrow,3
 breq sr23
 cpi endrow,2
 breq sr22
 cpi endrow,1
 breq sr21
 ret
sr28: ldi ZL,LOW(chess8)
 ldi ZH,HIGH(chess8)
 rjmp gp2
sr27: ldi ZL,LOW(chess7)
 ldi ZH,HIGH(chess7)
 rjmp gp2
sr26: ldi ZL,LOW(chess6)
 ldi ZH,HIGH(chess6)
 rjmp gp2
sr25: ldi ZL,LOW(chess5)
 ldi ZH,HIGH(chess5)
 rjmp gp2
sr24: ldi ZL,LOW(chess4)
 ldi ZH,HIGH(chess4)
 rjmp gp2
sr23: ldi ZL,LOW(chess3)
 ldi ZH,HIGH(chess3)
 rjmp gp2
sr22: ldi ZL,LOW(chess2)
 ldi ZH,HIGH(chess2)
 rjmp gp2
sr21: ldi ZL,LOW(chess1)
 ldi ZH,HIGH(chess1)
 rjmp gp2
gp2: subi endcol,1
 clr temp
 add temp,endcol
 add temp,endcol
 add temp,endcol
 ld temp2,z  ;get rid of first two stored terms
 st z+,temp2
 ld temp2,z
 st z+,temp2
ny2: cpi temp,0
 breq h2
 ld temp2,z
 st z+,temp2
 dec temp
 rjmp ny2
h2: st z+,color
 st z,type
 ret

;----------------------------------------------------------------------------------------
;Print Board for Chess
;----------------------------------------------------------------------------------------

 PrCheBd:
 ;print chess board
 ;setup ptr for <crlf> string

 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ;setup ptr for <crlf> string
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 
 ;setup ptr for < | 1| 2| 3...> string
 ldi ZL, LOW(colln<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(colln<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt
 rcall TXwait

 rcall Cheline

 ;line1
 ldi ZL, LOW(chess1)
 ldi ZH, HIGH(chess1)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline

 ;line2
 ldi ZL, LOW(chess2)
 ldi ZH, HIGH(chess2)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline

 ;line3
 ldi ZL, LOW(chess3)
 ldi ZH, HIGH(chess3)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait
 
 rcall  Cheline

 ;line4
 ldi ZL, LOW(chess4)
 ldi ZH, HIGH(chess4)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline

 ;line5
 ldi ZL, LOW(chess5)
 ldi ZH, HIGH(chess5)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline

 ;line6
 ldi ZL, LOW(chess6)
 ldi ZH, HIGH(chess6)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline

 ;line7
 ldi ZL, LOW(chess7)
 ldi ZH, HIGH(chess7)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait

 rcall Cheline
 
 ;line8
 ldi ZL, LOW(chess8)
 ldi ZH, HIGH(chess8)
 ld r0, Z
 out UDR, r0
 clr TXflash
 ser TXbusy
 sbi UCR, UDRIE
 rcall TXwait
 

 ;setup ptr for <crlf> string
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait

 ret
 
Cheline:
 ;setup ptr for <crlf> string
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 

 ;setup ptr for <----> string
 ldi ZL, LOW(chln<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(chln<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt
 rcall TXwait

 ;setup ptr for <crlf> string
 ldi ZL, LOW(crlf<<1)  ;shifted becuase pgm memory is words

 ldi ZH, HIGH(crlf<<1)

 lpm

 out UDR, r0  ;trigger the UART TX

 ser TXflash  ;text string in flash memory

 ser TXbusy  ;and set the TX busy flag

 sbi UCR, UDRIE ;enable the TXempty interrupt

 rcall TXwait
 ret
;************************************************************************************************

;interrupt routines

;************************************************************************************************
 

sendTxt:
 tst TXram
 brne _sndRAM
 lpm
 rjmp _sndFLSH
_sndRAM: ld r0,Z
_sndFlsh:tst r0
 breq _sndEND
 cpi charcnt,8
 brne _writit
 ldi temp, 0xC0
 ;rcall lcdcmd
_writit:mov temp, r0
 ;rcall lcdput
 inc charcnt
 adiw ZL,1
 rjmp sendTxt
_sndEND:ret

; UART needs a character

TXempty:in savSREG, SREG ;save processor status

 tst TXflash  ;Is the string in flash memory?

 breq TXram  ;If not, it is in RAM

 inc ZL  ;get the next char from flash

 lpm   ;and put it in r0

 rjmp TXfls

TXram:  inc ZL  ;get the next char from RAM

 ld r0,Z

TXfls: tst r0  ;if char is zero then exit

 breq TXend

 out  UDR, r0  ;otherwise transmit it

 rjmp TXexit  ;exit until next char

TXend: clr TXbusy  ;no more chars

 cbi UCR, UDRIE ;clear the TXempty interrupt

TXexit: out SREG, savSREG ;restore proc status

 reti   ;back to pgm
 
 

; TX done -- buffer is empty  -- unused here

TXdone: in savSREG, SREG ;save processor status

 out SREG, savSREG ;restore proc status

 reti   ;back to pgm
 
 

; UART read a character

RXdone: in savSREG, SREG ;save processor status

 in RXchar, UDR ;get the character

 out SREG, savSREG ;restore proc status

 reti   ;back to pgm
 
 

;*****************************

;subroutine
 
 

TXwait: tst TXbusy  ;now wait for the tranmission to finish

 brne TXwait

 ret
 
 

;****************getkey function*******************************
getkey:
 push temp
 push temp2
loop:  clr temp2
 ldi  timeout,30
 rcall delay
 ldi temp, 0x0f ;set lower four lines to output
 out  DDRA, temp
 ldi temp, 0xf0 ;and turn on the pullups on the inputs
 out PORTA, temp
 nop   ;Need some time for the pullups to
 nop   ;charge the port pins
 nop
 nop
 in temp, PINA ;read the high nibble
 mov key, temp ;and store it (with zeros in the low nibble)
 

  ldi temp, 0xf0 ;set upper four lines to outputs
 out  DDRA, temp
 ldi temp, 0x0f ;and turn on pullups on the inputs
 out PORTA, temp
 
 nop   ;As before wait for the pin to charge
 nop
 nop
 nop
 in temp, PINA ;read the low nibble
 or key, temp ;combine to make key code
 ldi temp,0xff
 cp key,temp
 breq illegal
 
 ;At the point the raw key code should have exactly one zero each in
 ;the lower and upper nibbles. Any other number of zeros indicates
 ;either no-button pressed or multiple-button pressed.

 ;Now search the table for a match to the raw key code
 ;and exit with a button number
 
 ldi ZL, low(keytbl*2) ;table pointer in FLASH
 ldi ZH, high(keytbl*2) ;so convert from word to byte addr
 ldi butnum, 0
tbllp:  lpm   ;get the table entry
 cp key, r0  ;match?
 breq foundit
 inc butnum  ;if not, have we exhaused the
 cpi butnum, 0x10 ;table
 breq illegal
 adiw ZL, 1  ;if not, get the next table entry
 rjmp tbllp

foundit:;now lookup from ascii table
 ldi ZL, low(asciikey*2) ;table pointer in FLASH
 ldi ZH, high(asciikey*2) ;so convert from word to byte addr
 clr  temp
 add ZL,butnum
 adc ZH,temp
 lpm
 mov RXchar,r0
 out  PORTB, butnum
 pop temp2
 pop temp
 ret

illegal:;nothing found, return to waiting
 tst temp2
 brne _getdone
 rjmp loop
 
_getdone:
 pop temp2
 pop temp
 ret
 
 
 
 

;=============================================

; subroutine waits for time equal to value in register timeout

;the register 'timeout' should be loaded before the call
 
 
 

delay: tst timeout

 brne delay
 

 ret
 
 

;=============================================
 

;***** Timer 0 overflow interrupt handler
 

;timer 0 ISR (timer-zero overflow)

;Enters every 1.0 mSec
 
 

t0int: in save, SREG
 push temp
 ldi temp,256-62

 out  TCNT0, temp; keeps clock ticking at 1 mSec
 
 

 dec  timeout  ;subtract another mSec
 
 

 out SREG, save
 pop temp

 reti   ;back to backgound tasks
 
 

;----------------------------------------------------------------------------
;check for valid chess moves
;----------------------------------------------------------------------------

chsval: mov tstartrow,startrow
 mov tendrow,endrow
 mov tstartcol,startcol
 mov tendcol,endcol
 ldi temp,'-'
 out UDR,temp
 ldi timeout,35
 rcall delay
 ldi temp,0x30
 add temp,startrow
 out UDR,temp
 ldi timeout,35
 rcall delay
 ldi temp,0x30
 add temp,startcol
 out UDR,temp
 ldi timeout,35
 rcall delay
 ldi temp,0x30
 add temp,endrow
 out UDR,temp
 ldi timeout,35
 rcall delay
 ldi temp,0x30
 add temp,endcol
 out UDR,temp
 ldi timeout,35
 rcall delay
 

 ldi temp,rook
 cp type, temp
 breq vR
 ldi temp,knight
 cp type, temp
 breq vK
 ldi temp,bishop
 cp type, temp
 breq vB
 ldi temp,king
 cp type, temp
 breq vUU
 ldi temp,queen
 cp type, temp
 breq vQ
 rjmp vP
vUU: rjmp vU
;--------------------------------------------------------
; KNIGHT
;--------------------------------------------------------
vK: subi startrow, 2  ;Knight moves 2 spaces then one space
 cp startrow, endrow
 breq Kup   ;2 space move in up-down direction
 subi startrow, -4
 cp startrow, endrow
 breq Kup
 subi startrow, 2
 subi startcol, 2
 cp startcol, endcol ;2 space move in right-left direction
 breq Kside
 subi startcol, -4
 cp startcol, endcol
 breq Kside
 rjmp bad   ;bad move
Kup: subi startcol, 1
 cp startcol, endcol ;1 space move right
 breq kgood
 subi startcol, -2
 cp startcol, endcol ;1 space move left
 breq kgood
 rjmp bad   ;bad move
Kside: subi startrow, 1
 cp startrow, endrow ;1 space move up
 breq kgood
 subi startrow, -2
 cp startrow, endrow ;1 space move down
 breq kgood
 rjmp bad   ;bad move
kgood: rjmp good
;--------------------------------------------------------
; ROOK
;--------------------------------------------------------
vR: cp startrow, endrow ;move in left-right direction
 breq good
 cp startcol, endcol ;move in up-down direction
 breq good
 rjmp bad
;--------------------------------------------------------
; BISHOP
;--------------------------------------------------------
vB: mov temp, startcol
 mov temp2, startrow
 sub temp, endcol  ;find number of cols moved
 sub temp2, endrow  ;find number of rows moved
 cp temp, temp2  ;must be equal for valid move
 breq good
 sub startcol, endcol
 sub endrow, startrow
 cp startcol, endrow
 breq good
 rjmp bad   ;bad move
;--------------------------------------------------------
; QUEEN
;--------------------------------------------------------
vQ: cp startrow, endrow ;check if move in left-right direction
 breq good
 cp startcol, endcol ;check if move in up-down direction
 breq good
 mov temp, startcol
 mov temp2, startrow  ;check if diagonal
 sub temp, endcol  ;find number of cols moved
 sub temp2, endrow  ;find number of rows moved
 cp temp, temp2  ;must be equal for valid move
 breq good
 sub startcol, endcol
 sub endrow, startrow
 cp startcol, endrow
 breq good
 rjmp bad
;--------------------------------------------------------
; KING
;--------------------------------------------------------
vU: cp startcol, endcol ;check for up-down move
 breq vplus
 cp startrow, endrow ;check for left-right move
 breq vplus
 sub startcol, endcol
 sub startrow, endrow
 cpi startcol, 1  ;check for diagonal moves
 breq good
 cpi startcol, -1
 breq good
 cpi startrow, 1
 breq good
 cpi startrow, -1
 breq good
 rjmp bad   ;bad move
vplus: sub startcol, endcol ;movement in 1 unit plus sign shape
 sub startrow, endrow
 cpi startcol, 1  ;check for 1 unit moves
 breq good
 cpi startcol, -1
 breq good
 cpi startrow, 1
 breq good
 cpi startrow, -1
 breq good
 rjmp bad
;--------------------------------------------------------
; GOOD MOVE
;--------------------------------------------------------
good: mov startrow, tstartrow
 mov endrow, tendrow
 mov startcol, tstartcol
 mov endcol, tendcol
 cp startrow, endrow ;check to see if piece actually moved anywhere
 brne good2
 cp startcol, endcol
 brne good2
 rjmp bad

good2: clr valid   ;move is good
 
 ret

bad: mov startrow, tstartrow
 mov endrow, tendrow
 mov startcol, tstartcol
 mov endcol, tendcol
 ldi temp,25
 mov valid,temp
 ret
 
;--------------------------------------------------------
; PAWN
;--------------------------------------------------------
vP: cp startcol, endcol
 breq Pup   ;pawn moved up
 subi startcol, -1
 cp startcol, endcol
 breq Pdiag   ;pawn moved diag right
 subi startcol, 2
 cp startcol, endcol
 breq Pdiag   ;pawn moved diag left
 rjmp bad
Pup: subi startrow, -1
 cp startrow, endrow ;legal down move
 breq good
 subi startrow, 2
 cp startrow, endrow
 breq good
 rjmp bad
Pdiag: subi startrow, -1
 cp startrow, endrow ;legal diag move
 breq good   ;NEED TO ADD CHECKING FOR PIECE TAKEN, ELSE MOVE IS ILLEGAL
 subi startrow, 2
 cp startrow, endrow ;legal diag move
 breq good   ;NEED TO ADD CHECKING FOR PIECE TAKEN, ELSE MOVE IS ILLEGAL
 rjmp bad