## Laboration 1 ### Givna subrutiner - `printchar` - `inituart` - `initgpioe` - `initgpiof` ### Begränsningar Du får enbart göra en läsning ifrån `0x2000100-0x20001003` och `0x20001010-0x2001013` i `checkcode`. ### Subrutiner att skriva #### printstring Skriver ut den textsträng som r4 pekar på på terminalen med hjälp av `printchar`. ```asm ; inargument: pekare till strängen i r4 ; längd på strängen i r5 ; utargument: inga ; ; funktion: skriver ut strängen mha subrutinen printchar ; ; förstör r0 och r1 printstring: mov r1,#0x00 printstring_print_next: mov r0,[r4,r6] ; indirekt register med register offset push lr bl printchar pop lr add r1,#0x01 ; next char ; have we printed all characters? cmp r5,r1 bne printstring_print_next ; yes, so return bx lr ``` #### deactivatealarm Får lysdioden att lysa grönt. ```asm ; inargument: inga ; utargument: inga ; ; funktion: tänder grön lysdiod (bit 3 = 1, bit 2 = 0, bit 1 = 0) ; ; förstör r0 och r1 deactivatealarm: ; read current data mov r0,#GPIOF_GPIODATA ldr r1,[r0] ; set bit 3 to 1 orr r1,r1,(0x04) ; 0x04 = 0000_0100 ; set bit 2 and 1 to 0 and r1,r1,(0xfc) ; 0xfc = 1111_1100 ; write new data str r1,[r0] bx lr ``` #### activatealarm Får lysdioden att lysa rött. ```asm ; inargument: inga ; utargument: inga ; ; funktion: tänder röd lysdiod (bit 3 = 0, bit 2 = 0, bit 1 = 1) ; ; förstör r0 och r1 activatealarm: ; read current data mov r0,#GPIOF_GPIODATA ldr r1,[r0] ; set bit 1 to 1 orr r1,r1,(0x01) ; 0x01 = 0000_0001 ; set bit 3 and 2 to 0 and r1,r1,(0xf9) ; 0xf9 = 1111_1001 ; write new data str r1,[r0] bx lr ``` #### getkey Vänta på att användaren trycker på en tangent. Se till att returnera först när användaren slutar trycka på tangenten. ```asm ; inargument: inga ; utargument: tryckt knapp i r4 ; ; förstör r0, r1 getkey: mov r0,#GPIOE_GPIODATA ; wait for strobe getkey_strobe_check: ldr r1,[r0] mov r4,r1 ands r1,r1,#0x10 ; 0x10 = 0001_0000 bne getkey_strobe_check ; strobe is high, so put char in r4 ands r4,r4,#0x0f ; 0x0f = 0000_1111 bx lr ``` #### addkey Lägg till ett tecken i inbuffern genom att skifta buffern framåt ett steg. Exempel: ``` Adress Ursprungstillstånd Efter att addkey anropats med 1 i r4 0x20001000 0x05 0x01 0x20001001 0x06 0x05 0x20001002 0xFF 0x06 0x20001003 0xFF 0xFF ``` ```asm ; inargument: vald tangent i r4 ; utargument: inga ; ; funktion: flyttar innehållet på 0x20001000-0x20001002 framåt en byte ; till 0x20001001-0x20001003. ; lagrar sedan innehållet i r4 på 0x20001000 ; ; förstör r0 addkey: ; ..02 -> ..03 ldrb r0,#0x20001002 strb r0,#0x20001003 ; ..01 -> ..02 ldrb r0,#0x20001001 strb r0,#0x20001002 ; ..00 -> ..01 ldrb r0,#0x20001000 strb r0,#0x20001001 ; r4 -> ..00 strb r4,#0x20001000 bx lr ``` #### clearinput Rensar inbuffern genom att lägga in en ogiltig kod. ```asm ; inargument: inga ; utargument: inga ; ; funktion: sätter innehållet på 0x20001000-0x20001003 till 0xFF ; ; förstör r0 clearinput: mov r0,#0xff strb r0,#0x20001000 strb r0,#0x20001001 strb r0,#0x20001002 strb r0,#0x20001003 bx lr ``` #### checkcode Kollar om den kod som ligger i inbuffern på 0x20001000 är korrekt. ```asm CODE_LENGTH .equ 0x04 ; inargument: inga ; utargument: returnerar 1 i r4 om koden var korrekt, ; annars 0 i r4 ; ; funktion: tänder grön lysdiod (bit 3 = 1, bit 2 = 0, bit 1 = 0) ; ; förstör r0, r1 och r2 checkcode: mov r0,#0x00 ; index mov r1,#0x20001000 ; to check mov r2,#0x20001010 ; key checkcode_next: ; check length cmp r0,#CODE_LENGTH beq checkcode_correct ; compare next byte cmp [r1,r0],[r2,r0] beq checkcode_next ; equal, check next b checkcode_incorrect ; not equal, so incorrect checkcode_incorrect: mov r4,#0x00 b checkcode_exit checkcode_correct: mov r4,#0x01 b checkcode_exit checkcode_exit: bx lr ```