Code:
'------------------------------------------------------------------------------- ' ' Unit: PREPBOOT.PBL ' Zweck: Funktionen zum Vorbereiten eines PC-Neustarts, u.a. ' Flush-Funktion für verschiedene Disk-Caches (ohne Prüfung), ' Netzwerkverbindungen aufheben usw. ' Version: 1.50 ' Stand: 28.10.97 ' Sprache: PowerBASIC 3 ' Autor: (C) M.Hoffmann, Wedeler Ldstr.139, 22559 Hamburg. ' Bemerkungen: ' Es wird nicht geprüft, welcher Cache oder ob ein Netzwerk geladen ist - ' die Funktionen werden alle "blind" aufgerufen. ' ACHTUNG: Alle offenen PB-Dateien werden geschlossen! ' Historie: ' 1.50 28.10.97 - Weitere(n) (Disk)Cache(s) berücksichtigen; PUSH/POP Regs; ' Löschen mit XOR a,a statt MOV a,0; PCTools-Flush-Funktion ' geändert. Evtl. noch überall PUSHALL/POPALL verwenden. ' ' c: prepboot.pbu 2119 9.07.96 15:53 v1.40 ' c: prepboot.pbu 2862 28.10.97 16:17 v1.50 ' '---Compiler-------------------------------------------------------------------- $compile unit $cpu 80386 $debug map-,pbdebug-,path-,unit- $dim all $error bounds-,numeric-,overflow-,stack- $event off $float emulate $lib all- $optimize size $static '---Definitionen---------------------------------------------------------------- %ax = 1 %bx = 2 %cx = 3 %dx = 4 %si = 5 %ds = 8 %es = 9 type dosdpltype notused as string*16 ' AX,BX,CX,DX,SI,DI,DS,ES (not used here) res as word ' RESERVED (0) cid as word ' COMPUTER ID (0 = CURRENT SYSTEM) pid as word ' PROCESS ID (PSP SEGMENT ON SPECIFIED COMPUTER) end type ' (not used here) type fastAPI_RequestPackettype sigptr as dword ' Zeiger auf Signaturstring bufptr as dword ' Zeiger auf Datenpuffer end type '---Routine--------------------------------------------------------------------- sub PrepareBoot (byval CallBack as dword,_ byval BootFlag as integer) local public ' ' Ist CallBack <> 0, wird VOR allen Systemaufrufen ein CALL FAR zur ' angegebenen Adresse durchgeführt, falls weitere - hier nicht vorgesehene - ' Operationen automatisch initiiert werden sollen. ' Ist BootFlag = 0, wird kein Neustart durchgeführt (wenig sinnvoll - ' der Neustart sollte dann im Hauptprogramm unmittelbar ' anschließend erfolgen). ' Ist BootFlag = 1, wird ein WARMstart durchgeführt. ' Ist BootFlag = 2, wird ein KALTstart durchgeführt. ' Ist BootFlag = 3, wird ein Boot über den Tastaturkontroller durchgeführt. ' Ist BootFlag < 0, wird ein Boot durchgeführt, wobei zuvor der Wert ' ABS(BootFlag) an die Speicheradresse 0040:0072 geschrieben ' wird. ' PowerBASIC-Dateien werden geFLUSHt und vor dem Booten geCLOSEd. ' dim l as local string dim i as local integer dim dosdpl as local dosdpltype dim fapirp as local fastAPI_RequestPackettype dim fapsig as local string*19 ' User-Callbackroutine if CallBack <> 0 then ' ACHTUNG: Routine muß mit FAR RETurn enden (z.B. PB's END SUB) und ' die Register erhalten! ! call dword ptr CallBack end if ' Broadcast (nur für TSRs, die diesen Call abfangen, sinnvoll) ! push si ! mov ax,&hffff ! mov bx,&heeee ! mov cx,&hdddd ! mov dx,&hcccc ! mov si,BootFlag ! int &h2f ! pop si ' SMARTDrive v4+ , PC-Cache (PCTools) v8.0 -- Flush ' (wird möglicherweise auch von NCache2 behandelt) ! mov ax,&h4A10 ! mov bx,&h0001 ! int &h2f ' PCTools Cache v5.x, QCache v4.00, Super PC-Kwik v3.20+ -- Flush ! push si ! mov ah,&hA1 ! mov si,&h4358 ! int &h13 ! pop si ' PCTools Cache v6+ -- Flush ! mov ax,&hFFA5 ! mov cx,&hDDDD ; zuvor FFFF ! int &h16 ' Norton NCache2 ab v7 -- Flush ! push si ! push di ! mov ax,&hFE03 ! mov di,&H4E55 ; "NU" ! mov si,&H4346 ; TSR-ID = "CF" für NCache ! int &h2f ! pop di ! pop si ' QuickCache II v4.20 ! mov ah,&h21 ! int &h13 ' FAST! v4.02+ fapsig = chr$(&h13,&h07,&h06,&h08,&h11,&h18,&h0f,&h0e,&h02,&h18,_ &h13,&h08,&h0b,&h08,&h01,&h00,&h04,&h08,&h15) fapirp.sigptr = varptr32(fapsig) reg %es,varseg(fapirp) reg %bx,varptr(fapirp) reg %ax,&h8009 ' Funktion 09 = Flush-Cache reg %cx,&h6572 ' Konstante reg %dx,&h1970 ' Konstante call interrupt &h13 ' PC Magazine PCSpool ! mov ah,&hC2 ! mov dx,0 ! int &h17 ! mov ah,&hC2 ! mov dx,1 ! int &h17 ! mov ah,&hC2 ! mov dx,2 ! int &h17 ! mov ah,&hC2 ! mov dx,3 ! int &h17 ' Dos-PRINT-Tsr (keine Prüfung, ob geladen) ! mov ax,&h0103 ; "Cancel all files" ! int &h2f ' close pending Network-print jobs ! mov ax,&h5D09 ! int &h21 ' SHARE: Close all files for given computer ' (entspricht NICHT net files /close) dosdpl.cid = 0 ' nur diese Angabe wird von diesem Call benutzt reg %ax,&h5D03 reg %ds,varseg(dosdpl) reg %dx,varptr(dosdpl) call interrupt &h21 ' Vor dem Aufheben der Netzwerkredirektionen auf das Startlaufwerk wechseln ' Bei Fehler jedoch zurück auf's aktuelle reg %ax,&h3305 call interrupt &h21 l = left$(curdir$,2) on local error resume next chdrive chr$(bits?(reg(%dx))+64) if errtest <> 0 then chdrive l end if on local error goto 0 ' Netzwerkredirektionen aufheben (ohne Prüfung, ob tatsächlich vorhanden) for i=65 to 93 if i < 91 then l = chr$(i)+":"+chr$(0) else l = "LPT"+chr$(i-42,0) end if reg %ax,&h5F04 reg %ds,strseg(l) reg %si,strptr(l) call interrupt &h21 next ' Manche Disk-Caches, z.B. NCache2 lt. Doku, werten diesen Funktions- ' aufruf als Zeichen, ausstehende Daten zurückzuschreiben; daher der ' Vollständigkeit halber. ! mov ah,&h0D ; Dos 'Disk Reset' ! int &h21 ' BIOS-Diskreset für Disks und Festplatten (evtl. ist dies der Call, ' den NCache abfängt (s.o.) ! xor ah,ah ! xor dl,dl ! int &h13 ! xor ah,ah ! mov dl,&h80 ! int &h13 ' Normale DOS-Idle-Calls als letztes (zur Sicherheit) call interrupt &h28 ' DOS-Idle ' INT28 zerstört Register, daher CALL (Fehler im DOS) ! mov ax,&h1680 ; release TimeSlice ! int &h2f ! mov ax,&h8400 ; Network-Keyboard-Busyloop ! int &h2a ' PB-Dateien FLUSHen flush def seg = &h40 if BootFlag = 1 then pokei &h72, &h1234 ' Expanded-Memory-Manager auf Warmstart vorbereiten ! mov ah,&h5C ! int &h67 elseif BootFlag = 2 then pokei &h72, &h0 elseif BootFlag < 0 then pokei &h72, abs(BootFlag) elseif BootFlag = 3 then reset do if (inp(&h64) and &b10) = &b00 then out &h64,&hFE rem Auf einigen Geräten scheint dies nicht zu gehen rem also mit anderer Methode fortfahren pokei &h72, &h0 BootFlag = 1 exit loop end if loop end if def seg if BootFlag < 3 and BootFlag <> 0 then ' PB-Dateien schließen reset def seg=&hffff i = 0 call absolute i end if end sub '===============================================================================