Full Version : Kwok & Leung Blackjack Machine (ASM)
avr >>GAME & VIDEO PROJECTS >>Kwok & Leung Blackjack Machine (ASM)


Admin5- 04-21-2006
Blackjack by Kenneth Kwok & Min Jee (Andy) Leung


Introduction
In this project we created a video blackjack machine using AT90S8535. In our previous labs we have gained familiarity with the 8-bit AVR microcontroller and the UART interface to transmit to and receive from a terminal. Our blackjack machine outputs text to the terminal through the UART, and at the same time accepts input from the user through push buttons. The core of our program is a random number generator which uses a 16-bit shift register and a primitive polynomial modulo 2.



Our rules of blackjack in this machine

The player attempts to beat the dealer (the computer) by obtaining a hand total that is equal to or less than 21 so that his/her total is higher than the dealer’s. Each card has the same value as its index except for the aces and the picture cards. All pictures cards are counted as 10, while aces can be counted as 11 or 1, depending on the player’s choice. At the beginning of the game, the player is first dealt two cards in sequence and the dealer receives two cards, one face up and one face down. The player then has the choice to stand (no more card), to hit (wants one more card), or to double down. Doubling down means the player want to double the amount of his initial bet and receives only one additional card only. After the third card, the player can only stand or hit. This continues until either the player is busted (his/her hand exceeds a total of twenty one) or the player stands. After this, the dealer exposes his first unexposed card and draws card until he/she has a total or 17 or above. The player wins if his hand is not busted and is greater than the dealer’s.



High-level design

Our blackjack machine is in fact a state machine. The algorithm of our machine is as follows:

Display the "Welcome to try our Black Jack" banner out of reset, and wait for player to press the "New Game" button.
At the beginning the player has 10 points in total, the program then asks how many points he/she wants to bet for this game. The program waits till the player has entered the bet and stores the value into RAM.
It deals 2 cards to dealer and 2 cards to player, and displays one of dealer’s cards and all of player’s cards.
If the player’s hand is black jack, player wins and game is over. If player is busted, player loses and game is over. (go to step 8)
The player selects either to stand, to hit or to double down. Doubling down is only available only when the player has two cards.
If player chooses to double down, deal him/her a card and then go to step 7. If player chooses to hit, deal him/her a card and go to step 4. If player chooses to stand, go to step 7.
Find out the score of player’s hand, and dealer receives cards until it reaches at least 17 or it is busted. If dealer’s hand is greater than the player’s, dealer wins; if player’s hand is greater, player wins; otherwise, the game is tied.
Game is over. It has two options. If player’s total point is greater than 0, player can choose "next round", "new game" or "to quit"; else, player can only choose "new game" or quit".

Here is the state diagram of our machine:



Specific Details

Random number generator

Our method for generating random numbers is to perform bit-wise operations in a 16-bit register (or two 8-bit registers since there are only 8 bit registers in the AT90S8535 microprocessor. We generate 8 random bits to obtain a random number. The theory of generating random bits is based on primitive polynomials modulo 2. Each primitive polynomial modulo 2 of order n defines a recurrence relation for obtaining a new random bit from the n preceding ones. It guarantees to generate 2n – 1 random bits before the sequence bits. In our sixteen-bit case, we are able to generate 215 – 1 (32767) bits in each cycle. We use the following primitive polynomial in our machine:

x15 + x + 1
This equation tells us how to generate the new bit from the 16 bit register. Let the bits be numbered starting b0 from the right to b15 at the very left. The new bit is simply b15 ^ b1 ^ b0. The old contents of the register is shifted to the left once and then this new bit is added to becomes b0. This operation is performed eight times to get a new word (8 bits). Procedure get_random performs the above operations.

Furthermore, get_random produces 10 different cards at a time. After it has got a random 8 bit number, it converts to a number ranged from 0-51 using the mod operation, and each number corresponds to a card. Each time a card is generated, the procedure will check with previous card values to ensure that cards are not duplicated. If the card is duplicated, the program will keep generating cards until they do not have identical values.

We first need an initial value (seed) to put into this 16-bit register. Our implementation of this game forces this seed to be different every time a new game is started. We first define an arbitrary value in the 16-bit register; however, when the program is waiting for the user to press "new game" to start a new game, inside the wait loop, the value in the 16-bit register keeps decrementing until the player pushes the button. This way we can ensure that a different set of cards will be dealt when a new game starts.

Hardware (Push buttons and LEDs)

Our project requires minimal hardware. In fact our initial machine involves no extra hardware at all since we make the full use of the UART interface to accept input from the keyboard and to output text to a computer terminal. Nevertheless, it now uses the push buttons to accept inputs. There are eight push buttons in our machine. Since during each user’s input selection, only a few buttons are valid. There are LEDs next to the buttons to show which ones are the valid inputs. Below shows a schematic of our hardware:





Output

Our user interface is text-based since it uses serial I/O UART. Since it’s only text based, we can only show the cards by numbers and letters. Here is our notation:
A - Ace
T - Ten
J - Jack
Q - Queen
K - King

D - Diamonds
C - Clubs
H - Hearts
S - Spades


For example, if the hand has 10 of Spades, Queen of Hearts, Ace of Spades, 6 of Clubs and 9 of Diamonds, it will be displayed as:

TS QH AS 6C 9D

The code involving UART is very simple. It is the same as the one we used in lab 4.



What we would do differently next time

While building this blackjack machine, we encountered few serious problems at the beginning with our code. For example, our cards generated were not random at all, and there were a lot of problems with the output of text messages through the UART interfaces. Nevertheless, these bugs were eliminated through our thorough inspection of our codes, and through simulating in AVR Studio. We have spent a substantial amount of time in debugging, and therefore, what we would do differently next time is to change our way of writing codes, and debugging. In the first two weeks of our project, we wrote our code for the whole game without testing them, and in the last week we encountered a lot of problems since the code was not working as expected. And we had no idea how to tackle the problems initially since the code is so big. Therefore, next time, we would write small pieces of code one by one, thoroughly test them pieces by pieces before merging into one big program.

Furthermore, since we output to a terminal through UART, our product is not portable at all. We would like to make it more portable next time. We looked at the catalog, and we could not find a good and inexpensive LCD. We do not use the LCD we used in Labs 5 & 6 for display because the 16-character limit is too restrictive. There is a 2-line LCD in the catalog; however, this 2-line limit is also restrictive in our opinion and we thus use the terminal for display. Next time we would like to use a color, bit-mapped LCD. We would not display the numbers and suits of the cards, but instead images of real cards. It would take us a lot of time, but only with this kind of display could we make our project more like a real product sold in market.

Link: http://instruct1.cit.cornell.edu/courses/e.../blackjack.html

CODE

;**** macros *******

.macro  ldi_ram;@0 variable @1 immediate value;write an immediate value into RAM
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
       ldi     temp, @1
   st  Z, temp
.endmacro

.macro  ld_ram ;@0 variable @1 register   ;write a register value into RAM
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   st  Z, @1
.endmacro

.macro  st_ram ;@0 register @1 variable in RAM;write from RAM to register
   ldi ZL, LOW(@1)
   ldi ZH, HIGH(@1)
   ld  @0, Z
.endmacro


.macro  add_ram;@0 variable in RAM @1 variable in RAM; add variables in RAM
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   ld  temp, Z

   ldi ZL, LOW(@1)
   ldi ZH, HIGH(@1)
   ld  temp1, Z

   add temp, temp1

   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   st  Z, temp
.endmacro

.macro  addi_ram   ;@0 variable in RAM @1 immediate value
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   ld  temp, Z

   ldi temp1, @1

   add temp, temp1

   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   st  Z, temp
.endmacro


.macro  sub_ram;@0 variable in RAM @1 variable in RAM; add variables in RAM
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   ld  temp, Z

   ldi ZL, LOW(@1)
   ldi ZH, HIGH(@1)
   ld  temp1, Z

   sub temp, temp1

   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   st  Z, temp
.endmacro

.macro  tst_ram;@0 variable in RAM; equivalent to tst
   ldi ZL, LOW(@0)
   ldi ZH, HIGH(@0)
   ld  temp, Z

       tst     temp
.endmacro


; given a 8-bit number (0-0xff), convert it into a number range from 0-52
; random MOD 13, quotient is corresponding to suit, and remainder + 1 is
; corresponding to card number
; quotient = 0: diamond 1: club 2: heart 3: spade
; probably can write a macro for the MOD function
; example: simple_mod  random, 52, remainder

.macro simple_mod

   lsr @0
ratio:
       cpi     @0, @1
       brlt    remainder
       subi    @0, @1
       rjmp    ratio
remainder:
   mov @2, @0
endm:
.endmacro


; given a random number(0-51), decode it as a card
; random MOD 13, quotient is corresponding to suit, and remainder + 1 is
;corresponding to card number
; quotient = 0: diamond 1: club 2: heart 3: spade
; probably can write a macro for the MOD function
; example: mod  random, 13, Dsuit3, Dcardnum3, DAce
;                 @0    @1    @2     @3         @4

.macro mod

   ldi ZL, LOW(@4)    ;st_ram temp2, @4
   ldi ZH, HIGH(@4)
   ld  temp2, Z

       clr     temp
ratio:
       cpi     @0, @1
       brlt    remainder
       subi    @0, @1
       inc     temp
       rjmp    ratio
remainder:
   mov temp1, @0  
   inc temp1
ace:
       cpi     temp1, 1
       brne    endm
       ldi     temp2, 1
endm:
   ldi ZL, LOW(@2);ld_ram @2, temp
   ldi ZH, HIGH(@2)
   st  Z, temp

   ldi ZL, LOW(@3);ld_ram @3, temp1
   ldi ZH, HIGH(@3)
   st  Z, temp1


   ldi ZL, LOW(@4);ld_ram @4, temp2
   ldi ZH, HIGH(@4)
   st  Z, temp2
.endmacro

; find out the largest possible hand and store it back to the 2nd parameter
; 1st parameter indicates if the hand has an Ace or not
; 2nd parameter originally stores the normal current hand without
; having the "Ace effect."
; example: AceHand  PAce, Phand
; if PAce is 1 and Phand is 11, then after calling AceHand
; Phand is equal to 21; on the other hand, if PAce is 0 or Phand
; is originally greater than 11, then Phand's final value will not be
; changed
 
.macro AceHand

   ldi ZL, LOW(@1);st_ram temp1, @1
   ldi ZH, HIGH(@1)
   ld  temp1, Z

   ldi ZL, LOW(@0);st_ram temp2, @0
   ldi ZH, HIGH(@0)
   ld  temp2, Z

       tst     temp2
       breq    noAce

       cpi     temp1, 12
       brge    noAce
       subi    temp1, -10

;   ldi ZL, LOW(@1);ld_ram @1, temp1
;   ldi ZH, HIGH(@1)
;   st  Z, temp1
noAce:  

.endmacro

.macro  tx_text_predefined
   
      ;now the pointer to the preset message
       ldi     ZL, LOW(@0<<1) ;ptr to message
       ldi     ZH, HIGH(@0<<1)
       lpm
       out     UDR, r0        ;fire off the UART transmit
       ser     TXflash        ;the string is in flash
       ser     TXbusy         ;and set the TX busy flag
       sbi     UCR, UDRIE     ;enable the TXempty interrupt
       rcall   TXwait
.endmacro

.macro  tx_text_variable
      ;now the pointer to the variable message in RAM
       ldi     ZL, LOW(@0) ;ptr to RAM
       ldi     ZH, HIGH(@0)
       ld      r0,Z
       out     UDR, r0        ;fire off the UART transmit
       clr     TXflash        ;the string is in RAM
       ser     TXbusy         ;and set the TX busy flag
       sbi     UCR, UDRIE     ;enable the TXempty interrupt
       rcall   TXwait
.endmacro

; prepare string pointers for the prepare_string routine

.macro  p_pre_string
   ldi ZL, low(@0)
   ldi ZH, high(@0)
   mov param1a, ZL
   mov param1b, ZH

   ldi ZL, low(@1)
   ldi ZH, high(@1)
   mov param2a, ZL
   mov param2b, ZH
.endmacro

;;;;;;;;;;;;;; END OF MACROS;;;;;;;;;;;;;;;;;;;

;Leung, Min Jee (Andy) & Kenneth Kwok
;Final Project: Black Jack

.include "c:\users\k&a\8535def.inc"
.device AT90S8535

.include "c:\users\k&a\final\macro.inc"

;***********************
.def    hundreds=r2
.def    tens =r3
.def    ones =r4
.def    rones=r5
.def    rzeros=r6

.def    tempran0 =r7
.def    tempran1 =r8
.def    tempran2 =r9

.def    param1a =r10
.def    param1b =r11
.def    param2a =r12
.def    param2b =r13

.def    count =r14 ;counter for random number generation
.def    count1=r15

.def    random  =r17
.def    temp    =r16   ;temporary register
.def    savSREG =r18   ;save the status register
.def    TXbusy  =r19   ;transmit busy flag
.def    RXchar  =r20   ;a received character
.def    TXflash =r21   ;text to be sent is in flash if <>0
.def    temp1   =r22
.def    temp2   =r23
.def    remainder=r24
.def    random_ptr = r25;pointer to a card in the random array
.def    response = r26
.def    mode = r27
.equ    baud96  =25    ;9600 baud constant for 4Mhz crystal
.equ    tteen   =13
.equ    go      ='g'   ;0x67 ascii 'g'
.equ    stop    ='s'   ;0x73 ascii 's'
.equ    azero   ='0'   ;0x30 ascii '0'
.equ    one     ='1'
.equ    two     ='2'
.equ    n       ='n'
.equ    r       ='r'
.equ    q       ='q'
.equ    hit     ='h'
.equ    double  ='d'
.equ    stand   ='s'
.equ    tee     = 'T'
.equ    jay     = 'J'
.equ    cue     = 'Q'
.equ    kay     = 'K'
.equ    ay      = 'A'
.equ    dee     = 'D'
.equ    cee     = 'C'
.equ    haych   = 'H'
.equ    es      = 'S'
.equ    space   = ' '

;**************************************
.dseg
;define variable strings to be tranmitted from RAM
;if have time, implement player's name as well
;playername: .byte   11 ;no longer than 10 chars + a zero terminate

Ppoints:    .byte 1    ;to store player's points
cards:      .byte 10   ;to store the ten cards generated randomly
bet:        .byte 1    ;player's current bet
Phand:      .byte 1    ;player's current hand
Dhand:      .byte 1    ;dealer's current hand
PAce:       .byte 1    ; Ace = 0:no Ace in hand =1: has Ace in hand for player
DAce:       .byte 1    ; Ace = 0:no Ace in hand =1: has Ace in hand for dealer
Busted:     .byte 1    ; not 0: hand is greater than 21
BlackJack:  .byte 1    ; not 0: hand is equal 21
Dsuit1:     .byte 1
Dcardnum1:  .byte 1
Dsuit2:     .byte 1
Dcardnum2:  .byte 1
Dsuit3:     .byte 1
Dcardnum3:  .byte 1
Dsuit4:     .byte 1
Dcardnum4:  .byte 1
Dsuit5:     .byte 1
Dcardnum5:  .byte 1
Psuit1:     .byte 1
Pcardnum1:  .byte 1
Psuit2:     .byte 1
Pcardnum2:  .byte 1
Psuit3:     .byte 1
Pcardnum3:  .byte 1
Psuit4:     .byte 1
Pcardnum4:  .byte 1
Psuit5:     .byte 1
Pcardnum5:  .byte 1

str_ptr:    .byte 4

;**************************************
.cseg
.org $0000
       rjmp    RESET  ;reset entry vector
   reti
   reti
       reti
       reti    
       reti    
       reti    
       reti    
       reti    
   reti
       reti                    
       rjmp    RXdone ;UART receive done
       rjmp    TXempty;UART buffer empty
       rjmp    TXdone ;UART transmit done
       reti
   reti
   reti
   reti

nextround_txt:
       .db     "Press 'n' to play next round or", 0x00
resetquit_txt:
       .db     "Press 'r' to start a new game or", 0x00
resetquit_txt1:
   .db "Press 'q' to quit the game: ", 0x00
welcome_txt:
       .db     "Welcome to try our Black Jack!", 0x00
welcome_txt1:
   .db "Please press 'g' to start the game: ", 0x00
win_txt:    
   .db     "You win!", 0x00
lose_txt:
   .db     "You lose.", 0x00
tie_txt:    
   .db "Tied Game!", 0x00

crlf:   .db     0x0d, 0x0a, 0x00       ;carrage return/line feed

;define fixed strings to be tranmitted from flash- zero terminated

junk:   .db "This space stores junks.......................", 0x00
points: .db     "Your Current Points: ", 0x00
bet_txt:
   .db     "How many points do you want to bet? (1 or 2): ", 0x00
bust_txt:  .db     "Your hand is busted!", 0x00
action_dd_txt:
   .db "or 'd' for 'double down':", 0x00

action_ndd_txt:
   .db     "Press 'h' for 'hit me', or 's' for 'stand': ", 0x00

bj_txt:     .db     "You have a Black Jack!", 0x00
dealer_txt: .db "Dealer's Hand: ", 0x00
player_txt: .db "Player's Hand: ", 0x00
dfirst_txt: .db "XX ", 0x00
gameover:  
       .db     "You have no more points left. Game Over!", 0x00


RESET:  ldi     temp, LOW(RAMEND);setup stack pointer  
       out     SPL, temp
       ldi     temp, HIGH(RAMEND)
       out     SPH, temp

       ldi     temp,1    
   mov rones, temp

   ldi temp, 0
   mov     rzeros, temp
   
   ldi temp, 0b01011010   ; for random number generator
   mov count, temp

   ldi temp, 0b01000000   ; for random number generator
   mov count1, temp


      ;initial conditions
       clr     TXbusy         ;start out not busy on TX
       ldi     RXchar, stop     ;start out not running

      ;setup UART -- enable TXempty & RXdone int, and RX, TX pins
       ldi     temp, 0b10111000
       out     UCR, temp      

  ;set baud rate to 9600
       ldi     temp, baud96
       out     UBRR, temp

       ser     Temp           ;set PORTB to be
       out     DDRB,Temp      ;all outputs

      ;intialize text pointer BEFORE turning on interrupts
      ;because RESET causes the TX empty flag to be SET

       ldi     ZL, LOW(crlf<<1);do shift to convert word-addr to byte
       ldi     ZH, HIGH(crlf<<1)

   
   ldi temp, 0xff
   out PORTB, temp

       sei; enable global interrupts and wait for Rxdone interrupt


      ;now print three strings and wait for incoming character interrupt
  ;clr     TXbusy         ;start out not busy on TX

; display banner of "Welcome to try our Black Jack" out of reset

      ;now the pointer to the preset message

   tx_text_predefined crlf
   tx_text_predefined welcome_txt
   tx_text_predefined crlf
   tx_text_predefined welcome_txt1


; wait for player to hit the "start" button
startWait:

   sub count, rones
   sbc count1, rzeros
       cpi     RXchar, go;wait for go signal - a 'g' on the keyboard
       brne    startWait

   tx_text_predefined crlf
; ask player to enter his/her name if we have time to implement this
;       rcall   get_name;store player's name into ram

newGame:
; At the beginning, player has 10 points.

   ldi_ram Ppoints, 10

   tx_text_predefined crlf
   rcall   display_points

nextGame:
; initialize some registers' values

   rcall   get_random  

       ldi_ram Phand, 0   ; player's current hand
       ldi_ram Dhand, 0   ; dealer's current hand
       ldi_ram PAce, 0    ; Ace = 0:no Ace in hand else: has Ace in hand for player
       ldi_ram DAce, 0    ; Ace = 0:no Ace in hand else: has Ace in hand for dealer
       ldi_ram Busted, 0  ; not 0: hand is greater than 21
       ldi_ram BlackJack, 0   ; not 0: hand is equal 21
   
  ;initialize all cards to -1 first  -- this is for display purpose
   ldi_ram Dsuit1, -1
   ldi_ram Dcardnum1, -1
   ldi_ram Dsuit2, -1
   ldi_ram Dcardnum2, -1
   ldi_ram Dsuit3, -1
   ldi_ram Dcardnum3, -1
   ldi_ram Dsuit4, -1
   ldi_ram Dcardnum4, -1
   ldi_ram Dsuit5, -1
   ldi_ram Dcardnum5, -1

   ldi_ram Psuit1, -1
   ldi_ram Pcardnum1, -1
   ldi_ram Psuit2, -1
   ldi_ram Pcardnum2, -1
   ldi_ram Psuit3, -1
   ldi_ram Pcardnum3, -1
   ldi_ram Psuit4, -1
   ldi_ram Pcardnum4, -1
   ldi_ram Psuit5, -1
   ldi_ram Pcardnum5, -1

   mov random_ptr, rzeros ;first element in the array

; ask player how much he/she wants to bet for this game

   tx_text_predefined crlf
   tx_text_predefined bet_txt

;wait for player to enter the bet
betWait:
       cpi     RXchar, one
       breq    betExit
       cpi     RXchar, two
       brne    betWait  
betExit:
   tx_text_predefined crlf

; store player's bet into variable bet
       mov     temp, Rxchar
       subi    temp, azero; convert from ascii to number
   ld_ram  bet, temp
               
; deal 2 cards to dealer and 2 cards to player

  ; get the first random # into register random
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Dsuit1, Dcardnum1, DAce; dealer's 1st card (hidden)
   
   st_ram  temp, Dcardnum1
   cpi temp, 10
   brlt    dc1_10
   addi_ram    Dhand, 10
   rjmp    dc1a_10
dc1_10: add_ram Dhand, Dcardnum1
dc1a_10:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Psuit1, Pcardnum1, PAce; player's 1st card

   st_ram  temp, Pcardnum1
   cpi temp, 10
   brlt    pc1_10
   addi_ram    Phand, 10
   rjmp    pc1a_10
pc1_10: add_ram Phand, Pcardnum1
pc1a_10:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Dsuit2, Dcardnum2, DAce; dealer's 2nd card

   st_ram  temp, Dcardnum2
   cpi temp, 10
   brlt    dc2_10
   addi_ram    Dhand, 10
   rjmp    dc2a_10
dc2_10: add_ram Dhand, Dcardnum2
dc2a_10:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Psuit2, Pcardnum2, PAce; player's 2nd card

   st_ram  temp, Pcardnum2
   cpi temp, 10
   brlt    pc2_10
   addi_ram    Phand, 10
   rjmp    pc2a_10
pc2_10: add_ram Phand, Pcardnum2
pc2a_10:


; display one of dealer's card and both of player's cards
       ldi     mode, 0; display mode
       rcall   display; display cards on screen depends on mode

       rcall   check_bj; store status of black jack into register BlackJack
   tst_ram BlackJack
       breq    Pcard3  
       add_ram bet, bet; double the bet
       rjmp    playerWon      
       
;now player need to decide to choose "hit me", "stand" or "double down"
;response = 0:hit me; 1:double down; 2:stand
Pcard3:
   ldi mode, 0
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    doubleDown3_temp

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit3, Pcardnum3, PAce
   rjmp    dd3_after
doubleDown3_temp: rjmp doubleDown3 ;branch too long

dd3_after:

   st_ram  temp, Pcardnum3
   cpi temp, 10
   brlt    pc3_10
   addi_ram    Phand, 10
   rjmp pc3a_10
pc3_10: add_ram Phand, Pcardnum3
pc3a_10:
       ldi     mode, 1
       rcall   display
       
       st_ram  temp, Phand

       rcall   check_busted; store status of busted into register Busted
   tst_ram Busted
       brne    pl1a
       rcall   check_bj; store status of black jack into register BlackJack  
   tst_ram BlackJack
       breq    Pcard4a
       add_ram bet, bet; double the bet
       rjmp    pw1
pl1a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl1; branch too long

doubleDown3:
       cpi     response, 1
       brne    dt1a
       add_ram bet, bet; double the bet              

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

   rjmp    Pcard4a_after  
Pcard4a:rjmp    Pcard4
dt1a:   rjmp dt1
Pcard4a_after:

       mod     random, 13, Psuit3, Pcardnum3, PAce

   st_ram  temp, Pcardnum3
   cpi temp, 10
   brlt    pc3_10a
   addi_ram    Phand, 10
   rjmp    pc3a_10a
pc3_10a: add_ram Phand, Pcardnum3
pc3a_10a:

   rjmp temp_tag1
dt1:    rjmp    dt2
pl1:    rjmp    pl2    ; branch too long
pw1:    rjmp    pw2

temp_tag1:
       ldi     mode, 1
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl2a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    dt2a
       add_ram bet, bet; double the bet
       rjmp    pw2
pl2a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl2
dt2a:   rjmp    dt2
Pcard4:
   ldi mode, 1
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    dt2

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit4, Pcardnum4, PAce
   st_ram  temp, Pcardnum4
   cpi temp, 10
   brlt    pc4_10
   addi_ram    Phand, 10
   rjmp    pc4a_10
pc4_10: add_ram Phand, Pcardnum4

pc4a_10:
   rjmp temp_tag2
dt2:    rjmp    dt3
pl2:    rjmp    pl3    ; branch too long
pw2:    rjmp    pw3

temp_tag2:

       ldi     mode, 2
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl3a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    Pcard5
       add_ram bet, bet; double the bet
       rjmp    pw3
pl3a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl3
Pcard5:
   ldi mode, 1
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    dt3

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit5, Pcardnum5, PAce
   st_ram  temp, Pcardnum5
   cpi temp, 10
   brlt    pc5_10
   addi_ram    Phand, 10
   rjmp    pc5a_10
pc5_10: add_ram Phand, Pcardnum5
pc5a_10:
   rjmp temp_tag3
dt3:    rjmp    dealersTurn
pl3:    rjmp    pl4    ; branch too long
pw3:    rjmp    pw4

temp_tag3:

       ldi     mode, 3
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl4a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    dealersTurn
       add_ram bet, bet; double the bet
       rjmp    pw4

pl4a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl4

dealersTurn:

;need to find out player's hand first

       AceHand PAce, Phand
   ldi ZL, LOW(Phand) ;ld_ram @1, temp1
   ldi ZH, HIGH(Phand)
   st  Z, temp1


   st_ram  temp, Phand
   AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl4

   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard3
   cp  temp1, temp
   breq    pt4
   brlt    pw4
   cp  temp, temp1
   brlt    pl4

Dcard3:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit3, Dcardnum3, DAce

   rjmp temp_tag4
pt4:    rjmp    pt5
pl4:    rjmp    pl5    ; branch too long
pw4:    rjmp    pw5

temp_tag4:

   st_ram  temp, Dcardnum3
   cpi temp, 10
   brlt    dc3_10
   addi_ram    Dhand, 10
   rjmp    dc3a_10
dc3_10: add_ram Dhand, Dcardnum3
dc3a_10:
   st_ram  temp, Dhand
       rcall   check_busted; store status of busted into register Busted
   tst_ram Busted
       brne    pw5a


   st_ram  temp, Phand
       AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl5a
   rjmp    pw5a_after
pw5a:   rjmp    pw5
pw5a_after:


   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard4
   cp  temp1, temp
   breq    pt5
   brlt    pw5
   cp  temp, temp1
   brlt    pl5
Dcard4:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit4, Dcardnum4, DAce
   st_ram  temp, Dcardnum4
   cpi temp, 10
   brlt    dc4_10
   addi_ram    Dhand, 10
   rjmp    dc4a_10
pl5a:   rjmp    pl5
dc4_10: add_ram Dhand, Dcardnum4
dc4a_10:

   rjmp temp_tag5
pt5:    rjmp    pt6
pl5:    rjmp    pl6    ; branch too long
pw5:    rjmp    pw6

temp_tag5:

       st_ram  temp, Dhand
       rcall   check_busted
       tst_ram Busted
       brne    pw6a


   st_ram  temp, Phand
       AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl6a
   rjmp    pw6a_after
pw6a:   rjmp    pw6
pw6a_after:
   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard5
   cp  temp1, temp
   breq    pt6
   brlt    pw6
   cp  temp, temp1
   brlt    pl6

Dcard5:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit5, Dcardnum5, DAce
   st_ram  temp, Dcardnum5
   cpi temp, 10
   brlt    dc5_10
   addi_ram    Dhand, 10
   rjmp    dc5a_10
pl6a:   rjmp    pl6
dc5_10: add_ram Dhand, Dcardnum5

dc5a_10:
   rjmp    temp_tag6
pt6:    rjmp    playerTie
pl6:    rjmp    playerLost     ; branch too long
pw6:    rjmp    playerWon

temp_tag6:


       st_ram  temp, Dhand
       rcall   check_busted
       tst_ram Busted
       brne    playerWon

   st_ram  temp, Phand
   AceHand DAce, Dhand
   cp  temp, temp1
   breq    playerTie
   brlt    playerLost
   cp  temp1, temp
   brlt    playerWon
playerWon:
       add_ram Ppoints, bet
       ldi     mode, 4
       rcall   display
       rjmp    next

playerTie:
       ldi     mode, 5
       rcall   display
       rjmp    next

playerLost:
       sub_ram Ppoints, bet

       ldi     mode, 6
       rcall   display
   st_ram  temp, Ppoints
       cpi     temp, 1; Ppoints <= 0?
       brge    next
   
;game over
;now player need to choose "new game" or "quit."
;game = 0:new; 1:quit;
;difference between get_next1 & get_next2 is the display

   tx_text_predefined gameover
   tx_text_predefined crlf
       rcall   get_next1; store player's decision into register game
       tst     temp1
       breq    newGame_tag
       rjmp    reset
newGame_tag:
   rjmp    newGame
;now player need to choose "next round," "new game" or "quit."
;game = 0:next; 1:new; 2:quit;

next:
       rcall   get_next2; store player's decision into register game
       cpi     temp1, 0
       brne    new
       rjmp    nextGame
new:
       cpi     temp1, 1
       breq    newGame_tag
       rjmp    reset

;*****************************
;interrupt routines

T0ovfl: in  savSREG, SREG
   dec     count
   out SREG, savSREG
   reti    
     
; UART needs a character
TXempty:in      savSREG, SREG  ;save processor status
       tst     TXflash        ;Is the string in flash memory?
       breq    TXram          ;If not, it is in RAM
       inc     ZL             ;get the next char from flash                  
       lpm                    ;and put it in r0
       rjmp    TXfls
TXram:  inc     ZL             ;get the next char from RAM
       ld      r0,Z
TXfls:  tst     r0             ;if char is zero then exit
       breq    TXend          
       out     UDR, r0        ;otherwise transmit it
       rjmp    TXexit         ;exit until next char
TXend:  clr     TXbusy         ;no more chars
       cbi     UCR, UDRIE     ;clear the TXempty interrupt
TXexit: out     SREG, savSREG  ;restore proc status
       reti                   ;back to pgm

; TX done -- buffer is empty  -- unused here
TXdone: in      savSREG, SREG  ;save processor status
       out     SREG, savSREG  ;restore proc status
       reti                   ;back to pgm

; UART read a character
RXdone: in      savSREG, SREG  ;save processor status  
       in      RXchar, UDR    ;get the character
       out     SREG, savSREG  ;restore proc status
       reti                   ;back to pgm

;*****************************
;subroutine

TXwait: tst     TXbusy         ;now wait for the tranmission to finish
       brne    TXwait
       ret
;---------------------------------
check_bj:
       AceHand PAce, Phand
       cpi     temp1, 21
       brne    bjExit
   tx_text_predefined bj_txt
   tx_text_predefined crlf
       ldi_ram BlackJack,1
bjExit: ret

;---------------------------------
check_busted:
       cpi     temp, 22
       brlt    bustExit
       ldi_ram Busted, 1
bustExit:
       ret

;---------------------------------
get_response:
   ldi RXchar, azero
   tx_text_predefined action_ndd_txt

   cpi mode, 0
   brne    responseWait
   tx_text_predefined action_dd_txt
   rjmp    responseWait

; wait for player to enter his/her decision
responseWait:
       cpi     RXchar, hit
       brne    check_d
       clr     response
       rjmp    responseExit
check_d:
   cpi mode, 0
   brne    check_s
       cpi     RXchar, double
       brne    check_s
       ldi     response, 1
       rjmp    responseExit
check_s:
       cpi     RXchar, stand
       brne    responseWait
       ldi     response, 2  
responseExit:
   tx_text_predefined  crlf
       ret

get_next1:
   tx_text_predefined crlf
   tx_text_predefined resetquit_txt
   tx_text_predefined crlf
   tx_text_predefined resetquit_txt1

; wait for player to enter his/her decision
next1Wait:
       cpi     RXchar, r
       brne    check_q
   clr     temp1
       rjmp    next1Exit
check_q:
       cpi     RXchar, q
       brne    next1Wait
       ldi     temp1, 1
next1Exit:

   tx_text_predefined  crlf
       ret
;--------------------------------
get_next2:
   tx_text_predefined  crlf
   tx_text_predefined nextround_txt
   tx_text_predefined  crlf
   tx_text_predefined resetquit_txt
   tx_text_predefined  crlf
   tx_text_predefined resetquit_txt1


; wait for player to enter his/her decision
next2Wait:
       cpi     RXchar, n
       brne    check_n2
       clr     temp1
       rjmp    next2Exit
check_n2:
       cpi     RXchar, r
       brne    check_q2
       ldi     temp1, 1
       rjmp    next2Exit
check_q2:
       cpi     RXchar, q
       brne    next2Wait
       ldi     temp1, 2  
next2Exit:

   tx_text_predefined  crlf

       ret


;----------------------------------------------
;get a random value from timer 0, and then find (random value mod 52) to get a number 0-51
;which represents a card. repeat ten times to find ten card... if number is the same, we simply
;add 1 to the value and check again if the number has been outputted or not.
; for (i = 0; i < 10; i++)
;   get random value (rv) from counter
;   number[i] = rv mod (52-i)  ; card number
;ag:   for (j = 0; j <i; j++)
;     if (number[i] == number[j])
;       number[i]++;
;       goto ag;
;     end if
;   end for
; end for


get_random:
  ;cli
   ldi ZL, LOW(cards) ;load pointer to cards in RAM
   ldi ZH, HIGH(cards)    
   ldi YL, LOW(cards)
   ldi YH, HIGH(cards)
   ldi temp, 1    ;load first counter
st: cpi temp,11
   brge    finish_get_random
   

;   in  random, TCNT0  ;load random number
;   out PORTB, random

   ldi temp2, 8
ran_gen:tst temp2
   breq    start_mod  

   mov tempran0, count1
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   and tempran0, rones

   mov tempran1, count
   lsr tempran1
   and tempran1, rones

   mov tempran2, count
   and tempran2, rones

   eor     tempran1, tempran2
   eor tempran0, tempran1
   lsl count      ;shift left
       rol     count1    
   bst tempran0, 0
   bld count, 0

   dec     temp2
   rjmp    ran_gen

start_mod:
   mov random, count

   simple_mod random, 52, remainder    
              ;find the corresponding card number
recheck:
   ldi temp1, 1   ;find if the number is duplicated
   ldi YL, LOW(cards)
   ldi YH, HIGH(cards)
loop:   cp  temp1, temp
   brge    ts

   ld  temp2, Y+  ; go throught the array of cards
   cp  remainder, temp2
   breq    skip
   subi    temp1, -1
   rjmp    loop
skip:   subi    remainder, -1
   cpi remainder,52   ;if remainder = 52, wrap around, and remainder becomes 0
   brne    skip1
   ldi remainder, 0
skip1:
   rjmp    recheck
       
ts: st  Z+, remainder
   subi    temp, -1
   rjmp    st

finish_get_random:
;   clr temp
;   out TCCR0, temp;stop timer 0
;   sei        ;reenable interrupts
       ret
; ---------------------------------------------------------------------------


prepare_string:;@0 = str_ptr, @1 = number, @2 = suit

   ldi YL, LOW(str_ptr)
   ldi YH, HIGH(str_ptr)

   mov ZL, param1a
   mov ZH, param1b
   ld  temp, Z
   cpi temp, 1
   brne    cp_1
   ldi temp, ay
   rjmp    p_suit
cp_1:  
   cpi temp, 10
   brne    cp_2
   ldi temp, tee
   rjmp    p_suit
cp_2:
   cpi temp, 11
   brne    cp_3
   ldi temp, jay
   rjmp    p_suit
cp_3:  
   cpi temp, 12
   brne    cp_4
   ldi temp, cue
   rjmp    p_suit
cp_4:  
   cpi temp, 13
   brne    numbers
   ldi temp, kay
   rjmp    p_suit
numbers:subi    temp, -azero    
p_suit: st  Y+, temp

   mov ZL, param2a
   mov ZH, param2b
   ld  temp, Z
   cpi temp, 0
   brne    cp_5
   ldi temp, dee
   rjmp    end_p
cp_5:  
   cpi temp, 1
   brne    cp_6
   ldi temp, cee
   rjmp    end_p
cp_6:  
   cpi temp, 2
   brne    cp_7
   ldi temp, haych
   rjmp    end_p
cp_7:  
   cpi temp, 3
   brne    end_p
   ldi temp, es

end_p:
   st  Y+, temp
   ldi temp, space
   st  Y+, temp
   ldi temp, 0
   st  Y, temp
   ret

display_points:

   tx_text_predefined points

      ; convert number in hex to ascii
   st_ram  temp, Ppoints
       clr     hundreds       ;clear registers
       clr     tens
       clr     ones
hun_digit:
   cpi temp, 100
   brlt    ten_digit
   subi    temp, 100
   inc hundreds
   rjmp    hun_digit

ten_digit:
       cpi     temp, 10
       brlt    one_digit
       subi    temp, 10
       inc     tens
       rjmp    ten_digit
one_digit:
       cpi     temp, 1
       brlt    to_ascii
       subi    temp, 1
       inc     ones
       rjmp    one_digit

to_ascii:
   ldi temp, -azero
       sub    ones, temp
       sub    tens, temp
       sub    hundreds, temp

      ; load values into RAM cntstr
       ldi     ZL, LOW(str_ptr) ;ptr to RAM
   ldi     ZH, HIGH(str_ptr)

   ldi temp, azero
   cp  hundreds, temp
   breq    skip_to_ten
       st      Z+, hundreds    ;write hundreds to RAM
skip_to_ten:
   cp  tens, temp
   breq    skip_to_one
       st      Z+, tens        ;write tens to RAM
skip_to_one:
       st      Z+, ones        ;write ones to RAM
       clr     temp
       st      Z, temp    ;terminate string

   tx_text_variable str_ptr    
   tx_text_predefined crlf
   ret

;----------------------------------------------------------------------------
;display: display dealer's hand and player's hand according to which state
;the program is at... you probably can use a register(mode) to indicate the
;states

display:
   tx_text_predefined crlf
   tx_text_predefined  dealer_txt

   cpi mode, 4
   brlt    no_show_d_first
   rjmp    show_d

Admin5- 04-21-2006
Version Two using Buttons instead of UART for Input/Output

CODE

;Leung, Min Jee (Andy) & Kenneth Kwok
;Final Project: Black Jack

.include "c:\users\k&a\8535def.inc"
.device AT90S8535

.include "c:\users\k&a\final\macro.inc"

;***********************
.def    hundreds=r2
.def    tens =r3
.def    ones =r4
.def    rones=r5
.def    rzeros=r6

.def    tempran0 =r7
.def    tempran1 =r8
.def    tempran2 =r9

.def    param1a =r10
.def    param1b =r11
.def    param2a =r12
.def    param2b =r13

.def    count =r14 ;counter for random number generation
.def    count1=r15

.def    random  =r17
.def    temp    =r16   ;temporary register
.def    savSREG =r18   ;save the status register
.def    TXbusy  =r19   ;transmit busy flag
.def    RXchar  =r20   ;a received character
.def    TXflash =r21   ;text to be sent is in flash if <>0
.def    temp1   =r22
.def    temp2   =r23
.def    remainder=r24
.def    random_ptr = r25;pointer to a card in the random array
.def    response = r26
.def    mode = r27
.equ    baud96  =25    ;9600 baud constant for 4Mhz crystal
.equ    tteen   =13
.equ    go      ='g'   ;0x67 ascii 'g'
.equ    stop    ='s'   ;0x73 ascii 's'
.equ    azero   ='0'   ;0x30 ascii '0'
.equ    one     ='1'
.equ    two     ='2'
.equ    n       ='n'
.equ    r       ='r'
.equ    q       ='q'
.equ    hit     ='h'
.equ    double  ='d'
.equ    stand   ='s'
.equ    tee     = 'T'
.equ    jay     = 'J'
.equ    cue     = 'Q'
.equ    kay     = 'K'
.equ    ay      = 'A'
.equ    dee     = 'D'
.equ    cee     = 'C'
.equ    haych   = 'H'
.equ    es      = 'S'
.equ    space   = ' '

;**************************************
.dseg
;define variable strings to be tranmitted from RAM
;if have time, implement player's name as well
;playername: .byte   11 ;no longer than 10 chars + a zero terminate

Ppoints:    .byte 1    ;to store player's points
cards:      .byte 10   ;to store the ten cards generated randomly
bet:        .byte 1    ;player's current bet
Phand:      .byte 1    ;player's current hand
Dhand:      .byte 1    ;dealer's current hand
PAce:       .byte 1    ; Ace = 0:no Ace in hand =1: has Ace in hand for player
DAce:       .byte 1    ; Ace = 0:no Ace in hand =1: has Ace in hand for dealer
Busted:     .byte 1    ; not 0: hand is greater than 21
BlackJack:  .byte 1    ; not 0: hand is equal 21
Dsuit1:     .byte 1
Dcardnum1:  .byte 1
Dsuit2:     .byte 1
Dcardnum2:  .byte 1
Dsuit3:     .byte 1
Dcardnum3:  .byte 1
Dsuit4:     .byte 1
Dcardnum4:  .byte 1
Dsuit5:     .byte 1
Dcardnum5:  .byte 1
Psuit1:     .byte 1
Pcardnum1:  .byte 1
Psuit2:     .byte 1
Pcardnum2:  .byte 1
Psuit3:     .byte 1
Pcardnum3:  .byte 1
Psuit4:     .byte 1
Pcardnum4:  .byte 1
Psuit5:     .byte 1
Pcardnum5:  .byte 1

str_ptr:    .byte 4

;**************************************
.cseg
.org $0000
       rjmp    RESET  ;reset entry vector
   reti
   reti
       reti
       reti    
       reti    
       reti    
       reti    
       reti    
   rjmp    T0ovfl
       reti                    
       rjmp    RXdone ;UART receive done
       rjmp    TXempty;UART buffer empty
       reti
       reti
   reti
   reti

nextround_txt:
       .db     "Press 'n' to play next round or", 0x00
resetquit_txt:
       .db     "Press 'r' to start a new game or", 0x00
resetquit_txt1:
   .db "Press 'q' to quit the game: ", 0x00
welcome_txt:
       .db     "Welcome to try our Black Jack!", 0x00
welcome_txt1:
   .db "Please press 'g' to start the game: ", 0x00
win_txt:    
   .db     "You win!", 0x00
lose_txt:
   .db     "You lose.", 0x00
tie_txt:    
   .db "Tied Game!", 0x00

crlf:   .db     0x0d, 0x0a, 0x00       ;carrage return/line feed

;define fixed strings to be tranmitted from flash- zero terminated

junk:   .db "This space stores junks.......................", 0x00
points: .db     "Your Current Points: ", 0x00
bet_txt:
   .db     "How many points do you want to bet? (1 or 2): ", 0x00
bust_txt:  .db     "Your hand is busted!", 0x00
action_dd_txt:
   .db "or 'd' for 'double down':", 0x00

action_ndd_txt:
   .db     "Press 'h' for 'hit me', or 's' for 'stand': ", 0x00

bj_txt:     .db     "You have a Black Jack!", 0x00
dealer_txt: .db "Dealer's Hand: ", 0x00
player_txt: .db "Player's Hand: ", 0x00
dfirst_txt: .db "XX ", 0x00
junk2:
       .db     "This space is somehow linked to junk....", 0x00
gameover:  
       .db     "You have no more points left. Game Over!", 0x00


RESET:  ldi     temp, LOW(RAMEND);setup stack pointer  
       out     SPL, temp
       ldi     temp, HIGH(RAMEND)
       out     SPH, temp

       ldi     temp,1    
   mov rones, temp

   ldi temp, 0
   mov     rzeros, temp
   
   ldi temp, 0b01011010   ; for random number generator
   mov count, temp

   ldi temp, 0b01000000   ; for random number generator
   mov count1, temp


      ;initial conditions
       clr     TXbusy         ;start out not busy on TX
       ldi     RXchar, stop     ;start out not running

      ;setup UART -- enable TXempty & RXdone int, and RX, TX pins
       ldi     temp, 0b10111000
       out     UCR, temp      

  ;set baud rate to 9600
       ldi     temp, baud96
       out     UBRR, temp

       ldi     Temp,exp2(TOIE0);enable timer interrupt
       out     TIMSK, Temp

   ldi temp, 0
   out TCCR0, temp

       ser     temp           ;set PORTB to be
       out     DDRB, temp      ;all outputs
  ;out    PORTB, temp
   
   out DDRD, temp
   
      ;intialize text pointer BEFORE turning on interrupts
      ;because RESET causes the TX empty flag to be SET

       ldi     ZL, LOW(crlf<<1);do shift to convert word-addr to byte
       ldi     ZH, HIGH(crlf<<1)
   
       sei; enable global interrupts and wait for Rxdone interrupt


      ;now print three strings and wait for incoming character interrupt
  ;clr     TXbusy         ;start out not busy on TX

; display banner of "Welcome to try our Black Jack" out of reset

      ;now the pointer to the preset message

   tx_text_predefined crlf
   tx_text_predefined welcome_txt
   tx_text_predefined crlf
   tx_text_predefined welcome_txt1


; wait for player to hit the "start" button
   sbi PORTB, 3
startWait:
   
   sub count, rones
   sbc count1, rzeros
   sbis    PINC, 3
   rjmp    startWait
;   rjmp    startExit
;cp_go:  cpi     RXchar, go;wait for go signal - a 'g' on the keyboard
;        brne    startWait

;startExit:
   cbi PORTB, 3
   tx_text_predefined crlf
; ask player to enter his/her name if we have time to implement this
;       rcall   get_name;store player's name into ram

newGame:
; At the beginning, player has 10 points.

   ldi_ram Ppoints, 10

   tx_text_predefined crlf
   rcall   display_points

nextGame:
; initialize some registers' values

   rcall   get_random  

       ldi_ram Phand, 0   ; player's current hand
       ldi_ram Dhand, 0   ; dealer's current hand
       ldi_ram PAce, 0    ; Ace = 0:no Ace in hand else: has Ace in hand for player
       ldi_ram DAce, 0    ; Ace = 0:no Ace in hand else: has Ace in hand for dealer
       ldi_ram Busted, 0  ; not 0: hand is greater than 21
       ldi_ram BlackJack, 0   ; not 0: hand is equal 21
   
  ;initialize all cards to -1 first  -- this is for display purpose
   ldi_ram Dsuit1, -1
   ldi_ram Dcardnum1, -1
   ldi_ram Dsuit2, -1
   ldi_ram Dcardnum2, -1
   ldi_ram Dsuit3, -1
   ldi_ram Dcardnum3, -1
   ldi_ram Dsuit4, -1
   ldi_ram Dcardnum4, -1
   ldi_ram Dsuit5, -1
   ldi_ram Dcardnum5, -1

   ldi_ram Psuit1, -1
   ldi_ram Pcardnum1, -1
   ldi_ram Psuit2, -1
   ldi_ram Pcardnum2, -1
   ldi_ram Psuit3, -1
   ldi_ram Pcardnum3, -1
   ldi_ram Psuit4, -1
   ldi_ram Pcardnum4, -1
   ldi_ram Psuit5, -1
   ldi_ram Pcardnum5, -1

   mov random_ptr, rzeros ;first element in the array

; ask player how much he/she wants to bet for this game

   tx_text_predefined crlf
   tx_text_predefined bet_txt

;wait for player to enter the bet
betWait:
   sbi PORTB, 6
   sbi PORTB, 7

   sbis    PINC, 7
   rjmp    cp_b2
   rjmp    betExit1
cp_b2:  sbis    PINC, 6
   rjmp    betWait
;        cpi     RXchar, one
;        breq    betExit
;        cpi     RXchar, two
;        brne    betWait  
betExit2:
   ldi temp, 1
   ld_ram  bet, temp
   rjmp    betExit
betExit1:
   ldi temp, 2
   ld_ram  bet, temp
betExit:
   cbi PORTB, 6
   cbi PORTB, 7
   tx_text_predefined crlf

; store player's bet into variable bet
;        mov     temp, Rxchar
;        subi       temp, azero; convert from ascii to number
;   ld_ram  bet, temp
               
; deal 2 cards to dealer and 2 cards to player

  ; get the first random # into register random
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Dsuit1, Dcardnum1, DAce; dealer's 1st card (hidden)
   
   st_ram  temp, Dcardnum1
   cpi temp, 10
   brlt    dc1_10
   addi_ram    Dhand, 10
   rjmp    dc1a_10
dc1_10: add_ram Dhand, Dcardnum1
dc1a_10:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Psuit1, Pcardnum1, PAce; player's 1st card

   st_ram  temp, Pcardnum1
   cpi temp, 10
   brlt    pc1_10
   addi_ram    Phand, 10
   rjmp    pc1a_10
pc1_10: add_ram Phand, Pcardnum1
pc1a_10:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Dsuit2, Dcardnum2, DAce; dealer's 2nd card

   st_ram  temp, Dcardnum2
   cpi temp, 10
   brlt    dc2_10
   addi_ram    Dhand, 10
   rjmp    dc2a_10
dc2_10: add_ram Dhand, Dcardnum2
dc2a_10:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z
       mod     random, 13, Psuit2, Pcardnum2, PAce; player's 2nd card

   st_ram  temp, Pcardnum2
   cpi temp, 10
   brlt    pc2_10
   addi_ram    Phand, 10
   rjmp    pc2a_10
pc2_10: add_ram Phand, Pcardnum2
pc2a_10:


; display one of dealer's card and both of player's cards
       ldi     mode, 0; display mode
       rcall   display; display cards on screen depends on mode

       rcall   check_bj; store status of black jack into register BlackJack
   tst_ram BlackJack
       breq    Pcard3  
       add_ram bet, bet; double the bet
       rjmp    playerWon      
       
;now player need to decide to choose "hit me", "stand" or "double down"
;response = 0:hit me; 1:double down; 2:stand
Pcard3:
   ldi mode, 0
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    doubleDown3_temp

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit3, Pcardnum3, PAce
   rjmp    dd3_after
doubleDown3_temp: rjmp doubleDown3 ;branch too long

dd3_after:

   st_ram  temp, Pcardnum3
   cpi temp, 10
   brlt    pc3_10
   addi_ram    Phand, 10
   rjmp pc3a_10
pc3_10: add_ram Phand, Pcardnum3
pc3a_10:
       ldi     mode, 1
       rcall   display
       
       st_ram  temp, Phand

       rcall   check_busted; store status of busted into register Busted
   tst_ram Busted
       brne    pl1a
       rcall   check_bj; store status of black jack into register BlackJack  
   tst_ram BlackJack
       breq    Pcard4a
       add_ram bet, bet; double the bet
       rjmp    pw1
pl1a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl1; branch too long

doubleDown3:
       cpi     response, 1
       brne    dt1a
       add_ram bet, bet; double the bet              

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

   rjmp    Pcard4a_after  
Pcard4a:rjmp    Pcard4
dt1a:   rjmp dt1
Pcard4a_after:

       mod     random, 13, Psuit3, Pcardnum3, PAce

   st_ram  temp, Pcardnum3
   cpi temp, 10
   brlt    pc3_10a
   addi_ram    Phand, 10
   rjmp    pc3a_10a
pc3_10a: add_ram Phand, Pcardnum3
pc3a_10a:

   rjmp temp_tag1
dt1:    rjmp    dt2
pl1:    rjmp    pl2    ; branch too long
pw1:    rjmp    pw2

temp_tag1:
       ldi     mode, 1
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl2a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    dt2a
       add_ram bet, bet; double the bet
       rjmp    pw2
pl2a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl2
dt2a:   rjmp    dt2
Pcard4:
   ldi mode, 1
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    dt2

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit4, Pcardnum4, PAce
   st_ram  temp, Pcardnum4
   cpi temp, 10
   brlt    pc4_10
   addi_ram    Phand, 10
   rjmp    pc4a_10
pc4_10: add_ram Phand, Pcardnum4

pc4a_10:
   rjmp temp_tag2
dt2:    rjmp    dt3
pl2:    rjmp    pl3    ; branch too long
pw2:    rjmp    pw3

temp_tag2:

       ldi     mode, 2
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl3a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    Pcard5
       add_ram bet, bet; double the bet
       rjmp    pw3
pl3a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl3
Pcard5:
   ldi mode, 1
       rcall   get_response; store player's action into register response    
       cpi     response, 0
       brne    dt3

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Psuit5, Pcardnum5, PAce
   st_ram  temp, Pcardnum5
   cpi temp, 10
   brlt    pc5_10
   addi_ram    Phand, 10
   rjmp    pc5a_10
pc5_10: add_ram Phand, Pcardnum5
pc5a_10:
   rjmp temp_tag3
dt3:    rjmp    dealersTurn
pl3:    rjmp    pl4    ; branch too long
pw3:    rjmp    pw4

temp_tag3:

       ldi     mode, 3
       rcall   display

       st_ram  temp, Phand
       rcall   check_busted; store status of busted into register Busted
       tst_ram Busted
       brne    pl4a
       rcall   check_bj; store status of black jack into register BlackJack  
       tst_ram BlackJack
       breq    dealersTurn
       add_ram bet, bet; double the bet
       rjmp    pw4

pl4a:
   tx_text_predefined bust_txt
   tx_text_predefined crlf
   rjmp    pl4

dealersTurn:

;need to find out player's hand first

       AceHand PAce, Phand
   ldi ZL, LOW(Phand) ;ld_ram @1, temp1
   ldi ZH, HIGH(Phand)
   st  Z, temp1


   st_ram  temp, Phand
   AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl4

   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard3
   cp  temp1, temp
   breq    pt4
   brlt    pw4
   cp  temp, temp1
   brlt    pl4

Dcard3:

   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit3, Dcardnum3, DAce

   rjmp temp_tag4
pt4:    rjmp    pt5
pl4:    rjmp    pl5    ; branch too long
pw4:    rjmp    pw5

temp_tag4:

   st_ram  temp, Dcardnum3
   cpi temp, 10
   brlt    dc3_10
   addi_ram    Dhand, 10
   rjmp    dc3a_10
dc3_10: add_ram Dhand, Dcardnum3
dc3a_10:
   st_ram  temp, Dhand
       rcall   check_busted; store status of busted into register Busted
   tst_ram Busted
       brne    pw5a


   st_ram  temp, Phand
       AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl5a
   rjmp    pw5a_after
pw5a:   rjmp    pw5
pw5a_after:


   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard4
   cp  temp1, temp
   breq    pt5
   brlt    pw5
   cp  temp, temp1
   brlt    pl5
Dcard4:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit4, Dcardnum4, DAce
   st_ram  temp, Dcardnum4
   cpi temp, 10
   brlt    dc4_10
   addi_ram    Dhand, 10
   rjmp    dc4a_10
pl5a:   rjmp    pl5
dc4_10: add_ram Dhand, Dcardnum4
dc4a_10:

   rjmp temp_tag5
pt5:    rjmp    pt6
pl5:    rjmp    pl6    ; branch too long
pw5:    rjmp    pw6

temp_tag5:

       st_ram  temp, Dhand
       rcall   check_busted
       tst_ram Busted
       brne    pw6a


   st_ram  temp, Phand
       AceHand DAce, Dhand
       cp      temp, temp1
       brlt    pl6a
   rjmp    pw6a_after
pw6a:   rjmp    pw6
pw6a_after:
   cpi temp1, 16      ; dealer stops dealing if its hand is greater than 16
   brlt    Dcard5
   cp  temp1, temp
   breq    pt6
   brlt    pw6
   cp  temp, temp1
   brlt    pl6

Dcard5:
   ldi ZL, LOW(cards)
   ldi ZH, HIGH(cards)
   add r30, random_ptr
   inc random_ptr
       ld  random, Z

       mod     random, 13, Dsuit5, Dcardnum5, DAce
   st_ram  temp, Dcardnum5
   cpi temp, 10
   brlt    dc5_10
   addi_ram    Dhand, 10
   rjmp    dc5a_10
pl6a:   rjmp    pl6
dc5_10: add_ram Dhand, Dcardnum5

dc5a_10:
   rjmp    temp_tag6
pt6:    rjmp    playerTie
pl6:    rjmp    playerLost     ; branch too long
pw6:    rjmp    playerWon

temp_tag6:


       st_ram  temp, Dhand
       rcall   check_busted
       tst_ram Busted
       brne    playerWon

   st_ram  temp, Phand
   AceHand DAce, Dhand
   cp  temp, temp1
   breq    playerTie
   brlt    playerLost
   cp  temp1, temp
   brlt    playerWon
playerWon:
       add_ram Ppoints, bet
       ldi     mode, 4
       rcall   display
       rjmp    next

playerTie:
       ldi     mode, 5
       rcall   display
       rjmp    next

playerLost:
       sub_ram Ppoints, bet

       ldi     mode, 6
       rcall   display
   st_ram  temp, Ppoints
       cpi     temp, 1; Ppoints <= 0?
       brge    next
   
;game over
;now player need to choose "new game" or "quit."
;game = 0:new; 1:quit;
;difference between get_next1 & get_next2 is the display

   tx_text_predefined gameover
   tx_text_predefined crlf
       rcall   get_next1; store player's decision into register game
       tst     temp1
       breq    newGame_tag
       rjmp    reset
newGame_tag:
   rjmp    newGame
;now player need to choose "next round," "new game" or "quit."
;game = 0:next; 1:new; 2:quit;

next:
       rcall   get_next2; store player's decision into register game
       cpi     temp1, 0
       brne    new
       rjmp    nextGame
new:
       cpi     temp1, 1
       breq    newGame_tag
       rjmp    reset

T0ovfl:
       set  ;Set T flag
       ldi     temp, 0     ;Timer 0 off
       out     TCCR0, temp     ;Stop timer
       reti
     
; UART needs a character
TXempty:in      savSREG, SREG  ;save processor status
       tst     TXflash        ;Is the string in flash memory?
       breq    TXram          ;If not, it is in RAM
       inc     ZL             ;get the next char from flash                  
       lpm                    ;and put it in r0
       rjmp    TXfls
TXram:  inc     ZL             ;get the next char from RAM
       ld      r0,Z
TXfls:  tst     r0             ;if char is zero then exit
       breq    TXend          
       out     UDR, r0        ;otherwise transmit it
       rjmp    TXexit         ;exit until next char
TXend:  clr     TXbusy         ;no more chars
       cbi     UCR, UDRIE     ;clear the TXempty interrupt
TXexit: out     SREG, savSREG  ;restore proc status
       reti                   ;back to pgm

; UART read a character
RXdone: in      savSREG, SREG  ;save processor status  
       in      RXchar, UDR    ;get the character
       out     SREG, savSREG  ;restore proc status
       reti                   ;back to pgm

;*****************************
;subroutine

TXwait: tst     TXbusy         ;now wait for the tranmission to finish
       brne    TXwait
       ret
;---------------------------------
check_bj:
       AceHand PAce, Phand
       cpi     temp1, 21
       brne    bjExit
   tx_text_predefined bj_txt
   tx_text_predefined crlf
       ldi_ram BlackJack,1
bjExit: ret

;---------------------------------
check_busted:
       cpi     temp, 22
       brlt    bustExit
       ldi_ram Busted, 1
bustExit:
       ret

;---------------------------------
get_response:
   ldi RXchar, azero
   tx_text_predefined action_ndd_txt

   cpi mode, 0
   brne    responseWait
   tx_text_predefined action_dd_txt
   rjmp    responseWait

; wait for player to enter his/her decision
responseWait:
   sbi PORTB, 3
   sbi PORTB, 4
   sbi PORTB, 5

   sbis    PINC, 4
   rjmp    check_d
;        cpi     RXchar, hit
;        brne    check_d

       ldi     temp1,3   ; then Wait 45ms to avoid debounce
offwait1:
   rcall   delay
       dec     temp1
       brne    offwait1

       clr     response
       rjmp    responseExit

check_d:
   cpi mode, 0
   brne    check_s

   sbis    PINC, 5
   rjmp    check_s
;        cpi     RXchar, double
;        brne    check_s
       ldi     response, 1
       rjmp    responseExit
check_s:
   sbis    PINC, 3
   rjmp    responseWait
;        cpi     RXchar, stand
;        brne    responseWait
       ldi     response, 2  
responseExit:
   cbi PORTB, 3
   cbi PORTB, 4
   cbi PORTB, 5
   tx_text_predefined  crlf
       ret

get_next1:
   tx_text_predefined crlf
   tx_text_predefined resetquit_txt
   tx_text_predefined crlf
   tx_text_predefined resetquit_txt1

; wait for player to enter his/her decision
next1Wait:
   sbi PORTD, 3
   sbi PORTB, 2

   sbis    PINC, 2
   rjmp    check_q
;        cpi     RXchar, r
;        brne    check_q
   clr     temp1
       rjmp    next1Exit
check_q:
   sbis    PINC, 0
   rjmp    next1Wait
;        cpi     RXchar, q
;        brne    next1Wait
       ldi     temp1, 1
next1Exit:
   cbi PORTD, 3
   cbi PORTB, 2
   tx_text_predefined  crlf
       ret
;--------------------------------
get_next2:
   tx_text_predefined  crlf
   tx_text_predefined nextround_txt
   tx_text_predefined  crlf
   tx_text_predefined resetquit_txt
   tx_text_predefined  crlf
   tx_text_predefined resetquit_txt1


; wait for player to enter his/her decision
next2Wait:
   sbi PORTD, 3
   sbi PORTB, 1
   sbi PORTB, 2

   sbis    PINC, 1
   rjmp    check_n2
;        cpi     RXchar, n
;        brne    check_n2
       clr     temp1
       rjmp    next2Exit
check_n2:
   sbis    PINC, 2
   rjmp    check_q2
;        cpi     RXchar, r
;        brne    check_q2
       ldi     temp1, 1
       rjmp    next2Exit
check_q2:
   sbis    PINC, 0
   rjmp    next2Wait
;        cpi     RXchar, q
;        brne    next2Wait
       ldi     temp1, 2  
next2Exit:
   cbi PORTD, 3
   cbi PORTB, 1
   cbi PORTB, 2
   tx_text_predefined  crlf

       ret


;----------------------------------------------
;get a random value from timer 0, and then find (random value mod 52) to get a number 0-51
;which represents a card. repeat ten times to find ten card... if number is the same, we simply
;add 1 to the value and check again if the number has been outputted or not.
; for (i = 0; i < 10; i++)
;   get random value (rv) from counter
;   number[i] = rv mod (52-i)  ; card number
;ag:   for (j = 0; j <i; j++)
;     if (number[i] == number[j])
;       number[i]++;
;       goto ag;
;     end if
;   end for
; end for


get_random:
  ;cli
   ldi ZL, LOW(cards) ;load pointer to cards in RAM
   ldi ZH, HIGH(cards)    
   ldi YL, LOW(cards)
   ldi YH, HIGH(cards)
   ldi temp, 1    ;load first counter
st: cpi temp,11
   brge    finish_get_random
   

;   in  random, TCNT0  ;load random number
;   out PORTB, random

   ldi temp2, 8
ran_gen:tst temp2
   breq    start_mod  

   mov tempran0, count1
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   lsr tempran0
   and tempran0, rones

   mov tempran1, count
   lsr tempran1
   and tempran1, rones

   mov tempran2, count
   and tempran2, rones

   eor     tempran1, tempran2
   eor tempran0, tempran1
   lsl count      ;shift left
       rol     count1    
   bst tempran0, 0
   bld count, 0

   dec     temp2
   rjmp    ran_gen

start_mod:
   mov random, count

   simple_mod random, 52, remainder    
              ;find the corresponding card number
recheck:
   ldi temp1, 1   ;find if the number is duplicated
   ldi YL, LOW(cards)
   ldi YH, HIGH(cards)
loop:   cp  temp1, temp
   brge    ts

   ld  temp2, Y+  ; go throught the array of cards
   cp  remainder, temp2
   breq    skip
   subi    temp1, -1
   rjmp    loop
skip:   subi    remainder, -1
   cpi remainder,52   ;if remainder = 52, wrap around, and remainder becomes 0
   brne    skip1
   ldi remainder, 0
skip1:
   rjmp    recheck
       
ts: st  Z+, remainder
   subi    temp, -1
   rjmp    st

finish_get_random:
       ret
; ---------------------------------------------------------------------------


prepare_string:;@0 = str_ptr, @1 = number, @2 = suit

   ldi YL, LOW(str_ptr)
   ldi YH, HIGH(str_ptr)

   mov ZL, param1a
   mov ZH, param1b
   ld  temp, Z
   cpi temp, 1
   brne    cp_1
   ldi temp, ay
   rjmp    p_suit
cp_1:  
   cpi temp, 10
   brne    cp_2
   ldi temp, tee
   rjmp    p_suit
cp_2:
   cpi temp, 11
   brne    cp_3
   ldi temp, jay
   rjmp    p_suit
cp_3:  
   cpi temp, 12
   brne    cp_4
   ldi temp, cue
   rjmp    p_suit
cp_4:  
   cpi temp, 13
   brne    numbers
   ldi temp, kay
   rjmp    p_suit
numbers:subi    temp, -azero    
p_suit: st  Y+, temp

   mov ZL, param2a
   mov ZH, param2b
   ld  temp, Z
   cpi temp, 0
   brne    cp_5
   ldi temp, dee
   rjmp    end_p
cp_5:  
   cpi temp, 1
   brne    cp_6
   ldi temp, cee
   rjmp    end_p
cp_6:  
   cpi temp, 2
   brne    cp_7
   ldi temp, haych
   rjmp    end_p
cp_7:  
   cpi temp, 3
   brne    end_p
   ldi temp, es

end_p:
   st  Y+, temp
   ldi temp, space
   st  Y+, temp
   ldi temp, 0
   st  Y, temp
   ret

display_points:

   tx_text_predefined points

      ; convert number in hex to ascii
   st_ram  temp, Ppoints
       clr     hundreds       ;clear registers
       clr     tens
       clr     ones
hun_digit:
   cpi temp, 100
   brlt    ten_digit
   subi    temp, 100
   inc hundreds
   rjmp    hun_digit

ten_digit:
       cpi     temp, 10
       brlt    one_digit
       subi    temp, 10
       inc     tens
       rjmp    ten_digit
one_digit:
       cpi     temp, 1
       brlt    to_ascii
       subi    temp, 1
       inc     ones
       rjmp    one_digit

to_ascii:
   ldi temp, -azero
       sub    ones, temp
       sub    tens, temp
       sub    hundreds, temp

      ; load values into RAM cntstr
       ldi     ZL, LOW(str_ptr) ;ptr to RAM
   ldi     ZH, HIGH(str_ptr)

   ldi temp, azero
   cp  hundreds, temp
   breq    skip_to_ten
       st      Z+, hundreds    ;write hundreds to RAM
skip_to_ten:
   cp  tens, temp
   breq    skip_to_one
       st      Z+, tens        ;write tens to RAM
skip_to_one:
       st      Z+, ones        ;write ones to RAM
       clr     temp
       st      Z, temp    ;terminate string

   tx_text_variable str_ptr    
   tx_text_predefined crlf
   ret

;----------------------------------------------------------------------------
;display: display dealer's hand and player's hand according to which state
;the program is at... you probably can use a register(mode) to indicate the
;states

display:
   tx_text_predefined crlf
   tx_text_predefined  dealer_txt

   cpi mode, 4
   brlt    no_show_d_first
   rjmp    show_d_first
no_show_d_first:
   tx_text_predefined  dfirst_txt

   p_pre_string    Dcardnum2, Dsuit2
   rcall prepare_string
   tx_text_variable    str_ptr

   tx_text_predefined  crlf
   tx_text_predefined  player_txt
   
   p_pre_string        Pcardnum1, Psuit1
   rcall   prepare_string      
   tx_text_variable    str_ptr

   p_pre_string        Pcardnum2, Psuit2
   rcall   prepare_string
   tx_text_variable    str_ptr
   cpi mode, 0
   breq    d_done_tag

   p_pre_string        Pcardnum3, Psuit3
   rcall   prepare_string      
   tx_text_variable    str_ptr
   cpi mode, 1
   breq    d_done_tag

   p_pre_string        Pcardnum4, Psuit4
   rcall   prepare_string
   tx_text_variable    str_ptr
   cpi mode, 2
   breq    d_done_tag
   p_pre_string        Pcardnum5, Psuit5
   rcall   prepare_string
   tx_text_variable    str_ptr
d_done_tag:
   rjmp    display_done

show_d_first:      ; show dealer's first card

   p_pre_string        Dcardnum1, Dsuit1
   rcall   prepare_string  
   tx_text_variable    str_ptr

   p_pre_string        Dcardnum2, Dsuit2
   rcall   prepare_string      
   tx_text_variable    str_ptr


   st_ram  temp, Dcardnum3
   cpi temp, -1
   breq p

   p_pre_string        Dcardnum3, Dsuit3
   rcall   prepare_string      
   tx_text_variable    str_ptr

   st_ram  temp, Dcardnum4
   cpi temp, -1
   breq p

   p_pre_string        Dcardnum4, Dsuit4
   rcall   prepare_string
   tx_text_variable    str_ptr

   st_ram  temp, Dcardnum5
   cpi temp, -1
   breq p
   p_pre_string        Dcardnum5, Dsuit5
   rcall   prepare_string
   tx_text_variable    str_ptr
p:

   tx_text_predefined  crlf
   tx_text_predefined  player_txt
   p_pre_string        Pcardnum1, Psuit1
   rcall prepare_string    
   tx_text_variable    str_ptr

   p_pre_string        Pcardnum2, Psuit2
   rcall   prepare_string  
   tx_text_variable    str_ptr

   st_ram  temp, Pcardnum3
   cpi temp, -1
   breq p1
   p_pre_string        Pcardnum3, Psuit3
   rcall   prepare_string  
   tx_text_variable    str_ptr

   st_ram  temp, Pcardnum4
   cpi temp, -1
   breq p1
   p_pre_string        Pcardnum4, Psuit4
   rcall   prepare_string  
   tx_text_variable    str_ptr

   st_ram  temp, Pcardnum5
   cpi temp, -1
   breq p1
   p_pre_string        Pcardnum5, Psuit5
   rcall prepare_string        
   tx_text_variable    str_ptr
p1:
   tx_text_predefined  crlf

   cpi     mode, 4
   brne    mode5
   tx_text_predefined  win_txt;player won
   rjmp    display_done
mode5:  cpi     mode, 5
   brne    mode6
   tx_text_predefined  tie_txt; tied game
   rjmp    display_done

mode6:  tx_text_predefined  lose_txt; player lost
   rjmp    display_done


display_done:
   tx_text_predefined  crlf
   rcall   display_points
   ret

delay:  in      savSREG,SREG      ;Save status register
   clr temp
       out     TCNT0,temp
       clt                    ;Clear T
       ldi     temp,4    ;Timer 0 prescaler, CK / 256
       out     TCCR0,temp     ;Run timer
dwait:  brtc    dwait          ;Wait for timer 0 interrupt to set T
       out     SREG,savSREG
       ret


Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.