.GLOBAL _start @ exports the start lable for linking @note: r1,r5,r6,r8,r9 shall be used as temp. don't rely on its value between calls. @note: r4 = draw key. set/no _start: @ start of the code. mov r0, #0x4000000 @ Display control ldr r1, =0x0000403 @ store requested vid mode strh r1, [r0] @ set it to background 2, mode 3 mov r0, #0x06000000 @ set video ram address @ldr r1, =0x0fff @ make a color @adr r2, Color @ copy address of Color into r2 @str r1, [r2] @ store r1 into color. add r7, r0, #0x130 @ add keys control reg. offset. R7 contains address to key states, r0 contains control reg base. mainloop: @ a label for the branch bl vblank @ wait for a vertical blank (so it only draws on frames. otherwise too fast.) bl GetInput @ branch off to a routine to get key information. @strh r1, [r0] @ put single pixel of above in vid ram @mov r2, #0x02 @ put 2 to increase the vram by @strh r1, [r0, r2] @ put the r1 pixel in [r0 + r2] b mainloop @ do the shit over and over. vblank: @ wait for a vertical blank mov r1, #0x4000000 @ control register base add r1, r1, #0x4 @ display status register vblankloop: @ start here for vblank loop. ldr r5, [r1] @ get contents of status reg. and r5, r5, #0x1 @ single out first bit cmp r5, #0x1 @ is bit 1 set? bne vblankloop @ loop until the bit's set. mov pc, lr @ Only executes when set. return to prev. location PaintScreen: @ whoo.. function to fill video ram with a color. mov r3, #0 @ 0 out r3 for addition and stuff. ldr r8, Color @ color is a label.. aka address. ldr loads the contents of the address. (the address of ColorData) ldrh r5, [r8] @ Get the contents of ColorData (the actual color) ldr r6, =0x12C00 @ end of display ram. PaintMain: @ loop point. strh r5, [r0,r3] @ copy pixel to video RAM at offset r3 add r3, r3, #2 @ increment r3 by 2 cmp r3, r6 @ end of display. beq PaintEnd @ when it's equal, it's done, this'll execute b PaintMain @ This will execute while the above is not equal... looping until it's done. PaintEnd: @ End of painting. Only gets here when done with display. mov pc, r14 @ When it's equal, it's done, and this'll execute. @from mappy sdk docs. @Offset Name Type F E D C B A 9 8 7 6 5 4 3 2 1 0 @$130 KEYS R/W L Shoulder Released R Shoulder Released Down Released Up Released Left Released Right Released Start Released Select Released B Released A Released GetInput: @ it'll get key input and interpret it. mov r9, #0x4000000 @ base control registers add r9, r9, #0x130 @ add keys control reg. offset. R7 contains address to key states, r0 contains control reg base. ldr r9, [r9] @ load the key settings into r9 mov r0, #0x01 @ common number... I can't use constant, only register. mov r8, r9 @ copy contents of r9 to r8.. I believe r8 is faster (lower number.) and r8, r8, r0 @ mask out all but bit 1. It will remain one unless pressed. cmp r8, r0 @ compare. If equal, then a is released. It'll be the only non-zero value. beq AUp @ Branches if it's equal (everything's 0, key's up) bne ADown @ Branch if A is 0, not equal, aka is down. branch someplace else. Makes this part of the code look nicer. AReturn: @ someplace to return to after the routine is done. mov r8, r9 @ copy contents of r9 to r8.. restore original. it was modified above. and r8, r8, r0, lsl #1 @ mask out all but bit 2. It will remain one unless pressed. cmp r8, r0, lsl #1 @ compare. If equal, then b is released. It'll be the only non-zero value. bne BDown @ branch to propper code. BReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #2 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #2 @ compare. If equal, then key is released. It'll be the only non-zero value. bne SelectDown @ branch to propper code. SelectReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #3 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #3 @ compare. If equal, then key is released. It'll be the only non-zero value. bne StartDown @ branch to propper code. StartReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #4 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #4 @ compare. If equal, then key is released. It'll be the only non-zero value. bne RightDown @ branch to propper code. RightReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #5 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #5 @ compare. If equal, then key is released. It'll be the only non-zero value. bne LeftDown @ branch to propper code. LeftReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #6 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #6 @ compare. If equal, then key is released. It'll be the only non-zero value. bne UpDown @ branch to propper code. UpReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #7 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #7 @ compare. If equal, then key is released. It'll be the only non-zero value. bne DownDown @ branch to propper code. DownReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #8 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #8 @ compare. If equal, then key is released. It'll be the only non-zero value. bne RDown @ branch to propper code. RReturn: @ someplace to return to after the routine is done. mov r8, r9 @ restore original. it was modified above. and r8, r8, r0, lsl #9 @ mask out all but desired bit. It will remain one unless pressed. cmp r8, r0, lsl #9 @ compare. If equal, then key is released. It'll be the only non-zero value. bne LDown @ branch to propper code. LReturn: @ someplace to return to after the routine is done. mov r0, #0x6000000 @ I destroyed the contents. Restore it. mov pc, r14 @ Returns after executing code for all keys. ADown: @shall print color to vid ram orr r4, r4, #0x1 @ set bit 1 - draw. b AReturn @ Return to process any more input. AUp: bic r4, r4, #0x1 @ bit clear bit 1 (draw set) b AReturn @ Return. Don't worry about catching the down in the input loop, because if it's up it can't be down. BDown: @shall change color adr r5, Pallette @ get address of pallette. ldr r6, ColorCounter @ Get address of Counter ldrb r1, [r6] @ Get contents of counter (one byte) add r1, r1, #0x1 @ increment color counter. remember r0 contains 1 from above. cmp r1, #0x8 @ compare to 8.. movhi r1, #0x0 @ reset to 0 if greater than 8 (past end of pallette) strh r1, [r6] @ save counter mov r2, #0x2 @ set multiple mul r1, r1, r2 @ multiply by 2 to get pallette offset ldrh r2, [r1,r5] @ load half-word. offset in pallette + pallette address. ldr r5, Color @ Get the contents of Color (address of ColorData) strh r2, [r5] @ Store color in variable. mov r1, LR @ I wish to preserve the return register so I can go back to input loop. mov r0, #0x6000000 @ vRam base... it was set to 1 above bl PaintScreen @ paint the screen a color. bl so it passes the next address for a return address. mov r0, #1 @ reset to 1. mov LR, r1 @ Reset return register to it'll work propperly. b BReturn @ Return to process any more input. SelectDown: b SelectReturn @ Return to process any more input. StartDown: b StartReturn @ Return to process any more input. RightDown: @direction of cursor and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bic r4, r4, #0x1e @ clear bits 2-5. Reset any previous drawing. orr r4, r4, #0x10 @ set bit to moving right. mov r3, r14 @ Store return address to input routine blne SkipDraw @ if not set, go elsewhere. and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bleq ColorDraw @ don't draw the color. eq so when above returns it won't execute. mov r14, r3 @ reset to propper value b RightReturn @ Return to process any more input. LeftDown: and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bic r4, r4, #0x1e @ clear bits 2-5. Reset any previous drawing. orr r4, r4, #0x8 @ set bit to moving left. mov r3, r14 @ Store return address to input routine blne SkipDraw @ if not set, go elsewhere. and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bleq ColorDraw @ don't draw the color. eq so when above returns it won't execute. mov r14, r3 @ reset to propper value b LeftReturn @ Return to process any more input. UpDown: and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bic r4, r4, #0x1e @ clear bits 2-5. Reset any previous drawing. orr r4, r4, #0x2 @ set bit to moving up. mov r3, r14 @ Store return address to input routine blne SkipDraw @ if not set, go elsewhere. and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bleq ColorDraw @ don't draw the color. eq so when above returns it won't execute. mov r14, r3 @ reset to propper value. the end. Reset no matter what. b UpReturn @ Return to process any more input. DownDown: and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bic r4, r4, #0x1e @ clear bits 2-5. Reset any previous drawing. orr r4, r4, #0x4 @ set bit to moving down. mov r3, r14 @ Store return address to input routine blne SkipDraw @ if not set, go elsewhere. and r5, r4, #0x1 @ get draw bit cmp r5, #0x1 @ compare to 1 (bit set) ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X bleq ColorDraw @ don't draw the color. eq so when above returns it won't execute. mov r14, r3 @ reset to propper value b DownReturn @ Return to process any more input. RDown: LDown: b LReturn @ Return to process any more input. @Draw cursor section. @ r4 contains settings: @ bit1: whether or not to draw the color, or reset the pixel to background color. @ bit2: moving up @ bit3: moving down @ bit4: moving left @ bit5: moving right ColorDraw: @place draw color pixel. mov r8, #0xf0 @ temp for multiple (width of screen) mul r5, r5, r8 @ Width of screen * y = offset in vid ram add r5, r5, r6 @ y offset + x offset = position for cursor mov r8, #0x2 @ 2 bytes for vid ram.. set multiple mul r5, r5, r8 @ and multiply. (2 bytes for every color, it's twice the #.) add r5, r5, #0x6000000 @ add video ram base... ldr r6, =0xfff @ Set draw color strh r6, [r5] @ Put color in vid ram. @modified them. Reset. ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X b GetDirection @ figure out what way to go SkipDraw: @Don't draw a colored pixel. Reset to background color. mov r8, #0xf0 @ temp for multiple (width of screen) mul r5, r5, r8 @ Width of screen * y = offset in vid ram add r5, r5, r6 @ y offset + x offset = position for cursor mov r8, #0x2 @ 2 bytes for vid ram.. set multiple mul r5, r5, r8 @ and multiply. (2 bytes for every color, it's twice the #.) add r5, r5, #0x6000000 @ add video ram base... ldr r6, Color @ Get address of the color ldrh r6, [r6] @ Get the color. Same as background strh r6, [r5] @ store address in vid ram. @modified them. Reset. ldr r6, CursorY @ Get cursor Y pointer ldrb r5, [r6] @ Get contents of cursor Y ldr r6, CursorX @ Get pointer to current x variable ldrb r6, [r6] @ get value of current X GetDirection: @Determine the direction to move the drawing. mov r8, r4 @ temp copy. and r8, r8, #0x1e @ mask out all but direction bits. cmp r8, #0x4 @ test bit 3 beq CursorDown @ if equal, bit 3 set, down. blo CursorUp @ if lower. Only one lower is colors up. cmp r8, #0x8 @ test bit 4.... beq CursorLeft @ if equal, bit 4 = left bhi CursorRight @ only higher is right. CursorDown: cmp r5, #0xA0 @ is it bottom of the screen? addne r5, r5, #0x1 @ if not, increment (Y becomes greater, closer to bottom). else, do nothing. b DrawCursor @ draw the cursor. CursorUp: cmp r5, #0x0 @ is it top of the screen? subne r5, r5, #0x1 @ if not, decrement (Y becomes less, closer to top). else, do nothing. b DrawCursor @ draw the cursor. CursorLeft: cmp r6, #0x0 @ is it left of screen? subne r6, r6, #0x1 @ if not, decrement. If so, do nothing. b DrawCursor @ draw the cursor. CursorRight: cmp r6, #0xF0 @ is it right of screen? addne r6, r6, #0x1 @ if yes, do nothing.. else, increment. b DrawCursor @ draw the cursor. DrawCursor: ldr r8, CursorY @ Get cursor Y pointer strb r5, [r8] @ store contents of cursor Y ldr r8, CursorX @ Get pointer to current x variable strb r6, [r8] @ store value of current X mov r8, #0xf0 @ temp for multiple (width of screen) mul r5, r5, r8 @ Width of screen * y = offset in vid ram add r5, r5, r6 @ y offset + x offset = position for cursor mov r8, #0x2 @ 2 bytes for vid ram.. set multiple mul r5, r5, r8 @ and multiply. (2 bytes for every color, it's twice the #.) add r5, r5, #0x6000000 @ add video ram base... mov r6, #0x0 @ r6 now holds black as a color. Used as the cursor. strh r6, [r5] @ and put a black dot for the cursor. mov pc, lr @ copy return address to program counter. aka, return. .pool @ so it can ldr r0,=0x0005 stuff... @ pointers to variables outside the rom section Color: .word ColorData ColorCounter: .word Counter CursorX: .word Cx CursorY: .word Cy @ stores different colors for the background Pallette: .hword 0x0, 0x7fff, 0x18, 0x100, 0x6000, 0x318, 0x6018, 0x6300, 0x6138 @ black white 2red 2grn 2blue 2gr 2br 2bg 2rgb .bss @ Specifies the .bss section ColorData: .hword 0xfff @ Variable Color. 2 bytes. Counter: .byte 0 @ a counter for going through background pallette. goes up to 8. Cx: .byte 0 @ Cursor X and Y Cy: .byte 0