IPS(Interpreter for Process Structures) for mbed
Dependencies: ConfigFile FATFileSystem mbed
IPS port from linux/unix version.
mbed_blinky.ips
0 VAR led1 " LED1 " DigitalOut led1 ! : main ANFANG 1 JA? 1 led1 @ write 200 wait_ms 0 led1 @ write 200 wait_ms DANN/NOCHMAL ; main
- ips-02.tgz - ips for linux/unix
- ipsdoc.zip - document
- https://bitbucket.org/va009039/ips/
BaseIPS.cpp
- Committer:
- va009039
- Date:
- 2015-05-24
- Revision:
- 4:b62b40563944
- Parent:
- 2:908338b1151a
File content as of revision 4:b62b40563944:
// BaseIPS.cpp 2015/5/22 #include <algorithm> #include "mbed.h" #include "BaseIPS.h" #ifndef NO_MATH #include <math.h> #define Round(x) ( (x>=0) ? (int)(x+0.5) : (int)(x-0.5) ) #endif BaseIPS::BaseIPS() { PS = 0xfff8; RS = 0x4f8; depth=0; idle=0; input_ptr = 512; cycle = 0; inputfile = NULL; } u16 BaseIPS::peek(u16 a) { return peekB(a) | peekB(a + 1)<<8; } void BaseIPS::poke(u16 a, u16 w) { pokeB(a, w & 0xff); pokeB(a + 1, w>>8); } u32 BaseIPS::peek32(u16 a) { return peekB(a) | peekB(a + 1)<<8 | peekB(a + 2)<<16 | peekB(a + 3)<<24; } void BaseIPS::push_ps(u16 w) { PS -= 2; poke(PS, w); } u16 BaseIPS::pull_ps() { PS += 2; return peek(PS - 2); } void BaseIPS::push_rs(u16 w) { RS -= 2; poke(RS, w); } u16 BaseIPS::pull_rs() { RS += 2; return peek(RS - 2); } void BaseIPS::c_rumpelstilzchen(void) { // 0 } void BaseIPS::c_defex(void) { // 1 push_rs(PPC); PPC = HP; depth++; } void BaseIPS::c_consex(void) { // 2 push_ps(peek(HP)); } void BaseIPS::c_varex(void) { // 3 push_ps(HP); } void BaseIPS::c_retex(void) { // 4 depth--; PPC = pull_rs(); } void BaseIPS::c_get(void) { // 5 poke(PS, peek(peek(PS))); } void BaseIPS::c_getB(void) { // 6 poke(PS, peekB(peek(PS))); } void BaseIPS::c_put(void) { // 7 u16 a = pull_ps(); u16 v = pull_ps(); if (peek(a) != v) idle=0; poke(a, v); } void BaseIPS::c_putB(void) { // 8 u16 a = pull_ps(); u16 v = pull_ps(); if (peekB(a) != v) idle=0; pokeB(a, v); idle=0; } void BaseIPS::c_1bliteral(void) { // 9 push_ps(peekB(PPC)); PPC++; } void BaseIPS::c_2bliteral(void) { // 10 push_ps(peek(PPC)); PPC += 2; } void BaseIPS::c_bronz(void) { // 11 if ((pull_ps() & 1) == 0) PPC=peek(PPC); else PPC += 2; } void BaseIPS::c_jump(void) { // 12 PPC = peek(PPC); } void BaseIPS::c_weg(void) { // 13 PS += 2; } void BaseIPS::c_pweg(void) { // 14 PS += 4; } void BaseIPS::c_plus(void) { // 15 s16 v = pull_ps(); poke(PS, peek(PS) + v); } void BaseIPS::c_minus(void) { // 16 s16 v = pull_ps(); poke(PS, peek(PS) - v); } void BaseIPS::c_dup(void) { // 17 push_ps(peek(PS)); } void BaseIPS::c_pdup(void) { // 18 push_ps(peek(PS + 2)); push_ps(peek(PS + 2)); } void BaseIPS::c_vert(void) { // 19 s16 h=peek(PS); poke(PS, peek(PS + 2)); poke(PS + 2, h); } void BaseIPS::c_zwo(void) { // 20 push_ps(peek(PS+2)); } void BaseIPS::c_rdu(void) { // 21 s16 h=peek(PS); poke(PS, peek(PS+2)); poke(PS+2, peek(PS+4)); poke(PS+4, h); } void BaseIPS::c_rdo(void) { // 22 s16 h=peek(PS+4); poke(PS+4, peek(PS+2)); poke(PS+2, peek(PS)); poke(PS, h); } void BaseIPS::c_index(void) { // 23 push_ps(peek(RS)); } void BaseIPS::c_s_to_r(void) { // 24 push_rs(pull_ps()); } void BaseIPS::c_r_to_s(void) { // 25 push_ps(pull_rs()); } void BaseIPS::c_eqz(void) { // 26 poke(PS,(peek(PS)==0)); } void BaseIPS::c_gz(void) { // 27 poke(PS,((s16)peek(PS)>0)); } void BaseIPS::c_lz(void) { // 28 poke(PS,((s16)peek(PS)<0)); } void BaseIPS::c_geu(void) { // 29 u16 a,b; b=pull_ps(); a=peek(PS); poke(PS,a>=b); } void BaseIPS::c_f_vergl(void) { // 30 int t; u16 n,a1,a2; n=pull_ps(); a2=pull_ps(); a1=peek(PS); t=1; do { int b; b=(s16)peekB(a1++)-(s16)peekB(a2++); if (b>0) t=2; else if (b<0) t=0; n=(n-1)&0xff; } while (n); poke(PS,t); } void BaseIPS::c_nicht(void) { // 31 poke(PS, 0xffff^peek(PS)); } void BaseIPS::c_und(void) { // 32 u16 v = pull_ps(); poke(PS, v & peek(PS)); } void BaseIPS::c_oder(void) { // 33 u16 v = pull_ps(); poke(PS, v | peek(PS)); } void BaseIPS::c_exo(void) { // 34 u16 v = pull_ps(); poke(PS, v ^ peek(PS)); } void BaseIPS::c_bit(void) { // 35 poke(PS, 1<<peek(PS)); } void BaseIPS::c_cbit(void) { // 36 int a = pull_ps(); int b = (pull_ps())&0x07; pokeB(a, peekB(a)&~(1<<b) ); } void BaseIPS::c_sbit(void) { // 37 int a,b; a=pull_ps(); b=(pull_ps())&0x07; pokeB(a, peekB(a)|(1<<b) ); } void BaseIPS::c_tbit(void) { // 38 int a,b; a=pull_ps(); b=(peek(PS))&0x07; if (peekB(a)&(1<<b)) poke(PS,1); else poke(PS,0); } void BaseIPS::loop_sharedcode(int i) { int l; l=(s16)peek(RS); if (i<=l) { push_rs(i); PPC=peek(PPC); } else { pull_rs(); PPC+=2; } } void BaseIPS::c_jeex(void) { // 39 PPC=peek(PPC); push_rs(pull_ps()); loop_sharedcode((s16)pull_ps()); } void BaseIPS::c_loopex(void) { // 40 loop_sharedcode((s16)(pull_rs()+1)); } void BaseIPS::c_plusloopex(void) { // 41 int i; i=(s16)(pull_rs()); loop_sharedcode(i+(s16)pull_rs()); } void BaseIPS::c_fieldtrans(void) { // 42 /* note: cannot call memcpy() here, because memcpy()'s behaviour is not defined when source and destination areas overlap */ /* memmove() cannot be used either, because its behaviour for overlap is different from what IPS expects */ int n,d,s,b; n=pull_ps(); d=pull_ps(); s=pull_ps(); do { b=peekB(s++); pokeB(d++,b); n=(n-1)&0xff; } while (n); if (d<=0x400) redraw=1; idle=0; } void BaseIPS::c_pmul(void) { // 43 u32 c = pull_ps() * pull_ps(); push_ps((s16)(c&0xffff)); push_ps(c>>16); } void BaseIPS::c_pdiv(void) { // 44 u32 q,n; u16 d,nh,nl,r; d=pull_ps(); nh=pull_ps(); nl=pull_ps(); n=(nh<<16)+nl; if (d==0) { q=0xffff; r=0; } else { q=n/d; r=n%d; if (q>=0x10000) { q=0xffff; r=0; } } push_ps(q); push_ps(r); } void BaseIPS::c_tue(void) { // 45 HP = pull_ps(); } void BaseIPS::c_polyname(void) { // 46 u32 x,p,d; d=pull_ps(); x=pull_ps(); p=pull_ps(); x= x | (p&0xff00) | ((p&0xff)<<16); p = d ^ x ^ (x>>1) ^ (x>>2) ^ (x>>7); x = x ^ ((p&0xff)<<24); x >>= 7; push_ps( (x&0xff00) | ((x>>16)&0xff) ); push_ps( (x&0xff) ); } void BaseIPS::c_scode(void) { // 47 int i; u32 nd; int offs=peek(a_Os); i=peek(a_NDptr); nd=peek32(i); i=peek(a_P3); while (i) { i+=offs; if ( ( (peek32(i) ^ nd) & 0xffffff3f) ==0) { push_ps(i+6); return; } i=peek(i+4); } push_ps(0); } void BaseIPS::c_cscan(void) { // 48 int a; int pi,pe; int comment=0; pi=peek(a_PI); pe=peek(a_PE); a=pull_ps(); if (a==1) { while (pi<=pe) { if (comment) { if (peekB(pi)==')') comment=0; } else { if (peekB(pi)=='(') comment=1; else if (peekB(pi)!=' ') { poke(a_PI,pi); push_ps(1); return; } } pi++; } push_ps(0); poke(a_P2,1); return; } else { while (pi<=pe) { if (peekB(pi)==' ') { break; } pi++; } poke(a_PI,pi); push_ps(0); } } void BaseIPS::c_chs(void) { // 49 poke(PS,-(s16)peek(PS)); } void BaseIPS::c_cyc2(void) { // 50 u32 ch,a,crcc; int i; ch=pull_ps(); a=pull_ps(); crcc=(a>>8)|((a&0xff)<<8); ch<<=8; for (i=0;i<=7;i++) { //int test; //test=(ch^crcc)&0x8000; crcc<<=1; ch<<=1; if ((ch^crcc)&0x10000) crcc^=0x1021; } push_ps( ((crcc&0xff)<<8) | ((crcc>>8)&0xff) ); } void BaseIPS::c_close(void) { // 51 if (inputfile) { file_close(inputfile); inputfile = NULL; } } void BaseIPS::c_open(void) { // 52 if (inputfile) { file_close(inputfile); } size_t namelen = pull_ps(); int namestart = pull_ps(); char filename[256]; namelen = std::min(namelen, sizeof(filename)-1); for(size_t i = 0; i < namelen; i++) { filename[i] = peekB(namestart + i); } filename[namelen] = '\0'; inputfile = file_open(filename); push_ps(inputfile != NULL ? 1 : 0); } void BaseIPS::c_oscli(void) { // 53 error("OSCLI not implemented!"); } void BaseIPS::c_load(void) { // 54 error("LOAD not implemented!"); } void BaseIPS::c_save(void) { // 55 int namelen = pull_ps(); int namestart = pull_ps(); int end = pull_ps(); int start = pull_ps(); char filename[256]; if (namelen > 255) namelen = 255; for(int i = 0; i < namelen; i++) { filename[i] = peekB(namestart + i); } filename[namelen] = 0; void* fh = file_open(filename, "wb"); if (fh == NULL) { push_ps(0); return; } for(int i = start; i < end; i++) { file_putc(peekB(i), fh); } file_close(fh); push_ps(1); } void BaseIPS::c_setkbptr(void) { // 56 input_ptr = pull_ps() & 0x3ff; } void BaseIPS::c_getPS(void) { // 57 push_ps(PS); } void BaseIPS::c_setPS(void) { // 58 PS=pull_ps(); } #ifndef NO_MATH void BaseIPS::c_rp_code(void) { // 59 double theta,x,y,r; pull_ps(); y=(s16)pull_ps(); x=(s16)pull_ps(); theta=((s16)pull_ps())/10430.38; /* convert to radians */ theta+=atan2(y,x); r=sqrt(x*x+y*y)*1.6468; push_ps(Round(theta*10430.38)); push_ps((int)(r+0.5)); push_ps(0); } void BaseIPS::c_tr_code(void) { // 60 double theta,x,y,r; pull_ps(); y=(s16)pull_ps(); x=(s16)pull_ps(); theta=((s16)pull_ps())/10430.38; /* convert to radians */ theta+=atan2(y,x); r=sqrt(x*x+y*y)*1.6468; push_ps(0); push_ps(Round(r*cos(theta))); push_ps(Round(r*sin(theta))); } #else void BaseIPS::c_rp_code(void) { error("c_rp_code not implemented!\n"); } void BaseIPS::c_tr_code(void) { error("c_tr_code not implemented!\n"); } #endif void BaseIPS::c_swap3(void) { // 61 u16 h; h=peek(PS+6); poke(PS+6,peek(PS)); poke(PS,h); h=peek(PS+8); poke(PS+8,peek(PS+2)); poke(PS+2,h); h=peek(PS+10); poke(PS+10,peek(PS+4)); poke(PS+4,h); } void BaseIPS::c_defchar(void) { // 62 error("DEFCHAR not implemented!\n"); } void BaseIPS::c_pplus(void) { // 63 u32 h=pull_ps(); u32 b=(h<<16)+pull_ps(); h=pull_ps(); u32 a=(h<<16)+pull_ps(); u32 c=a+b; push_ps(c&0xffff); push_ps(c>>16); } void BaseIPS::c_pminus(void) { // 64 u32 h = pull_ps(); u32 b = (h<<16)+pull_ps(); h = pull_ps(); u32 a = (h<<16)+pull_ps(); u32 c = a - b; push_ps(c&0xffff); push_ps(c>>16); } void BaseIPS::do_20ms(void) { pokeB(UHR, peekB(UHR) + 2); // 20ms if (peekB(UHR) == 100) { pokeB(UHR, 0); pokeB(UHR+1, peekB(UHR+1) + 1); if (peekB(UHR+1) == 60) { pokeB(UHR+1, 0); pokeB(UHR+2, peekB(UHR+2) + 1); if (peekB(UHR+2) == 60) { pokeB(UHR+2, 0); pokeB(UHR+3, peekB(UHR+3) + 1); if (peekB(UHR+3) == 24) { pokeB(UHR+3, 0); poke(UHR+4, peek(UHR+4) + 1); } } } } const int sus[4]={SU0,SU1,SU2,SU3}; for (int i = 0; i < 4; i++) { int su=sus[i]; if ((peekB(su)&1) == 0) { if (peekB(su) != 0) { pokeB(su, peekB(su) - 2); } else { if (peekB(su+1) != 0) { pokeB(su, 98); pokeB(su+1, peekB(su+1) - 1); } else { if (peekB(su+2) != 0) { pokeB(su+1, 59); pokeB(su+2, peekB(su+2) - 1); } else { if (peekB(su+3) != 0) { pokeB(su+2, 255); pokeB(su+3, peekB(su+3) - 1); } else { pokeB(su, 1); } } } } } } } void BaseIPS::read_inputfile(void) { for(int i = 0x200; i < 0x400; i++) { pokeB(i, ' '); } do { int ch = file_getc(inputfile); if (ch<1) { if (input_ptr == peek(a_PI)) { file_close(inputfile); inputfile = NULL; pokeB(LOADFLAG, 0); input_ptr = 0x200; } break; } if (ch=='\r') { /* ignore \r, we expect at least also a \n as end-of-line */ } else if (ch=='\n') { input_ptr=(input_ptr&0xffc0)+64; } else { pokeB(input_ptr++,ch); } } while (input_ptr<1024 && inputfile); /* 1024 = TVE */ if (input_ptr!=peek(a_PI)) { pokeB(READYFLAG,1); poke(a_PE,input_ptr-1); idle=0; } } void BaseIPS::emulator() { PPC = 0x0400; input_ptr = peek(a_PI); while(1) { HP = peek(PPC); PPC += 2; exec: u16 CPC = peek(HP); HP += 2; trace(cycle++, PPC-2, HP-2, CPC, PS, RS); switch(CPC) { case 0: c_rumpelstilzchen(); break; case 1: c_defex(); break; case 2: c_consex(); break; case 3: c_varex(); break; case 4: c_retex(); break; case 5: c_get(); break; case 6: c_getB(); break; case 7: c_put(); break; case 8: c_putB(); break; case 9: c_1bliteral(); break; case 10: c_2bliteral(); break; case 11: c_bronz(); break; case 12: c_jump(); break; case 13: c_weg(); break; case 14: c_pweg(); break; case 15: c_plus(); break; case 16: c_minus(); break; case 17: c_dup(); break; case 18: c_pdup(); break; case 19: c_vert(); break; case 20: c_zwo(); break; case 21: c_rdu(); break; case 22: c_rdo(); break; case 23: c_index(); break; case 24: c_s_to_r(); break; case 25: c_r_to_s(); break; case 26: c_eqz(); break; case 27: c_gz(); break; case 28: c_lz(); break; case 29: c_geu(); break; case 30: c_f_vergl(); break; case 31: c_nicht(); break; case 32: c_und(); break; case 33: c_oder(); break; case 34: c_exo(); break; case 35: c_bit(); break; case 36: c_cbit(); break; case 37: c_sbit(); break; case 38: c_tbit(); break; case 39: c_jeex(); break; case 40: c_loopex(); break; case 41: c_plusloopex(); break; case 42: c_fieldtrans(); break; case 43: c_pmul(); break; case 44: c_pdiv(); break; case 45: c_tue(); goto exec; case 46: c_polyname(); break; case 47: c_scode(); break; case 48: c_cscan(); break; case 49: c_chs(); break; case 50: c_cyc2(); break; case 51: c_close(); break; case 52: c_open(); break; case 53: c_oscli(); break; case 54: c_load(); break; case 55: c_save(); break; case 56: c_setkbptr(); break; case 57: c_getPS(); break; case 58: c_setPS(); break; case 59: c_rp_code(); break; case 60: c_tr_code(); break; case 61: c_swap3(); break; case 62: c_defchar(); break; case 63: c_pplus(); break; case 64: c_pminus(); break; default: usercode(CPC); break; } do_io(); if (test_20ms()) { do_20ms(); } if (inputfile) { if (!(peekB(READYFLAG)&1) && (peekB(LOADFLAG)&1)) { read_inputfile(); } } } } void BaseIPS::load_image(const u8* image, int size) { for(int i = 0; i < size; i++) { pokeB(i, *image++); } } void BaseIPS::command(const char* s) { if (s) { int cmd_len = strlen(s); for(int i = 0; i < cmd_len; i++) { pokeB(i + 64*8, *s++); } poke(a_PE, 0x200 + cmd_len); pokeB(READYFLAG, 1); } }