//Dup the function of sched1.asm //used as an example in the program organization doc. #asm .equ __lcd_port=0x15 #endasm #include // LCD driver routines #include <90s8515.h> #include #include //timeout values for each task #define t1 60 #define t2 125 #define t3 225 #define Release 1 #define DebouncePress 2 #define StillPressed 3 #define DebounceRelease 4 #define Button0 1 #define Button1 2 #define Button2 4 #define Button3 8 #define Button4 16 #define Button5 32 #define Button6 64 #define Button7 128 #define menu 1 #define game1 2 #define game2 3 #define player 1 #define dealer 2 #define done 3 #define off 4 #define LCDwidth 16 //characters //the three task subroutines void task1(void); void task2(void); void task3(void); //deal char deal(void); //reset function void reset(void); void initialize(void); //all the usual mcu stuff unsigned char reload; //timer 0 reload to set 1 mSec unsigned char time1, time2, time3; //timeout counters unsigned char maybe, button, buttonstate; unsigned char menustate; unsigned char game1state; // variables for implementing the cards unsigned char playerpoints1; unsigned char playerpoints2; unsigned char playercards1[21]; unsigned char playercards2[21]; unsigned char dealercards[21]; unsigned char dealerpoints; unsigned char split; unsigned char playerpointer1, playerpointer2, dealerpointer; unsigned char current; // other temporary variables unsigned int i; unsigned char random; unsigned char pos; // counter for each card unsigned int cards[13]; // display string for each hand unsigned char playermap1[13]; unsigned char playermap2[13]; unsigned char dealermap[21]; // number of aces in each hand unsigned char playerace1; unsigned char playerace2; unsigned char dealerace; // point values of each card flash unsigned char cardval[13] = {11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10}; // ASCII version of cards flash unsigned char cardmap[13] = {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'}; unsigned char cardcnt; //undealt card count unsigned char LED; //LED display vector (debuggin) //money stuff unsigned int money; unsigned int bet; //temporary pointer for itoa conversion unsigned char *moneystring; unsigned char *betstring; unsigned char *pointstring; //double down or not unsigned char dbl; //********************************************************** //timer 1 compare-match A ISR interrupt [TIM1_COMPA] void cmpA_overflow(void) { // increment random counter random++; } //********************************************************** //timer 0 overflow ISR interrupt [TIM0_OVF] void timer0_overflow(void) { //reload to force 1 mSec overflow TCNT0=reload; //Decrement the three times if they are not already zero if (time1>0) --time1; if (time2>0) --time2; if (time3>0) --time3; // random++; } //********************************************************** //Entry point and task scheduler loop void main(void) { initialize(); //main task scheduler loop while(1) { if (time1==0) task1(); if (time2==0) task2(); if (time3==0) task3(); } } //********************************************************** //Deal cards char deal(void){ char ran2; ran2 = random; ran2 = ran2%cardcnt; i = 0; while (ran2 > cards[i]){ ran2 -= cards[i]; i++; } cards[i]--; cardcnt--; return i; } //*********************************************************** //Reset function void reset(void){ // reset everything to pregame state playerpoints1 = 0; playerpoints2 = 0; dealerpoints = 0; cardcnt = 208; for (i = 0; i < 13; i++) cards[i] = 16; for (i = 0; i < 13; i++){ playercards1[i] = 0; playercards2[i] = 0; dealercards[i] = 0; playermap1[i] = 0; playermap2[i] = 0; dealermap[i] = 0; } playerace1 = 0; playerace2 = 0; dealerace = 0; split = 0; playerpointer1 = 0; playerpointer2 = 0; dealerpointer = 0; current = 0; bet = 20; dbl = 0; } //********************************************************** //Task subroutines //Task 1 //Detect button pushes // //Start menu: // Button0 - Enter Blackjack // //Blackjack: // Button0 - Deal // Button1 - Hit // Button2 - Stay // Button3 - Double // Button4 - Quit // Button5 - Split // Button6 - Up // Button7 - Down void task1(void) { time1 = t1; switch (buttonstate){ case Release: // no button pushed if (0 != ~PINA){ maybe = ~PINA; buttonstate = DebouncePress; } break; case DebouncePress: // a button might be pushed if (maybe == ~PINA){ button = ~PINA; // set global variable buttonstate = StillPressed; } else buttonstate = Release; break; case StillPressed: // a button is still pushed if (maybe != ~PINA) buttonstate = DebounceRelease; break; case DebounceRelease: // button might be released if (maybe == ~PINA) buttonstate = StillPressed; else{ if (Button6 == button || Button7 == button){ button = 0; // reset global variable } buttonstate = Release; } break; } } //******************************* //Task 2 void task2(void) { time2 = t2; switch (menustate){ case menu: // display menu lcd_gotoxy(0,0); lcd_putsf("Blackjack"); //another string from flash lcd_gotoxy(0,1); lcd_putsf("Press Deal"); //another string from flash // Deal button pushed, start game if (Button0 == button){ TCCR0 = 0; button = 0; menustate = game1; game1state = done; lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); TCCR0 = 3; } break; case game1: // between hands and reset button pushed if (done == game1state && Button4 == button){ button = 0; menustate = menu; money = 1000; game1state = off; } break; } } //******************************* //Task 3 void task3(void) { time3 = t3; if (game1 == menustate){ switch (game1state){ case off: // game is not running, do nothing break; case done: // between hands if (0 >= money){ // run out of money? TCCR0 = 0; lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("You Are Broke"); reset(); i = 0; while (i < 65535) i++; i = 0; while (i < 65535) i++; lcd_clear(); menustate = menu; money = 1000; TCCR0 = 3; break; } // display current bet lcd_gotoxy(0,0); lcd_putsf("Bet:"); itoa(bet,betstring); lcd_puts(betstring); if (Button6 == button){ // Up button pushed TCCR0 = 0; if (bet < money) // can't bet more than what you have bet++; itoa(bet,betstring); lcd_gotoxy(4,0); lcd_puts(betstring); TCCR0 = 3; } if (Button7 == button){ // Down button pushed TCCR0 = 0; if (1 < bet) // have to bet at least 1 bet--; itoa(bet,betstring); lcd_gotoxy(4,0); lcd_puts(betstring); TCCR0 = 3; } else if (Button0 == button){ //Deal button pushed TCCR0 = 0; button = 0; lcd_clear(); playercards1[0] = deal(); //first card for player if (0 == playercards1[0]) playerace1++; playermap1[0] = cardmap[playercards1[0]]; lcd_gotoxy(0,0); lcd_putsf("D:"); dealercards[0] = deal(); // first card for dealer if (0 == dealercards[0]) dealerace++; dealermap[0] = cardmap[dealercards[0]]; lcd_puts(dealermap); playercards1[1] = deal(); // second card for player if (0 == playercards1[1]) playerace1++; playermap1[1] = cardmap[playercards1[1]]; playerpointer1 = 1; dealerpointer = 1; lcd_gotoxy(0,1); lcd_putsf("P:"); lcd_puts(playermap1); dealercards[1] = deal(); // second card for dealer if (0 == dealercards[1]) dealerace++; dealermap[1] = cardmap[dealercards[1]]; // update points playerpoints1 += cardval[playercards1[0]]; playerpoints1 += cardval[playercards1[1]]; dealerpoints += cardval[dealercards[0]]; dealerpoints += cardval[dealercards[1]]; //print points lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); if (21 > playerpoints1) game1state = player; else if (21 == playerpoints1){ //blackjack if (21 > dealerpoints){ lcd_gotoxy(10,1); lcd_putsf("BJ [W]"); // update money money += bet; i = 0; while (i < 65535){ i++; } i = 0; while (i < 65535){ i++; } i = 0; while (i < 65535){ i++; } reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; TCCR0 = 3; break; } else{ lcd_gotoxy(10,0); lcd_putsf("BJ [W]"); lcd_gotoxy(10,1); lcd_putsf("BJ"); // update money money -= bet; i = 0; while (i < 65535){ i++; } reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; TCCR0 = 3; break; } } // 2 aces else if (21 < playerpoints1){ playerace1--; playerpoints1 -= 10; game1state = player; } if (playercards1[0] == playercards1[1]){ lcd_gotoxy(10,1); lcd_putsf("Split?"); } else{ lcd_gotoxy(9,1); lcd_putsf("Double?"); } TCCR0 = 3; } break; case player: if (playercards1[0] == playercards1[1] && split == 0){ //update display for split if (Button5 == button){ // split pushed TCCR0 = 0; button = 0; playercards2[0] = playercards1[1]; playermap2[0] = cardmap[playercards2[0]]; playerpoints1 -= cardval[playercards1[1]]; playercards1[1] = deal(); playermap1[1] = cardmap[playercards1[1]]; playerpoints1 += cardval[playercards1[1]]; lcd_gotoxy(3,1); lcd_putsf(" "); i= 0; while(i < 65535) i++; playerpointer1 = 1; playerpointer2 = 1; lcd_gotoxy(2,1); lcd_puts(playermap1); playercards2[1] = deal(); playermap2[1] = cardmap[playercards2[1]]; playerpoints2 += cardval[playercards2[0]]; playerpoints2 += cardval[playercards2[1]]; lcd_gotoxy(9,1); lcd_putsf("Double?"); i = 0; while(i < 65535) i++; split = 1; current = 1; //break; TCCR0 = 3; } } else if (Button3 == button && 0 == dbl){ // double down? TCCR0 = 0; button = 0; bet = bet + bet; dbl = 1; lcd_gotoxy(9,1); lcd_putsf(" "); lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); i = 0; while (i < 65535) i++; playerpointer1++; playercards1[playerpointer1] = deal(); if (0 == playercards1[playerpointer1]) playerace1++; playermap1[playerpointer1] = cardmap[playercards1[playerpointer1]]; playerpoints1 += cardval[playercards1[playerpointer1]]; if ((playerpoints1 > 21) && (playerace1 > 0)){ playerace1--; playerpoints1 -= 10; } lcd_gotoxy(2,1); lcd_puts(playermap1); lcd_gotoxy(14,1); itoa(playerpoints1, pointstring); lcd_puts(pointstring); LED = ~playerpoints1; PORTB = LED; i = 0; while (i < 65535) i++; // check points if (playerpoints1 > 21){ lcd_gotoxy(2,1); lcd_putsf("Bust "); money -= bet; i = 0; while (i < 65535) i++; reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; } else { current = 0; lcd_gotoxy(2,0); lcd_puts(dealermap); lcd_gotoxy(14,0); itoa(dealerpoints,pointstring); lcd_puts(pointstring); i = 0; while (i < 65535){ i++; } game1state = dealer; } TCCR0 = 3; break; } // double down on a split if (1 == split && 1 == playerpointer1 && 1 == playerpointer2 && 1 == current && 0 == dbl && Button3 == button){ button = 0; bet = bet + bet; dbl = 1; lcd_gotoxy(9,1); lcd_putsf(" "); } if (Button1 == button){ //Hit button pushed TCCR0 = 0; if (0 == dbl){ dbl = 1; lcd_gotoxy(9,1); lcd_putsf(" "); } PORTB = 0; button = 0; if (1 == split && 1 == current){ // playing hand #1 playerpointer1++; playercards1[playerpointer1] = deal(); if (0 == playercards1[playerpointer1]) playerace1++; playermap1[playerpointer1] = cardmap[playercards1[playerpointer1]]; lcd_gotoxy(2,1); lcd_putsf(" "); lcd_gotoxy(2,1); lcd_puts(playermap1); playerpoints1 += cardval[playercards1[playerpointer1]]; if ((playerpoints1 > 21) && (playerace1 > 0)){ playerace1--; playerpoints1 -= 10; } lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); if (playerpoints1 > 21){ lcd_gotoxy(2,1); lcd_putsf("Bust "); playerpoints1 = 250; i = 0; while (i < 65535){ i++; } lcd_gotoxy(2,1); lcd_putsf(" "); lcd_gotoxy(2,1); lcd_puts(playermap2); lcd_gotoxy(14,1); lcd_putsf(" "); lcd_gotoxy(14,1); itoa(playerpoints2,pointstring); lcd_puts(pointstring); current = 2; } } else if (1 == split && 2 == current){ // player hand #2 playerpointer2++; playercards2[playerpointer2] = deal(); if (0 == playercards2[playerpointer2]) playerace2++; playermap2[playerpointer2] = cardmap[playercards2[playerpointer2]]; lcd_gotoxy(2,1); lcd_puts(playermap2); playerpoints2 += cardval[playercards2[playerpointer2]]; if ((playerpoints2 > 21) && (playerace2 > 0)){ playerace2--; playerpoints2 -= 10; } lcd_gotoxy(14,1); itoa(playerpoints2,pointstring); lcd_puts(pointstring); if (playerpoints2 > 21){ lcd_gotoxy(2,1); lcd_putsf("Bust "); playerpoints2 = 250; i = 0; while (i < 65535){ i++; } if (playerpoints1 <= 21){ // hand one is still good current = 0; lcd_gotoxy(2,0); lcd_puts(dealermap); i = 0; while (i < 65535){ i++; } lcd_gotoxy(14,0); itoa(dealerpoints,pointstring); lcd_puts(pointstring); game1state = dealer; } else{ //both bust // update money money -= bet; money -= bet; i = 0; while (i < 65535){ i++; } reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; } } } else{ //not split playerpointer1++; playercards1[playerpointer1] = deal(); if (0 == playercards1[playerpointer1]) playerace1++; playermap1[playerpointer1] = cardmap[playercards1[playerpointer1]]; lcd_gotoxy(2,1); lcd_puts(playermap1); playerpoints1 += cardval[playercards1[playerpointer1]]; if ((playerpoints1 > 21) && (playerace1 > 0)){ playerace1--; playerpoints1 -= 10; } lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); i = 0; while (i < 65535){ i++; } // update and check value, set gamestate if (playerpoints1 > 21){ lcd_gotoxy(2,1); lcd_putsf("Bust "); // update money money -= bet; i = 0; while (i < 65535){ i++; } reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; } } TCCR0 = 3; } else if (Button2 == button){ //stay TCCR0 = 0; if (0 == dbl){ // delete option for doubling down dbl = 1; lcd_gotoxy(9,1); lcd_putsf(" "); if (0 == split){ lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); } else if (1 == current){ lcd_gotoxy(14,1); itoa(playerpoints1,pointstring); lcd_puts(pointstring); } else if (2 == current){ lcd_gotoxy(14,1); itoa(playerpoints2,pointstring); lcd_puts(pointstring); } } button = 0; if (1 == split && 1 == current){ // if split and playing hand #1 current = 2; lcd_gotoxy(2,1); lcd_putsf(" "); lcd_gotoxy(2,1); lcd_puts(playermap2); lcd_gotoxy(14,1); itoa(playerpoints2,pointstring); lcd_puts(pointstring); } else { // not split or playing hand #2 current = 0; lcd_gotoxy(2,0); lcd_puts(dealermap); lcd_gotoxy(14,0); itoa(dealerpoints,pointstring); lcd_puts(pointstring); i = 0; while (i < 65535){ i++; } game1state = dealer; } TCCR0 = 3; } break; case dealer: // repeated deal cards until >=17 TCCR0 = 0; if ((17 > dealerpoints) && (dealerpoints < 33)){ dealerpointer++; dealercards[dealerpointer] = deal(); if (0 == dealercards[dealerpointer]) dealerace++; dealermap[dealerpointer] = cardmap[dealercards[dealerpointer]]; lcd_gotoxy(2,0); lcd_puts(dealermap); dealerpoints += cardval[dealercards[dealerpointer]]; if ((21 < dealerpoints) && (0 < dealerace)){ dealerace--; dealerpoints -= 10; } lcd_gotoxy(14,0); itoa(dealerpoints,pointstring); lcd_puts(pointstring); i = 0; while (i < 65535) i++; i = 0; while (i < 65535) i++; } // check points for outcome else{ if (21 < dealerpoints && 0 == split){ // dealer busts lcd_gotoxy(2,0); lcd_putsf("Bust "); lcd_gotoxy(13,1); lcd_putsf("[W]"); // update money money += bet; } else if (0 == split && dealerpoints >= playerpoints1){ // dealer wins lcd_gotoxy(13,0); lcd_putsf("[W]"); // update money money -= bet; } else if (0 == split && dealerpoints < playerpoints1){ // player wins lcd_gotoxy(13,1); lcd_putsf("[W]"); // update money money += bet; } else if (1 == split){ // on a split if (21 < dealerpoints){ // dealer busts if (dealerpoints < playerpoints1){ lcd_gotoxy(10,0); lcd_putsf("[W]"); lcd_gotoxy(10,1); lcd_putsf("[L]"); //update money money -= bet; } else{ lcd_gotoxy(10,0); lcd_putsf("[L]"); lcd_gotoxy(10,1); lcd_putsf("[W]"); // update money money += bet; } if (dealerpoints < playerpoints2){ lcd_gotoxy(13,0); lcd_putsf("[W]"); lcd_gotoxy(13,1); lcd_putsf("[L]"); //update money money -= bet; } else{ lcd_gotoxy(13,0); lcd_putsf("[L]"); lcd_gotoxy(13,1); lcd_putsf("[W]"); // update money money += bet; } } else{ // dealer did not busts if (dealerpoints >= playerpoints1 || 21 < playerpoints1){ lcd_gotoxy(10,0); lcd_putsf("[W]"); lcd_gotoxy(10,1); lcd_putsf("[L]"); //update money money -= bet; } else{ lcd_gotoxy(10,0); lcd_putsf("[L]"); lcd_gotoxy(10,1); lcd_putsf("[W]"); // update money money += bet; } if (dealerpoints >= playerpoints2 || 21 < playerpoints2){ lcd_gotoxy(13,0); lcd_putsf("[W]"); lcd_gotoxy(13,1); lcd_putsf("[L]"); //update money money -= bet; } else{ lcd_gotoxy(13,0); lcd_putsf("[L]"); lcd_gotoxy(13,1); lcd_putsf("[W]"); //update money money += bet; } } } i = 0; while (i < 65535) i++; i = 0; while (i < 65535) i++; i = 0; while (i < 65535) i++; i = 0; while (i < 65535) i++; reset(); lcd_clear(); lcd_gotoxy(0,1); lcd_putsf("Money:"); itoa(money,moneystring); lcd_puts(moneystring); game1state = done; // move on to next hand } TCCR0 = 3; break; } } } //********************************************************** //Set it all up void initialize(void) { //set up the ports DDRA=0x00; // PORT A is an input (Buttons) DDRB=0xff; // PORT B is an ouput LED = 0; PORTB=~LED; //set up timer 0 reload=256-62; //value for 1 Msec TCNT0=reload; TIMSK=2; //turn on timer 0 overflow ISR TCCR0=3; //prescalar to 64 //set up timer 1 TIMSK=TIMSK | 0x40; //turn on timer 1 compare match interrupt TCNT1 = 0; //and zero the timer TCCR1B = 9; OCR1A = 125; //init the lcd pos=4; lcd_init(LCDwidth); //initialize the display lcd_clear(); //clear the display /* lcd_gotoxy(0,0); //position to upper left on display lcd_putsf("Blackjack"); //another string from flash lcd_gotoxy(0,1); lcd_putsf("Deal to play"); //another string from flash */ //init the task timers time1=t1; time2=t2; time3=t3; random = 0; maybe = 0; button = 0; buttonstate = Release; menustate = menu; game1state = done; playerpoints1 = 0; playerpoints2 = 0; dealerpoints = 0; cardcnt = 208; for (i = 0; i < 13; i++) cards[i] = 16; for (i = 0; i < 13; i++){ playercards1[i] = 0; playercards2[i] = 0; dealercards[i] = 0; } playerace1 = 0; playerace2 = 0; dealerace = 0; split = 0; playerpointer1 = 0; playerpointer2 = 0; dealerpointer = 0; current = 0; money = 1000; bet = 20; dbl = 0; //crank up the ISRs #asm sei #endasm }