Spring 2010 Prof. Hyesoon Kim• DevKit Pro is a collection of tool chain for homebrew applications developers for various architectures • DevKitARM: ARM binaries • Not official development tool chain – Much simpler and naïve• libnds– Started with header files for definition – Extended to have other data structures, simple APIs• *.nds– A binary for Nintendo DS, a separate region for ARM7 and ARM9 http://patater.com/files/projects/manual/manual.html#id2612503int main(void) {consoleDemoInit(); //Initialize the consoleirqSet(IRQ_VBLANK, Vblank); //this line says: When the IRQ_VBLANK interrupt occurs execute function Vblankiprintf(" Hello DS dev'rs\n");while(1) {iprintf("\x1b[10;0HFrame = %d",frame); //print out the current frame numberswiWaitForVBlank(); //This line basically pauses the while loop and makes it //wait for the IRQ_VBLANK interrupt to occur. This way, we print only once //per frame.}return 0;}• 2 screens, 2 GPUs, only bottom has a touch screen • A screen mode where the screen is mapped to a portion of memory• Writing data to this memory area will result in data appearing on the screen • Each screen’s pixel is represented by 2 B. • Represented with 555 format • 0123 4567 0123 4567-rrr rr-- ---- ---- (bitmask: 0x7C00) ---- --gg ggg- ---- (bitmask: 0x3E0) ---- ---- --b bbbb (bitmask: 0x1F)• But a simple macro RGB15 ColorRGB15(31,0,0) Red RGB15(0,31,0) Green RGB15(0,0,31) Blue RGB15(0,0,0) Black RGB15(31,31,31) WhiteEvery 1/60thseconds, the hardware redraws. Visiting each pixel row by row, copying the contents of the framebufferfor that pixel to the hardware screen pixelVertical blank interrupt: when it finishes drawing the screenInterrupt Drawing Updating• ARM assembly code – Build a simple counter– A key increment a counter – B key decrement a counter– Start: reset to zero– Up arrow +10– Down arrow -10 – No need to use interrupt, use a polling method• Instead of pure assembly coding, we will use inline assembly programming • Not only ARM, x86 etc. • Good place to look at http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3http://www.ethernut.de/en/documents/arm-inline-asm.htmlNOP asm( "mov r0, r0\n\t" "mov r0, r0\n\t" "mov r0, r0\n\t" "mov r0, r0" );Use deliminaters Linefeed or tab to differentitate assembly lines http://www.ethernut.de/en/documents/arm-inline-asm.htmlasm(code : output operand list : /* optional*/ input operand list : /* optional*/ clobber list /* optional*/ );/* Rotating bits example */asm("mov %[result], %[value], ror #1" : [result] "=r" (y) :[value] "r" (x));Symbolic name encoded in square brackets followed by a constraint string, followed by a C expression enclosed in parenthesese.g.) sets the current program status register of the ARM CPUasm("msr cpsr,%[ps]" :: [ps]"r"(status));• Some instructions clobber some hardware registers. • We have to list those registers in the clobber-list • Shouldn’t list input & output (already given)nt main(void) {//---------------------------------------------------------------------------------consoleDemoInit();int* notGood= (int *)0xb0; //bad*notGood= 10;int better=20;irqSet(IRQ_VBLANK, Vblank);printf(" Hello CS4803DGC");// case 1 asm("MOV R1, #0xb0"); //init R1 to addressasm("LDR R0, [R1]");asm("ADD R0, R0, R0"); asm("STR R0, [R1]");// case 2 asm ("MOV R1, %[value]"::[value]"r"(better));asm ("ADD R1, R1, R1");asm ("MOV %[result], R1":[result]"=r"(better):);while(1) {swiWaitForVBlank();// print at using ansi escape sequence \x1b[line;columnHprintf("\x1b[10;0HFrame = %d",frame);printf ("\nblah is: %d, %d", *notGood, better);}return 0;}Please note that this code does not correctly!• Button, touch screen, microphone • Libnds key definition KEY_A1 << 0A ButtonKEY_B1 << 1B ButtonKEY_SELECT1 << 2Select ButtonKEY_START1 << 3Start ButtonKEY_RIGHT1 << 4Right D-padKEY_LEFT1 << 5Left D-padKEY_UP1 << 6Up D-padKEY_DOWN1 << 7Down D-padKEY_R1 << 8R ButtonKEY_L1 << 9L ButtonKEY_X1 << 10X ButtonKEY_Y1 << 11Y ButtonKEY_TOUCH1 << 12Pen Touching Screen (no coordinates)KEY_LID1 << 13Lid shutting (useful for sleeping)0x4000130• The current status of the keys is stored in memory at address 0x4000130. • When no key is pressed- the value is 1023. • A key press causes a change in the value at this location. The new value depends on which key is pressed. • Here are the values for various keys. A- #1022 b 11 1111 1110B- #1021 b 11 1111 1101start- #1015 b 11 1111 1011 UP- #959 b 11 1011 1111 DOWN- #895 b 11 0111 1111asm ("MOV R4, #0x0000"); //R4 has the counter.. funny things happening with R1while(1) {swiWaitForVBlank();//init R4 to addressasm ("MOV R0, #0x4000000"); //R0 has the addressasm ("ADD R0, #0x130"); // finished moving address//load value from that addressasm ("LDR R2, [R0]");// check the register value of R2 and compare and then increment the counter // use condition code or shift etc. //move counter value from R2 to C variableasm ("MOV %[result], R2":[result]"=r"(result_):);• Compiler still rearranges the assembly code. • Use ASM volatile (“ “) to prevent compiler’s optimizations • Default compilation mode is ARM-thumb • The makefile has to be modified- set it to no optimization by -O0• change line ARCH := -mthumb –mthumb-interwork TO ARCH := -marm• N: Negative (the last ALU operation)• Z: zero (the last ALU operation)• C: carry (the last ALU or from shifter) • V: overflow N Z C V unused IF T mode31 28 27 8 7 6 5 4 0COND31 28Steve Furber, ARM system-on-chip architecture 2ndeditionSteve Furber, ARM system-on-chip architecture
View Full Document