;; THE LOTTERY GAME ;; L14.src ;; Last Edit: 4/4/95 ;; 722 machine words ; Lottery Machine Game Design by: Louis Guzik EET 416 Spring 1995 ; Using the PIC16C57 by MicroChip Inc. DEVICE PIC16C57,XT_OSC,WDT_OFF,PROTECT_OFF RESET Start ;; ;; clrb pa1 ; make sure we are at page 0, must run after lcall ;; ; and before any kind of jmp into page 0 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PROCEDURCES BEGIN ;; ;; ;; long calls for page 2 of memory org 400h M_Button jb Button0, M_Button ; Momentary Button ret ; Is Select Button0 pressed Debounce call LongWait jnb Button0, Debounce call LongWait ret ; debounce LongWait ;; Create a delay loop for about .15 secs at 4 mhz. mov temp2, #225 ; was 130 mov temp, #255 :loop djnz temp,:loop djnz temp2,:loop ret ; LongWait ClearLCD clrb RS ; Clear RS to send instruction. mov temp2, #1 call blip_E setb RS ret ; CLEAR LCD BackSpace clrb RS mov temp2, #crsr_l ; move back one space LCD call blip_E setb RS ret ; BackSpace ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; blip_E ; Write data or instructions (in variable temp2) to the LCD. movb pa2, RS ;Store current state of RS in unused bit. clrb RS ;Clear RS to send instruction. setb RW ;Set RW to read. mov !rb, #255 ;Port rb: all inputs. :loop setb E ;Enable the LCD. nop mov temp, data ;Put LCD data (rb) into temp. clrb E ;Disable LCD. snb temp.7 ;Is the LCD busy? jmp :loop ;Yes, try again later. movb RS, pa2 ;No, send the data or instruction. clrb RW mov !rb, #0 mov data, temp2 setb E nop clrb E clrb pa2 ; lgg inserted, try to stay on page 0 ret ; blib_e ; ;; blip_e END ;--------------------------------------------------------------------------- ; ; Converts a binary number to BCD format (fast) ; Called with binary number in W and pointer to BCD number in FSR ; If the binary number is greater than 99, Z is set to 1, and the BCD number ; is set to 00h bin2bcd mov accum, W ;Save binary value clr INDIRECT ;Start with 00h in result cja accum, #99,:ov ;Overflow if greater than 99 sub accum, #10 * 8 ;Divide by 10 using weighted subtract rl INDIRECT ;Rotate bit into result sb INDIRECT.0 ;Skip value restore if no underflow add accum, W ;Underflow, restore value sub accum, #10 * 4 ; rl INDIRECT ; sb INDIRECT.0 ; add accum, W ; ; sub accum, #10 * 2 ;\ rl INDIRECT ; \ sb INDIRECT.0 ; / Do all four bits of divide add accum, W ;/ ; sub accum, #10 ; rl INDIRECT ; sb INDIRECT.0 ; add accum, W ; swap INDIRECT ;Move result of divide to ten's place or INDIRECT, accum ;Add one's place (remainder) clz ;Indicate valid BCD conversion ret ;Return with Z=0 :ov stz ;Overflow, return 00 in bcd and Z set ret ; ;- bin2bcd ----------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NameDaily jmp pc+w retw 'D','a','i','l','y',' ','#',' ' NameBig4 jmp pc+w retw 'B','i','g',' ','4',' ','#',' ' NamePick6 jmp pc+w retw 'P','i','c','k','6',' ','#',' ' NamePick7 jmp pc+w retw 'P','i','c','k','7',' ','#',' ' NameEnd jmp pc+w retw ' ','#',' ' ; ,' ','E','n','d','.' Credits jmp pc+w retw ' ',' ','P','l','a','y',' ','t','h','e',' ','L' ; 12 chars retw 'o','t','t','e','r','y',' ','G','a','m','e',' ' ; 24 chars retw ' ','E','E','T','-','4','1','6',' ',' ','S','p' ; 36 chars retw 'r','i','n','g',' ',' ','1','9','9','5',' ',' ' ; 48 chars retw 'D','e','s','i','g','n',' ',' ','b','y',' ',' ' ; 60 chars retw 'L','o','u','i','s',' ','G','.',' ','G','u','z' ; 72 chars retw 'i','k',' ',' ','*','*','*',' ' ; 80 chars Instructions jmp pc+w retw ' ','0','0','-','D','a','i','l','y',' ',' ','0' retw '1','-','B','i','g','4',' ','1','0','-','P','i' retw 'c','k','6',' ',' ','1','1','-','P','i','c','k' retw '7',' ' ;; ;; PROCEDURCES END ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DATA ;; ; ; Set RAM origin above special registers, declare variables, and set code ; origin. ; org 8 GameName ds 1 ; 00b = Daily, 01b = Big 4 ; 10b = Pick 6, 11b = Pick 7 MyCount ds 1 NumberLimit ds 1 MaxPairs ds 1 bcd_num ds 1 ; Place to hold the BCD number bcd_rev ds 1 ; swaped bcd nibles bin_num ds 1 ; Place to hold the binary number round_num ds 1 ; index ds 1 ; index for arrary N[0-7] temp ds 1 ; Temporary counter. temp2 ds 1 ; Pass data or instructions to blip_E. counter ds 1 ; Index variable. accum ds 1 ; Used for math in bin2bcd routine N0 ds 1 ; N0 not used, place holder N1 ds 1 ; array of used numbers for pick6, pick7 N2 ds 1 ; N3 ds 1 ; N4 ds 1 ; N5 ds 1 ; N6 ds 1 ; N7 ds 1 ; array of used numbers for pick6, pick7 org 0 ;; PORT ASSIGNMENTS ; Button0 equ RC.0 ; Momentary Switch Button1 equ RC.1 ; LSD for selecting game Button2 equ RC.2 ; MSD for selecting game LCD_pwr = ra.3 ;+5 to LCD module RS = ra.2 ;0 = write, 1 = read RW = ra.1 ;0 = instruction, 1 = data E = ra.0 ;0 = disable, 1 = enable data = rb ;Data to LCD ; Declare constants for common LCD instructions. To perform the functions ; listed below, clear bit RS and send #constant to the display. Remember to set ; RS again before sending characters to the LCD. clear = 1 ; Clears the display (fills with blanks) home = 2 ; Returns display to the home position. shift_l = 24 ; Shifts display to the left. shift_r = 28 ; Shifts display to the right. crsr_l = 16 ; Moves cursor to the left. crsr_r = 20 ; Moves cursor to the right. blink_c = 11 ; Blinks whole char to indicate cursor position. no_crsr = 8 ; Turns off the cursor. crsr_on = 14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; START HERE ONCE ;; ; Start mov ra, #0 mov rb, #0 mov rc, #0 mov !RC, #00000111b ; Set RC0, RC1, RC2 to Inputs mov !RA, #00000000b ; Set All others to Outputs mov !RB, #00000000b ;; init LCD setb LCD_pwr lcall LongWait lcall LongWait mov temp2,#00110000b ; bit4 0 = 1-line; 1 = 2-lines lcall blip_E ; Init LCD: set 8-bit, 1-line mov temp2,#00001110b ; SET 1110b for cursor. lcall blip_E mov temp2,#00000110b ; incr addr by 1, move cusor to right after write lcall blip_E mov temp2, #01000000b ; Write to CG RAM: start at address 0. lcall blip_E mov temp2, #10000000b ; Address 0 of DD RAM. lcall blip_E setb RS ; set TO SEND DATA ;; SCROLL CREDITS ;; mov counter, #0 :loop mov w, counter lcall Credits ; scroll credits mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #80, :loop ; 80 chars in credits Intro lcall LongWait clrb rs mov temp2, #24 ; #24 shift left lcall blip_E setb rs clrb pa1 ; make sure we are at page 0 jnb Button0, OffWeGo ; if button0 is pressed goto jmp Intro OffWeGo lcall Debounce lcall ClearLCD clrb RS ; Clear RS to send instruction. mov temp2,#00111000b ; bit4 0 = 1-line; 1 = 2-lines lcall blip_E ; Initialize LCD: set 8-bit, 2-line setb RS ;; THE BIG LOOP ;; ;; BigLoop lcall ClearLCD clr round_num ;; SHOW INSTRUCTIONS mov counter, #0 :loop mov w, counter lcall Instructions mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #18, :loop clrb RS mov temp2, #0011000000b ; move to 2nd line lcall blip_E setb RS :loop2 mov w, counter lcall Instructions mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #38, :loop2 lcall M_Button ; Wait for Select Button lcall Debounce clr GameName clrb pa1 ; make sure we are at page 0 jb Button1, MSD ; Is Game Button1 Pressed setb GameName.0 ; Incr GameName LSD if it is pressed MSD jb Button2, Cont ; MSD; Is Game Button2 Pressed setb GameName.1 ; Set GameName MSD if it is pressed Cont lcall ClearLCD mov counter, #0 clrb pa1 ; make sure we are at page 0 cje GameName, #3, SetUpP7 cje GameName, #2, SetUpP6 cje GameName, #1, SetUpB4 ; DEFAULT IS DAILY NUMBER ;; DISPLAY NAME OF GAME DAILY :loop mov w, counter lcall NameDaily mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #8, :loop ;; SETUPDAILY mov NumberLimit, #9 mov MaxPairs, #3 mov MyCount, #0 jmp PlayGame SetUpB4 ;; DISPLAY NAME OF GAME BIG 4 :loop mov w, counter lcall NameBig4 mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #8, :loop ;; SETUPB4 mov NumberLimit, #9 mov MaxPairs, #4 mov MyCount, #0 jmp PlayGame SetUpP6 ;; DISPLAY NAME OF GAME PICK 6 :loop mov w, counter lcall NamePick6 mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #8, :loop ;; SETUP6 mov NumberLimit, #48 mov Maxpairs, #6 mov MyCount, #1 jmp PlayGame SetUpP7 ;; DISPLAY NAME OF GAME PICK 7 :loop mov w, counter lcall NamePick7 mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #8, :loop ;; SETUP7 mov NumberLimit, #74 mov MaxPairs, #7 mov MyCount, #1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PlayGame cja MyCount, NumberLimit, ClearCount ;; MOST CODE IN PLAYGAME IS FOR ROLLING NUMBERS ON LCD BEFORE BEING PICKED ;; mov FSR, #bcd_num ; Point FSR to where the BCD number is mov W, MyCount ; Load W with the number to convert lcall bin2bcd ; Call conversion routine mov bcd_rev, bcd_num clrb pa1 ; make sure we are at page 0 cjbe GameName, #1, Skip2 swap bcd_rev and bcd_rev, #00001111b add bcd_rev, #30h ; convert to char mov temp2, bcd_rev ; write number to lcd lcall blip_E Skip2 and bcd_num, #00001111b add bcd_num, #30h ; convert to char mov temp2, bcd_num ; write number to lcd lcall blip_E clrb pa1 ; make sure we are at page 0 cjbe GameName, #1, Skip3 lcall BackSpace Skip3 lcall BackSpace clrb pa1 ; make sure we are at page 0 mov temp2, #3 mov temp, #255 ShortWait1 djnz temp, ShortWait1 djnz temp2, ShortWait1 cjae GameName, #2, Skip4 ; if it a digit game, wait longer mov temp2, #3 mov temp, #255 ShortWait2 djnz temp, ShortWait2 ; make digit game wait longer djnz temp2, ShortWait2 Skip4 ;; ;; END ROLLING NUMBERS jnb Button0, Select inc MyCount jmp PlayGame ClearCount cjae GameName, #2, Skip1 ; CLEARCOUNT PROC mov MyCount, #0 jmp PlayGame Skip1 mov MyCount, #1 jmp PlayGame Select lcall Debounce ; SELECT PROC inc round_num clrb pa1 ; make sure we are at page 0 cjae GameName, #2, Pick_X ;; DEFAULT IS DAILY NUMBER AND BIG4 mov FSR, #bcd_num ; Point FSR to where the BCD number is mov W, MyCount ; Load W with the number to convert lcall bin2bcd ; Call conversion routine add bcd_num, #30h ; convert to char mov temp2, bcd_num lcall blip_E clrb pa1 ; make sure we are at page 0 cjb round_num, MaxPairs, PlayGame jmp EndGame Pick_X ;; ;; CHECK FOR REPEAT NUMBERS Check mov FSR, #N0 ; Point FSR to Beginning of Array N mov index, #1 :loop cje index, round_num, EnterNumb inc FSR cje INDIRECT, MyCount, Resolve ; Is MyCount In N[ index ] inc index jmp :loop Resolve ; RESOLVE CONFICT BETWEEN MYCOUNT AND ARRARY[ index ] inc MyCount cja MyCount, NumberLimit, ClearMyCount jmp Check ClearMyCount mov MyCount, #1 jmp Check EnterNumb mov FSR, #N0 ; Point FSR to Beginning of Array N add FSR, index ; point to correct arrary element mov INDIRECT, MyCount ;; PROCESS NUMBER mov FSR, #bcd_num ; Point FSR to where the BCD number is mov W, MyCount ; Load W with the number to convert lcall bin2bcd ; Call conversion routine mov bcd_rev, bcd_num swap bcd_rev and bcd_rev, #00001111b ; MSD add bcd_rev, #30h ; convert to char mov temp2, bcd_rev lcall blip_E and bcd_num, #00001111b ; LSD add bcd_num, #30h ; convert to char mov temp2, bcd_num lcall blip_E mov temp2, #20h ; space between #'s lcall blip_E clrb pa1 ; make sure we are at page 0 cjne round_num, #4, Skip ;; IF WE ARE AT ROUND 4 clrb RS mov temp2, #0011000000b ; move to 2nd line lcall blip_E setb RS mov counter, #0 :loop mov w, counter ; add spaces to 2nd line mov temp2, #20h lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #8, :loop Skip cjb round_num, MaxPairs, PlayGame ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EndGame ;; DISPLAY END OF GAME mov counter, #0 :loop mov w, counter lcall NameEnd mov temp2, w lcall blip_E inc counter clrb pa1 ; make sure we are at page 0 cjb counter, #3, :loop lcall M_Button ; Wait for Select Button lcall Debounce clrb pa1 ; make sure we are at page 0 jmp BigLoop ;;;;; END OF THE LOTTERY GAME ;;;;;