; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

       page       ,132

;-----------------------------------------------------------------------------
;
; Source File: dhsysdmp.asm
;
; Description:
;      This file contains the DosHlp routines for processing stand alone
;      system dump.
;
; Entry Points:
;      DHInitSystemDump  -- Preprocess system  dump
;      DHSystemDump      -- initiate a system dump
;
; External References:
;

        .286P

        .XLIST
        INCLUDE SEGMENTS.INC      ; USE16
        INCLUDE BASEMACA.INC
        INCLUDE DOSHLP.INC
        INCLUDE INT.INC           ; Interrupt manager structures
        INCLUDE STRUC.INC
        INCLUDE BASEMID.INC
        INCLUDE IODELAY.INC
        .LIST

; 8259 interrupt controller equates

x287              EQU     0F0H               ; co-processor
INTA00            EQU     020H
INTA01            EQU     021H
INTB00            EQU     0A0H
INTB01            EQU     0A1H
INT_TYPE          EQU     070H
INT_VIDEO         EQU     010H
CONT1_ICW1        EQU     011H               ; Controller 1 master
CONT1_ICW2        EQU     08                 ; Controller 1 ICW2
CONT1_ICW3        EQU     04                 ; Controller 1 ICW3
CONT1_ICW4        EQU     01                 ; Controller 1 ICW4
CONT2_ICW1        EQU     011H               ; Controller 2 slave
CONT2_ICW3        EQU     02                 ; Controller 2 ICW3
CONT2_ICW4        EQU     01                 ; Controller 2 ICW4

KBDTIMERDISK      EQU     0B8H               ; Keyboard, disk, timer
CLOCK             EQU     0FEH               ; real time clock

; Display equates

COLOR80           EQU     3                  ; Color display 80 x 25
MONOTEXT          EQU     7                  ; Mono (alpha)
MONOGRAPHIC       EQU     0Fh                ; Mono (graphics)
ROW               EQU     5                  ; Row on display
COLUMN            EQU     0                  ; Column on display
PAGENO            EQU     0                  ; Page number of display
STRING            EQU     1                  ; String attribute
NORMAL            EQU     7                  ; Normal attribute
GETMODE           EQU     15                 ; Get mode command
SETMODE           EQU     0                  ; Set mode command
WRITESTRING       EQU     19                 ; Write string command

; Diskette equates

TRACK             EQU     0                  ; Track to read
SECTOR            EQU     1                  ; Sector to read
HEAD              EQU     0                  ; Head to read
COUNT             EQU     1                  ; Number of sectors to read
READ              EQU     2                  ; Bios read
RESET             EQU     0                  ; Reset diskette command
DRIVE_A           EQU     0                  ; Disk drive
CHANGE_LINE       EQU     0EFH               ; Show change line
CHANGE_LINE_LOC   EQU     090H               ; Change line location
DASD_TYPE         EQU      15H               ; Type drive
DISK_NO_CHANGE    EQU     1                  ; No Change line
DISK_CHANGE       EQU     2                  ; Change line available

; Keyboard equates

QUERYKEY          EQU     1                  ; key available
READKEY           EQU     0                  ; Read available key

; Message equates and BIOS information

VECTORBYTES       EQU     128                ; BIOS vector bytes
VECTORSEG         EQU     0                  ; Interrupt vector seg
VECTOROFFSET      EQU     0                  ; Int vector offset
BIOSBYTES         EQU     256                ; BIOS (40:0) bytes
OFFSET_INT07      EQU     1CH                ; Location of INT 7
OFFSET_INT0D      EQU     34H                ; Location of INT D
OFFSET_INT1E      EQU     120                ; Location of INT 1EH
INT_1E_OFFSET     EQU     0EFC7H             ; Offset of INT 1EH
INT_1E_SEGMENT    EQU     0F000H             ; Segment of INT 1EH
OFFSET_INT40      EQU     100H               ; Location of INT 40H
INT_40_OFFSET     EQU     0EC59H             ; Offset of INT 40H
INT_40_SEGMENT    EQU     0F000H             ; Segment ofINT 40H
BIOSDATA_SEG      EQU     40H                ; BIOS data segment data
BIOSDATA_OFFSET   EQU     00H                ; Offset of BIOS data
DEBUGOFFSET       EQU     218H               ; Debug data
DEBUG_LEN         EQU     36                 ; Number of debug bytes

; Timer equates

TIMER_0           EQU     40H                ; Select timer 0
TIMER_3           EQU     43H                ; Select timer 3
SELECT_TIMER      EQU     36H                ; Select timer

; Miscellaneous equates

DELAY_COUNT       EQU     30                 ; Timing Loop value

; The bootstrap loader always loads the booted code to 7C00h and loads
; 200h(512) bytes.
BOOT_SEG          EQU    07C0h
BOOT_OFFSET       EQU    0000h
RASCRV_LENGTH     EQU    0200h

BUFFER_LENGTH     EQU    0200h
BUFFER_SEG        EQU    07E0h
BUFFER_OFFSET     EQU    0000h

CBIOS_DATA_SEG    EQU     40H        ; CBIOS Data Segment
CBIOS_RESET_LOC   EQU     72H        ; Offset location of dump flag
CBIOS_RETURN_LOC  EQU     67H        ; Offset to place return addr

; Information necessary to have Compatibility BIOS reset the Hardware

DUMP_FLAG         EQU   4321H           ; Stand-alone dump reset

Max_Slot          EQU     8             ;  Max slot #
Atlas_ID          EQU     0EFFEH        ;  Atlas ID
AtlasEVT_ID       EQU     0FFEDH        ;  Atlas ID
Toledo_ID         EQU     0EFFFH        ;  Toledo ID
Atlas_Kent_ID     EQU     0ECECH        ;  Atlas ID

ABIOS_PRESENT_FLAG  EQU    1            ; ABIOS Present Flag from RASRST
HYBRID_PRESENT_FLAG EQU    2            ; HYBRID Present Flag from RASRST
DCBS_PRESENT_FLAG   EQU    8            ; DCBS Present Flag from RASRST

DosHlpData      SEGMENT
      public RAS_BIOS_data
      public rasdmp

RAS_BIOS_data   db  VECTORBYTES DUP(?)
                db  BIOSBYTES DUP(?)

rasdmp          db  "RASDMP  COM"       ; dump file name
copy7c00        equ  rasdmp

display_mode    db  ?                   ; mode

try_count       db  ?                   ; Number of times to try

Display_Slot    db  0                   ;

        INCLUDE dhsysdmp.inc

               even                     ; needed for stack in data seg

;  Reserve a 512 byte area for saving 7C00h data area
;  We can overlay area starting at rasdmp so not to waste space

                db  (512 - ($ - offset rasdmp)) dup (' ')

copy7e00        db  0

dummy_segment   dw     0                ; Size limit of segment
dummy_low       dw     0                ; 24 bit address - lower 16 bits

;  Reserve a 512 byte area for reading a diskette sector
;  We can overlay area starting at DumpProc so not to waste space

                db  (512 - ($ - offset copy7e00)) dup (' ')

DosHlpData      ENDS



DosHlpCode      SEGMENT



;****************************************************************************
;*                                                                          *
;* DHInitSystemDump - initialize a system dump                              *
;*                                                                          *
;* Description:                                                             *
;*     This routine will reset the PICs and timers, if AX is 1.  It will    *
;*     also restore the IVT to its pre-OS/2 condition, and restore the      *
;*     bios data area to its pre-OS/2 condition.  Finally, it will reset    *
;*     the video.                                                           *
;*                                                                          *
;* Linkage:                                                                 *
;*      far call                                                            *
;*                                                                          *
;* Input:                                                                   *
;*    AX = 0 -- indicates that the hardware needs to be reset by this pgm   *
;*    AX = 1 -- indicates hardware reset to be done by BIOS                 *
;*    DS = DOSGROUP                                                         *
;*    DS:SI -> fmtr_parms                                                   *
;*                                                                          *
;* Exit:                                                                    *
;*      None                                                                *
;* Uses:                                                                    *
;*      all, except AX                                                      *
;*                                                                          *
;* Internal References:                                                     *
;*      none                                                                *
;*                                                                          *
;* External References:                                                     *
;*      none                                                                *
;*                                                                          *
;****************************************************************************

        assume  cs:DosHlpCode, ds:nothing, es:nothing, ss:nothing

        public    DHInitSystemDump
DHInitSystemDump  proc  far                            ; ENTRY POINT FROM DOS

        pusha
        push    ax   ; save the parm for later

        ;------------------------------------------------------------;
        ; Perform loop to give disk I/O a chance to complete         ;
        ; and also flush any keys which may be held over from INTs.  ;
        ;------------------------------------------------------------;

        mov     bx,DELAY_COUNT          ; Outer loop count
dmp1:   mov     cx,0FFFFh               ; Inner loop count
dmp2:   loop    dmp2                    ; LOOP
        in      al,60H                  ; Flush Keyboard Port
        dec     bx                      ; Dec outer loop
        jnz     dmp1                    ; Loop until zero

        ;-----------------------------;
        ; disable LAN card if present ;
        ;-----------------------------;

        xor     cx,cx                   ; clear slot counter

ck_card:
        call    get_card_id_x           ;get card id for slot x
        cmp     ax,06042H               ;is it ethernet card?
        je      found_card              ;yes, then shut it down else
        cmp     ax,08F70H               ;is it an ARTIC card
        je      found_card              ;yes, then shut it down else
        cmp     ax,0EFEFH               ;is it net card?
        je      found_card              ;yes, then shut it down else
        cmp     ax,0E000H               ;is it token ring 4/4 card?
        je      found_card              ;yes, then shut it down else
        cmp     ax,0E001H               ;is it token ring 16/4 card?
        je      found_card              ;yes, then shut it down else
        cmp     ax,00808H               ;is it BIC ethernet card?
        je      found_card              ;yes, then shut it down else
        jmp     short try_next_card     ;no match on ID so try next slot

found_card:
        call    setup_slot_x            ;setup slot with net card
        mov     dx,102h                 ;point to pos byte 0
        in      al,dx                   ;get pos byte 0

        dhIODelay bx

        and     al,0feh                 ;turn off the enable bit(bit 0)
        out     dx,al                   ;disable the card

        dhIODelay bx

        call    enable_slots            ;turn back on the slots

try_next_card:
        inc     cx                      ;no, increment slot number
        cmp     cx,7                    ;are we beyond slot 7 (slot 0-7)
        jbe     ck_card                 ;no, try next slot.

        pop     ax                      ; get the parm back
        push    ax                      ; save for later

        push    ds                      ; save DOSGROUP
        mov     bx,VECTORSEG            ; BIOS int vectors
        mov     ds,bx                   ; source starts at 0:0

        ;--------------------------------------------------------;
        ; This program will use DS as the base reg for seg 0000h ;
        ;--------------------------------------------------------;

        ;----------------------------------------;
        ; Re-initialize the 8259 controller  # 1 ;
        ;----------------------------------------;

        push    dx                      ; save reg used in io delay

        sub     al,al                   ; No CBIOS available
        out     x287+1,al               ; Reset co-processor
        mov     al,CONT1_ICW1           ; Master controller
        out     INTA00,al

        dhIODelay dx

        mov     al,CONT1_ICW2
        out     INTA01,al               ; ICW 2

        dhIODelay dx

        mov     al,CONT1_ICW3           ; Setup ICW 3
        out     INTA01,al

        dhIODelay dx

        mov     al,CONT1_ICW4           ; Setup ICW 4
        out     INTA01,al

        dhIODelay dx

        mov     al,KBDTIMERDISK         ; Enable Keyboard, disk
        out     INTA01,al

        dhIODelay dx

; Re-initialize the 8259 interrupt #2 controller chip

        mov     al,CONT2_ICW1           ; ICW 1
        out     INTB00,al

        dhIODelay dx

        mov     al,INT_TYPE             ; Setup ICW 2
        out     INTB01,al

        dhIODelay dx

        mov     al,CONT2_ICW3           ; Setup ICW 3
        out     INTB01,al

        dhIODelay dx

        mov     al,CONT2_ICW4           ; Setup ICW 4
        out     INTB01,al

        dhIODelay dx

        mov     al,CLOCK                ; Enable real time clock
        out     INTB01,al               ; Enable interrupts

        dhIODelay dx

; reset the 8253 timer

        mov     al,SELECT_TIMER         ; Sel timer 0,LSB, MSB, mode 3
        out     TIMER_3,al              ; Write timer mode register

        dhIODelay dx

        mov     al,0
        out     TIMER_0,al              ; Write LSB to timer 0 REG

        dhIODelay dx

        out     TIMER_0,al              ; Write MSB to timer 0 reg

        dhIODelay dx

        pop     dx

        ;----------------------------------------;
        ; Restore INT 40H with architected value ;
        ;----------------------------------------;
        mov     bx,OFFSET_INT40         ; interrupt 40
        mov     ax,INT_40_OFFSET        ; arch'ed offset
        mov     ds:[bx],ax
        mov     ax,INT_40_SEGMENT       ; arch'ed segment
        mov     ds:[bx + 2],ax

        ;----------------------------------------;
        ; Restore INT 1EH with architected value ;
        ;----------------------------------------;
        mov     bx,OFFSET_INT1E         ; interrupt 1EH
        mov     ax,INT_1E_OFFSET        ; arch'ed offset
        mov     ds:[bx],ax
        mov     ax,INT_1E_SEGMENT       ; arch'ed segment
        mov     ds:[bx + 2],ax

sd10:
        push    cs
        pop     es

        assume  es:DosHlpData           ; in real mode cs=doshlpseg

        ;------------------------------------------------------------;
        ; Now restore/save(exchange) the BIOS interrupt vectors.     ;
        ; This should be done even on an ABIOS Machine so            ;
        ; Interrupt Vectors can later be interrogated even though    ;
        ; ABIOS_RST(Power_On_Reset) will refresh them too.           ;
        ;                                                            ;
        ; DEBUGGING will not work after the vectors and data areas   ;
        ; arerestored. Kernel debugger will not work either. I think ;
        ; it may be possible to save and restore INT 0h, 1h and 3h   ;
        ; to get the kernel debugger working.  Not sure if this      ;
        ; will work after the ABIOS_RST(Power_On_Reset).             ;
        ;------------------------------------------------------------;

        pop      di                     ; get DOSGROUP parm from the stack
        push     ds                     ; save VECTORSEG address
        mov      ds,di

        ;---------------------------------------------;
        ; Save address of the vectors at failure time ;
        ; for DUMPFMTR in the parms list              ;
        ;---------------------------------------------;

        mov     ds:[si],es              ; selector
        lea     di,RAS_BIOS_data        ; offest
        mov     ds:[si+2],di            ; vect_ptr

        ;-----------------------------------------------;
        ; Save address of the bios data at failure time ;
        ; for DUMPFMTR in the parms list                ;
        ;-----------------------------------------------;

        mov     ds:[si+4],es                  ; selector
        lea     di,RAS_BIOS_data+VECTORBYTES  ; offest
        mov     ds:[si+6],di                  ; bios_ptr

        ;------------------------------------------------;
        ; Save address of bootstrap area at failure time ;
        ; for DUMPFMTR in the parms list                 ;
        ;------------------------------------------------;

        mov     ds:[si+8],es            ; selector
        lea     di,copy7c00             ; offest
        mov     ds:[si+10],di           ; boot_ptr

        pop      bx                     ; restore VECTORSEG address
        push     ds                     ; save DOSGROUP for next parm
        mov      ds,bx                  ; restore VECTORSEG address

        ;---------------------------------;
        ; The program will now use DI as  ;
        ; the index reg for RAS_BIOS_data ;
        ;---------------------------------;

        lea     di,RAS_BIOS_data        ; offset into DI
        mov     cx,VECTORBYTES          ; 128 bytes of vectors
        mov     bx,VECTOROFFSET         ; offset into es:di

change:
        mov     al,es:[di + bx]         ; Get current value
        xchg    ds:[bx],al              ; exchange curr/origin
        mov     es:[di + bx],al         ; store the original
        inc     bx

        loop    change

        ;---------------------------------------------;
        ; Now restore the BIOS data area              ;
        ; Save address of the BIOS data for DUMPFMTR  ;
        ;---------------------------------------------;

        mov     bx,VECTORBYTES          ; Offset of data area
        mov     cx,BIOSBYTES            ; # bytes of data
        mov     ax,BIOSDATA_SEG
        mov     ds,ax                   ; BIOS data at 40:0
        mov     si,BIOSDATA_OFFSET

;------------------------------------------------------------------;
; The program will now use DS as the base reg for seg 0040h        ;
; The program will now use SI as the index reg for BIOSDATA_OFFSET ;
;------------------------------------------------------------------;

cont:
        mov     al,es:[di + bx]         ; Get current value
        xchg    ds:[si],al              ; Exchange with original
        mov     es:[di + bx],al
        inc     bx
        inc     si

        loop    cont

        ;-------------------------------------------------;
        ; Now show the change line as active, this forces ;
        ; INT 13H to re-establish the diskette media.     ;
        ;-------------------------------------------------;

        mov     si,CHANGE_LINE_LOC               ; Change line active
        and     byte ptr ds:[si],CHANGE_LINE     ; make status line on

        ;--------------------------------;
        ; Now issue an INT 10 to get and ;
        ;  reset video mode of display.  ;
        ;--------------------------------;

        mov  ah,GETMODE                 ; Get mode
        INT  10H                        ; Tell BIOS to get mode

        .if <al eq MONOTEXT> or
        .if <al eq MONOGRAPHIC>
           mov display_mode,MONOTEXT    ; Mono Display
        .else
           mov display_mode,COLOR80     ; Color Display
        .endif

        mov     al,display_mode         ; get mode
        mov     ah,SETMODE              ; Set mode command
        int     10H                     ; set mode

        pop   ds   ; DOSGROUP
        pop   ax   ; get the parm back

        ;---------------------------------------------;
        ; IF the hardware is capable of resetting the ;
        ; necessary hardware to initiate a dump,      ;
        ; then let ABIOS_RST reset hardware.          ;
        ;---------------------------------------------;

; If it's an IBM machine, then it's OK to call POST to reset the
; hardware.  Not all OEM machines recognize the RAS REBOOT flag (4321H)
; so for OEM's, don't call post.

        test    ax,ABIOS_PRESENT_FLAG   ; if no ABIOS, don't do ROM check
        jz      NOTPS2
        mov     ax,0f000h               ; point to IBM ROM signature
        mov     es,ax
        mov     di,0e00dh               ; look for ' IBM'
        cmp     word ptr es:[di],'I '
        jne     NOTPS2                  ; must be OEM
        cmp     word ptr es:2[di],'MB'
        je      PRESNT                  ; PS/2 or Hybrid

NOTPS2:
        jmp   NOPRESNT                  ; must be an OEM machine


PRESNT:

;            if <DBCS_Codepg ne 0FFFFh>
;            near DBCS consideration need

        test  ax,DCBS_PRESENT_FLAG

          .if <nz> near

            ; DBCS consideration need to be taken
            ;
            ; The E0000 address is used as DBCS display adapter's
            ; refresh buffer(4K byte) in DBCS OS/2 system.  However,
            ; ABIOS_RST routine jumps to F000:FFF0 and then
            ; checks checksum of memory from E000. To enable this
            ; activity, ROM address space should be enabled.
            ; After this, even DBCS system does not need to reenable
            ; DBCS video adapter. Instead, VGA is used because DBCS
            ; font mgr is freezed by system when DUMP is invoked.

               push    ax                 ; Save Registers
               push    bx                 ;
               push    cx                 ;
               push    dx                 ;

            ;Find Atlas card
               mov    bx,0001h
               mov    cl,01h
               mov    dx,0074h            ;CMOS Address register

             .repeat
                   mov    ax,bx           ;odd adrress
                   out    dx,ax
                   push   ax
                   dhIODelay ax
                   pop    ax
                   add    dx,2
                   in     al,dx           ;al high data
                   sub    dx,2
                   dec    bx              ;even address
                   xchg   ax,bx
                   out    dx,ax
                   push   ax
                   dhIODelay ax
                   pop    ax
                   xchg   ax,bx
                   inc    bx              ;odd address
                   mov    ah,al
                   add    dx,2
                   in     al,dx           ;al low  data
                   sub    dx,2
                   .if  <ax e Atlas_Kent_ID> or  ; Check  DBCS
                   .if  <ax e Atlas_ID>      or  ; VIDEO ADAPTER
                   .if  <ax e AtlasEVT_ID>   or  ; ID .
                   .if  <ax e Toledo_ID>         ;

                       .if  <ax e Toledo_ID>     ; Old type ?
                          or     cl,80h          ;  then mark
                       .endif
                       mov    Display_Slot,cl    ; Save Video slot
                       .leave
                   .else
                       inc    cl
                       add    bx,0023H    ; next entry
                   .endif

             .until < cl e Max_Slot-1 >   ; Check next Slot

          ;Disable Atlas card

              cli
              test    Display_Slot,80H    ;

              .if  z  ;Not Tolade         ; If not Old type

                 mov     dx,3e0h          ; rout to VGA
                 mov     ax,0302h
                 out     dx,ax

              .endif

              mov     dx,96h
              mov     al,Display_Slot
              and     al,7FH              ;
              dec     al
              add     al,078h             ;disable Atlas
              out     dx,al
              dhIODelay ax
              mov     dx,102h
              xor     al,al
              out     dx,al
              dhIODelay ax
              mov     dx,96h
              mov     al,70h
              out     dx,al
              dhIODelay ax

          ;enable VGA

              mov     al,0DFh
              out     094h,al
              dhIODelay ax
              mov     al,11h
              mov     dx,102h
              out     dx,al
              dhIODelay ax
              mov     al,0FFh
              out     094h,al
              dhIODelay ax

          ;At last enable ROM BIOS E0000 - E0FFF

              mov     al,7Fh
              out     094h,al
              dhIODelay ax
              mov     al,0FEh
              mov     dx,104h
              out     dx,al
              dhIODelay ax
              mov     al,0FFh
              out     094h,al
              dhIODelay ax

              pop     dx                ; Restore registers
              pop     cx                ;
              pop     bx                ;
              pop     ax                ;
              sti                       ;

          .endif      ; END DBCS consideration

        push  ds

        ;-------------------------------------------------;
        ; If the hardware is capable of resetting         ;
        ; the necessary hardware to initiate a dump,      ;
        ; then let the BIOS Post code reset the Hardware. ;
        ;-------------------------------------------------;

        assume ds:nothing

        ;-------------------------------------------------;
        ; Set stand-alone dump flag in ROM BIOS Data Area ;
        ;-------------------------------------------------;

        mov  ax,CBIOS_DATA_SEG          ; BIOS data segment
        mov  ds,ax                      ;

        assume ds:nothing

        mov  bx,CBIOS_RESET_LOC         ; Offset to store reset flag
        mov  ds:[bx],DUMP_FLAG          ; Move in Dump Flag

        ;--------------------------------------------------;
        ; Set O/S return address in the ROM BIOS Data Area ;
        ;--------------------------------------------------;

        mov  bx,CBIOS_RETURN_LOC          ; Offset to store return addr
        mov  ax,offset return_from_reset  ; Place to return to
        mov  ds:[bx],ax                   ; set Return CS:IP
        mov  ds:[bx+2],cs                 ; set Return CS:IP

        assume  ds:DosHlpData

        push  cs
        pop   ds

        mov  ax,ss                      ; Save stack segment
        mov  dummy_segment,ax           ;
        mov  dummy_low,sp               ; Save Stack Pointer

        jmp cs:dword ptr post_reset_loc ; Let Post reset hardware

post_reset_loc   dw  0FFF0h             ; Post Code Location
                 dw  0F000h             ;

        ;----------------------------------------------------------;
        ;  This is where POST returns after resetting the hardware ;
        ;----------------------------------------------------------;

return_from_reset:

        cli                             ; Make sure IRQ's are disable
                                        ; BIOS may have enabled

        push cs                         ; Get data Segment
        pop  ds                         ;

        assume  ds:DosHlpData

        mov  ax,dummy_segment           ; Restore the Stack
        mov  ss,ax
        mov  sp,dummy_low

        pop  ds

NOPRESNT:

        popa

        ret

DHInitSystemDump  endp



;****************************************************************************
;*                                                                          *
;* DHSystemDump - Start the system dump                                     *
;*                                                                          *
;* Description:                                                             *
;*      The DosHlpSystemDump function is responsible for initiating a       *
;*      system dump.  The function should prompt the user to insert a       *
;*      dump diskette and boot that diskette.  The dump diskette, created   *
;*      by createdd utility, will perform the actual system dump using      *
;*      the system dump information passed to DosHlpSystemDump.             *
;*                                                                          *
;*                                                                          *
;* Linkage:                                                                 *
;*      far call                                                            *
;*                                                                          *
;* Input:                                                                   *
;*                                                                          *
;*      ES:BX -> address of the system supplied dump procedure              *
;*               if 0, then NO dump procedure is supplied.  The dump        *
;*               should be performed via INT 19H.                           *
;*                                                                          *
;*      DS:SI -> offset of fmtr_parms                                       *
;*                                                                          *
;*      CX    -> rasrst code segment for stack segment at end of program    *
;*         AX -> end of rasrst code segment, top of rascrv stack            *
;*                                                                          *
;* Exit:                                                                    *
;*      Boot dump disk                                                      *
;*                                                                          *
;* Uses:                                                                    *
;*      all                                                                 *
;*                                                                          *
;* Internal References:                                                     *
;*      none                                                                *
;*                                                                          *
;* External References:                                                     *
;*      none                                                                *
;*                                                                          *
;****************************************************************************


        assume  CS:DosHlpCode,DS:NOTHING,ES:NOTHING,SS:NOTHING

        PUBLIC  DHSystemDump
DHSystemDump    PROC FAR


        push   cx                       ; save DOSCODE segment address
        push   ax                       ; save RASRST code end offset
        push   ds                       ; save DOSGROUP segment address

        ;-------------------------------------------------;
        ; Check to see if a stand-alone dump exit routine ;
        ; has been provided by  a Mini-FSD. If one has    ;
        ; been provided, then "jmp" to this routine.      ;
        ;-------------------------------------------------;

        mov     ax, es
        or      ax, bx                  ; Is the dump address == 0?

       .if     <nz>                    ; No

        ;------------------------------------------------------;
        ; Display message that dump facility is being accessed ;
        ;------------------------------------------------------;

          push es
          push bx                       ; move/save the dump address to stack

          push cs
          pop  es

          assume es:DosHlpData

          mov  cx,word ptr TXT_MSG_SAD_REMOTE_DUMP
          mov  bp,offset TXT_MSG_SAD_REMOTE_DUMP+2
          mov  ax,1301h                                ; write string
          mov  dx,500h                                 ; row 5, col 0
          mov  bx,7                                    ; page number 0, attr 7
          int  10h                                     ; display the message

        ;-------------------------------------;
        ; Set up pointers to 2 OS/2 messages, ;
        ; "Insert diskette in drive A" and    ;
        ; "Stand-alone dump not available".   ;
        ;                                     ;
        ; ds:si -> insert diskette            ;
        ; es:di -> Dump not available         ;
        ;-------------------------------------;

          lea  si,TXT_MSG_SAD_INSERT_DUMP
          add  si,2

          lea  di,TXT_MSG_SAD_NOT_AVAILABLE+2
          mov  bp, sp
          jmp  DWORD PTR ss:[bp]                  ; go to the routine

          ;-------------------------;
          ; we NEVER return to here ;
          ;-------------------------;

        assume es:nothing

       .endif



        ;------------------------------------------------;
        ; the segment registers will be used as follows: ;
        ; DS = DOSGROUP                                  ;
        ;    = 07E0h                                     ;
        ;    = 07C0h                                     ;
        ;    = 0000h                                     ;
        ; ES = DosHlpData                                ;
        ;------------------------------------------------;

        assume es:nothing

        push cs
        pop  es

        ;--------------------------------------------------------;
        ; The program will use ES as the base reg for DosHlpData ;
        ;--------------------------------------------------------;

        assume es:DosHlpData

        mov     ax,VECTORSEG            ; BIOS int vectors
        mov     ds,ax                   ; source starts at 0:0

        ;--------------------------------------------------------;
        ; The program will use DS as the base reg for seg 0000h  ;
        ;--------------------------------------------------------;

        ;------------------------------------------------;
        ; put parm address in INT 7 vector as pointer to ;
        ; parms list for DUMPFMTR                        ;
        ;------------------------------------------------;

        pop     ax                      ; get DOSGROUP seg
        mov     bx,OFFSET_INT07         ; offset (001Ch)
        mov     ds:[bx],ax              ; segment
        mov     ds:[bx+2],si            ; si is fmtr_parms, offset

        ;-------------------------------------------------;
        ; Save 7E00-7FFFh because that is area used by    ;
        ; this program and by RASCRV as a diskette        ;
        ; buffer area.  DUMPFMTR will restore the         ;
        ; area(7E00h) from this area(DosHlpData:COPY7E00) ;
        ;-------------------------------------------------;

        lea     di,copy7e00             ; dest. offset
        mov     cx,BUFFER_LENGTH        ; BUFFER size (200h)
        mov     ax,BUFFER_SEG           ; BUFFER segment(07E0h)
        mov     ds,ax                   ; source segment
        mov     si,BUFFER_OFFSET        ; source offset
                                        ; BUFFER offset (0000h)
repnz   movsb                           ; move bytes ES:DI,DS:SI

        ;-------------------------------------------------------------;
        ; Make sure there is a diskette drive available.  If there is ;
        ; not, then display a message instructing the user to reboot. ;
        ;-------------------------------------------------------------;


        mov  ah,DASD_TYPE                ; Check Drive type
        mov  dl,DRIVE_A                  ; Check A drive
        int  13H                         ; Check it

       .if  <ah ne DISK_NO_CHANGE> and   ; Must be diskette
       .if  <ah ne DISK_CHANGE>

        ;-------------------------------------------------;
        ; if not a diskette then display message and loop ;
        ;-------------------------------------------------;

          mov   cx,word ptr TXT_MSG_SAD_NOT_AVAILABLE
          lea   bp,TXT_MSG_SAD_NOT_AVAILABLE
          add   bp,2

          mov   ax,1301h                ; write string
          mov   dx,500h                 ; row 5, col 0
          mov   bx,7                    ; page number 0, attribute 7
          int   10h                     ; display the message
NoDisk:
          jmp   NoDisk                  ; Loop forever

      .endif                            ; No diskette

        ;----------------------------------;
        ; Do until a CREATEDD diskette has ;
        ; been inserted in drive A:        ;
        ;----------------------------------;

        mov  al,0AEh                    ; force ketboard reset command
        out  64h,al                     ; Compaq is hung

        xor  cx,cx

       .repeat                            ; repeat until dump diskette found

        ;--------------------;
        ; Flush the keyboard ;
        ;--------------------;

          .repeat                       ; Do at least once

             mov  ah,QUERYKEY           ; Check for key
             int  16h                   ; Look for key

            .if <nz>                    ; Code is available

               mov  ah,READKEY
               int  16H                 ; Get the key

            .endif

          .until <z>                    ; Repeat til key pressed

        mov  al,display_mode            ; get mode
        mov  ah,SETMODE                 ; Set mode command
        int  10H                        ; set mode

        mov  cx,word ptr TXT_MSG_SAD_INSERT_DUMP
        lea  bp,TXT_MSG_SAD_INSERT_DUMP
        add  bp,2

        mov  ax,1301h                   ; write string
        mov  dx,500h                    ; row 5, col 0
        mov  bx,7                       ; page number 0, attribute 7
        int  10h                        ; display the message

        .repeat                         ; until good read

        ;------------------------------;
        ; Wait for a key to be pressed ;
        ;------------------------------;

          mov  ah,READKEY               ; Get next key
          int  16h                      ; look for key
          mov  try_count,3              ; try 3 times

         .repeat

           push    es                   ; ES will be destroyed by int13
           mov     ah,RESET             ; Reset Diskette
           mov     dl,DRIVE_A           ; reset A:
           int     13H                  ; Tell Bios to reset
           mov     bx,BUFFER_SEG        ; segment addr of buffer
           push    bx                   ;   information area
           pop     es

           assume  es:nothing

           mov     bx,BUFFER_OFFSET     ; Read to system dump
           mov     ah,READ              ; Tell BIOS to read
           mov     ch,TRACK             ; track
           mov     cl,SECTOR            ; sector
           mov     dl,DRIVE_A           ; drive number
           mov     dh,HEAD              ; Head
           mov     al,COUNT             ; # sectors to read
           int     13H                  ; do the read to ES:BX
           pop     es

           assume  es:DosHlpData

           dec     try_count            ; # times tried

         .until  <nc>  or               ; Stop if good read
         .until  <try_count eq 0>       ; OR if tried 4 times

        .until <ah eq 0>                ; until read good

        ;---------------------------------------------------;
        ; Compare the string which resides in the           ;
        ; DUMP bootstrap with "rasdmp  com"                 ;
        ; to make sure that this is really a dump diskette. ;
        ;---------------------------------------------------;

                                        ; DS = 07E0h
        cld                             ; clear direction
        mov  si,BUFFER_OFFSET           ; bootstrap location
        add  si,BOOTOFFSET              ; message string
        lea  di,rasdmp                  ; dump file name
        mov  cx,11                      ; length of file name
repz    cmpsb                           ; compare file name to
                                        ; bootstrap DS:SI to ES:DI

       .until <z>                       ; Stop if DUMP diskette

        ;----------------------------------------------;
        ; Save 7C00-7DFFh because that is area used    ;
        ; by the BOOTSTRAP loader as the RASCRV CODE   ;
        ; area.  DUMPFMTR will restore the area(7C00h) ;
        ; from this area(DosHlpData:COPY7C00)          ;
        ;----------------------------------------------;

        lea     di,copy7c00             ; destination offest
        mov     cx,RASCRV_LENGTH        ; RASCRV size (200h)
        mov     ax,BOOT_SEG             ; RASCRV segment(07C0h)

        assume  ds:nothing

        mov     ds,ax                   ; source segment
        mov     si,BOOT_OFFSET          ; source offset
                                        ; RASCRV offset (0000h)
repnz   movsb                           ; move bytes ES:[DI],DS[SI]

        pop     ax     ; original RASRST code end offset passed from RASRST
        pop     ss     ; original DOSCODE passed from RASRST; Ints disabled
        mov     sp,ax  ; original RASRST code end offset passed from RASRST

        ;----------------------------------------------;
        ; Pass control to RASCRV thru bootstrap loader ;
        ;----------------------------------------------;
;       Int 19h doesn't work on the ALR powerflex 20SX, so code the equivalent
;       int     19H                     ; BOOTSTRAP to DUMP
        mov     ax,0201h                ; read 1 sector
        mov     bx,7c0h                 ; segment 7C0h
        mov     es,bx
        xor     bx,bx                   ; offset 0
        xor     dx,dx                   ; drive A, head 0
        mov     cx,1                    ; track 0, sector 1
        int     13h                     ; read the boot sector
        jmp     cs:dword ptr bootloc    ; execute the boot sector code at 7C00h
bootloc: dw     0,7c0h

DHSystemDump                            endp


        ;-------------------------------;
        ; cl = slot to get card id from ;
        ;-------------------------------;

get_card_id_x   proc    near

        call    setup_slot_x            ;slot_x in setup mode

        push    dx                      ;save dx
        mov     dx,101h                 ;set up for read
        in      al,dx                   ;get card id hi

        dhIODelay bx

        mov     ah,al                   ;put hi byte in ah
        dec     dx                      ;set up for lo byte
        in      al,dx                   ;get card id lo

        dhIODelay bx

        pop     dx                      ;restore dx
        call    enable_slots            ;enable slots
        ret

get_card_id_x   endp


setup_slot_x    proc    near

        ; cl = slot number to put into setup mode (0-7)

        push    ax
        mov     al,cl                   ;put in slot number 0-7
        or      al,8                    ;or in the setup mode bit.
        out     96h,al                  ;setup mode slot x

        dhIODelay bx

        pop     ax
        ret

setup_slot_x    endp



enable_slots    proc    near

        push    ax
        xor     al,al                   ;set enable
        out     96h,al                  ;enable all slots

        dhIODelay bx

        pop     ax
        ret

enable_slots    endp

DosHlpCode      ends

_TEXT           SEGMENT




;----------------------------------------------------------------;
;                                                                ;
;*** getdhsysdump - Save vectors and bios data for system dump   ;
;                                                                ;
;       This routine is called from main so that data critical   ;
;       for performing a system dump can be saved.               ;
;                                                                ;
;       ENTRY:  REAL MODE                                        ;
;               DS = DGROUP                                      ;
;                                                                ;
;       EXIT:   NONE                                             ;
;                                                                ;
;       USES:   NONE                                             ;
;----------------------------------------------------------------;

        assume  cs:_TEXT,ds:DGROUP,es:nothing,ss:nothing

        PUBLIC  getdhsysdmp

getdhsysdmp     PROC NEAR

        push    ds
        push    es
        pusha
;
; Save interrupt vectors and ROM data areas for System Dump
;
        push    ds                      ; DS currently => DGROUP
        pop     es

        assume  es:DosHlpData           ; ES:DI => bios data save area

        lea     di,RAS_BIOS_data

        push    VECTORSEG               ; DS:SI = address of interrupt
        pop     ds                      ;         vectors

        assume  ds:NOTHING

        mov     si,VECTOROFFSET
        mov     cx,VECTORBYTES/2        ; CX = number of words to save
        rep     movsw                   ; save interrupt vectors

        push    BIOSDATA_SEG            ; DS:SI = address of ROM data
        pop     ds

        assume  ds:NOTHING

        mov     si,BIOSDATA_OFFSET
        mov     cx,BIOSBYTES/2          ; CX = number of words to save
        rep     movsw                   ; save ROM data

        popa
        pop     es
        pop     ds

        ret

getdhsysdmp     ENDP

_TEXT           ENDS


                END
