; *****************************************************************************
;
; TRIO.ASM [ WINTRIO.ASM ]
;
; Turkish Rational's
; (MS-DOS 6.2 Clone) Disk Operation System v1.0 Project
; TR-DOS Executer Operation System Startup File for Windows 95/98 boot sector.
; [ attrib -s -h -r a:\IO.SYS ->
; rename a:\IO.SYS a:\GO.SYS ->
; masm trio ->
; link /t trio ->
; copy trio.com a:\IO.SYS ]
; Copyright (C) 2000 Erdogan TAN [ 16/03/2000 ] Last Update: 14/06/2004
;
; *****************************************************************************
; Boot Sector Parameters at 7C00h
DataArea1 equ -4
DataArea2 equ -2
BootStart equ 0h
OemName equ 03h
BytesPerSec equ 0Bh
SecPerClust equ 0Dh
ResSectors equ 0Eh
FATs equ 10h
RootDirEnts equ 11h
Sectors equ 13h
Media equ 15h
FATsecs equ 16h
SecPerTrack equ 18h
Heads equ 1Ah
Hidden1 equ 1Ch
Hidden2 equ 1Eh
HugeSec1 equ 20h
HugeSec2 equ 22h
DriveNumber equ 24h
Reserved1 equ 25h
bootsignature equ 26h
VolumeID equ 27h
VolumeLabel equ 2Bh
FileSysType equ 36h
Reserved2 equ 3Eh ; Starting cluster of P2000
Present segment Para 'code'
assume CS:Present, DS:Present, ES:Present, SS:Present
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_start
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_start proc near
start:
db 'MZ'
wait_seconds: dw 01A1h
Msg_Trio_Version:
db 0Dh, 0Ah
db "TR-DOS Startup File for WINDOWS 4 [ TRIO.SYS Version W4.1.0 ]"
db 0Dh, 0Ah
db "[ (c) Erdogan Tan - 2004 ]"
db 0Dh, 0Ah, 0
db 1 dup (0)
org 100h
Starting_Msg:
db 0Dh, 0Ah
db "Loading Kernel TRDOS... ", 0
db 1 dup (0)
org 200h
inc dx
dec dx
push cs
pop ds
mov bp, 7C00h ; ( SS = 0 )
mov si, offset Starting_Msg
call proc_printmsg
mov ah, 02h
int 1Ah
mov byte ptr [wait_seconds], dh
jc short pass_delay_loop
delay_loop:
mov ah, 11h
int 16h
jnz short loc_get_char
mov ah, 02h
int 1Ah
cmp dh, byte ptr [wait_seconds]
je short delay_loop
pass_delay_loop:
mov ah, 11h
int 16h
jz short load_run_time_system
loc_get_char:
mov ah, 10h
int 16h
or al, al
jz short load_run_time_system
cmp al, 1Bh
jnz short load_run_time_system
mov si, offset Msg_Trio_Version
call proc_printmsg
xor ah, ah
int 16h
jmp short load_ms_windows
load_run_time_system:
mov si, offset nextline
call proc_printmsg
call proc_loadrootdir
jc short load_ms_windows
call proc_find_file
cmp bx, 2
jb short load_ms_windows
mov word ptr [Destination], 8100h
mov ax, bx
loc_load_next_cluster:
mov word ptr [FAT_CurrentCluster], ax
mov bx, word ptr [Destination]
dec AX
dec AX
xor CH,CH
mov CL,Byte Ptr [bp][SecPerClust]
push ax
mov ax, word ptr [bp][BytesPerSec]
mul cx
add word ptr [Destination], ax
pop ax
mul CX
add AX,Word Ptr [bp][DataArea1]
adc DX,Word Ptr [bp][DataArea2]
; Linear address of the cluster
call proc_read
jc short loc_failed
mov ax, word ptr [FAT_CurrentCluster]
call proc_get_next_cluster
jc short loc_failed
cmp al, 0F0h
jb short loc_load_next_cluster
cmp byte ptr [bp][DriveNumber], 80h
jnb short pass_fat12_eoc_check
cmp ah, 0Fh
jb short loc_load_next_cluster
jmp short pass_fat16_eoc_check
pass_fat12_eoc_check:
cmp ah, 0FFh
jb short loc_load_next_cluster
pass_fat16_eoc_check:
mov bx, 800h
mov ds, bx
mov es, bx
mov ss, bx
mov sp, 0FFFFh
jmp dword ptr CS:[trio_offset]
loc_failed:
mov SI, offset trfailedmsg
call proc_printmsg
loc_retry:
xor AX,AX
int 16h
int 19h ; Reboot
Destination: dw 0
load_ms_windows:
mov si, offset nextline
call proc_printmsg
xor si, si
mov ds, si
mov si, 7DD8h ; "I" address of "IO.SYS"
dec byte ptr [SI] ; Convert JO.SYS to IO.SYS or
dec byte ptr [SI] ; IO.SYS to GO.SYS
jmp dword ptr CS:[win_boot_addr]
proc_start endp
proc_printmsg proc near
loc_print:
lodsb ; Load byte at DS:SI to AL
and AL,AL
je short loc_return ; If AL = 00h then return
mov AH,0Eh
mov BX,07h
int 10h ; BIOS Service func ( ah ) = 0Eh
; Write char as TTY
;AL-char BH-page BL-color
jmp short loc_print
loc_return:
retn
proc_printmsg endp
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_read
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_read proc near ; FAT/FILE Transfer Procedure
mov Byte Ptr [RetryCount],04h
loop_loc_14:
push CX ; # of FAT/FILE/DIR sectors
push AX ; Linear sector #
push DX ; DX_AX = Linear address (sectors)
mov CX,Word Ptr [bp][SecPerTrack]
push BX
call RX_DOS_DIV32 ; Special 32 bit divide !!!
; To fix large disk problem.
; After division, DX must
; contain high word part of
; number of track.
; Example : 63 sectors/track
; max. possible track no.
; without this bugfix = FFFFh
; (AX) and DX is remain.
; Max. possible sector number
; to read = FFFFh * 63.
; After bugfix, it is
; FFFFFFFFh
; (c) Erdogan Tan 1999
; (October 20th, 1999)
mov CX, BX ; Sector (zero based)
inc CX ; To make it 1 based
push CX
mov CX,Word Ptr [bp][Heads]
call RX_DOS_DIV32 ; Convert track to head & cyl
mov DH, BL ; BX = Head (max. FFh)
pop CX
; AX=Cyl, DH=Head, CX=Sector
pop BX ; ES:BX = Buffer
mov DL,Byte Ptr [bp][DriveNumber]
mov CH,AL
ror AH,1 ; Rotate right
ror AH,1
or CL,AH
mov AX,0201h
int 13h ; BIOS Service func ( ah ) = 2
; Read disk sectors
;AL-sec num CH-track CL-sec
; DH-head DL-drive ES:BX-buffer
;CF-flag AH-stat AL-sec read
; If CF = 1 then (If AH > 0)
jnc short pass_hex ; error code in AH
xchg AH,AL ; now it is in AL
call proc_hex ; Makes error code to visible
mov Word Ptr [Register_AX],AX
stc ; Set carry flag, again
pass_hex:
pop DX
pop AX
pop CX
jc short loc_16
add AX,1
adc DX,0
jc short loc_17
loc_15:
add BX,Word Ptr [bp][BytesPerSec]
loop loop_loc_14 ; Loop if CX > 0
retn
loc_16:
dec Byte Ptr [RetryCount]
jnz short loop_loc_14
loc_17:
retn
proc_read endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Rx_DOS 32 bit Divide ;
; (Special version by Erdogan Tan) ;
;- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -;
; ;
; input -> DX_AX = 32 bit dividend ;
; input -> CX = 16 bit divisor ;
; output -> DX_AX = 32 bit quotient ;
; output -> BX = 16 bit remainder ;
; ;
; This procedure divides the requested 32 bit number ;
; and gives the result in DX, AX and BX (remainder) ;
; ;
; Original Procedure by Michael Podanoffsky / Real Time DOS ;
; (c) Erdogan TAN 1999 [ RXDOSBIO.ASM ] ;
;............................................................;
Rx_Dos_Div32 proc near
mov bx, dx
xchg ax, bx
xor dx, dx
div cx ; at first, divide DX
xchg ax, bx ; remainder is in DX
; now, BX has quotient
; save remainder
div cx ; so, DX_AX divided and
; AX has quotient
; DX has remainder
xchg dx, bx ; finally, BX has remainder
retn
Rx_Dos_Div32 endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; From binary (byte) to hexadecimal (character) converter ;
; ;
; input -> AL = byte (binary number) to be converted ;
; output -> AH = First character of hexadecimal number ;
; output -> AL = Second character of hexadecimal number ;
; ;
; (c) Erdogan TAN 1998 - 1999 ;
;............................................................;
; 1998
proc_hex proc near
db 0D4h,10h ; Undocumented inst. AAM
; AH = AL / 10h
; AL = AL MOD 10h
or AX,'00' ; Make it ZERO (ASCII) based
xchg AH,AL
; 1999
cmp AL,'9'
jna pass_cc_al
add AL,7
pass_cc_al:
cmp AH,'9'
jna pass_cc_ah
add AH,7
pass_cc_ah:
; 1998
retn
proc_hex endp
proc_loadrootdir proc near
mov AL,Byte Ptr [bp][FATs] ; 10h = Number of FATs
cbw
mul Word Ptr [bp][FATsecs] ; 16h = # of FAT sectors
add AX,Word Ptr [bp][Hidden1]
adc DX,Word Ptr [bp][Hidden2]
add AX,Word Ptr [bp][ResSectors]
adc DX,0
mov Word Ptr [bp][DataArea1],AX
mov Word Ptr [bp][DataArea2],DX
push AX
push DX
mov AX,20h ; Size of a directory entry
mov CX,Word Ptr [bp][RootDirEnts]
mul CX
mov BX,Word Ptr [bp][BytesPerSec]
add AX,BX ; Round up
dec AX
div BX
add Word Ptr [bp][DataArea1],AX ; Location of the 1st data cluster
adc Word Ptr [bp][DataArea2],0
; AX = Total sectors of root directory
mov cx,ax
xor BX,BX ; Root directory buffer segment
mov ES,BX
mov BX,8000h
pop DX ; DX_AX = Location of root directory
pop AX
call proc_read
retn
proc_loadrootdir endp
proc_get_next_cluster proc near
; INPUT -> AX = Cluster Number, 16 bit
; OUTPUT -> clc -> No Error
; AX: Next Cluster Number, 16 bit
; stc -> Error
; mov word ptr [FAT_CurrentCluster], ax
xor dx, dx
; mov es, dx
mov di, 7000h ; [FAT_Buffer]
check_next_cluster_fat_type:
cmp byte ptr [bp][DriveNumber], 80h
jb short get_FAT12_next_cluster
get_FAT16_next_cluster:
mov bx, 300h ;768
div bx
; AX = Count of 3 FAT sectors
; DX = Sector Offset
shl dx, 1 ; Multiply by 2
push dx
mov bx, 3
mul bx
pop bx ; Sector Offset
; AX = FAT Sector
; DX = 0
cmp ax, word ptr [FAT_BufferSector]
jne load_FAT_sectors
mov ax, word ptr ES:[DI][BX]
retn
get_FAT12_next_cluster:
mov bx, 400h ;1024
div bx
; AX = Count of 3 FAT sectors
; DX = Buffer Entry Offset
push ax
mov ax, 3
mul dx ; Multiply by 3
shr ax, 1 ; Divide by 2
mov dx, ax
pop ax
push dx
mov bx, 3
mul bx
pop bx ; Buffer Byte Offset
; AX = FAT Beginning Sector
; DX = 0
cmp ax, word ptr [FAT_BufferSector]
jne short load_FAT_sectors
mov cx, word ptr [FAT_CurrentCluster]
shr cx, 1
mov ax, word ptr ES:[DI][BX]
jnc short get_FAT12_nc_even
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
get_FAT12_nc_even:
and ah,0Fh
retn
load_FAT_sectors:
mov word ptr [FAT_BufferSector], ax
xor dx, dx
add ax, word ptr [bp][Hidden1]
adc dx, word ptr [bp][Hidden2]
add ax, word ptr [bp][ResSectors]
adc dx, 0
mov bx, 7000h
mov cx, 3
call proc_read
jnc short pass_FAT_sectors_load_error
retn
pass_FAT_sectors_load_error:
mov ax, word ptr [FAT_CurrentCluster]
xor dx, dx
jmp check_next_cluster_fat_type
FAT_CurrentCluster: dw 0
FAT_BufferSector: dw 01A1h
proc_get_next_cluster endp
TRDOS_Kernel:
db "TRDOS RTS"
db 0
proc_find_file proc near
xor bx, bx
mov di, 8000h
mov cx, word ptr [bp][RootDirEnts]
push cx
loc_start_scan:
cmp byte ptr ES:[DI], 0
je short retn_from_find_file
push di
mov cx, 11
mov si, offset TRDOS_Kernel
loc_next_char:
cmpsb
jne next_file_search
loop loc_next_char
pop di
test byte ptr ES:[DI]+0Bh, 10h
jnz short retn_from_find_file ; It is a directory (BX=0)
mov bx, word ptr ES:[DI]+1Ah ; First Cluster
retn_from_find_file:
pop cx
retn
next_file_search:
pop di
add di,20h
pop cx
push cx
loop loc_start_scan
jmp short retn_from_find_file
proc_find_file endp
trio_offset: dw 0100h
trio_segment: dw 0800h
trfailedmsg:
db 0Dh, 0Ah
db 'DISK IO Error... '
Register_AX: db '0'
db '0'
Hex_Sign: db 'h'
Retry_Msg: db 0Dh, 0Ah
db 'Press any key to retry or reboot from another disk...'
NextLine: db 0Dh, 0Ah, 0
win_boot_addr: dw 7C00h
dw 0
RetryCount:
db 0A1h
db 1 dup(1)
Present ends
end start