mirror of
https://github.com/makarcz/vm6502.git
synced 2024-12-28 05:29:47 +00:00
d99ed03232
I am not sure what happend. GitHub broke this file.
1052 lines
30 KiB
NASM
1052 lines
30 KiB
NASM
;***********************************************************************
|
|
;
|
|
; MicroChess (c) 1996-2002 Peter Jennings, peterj@benlo.com
|
|
;
|
|
;***********************************************************************
|
|
; Daryl Rictor:
|
|
; I have been given permission to distribute this program by the
|
|
; author and copyright holder, Peter Jennings. Please get his
|
|
; permission if you wish to re-distribute a modified copy of
|
|
; this file to others. He specifically requested that his
|
|
; copyright notice be included in the source and binary images.
|
|
; Thanks!
|
|
;
|
|
; Marek Karcz:
|
|
; I have been given permission to distribute this program by the
|
|
; original author Peter Jennings under condition that I include
|
|
; link to his website in attribution.
|
|
; Here it is: http://www.benlo.com/microchess/index.html
|
|
; I did not bother to contact Daryl Rictor to ask permission to
|
|
; distribute his modifications to this software because according to
|
|
; the copyright notice on the web page of his project, permission is
|
|
; already given for personal non-commercial use:
|
|
; http://sbc.rictor.org/avr65c02.html
|
|
; http://sbc.rictor.org/download/AVR65C02.zip, readme.txt
|
|
; If this is incorrect or I misunderstood the author's intention,
|
|
; please note that I acted with no malicious intent and will remove
|
|
; this file from my project if I receive such request.
|
|
;
|
|
; To build this program with CL65:
|
|
;
|
|
; cl65 -C microchess.cfg -l --start-addr 1024 -t none -o microchess.bin
|
|
; microchess.asm
|
|
;
|
|
; Binary image microchess.bin can be loaded to emulator with 'L'
|
|
; command in debug console. Start emulator: mkbasic, then issue
|
|
; command in debug console:
|
|
; L B MICROCHESS.BIN
|
|
;
|
|
; Memory image definition file can be generated which can be loaded
|
|
; to emulator via command line argument and automatically executed.
|
|
; To create that file, build microchess.bin image, then execute:
|
|
;
|
|
; bin2hex -f microchess.bin -o microchess.dat -w 0 -x 1024 -z
|
|
;
|
|
; and add following lines at the end of microchess.dat file:
|
|
;
|
|
; IOADDR
|
|
; $E000
|
|
; ENIO
|
|
;
|
|
; Instructions to play:
|
|
;
|
|
; Load the game to emulator and auto-execute with command:
|
|
; mkbasic microchess.dat
|
|
; then perform following steps:
|
|
; 1. Press 'C' to setup board.
|
|
; 2. Enter your move: 4 digits - BBEE, BB - piece coordinates,
|
|
; EE - destination coordinates and press ENTER
|
|
; 3. After board is updated, press 'P' to make program make the move.
|
|
; 4. Repeat steps 2 and 3 until the game is finished.
|
|
;
|
|
;
|
|
; 1/14/2012
|
|
; Modified Daryl Rictor's port to run on MKHBC-8-R1 homebrew
|
|
; computer under MKHBCOS (derivative of M.O.S. by Scott
|
|
; Chidester).
|
|
;
|
|
; 3/11/2016
|
|
; Adapted to run in MKBASIC (V65) emulator.
|
|
;
|
|
; 3/12/2016
|
|
; Modified UI behavior:
|
|
; - chess board is only printed after move, not after each
|
|
; keystroke
|
|
; - copyright banner is only printed once at the start
|
|
; of the program
|
|
;
|
|
; 6551 I/O Port Addresses
|
|
;
|
|
;ACIADat = $7F70
|
|
;ACIAsta = $7F71
|
|
;ACIACmd = $7F72
|
|
;ACIACtl = $7F73
|
|
|
|
; M.O.S. API defines (kernal) - OK for emulator, no changes
|
|
|
|
.define mos_StrPtr $E0
|
|
.define tmp_zpgPt $F6
|
|
|
|
; jumps, originally for M.O.S., now modified for emulator
|
|
|
|
.define mos_CallGetCh $FFED
|
|
.define mos_CallPutCh $FFF0
|
|
.define mos_CallPuts $FFF3
|
|
|
|
|
|
;
|
|
; page zero variables
|
|
;
|
|
BOARD = $50
|
|
BK = $60
|
|
PIECE = $B0
|
|
SQUARE = $B1
|
|
SP2 = $B2
|
|
SP1 = $B3
|
|
incHEK = $B4
|
|
STATE = $B5
|
|
MOVEN = $B6
|
|
REV = $B7
|
|
OMOVE = $2C
|
|
WCAP0 = $2D
|
|
COUNT = $2E
|
|
BCAP2 = $2E
|
|
WCAP2 = $2F
|
|
BCAP1 = $20
|
|
WCAP1 = $21
|
|
BCAP0 = $22
|
|
MOB = $23
|
|
MAXC = $24
|
|
CC = $25
|
|
PCAP = $26
|
|
BMOB = $23
|
|
BMAXC = $24
|
|
BMCC = $25 ; was bcc (TASS doesn't like it as a label)
|
|
BMAXP = $26
|
|
XMAXC = $28
|
|
WMOB = $2B
|
|
WMAXC = $3C
|
|
WCC = $3D
|
|
WMAXP = $3E
|
|
PMOB = $3F
|
|
PMAXC = $40
|
|
PCC = $41
|
|
PCP = $42
|
|
OLDKY = $43
|
|
BESTP = $4B
|
|
BESTV = $4A
|
|
BESTM = $49
|
|
DIS1 = $4B
|
|
DIS2 = $4A
|
|
DIS3 = $49
|
|
temp = $4C
|
|
|
|
;
|
|
;
|
|
;
|
|
|
|
.segment "BEGN"
|
|
|
|
.ORG $0000
|
|
|
|
.segment "CODE"
|
|
|
|
.ORG $0400 ; load into RAM @ $1000-$15FF
|
|
|
|
lda #$00 ; REVERSE TOGGLE
|
|
sta REV
|
|
jmp CHESS
|
|
|
|
PAINT: .byte $FF ; set this flag if board needs painting
|
|
; unset otherwise
|
|
PRNBANN:
|
|
.byte $FF ; set this flag to print copyright banner
|
|
|
|
;jsr Init_6551
|
|
CHESS: cld ; INITIALIZE
|
|
ldx #$FF ; TWO STACKS
|
|
txs
|
|
ldx #$C8
|
|
stx SP2
|
|
;
|
|
; ROUTINES TO LIGHT LED
|
|
; DISPLAY and GET KEY
|
|
; FROM KEYBOARD
|
|
;
|
|
OUT: jsr POUT ; DISPLAY and
|
|
jsr KIN ; GET INPUT *** my routine waits for a keypress
|
|
cmp #$43 ; [C]
|
|
bne NOSET ; SET UP
|
|
lda #$FF ; set PAINT flag
|
|
sta PAINT ; board needs to be diplayed
|
|
ldx #$1F ; BOARD
|
|
WHSET: lda SETW,X ; FROM
|
|
sta BOARD,X ; SETW
|
|
dex
|
|
bpl WHSET
|
|
ldx #$1B ; *ADDED
|
|
stx OMOVE ; INITS TO $FF
|
|
lda #$CC ; DISPLAY CCC
|
|
bne CLDSP
|
|
;
|
|
NOSET: cmp #$45 ; [E]
|
|
bne NOREV ; REVERSE
|
|
lda #$FF
|
|
sta PAINT
|
|
jsr REVERSE ; BOARD IS
|
|
sec
|
|
lda #$01
|
|
sbc REV
|
|
sta REV ; TOGGLE REV FLAG
|
|
lda #$EE ; IS
|
|
bne CLDSP
|
|
;
|
|
NOREV: cmp #$40 ; [P]
|
|
bne NOGO ; PLAY CHESS
|
|
lda #$FF
|
|
sta PAINT
|
|
jsr GO
|
|
CLDSP: sta DIS1 ; DISPLAY
|
|
sta DIS2 ; ACROSS
|
|
sta DIS3 ; DISPLAY
|
|
bne CHESS
|
|
;
|
|
NOGO: cmp #$0D ; [Enter]
|
|
bne NOMV ; MOVE MAN
|
|
pha
|
|
lda #$FF
|
|
sta PAINT
|
|
pla
|
|
jsr MOVE ; AS ENTERED
|
|
jmp DISP
|
|
NOMV: cmp #$41 ; [Q] ***Added to allow game exit***
|
|
beq DONE ; quit the game, exit back to system.
|
|
pha
|
|
lda #$00
|
|
sta PAINT
|
|
pla
|
|
jmp INPUT ; process move
|
|
DONE: rts
|
|
;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 OHM ; 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: cmp #$08 ; NOT A LEGAL
|
|
bcs ERROR ; SQUARE #
|
|
jsr DISMV
|
|
DISP: ldx #$1F
|
|
SEARCH: lda BOARD,X
|
|
cmp DIS2
|
|
beq HERE ; DISPLAY
|
|
dex ; PIECE AT
|
|
bpl SEARCH ; FROM
|
|
HERE: stx DIS1 ; SQUARE
|
|
stx PIECE
|
|
ERROR: jmp CHESS
|
|
;
|
|
; 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 #'.' ; print ... instead of flashing disp
|
|
jmp syschout ; print . and return
|
|
;
|
|
; 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
|
|
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 BMCC ; secTION]
|
|
sbc BMCC
|
|
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
|
|
|
|
|
|
;-----------------------------------------------------------------
|
|
; The following routines were added to allow text-based board
|
|
; DISPLAY over a standard RS-232 port.
|
|
;
|
|
POUT: lda PAINT
|
|
bne POUT0
|
|
rts ; return if PAINT flag = 0
|
|
POUT0: jsr POUT9 ; print CRLF
|
|
jsr POUT13 ; print copyright
|
|
jsr POUT10 ; print column labels
|
|
ldy #$00 ; init board location
|
|
jsr POUT5 ; print board horz edge
|
|
POUT1: lda #'|' ; print vert edge
|
|
jsr syschout ; PRINT ONE ASCII CHR - SPACE
|
|
ldx #$1F
|
|
POUT2: tya ; scan the pieces for a location match
|
|
cmp BOARD,X ; match found?
|
|
beq POUT4 ; yes; print the piece's color and type
|
|
dex ; no
|
|
bpl POUT2 ; if not the last piece, try again
|
|
tya ; empty square
|
|
and #$01 ; odd or even column?
|
|
sta temp ; save it
|
|
tya ; is the row odd or even
|
|
lsr ; shift column right 4 spaces
|
|
lsr ;
|
|
lsr ;
|
|
lsr ;
|
|
and #$01 ; strip LSB
|
|
clc ;
|
|
adc temp ; combine row & col to determine square color
|
|
and #$01 ; is board square white or blk?
|
|
bne POUT25 ; white, print space
|
|
lda #'*' ; black, print *
|
|
|
|
.byte $2c ; used to skip over lda #$20
|
|
;jmp POUT25A
|
|
|
|
POUT25: lda #$20 ; ASCII space
|
|
POUT25A:jsr syschout ; PRINT ONE ASCII CHR - SPACE
|
|
jsr syschout ; PRINT ONE ASCII CHR - SPACE
|
|
POUT3: iny ;
|
|
tya ; get row number
|
|
and #$08 ; have we completed the row?
|
|
beq POUT1 ; no, do next column
|
|
lda #'|' ; yes, put the right edge on
|
|
jsr syschout ; PRINT ONE ASCII CHR - |
|
|
jsr POUT12 ; print row number
|
|
jsr POUT9 ; print CRLF
|
|
jsr POUT5 ; print bottom edge of board
|
|
clc ;
|
|
tya ;
|
|
adc #$08 ; point y to beginning of next row
|
|
tay ;
|
|
cpy #$80 ; was that the last row?
|
|
beq POUT8 ; yes, print the LED values
|
|
bne POUT1 ; no, do new row
|
|
|
|
POUT4: lda REV ; print piece's color & type
|
|
beq POUT41 ;
|
|
lda cpl+16,X ;
|
|
bne POUT42 ;
|
|
POUT41: lda cpl,x ;
|
|
POUT42: jsr syschout ;
|
|
lda cph,x ;
|
|
jsr syschout ;
|
|
bne POUT3 ; branch always
|
|
|
|
POUT5: txa ; print "-----...-----<crlf>"
|
|
pha
|
|
ldx #$19
|
|
lda #'-'
|
|
POUT6: jsr syschout ; PRINT ONE ASCII CHR - "-"
|
|
dex
|
|
bne POUT6
|
|
pla
|
|
tax
|
|
jsr POUT9
|
|
rts
|
|
|
|
POUT8: jsr POUT10 ;
|
|
lda BESTP
|
|
jsr syshexout ; PRINT 1 BYTE AS 2 HEX CHRS
|
|
lda #$20
|
|
jsr syschout ; PRINT ONE ASCII CHR - SPACE
|
|
lda BESTV
|
|
jsr syshexout ; PRINT 1 BYTE AS 2 HEX CHRS
|
|
lda #$20
|
|
jsr syschout ; PRINT ONE ASCII CHR - SPACE
|
|
lda DIS3
|
|
jsr syshexout ; PRINT 1 BYTE AS 2 HEX CHRS
|
|
|
|
POUT9: lda #$0D
|
|
jsr syschout ; PRINT ONE ASCII CHR - CR
|
|
lda #$0A
|
|
jsr syschout ; PRINT ONE ASCII CHR - LF
|
|
rts
|
|
|
|
POUT10: ldx #$00 ; print the column labels
|
|
POUT11: lda #$20 ; 00 01 02 03 ... 07 <CRLF>
|
|
jsr syschout
|
|
txa
|
|
jsr syshexout
|
|
inx
|
|
cpx #$08
|
|
bne POUT11
|
|
beq POUT9
|
|
POUT12: tya
|
|
and #$70
|
|
jsr syshexout
|
|
rts
|
|
|
|
; print banner only once, preserve registers A, X, Y
|
|
POUT13: stx tmp_zpgPt
|
|
sta tmp_zpgPt+1
|
|
sty tmp_zpgPt+2
|
|
lda PRNBANN
|
|
beq NOPRNBANN
|
|
lda #<banner
|
|
sta mos_StrPtr
|
|
lda #>banner
|
|
sta mos_StrPtr+1
|
|
jsr mos_CallPuts
|
|
NOPRNBANN:
|
|
lda #$00
|
|
sta PRNBANN
|
|
ldx tmp_zpgPt
|
|
lda tmp_zpgPt+1
|
|
ldy tmp_zpgPt+2
|
|
rts
|
|
|
|
; ldx #$00 ; Print the copyright banner
|
|
;POUT14: lda banner,x
|
|
; beq POUT15
|
|
; jsr syschout
|
|
; inx
|
|
; bne POUT14
|
|
;POUT15: rts
|
|
|
|
KIN: lda #'?'
|
|
jsr syschout ; PRINT ONE ASCII CHR - ?
|
|
jsr syskin ; GET A KEYSTROKE FROM SYSTEM
|
|
jsr syschout ; echo entered character
|
|
and #$4F ; MASK 0-7, and ALpha'S
|
|
rts
|
|
;
|
|
; 6551 I/O Support Routines
|
|
;
|
|
;
|
|
;Init_6551 lda #$1F ; 19.2K/8/1
|
|
; sta ACIActl ; control reg
|
|
; lda #$0B ; N parity/echo off/rx int off/ dtr active low
|
|
; sta ACIAcmd ; command reg
|
|
; rts ; done
|
|
;
|
|
; input chr from ACIA1 (waiting)
|
|
;
|
|
syskin:
|
|
jsr mos_CallGetCh
|
|
rts
|
|
|
|
;lda ACIAsta ; Serial port status
|
|
;and #$08 ; is recvr full
|
|
;beq syskin ; no char to get
|
|
;lda ACIAdat ; get chr
|
|
;rts ;
|
|
;
|
|
; output to OutPut Port
|
|
;
|
|
syschout: ; MKHBCOS: must preserve X, Y and A
|
|
stx tmp_zpgPt
|
|
sta tmp_zpgPt+1
|
|
;sty tmp_zpgPt+2
|
|
jsr mos_CallPutCh
|
|
ldx tmp_zpgPt
|
|
lda tmp_zpgPt+1
|
|
;ldy tmp_zpgPt+2
|
|
rts
|
|
; pha ; save registers
|
|
;ACIA_Out1 lda ACIAsta ; serial port status
|
|
; and #$10 ; is tx buffer empty
|
|
; beq ACIA_Out1 ; no
|
|
; pla ; get chr
|
|
; sta ACIAdat ; put character to Port
|
|
; rts ; done
|
|
|
|
syshexout: pha ; prints AA hex digits
|
|
lsr ; MOVE UPPER NIBBLE TO LOWER
|
|
lsr ;
|
|
lsr ;
|
|
lsr ;
|
|
jsr PrintDig ;
|
|
pla ;
|
|
PrintDig:
|
|
sty tmp_zpgPt+2
|
|
and #$0F ;
|
|
tay ;
|
|
lda Hexdigdata,Y ;
|
|
ldy tmp_zpgPt+2 ;
|
|
jmp syschout ;
|
|
|
|
Hexdigdata: .byte "0123456789ABCDEF"
|
|
banner: .byte "MicroChess (c) 1996-2002 Peter Jennings, peterj@benlo.com"
|
|
.byte $0d, $0a, $00
|
|
cpl: .byte "WWWWWWWWWWWWWWWWBBBBBBBBBBBBBBBBWWWWWWWWWWWWWWWW"
|
|
cph: .byte "KQCCBBRRPPPPPPPPKQCCBBRRPPPPPPPP"
|
|
.byte $00
|
|
;
|
|
; end of added code
|
|
;
|
|
; BLOCK DATA
|
|
|
|
.segment "DATA"
|
|
|
|
.ORG $0A20
|
|
|
|
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
|
|
|
|
.segment "KERN"
|
|
|
|
.ORG $FE00
|
|
|
|
CHRIN: lda $E000
|
|
rts
|
|
|
|
CHROUT: sta $E000
|
|
rts
|
|
|
|
; this function was shamelessly ripped :-) from M.O.S. code (c) by Scott Chidester
|
|
|
|
STROUT:
|
|
ldy #0 ; Non-indexed variant starts at zero, of course
|
|
lda mos_StrPtr+1 ; Save StrPtr so it isn't modified
|
|
pha
|
|
PutsLoop:
|
|
lda (mos_StrPtr),y ; Get the next char in the string
|
|
beq PutsDone ; Zero means end of string
|
|
jsr CHROUT ; Otherwise put the char
|
|
|
|
; Update string pointer
|
|
iny ; increment StrPtr-lo
|
|
bne PutsLoop ; No rollover? Loop back for next character
|
|
inc mos_StrPtr+1 ; StrPtr-lo rolled over--carry hi byte
|
|
jmp PutsLoop ; Now loop back
|
|
|
|
PutsDone:
|
|
pla
|
|
sta mos_StrPtr+1 ; Restore StrPtr
|
|
rts
|
|
|
|
.segment "VECT"
|
|
|
|
.ORG $FFED
|
|
|
|
jmp CHRIN
|
|
jmp CHROUT
|
|
jmp STROUT
|
|
|
|
;
|
|
;
|
|
; end of file
|
|
;
|