; CENTRAL.COM (CENTRAL.ASM)
; "Turkish Rational CENTRAL" Standalone Program (TR-CENTRAL v1.0)
; (C)opyright Erdogan Tan - 30 DECEMBER 2000
; Not completed...
; [ Under development since 23/11/2000 ]
; the DEVELOPMENT HISTORY:
; 1993: Starting with AMD 386DX-40, 4 MB RAM, 240 MB fdisk, Sound Blaster Pro
; 1993-1996 : C, Assembly, Visual Basic, DOS, XENIX/UNIX, WINDOWS experiences
; 1996 : Deciding to develop 417 DOS (ALTERNATIVE DOS, TR-DOS), TR-CENTRAL
; (Planning the final stage as MULTIX 2000 Operation System)
; (on DEVICE:SECTION:DISPLACEMENT logic)
; Deciding to use 'TURKISH RATIONAL' mark. Shortly, 'TR'.
; 1996-1998:
; Visual Basic, C and Assembly Programs
; ADRES 417, URETIM 417 programs with original DATA INDEXING methods
; 1998:
; Entrance to Internet, beginning of WEB SITE works
; (Deciding to use TRANSACTION term instead of EXECUTION or OPERATION)
; (Revisioning MULTIX-2000 OS plans to MULTIX-2004 TS)
;
; 1998-2000: PRESENTATOR (P2000.ASM), the beginning/rising of TR-DOS.
; 1999:
; WWW.SINGLIX.COM
; Deciding to develop SINGLIX before TR-Multix
; 2000: Finishing of the first TR-DOS Operation System stage (P2000.ASM v1.1)
; Beginning of TR-CENTRAL Standalone Program development
; (Beginning of developing/creating TR-MULTIX's particular FS elements)
; 23/11/2000 : Writing CENTRAL's INITIALIZATION code ...
; (Enabling A20 line, re-vectoring INT 18h)
; 25/11/2000 : Initialization Success !!! (Program will grow by time)
; 28/11/2000 : INT 18h -> AX=01A1h, BH=0 BL=0 Function = Print ASCIIZ string.
; This function's procedure is placed in Conventional Memory.
; "If AX <> 01A1h then START TR-CENTRAL (MENUPROG)" func is OK.
; 29/11/2000 : Running INT 18h handler in Extended Memory is OK.
; (Code located at FFFFh:0300h) (FFFFh:0010h -> 'TR')
; 02/12/2000 : Temporary "Invalid INT 18h Function Call !" function is OK.
; 03/12/2000 : INT 18h -> AX=01A1h, BH=0 BL=1 to FFh
; Function = Print ASCII ZERO string with requested color in BL.
; (At current cursor location. On current page.)
; Return -> BL = 7
; NOTE : INT 18h -> AX= 01A1h BX=0 is direct write the ASCII ZERO string
; to Page 0 with Color/Attribute 7. (INT 10h -> AH= 0Eh, BX= 07h)
; 08/12/2000 : INT 18h -> AX= 01A1h BH=1
; Function = Change color or attribute of a bar (character block)
; BL= Color&Attrib CL= Number of colums CH= Columns per line
; DL= Beginning column DL= Beginning line
; DI= Video buffer segment (ES<-DI, DI<-0) (B800h, B000h etc.)
; 12/12/2000 : INT 18h Entrance code and Function bh0 (bh=0) optimized.
; ("cmpsw" instruction before "read_port_60h")
; 16/12/2000 : INT 18h AX=01A1h BH=2 BL=0 32 bit single/simple division
; DX_AX = dividend , CX = divisor
; DS:SI = pointer for AX, DX, CX
; 16/12/2000 : INT 18h AX=01A1h BH=2 BL>0 32 bit repetitive division
; BL = number of digits, CX = 10 (divisor), DX_AX = dividend
; DS:SI = pointer for AX, DX, CX
; ES:DI = result buffer (for string of decimal result)
; 17/12/2000 : INT 18h AX=01A1h BH=3 BL = Drive Number
; Function = Get disk/drive parameters
; DS:SI = pointer for TR-DOS physical disk parameter table
; OUTPUT = Parameters recorded in DS:SI fields . CF=1 -> error
; 17/12/2000 : INT 18h AX=01A1h BH=4 BL = the byte to be converted
; Function = Convert byte to hexadecimal number digits (char)
; OUTPUT -> AX = Hex number digits in AL (x1) and AH (x16)
; 17/12/2000 : INT 18h AX=01A1h BH=5 BL = Retry Count for failed reading
; Function = READ DISK SECTORS
; DS:SI = pointer for TR-DOS physical disk parameter table
; (OUTPUT : If CF=1 -> reading failed ; CX = remain sectors)
; 24/12/2000 : INT 18h AX=01A1h BH=6 BL= Sector count of the GP Buffer
; Function = INITIALIZE (RESET) RUN TIME SYSTEM DESCRIPTORS
; DS:SI = Requested Location of MAIN DESCRIPTOR TABLE
; ES:DI = Requested Location of General Purpose Buffer
; OUTPUT => ax = 01A1h -> successful bh = major version of RTS
; bl = minor version of RTS (TR-CENTRAL)
; WARNING! All buffers and descriptor data (parameter tables)
; will be reset. Also, MEMORY ALLOCATION TABLE will be reset...
; NOTE: Minimum: 7 + total DOS Drives, Maximum: 7+26 sectors must be
; available (free) from beginning at DS:SI. Otherwise, some
; data (in these sectors) will be erased/overwritten. Also,
; offset value for main descriptor table, must be less than
; 65636 - (512*(7+ total DOS drives)) or < BE00h is good...
; DOS DRIVES: 2 Floppy + 4 Primary + 16 Logical + 4 Virtual = 26 (maximum).
; 28/12/2000 : INT 18h AX=01A1h BH=7 BL= 0
; Function = RETURN (GET) MAIN DESCRIPTOR TABLE ADDRESS
; OUTPUT => ax= offset of MDT, dx= segment of MDT
; bh= major version of MDT (RTS), bl= minor version of MDT.
; * BL = 1 -> Function = RETURN MEMORY ALLOCATION TABLE ADDRESS
; Output => ax= MAT offset, dx= MAT segment, bx= MDT version
; * BL = 2 -> Function = Return General Purpose Buffer Address
; Output => ax= GPB offset, dx= GPB segment, bx= sector count
; * BL = 3 -> Function = RETURN CURRENT DOS DRV PRM. TBL. ADDRESS
; Output => ax= Offset of Current DOS Drive Parameter Table
; dx= Segment of Current DOS Drive Parameter Table
; bx= Number of DOS drives (the result of RTS init)
; * BL = 4 -> Function = RETURN FREE (CONVENTIONAL) MEMORY COUNT
; Output => ax= First free block number (1 block = 512 bytes)
; dx= Free block count from the first block
; bx= Total free block count (Free bytes = bx * 512)
; * BL = 5 -> Function = RETURN FREE CONTINUOUS MEMORY COUNT
; Output => ax= Beginning block (Beginning of Max. free blocks)
; dx= Free continouos block count from the beginning
; bx= Total free block count (Free bytes = bx * 512)
; * BL > 5 -> Invalid Function Call
;###############################################################################
; CENTRAL.ASM (CENTRAL.COM, CENTRAL.BIN)
PAGE 60,132
Reserved1 equ 12h ; FFFFh:0012h -> Reserved Word 1
Reserved2 equ 14h ; FFFFh:0014h -> Reserved Word 2
CentralVer equ 16h ; FFFFh:0016h -> TR-CENTRAL Version, 0 -> 1.0
RetryCount equ 17h ; Byte ptr, FFFFh:0017h
MDT_Offset equ 18h ; Word ptr, FFFFh:0018h
MDT_Segment equ 1Ah ; Word ptr, FFFFh:001Ah
GPB_Offset equ 1Ch
GPB_Segment equ 1Eh
GPB_Sectors equ 20h
DOS_Drives equ 21h
;ÄÄÄÄÄÄÄÄÄÄ CODE_SEG ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
CODE_SEG segment para public
assume CS:CODE_SEG, DS:CODE_SEG, SS:CODE_SEG, ES:CODE_SEG
org 100h ; org 7E00h (CENTRAL.BIN)
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± ENTRY POINT
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_start
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_start proc near
start: ; N-Ref=0
jmp load
dw 1 dup(01A1h)
proc_start endp
org 200h
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_handler
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_handler proc far
INT18h_handler:
cld
cmp ax, 01A1h
jne short pass_01A1h_function0
cmp bx, 0
ja short pass_01A1h_function1
call proc_print_msg
IRET
pass_01A1h_function0:
xor bx, bx
pass_01A1h_function1:
cli
push cx
push di
push si
push es
push ds
xor si, si
mov ds, si
mov di, 0FFFFh
mov es, di
mov di, 10h
cmpsw
push cs
pop ds
jne short pass_read_port_60h
call check_input_buffer
jnz short return_with_error
mov al, 0D0h
out 64h, al
call check_input_buffer
jnz short return_with_error
xor cx, cx
read_port_60h:
in al, 60h
and al, 2
loopz read_port_60h
jz short pass_msg_performed
pass_read_port_60h:
mov di, 10h
cmp word ptr ES:[DI], 'RT'
je short pass_msg_tr_failed
mov si, offset msg_tr_failed
call proc_print_msg
mov si, offset msg_01A1h
call proc_print_msg
jmp short return_from_INT18h
pass_msg_tr_failed:
call dword ptr [Extended_Int18h_Handler]
jmp short return_from_INT18h
pass_msg_performed:
call proc_enable_a20_line
jnz short return_with_error
mov si, offset msg_A20_line_enabled
call proc_print_msg
jmp short pass_msg_tr_failed
check_input_buffer:
xor cx, cx
loc_in_al:
in al, 64h
and al, 2
loopnz loc_in_al
retn
return_with_error:
mov si, offset msg_tr_failed
call proc_print_msg
mov si, offset msg_a20_line
call proc_print_msg
return_from_INT18h:
pop ds
pop es
pop si
pop di
pop cx
sti
IRET
proc_handler endp
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_enable_a20_line
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_enable_a20_line proc near
enable_a20_line:
mov al, 0D1h
out 64h, al
call check_input_buffer
jnz short return_from_enabling
mov al, 0DFh
out 60h, al
call check_input_buffer
return_from_enabling:
retn
proc_enable_a20_line endp
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_print_msg
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_print_msg 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_print_msg endp
msg_tr_failed:
db 07h
db 0Dh, 0Ah
db 'TRANSACTION FAILED !'
db 0Dh, 0Ah
db 'Error Code : '
db 0
msg_a20_line:
db 'A20'
db 0Dh, 0Ah, 0
msg_01A1h:
db '01A1h'
db 0Dh, 0Ah, 0
msg_A20_line_enabled:
db 07h
db 0Ah, 0Dh
db 'A20 LINE ENABLED ...'
db 0Ah, 0Dh, 0
var_INT18h_off: dw 0
var_INT18h_seg: dw 0
Extended_Int18h_Handler:
dw 0300h ; Offset
dw 0FFFFh ; Segment
ReservedWord:
dw 0A500h
org 300h
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_ext_int18h
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_ext_int18h proc far
begin:
pop word ptr CS:[Reserved1]
pop word ptr CS:[Reserved2]
pop ds
pop es
pop si
pop di
pop cx
push cx
push di
push si
push es
push ds
push word ptr CS:[Reserved2]
push word ptr CS:[Reserved1]
cmp bx,0
ja short pass_start_menuprog
start_menuprog:
mov si, offset msg_performed
call call_from_start_menuprog
retf
pass_start_menuprog:
mov al,bh
cbw
shl ax, 1
push bp
mov bp, ax
add bp, 100h
call word ptr CS:[BP]
pop bp
retf
function_bh0:
; push bx
mov ah, 0Fh
int 10h
; pop ax
; mov bl, al
push bx
mov ah, 3
int 10h
push ds
push si
pop bp
pop es
xor cx, cx
loc_scanb:
lodsb
and al,al
jz short pass_repeat_scanb
inc cx
jmp short loc_scanb
pass_repeat_scanb:
mov ax, 1301h
int 10h
retn_from_bh0:
pop bx
mov bl, 7
mov ax, 0920h
mov cx, 80
int 10h
retn
function_bh1:
push di
push cx
push di
pop es
mov al, dh
mul ch
add al, dl
adc ah, 0
shl ax, 1
mov di, ax
xor ch, ch
change_next_column_color:
mov byte ptr ES:[DI]+1, bl
inc di
inc di
loop change_next_column_color
pop cx
pop di
retn
function_bh2:
; DI:SI = Pointer for AX, DX, CX, BX from caller
mov ax, word ptr [SI]
mov bx, word ptr [SI]+2
mov cx, word ptr [SI]+4
and bl, bl
jz short rxdos_div32
xor bh, bh
mov cx, 10 ; Divisor
trdos_re_div32:
push bp
mov bp, bx ; Repetition, number of digits
rediv32_divide_loop:
call rxdos_div32
add bl, '0' ; To make visible
mov byte ptr ES:[DI][bp], bl ; ES:DI = Result Buffer
dec bp
or ax, ax
ja short rediv32_divide_loop
or dx, dx
ja short rediv32_divide_loop
fill_digit_space:
mov byte ptr ES:[DI][bp], 20h
or bp, bp
jna short end_of_rediv32
dec bp
jmp short fill_digit_space
end_of_rediv32:
pop bp
retn
rxdos_div32:
; DX_AX = 32 bit dividend
; CX = 16 bit divisor
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
; DX_AX = 32 bit quotient
; BX = 16 bit remainder
; CX = 16 bit divisor
retn
function_bh3:
push dx
mov byte ptr [SI], bl ; Drive number
mov dl, bl
mov ah, 8
int 13h
jnc short dparam_no_error
call proc_hex
; AX = Error code , DS:SI = Disk parameter table (offset +2)
stc
jmp short return_from_dparam
dparam_no_error:
mov byte ptr [SI]+1, dl ; Number of (this type) disks
mov word ptr [SI]+2, 200h ; Bytes per Sector
push cx
and cl, 3Fh
xor ch, ch
; DS:SI = disk parameter table (offset +2)
mov word ptr [SI]+4, cx ; Sector per Track
pop cx
mov dl, dh
xor dh, dh
inc dx
mov word ptr [SI]+6, dx ; Heads
shr cl, 1
shr cl, 1
shr cl, 1
shr cl, 1
shr cl, 1
shr cl, 1
xchg ch, cl
inc cx
mov word ptr [SI]+8, cx ; Cylinders
; ES:DI = BIOS disk parameter table address (INT 13h output)
mov word ptr [SI]+22, di
mov word ptr [SI]+24, es
; DS:[SI]+12 = Current disk sector (linear)
; DS:[SI]+16 = Sector count
; DS:[SI]+18 = Buffer offset
; DS:[SI]+20 = Buffer segment
; DS:[SI]+22 = BIOS disk parameter table offset
; DS:[SI]+24 = BIOS disk parameter table segment
; DS:[SI]+26 = Number of sectors, low word
; DS:[SI]+28 = Number of sectors, hight word
; DS:[SI]+30 = Reserved word
cmp byte ptr [SI], 80h
jb short dparam_15h_error
mov dl, byte ptr [SI] ; Drive number
mov ah, 15h
int 13h
jc short dparam_15h_error
mov word ptr [SI]+26, dx
mov word ptr [SI]+28, cx
mov al, 15h
mov word ptr [SI]+30, ax
xor ax, ax
return_from_dparam:
mov word ptr [SI]+10, ax
pop dx
retn
dparam_15h_error:
xor ax, ax
mov word ptr [SI]+26, ax
mov word ptr [SI]+28, ax
mov word ptr [SI]+30, ax ; Reset of the reserved word
jmp short return_from_dparam
function_bh4:
mov al, bl
proc_hex:
db 0D4h, 10h ; AAM
; output : AH = AL / 10h
; AL = AL mod 10h
or ax, '00'
xchg ah, al
cmp al, '9'
jna short pass_cc_al
add al, 7
pass_cc_al:
cmp ah, '9'
jna short retn_from_bh4
add ah, 7
retn_from_bh4:
retn
function_bh5:
; BL = Retry count
; Number of sectors is in DS:[SI]+16,
; beginning sector is in DS:[SI]+12,
; buffer is in DS:[SI]+18,
; drive number is in DS:[SI]
; sector per track is in DS:[SI]+4
; heads is in DS:[SI]+6
; bytes per sector is in DS:[SI]+2
; error code will be in DS:[SI]+10
mov byte ptr CS:[RetryCount], bl
mov cx, word ptr [SI]+16
mov ax, word ptr [SI]+12
mov dx, word ptr [SI]+14
mov es, word ptr [SI]+20
mov bx, word ptr [SI]+18
mov word ptr [SI]+10, 3030h ; Error code
proc_read:
push CX ; Number of sectors
push AX
push DX ; DX_AX = beginning sector
mov CX,Word Ptr [SI]+4 ; Sectors per track
push BX
call rxdos_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 [SI]+6 ; Number of Heads
call rxdos_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 [SI] ; Drive number
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_read_error ; error code in AH
xchg AH,AL ; now it is in AL
call proc_hex ; Makes error code to visible
mov Word Ptr [SI]+10,AX
stc ; Set carry flag, again
pass_read_error:
pop DX ; DX_AX = Current Sector
pop AX
pop CX ; CX = Sector count
jc short dec_retry_count
add AX,1
adc DX,0
jc short retn_from_bh5
add BX,Word Ptr [SI]+2 ; Bytes per sector
jnc short pass_next_buffer_segment
push BX
mov BX, ES
add BX, 1000h
mov ES, BX
clc ; Return from F000 to 0 will be accepted.
pop BX
pass_next_buffer_segment:
loop proc_read ; Repeat if CX > 0
retn
dec_retry_count:
dec Byte Ptr CS:[RetryCount]
jnz short proc_read
retn_from_bh5:
retn
function_bh6:
push ds
xor ax, ax ; Instead of
dec ax ; MOV AX, 0FFFFh instruction
mov ds, ax
pop ax
mov word ptr DS:[MDT_Offset], si
mov word ptr DS:[MDT_Segment], ax ; DS
mov word ptr DS:[GPB_Offset], di
mov word ptr DS:[GPB_Segment], es
mov byte ptr DS:[GPB_Sectors], bl
mov byte ptr DS:[DOS_Drives], 0
mov ds, ax
mov word ptr [SI], 'DM' ; MDT Sign And Version (0)
mov byte ptr [SI]+2, 'T'
mov byte ptr [SI]+3, 0
mov word ptr [SI]+4, DI ; General Purpose Buffer Offset
mov word ptr [SI]+6, ES ; General Purpose Buffer Segment
xor bh, bh
mov word ptr [SI]+8, BX ; GP Buffer Sector Count
mov bx, si
add bx, 128
mov word ptr [SI]+116, BX ; Offset of V. Disk Parameter Tbl.
mov word ptr [SI]+118, DS ; Segment of Virtual Disk P. Tbl.
mov word ptr [SI]+120, 0420h ; [SI]+120= Number of vdisks, 4
; [SI]+121= Table size, 32 bytes
; [SI]+128 -> Virtual Disk P. Tbl.
; !!! Virtual disk functions not
; included by this RTS version !!!
add bx, 128
mov word ptr [SI]+16, BX ; Offset of P. Disk Parameter Tbl.
mov word ptr [SI]+18, DS ; Segment of Physical Disk P. Tbl.
mov word ptr [SI]+20, 0820h ; [SI]+20= Number of Disks, 8
; [SI]+21= Table size, 32 bytes
; [SI]+256 -> P. Disk Paramater T.
add bx, 256
mov word ptr [SI]+10, BX ; Offset of Memory Alloc Table
mov word ptr [SI]+12, DS ; Segment of Memory Alloc Table
mov word ptr [SI]+14, 2048 ; Size of MAT in bytes
add bx, 2048
mov word ptr [SI]+22, BX ; Offset of P. DOS Partition Tbl.
mov word ptr [SI]+24, DS ; Segment of Primary DOS P. Tables
mov word ptr [SI]+26, 0404h ; [SI]+26= Number of P. DOS P.
; [SI]+27= Number of Ext. DOS P.
; [SI]+21= Table size, 32 bytes
; [SI]+2048+256 = non-dos partition
; tables. 8 tables, 32 bytes/table
add bx, 512
mov word ptr [SI]+28, BX ; Offset of Logical DOS P. Tables
mov word ptr [SI]+30, DS ; Segment of L. DOS Partition Tbl.
mov word ptr [SI]+32, 1020h ; [SI]+32= Number of L. DOS P.
; [SI]+33= Table size, 32 bytes
add bx, 512
mov word ptr [SI]+34, BX ; Offset of Current DOS Drv Tbl.
mov word ptr [SI]+36, DS ; Segment of Current DOS Drv Tbl.
mov word ptr [SI]+38, 0 ; [SI]+38= DOS Drive Number
; [SI]+39= File System Type
; 0= Non-dos or unknown
; 1= FAT 12 ;12 bit cluster
; 2= FAT 16 ;16 bit cluster
; 3= FAT 32 ;28 (+4) bit cluster
; 4= FAT 24 ;24 (+8) bit cluster
; FAT 24 is a TR-DOS FS Feature
add bx, 512
mov word ptr [SI]+40, BX ; Offset of DOS Drive Tables
mov word ptr [SI]+42, DS ; Segment of DOS Drive Tables
mov word ptr [SI]+44, 0 ; [SI]+44= Number of DOS Drives
; [SI]+45= Drive Table Version (0)
; mov word ptr [SI]+46, 0 ; Location of Source (Read) Buffer
; mov word ptr [SI]+48, 0
; mov word ptr [SI]+50, 0 ; Source Device (Read) Buffer size
; mov word ptr [SI]+52, 0 ; Source device
; [SI]+52 -> Disk or dos drive no.
; [SI]+53 -> 0 = non-dos (disk)
; [SI]+53 -> 1-4 = FAT (DOS drive)
; mov word ptr [SI]+54, 0 ; Location of Dest (Write) Buffer
; mov word ptr [SI]+56, 0
; mov word ptr [SI]+58, 0 ; Destination Device Buffer size
; mov word ptr [SI]+60, 0 ; Destination device
; [SI]+60 -> Disk or dos drive no.
; [SI]+61 -> 0 = non-dos (disk)
; [SI]+61 -> 1-4 = FAT (DOS drive)
; mov dword ptr [SI]+64, 0 ; Location of FAT Description Tbl.
; mov dword ptr [SI]+68, 0 ; Location of FAT Buffer
; mov word ptr [SI]+72, 0 ; FAT Buffer Size in sectors
; mov dword ptr [SI]+74, 0 ; Location of DIR Description Tbl.
; mov dword ptr [SI]+78, 0 ; Location of DIRECTORY Buffer
; mov word ptr [SI]+82, 0 ; DIR Buffer Size in sectors
; mov dword ptr [SI]+84, 0 ; Source File Description Table
; mov dword ptr [SI]+88, 0 ; Source File Cluster Chain
; mov word ptr [SI]+92, 0 ; Number of Source File Clusters
; mov dword ptr [SI]+94, 0 ; Destination File Desc. Table
; mov dword ptr [SI]+98, 0 ; Destination File Cluster Chain
; mov word ptr [SI]+102, 0 ; Number of Dest File Clusters
; mov dword ptr [SI]+104, 0 ; Current Dir Cluster Chain
; mov word ptr [SI]+108, 0 ; Number of Current Dir Clusters
; mov word ptr [SI]+110, 0 ; Free Memory Sectors
; mov word ptr [SI]+112, 0 ; Max. free continuous mem secs
; mov word ptr [SI]+114, 0 ; Beginning of max. free sectors
; mov byte ptr [SI]+122, 0 ; Number of open files
; mov byte ptr [SI]+123, 0 ; Maximum number of open files
; mov word ptr [SI]+124, 0 ; Reserved
; mov word ptr [SI]+126, 0 ; Reserved
mov di, si
add di, 46
push ds
pop es
xor ax, ax
mov cx, 1513 ; 233 + 2048/2 + 512/2
rep stosw
mov word ptr [SI]+62, '01' ; RTS Version (1.0)
; ############ Memory Allocation Table initialization #######################
push ds
xor ax, ax ; Instead of
dec ax ; MOV AX, 0FFFFh instruction
mov ds, ax
add si, 512 ; Memory Allocation Table Offset
mov di, si
mov ax, 0101h ; 1 = Reserved area identifier
mov cx, 4 ; 8 blocks
rep stosw ; Memory location = 0-4096 (0-1000h)
mov dx, word ptr DS:[GPB_Segment]
mov ax, word ptr DS:[GPB_Offset]
call Convert_Address_to_Memory_Block
mov di, si
add di, ax ; MAT Block Offset
xor ch, ch
mov cl, byte ptr DS:[GPB_Sectors]
mov al, 2 ; 2 = General purpose buffer
rep stosb
mov di, si ; MAT Offset
mov dx, word ptr DS:[MDT_Segment]
mov ax, word ptr DS:[MDT_Offset]
call Convert_Address_to_Memory_Block
add di, ax ; MAT Block Offset
mov al, 3 ; 3 = Main Descriptor Table
stosb
mov ax, 0404h ; 4 = Memory Allocation Table
stosw
stosw
mov al, 5 ; 5 = Partition parameter tables
stosb
mov al, 6 ; 6 = Current DOS drv parameter tbl.
stosb
xor ch, ch
mov cl, byte ptr DS:[DOS_Drives]
mov al, 7 ; 7 = DOS drive parameter tables
rep stosb
mov al, 8 ; 8 = Boot Sector Buffer
mov byte ptr ES:[SI]+62, al ; SI = MAT offset,
; 62 = Mem. block no. of 0:7C00h
; 512+62 = 574 = memory block offset
mov di, si
add di, 1280
mov ax, 0101h ; 1 for A000:0000 to FFFF:000F
mov cx, 384
rep stosw
; 9 = TR-DOS kernel
; 0Ah = FAT Buffer Description Table
; 0Bh = FAT Buffer
; 0Ch = DIR Buffer Description Table
; 0Dh = DIRECTORY Buffer
; 0Eh = Transaction Descriptor Table
; 0Fh = Undefined DATA (buffer etc.)
; 10h-EFh = Files (14 open files)
; ?0h -> File Description Table
; ?1h -> 1'st part of file
; ?Eh -> 14'th part of file
; ?Fh -> undefined data for file
; F0h-FFh = Reserved for TR-DOS
pop ds
; ############ Disk Parameters Tables initialization ########################
xor bl, bl
sub si, 256 ; DS:SI = MAT location
; SI-256 = Offset of fd0 Param. Tbl.
push si
call function_bh3
cmp byte ptr [SI]+1, 2
jb short pass_dpt_init_fd
mov bl, 1
add si, 32 ; SI+32 = Offset of fd1 Param. Tbl.
call function_bh3
pass_dpt_init_fd:
pop si
add si, 64
mov bl, 80h
call function_bh3
xor ch, ch
mov cl, byte ptr [SI]+1
repeat_dpt_init_hd:
cmp cl, 2
jb short end_of_dpt_init_hd
dec cl
inc bl
push cx
add si, 32
call function_bh3
pop cx
loop repeat_dpt_init_hd
end_of_dpt_init_hd:
; PROCEDURE initialize DOS drives (A: -> Z:)
; the CODE is NOT READY yet
; (Partition description tables and
; dos drive description tables would be initialized, here)
; End of DOS drive initialization procedure
push ds
xor ax, ax ; Instead of
dec ax ; MOV AX, 0FFFFh instruction
mov ds, ax
xor dh, dh
mov dl, byte ptr DS:[DOS_Drives] ; Number of DOS drives
mov bh, 0 ; Version 1.0
mov bl, byte ptr DS:[GPB_Sectors]
pop ds
mov ax, 01A1h ; Successful
; NOTE: DS:SI and ES:DI will be returned with their
; beginning values, already, they are MDT and GPB pointers
; ALSO, Version number recorded at DS:[SI]+62 (MDT offset 62)
retn
Convert_Address_to_Memory_Block:
; dx = Segment
; ax = Offset
push ax
mov ax, 16
mul dx
pop cx
add ax, cx
adc dx, 0
add ax, 511
adc dx, 0
mov cx, 512
call RXDOS_DIV32
; AX = Block Number
; DX = 0
; CX = 512
; BX = Remainder of DX_AX + 511
end_of_catmb:
retn
function_bh7:
cmp bl, 5
ja invalid_fcall
cmp bl, 2
jz short loc_bh7_bl2
mov si, word ptr CS:[MDT_Offset]
mov ds, word ptr CS:[MDT_Segment]
ja short loc_bh7_bl3
and bl, bl
mov bx, word ptr [SI]+62 ; Version
jz short loc_bh7_bl0
add si, 512 ; MAT offset
loc_bh7_bl0:
mov ax, si
mov dx, ds
retn
loc_bh7_bl2:
mov ax, word ptr CS:[GPB_Offset]
mov dx, word ptr CS:[GPB_Segment]
xor bh, bh
mov bl, byte ptr CS:[GPB_Sectors]
retn
loc_bh7_bl3:
cmp bl, 3
jnz short loc_bh7_bl4_bl5
mov ax, word ptr [SI]+34 ; Offset
mov dx, word ptr [SI]+36 ; Segment
mov bh, byte ptr [SI]+38 ; DOS drive number (0 based)
mov bl, byte ptr CS:[DOS_Drives] ; Number of DOS drives
retn
loc_bh7_bl4_bl5:
mov cx, 2048
add si, 511
mov di, si
xor ax, ax
repeat_bh7_scan_mat0:
inc si
cmp byte ptr [SI], 0
ja short pass_inc_bh7_scan_mat0
inc ax
pass_inc_bh7_scan_mat0:
loop repeat_bh7_scan_mat0
mov cx, 2048
mov si, di
xor dx, dx
cmp bl, 4
mov bx, ax ; Total free blocks (512 bytes)
ja short repeat_bh7_scan_mat2
repeat_bh7_scan_mat1:
inc si
cmp byte ptr [SI], 0
je short pass_inc_bh7_scan_mat1
loop repeat_bh7_scan_mat1
mov ax, 0FFFFh
retn
pass_inc_bh7_scan_mat1:
mov ax, si
inc di
sub ax, di
inc dl
jmp short bh7_scan_mat1x_dec_cx
repeat_bh7_scan_mat1x:
inc si
cmp byte ptr [SI], 0
ja short pass_inc_bh7_scan_mat1x
inc dx
bh7_scan_mat1x_dec_cx:
loop repeat_bh7_scan_mat1x
pass_inc_bh7_scan_mat1x:
retn
repeat_bh7_scan_mat2:
inc si
cmp byte ptr [SI], 0
je short pass_inc_bh7_scan_mat2
loop repeat_bh7_scan_mat2
mov ax, 0FFFFh
retn
pass_inc_bh7_scan_mat2:
inc dl
mov bp, si
inc di
sub bp, di
xor ax, ax
inc al
jmp short bh7_scan_mat2x_dec_cx
repeat_bh7_scan_mat2x:
inc si
cmp byte ptr [SI], 0
ja short pass_inc_bh7_scan_mat2x
inc ax
bh7_scan_mat2x_dec_cx:
loop repeat_bh7_scan_mat2x
inc si
and ax, ax
jnz short pass_inc_bh7_scan_mat2x
mov ax, bp
retn
pass_inc_bh7_scan_mat2x:
cmp ax, dx
jb short pass_bh7_chg_mb_count_base
mov dx, ax
mov bp, si
add ax, di
sub bp, ax
pass_bh7_chg_mb_count_base:
xor ax, ax
and cx, cx
jnz short bh7_scan_mat2x_dec_cx
mov ax, bp
retn
invalid_fcall:
mov si, offset msg_invalid
call_from_start_menuprog:
push cs
pop ds
mov bl, 7
call function_bh0
stc
retn
msg_Performed:
db 07h
db 0Ah, 0Dh
db 'Extended INT 18h Function Call Performed ...'
db 0Ah, 0Dh, 0h
msg_Invalid:
db 07h
db 0Ah, 0Dh
db 'Invalid INT 18h Function Call !'
db 0Ah, 0Dh, 0h
db '417'
proc_ext_int18h endp
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_load
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_load proc near
load:
xor BX,BX
mov ES,BX
mov BX,60h
cmp Word ptr ES:[BX], 200h
jnz short pass_INT18h_segment_ctrl
cmp Word ptr ES:[BX]+2, 0
jnz short pass_INT18h_segment_ctrl
mov AX, word ptr ES:[var_INT18h_off]
mov DX, word ptr ES:[var_INT18h_seg]
jmp short pass_change_vectors
pass_INT18h_segment_ctrl:
mov AX, word ptr ES:[BX]
mov DX, word ptr ES:[BX]+2
mov word ptr ES:[BX], 200h
mov word ptr ES:[BX]+2, 0
pass_change_vectors:
mov Word Ptr [var_INT18h_off],AX
mov Word Ptr [var_INT18h_seg],DX
mov si, offset INT18h_handler
mov di, 200h
mov cx, 80h
rep movsw
; mov ax, 3
; int 10h
mov SI, offset msg_central_start
call proc_print_msg
call proc_enable_a20_line
jnz short A20_line_error
mov di, 0FFFFh
mov es, di
mov di, 10h
mov word ptr ES:[DI], 'RT'
mov word ptr ES:[CentralVer], 0400h
; 0 = Central Version 1.0
; 4 = Init Value of Retry Count
mov di, 300h
mov si, offset Begin
mov cx, offset Load
sub cx, si
rep movsb
mov di, 100h
mov ax, offset function_bh0
stosw
mov ax, offset function_bh1
stosw
mov ax, offset function_bh2
stosw
mov ax, offset function_bh3
stosw
mov ax, offset function_bh4
stosw
mov ax, offset function_bh5
stosw
mov ax, offset function_bh6
stosw
mov ax, offset function_bh7
stosw
mov cx, 2FEh
sub cx, di
shr cx, 1
mov ax, offset invalid_fcall
rep stosw
xor dx, dx
mov es, dx ; GP Buffer Segment
mov si, 3800h ; MDT Offset
mov di, 1000h ; GP Buffer Offset
push ds
mov ds, dx ; MDT Buffer Segment
mov bl, 20 ; GP Buffer Size
call function_bh6
pop ds
cmp ax, 01A1h
jnz short Initialization_Error
loc_exit:
int 20h
A20_line_error:
mov si, offset A20_line_error
call proc_print_msg
int 20h
Initialization_Error:
mov si, offset Msg_Init_error
call proc_print_msg
int 20h
msg_central_start:
db 07h
db 0Ah, 0Dh
db 'STARTING TR-CENTRAL ...'
db 0Ah, 0Dh, 0h
msg_a20_line_error:
db 07h
db 0Ah, 0Dh
db 'A20 LINE ERROR !'
db 0Ah, 0Dh, 0h
Msg_init_error:
db 07h
db 0Ah, 0Dh
db 'INITIALIZATION FAILED !'
db 0Ah, 0Dh, 0h
Msg_tr_error:
db 07h
db 0Ah, 0Dh
db 'TRANSACTION FAILED !'
db 0Ah, 0Dh
db 'Error Code: '
Error_Code: dw 3030h
db 'h'
db 0Dh, 0Ah, 0h
proc_load endp
CODE_SEG ends
end start