home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / dosutils / reboot21.arj / REBOOT.ASM next >
Encoding:
Assembly Source File  |  1991-09-22  |  11.8 KB  |  494 lines

  1.     page    66,80
  2.     TITLE    REBOOT.COM  reboots the system
  3.     .model    small        ; really tiny, but AT Segs freak MASM 6.0
  4.             
  5. comment √
  6.     Version 2.1 1991/09/22 by Roedy Green
  7.     works with MASM 5.0, 6.0 and Optasm
  8.         MASM 6.0 will not allow /AT or /TINY.  Must use EXE2BIN to do the
  9.         conversion of a EXE to COM file.
  10.  
  11.   USAGE:
  12.  
  13.   for a warm boot (no ram test):
  14.   Reboot
  15.   Reboot /W
  16.   Reboot /Warm
  17.  
  18.   for cold boot (with ram test):
  19.   Reboot /C
  20.   Reboot /Cold
  21.  
  22. Version 2.1
  23.   - fast reboot in DESQ if there is only one window open.
  24.   - now uses DVAPI.INC -- DESQ api interface.
  25.  
  26. Version 2.0
  27.   - improved DESQview Awareness
  28.   - Windows 3.0 enhanced awareness
  29.  
  30. Version 1.9
  31.   - added DESQview Awareness
  32.  
  33. Version 1.8
  34.   - added clear of all serial ports to stop interrupts during reboot
  35.   - mice or modems could interfere.
  36.  
  37. Version 1.7
  38.   - added Disk Reset
  39.  
  40. Version 1.6
  41.   - added both Warm and Cold boot options.
  42.  
  43. √  ; end of comment
  44.  
  45.     include D:\DV\dvapi.inc ; DESQ macros
  46.                 ; part of DESQ Application Programmer Interface
  47.  
  48. BIOSDATA    segment AT 40h    ; dummy segment in low RAM
  49.     org    0h
  50. BIOSComAddrs    dw    ?    ; 4 words of COM1: .. COM4:
  51.         dw    ?    ; device addresses
  52.         dw    ?
  53.         dw    ?
  54.         org    72h
  55. BIOSWarmFlag    dw    ?
  56. BIOSDATA    ends
  57.  
  58. ROMBIOS     segment AT 0f000h    ; dummy segment inside ROM BIOS
  59.         org    0fff0h
  60. BIOSReset    label    far        ; reset code at FFFF:0000
  61.                     ; better represented as F000:FFF0
  62.         org    0fffEh
  63. BIOSMachineId    db    ?        ; BIOS machine type code
  64. ROMBIOS     ends
  65.  
  66. CODE    segment public
  67.  
  68. DATA    segment
  69. DATA    ends
  70.  
  71. cgroup    group    Code,Data
  72.     assume    cs:cgroup,ss:cgroup,ds:cgroup,es:cgroup
  73.     org    100h
  74. ;==========================
  75.  
  76. Start    proc    far
  77.     lea    dx,BannerMsg    ; display banner
  78.     Call    Say
  79.  
  80.     call    Parse        ; parse the command line
  81.  
  82.     call    Analyze     ; analyze the /parameter
  83.  
  84.     call    DiskReset    ; Make DOS flush the buffers
  85.  
  86.  
  87.     call    Breath        ; wait one breath
  88.                 ; to give the world time to settle
  89.                 ; and allow time to admire the banner.
  90.                 ; interrupts are still on to allow windup.
  91.  
  92.     Call    BootDESQ    ; reboot DESQ if needed
  93.  
  94.     Call    BootWIN3E    ; reboot Windows 3 enhanced mode if needed
  95.                 ; Can't do this with DESQ or Windows or
  96.                 ; else mouse would die
  97.  
  98.     call    KillComs    ; kill interrupts on all com ports
  99.  
  100.     Call    Boot        ; jump to BIOS reset
  101.  
  102.     ; Will not come back.
  103.  
  104.  
  105. ;==============================================================
  106. ;  V A R I A B L E S
  107.  
  108. ;  We put variables in this odd place so that MASM will not get
  109. ;  phase errors.  It cannot handle forward references well.
  110.  
  111. QuitTime    DD    0    ; time in ticks to quit waiting
  112.  
  113. MyWarmFlag    DW    01234h    ; 1234h if warm boot
  114.                 ; 0    if cold boot
  115.  
  116.  
  117. BannerMsg    DB '░▒▓█ Reboot 2.1 █▓▒░',13d,10d
  118.         DB 13d,10d
  119.         DB 'Copyright (c) 1990 Roedy Green Canadian Mind Products',13,10
  120.         DB 'May be freely distributed and used for any purpose except military.',13,10,'$'
  121.  
  122. Usage        db 'Error in command line.',13,10
  123.         db 'Try Reboot /W or plain Reboot for a warm boot or Reboot /C for a cold boot.',13,10,'$'
  124.  
  125. DESQMsg     db 13,10
  126.         db 'DESQview Active.  Close all other windows then reboot with Ctrl-Shift-Del.',13,10,'$'
  127.  
  128. WIN3EMsg    db 13,10
  129.         db 'Windows 3 enhanced mode Active.',13,10
  130.         db 'Use Ctrl-Esc and close all other tasks then reboot with Ctrl-Alt-Del.',13,10,'$'
  131.  
  132. ;===============================================================
  133.  
  134. Say    Proc
  135. ;    on entry DX points to a string to display
  136.     MOV    AH,9
  137.     Int    21h
  138.     ret
  139. Say    EndP
  140.  
  141. ;===============================================================
  142.  
  143. MLeading    PROC    Near
  144. ;    on entry BX is addr of string, CX its length
  145. ;    trims off any leading blanks, leaving result in BX CX
  146. ;    length may also be 0 or 1, but not -ve
  147. ;    If the entire string is blank the result is the null string
  148.     mov    di,bx
  149.     mov    al,20H        ; AL = blank  -- the search char
  150.     jcxz    mleading2    ; jump if null string
  151.     repe    scasb        ; scan ES:DI forwards till hit non blank
  152.                 ; DI points just after it (wrap ok)
  153.                 ; cx IS ONE TOO SMALL, OR 0 IF NONE FOUND
  154.     je    mleading1    ; jump if entire string was blank
  155.     inc    cx        ; CX is length of remainder of string
  156. mleading1:
  157.     dec    di        ; DI points to non-blank
  158. mleading2:
  159.     mov    bx,di        ; put address back
  160.     ret
  161. MLeading    ENDP
  162.  
  163. ;========================================
  164.  
  165. MTrailing    PROC    Near
  166. ;    on entry BX is addr of string, CX its length
  167. ;    trims off any trailing blanks, leaving result in BX CX
  168. ;    length may also be 0 or 1, but not -ve
  169. ;    If the entire string is blank the result is the null string
  170.     mov    di,bx
  171.     add    di,cx        ; calc addr last char in string
  172.     dec    di
  173.     mov    al,20H        ; AL = blank  -- the search char
  174.     jcxz    mtrailing1    ; jump if null string
  175.     std
  176.     repe    scasb        ; scan ES:DI backwards till hit non blank
  177.                 ; DI points just ahead of it (wrap ok)
  178.                 ; CX is one too small, or 0 if none found
  179.     cld
  180.     je    mtrailing1    ; jump if whole string was blank
  181.     inc    cx
  182. mtrailing1:
  183.     ret
  184. MTrailing    ENDP
  185.  
  186. ;========================================
  187.  
  188. Parse    PROC    NEAR
  189. ;    Parse the command line to remove lead/trail blanks
  190. ;
  191. ;    sample inputs
  192. ;    Reboot /Cold
  193. ;    Reboot /W
  194. ;    Reboot
  195. ;
  196. ;    When Done DS:BX points to start of string.
  197. ;    CX counts bytes in string
  198.                 ; counted string at HEX 80 PSP
  199.                 ; contains command line.
  200.                 ; Preceeded by unwanted spaces.
  201.                 ; possibly followed by unwanted spaces.
  202.     xor    ch,ch
  203.     mov    cl,ds:80H
  204.     mov    bx,81H
  205.     call    Mleading    ; get rid of leading blanks
  206.     call    MTrailing    ; get rid of trailing blanks
  207.     ret
  208. Parse    ENDP
  209.  
  210. ;======================================
  211.  
  212. Analyze PROC    NEAR
  213. ;    analyses the /C or /W parameter
  214. ;    On entry DS:BX points to start of string.
  215. ;    CX counts bytes in string
  216. ;    lead/trail spaces are gone.
  217.  
  218.     jcxz    AnalDone    ; was no /parm, treat as warm
  219.     cmp    cx,2
  220.     jl    BadCmd        ; kick out plain /
  221.     mov    ax,[bx]     ; get chars AL<-/  AH<-C
  222.     cmp    al,'/'        ; make sure first char is /
  223.     jne    BadCmd
  224.     mov    al,ah
  225.     call    ToUc
  226.     cmp    al,'C'
  227.     je    WasCold
  228.     cmp    al,'W'
  229.     je    WasWarm
  230. BadCmd: LEA    dx,Usage
  231.     Call    Say
  232.     Jmp    Abort
  233. WasCold:
  234.     Mov    MyWarmFlag,0
  235. WasWarm:
  236. AnalDone:
  237.     RET
  238. Analyze ENDP
  239.  
  240. ;======================================
  241.  
  242. ToUC    PROC    NEAR
  243. ;    converts char in AL to upper case
  244.     cmp    al,'a'
  245.     jb    FineAsIs
  246.     cmp    al,'z'
  247.     ja    FineAsIs
  248.     sub    al,20H        ; convert a to A
  249. FineAsIs:
  250.     ret
  251. ToUc    ENDP
  252.  
  253. ;======================================
  254.  
  255. KillComs    Proc    Near
  256.  
  257. ;    Clear any serial ports, so they will stop interrupting
  258. ;    i.e. clear the modem control registers
  259. ;    e.g. 3FC on COM1 .. 4
  260.     push    DS
  261.     mov    ax,BIOSDATA
  262.     mov    DS,ax
  263.     xor    bx,bx
  264.     assume    DS:BIOSDATA
  265.     lea    si,BIOSComAddrs ; 4 words of device address
  266.     mov    cx,4
  267.  
  268. KillLoop:
  269.     lodsw            ; ax = next device address
  270.     cmp    ax,bx        ; is it zero?
  271.     je    NoCom        ; yes, then there is nothing to do.
  272.     mov    dx,ax        ; dx=port base
  273.     add    dx,4        ; dx=port of modem control reg
  274.     mov    ax,bx        ; ax=0
  275.     out    dx,al        ; clear modem control device reg
  276. NoCom:
  277.     loop    KillLoop    ; repeat for 4 com ports
  278.     pop    DS
  279.     ret
  280. KillComs    EndP
  281.  
  282. ;===============================================================
  283.  
  284. DiskReset    Proc    Near
  285.  
  286. ;    Ask DOS to flush her buffers.
  287. ;    Presumably, cachers will intercept this and flush their
  288. ;    buffers too.
  289.  
  290.     mov    ah,0dh        ; disk reset function
  291.     int    021h        ; call DOS
  292.     ret
  293. DiskReset    EndP
  294.  
  295. ;===============================================================
  296.  
  297. Breath    Proc    Near
  298.  
  299. ;    Waste 20 ticks to give the world time to settle down
  300. ;    A delayed write cache has time to flush etc.
  301.  
  302.     Call    GetTicks        ; time in cx:dx
  303.     add    dx,020d
  304.     adc    cx,0
  305.     mov    word ptr QuitTime+0,dx    ; Ptr needed because QuitTime is DWORD
  306.     mov    word ptr QuitTime+2,cx
  307. Pause:
  308.     Call    GetTicks
  309.     cmp    cx,word ptr QuitTime+2    ; quitting time yet?
  310.     ja    PauseDone
  311.     cmp    DX,word ptr QuitTime+0
  312.     jb    Pause
  313. PauseDone:
  314.     ret
  315. Breath    EndP
  316.  
  317. ;===============================================================
  318.  
  319. GetTicks    PROC    Near
  320. ;    Get time of day in 1/18.2 second clock ticks since midnight.
  321. ;    leaves tick count in cx:dx
  322.  
  323.     mov    ah,0
  324.     int    1Ah        ; BIOS ticks since midnight
  325.                 ; cx:DX is count
  326.     ret
  327. GetTicks    EndP
  328.  
  329. ;==============================================================
  330.  
  331. BootDESQ    Proc    Near
  332.  
  333. ;    reboot Desqview if present
  334.  
  335.     @CALL    DVPRESENT
  336.     test    ax,ax
  337.     jnz    DESQPresent
  338. DESQAbsent:
  339.     ret
  340.  
  341. DESQPresent:
  342.     call    Alone
  343.     test    ax,ax
  344.     jz    ManualClose
  345.     ret            ; We are alone, we can safely auto-reboot
  346.  
  347. ManualClose:            ; must ask user to manually close windows
  348.                 ; or manually reboot.
  349.     lea    dx,DESQMsg
  350.     call    Say
  351.  
  352. NowIsTheEnd:
  353. ;                ; loop till he reboots 
  354.     @Call    PAUSE        ; give up rest of slice
  355.                 ; we CANNOT call Alone and autoreboot when
  356.                 ; all windows closed, because Alone twitches
  357.                 ; the windows making it impossible to close them.
  358.     jmp    NowIsTheEnd
  359.  
  360. BootDESQ    Endp
  361.  
  362. ;==============================================================
  363.  
  364. Alone    Proc    Near
  365.  
  366. Comment √
  367.  
  368. Returns AX=0 if we are not alone, AX=1 if alone.
  369.  
  370. Determine if 1, or more than 1 window is currently open under
  371. DESQview.  Note that we assume that we are running under DV and
  372. do not test for it.
  373.  
  374. Program works by asking DV to notify when window goes to
  375. background, then asks to be put in the background.  If there are
  376. no other windows open, there is no background, hence no message.
  377. I am unable to think of an easy way to count the number of
  378. windows.
  379.  
  380. Unfortunately, a side effect of this method is the windows
  381. rapidly swap on the screen making the screen unreadable as Alone
  382. executes.
  383.  
  384. Code based on the ONEWIN program by Phil Graham [BIXname
  385. pgraham] of Dynamic Data.  He restricts this code to
  386. non-commerical use.
  387.  
  388.  
  389. End Comment √
  390.  
  391. Data    Segment
  392.  
  393. make_bottom    db    1Bh,10h,2,0,04Bh,0C9h
  394.     ; makes receiving application bottommost and notify when background
  395. make_bottom_length equ $-make_bottom
  396.  
  397. make_fore    db    1Bh,10h,1,0,0C1h ; makes receiving application for
  398. make_fore_length equ $-make_fore
  399.  
  400. Data    EndS
  401.  
  402.     @send    open,mailme        ; open my mailbox for notification
  403.     @send    erase,mailme        ; clear out any old messages
  404.     lea    di,make_bottom        ; address of make-bottom stream
  405.     @push    DSDI            ; push address as 1st parm
  406.     mov    cx,make_bottom_length    ; length of stream
  407.     xor    dx,dx            ; convert to dword
  408.     @push    DXCX
  409.     @send    write,me        ; move me to bottom of window list
  410.     @call    pause            ; be sure notify message gets send
  411.     @send    sizeof,mailme        ; any messages in my mailbox?
  412.     @pop    ESSI            ; # of messages in SI
  413.     lea    di,make_fore        ; address of make-foreground stream
  414.     @push    DSDI            ; push address as 1st parm
  415.     mov    cx,make_fore_length    ; length of stream
  416.     xor    dx,dx            ; convert to dword
  417.     @push    DXCX
  418.     @send    write,me        ; move me to bottom of window list
  419.     test    si,si            ; did I get move-to-bottom message
  420.     jz    OnlyOne         ; NO! I must be the only window open
  421.     mov    ax,0            ; There are other windows active
  422.     ret
  423.  
  424. OnlyOne:
  425.     mov    ax,1            ; we are alone, -- the only window
  426.     ret
  427.  
  428. Alone    EndP
  429.  
  430. ;==============================================================
  431.  
  432. BootWIN3E    Proc    Near
  433. ;    reboot WIN3E if present
  434.  
  435.     mov    ax,1600h    ; Test for Windows 3E 4E.
  436.     int    2fh
  437.     and    ax,07fh     ; AL = 00 if nothing, WIN3r, or WIN3s
  438.                 ;      01 if WIN 2.x
  439.                 ;      03 if WIN3e
  440.                 ;      04 if WIN4e
  441.                 ;      7F if WIN 2.x
  442.                 ;      else treat as nothing
  443.     cmp    al,3
  444.     je    WIN3EPresent
  445.     cmp    al,4
  446.     je    WIN3EPresent
  447.  
  448. WIN3EAbsent:
  449.     ret
  450.  
  451. WIN3EPresent:
  452.     lea    dx,WIN3EMsg
  453.     call    Say
  454.  
  455. WaitForTheEnd:
  456.                 ; loop endlessly till he reboots
  457.     mov    ah,0bH        ; check if char waiting
  458.     int    21h        ; this should give Windows a hint we are idling
  459.     jmp    WaitForTheEnd
  460.  
  461. BootWIN3E    Endp
  462.  
  463. ;==============================================================
  464.  
  465. Boot    Proc    Near
  466.  
  467. ;    set system reset flag at 0040:0072 to 01234 for warm or 0 for cold
  468.     mov    ax,BIOSDATA
  469.     mov    ds,ax
  470.     assume    ds:BIOSDATA
  471.     mov    ax,MyWarmFlag
  472.     mov    BIOSWarmFlag,ax
  473.                 ; far jump to FFFF:0000 alias F000:FFF0
  474.     jmp    BIOSReset    ; to simulate a Ctrl-Alt-Del
  475.     assume    ds:code
  476.  
  477. Boot    Endp
  478.  
  479. ;==============================================================
  480.  
  481. Abort:
  482.                 ; error exit
  483.     mov  ax, 4c04h        ; ERRORLEVEL = 4
  484.     int    21h        ; DIE
  485.                 ; we do not reboot.
  486.  
  487. ;==============================================================
  488.  
  489. Start    endp
  490.  
  491. ;==========================
  492. CODE    ends            ; end of code segment
  493.     end    Start
  494.