├── editor.h ├── dlgRunProgram.h ├── save.h ├── .gitattributes ├── ABasm.ino ├── Ardumod.h ├── vm.h ├── .gitignore ├── save.cpp ├── dlgRunProgram.cpp ├── globals.h ├── globals.cpp ├── readme.md ├── Ardumod.cpp ├── vm.cpp ├── data.h └── editor.cpp /editor.h: -------------------------------------------------------------------------------- 1 | #ifndef _EDITOR_H 2 | #define _EDITOR_H 3 | 4 | #include "dlgRunProgram.h" 5 | 6 | void showEditor(); 7 | 8 | #endif -------------------------------------------------------------------------------- /dlgRunProgram.h: -------------------------------------------------------------------------------- 1 | #ifndef _DLG_RUN_PROGRAM_H 2 | #define _DLG_RUN_PROGRAM_H 3 | 4 | bool showRunProgramDialog(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /save.h: -------------------------------------------------------------------------------- 1 | #ifndef _SAVE_H 2 | #define _SAVE_H 3 | 4 | #define PROGRAM_EEPROM_START 768 5 | 6 | void saveProgram(); 7 | void loadProgram(); 8 | 9 | void defaultProgram(); 10 | void emptyProgram(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /ABasm.ino: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "data.h" 3 | #include "vm.h" 4 | 5 | #include "save.h" 6 | 7 | #include "editor.h" 8 | 9 | void setup() 10 | { 11 | arduboy.begin(); 12 | 13 | while(!arduboy.nextFrame()); 14 | updateInput(); 15 | 16 | if(LEFT_DOWN) 17 | { 18 | defaultProgram(); 19 | } 20 | else if(DOWN_DOWN) 21 | { 22 | emptyProgram(); 23 | } 24 | else 25 | { 26 | loadProgram(); 27 | } 28 | } 29 | 30 | void loop() 31 | { 32 | showEditor(); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /Ardumod.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARDUMOD_H 2 | #define _ARDUMOD_H 3 | 4 | #include 5 | 6 | class Ardumod : public Arduboy 7 | { 8 | public: 9 | void invertRect(int16_t x, int16_t y, uint8_t w, uint8_t h); 10 | void drawPixel(int x, int y, uint8_t color); 11 | void grayRect(int16_t x, int16_t y, uint8_t w, uint8_t h); 12 | void fillRect(int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color); 13 | void drawFastVLine(int16_t x, int16_t y, uint8_t h, uint8_t color); 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /vm.h: -------------------------------------------------------------------------------- 1 | #ifndef _VM_H 2 | #define _VM_H 3 | 4 | #define VM_NUM_REGISTERS 8 5 | 6 | #define PROGRAM_CODE_LENGTH 256 7 | 8 | #define VMRUN_RETURN_EXIT 0 9 | #define VMRUN_RETURN_BREAK 1 10 | #define VMRUN_RETURN_KILL 2 11 | #define VMRUN_RETURN_ERROR 3 12 | 13 | struct VMState { 14 | unsigned char registers[8]; 15 | unsigned char pc; 16 | bool skipInstruction; 17 | bool breakpointsEnabled; 18 | }; 19 | 20 | extern unsigned char initCode[PROGRAM_CODE_LENGTH]; 21 | extern unsigned char lineFlags[PROGRAM_CODE_LENGTH/2]; 22 | unsigned char vmRun(VMState* vmPtr); 23 | unsigned char vmReset(VMState* vmPtr, bool breakpointsEnabled); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /save.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "save.h" 3 | 4 | #include "vm.h" 5 | 6 | void saveProgram() 7 | { 8 | short dataIndex; 9 | unsigned char data; 10 | for(dataIndex = 0; dataIndex < PROGRAM_CODE_LENGTH; dataIndex++) 11 | { 12 | data = EEPROM.read(PROGRAM_EEPROM_START + dataIndex); 13 | if(data != initCode[dataIndex]) 14 | { 15 | EEPROM.write(PROGRAM_EEPROM_START + dataIndex, initCode[dataIndex]); 16 | } 17 | } 18 | } 19 | 20 | void loadProgram() 21 | { 22 | short dataIndex; 23 | for(dataIndex = 0; dataIndex < PROGRAM_CODE_LENGTH; dataIndex++) 24 | { 25 | initCode[dataIndex] = EEPROM.read(PROGRAM_EEPROM_START + dataIndex); 26 | } 27 | } 28 | 29 | void defaultProgram() 30 | { 31 | 32 | } 33 | 34 | void emptyProgram() 35 | { 36 | unsigned short dataIndex = 0; 37 | 38 | for(dataIndex = 0; dataIndex < PROGRAM_CODE_LENGTH - 1; dataIndex += 2) 39 | { 40 | initCode[dataIndex] = 0xf0; 41 | initCode[dataIndex+1] = 0x00; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dlgRunProgram.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "data.h" 3 | #include "dlgRunProgram.h" 4 | #include "save.h" 5 | 6 | bool showRunProgramDialog() 7 | { 8 | arduboy.fillRect(18-1, 8-1, 96+2, 48+2, 0); 9 | arduboy.drawBitmap(18, 8, gfx_rundialog, 96, 48, 1); 10 | arduboy.display(); 11 | 12 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 13 | 14 | updateInput(); 15 | 16 | while(true) 17 | { 18 | if(!arduboy.nextFrame()) continue; 19 | 20 | if(B_PRESSED) 21 | { 22 | arduboy.drawBitmap(24, 38, gfx_invertbutton, 28, 11, 2); 23 | arduboy.display(); 24 | 25 | while(true) 26 | { 27 | if(!arduboy.nextFrame()) continue; 28 | 29 | if(B_RELEASED) 30 | { 31 | return false; 32 | } 33 | 34 | updateInput(); 35 | } 36 | } 37 | else if(A_PRESSED) 38 | { 39 | arduboy.drawBitmap(79, 38, gfx_invertbutton, 28, 11, 2); 40 | arduboy.display(); 41 | 42 | while(true) 43 | { 44 | if(!arduboy.nextFrame()) continue; 45 | 46 | if(A_RELEASED) 47 | { 48 | if(!(UP_DOWN || DOWN_DOWN || LEFT_DOWN || RIGHT_DOWN)) 49 | saveProgram(); 50 | return true; 51 | } 52 | updateInput(); 53 | } 54 | } 55 | 56 | updateInput(); 57 | } 58 | } -------------------------------------------------------------------------------- /globals.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBALS_H 2 | #define _GLOBALS_H 3 | 4 | #include "Ardumod.h" 5 | 6 | extern Ardumod arduboy; 7 | 8 | #define A_DOWN new_a 9 | #define A_PRESSED (new_a && !old_a) 10 | #define A_RELEASED (!new_a && old_a) 11 | 12 | #define B_DOWN new_b 13 | #define B_PRESSED (new_b && !old_b) 14 | #define B_RELEASED (!new_b && old_b) 15 | 16 | #define UP_DOWN new_up 17 | #define UP_PRESSED (new_up && !old_up) 18 | #define UP_RELEASED (!new_up && old_up) 19 | 20 | #define DOWN_DOWN new_down 21 | #define DOWN_PRESSED (new_down && !old_down) 22 | #define DOWN_RELEASED (!new_down && old_down) 23 | 24 | #define LEFT_DOWN new_left 25 | #define LEFT_PRESSED (new_left && !old_left) 26 | #define LEFT_RELEASED (!new_left && old_left) 27 | 28 | #define RIGHT_DOWN new_right 29 | #define RIGHT_PRESSED (new_right && !old_right) 30 | #define RIGHT_RELEASED (!new_right && old_right) 31 | 32 | 33 | 34 | #define TONE_MENUBAR_CURSOR 880 35 | #define TONE_MENUBAR_BEEP 1174 36 | #define TONE_MENUBAR_FLIP 990 37 | #define TONE_MENUBAR_SHOW 1174 38 | 39 | extern bool new_a, new_b, new_up, new_left, new_down, new_right; 40 | extern bool old_a, old_b, old_up, old_down, old_left, old_right; 41 | 42 | void updateInput(); 43 | 44 | void printDecimal(unsigned char x, unsigned char y, unsigned char num); 45 | void printHex(unsigned char x, unsigned char y, unsigned char num); 46 | void printHexDigit(unsigned char x, unsigned char y, unsigned char num); 47 | void drawChar(unsigned char x, unsigned char y, unsigned char ch); 48 | bool modValue(unsigned char &start, short delta, short min, short max); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /globals.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "data.h" 3 | 4 | Ardumod arduboy; 5 | 6 | bool new_a, new_b, new_up, new_left, new_down, new_right; 7 | bool old_a, old_b, old_up, old_down, old_left, old_right; 8 | 9 | void updateInput() 10 | { 11 | old_a = new_a; 12 | old_b = new_b; 13 | old_up = new_up; 14 | old_down = new_down; 15 | old_left = new_left; 16 | old_right = new_right; 17 | 18 | new_a = arduboy.pressed(B_BUTTON); 19 | new_b = arduboy.pressed(A_BUTTON); 20 | new_up = arduboy.pressed(UP_BUTTON); 21 | new_down = arduboy.pressed(DOWN_BUTTON); 22 | new_left = arduboy.pressed(LEFT_BUTTON); 23 | new_right = arduboy.pressed(RIGHT_BUTTON); 24 | } 25 | 26 | bool modValue(unsigned char &start, short delta, short min, short max) 27 | { 28 | short val = start; 29 | val += delta; 30 | if(val < min) val = min; 31 | if(val > max) val = max; 32 | bool changed = (unsigned char)start != (unsigned char)val; 33 | start = val; 34 | return changed; 35 | } 36 | 37 | void printDecimal(unsigned char x, unsigned char y, unsigned char num) 38 | { 39 | if(num >= 100) drawChar(x, y, '0' + num/100); 40 | if(num >= 10) drawChar(x+4, y, '0' + (num%100/10)); 41 | drawChar(x+8, y, '0' + (num%10)); 42 | } 43 | 44 | void printHex(unsigned char x, unsigned char y, unsigned char num) 45 | { 46 | printHexDigit(x, y, num/16); 47 | printHexDigit(x+4, y, num%16); 48 | } 49 | 50 | void printHexDigit(unsigned char x, unsigned char y, unsigned char num) 51 | { 52 | if(num < 0x0a) 53 | { 54 | drawChar(x, y, '0' + num); 55 | } 56 | else 57 | { 58 | drawChar(x, y, 'A' + (num-10)); 59 | } 60 | } 61 | 62 | void drawChar(unsigned char x, unsigned char y, unsigned char ch) 63 | { 64 | arduboy.drawBitmap(x, y, gfx_font + (unsigned short)3 * (ch - '0'), 3, 8, 1); 65 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | ABasm is an Arduboy game that lets you program your own Arduboy games, on your Arduboy! It uses an assembly language-style of programming with its own bytecode format. 3 | 4 | ## Instructions 5 | 6 | To quickly get up and running, hold left on boot to load up the example program. From there you can use the D-Pad to select an opcode. Hold A and press Up or Down to change a parameter. Hold B to open the menu bar, and release B to choose an option. 7 | 8 | ## Media 9 | 10 |

Makin' games for the Arduboy, on the Arduboy! #gamedev #assembly #virtualmachine pic.twitter.com/QHreqbxjKu

— fuopy (@fuopy) June 22, 2016
11 | 12 | 13 | ## Installation 14 | 15 | * Download the [Souce Code ZIP](https://github.com/fuopy/ABasm) from GitHub 16 | * Rename the extracted "ABasm-master" folder to "ABasm" 17 | * Open ABasm.ino with Arduino IDE 1.6.12+ 18 | * Click the upload button to install to your Arduboy 19 | 20 | ## Tips 21 | 22 | * The cursor position in the menubar is stored. This is useful for repeating an operation, such as Delete+MoveJumps 23 | * Hold LEFT on boot to load the default program 24 | * Hold DOWN on boot to start with an empty program 25 | 26 | ## Developer's Notice 27 | 28 | I have released this under the label "Developer Preview 1." As a hobby, I've been working on figuring out different ways of describing the types of games I'd like to make. This was created in an attempt to capture something I really want to see more of-- portable game development. While I'm pretty happy to share this project with everyone, I know I need to do many more redesigns before I can be satisfied. Either way, I hope you enjoy it! I'd love to hear feedback from anyone attempting to create something with it. And I definitely want to hear any sort of criticism about the bytecode format (or anything else you see!) -------------------------------------------------------------------------------- /Ardumod.cpp: -------------------------------------------------------------------------------- 1 | #include "Ardumod.h" 2 | 3 | 4 | void Ardumod::invertRect(int16_t x, int16_t y, uint8_t w, uint8_t h) 5 | { 6 | if(y < 0) 7 | { 8 | h += y; 9 | y = 0; 10 | } 11 | if(x < 0) 12 | { 13 | w += x; 14 | x = 0; 15 | } 16 | 17 | uint8_t row, page, col; 18 | 19 | unsigned char pageY = y%8; 20 | unsigned char fullPages = (h - (8 - pageY))/8; 21 | 22 | unsigned char lowerPart = 0xff << pageY; 23 | unsigned char upperPart = ~(0xff << ((y+h)%8)); 24 | 25 | row = y/8; 26 | 27 | for(col = 0; col < w; col++) 28 | { 29 | int16_t address = (row*WIDTH) + (uint8_t)x+col; 30 | if(address > sizeof(sBuffer)) continue; 31 | if(address < 0) continue; 32 | 33 | sBuffer[address] ^= lowerPart; 34 | } 35 | 36 | 37 | for(page = 1; page <= fullPages && page < 8; page++) 38 | //for(page = 0; page < h/8; page++) 39 | { 40 | row = page + y/8; 41 | 42 | for(col = 0; col < w; col++) 43 | { 44 | int16_t address = (row*WIDTH) + (uint8_t)x+col; 45 | if(address > sizeof(sBuffer)) continue; 46 | if(address < 0) continue; 47 | 48 | sBuffer[address] ^= 0xff; 49 | } 50 | } 51 | 52 | row = page + y/8; 53 | 54 | for(col = 0; col < w; col++) 55 | { 56 | int16_t address = (row*WIDTH) + (uint8_t)x+col; 57 | if(address > sizeof(sBuffer)) continue; 58 | if(address < 0) continue; 59 | 60 | sBuffer[address] ^= upperPart; 61 | } 62 | } 63 | 64 | void Ardumod::drawPixel(int x, int y, uint8_t color) 65 | { 66 | #ifdef PIXEL_SAFE_MODE 67 | if (x < 0 || x > (WIDTH-1) || y < 0 || y > (HEIGHT-1)) 68 | { 69 | return; 70 | } 71 | #endif 72 | 73 | uint8_t row = (uint8_t)y / 8; 74 | if (color == 1) 75 | { 76 | sBuffer[(row*WIDTH) + (uint8_t)x] |= _BV((uint8_t)y % 8); 77 | } 78 | else if(color == 0) 79 | { 80 | sBuffer[(row*WIDTH) + (uint8_t)x] &= ~ _BV((uint8_t)y % 8); 81 | } 82 | else 83 | { 84 | sBuffer[(row*WIDTH) + (uint8_t)x] ^= _BV((uint8_t)y % 8); 85 | } 86 | } 87 | 88 | void Ardumod::grayRect(int16_t x, int16_t y, uint8_t w, uint8_t h) 89 | { 90 | if(y < 0) 91 | { 92 | h += y; 93 | y = 0; 94 | } 95 | if(x < 0) 96 | { 97 | w += x; 98 | x = 0; 99 | } 100 | 101 | uint8_t row, page, col; 102 | 103 | for(page = 0; page < h/8; page++) 104 | { 105 | row = (uint8_t)y / 8 + page; 106 | 107 | for(col = 0; col < w; col++) 108 | { 109 | int16_t address = (row*WIDTH) + (uint8_t)x+col; 110 | if(address > sizeof(sBuffer)) continue; 111 | if(address < 0) continue; 112 | 113 | if(col%2 == 0) 114 | sBuffer[address] = 0b01010101; 115 | else 116 | sBuffer[address] = 0b10101010; 117 | } 118 | } 119 | } 120 | 121 | /* unmodified from core lib 1.1 */ 122 | 123 | void Ardumod::fillRect 124 | (int16_t x, int16_t y, uint8_t w, uint8_t h, uint8_t color) 125 | { 126 | drawFastHLine(x, y, w, color); // stupidest version - update in subclasses if desired! 127 | for (int16_t i=x; i= PROGRAM_CODE_LENGTH) 217 | return VMRUN_RETURN_ERROR; 218 | 219 | if(!justResumed && lineFlags[vms.pc/2] == 1) 220 | return VMRUN_RETURN_BREAK; 221 | 222 | justResumed = false; 223 | 224 | opcode = initCode[vms.pc++]; 225 | 226 | /* 227 | arduboy.setCursor(0, 64-8); 228 | arduboy.print("["); 229 | arduboy.print(pc-1); 230 | ; arduboy.print("], "); 231 | arduboy.print(opcode); 232 | arduboy.print(", "); 233 | arduboy.print(initCode[pc]); 234 | arduboy.print(" "); 235 | arduboy.display(); 236 | */ 237 | 238 | //pdelay(25); 239 | 240 | if(vms.skipInstruction) 241 | { 242 | vms.pc++; 243 | vms.skipInstruction = false; 244 | continue; 245 | } 246 | 247 | 248 | if(opcode < 0xF0) // register opcodes 249 | { 250 | reg1 = (opcode & 0b01110000) >> 4; 251 | opcode &= 0b00001111; 252 | 253 | if(opcode == 0x00) // set immediate 254 | { 255 | vms.registers[reg1] = initCode[vms.pc++]; 256 | } 257 | else if(opcode == 0x01) // copy from reg 258 | { 259 | vms.registers[reg1] = vms.registers[initCode[vms.pc++]]; 260 | } 261 | else if(opcode == 0x02) // add immediate 262 | { 263 | vms.registers[reg1] += initCode[vms.pc++]; 264 | } 265 | else if(opcode == 0x03) // add with reg 266 | { 267 | vms.registers[reg1] += vms.registers[initCode[vms.pc++]]; 268 | } 269 | else if(opcode == 0x04) // subtract immediate 270 | { 271 | vms.registers[reg1] -= initCode[vms.pc++]; 272 | } 273 | else if(opcode == 0x05) // subtract using reg 274 | { 275 | vms.registers[reg1] -= vms.registers[initCode[vms.pc++]]; 276 | } 277 | else if(opcode == 0x06) // muliply immediate 278 | { 279 | vms.registers[reg1] *= vms.registers[initCode[vms.pc++]]; 280 | } 281 | else if(opcode == 0x07) // multiply using reg 282 | { 283 | vms.registers[reg1] *= vms.registers[initCode[vms.pc++]]; 284 | } 285 | else if(opcode == 0x08) // divide using reg 286 | { 287 | vms.registers[reg1] /= vms.registers[initCode[vms.pc++]]; 288 | } 289 | else if(opcode == 0x09) // mod using reg 290 | { 291 | vms.registers[reg1] %= vms.registers[initCode[vms.pc++]]; 292 | } 293 | else if(opcode == 0x0a) // skip instruction if reg is not equal to val 294 | { 295 | if(vms.registers[reg1] != initCode[vms.pc++]) vms.skipInstruction = true; 296 | } 297 | else if(opcode == 0x0b) // skip instruction if reg is not equal to reg 298 | { 299 | if(vms.registers[reg1] != vms.registers[initCode[vms.pc++]]) vms.skipInstruction = true; 300 | } 301 | else if(opcode == 0x0c) // skip instruction if reg is equal to reg 302 | { 303 | if(vms.registers[reg1] == vms.registers[initCode[vms.pc++]]) vms.skipInstruction = true; 304 | } 305 | else if(opcode == 0x0d) // skip instruction if reg is less than reg 306 | { 307 | if(vms.registers[reg1] < vms.registers[initCode[vms.pc++]]) vms.skipInstruction = true; 308 | } 309 | else if(opcode == 0x0e) // skip instruction if reg is greater than reg 310 | { 311 | if(vms.registers[reg1] > vms.registers[initCode[vms.pc++]]) vms.skipInstruction = true; 312 | } 313 | else if(opcode == 0x0f) // skip instruction if reg is equal to val 314 | { 315 | if(vms.registers[reg1] == initCode[vms.pc++]) vms.skipInstruction = true; 316 | } 317 | } 318 | else // general opcodes 319 | { 320 | if(opcode == 0xf0) // no operation 321 | { 322 | vms.pc++; 323 | } 324 | else if(opcode == 0xf1) // fill screen with color 325 | { 326 | arduboy.fillScreen(initCode[vms.pc++]); 327 | } 328 | else if(opcode == 0xf2) // set pixel on screen (lsb: rx, ry, color) 329 | { 330 | opcode = initCode[vms.pc++]; 331 | reg1 = opcode & 0b00000111; 332 | reg2 = (opcode & 0b00111000) >> 3; 333 | reg3 = (opcode & 0b11000000) >> 6; 334 | 335 | arduboy.drawPixel(vms.registers[reg1], vms.registers[reg2], reg3); 336 | } 337 | else if(opcode == 0xf3) // get pixel on screen (lsb: rx, ry, rdest) 338 | { // does not modify rdest if coords are offscreen 339 | opcode = initCode[vms.pc++]; 340 | reg1 = opcode & 0b00000111; 341 | reg2 = (opcode & 0b00111000) >> 3; 342 | reg3 = ((opcode & 0b11000000) >> 6) + 4; 343 | 344 | x = vms.registers[reg1]; 345 | y = vms.registers[reg2]; 346 | 347 | if(x < WIDTH && y < HEIGHT) 348 | vms.registers[reg3] = arduboy.getPixel(x, y); 349 | } 350 | else if(opcode == 0xf4) // play a tone (lsb: rtoneLo, rtoneHi, rDelay) 351 | { 352 | opcode = initCode[vms.pc++]; 353 | reg1 = opcode & 0b00000111; 354 | reg2 = (opcode & 0b00111000) >> 3; 355 | reg3 = ((opcode & 0b11000000) >> 6) + 4; 356 | 357 | arduboy.tunes.tone(((short)vms.registers[reg2])*16 + vms.registers[reg1], vms.registers[reg3]); 358 | } 359 | else if(opcode == 0xf5) // wait for the next frame 360 | { 361 | while(!arduboy.nextFrame()); 362 | vms.pc++; 363 | } 364 | else if(opcode == 0xf6) // skip if desired buttons are down 365 | { 366 | reg1 = initCode[vms.pc++]; 367 | if(arduboy.pressed(reg1)) vms.skipInstruction = true; 368 | } 369 | else if(opcode == 0xf7) // skip if desired buttons are up 370 | { 371 | reg1 = initCode[vms.pc++]; 372 | if(arduboy.notPressed(reg1)) vms.skipInstruction = true; 373 | } 374 | else if(opcode == 0xf8) // jump pc to address in eeprom 375 | { 376 | opcode = initCode[vms.pc++]; 377 | vms.pc = opcode; 378 | } 379 | else if(opcode == 0xf9) // jump pc to address in eeprom indirect reg 380 | { 381 | reg1 = initCode[vms.pc++]; 382 | vms.pc = vms.registers[reg1]; 383 | } 384 | else if(opcode == 0xfa) // restore register values from eeprom address 385 | { 386 | // todo 387 | vms.pc++; 388 | } 389 | else if(opcode == 0xfb) // dump register values to eeprom address 390 | { 391 | // todo 392 | vms.pc++; 393 | } 394 | else if(opcode == 0xfc) // print a number of following characters 395 | { 396 | reg1 = initCode[vms.pc++]; 397 | arduboy.setCursor(0, 0); 398 | for(iterator = 0; iterator < reg1; iterator++) 399 | { 400 | arduboy.print((char)initCode[vms.pc++]); 401 | } 402 | } 403 | else if(opcode == 0xfd) // display buffer to screen 404 | { 405 | arduboy.display(); 406 | vms.pc++; 407 | } 408 | else if(opcode == 0xfe) // reserved 409 | { 410 | vms.pc++; 411 | } 412 | else if(opcode == 0xff) // exit init routine 413 | { 414 | vms.pc++; 415 | return VMRUN_RETURN_EXIT; 416 | } 417 | } 418 | } 419 | } -------------------------------------------------------------------------------- /data.h: -------------------------------------------------------------------------------- 1 | #ifndef _DATA_H 2 | #define _DATA_H 3 | 4 | // 53 x 6 5 | const unsigned char gfx_iconmenu[] PROGMEM = { 6 | 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x03, 0x35, 0x03, 7 | 0x3f, 0x01, 0x17, 0x0f, 0x27, 0x1b, 0x27, 0x23, 8 | 0x1f, 0x23, 0x3b, 0x01, 0x3b, 0x3f, 0x3f, 0x03, 9 | 0x35, 0x03, 0x3f, 0x01, 0x17, 0x2f, 0x3f, 0x03, 10 | 0x35, 0x03, 0x3f, 0x13, 0x13, 0x0b, 0x3f, 0x07, 11 | 0x3b, 0x07, 0x3b, 0x07, 0x3f, 0x1f, 0x3f, 0x1f, 12 | 0x3f, 0x1f, 0x3f, 0x3f, 0x3f, 13 | }; 14 | 15 | // 61 x 27 16 | /* 17 | const unsigned char gfx_iconmenu[] PROGMEM = { 18 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xf5, 0xc3, 19 | 0xff, 0xc1, 0xd7, 0xcf, 0xe7, 0xdb, 0xe7, 0xe3, 20 | 0xdf, 0xe3, 0xfb, 0xc1, 0xfb, 0xff, 0xff, 0xc3, 21 | 0xf5, 0xc1, 0xff, 0xc1, 0xd5, 0xeb, 0xff, 0xc3, 22 | 0xf5, 0xc3, 0xff, 0xd3, 0xd3, 0xcb, 0xff, 0xc7, 23 | 0xfb, 0xc7, 0xfb, 0xc7, 0xff, 0xdf, 0xff, 0xdf, 24 | 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 25 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfb, 26 | 0xff, 0xfb, 0x7f, 0x7b, 0x7f, 0x7b, 0x7f, 0xfb, 27 | 0xff, 0xfb, 0x7f, 0x7b, 0xff, 0xfb, 0xff, 0xfb, 28 | 0xff, 0x7b, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 29 | 0xff, 0xfb, 0xff, 0x7b, 0xff, 0xfb, 0xff, 0xfb, 30 | 0xff, 0xfb, 0x7f, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 31 | 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 32 | 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 33 | 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 34 | 0xb4, 0x72, 0x74, 0x70, 0xff, 0xff, 0x78, 0xb7, 35 | 0xb7, 0xff, 0xf9, 0x76, 0xf0, 0xff, 0x70, 0x7f, 36 | 0xf9, 0xf6, 0x76, 0x3f, 0x78, 0xf7, 0x70, 0xff, 37 | 0x70, 0xff, 0xf9, 0x76, 0xf0, 0xff, 0x3e, 0xf0, 38 | 0xfe, 0xff, 0xf9, 0x36, 0xb9, 0x7f, 0xf0, 0xfd, 39 | 0x7e, 0x7f, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xff, 40 | 0x7f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x07, 41 | 0x07, 0x07, 0x07, 0x07, 0x03, 0x06, 0x03, 0x07, 42 | 0x03, 0x07, 0x07, 0x04, 0x03, 0x03, 0x07, 0x04, 43 | 0x03, 0x04, 0x07, 0x00, 0x07, 0x00, 0x07, 0x07, 44 | 0x00, 0x07, 0x07, 0x00, 0x06, 0x07, 0x07, 0x04, 45 | 0x03, 0x04, 0x07, 0x00, 0x07, 0x07, 0x07, 0x07, 46 | 0x00, 0x06, 0x06, 0x07, 0x04, 0x03, 0x00, 0x07, 47 | 0x00, 0x07, 0x00, 0x07, 0x04, 0x01, 0x02, 0x07, 48 | 0x00, 0x07, 0x07, 0x07, 49 | }; 50 | */ 51 | 52 | // 68 x 27 53 | const unsigned char gfx_editmenu[] PROGMEM = { 54 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xc1, 0xdd, 55 | 0xc3, 0xfb, 0xc7, 0xff, 0xd3, 0xd3, 0xcb, 0xff, 56 | 0xe7, 0xcb, 0xd7, 0xff, 0xc3, 0xf7, 0xfb, 0xfb, 57 | 0xc1, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 58 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 59 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 60 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 61 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 63 | 0xff, 0x6e, 0x60, 0xee, 0xe1, 0xfd, 0xe3, 0xff, 64 | 0xe9, 0x69, 0xe5, 0xff, 0xf3, 0xe5, 0xeb, 0xff, 65 | 0x61, 0xfb, 0xfd, 0xfd, 0xe0, 0xfd, 0xff, 0xfb, 66 | 0xf1, 0xfb, 0xff, 0xe0, 0xfd, 0xfb, 0xfd, 0xe0, 67 | 0xf3, 0xed, 0xf3, 0xf1, 0xef, 0xf1, 0xf3, 0xe5, 68 | 0xeb, 0xff, 0xef, 0xf2, 0xff, 0xf1, 0xef, 0xf1, 69 | 0xff, 0xe1, 0xfd, 0xe3, 0xfd, 0xe1, 0xff, 0xe1, 70 | 0xf5, 0xf9, 0xff, 0xe9, 0xe9, 0xe5, 0xff, 0xff, 71 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0xb7, 0x78, 72 | 0xff, 0xf9, 0x72, 0xf5, 0xff, 0x30, 0xff, 0xf9, 73 | 0x72, 0xf5, 0xff, 0x7e, 0x30, 0x7e, 0xff, 0xf9, 74 | 0x72, 0xf5, 0xff, 0xff, 0x7f, 0xff, 0xff, 0x3f, 75 | 0x7f, 0xff, 0x7f, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 76 | 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xbf, 77 | 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x7f, 0xff, 78 | 0x7f, 0x7f, 0xff, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 79 | 0x7f, 0xff, 0xff, 0xff, 0x07, 0x07, 0x07, 0x07, 80 | 0x07, 0x00, 0x03, 0x04, 0x07, 0x04, 0x01, 0x02, 81 | 0x07, 0x00, 0x07, 0x04, 0x01, 0x02, 0x07, 0x07, 82 | 0x00, 0x07, 0x07, 0x04, 0x01, 0x02, 0x07, 0x06, 83 | 0x04, 0x06, 0x07, 0x00, 0x07, 0x06, 0x07, 0x00, 84 | 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04, 0x01, 85 | 0x02, 0x07, 0x03, 0x04, 0x07, 0x04, 0x03, 0x04, 86 | 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 87 | 0x05, 0x06, 0x02, 0x02, 0x01, 0x07, 0x07, 0x07, 88 | }; 89 | 90 | // 62 x 46 91 | const unsigned char gfx_aboutdialog[] PROGMEM = { 92 | 0x00, 0xfe, 0x02, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 93 | 0xfa, 0x7a, 0x1a, 0xda, 0x1a, 0x7a, 0xba, 0x5a, 94 | 0xba, 0xfa, 0xfa, 0xfa, 0x3a, 0x1a, 0x9a, 0x1a, 95 | 0x3a, 0xfa, 0x1a, 0x1a, 0x7a, 0x7a, 0xfa, 0xfa, 96 | 0x1a, 0xda, 0xda, 0xda, 0x9a, 0x5a, 0xda, 0xda, 97 | 0x5a, 0x5a, 0x1a, 0x5a, 0xda, 0xda, 0xda, 0xba, 98 | 0xba, 0x9a, 0xda, 0xda, 0xba, 0x7a, 0xfa, 0xfa, 99 | 0xfa, 0xfa, 0xfa, 0x02, 0xfe, 0x00, 0x00, 0xff, 100 | 0x00, 0xff, 0xff, 0xe3, 0xeb, 0x49, 0xbe, 0x6f, 101 | 0x59, 0xdf, 0x5f, 0x79, 0xbe, 0xc9, 0xeb, 0xe3, 102 | 0xff, 0xff, 0x10, 0xd0, 0x3c, 0xf0, 0x70, 0xbf, 103 | 0x70, 0xf0, 0x72, 0xf0, 0x78, 0xff, 0x70, 0xb7, 104 | 0x77, 0xf2, 0x1b, 0xfb, 0x76, 0xb5, 0x71, 0xf5, 105 | 0x35, 0xb7, 0x76, 0xf5, 0x73, 0xb7, 0x77, 0xf5, 106 | 0x33, 0x79, 0xb7, 0xf7, 0xf6, 0xf5, 0xf3, 0xf7, 107 | 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 108 | 0xff, 0xff, 0xfe, 0xfd, 0xfe, 0xff, 0xfc, 0xfd, 109 | 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 110 | 0x04, 0xd5, 0xee, 0xff, 0x1e, 0xdc, 0xfd, 0x9f, 111 | 0x2e, 0x5d, 0xfe, 0x9f, 0x7e, 0x9c, 0xfd, 0x17, 112 | 0xfc, 0x9f, 0x2e, 0x5d, 0xfe, 0x9f, 0x78, 0xbd, 113 | 0x7e, 0x9f, 0xfe, 0xfc, 0xfd, 0x77, 0x04, 0x7f, 114 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 115 | 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0xfb, 0xfb, 116 | 0xfb, 0x3b, 0xdb, 0x2b, 0xab, 0xab, 0xdb, 0x3b, 117 | 0xfb, 0xfb, 0xfb, 0xdb, 0xeb, 0x1b, 0xfb, 0x1b, 118 | 0xeb, 0x1b, 0xfb, 0xdb, 0x0b, 0xfb, 0xfb, 0x1b, 119 | 0x6b, 0xdb, 0xfb, 0xfb, 0xfb, 0xfb, 0x1b, 0x6b, 120 | 0xdb, 0xfb, 0x1b, 0xfb, 0x1b, 0xfb, 0x3b, 0xdb, 121 | 0x3b, 0xfb, 0x1b, 0xdb, 0x3b, 0xfb, 0x1b, 0xfb, 122 | 0x1b, 0xfb, 0xfb, 0xfb, 0xff, 0x00, 0xff, 0x00, 123 | 0x00, 0xff, 0x00, 0xff, 0x5f, 0x5f, 0x1f, 0xfe, 124 | 0x1d, 0xda, 0x1a, 0xfa, 0xbd, 0xfe, 0xbf, 0x1f, 125 | 0xff, 0xf9, 0x1a, 0x7b, 0x1f, 0xfc, 0xfb, 0xfc, 126 | 0xff, 0x5b, 0x58, 0x1b, 0xff, 0x1c, 0xdb, 0x1c, 127 | 0xff, 0xbf, 0x1f, 0xff, 0xf8, 0x1f, 0x5f, 0x5f, 128 | 0xfc, 0xfb, 0x1c, 0xdf, 0x1c, 0xfb, 0x1c, 0x5f, 129 | 0x58, 0xfe, 0xff, 0x5f, 0x5d, 0x1a, 0xfc, 0x5f, 130 | 0x5f, 0x1f, 0xff, 0x00, 0xff, 0x00, 0x00, 0x1f, 131 | 0x10, 0x17, 0x14, 0x15, 0x15, 0x17, 0x14, 0x15, 132 | 0x14, 0x17, 0x16, 0x17, 0x15, 0x14, 0x15, 0x17, 133 | 0x17, 0x17, 0x14, 0x17, 0x17, 0x17, 0x17, 0x14, 134 | 0x15, 0x15, 0x17, 0x14, 0x15, 0x14, 0x17, 0x15, 135 | 0x14, 0x15, 0x17, 0x14, 0x15, 0x14, 0x17, 0x17, 136 | 0x14, 0x15, 0x14, 0x17, 0x14, 0x15, 0x14, 0x17, 137 | 0x17, 0x14, 0x15, 0x15, 0x17, 0x15, 0x15, 0x14, 138 | 0x17, 0x10, 0x1f, 0x00, 139 | }; 140 | 141 | // 65 x 27 142 | const unsigned char gfx_runmenu[] PROGMEM = { 143 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xd5, 0xed, 144 | 0xff, 0xe7, 0xdb, 0xc3, 0xff, 0xe3, 0xdf, 0xe3, 145 | 0xff, 0xe7, 0xcb, 0xd7, 0xff, 0xff, 0xff, 0xf9, 146 | 0xff, 0xc3, 0xfb, 0xc7, 0xff, 0xf9, 0xff, 0xff, 147 | 0xff, 0xc1, 0xf5, 0xcb, 0xff, 0xe3, 0xdf, 0xe3, 148 | 0xff, 0xc3, 0xfb, 0xc7, 0xff, 0xff, 0xff, 0xff, 149 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 150 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 151 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x7a, 152 | 0xe5, 0xff, 0xf1, 0xef, 0xf1, 0xff, 0xe1, 0xfd, 153 | 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 154 | 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xff, 155 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 156 | 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 157 | 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 158 | 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 159 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 160 | 0xbd, 0x72, 0xf8, 0xf7, 0x78, 0xf0, 0xfe, 0x71, 161 | 0x7f, 0x7f, 0xf0, 0x73, 0xf0, 0x7b, 0xfd, 0x7e, 162 | 0x79, 0x76, 0xf9, 0xff, 0x70, 0xf5, 0xfa, 0xf1, 163 | 0xfb, 0xfd, 0xf9, 0xf2, 0xf5, 0xff, 0xf9, 0xf6, 164 | 0xf0, 0xff, 0xf0, 0xfd, 0xf2, 0xff, 0xf0, 0xfa, 165 | 0xf9, 0xf9, 0xf6, 0xf9, 0xff, 0xf1, 0xf0, 0xfe, 166 | 0xf1, 0xfe, 0xf0, 0xfe, 0xf4, 0xf4, 0xf2, 0xff, 167 | 0xff, 0xff, 0xff, 0x07, 0x07, 0x07, 0x07, 0x07, 168 | 0x00, 0x06, 0x01, 0x07, 0x04, 0x01, 0x02, 0x07, 169 | 0x02, 0x02, 0x01, 0x07, 0x00, 0x03, 0x04, 0x07, 170 | 0x00, 0x06, 0x00, 0x07, 0x04, 0x01, 0x02, 0x07, 171 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 172 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 173 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 174 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 175 | 0x07, 0x07, 0x07, 0x07, 176 | }; 177 | 178 | 179 | // 39 x 48 180 | const unsigned char gfx_filemenu[] PROGMEM = { 181 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xfd, 0xc3, 182 | 0xff, 0xe7, 0xcb, 0xd7, 0xff, 0xc7, 0xcf, 0xc7, 183 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 184 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 185 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 186 | 0xff, 0xff, 0xff, 0xff, 0x71, 0x6e, 0xf1, 0xff, 187 | 0xe1, 0xf5, 0xf3, 0xff, 0xf3, 0xe5, 0xeb, 0xff, 188 | 0xe1, 0xfd, 0xe3, 0xff, 0x6f, 0xff, 0xef, 0xff, 189 | 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 190 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 191 | 0xff, 0xff, 0xff, 0xf0, 0xfd, 0xf2, 0xff, 0xf9, 192 | 0xf2, 0xf5, 0xff, 0xf9, 0xf6, 0xf6, 0xff, 0xf9, 193 | 0xf2, 0xf5, 0xff, 0xf1, 0xff, 0xf9, 0xf7, 0xf9, 194 | 0xff, 0xf9, 0xf2, 0xf5, 0xff, 0xf7, 0xff, 0xf7, 195 | 0xff, 0xf7, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 196 | 0xff, 0xfe, 0xbf, 0x5e, 0xdf, 0xfe, 0x7f, 0x7e, 197 | 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xbe, 198 | 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 199 | 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 200 | 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 201 | 0xff, 0xdd, 0xad, 0x6e, 0xff, 0x3e, 0xbd, 0x3c, 202 | 0xff, 0x3e, 0xfd, 0x3e, 0xff, 0x3e, 0x5c, 0xbd, 203 | 0xff, 0x1f, 0xaf, 0x1f, 0xff, 0x9f, 0x5f, 0x5f, 204 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 205 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 206 | 0x6e, 0x56, 0xb7, 0xff, 0x9f, 0x2e, 0x5e, 0xff, 207 | 0x1f, 0xde, 0x3f, 0xff, 0x9f, 0x5e, 0x06, 0xff, 208 | 0x7e, 0xff, 0x7e, 0xff, 0x7e, 0xfe, 0xfe, 0xff, 209 | 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 210 | 0xff, 0xff, 211 | }; 212 | 213 | // 128 x 8 214 | 215 | const unsigned char gfx_menubar[] PROGMEM = { 216 | 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xd7, 0xe3, 0xc9, 217 | 0xe3, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 218 | 0xff, 0xc1, 0xd5, 0xdd, 0xff, 0xcf, 0xd7, 0xc1, 219 | 0xff, 0xc5, 0xff, 0xfb, 0xc1, 0xfb, 0xff, 0xff, 220 | 0xff, 0xff, 0xc1, 0xf5, 0xc9, 0xff, 0xe3, 0xdf, 221 | 0xc3, 0xff, 0xc3, 0xfb, 0xc7, 0xff, 0xff, 0xff, 222 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 223 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 224 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 225 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 226 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 227 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 228 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 229 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 230 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 231 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 232 | }; 233 | 234 | /* 235 | const unsigned char gfx_menubar[] PROGMEM = { 236 | 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xd7, 0xe3, 0xc9, 237 | 0xe3, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 238 | 0xff, 0xc1, 0xf5, 0xfd, 0xff, 0xc5, 0xff, 0xc1, 239 | 0xff, 0xe7, 0xcb, 0xd7, 0xff, 0xff, 0xff, 0xff, 240 | 0xc1, 0xd5, 0xdd, 0xff, 0xcf, 0xd7, 0xc1, 0xff, 241 | 0xc5, 0xff, 0xfb, 0xc1, 0xfb, 0xff, 0xff, 0xff, 242 | 0xff, 0xc1, 0xf5, 0xc9, 0xff, 0xe3, 0xdf, 0xc3, 243 | 0xff, 0xc3, 0xfb, 0xc7, 0xff, 0xff, 0xff, 0xff, 244 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 245 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 246 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 247 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 248 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 249 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 250 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 251 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 252 | }; 253 | */ 254 | 255 | // 96 x 48 256 | const unsigned char gfx_rundialog[] PROGMEM = { 257 | 0xff, 0x01, 0xfd, 0xfd, 0xfd, 0x1d, 0xdd, 0xdd, 258 | 0xdd, 0xdd, 0x1d, 0x1d, 0x1d, 0x9d, 0x9d, 0x1d, 259 | 0x1d, 0x1d, 0x1d, 0x1d, 0xfd, 0xfd, 0xfd, 0xfd, 260 | 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x7d, 0xbd, 0xbd, 261 | 0xbd, 0xfd, 0xfd, 0x7d, 0x7d, 0x7d, 0xfd, 0x7d, 262 | 0xfd, 0xfd, 0x7d, 0xfd, 0xfd, 0x7d, 0x7d, 0xfd, 263 | 0xfd, 0xfd, 0xfd, 0xfd, 0x7d, 0x7d, 0xfd, 0xfd, 264 | 0xfd, 0xfd, 0xfd, 0x3d, 0xfd, 0xfd, 0xbd, 0xfd, 265 | 0xfd, 0x3d, 0xfd, 0xfd, 0xfd, 0x7d, 0x7d, 0x7d, 266 | 0xfd, 0xfd, 0xfd, 0x7d, 0x7d, 0x7d, 0xfd, 0x7d, 267 | 0xfd, 0x7d, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x3d, 268 | 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x01, 0xff, 269 | 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xfc, 270 | 0xdf, 0x1f, 0x20, 0x5e, 0x41, 0x22, 0x20, 0x11, 271 | 0x0e, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 272 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xf6, 0xf6, 273 | 0xf9, 0xff, 0xf8, 0xf7, 0xfb, 0xf0, 0xff, 0xf8, 274 | 0xf7, 0xfb, 0xfc, 0xff, 0xf8, 0xf5, 0xf5, 0xf6, 275 | 0xff, 0xff, 0xff, 0xf8, 0xf5, 0xf5, 0xf6, 0xff, 276 | 0xf9, 0xf6, 0xf6, 0xf8, 0xf7, 0xff, 0xf0, 0xff, 277 | 0xfe, 0xf0, 0xfe, 0xff, 0xf6, 0xf5, 0xf5, 0xfb, 278 | 0xff, 0xff, 0xf8, 0xf7, 0xfb, 0xf0, 0xff, 0xf0, 279 | 0xfe, 0xff, 0xf0, 0xff, 0xf9, 0x76, 0x76, 0x78, 280 | 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 281 | 0xff, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xf7, 0xf7, 282 | 0xf5, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 283 | 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 284 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xfd, 0xfe, 285 | 0xfe, 0xff, 0xf0, 0xef, 0xef, 0xf0, 0xef, 0xff, 286 | 0xe0, 0xfd, 0xfe, 0xe1, 0xff, 0xff, 0xff, 0x80, 287 | 0xee, 0xee, 0xf1, 0xff, 0xe0, 0xfd, 0xfe, 0xfe, 288 | 0xff, 0xf1, 0xee, 0xee, 0xf1, 0xff, 0xb1, 0xae, 289 | 0xae, 0xc1, 0xff, 0xe0, 0xfd, 0xfe, 0xff, 0xf1, 290 | 0xee, 0xf6, 0xe0, 0xff, 0xe0, 0xfd, 0xfe, 0xe1, 291 | 0xfd, 0xfe, 0xe1, 0xff, 0xfe, 0xff, 0xe9, 0xfd, 292 | 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 293 | 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 294 | 0x7f, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 295 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 296 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x7f, 297 | 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 298 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 299 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 300 | 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x9f, 0x9f, 301 | 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 302 | 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 303 | 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x9f, 0x9f, 304 | 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 305 | 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x3e, 306 | 0x7f, 0xe3, 0xdd, 0xdd, 0xff, 0xe7, 0xd7, 0xc7, 307 | 0xff, 0xc7, 0xf7, 0xcf, 0xff, 0xef, 0xd7, 0xd7, 308 | 0xff, 0xe7, 0xcb, 0xd7, 0xff, 0xc1, 0xff, 0x7f, 309 | 0x3e, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 310 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 311 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 312 | 0xff, 0xff, 0xff, 0xc1, 0x00, 0x3e, 0xc1, 0xbe, 313 | 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x63, 0x5d, 314 | 0x63, 0x7f, 0x41, 0x77, 0x49, 0x7f, 0x7f, 0x7f, 315 | 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xbe, 0xc1, 316 | 0x3e, 0x00, 0xc1, 0xff, 0xff, 0xff, 0x00, 0xff, 317 | 0xff, 0x80, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 318 | 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 319 | 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 320 | 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 321 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 322 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 323 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 324 | 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbc, 0xbc, 325 | 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 326 | 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 327 | 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xbc, 0xbc, 328 | 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x80, 0xff, 329 | }; 330 | 331 | //28 x 11 332 | const unsigned char gfx_invertbutton[] PROGMEM = { 333 | 0xf8, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 334 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 335 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 336 | 0xff, 0xfe, 0xfe, 0xf8, 0x00, 0x03, 0x03, 0x07, 337 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 338 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 339 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x00, 340 | }; 341 | 342 | 343 | // from '0' to 'Z' 344 | // 3x5 345 | const unsigned char gfx_font[] PROGMEM = { 346 | 0x1e, 0x11, 0x0f, 0x12, 0x1f, 0x10, 0x12, 0x19, 347 | 0x17, 0x11, 0x15, 0x1b, 0x06, 0x04, 0x1f, 0x17, 348 | 0x13, 0x0d, 0x0e, 0x15, 0x1d, 0x19, 0x05, 0x03, 349 | 0x1a, 0x15, 0x0b, 0x12, 0x15, 0x0e, 0x00, 0x0a, 350 | 0x00, 0x00, 0x10, 0x00, 0x00, 0x17, 0x00, 0x18, 351 | 0x04, 0x03, 0x09, 0x04, 0x12, 0x01, 0x15, 0x07, 352 | 0x00, 0x04, 0x00, 0x1e, 0x05, 0x1e, 0x1f, 0x15, 353 | 0x0a, 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x0e, 0x1f, 354 | 0x15, 0x11, 0x1f, 0x05, 0x01, 0x0e, 0x11, 0x1d, 355 | 0x1f, 0x04, 0x1f, 0x11, 0x1f, 0x11, 0x11, 0x0f, 356 | 0x01, 0x1f, 0x04, 0x1b, 0x1f, 0x10, 0x10, 0x1f, 357 | 0x07, 0x1f, 0x1f, 0x01, 0x1e, 0x0e, 0x11, 0x0e, 358 | 0x1f, 0x05, 0x06, 0x0f, 0x09, 0x17, 0x1f, 0x05, 359 | 0x1b, 0x16, 0x15, 0x0d, 0x01, 0x1f, 0x01, 0x1f, 360 | 0x10, 0x0f, 0x07, 0x18, 0x07, 0x1f, 0x18, 0x1f, 361 | 0x1b, 0x04, 0x1b, 0x03, 0x1c, 0x03, 0x19, 0x15, 362 | 0x13, 363 | }; 364 | 365 | 366 | // 8 of 'em 367 | // 8x8 368 | const unsigned char gfx_registers[] PROGMEM = { 369 | 0x1c, 0x08, 0x04, 0x00, 0x1e, 0x11, 0x0f, 0x00, 370 | 0x1c, 0x08, 0x04, 0x00, 0x12, 0x1f, 0x10, 0x00, 371 | 0x1c, 0x08, 0x04, 0x00, 0x12, 0x19, 0x16, 0x00, 372 | 0x1c, 0x08, 0x04, 0x00, 0x11, 0x15, 0x1f, 0x00, 373 | 0x1c, 0x08, 0x04, 0x00, 0x07, 0x04, 0x1f, 0x00, 374 | 0x1c, 0x08, 0x04, 0x00, 0x17, 0x13, 0x0d, 0x00, 375 | 0x1c, 0x08, 0x04, 0x00, 0x0e, 0x15, 0x09, 0x00, 376 | 0x1c, 0x08, 0x04, 0x00, 0x19, 0x05, 0x03, 0x00, 377 | }; 378 | 379 | // 8 of 'em 380 | // 8x8 381 | const unsigned char gfx_buttons[] PROGMEM = { 382 | 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 383 | 0x00, 0x4e, 0x1f, 0x5f, 0x1f, 0x4e, 0x00, 0x00, 384 | 0x00, 0x4e, 0x11, 0x51, 0x11, 0x4e, 0x00, 0x00, 385 | 0x00, 0x44, 0x08, 0x5f, 0x08, 0x44, 0x00, 0x00, 386 | 0x00, 0x44, 0x0e, 0x55, 0x04, 0x44, 0x00, 0x00, 387 | 0x00, 0x44, 0x04, 0x55, 0x0e, 0x44, 0x00, 0x00, 388 | 0x00, 0x44, 0x02, 0x5f, 0x02, 0x44, 0x00, 0x00, 389 | 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 390 | }; 391 | 392 | 393 | // 32 of 'em 394 | // 38 x 8 395 | const unsigned char gfx_opcodes[] PROGMEM = { 396 | 0x1f, 0x01, 0x1e, 0x00, 0x0c, 0x12, 0x0c, 0x00, 397 | 0x0e, 0x11, 0x0e, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 398 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 399 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 400 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x05, 401 | 0x01, 0x1a, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x16, 402 | 0x15, 0x0d, 0x00, 0x1c, 0x14, 0x00, 0x1c, 0x08, 403 | 0x04, 0x00, 0x0c, 0x1a, 0x14, 0x00, 0x0c, 0x1a, 404 | 0x14, 0x00, 0x1c, 0x04, 0x18, 0x00, 0x00, 0x00, 405 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x11, 0x0e, 0x00, 406 | 0x1c, 0x08, 0x04, 0x00, 0x0c, 0x14, 0x1c, 0x00, 407 | 0x1c, 0x18, 0x1c, 0x00, 0x1f, 0x05, 0x06, 0x00, 408 | 0x1a, 0x00, 0x14, 0x08, 0x14, 0x00, 0x0c, 0x1a, 409 | 0x14, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 410 | 0x00, 0x00, 0x0e, 0x11, 0x1d, 0x00, 0x0c, 0x1a, 411 | 0x14, 0x00, 0x02, 0x1f, 0x02, 0x00, 0x1f, 0x05, 412 | 0x06, 0x00, 0x1a, 0x00, 0x14, 0x08, 0x14, 0x00, 413 | 0x0c, 0x1a, 0x14, 0x00, 0x1f, 0x00, 0x00, 0x00, 414 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 415 | 0x1f, 0x05, 0x06, 0x00, 0x1f, 0x00, 0x0c, 0x14, 416 | 0x1c, 0x00, 0x12, 0x14, 0x0e, 0x00, 0x01, 0x1f, 417 | 0x01, 0x0c, 0x12, 0x0c, 0x00, 0x1e, 0x02, 0x1c, 418 | 0x00, 0x0c, 0x1a, 0x14, 0x00, 0x00, 0x00, 0x00, 419 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 420 | 0x1f, 0x00, 0x0c, 0x14, 0x1c, 0x00, 0x1d, 0x02, 421 | 0x1f, 0x02, 0x00, 0x1f, 0x05, 0x19, 0x14, 0x08, 422 | 0x1e, 0x04, 0x02, 0x00, 0x1f, 0x05, 0x1d, 0x08, 423 | 0x04, 0x0c, 0x14, 0x1c, 0x00, 0x1c, 0x0c, 0x1c, 424 | 0x00, 0x0c, 0x1a, 0x14, 0x16, 0x15, 0x0d, 0x00, 425 | 0x1f, 0x04, 0x1a, 0x00, 0x1a, 0x00, 0x1e, 0x0a, 426 | 0x0c, 0x00, 0x11, 0x1f, 0x11, 0x04, 0x1e, 0x05, 427 | 0x00, 0x1f, 0x11, 0x0e, 0x00, 0x0c, 0x12, 0x0c, 428 | 0x00, 0x0e, 0x10, 0x0c, 0x10, 0x0e, 0x00, 0x1e, 429 | 0x02, 0x1c, 0x16, 0x15, 0x0d, 0x00, 0x1f, 0x04, 430 | 0x1a, 0x00, 0x1a, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 431 | 0x11, 0x1f, 0x11, 0x04, 0x1e, 0x05, 0x00, 0x1f, 432 | 0x10, 0x0f, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 0x00, 433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 434 | 0x11, 0x0f, 0x01, 0x00, 0x0e, 0x10, 0x1e, 0x00, 435 | 0x1e, 0x0c, 0x1c, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 436 | 0x01, 0x1f, 0x01, 0x0c, 0x12, 0x0c, 0x00, 0x00, 437 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 438 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x0f, 439 | 0x01, 0x00, 0x0e, 0x10, 0x1e, 0x00, 0x1e, 0x0c, 440 | 0x1c, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 0x00, 0x07, 441 | 0x18, 0x07, 0x00, 0x1a, 0x00, 0x0c, 0x14, 0x1c, 442 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 443 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x01, 0x1e, 0x00, 444 | 0x0c, 0x12, 0x0c, 0x00, 0x0e, 0x11, 0x0e, 0x00, 445 | 0x1e, 0x0a, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 446 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 447 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 448 | 0x00, 0x00, 0x1f, 0x01, 0x1e, 0x00, 0x0c, 0x12, 449 | 0x0c, 0x00, 0x0e, 0x11, 0x0e, 0x00, 0x1e, 0x0a, 450 | 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 451 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 452 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 453 | 0x1f, 0x05, 0x06, 0x00, 0x1e, 0x04, 0x02, 0x00, 454 | 0x1d, 0x00, 0x1e, 0x02, 0x1c, 0x00, 0x02, 0x1f, 455 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 457 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 458 | 0x0f, 0x1e, 0x0a, 0x0c, 0x18, 0x14, 0x1f, 0x0c, 459 | 0x14, 0x1c, 0x04, 0x1f, 0x04, 0x0c, 0x1a, 0x14, 460 | 0x00, 0x1f, 0x11, 0x0e, 0x1d, 0x00, 0x16, 0x1a, 461 | 0x00, 0x1e, 0x0a, 0x0c, 0x1f, 0x0c, 0x14, 0x1c, 462 | 0x00, 0x12, 0x14, 0x0e, 0x1f, 0x01, 0x1e, 0x00, 463 | 0x0c, 0x12, 0x0c, 0x00, 0x0e, 0x11, 0x0e, 0x00, 464 | 0x1e, 0x0a, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 466 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 467 | 0x00, 0x00, 0x1f, 0x15, 0x11, 0x00, 0x14, 0x08, 468 | 0x14, 0x00, 0x1d, 0x00, 0x02, 0x1f, 0x02, 0x00, 469 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 470 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 471 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 472 | 0x16, 0x15, 0x09, 0x00, 0x0c, 0x1a, 0x16, 0x00, 473 | 0x02, 0x1f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 474 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 475 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 476 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x15, 477 | 0x09, 0x00, 0x0c, 0x1a, 0x16, 0x00, 0x02, 0x1f, 478 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 479 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 480 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 481 | 0x00, 0x00, 0x00, 0x03, 0x1e, 0x05, 0x1e, 0x00, 482 | 0x18, 0x14, 0x1f, 0x00, 0x18, 0x14, 0x1f, 0x00, 483 | 0x00, 0x00, 0x01, 0x1f, 0x01, 0x0c, 0x12, 0x0c, 484 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 485 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 486 | 0x00, 0x03, 0x1e, 0x05, 0x1e, 0x00, 0x18, 0x14, 487 | 0x1f, 0x00, 0x18, 0x14, 0x1f, 0x00, 0x00, 0x00, 488 | 0x01, 0x1f, 0x01, 0x0c, 0x12, 0x0c, 0x00, 0x00, 489 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 490 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 491 | 0x16, 0x15, 0x0d, 0x0e, 0x10, 0x1e, 0x00, 0x1f, 492 | 0x14, 0x18, 0x02, 0x1f, 0x02, 0x1e, 0x04, 0x02, 493 | 0x10, 0x00, 0x01, 0x1f, 0x01, 0x0c, 0x12, 0x0c, 494 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 495 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x15, 496 | 0x0d, 0x0e, 0x10, 0x1e, 0x00, 0x1f, 0x14, 0x18, 497 | 0x02, 0x1f, 0x02, 0x1e, 0x04, 0x02, 0x10, 0x00, 498 | 0x01, 0x1f, 0x01, 0x0c, 0x12, 0x0c, 0x00, 0x00, 499 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 500 | 0x00, 0x00, 0x00, 0x03, 0x1f, 0x03, 0x1f, 0x00, 501 | 0x0e, 0x10, 0x1e, 0x00, 0x1f, 0x00, 0x02, 0x1f, 502 | 0x02, 0x1d, 0x00, 0x1e, 0x0a, 0x0c, 0x1f, 0x12, 503 | 0x14, 0x1e, 0x01, 0x1f, 0x0d, 0x12, 0x0c, 0x03, 504 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 505 | 0x00, 0x03, 0x1f, 0x03, 0x1f, 0x00, 0x0e, 0x10, 506 | 0x1e, 0x00, 0x1f, 0x00, 0x02, 0x1f, 0x02, 0x1d, 507 | 0x00, 0x1e, 0x0a, 0x0c, 0x1f, 0x12, 0x14, 0x1e, 508 | 0x01, 0x1f, 0x0d, 0x12, 0x0c, 0x03, 0x00, 0x00, 509 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 510 | 0x1f, 0x11, 0x0e, 0x00, 0x1d, 0x00, 0x0c, 0x10, 511 | 0x0c, 0x00, 0x1d, 0x00, 0x18, 0x14, 0x1f, 0x00, 512 | 0x0c, 0x1a, 0x14, 0x01, 0x1f, 0x01, 0x0c, 0x12, 513 | 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 514 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1f, 0x03, 515 | 0x1f, 0x08, 0x14, 0x08, 0x18, 0x14, 0x1f, 0x0c, 516 | 0x10, 0x1c, 0x00, 0x1f, 0x00, 0x0c, 0x10, 0x1c, 517 | 0x08, 0x14, 0x08, 0x01, 0x1f, 0x01, 0x0c, 0x12, 518 | 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 519 | 0x00, 0x00, 0x00, 0x03, 0x16, 0x15, 0x0d, 0x00, 520 | 0x1f, 0x04, 0x1a, 0x00, 0x1d, 0x00, 0x1e, 0x0a, 521 | 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1a, 522 | 0x0e, 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03, 523 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 524 | 0x00, 0x03, 0x16, 0x15, 0x0d, 0x00, 0x1f, 0x04, 525 | 0x1a, 0x00, 0x1d, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 526 | 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1a, 0x0e, 0x0b, 527 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 528 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 529 | 0x16, 0x15, 0x0d, 0x00, 0x1f, 0x04, 0x1a, 0x00, 530 | 0x1d, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 0x00, 0x00, 531 | 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 532 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 533 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x15, 534 | 0x0d, 0x00, 0x1f, 0x04, 0x1a, 0x00, 0x1d, 0x00, 535 | 0x1e, 0x0a, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 536 | 0x00, 0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, 537 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 538 | 0x00, 0x00, 0x00, 0x03, 0x16, 0x15, 0x0d, 0x00, 539 | 0x1f, 0x04, 0x1a, 0x00, 0x1d, 0x00, 0x1e, 0x0a, 540 | 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 541 | 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 542 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 543 | 0x00, 0x03, 0x16, 0x15, 0x0d, 0x00, 0x1f, 0x04, 544 | 0x1a, 0x00, 0x1d, 0x00, 0x1e, 0x0a, 0x0c, 0x00, 545 | 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 546 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 547 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 548 | }; 549 | 550 | #endif 551 | -------------------------------------------------------------------------------- /editor.cpp: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "editor.h" 3 | #include "vm.h" 4 | #include "data.h" 5 | 6 | #define PARAM_FORM_NOTHING 0 7 | #define PARAM_FORM_NUM 1 8 | #define PARAM_FORM_ADDRESS 2 9 | #define PARAM_FORM_BUTTONMAP 3 10 | #define PARAM_FORM_REG 4 11 | #define PARAM_FORM_REG_REG_NUM 5 12 | #define PARAM_FORM_REG_REG_REG 6 13 | 14 | #define PARAM_SPACING 2 15 | #define CHAR_WIDTH 4 16 | #define REGISTER_WIDTH 8 17 | #define BUTTON_WIDTH 8 18 | #define OPCODE_WIDTH 38 19 | #define BREAKPOINT_WIDTH 5 20 | 21 | #define OPCODE_START 12 22 | 23 | #define REPEAT_DELAY_TIME 20 24 | 25 | 26 | #define MENU_ICON 0 27 | #define MENU_EDIT 1 28 | #define MENU_RUN 2 29 | #define MENU_FILE 999 30 | 31 | //#define MENU_FILE 1 32 | //#define MENU_EDIT 2 33 | //#define MENU_RUN 3 34 | 35 | unsigned char cursorY = 0; 36 | unsigned char cursorX = 0; 37 | unsigned char scrollY = 255; 38 | unsigned char repeatDelay = REPEAT_DELAY_TIME; 39 | unsigned char offsetY = 0; 40 | 41 | VMState vms = { 42 | {0, 0, 0, 0, 0, 0, 0, 0}, 0, false 43 | }; 44 | 45 | const unsigned char opcode_param_counts[] = { 46 | 0, 1, 1, 6, 1, 3, 3 47 | }; 48 | 49 | const unsigned char opcode_params[] = { 50 | // 00 through 0f 51 | PARAM_FORM_NUM, 52 | PARAM_FORM_REG, 53 | PARAM_FORM_NUM, 54 | PARAM_FORM_REG, 55 | PARAM_FORM_NUM, 56 | PARAM_FORM_REG, 57 | PARAM_FORM_NUM, 58 | PARAM_FORM_REG, 59 | PARAM_FORM_REG, 60 | PARAM_FORM_REG, 61 | PARAM_FORM_NUM, 62 | PARAM_FORM_REG, 63 | PARAM_FORM_REG, 64 | PARAM_FORM_REG, 65 | PARAM_FORM_REG, 66 | PARAM_FORM_NUM, 67 | 68 | // f0 through ff 69 | PARAM_FORM_NOTHING, 70 | PARAM_FORM_NUM, 71 | PARAM_FORM_REG_REG_NUM, 72 | PARAM_FORM_REG_REG_REG, 73 | PARAM_FORM_REG_REG_REG, 74 | PARAM_FORM_NOTHING, 75 | PARAM_FORM_BUTTONMAP, 76 | PARAM_FORM_BUTTONMAP, 77 | PARAM_FORM_ADDRESS, 78 | PARAM_FORM_REG, 79 | PARAM_FORM_ADDRESS, 80 | PARAM_FORM_ADDRESS, 81 | PARAM_FORM_NUM, 82 | PARAM_FORM_NOTHING, 83 | PARAM_FORM_NOTHING, 84 | PARAM_FORM_NOTHING 85 | }; 86 | 87 | void drawEditor(); 88 | 89 | void insertOperation(bool updateJumps); 90 | void deleteOperation(bool updateJumps); 91 | 92 | void printRegister(unsigned char x, unsigned char y, unsigned char num); 93 | void printButtonMap(unsigned char x, unsigned char y, unsigned char num); 94 | void printButton(unsigned char x, unsigned char y, unsigned char num); 95 | 96 | unsigned char getOpcodeParamForm(unsigned char opcode); 97 | unsigned char elementCount(unsigned char line); 98 | 99 | void drawCodeLines(unsigned char start); 100 | void drawCodeLine(unsigned char x, unsigned char y, unsigned char line, unsigned char opcode, unsigned char param); 101 | void drawOpcodeAndParam(unsigned char x, unsigned char y, unsigned char opcode, unsigned char param); 102 | void drawOpcode(unsigned char x, unsigned char y, unsigned char id); 103 | void drawParam(unsigned char x, unsigned char y, unsigned char param, unsigned char form); 104 | void drawCursor(); 105 | 106 | void drawScrollbar(); 107 | void drawScrollLine(unsigned char x, unsigned short y, unsigned char line, unsigned char opcode, unsigned char param); 108 | 109 | void updateCursorDelay(); 110 | bool checkCursorDelay(); 111 | void moveCursor(char dx, char dy); 112 | void activateCursor(); 113 | void activateOpcode(unsigned char opcodeIndex); 114 | void activateParam(unsigned char paramIndex, unsigned char paramElement, unsigned char form); 115 | 116 | unsigned char menuBlinkDelay = 35; 117 | unsigned char menuBlinkEnabled = false; 118 | unsigned char menuReleaseActivate = true; 119 | 120 | void printRegister(unsigned char x, unsigned char y, unsigned char num) 121 | { 122 | arduboy.drawBitmap(x, y, gfx_registers + (unsigned short)8 * num, 8, 8, 1); 123 | } 124 | 125 | void printButtonMap(unsigned char x, unsigned char y, unsigned char num) 126 | { 127 | 128 | if(num & 128) printButton(x, y, 6); else printButton(x, y, 0); 129 | x += BUTTON_WIDTH + PARAM_SPACING; 130 | if(num & 64) printButton(x, y, 5); else printButton(x, y, 0); 131 | x += BUTTON_WIDTH + PARAM_SPACING; 132 | if(num & 32) printButton(x, y, 4); else printButton(x, y, 0); 133 | x += BUTTON_WIDTH + PARAM_SPACING; 134 | if(num & 16) printButton(x, y, 3); else printButton(x, y, 0); 135 | x += BUTTON_WIDTH + PARAM_SPACING; 136 | if(num & 8) printButton(x, y, 2); else printButton(x, y, 0); 137 | x += BUTTON_WIDTH + PARAM_SPACING; 138 | if(num & 4) printButton(x, y, 1); else printButton(x, y, 0); 139 | } 140 | 141 | void printButton(unsigned char x, unsigned char y, unsigned char num) 142 | { 143 | arduboy.drawBitmap(x, y, gfx_buttons + (unsigned short)8 * num, 8, 8, 1); 144 | } 145 | 146 | 147 | void drawOpcode(unsigned char x, unsigned char y, unsigned char id) 148 | { 149 | unsigned short offset = (id&0x0f) * OPCODE_WIDTH; 150 | 151 | if(id < 0xf0) 152 | { 153 | offset = ((id&0x0f)+16) * OPCODE_WIDTH; 154 | 155 | arduboy.drawBitmap(x+29, y, gfx_registers + 8*((id&0xf0)>>4), 8, 8, 1); 156 | } 157 | 158 | arduboy.drawBitmap(x, y, gfx_opcodes + offset, OPCODE_WIDTH, 8, 1); 159 | } 160 | 161 | 162 | void drawScrollbar() 163 | { 164 | unsigned char line; 165 | 166 | unsigned char opcode; 167 | unsigned char param; 168 | unsigned char index; 169 | unsigned char bonus; 170 | 171 | unsigned char scrollArea = WIDTH - 10; 172 | 173 | for(line = 0; line < PROGRAM_CODE_LENGTH/2; line++) 174 | { 175 | index = line*2; 176 | if(index >= PROGRAM_CODE_LENGTH) break; 177 | 178 | opcode = initCode[index]; 179 | param = initCode[index + 1]; 180 | 181 | drawScrollLine(scrollArea, offsetY + line*2 - cursorY*2 + 32, 2*line, opcode, param); 182 | } 183 | } 184 | 185 | void updateCursorDelay() 186 | { 187 | if(UP_DOWN || DOWN_DOWN || LEFT_DOWN || RIGHT_DOWN) 188 | { 189 | if(repeatDelay > 0) 190 | { 191 | repeatDelay--; 192 | } 193 | else if(repeatDelay == 0) 194 | { 195 | if(UP_DOWN || DOWN_DOWN || LEFT_DOWN || RIGHT_DOWN) 196 | { 197 | repeatDelay = 2; 198 | } 199 | } 200 | } 201 | else 202 | { 203 | repeatDelay = REPEAT_DELAY_TIME; 204 | } 205 | } 206 | 207 | bool checkCursorDelay() 208 | { 209 | return repeatDelay == 0; 210 | } 211 | 212 | unsigned char getOpcodeParamForm(unsigned char opcode) 213 | { 214 | if(opcode < 0xf0) 215 | { 216 | return opcode_params[opcode&0x0f]; 217 | } 218 | 219 | return opcode_params[opcode - 0xf0 + 0x10]; 220 | } 221 | 222 | void drawParam(unsigned char x, unsigned char y, unsigned char param, unsigned char form) 223 | { 224 | if(form == PARAM_FORM_NOTHING) 225 | { 226 | // do nothing 227 | } 228 | else if(form == PARAM_FORM_NUM) 229 | { 230 | printHex(x, y, param); 231 | printButton(x, y, 0); 232 | } 233 | else if(form == PARAM_FORM_ADDRESS) 234 | { 235 | // printAddress(x, y, param); 236 | printHex(x, y, param); 237 | printButton(x, y, 0); 238 | } 239 | else if(form == PARAM_FORM_BUTTONMAP) 240 | { 241 | printButtonMap(x, y, param); 242 | } 243 | else if(form == PARAM_FORM_REG) 244 | { 245 | printRegister(x, y, param); 246 | printButton(x, y, 0); 247 | } 248 | else if(form == PARAM_FORM_REG_REG_NUM) 249 | { 250 | printRegister(x, y, (param&0b00000111)); 251 | printButton(x, y, 0); 252 | 253 | printRegister(x+10, y, (param&0b00111000)>>3); 254 | printButton(x+10, y, 0); 255 | 256 | printHex(x+20, y, (param&0b11000000)>>6); 257 | printButton(x+20, y, 0); 258 | } 259 | else if(form == PARAM_FORM_REG_REG_REG) 260 | { 261 | printRegister(x, y, (param&0b00000111)); 262 | printButton(x, y, 0); 263 | 264 | printRegister(x+10, y, (param&0b00111000)>>3); 265 | printButton(x+10, y, 0); 266 | 267 | printRegister(x+20, y, ((param&0b11000000)>>6) + 4); 268 | printButton(x+20, y, 0); 269 | } 270 | } 271 | 272 | 273 | void drawCodeLine(unsigned char x, unsigned char y, unsigned char line, unsigned char opcode, unsigned char param) 274 | { 275 | if(lineFlags[line/2] == 1) 276 | { 277 | arduboy.fillRect(x, y+1, 3, 3, 1); 278 | } 279 | printHex(x+BREAKPOINT_WIDTH, y, line); 280 | drawChar(x+8+BREAKPOINT_WIDTH, y, ':'); 281 | drawOpcodeAndParam(x+12+BREAKPOINT_WIDTH, y, opcode, param); 282 | } 283 | 284 | const unsigned char opcodeLengths[] = { 285 | 1,3,3,2,2,3,3,2,2,2,1,1,1,3,1,1, 286 | 1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2 287 | }; 288 | 289 | void drawScrollLine(unsigned char x, unsigned short y, unsigned char line, unsigned char opcode, unsigned char param) 290 | { 291 | unsigned char form = getOpcodeParamForm(opcode); 292 | unsigned char opcodeLength = 0; 293 | 294 | if(line == cursorY*2) 295 | { 296 | arduboy.drawPixel(x-2, y, 1); 297 | } 298 | 299 | // if it's a register opcode 300 | if(opcode < 0xf0) 301 | { 302 | opcode &= 0x0f; 303 | opcode += 0x10; 304 | opcodeLength = opcodeLengths[opcode]; 305 | arduboy.drawPixel(x+2, y, 1); 306 | } 307 | // if it's a general opcode 308 | else 309 | { 310 | opcode = opcode - 0xf0; 311 | opcodeLength = opcodeLengths[opcode]; 312 | } 313 | 314 | arduboy.drawFastHLine(x, y, opcodeLength, 1); 315 | 316 | x += 4; 317 | 318 | if(form == PARAM_FORM_NOTHING) 319 | { 320 | // do nothing 321 | } 322 | else if(form == PARAM_FORM_NUM || form == PARAM_FORM_ADDRESS || form == PARAM_FORM_REG) 323 | { 324 | // draw a single pixel 325 | arduboy.drawPixel(x, y, 1); 326 | } 327 | else if(form == PARAM_FORM_REG_REG_NUM || form == PARAM_FORM_REG_REG_REG) 328 | { 329 | // draw three pixels 330 | arduboy.drawPixel(x, y, 1); 331 | arduboy.drawPixel(x+2, y, 1); 332 | arduboy.drawPixel(x+4, y, 1); 333 | } 334 | else if(form == PARAM_FORM_BUTTONMAP) 335 | { 336 | // draw the relevant pixels 337 | arduboy.drawFastHLine(x, y, 5, 1); 338 | } 339 | } 340 | 341 | 342 | void drawOpcodeAndParam(unsigned char x, unsigned char y, unsigned char opcode, unsigned char param) 343 | { 344 | unsigned char form = getOpcodeParamForm(opcode); 345 | 346 | drawOpcode(x, y, opcode); 347 | 348 | drawParam(x+OPCODE_WIDTH+PARAM_SPACING, y, param, form); 349 | } 350 | 351 | void drawCodeLines(unsigned char start) 352 | { 353 | unsigned char line; 354 | 355 | unsigned char opcode; 356 | unsigned char param; 357 | unsigned char index; 358 | unsigned char verticalOffset = 0; 359 | unsigned char newStart = start; 360 | 361 | if(newStart == 255) 362 | { 363 | newStart = 0; 364 | verticalOffset = 1; 365 | } 366 | 367 | for(line = 0; line < 8-verticalOffset; line++) 368 | { 369 | index = line*2 + newStart*2; 370 | if((line == 7) && (start == PROGRAM_CODE_LENGTH/2 - 7)) break; 371 | 372 | opcode = initCode[index]; 373 | param = initCode[index + 1]; 374 | drawCodeLine(0, verticalOffset*8 + offsetY + line*8 + 1, 2*(line+newStart), opcode, param); 375 | } 376 | } 377 | 378 | 379 | unsigned char elementCount(unsigned char line) 380 | { 381 | unsigned char index = line*2; 382 | unsigned char opcode = initCode[index]; 383 | unsigned char param = initCode[index+1]; 384 | unsigned char form = getOpcodeParamForm(opcode); 385 | 386 | return opcode_param_counts[form]; 387 | } 388 | 389 | void drawCursor() 390 | { 391 | unsigned char verticalOffset = 0; //(scrollY == 255) ? 8 : 0; 392 | unsigned char screenY = verticalOffset + offsetY + 8*(cursorY - scrollY); 393 | unsigned char screenHeight = 8; 394 | unsigned char screenX; 395 | unsigned char screenWidth; 396 | 397 | if(cursorX == 0) 398 | { 399 | screenX = BREAKPOINT_WIDTH; 400 | screenWidth = OPCODE_WIDTH + 1; 401 | } 402 | else 403 | { 404 | screenWidth = REGISTER_WIDTH; 405 | screenX = BREAKPOINT_WIDTH + OPCODE_WIDTH + PARAM_SPACING + (PARAM_SPACING + REGISTER_WIDTH)*(cursorX-1); 406 | } 407 | 408 | if(A_DOWN) 409 | { 410 | arduboy.drawRect(screenX + OPCODE_START - 2, screenY-1, screenWidth + 3, screenHeight+2, 1); 411 | } 412 | else 413 | { 414 | arduboy.invertRect(screenX + OPCODE_START - 1, screenY, screenWidth + 1, screenHeight); 415 | } 416 | } 417 | 418 | #define TONE_EDITOR_HORIZONTAL 880 419 | #define TONE_EDITOR_VERTICAL 440 420 | 421 | #define TONE_EDITOR_OPCODE 440 422 | #define TONE_EDITOR_PARAM 880 423 | 424 | #define TONE_EDITOR_VALUEUP 1200 425 | #define TONE_EDITOR_VALUEDOWN 1000 426 | #define TONE_EDITOR_BREAKON 660 427 | #define TONE_EDITOR_BREAKOFF 550 428 | 429 | void moveCursor(char dx, char dy) 430 | { 431 | unsigned char elements; 432 | if(dx < 0) 433 | { 434 | if(cursorX > 0) 435 | { 436 | cursorX--; 437 | if(cursorX == 0) 438 | arduboy.tunes.tone(TONE_EDITOR_OPCODE, 10); 439 | else 440 | arduboy.tunes.tone(TONE_EDITOR_PARAM, 10); 441 | 442 | } 443 | else 444 | { 445 | if(!lineFlags[cursorY]) 446 | { 447 | lineFlags[cursorY] = 1; 448 | arduboy.tunes.tone(TONE_EDITOR_BREAKON, 10); 449 | } 450 | else 451 | { 452 | lineFlags[cursorY] = 0; 453 | arduboy.tunes.tone(TONE_EDITOR_BREAKOFF, 10); 454 | } 455 | } 456 | } 457 | else if(dx > 0 && cursorX < elementCount(cursorY)) 458 | { 459 | cursorX++; 460 | arduboy.tunes.tone(TONE_EDITOR_PARAM, 10); 461 | } 462 | 463 | if(dy < 0 && cursorY > 0) 464 | { 465 | cursorY--; 466 | elements = elementCount(cursorY); 467 | if(cursorX > elements) cursorX = elements; 468 | if(cursorX == 0) 469 | arduboy.tunes.tone(TONE_EDITOR_OPCODE, 10); 470 | else 471 | arduboy.tunes.tone(TONE_EDITOR_PARAM, 10); 472 | } 473 | else if(dy > 0 && cursorY < (PROGRAM_CODE_LENGTH/2 - 1)) 474 | { 475 | cursorY++; 476 | elements = elementCount(cursorY); 477 | if(cursorX > elements) cursorX = elements; 478 | if(cursorX == 0) 479 | arduboy.tunes.tone(TONE_EDITOR_OPCODE, 10); 480 | else 481 | arduboy.tunes.tone(TONE_EDITOR_PARAM, 10); 482 | } 483 | 484 | if((cursorY+1 > scrollY+1 + 6) || (scrollY == 255 && cursorY >= 6)) 485 | { 486 | scrollY++; 487 | } 488 | else if(cursorY+1 < scrollY+1 + 1) 489 | { 490 | if(scrollY != 255) 491 | scrollY--; 492 | } 493 | } 494 | 495 | void activateCursor() 496 | { 497 | unsigned char index = cursorY*2; 498 | unsigned char opcode = initCode[index]; 499 | unsigned char param = initCode[index+1]; 500 | unsigned char form = getOpcodeParamForm(opcode); 501 | 502 | if(cursorX > 0) 503 | { 504 | activateParam(index+1, cursorX, form); 505 | } 506 | else 507 | { 508 | activateOpcode(index); 509 | } 510 | } 511 | 512 | #define TONE_EDITOR_OPCODE_UPREG 1000 513 | #define TONE_EDITOR_OPCODE_DOWNREG 800 514 | #define TONE_EDITOR_OPCODE_REG 900 515 | #define TONE_EDITOR_OPCODE_GENERAL 1200 516 | 517 | 518 | void activateOpcode(unsigned char opcodeIndex) 519 | { 520 | unsigned char oldVal = initCode[opcodeIndex]; 521 | 522 | if(LEFT_PRESSED) 523 | { 524 | if(modValue(initCode[opcodeIndex], -16, 0, 0x7f)) 525 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_DOWNREG, 10); 526 | } 527 | else if(RIGHT_PRESSED) 528 | { 529 | if(modValue(initCode[opcodeIndex], 16, 0, 0x7f)) 530 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_UPREG, 10); 531 | } 532 | else if(UP_PRESSED || (UP_DOWN && checkCursorDelay())) 533 | { 534 | // If among the register opcodes 535 | if(initCode[opcodeIndex] < 0xf0) 536 | { 537 | // If going past the highest in a set 538 | if(initCode[opcodeIndex]%16 == 15) 539 | 540 | // Go to general opcodes 541 | initCode[opcodeIndex] = 0xf0; 542 | else 543 | 544 | // Go to next register opcode 545 | initCode[opcodeIndex]++; 546 | } 547 | // If among the general opcodes 548 | else 549 | { 550 | // If not on the highest opcode 551 | if(initCode[opcodeIndex] != 0xff) 552 | 553 | // Go to the next opcode 554 | initCode[opcodeIndex]++; 555 | } 556 | 557 | if(oldVal != initCode[opcodeIndex]) 558 | { 559 | if(initCode[opcodeIndex] < 0xf0) 560 | { 561 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_REG, 10); 562 | } 563 | else 564 | { 565 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_GENERAL, 10); 566 | } 567 | } 568 | } 569 | else if(DOWN_PRESSED || (DOWN_DOWN && checkCursorDelay())) 570 | { 571 | // If among the register opcodes 572 | if(initCode[opcodeIndex] < 0xf0) 573 | { 574 | // Don't go past the lowest in a set 575 | if(initCode[opcodeIndex]%16 != 0) 576 | 577 | // Go to next register opcode 578 | initCode[opcodeIndex]--; 579 | } 580 | // If among the general opcodes 581 | else 582 | { 583 | // If going to the opcode before the beginning of the set 584 | if(initCode[opcodeIndex] == 0xf0) 585 | 586 | // Go to the set of register opcodes 587 | initCode[opcodeIndex] = 0x0f; 588 | 589 | else 590 | initCode[opcodeIndex]--; 591 | } 592 | 593 | if(oldVal != initCode[opcodeIndex]) 594 | { 595 | if(initCode[opcodeIndex] < 0xf0) 596 | { 597 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_REG, 10); 598 | } 599 | else 600 | { 601 | arduboy.tunes.tone(TONE_EDITOR_OPCODE_GENERAL, 10); 602 | } 603 | } 604 | } 605 | 606 | } 607 | 608 | void activateParam(unsigned char paramIndex, unsigned char paramElement, unsigned char form) 609 | { 610 | unsigned char val1, val2, val3; 611 | 612 | if(form == PARAM_FORM_NUM || form == PARAM_FORM_ADDRESS) 613 | { 614 | // number picker 615 | if(UP_PRESSED || (UP_DOWN && checkCursorDelay())) 616 | { 617 | if(modValue(initCode[paramIndex], 1, 0, 255)) 618 | { 619 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 620 | } 621 | } 622 | else if(DOWN_PRESSED || (DOWN_DOWN && checkCursorDelay())) 623 | { 624 | if(modValue(initCode[paramIndex], -1, 0, 255)) 625 | { 626 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 627 | } 628 | } 629 | else if(LEFT_PRESSED || (LEFT_DOWN && checkCursorDelay())) 630 | { 631 | if(modValue(initCode[paramIndex], -0x10, 0, 255)) 632 | { 633 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 634 | } 635 | } 636 | else if(RIGHT_PRESSED || (RIGHT_DOWN && checkCursorDelay())) 637 | { 638 | if(modValue(initCode[paramIndex], 0x10, 0, 255)) 639 | { 640 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 641 | } 642 | } 643 | } 644 | /* 645 | else if(form == PARAM_FORM_ADDRESS) 646 | { 647 | // address AKA NUMBER picker for now 648 | if(UP_PRESSED || (UP_DOWN && checkCursorDelay())) 649 | { 650 | 651 | if(modValue(initCode[paramIndex], 1, 0, 255)) 652 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 653 | } 654 | else if(DOWN_PRESSED || (DOWN_DOWN && checkCursorDelay())) 655 | { 656 | if(modValue(initCode[paramIndex], -1, 0, 255)); 657 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 658 | } 659 | } 660 | */ 661 | else if(form == PARAM_FORM_BUTTONMAP) 662 | { 663 | // toggle buttons individually 664 | if(A_PRESSED) 665 | { 666 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 667 | initCode[paramIndex] ^= (1<<(8-paramElement)); 668 | } 669 | } 670 | else if(form == PARAM_FORM_REG) 671 | { 672 | // register picker 673 | if(UP_PRESSED || (UP_DOWN && checkCursorDelay())) 674 | { 675 | if(modValue(initCode[paramIndex], 1, 0, 7)) 676 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 677 | } 678 | else if(DOWN_PRESSED || (DOWN_DOWN && checkCursorDelay())) 679 | { 680 | if(modValue(initCode[paramIndex], -1, 0, 7)) 681 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 682 | } 683 | } 684 | else if(form == PARAM_FORM_REG_REG_NUM || form == PARAM_FORM_REG_REG_REG) 685 | { 686 | val1 = (initCode[paramIndex] & 0b00000111); 687 | val2 = (initCode[paramIndex] & 0b00111000)>>3; 688 | val3 = (initCode[paramIndex] & 0b11000000)>>6; 689 | 690 | // pick a register or number 691 | if(UP_PRESSED || (UP_DOWN && checkCursorDelay())) 692 | { 693 | if(paramElement == 1) 694 | { 695 | if(modValue(val1, 1, 0, 7)) 696 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 697 | } 698 | else if(paramElement == 2) 699 | { 700 | if(modValue(val2, 1, 0, 7)) 701 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 702 | } 703 | else if(paramElement == 3) 704 | { 705 | if(modValue(val3, 1, 0, 3)) 706 | arduboy.tunes.tone(TONE_EDITOR_VALUEUP, 10); 707 | } 708 | } 709 | else if(DOWN_PRESSED || (DOWN_DOWN && checkCursorDelay())) 710 | { 711 | if(paramElement == 1) 712 | { 713 | if(modValue(val1, -1, 0, 7)) 714 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 715 | } 716 | else if(paramElement == 2) 717 | { 718 | if(modValue(val2, -1, 0, 7)) 719 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 720 | } 721 | else if(paramElement == 3) 722 | { 723 | if(modValue(val3, -1, 0, 3)) 724 | arduboy.tunes.tone(TONE_EDITOR_VALUEDOWN, 10); 725 | } 726 | } 727 | 728 | initCode[paramIndex] = val1 | (val2<<3) | (val3<<6); 729 | } 730 | } 731 | 732 | //#define MENU_BAR_ITEMS 4 733 | #define MENU_BAR_ITEMS 3 734 | 735 | unsigned char menuBarAnchors[] = { 736 | //3, 15, 30, 47 737 | 3, 15, 32 738 | }; 739 | unsigned char menuBarWidths[] = { 740 | 9, 17, 15 741 | //9, 15, 17, 15 742 | }; 743 | 744 | struct PullDown { 745 | unsigned char items; 746 | unsigned char w; 747 | unsigned char h; 748 | const unsigned char* img; 749 | }; 750 | 751 | PullDown pulldowns[MENU_BAR_ITEMS] = { 752 | //{4, 61, 27, gfx_iconmenu}, 753 | {1, 53, 6, gfx_iconmenu}, 754 | //{7, 39, 48, gfx_filemenu}, 755 | {4, 68, 27, gfx_editmenu}, 756 | {4, 65, 27, gfx_runmenu}, 757 | }; 758 | 759 | 760 | void drawPulldownSelection(unsigned char x, unsigned char y, unsigned char id, unsigned char cursorPos) 761 | { 762 | arduboy.fillRect(x+1, 1+y+7*(cursorPos-1), pulldowns[id].w, 7, 2); 763 | } 764 | 765 | void drawPulldown(unsigned char x, unsigned char y, unsigned char id, unsigned char cursorPos) 766 | { 767 | PullDown& pd = pulldowns[id]; 768 | 769 | arduboy.fillRect(x, y, pd.w+2, pd.h+4, 0); 770 | arduboy.drawFastHLine(x+1, y+pd.h+1, pd.w, 1); 771 | arduboy.drawFastHLine(x+1, y+pd.h+2, pd.w, 1); 772 | arduboy.drawBitmap(x+1, y+1, pd.img, pd.w, pd.h, 1); 773 | drawPulldownSelection(x, y, id, cursorPos); 774 | } 775 | 776 | unsigned char menuBarCursorX = 1; 777 | unsigned char menuBarCursorY = 0; 778 | 779 | void moveMenuBarCursor(char dx, char dy) 780 | { 781 | unsigned char ox = menuBarAnchors[menuBarCursorX]; 782 | 783 | if(dx < 0) 784 | { 785 | arduboy.tunes.tone(TONE_MENUBAR_CURSOR, 10); 786 | menuBarCursorX--; 787 | if(menuBarCursorX >= MENU_BAR_ITEMS) menuBarCursorX = MENU_BAR_ITEMS-1; 788 | if(menuBarCursorY >= pulldowns[menuBarCursorX].items + 1) 789 | menuBarCursorY = pulldowns[menuBarCursorX].items; 790 | } 791 | else if(dx > 0) 792 | { 793 | arduboy.tunes.tone(TONE_MENUBAR_CURSOR, 10); 794 | menuBarCursorX++; 795 | if(menuBarCursorX >= MENU_BAR_ITEMS) menuBarCursorX = 0; 796 | if(menuBarCursorY >= pulldowns[menuBarCursorX].items + 1) 797 | menuBarCursorY = pulldowns[menuBarCursorX].items; 798 | } 799 | 800 | if(dy < 0) 801 | { 802 | arduboy.tunes.tone(TONE_MENUBAR_CURSOR, 10); 803 | drawPulldownSelection(ox, 8, menuBarCursorX, menuBarCursorY); 804 | menuBarCursorY--; 805 | if(menuBarCursorY >= pulldowns[menuBarCursorX].items + 1) 806 | menuBarCursorY = pulldowns[menuBarCursorX].items; 807 | drawPulldownSelection(ox, 8, menuBarCursorX, menuBarCursorY); 808 | } 809 | else if(dy > 0) 810 | { 811 | arduboy.tunes.tone(TONE_MENUBAR_CURSOR, 10); 812 | drawPulldownSelection(ox, 8, menuBarCursorX, menuBarCursorY); 813 | menuBarCursorY++; 814 | if(menuBarCursorY >= pulldowns[menuBarCursorX].items + 1) 815 | menuBarCursorY = 0; 816 | drawPulldownSelection(ox, 8, menuBarCursorX, menuBarCursorY); 817 | } 818 | } 819 | 820 | void showAboutMenu() 821 | { 822 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 823 | 824 | arduboy.fillRect(31, 12, 62, 46, 0); 825 | arduboy.drawBitmap(31, 12, gfx_aboutdialog, 62, 46, 1); 826 | arduboy.display(); 827 | 828 | updateInput(); 829 | 830 | while(true) 831 | { 832 | if(!arduboy.nextFrame()) continue; 833 | 834 | updateInput(); 835 | 836 | if(B_PRESSED || A_PRESSED) 837 | return; 838 | } 839 | } 840 | 841 | void activateMenuBar() 842 | { 843 | // Icon Menu 844 | if(menuBarCursorX == MENU_ICON) 845 | { 846 | // About 847 | if(menuBarCursorY == 1) 848 | { 849 | showAboutMenu(); 850 | } 851 | 852 | // Calculator 853 | else if(menuBarCursorY == 3) 854 | { 855 | 856 | } 857 | 858 | // Control Panel 859 | else if(menuBarCursorY == 4) 860 | { 861 | 862 | } 863 | 864 | } 865 | // File Menu 866 | else if(menuBarCursorX == MENU_FILE) 867 | { 868 | // New 869 | if(menuBarCursorY == 1) 870 | { 871 | 872 | } 873 | 874 | // Open 875 | else if(menuBarCursorY == 2) 876 | { 877 | 878 | } 879 | 880 | // Receive 881 | else if(menuBarCursorY == 3) 882 | { 883 | 884 | } 885 | 886 | // Save 887 | else if(menuBarCursorY == 5) 888 | { 889 | 890 | } 891 | 892 | // Save As 893 | else if(menuBarCursorY == 6) 894 | { 895 | 896 | } 897 | 898 | // Send 899 | else if(menuBarCursorY == 7) 900 | { 901 | 902 | } 903 | } 904 | // Edit Menu 905 | else if(menuBarCursorX == MENU_EDIT) 906 | { 907 | 908 | // Insert 909 | if(menuBarCursorY == 1) 910 | { 911 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 912 | insertOperation(false); 913 | } 914 | 915 | // Insert and update jumps 916 | else if(menuBarCursorY == 2) 917 | { 918 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 919 | insertOperation(true); 920 | } 921 | 922 | // Delete 923 | else if(menuBarCursorY == 3) 924 | { 925 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 926 | deleteOperation(false); 927 | } 928 | 929 | // Delete and updage jumps 930 | else if(menuBarCursorY == 4) 931 | { 932 | arduboy.tunes.tone(TONE_MENUBAR_BEEP, 10); 933 | deleteOperation(true); 934 | } 935 | } 936 | // Run Menu 937 | else if(menuBarCursorX == MENU_RUN) 938 | { 939 | // Save 'n' Run 940 | if(menuBarCursorY == 1) 941 | { 942 | if(showRunProgramDialog()) 943 | { 944 | vmReset(&vms, true); 945 | vmRun(&vms); 946 | } 947 | } 948 | 949 | // Run 950 | else if(menuBarCursorY == 2) 951 | { 952 | vmReset(&vms, true); 953 | vmRun(&vms); 954 | } 955 | 956 | // Run W/O breakpoints 957 | else if(menuBarCursorY == 3) 958 | { 959 | vmReset(&vms, false); 960 | vmRun(&vms); 961 | } 962 | 963 | // Resume 964 | else if(menuBarCursorY == 4) 965 | { 966 | vmRun(&vms); 967 | } 968 | } 969 | } 970 | 971 | void drawMenuBar() 972 | { 973 | drawEditor(); 974 | unsigned char ox; 975 | 976 | ox = menuBarAnchors[menuBarCursorX]; 977 | 978 | arduboy.fillRect(0, 0, 128, 8, 0); 979 | arduboy.drawBitmap(0, 0, gfx_menubar, 128, 8, 1); 980 | arduboy.invertRect(ox, 0, menuBarWidths[menuBarCursorX], 8); 981 | arduboy.drawFastHLine(0, 8, WIDTH, 0); 982 | } 983 | 984 | 985 | void showMenuBar() 986 | { 987 | if(cursorY == scrollY) 988 | offsetY = 8; 989 | 990 | unsigned char repeatTimes; 991 | bool redraw = true; 992 | 993 | bool menuBlinkEnabled = true; 994 | 995 | arduboy.tunes.tone(TONE_MENUBAR_SHOW, 10); 996 | 997 | while(true) 998 | { 999 | if(!arduboy.nextFrame()) continue; 1000 | 1001 | arduboy.clear(); 1002 | 1003 | if(redraw) 1004 | { 1005 | drawMenuBar(); 1006 | 1007 | if(menuBarCursorY > 0) 1008 | drawPulldown(menuBarAnchors[menuBarCursorX], 8, menuBarCursorX, menuBarCursorY); 1009 | } 1010 | 1011 | arduboy.display(); 1012 | 1013 | updateInput(); 1014 | 1015 | if(LEFT_PRESSED) 1016 | { 1017 | moveMenuBarCursor(-1, 0); 1018 | redraw = true; 1019 | } 1020 | else if(RIGHT_PRESSED) 1021 | { 1022 | moveMenuBarCursor(1, 0); 1023 | redraw = true; 1024 | } 1025 | else if(UP_PRESSED) 1026 | { 1027 | moveMenuBarCursor(0, -1); 1028 | redraw = true; 1029 | } 1030 | else if(DOWN_PRESSED) 1031 | { 1032 | moveMenuBarCursor(0, 1); 1033 | redraw = true; 1034 | } 1035 | 1036 | 1037 | if((menuReleaseActivate && B_RELEASED) || (!menuReleaseActivate && A_PRESSED)) 1038 | { 1039 | if(menuBarCursorY > 0) 1040 | { 1041 | //if(menuBlinkEnabled) 1042 | if(menuBarCursorX != MENU_EDIT) 1043 | { 1044 | for(repeatTimes = 8; repeatTimes > 0; repeatTimes--) 1045 | { 1046 | drawPulldownSelection(menuBarAnchors[menuBarCursorX], 8, menuBarCursorX, menuBarCursorY); 1047 | arduboy.display(); 1048 | arduboy.tunes.tone(TONE_MENUBAR_FLIP, 10); 1049 | delay(menuBlinkDelay); 1050 | } 1051 | } 1052 | } 1053 | 1054 | arduboy.clear(); 1055 | drawMenuBar(); 1056 | arduboy.display(); 1057 | 1058 | activateMenuBar(); 1059 | break; 1060 | } 1061 | else if((menuReleaseActivate && A_PRESSED) || (!menuReleaseActivate && B_PRESSED)) 1062 | { 1063 | break; 1064 | } 1065 | } 1066 | 1067 | offsetY = 0; 1068 | } 1069 | 1070 | void drawEditor() 1071 | { 1072 | drawCodeLines(scrollY); 1073 | drawScrollbar(); 1074 | drawCursor(); 1075 | } 1076 | 1077 | void showEditor() 1078 | { 1079 | bool redraw = true; 1080 | 1081 | while(true) 1082 | { 1083 | if(!arduboy.nextFrame()) return; 1084 | 1085 | updateInput(); 1086 | 1087 | updateCursorDelay(); 1088 | 1089 | if(A_DOWN) 1090 | { 1091 | activateCursor(); 1092 | redraw = true; 1093 | } 1094 | else if((UP_PRESSED) || (UP_DOWN && checkCursorDelay())) 1095 | { 1096 | moveCursor(0, -1); 1097 | redraw = true; 1098 | } 1099 | else if((DOWN_PRESSED) || (DOWN_DOWN && checkCursorDelay())) 1100 | { 1101 | moveCursor(0, 11); 1102 | redraw = true; 1103 | } 1104 | else if(LEFT_PRESSED) 1105 | { 1106 | moveCursor(-1, 0); 1107 | redraw = true; 1108 | } 1109 | else if(RIGHT_PRESSED) 1110 | { 1111 | moveCursor(1, 0); 1112 | redraw = true; 1113 | } 1114 | 1115 | if(redraw) 1116 | { 1117 | arduboy.clear(); 1118 | drawEditor(); 1119 | 1120 | arduboy.display(); 1121 | } 1122 | 1123 | redraw = false; 1124 | 1125 | if(B_PRESSED) 1126 | { 1127 | showMenuBar(); 1128 | redraw = true; 1129 | } 1130 | } 1131 | } 1132 | 1133 | void insertOperation(bool updateJumps) 1134 | { 1135 | unsigned char index = cursorY * 2; 1136 | unsigned char lineIndex; 1137 | unsigned char jumpsModifiedStart = index; 1138 | 1139 | // Push down the lines 1140 | for(lineIndex = PROGRAM_CODE_LENGTH-2; lineIndex > index; lineIndex -= 2) 1141 | { 1142 | initCode[lineIndex] = initCode[lineIndex-2]; 1143 | initCode[lineIndex+1] = initCode[lineIndex-1]; 1144 | } 1145 | 1146 | initCode[lineIndex] = 0xf0; 1147 | initCode[lineIndex+1] = 0x00; 1148 | 1149 | // update the jumps 1150 | if(updateJumps) 1151 | { 1152 | for(lineIndex = 0; lineIndex < PROGRAM_CODE_LENGTH-2; lineIndex += 2) 1153 | { 1154 | if((initCode[lineIndex] == 0xf8) && (initCode[lineIndex+1] > jumpsModifiedStart)) 1155 | { 1156 | initCode[lineIndex+1] += 2; 1157 | } 1158 | } 1159 | } 1160 | } 1161 | 1162 | void deleteOperation(bool updateJumps) 1163 | { 1164 | unsigned char index = cursorY * 2; 1165 | unsigned char lineIndex; 1166 | unsigned char jumpsModifiedStart = index; 1167 | 1168 | for(lineIndex = index; lineIndex < PROGRAM_CODE_LENGTH-2; lineIndex += 2) 1169 | { 1170 | initCode[lineIndex] = initCode[lineIndex+2]; 1171 | initCode[lineIndex+1] = initCode[lineIndex+3]; 1172 | } 1173 | 1174 | initCode[lineIndex] = 0xf0; 1175 | initCode[lineIndex+1] = 0x00; 1176 | 1177 | // update the jumps 1178 | if(updateJumps) 1179 | { 1180 | for(lineIndex = 0; lineIndex < PROGRAM_CODE_LENGTH-2; lineIndex += 2) 1181 | { 1182 | if((initCode[lineIndex] == 0xf8) && (initCode[lineIndex+1] > jumpsModifiedStart)) 1183 | { 1184 | initCode[lineIndex+1] -= 2; 1185 | } 1186 | } 1187 | } 1188 | 1189 | } 1190 | --------------------------------------------------------------------------------