prepared for the SX Starter Contest July 2002
My entry for the contest is an SX-based contestant lockout system, for 8-player, 2-team games, like Reach For The Top (where Alex Trebek got his start). It's like Jeopardy, but with 2 teams of 4 members each. One member answers the question by "buzzing in", at which point a tone sounds, their light lights, and everyone else is locked out.
My system adds a twist - an auto-reset 4 seconds after the sound ends. This is due to my own experiences, where moderators forget to reset the board, and no one can buzz in for the next question.
The code uses the RTCC interrupt to generate the tone, and the RB interrupt to detect when someone has buzzed in. I've designed it to run on a 4 MHz oscillator, in Turbo mode. Details on hardware connections are in the attached ASM file.
The code is untested, of course, and not likely to work the first time. It's my first attempt at writing for the SX (long time lurker).
Thanks,
-Randy Glenn
Comp. Eng. & Mgt. II, McMaster
University
===================================================
picxpert-at-cogeco.ca - glennrb-at-mcmaster.ca
picxpert-at-yahoo.com - randy_glenn-at-ieee.org
http://picxpert.dyndns.org/
===================================================
; Contestant Lockout System ; by Randy Glenn ; prepared for the SX Starter Contest July 2002 ; Version 1.0 - July 31, 2002 ; - initial release ; 8 buttons in on RB ; 8 LEDs out on RC ; Audio out on RA1 ; Manual reset button attached to reset line ; Code is supposed to work like this: ; Contestant pushes button, a team tone sounds, and their light is lit - others locked out ; Tone lasts for 1 sec, followed by 4 sec until auto-reset (lights out, board unlocked) device turbo,stackx_optionx reset startup freq 4000000 ;4 MHz org 8 SysStat ds 1 ; variable to hold flags for delay loop status, sound output i ds 1 ; counter variables j ds 1 k ds 1 InpBuf ds 1 ; variable to buffer RB ; variable declarations org 0 isr snb SysStat.0 ; are we in a delay? jmp :ProcDelay snb SysStat.2 ; are we doing tone 1? jmp :ProcTone1 snb SysStat.3 ; are we doing tone 2? jmp :ProcTone2 ; we must be checking input then :ProcInput mov M, #$09 ; set mode register to read pending RB interrupts mov W, !RB ; read pending RB interrupts mov M, #$0B ; disable RB interrupts clr !RB mov M, #$0F ; reset the mode register to power-up condition mov InpBuf, W ; move the W reg into an input buffer snb InpBuf.0 ; check to see which light to light jmp :Player1 snb InpBuf.1 jmp :Player2 snb InpBuf.2 jmp :Player3 snb InpBuf.3 jmp :Player4 snb InpBuf.4 jmp :Player5 snb InpBuf.5 jmp :Player6 snb InpBuf.6 jmp :Player7 snb InpBuf.7 jmp :Player8 :Player1 call SetupTone1 ; set variables for the appropriate tone clr RC ; clear the port setb RC.0 ; turn on the appropriate light jmp iout ; done interrupt :Player2 call SetupTone1 clr RC setb RC.1 jmp iout :Player3 call SetupTone1 clr RC setb RC.2 jmp iout :Player4 call SetupTone1 clr RC setb RC.3 jmp iout :Player5 call SetupTone2 clr RC setb RC.4 jmp iout :Player6 call SetupTone2 clr RC setb RC.5 jmp iout :Player7 call SetupTone2 clr RC setb RC.6 jmp iout :Player8 call SetupTone2 clr RC setb RC.7 jmp iout :ProcDelay ;standard delay loop - 256 * 256 * 244 = 4 sec at 4MHz djnz i, :DoneDelay mv i, #255 djnz j, :DoneDelay setb SysStat.1 :DoneDelay jmp iout :ProcTone1 ;tone 1 - 1 KHz, 1 sec long djnz i, iout ; invert RA1 every 16 interrupts mv i, #16 sb RA.1 jmp :ClearSnd1 jmp :SetSnd1 :ContSnd1 djnz j, iout ; various counters to allow for 1 second tone mv j, #250 djnz k, iout clrb SysStat.2 setb SysStat.0 ; set up registers for 4 sec delay before auto-reset mv i, #255 mv j, #254 jmp iout :ClearSnd1 clrb RA.1 jmp :ContSnd1 :SetSnd1 setb RA.1 jmp :ContSnd1 :ProcTone2 ;tone 2 - different constants for 600 KHz tone, 1 sec ; otherwise, same deal as tone 1 djnz i, iout mv i, #25 sb RA.1 jmp :ClearSnd2 jmp :SetSnd2 :ContSnd2 djnz j, iout mv j, #150 djnz k, iout clrb SysStat.3 setb SysStat.0 mv i, #255 mv j, #254 jmp iout :ClearSnd2 clrb RA.1 jmp :ContSnd2 :SetSnd2 setb RA.1 jmp :ContSnd2 iout reti startup clr SysStat ; clear all variables, just in case (and for auto-reset) clr InpBuf clr i clr j clr k mov !rb, #$FF ; rb is all inputs mov !rc, #$00 ; rc is all outputs mov M, #$0B ; set rb to allow interrupts mov !rb, #$00 mov M, #$0A ; rb is edge detect mov !rb, #$00 mov M, #$0F ; revert MODE to post-reset status mov !option, #$87 ; enable RTCC interrupt, prescaler 1:256 :loop snb SysStat.1 ; if no auto-reset has occured, keep looping jmp :loop ; otherwise restart jmp startup ; otherwise restart SetupTone1 setb SysStat.2 ; tone 1 mv i, #16 ; toggle audio pin every 16 interrupts for 1 KHz-ish mv j, #259 ; 250 * 4 = 1000 toggles = 1 sec mv k, #4 ret SetupTone2 setb SysStat.3 ; tone 2 mv i, #25 ; toggle audio pin every 25 interrupts for 600 Hz-ish tone mv j, #150 ; 150 * 4 = 600 toggles = 1 sec mv k, #4 ret
Randy G Glenn Says:
Yes, folks, I know there's an error here - a fairly colossal error, that causes any timed loops to run about 256 times longer than the comments would indicate. 'twill be fixed.