LABORATION DATORTEKNIK Y DATORTEKNIK D Avbrottsprogrammering på M68008 Version: 3.2 203 (OVA) Namn och personnummer Godkänd
Till laboranten Inledning Syftet med laborationen är först att ge övning i avbrottsprogrammering (del A) samt därefter att tillämpa dessa kunskaper på ett större problem (del B). Syftet är också att skapa större förståelse för stackhantering i en processor. Efter genomförd laboration ska du, med hjälp av manual över parallellporten, kunna skriva 68000-program som kommunicerar med omvärlden via avbrottsstyrd parallellport. I del A kan det vara en fördel att använda den inbyggda radassemblern i TUTOR eftersom du då har större kontroll över var avbrottshanterare samt subrutiner hamnar. Labhäftet är också skrivet utifrån antagandet att radassemblern används. Väljer du att använda korsassemblern i del A behöver du kolla i listfilen för att få reda på var dina olika rutiner har hamnat. I del B används med fördel en korsassembler, se bilaga. Börja med att studera åtminstone kapitel 4.5-4.8 i häftet TUTOR M68008 system och assembler. En del förtydliganden om PIA:n finns som bilaga. Till laborationen ska du ha med dig egna lösningsförslag på alla laborationsuppgifter. Till del B bör det även finnas ett flödesschema. Tänk på att utnyttja eventuella labförberedande lektioner som kan komma att ges i anslutning till laborationstillfället. Extrauppgifterna görs i mån av tid. Praktiska råd Skriv upp vilka adresser du lägger dina program på, välj förslagsvis enkla siffror t.ex. $000, $00, $200 osv. Egentligen disponerar du adressrymden $900 - $7000, men adressområdet $2000 - $2500 kommer att användas av de färdiga subrutinerna. Du kommer att behöva en stack och ditt program måste därför börja med att ladda stackpekaren med något vettigt. Eftersom stacken växer mot lägre adresser kan $7000 vara en lämplig stackstart. Tänk på skillnaden mellan avbrottsnivå i CPU:n och avbrottsflagga i PIA:n. Om programmen inte uppför sig på förväntat sätt måste du felsöka. Störst nytta har du då av kommandot BR (Breakpoint). TR (Trace) är mindre lämpligt eftersom Trace utnyttjar avbrott med lägre prioritet än parallellporten. Om ditt program mystiskt försvinner kan det bero på stack overflow.
Färdiga subrutiner För att kunna fokusera på avbrottshanteringen finns det ett antal färdiga subrutiner. Dessa subrutiner finns lagrade i ROM men måste flyttas till RAM, ty om ett program befinner sig i ROM kan man inte sätta brytpunkter i det. Vid laborationens början skall du därför köra ett speciellt skyfflingsprogram för att ladda ner rutinerna till RAM. Detta program har startadressen $C300. Programmet laddar ner följande till minnet: Adress Rutin $20EC PINIT Programmerar PIA:ns PA7-PA0, PB7-PB0 som utgångar samt programmerar CA, CA2, CB och CB2 för att begära avbrott på positiv flank. $2020 SKBAK Skriver på terminalens skärm texten: BAKGRUNDSPROGRAM Texten skrivs längst till vänster på skärmen. $2048 SKAVV Skriver på terminalens skärm texten: AVBROTT vänster SLUT vänster Raderna skrivs i mitten av skärmen med en sekunds intervall. Rutinen förutsätter att köras som avbrottsnivå 2 $20A6 SKAVH Skriver på terminalens skärm texten: AVBROTT höger SLUT höger Raderna skrivs till höger på skärmen med en sekunds intervall. Rutinen förutsätter att köras som avbrottsnivå 5 $2000 DELAY Fördröjningsrutin. Anropas med önskad fördröjning i millisekunder i register D0 (32 bitar) 2 januari 25, 203 2
Du kan självklart titta på samtliga färdiga rutiner under laborationstiden, men några kan vara av intresse redan vid förberedelsearbetet och visas därför nedan. PINIT: DELAY: 0020EC 42390000084 CLR.B $0000084 0020F2 42390000086 CLR.B $0000086 0020F8 3FC00FF0000080 MOVE.B #255,$0000080 00200 3FC00FF0000082 MOVE.B #255,$0000082 00208 3FC00F0000084 MOVE.B #3,$0000084 0020 3FC00F0000086 MOVE.B #3,$0000086 0028 4A390000080 TST.B $0000080 002E 4A390000082 TST.B $0000082 00224 4E75 RTS 002000 2F0 MOVE.L D,-(A7) 002002 223C00000068 MOVE.L #04,D 002008 0480000000 SUB.L #,D 00200E 6AF8 BPL.S $002008 00200 5380 SUBQ.L #,D0 00202 6AEE BPL.S $002002 00204 22F MOVE.L (A7)+,D 00206 4E75 RTS 3
Laborationsuppgifter Del A Del A av laborationen består i att göra grundläggande undersökningar av ett mycket enkelt och schematiskt avbrottssystem för M68008. Ett program som skriver texten BAKGRUNDSPROGRAM på terminalen skall kunna avbrytas av två knappar, en som ger ett avbrott på nivå 2 och en som ger ett avbrott på nivå 5. Uppgift Skriv ett bakgrundsprogram som initierar systemet och sedan går in i en oändlig slinga där texten BAKGRUNDSPROGRAM skrivs på skärmen med en sekunds intervall. Initieringen behövs framförallt för uppgift 2 och framåt, och är enligt följande: Ladda stackpekaren, t.ex. med $7000. Programmera PIA:n, t.ex. genom att anropa PINIT. Ladda avbrottsvektorerna för avbrottsnivå 2 och 5 med adresserna $00 respektive $200. Möjliggör avbrott i processorn genom att sänka avbrottsnivån till 0. (Ändra inte bitarna S och T i Statusregistret!) Jorda avbrottsingångarna, dvs anslut CA, CA2, CB och CB2 till 0 på kopplingsplattan. Mata in ditt program med början på adress $000. Provkör. Stoppa med den svarta knappen (ABORT). Tag sedan bort jordanslutningen till CA och CB och anslut i stället de två tryckknapparna. Den vänstra skall anslutas till CB och den högra till CA, så att vänster knapp ger avbrott på nivå 2 och höger på nivå 5. Uppgift 2 Skriv två avbrottsrutiner av vilka den ena ska ge utskriften AVBROTT vänster och den andra utskriften AVBROTT höger. Respektive avbrottsflagga i PIA:n ska nollställas innan utskriften påbörjas, så att ytterligare en avbrottsbegäran kan tas emot under tiden avbrottsrutinen körs. Nollställningen ska ske med en instruktion som inte påverkar innehållet i något data- eller adressregister. I en verklig tillämpning sparar man normalt undan en del interna register på stacken först i sina avbrottsrutiner. Vi skall emellertid i laborationen gå in och titta på stackens innehåll, och för att göra det lätt att hitta och inte få för mycket ovidkommande data på stacken skall du inte spara några register i dina avbrottsrutiner. De färdiga subrutinerna, SKAVV och SKAVH, är skrivna så att de inte förstör varandras registerinnehåll. Mata in dina avbrottsrutiner på adresserna $00 respektive $200. Kontrollera att avbrottsvektorerna i ditt huvudprogram pekar på rätt avbrottsrutin, och att avbrottsrutinerna nollställer rätt port i PIA:n. 4 januari 25, 203 4
Kör huvudprogrammet på adress $000 och kontrollera funktionen hos ditt system enligt följande: Tryck på vänster knapp Vänta tills avbrottsrutinen är klar Tryck på höger knapp Om programmet uppförde sig som väntat gör du följande test: Tryck på vänster knapp Vänta någon sekund Tryck i snabb följd höger, vänster, höger. Om dina avbrottsrutiner är korrekt skrivna skall samtliga avbrott (totalt fyra stycken) tas om hand. Rita ett enkelt diagram som visar i vilken ordning begäran om avbrott kommer in, och i vilken ordning avbrottsrutinerna anropas. Förklara orsaken till att avbrotten inte åtgärdas i den ordning de begärs. Uppgift 3 Du kan genom tryckningar, på knapparna, på olämpliga ställen få texten BAK- GRUNDSPROGRAM att bli osammanhängande. Vi anser det vara väldigt viktigt att utskriften inte avbryts mitt i ett ord, utan kan bara acceptera avbrott i pauserna mellan utskrifter. Vad kan man göra för att få programmet att bete sig så? Gör det! (PIA-kretsen skall inte programmeras om.)... Tryck nu på den svarta ABORT-knappen när bakgrundsprogrammet exekveras. Om du trycker vid en väl (eller illa) vald tidpunkt kan du fortfarande störa utskriften mitt i ordet BAKGRUNDSPROGRAM. Hur är detta möjligt trots den åtgärd du nyss vidtog?... 5
Uppgift 4 Tryck på ABORT-knappen mellan två utskrifter av BAKGRUNDSPROGRAM. Programmet befinner sig nu med största sannolikhet i väntesubrutinen DELAY ($2000-$206) och stackdjupet blir då 8 bytes. (Med detta menas att det ligger 8 bytes på stacken, och att stackpekarens värde alltså är $6FF8 om stackpekaren var $7000 från början.) Om du inte skulle få stackdjupet 8 bytes när du avbryter, försök igen. Observera att avbrott genom tryckning på ABORT inte påverkar innehållet på stacken, eftersom avbrottsrutinen för ABORT är skriven så. Du kan om du så vill återstarta ditt program med GO, och det fortsätter som om inget hänt. När du avbrutit med ABORT och stackpekaren har värdet $6FF8, läs av vad som finns på stacken med kommandot MD. Identifiera vad det är som ligger där och varifrån det kommer. Ledning: titta vad som händer först i subrutinen DELAY. Adress Data 6FF8...... 6FFF Uppgift 5 Sätt nu en brytpunkt på den första instruktionen i subrutinen SKAVH ($20A6). Kör programmet och tryck i snabb följd mellan två utskrifter först på vänster knapp, och sedan på höger knapp. Om du inte har en väldig otur kommer såväl bakgrundsprogrammet som vänster avbrottsrutin att bli avbrutna i subrutinen DELAY ($2000-$206). Stackdjupet blir då 36 bytes. Om du skulle få ett annat stackdjup, starta om och försök igen. Vad bör stackpekaren ha för värde?... Läs återigen av vad som finns på stacken, hela vägen ner till botten, och identifiera exakt vad som ligger där och varifrån det kommer. Rita även en enkel figur som med pilar visar de hopp som sker mellan de olika rutinerna i programmet innan brytpunkten nås. Förklara anledningen till samtliga hopp och vad som lagras på stacken i varje steg. 6 januari 25, 203 6
På vilken adress blev bakgrundsprogrammet avbrutet? På vilken adress blev den lägsta avbrottsrutinen avbruten?... Uppgift 6 (Extrauppgift) Antag samma situation som i uppgift 5, men utan brytpunkt. Vad blir det maximala stackdjupet?... 7
Laborationsuppgifter Del B Uppgift 7 Konstruera ett PING-PONG spel. Använd två studsfria tryckomkopplare som ansluts till CA respektive CB, samt åtta lysdioder som ansluts till PIAA, se figur. Bollen markeras med en tänd lysdiod, och ska förflyttas fram och tillbaka över lysdiodarrayen så länge de bägge spelarna trycker ned sin knapp exakt då bollen befinner sig i respektive ändläge. U 0 2 3 4 5 6 7 PA PB CA 0 2 CA2 3 4 CB 5 6 CB2 7 0 0 Spelare V Spelare H Figur. Spelregler Den som vinner en boll får serva. Serve markeras med stillastående boll på den servandes sida. Bollen börjar att röra sig då knappen trycks ned. Spelare V börjar att serva vid spelets start. Om en spelare trycker antingen för tidigt eller för sent när bollen är i spel vinner den andre bollen och får poäng. Likaså om bollen går ut och spelaren inte trycker, då vinner den andre bollen. Nytt servläge ska komma automatiskt när en spelare har fått poäng. 8 januari 25, 203 8
Utförande Knappnedtryckningarna ska detekteras mha avbrott. Avbrottsrutinen ska byta flyttningsriktning om bollen är i ändläget hos respektive spelare, annars vidta lämplig åtgärd. Registren D3 och D4 ska, då spelet stoppas (med ABORT), innehålla hur många bollar respektive spelare har vunnit. Ditt program ska innehålla 2 statusflaggor, en som indikerar flyttningsriktning, och en som indikerar om serve ska göras. Då vi har gott om register använder vi ett helt register för respektive flagga. Lämplig registeranvändning är: D0: Tidsfördröjning vid anrop av DELAY. D2: Lagring av hur lysdioderna är tända. D3: Resultatregister spelare A. D4: Resultatregister spelare B. D5: Flyttningsriktning: 00=vänster, FF=höger. D6: Servstatus: 00=ej serve, FF=serve. Uppgift 8 (Extrauppgift) Komplettera spelet med poängvisning på 7-segmentdisplayer. Utnyttja port PIAB enligt figur 2. Poängvisning ska ske med en decimal siffra (0-9) för varje spelare. Om poängsiffran är större än nio ska istället bokstaven E visas. U 0 2 3 4 5 6 7 PA PB CA 0 2 CA2 3 4 CB 5 6 CB2 7 0 0 PB3-PB0 PB7-PB4 Spelare V Spelare H Figur 2. 9
Parallellporten (M682 PIA) Det mesta om parallellporten finns att läsa i kapitel 4.5-4.7 i häftet TUTOR M68008 system och assembler, men några saker kommer att förtydligas här. Kontrollregistrets CR-7 och CR-6 är inte programmerbara, utan nollställning görs genom en läsning av respektive ports data, se figur 3. Figur 4 visar prioritetsavkodningen mellan ABORT, IRQ A och IRQ B, vilket ligger utanför CPU:n. Till CPU:n kommer alltså en avbrottsbegäran, som är den högsta aktuella, och detta jämförs sedan internt med CPU:ns avbrottsnivå. CA- S R Q CRA-7 CRA-0 & IRQA CA-2 S R Q CRA-6 CRA-3 & Läsning i PIAA Figur 3. IRQ A IRQ 5 IRQ B & IRQ 2 ABORT Figur 4. 0 januari 25, 203 0
Korsassembler I Tutorkortets programvara finns en Radassembler som erbjuder en möjlighet att snabbt och enkelt komma igång med skrivandet och provkörning av assemblerprogram. Ganska snart upptäcker man att radassemblern är en primitiv utvecklingsmiljö lämpad för små testprogram i storleksordningen 0-20 rader. Vid större assemblerprogram saknar man en del finesser, t.ex: Möjlighet att spara. Möjlighet att använda en avancerad editor. Möjlighet att använda symboliska hoppadresser, så kallade Labels. Lösningen på detta är att använda en PC där en större utvecklingsmiljö är installerad, och du får tillgång till detta genom att i ett terminalfönster skriva module add BUSSENLAB. Vår miljö erbjuder följande: En korsassembler, som är en assembler som körs på en fristående utvecklinsdator, men som genererar kod för ett annat system, målsystemet, i vårt fall Tutor. Ett förbättrat terminalprogram som kan ladda ner binärkod till Tutorkortets RAM. Miljön är enkel att använda och arbetsgången beskrivs i punkterna nedan: Hela assemblerkoden skrivs i en editor och lagras på en fil, t.ex. lab.s. Assemblera filen pingpong.s med kommandot assemble.sh lab.s i ett terminalfönster. Filen assemble.sh är ett s.k. script och innehåller de kommandon som behövs för att assemblera koden. Startadressen kommer alltid att bli $000. Reslutatet kan beskådas i en listfil där talet $000 måste adderas till adressen. Terminalprogrammet körs med kommandot tutor.sh i ett terminalfönster. Med spänningen påslagen ska tutorprompten dyka upp när du slår några returtecken. Den kompilerade filen kan nedladdas till tutorkortet med kommandot ctrl-f l (control-eff ell). Terminalprogrammet avslutas med kommandot ctrl-e. Eventuella brytpunkter kommer att försvinna vid en nerladdning. Tyvärr kan INTE de svenska bokstäverna å,ä och ö ingå i assemblerfilen. Det kan vara lämpligt att lägga editor, assemblering och terminalprogram i olika terminalfönster och att ha dessa uppe samtidigt. Här följer ett programexempel: START MOVE.L #TABS,A2 Kommentar LOOP CMP.B #$0D,(A2)+ Kommentar 2 BNE.S LOOP MOVE.B #228,D7 TRAP #4 TABS DC.B Provstrang DC.B $0D END