Subject: [stella] Introduction and new game From: "Erik J. Eid" <eeid@xxxxxxxxx> Date: Wed, 06 Jun 2001 22:23:19 -0400 |
; ; Euchre game program for the Atari 2600 video computer system ; ; Copyright 2001 by Erik Eid (eeid@xxxxxxxxx) ; ; Last update: June 3, 2001 ; ; Compiled with the dasm assembler using the -f3 option ; processor 6502 include vcs.h ; Constants seg.u defines CardsInDeck = $18 ; 24 cards in a Euchre deck Team1Color = $88 Team2Color = $38 TableRegionColor = $d4 CardTableColor = $0f RedSuitColor = $36 BlackSuitColor = $00 MessageRegionColor = $22 RankMask = %00000111 ; Bit mask for rank of a card DispSuitMask = %00011000 ; Bit mask for suit displayed on a card RealSuitMask = %01100000 ; Bit mask for suit used when following (the left ; bower becomes the suit of the right bower) ShowCardMask = %10000000 ; Bit mask for determining if a card is shown BlackSuitMask = %00010000 SWACNT = $281 ; Strangely not part of the original vcs.h VS_Disable = 0 ; Ditto CenterRankPos = $75 ; Player positions CenterSuitPos = $66 LeftRankPos = $a2 RightRankPos = $57 MessageP0Pos = $44 MessageP1Pos = $c4 ; Variables seg.u vars org $80 Team1Score ds 1 Team2Score ds 1 Team1Tricks ds 1 Team2Tricks ds 1 NorthHand ds 5 ; Cards in a player's hand EastHand ds 5 SouthHand ds 5 WestHand ds 5 NorthCard ds 1 ; Cards down on the table EastCard ds 1 SouthCard ds 1 WestCard ds 1 ImgPtr1 ds 2 ; Pointers to playfield and player images ImgPtr2 ds 2 ImgPtr3 ds 2 ImgPtr4 ds 2 HandCard ds 1 ; Pointer to a card in a hand T1 ds 1 ; Temporary variables used in subroutines T2 ds 1 T3 ds 1 rand1 ds 1 ; Locations to hold bits of random number rand2 ds 1 rand3 ds 1 rand4 ds 1 NeedShuffle ds 1 ; Flag indicating if a shuffle is needed DeckStart = NorthHand ; Program seg code org $f000 ; 4K cartridge ; ; Initialization ; CartStart sei ; Disable all interrupts cld ; Clear decimal mode (so carry is at 256, not 100) ldx #$ff txs ; Reset the stack pointer to the highest point possible ; Clear out registers and variables lda #$00 ClearRAM sta $00,x dex bne ClearRAM ; Loop does not zero WSYNC, but it's not needed sta SWACNT ; Tell port A to accept input lda #$6d ; seed random number generator sta rand1 sta rand2 sta rand3 sta rand4 ProgStart ; ; Begin a new game ; GameStart lda #$00 sta Team1Score sta Team2Score ; ; Begin a new hand ; HandStart lda #$00 sta Team1Tricks sta Team2Tricks lda #$01 sta NeedShuffle ; ; Main loop ; Main ; Start of display kernel ; Provide three lines of vertical sync lda #VS_Enable sta WSYNC sta WSYNC sta WSYNC sta VSYNC sta WSYNC sta WSYNC sta WSYNC lda #VS_Disable sta VSYNC ; Provide 37 scanlines of vertical blank lda #43 ; 37 lines * 76 cycles/line = 2812 cycles / 64 cycles/interval = 43.96 intervals sta TIM64T ; When it comes time, check console switches here lda NeedShuffle beq PostShuffle jsr ShuffleDeck lda #$00 sta NeedShuffle PostShuffle jsr RandomBit ; keep the randomness flowing WaitVBlank lda INTIM nop bne WaitVBlank sta WSYNC ; Finish up last line sta VBLANK ; Stop vertical blank (accumulator holds zero) ; Now we start on the visible portion of the screen ; First eight lines are blank... lda #9 ; 8 lines * 76 cycles/line = 608 cycles / 64 cycles/interval = 9.5 intervals sta TIM64T ; Since we have some time, prepare the playfield for displaying the scores ; and get pointers to playfield images for them. lda #Team1Color sta COLUP0 lda #Team2Color sta COLUP1 lda #PF_Score sta CTRLPF ldx Team1Score ldy #ImgPtr1 jsr GetScoreImage ldx Team2Score ldy #ImgPtr2 jsr GetScoreImage WaitEndScore lda INTIM nop bne WaitEndScore ; Now we spend ten lines drawing the scores on the playfield ldx #$09 ScoresLoop sta WSYNC txa lsr tay lda (ImgPtr1),y sta PF1 ror T1 ror T1 nop nop nop lda (ImgPtr2),y sta PF1 dex bpl ScoresLoop ; Pause for four lines and prepare to show tricks sta WSYNC lda #$00 sta PF1 lda #4 sta TIM64T WaitBeginTricks lda INTIM nop bne WaitBeginTricks ; Trick graphics are four lines with the same value, so the offset into ; the TrickImages table is for the number of tricks rather than the xth ; byte of an image. ldy #$04 TricksLoop sta WSYNC ldx Team1Tricks lda TrickImages,x sta PF1 ror T1 ror T1 nop nop nop ldx Team2Tricks lda TrickImages,x sta PF1 dey bne TricksLoop ; Pause for eight more lines. sta WSYNC lda #$00 sta PF1 lda #7 sta TIM64T ; Position the players for display of a card. This is well in advance but ; we have time now. lda #CenterRankPos ldx #0 jsr PositionPlayer lda #CenterSuitPos ldx #1 jsr PositionPlayer sta WSYNC sta HMOVE WaitBeginTable lda INTIM nop bne WaitBeginTable ; Now switch to the "card table" display sta WSYNC lda #TableRegionColor sta COLUBK lda #CardTableColor sta COLUPF lda #PF_Reflect sta CTRLPF lda #$0f sta PF1 lda #$ff sta PF2 lda NorthCard ldx #ImgPtr1 ldy #ImgPtr2 jsr GetCardGraphics sta COLUP0 sta COLUP1 jsr DrawSingleCard lda #$00 sta GRP0 sta GRP1 ; Now we come to the hard one... both West and East lda #P_TwoClose ; Two copies close sta NUSIZ0 sta NUSIZ1 lda WestCard ldx #ImgPtr1 ldy #ImgPtr3 jsr GetCardGraphics sta COLUP0 lda EastCard ldx #ImgPtr2 ldy #ImgPtr4 jsr GetCardGraphics sta COLUP1 lda #LeftRankPos ldx #0 jsr PositionPlayer lda #RightRankPos ldx #1 jsr PositionPlayer sta WSYNC sta HMOVE ldy #7 DrawWestEastCards nop nop ror T1 ror T1 lda (ImgPtr3),y tax lda (ImgPtr1),y sta GRP0 stx GRP0 pha lda (ImgPtr4),y tax lda (ImgPtr2),y sta GRP1 stx GRP1 pla sta WSYNC dey bpl DrawWestEastCards lda #$00 sta GRP0 sta GRP1 sta NUSIZ0 sta NUSIZ1 lda #CenterRankPos ldx #0 jsr PositionPlayer lda #CenterSuitPos ldx #1 jsr PositionPlayer sta WSYNC sta HMOVE lda SouthCard ldx #ImgPtr1 ldy #ImgPtr2 jsr GetCardGraphics sta COLUP0 sta COLUP1 jsr DrawSingleCard lda #4 sta TIM64T WaitEndSouth lda INTIM nop bne WaitEndSouth lda #9 ; burn 8 lines sta TIM64T lda #$00 sta COLUBK sta PF1 sta PF2 WaitBeforeHand lda INTIM nop bne WaitBeforeHand ; Draw the five cards in the player's hand. For each of the cards, draw four ; black lines then twelve card lines. The middle eight lines of the card have ; the images. During the four black lines, get the image pointers and player ; colors. lda #$00 sta HandCard ShowHandLoop lda #4 sta TIM64T lda #$00 sta COLUBK sta PF2 ldx HandCard lda SouthHand,x ldx #ImgPtr1 ldy #ImgPtr2 jsr GetCardGraphics sta COLUP0 sta COLUP1 WaitToDrawHandCard lda INTIM nop bne WaitToDrawHandCard lda #$f0 sta PF2 sta WSYNC sta WSYNC jsr DrawSingleCard lda #$00 sta GRP0 sta GRP1 sta WSYNC sta WSYNC inc HandCard lda HandCard cmp #$05 bne ShowHandLoop ; Now the gap between the last card and the message region lda #9 sta TIM64T lda #$00 sta COLUBK sta PF2 sta COLUP0 sta COLUP1 WaitForGap lda INTIM nop bne WaitForGap lda #MessageRegionColor sta COLUBK lda #MessageP0Pos ldx #0 jsr PositionPlayer lda #MessageP1Pos ldx #1 jsr PositionPlayer lda P_ThreeClose sta NUSIZ0 sta NUSIZ1 lda #19 ; 16 lines of message sta TIM64T WaitForMessage lda INTIM nop bne WaitForMessage lda #$00 sta COLUPF lda #9 ; 8 lines sta INTIM lda #$00 sta WSYNC sta PF1 sta PF2 sta COLUBK sta COLUP0 sta COLUP1 sta COLUPF sta CTRLPF sta GRP0 sta GRP1 sta NUSIZ0 sta NUSIZ1 WaitForEnd lda INTIM nop bne WaitForEnd sta WSYNC lda #35 ; 30 lines of overscan sta TIM64T lda #$02 sta VBLANK CheckReset lda SWCHB and #$01 cmp #$01 beq WaitOverscan jmp ProgStart WaitOverscan lda INTIM nop bne WaitOverscan sta WSYNC jmp Main GetScoreImage txa asl tax lda ScoreImages,x sta $00,y lda ScoreImages+1,x sta $01,y rts GetRankImage txa asl tax lda RankImages,x sta $00,y lda RankImages+1,x sta $01,y rts GetSuitImage txa asl tax lda SuitImages,x sta $00,y lda SuitImages+1,x sta $01,y rts NewDeck .byte $00,$01,$02,$03,$04,$05 .byte $28,$29,$2a,$2b,$2c,$2d .byte $50,$51,$52,$53,$54,$55 .byte $78,$79,$7a,$7b,$7c,$7d ; All images are reversed since they are read by decrementing loops. ScoreImage0 .byte $07,$05,$05,$05,$07 ScoreImage1 .byte $07,$02,$02,$06,$02 ScoreImage2 .byte $07,$04,$07,$01,$07 ScoreImage3 .byte $07,$01,$03,$01,$07 ScoreImage4 .byte $01,$05,$07,$01,$01 ScoreImage5 .byte $07,$01,$07,$04,$07 ScoreImage6 .byte $07,$04,$07,$05,$07 ScoreImage7 .byte $04,$04,$02,$01,$07 ScoreImage8 .byte $07,$05,$02,$05,$07 ScoreImage9 .byte $07,$01,$07,$05,$07 ScoreImage10 .byte $77,$25,$25,$65,$27 ScoreImage11 .byte $72,$22,$22,$62,$22 ScoreImage12 .byte $77,$24,$27,$61,$27 ScoreImage13 .byte $77,$21,$23,$61,$27 ScoreImages .byte <ScoreImage0 .byte >ScoreImage0 .byte <ScoreImage1 .byte >ScoreImage1 .byte <ScoreImage2 .byte >ScoreImage2 .byte <ScoreImage3 .byte >ScoreImage3 .byte <ScoreImage4 .byte >ScoreImage4 .byte <ScoreImage5 .byte >ScoreImage5 .byte <ScoreImage6 .byte >ScoreImage6 .byte <ScoreImage7 .byte >ScoreImage7 .byte <ScoreImage8 .byte >ScoreImage8 .byte <ScoreImage9 .byte >ScoreImage9 .byte <ScoreImage10 .byte >ScoreImage10 .byte <ScoreImage11 .byte >ScoreImage11 .byte <ScoreImage12 .byte >ScoreImage12 .byte <ScoreImage13 .byte >ScoreImage13 TrickImages .byte $00,$01,$05,$15,$55,$FF ; routine to draw a single card ; assumes ImgPtr1 and ImgPtr2 point to proper images, sprites are ; positioned, and so on DrawSingleCard ldy #07 DrawCardLoop sta WSYNC lda (ImgPtr1),y sta GRP0 lda (ImgPtr2),y sta GRP1 dey bpl DrawCardLoop rts ; routine to shuffle the deck ShuffleDeck ldx #CardsInDeck RefreshDeck dex lda NewDeck,x sta DeckStart,x bne RefreshDeck lda #$08 sta T3 ShuffleLoop ldx #CardsInDeck OneShuffle dex stx T1 jsr RandomByte ModLoop cmp #CardsInDeck bcc LTCards sec sbc #CardsInDeck jmp ModLoop LTCards ldx T1 tay lda DeckStart,x sta T2 lda DeckStart,y sta DeckStart,x lda T2 sta DeckStart,y ldx T1 bne OneShuffle dec T3 bne ShuffleLoop rts org $fd00 ; routine for getting images and colors of a card ; a = card ; x = image pointer for rank ; y = image pointer for suit ; returns: a = color of card GetCardGraphics sta T1 stx T2 sty T3 lda T1 and #RankMask tax ldy T2 jsr GetRankImage lda T1 and #DispSuitMask lsr lsr lsr tax ldy T3 jsr GetSuitImage lda T1 and #BlackSuitMask bne CardIsBlack lda #RedSuitColor jmp LeaveGetCardGraphics CardIsBlack lda #BlackSuitColor LeaveGetCardGraphics rts org $fe00 ; routine to position a player ; original version by Erik Mooney in the Stella mailing list message ; "Re: [stella] sexp8.bin Multi-Japanese Sprites" from April 18, 1998 ; (http://www.biglist.com/lists/stella/archives/199804/msg00170.html) ; modified to work on both player 0 and 1 and to take a hard-coded ; position value rather than look at a table (there is no motion in ; this game, so the table is not necessary) ; ; a = position value - high nybble = fine position, low nybble = ; course position ; x = player number PositionPlayer sta WSYNC ror T1 ; waste 5 cycles sta HMP0,x and #$0f tay P0 dey bpl P0 sta RESP0,x ; Rather than WSYNC and HMOVE now, let the calling routine do it. If both ; players are positioned in succession, this saves a scanline. rts ; routine to generate a random number ; original version by Erik Mooney in the Stella mailing list message ; "Re: [stella] demo update: PCMSD20.BIN" from April 14, 1997 ; (http://www.biglist.com/lists/stella/archives/199704/msg00136.html) ; requires four memory locations to be reserved for generation ; ; returns: a = random number RandomBit lda rand4 asl asl asl eor rand4 ;new bit is now in bit 6 of A asl asl ;new bit is now in carry rol rand1 ;shift new bit into bit 0 of register; bit 7 goes into carry rol rand2 ;shift old bit 7 into bit 8, etc. rol rand3 rol rand4 rts RandomByte ldx #8 RandomByte1 jsr RandomBit dex bne RandomByte1 lda rand1 rts org $ff00 ; All images are reversed since they are read by decrementing loops. RankImage9 .byte $00,$3c,$46,$06,$3e,$66,$66,$3c RankImage10 .byte $00,$ee,$5b,$5b,$5b,$5b,$db,$4e RankImageJack .byte $00,$3c,$66,$06,$06,$06,$06,$0e RankImageQueen .byte $00,$3a,$64,$6a,$66,$66,$66,$3c RankImageKing .byte $00,$66,$6c,$78,$70,$78,$6c,$66 RankImageAce .byte $00,$c6,$c6,$fe,$fe,$c6,$7c,$38 RankImageLeft .byte $00,$ec,$8a,$8a,$8c,$8a,$8a,$8c ; debug "LB" ; .byte $00,$3c,$66,$06,$06,$06,$06,$0e RankImageRight .byte $00,$ac,$aa,$aa,$cc,$aa,$aa,$cc ; debug "RB" ; .byte $00,$3c,$66,$06,$06,$06,$06,$0e SuitImageHeart .byte $00,$10,$38,$7c,$fe,$fe,$ee,$44 SuitImageDiamond .byte $00,$10,$38,$7c,$fe,$7c,$38,$10 SuitImageClub .byte $00,$18,$7e,$ff,$7e,$18,$3c,$18 SuitImageSpade .byte $00,$38,$ba,$fe,$fe,$7c,$38,$10 RankImages .byte <RankImage9 .byte >RankImage9 .byte <RankImage10 .byte >RankImage10 .byte <RankImageJack .byte >RankImageJack .byte <RankImageQueen .byte >RankImageQueen .byte <RankImageKing .byte >RankImageKing .byte <RankImageAce .byte >RankImageAce .byte <RankImageLeft .byte >RankImageLeft .byte <RankImageRight .byte >RankImageRight SuitImages .byte <SuitImageHeart .byte >SuitImageHeart .byte <SuitImageDiamond .byte >SuitImageDiamond .byte <SuitImageClub .byte >SuitImageClub .byte <SuitImageSpade .byte >SuitImageSpade org $fffc .byte <CartStart .byte >CartStart .byte <CartStart .byte >CartStart
Attachment:
Euchre.bin
Description: Binary data
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Aw: Re: [stella] Infogrames conside, cybergoth | Thread | Re: [stella] Introduction and new g, Manuel Polik |
Re: [stella] Infogrames considers A, Thomas Jentzsch | Date | Re: [stella] Infogrames considers A, Russ Perry Jr |
Month |