291 lines
8.2 KiB
NASM
291 lines
8.2 KiB
NASM
; ========================================================
|
|
|
|
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
|
|
|
|
; ========================================================
|