void showstack() { Z80 &cpu = CpuMgr.Cpu(); for (unsigned i = 0; i < stack_size; i++) { char xx[10]; //-2:1234 //SP:1234 //+2: if (!i) *(unsigned*)xx = WORD2('-','2'); else if (i==1) *(unsigned*)xx = WORD2('S','P'); else sprintf(xx, (i > 8) ? "%X" : "+%X", (i-1)*2); sprintf(xx+2, ":%02X%02X", cpu.DirectRm(cpu.sp+(i-1)*2+1), cpu.DirectRm(cpu.sp+(i-1)*2)); tprint(stack_x, stack_y+i, xx, W_OTHER); } tprint(stack_x, stack_y-1, "stack", W_TITLE); frame(stack_x, stack_y, 7, stack_size, FRAME); }
int C_Fdd::addfile(uint8_t *hdr, uint8_t *data) { t.seek(this, 0, 0, LOAD_SECTORS); s_SecHdr *s8 = t.get_sector(9); if (!s8) return 0; unsigned len = hdr[13]; unsigned pos = s8->data[0xE4] * 0x10; s_SecHdr *dir = t.get_sector(1 + pos / 0x100); if (!dir) return 0; if (WORD2(s8->data[0xE5], s8->data[0xE6]) < len) return 0; // disk full memcpy(dir->data + (pos & 0xFF), hdr, 14); dir->data[(pos & 0xFF) + 14] = s8->data[0xE1]; dir->data[(pos & 0xFF) + 15] = s8->data[0xE2]; t.write_sector(1 + pos / 0x100, dir->data); pos = s8->data[0xE1] + 16*s8->data[0xE2]; s8->data[0xE1] = (pos + len) & 0x0F; s8->data[0xE2] = (pos + len) >> 4; s8->data[0xE4]++; int newlen = WORD2(s8->data[0xE5], s8->data[0xE6]) - len; s8->data[0xE5] = (newlen & 0xFF); s8->data[0xE6] = (newlen >> 8); t.write_sector(9, s8->data); // goto next track. s8 become invalid for (unsigned i = 0; i < len; i++, pos++) { t.seek(this, pos/32, (pos/16) & 1, LOAD_SECTORS); if (!t.trkd) return 0; if (!t.write_sector((pos&0x0F)+1, data+i*0x100)) return 0; } return 1; }
unsigned calc(const Z80 *cpu, unsigned *script) { unsigned stack[64]; unsigned *sp = stack-1, x; while (*script) { switch (*script++) { case 'M': *sp = cpu->DirectRm(*sp); break; case '!': *sp = !*sp; break; case '~': *sp = ~*sp; break; case '+': *(sp-1) += *sp; goto arith; case '-': *(sp-1) -= *sp; goto arith; case '*': *(sp-1) *= *sp; goto arith; case '/': if (*sp) *(sp-1) /= *sp; goto arith; case '%': if (*sp) *(sp-1) %= *sp; goto arith; case '&': *(sp-1) &= *sp; goto arith; case '|': *(sp-1) |= *sp; goto arith; case '^': *(sp-1) ^= *sp; goto arith; case WORD2('-','>'): *(sp-1) = cpu->DirectRm(*sp + sp[-1]); goto arith; case WORD2('>','>'): *(sp-1) >>= *sp;goto arith; case WORD2('<','<'): *(sp-1) <<= *sp;goto arith; case WORD2('!','='): *(sp-1) = (sp[-1]!=*sp);goto arith; case '=': case WORD2('=','='): *(sp-1) = (sp[-1]==*sp);goto arith; case WORD2('<','='): *(sp-1) = (sp[-1]<=*sp);goto arith; case WORD2('>','='): *(sp-1) = (sp[-1]>=*sp);goto arith; case WORD2('|','|'): *(sp-1) = (sp[-1]||*sp);goto arith; case WORD2('&','&'): *(sp-1) = (sp[-1]&&*sp);goto arith; case '<': *(sp-1) = (sp[-1]<*sp);goto arith; case '>': *(sp-1) = (sp[-1]>*sp);goto arith; arith: sp--; break; case DB_CHAR: case DB_SHORT: x = *script++; goto push; case DB_PCHAR: x = *(u8*)*script++; goto push; case DB_PSHORT: x = 0xFFFF & *(unsigned*)*script++; goto push; case DB_PINT: x = *(unsigned*)*script++; goto push; case DB_PFUNC: x = ((func_t)*script++)(); goto push; push: *++sp = x; break; } // switch (*script) } // while if (sp != stack) calcerr = 1; return *sp; }
void spectrum_frame() { if (!temp.inputblock || input.keymode != K_INPUT::KM_DEFAULT) input.make_matrix(); init_snd_frame(); init_frame(); if(cpu.dbgchk) { cpu.SetDbgMemIf(); z80dbg::z80loop(); } else { cpu.SetFastMemIf(); z80fast::z80loop(); } if (modem.open_port) modem.io(); flush_snd_frame(); flush_frame(); showleds(); if (!cpu.iff1 || // int disabled in CPU ((conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3) && !(comp.pFF77 & 0x20))) // int disabled by ATM hardware { unsigned char *mp = am_r(cpu.pc); if (cpu.halted) { strcpy(statusline, "CPU HALTED"); statcnt = 10; } if (*(unsigned short*)mp == WORD2(0x18,0xFE) || ((*mp == 0xC3) && *(unsigned short*)(mp+1) == (unsigned short)cpu.pc)) { strcpy(statusline, "CPU STOPPED"); statcnt = 10; } } comp.t_states += conf.frame; cpu.t -= conf.frame; cpu.eipos -= conf.frame; comp.frame_counter++; }
int FDD::write_td0(FILE *ff) { u8 zerosec[256] = { 0 }; u8 td0hdr[12] = { 0 }; *(u16*)td0hdr = WORD2('T','D'); td0hdr[4] = 21; td0hdr[6] = 2; td0hdr[9] = (u8)sides; if (*dsc) td0hdr[7] = 0x80; *(u16*)(td0hdr + 10) = crc16(td0hdr, 10); fwrite(td0hdr, 1, 12, ff); if (*dsc) { u8 inf[0x200] = { 0 }; strcpy((char*)inf+10, dsc); unsigned len = strlen(dsc)+1; *(unsigned*)(inf+2) = len; *(u16*)inf = crc16(inf+2, len+8); fwrite(inf, 1, len+10, ff); } unsigned c; //Alone Coder 0.36.7 for (/*unsigned*/ c = 0; c < cyls; c++) for (unsigned s = 0; s < sides; s++) { t.seek(this,c,s,LOAD_SECTORS); u8 bf[16]; *bf = t.s; bf[1] = c, bf[2] = s; bf[3] = (u8)crc16(bf, 3); fwrite(bf, 1, 4, ff); for (unsigned sec = 0; sec < t.s; sec++) { if (!t.hdr[sec].data) { t.hdr[sec].data = zerosec, t.hdr[sec].datlen = 256, t.hdr[sec].l = 1; } *(unsigned*)bf = *(unsigned*)&t.hdr[sec]; bf[4] = 0; // flags bf[5] = (u8)crc16(t.hdr[sec].data, t.hdr[sec].datlen); *(u16*)(bf+6) = t.hdr[sec].datlen + 1; bf[8] = 0; // compression type = none fwrite(bf, 1, 9, ff); if (fwrite(t.hdr[sec].data, 1, t.hdr[sec].datlen, ff) != t.hdr[sec].datlen) return 0; } } c = WORD4(0xFF,0,0,0); if (fwrite(&c, 1, 4, ff) != 4) return 0; return 1; }
int FDD::read_td0() { if (*(short*)snbuf == WORD2('t','d')) { // packed disk u8 *tmp = (u8*)malloc(snapsize); memcpy(tmp, snbuf+12, snapsize-12); snapsize = 12+unpack_lzh(tmp, snapsize-12, snbuf+12); ::free(tmp); //*(short*)snbuf = WORD2('T','D'); } char dscbuffer[sizeof(dsc)]; *dscbuffer = 0; u8 *start = snbuf+12; if (snbuf[7] & 0x80) // coment record { start += 10; unsigned len = *(u16*)(snbuf+14); start += len; if (len >= sizeof dsc) len = sizeof(dsc)-1; memcpy(dscbuffer, snbuf+12+10, len); dscbuffer[len] = 0; } u8 *td0_src = start; unsigned max_cyl = 0, max_head = 0; for (;;) { u8 s = *td0_src; // Sectors if (s == 0xFF) break; max_cyl = max(max_cyl, td0_src[1]); // PhysTrack max_head = max(max_head, td0_src[2]); // PhysSide td0_src += 4; // sizeof(track_rec) for (; s; s--) { u8 flags = td0_src[4]; td0_src += 6; // sizeof(sec_rec) assert(td0_src <= snbuf + snapsize); if (td0_src > snbuf + snapsize) return 0; td0_src += *(u16*)td0_src + 2; // data_len } } newdisk(max_cyl+1, max_head+1); memcpy(dsc, dscbuffer, sizeof dsc); td0_src = start; for (;;) { u8 t0[16384]; u8 *dst = t0; u8 *trkh = td0_src; td0_src += 4; // sizeof(track_rec) if (*trkh == 0xFF) break; t.seek(this, trkh[1], trkh[2], JUST_SEEK); unsigned s = 0; for (unsigned se = 0; se < trkh[0]; se++) { TTd0Sec *SecHdr = (TTd0Sec *)td0_src; unsigned sec_size = 128U << (SecHdr->n & 3); // [vv] u8 flags = SecHdr->flags; // printf("fl=%x\n", flags); // printf("c=%d, h=%d, s=%d, n=%d\n", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n); if (flags & (TD0_SEC_NO_ID | TD0_SEC_NO_DATA | TD0_SEC_NO_DATA2)) // skip sectors with no data & sectors without headers { td0_src += sizeof(TTd0Sec); // sizeof(sec_rec) unsigned src_size = *(u16*)td0_src; // printf("sz=%d\n", src_size); td0_src += 2; // data_len u8 *end_packed_data = td0_src + src_size; /* u8 method = *td0_src++; printf("m=%d\n", method); switch(method) { case 0: { char name[MAX_PATH]; sprintf(name, "%02d-%d-%03d-%d.trk", SecHdr->c, SecHdr->h, SecHdr->s, SecHdr->n); FILE *f = fopen(name, "wb"); fwrite(td0_src, 1, src_size - 1, f); fclose(f); break; } case 1: { unsigned n = *(u16*)td0_src; td0_src += 2; u16 data = *(u16*)td0_src; printf("len=%d, data=%04X\n", n, data); break; } } */ td0_src = end_packed_data; continue; } // c, h, s, n t.hdr[s].c = SecHdr->c; t.hdr[s].s = SecHdr->h; t.hdr[s].n = SecHdr->s; t.hdr[s].l = SecHdr->n; t.hdr[s].c1 = t.hdr[s].c2 = 0; t.hdr[s].data = dst; td0_src += sizeof(TTd0Sec); // sizeof(sec_rec) unsigned src_size = *(u16*)td0_src; td0_src += 2; // data_len u8 *end_packed_data = td0_src + src_size; memset(dst, 0, sec_size); switch (*td0_src++) // Method { case 0: // raw sector memcpy(dst, td0_src, src_size-1); break; case 1: // repeated 2-byte pattern { unsigned n = *(u16*)td0_src; td0_src += 2; u16 data = *(u16*)td0_src; for (unsigned i = 0; i < n; i++) *(u16*)(dst+2*i) = data; break; } case 2: // RLE block { u16 data; u8 s; u8 *d0 = dst; do { switch (*td0_src++) { case 0: // Zero count means a literal data block for (s = *td0_src++; s; s--) *dst++ = *td0_src++; break; case 1: // repeated fragment s = *td0_src++; data = *(u16*)td0_src; td0_src += 2; for ( ; s; s--) { *(u16*)dst = data; dst += 2; } break; default: goto shit; } } while (td0_src < end_packed_data); dst = d0; break; } default: // error! shit: errexit("bad TD0 file"); } dst += sec_size; td0_src = end_packed_data; s++; } t.s = s; t.format(); } return 1; }
void savesnddialog() { sound_stop(); //Alone Coder unsigned end; //Alone Coder 0.36.7 if (savesndtype) { if (savesndtype == 1) { // wave unsigned fsize = ftell(savesnd); fseek(savesnd, 0, SEEK_SET); fsize -= sizeof wavhdr; *(unsigned*)(wavhdr+4) = fsize+0x2c-8; *(unsigned*)(wavhdr+0x28) = fsize; fwrite(wavhdr, 1, sizeof wavhdr, savesnd); MessageBox(wnd, "WAV save done", "Save sound", MB_ICONINFORMATION); } else { // vtx savesndtype = 0; u8 *newb = (u8*)malloc(vtxbuffilled); for (/*unsigned*/ end = 0; end < (int)vtxbuffilled && silence(end); end += 14); vtxbuffilled -= end; memcpy(vtxbuf, vtxbuf+end, vtxbuffilled); for (end = vtxbuffilled; end && silence(end-14); end -= 14); vtxbuffilled = end; int nrec = vtxbuffilled/14; for (int i = 0; i < nrec; i++) for (int j = 0; j < 14; j++) newb[j*nrec+i] = vtxbuf[i*14+j]; free(vtxbuf); FILE *ff = fopen("vtx.tmp", "wb"); if (!ff) return; fwrite(newb, 1, vtxbuffilled, ff); fclose(ff); STARTUPINFO si = { sizeof si }; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; PROCESS_INFORMATION pi; char Parh[] = "lha a vtx.lzh vtx.tmp"; if (CreateProcess(0, Parh, 0, 0, 0, 0, 0, 0, &si, &pi)) { WaitForSingleObject(pi.hProcess, 5000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); DeleteFile("vtx.tmp"); } else { DeleteFile("vtx.tmp"); MessageBox(wnd, "LHA.EXE not found in %PATH%", 0, MB_ICONERROR); return; } ff = fopen("vtx.lzh", "rb"); if (!ff) return; fseek(ff, 0x22, SEEK_SET); unsigned packed = fread(newb, 1, vtxbuffilled, ff)-1; fclose(ff); DeleteFile("vtx.lzh"); DialogBox(hIn, MAKEINTRESOURCE(IDD_VTX), wnd, VtxDlg); vtxheader.sig = (vtxchip & 1) ? WORD2('y','m') : WORD2('a','y'); static u8 ste[] = { 1, 2, 0 }; vtxheader.stereo = ste[vtxchip/2]; vtxheader.ayfq = conf.sound.ayfq; vtxheader.intfq = 50; vtxheader.year = vtxyear; vtxheader.rawsize = vtxbuffilled; fwrite(&vtxheader, 1, 0x10, savesnd); fwrite(vtxname, 1, strlen(vtxname)+1, savesnd); fwrite(vtxauthor, 1, strlen(vtxauthor)+1, savesnd); fwrite(vtxsoft, 1, strlen(vtxsoft)+1, savesnd); fwrite(vtxtracker, 1, strlen(vtxtracker)+1, savesnd); fwrite(vtxcomm, 1, strlen(vtxcomm)+1, savesnd); fwrite(newb, 1, packed, savesnd); } fclose(savesnd); savesndtype = 0; } else { OPENFILENAME ofn = { 0 }; char sndsavename[0x200]; *sndsavename = 0; ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME); ofn.lpstrFilter = "All sound (WAV)\0*.wav\0AY sound (VTX)\0*.vtx\0"; ofn.lpstrFile = sndsavename; ofn.nMaxFile = sizeof sndsavename; ofn.lpstrTitle = "Save Sound"; ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; ofn.hwndOwner = wnd; ofn.nFilterIndex = 1; if (GetSaveFileName(&ofn)) { char *name = sndsavename; for (char *x = name; *x; x++) if (*x == '\\') name = x+1; if (!strchr(name, '.')) { if (ofn.nFilterIndex == 1) strcat(sndsavename, ".wav"); else strcat(sndsavename, ".vtx"); } savesnd = fopen(ofn.lpstrFile, "wb"); if (!savesnd) MessageBox(wnd, "Can't create file", 0, MB_ICONERROR); else if (ofn.nFilterIndex == 2) { // vtx savesndtype = 2; vtxbuf = 0; } else { // wave. all params, except fq are fixed: 16bit,stereo *(unsigned*)(wavhdr+0x18) = conf.sound.fq; // fq *(unsigned*)(wavhdr+0x1C) = conf.sound.fq*4; // bitrate fwrite(wavhdr, 1, 44, savesnd); // header savesndtype = 1; } } } eat(); sound_play(); //Alone Coder }
u8 toscript(char *script, unsigned *dst) { unsigned *d1 = dst; static struct { u16 op; u8 prior; } prio[] = { { '(', 10 }, { ')', 0 }, { '!', 1 }, { '~', 1 }, { 'M', 1 }, { WORD2('-','>'), 1 }, { '*', 2 }, { '%', 2 }, { '/', 2 }, { '+', 3 }, { '-', 3 }, { WORD2('>','>'), 4 }, { WORD2('<','<'), 4 }, { '>', 5 }, { '<', 5 }, { '=', 5 }, { WORD2('>','='), 5 }, { WORD2('<','='), 5 }, { WORD2('=','='), 5 }, { WORD2('!','='), 5 }, { '&', 6 }, { '^', 7 }, { '|', 8 }, { WORD2('&','&'), 9 }, { WORD2('|','|'), 10 } }; const Z80 &cpu = CpuMgr.Cpu(); DECL_REGS(regs, cpu); unsigned sp = 0; unsigned stack[128]; for (char *p = script; *p; p++) if (p[1] != 0x27) *p = toupper(*p); while (*script) { if (*(u8*)script <= ' ') { script++; continue; } if (*script == '\'') { // char *dst++ = DB_CHAR; *dst++ = script[1]; if (script[2] != '\'') return 0; script += 3; continue; } if ( isalnum(*script) ) { unsigned r = -1, p = *(unsigned*)script; unsigned ln = 0; for (int i = 0; i < _countof(regs); i++) { unsigned mask = 0xFF; ln = 1; if (regs[i].reg & 0xFF00) mask = 0xFFFF, ln = 2; if (regs[i].reg & 0xFF0000) mask = 0xFFFFFF, ln = 3; if (regs[i].reg & 0xFF000000) mask = 0xFFFFFFFF, ln = 4; if (regs[i].reg == (p & mask)) { r = i; break; } } if (r != -1) { script += ln; switch (regs[r].size) { case 0: *dst++ = DB_PFUNC; break; case 1: *dst++ = DB_PCHAR; break; case 2: *dst++ = DB_PSHORT; break; case 4: *dst++ = DB_PINT; break; default: errexit("BUG01"); } *dst++ = (unsigned)regs[r].ptr; continue; } else if ( *script != 'M' ) { // number if (*script > 'F') return 0; for (r = 0; isalnum(*script) && *script <= 'F'; script++) r = r*0x10 + ((*script >= 'A') ? *script-'A'+10 : *script-'0'); *dst++ = DB_SHORT; *dst++ = r; continue; } } // find operation u8 pr = 0xFF; unsigned r = *script++; if (strchr("<>=&|-!", (char)r) && strchr("<>=&|", *script)) r = r + 0x100 * (*script++); for (int i = 0; i < _countof(prio); i++) { if (prio[i].op == r) { pr = prio[i].prior; break; } } if (pr == 0xFF) return 0; if (r != '(') { while (sp && ((stack[sp] >> 16 <= pr) || (r == ')' && (stack[sp] & 0xFF) != '('))) { // get from stack *dst++ = stack[sp--] & 0xFFFF; } } if (r == ')') sp--; // del opening bracket else stack[++sp] = r+0x10000*pr; // put to stack if ((int)sp < 0) return 0; // no opening bracket } // empty stack while (sp) { if ((stack[sp] & 0xFF) == '(') return 0; // no closing bracket *dst++ = stack[sp--] & 0xFFFF; } *dst = DB_STOP; calcerr = 0; calc(&cpu, d1); return (1-calcerr); }