1133 lines
20 KiB
NASM
1133 lines
20 KiB
NASM
|
|
; MicroChess (c) 1976-2002 Peter Jennings, peterj@benlo.com
|
|
|
|
; this version for the integrated macroassembler, simulator and debugger for
|
|
; 650x microprocessor family by Michal Kowalski http://home.pacbell.net/michal_k/
|
|
|
|
; additions and changes by Lee Davison http://members.lycos.co.uk/leeedavison/
|
|
; from suggested ASCII routines in the KIM MicroChess programmers notes
|
|
|
|
; this version is posted with permission of Peter Jennings, peterj@benlo.com
|
|
|
|
; display flash during compute move replaced by '?' prompt flash
|
|
; piece display changed to display piece at 'to' square after each move
|
|
|
|
; Simulator I/O addresse is $F000
|
|
; Simulator window size is 64 columns x 20 rows
|
|
|
|
IO_AREA = $F000
|
|
|
|
ACIAsimwr = IO_AREA+$01
|
|
ACIAsimrd = IO_AREA+$04
|
|
DispPosX = IO_AREA+$05
|
|
DispPosY = IO_AREA+$06
|
|
|
|
; page zero variables
|
|
|
|
BOARD = $50
|
|
BK = $60
|
|
PIECE = $B0
|
|
SQUARE = $B1
|
|
SP2 = $B2
|
|
SP1 = $B3
|
|
INCHEK = $B4
|
|
STATE = $B5
|
|
MOVEN = $B6
|
|
OMOVE = $DC
|
|
WCAP0 = $DD
|
|
COUNT = $DE
|
|
BCAP2 = $DE
|
|
WCAP2 = $DF
|
|
BCAP1 = $E0
|
|
WCAP1 = $E1
|
|
BCAP0 = $E2
|
|
MOB = $E3
|
|
MAXC = $E4
|
|
CC = $E5
|
|
PCAP = $E6
|
|
BMOB = $E3
|
|
BMAXC = $E4
|
|
_BCC = $E5 ; was BCC
|
|
BMAXP = $E6
|
|
XMAXC = $E8
|
|
WMOB = $EB
|
|
WMAXC = $EC
|
|
WCC = $ED
|
|
WMAXP = $EE
|
|
PMOB = $EF
|
|
PMAXC = $F0
|
|
PCC = $F1
|
|
PCP = $F2
|
|
OLDKY = $F3
|
|
BESTP = $FB
|
|
BESTV = $FA
|
|
BESTM = $F9
|
|
DIS1 = $FB
|
|
DIS2 = $FA
|
|
DIS3 = $F9
|
|
|
|
prompt = $FC ; prompt character, '?' or ' '
|
|
reverse = $FD ; which way round is the display board
|
|
|
|
*=$1000 ; load into RAM @ $1000 onwards
|
|
|
|
CHESS
|
|
CLD ; INITIALIZE
|
|
LDX #$FF ; TWO STACKS
|
|
TXS
|
|
LDX #$C8
|
|
STX SP2
|
|
|
|
; ROUTINES TO LIGHT LED
|
|
; DISPLAY AND GET KEY
|
|
; FROM KEYBOARD
|
|
|
|
OUT
|
|
JSR DrawBoard ; draw board
|
|
LDA #'?' ; prompt character
|
|
STA prompt ; save it
|
|
GetKey
|
|
JSR UpdateDisp ; update prompt & display
|
|
JSR asciiin ; get key press
|
|
|
|
CMP #'C' ; is it "C"
|
|
BNE NOSET ; branch if not
|
|
|
|
; else set up board
|
|
LDX #$1F ; 32 pieces to do
|
|
WHSET
|
|
LDA SETW,X ; FROM
|
|
STA BOARD,X ; SETW
|
|
DEX
|
|
BPL WHSET
|
|
|
|
LDA #$00 ; no reverse
|
|
STA reverse ; set it
|
|
|
|
LDX #$1B ; *ADDED
|
|
STX OMOVE ; INITS TO $FF
|
|
LDA #$CC ; Display CCC
|
|
BNE CLDSP
|
|
|
|
NOSET
|
|
CMP #'E' ; [E]
|
|
BNE NOREV ; REVERSE
|
|
|
|
JSR REVERSE ; BOARD IS
|
|
|
|
LDA reverse ; get reversed flag
|
|
EOR #$01 ; toggle reverse bit
|
|
STA reverse ; save flag
|
|
|
|
LDA #$EE ; IS
|
|
BNE CLDSP
|
|
|
|
NOREV
|
|
CMP #'P' ; [P]
|
|
BNE NOGO ; PLAY CHESS
|
|
|
|
JSR GO
|
|
CLDSP
|
|
STA DIS1 ; DISPLAY
|
|
LDA #$00
|
|
STA DIS2 ; ACROSS
|
|
STA DIS3 ; DISPLAY
|
|
BEQ CHESS
|
|
|
|
NOGO
|
|
CMP #$0D ; [Enter]
|
|
BNE NOMV ; MOVE MAN
|
|
|
|
JSR MOVE ; AS ENTERED
|
|
; JSR DISP2 ; piece into display
|
|
JSR DISP3 ; piece into display
|
|
JMP CHESS ; main loop
|
|
|
|
NOMV
|
|
; CMP #'Q' ; [Q] ***Added to allow game exit***
|
|
; BEQ DONE ; quit the game, exit back to system.
|
|
|
|
; removed from simulator version as no system!
|
|
|
|
JMP INPUT ; process move
|
|
;DONE
|
|
; JMP $FF00 ; *** MUST set this to YOUR OS starting address
|
|
|
|
; THE ROUTINE JANUS DIRECTS THE
|
|
; ANALYSIS BY DETERMINING WHAT
|
|
; SHOULD OCCUR AFTER EACH MOVE
|
|
; GENERATED BY GNM
|
|
|
|
JANUS
|
|
LDX STATE
|
|
BMI NOCOUNT
|
|
|
|
; THIS ROUTINE COUNTS OCCURRENCES
|
|
; IT DEPENDS UPON STATE TO INDEX
|
|
; THE CORRECT COUNTERS
|
|
|
|
COUNTS
|
|
LDA PIECE
|
|
BEQ OVER ; IF STATE=8
|
|
CPX #$08 ; DO NOT COUNT
|
|
BNE OVER ; BLK MAX CAP
|
|
CMP BMAXP ; MOVES FOR
|
|
BEQ XRT ; WHITE
|
|
|
|
OVER
|
|
INC MOB,X ; MOBILITY
|
|
CMP #$01 ; + QUEEN
|
|
BNE NOQ ; FOR TWO
|
|
INC MOB,X
|
|
|
|
NOQ
|
|
BVC NOCAP
|
|
LDY #$0F ; CALCULATE
|
|
LDA SQUARE ; POINTS
|
|
ELOOP
|
|
CMP BK,Y ; CAPTURED
|
|
BEQ FOUN ; BY THIS
|
|
DEY ; MOVE
|
|
BPL ELOOP
|
|
FOUN
|
|
LDA POINTS,Y
|
|
CMP MAXC,X
|
|
BCC LESS ; SAVE IF
|
|
STY PCAP,X ; BEST THIS
|
|
STA MAXC,X ; STATE
|
|
|
|
LESS
|
|
CLC
|
|
PHP ; ADD TO
|
|
ADC CC,X ; CAPTURE
|
|
STA CC,X ; COUNTS
|
|
PLP
|
|
|
|
NOCAP
|
|
CPX #$04
|
|
BEQ ON4
|
|
BMI TREE ; (=00 ONLY)
|
|
XRT
|
|
RTS
|
|
|
|
; GENERATE FURTHER MOVES FOR COUNT
|
|
; AND ANALYSIS
|
|
|
|
ON4
|
|
LDA XMAXC ; SAVE ACTUAL
|
|
STA WCAP0 ; CAPTURE
|
|
LDA #$00 ; STATE=0
|
|
STA STATE
|
|
JSR MOVE ; GENERATE
|
|
JSR REVERSE ; IMMEDIATE
|
|
JSR GNMZ ; REPLY MOVES
|
|
JSR REVERSE
|
|
|
|
LDA #$08 ; STATE=8
|
|
STA STATE ; GENERATE
|
|
JSR GNM ; CONTINUATION
|
|
JSR UMOVE ; MOVES
|
|
|
|
JMP STRATGY ; FINAL EVALUATION
|
|
NOCOUNT
|
|
CPX #$F9
|
|
BNE TREE
|
|
|
|
; DETERMINE IF THE KING CAN BE
|
|
; TAKEN, USED BY CHKCHK
|
|
|
|
LDA BK ; IS KING
|
|
CMP SQUARE ; IN CHECK?
|
|
BNE RETJ ; SET INCHEK=0
|
|
LDA #$00 ; IF IT IS
|
|
STA INCHEK
|
|
RETJ
|
|
RTS
|
|
|
|
; IF A PIECE HAS BEEN CAPTURED BY
|
|
; A TRIAL MOVE, GENERATE REPLIES &
|
|
; EVALUATE THE EXCHANGE GAIN/LOSS
|
|
|
|
TREE
|
|
BVC RETJ ; NO CAP
|
|
LDY #$07 ; (PIECES)
|
|
LDA SQUARE
|
|
LOOPX
|
|
CMP BK,Y
|
|
BEQ FOUNX
|
|
DEY
|
|
BEQ RETJ ; (KING)
|
|
BPL LOOPX ; SAVE
|
|
FOUNX
|
|
LDA POINTS,Y ; BEST CAP
|
|
CMP BCAP0,X ; AT THIS
|
|
BCC NOMAX ; LEVEL
|
|
STA BCAP0,X
|
|
NOMAX
|
|
DEC STATE
|
|
LDA #$FB ; IF STATE=FB
|
|
CMP STATE ; TIME TO TURN
|
|
BEQ UPTREE ; AROUND
|
|
JSR GENRM ; GENERATE FURTHER
|
|
UPTREE
|
|
INC STATE ; CAPTURES
|
|
RTS
|
|
|
|
; THE PLAYER'S MOVE IS INPUT
|
|
|
|
INPUT
|
|
SEC ; set for subtract
|
|
SBC #'0' ; convert ASCII # to binary
|
|
|
|
CMP #$08 ; NOT A LEGAL
|
|
BCS ERROR ; SQUARE #
|
|
|
|
JSR DISMV
|
|
JSR DISP2 ; put piece into display
|
|
ERROR
|
|
JMP GetKey ; go update move display and wait for next key
|
|
; JMP CHESS
|
|
|
|
DISP3
|
|
LDA DIS3 ; get position
|
|
.byte $2C ; make next LDA into BIT xxxx
|
|
DISP2
|
|
LDA DIS2 ; get position
|
|
LDX #$1F
|
|
SEARCH
|
|
CMP BOARD,X ; compare with this piece's position
|
|
; LDA BOARD,X
|
|
; CMP DIS2
|
|
BEQ HERE ; DISPLAY
|
|
DEX ; PIECE AT
|
|
BPL SEARCH ; FROM
|
|
LDX #$BB ; blank square if no matching piece
|
|
HERE
|
|
STX DIS1 ; SQUARE
|
|
STX PIECE
|
|
RTS
|
|
|
|
; GENERATE ALL MOVES FOR ONE
|
|
; SIDE, CALL JANUS AFTER EACH
|
|
; ONE FOR NEXT STE?
|
|
|
|
GNMZ
|
|
LDX #$10 ; CLEAR
|
|
GNMX
|
|
LDA #$00 ; COUNTERS
|
|
CLEAR
|
|
STA COUNT,X
|
|
DEX
|
|
BPL CLEAR
|
|
|
|
GNM
|
|
LDA #$10 ; SET UP
|
|
STA PIECE ; PIECE
|
|
NEWP
|
|
DEC PIECE ; NEW PIECE
|
|
BPL NEX ; ALL DONE?
|
|
RTS ; #NAME?
|
|
|
|
NEX
|
|
JSR RESET ; READY
|
|
LDY PIECE ; GET PIECE
|
|
LDX #$08
|
|
STX MOVEN ; COMMON START
|
|
CPY #$08 ; WHAT IS IT?
|
|
BPL PAWN ; PAWN
|
|
CPY #$06
|
|
BPL KNIGHT ; KNIGHT
|
|
CPY #$04
|
|
BPL BISHOP ; BISHOP
|
|
CPY #$01
|
|
BEQ QUEEN ; QUEEN
|
|
BPL ROOK ; ROOK
|
|
|
|
KING
|
|
JSR SNGMV ; MUST BE KING!
|
|
BNE KING ; MOVES
|
|
BEQ NEWP ; 8 TO 1
|
|
QUEEN
|
|
JSR LINE
|
|
BNE QUEEN ; MOVES
|
|
BEQ NEWP ; 8 TO 1
|
|
|
|
ROOK
|
|
LDX #$04
|
|
STX MOVEN ; MOVES
|
|
AGNR
|
|
JSR LINE ; 4 TO 1
|
|
BNE AGNR
|
|
BEQ NEWP
|
|
|
|
BISHOP
|
|
JSR LINE
|
|
LDA MOVEN ; MOVES
|
|
CMP #$04 ; 8 TO 5
|
|
BNE BISHOP
|
|
BEQ NEWP
|
|
|
|
KNIGHT
|
|
LDX #$10
|
|
STX MOVEN ; MOVES
|
|
AGNN
|
|
JSR SNGMV ; 16 TO 9
|
|
LDA MOVEN
|
|
CMP #$08
|
|
BNE AGNN
|
|
BEQ NEWP
|
|
|
|
PAWN
|
|
LDX #$06
|
|
STX MOVEN
|
|
P1
|
|
JSR CMOVE ; RIGHT CAP?
|
|
BVC P2
|
|
BMI P2
|
|
JSR JANUS ; YES
|
|
P2
|
|
JSR RESET
|
|
DEC MOVEN ; LEFT CAP?
|
|
LDA MOVEN
|
|
CMP #$05
|
|
BEQ P1
|
|
P3
|
|
JSR CMOVE ; AHEAD
|
|
BVS NEWP ; ILLEGAL
|
|
BMI NEWP
|
|
JSR JANUS
|
|
LDA SQUARE ; GETS TO
|
|
AND #$F0 ; 3RD RANK?
|
|
CMP #$20
|
|
BEQ P3 ; DO DOUBLE
|
|
JMP NEWP
|
|
|
|
; CALCULATE SINGLE STEP MOVES
|
|
; FOR K,N
|
|
|
|
SNGMV
|
|
JSR CMOVE ; CALC MOVE
|
|
BMI ILL1 ; -IF LEGAL
|
|
JSR JANUS ; -EVALUATE
|
|
ILL1
|
|
JSR RESET
|
|
DEC MOVEN
|
|
RTS
|
|
|
|
; CALCULATE ALL MOVES DOWN A
|
|
; STRAIGHT LINE FOR Q,B,R
|
|
|
|
LINE
|
|
JSR CMOVE ; CALC MOVE
|
|
BCC OVL ; NO CHK
|
|
BVC LINE ; NOCAP
|
|
OVL
|
|
BMI ILL ; RETURN
|
|
PHP
|
|
JSR JANUS ; EVALUATE POSN
|
|
PLP
|
|
BVC LINE ; NOT A CAP
|
|
ILL
|
|
JSR RESET ; LINE STOPPED
|
|
DEC MOVEN ; NEXT DIR
|
|
RTS
|
|
|
|
; EXCHANGE SIDES FOR REPLY
|
|
; ANALYSIS
|
|
|
|
REVERSE
|
|
LDX #$0F
|
|
ETC
|
|
SEC
|
|
LDY BK,X ; SUBTRACT
|
|
LDA #$77 ; POSITION
|
|
SBC BOARD,X ; FROM 77
|
|
STA BK,X
|
|
STY BOARD,X ; AND
|
|
SEC
|
|
LDA #$77 ; EXCHANGE
|
|
SBC BOARD,X ; PIECES
|
|
STA BOARD,X
|
|
DEX
|
|
BPL ETC
|
|
RTS
|
|
|
|
; CMOVE CALCULATES THE TO SQUARE
|
|
; USING SQUARE AND THE MOVE
|
|
; TABLE FLAGS SET AS FOLLOWS:
|
|
; N#NAME? MOVE
|
|
; V#NAME? (LEGAL UNLESS IN CR)
|
|
; C#NAME? BECAUSE OF CHECK
|
|
; [MY &THANKS TO JIM BUTTERFIELD
|
|
; WHO WROTE THIS MORE EFFICIENT
|
|
; VERSION OF CMOVE)
|
|
|
|
CMOVE
|
|
LDA SQUARE ; GET SQUARE
|
|
LDX MOVEN ; MOVE POINTER
|
|
CLC
|
|
ADC MOVEX,X ; MOVE LIST
|
|
STA SQUARE ; NEW POS'N
|
|
AND #$88
|
|
BNE ILLEGAL ; OFF BOARD
|
|
LDA SQUARE
|
|
|
|
LDX #$20
|
|
LOOP
|
|
DEX ; IS TO
|
|
BMI NO ; SQUARE
|
|
CMP BOARD,X ; OCCUPIED?
|
|
BNE LOOP
|
|
|
|
CPX #$10 ; BY SELF?
|
|
BMI ILLEGAL
|
|
|
|
LDA #$7F ; MUST BE CAP!
|
|
ADC #$01 ; SET V FLAG
|
|
BVS SPX ; (JMP)
|
|
|
|
NO
|
|
CLV ; NO CAPTURE
|
|
|
|
SPX
|
|
LDA STATE ; SHOULD WE
|
|
BMI RETL ; DO THE
|
|
CMP #$08 ; CHECK CHECK?
|
|
BPL RETL
|
|
|
|
; CHKCHK REVERSES SIDES
|
|
; AND LOOKS FOR A KING
|
|
; CAPTURE TO INDICATE
|
|
; ILLEGAL MOVE BECAUSE OF
|
|
; CHECK SINCE THIS IS
|
|
; TIME CONSUMING, IT IS NOT
|
|
; ALWAYS DONE
|
|
|
|
CHKCHK
|
|
PHA ; STATE #392
|
|
PHP
|
|
LDA #$F9
|
|
STA STATE ; GENERATE
|
|
STA INCHEK ; ALL REPLY
|
|
JSR MOVE ; MOVES TO
|
|
JSR REVERSE ; SEE IF KING
|
|
JSR GNM ; IS IN
|
|
JSR RUM ; CHECK
|
|
PLP
|
|
PLA
|
|
STA STATE
|
|
LDA INCHEK
|
|
BMI RETL ; NO - SAFE
|
|
SEC ; YES - IN CHK
|
|
LDA #$FF
|
|
RTS
|
|
|
|
RETL
|
|
CLC ; LEGAL
|
|
LDA #$00 ; RETURN
|
|
RTS
|
|
|
|
ILLEGAL
|
|
LDA #$FF
|
|
CLC ; ILLEGAL
|
|
CLV ; RETURN
|
|
RTS
|
|
|
|
; REPLACE PIECE ON CORRECT SQUARE
|
|
|
|
RESET
|
|
LDX PIECE ; GET LOGAT
|
|
LDA BOARD,X ; FOR PIECE
|
|
STA SQUARE ; FROM BOARD
|
|
RTS
|
|
|
|
GENRM
|
|
JSR MOVE ; MAKE MOVE
|
|
GENR2
|
|
JSR REVERSE ; REVERSE BOARD
|
|
JSR GNM ; GENERATE MOVES
|
|
RUM
|
|
JSR REVERSE ; REVERSE BACK
|
|
|
|
; ROUTINE TO UNMAKE A MOVE MADE BY
|
|
; MOVE
|
|
|
|
UMOVE
|
|
TSX ; UNMAKE MOVE
|
|
STX SP1
|
|
LDX SP2 ; EXCHANGE
|
|
TXS ; STACKS
|
|
PLA ; MOVEN
|
|
STA MOVEN
|
|
PLA ; CAPTURED
|
|
STA PIECE ; PIECE
|
|
TAX
|
|
PLA ; FROM SQUARE
|
|
STA BOARD,X
|
|
PLA ; PIECE
|
|
TAX
|
|
PLA ; TO SOUARE
|
|
STA SQUARE
|
|
STA BOARD,X
|
|
JMP STRV
|
|
|
|
; THIS ROUTINE MOVES PIECE
|
|
; TO SQUARE, PARAMETERS
|
|
; ARE SAVED IN A STACK TO UNMAKE
|
|
; THE MOVE LATER
|
|
|
|
MOVE
|
|
TSX
|
|
STX SP1 ; SWITCH
|
|
LDX SP2 ; STACKS
|
|
TXS
|
|
LDA SQUARE
|
|
PHA ; TO SQUARE
|
|
TAY
|
|
LDX #$1F
|
|
CHECK
|
|
CMP BOARD,X ; CHECK FOR
|
|
BEQ TAKE ; CAPTURE
|
|
DEX
|
|
BPL CHECK
|
|
TAKE
|
|
LDA #$CC
|
|
STA BOARD,X
|
|
TXA ; CAPTURED
|
|
PHA ; PIECE
|
|
LDX PIECE
|
|
LDA BOARD,X
|
|
STY BOARD,X ; FROM
|
|
PHA ; SQUARE
|
|
TXA
|
|
PHA ; PIECE
|
|
LDA MOVEN
|
|
PHA ; MOVEN
|
|
STRV
|
|
TSX
|
|
STX SP2 ; SWITCH
|
|
LDX SP1 ; STACKS
|
|
TXS ; BACK
|
|
RTS
|
|
|
|
; CONTINUATION OF SUB STRATGY
|
|
; -CHECKS FOR CHECK OR CHECKMATE
|
|
; AND ASSIGNS VALUE TO MOVE
|
|
|
|
CKMATE
|
|
LDY BMAXC ; CAN BLK CAP
|
|
CPX POINTS ; MY KING?
|
|
BNE NOCHEK
|
|
LDA #$00 ; GULP!
|
|
BEQ RETV ; DUMB MOVE!
|
|
|
|
NOCHEK
|
|
LDX BMOB ; IS BLACK
|
|
BNE RETV ; UNABLE TO
|
|
LDX WMAXP ; MOVE AND
|
|
BNE RETV ; KING IN CH?
|
|
LDA #$FF ; YES! MATE
|
|
|
|
RETV
|
|
LDX #$04 ; RESTORE
|
|
STX STATE ; STATE=4
|
|
|
|
; THE VALUE OF THE MOVE (IN ACCU)
|
|
; IS COMPARED TO THE BEST MOVE AND
|
|
; REPLACES IT IF IT IS BETTER
|
|
|
|
PUSH
|
|
CMP BESTV ; IS THIS BEST
|
|
BCC RETP ; MOVE SO FAR?
|
|
BEQ RETP
|
|
STA BESTV ; YES!
|
|
LDA PIECE ; SAVE IT
|
|
STA BESTP
|
|
LDA SQUARE
|
|
STA BESTM ; FLASH DISPLAY
|
|
RETP
|
|
LDA prompt ; get prompt character
|
|
EOR #$1F ; toggle between [SPACE] and '?'
|
|
STA prompt ; save it back
|
|
JMP UpdateDisp ; update prompt & display
|
|
|
|
; MAIN PROGRAM TO PLAY CHESS
|
|
; PLAY FROM OPENING OR THINK
|
|
|
|
GO
|
|
LDX OMOVE ; OPENING?
|
|
BMI NOOPEN ; -NO *ADD CHANGE FROM BPL
|
|
LDA DIS3 ; -YES WAS
|
|
CMP OPNING,X ; OPPONENT'S
|
|
BNE END ; MOVE OK?
|
|
DEX
|
|
LDA OPNING,X ; GET NEXT
|
|
STA DIS1 ; CANNED
|
|
DEX ; OPENING MOVE
|
|
LDA OPNING,X
|
|
STA DIS3 ; DISPLAY IT
|
|
DEX
|
|
STX OMOVE ; MOVE IT
|
|
BNE MV2 ; (JMP)
|
|
|
|
END
|
|
LDA #$FF ; *ADD - STOP CANNED MOVES
|
|
STA OMOVE ; FLAG OPENING
|
|
NOOPEN
|
|
LDX #$0C ; FINISHED
|
|
STX STATE ; STATE=C
|
|
STX BESTV ; CLEAR BESTV
|
|
LDX #$14 ; GENERATE P
|
|
JSR GNMX ; MOVES
|
|
|
|
LDX #$04 ; STATE=4
|
|
STX STATE ; GENERATE AND
|
|
JSR GNMZ ; TEST AVAILABLE
|
|
;
|
|
; MOVES
|
|
|
|
LDX BESTV ; GET BEST MOVE
|
|
CPX #$0F ; IF NONE
|
|
BCC MATE ; OH OH!
|
|
|
|
MV2
|
|
LDX BESTP ; MOVE
|
|
LDA BOARD,X ; THE
|
|
STA BESTV ; BEST
|
|
STX PIECE ; MOVE
|
|
LDA BESTM
|
|
STA SQUARE ; AND DISPLAY
|
|
JSR MOVE ; IT
|
|
|
|
JSR DISP3 ; piece into display
|
|
|
|
JMP CHESS
|
|
|
|
MATE
|
|
LDA #$FF ; RESIGN
|
|
RTS ; OR STALEMATE
|
|
|
|
; SUBROUTINE TO ENTER THE
|
|
; PLAYER'S MOVE
|
|
|
|
DISMV
|
|
LDX #$04 ; ROTATE
|
|
DROL
|
|
ASL DIS3 ; KEY
|
|
ROL DIS2 ; INTO
|
|
DEX ; DISPLAY
|
|
BNE DROL ;
|
|
|
|
ORA DIS3
|
|
STA DIS3
|
|
STA SQUARE
|
|
RTS
|
|
|
|
; THE FOLLOWING SUBROUTINE ASSIGNS
|
|
; A VALUE TO THE MOVE UNDER
|
|
; CONSIDERATION AND RETURNS IT IN
|
|
; THE ACCUMULATOR
|
|
|
|
|
|
STRATGY
|
|
CLC
|
|
LDA #$80
|
|
ADC WMOB ; PARAMETERS
|
|
ADC WMAXC ; WITH WHEIGHT
|
|
ADC WCC ; OF O25
|
|
ADC WCAP1
|
|
ADC WCAP2
|
|
SEC
|
|
SBC PMAXC
|
|
SBC PCC
|
|
SBC BCAP0
|
|
SBC BCAP1
|
|
SBC BCAP2
|
|
SBC PMOB
|
|
SBC BMOB
|
|
BCS POS ; UNDERFLOW
|
|
LDA #$00 ; PREVENTION
|
|
POS
|
|
LSR
|
|
CLC ; **************
|
|
ADC #$40
|
|
ADC WMAXC ; PARAMETERS
|
|
ADC WCC ; WITH WEIGHT
|
|
SEC ; OF 05
|
|
SBC BMAXC
|
|
LSR ; **************
|
|
CLC
|
|
ADC #$90
|
|
ADC WCAP0 ; PARAMETERS
|
|
ADC WCAP0 ; WITH WEIGHT
|
|
ADC WCAP0 ; OF 10
|
|
ADC WCAP0
|
|
ADC WCAP1
|
|
SEC ; [UNDER OR OVER-
|
|
SBC BMAXC ; FLOW MAY OCCUR
|
|
SBC BMAXC ; FROM THIS
|
|
SBC _BCC ; SECTION]
|
|
SBC _BCC
|
|
SBC BCAP1
|
|
LDX SQUARE ; ***************
|
|
CPX #$33
|
|
BEQ POSN ; POSITION
|
|
CPX #$34 ; BONUS FOR
|
|
BEQ POSN ; MOVE TO
|
|
CPX #$22 ; CENTRE
|
|
BEQ POSN ; OR
|
|
CPX #$25 ; OUT OF
|
|
BEQ POSN ; BACK RANK
|
|
LDX PIECE
|
|
BEQ NOPOSN
|
|
LDY BOARD,X
|
|
CPY #$10
|
|
BPL NOPOSN
|
|
POSN
|
|
CLC
|
|
ADC #$02
|
|
NOPOSN
|
|
JMP CKMATE ; CONTINUE
|
|
|
|
; most new code from here on
|
|
|
|
; update move display, do prompt, piece, 'FROM' and 'TO' squares
|
|
|
|
UpdateDisp
|
|
LDA #$26 ; set cursor X
|
|
STA DispPosX ; set cursor X
|
|
LDA #$08 ; set cursor Y
|
|
STA DispPosY ; set cursor Y
|
|
LDA prompt ; prompt
|
|
JSR asciiout ; byte out to display
|
|
JSR space ; [SPACE] out to display
|
|
|
|
JSR DisPiece ; display piece (from byte in DIS1)
|
|
|
|
JSR space ; [SPACE] out to display
|
|
LDA DIS2 ; 2nd display byte
|
|
JSR PSquare ; Print square
|
|
JSR space ; [SPACE] out to display
|
|
LDA DIS3 ; 3rd display byte
|
|
JMP PSquare ; Print square
|
|
|
|
; draw board on an ASCII character display
|
|
; the display in the simulator has cursor
|
|
; positioning. Other displays may use escape
|
|
; codes to the same ends.
|
|
|
|
DrawBoard
|
|
JSR Print_c_ ; print copyright
|
|
LDA #$00 ; set initial position (0,0) is top left
|
|
STA DispPosX ; set cursor X
|
|
STA DispPosY ; set cursor Y
|
|
JSR PColNum ; print column labels
|
|
JSR Hline ; print horizontal line
|
|
LDY #$00 ; init board location
|
|
PNewVert
|
|
JSR PRowNum ; print row number
|
|
PVert
|
|
LDA #'|' ; print vertical edge
|
|
JSR asciiout ; byte out to display
|
|
|
|
LDX #$1F ; for each piece
|
|
TYA ; copy square #
|
|
PPiece
|
|
CMP BOARD,X ; this piece in this square?
|
|
BEQ PieceOut ; if so print the piece's color and type
|
|
|
|
DEX ; else try next piece
|
|
BPL PPiece ; if not done then loop
|
|
|
|
TYA ; copy square #
|
|
ASL ; shift column LSB into Cb
|
|
ASL ;
|
|
ASL ;
|
|
ASL ;
|
|
TYA ; copy square # again
|
|
ADC #$00 ; add column LSB
|
|
LSR ; result into carry
|
|
LDA #' ' ; assume white square
|
|
BCC Iswhite ; branch if white
|
|
|
|
LDA #'#' ; else make square black
|
|
Iswhite
|
|
JSR asciiout ; byte out to display
|
|
JSR asciiout ; byte out to display
|
|
PNextCol
|
|
INY ; next column
|
|
TYA ; get square #
|
|
AND #$08 ; have we completed the row?
|
|
BEQ PVert ; if not go do next column
|
|
|
|
LDA #'|' ; yes, put the right edge on
|
|
JSR asciiout ; byte out to display
|
|
JSR PRowNum ; print row number
|
|
JSR CRLF ; print CRLF
|
|
JSR Hline ; print horizontal line
|
|
TYA ; copy square #
|
|
CLC ; clear for add
|
|
ADC #$08 ; increment to beginning of next row
|
|
BMI PColNum ; done so go finish board
|
|
|
|
TAY ; else copy new square #
|
|
BPL PNewVert ; go do next row
|
|
|
|
; output piece's color & type
|
|
|
|
PieceOut
|
|
LDA #'W' ; assume white
|
|
CPX #$10 ; compare with breakpoint (result in Cb)
|
|
BIT reverse ; test reverse byte
|
|
BEQ Noflip ; branch if not reverse
|
|
|
|
; else toggle Cb state
|
|
ROL ; Cb into D0
|
|
EOR #$01 ; toggle bit
|
|
ROR ; D0 into Cb
|
|
Noflip
|
|
BCC NotBlack ; branch if white
|
|
|
|
LDA #'B' ; else make black
|
|
NotBlack
|
|
JSR asciiout ; byte out to display
|
|
TXA ; copy piece
|
|
AND #$0F ; mask black/white
|
|
TAX ; back to index
|
|
LDA P_piece,x ; get current piece 2nd byte
|
|
JSR asciiout ; byte out to display
|
|
BNE PNextCol ; branch always
|
|
|
|
; print " ", line of -'s then [CR][LF]
|
|
|
|
Hline
|
|
JSR space ; [SPACE] out to display
|
|
JSR asciiout ; byte out to display (2nd [SPACE])
|
|
LDA #'-' ; line of -'s
|
|
LDX #$19 ; 25 -'s to do
|
|
HlineL
|
|
JSR asciiout ; byte out to display
|
|
DEX ; decrement count
|
|
BNE HlineL ; loop if not all done
|
|
|
|
; do newline
|
|
|
|
CRLF
|
|
LDA #$0D ; [CR]
|
|
JSR asciiout ; byte out to display
|
|
LDA #$0A ; [LF]
|
|
JMP asciiout ; byte out to display & return
|
|
|
|
; print the column labels
|
|
|
|
PColNum
|
|
JSR space ; [SPACE] out to display
|
|
JSR asciiout ; byte out to display (2nd [SPACE])
|
|
LDX #$00 ; clear index
|
|
PNextCNum
|
|
JSR space ; [SPACE] out to display
|
|
TXA ; get column number
|
|
JSR hexout ; A out as hex
|
|
INX ; next column
|
|
CPX #$08 ; is it done?
|
|
BNE PNextCNum ; loop if not
|
|
|
|
BEQ CRLF ; else do newline and return
|
|
|
|
; print (c) message
|
|
|
|
; text lines are ...
|
|
; Xpos,Ypos,"text",0
|
|
; .. for lines with following lines and ...
|
|
; Xpos,Ypos,"text",255
|
|
; for the last line
|
|
|
|
Print_c_
|
|
LDX #$FF ; initial -1
|
|
Print_c_n
|
|
INX ; increment index
|
|
LDA _c_,X ; get cursor X
|
|
STA DispPosX ; set cursor X
|
|
INX ; increment index
|
|
LDA _c_,X ; get cursor Y
|
|
STA DispPosY ; set cursor Y
|
|
INX ; increment index
|
|
Print_c_l
|
|
LDA _c_,X ; get byte
|
|
BEQ Print_c_n ; do next line if $00 [EOL]
|
|
|
|
BMI Print_c_e ; exit if $FF [EOT]
|
|
|
|
JSR asciiout ; byte out to display
|
|
INX ; increment index
|
|
BNE Print_c_l ; loop
|
|
|
|
Print_c_e
|
|
RTS
|
|
|
|
; wait for key
|
|
|
|
asciiin
|
|
LDA ACIAsimrd ; get chr
|
|
BEQ asciiin ; no char to get
|
|
|
|
CMP #'a' ; lowe case ASCII
|
|
BCC asciirts ; skip if not >=
|
|
|
|
AND #$DF ; # and upper case alpha only
|
|
asciirts
|
|
RTS
|
|
|
|
PRowNum
|
|
TYA ; copy row number
|
|
PSquare
|
|
AND #$77 ; mask unused bits
|
|
|
|
; output A as two hex digits
|
|
|
|
hexout
|
|
PHA ; save for lower digit
|
|
LSR ; shift upper ..
|
|
LSR ; .. nibble to ..
|
|
LSR ; .. lower nibble ..
|
|
LSR ; .. and clear upper
|
|
JSR PrintDig ; output hex digit
|
|
PLA ; get byte back
|
|
AND #$0F ; clear upper nibble
|
|
PrintDig
|
|
SED ; set for hex convert
|
|
CMP #$0A ; compare with breakpoint
|
|
ADC #'0' ; add to "0"
|
|
CLD ; clear again
|
|
|
|
; byte out to display
|
|
|
|
asciiout
|
|
STA ACIAsimwr ; byte out to port
|
|
RTS
|
|
|
|
space
|
|
LDA #$20 ; [SPACE]
|
|
BNE asciiout ; print and return
|
|
|
|
; display piece byte in DIS1 as ASCII string
|
|
|
|
DisPiece
|
|
LDA DIS1 ; get piece for this move
|
|
BMI DisSpecial ; branch if not piece
|
|
|
|
AND #$0F ; don't care black or white
|
|
ASL ; *2
|
|
ASL ; *4
|
|
ASL ; *8
|
|
TAX ; copy index
|
|
DisString
|
|
LDY #$08 ; character count
|
|
DisLoop
|
|
LDA PieceName,X ; get byte
|
|
JSR asciiout ; out to display
|
|
INX ; increment index
|
|
DEY ; decrement count
|
|
BNE DisLoop ; loop if not done
|
|
|
|
RTS
|
|
|
|
; set X for 'special' $CC, $EE and $FF piece codes, else set null
|
|
|
|
DisSpecial
|
|
CMP #$CC ; compare with reset
|
|
BNE NotReset ; branch if not reset
|
|
|
|
LDX #PRes-PieceName ; set pointer
|
|
BNE DisString ; go print it
|
|
|
|
NotReset
|
|
CMP #$EE ; compare with exchange
|
|
BNE NotExcg ; branch if not exchange
|
|
|
|
LDX #PExg-PieceName ; set pointer
|
|
BNE DisString ; go print it
|
|
|
|
NotExcg ; else null
|
|
CMP #$FF ; compare with check mate
|
|
BNE NotChkm ; branch if not check mate
|
|
|
|
LDX #PCkm-PieceName ; set pointer
|
|
BNE DisString ; go print it
|
|
|
|
NotChkm ; else null
|
|
LDX #PNul-PieceName ; set pointer
|
|
BNE DisString ; go print it
|
|
|
|
; text descriptions for the byte in DIS1
|
|
|
|
PieceName
|
|
.byte "King "
|
|
.byte "Queen "
|
|
.byte "K Rook "
|
|
.byte "Q Rook "
|
|
.byte "K Bishop"
|
|
.byte "Q Bishop"
|
|
.byte "K Knight"
|
|
.byte "Q Knight"
|
|
.byte "K R Pawn"
|
|
.byte "Q R Pawn"
|
|
.byte "K N Pawn"
|
|
.byte "Q N Pawn"
|
|
.byte "K B Pawn"
|
|
.byte "Q B Pawn"
|
|
.byte "Q Pawn "
|
|
.byte "K Pawn "
|
|
PRes
|
|
.byte "Reset "
|
|
PExg
|
|
.byte "Exchange"
|
|
PCkm
|
|
.byte "Mate"
|
|
PNul
|
|
.byte " "
|
|
|
|
; copyright banner
|
|
|
|
_c_
|
|
.byte $24,$01,"+--------------------+",$00
|
|
.byte $24,$02,"| MicroChess |",$00
|
|
.byte $24,$03,"| (c) 1976-2002 |",$00
|
|
.byte $24,$04,"| Peter Jennings |",$00
|
|
.byte $24,$05,"| peterj@benlo.com |",$00
|
|
.byte $24,$06,"+--------------------+",$FF
|
|
|
|
; piece character table
|
|
|
|
P_piece
|
|
.byte "KQCCBBkkPPPPPPPP"
|
|
|
|
; end of new code
|
|
|
|
; BLOCK DATA
|
|
; *= $1580
|
|
|
|
; initial positions
|
|
|
|
SETW
|
|
.byte $03, $04, $00, $07, $02, $05, $01, $06
|
|
.byte $10, $17, $11, $16, $12, $15, $14, $13
|
|
.byte $73, $74, $70, $77, $72, $75, $71, $76
|
|
.byte $60, $67, $61, $66, $62, $65, $64, $63
|
|
|
|
MOVEX
|
|
.byte $00, $F0, $FF, $01, $10, $11, $0F, $EF, $F1
|
|
.byte $DF, $E1, $EE, $F2, $12, $0E, $1F, $21
|
|
|
|
POINTS
|
|
.byte $0B, $0A, $06, $06, $04, $04, $04, $04
|
|
.byte $02, $02, $02, $02, $02, $02, $02, $02
|
|
|
|
OPNING
|
|
.byte $99, $25, $0B, $25, $01, $00, $33, $25
|
|
.byte $07, $36, $34, $0D, $34, $34, $0E, $52
|
|
.byte $25, $0D, $45, $35, $04, $55, $22, $06
|
|
.byte $43, $33, $0F, $CC
|
|
|
|
; end of file
|