windows-nt/Source/XPSP1/NT/base/ntsetup/textmode/winnt/dna.asm

291 lines
8.2 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
; ========================================================
if 0
REBOOT.ASM
Copyright (c) 1991 - Microsoft Corp.
All rights reserved.
Microsoft Confidential
johnhe - 12/01/89
endif
;-----------------------------------------------------------------------------;
; K E Y B O A R D S C A N C O D E S ;
;-----------------------------------------------------------------------------;
KB_INTERCEPT EQU 4fh
DEL_KEY EQU 53h
ALT_SHIFT EQU 08h
CTL_SHIFT EQU 04h
WARM_BOOT_CODE EQU 1234h
;-----------------------------------------------------------------------------;
; BIOS DATA AREA LOCATED AT 40:00
;-----------------------------------------------------------------------------;
ROM_DATA SEGMENT AT 040h
org 17h
KB_FLAG LABEL BYTE
org 072h
WarmBootFlag LABEL WORD
ROM_DATA ENDS
;-----------------------------------------------------------------------------;
; CPU POWER-ON STARTUP LOCATION AT ffff:00
;-----------------------------------------------------------------------------;
ROM_BIOS SEGMENT AT 0ffffh
org 0
PowerOnReset LABEL FAR
ROM_BIOS ENDS
;-----------------------------------------------------------------------------;
;include MODEL.INC
;-----------------------------------------------------------------------------;
;.CODE
_TEXT segment public 'CODE'
assume cs:_TEXT,ds:nothing
public _DnaReboot
_DnaReboot PROC near
;RebootSystem PROC
ifdef NEC_98
DoInt15:
;
; 37h bit 2 is shutdown bit.
;
mov al,0bh
out 37h,al
mov al,0fh
out 37h,al
mov al,0h
out 0f0h,al
jmp DoInt15
else ; PC98
mov AX,3515h
int 21h ; Get int 15h vector in ES:BX
mov AX,ES ; AX == Segment
or AX,BX ; Is this a NULL ptr
jz WarmBoot ; If zero we can't do an int 15h
DoInt15:
mov ax, seg WarmBootFlag
mov ds, ax
assume DS:ROM_DATA
mov KB_FLAG,ALT_SHIFT OR CTL_SHIFT
mov AX,(KB_INTERCEPT SHL 8) OR DEL_KEY
int 15h ; Put Ctrl/Alt/Del into key buffer
WarmBoot:
cli
cld
mov ax, seg WarmBootFlag
mov ds, ax
assume DS:ROM_DATA
mov WarmBootFlag, WARM_BOOT_CODE
jmp PowerOnReset
; Jump to the processor power-on address FFFF:0000h
endif ; NEC_98 `
_DnaReboot ENDP
;RebootSystem ENDP
; ========================================================
;++
;
; BOOLEAN
; _far
; _cdecl
; DnAbsoluteSectorIo(
; IN unsigned Drive, //0=A, etc
; IN ULONG StartSector,
; IN USHORT SectorCount,
; IN OUT PVOID Buffer,
; IN BOOLEAN Write
; )
;
;--
public _DnAbsoluteSectorIo
_DnAbsoluteSectorIo PROC far
; params
Drive equ 6
Int2526Packet equ 8
Write equ 18
; locals
GotLock equ -2
push bp
mov bp,sp
sub sp,2
push ds
push es
push bx
push si
push di
mov byte ptr [bp].GotLock,0 ; initialize lock state flag
;
; Check for Win9x by checking for version 7 or greater.
; The minor version number is 10 for OSR2.
;
; We might also be running on some other vendor's DOS 7,
; so if locking fails we try the i/o anyway.
;
mov ax,3306h ; get MS-DOS version
int 21h
cmp bl,8 ; Is Millenium ?
je milljmp ;
cmp bl,7 ; check for DOS7 or above (Win9x)
jb dosjmp ; not Win9x
jmp winjmp ; Regular Win9x jmp
dosjmp:
mov bl,8 ; assume standard ioctl
jmp locked ; not Win9x
milljmp:
mov bl,48h ; extended ioctl
jmp getlock
winjmp:
mov bl,48h ; DOS 7 or above, assume extended ioctl
cmp bh,10 ; test OSR2
jae getlock ; OSR2, leave bl alone, use ext ioctl
mov bl,8 ; Win9x gold, use standard ioctl
getlock:
push bx ; standard/extended ioctl
.286
push 4ah ; lock volume ioctl code
.8086
push [bp].Drive
call LockOrUnlock
jc locked ; failure, try i/o anyway
inc byte ptr [bp].GotLock ; remember we have level 0 lock
locked:
;
; Dirty hack -- the int25/26 buffer is laid
; out exactly the way the parameters are passed
; on the stack.
;
; In OSR2 or later case, try new int21 first. Int25/26 don't work on FAT32.
;
cmp bl,48h ; OSR2 or later?
mov ax,ss
mov ds,ax
push bx ; save OSR2 or later flag
lea bx,[bp].Int2526Packet ; ds:bx = disk i/o param
mov cx,0ffffh ; tell DOS to use param packet
jne int2526 ; don't try new int21 on old system
mov ax,7305h ; new abs disk i/o int21 call
mov dl,[bp].Drive ; fetch drive
inc dl ; make drive 1-based
mov si,0 ; assume read
cmp byte ptr [bp].Write,0 ; write operation?
je doint21 ; no, read op
inc si ; write op
doint21:
int 21h ; call DOS
jnc did_io ; no error, done
int2526:
mov al,[bp].Drive ; fetch drive (0-based)
cmp byte ptr [bp].Write,0 ; write operation?
je @f ; no, read op
int 26h ; abs disk write
jmp short didio1
@@: int 25h
didio1: pop ax ; int 25/26 wierdness
did_io:
pop bx ; restore osr2 flag in bx
.386
setnc al ; convert carry status to boolean return code
.8086
push ax ; save return code
;
; Unlock if necessary, using same lock level
; of successful lock.
;
cmp byte ptr [bp].GotLock,0
je done ; no lock to undo
push bx ; osr2 or later flag/ioctl category
.286
push 6ah ; unlock volume ioctl code
.8086
push [bp].Drive
call LockOrUnlock
done: pop ax ; restore return code in al
pop di ; restore caller registers
pop si
pop bx
pop es
pop ds
mov sp,bp ; restore stack frame
pop bp
ret
_DnAbsoluteSectorIo ENDP
LockOrUnlock PROC near
.286
pusha ; pushes 16 bytes
mov bp,sp
dolock:
mov ch,byte ptr [bp+22] ; get ioctl category, 8 or 48
mov ax,440dh ; generic ioctl code
.386
movzx bx,byte ptr [bp+18] ; bl = drive, bh = lock level 0
.286
inc bl ; convert drive to 1-based
mov cl,byte ptr [bp+20] ; lock/unlock ioctl code
xor dx,dx ; non-format lock
int 21h
jnc lockdone
cmp byte ptr [bp+22],8 ; tried regular ioctl? (clobbers carry)
mov byte ptr [bp+22],8 ; try regular ioctl on next pass
jne dolock ; try regular ioctl
stc ; error return
lockdone:
popa
ret 6 ; carry set for return
.8086
LockOrUnlock ENDP
_TEXT ends
END
; ========================================================