void bootstrap1() { /* * Try and read the first sector off the diskette */ setAH(2); /* read */ setAL(1); /* 1 block */ #ifdef SECURE if ((IBOOL) config_inquire(C_SECURE, NULL)) { setDH(0); /* Head 0 */ setDL(0x80); /* on Hard Disk */ } else { setDX(0); /* head 0 on drive 0 (floppy)*/ } #else setDX(0); /* head 0 on drive 0 (floppy)*/ #endif setCX(1); /* track 0, sector 1 */ setES(DOS_SEGMENT); /* Load address */ setBX(DOS_OFFSET); }
Crlp4002::Crlp4002(CPObject *parent):CPObject(parent) { //[constructor] Q_UNUSED(parent) setfrequency( 0); BackGroundFname = P_RES(":/rlh1000/rlp4002.png"); setcfgfname("rlp4002"); pTIMER = new Ctimer(this); pKEYB->setMap("rlp4002.map"); setDXmm(227); setDYmm(95); setDZmm(31); // Ratio = 3,57 setDX(848);//Pc_DX = 75; setDY(340);//Pc_DY = 20; rotate = false; slotChanged = false; connected = false; rts = false; cts = false; memsize = 0x2000; InitMemValue = 0x7f; SlotList.clear(); SlotList.append(CSlot(8 , 0x0000 , P_RES(":/rlh1000/Telecomputing_2.bin") , "" , CSlot::ROM , "ROM")); }
Ce500::Ce500(CPObject *parent) : CpcXXXX(parent) { //[constructor] setfrequency( (int) 3072000/3); setcfgfname(QString("e500")); SessionHeader = "E500PKM"; Initial_Session_Fname ="e500.pkm"; BackGroundFname = P_RES(":/e500/pc-e500.png"); LcdFname = P_RES(":/e500/e500lcd.png"); SymbFname = P_RES(":/e500/e500symb.png"); memsize = 0x100000; InitMemValue = 0xff; /* ROM area(c0000-fffff) S3: */ SlotList.clear(); SlotList.append(CSlot(256, 0x40000 , "" , "" , RAM , "RAM S1")); SlotList.append(CSlot(256, 0x80000 , "" , "" , RAM , "RAM S2")); SlotList.append(CSlot(256, 0xC0000 , P_RES(":/e500/s3.rom"), "e500/s3.rom" , ROM , "ROM S3")); PowerSwitch = 0; Pc_Offset_X = Pc_Offset_Y = 0; setDXmm(200); setDYmm(100); setDZmm(14); setDX(715); setDY(357); Lcd_X = 69; Lcd_Y = 99; Lcd_DX = 240;//168;//144 ; Lcd_DY = 32; Lcd_ratio_X = 348.0/240; Lcd_ratio_Y = 60.0/32; Lcd_Symb_X = 69;//(int) (45 * 1.18); Lcd_Symb_Y = 79;//(int) (35 * 1.18); Lcd_Symb_DX = 348; Lcd_Symb_DY = 20; Lcd_Symb_ratio_X = 1;//1.18; pLCDC = new Clcdc_e500(this); pCPU = new Csc62015(this); pTIMER = new Ctimer(this); pKEYB = new Ckeyb(this,"e500.map"); pHD61102_1 = new CHD61102(this); pHD61102_2 = new CHD61102(this); // pRP5C01 = new CRP5C01(this); start2khz = 0; start4khz = 0; Xin=Xout=false; tmp_state=0; ioFreq=0; }
Cfp100::Cfp100(CPObject *parent):Cce515p(this) { setfrequency( 4000); ioFreq = 0; setcfgfname(QString("fp100")); BackGroundFname = P_RES(":/ext/fp100.png"); delete pKEYB; pKEYB = new Ckeyb(this,"x710.map"); setDXmm(302);//Pc_DX_mm = 256; setDYmm(120);//Pc_DY_mm = 185; setDZmm(36);//Pc_DZ_mm = 42; setDX(1078);//Pc_DX = 895; setDY(817);//Pc_DY = 615; printerACK = false; printerBUSY = false; capot = LoadImage(QSize(849,274),P_RES(":/ext/fp100-capot.png")); head = LoadImage(QSize(79,161),P_RES(":/ext/fp100head.png")); cable = LoadImage(QSize(75,10),P_RES(":/ext/fp100cable.png")); margin = 40; Paper_DX = 960+2*margin; setPaperPos(QRect(154,26,731,300)); }
Cpc2021::Cpc2021(CPObject *parent):Cprinter(parent) { //[constructor] setfrequency( 0); pc2021buf = 0; pc2021display= 0; //bells = 0; charTable = 0; margin = 25; ToDestroy = false; BackGroundFname = P_RES(":/ext/pc-2021.png"); setcfgfname("pc2021"); settop(10); setposX(0); pTIMER = new Ctimer(this); KeyMap = KeyMappc2021; KeyMapLenght= KeyMappc2021Lenght; pKEYB->setMap("pc2021.map"); setDXmm(108); setDYmm(130); setDZmm(43); setDX(386); setDY(464); setPaperPos(QRect(70,-3,275,149)); ctrl_char = false; t = 0; c = 0; rmtSwitch = false; internal_device_code = 0x0f; }
Cce1600f::Cce1600f(CPObject *parent):CPObject(parent) { BackGroundFname = P_RES(":/ext/ce-1600f.png"); setcfgfname(QString("ce1600f")); setDXmm(95); setDYmm(120); setDZmm(39); setDX(339); setDY(428); pKEYB->setMap("ce1600f.map",0); bus = new CbusPc1500(); error = false; ready = true; ChangedDisk = false; busy = false; ack = false; isDisk = true; writeProtect = false; motorRunning = false; sector = 0; startMotorState = 0; countWrite = 0; memset(data,0,sizeof(data)); }
Crlh1000::Crlh1000(CPObject *parent) : CpcXXXX(parent) { //[constructor] setfrequency( (int) 4194300/4); setcfgfname(QString("rlh1000")); SessionHeader = "RLH1000PKM"; Initial_Session_Fname ="rlh1000.pkm"; BackGroundFname = P_RES(":/rlh1000/rlh1000.png"); LeftFname = P_RES(":/rlh1000/rlh1000Left.png"); // RightFname = P_RES(":/rlh1000/rlh1000Right.png"); BackFname = P_RES(":/rlh1000/rlh1000BackOpen.png"); TopFname = P_RES(":/rlh1000/rlh1000Top.png"); BottomFname = P_RES(":/rlh1000/rlh1000Bottom.png"); backDoorImage = new QImage(QString(P_RES(":/rlh1000/trappe.png"))); memsize = 0x20000; InitMemValue = 0x7F; SlotList.clear(); SlotList.append(CSlot(8 , 0x0000 , "" , "" , CSlot::RAM , "RAM")); SlotList.append(CSlot(8 , 0x2000 , "" , "" , CSlot::ROM , "Ext ROM")); SlotList.append(CSlot(16, 0x4000 , "" , "" , CSlot::ROM , "ROM Capsules 1")); SlotList.append(CSlot(16, 0x8000 , "" , "" , CSlot::NOT_USED , "Ext RAM")); SlotList.append(CSlot(16, 0xC000 , P_RES(":/rlh1000/HHC-rom-C000-FFFF.bin"),"" , CSlot::ROM , "ROM")); SlotList.append(CSlot(16, 0x10000 , "" , "" , CSlot::ROM , "ROM Capsules 2")); SlotList.append(CSlot(16, 0x14000 , "" , "" , CSlot::ROM , "ROM Capsules 3")); // Ratio = 3,57 setDXmm(227); setDYmm(95); setDZmm(31); setDX(811); setDY(340); PowerSwitch = 0; pLCDC = new Clcdc_rlh1000(this, QRect(205,55,159*2.5,8*3), QRect()); pCPU = new Cm6502(this); m6502 = (Cm6502*)pCPU; pTIMER = new Ctimer(this); pKEYB->setMap("rlh1000.map"); backdoorKeyIndex=0; capsuleKeyIndex=0; ioFreq = 0; extrinsicRAM = 0xff; extrinsicROM = 0xff; bus = new CbusPanasonic(); backdoorOpen = false; backdoorFlipping = false; m_backdoorAngle = 0; }
void SS_boomerang::mouseReleaseEvent(QMouseEvent *event) { double new_dphi = sqrt((event->globalX() - getPrevMouseX()) * (event->globalX() - getPrevMouseX()) + (event->globalY() - getPrevMouseY()) * (event->globalY() - getPrevMouseY())); setDX((event->globalX() - getPrevMouseX()) / 50); setDY((event->globalY() - getPrevMouseY()) / 50); setDAngle(new_dphi / 10000); }
void SS_boomerang::mousePressEvent(QMouseEvent *event) { setDAngle(0); setDX(0); setDY(0); setPrevMouseX(event->globalX()); setPrevMouseY(event->globalY()); }
Cpb1000::Cpb1000(CPObject *parent) : CpcXXXX(parent) { //[constructor] setfrequency( (int) 910000/1); ioFreq = 0; setcfgfname(QString("pb1000")); SessionHeader = "PB1000PKM"; Initial_Session_Fname ="pb1000.pkm"; BackGroundFname = P_RES(":/pb1000/pb-1000.png"); back = new QImage(P_RES(":/pb1000/pb1000back.png")); memsize = 0x20000; InitMemValue = 0xff; SlotList.clear(); SlotList.append(CSlot(6 , 0x0000 , P_RES(":/pb1000/rom0.bin") , "" , CSlot::ROM , "CPU ROM")); SlotList.append(CSlot(8 , 0x6000 , "" , "" , CSlot::RAM , "RAM0")); SlotList.append(CSlot(32, 0x8000 , P_RES(":/pb1000/rom1.bin") , "" , CSlot::ROM , "ROM")); SlotList.append(CSlot(32, 0x18000 , "" , "" , CSlot::RAM , "RAM1")); SlotList.append(CSlot(1 , 0x1800 , "" , "" , CSlot::ROM , "PORT")); PowerSwitch = 0; setDXmm(187); setDYmm(177); setDZmm(24); setDX(668);//715); setDY(633);//465); PowerSwitch = 0; pLCDC = new Clcdc_pb1000(this, QRect(90,130,192*2,32*2), QRect()); pCPU = new CHD61700(this); pTIMER = new Ctimer(this); pKEYB->setMap("pb1000.map"); pHD44352 = new CHD44352(this,P_RES(":/pb1000/chr.bin")); m_kb_matrix = 0; // shift=fct = false; closed = false; loc_flipping = false; loc_m_angle = 180; loc_m_zoom = 1; writeIO = false; adrBus = 0; }
void bootstrap() { /* * First reset the disk and diskette. */ #ifdef SECURE boot_has_finished = FALSE; #endif setAX(0); /* reset floppy */ setDX(0x80); /* drive 0 */ }
Cce515p::Cce515p(CPObject *parent):Cprinter(parent) { //[constructor] BackGroundFname = P_RES(":/ext/ce-150.jpg"); PaperFname = "ext/ce-150paper.jpg"; setcfgfname(QString("ce515p")); Paper_X = 100; Paper_DX = 500; Paper_Y = 100; //PaperWidgetRect = QRect(80,46,167,170); setDX(960); setDY(320); //pCONNECTOR = new Cconnector(this,5,"Internal connector 5 pins",true); publish(pCONNECTOR); pTIMER = new Ctimer(this); KeyMap = 0; KeyMapLenght= 0; pKEYB->setMap("ce150.map"); Print_Mode = 0; Pen_X = 0; Pen_Y = 0; orig_X = 0; orig_Y = 100; Pen_Z = 0; prev_Pen_X = 0; prev_Pen_Y = 0; prev_Pen_Z = 0; Pen_Status = PEN_UP; Pen_Color = 0; Rot = 0; //960,320,388,0) ce515pbuf=0; ce515pdisplay=0; needRedraw = true; setPaperPos(QRect(75,46,380,170)); #ifndef NO_SOUND clac = 0; #endif StartRot = false; Change_Color = true; Sii_wait = 0; oldstate_run = 0; printer_oldstate_draw = 0; printer_oldstate_paperfeed=0; t=c=0; waitbitstart=1; waitbitstop=0; lastX = 0; margin = 0; }
Cce127r::Cce127r(CPObject *parent) : Cce152(parent) { BackGroundFname = P_RES(":/ext/ce-127r.png"); setcfgfname("ce127r"); setDXmm(132);//Pc_DX_mm = 135; setDYmm(74);//Pc_DY_mm = 70; setDZmm(25);//Pc_DZ_mm = 10; setDX(472);//Pc_DX = 483;//409; setDY(266);//Pc_DY = 252;//213; pKEYB->fn_KeyMap = "ce127r.map"; }
Cpc2081::Cpc2081(CPObject *parent) : Cce152(parent) { BackGroundFname = P_RES(":/ext/pc-2081.png"); setcfgfname("pc2081"); setDXmm(184);//Pc_DX_mm = 135; setDYmm(114);//Pc_DY_mm = 70; setDZmm(31);//Pc_DZ_mm = 10; setDX(658);//Pc_DX = 483;//409; setDY(410);//Pc_DY = 252;//213; pKEYB->fn_KeyMap = "pc2081.map"; }
SS_boomerang &SS_boomerang::operator =(const SS_boomerang &other) { setDX(other.getDX()); setDY(other.getDY()); setDAngle(other.getAngle()); setX(other.getX()); setY(other.getY()); setAngle(other.getAngle()); setHeight(other.getHeight()); setWidth(other.getWidth()); return *this; }
Crlp6001::Crlp6001(CPObject *parent ) : CPObject(this) { //[constructor] setfrequency( 0); BackGroundFname = P_RES(":/rlh1000/rlp6001.png"); setDXmm(85); setDYmm(318); setDZmm(51); // Ratio = 3,57 setDX(303);//Pc_DX = 75; setDY(1035);//Pc_DY = 20; }
/** * @brief * * @param parent */ Cjr800::Cjr800(CPObject *parent) : CpcXXXX(parent) { //[constructor] setfrequency( (int) 4915200/4); setcfgfname(QString("jr800")); SessionHeader = "JR800PKM"; Initial_Session_Fname ="jr800.pkm"; BackGroundFname = P_RES(":/jr800/jr800.png"); RightFname = P_RES(":/jr800/jr800Right.png"); LeftFname = P_RES(":/jr800/jr800Left.png"); TopFname = P_RES(":/jr800/jr800Top.png"); // BackFname = P_RES(":/jr800/jr800Back.png"); memsize = 0xFFFF; InitMemValue = 0xFF; SlotList.clear(); SlotList.append(CSlot(32 ,0x0000 , "" , "" , CSlot::RAM , "RAM")); SlotList.append(CSlot(32, 0x8000 , P_RES(":/jr800/rom-8000-FFFF.bin"), "" , CSlot::ROM , "ROM")); PowerSwitch = 0; setDXmm(255); setDYmm(140); setDZmm(32); setDX(911); setDY(501); PowerSwitch = 0; pLCDC = new Clcdc_jr800(this, QRect(98,94,340,115), QRect(86,94,364,115)); pCPU = new Cmc6800(this); for (int i=0;i<8;i++) { hd44102[i] = new CHD44102(this); hd44102[i]->setObjectName(QString("%1").arg(i)); qWarning()<<hd44102[i]; } pTIMER = new Ctimer(this); pKEYB->setMap("jr800.map"); ioFreq = 9600; }
Cce122::Cce122(CPObject *parent):Cce126(parent) { //[constructor] BackGroundFname = P_RES(":/ext/ce-122.png"); setcfgfname("ce122"); setDX(1002);//Pc_DX = 282; setDY(330);//Pc_DY = 95; setDXmm(282); setDYmm(95); setPaperPos(QRect(90,0,158,151)); pKEYB->setMap("ce122.map"); setPower(true); printSwitch = true; }
Cx710::Cx710(CPObject *parent):Cce515p(parent) { //setfrequency( 0); setcfgfname(QString("x710")); BackGroundFname = P_RES(":/x07/x710.png"); setDXmm(200); setDYmm(120); setDZmm(36); setDX(715); setDY(665); setPaperPos(QRect(155,46,400,300)); delete(pKEYB); pKEYB->setMap("x710.map",0); }
Csio::Csio(CPObject *parent) : CPObject(parent) { //[constructor] si=so=0; //si,so port access?(0:none, 1:access) plink=0; //aplinks using?(0:none, 1:using) plinkmode=0; //select plink client(0:plink, 1:plinkc) exportbit=0; exportbyte=1; convCRLF=1; currentBit=oldstate_in=0; Start_Bit_Sent = false; t=c=0;waitbitstart=1;waitbitstop=waitparity=0; baudrate = 9600; ToDestroy = false; outBitNb = 0; Sii_ndx = 0; Sii_wait = 0; Sii_wait_recv = 0; Sii_startbitsent = false; Sii_stopbitsent = true; Sii_TransferStarted = false; Sii_TextLength = 0; Sii_Bit_Nb = 0; Sii_LfWait = 500; setfrequency( 0); ioFreq = 0; BackGroundFname = P_RES(":/ext/serial.png"); pTIMER = new Ctimer(this); setDX(195); setDY(145); setDXmm(50); setDYmm(55); setDZmm(33); dialogconsole = new DialogConsole(this); }
Cce152::Cce152(CPObject *parent) : CPObject(parent) { // if (parent == 0) pPC = (CPObject *)this; BackGroundFname = P_RES(":/ext/ce-152.png"); setcfgfname("ce152"); Tapein = 0; //Tape loaded (0:none, other:access) TapeCounter = 0; mode = EJECT; SoundOn = FALSE; info.ptrFd = 0; pTIMER = new Ctimer(this); setDX(200);//Pc_DX = 200; setDY(320);//Pc_DY = 320; KeyMap = KeyMapce152; KeyMapLenght= KeyMapce152Lenght; pKEYB = new Ckeyb(this,"ce152.map"); first_state = 0; counter = 0; GetWav_Val = 0; previous_state_setwav = 0; }
Cmd100::Cmd100(CPObject *parent):CPObject(parent) { //[constructor] setfrequency( 0); BackGroundFname = P_RES(":/md100/md-100.png"); setcfgfname("md100"); pTIMER = new Ctimer(this); setDX(1203);//Pc_DX = 620;//480; setDY(779);//Pc_DY = 488;//420; setDXmm(337); setDYmm(218); setDZmm(46); port = 0x08; adrBus=prev_adrBus=0; }
Crlp9001::Crlp9001(CPObject *parent ) : CPObject(this) { //[constructor] setfrequency( 0); BackGroundFname = P_RES(":/rlh1000/rlp9002.png"); setDXmm(113); setDYmm(95); setDZmm(51); // Ratio = 3,57 setDX(403);//Pc_DX = 75; setDY(340);//Pc_DY = 20; rotate = false; memsize = 0x4000; InitMemValue = 0xff; SlotList.clear(); SlotList.append(CSlot(16 , 0x0000 , "" , "" , RAM , "RAM 16Ko")); }
Ccl1000::Ccl1000(CPObject *parent):Cce515p(this) { setfrequency( 0); ioFreq = 0; setcfgfname(QString("cl1000")); BackGroundFname = P_RES(":/ext/cl-1000.png"); delete pKEYB; pKEYB = new Ckeyb(this,"cl1000.map"); setDXmm(260);//Pc_DX_mm = 256; setDYmm(225);//Pc_DY_mm = 185; setDZmm(42);//Pc_DZ_mm = 42; setDX(928);//Pc_DX = 895; setDY(804);//Pc_DY = 615; printerACK = false; printerBUSY = false; margin = 20; Paper_DX = 240+2*margin; setPaperPos(QRect(90,0,214,245)); }
Cce126::Cce126(CPObject *parent):Cprinter(parent) { //[constructor] Q_UNUSED(parent) setfrequency( 0); ce126buf = 0; ce126display= 0; //bells = 0; charTable = 0; margin = 25; ToDestroy = false; BackGroundFname = P_RES(":/ext/ce-126p.png"); setcfgfname("ce126p"); settop(10); setposX(0); pTIMER = new Ctimer(this); KeyMap = KeyMapce126; KeyMapLenght= KeyMapce126Lenght; pKEYB->setMap("ce126.map"); setDX(620); setDY(488); setDXmm(116); setDYmm(140); setDZmm(23); setPaperPos(QRect(150,-3,207,149)); ctrl_char = false; t = 0; c = 0; rmtSwitch = false; internal_device_code = 0x0f; }
Chp82143A::Chp82143A(CPObject *parent):Cprinter(parent) { setcfgfname(QString("hp82143a")); BackGroundFname = P_RES(":/hp41/hp82143a.png"); pKEYB->setMap("hp82143a.map"); setDXmm(180); setDYmm(130); setDZmm(60); setDX(643); setDY(464); margin = 30; paperWidth = 24*7+margin+margin; setPaperPos(QRect(355,16,216,250)); Mode = TRACE_MODE; flow = fdwid = fprint = fpadv = fgraph = feol = frjust = fignADV = false; isready = false; intensity = 0; }
Crlp1002::Crlp1002(CPObject *parent):Cce515p(parent) { //[constructor] Q_UNUSED(parent) setfrequency( 0); margin = 25; BackGroundFname = P_RES(":/rlh1000/rlp1002.png"); setcfgfname("rlp1002"); pTIMER = new Ctimer(this); pKEYB->setMap("rlp1002.map"); setDXmm(227); setDYmm(95); setDZmm(31); setDX(848); setDY(340); setPaperPos(QRect(57,-20,318,236)); rotate = false; INTrequest = false; printing = false; receiveMode = false; CRLFPending = false; memsize = 0x2000; InitMemValue = 0x7f; SlotList.clear(); SlotList.append(CSlot(8 , 0x0000 , P_RES(":/rlh1000/rlp1002.bin") , "" , CSlot::ROM , "Printer ROM")); }
int main(int argc, char* argv[]) { if (argc < 2) { printf("Usage: %s <program name>\n", argv[0]); exit(0); } filename = argv[1]; FILE* fp = fopen(filename, "rb"); if (fp == 0) error("opening"); ram = (Byte*)malloc(0x10000); memset(ram, 0, 0x10000); if (ram == 0) { fprintf(stderr, "Out of memory\n"); exit(1); } if (fseek(fp, 0, SEEK_END) != 0) error("seeking"); length = ftell(fp); if (length == -1) error("telling"); if (fseek(fp, 0, SEEK_SET) != 0) error("seeking"); if (length > 0x10000 - 0x100) { fprintf(stderr, "%s is too long to be a .com file\n", filename); exit(1); } if (fread(&ram[0x100], length, 1, fp) != 1) error("reading"); fclose(fp); Word segment = 0x1000; setAX(0x0000); setCX(0x00FF); setDX(segment); registers[3] = 0x0000; setSP(0xFFFE); registers[5] = 0x091C; setSI(0x0100); setDI(0xFFFE); for (int i = 0; i < 4; ++i) registers[8 + i] = segment; Byte* byteData = (Byte*)®isters[0]; int bigEndian = (byteData[2] == 0 ? 1 : 0); int byteNumbers[8] = {0, 2, 4, 6, 1, 3, 5, 7}; for (int i = 0 ; i < 8; ++i) byteRegisters[i] = &byteData[byteNumbers[i] ^ bigEndian]; bool prefix = false; for (int i = 0; i < 1000000000; ++i) { if (!repeating) { if (!prefix) { segmentOverride = -1; rep = 0; } prefix = false; opcode = fetchByte(); } wordSize = ((opcode & 1) != 0); bool sourceIsRM = ((opcode & 2) != 0); int operation = (opcode >> 3) & 7; bool jump; switch (opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x10: case 0x11: case 0x12: case 0x13: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x20: case 0x21: case 0x22: case 0x23: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x30: case 0x31: case 0x32: case 0x33: case 0x38: case 0x39: case 0x3a: case 0x3b: // alu rmv,rmv data = readEA(); if (!sourceIsRM) { destination = data; source = getReg(); } else { destination = getReg(); source = data; } aluOperation = operation; doALUOperation(); if (aluOperation != 7) { if (!sourceIsRM) finishWriteEA(data); else setReg(data); } break; case 0x04: case 0x05: case 0x0c: case 0x0d: case 0x14: case 0x15: case 0x1c: case 0x1d: case 0x24: case 0x25: case 0x2c: case 0x2d: case 0x34: case 0x35: case 0x3c: case 0x3d: // alu accum,i destination = getAccum(); source = !wordSize ? fetchByte() : fetchWord(); aluOperation = operation; doALUOperation(); if (aluOperation != 7) setAccum(); break; case 0x06: case 0x0e: case 0x16: case 0x1e: // PUSH segreg push(registers[operation + 8]); break; case 0x07: case 0x17: case 0x1f: // POP segreg registers[operation + 8] = pop(); break; case 0x26: case 0x2e: case 0x36: case 0x3e: // segment override segmentOverride = operation; prefix = true; break; case 0x27: case 0x2f: // DA if (af() || (al() & 0x0f) > 9) { data = al() + (opcode == 0x27 ? 6 : -6); setAL(data); setAF(true); if ((data & 0x100) != 0) setCF(true); } setCF(cf() || al() > 0x9f); if (cf()) setAL(al() + (opcode == 0x27 ? 0x60 : -0x60)); wordSize = false; data = al(); setPZS(); break; case 0x37: case 0x3f: // AA if (af() || (al() & 0xf) > 9) { setAL(al() + (opcode == 0x37 ? 6 : -6)); setAH(ah() + (opcode == 0x37 ? 1 : -1)); setCA(); } else clearCA(); setAL(al() & 0x0f); break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: // incdec rw destination = rw(); wordSize = true; setRW(incdec((opcode & 8) != 0)); break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: // PUSH rw push(rw()); break; case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: // POP rw setRW(pop()); break; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: case 0xc0: case 0xc1: case 0xc8: case 0xc9: // invalid case 0xcc: case 0xf0: case 0xf1: case 0xf4: // INT 3, LOCK, HLT case 0x9b: case 0xce: case 0x0f: // WAIT, INTO, POP CS case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: // escape case 0xe4: case 0xe5: case 0xe6: case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: // IN, OUT fprintf(stderr, "Invalid opcode %02x", opcode); runtimeError(""); break; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: // Jcond cb switch (opcode & 0x0e) { case 0x00: jump = of(); break; case 0x02: jump = cf(); break; case 0x04: jump = zf(); break; case 0x06: jump = cf() || zf(); break; case 0x08: jump = sf(); break; case 0x0a: jump = pf(); break; case 0x0c: jump = sf() != of(); break; default: jump = sf() != of() || zf(); break; } jumpShort(fetchByte(), jump == ((opcode & 1) == 0)); break; case 0x80: case 0x81: case 0x82: case 0x83: // alu rmv,iv destination = readEA(); data = fetch(opcode == 0x81); if (opcode != 0x83) source = data; else source = signExtend(data); aluOperation = modRMReg(); doALUOperation(); if (aluOperation != 7) finishWriteEA(data); break; case 0x84: case 0x85: // TEST rmv,rv data = readEA(); test(data, getReg()); break; case 0x86: case 0x87: // XCHG rmv,rv data = readEA(); finishWriteEA(getReg()); setReg(data); break; case 0x88: case 0x89: // MOV rmv,rv ea(); finishWriteEA(getReg()); break; case 0x8a: case 0x8b: // MOV rv,rmv setReg(readEA()); break; case 0x8c: // MOV rmw,segreg ea(); wordSize = 1; finishWriteEA(registers[modRMReg() + 8]); break; case 0x8d: // LEA address = ea(); if (!useMemory) runtimeError("LEA needs a memory address"); setReg(address); break; case 0x8e: // MOV segreg,rmw wordSize = 1; data = readEA(); registers[modRMReg() + 8] = data; break; case 0x8f: // POP rmw writeEA(pop()); break; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: // XCHG AX,rw data = ax(); setAX(rw()); setRW(data); break; case 0x98: // CBW setAX(signExtend(al())); break; case 0x99: // CWD setDX((ax() & 0x8000) == 0 ? 0x0000 : 0xffff); break; case 0x9a: // CALL cp savedIP = fetchWord(); savedCS = fetchWord(); farCall(); break; case 0x9c: // PUSHF push((flags & 0x0fd7) | 0xf000); break; case 0x9d: // POPF flags = pop() | 2; break; case 0x9e: // SAHF flags = (flags & 0xff02) | ah(); break; case 0x9f: // LAHF setAH(flags & 0xd7); break; case 0xa0: case 0xa1: // MOV accum,xv data = read(fetchWord()); setAccum(); break; case 0xa2: case 0xa3: // MOV xv,accum write(getAccum(), fetchWord()); break; case 0xa4: case 0xa5: // MOVSv stoS(lodS()); doRep(); break; case 0xa6: case 0xa7: // CMPSv lodDIS(); source = data; sub(); doRep(); break; case 0xa8: case 0xa9: // TEST accum,iv data = fetch(wordSize); test(getAccum(), data); break; case 0xaa: case 0xab: // STOSv stoS(getAccum()); doRep(); break; case 0xac: case 0xad: // LODSv data = lodS(); setAccum(); doRep(); break; case 0xae: case 0xaf: // SCASv lodDIS(); destination = getAccum(); source = data; sub(); doRep(); break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: setRB(fetchByte()); break; case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: // MOV rv,iv setRW(fetchWord()); break; case 0xc2: case 0xc3: case 0xca: case 0xcb: // RET savedIP = pop(); savedCS = (opcode & 8) == 0 ? cs() : pop(); if (!wordSize) setSP(sp() + fetchWord()); farJump(); break; case 0xc4: case 0xc5: // LES/LDS ea(); farLoad(); *modRMRW() = savedIP; registers[8 + (!wordSize ? 0 : 3)] = savedCS; break; case 0xc6: case 0xc7: // MOV rmv,iv ea(); finishWriteEA(fetch(wordSize)); break; case 0xcd: data = fetchByte(); if (data != 0x21) { fprintf(stderr, "Unknown interrupt 0x%02x", data); runtimeError(""); } switch (ah()) { case 2: printf("%c", dl()); break; case 0x4c: printf("*** Bytes: %i\n", length); printf("*** Cycles: %i\n", ios); printf("*** EXIT code %i\n", al()); exit(0); break; default: fprintf(stderr, "Unknown DOS call 0x%02x", data); runtimeError(""); } break; case 0xcf: ip = pop(); setCS(pop()); flags = pop() | 2; break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: // rot rmv,n data = readEA(); if ((opcode & 2) == 0) source = 1; else source = cl(); while (source != 0) { destination = data; switch (modRMReg()) { case 0: // ROL data <<= 1; doCF(); data |= (cf() ? 1 : 0); setOFRotate(); break; case 1: // ROR setCF((data & 1) != 0); data >>= 1; if (cf()) data |= (!wordSize ? 0x80 : 0x8000); setOFRotate(); break; case 2: // RCL data = (data << 1) | (cf() ? 1 : 0); doCF(); setOFRotate(); break; case 3: // RCR data >>= 1; if (cf()) data |= (!wordSize ? 0x80 : 0x8000); setCF((destination & 1) != 0); setOFRotate(); break; case 4: // SHL case 6: data <<= 1; doCF(); setOFRotate(); setPZS(); break; case 5: // SHR setCF((data & 1) != 0); data >>= 1; setOFRotate(); setAF(true); setPZS(); break; case 7: // SAR setCF((data & 1) != 0); data >>= 1; if (!wordSize) data |= (destination & 0x80); else data |= (destination & 0x8000); setOFRotate(); setAF(true); setPZS(); break; } --source; } finishWriteEA(data); break; case 0xd4: // AAM data = fetchByte(); if (data == 0) divideOverflow(); setAH(al() / data); setAL(al() % data); wordSize = true; setPZS(); break; case 0xd5: // AAD data = fetchByte(); setAL(al() + ah()*data); setAH(0); setPZS(); break; case 0xd6: // SALC setAL(cf() ? 0xff : 0x00); break; case 0xd7: // XLATB setAL(readByte(bx() + al())); break; case 0xe0: case 0xe1: case 0xe2: // LOOPc cb setCX(cx() - 1); jump = (cx() != 0); switch (opcode) { case 0xe0: if (zf()) jump = false; break; case 0xe1: if (!zf()) jump = false; break; } jumpShort(fetchByte(), jump); break; case 0xe3: // JCXZ cb jumpShort(fetchByte(), cx() == 0); break; case 0xe8: // CALL cw call(ip + fetchWord()); break; case 0xe9: // JMP cw ip += fetchWord(); break; case 0xea: // JMP cp savedIP = fetchWord(); savedCS = fetchWord(); farJump(); break; case 0xeb: // JMP cb jumpShort(fetchByte(), true); break; case 0xf2: case 0xf3: // REP rep = opcode == 0xf2 ? 1 : 2; prefix = true; break; case 0xf5: // CMC flags ^= 1; break; case 0xf6: case 0xf7: // math rmv data = readEA(); switch (modRMReg()) { case 0: case 1: // TEST rmv,iv test(data, fetch(wordSize)); break; case 2: // NOT iv finishWriteEA(~data); break; case 3: // NEG iv source = data; destination = 0; sub(); finishWriteEA(data); break; case 4: case 5: // MUL rmv, IMUL rmv source = data; destination = getAccum(); data = destination; setSF(); setPF(); data *= source; setAX(data); if (!wordSize) { if (modRMReg() == 4) setCF(ah() != 0); else { if ((source & 0x80) != 0) setAH(ah() - destination); if ((destination & 0x80) != 0) setAH(ah() - source); setCF(ah() == ((al() & 0x80) == 0 ? 0 : 0xff)); } } else { setDX(data >> 16); if (modRMReg() == 4) { data |= dx(); setCF(dx() != 0); } else { if ((source & 0x8000) != 0) setDX(dx() - destination); if ((destination & 0x8000) != 0) setDX(dx() - source); data |= dx(); setCF(dx() == ((ax() & 0x8000) == 0 ? 0 : 0xffff)); } } setZF(); setOF(cf()); break; case 6: case 7: // DIV rmv, IDIV rmv source = data; if (source == 0) divideOverflow(); if (!wordSize) { destination = ax(); if (modRMReg() == 6) { div(); if (data > 0xff) divideOverflow(); } else { destination = ax(); if ((destination & 0x8000) != 0) destination |= 0xffff0000; source = signExtend(source); div(); if (data > 0x7f && data < 0xffffff80) divideOverflow(); } setAH(remainder); setAL(data); } else { destination = (dx() << 16) + ax(); div(); if (modRMReg() == 6) { if (data > 0xffff) divideOverflow(); } else { if (data > 0x7fff && data < 0xffff8000) divideOverflow(); } setDX(remainder); setAX(data); } break; } break; case 0xf8: case 0xf9: // STC/CLC setCF(wordSize); break; case 0xfa: case 0xfb: // STI/CLI setIF(wordSize); break; case 0xfc: case 0xfd: // STD/CLD setDF(wordSize); break; case 0xfe: case 0xff: // misc ea(); if ((!wordSize && modRMReg() >= 2 && modRMReg() <= 6) || modRMReg() == 7) { fprintf(stderr, "Invalid instruction %02x %02x", opcode, modRM); runtimeError(""); } switch (modRMReg()) { case 0: case 1: // incdec rmv destination = readEA2(); finishWriteEA(incdec(modRMReg() != 0)); break; case 2: // CALL rmv call(readEA2()); break; case 3: // CALL mp farLoad(); farCall(); break; case 4: // JMP rmw ip = readEA2(); break; case 5: // JMP mp farLoad(); farJump(); break; case 6: // PUSH rmw push(readEA2()); break; } break; } } runtimeError("Timed out"); }
static VOID WINAPI XmsBopProcedure(LPWORD Stack) { switch (getAH()) { /* Get XMS Version */ case 0x00: { setAX(0x0300); /* XMS version 3.00 */ setBX(0x0301); /* Driver version 3.01 */ setDX(0x0001); /* HMA present */ break; } /* Request HMA */ case 0x01: { /* Check whether HMA is already reserved */ if (IsHmaReserved) { /* It is, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_IN_USE); break; } // NOTE: We implicitely suppose that we always have HMA. // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST // error code. /* Check whether the requested size is above the minimal allowed one */ if (getDX() < HmaMinSize) { /* It is not, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_MIN_SIZE); break; } /* Reserve it */ IsHmaReserved = TRUE; setAX(0x0001); setBL(XMS_STATUS_SUCCESS); break; } /* Release HMA */ case 0x02: { /* Check whether HMA was reserved */ if (!IsHmaReserved) { /* It was not, bail out */ setAX(0x0000); setBL(XMS_STATUS_HMA_NOT_ALLOCATED); break; } /* Release it */ IsHmaReserved = FALSE; setAX(0x0001); setBL(XMS_STATUS_SUCCESS); break; } /* Global Enable A20 */ case 0x03: { /* Enable A20 if needed */ if (!IsA20Enabled) { XmsLocalEnableA20(); if (getAX() != 0x0001) { /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */ break; } IsA20Enabled = TRUE; } setAX(0x0001); /* Line successfully enabled */ setBL(XMS_STATUS_SUCCESS); break; } /* Global Disable A20 */ case 0x04: { UCHAR Result = XMS_STATUS_SUCCESS; /* Disable A20 if needed */ if (IsA20Enabled) { XmsLocalDisableA20(); if (getAX() != 0x0001) { /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */ break; } IsA20Enabled = FALSE; Result = getBL(); } setAX(0x0001); /* Line successfully disabled */ setBL(Result); break; } /* Local Enable A20 */ case 0x05: { /* This call sets AX and BL to their correct values */ XmsLocalEnableA20(); break; } /* Local Disable A20 */ case 0x06: { /* This call sets AX and BL to their correct values */ XmsLocalDisableA20(); break; } /* Query A20 State */ case 0x07: { setAX(EmulatorGetA20()); setBL(XMS_STATUS_SUCCESS); break; } /* Query Free Extended Memory */ case 0x08: { setAX(XmsGetLargestFreeBlock()); setDX(FreeBlocks); if (FreeBlocks > 0) setBL(XMS_STATUS_SUCCESS); else setBL(XMS_STATUS_OUT_OF_MEMORY); break; } /* Allocate Extended Memory Block */ case 0x09: { WORD Handle; UCHAR Result = XmsAlloc(getDX(), &Handle); if (Result == XMS_STATUS_SUCCESS) { setAX(1); setDX(Handle); } else { setAX(0); setBL(Result); } break; } /* Free Extended Memory Block */ case 0x0A: { UCHAR Result = XmsFree(getDX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Move Extended Memory Block */ case 0x0B: { PVOID SourceAddress, DestAddress; PXMS_COPY_DATA CopyData = (PXMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI()); PXMS_HANDLE HandleEntry; if (CopyData->SourceHandle) { HandleEntry = GetHandleRecord(CopyData->SourceHandle); if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_BAD_SRC_HANDLE); break; } if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE) { setAX(0); setBL(XMS_STATUS_BAD_SRC_OFFSET); } SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset); } else { /* The offset is actually a 16-bit segment:offset pointer */ SourceAddress = FAR_POINTER(CopyData->SourceOffset); } if (CopyData->DestHandle) { HandleEntry = GetHandleRecord(CopyData->DestHandle); if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_BAD_DEST_HANDLE); break; } if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE) { setAX(0); setBL(XMS_STATUS_BAD_DEST_OFFSET); } DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset); } else { /* The offset is actually a 16-bit segment:offset pointer */ DestAddress = FAR_POINTER(CopyData->DestOffset); } /* Perform the move */ RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count); setAX(1); setBL(XMS_STATUS_SUCCESS); break; } /* Lock Extended Memory Block */ case 0x0C: { DWORD Address; UCHAR Result = XmsLock(getDX(), &Address); if (Result == XMS_STATUS_SUCCESS) { setAX(1); /* Store the LINEAR address in DX:BX */ setDX(HIWORD(Address)); setBX(LOWORD(Address)); } else { setAX(0); setBL(Result); } break; } /* Unlock Extended Memory Block */ case 0x0D: { UCHAR Result = XmsUnlock(getDX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Get Handle Information */ case 0x0E: { PXMS_HANDLE HandleEntry = GetHandleRecord(getDX()); UINT i; UCHAR Handles = 0; if (!ValidateHandle(HandleEntry)) { setAX(0); setBL(XMS_STATUS_INVALID_HANDLE); break; } for (i = 0; i < XMS_MAX_HANDLES; i++) { if (HandleTable[i].Handle == 0) Handles++; } setAX(1); setBH(HandleEntry->LockCount); setBL(Handles); setDX(HandleEntry->Size); break; } /* Reallocate Extended Memory Block */ case 0x0F: { UCHAR Result = XmsRealloc(getDX(), getBX()); setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } /* Request UMB */ case 0x10: { BOOLEAN Result; USHORT Segment = 0x0000; /* No preferred segment */ USHORT Size = getDX(); /* Size is in paragraphs */ Result = UmaDescReserve(&Segment, &Size); if (Result) setBX(Segment); else setBL(Size > 0 ? XMS_STATUS_SMALLER_UMB : XMS_STATUS_OUT_OF_UMBS); setDX(Size); setAX(Result); break; } /* Release UMB */ case 0x11: { BOOLEAN Result; USHORT Segment = getDX(); Result = UmaDescRelease(Segment); if (!Result) setBL(XMS_STATUS_INVALID_UMB); setAX(Result); break; } /* Reallocate UMB */ case 0x12: { BOOLEAN Result; USHORT Segment = getDX(); USHORT Size = getBX(); /* Size is in paragraphs */ Result = UmaDescReallocate(Segment, &Size); if (!Result) { if (Size > 0) { setBL(XMS_STATUS_SMALLER_UMB); setDX(Size); } else { setBL(XMS_STATUS_INVALID_UMB); } } setAX(Result); break; } default: { DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH()); setBL(XMS_STATUS_NOT_IMPLEMENTED); } } }
VOID cmdCheckBinary (VOID) { LPSTR lpAppName; ULONG BinaryType; PPARAMBLOCK lpParamBlock; PCHAR lpCommandTail,lpTemp; ULONG AppNameLen,CommandTailLen = 0; USHORT CommandTailOff,CommandTailSeg,usTemp; NTSTATUS Status; UNICODE_STRING Unicode; OEM_STRING OemString; ANSI_STRING AnsiString; if(DontCheckDosBinaryType){ setCF(0); return; // DOS Exe } lpAppName = (LPSTR) GetVDMAddr (getDS(),getDX()); Unicode.Buffer = NULL; AnsiString.Buffer = NULL; RtlInitString((PSTRING)&OemString, lpAppName); Status = RtlOemStringToUnicodeString(&Unicode,&OemString,TRUE); if ( NT_SUCCESS(Status) ) { Status = RtlUnicodeStringToAnsiString(&AnsiString, &Unicode, TRUE); } if ( !NT_SUCCESS(Status) ) { Status = RtlNtStatusToDosError(Status); } else if (GetBinaryType (AnsiString.Buffer,(LPLONG)&BinaryType) == FALSE) { Status = GetLastError(); } if (Unicode.Buffer != NULL) { RtlFreeUnicodeString( &Unicode ); } if (AnsiString.Buffer != NULL) { RtlFreeAnsiString( &AnsiString); } if (Status){ setCF(1); setAX((USHORT)Status); return; // Invalid path } if (BinaryType == SCS_DOS_BINARY) { setCF(0); return; // DOS Exe } // Prevent certain WOW apps from being spawned by DOS exe's // This is for win31 compatibility else if (BinaryType == SCS_WOW_BINARY) { if (!IsWowAppRunnable(lpAppName)) { setCF(0); return; // Run as DOS Exe } } if (VDMForWOW && BinaryType == SCS_WOW_BINARY && IsFirstWOWCheckBinary) { IsFirstWOWCheckBinary = FALSE; setCF(0); return; // Special Hack for krnl286.exe } // dont allow running 32bit binaries from autoexec.nt. Reason is that // running non-dos binary requires that we should have read the actual // command from GetNextVDMCommand. Otherwise the whole design gets into // synchronization problems. if (IsFirstCall) { setCF(1); setAX((USHORT)ERROR_FILE_NOT_FOUND); return; } // Its a 32bit exe, replace the command with "command.com /z" and add the // original binary name to command tail. AppNameLen = strlen (lpAppName); lpParamBlock = (PPARAMBLOCK) GetVDMAddr (getES(),getBX()); if (lpParamBlock) { CommandTailOff = FETCHWORD(lpParamBlock->OffCmdTail); CommandTailSeg = FETCHWORD(lpParamBlock->SegCmdTail); lpCommandTail = (PCHAR) GetVDMAddr (CommandTailSeg,CommandTailOff); if (lpCommandTail){ CommandTailLen = *(PCHAR)lpCommandTail; lpCommandTail++; // point to the actual command tail if (CommandTailLen) CommandTailLen++; // For CR } // We are adding 3 below for "/z<space>" and anothre space between // AppName and CommandTail. if ((3 + AppNameLen + CommandTailLen ) > 128){ setCF(1); setAX((USHORT)ERROR_NOT_ENOUGH_MEMORY); return; } } // copy the stub command.com name strcpy ((PCHAR)&pSCSInfo->SCS_ComSpec,lpszComSpec+8); lpTemp = (PCHAR) &pSCSInfo->SCS_ComSpec; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setDS(usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setDX((usTemp)); // Form the command tail, first "3" is for "/z " pSCSInfo->SCS_CmdTail [0] = (UCHAR)(3 + AppNameLen + CommandTailLen); RtlCopyMemory ((PCHAR)&pSCSInfo->SCS_CmdTail[1],"/z ",3); strcpy ((PCHAR)&pSCSInfo->SCS_CmdTail[4],lpAppName); if (CommandTailLen) { pSCSInfo->SCS_CmdTail[4+AppNameLen] = ' '; RtlCopyMemory ((PCHAR)((ULONG)&pSCSInfo->SCS_CmdTail[4]+AppNameLen+1), lpCommandTail, CommandTailLen); } else { pSCSInfo->SCS_CmdTail[4+AppNameLen] = 0xd; } // Set the parameter Block if (lpParamBlock) { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,lpParamBlock->SegEnv); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,lpParamBlock->pFCB1); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,lpParamBlock->pFCB2); } else { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,0); } lpTemp = (PCHAR) &pSCSInfo->SCS_CmdTail; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); STOREWORD(pSCSInfo->SCS_ParamBlock.OffCmdTail,usTemp); usTemp = (USHORT)((ULONG)lpTemp >> 4); STOREWORD(pSCSInfo->SCS_ParamBlock.SegCmdTail,usTemp); lpTemp = (PCHAR) &pSCSInfo->SCS_ParamBlock; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setES (usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setBX (usTemp); setCF(0); return; }