; *****************************************************************************
;
; 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:\IO.WIN ->
; masm trio ->
; link /t trio ->
; copy trio.com a:\IO.SYS ]
; Copyright (C) 2000  Erdogan TAN  [ 16/03/2000 ]  Last Update: 18/04/2000
;
; *****************************************************************************

; Masterboot / Partition Table at Beginning+1BEh
ptBootable       equ 0
ptBeginHead      equ 1
ptBeginSector    equ 2
ptBeginCylinder  equ 3
ptFileSystemName equ 4
ptEndHead        equ 5
ptEndSector      equ 6
ptEndCylinder    equ 7
ptStartSector    equ 8
ptSectors        equ 12

; 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 - 2000 ]"
                db 0Dh, 0Ah, 0
                db 1 dup (0)

                org 100h
Starting_Msg:
                db 0Dh, 0Ah
                db "Starting TR-DOS..."
                db 0Dh, 0Ah, 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 pass_esc_check
                cmp al, 1Bh
                jnz short load_run_time_system
                mov si, offset Msg_Trio_Version
                call proc_printmsg

                jmp short load_run_time_system
                 
pass_esc_check:
                cmp ah, 3Bh
                jb short load_run_time_system
                cmp ah, 86h
                ja short load_run_time_system
                mov dl, 80h
                cmp ah, 44h
                jna short perform_required_func_0
                cmp ah, 84h
                ja short perform_required_func_1

load_run_time_system:
                mov si, offset nextline
                call proc_printmsg

                call proc_loadrootdir
                jc short loc_failed

                call proc_find_file
                cmp bx, 2
                jb loc_file_not_found

                mov word ptr [bp][Reserved2], bx
                
                mov ax, bx
                mov bx, 7E00h

		dec     AX
		dec     AX
                xor     CH,CH
                mov     CL,Byte Ptr [bp][SecPerClust]
		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

                xor     bx, bx
                mov     ds, bx

                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

perform_required_func_0:
                cmp ah, 43h
                jz  short load_presentator
                cmp ah, 44h
                jz  short load_tr_central
                mov al, ah
                sub al, 3Ah
                cmp ah, 3Eh
                jna short load_masterboot_of_hd
                inc dl
                sub al, 4
                jmp short load_masterboot_of_hd

perform_required_func_1:
                xor al, al
                cmp ah, 86h
                jnz short load_masterboot_of_hd
                inc dl
                jmp short load_masterboot_of_hd

load_presentator:
                mov si, offset presentator
move_file_name:
                mov di, offset S_File_Name
                push ds
                pop es
                mov cx, 11
                rep movsb
                jmp short load_run_time_system
load_tr_central:
                mov si, offset central
                jmp short move_file_name

load_masterboot_of_hd:
                mov byte ptr [Hard_Disk], dl
                mov byte ptr [Partition], al
                call proc_load_masterboot
                jc short loc_retry
                cmp byte ptr [Partition], 0
                ja short pass_print_ptable
                call proc_print_ptable
                mov si, offset Msg_Press_Part_Number
                call proc_printmsg
get_part_number:
                xor ah, ah
                int 16h
                sub al, '0'
                jna short get_part_number
                cmp al, 4
                ja short get_part_number
                mov byte ptr [Partition], al
pass_print_ptable:
                call proc_start_partition
                jc short loc_retry

                mov word ptr [Trio_Offset], BP

                jmp dword ptr [Trio_Offset]

loc_file_not_found:
                cmp byte ptr [S_File_Name], 'T'
                jnz short pass_trdos_rts
                mov si, offset trdosrts
print_f_not_found:
                call proc_printmsg
                mov si, offset Msg_NotFound
                call proc_printmsg
                mov si, offset Retry_Msg
                call proc_printmsg
                jmp loc_retry
pass_trdos_rts:
                cmp byte ptr [S_File_Name], 'C'
                jnz short pass_central_std
                mov si, offset trcentralstd
                jmp short print_f_not_found
pass_central_std:
                mov si, offset presentator
                jmp short print_f_not_found

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

trio_offset:    dw   7E00h
trio_segment:   dw   0

trfailedmsg:
		db   0Dh, 0Ah
		db   'Transaction failed...     Error code : '
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, 0h
RetryCount:
		db   0A1h

		db   1 dup(1)

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,1000h

		pop     DX                      ; DX_AX = Location of root directory
		pop     AX

                call proc_read

                retn

proc_loadrootdir        endp

central:
                db "CENTRAL STD"
                db 0
S_File_Name:
                db "TRDOS   RTS"
		db 0
Msg_NotFound:
                db "not found !"
		db 0Dh, 0Ah
		db 0
trdosrts:
                db "TRDOS.RTS"
                db 20h
                db 0
presentator:
                db "PRESENTATOR"
                db 20h
                db 0
trcentralstd:
                db "CENTRAL.STD"
                db 20h
                db 0

proc_find_file proc near
     xor bx, bx
     mov di, 1000h
     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 S_File_Name
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

proc_load_masterboot proc near

		    xor ah,ah
		    int 13h
		    jnc short pass_reset_error
harddisk_error:
		    xchg ah,al
		    call proc_hex
		    mov word Ptr [Register_AX], AX
		    mov si, offset HdResetFailedMsg
print_hd_err_message:
		    call proc_printmsg

		    stc

		    retn
pass_reset_error:
		    mov bx,700h
		    mov ax,0201h
		    mov cx,1
		    xor dh,dh
		    int 13h
		    jc short harddisk_error

                    mov si, 1FEh               ; 700h + 1FEh
                    cmp word ptr [SI],0AA55h
                    jnz short loc_not_masterboot

		    retn

loc_not_masterboot:
                    mov si, offset Msg_MasterBoot_Err
		    call proc_printmsg

		    stc

		    retn

proc_load_masterboot endp

proc_start_partition proc near

                    mov si, 1BEh ; 700h+1BEh, beginning of partition table
		    mov al, byte ptr [Partition]
		    dec al
		    mov bl, 10h
		    mul bl
		    add si, ax
                    cmp byte ptr [SI][ptFileSystemName],05h ; DOS EXT
                    jz short loc_ext_p_not_boot
                    cmp byte ptr [SI][ptFileSystemName],0Fh ; WIN 95/98 EXT
                    jnz short loc_this_partition
loc_ext_p_not_boot:
                    mov si, offset Ext_Dos_not_boot
		    call proc_printmsg

		    stc

		    retn

loc_this_partition:
                    mov dl, byte ptr [Hard_Disk]
                    mov bx, 7C00h
                    mov dh, byte ptr [SI][ptBeginHead]
                    mov cx, word ptr [SI][ptBeginSector]
		    mov ax, 0201h
		    int 13h
                    jc  short harddisk_error

                    mov si, offset NextLine
                    call proc_printmsg

                    cmp word ptr [BP]+1FEh, 0AA55h
                    jnz short it_is_not_boot_sec

		    retn

it_is_not_boot_sec:
                    mov si, offset Msg_Boot_Err
		    call proc_printmsg

		    stc

		    retn

proc_start_partition endp

proc_print_ptable  proc near

                   push ES

                   push DS
                   pop  ES

                   mov bl, byte ptr [Hard_Disk]
                   sub bl, 80h
                   add bl, '1'
                   mov byte ptr [Pt_Drive_Num], bl

                   mov si, offset P_Table_Header
		   call proc_printmsg

		   mov cx,4
		   mov bl,'0'
                   mov si, 1AEh
loc_next_p_entry:
		   inc bl
		   add si, 10h
		   mov byte ptr [P_Number], bl
                   mov al, byte ptr [SI][ptFileSystemName]
                   cmp al, 0
                   jna short loc_free_entry
loc_filesys_str:
                   push si
                   push bx
                   cmp  al, 7
                   jna  short loc_microsoft_fs
; loc_non_dos_fs:
                   mov si, offset FS_WIN_32
                   cmp al, 0Bh                
                   jz short loc_move_fsname
                   cmp al, 0Ch
                   jz short loc_move_fsname
                   mov si, offset FS_WIN_P
                   cmp al, 0Eh
		   jz short loc_move_fsname
		   mov si, offset FS_WIN_EXT
                   cmp al, 0Fh
		   jz short loc_move_fsname
		   mov si, offset FS_SCO
                   cmp al, 63h
		   jz short loc_move_fsname
		   mov si, offset FS_Linux
                   cmp al, 83h
		   jz short loc_move_fsname
		   mov si, offset FS_LinuxSwap
                   cmp al, 82h
		   jz short loc_move_fsname
                   mov si, offset FS_LinuxExt
                   cmp al, 85h
		   jz short loc_move_fsname
                   mov si, offset FS_TR
                   cmp al, 0A1h
		   jz short loc_move_fsname
		   mov si, offset FS_Others
		   jmp short loc_move_fsname
loc_microsoft_fs:
                   dec  al
                   mov  bh, 0Bh
                   mul  bh
		   mov  si, offset FileSys_Names
		   add  si, ax
loc_move_fsname:
                   mov  di, offset P_FileSystem
		   push cx
		   mov  cx,11
		   rep  movsb
		   pop  cx
print_p_entry:
		   mov si, offset Partition_Table
		   call proc_printmsg

                   pop bx
                   pop si
loc_free_entry:
                   dec cx
		   jnz loc_next_p_entry
end_of_ptable:
                   pop ES

                   retn

proc_print_ptable  endp

Hard_Disk:         db 80h
Partition:         db 0
HdResetFailedMsg:  db 0Dh,0Ah
                   db "Drive is not ready !"
                   db 0Dh, 0Ah, 0h
Msg_MasterBoot_Err:
                   db 0Dh, 0Ah
                   db "MASTER"
Msg_Boot_Err:      db "BOOT ERROR : "
                   db "Not a valid boot sector !"
                   db 0Dh, 0Ah, 0h
Ext_Dos_not_boot:
                   db 0Dh, 0Ah
                   db "Extended DOS partition is not bootable !"
                   db 0Dh, 0Ah, 0h
P_Table_Header:
		   db 0Dh, 0Ah
                   db "FIXED DISK DRIVE : "
PT_Drive_Num:      db '1'
                   db 0Dh, 0Ah, 0Dh, 0Ah, 0
Partition_Table:
                   db "PARTITION "
P_Number:          db '0'
                   db 20h
                   db '-'
                   db 20h
                   db "TYPE : "
P_FileSystem:      db 11 dup(20h)
		   db 0Dh, 0Ah, 0h
Msg_Press_Part_Number:
                   db 0Dh, 0Ah 
                   db "Press a NUMBER key for starting related partition..."
                   db 0Dh, 0Ah, 0
FileSys_Names:
		   db "DOS FAT12  "
                   db "XENIX      "    
		   db "XENIX User "
		   db "DOS FAT16  "
		   db "DOS EXT    "
		   db "DOS FAT16  "
FS_NTFS:           db "WINDOWS NT "  ; 07h , WINDOWS 2000 NTFS File System
FS_WIN_32:         db "WIN4 FAT32 "
FS_WIN_P:          db "WIN4 FAT16 "
FS_WIN_EXT:        db "WIN4 EXT   "    
FS_SCO:            db "SCO Unix   "  ; 63h , SCO UNIX, UNIXWARE, OPENSERVER
FS_Linux:          db "Linux      "  ; 83h , LINUX NATIVE (ext2) Partition
FS_LinuxSwap:      db "Linux Swap "  ; 82h , LINUX SWAP Partition
FS_LinuxExt:       db "Linux Ext  "  ; 85h , LINUX EXTENDED Partition
FS_TR:             db "TR-MULTIX  "  ; A1h , MULTIX 2004 File System (i386) !
FS_Others:         db "Non-DOS    "

MagicBytes:        db "417"
                   db 0
MagicWord:         dw 07ACh

Present            ends

		   end  start
