int main ( int argc, char** argv ) { SchObj robj,ret; int opt; char * fname = 0; char * expr = 0; #ifdef USE_BOEHM_GC GC_INIT(); #endif ensure_init_symtable(); init_reader(); init_port(); flag_use_profiler = 0; while ( (opt = getopt(argc,argv,"pf:e:")) != -1 ) { switch ( opt ) { case 'p': { flag_use_profiler = 1; } break; case 'f': { fname = SCH_MALLOC(strlen(optarg) + 1); strcpy(fname,optarg); } break; case 'e':{ expr = SCH_MALLOC(strlen(optarg) + 1); strcpy(expr,optarg); }break; }; } if ( expr ) { robj = sch_read_string(expr); ret = vm_compile(robj); SCH_WRITE(ret); SCH_DISPLAY(SCH_CHAR('\n')); } else if ( fname ) { sch_load(SCH_STRING_OBJ(SCH_STRING(fname))); } else { while ( 1 ) { robj = sch_read(NULL); ret = vm_compile(robj); SCH_WRITE(ret); } } return 0; }
int runtest(char*code,uint32_t correct_stacktop) { vm_init(); vm_compile(code); while(!vm.stopped) vm_run(); if(vm.stack[vm.sp]==correct_stacktop) return 0; fprintf(stderr,"unit test failed with code \"%s\"\n",code); fprintf(stderr,"stacktop=%x (should have been %x)\n", vm.stack[vm.sp],correct_stacktop); exit(1); }
void TocGen(const struct workset *ws, const struct pgc *fpc, const char *fname) /* writes the IFO for a VMGM. */ { static unsigned char buf[2048]; int nextsector, offset, i, j, vtsstart; const bool forcemenus = needmenus(ws->menus); FILE *h; h = fopen(fname, "wb"); memset(buf, 0, 2048); memcpy(buf, "DVDVIDEO-VMG", 12); buf[0x21] = 0x11; /* version number */ buf[0x27] = 1; /* number of volumes */ buf[0x29] = 1; /* volume number */ buf[0x2a] = 1; /* side ID */ write2(buf + 0x3e, ws->titlesets->numvts); /* number of title sets */ strncpy((char *)(buf + 0x40), PACKAGE_STRING, 31); /* provider ID */ buf[0x86] = 4; /* start address of FP_PGC = 0x400 */ nextsector = 1; write4(buf + 0xc4, nextsector); /* sector pointer to TT_SRPT (table of titles) */ nextsector += Create_TT_SRPT(0, ws->titlesets, 0); /* just to figure out how many sectors will be needed */ if (jumppad || forcemenus) { write4(buf + 0xc8, nextsector); /* sector pointer to VMGM_PGCI_UT (menu PGC table) */ nextsector += CreatePGC(0, ws, VTYPE_VMGM); } /*if*/ write4(buf + 0xd0, nextsector); /* sector pointer to VMG_VTS_ATRT (copies of VTS audio/subpicture attrs) */ /* I will output it immediately following IFO header */ nextsector += (8 + ws->titlesets->numvts * 0x30c + 2047) / 2048; /* round up size of VMG_VTS_ATRT to whole sectors */ if (jumppad || forcemenus) { write4(buf + 0xd8, nextsector); /* sector pointer to VMGM_C_ADT (menu cell address table) */ /* I make it follow VMG_VTS_ATRT */ nextsector += CreateCellAddressTable(0, ws->menus->vg); /* how much room it will need */ write4(buf + 0xdc, nextsector); /* sector pointer to VMGM_VOBU_ADMAP (menu VOBU address map) */ nextsector += numsectVOBUAD(ws->menus->vg); } /*if*/ write4(buf + 0x1c, nextsector - 1); /* last sector of IFO */ vtsstart = nextsector * 2; /* size of two copies of everything above including BUP */ if (jumppad || forcemenus) { write4(buf + 0xc0, nextsector); /* start sector of menu VOB */ vtsstart += getvoblen(ws->menus->vg); } /*if*/ write4(buf + 0xc, vtsstart - 1); /* last sector of VMG set (last sector of BUP) */ if (forcemenus) BuildAVInfo(buf + 256, ws->menus->vg); /* create FPC at 0x400 as promised */ buf[0x407] = (getratedenom(ws->menus->vg) == 90090 ? 3 : 1) << 6; // only set frame rate XXX: should check titlesets if there is no VMGM menu buf[0x4e5] = 0xec; /* offset to command table, low byte */ offset = 0x4f4; /* commands start here, after 8-byte header of command table */ if (fpc) { unsigned char *pi; if (fpc->posti || fpc->numsources || fpc->numbuttons || fpc->entries) { fprintf(stderr,"ERR: FPC can ONLY contain prei commands, nothing else\n"); exit(1); } /*if*/ if (ws->menus && ws->menus->numgroups) pi = vm_compile(buf + offset, buf + offset, ws, ws->menus->groups[0].pg, 0, fpc->prei, 2); // XXX: just use the first pgcgroup as a reference else pi = vm_compile(buf + offset, buf + offset, ws, 0, 0, fpc->prei, 2); if (!pi) { fprintf(stderr,"ERR: in FPC\n"); exit(1); } /*if*/ offset = (pi - buf - offset) / 8; /* number of instructions */ assert(offset <= 128); buf[0x4ed] = offset; /* number of pre commands, low byte */ } else { /* generate default FPC */ if (forcemenus) { buf[offset + 0] = 0x30; // jump to VMGM 1 buf[offset + 1] = 0x06; buf[offset + 2] = 0x00; buf[offset + 3] = 0x00; buf[offset + 4] = 0x00; buf[offset + 5] = 0x42; buf[offset + 6] = 0x00; buf[offset + 7] = 0x00; } else if (ws->titlesets->numvts && ws->titlesets->vts[0].hasmenu) { buf[offset + 0] = 0x30; // jump to VTSM vts=1, ttn=1, menu=1 buf[offset + 1] = 0x06; buf[offset + 2] = 0x00; buf[offset + 3] = 0x01; buf[offset + 4] = 0x01; buf[offset + 5] = 0x83; buf[offset + 6] = 0x00; buf[offset + 7] = 0x00; } else { buf[offset + 0] = 0x30; // jump to title 1 buf[offset + 1] = 0x02; buf[offset + 2] = 0x00; buf[offset + 3] = 0x00; buf[offset + 4] = 0x00; buf[offset + 5] = 0x01; buf[offset + 6] = 0x00; buf[offset + 7] = 0x00; } /*if*/ buf[0x4ed] = 1; /* number of pre commands, low byte */ } /*if*/ write2(buf + 0x4f2, 7 + buf[0x4ed] * 8); /* end address relative to command table */ write2(buf + 0x82 /* end byte address, low word, of VMGI_MAT */, 0x4ec + read2(buf + 0x4f2)); nfwrite(buf, 2048, h); Create_TT_SRPT(h, ws->titlesets, vtsstart); /* generate it for real */ // PGC if (jumppad || forcemenus) CreatePGC(h, ws, VTYPE_VMGM); /* VMG_VTS_ATRT contains copies of menu and title attributes from all titlesets */ /* output immediately following IFO header, as promised above */ memset(buf, 0, 2048); j = 8 + ws->titlesets->numvts * 4; write2(buf, ws->titlesets->numvts); /* number of titlesets */ write4(buf + 4, ws->titlesets->numvts * 0x30c + 8 - 1); /* end address (last byte of last VTS_ATRT) */ for (i = 0; i < ws->titlesets->numvts; i++) write4(buf + 8 + i * 4, j + i * 0x308); /* offset to VTS_ATRT i */ nfwrite(buf, j, h); for (i = 0; i < ws->titlesets->numvts; i++) /* output each VTS_ATRT */ { write4(buf, 0x307); /* end address */ memcpy(buf + 4, ws->titlesets->vts[i].vtscat, 4); /* VTS_CAT (copy of bytes 0x22 .. 0x25 of VTS IFO) */ memcpy(buf + 8, ws->titlesets->vts[i].vtssummary, 0x300); /* copy of VTS attributes (bytes 0x100 onwards of VTS IFO) */ nfwrite(buf, 0x308, h); j += 0x308; } /*for*/ j = 2048 - (j & 2047); if (j < 2048) { /* pad to next whole sector */ memset(buf, 0, j); nfwrite(buf, j, h); } /*if*/ if (jumppad || forcemenus) { CreateCellAddressTable(h, ws->menus->vg); /* actually generate VMGM_C_ADT */ CreateVOBUAD(h, ws->menus->vg); /* generate VMGM_VOBU_ADMAP */ } /*if*/ fflush(h); if (errno != 0) { fprintf(stderr, "\nERR: Error %d -- %s -- flushing VMGM\n", errno, strerror(errno)); exit(1); } /*if*/ fclose(h); } /*TocGen*/