Laboration Datorteknik D 4. Spel Michael Josefsson version 2.2
Innehåll 1. Inledning 5 2. Hårdvara 7 2.1. Styrspak..................................... 7 2.2. Spelplan..................................... 8 2.3. A/D-omvandlare................................ 8 2.4. Högtalare.................................... 9 3. Spelet 11 3.1. Spelkrav..................................... 11 3.2. Hårdvara.................................... 11 3.3. Förberedelse- och laborationsuppgifter.................... 13 3.4. Överväganden.................................. 14 4. Diskussion 15 A. Slumpgenerator 17 B. Schema lysdiodsmatris 19 C. Schema styrspak 21 D. Programskelett 23 E. A/D-omvandlare MAX150/AD7820 29 3
4
1. Inledning Denna laboration är ett miniprojekt där du skall tillverka ett enklare digitalt spel, sänka fartyg. Spelet går ut på att med en styrspak, joystick, leta upp fartyget som sänks då din markör träffar målet. Som spelplan används en lysdiodmatris om 5x7 tecken. Målet markeras med en tänd lysdiod och din markör med en annan lysdiod. Programstrukturen är redan tillverkad men det saknas flera viktiga rutiner. I programlistningen i bilagorna anges vad som skall hända i respektive rutin. Det är din uppgift att skriva färdigt programmet. Laborationshandledningen beskriver den tillgängliga hårdvaran och pekar på sätt att använda den, men innehåller få detaljer om lösningsgången. Däremot finns åtskilliga checkfrågor som är tänkta att vara en påminnelse om speciella moment för uppgiftens lösande. Obs! I laborationen finns inga förberedelseuppgifter angivna. Det betyder dock inte att förberedelser inte behövs. Tvärtom, i denna laboration är de mer nödvändiga än någonsin tidigare och alla uppgifter måste förberedas. Det är upp till dig att komma till laborationen tillräckligt förberedd. Till laborationen måste du medföra konstruktionsunderlag, exempelvis flödesscheman och programkod. Du måste dessutom använda ett strukturerat angreppssätt i programmeringen och ett ingenjörsmässigt tänkande genom hela uppgiften. Det finns många fallgropar och förmågan att inse dessa i tid, och gå runt dem eller lösa dem, är väsentlig i speciellt den här laborationen. 5
6
2. H ardvara Till den h ar laborationen h or en del ny h ardvara som beskrivs nedan. Ut over de beskrivna modulerna kommer du att anv anda den normala laborationsh ardvaran dvs processorn 68008 p a labkortet Tutor med PIA:n 6821. 2.1. Styrspak Modulen best ar av tv a potentiometrar om 10 kω som ar monterade s a att de kan p averkas av en aterfj adrande styrspak. Spaken kan r oras i horisontell eller vertikal led och ger via sp anningsdelning en utsignal proportionell mot spakutslaget. Styrspaksmodulen med sina tv a sp anningsutg angar, respektive l. Styrspaken har aterfj adring s a att utsignalen vid vila ar halva matningssp anningen U. Aven om styrspaken skall t ala att spelas med m aste du vara f orsiktig s a att du inte bryter den mot dess andl agen. 7
2.2. Spelplan Som spelplan anv ands en lysdiodsmatris med 5 rader om 7 lysdioder. Modulen ar multiplexad s a att man v aljer rad f orst och sedan l agger p a det onskade bitm onstret. Raden v aljs ut genom att l agga dess bin ara nummer p a ing angarna C A. A a r minst siginifkant bit och raderna r aknas nedifr an (0, 1,..., 4). Adresseras andra rader an dessa medf or det en sl ackt matris. En 7x5-LED-matris tj anstg or som spelplan. Signalen E m aste anslutas till logisk etta f or att matrisen skall lysa upp. Modulen ar multiplexad. 2.3. A/D-omvandlare F or att l asa av styrspakens l age beh ovs en omvandlare mellan styrspakens analoga sp anning och det digitala v arde programmet f orv antar sig. Till detta anv ands den snabba analog-digital-omvandlaren MAX150. Kretsen MAX150 ar f ardigmonterad p a en A/Domvandlarmodul, men beh over ytterligare anslutningar f or att fungera som avsett. Databladet f or MAX150 aterfinns i bilagorna. Studera hela databladet och anv and omvandlaren i Stand-Alone Operation (figur 8 i databladet). 8
För att spara in på antalet pinnar kan du låta starta omvandling -signalen gå till båda omvandlarnas respektive ingångar. Omvandlingen sker då parallellt och du kan därefter välja vilken omvandlare du vill läsa av. Ut från omvandlaren kommer ett 8-bitars digitalt värde motsvarande ett av 2 8 = 256 spänningsvärden mellan V REF och V REF +, där V REF i laborationen är 0 V och V REF + är +5 V. A/D-omvandlarens överföringskurva. En analog insignal översätts till en av 256 olika digitala värden. Lägg märke till att man alltid förlorar information eftersom höjden på trappstegen i figuren inte är oändligt små. 2.4. Högtalare Högtalaren i laborationen är monterad på ett labkort med en potentiometer som volymkontroll och fungerar som en vanlig högtalare med talspole, dvs den återger den inkommande signalens frekvens. För att åstadkomma ett hörbart ljud från den måste insignalen alltså hela tiden växla mellan låga och höga värden. 9
10
3. Spelet Spelkonstruktionen uppdelas lämpligen i två delar: En del som sköter displayen och en del som är själva spelmaskinen. Spelet har få grundkrav, de krav som spelet måste uppfylla anges under Spelkrav nedan. 3.1. Spelkrav Vid spelstart skall ett mål placeras någonstans på spelplanens vänstra halva. Samtidigt skall en markör placeras i kolumnen längst till höger på spelplanen. Spelarens uppgift är att flytta markören till målet. När målet är täckt av markören skall träff signaleras med en ljudsignal i en högtalare. Spelet skall då startas om. 3.2. Hårdvara Spelet kräver styrspak, A/D-omvandlare, Tutor med PIA, spelplan och högtalare. Dessutom skall en yttre multiplexsignal initiera uppdatering av spelplanen. Vissa komponenter återfinns mer detaljerat beskrivet i bilagorna. Figuren nedan anger den principiella uppbyggnaden. Högtalare Multiplexfrekvens A/D Tutor med PIA A/D Styrspak (x y) Spelplan Hårdvarans uppkoppling. Styrspaken läge omvandlas i två A/D-omvandlare vars värden används av programmet för att styra den egna markören. Målet utgörs av en lysdiod i spelplanens vänstra halva. Vid träff skall ett ljud höras ur högtalaren. 11
Spelplansuppdatering Spelet skall utföras med en avbrottsstyrd spelplansuppdatering. Den yttre multiplexfrekvensen i figuren ovan generas av en tidbasmodul med 1, 10, 100 eller 1000 Hz frekvens. Multiplexsignalen skall starta en avbrottsrutin som uppdaterar matrisen enligt informationen i videominnet, som beskrivs nedan. Videominne Traditionellt bygger man upp nästa bild som ska skickas ut till en datorskärm i ett videominne. Detta garanterar flimmerfri bild om skärmen uppdateras tillräckligt ofta. Videominnet är vanligen mycket stort, åtskilliga megabyte är inte ovanligt. Då spelplanen i det här fallet omfattar 35 punkter kan ett betydligt mindre videominne användas. Spelet skall använda ett videominne omfattande 5 bytes placerade på adresserna $900 $904. Då spelplanen är 5x7 lysdioder används en byte per rad och högsta biten i varje byte används inte. En tänd lysdiod markeras med en logisk etta och en släckt med logisk nolla. bitnummer 7 6 5 4 3 2 1 0? 0 0 0 0 0 0 0? 0 1 0 0 0 0 0? 0 0 0 0 0 0 1? 0 0 0 0 0 0 0? 0 0 0 0 0 0 0 $904 $903 $902 $901 $900 adress Spelplanen och dess enkla videominne. En rad på spelplanen motsvarar 7 bits i respektive byte. Den mest signifikanta biten i varje byte används inte. I spelplanens vänstra del skall målet befinna sig. Styrspak I laborationen har vi inte möjlighet att på ett enkelt sätt läsa in A/D-omvandlarnas 2 x 8 bitar. 1 Istället skall omvandlarna användas så att bara två bitar från vardera omvandlare används. Med de två högsta bitarna från de båda omvandlarna kan vi bestämma fyra lägen i vardera ledd hos styrspaken. Det finns inget digitalt värde som kan motsvara att styrspaken är i viloläge. För att komma undan detta problem används bitarna på följande sätt: 1 Varför inte? 12
b7b6 riktning y-led riktning y-led 11 upp vänster 10 - - 01 - - 00 ner höger Genom att studera varje omvandlares två mest siginifikanta bitar (b7 och b6) kan vi avgöra om spaken är i något av sina ändlägen eller i ett läge någonstans i mitten av sitt utslag. Med denna konvention kan naturligtvis också kombinationer av dessa, exempelvis snett nedåt höger, detekteras: x-led 11 xx 00 11 y-led xx 00 Med två oberoende A/D-omvandlare kan riktningarna upp, ner, höger, vänster såväl som diagonalriktningarna kännas av. För bästa spelupplevelse bör möjligheten att gå diagonalt på spelplanen utnyttjas. 3.3. Förberedelse- och laborationsuppgifter Rita upp ett schema över hur uppgiften kan lösas med befintlig hårdvara. Schemat skall vara så detaljerat som möjligt, dvs varje koppling mellan komponenterna skall redovisas, exempelvis de mellan PIA och A/D-omvandlare och mellan PIA och spelplan. Konsultera programskelettet i bilagorna för mer information. Denna förberedelseuppgift är direkt underlag för den senare programmeringen. Var noggrann och ha schemat framför dig på laborationen. Att tänka på Hur skall PIA:n användas? Vilka portar är lämpliga för respektive uppgift? Hur skall man styra avläsningen av A/D-omvandlarna? 13
Laborationsuppgift Använd programskelettet som underlag och komplettera det i tillämpliga delar. Skriv in koden, kompilera, felsök. 3.4. Överväganden Som konstruktör av programmet är du ansvarig för alla delar av det. Du känner din egen styrka och dina egna svagheter. Tänk på att målet med laborationen är att i första hand få igång spelet. Du har en unik frihet att inom denna ram avgöra förenklingar: Är det för svårt att få fram bra slumptal? Gör då åtminstone till en början en slumptalsrutin som alltid ger samma slumptal. Det duger för att fortsätta programmeringen och du kan koncentra dig på uppgiften enligt de krav som finns under 3.1. Detaljerna i slumptalsgeneratorn kan du ta senare. Du kanske finner det lämpligt att först bara använda en (1) A/D-omvandlare? Gör då det och koppla in den andra först när du fått erfarenhet av den första. Är det komplicerat att gå diagonalt på spelplanen? Koncentera dig då på att enbart styra i x- och y-led. Du får ett fungerande spel ändå. Gör hela tiden denna form av ingenjörsmässiga överväganden och förenklingar. Se bara till att du kan motivera varför en förenkling gjordes och att spelkraven är uppfyllda. Tänk på att målet med laborationen är att få igång ett spel enligt kapitel 3.1. 14
4. Diskussion Du har i laborationen konstruerat ett enkelt datorspel. Trots den enkla uppgiften har den tvingat fram åtskilliga programmeringsknep och metoder. I spelet har du använt subrutiner, slumpgenerator, periferikrets med in- och utmatning, A/D-omvandlare och videominne för att inte tala om din egen kreativitet. Flera uppenbara tillägg till spelet kan göras. Skulle det till exempel vara svårt att införa följande förändringar? Få målet och/eller markören att blinka. Ändra hastigheten hos markören. Låta målet flytta sig då markören är nära. Göra roligare ljudeffekt?... -o-o-o- 15
16
A. Slumpgenerator Det är i allmänhet mycket svårt att tillverka en bra slumpgenerator med ett datorprogram. Riktig slump återfinns i praktiken bara i naturen i form av olika sorters brus. En form av slumpgeneratorer innehåller en förspänd diod varifrån man förstärker det termiska brus som olika atomnära processer skapar. Dessa slumpgeneratorer används som brusgeneratorer i professionella sammanhang där man exempelvis vill ha en helt slumpmässigt insignal till olika typer av filter, krypton med flera tillämningar. En dator är deterministisk av sin natur, dvs allt den kommer att göra i nästa tidsinstervall är bestämt av vad den gör i det nuvarande tidsintervall. 1 Det finns algoritmer som försöker efterlikna det slumpmässiga bruset men då de är algoritmer kan nästa utvärde alltid beräknas. Låt vara att det kan vara godtyckligt krångligt att göra det. I datorer finns ofta behov av en slumptalsgenerator. Till exempel för att generera s.k. frö, en slags startvärde, till kryperingsalgoritmer för ssh och WLAN. 2 I vårt fall kan vi lugnt använda enklare former av slump. Om vi låter varje anrop till en viss subrutin också räkna upp en räknare i en minnescell kan vi anta att innehållet i minnescellen är tillräckligt slumpartat då vi emellanåt läser av det. Gör läsningarna ofta, eller uppräkningarna sällan. kan man trots allt se en trend bland talen. Då kan man bestämma sig att använda bara de lägre bitarna, de ändras antagligen tillräckligt fort för att kunna ses som slumpartade. En annan möjlighet är att stuva om bitarna i minnescellen enligt ett fast mönster innan det används. På så sätt undviker man att närliggande tal i minnescellen ger ungefärligen samma slumptal. Förslag till slumpgenerator 0 och 4. Det är tillräckligt om vi kan ta fram två slumptal mellan Låt varje anrop till avbrottsrutinen för spelplansuppdatering räkna upp en byte i minnet. Det gör inget i det här fallet är det faktiskt en fördel om innehållet snabbt räknas upp som 254, 255, 0, 1,.... Använd de tre lägsta bitarna som slumptal. Om de tre lägsta bitarna ger ett tal som är större än vi önskar subtraherar vi 4 från det och använder 1 Även om man ibland tvingas tro det motsatta. 2 Det var på grund av bristande val av frö till en slumptalsgenerator som wep en standard för trådlös dataöverföring kunde analyseras och knäckas. Det visade sig att alla tillverkare av trådlösa instickskort till datorer använde samma, eller tillräckligt samma, frö. 17
resultatet som slumptal. Gör vi detta två gånger kan vi använda talen som koordinater i x- och y-led för målet. Du får naturligtvis hellre hitta på en egen metod att ta fram slumptalen! 18
19
B. Schema lysdiodsmatris 20
21
C. Schema styrspak 22
D. Programskelett 23
; ; Spelet "Sänka fartyg" ; Labskelett att komplettera ; Version 1.1 ; Programstrukturen är given. Några rutiner saknas. ; Det som måste kompletteras är markerat med '***' ; PIA:n skall anslutas/konfigureras enligt följande: ; PIAA b7-b6 A/D-omvandlare i X-led ; b5-b4 A/D-omvandlare i Y-led ; b3 Används inte ; b2-b0 Styr diodmatrisens multiplexingångar ; ; CA b2 Signal till högtalare ; b1 Avbrottssignal för MUX-rutinen ; ; PIAB b7 Används inte ; b6-b0 Diodmatrisens bitmönster ; ; CB b2 Starta omvandling hos A/D-omvandlare ; b1 Används inte ; jump to program jmp COLDSTART ; game variables ; define x- and y-coordinates of game area ; movable cursor position POSX dc.b 0 ; rightmost column (0..6) POSY dc.b 0 ; middle row (0..4) ; fixed target position TPOSX dc.b 0 ; target position (0..6) TPOSY dc.b 0 ; target position (0..4) ; line shown for multiplexing LINE dc.b 0 ; current line 0..4 shown on display ; random number RND dc.b 0 ; random number COLDSTART *** ; set stack pointer jsr PIAINIT ; setup I/O jsr INSTALLINTS ; install and enable interrupts ; short CB1 to GND for now unless ; you really want interrupts WARMSTART move.b #0,POSX ; we always start from here
move.b #2,POSY ; GAME jsr RANDOMTARGET ; positon target ; sense joystick and update POSX, POSY jsr JOYSTICK ; update videomem with POSX, POSY and target jsr VIDEOINIT ; clear it to draw a new frame move.b POSY,d0 and.l #$000000ff,d0 lea $900,a0 add.l d0,a0 move.b POSX,d0 bset d0,(a0) ; target position also move.b TPOSY,d0 and.l #$7,d0 lea $900,a0 add.l d0,a0 move.b TPOSX,d0 bset d0,(a0) ; wait a bit move.l #10000,d7 DLY sub.l #1,d7 bne DLY ; analyze situation ; we have a hit if POSX=TPOSX and POSY=TPOSY *** skriv rutinen som kollar om vi har träff *** *** om inte träff börjar programmet om från GAME *** ; we have a hit! Sound the alarm! jsr BEEP ; and restart jmp WARMSTART JOYSTICK ; ; Joystick sensing routine ; also sets X- and Y-coords ; *** starta en omvandling hos A/D-omvandlarna *** XCOORD move.b $10080,d0 ; read both A/D:s *** skriv kod som ökar eller minskar POSX beroende *** *** på insignalen från A/D-omvandlaren i X-led *** YCOORD move.b $10080,d0 ; what was it now again?
*** skriv kod som ökar eller minskar POSY beroende *** *** på insignalen från A/D-omvandlaren i Y-led *** jsr LIMITS ; bounds check before leaving rts ; LIMITS keeps us from falling off the edge of the world ; Allowed: POSX 0..6 ; POSY 0..4 LIMITS move.b POSX,d0 LIM1 LIMY LIM2 ; get current (updated) X-coord bpl LIM1 ; too much to right? move.b #0,POSX ; not any longer cmp.b #7,d0 ; too much to left? bne LIMY ; nope, check Y-coord move.b #6,POSX ; stick to left border move.b POSY,d0 ; get current (updated) Y-coord bpl LIM2 ; below arena? move.b #0,POSY ; keep on arena cmp.b #5,d0 ; above arena? bne LIM_EXIT ; no. move.b #4,POSY ; keep on arena LIM_EXIT ; both coords within bounds here rts ; done MUX ; ; Interrupt routine for multiplexing ; Installed as IRQA ; *** skriv rutin som handhar multiplexningen och *** *** utskriften till diodmatrisen *** add.b #1,RND rte ; update random number ; ; Videoinit clears video mem ; VIDEOINIT clr.b $900 ; clear memory clr.b $901 ;... ditto clr.b $902 ; clr.b $903 ; clr.b $904 ; done rts ; ; Simple (crude!) random generator for target ;
RANDOMTARGET move.b RND,d0 ; get random number *** skriv kod som överför RND-värdet till önskat intervall *** move.b d0,tposx ; TPOSX now in interval move.b RND,d0 ; get random number *** skriv kod som överför RND-värdet till önskat intervall *** move.b d0,tposy rts PIAINIT ; ; Init PIA ; *** skriv kod som initierar PIA:n *** rts INSTALLINTS ; ; Install and enable ints ; *** skriv kod som installerar avbrottsrutinen och *** *** sänker processorns IPL så att avbrott accepteras *** rts BEEP ; ; Make a silly sound ; *** skriv kod för en utsignal med lämlig frekvens som *** *** ska markera träff *** rts END
28
E. A/D-omvandlare MAX150/AD7820 29