;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