A paint program (made in Senbir)

SenbirPaint.gif Not the MOST exciting thing to post about (everyone's used paint programs by now!), but it IS a paint program made for running on Senbir's Extended mode computer.

For those curious to give it a try in-game, the code: //==PAINT== //WASD to navigate. Spacebar toggles if you're painting or not. Use E and Q to shift forwards and backwards through the list of colors, respectively. //This version was made for EXTENDED MODE, with its 16x8 resolution, and 4-color capability. //=REGISTER USAGE= //REGISTER 00: BRUSH DOWN? //REGISTER 01->2: KEY PRESS THIS TICK //REGISTER 03: USED FOR IFJMPS //REGISTER 04: BRUSH X //REGISTER 05: BRUSH Y //REGISTER 06: BACKGROUND COLOR REGISTER (USED IF BRUSH IS NOT DOWN) //REGISTER 07: BRUSH COLOR REGISTER (USED IF BRUSH IS DOWN) //REGISTER 08: TEMPORARY MODIFICATION REGISTER //REGISTER 12: INT 16 //REGISTER 13: INT 8 //REGISTER 14: INT 4 //REGISTER 15: INT 1 SET 15 3 00000001 //Set register 15 to the integer 01. Addr0. SET 14 3 00000100 //Set register 14 to the integer 04. Addr1. SET 13 3 00001000 //Set register 13 to the integer 08. Addr1. Yes, I know, there's a duplicate. SET 12 3 00010000 //Set register 12 to the integer 16. Addr2. SET 6 0 00000000 //Set register 6 to have the appropriate color. Addr3. SET 7 0 01000000 //Set register 7 to have the appropriate color - white. Addr4. GETDATA 2 3 0 //Get the last keyboard input. Addr5. PMOV 1 2 0 31 0 0 //Move the last keyboard input into register 2. Addr6. IFJMP 0 15 1 //If a key was pressed, jump to the input subroutine. Addr7. JMP 2 3 //Otherwise, do nothing. Addr8. PMOV 9 2 0 31 0 0 //Put the "brush down" variable in so IFJMP'll accept it. Addr9. IFJMP 0 2 0 //Jump to the background restore if the brush isn't down. Addr10. JMP 0 2 //Otherwise, jump past it. Addr11. SETDATA 0 3 6 //Wipe the old one. Addr12. PMOV 4 7 28 31 6 1 //Splice the last 4 bits of the X register (the actual x position) into the rendering register, offset +6 (<28>XXXX -> CCXXXX<26>). Addr13. PMOV 5 7 29 31 9 1 //Splice the last 3 bits of the Y register (the actual y position) into the rendering register, offset +9 (<29>YYY -> CCXXXXYYY<23>). Addr14. PMOV 7 8 0 31 30 1 //Addr15. GETDATA 0 3 8 //Get the monitor data. Addr16. MATH 1 6 5 //Paste the color in. Addr17. JMP 0 1 //Addr18. JMP 0 1 //Addr19. SETDATA 0 3 7 //Render the brush. Addr20. JMP 2 16 //Jump back to the start of the loop. Addr21. SET 0 0 01011101 //START OF INPUT SUBROUTINE. Set Register 0 to the key ID for W. Addr22. SET 0 1 11000000 //Set Register 0 to the key ID for W. Addr23. GETDATA 2 3 0 //Check the W. Addr24. MATH 1 2 5 //Move the result of GetData in. Addr25. IFJMP 0 34 1 //If W IS pressed, jump to the appropriate memory position. Addr26. SET 0 0 01011000 //Set Register 0 to the key ID for A. Addr27. SET 0 1 01000000 //Set Register 0 to the key ID for A. Addr28. GETDATA 2 3 0 //Check the A. Addr29. MATH 1 2 5 //Move the result of GetData in. Addr30. IFJMP 0 32 1 //If A IS pressed, jump to the appropriate memory position. Addr31. SET 0 0 01011100 //Set Register 0 to the key ID for S. Addr32. SET 0 1 11000000 //Set Register 0 to the key ID for S. Addr33. GETDATA 2 3 0 //Check the S. Addr34. MATH 1 2 5 //Move the result of GetData in. Addr35. IFJMP 0 30 1 //If S IS pressed, jump to the appropriate memory position. Addr36. SET 0 0 01011001 //Set Register 0 to the key ID for D. Addr37. SET 0 1 00000000 //Set Register 0 to the key ID for D. Addr38. GETDATA 2 3 0 //Check the D. Addr39. MATH 1 2 5 //Move the result of GetData in. Addr40. IFJMP 0 28 1 //If D IS pressed, jump to the appropriate memory position. Addr41. SET 0 0 01001000 //Set Register 0 to the key ID for SPACEBAR. Addr42. SET 0 1 00000000 //Set Register 0 to the key ID for SPACEBAR. Addr43. GETDATA 2 3 0 //Check the SPACEBAR. Addr44. MATH 1 2 5 //Move the result of GetData in. Addr45. IFJMP 0 26 1 //If SPACEBAR IS pressed, jump to the appropriate memory position. Addr46. SET 0 0 01011100 //Set Register 0 to the key ID for Q. Addr47. SET 0 1 01000000 //Set Register 0 to the key ID for Q. Addr48. GETDATA 2 3 0 //Check the Q. Addr49. MATH 1 2 5 //Move the result of GetData in. Addr50. IFJMP 0 28 1 //If Q IS pressed, jump to the appropriate memory position. Addr51. SET 0 0 01011001 //Set Register 0 to the key ID for E. Addr52. SET 0 1 01000000 //Set Register 0 to the key ID for E. Addr53. GETDATA 2 3 0 //Check the E. Addr54. MATH 1 2 5 //Move the result of GetData in. Addr55. IFJMP 0 33 1 //If E IS pressed, jump to the appropriate memory position. Addr56. SET 0 0 00000000 //Unset 0. Addr57. SET 0 1 00000000 //Unset 0. Addr58. JMP 2 50 //Jump back to the render loop. Addr59. MATH 15 5 1 //W WAS PRESSED. Increment Y down by one. Addr60. MATH 13 5 4 //Modulo Y just in case. Addr61. JMP 2 5 //Jump back to the render loop. Addr62. MATH 15 4 1 //A WAS PRESSED. Increment X down by one. Addr63. MATH 12 4 4 //Modulo Y just in case. Addr64. JMP 2 3 //Jump back to the render loop. Addr65. MATH 15 5 0 //S WAS PRESSED. Increment Y up by one. Addr66. MATH 13 5 4 //Modulo Y just in case. Addr67. JMP 2 3 //Jump back to the render loop. Addr68. MATH 15 4 0 //D WAS PRESSED. Increment X up by one. Addr69. MATH 12 4 4 //Modulo Y just in case. Addr70. JMP 2 3 //Jump back to the render loop. Addr71. MATH 9 2 5 //Move the contents of Address 9 (the brush toggle) into 2 for IFJMP use. Addr72. IFJMP 0 2 0 //Is the brush up? Addr73. JMP 0 3 //Nope. Addr74. SET 9 3 00000001 //Turn the brush on. Addr75. JMP 0 2 //Skip past turning it off. Addr76. SET 9 3 00000000 //Turn the brush off. Addr77. JMP 2 7 //Jump back to the render loop. Addr78. SET 8 0 00000000 //Addr79. SET 8 1 00000000 //Addr80. SET 8 2 00000000 //Addr81. SET 8 3 00000000 //Addr82. MATH 7 8 5 //Splice the color in. Addr83. PMOV 7 8 0 1 30 1 //THING. Addr84. MATH 15 8 1 //Q WAS PRESSED. Increment COL down by one. Addr85. MATH 14 8 4 //Modulo COL just in case. Addr86. PMOV 8 7 28 31 30 0 //Splice it back into the renderer. Addr87. JMP 2 10 //Jump back to the render loop. Addr88. SET 8 0 00000000 //Addr89. SET 8 1 00000000 //Addr90. SET 8 2 00000000 //Addr91. SET 8 3 00000000 //Addr92. MATH 7 8 5 //Splice the color in. Addr93. PMOV 7 8 0 1 30 1 //THING. Addr94. MATH 15 8 0 //E WAS PRESSED. Increment COL up by one. Addr95. MATH 14 8 4 //Modulo COL just in case. Addr96. PMOV 8 7 28 31 30 0 //Splice it back into the renderer. Addr97. JMP 2 10 //Jump back to the render loop. Addr98.

I also have a Custom preset & updated version that're better for pixel art-ing up in a thread on Itch.IO: https://itch.io/t/279217/code-sharing-megathread

If you want to see what Senbir's VM is capable of without having to muck around in the code yourself, this is a good way to do it.

You can compile it straight to the computer's ROM once you've pasted it into the Assembler window. Turn the computer on, activate the keyboard (look at it and press F), and then use WASD to move the paint cursor around, spacebar to toggle drawing, and Q/E to cycle colors.