gigatron/rom/Apps/Microchess/asm/org/uchess_sim.asm
2025-01-28 19:17:01 +03:00

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