LABORATION Datorteknik Y Kodlås på MC68008 Version 1.6 2012 (AE) 2013 (AE) 2014 (AE) Namn och personnummer Godkänd 1
1 Inledning Syftet med laborationen är att ge övning i assemblerprogrammering samt att skapa nödvändig kännedom om laborationsutrustningen inför senare laborationer i denna kurs. Efter den här laborationen kommer du att ha bra koll på instruktionsuppsättningen på MC68008 samt hur du hanterar in och utmatning på det labsystem vi använder. Du ska även vara förtrogen med labsystemet Tutor och dess kommandon. Innan du tar itu med förberedelserna bör du åtminstone läsa kapitel 2, 5, 6 och 7 i häftet TUTOR MC68008 system och assembler, samt den del av kapitel 4 som handlar om PIAA och PIAB (förutom avbrott och PIAA/PIAB). Det är lämpligt att du ägnar åtminstone någon timme åt labförberedelser innan den labförberedande lektionen för att kunna utnyttja detta lektionstillfälle till fullo. Till laborationen ska du ha med dig lösningsförslag på samtliga obligatoriska uppgifter i detta labhäfte samt åtminstone två av de extrauppgifter som ingår. (Det är obligatoriskt att på laborationen genomföra åtminstone en av dessa extrauppgifter.) 2 Praktiska tips Ett av de allra vanligaste felen är att man förväxlat syntaxen för absolut och omedelbar adresseringsmod. Det vill säga, att man antingen lagt till ett # där det inte ska finnas, alternativt glömt bort att lägga till det där det ska finnas. Ett annat vanligt fel är att man har glömt att ange ordlängd eller angett fel ordlängd. Med andra ord, du har angett fel suffix av (.B,.W, eller.l) på en viss instruktion. Slutligen så kan man få mycket underliga resultat om man har glömt att sätta stackpekaren. Boett från denna typ av felskrivningar som nämnts ovan så är det vanligt med rent logiska fel i programmet. För att hitta denna typ av fel är det viktigt att gå systematiskt till väga. Gå igenom ditt program steg för steg och försäkra dig om vilka delar det är som fungerar. Har du delat upp ditt program i subrutiner så blir detta betydligt enklare. Du kan då testa en subrutin i taget för att se om subrutinerna fungerar korrekt var för sig. Möjligheten att stega sig igenom programmet (kommandot TR i Tutor) samt sätta breakpoints (BR) kommer du också ha stor nytta av. 2
Terminal TUTOR 1.3 > GO 1000 PHYSICAL ADDRESS=00001000 Felaktig kod! (1) Felaktig kod! (2) Lysdiod ACIA (Serieport) PIA A PIN 0 PIA B PIN 0 PIA B PIN 1 PIA B PIN 2 PIA B PIN 3 A (LSB) B C D (MSB) Hextangentbord 1 2 3 A 4 5 6 B MC68008 PIA B PIN 4 STROBE 7 8 9 C D 0 E F Figur 1: Labuppkopplingen 3 Specifikation av kodlåsets funktion I denna laboration ska du implementera ett enkelt kodlås i assembler på labsystemet. Kodlåset är tänkt att sitta i ett störra system där det används för att slå på respektive av ett larm av något slag. Att larmet är aktiverat visar vi i denna laboration genom att tända en lysdiod. Ett hextangentbord med knapparna 0 9 och A F används för att aktivera respektive avaktivera larmet enligt följande specifikation: När du trycker på tangenten A på knappsatsen ska kodlåset aktivera larmet (dvs tända lysdioden). Du ska kunna trycka in en fyrsiffrig kod följd av tangenten F för att avaktivera larmet. Om rätt kod skrivs in så ska lysdioden som indikerar att larmet är på släckas). Om felaktig kod skrivs in så ska istället texten Felaktig kod! skrivas ut på terminalen. Det är de senaste fyra siffrorna som räknas. Det vill säga, om rätt kod är 6510 så ska man exempelvis kunna trycka in sekvensen 6526510F för att låsa upp dörren. 4 Inkoppling av knappsats och lysdiod Kodlåset ska kopplas in enligt figur 1. Kodlåset har fem signaler som ska kopplas in (utöver jord och matningsspänning). Fyra av dessa signaler (A-D) visar vilken knapp som tryckts ner på hextangentbordet. Den sista signalen (Strobe) signalerar att en tangent trycks ner genom att gå hög. Denna signal är avstudsad. Utöver detta ska du koppla in en lysdiod enligt figuren som används för att visa att larmet är aktiverat. 3
5 Rekommenderade minnesadresser Om du använder de här minnesadresserna så blir det lättare för labassistenterna att hjälpa dig om du får problem: $1000: Här startar programmet $4000 $4003: Här ska du lagra de fyra senaste siffrorna som skrivits in på hextangentbordet. (Den tangent som tryckts in senast lagras på adress $4003.) $4010 $4013: Här ska den korrekta koden finnas lagrad. $4020 : Här ska textsträngen Felaktig kod! finnas lagrad med hjälp av ASCIIkodning, följd av koden för newline och carriage return. $7000: Detta är ett lämpligt startvärde för stackpekaren. 6 Subrutiner Det här avsnittet innehåller information om de subrutiner som vi rekommenderar att du delar upp ditt program i. Förutom huvudprogrammet så ska du skriva åtminstone 9 subrutiner: printchar: Skriv ut ett tecken till terminalen setuppia: Initiera parallellporten printstring: Skriv ut en textsträng deactivatealarm: Avaktivera larmet activatealarm: Aktivera larmet getkey: Hämta tecken från hextangentbordet addkey: Lägg till tangent i inbuffern clearinput: Rensa inbuffer checkcode: Kolla om rätt kod tryckts in När du kommer till laborationen ska du ha förberett assemblerkod för alla dessa subrutiner. Du ska givetvis förbereda huvudprogrammet i förväg också. Du får gärna lägga till fler subrutiner om du känner att du behöver det. 4
6.1 printchar - Utskriftsrutin Följande subrutin skriver ut ett ASCII-kodat tecken i register d4 på terminalen. ; Inargument: ASCII-kodat tecken i register d4 ; Varning - Denna rutin går inte att stega sig igenom med TRACE då den ; använder serieporten på ett sätt som är inkompatibelt med TRACE. printchar move.b d5,-(a7) ; Spara undan d5 på stacken waittx move.b $10040,d5 ; Serieportens statusregister and.b #2,d5 ; Isolera bit 1 (Ready to transmit) beq waittx ; Vänta tills serieporten är klar att sända move.b d4,$10042 ; Skicka ut move.b (a7)+,d5 ; Återställ d5 ; Tips: Sätt en breakpoint här om du har problem med trace! Tips: Denna subrutin kan du testa i förväg via tutor.edu.isy.liu.se! 6.2 setuppia - Initiera parallellporten Följande subrutin sätter upp parallellporten så att pinne 0 på PIAA är en utgång och resten av pinnarna är ingångar. setuppia move.b #0,$10084 ; Välj datariktningsregistret (DDRA) move.b #1,$10080 ; Sätt pinne 0 på PIAA som utgång move.b #4,$10084 ; Välj in/utgångsregistret move.b #0,$10086 ; Välj datariktningsregistret (DDRB) move.b #0,$10082 ; Sätt alla pinnar som ingångar move.b #4,$10086 ; Välj in/utgångsregistret 6.3 printstring - Skriv ut en textsträng Den här subrutinen ska skriva ut en textsträng på terminalen (med hjälp av subrutinen printchar). ; Inargument: Pekare till strängen i a4 ; Längd på strängen i d5 printstring ; Förberedelseuppgift: Skriv denna subrutin! Tips: Denna subrutin kan du testa i förväg via tutor.edu.isy.liu.se! 5
6.4 deactivatealarm - Avaktivera larm Den här subrutinen ska släcka lysdioden. ; Inargument: Inga ; Utargument: Inga ; ; Funktion: Släcker lysdioden kopplad till PIAA deactivatealarm ; Förberedelseuppgift: Skriv denna subrutin! 6.5 activatealarm - Aktivera larm Den här subrutinen ska tända lysdioden. ; Inargument: Inga ; Utargument: Inga ; ; Funktion: Tänder lysdioden kopplad till PIAA activatealarm ; Förberedelseuppgift: Skriv denna subrutin! 6.6 getkey - Hämta tecken från hextangentbordet Den här subrutinen är tänkt att vänta på att användaren trycker på en tangent på hextangentbordet. Tips: Om du vill göra ditt huvudprogram enklare så returnerar du ifrån denna subrutin först när användaren slutar trycka på tangenten! ; Inargument: Inga ; Utargument: Tryckt knappt returneras i d4 getkey ; Förberedelseuppgift: Skriv denna subrutin! 6
6.7 addkey - Lägg till tangent i inbuffern Den här subrutinen är tänkt att lägga till ett tecken i inbuffern genom att skifta buffern framåt ett steg. (Se exemplet nedan.) Ursprungstillstånd Efter det att addkey anropats med värdet 1 i d4 $4000: $FF $4000 $FF $4001: $FF $4001 $06 $4002: $06 $4002 $05 $4003: $05 $4003 $01 ; Inargument: Vald tangent i d4 ; Utargument: Inga ; ; Funktion: Flyttar innehållet på $4001-$4003 bakåt en byte till ; $4000-$4002. Lagrar sedan innehållet i d4 på adress $4003. addkey ; Förberedelseuppgift: Skriv denna subrutin! Tips: Denna subrutin kan du testa i förväg via tutor.edu.isy.liu.se! 6.8 clearinput - Rensa inbuffer Den här subrutinen är tänkt att lägga in en ogiltig kod i inbuffern. ; Inargument: Inga ; Utargument: Inga ; ; Funktion: Sätter innehållet på $4000-$4003 till $FF clearinput ; Förberedelseuppgift: Skriv denna subrutin! Tips: Denna subrutin kan du testa i förväg via tutor.edu.isy.liu.se! 7
6.9 checkcode - Kolla om rätt kod tryckts in Den här subrutinen kollar om den kod som ligger i inbuffern på $4000 är korrekt. Krav: Du får enbart göra en läsning ifrån $4000 $4003 respektive $4010 $4013 i denna subrutin. ; Inargument: Inga ; Utargument: Returnerar 1 i d4 om koden var korrekt, annars 0 i d4 checkcode ; Förberedelseuppgift: Skriv denna subrutin! Tips: Denna subrutin kan du testa i förväg via tutor.edu.isy.liu.se! 7 DEL 0: Testa dina subrutiner var för sig Innan du försöker implementera hela kodlåset är det smart att testa dina subrutiner var för sig. Här nedan finns tips på hur du skriver program som testar de subrutiner som vi rekommenderar att du använder i denna laboration. Det här borde också kunna hjälpa dig att förbereda laborationen hemifrån genom att testköra vissa subrutiner redan innan du kommer till laborationen. Se även avsnitt 10 för lite tips om hur du kan testköra ditt program hemifrån. 7.1 printchar Sätt d4 till 64 Anropa printchar Avsluta programmet och dumpa alla register med följande kodsnutt: move.b #255,d7 trap #14 När du kör programmet ska ett snabela skrivas ut (innan tutor skriver ut ett felmeddelande och dumpar alla register). 7.2 setuppia Anropa setuppia Avsluta programmet (enligt beskrivning ovan) 8
Dumpa PIANs minnesinnehåll med hjälp av kommandot MD 10080 Håll inne en knapp på hextangentbordet. Dumpa minnet igen. Nu ska värdet på position $10082 ändrat sig beroende på vilken knapp du tryckte på. Skriv in en etta till adress $10080 med hjälp av kommandot MM. Då ska lysdioden tändas. 7.3 printstring Sätt A4 till $C126 Sätt d5 till 16 Anropa printstring Avsluta programmet (enligt beskrivning ovan) När du kör programmet ska strängen BAKGRUNDSPROGRAM skrivas ut. 7.4 deactivatealarm och activatealarm Anropa setuppia Anropa activatealarm Avsluta programmet enligt ovan. När du kör programmet nu så ska lysdioden tändas. Ändra programmet så att du anropar deactivaetalarm istället för activatealarm. När du kör programmet nu så ska lysdioden släckas. 7.5 getkey Anropa getkey Avsluta programmet enligt ovan Kör programmet, tryck på valfri knapp.nu ska du i registerdumpen kunna se vilken knapp du tryckte in genom att titta på innehållet i D4. Notera att programmet inte ska avslutas förräns du släppt tangenten. 9
7.6 clearinput Anropa clearinput Avsluta programmet enligt ovan Verifiera att $4000 $4003 innehåller värdet FF FF FF FF med hjälp av kommandot MD 7.7 addkey Anropa clearinput Sätt d4 till 1 Anropa addkey Sätt d4 till 2 Anropa addkey Sätt d4 till 3 Anropa addkey Sätt d4 till 4 Anropa addkey Avsluta programmet enligt ovan Dumpa innehållet i $4000 $4003 med hjälp av kommandot MD. Det ska innehålla 01 02 03 04 7.8 checkcode Anropa checkcode Avsluta programmet enligt ovan Innan du kör detta program så använder du kommandot MM för att skriva in två koder som är identiska på position $4000 $4003 respektive $4010 $4013. När du kör programmet så ska du i registerdumpen se att d4 fick värdet 1. Ändra i minnet med MM så att koderna inte är identiska. Kör sedan programmet igen och verifiera att d4 innehåller 0. 10
7.9 Trace och brytpunkter Tänk också på att du kan använda BR och TR för att stega dig igenom programmet. 8 DEL A: Kodlåset Nu när du har verifierat att alla dina subrutiner fungerar kan du kombinera dessa i ett huvudprogram som implementerar kodlåset. 9 DEL B: Varianter på kodlåset Inför laborationen så ska du förbereda minst två av dessa varianter. 1 Du behöver dock enbart redovisa en variant på laborationstillfället. Tips: Om du lägger till eller modifierar subrutiner, testa dessa subrutiner separat på samma sätt som du testade dina övriga subrutiner innan du lade in dessa i huvudprogrammet! 9.1 Blinkande lysdiod Istället för att lysdioden lyser med fast sken när larmet är aktiverat så ska lysdioden blinka med en ungefärlig frekvens på 1 Hz. 9.2 Tidsbegränsad öppning När du avaktiverat larmet så ska larmet aktiveras igen efter cirka fem sekunder. Så snart en knapp (förutom A) trycks ner så nollställs denna tidsfördröjning. 9.3 Möjlighet att byta kod Det ska vara möjligt att byta kod på låset genom att trycka in den nya koden två gånger i rad och sedan trycker du på tangenten C på hextangentbordet. Om samma kod trycktes in två gånger i rad så ska larmet aktiveras och koden bytas. Om inte så ska ingenting hända. Detta ska enbart vara möjligt att göra när larmet är avaktiverat. 9.4 Bättre felmeddelanden till terminalen När textsträngen Felaktig kod! skrivs ut på terminalen så ska du också skriva ut antalet gånger som felaktid kod skrivits in. (Räknaren nollställs när rätt kod skrivs in.) Du behöver kunna hålla ordning på max 63 felaktiga försök. (Men det gör inget om du håller ordning på fler.) Antalet felaktiga försök ska skrivas ut decimalt! 1 Detta för att du lätt ska kunna byta till en annan variant på laborationen om det visar sig att koden för den första varianten du provat är helt fel. 11
10 Tips på hur du testkör subrutiner i förväg För att testköra delar av ditt program i förväg så kan du logga in på ett av tolv labsystem även när det inte är ett labtillfälle. Detta gör du genom att logga in på datorn tutor.edu.isy.liu.se via ssh. OBS: Om du inte sitter inloggad på en av ISY:s datorer måste du först logga in på ixtab.edu.isy.liu.se via ssh. Kör du Linux eller Mac så har du troligtvis redan ssh installerat. Kör du Windows så måste du installera en SSH-klient, exempelvis PuTTY för att kunna komma in på ixtab.edu.isy.liu.se. Se http://www.da.isy.liu.se/courses/tsea28/ tutor-pm.pdf för mer information om vissa specialkommandon för Tutorsystemet. Här nedan följer ett exempel på hur jag testar en subrutin som är tänkt att sätta den korrekta koden till 6510. Eftersom jag inte har en korsassembler här så måste jag själv hålla ordning på var subrutiner börjar och slutar. För att göra det lättare för mig att hålla ordning på detta så låter jag subrutinen börja på en jämn adress ($1100). Huvudprogrammet börjar med att sätta upp stackpekaren. Sedan anropas subrutinen och slutligen så avslutar jag programmet genom att starta en oändlig loop. För att förhindra att programmet verkligen hänger sig här så sätter jag en breakpoint på denna rad med kommandot BR. Det finns även andra sätt att avsluta ett program på TUTOR-systemet. För mer information om tutorsystemet, se häftet TUTOR MC68008 system och assembler. ixtab:~> ssh tutor.edu.isy.liu.se Password: TUTOR 1.3 > MM 1000;DI 001000 4845 SWAP.W D5? MOVE.l #$7000,A7 001006 484F DC.W $484F? JSR $1100 00100A 454A DC.W $454A? BRA * 00100C 454B DC.W $454B?. TUTOR 1.3 > MM 1100;DI 001100 0000002C OR.B #44,D0? MOVE.L #$06050100,D6 001106 000000F1 OR.B #241,D0? MOVE.L D6,$4010 00110A 00EB DC.W $00EB? RTS 00110C 00940000003F OR.L #63,(A4)?. TUTOR 1.3 > BR 100A BREAKPOINTS 00100A 00100A TUTOR 1.3 > GO 1000 PHYSICAL ADDRESS=00001000 AT BREAKPOINT PC=0000100A SR=2700=.S7.. US=FFFFFFFF SS=00007000 D0=000004D2 D1=00000929 D2=00000D80 D3=000011D7 D4=00147B89 D5=0001F55B D6=06050100 D7=0002DCFF A0=000001F4 A1=000004D2 A2=00001A62 A3=00014F05 A4=006897B0 A5=050D4839 A6=000A759B A7=00007000 --------------------00100A 60FE BRA.S $00100A TUTOR 1.3 > MD 4010 004010 06 05 01 00 44 FF 00 9B C9 FF 00 FF 20 FF 00 86.DI TUTOR 1.3 > Exit from TUTOR-server. Welcome back! Notera att det är ett mellanslag mellan frågetecknet och assemblerkommandot som jag skriver in. Utan det kommer Tutor att skriva ut X? på skärmen och du får en ny chans att skriva in något på den raden. 12
Vi har fått in några rapporter om att backspace/delete-knappen fungerar dåligt på vissa system. Om så är fallet för dig kan du istället använda ctrl-h för att radera ett tecken. 11 ASCII-tabell $00 NUL \0 $20 SPACE $40 @ $60 $01 SOH (start of heading) $21! $41 A $61 a $02 STX (start of text) $22 $42 B $62 b $03 ETX (end of text) $23 # $43 C $63 c $04 EOT (end of transmission) $24 $ $44 D $64 d $05 ENQ (enquiry) $25 % $45 E $65 e $06 ACK (acknowledge) $26 & $46 F $66 f $07 BEL \a (bell) $27 $47 G $67 g $08 BS \b (backspace) $28 ( $48 H $68 h $09 HT \t (horizontal tab) $29 ) $49 I $69 i $0A LF \n (new line) $2A * $4A J $6A j $0B VT \v (vertical tab) $2B + $4B K $6B k $0C FF \f (form feed) $2C, $4C L $6C l $0D CR \r (carriage ret) $2D - $4D M $6D m $0E SO (shift out) $2E. $4E N $6E n $0F SI (shift in) $2F / $4F O $6F o $10 DLE (data link escape) $30 0 $50 P $70 p $11 DC1 (device control 1) $31 1 $51 Q $71 q $12 DC2 (device control 2) $32 2 $52 R $72 r $13 DC3 (device control 3) $33 3 $53 S $73 s $14 DC4 (device control 4) $34 4 $54 T $74 t $15 NAK (negative ack.) $35 5 $55 U $75 u $16 SYN (synchronous idle) $36 6 $56 V $76 v $17 ETB (end of trans. blk) $37 7 $57 W $77 w $18 CAN (cancel) $38 8 $58 X $78 x $19 EM (end of medium) $39 9 $59 Y $79 y $1A SUB (substitute) $3A : $5A Z $7A z $1B ESC (escape) $3B ; $5B [ $7B { $1C FS (file separator) $3C < $5C $7C $1D GS (group separator) $3D = $5D ] $7D } $1E RS (record separator) $3E > $5E ˆ $7E $1F US (unit separator) $3F? $5F $7F DEL Kommentarer: Den första kolumnen innehåller diverse kontrolltecken där de viktigaste tecknena är $0A (nyrad) och $0D (förflyttning av markören till början av raden). 13
12 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 10-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 instal- lerad, 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 utvecklingsdator, 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. lab1.s. Assemblera filen pingpong.s med kommandot assemble.sh lab1.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 $1000. Reslutatet kan beskådas i en listfil där talet $1000 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 1 LOOP CMP.B #$0D,(A2)+ * Kommentar 2 BNE LOOP MOVE.B #228,D7 TRAP #14 TABS DC.B Provstrang DC.B $0D END 14
Revisioner 1.5 Lade till information om strobe, tips om trace och printchar, samt att man bör läsa i kapitel 4 om PIAA/PIAB. 1.6 Tog bort krav på att använda LSL i addkey. Förtydligade att antalet felaktiga försök i en av extrauppgifterna ska skrivas ut decimalt. 15