#include #include "number.h" #define BUFFER_SIZE 16 UBYTE keyBuffer[BUFFER_SIZE]; UBYTE head, tail, exist; UBYTE cardinal; //DEC..0 HEX..1 BIN..2 DWORD dec[] = {10000000, 1000000, 100000, 10000, 1000, 100, 10, 1}; DWORD number, mod, stack[10]; UBYTE ans; void setData(UBYTE data) { UBYTE p; p = tail; keyBuffer[p++] = data; if(p == BUFFER_SIZE) p = 0; if(p != head) tail = p; exist = TRUE; } UBYTE getData() { UBYTE b; if(!exist) return 0xFF; b = keyBuffer[head++]; if(head == BUFFER_SIZE) head = 0; if(head == tail) exist = FALSE; return b; } void bufferClear() { head = 0; tail = 0; exist = FALSE; } void keyCodeReceive() { SC_REG &= 0x7f; //受信停止 setData(SB_REG); SC_REG = 0x80; //受信開始 } //10進数表示 void decimalDisplay(UBYTE y, DWORD n) { UBYTE i, digit, top = TRUE; DWORD num; if(n < 0) { set_bkg_tiles(0, y * 2, 2, 2, number_tiles + 64); num = -n; } else { num = n; set_bkg_tiles(0, y * 2, 2, 2, NULL); } if(num > 99999999) num %= 100000000; for(i=0; i!=8; i++) //<、<=、>、>=より==と!=の方が生成コードが短くなる { digit = num / dec[i]; num %= dec[i]; if(digit != 0) top = FALSE; if(digit == 0 && top) { if(i != 7) set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, 0); else set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, number_tiles + digit * 4); } else set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, number_tiles + digit * 4); } } //16進数表示 void hexDisplay(UBYTE y, DWORD n) { UBYTE i, digit, top = TRUE; DWORD num; num = n & 0xFFFFFFFF; for(i=0; i!=8; i++) { digit = (num >> ((7 - i) * 4)) & 0xF; if(digit != 0) top = FALSE; if(digit == 0 && top) { if(i != 7) set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, 0); else set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, number_tiles + digit * 4); } else set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, number_tiles + digit * 4); } } //2進数表示 void binaryDisplay(UBYTE y, DWORD n) { UBYTE i, digit; DWORD num; num = n & 0xFF; for(i=0; i!=8; i++) { digit = (num >> (7 - i)) & 1; set_bkg_tiles(i * 2 + 2, y * 2, 2, 2, number_tiles + digit * 4); } } void display() { switch(cardinal) { case 0: decimalDisplay(1, number); break; case 1: hexDisplay(1, number); break; case 2: binaryDisplay(1, number); break; } } void displayAll() { switch(cardinal) { case 0: decimalDisplay(1, number); decimalDisplay(2, mod); decimalDisplay(4, stack[0]); decimalDisplay(5, stack[1]); decimalDisplay(6, stack[2]); decimalDisplay(7, stack[3]); break; case 1: hexDisplay(1, number); hexDisplay(2, mod); hexDisplay(4, stack[0]); hexDisplay(5, stack[1]); hexDisplay(6, stack[2]); hexDisplay(7, stack[3]); break; case 2: binaryDisplay(1, number); binaryDisplay(2, mod); binaryDisplay(4, stack[0]); binaryDisplay(5, stack[1]); binaryDisplay(6, stack[2]); binaryDisplay(7, stack[3]); break; } } void push() { UBYTE i; for(i=9; i>0; i--) stack[i] = stack[i - 1]; stack[0] = number; number = 0; } DWORD pop() { DWORD p; UBYTE i; p = stack[0]; for(i=0; i<9; i++) stack[i] = stack[i + 1]; stack[9] = 0; return p; } void div(DWORD n, DWORD d) { //割られる数より割る数の絶対値が大きいとフリーズする if((UDWORD)n < (UDWORD)d) { number = 0; if(n < 0) mod = -n; else mod = n; } else { number = n / d; mod = n % d; if(mod < 0) mod = -mod; } } void main() { UBYTE i, keyin; DWORD n, w; cardinal = 0; //10進数 ans = FALSE; //背景データ収納(数字) set_bkg_data(1, number_data_length, number_data); //表示初期化 number = 0; mod = 0; for(i=0; i!=9; i++) stack[i] = 0; displayAll(); SHOW_BKG; //背景表示 bufferClear(); set_interrupts(SIO_IFLAG); add_SIO(keyCodeReceive); SC_REG = 0x80; //受信開始(外部クロック) while(1) { if(exist) { keyin = getData(); if(keyin < 16) //0〜F { if(ans) { push(); displayAll(); ans = FALSE; } n = keyin; if(cardinal == 0) { if(n < 10) //入力は0〜9 { if(number < 0) //マイナス { w = number * 10 - n; if(w > -100000000) //最小値を超えない number = w; } else { w = number * 10 + n; if(w < 100000000) //最大値を超えない number = w; } } } else if(cardinal == 1) { if((number & 0xF0000000) == 0) //最大値を超えない { number <<= 4; number += n; } } else { if(n < 2) //入力は0〜1 { if((number & 0x80) == 0) //最大値を超えない { number <<= 1; number += n; } } } display(); } else { switch(keyin) { case 16: //Enter push(); ans = FALSE; break; case 17: //+ if(cardinal) //16,2進数 number = (UDWORD)pop() + (UDWORD)number; else //10進数 number = pop() + number; ans = TRUE; break; case 18: //- if(cardinal) //16,2進数 number = (UDWORD)pop() - (UDWORD)number; else //10進数 number = pop() - number; ans = TRUE; break; case 19: //* if(cardinal) //16,2進数 number = (UDWORD)pop() * (UDWORD)number; else //10進数 number = pop() * number; ans = TRUE; break; case 20: //'/' if(number == 0) //0で除算 break; if(cardinal) //16,2進数 { w = pop(); n = number; number = (UDWORD)w / (UDWORD)n; mod = (UDWORD)w % (UDWORD)n; } else //10進数 div(pop(), number); ans = TRUE; break; case 21: //OR number = pop() | number; ans = TRUE; break; case 22: //NOT number = ~number; ans = TRUE; break; case 23: //AND number = pop() & number; ans = TRUE; break; case 24: //XOR n = number; //別の変数に代入しないと正しく演算できない number = pop() ^ n; ans = TRUE; break; case 25: //'+/-' if(cardinal == 0) number = -number; break; case 26: //Clear number = 0; ans = FALSE; break; case 27: //Clear Stack number = 0; for(i=0; i!=10; i++) stack[i] =0; ans = FALSE; break; case 28: //Cardinal if(cardinal == 0) { cardinal = 1; for(i=1; i!=8; i++) set_bkg_tiles(0, i * 2, 2, 2, NULL); } else if(cardinal == 1) { cardinal = 2; for(i=1; i!=8; i++) set_bkg_tiles(0, i * 2, 2, 2, NULL); } else cardinal = 0; break; } displayAll(); mod = 0; } } } }