mirror of
https://github.com/makarcz/vm6502.git
synced 2024-11-18 18:10:43 +00:00
67f1a62596
Version 2.0, full emulation of 6502 op-codes, fully tested and functional. Extended description in ReadMe file. Bin2Hex tool to convert binary images to memory definition format. Microchess, EhBasic added.
1052 lines
31 KiB
NASM
1052 lines
31 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
|
|
;
|