;*************************************************************************
;Casino for Zshell v1.0b
;by Doug Melton
;
;last update 11/21/96
;

#include "ti-85.h"

.org 0
.db "Casino v1.0 by DM", 0

game            = TEXT_MEM
randNum         = TEXT_MEM+1                     ;random number seed
cardsLeft       = TEXT_MEM+2
asciiNumb       = TEXT_MEM+3                     ;ascii for output of a number (6 bytes)
bet             = TEXT_MEM+9                     ;bet player has placed
tmpMoney        = TEXT_MEM+11                    ;location for player $ during game
tmp             = TEXT_MEM+13                    ;temporary variable for misc. stuff
deck            = TEXT_MEM+15                    ;52 cards (bytes)
GAME_OFFSET     = TEXT_MEM+67                    ;starting point for different game variables

BJ              = $10
POKER           = $14
SLOTS           = $18
EXIT            = $1C


        ld      a, 4
        out     (5), a                           ;graphics mode

        ld      a, BJ
        ld      (game), a                        ;bj is default game

        xor     a
        ld      (cardsLeft), a                   ;make calc. reshuffle
        ld      (randNum), a                     ;make first randNum 0

        ld      a, 10                            
        ld      (bet), a                         ;starting bet is $10

        ld      hl, money                        ;load old money and put in
        ld      de, (PROGRAM_ADDR)               ;temporary mem.
        add     hl, de                               
        call    LD_HL_MHL

        ld      a, h                             ;if the player has $0,
        or      l
        jr      nz, NoMoreMoney
        ld      hl, 100                          ;give him $100
NoMoreMoney:
        ld      (tmpMoney), hl

DispTitlePic:
        ld      de, titleScreen
        CALL_(  ZCP20)                           ;draw main menu

        ld      bc, $1A26
        ld      hl, msgByLine
        CALL_(  DisplayMenuTxt)
        ld      bc, $221B
        ld      hl, msgAddx
        CALL_(  DisplayMenuTxt)
        ld      bc, $302B
        ld      hl, msgThanks
        CALL_(  DisplayMenuTxt)
        ld      bc, $370D
        ld      hl, msgThanks2
        CALL_(  DisplayMenuTxt)

TitlePicEnter:
        call    GET_KEY
        or      a
        jr      z, TitlePicEnter

;************************** Main Menu *****************************
MainTop:
        ld      hl, (tmpMoney)
        ld      a, h
        or      l
        JUMP_Z( QuitGame)

        ld      de, titleScreen
        CALL_(  ZCP20)                           ;draw main menu

        ld      a, r
	ld	(randNum), a                     ;randomize


;************
        ld      bc, $190F                        ;show their bet and $
        ld      hl, msgBet
        CALL_(  DisplayMenuTxt)

        ld      bc, $193E
        ld      hl, msgMoney
        CALL_(  DisplayMenuTxt)

DrawMainPic:                                     ;display menu picture
        ld      hl, menuData
        add     hl, de                           ;de is (program_addr)
        ld      de, VIDEO_MEM+$0220              ;location on screen
        ld      bc, 432                          ;there are 432 bytes to copy
        ldir
;************

        CALL_(  Invert)

MainDisplayMoney:
        ld      hl, (tmpMoney)
        ld      b, 5
        ld      de, $195C
        CALL_(  DisplayNumber)                   ;show their money

MainDisplayBet:
        ld      hl, (tmpMoney)                   ;if their $ is less than
        ld      de, (bet)                        ;their bet, then ignore
        call    CP_HL_DE
        jr      nc, MainDisplayBet2
        ld      (bet), hl
MainDisplayBet2:
        ld      hl, (bet)
        ld      b, 5
        ld      de, $1922
        CALL_(  DisplayNumber)                   ;show their bet

MainKeyTest:
        halt                                     ;saves power
        call    GET_KEY
        cp      K_EXIT
        jr      z, QuitGame
        cp      K_LEFT
        jr      z, MainKeyLeft
        cp      K_RIGHT
        jr      z, MainKeyRight
        cp      K_UP
        jr      z, MainKeyUp
        cp      K_DOWN
        jr      z, MainKeyDown
        cp      K_ENTER
        jr      z, MainKeyEnter
        jr      MainKeyTest

QuitGame:
        res     3, (IY+5)
        ld      hl, ZS_BITS
        set     0, (hl)                          ;make zshell recalc. checksum

        ld      hl, money                        ;store bet in program
        ld      de, (PROGRAM_ADDR)
        add     hl, de
        ld      de, (tmpMoney)
        ld      (hl), e
        inc     hl
        ld      (hl), d

        ret

MainKeyUp:
        ld      hl, (bet)
        inc     hl
        jr      MainKeyUpDown
MainKeyDown:
        ld      hl, (bet)
        dec     hl
MainKeyUpDown:
        ld      a, h
        or      l
        jr      z, MainDisplayBet
        ld      (bet), hl
        jr      MainDisplayBet

MainKeyLeft:
        ld      b, -4
        jr      MainKeyLeftRight
MainKeyRight:
        ld      b, 4
MainKeyLeftRight:
        CALL_(  Invert)
        ld      a, (game)
        add     a, b
        cp      BJ-4
        jr      nz, MainKeyLeftRight2
        ld      a, EXIT
MainKeyLeftRight2:
        cp      EXIT+4
        jr      nz, MainKeyLeftRight3
        ld      a, BJ
MainKeyLeftRight3:
        ld      (game), a
        CALL_(  Invert)
        jr      MainKeyTest

MainKeyEnter:
        ROM_CALL(CLEARLCD)
        ld      a, (game)
        cp      EXIT
        jr      z, QuitGame
        cp      BJ
        jr      z, PlayBJ
        cp      POKER
        JUMP_Z( PlayPoker)
        cp      SLOTS
        JUMP_Z( PlaySlots)

Invert:                                          ;invert a block of the screen
        push    bc
        ld      hl, (game)
        ld      h, $FE

        ld      de, $000C
        ld      c, $1D
InvertLoop1:
        ld      b, 4
InvertLoop2:
        ld      a, (hl)
        xor     $FF
        ld      (hl), a
        inc     hl
        djnz    InvertLoop2

        add     hl, de
        dec     c
        jr      nz, InvertLoop1

        pop     bc
        ret

;********************** Play Black-Jack *****************************
bj_bits         = GAME_OFFSET
CAN_DOUBLE      = 0
DOUBLED         = 1
CAN_INSURE      = 2

player_total    = GAME_OFFSET+1                  ;player's score: bit 0-5,
                                                 ;    has an Ace: bit 6
player_cards    = player_total+1                 ;pos'n of next card, word

dealer_total    = GAME_OFFSET+4
dealer_cards    = dealer_total+1
dealer_1st      = dealer_total+3                 ;dealer's 1st card

SCORE_MASK      = 00111111b                      ;total amount for cards

PlayBJ:
	xor	a
        ld      (player_total), a                ;initialize player's total to 0
        ld      (dealer_total), a
        ld      (bj_bits), a

        ld      hl, $0838
        ld      (player_cards), hl               ;initialize player's 1st card pos.
        ld      hl, $001C
        ld      (dealer_cards), hl                     

        ld      a, (cardsLeft)
        cp      9
        CALL_C( Shuffle)                         ;shuffle if cards left < 9

        CALL_(  DisplayMenu)

        ld      bc, $0005
        ld      hl, msgYourHand
        CALL_(  DisplayMenuTxt)

        ld      b, $1C
        ld      hl, msgDealerHand
        CALL_(  DisplayMenuTxt)

BJInitialDraw:
        CALL_(  BJPlayerCard)
        CALL_(  BJDealerCard)
        CALL_(  BJPlayerCard)
        CALL_(  BJDealerCard)

        ld      a, (player_total)                ;check for player blackjack
        and     SCORE_MASK
        cp      21
        jr      nz, BJTestDouble
        ld      b, a
        ld      a, (dealer_total)
        and     SCORE_MASK
        cp      b
        JUMP_Z( BJStand)

        ld      e, 3
        ld      hl, msgBlackJack
        JUMP_(  WonMoney)                        ;you win!

BJTestDouble:
        ld      hl, (bet)                        ;all this stuff is to see
        ld      de, (tmpMoney)                   ;if you can double down
        add     hl, hl                           
        call    CP_HL_DE                         ;see if theres enough $
        ld      hl, bj_bits
        jr      c, BJTestDouble3                       

        ld      a, (player_total)
        and     SCORE_MASK                       
        cp      10                               
        jr      nz, BJTestDouble2                      
        set     CAN_DOUBLE, (hl)                 ;see if its a 10 or 11 score
BJTestDouble2:
        cp      11                               
        jr      nz, BJTestDouble3                      
        set     CAN_DOUBLE, (hl)              
BJTestDouble3:
        ld      bc, $3A0A
        ld      hl, msgHit
        CALL_(  DisplayMenuTxt)

        ld      bc, $3A1C
        ld      hl, msgStand
        CALL_(  DisplayMenuTxt)

        ld      hl, bj_bits
        bit     CAN_DOUBLE, (hl)
        jr      z, BJKeyTest
        ld      bc, $3A36
        ld      hl, msgDouble
        CALL_(  DisplayMenuTxt)

BJKeyTest:
        call    GET_KEY
        cp      K_F1
        jr      z, BJHit
        cp      K_F2
        jr      z, BJStand
        cp      K_F3
        jr      z, BJDouble
        jr      BJKeyTest

BJDouble:
        ld      hl, bj_bits
        bit     CAN_DOUBLE, (hl)
        jr      z, BJKeyTest
        set     DOUBLED, (hl)
        CALL_(  BJPlayerCard)
        jr      BJStand

BJHit:
        CALL_(  BJPlayerCard)
        ld      a, (player_total)
        and     SCORE_MASK
        cp      22
        jr      nc, BJYouLose
        ld      a, (player_cards+1)
        cp      $80
        jr      z, BJYouWin
        jr      BJKeyTest

BJStand:
        ld      hl, $081C
        ld      a, (dealer_1st)
        ld      c, a
        CALL_(  DrawCardS)                       ;draw card on screen

        ld      b, 50
BJStand_loop:
        halt
        djnz    BJStand_loop

BJDealerHit:
        ld      a, (dealer_total)                ;if the dealer has < 17,
        and     SCORE_MASK                       ;keep hitting
        cp      17
        jr      nc, BJDealerStand
        CALL_(  BJDealerCard)
        jr      BJDealerHit

BJDealerStand:
        cp      22                               ;if the dealer has > 21,
        jr      nc, BJYouWin                     ;you win

        ld      b, a                             ;if you have > dealer,
        ld      a, (player_total)                ;you win
        and     SCORE_MASK
        cp      b
        jr      z, BJPush
        jr      nc, BJYouWin

BJYouLose:                                       ;else
        ld      e, 0                             ;you lose
        ld      hl, msgYouLose
        jr      BJDone
BJYouWin:
        ld      e, 2                             ;you win
        ld      hl, bj_bits
        bit     DOUBLED, (hl)
        jr      z, BJYouWin2
        inc     e
BJYouWin2:
        ld      hl, msgYouWin
        jr      BJDone
BJPush:
        ld      e, 1                             ;its a push!
        ld      hl, msgPush

BJDone:
        JUMP_(  WonMoney)

BJPlayerCard:                                    ;Draw one card for BJ
        ld      ix, player_total
        jr      BJ1Card
BJDealerCard:
        ld      ix, dealer_total
BJ1Card:
        CALL_(  DrawCardD)                       ;draw card from deck
        ld      a, c
	rra
	rra
	rra
	rra
	and	00001111b

        cp      1                                ;if the card is an ace...
        jr      nz, BJ1Card_a
        bit     6, (ix)
        jr      nz, BJ1Card_a
        ld      a, 11                            ;make it 11
        set     6, (ix)
        jr      BJ1Card_b
BJ1Card_a:
        cp      10
        jr      c, BJ1Card_b
        ld      a, 10
BJ1Card_b:
        add     a, (ix)
        ld      (ix), a                          ;store updated score in (ix)
        and     SCORE_MASK
        cp      22
        jr      c, BJ1Card_c                     ;if the score is > 21 then
        bit     6, (ix)
        jr      z, BJ1Card_c                     ;if there's an ace as an 11, then
        sub     10                               ;subtract 10
        ld      (ix), a
        res     6, (ix)
BJ1Card_c:
        ld      a, (ix+1)
        ld      l, a
        cp      $1C                              ;if it is not the dealer,
        ld      a, (ix+2)                        ;jump to display card
        jr      nz, BJ1Card_d                         
	and	a
        jr      nz, BJ1Card_d
        ld      a, c
        ld      (dealer_1st), a
        ld      c, 0                             ;don't show it
        ld      a, 8

BJ1Card_d:
        ld      h, a
        CALL_(  DrawCardS)                       ;draw card on screen
        ld      (ix+2), h
        ld      (ix+1), l
        
        ld      a, (ix+1)
        cp      $1C                              ;if it is not the dealer,
        ret     z                                ;show the score

        ld      h, 0
        ld      a, (ix)
        and     SCORE_MASK
        ld      l, a
        ld      b, 2
        ld      de, $0029
        CALL_(  DisplayNumber)                   ;display the total on the screen
        ret

;************************* Play Poker *******************************
player_hand     = GAME_OFFSET                    ;player's 5 cards
player_held     = GAME_OFFSET+5                  ;cards held: bit 0-4
poker_bits      = GAME_OFFSET+6                  ;bit 0-3 = cards match
                                                 ;bit 4   = flush
                                                 ;bit 5   = strait

PlayPoker:

;***** Draw initial hand
PokerHand1:
	xor	a
        ld      (player_hand), a
        ld      (player_hand+1), a
        ld      (player_hand+2), a
        ld      (player_hand+3), a
        ld      (player_hand+4), a
        ld      (player_held), a
        ld      (poker_bits), a

        CALL_(  Shuffle)

        ld      bc, $0705
        ld      hl, msgYourHand
        CALL_(  DisplayMenuTxt)

        ld      ix, player_hand
        ld      hl, $082F
        ld      b, 5
PokerLoop1:
        CALL_(  DrawCardD)                       ;draw card from deck
        push    bc

        ld      (ix), c                          ;store card in mem.
        inc     ix

        CALL_(  DrawCardS)                       ;draw card on screen
        pop     bc

        djnz    PokerLoop1


;***** let player hold wanted cards
PokerKeyTest:
        ld      bc, $000B
        ld      d, 1

        halt
        call    GET_KEY
        cp      K_F5
        jr      z, PokerHeld5
        cp      K_F4
        jr      z, PokerHeld4
        cp      K_F3
        jr      z, PokerHeld3
        cp      K_F2
        jr      z, PokerHeld2
        cp      K_F1
        jr      z, PokerHeld1
        cp      K_ENTER
        JUMP_Z( PokerHand2)
        jr      PokerKeyTest

PokerHeld5:
        inc     b
PokerHeld4:
        inc     b
PokerHeld3:
        inc     b
PokerHeld2:
        inc     b

        ld      a, c
PokerHeldLoop:
        rlc     d
        add     a, $18
        djnz    PokerHeldLoop
        ld      c, a

PokerHeld1:
        ld      a, (player_held)
        xor     d
        ld      (player_held), a

        ld      hl, msgHeld
        ld      b, $26
        CALL_(  DisplayMenuTxt)

        JUMP_(  PokerKeyTest)


;***** Draw second hand *****
PokerHand2:
        ROM_CALL(CLEARLCD)

        ld      bc, $0705
        ld      hl, msgYourHand
        CALL_(  DisplayMenuTxt)

        ld      ix, player_hand
        ld      b, 1                             ;start with card 1
        ld      hl, $082F
PokerLoop2:
        ld      c, (ix)
        ld      a, (player_held)
        and     b
        CALL_Z( DrawCardD)
        ld      (ix), c
        push    bc
        CALL_(  DrawCardS)
        pop     bc

        inc     ix
        rlc     b
        ld      a, b
        cp      0100000b
        jr      nz, PokerLoop2


;***** Check for winnings *****

PokerHasFlush:                                   ;check for a flush
        ld      hl, player_hand
        ld      a, (hl)
        and     $0F
        ld      b, 4
PokerHasFlushLoop:
        ld      c, a
        inc     hl
        ld      a, (hl)
        and     $0F
        cp      c
        jr      nz, PokerHasStraight
        djnz    PokerHasFlushLoop

        ld      a, $10                           ;actually has a flush
        ld      (poker_bits), a

PokerHasStraight:                                ;check for a straight
        CALL_(  SortA)                           ;sort the cards
        ld      hl, player_hand
        ld      a, (hl)
        and     $F0
        ld      b, 4
PokerHasStraightLoop:
        add     a, $10
        ld      c, a
        inc     hl
        ld      a, (hl)
        and     $F0
        cp      c
        jr      nz, PokerHasStraight2
        djnz    PokerHasStraightLoop

        ld      a, (poker_bits)                  ;actually has a straight
        or      $20
        ld      (poker_bits), a
PokerHasStraight2:                               ;as long as the first is an Ace
        ld      a, (player_hand)                 ;keep changing it to 14 and looping
        and     $F0
        cp      $10
        jr      nz, PokerHasPair
        ld      a, (player_hand)
        xor     $F0
        ld      (player_hand), a
        jr      PokerHasStraight

PokerHasPair:
        ld      hl, player_hand
        ld      a, (hl)
        and     $F0
        ld      b, 4
        ld      d, 1
PokerHasPairLoop:
        ld      c, a
        inc     hl
        ld      a, (hl)
        and     $F0
        cp      c
        jr      nz, PokerHasPairLoop2

        push    af                               ;actually has a pair
        ld      a, (poker_bits)                       
        or      d
        ld      (poker_bits), a
        pop     af
PokerHasPairLoop2:
        rlc     d
        djnz    PokerHasPairLoop


PokerWonRoyalF:
        ld      a, (poker_bits)
        cp      110000b
        jr      nz, PokerWonStraightF
        ld      a, (player_hand)
        and     $F0
        cp      $A0
        jr      nz, PokerWonStraightF
        ld      e, 200                           ;actually won!!
        ld      hl, msgRoyalF
        JUMP_(  PokerDone)

PokerWonStraightF:
        ld      a, (poker_bits)
        cp      110000b
        jr      nz, PokerWon4
        ld      e, 50                            ;actually won!!
        ld      hl, msgStraightF
        JUMP_(  PokerDone)
        
PokerWon4:
        cp      1110b
        jr      z, PokerWon4_b
        cp      0111b
        jr      z, PokerWon4_b
        jr      PokerWonFullH
PokerWon4_b:
        ld      e, 25                            ;actually won!!
        ld      hl, msg4
        JUMP_(  PokerDone)

PokerWonFullH:
        cp      1011b
        jr      z, PokerWonFullH_b
        cp      1101b
        jr      z, PokerWonFullH_b
        jr      PokerWonFlush
PokerWonFullH_b:                                 ;actually won!!
        ld      e, 9
        ld      hl, msgFullH
        jr      PokerDone

PokerWonFlush:
        cp      $10
        jr      nz, PokerWonStraight
        ld      e, 6                             ;actually won!!
        ld      hl, msgFlush
        jr      PokerDone

PokerWonStraight:
        cp      $20
        jr      nz, PokerWon3
        ld      e, 4                             ;actually won!!
        ld      hl, msgStraight
        jr      PokerDone

PokerWon3:
        cp      1100b
        jr      z, PokerWon3_b
        cp      0110b
        jr      z, PokerWon3_b
        cp      0011b
        jr      z, PokerWon3_b
        jr      PokerWon2Pair
PokerWon3_b:
        ld      e, 3                             ;actually won!!
        ld      hl, msg3
        jr      PokerDone

PokerWon2Pair:
        cp      1010b
        jr      z, PokerWon2Pair_b
        cp      1001b
        jr      z, PokerWon2Pair_b
        cp      0101b
        jr      z, PokerWon2Pair_b
        jr      PokerWonJacks
PokerWon2Pair_b:
        ld      e, 2                             ;actually won!!
        ld      hl, msg2Pair
        jr      PokerDone

PokerWonJacks:
        cp      1000b
        jr      nz, PokerWonJacks_b
        ld      a, (player_hand+3)
        jr      PokerWonJacks_e
PokerWonJacks_b:
        cp      0100b
        jr      nz, PokerWonJacks_c
        ld      a, (player_hand+2)
        jr      PokerWonJacks_e
PokerWonJacks_c:
        cp      0010b
        jr      nz, PokerWonJacks_d
        ld      a, (player_hand+1)
        jr      PokerWonJacks_e
PokerWonJacks_d:
        cp      0001b
        jr      nz, PokerYouLose
        ld      a, (player_hand)
PokerWonJacks_e:
        and     $F0
        cp      $B0
        jr      c, PokerYouLose
        ld      e, 1                             ;actually won!!
        ld      hl, msgJacks
        jr      PokerDone

PokerYouLose:
        ld      e, 0                             ;you lose!
        ld      hl, msgYouLose

PokerDone:
        JUMP_(  WonMoney)

;************************* Play Slots *******************************
rand_nums       = GAME_OFFSET                    ;player's 3 random slots

PlaySlots:

        ld      de, SlotMach
        CALL_(  ZCP20)                           ;draw slot machine
SlotsPressEnter:
	call	GET_KEY
	or	a
	jr	z, SlotsPressEnter	

        ld      a, r
        and     7
        add     a, 46
        ld      b, a
        ld      a, r
        and     7
        add     a, b
        add     a, 46
        ld      c, a

        ld      a, 200
SlotsGetNum1:
        ld      e, 0
        CALL_(  SlotsDrawIcon)
SlotsGetNum2:
        ld      e, 1
        CALL_(  SlotsDrawIcon)
SlotsGetNum3:
        ld      e, 2
        CALL_(  SlotsDrawIcon)
        halt
        halt
        dec     a
        cp      c
        jr      nc, SlotsGetNum1
        cp      b
        jr      nc, SlotsGetNum2
        cp      0
        jr      nz, SlotsGetNum3

SlotsCheckWin:
        ld      hl, msgYouWin
        ld      ix, rand_nums
        ld      a, (ix+1)
        cp      (ix)
	jr	nz, SlotsCheckWin2
        cp      (ix+2)
	jr	nz, SlotsCheckWin2

        ld      e, a
        sla     e
        jr      nz, WonMoney                     ;if all 3 have bit in common

SlotsCheckWin2:
        ld      e, 2
        ld      a, (ix+1)
        cp      (ix)
        jr      z, WonMoney                      ;if first 2 are =

        cp      (ix+2)
        jr      z, WonMoney                      ;if last 2 are =

        ld      hl, msgYouLose
        ld      e, 0
        jr      WonMoney


;asdf

SlotsDrawIcon:
        push    af
        push    bc
SlotsDILoop:
        CALL_(  rand)
        rra
        rra
        and     7
        cp      5
        jr      nc, SlotsDILoop
        ld      d, 0
        ld      hl, rand_nums
        add     hl, de
        ld      (hl), a                          ;a contains random # from 1-5
	inc	(hl)

        ld      h, d
        ld      l, e
        add     hl, de
        add     hl, de
        ld      de, VIDEO_MEM+$111
        add     hl, de                           
        ex      de, hl                           ;de contains location to draw

        ld      hl, slotIcons
        ld      bc, (PROGRAM_ADDR)
        add     hl, bc
        ld      b, a
        sla     a                                ;multiply a * 2
        add     a, b                             ;* 3
        sla     a                                ;* 6
        sla     a                                ;* 12
        sla     a                                ;* 24
        ld      b, 0
        ld      c, a
        add     hl, bc                          ;hl contains mem loc. of icon

        ld      b, 12
DrawIconLoop:
        push    bc
        ldi
        ldi
        ex      de, hl
        ld      bc, $000E
        add     hl, bc
        ex      de, hl
        pop     bc
        djnz    DrawIconLoop

        pop     bc
        pop     af
        ret

;************************** Routines ********************************

;********************* Actually Won Money ***************************
;Description:   Displays a "you won" message and updates score
;Parameters:    hl - address of message relative to program
;               a - amount to multiply winnings by
;Destroys:      bc, de, hl

WonMoney:
        ROM_CALL(BUSY_ON)
        push    hl
        ld      b, e
        ld      de, (bet)
        ld      hl, (tmpMoney)
        ld      a, b
	and	a
        jr      z, NoMult
Mult816:
        add     hl, de
        djnz    Mult816
NoMult:
        sbc     hl, de
        ld      (tmpMoney), hl

        ld      b, 255                           ;a delay so you can see the
WMDelay_loop:                                    ;last card
        halt
        djnz    WMDelay_loop
        ROM_CALL(BUSY_OFF)

        ld      hl, VIDEO_MEM+$0183
        ld      c, 16
        ld      de, $0006
WMDrawBox:
        ld      b, 10
WMDrawBox2:
        ld      (hl), $FF
        inc     hl
        djnz    WMDrawBox2
        add     hl, de
        dec     c
        jr      nz, WMDrawBox

WMDispMsg:
        ld      hl, (tmpMoney)
        ld      a, h
        or      l
	and	a
        pop     hl
        jr      nz, WMDispMsg2
        ld      hl, msgGameOver

WMDispMsg2:
        ld      de, (PROGRAM_ADDR)
        add     hl, de

        ld      a, $27
        add     a, (hl)
        inc     hl
        ld      b, $1C
        ld      c, a
        ld      (CURSOR_X), bc
        set     3, (IY+5)                        ;make menu text invert screen
	ROM_CALL(D_ZM_STR)

WonMoneyPause:
        halt
        call    GET_KEY
	and	a
        jr      z, WonMoneyPause
        JUMP_(  MainTop)

;******************* Display Text routines **************************
;Description:   Displays zero terminated text on the screen
;               in menu or regular format
;Parameters:    hl - address of zero terminated string
;                    relative to top of program
;               bc - location on screen
;Destroys:      bc, de, hl

DisplayMenuTxt:
        ld      (CURSOR_X), bc
        ld      de, (PROGRAM_ADDR)
        add     hl, de
        set     3, (IY+5)                        ;make menu text invert screen
	ROM_CALL(D_ZM_STR)
	ret

;DisplayBigTxt:
;	ld      (CURSOR_ROW), bc
;	ld      de, (PROGRAM_ADDR)
;	add     hl, de
;	res     3, (IY+5)
;	ROM_CALL(D_ZT_STR)
;	ret

;******************* Display Number routine *************************
;Description:   Displays a number on the screen in menu format
;Parameters:    hl - number to display
;               b  - number of places (1-5) to display
;               de - location on screen
;Destroys:      a, b, de, hl

DisplayNumber:
        push    de
        ld      de, asciiNumb+5
DispNumbLoop:
        dec     de
        call    UNPACK_HL
        add     a, '0'
        ld      (de), a
        djnz    DispNumbLoop

        ex      de, hl
        pop     de
        ld      (CURSOR_X), de
        res     3, (IY+5)
	ROM_CALL(D_ZM_STR)
	ret

;********************* Display Menu routine *************************
;Description:   Draws the menu bar at the bottom of the screen
;Parameters:    none
;Destroys:      a, bc, hl

DisplayMenu:
        ld      hl, VIDEO_MEM+$380
        ld      b, 32
DisplayMenuLoop1:
        ld      (hl), $FF
        inc     hl
        djnz    DisplayMenuLoop1

        ld      b, 36
        ld      a, $C0
DisplayMenuLoop2:
        ld      (hl), a
        inc     hl
        inc     hl
        inc     hl
        rra
        cp      3
        jr      nz, DisplayMenuLoop2
        ld      a, $C0
        dec     hl
        dec     hl
        djnz    DisplayMenuLoop2

        ret

;************************ Sorting Routine ***************************
;Description:   sorts a list of one byte elements
;Parameters:    c  - number of elements to sort (count)
;               hl - address of first element
;Destroys:      a, hl, ix

SortA:
        ld      c, 5                                  
        ld      hl, player_hand

        push    bc
        push    de

        ld      (tmp), hl
SortAAgain:
        ld      ix, (tmp)
        res     6, h
        ld      b, c
        dec     b
SortANext:
        ld      a, (ix)
        ld      d, a
        ld      e, (ix+1)
        cp      e
        jr      c, SortANoSwitch
SortAXChange:
        ld      (ix), e
        ld      (ix+1), d
        set     6, h
SortANoSwitch:
        inc     ix
        djnz    SortANext

        bit     6, h
        jr      nz, SortAAgain

        pop     de
        pop     bc
        ret

;***************** the random number routine ************************
;Description:   returns a, a random number
;Parameters:    none
;Destroys:      a, d

rand:                                            ;ld's a with a rnd #
        ld      a, (randNum)   
        ld      d, a                             
        sla     d
        sla     d
        add     a, d
        sla     d
        sla     d
        add     a, d
        inc     a
        ld      (randNum), a
        ret

;************* the random card dealing routine **********************
;Description:   returns c, a random card
;Parameters:    none
;Destroys:      a, c

DrawCardD:
        push    de
        push    hl
        ld      a, (cardsLeft)                   ;subtract 1 from cards left
        dec     a
        ld      (cardsLeft), a

DCDrand:
        CALL_(  rand)
        srl     a
        srl     a

        cp      51
        jr      nc, DCDrand

DCDCheck:
        ld      hl, deck                         ;find the card's mem. loc.
        ld      e, a                             ;by adding 0-51 to the first
        ld      d, 0
        add     hl, de                           ;card's loc.

        ld      a, (hl)
	and	a
        jr      nz, DCDLegal

        ld      a, e
        inc     a
        cp      52
        jr      c, DCDCheck
	xor	a
        jr      DCDCheck

DCDLegal:
        ld      c, a
        ld      (hl), 0

        pop     hl
        pop     de

        ret

;***************** the card shuffling routine ***********************
;Description:   resets the deck of cards
;Parameters:    none
;Destroys:      a, bc, de, hl

Shuffle:
        ld      bc, $005A
        ld      hl, msgShuffling
        CALL_(  DisplayMenuTxt)

        ld      hl, 52
        ld      (cardsLeft), hl

        ld      hl, deck
        ld      c, 3
ShuffleLoop1:
        ld      b, 13
ShuffleLoop2:
        halt
        halt
        halt
        ld      a, b
        rla
        rla
        rla
        rla
        add     a, c
        ld      (hl), a
        inc     hl
        djnz    ShuffleLoop2

        dec     c
        ld      a, c
        cp      -1
        jr      nz, ShuffleLoop1

        ld      bc, $005A
        ld      hl, msgShuffling
        CALL_(  DisplayMenuTxt)

        ret

;************ the card drawing routines and DBs *********************
;Description:   Draws a card on the graphics screen
;Parameters:    c - card: high nibble = card #(0-13)
;                         low nibble = suit (0-3)
;               hl - position on screen
;Destroys:      a, bc, de
;               hl = next avail. screen pos. (x + 1, y)


;*** Draw the outline of the card:
DrawCardS:
        ld      b, 50
DCDelay_loop:
        halt
        djnz    DCDelay_loop

        ld      a, c
        srl     a
        srl     a
        srl     a
        srl     a
        ld      b, a                             ;b now contains the card #

        ld      a, c
        and     $3
        ld      c, a                             ;c contains the suit

        push    hl
        push    bc

        ld      b, h
        ld      c, l
        ROM_CALL(FIND_PIXEL)
        ld      de, $FC00
        add     hl, de

        ld      de, $000E

        ld      (hl), $FF                        ;top
        inc     hl
        ld      (hl), $FF
        inc     hl
        ld      (hl), $E0
        ld      b, 18
SideLoop:                                        ;sides
        add     hl, de
        ld      (hl), $80
        inc     hl
        ld      (hl), $00
        inc     hl
        ld      (hl), $20
        djnz    SideLoop

        add     hl, de                           ;bottom
        ld      (hl), $FF
        inc     hl
        ld      (hl), $FF
        inc     hl
        ld      (hl), $E0


;*** Draw the number of the card:
DrawCardNo:
        pop     bc                               ;b contains card #, c contains suit
        pop     hl                               ;hl contains position

        ld      de, $1800                             
        add     hl, de                           ;move hl to the next scrn. pos.

        ld      a, b                             ;check for hidden card (dealer's card)
	and	a
        ret     z

        push    hl                               ;store for end of routine
        ld      de, -$1800
        add     hl, de
        push    hl

        ld      a, $40
        sub     l
        ld      d, a

        ld      e, h
        inc     e
        inc     e

        ex      de, hl

        ld      (CURSOR_X), hl
        ld      hl, (PROGRAM_ADDR)
        ld      de, CardNos
        add     hl, de

cardNoLoop:
        inc     hl
        inc     hl
        djnz    cardNoLoop

        ld      b, 2
        ROM_CALL(D_LM_STR)


;*** Draw the suit of the card:
        ld      a, c

DrawSpade:
        ld      de, spade
        cp      $03
        jr      z, DrawSuit

DrawClub:
        ld      de, club
        cp      $02
        jr      z, DrawSuit

DrawHeart:
        ld      de, heart
        cp      $01
        jr      z, DrawSuit

DrawDiamond:
        ld      de, diamond

DrawSuit:
        ld      hl, (PROGRAM_ADDR)
        add     hl, de
        ex      de, hl

        pop     bc
        ROM_CALL(FIND_PIXEL)
        ld      bc, $FCB1
        add     hl, bc

        ld      bc, $0010

SuitLoop:
        ld      a, (de)
        ld      (hl), a

        add     hl, bc

        inc     de
        ld      a, (de)
        cp      $FF
        jr      nz, SuitLoop

        pop     hl
        ret

spade:          .db $00, $08, $1C, $3E, $7F, $2A, $08, $FF
club:           .db $00, $08, $1C, $2A, $7F, $2A, $08, $FF
heart:          .db $00, $36, $49, $41, $22, $14, $08, $FF
diamond:        .db $08, $14, $22, $41, $22, $14, $08, $FF

cardnos:        .db "  A 2 3 4 5 6 7 8 9 10J Q K "

;**************** Zshell Compressed Pictures ************************
;The TI-based decoder source : zcp.asm
;-------------------------------------
;---
;--- ZCP decoding routine for ZShell 4.0
;--- original by Stephane Jantzen - 12/16/1995
;--- 
;--- This version by Pascal Bouron - 02/11/96
;---
;--- Please report all bugs to :
;--- Bouron@YOKO.ENS-cachan.fr, or
;--- Stephane.Jantzen@scinfo.u-nancy.fr
;---
;paramaters: de - relative loc. of picture data


ZCP20:
        DI
        push    DE
        ld      HL, VIDEO_MEM+$03FF
        xor     A
        ld      (HL), A
        ld      DE, $FFFE
        ld      BC, $03FF
        lddr
        exx
        ld      HL, (PROGRAM_ADDR)
        pop     DE
        add     HL, DE
        ld      C, $80
Loop:
        ld      A, (HL)
        inc     HL
        ld      D, A
        or      A
        jr      Z, EndDecode
        rlca
        jr      C, Copy
Stream:
        ld      A, D
        and     $3F
        ld      B, A
        ld      A, D
        and     $40
StreamLoop:
        or      A
        jr      Z, SLSuite
        ex      AF, AF'
        ld      A, C
        exx
        or      (HL)
        ld      (HL), A
        exx
        ex      AF, AF'
SLSuite:
        srl     C
        jr      NC, DjnzSL
        exx
        inc     HL
        exx
        ld      C, $80
DjnzSL:
        djnz    StreamLoop
        jr      Loop
Copy:
        ld      B, $07
CopyLoop:
        rlca
        jr      NC, CLSuite
        ex      AF, AF'
        ld      A, C
        exx
        or      (HL)
        ld      (HL), A
        exx
        ex      AF, AF'
CLSuite:
        srl     C
        jr      NC, DjnzCL
        exx
        inc     HL
        exx
        ld      C,$80
DjnzCL:
        djnz    CopyLoop
        jr      Loop
EndDecode:
        exx
        EI
        ret


;********************* Main program DBs *****************************
;*** common to all games
money:          .dw 0

msgByLine:      .db "by Doug Melton",0
msgAddx:        .db "<dx4@smartlink.net>",0
msgThanks:	.db "Thanks to:",0
msgThanks2:	.db "Andreas Ess, Stephane Jantzen",0

msgBet:         .db "Bet:$",0
msgMoney:       .db "Money:$",0

msgShuffling:   .db "Shuffling...",0
msgYouWin:      .db 11,"You Win!",0
msgYouLose:     .db 10,"You Lose!",0

msgGameOver:    .db 07,"Game Over!",0

msgYourHand:    .db "Your Hand:",0

;*** blackjack
msgDealerHand:  .db "Dealer Hand:",0
msgBlackJack:   .db 05,"Black Jack!",0
msgPush:        .db 08,"Its a Push!",0

msgHit:         .db "HIT",0
msgStand:       .db "STAND",0
msgDouble:      .db "DUBLE",0
msgInsure:      .db "INSURE",0
msgForfeit:     .db "FORFIT",0

;*** poker
msgHeld:        .db "Held",0

msgRoyalF:      .db 03,"Royal  Flush!",0
msgStraightF:   .db 00,"Straight  Flush!",0
msg4:           .db 06,"4 of a Kind!",0
msgFullH:       .db 07,"Full  House!",0
msgFlush:       .db 13,"Flush!",0
msgStraight:    .db 09,"Straight!",0
msg3:           .db 06,"3 of a Kind!",0
msg2Pair:       .db 13,"2 Pair!",0
msgJacks:       .db 00,"Jacks or Better!",0

;*** slots
slotIcons:      ;each should be 16x12
cherry:         .db $00, $00, $00, $00, $00, $40, $00, $80, $00, $80, $00, $80
                .db $03, $F0, $06, $78, $07, $F8, $03, $F0, $00, $00, $00, $00
hpyface:        .db $00, $00, $03, $C0, $04, $20, $08, $10, $12, $48, $10, $08
                .db $14, $28, $13, $C8, $08, $10, $04, $20, $03, $C0, $00, $00
seven:          .db $00, $00, $3F, $FE, $20, $06, $2F, $CC, $38, $48, $30, $D8
                .db $01, $90, $01, $30, $03, $20, $02, $20, $03, $F0, $00, $00
star:           .db $00, $00, $01, $00, $03, $80, $03, $80, $7F, $FC, $3F, $F8
                .db $0F, $E0, $07, $C0, $0F, $E0, $0E, $E0, $1C, $70, $00, $00
bar:            .db $00, $00, $00, $00, $00, $00, $7F, $FE, $48, $02, $4D, $B2
                .db $4D, $A2, $7F, $FE, $00, $00, $00, $00, $00, $00, $00, $00

;*** the compressed picture of the title screen
menuData: ;should have 27 lines of 16 bytes
        .db $00,$40,$02,$00, $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00
        .db $00,$A0,$05,$00, $7D,$F7,$DF,$7C, $7F,$FF,$FF,$EE, $38,$00,$00,$0E
        .db $01,$10,$08,$80, $65,$96,$59,$64, $40,$00,$00,$2E, $3E,$01,$C0,$3E
        .db $02,$08,$10,$40, $65,$96,$59,$64, $5F,$9F,$9F,$AE, $3F,$81,$00,$FE
        .db $04,$04,$20,$A0, $45,$14,$51,$44, $50,$90,$90,$AE, $3F,$E1,$83,$FE
        .db $09,$C2,$51,$10, $45,$14,$51,$44, $54,$92,$94,$AE, $3F,$F1,$07,$FE
        .db $11,$21,$92,$08, $45,$14,$51,$44, $52,$94,$92,$A6, $3F,$F1,$C7,$FE
        .db $09,$50,$8C,$10, $45,$14,$51,$44, $50,$90,$90,$A6, $3F,$F0,$07,$FE
        .db $04,$80,$40,$20, $7D,$F7,$DF,$7C, $5F,$9F,$9F,$A6, $3F,$F1,$47,$FE
        .db $02,$40,$20,$40, $00,$00,$00,$00, $40,$00,$00,$26, $3F,$F1,$47,$FE
        .db $01,$00,$40,$80, $00,$00,$00,$00, $7F,$FF,$FF,$E6, $3F,$F0,$87,$FE
        .db $00,$80,$81,$00, $00,$02,$00,$00, $00,$00,$00,$06, $3F,$F1,$47,$FE
        .db $00,$41,$82,$00, $3C,$02,$00,$00, $7F,$FF,$FF,$E6, $3F,$91,$44,$FE
        .db $00,$22,$44,$00, $22,$02,$00,$00, $5C,$07,$01,$E6, $3F,$90,$04,$FE
        .db $00,$14,$28,$00, $22,$72,$40,$00, $62,$E8,$BA,$26, $3F,$F1,$C7,$FE
        .db $00,$08,$10,$00, $22,$8A,$80,$B0, $63,$18,$C6,$26, $3F,$F0,$87,$FE
        .db $08,$42,$02,$00, $3C,$8B,$00,$C8, $63,$18,$C6,$26, $3F,$F0,$87,$FE
        .db $08,$45,$1A,$00, $20,$8A,$8C,$80, $5D,$17,$45,$E6, $3F,$F0,$87,$FE
        .db $0E,$47,$22,$B8, $20,$8A,$52,$80, $40,$E0,$38,$26, $3F,$F1,$C7,$FE
        .db $09,$45,$23,$00, $20,$70,$1E,$80, $7F,$FF,$FF,$E6, $3F,$F0,$07,$FE
        .db $0E,$78,$1A,$80, $20,$00,$10,$80, $00,$00,$00,$00, $3F,$F1,$C7,$FE
        .db $00,$00,$00,$00, $20,$00,$12,$00, $0E,$40,$04,$38, $3F,$F0,$87,$FE
        .db $00,$12,$05,$00, $00,$00,$0C,$00, $10,$41,$8E,$40, $3F,$E0,$83,$FE
        .db $00,$15,$36,$00, $00,$00,$00,$00, $0C,$42,$44,$30, $3F,$80,$80,$FE
        .db $00,$17,$44,$00, $00,$00,$00,$00, $02,$42,$44,$08, $3E,$00,$80,$3E
        .db $00,$95,$46,$00, $00,$00,$00,$00, $1C,$71,$84,$70, $38,$00,$00,$0E
        .db $00,$60,$35,$00, $00,$00,$00,$00, $00,$00,$00,$00, $00,$00,$00,$00

;*** the compressed picture of the title screen
titleScreen:
      .db    $3F,$3F,$3F,$3F,$10,$49,$13,$FF,$24,$F0,$32,$4B,$0F,$4B,$22,$F0
      .db    $32,$4B,$0E,$4C,$22,$F0,$39,$F8,$0A,$FC,$8E,$22,$E0,$37,$FC,$0B
      .db    $F8,$1C,$FF,$83,$3C,$FC,$0B,$F8,$16,$F1,$FF,$83,$DC,$11,$F8,$1C
      .db    $FC,$0C,$F8,$11,$49,$BF,$F0,$BF,$49,$80,$49,$1D,$FC,$0D,$F0,$0F
      .db    $4B,$BC,$08,$50,$83,$49,$1B,$FC,$0E,$F0,$0E,$4C,$BF,$08,$F7,$49
      .db    $87,$4A,$19,$FC,$0F,$F0,$0D,$FD,$FE,$BF,$C1,$F7,$E3,$F1,$F8,$BC
      .db    $17,$F8,$80,$FF,$B8,$0E,$F0,$BE,$8F,$E1,$F7,$C1,$F3,$E0,$BC,$16
      .db    $F8,$08,$FF,$B8,$0D,$F8,$8F,$80,$F8,$F9,$E0,$F9,$F0,$8E,$16,$F8
      .db    $0C,$FB,$C0,$0A,$F0,$87,$08,$F9,$F3,$C1,$F3,$C0,$9E,$14,$F8,$12
      .db    $F8,$0C,$F0,$87,$09,$F3,$C7,$83,$E7,$C0,$FC,$13,$F8,$9F,$0C,$F8
      .db    $83,$C7,$08,$FE,$87,$CE,$9C,$8F,$8F,$87,$E0,$11,$4F,$0B,$FE,$87
      .db    $E7,$C0,$48,$8F,$CF,$BC,$8F,$8F,$DF,$C0,$11,$4F,$0C,$4F,$8F,$87
      .db    $4D,$8F,$BC,$8F,$87,$FF,$18,$4D,$0F,$4D,$87,$54,$83,$9E,$83,$C1
      .db    $FF,$19,$FC,$17,$4A,$81,$4C,$9F,$C0,$83,$C0,$09,$FC,$3F,$0A,$FE
      .db    $B0,$00

;*** the compressed picture of the slot machine, full screen
SlotMach:
      .db    $3F,$3F,$3F,$3F,$0F,$4A,$3F,$35,$4E,$3F,$31,$FE,$87,$74,$10,$48
      .db    $26,$FC,$83,$75,$0D,$FD,$F8,$21,$FC,$80,$76,$0C,$C2,$CE,$22,$F8
      .db    $08,$E0,$0E,$FC,$15,$4C,$8F,$97,$98,$1F,$F8,$08,$E0,$0E,$FC,$15
      .db    $4D,$98,$D0,$90,$1E,$F8,$08,$F0,$0E,$FC,$15,$4D,$98,$B5,$90,$1E
      .db    $F8,$08,$7E,$97,$AF,$F0,$1E,$F8,$08,$7E,$9E,$F7,$E0,$1E,$FC,$80
      .db    $7F,$8F,$F7,$C0,$1D,$FF,$80,$7F,$C3,$48,$24,$48,$83,$7F,$08,$F8
      .db    $23,$7F,$4F,$08,$F8,$23,$7F,$50,$80,$F8,$21,$F8,$11,$F0,$10,$F0
      .db    $10,$4B,$80,$F8,$21,$F8,$11,$F0,$10,$F0,$10,$4B,$80,$F8,$21,$F8
      .db    $11,$F0,$10,$F0,$10,$4B,$80,$F8,$21,$F8,$11,$F0,$10,$F0,$10,$4B
      .db    $80,$F0,$21,$F8,$11,$F0,$10,$F0,$10,$4B,$80,$F0,$21,$F8,$11,$F0
      .db    $10,$F0,$10,$4B,$80,$F0,$21,$F8,$11,$F0,$10,$F0,$10,$4B,$80,$F0
      .db    $21,$F8,$11,$F0,$10,$F0,$10,$4B,$80,$F0,$21,$F8,$11,$F0,$10,$F0
      .db    $10,$4B,$80,$F0,$21,$F8,$11,$F0,$10,$F0,$10,$4B,$80,$F0,$21,$F8
      .db    $11,$F0,$10,$F0,$10,$4B,$80,$F0,$21,$F8,$11,$F0,$10,$F0,$10,$4B
      .db    $80,$F0,$21,$7F,$52,$80,$F0,$21,$7F,$52,$80,$F0,$21,$7F,$53,$81
      .db    $E0,$20,$F0,$3F,$9F,$FC,$87,$25,$F0,$27,$C0,$13,$4A,$81,$E0,$20
      .db    $F0,$8F,$F0,$FC,$11,$F0,$14,$53,$25,$F8,$9F,$F9,$FE,$11,$F0,$13
      .db    $54,$25,$F8,$9F,$FB,$FE,$11,$F0,$13,$54,$25,$F8,$81,$F7,$EE,$9F
      .db    $C7,$C4,$BF,$83,$E0,$BF,$FE,$2C,$F8,$81,$F7,$C0,$BF,$CF,$EE,$BF
      .db    $C7,$F0,$BF,$FE,$2C,$F8,$83,$E7,$80,$48,$9F,$DC,$48,$BF,$E1,$4B
      .db    $2D,$F8,$87,$C7,$80,$F3,$CF,$8E,$BB,$EE,$F8,$BF,$FE,$2E,$F8,$BC
      .db    $9E,$83,$CE,$BF,$B9,$E7,$B1,$E7,$4B,$2F,$F8,$BC,$9F,$9B,$CE,$8F
      .db    $B9,$E7,$BB,$E7,$4B,$2F,$F8,$49,$BF,$EF,$FB,$FD,$E7,$9D,$FF,$9F
      .db    $49,$2F,$F8,$49,$9F,$E7,$FB,$FD,$E7,$9C,$FE,$9F,$49,$2F,$F8,$49
      .db    $8F,$E3,$F9,$F8,$E6,$98,$BC,$9F,$49,$2F,$F8,$3C,$4E,$2F,$7F,$52
      .db    $30,$7F,$51,$30,$7F,$51,$30,$7F,$50,$31,$7F,$4F,$33,$7F,$4E,$34
      .db    $7F,$4C,$35,$7F,$4D,$34,$7F,$4D,$33,$7F,$4D,$34,$7F,$4D,$33,$7F
      .db    $4D,$34,$7F,$4C,$36,$7F,$4A,$3F,$21,$48,$00

.end

