Title DSVCTL -- modified from prior MIDAS version Search MacSym,MonSym StdAC. PDLen==40 IPCFch==0 ;Channel for IPCF requests to knock on Define Bit ($n)<<1b<$n>>> Define FATAL ($msg)< Jrst [tmsg $msg Call Croak]> Define NOTE ($string)< Hrroi 1,[Asciz $string] Call CTYMSG> PDList: -PDLen,,. Block PDLen DebugP: -1 ;non-zero for debugging output ExeNam: Asciz /DOMAIN:NUMAIN.EXE/ ExeJfn: 0 ExeHan: 0 LinBuf: Block 100 ;message parsing buffer HdrBuf: Block 20 ;header type FooBuf: Block 100 ;random buffer BarBuf: Block 100 ;random buffer FrkHan: Block 1 ;fork handle RcvBP: Block 1 ;point to RcvBuf RcvBPO: Block 1 ;point to RcvBuf RcvBuf: Block 5000 ;receive buffer RcvBfe: Block 1 ;end of buffer marker CR: Asciz " " CRLF: Asciz " " LEVTAB: PSIPC1 PSIPC2 PSIPC3 PSIPC1: 0 PSIPC2: 0 PSIPC3: 0 CHNTAB: Repeat <^d36>,<0> reloc chntab+IPCFch 2,,Answer ;IPCF interrupt reloc CrePak: IP%CPD ;Make me a PID MyPID: 0 0 ;To INFO 4,,ArgBlk PakLen==.-CrePak ArgBlk: .IPCII ;Assign this name to the PID 0 Asciz "DSVCTL" InfPak: 0 ;INFO's reply. 0 0 4,,InfBlk InfBlk: Block 4 ShoPak: 0 0 0 1,,Comand Comand: 0 DatPak: IP%CFV ;Full page 0 0 1000,,DatPag RepPak: IP%CFV 0 HisPID: 0 1000,,RepPag ;Single word reply code MBlock: .MUPIC MutPID: 0 IPCFch MBlokl==.-MBlock Start: RESET Move P,PDList movei 1,.fhslf movx 3,-1 epcap Movei 1,.FHSLF Move 2,[LEVTAB,,CHNTAB] SIR EIR Movei 1,PakLen Movei 2,CrePak MSEND Fatal "Can't send request to INFO" Move 1,MyPID Movem 1,MutPID Movem 1,InfPak+.IPCFR Movem 1,ShoPak+.IPCFR Movem 1,DatPak+.IPCFR Movei 1,PakLen Movei 2,InfPak MRECV Fatal "Can't get INFO's reply" ldb 1,[pointr (.ipcfl+infpak,IP%CFE)] Jumpn 1,[Cain 1,.IPCDN Fatal "Someone already has a PID named 'DSVCTL'" Fatal "Random error reply from INFO"] Movei 1,.FHSLF Movx 2,Bit(IPCFch) ;Enable IPCF interrupt channel. AIC Movei 1,MBlokl Movei 2,MBlock MUTIL Fatal "Can't assign interrupt channel to PID" Note " Initialized." Call StExe Lounge: WAIT% ;wait for a kick in the ass. Jrst .-1 ;start inferior process StExe: Skipe 1,ExeHan jrst [KFORK% erjmp .+1 Move 1,ExeHan RFRKH% erjmp .+1 jrst .+1] Skipe 1,ExeJFN jrst [RLJFN% erjmp .+1 jrst .+1] Seto 1, RELIQ% erjmp [Tmsg "Queue not released. " jrst .+1] Movx 1,GJ%SHT!GJ%OLD Hrroi 2,ExeNam GTJFN% Erjmp [Tmsg "EXE file not found. " jrst die] Movem 1,ExeJFN movx 1,cr%cap CFORK% erjmp [Tmsg "Couldn't create inferior fork. " jrst die] movem 1,ExeHan hrl 1,exejfn movs 1,1 GET% erjmp [Tmsg "Couldn't get EXE file. " jrst die] Move 1,ExeHan Setz 2, SFRKV% erjmp [Tmsg "EXE not started. " jrst die] Ret ;Answer a request to us. It's expected to be a full page. Answer: Call DoIPCF ;Pick up the message (which loops in self) DEBRK ;and then done. DoIPCF: Movx 1,IP%CFB!IP%CFV Movem 1,DatPak+.IPCFL Movei 1,7 Movei 2,DatPak MRECV Jrst [Caie 1,IPCF16 ;Wrong size of block? Ret ; Probably no more for us (good!). Jrst gShort] ;Yes, so try short size. Move 1,DatPak+.IPCFS Movem 1,HisPID ;Hee hoo (dares pester us) Jrst DoReq gShort: Movx 1,IP%TTL ;Short packet, OK if too long. Movem 1,ShoPak+.IPCFL Movei 1,PakLen Movei 2,ShoPak MRECV Ret Move 1,ShoPak+.IPCFL ;Get flag word Txne 1,IP%CFZ ;0-length message? Jrst DoReq ; Yes, so just pick up queued requests. Move 1,Comand ;Else see what first word is. Jrst DoReq ;Wake-up and look for requests. Tmsg "Mystery packet! " Jrst DoIPCF DoReq: ; DEBUG "Aha! A reset request!" Tmsg <[DSVCTL] Server restarted by > Movei 1,.PRIOU Move 2,DatPak+.IPCFD DIRST% Erjmp [Tmsg "(unknown)" Jrst .+1] Tmsg < > Call StExe Jrst DoIPCF ; No, so pick up next IPCF request. Barf: Tmsg Movei 1,.PRIOU Hrloi 2,.FHSLF Setz 3, ERSTR Nop Tmsg < > Ret CTYMSG: Push P,1 Movei 1,.PRIOU DOBE Tmsg <[DSVCTL] > Pop P,1 Tlo 1,-1 PSOUT Hrroi 1,CRLF PSOUT Ret DBGMSG: Skipn DebugP Ret Ret ;This is where we come to die... Croak: Push P,1 Tmsg "?" Pop P,1 PSOUT% Tmsg " # # DSVCTL crash at " Movei 1,.PRIOU Hrrz 2,(P) Movei 3,^d8 NOUT Nop Tmsg " # Last error: " Movei 1,.PRIOU Hrloi 2,.FHSLF ERSTR Nop Nop Tmsg " # " Die: HALTF Jrst .-1 DatPag==<<.+777>/1000>+1 DatAdr=DatPag*1000 RepPag==DatPag+10 RepAdr=RepPag*1000 End Start