Spring 2011 Prof. Hyesoon Kim• 2ndpart of programming platform• Programming with Nintendo DS • http://www.cc.gatech.edu/~hyesoon/spr11/lab4.html• Installation Guide and Hello worldhttp://www.cosc.brocku.ca/Offerings/3P92/seminars/nintendo_ds_slideshow.pdf• Dual TFT LCD screens • CPUs – ARM 7 TDMI (33MHz)– ARM 9 946E-S (67MHz)• Main memory: 4MB RAM– VRAM: 656 KB • 2D graphics – Up to 4 backgrounds • 3D graphics• Both can be running code at the same time. • ARM 7 is the only CPU that controls the touch screen. – Interrupt based• 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;}• ARM assembly code – Up: OR operation Down: AND operation start: Reset to default values A: Exclusive OR operation B: AND NOT (BIC) operation Left: left shift by #1 Right: right shift by #1 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 : // opcode , destination, srcoutput 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));ConstraintUsage in ARM stateUsage in Thumb statefFloating point registers f0 .. f7Not availablehNot availableRegisters r8..r15GImmediate floating point constantNot availableHSame a G, but negatedNot availableIImmediate value in data processing instructionse.g. ORR R0, R0, #operand Constant in the range 0 .. 255e.g. SWI operand JIndexing constants -4095 .. 4095e.g. LDR R1, [PC, #operand] Constant in the range -255 .. -1e.g. SUB R0, R0, #operand KSame as I, but invertedSame as I, but shiftedLSame as I, but negatedConstant in the range -7 .. 7e.g. SUB R0, R1, #operand lSame as rRegisters r0..r7e.g. PUSH operand MConstant in the range of 0 .. 32 or a power of 2e.g. MOV R2, R1, ROR #operand Constant that is a multiple of 4 in the range of 0 .. 1020e.g. ADD R0, SP, #operand mAny valid memory addressNNot availableConstant in the range of 0 .. 31e.g. LSL R0, R1, #operand ONot availableConstant that is a multiple of 4 in the range of -508 .. 508e.g. ADD SP, #operand rGeneral register r0 .. r15e.g. SUB operand1, operand2, operand3 Not availablewVector floating point registers s0 .. s31Not availableXAny operandModifierSpecifies= Write-only operand, usually used for all output operands + Read-write operand, must be listed as an output operand & A register that should be used for output only asm("mov %[value], %[value], ror #1" : [value] "+r" (y));Same register value• MOV– MOV{S}{cond} Rd, Operand2 – MOV{cond} Rd, #imm16• MSRLoad an immediate value, or the contents of a general-purpose register, into specified fields of a Program Status Register (PSR)SyntaxMSR{cond} APSR_flags, Rm where:– Cond is an optional condition code.– Flags specifies the APSR flags to be moved. flags can be one or more of:– Nzcvq ALU flags field mask, PSR[31:27] (User mode)– gSIMD GE flags field mask, PSR[19:16] (User mode).– Rm: is the source register. Rm must not be PC.N Z C V unused IF T mode31 28 27 8 7 6 5 4 0• Some instructions clobber some hardware registers. • We have to list those registers in the clobber-listnt 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 run 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/* We have only 8-bit immediate
View Full Document