; TR-DOS PRESENTATION 2000
; the PRESENTA.TOR : Standalone/Kernel starter of TR-DOS eXecuter O.S.
; P2000.ASM [ in MICROSOFT MACRO ASSEMBLER format ] !!! Freeware !!!
; (c) Erdogan TAN 1998-1999-2000
; (Version 1.1b -> Build : 2000.12.17 -> Date: 17 December 2000)
; Current : Version 1.1b -> Code optimization
; (short jumps, "EkstraSegment" variable removed)
; (ES segment register direct loaded by pointers)
; ( "and reg,reg" used instead of "cmp reg,0")
;
; Version 1.1a, Extended DOS partition
; (file and directory handling) support added.
; (Build : 2000.10.29)
;
; Version 1.0a -> Build : 2000.07.15 -> 15 July 2000
; DEVELOPMENT STAGES/HISTORY AND DETAILS:
; (as noted at development time)
; Boot prompt and walking on FAT is OK. (The 1st development stage of TR-DOS)
; Directory list ("dir" command) is OK.
; Special MS-DOS, WIN 95/98 boot support ("msdos" command) is OK.
; "trdos","rxdos" commands (for special boot purposes) are OK.
; Above 3 commands have same behavior but load different files.
; MSDOS.BIN, RXDOS.BIN, TRDOS.BIN, CENTRAL.BIN
; "central" command loads special "tr-central" standalone
; program via "central.bin" file.
; Listing partition table & loading selected harddisk partition
; via "mb, mb0, mb1, hd, hd0, hd1, hd0a, hd1a, hd0d, hd1d
; p, p0, p1, p2, p3, p4, pt, pt0, pt1" commands is OK.
; "dos, xenix, unix, linux, multix" partition loading commands are OK.
; "win" (Windows NT or 2000) NTFS partition loading command is OK.
; "cd" command is OK!
; "cd" command changes current drive and/or directory.
; "cd hd0:" changes current drive to (1st) dos partition of drive hd0.
; "cd fd0:" changes current drive to dos formatted disk on drive fd0.
; "cd hd1:" and "cd fd1:" also available.
; "cd" command without parameter, prints current drive and dir name.
; "hd0e" and "hd1e" extended parttion table printing commands are OK.
; Logical drives in an extended dos partition can be listed by above
; commands. "hd0e" is for the fist extended dos partition of drive hd0.
; And "hd1e" is for the first dos extended partition of drive hd1.
; [ 29 October 2000 ]
; Partition table of "hd0e" is called as "ep0" and other is "ep1".
; Logical drive names are "ld0:" to "ld3:" for "hd0e" and "ld4:" to
; "ld7:" for "hd1e". These drive names used with "cd" command.
; Example: "cd ld0:" is "change drive to the first logical drive of the
; first extended dos partition of the first harddisk or hd0."
; [ 29 October 2000 ]
; Warning ! Presentator will change hidden1, hidden2 (word pointers)
; boot data/parameter areas after extended partition's logical drive
; access by adding start sector value of the extended dos partition to
; start sector value of the logical dos drive (in extended partition
; record) and result will be saved as hidden sectors (double word
; pointer) value in boot sector of the logical drive.
; Do not save boot sector of logical dos drive after that. "Hidden sector"
; value always must be checked with "start sector" value (in extended
; partition beginning sector) before saving a logical drive's boot sector
; by Presentator !!! "Start sector" must be equal to "hidden sector" !!!
; "start <filename>" command is OK. Example: "start trdos.rts"
; "start" command loads specified file at 0:7C00h or 0:7E00h and
; jumps to it. Jump address = 7C00h for BIN files, 7E00h for others.
; Maximum loadable file size is 64K.
; File name extensions can be TOR, BIN, STD or RTS.
; File must be a kernel or standalone program for running from 7C00h.
; "run <filename>" command is OK. Example: "run runme.com"
; "run" command loads specified file at 4000h:0100h (for COM files)
; or at 4000h:0000h for others. And jumps to it.
; File extensions must be COM, BIN, STD or RTS. Except COM files,
; other file types are standalone files and COM file must be standalone.
; Except INT 20h for returning to PRESENTATOR,
; user must not use another DOS (non-bios) interrupt;
; or must not run a COM file which contains DOS interrupts.
; (It can be possible to run non-standalone com files after setup of
; DOS interrupts by using an interrupt setup program -in fact, a kernel
; or simple/little kernel-)
; Presentator's "run" command assumes "com" file/program will use
; INT 20h or final "RET" instruction to give back control to Presentator.
; For "COM" file execution, "run" pushes 4000h:0000h address onto STACK
; for near and far call and reserves INT 20h command at 4000h:0000h
; for default "come back". (for RETN and RETF instructions.)
; After temporary INT 20h allocation and execution, "run" command's
; temporary INT 20h code restores original INT 20h interrupt handler.
; And jumps to beginning/start of PRESENTATOR. Of course, it will be
; possible to continue without any hangs; if presentator still existent
; in its place on the memory and register (CPU etc.) conditions are still
; proper to run TR-DOS presentator. Otherwise, reboot will be necessary.
; Reason of return to original INT 20h segment and offset values, is
; to keep all critical memory variables as unchanged by Presentator.
; Because, presentator will be able to check/print original
; and critical memory contents after ROM-BIOS boot/initialization,
; after soft reset (reboot) and after "run" command.
; "load <file>" command loads specified file (max. 256K) at
; predetermined memory Segment and Offset (Default Segment is 4000h
; and default offset = 0000h, these values can be changed by "start"
; (changes offset value) and "run" (changes offset and segment
; values) command or by using (Set) "Segment <Hex. Value>",
; "Offset <Hex. Value>" commands.
; If "load" (and also, "show" or "read") command loads any parts
; of the file (sectors) onto directory, FAT sections or another
; active (in using) memory section as critical, execution/transaction
; will be affected after load ("show or "read") command.
; Of course, reset/reboot may be necessary after overwrite.
; "show" command shows/prints (on screen) the last loaded file.
; (If there is a loaded file just before "show" command.)
; "show <file>" command loads and shows specified file (max. 256K)
; at predetermined memory Segment and Offset, like as "load" command.
; It shows file characters as pages of 20 lines (22 lines for first page)
; without any limitation except file size.
; To see next page (next 20 lines), user must press any key,
; like as "dir" command with pages of 16 lines.
; "offset" and "segment" commands are OK.
; "offset" is get current loading offset, "offset XXXX" is set offset
; "segment" is get current loading segment, "segment XXXX" is set segment
; "XXXX" means hex. address (word).
; "hex" command is OK.
; "hex" command prints memory contents as hexadecimal.
; Starting segment and offset address values are predetermined values
; by above "segment" and "offset" commands or default/remain values
; from previous command/procedure.
; If there is no procedure which has changed those (address/pointer)
; values before "hex" command, those values keep their initial values.
; "hex -p" is "hex" command but non-printable chars (for printer)
; will not be shown, due to PRINT SCREEN function to print screen
; contents excluding chars which are printer control codes.
; <Print Scrn> key can be used to print screen by printer.
; (To write memory or file contents on paper in hexadecimal form.)
; (It is useful for binary check and disassembly working.)
; "jump" command is OK. # Jump to predetermined memory address #
; Warning ! Critical command ! "jump" can cause unknown or
; bad results due to random jump to any code.
; "jump" uses "segment" and "offset" pointers as target address.
; Execution/Transaction can fail after that command.
; "sector" command is OK. "Set/Get the beginning sector of selected
; device for reading/writing". Without a command parameter,
; it will show "read (from device)" parameters. Other related
; commands are "device" and "count". And main using purpose of above
; commands is prepare/see the parameters for "read" command.
; Sector number (as command parameter) must be in decimal format and
; maximum valid sector value/input is FFFFFFFFh as hexadecimal.
; (You can enter a value in decimal format, between 0 and FFFFFFFFh
; as hexadecimal.) Sample command with parameter: "sector 1447".
; "device" command is OK. "Set/Get device name & number for
; reading/writing". Without a command parameter, it will show
; "read (from device)" or "write (to device)" parameters.
; Device names may be "fd" or "hd". Device numbers may be 0 or 1.
; Sample commands with parameter: "device fd0", "device fd0:".
; "count" command is OK. "Set/Get sector count for reading/writing".
; Without a command parameter, it will show "read (from device)"
; or "write (to device)" parameters. Sector count may be 0 to 512
; but must be less than free space in memory. Directory
; and fat buffers must not be overwritten at 7000h:0000h and
; 8000h:0000h. Also, segment value must point an address after
; the last byte of presentator. (Maximum presentator size is 256K
; and beginning address of presentator is 0000h:7E00h.)
; If segment value is 4000h, suggested sector count is 384.
; (If segment is 3000h, suggested maximum sector count is 512.)
; If sector count is 0, reading and/or writing will be disabled.
; "read" command is OK. "Read device (disk) sectors".
; "device", "sector" and "count" are determined by related commands
; before "read" command. The destination address in RAM/memory
; is determined by "segment" and "offset" commands before "read".
; NOTICE : "read" command provides possibility to read NON-DOS FS.
; "write" command is OK. "Write data/sectors onto disk".
; "device", "sector" and "count" are determined by related commands
; before "write" command. The source address in RAM/memory
; is determined by "segment" and "offset" commands before "write".
; Destination is predetermined device/disk sector address.
; Number of sectors to be written is determined by sector "count".
; NOTICE : "write" command provides possibility to write onto a
; NON-DOS FS. It is possible to restore original disk sectors
; and filesystem or partition (masterboot/boot) records which are
; affected/damaged/destroyed by any viruses or wrong operation.
; WARNING ! "write" is very dangerous command due to direct write
; onto disks (without using filesystem procedures).
; Please use it only when you need it for recovering original data
; (which is recorded/saved before).
; Do not use it when you are not sure what are you doing.
; Otherwise, you can damage any existent filesystems or partitions
; of target (specified/predetermined) disk/device.
; "edit" command is OK. It is hexadecimal editor of presentator.
; It can be used after "read" command and/or before "write" command.
; It uses existent "segment" and "offset" values for "edit".
; User can change values/characters on screen which points
; related bytes in specified RAM/memory location.
; Main target of using this command is to recover/restore/update
; data for solving a problem (virus problem or failure etc.)
; For example: "edit" command can be used for recovering/restoring
; masterboot and boot sectors. Of course, "write" (warning!)
; command is required for completing recovery operation.
; "volume" command is OK. "Write volume label, serial number and
; free space of current/active dos drive". If "FreeSpace" is more
; than FFFFFE00h (4,294,966,784) bytes (7FFFFFh sectors), value of
; freespace will be displayed in sectors; otherwise, in bytes.
; (Because of 800000h in sectors is more than 32 bits in bytes.)
; (FILE/DIRECTORY) DELETE/SAVE Commands (After January 14, 2000):
; ! WARNING !
; These are dangerous commands which can damage files and/or dirs.
; "save <file>" command is OK (!!!) . "Save as <FILENAME>".
; "save" command writes specified/determined bytes into a file.
; If file with a valid file name exists, user will be prompted for
; overwrite confirmation. If attributes of existing file are S,H or R,
; overwrite permission of the file will be denied till file attributes
; will be reduced to regular (normal) file.
; (Erased/Deleted file entries will be overwritten, but, directory
; names and WINDOWS 95/98 long file names and volume name will not be
; overwritten.)
; As default, file size will be 512 bytes and beginning address
; of contents will be taken from specified/predetermined segment and
; offset values/address.
; After every succesfull "read" command, file (saving) size will be
; 512 x sector count. After every successful "load" command, file
; size will be equal to the last loaded file's size.
; Before "save" and after "read" or "load", file size can be changed
; by "size" command.
; It is possible to save full 1 MB conventional (real mode) memory
; to disk by using one file or multiple files.
; So, maximum file size is 1 MB (1,048,576 bytes) for saving.
; Notice that, saving starts from predetermined address by "segment"
; and "offset" commands or 4000h:0000h as initial (default) value.
; If any files or disk sectors will be copied (Max. loadable file
; size is 256 KB.), at first, must be loaded (by load/read commands)
; and after that must be saved (onto same disk or another disk).
;
; EXAMPLE 1:
; segment F000
; offset 0000
; size 65536
; save rombios.dat
;
; Above save command will save 65536 bytes from F000h:0000h into
; a file in current directory with "ROMBIOS.DAT" file name.
; EXAMPLE 2:
; segment 4000
; offset 0000
; device hd0
; sector 0
; count 1
; read
; save mboot.bin
;
; Above save command will save masterboot sector of hd0:
; (1st hard disk) into "MBOOT.BIN" file as 512 bytes.
; If sector would be 63 and it would be the beginning/first
; sector of primary dos partition, "save" command would save
; that partition's boot sector, like as "save msdos.bin".
; NOTE: "save" command will fail when all entries are used in
; existing sub dir clusters and a new cluster is needed for a
; new dir entry. For example: Any clusters in 1 sector per cluster
; format, can have 512/32 = 16 entries per cluster. So, for a
; directory which have only 1 cluster, 17th entry needs a new (next)
; cluster but "save" command does/can not make/create it.
; Also, "save" command can not use entry space of a directory after
; 2048th entry. So, it is not possible to list or save an 2049th
; entry or other entries after 2048th within TR-DOS Presentator.
; "erase <file>" command is OK. "Erase/Delete <FILENAME>".
; "erase" command erases/deletes/removes specified/determined file in
; current directory of current drive. File attribute must not be S, H
; or R to complete erase operation.
; "cluster" command is OK. "cluster XXXX" or "cluster".
; This command follows and shows clusters (in hex format) and equivalent
; sectors to them (in decimal format) from first/current/given
; number to the end of cluster chain or until an invalid cluster number.
; If cluster number (input) is less than 2 or more than
; number of clusters, total cluster number and first free cluster number
; will be shown. ("XXXX" means hex. number.)
; "info" command is OK.
; "info <file/directory>" shows dir entry parameters/elements of
; specified file or directory.
; "info" (without a command parameter) shows parameters
; (of boot sector) of current dos drive.
; "info" command runs by trusting boot sector buffer at 0000h:7C00h.
; So, boot sector buffer must be true/correct for reading original
; boot parameters. It can be more good if "info" (disk/drive info)
; command will be used just after a change drive (like "cd hd0:" or
; "cd fd0:" etc.) command or before overwriting bytes at 0000:7C00h.
; Examples:
; File info -> "info presenta.tor"
; Current Disk/Drive info -> "info"
; NOTE: Generally, TR-DOS Presentator does not check (set or get)
; parameters which are already accessable (in order to set and get
; purposes) by CMOS setup or ROM-BIOS setup. For example: date
; and time can be changed via CMOS/BIOS setup program. And, it is not
; required to change these values in Presentator. Also, physical disk
; paramaters, hardware configuration etc. can be obtained and set via
; CMOS/BIOS setup. So, as result of that logic; direct IO address
; based input, output instructions or commands (like to change CMOS
; setup parameters) are not included.
; (If you can not enter CMOS setup program or you can not change
; parameters via CMOS setup program due to lost password, you can
; remove CMOS ram battery on mainboard of your computer. After that,
; CMOS ram will be reset and password will be disabled. But, current
; hardware setup/configuration will be reset, too. So, you may need
; a new setup (configuration) for proper running of your computer.)
; "find" command is OK.
; "find <string>" finds and shows requested string at memory.
; "find -b <bytes>" find and shows requested byte/bytes or
; byte chain at memory. Searching begins from beginning
; (start) segment and offset (which are predetermined by
; "segment" and "offset" command) to end conventional memory
; (1MB RAM). If string is found, find command shows it by calling
; hex command otherwise, "find" will return to boot prompt
; without any outputs or warnings.
; To exit from "hex" view procedure, user must press <ESC>;
; to return to boot prompt, (second) <ESC> again.
; For checking disk sectors (for requested string or bytes),
; user can use "read" command before find command and continue
; to search next or other requested sectors with proper device,
; (beginning) sector and sector count parameters.
; Examples: "find Erdogan Tan", "find -b AA55" or "find -b AA55h".
; "size" command is OK. "Set/Get (file) size for save command.
; Without a command parameter, it will show current size.
; Size input must be max. 7 digit decimal number and must not be
; more than 1 MB (1048576 bytes) real mode limit.
; "attrib" command is OK.
; "change attributes of the file/directory".
; It changes attributes of an existing file/directory or
; determines new attributes of any files for "save" command.
; "attrib" shows current attributes set.
; "attrib +s +h +r PRESENTA.TOR" changes attributes of
; "PRESENTA.TOR" file to "SHR" (System + Hidden + Read only).
; "attrib -s -h -r -a jo.sys" resets all attributes of
; the file "JO.SYS".
; "attrib -s -h -r -a" changes attributes of a new file which
; will be saved. Note: "-s -h -r -a" is same with "-shra".
; If attributes are not proper for saving ("S" and/or "H"
; and/or "R" status), "permission denied" message will be
; appeared. So, "attrib" command provides permission for "save"
; command (by reducing attribute/protection levels to minimum).
; Example: "attrib +shr -a presenta.tor".
; "mkdir" command is OK. (18 June 2000)
; "mkdir <directory name>"
; "mkdir" command makes a new sub directory with normal+directory
; attribute.
; "rmdir" command is OK. (25 June 2000)
; "rmdir <directory name>"
; "rmdir" command removes/erases specified empty directory with
; normal+directory attribute.
; "rename" command is OK. (29 June 2000)
; Rename specified file or directory (with normal attribute).
; Command format: "rename <file_name> <new_file_name>"
; This command does not change anything except name of specified
; file/directory. But, as save, erase, mkdir, rmdir commands
; it will overwrite directory entry sectors. Except rename,
; above commands overwrite FAT sectors and file data sectors, too.
; End of destructive P2000 commands (29 June 2000) !!! ...
; Rename command is the last developed "overwriting" command which
; have dangerous (FAT based file/sector overwriting) features.
; save, erase, mkdir, rmdir and rename are destructive file handling
; commands of tr-dos presentator. (FAT based writing commands)
; read, write are destructive sector handling commands.
; (Direct sector writing commands. Valid for non-dos disks, also.)
; Other P2000 commands are not destructive commands.
; By finishing of "save" command (20 May 2000) development, now,
; TR-DOS Presentator has wonderful (emergency) system backup,
; recovery and code grab features on directions from file to file,
; sector to file and memory to file. Now, masterboot, boot sectors,
; all conventional memory and all disk sectors can be saved as file
; without any file system supports, only by using "Presentator".
; Also, non-dos disks can be read and saved by using TR-DOS's sector
; handling commands. Reading and saving non-dos disk's sectors or
; dos-disk sectors without FAT file system procedures is useful for
; GRAB, CRACK and RECOVERY purposes. Related commands: "load, save,
; read, write" and their accessory commands like "cd, dir, device,
; sector, count, segment, offset, size, attrib, hex, edit, pt, info,
; cluster, show, volume, find, erase, rename, mkdir, rmdir"
; commands. "load" and "save" are file handling commands, while
; "read" and "write" are sector handling commands.
; Default command execution of TR-DOS Presentator is OK.
; (17 July 2000)
; At the beginning (just after loading PRESENTATOR or P2000) user
; will be prompted for boot command. If user does not enter/press a
; key or character in 30 seconds (546 ticks), PRESENTATOR will
; search "P2000.DEF" file for default command execution.
; If "P2000.DEF" is present/ready in root directory and it's file
; size is not more than 512 bytes, it will be loaded by PRESENTATOR
; and PRESENTATOR will take default command line as the first 72 bytes
; of loaded "P2000.DEF" file. (Loading address is 0:700h and sector
; count is 1 or loading size is 512 bytes.) After copying 72 bytes
; to CommandBuffer, PRESENTATOR will jump to command handling
; procedure.
; "P2000.DEF" file can be a normal text file and the first 72 or less
; bytes must have default command line contents like "dos" command.
; If "P2000.DEF" is not present in current directory, presentator will
; ignore default command execution without showing an error message.
; Viva Presentator/P2000 !
; *******************************************************************
; ASSEMBLY (MICROSOFT MACRO ASSEMBLER) CODE STARTS FROM HERE
; *******************************************************************
; 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
org 7E00h
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_start
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_start proc far
start:
call proc_fat_load ; Major Update since 1998
; (c) Erdogan Tan 25/1/2000
jc short loc_failed
xor BH,BH
mov BL,Byte Ptr [bp][SecPerClust]
mov AX,Word Ptr [bp][BytesPerSec]
mul BX
; DX must be zero ?!
xor BX,BX
mov ES,BX ; Start segment of presentator
mov BX,7E00h
add BX,AX ; AX = displacement
jnc short firstp2000cluster
mov BX,1000h
mov ES,BX
xor BX,BX
firstp2000cluster:
mov cx, word ptr [bp][Reserved2]
; CX contains the first cluster
mov Word Ptr [Counter], 200h ; Maximum number of clusters
mov si, offset retn_from_load_p2000 ; Major Update
push si ; Major Update
jmp load_p2000_clusts ; in proc_file_read ; Major Update
retn_from_load_p2000:
jc short loc_failed
call proc_loadrootdir
jnc loc_initial_command_waiting
loc_failed:
mov SI, offset trfailedmsg
call proc_printmsg
loc_retry:
xor ah,ah
int 16h ; BIOS Service func ( ah ) = 0
; Read next kbd char
;AH-scan code AL-char code
int 19h ; Reboot
proc_start endp
proc_fat_load proc near
xor DX,DX
mov BP,7C00h
mov AX,Word Ptr [bp][ResSectors]
add AX,Word Ptr [bp][Hidden1]
adc DX,Word Ptr [bp][Hidden2]
mov CX,Word Ptr [bp][FATsecs]
mov BX,8000h ; First FAT buffer segment
mov ES,BX
xor BX,BX
call proc_read
retn
proc_fat_load endp
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;±
;± PROCEDURE proc_read
;±
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
proc_read proc near ; FAT/FILE Transfer Procedure
loop_loc_13:
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]
jnc short passnext
push BX
mov BX, ES
add BX, 1000h
mov ES, BX
clc ; Return from F000 to 0 will be accepted.
pop BX
passnext:
loop loop_loc_13 ; 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
proc_nextread proc near
mov Word Ptr [Register_AX],3030h
push CX ; Save the cluster number
mov AX,CX
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
pop CX
retn
proc_nextread 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 short pass_cc_al
add AL,7
pass_cc_al:
cmp AH,'9'
jna short pass_cc_ah
add AH,7
pass_cc_ah:
; 1998
retn
proc_hex endp
proc_file_read proc near
call proc_nextread
load_p2000_clusts: ; from Start
cmp Word Ptr [bp][Sectors],0 ; Is it > 32M (FAT12 limit) ?
; Zero value points FAT16.
; Other MS-DOS clones use
; maximum cluster number
; and FAT12/FAT16 strings
; for checking FAT type.
; TR-DOS only uses 32 MB
; barrier for this purpose.
; TR-DOS does not assume
; that, there is a FAT16
; File System which less
; than 32 megabyte size !!!.
jz short F_ReadFAT16Clust
jmp short F_ReadFAT12Clust
F_FAT16Next_Read:
call proc_nextread
jnc short F_ReadFAT16Clust
retn
F_ReadFAT16Clust:
push ES
mov si, 8000h ; First FAT buffer segment
mov ES,si
mov si,cx
add si,cx ; 1 cluster pointer = 2 bytes
jnc short F_updateclusterno
mov cx, 9000h ; Second FAT buffer segment
mov ES,cx
F_updateclusterno:
mov cx,Word Ptr ES:[si]
pop ES
cmp cx,0FFF0h ; Clears CF if at end of file
jnb short F_EndOfRead
dec Word Ptr [Counter]
jnz short F_FAT16Next_Read ; File size < = counter
retn
F_FAT12Next_Read:
call proc_nextread
jnc short F_ReadFAT12Clust
retn
F_ReadFAT12Clust:
push ES
mov si,8000h
mov ES,si
mov si,cx ; Multiply by 3/2
shr cx,1
pushf ; CF now set if odd
add si,cx
mov cx,Word Ptr ES:[si]
popf
jnc short F_nc_even
shr cx,1 ; Needed for odd only
shr cx,1
shr cx,1
shr cx,1
F_nc_even:
pop ES
and ch,0Fh
cmp cx,0FF0h
jnb short F_EndOfRead
dec Word Ptr [Counter]
jnz short F_FAT12Next_Read
F_EndOfRead:
retn
proc_file_read 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
trfailedmsg:
db 0Dh, 0Ah
db 'Transaction failed... Error code : '
Register_AX: db '0'
db '0'
Hex_Sign: db 'h'
db 0Dh, 0Ah
db 'Press any key to retry or reboot from another disk...'
nextline:
db 0Dh, 0Ah, 0h
CCCpointer equ 0450h ; BIOS data, current cursor column
Counter:
dw ?
RootDir1:
dw ?
RootDir2:
dw ?
Clock_Tick_Count:
dd 0
Msg_P2000_COM:
db "P2000.COM"
RetryCount:
db 0A1h
db 1 dup(1)
proc_loadrootdir proc near
mov byte ptr [Current_Dir], 0 ; Reset current dir
mov word ptr [Dir_Pointer], 0
mov word ptr [Clust_Of_Dir], 0
mov AL,Byte Ptr [bp][FATs] ; BP+10h = Number of FATs
cbw
mul Word Ptr [bp][FATsecs] ; BP+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 [RootDir1],AX
mov Word Ptr [RootDir2],DX
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]
mov word ptr [DirEntries], cx
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
mov BX,7000h ; Root directory buffer segment
mov ES,BX
xor BX,BX
pop DX ; DX_AX = Location of root directory
pop AX
call proc_read
retn
proc_loadrootdir endp
proc_p2000_prompt proc near
loc_initial_command_waiting: ; 17 July 2000
mov al, byte ptr [bp][DriveNumber]
cmp al, 80h
jb short pass_init_drive_name_hd
mov byte ptr [Drive_Name], 'h'
sub al, 80h
pass_init_drive_name_hd:
add al, 30h
mov byte ptr [Drive_Num], al
mov si, offset P2000msg
call proc_printmsg
loc_initial_clock_ticks:
xor ah, ah
int 1Ah
add dx, 546 ; 546 ticks, approx. 18.2 ticks per second.
adc cx, 0 ; 30 seconds added for waiting a command
mov word ptr [clock_tick_count], cx
mov word ptr [clock_tick_count]+2, dx
command_waiting_loop:
mov ah, 01h
int 16h
jnz pass_initial_waiting_loop
xor ah, ah
int 1Ah
cmp al, 0
ja short loc_initial_clock_ticks
mov ax, word ptr [clock_tick_count]+2
sub ax, dx
mov dx, word ptr [clock_tick_count]
sbb dx, cx
jc loc_default_transaction
or ax, dx
jnz short command_waiting_loop
jmp loc_default_transaction
p2000_prompt:
mov SI, offset P2000msg
call proc_printmsg
pass_initial_waiting_loop:
xor AX,AX
mov ES,AX
mov BP, 7C00h
mov ah,03h
mov bx,07h ; Always in presentator
int 10h
mov Byte Ptr [CursorColumn],dl
xor ch,ch
call proc_rw_char
mov Byte Ptr [CommandBuffer]+79,0
loc_move_command:
mov CX,7
mov SI,7
mov DI, offset CommandBuffer
next_command_char:
mov al, byte ptr [SI][CommandBuffer]
inc si
cmp al, 20h
ja short pass_space_control
jb short pass_move_command
cmp cx,7
jb short pass_move_command
cmp si,79
jb short next_command_char
jmp short pass_move_command
pass_space_control:
cmp al,61h
jb short pass_capitalize
cmp al,7Ah
ja short pass_capitalize
and al,0DFh
pass_capitalize:
stosb
loop short next_command_char
pass_move_command:
mov byte ptr [DI],0
cmp byte ptr [CommandBuffer],21h
jb start
call command_interpreter
call proc_cmdb_reset
jmp short p2000_prompt
proc_p2000_prompt endp
proc_rw_char proc near
readnextchar:
xor ah,ah
int 16h
and al,al
jz short loc_arrow
cmp al,0E0h
jz short loc_arrow
cmp al,08h
jnz short char_return
loc_back:
mov dl,Byte ptr ES:[CCCpointer]
cmp dl,Byte ptr [CursorColumn]
ja short prev_column
jmp short readnextchar
prev_column:
dec dl
set_cursor_pos:
mov ah,02h
int 10h
mov ah,09h
mov al,20h
mov cl,dl
mov bp,cx
mov Byte Ptr [bp][CommandBuffer],al
mov cl,1
loc_write_it:
int 10h
mov dl,Byte Ptr ES:[CCCpointer]
jmp short readnextchar
loc_arrow:
cmp AH,4Bh
jz short loc_back
cmp AH,53h
jz short loc_back
cmp AH,4Dh
jnz short readnextchar
cmp dl,79
jnb short readnextchar
inc dl
jmp short set_cursor_pos
char_return:
mov ah,0Eh
cmp al,20h
jb short loc_escape
mov cl,dl
mov bp,cx
mov Byte Ptr [bp][CommandBuffer],al
cmp dl,79
jb short loc_write_it
jmp short readnextchar
loc_escape:
cmp al,1Bh
jnz pass_escape
call proc_cmdb_reset
mov si,offset nextline
call proc_printmsg
mov si, offset P2000msg
call proc_printmsg
jmp short readnextchar
pass_escape:
cmp al,0Dh
jnz short readnextchar
int 10h
mov al,0Ah
int 10h
retn
proc_rw_char endp
proc_cmdb_reset proc near
mov al, byte ptr [CmdNo]
cmp al, byte ptr [Status]
je short pass_status_reset
mov byte ptr [Status], 0
pass_status_reset:
; mov byte ptr [Prev_Cmd], al
mov byte ptr [CmdNo], 0FFh
xor ax, ax
mov ES, ax
mov cx, 36
mov DI, offset [CommandBuffer]+7
reset_cmd_buffer:
stosw
loop reset_cmd_buffer
mov bp, 7C00h
retn
proc_cmdb_reset endp
CursorColumn:
db ?
File_Name:
db 12 dup(20h)
db 20h
Dir_Or_FileSize:
db 10 dup(20h)
db 20h
File_Attribute:
db 4 dup(20h)
db 20h
File_Day:
db 2 dup('0')
db '/'
File_Month:
db 2 dup('0')
db '/'
File_Year:
db 4 dup('0')
db 20h
File_Hour:
db 2 dup('0')
db ':'
File_Minute:
db 2 dup('0')
db 0
Type_Dir: db '<DIR> '
P2000msg:
db 0Dh, 0Ah
db 'TR-DOS Presentation 2000'
db 0Dh, 0Ah
db 'Boot : ',0h
Drive_Str:
db "Drive: "
Drive_Name:
db "fd"
Drive_Num:
db "0"
db 0Dh, 0Ah
Dir_Str:
db "Directory: /"
Current_Dir:
db 67 dup (0)
DirEntries:
dw 200h
Cmd_Dir:
db "DIR" ; List current directory
Cmd_Msdos:
db "MSDOS" ; Alternative/MSDOS boot via "msdos.bin"
Cmd_Rxdos:
db "RXDOS" ; Alternative boot via "rxdos.bin"
Cmd_Trdos:
db "TRDOS" ; Start tr-dos via "trdos.bin"
db 0
Cmd_Central:
db "CENTRAL" ; Start tr-central via "central.bin"
db 0
Cmd_Multix:
db "MULTIX" ; Start tr-multix partition on def. harddisk
db 0
Cmd_Linux:
db "LINUX" ; Start linux partition on default harddisk
db 0
Cmd_Unix:
db "UNIX" ; Start sco-unix partition on def. harddisk
db 0
Cmd_Xenix:
db "XENIX" ; Start xenix partition on default harddisk
db 0
Cmd_Dos:
db "DOS" ; Start dos partition on default harddisk
db 0
Cmd_Win:
db "WIN" ; Start Windows NT or Windows 2000 NTFS
db 0 ; partition on default harddisk.
;Cmd_CD: db "CD" ; Change drive and/or directory
;Cmd_HD0_or_HD: db "HD0" ; Start active partition on hd0
;Cmd_HD1: db "HD1" ; Start active partition on hd1
;Cmd_HD0A: db "HD0A" ; Start active partition on hd0
;CMD_HD1A: db "HD1A" ; Satart active partition on hd1
;Cmd_HD0D: db "HD0D" ; Start dos partition on hd0
;Cmd_HD1D: db "HD1D" ; Start dos partition on hd1
;Cmd_HD0E: db "HD0E" ; Show table of ext dos partition on hd0
;Cmd_HD1E: db "HD1E" ; Show table of ext dos partition on hd1
; Note : MS-DOS partitions on second hard disk are not capable to boot
; (except win 95/98 versions of them) but if they have or they
; will have Turkish Rational's compatible transaction systems
; as TR-DOS eXecuter operation system in MS-DOS FAT16 file system,
; it will be possible to boot from DOS partitions of 2nd hard disk.
; This is not a presentator defect. Reason of this failure comes
; from MS-DOS startup features. Already, windows 95/98 formatted
; MS-DOS partitions can perform their boot on second hard disk
; but they only use first hard disk as root, during startup.
;Cmd_MB0_or_MB: db "MB0" ; Set default harddisk to 80h
;Cmd_MB1: db "MB1" ; Set default hardisk to 81h
;Cmd_P0_or_P: db "P0" ; Start Active Partition on default harddisk
;Cmd_P1: db "P1" ; Start Partition 1 on default harddisk
;Cmd_P2: db "P2"
;Cmd_P3: db "P3" ; Start Partition 3 on default harddisk
;Cmd_P4: db "P4"
;Cmd_PT: db "PT" ; List partion table on default harddisk
;Cmd_PT0: db "PT0" ; Set default harddisk to 80h and
; list partition table on harddisk 0 (80h)
;Cmd_PT1: db "PT1" ; Set default harddisk to 81h and
; list partition table on harddisk 1 (81h)
Cmd_Start: db "START" ; Start a kernel or standalone program
; Loads a BIN file (size <= 64K) at 7C00h
; Loads other files (size <= 64K) at 7E00h
; File extension must be TOR,BIN,STD or RTS
; BP=700h. ( Last Update: 12 March 2000 )
Cmd_Run: db "RUN" ; Run a specified program/file
; Loads a COM file (<= 64K) at 4000h:0100h
; Loads other files (<= 256K) at 4000h:0000h
; File extension must be COM,BIN,STD or RTS
; Files must be standalone
; or only must use INT 20h interrupt
; except ROM-BIOS interrupts
Cmd_Load: db "LOAD" ; Load a specified program/file at
; predetermined location via Segment and
; Offset variables or default/current
; loading segment and offset pointers.
; File size must be <= 256K.
Cmd_Show: db "SHOW" ; Show a specified or last loaded
; program/file at predetermined memory
; location. It is unlimited show/print
; utility which prints file on screen as
; 22 plus 20 lines and wait for any key
; (int 16h) in order to show next 20 lines.
Cmd_Offset: db "OFFSET" ; Set (with hex. address) offset
; or get (without any parameters) offset
; (as part of loading address)
Cmd_Segment: db "SEGMENT" ; Set (with hex. address) segment
; or get (without any parameters) segment
; (as part of loading address)
;Cmd_Hex: db "HEX" ; Print/Show memory content as hexadecimal
; Prints 16 bytes per line, per hit (a key)
; ESC is exit key
; Start offset and segment are predetermined
; values (pointers by "offset" and "segment"
Cmd_Jump: db "JUMP" ; Jump to predetermined address
; Notice that "segment" and "offset"
; pointers give the target adress to "jump"
Cmd_Sector: db "SECTOR" ; "Set (Get) Logical/Flat Sector Value"
; for selected device (disk). For read
; (from device) and write to RAM (memory).
; Target memory address is as determined by
; "segment" and "offset" commands.
; It performs "Get (Logical Sector Number)"
; function by using the command without
; decimal sector input as commmand parameter.
; Command parameter (Sector) must be decimal
; number as max. 9999999 and min 0.
Cmd_Device: db "DEVICE" ; "Set (Get) device name and number"
; For read (from device).
; It performs "Get (Device Name & Number)"
; function by using the command without
; device name as command parameter.
; Device name (& number) may be "fd0","hd0",
; "fd1", "hd1". Maximum device number is 4.
Cmd_Count: db "COUNT" ; "Set (Get) sector count for read
; (from selected device)". It performs
; "Get (Sector Count)" function by using
; the command without number of sectors
; as command parameter.
; Maximum sector count is 512. Sector count
; must be entered in decimal format.
Cmd_Read: db "READ" ; "Read device (disk) sectors"
; Device, sector and sector count
; determined by related commands before read
; command. The destination address
; in memory is determined by segment and
; offset command before read command.
Cmd_Write: db "WRITE" ; "Write data/dectors onto disk (device)"
; Destination is a sector address of
; requested device/disk by device, sector
; and sector count parameters/values
; which are determined before write
; command. The source address
; in memory determined by segment and
; offset command before write command.
Cmd_Edit: db "EDIT" ; Hexadecimal editor.
; It is used to change bytes in specified
; RAM/memory location by using equivalent
; hexadecimal values/characters on screen.
; ENTER = Save/Update
; ESC = Exit (without save) ; is Destination is a sector address of
Cmd_Volume: db "VOLUME" ; Write volume label, serial number and
; free space of current/active dos drive.
; If freespace value is more than FFFFFE00h,
; freespace will be displayed in "sectors".
; (Normally, unit of freespace is "bytes".)
Cmd_Save: db "SAVE" ; Save as <FILENAME>
; It writes specified bytes into a file.
; If file with a valid file name exists,
; user will be prompted for overwrite
; confirmation. If attributes of existent file
; are S,H or R, overwrite permission of the
; file will be denied till file attributes
; will be reduced to regular (normal) file.
; As default, file size will be taken from
; sector count and contents will be taken
; from specified/predetermined segment and
; offset address. If save command is used
; with "-s" command, it will use "FILE_SIZE"
; parameter/value (in bytes) which was
; determined by last load command or "size"
; command after file size confirmation for
; determining file size.
; File size must be <= Free Space of Current
; Disk. Of course, file name will be checked
; in current dir and file will be saved in
; current dir by seeking/looking first
; proper entry location and by following
; free clusters from beginning of FAT.
Cmd_Erase: db "ERASE" ; Erase <FILENAME>
; "erase" command erases/deletes/removes
; specified/determined file in
; current directory of current drive.
; File attribute must be proper to complete
; erase/delete/remove operation.
; Attribute can not be S, H or R.
Cmd_Cluster: db "CLUSTER" ; "cluster XXXX" or "cluster"
; Follows clusters from first/current/given
; number to the end of cluster chain or
; until an invalid cluster number. And,
; gives equivalent sector number to cluster
; number in decimal format. Also, gives
; next cluster value. If cluster number
; (input) is less than 2 or more than number
; of clusters, total cluster number and
; first free cluster number will be shown.
Cmd_Info: db "INFO" ; "info <FILE/DIR>" gives information
; about specified file or sub dir in current
; directory. "info" (without a command
; parameter) gives information about
; (boot parameters of) current dos drive.
Cmd_Find: db "FIND" ; "find <string>" finds and shows requested
; string at memory. From beginning segment
; and offset (which are predetermined by
; "segment" and "offset" command) to end
; conventional memory (1MB RAM).
; "find -b <bytes>" find and shows
; requested byte/bytes or byte chain.
Cmd_Ver: db "VER" ; Get version information
Cmd_Build: db "BUILD" ; Get build information
; Cmd_TR: db "TR" ; Change keyboard and codepage to Turkish.
; Loads Turkish fonts and changes INT16h
; vector for remapping keyboard.
; To reset/restore English/default keyboard
; and codepage (in fact, original INT 16h),
; "en" command needed.
; Due to interrupt (16h) handler is changed
; to be in conventional memory (which will
; be overwritten by any programs), before
; any overwritings, reset is required.
; Otherwise, computer will hang during
; first next INT 16h request.
; --- 8 March 2000 ---
; Cmd_EN: db "EN" ; Reset default/english keyboard and
; codepage (Return to English from Turkish).
Cmd_Size: db "SIZE" ; Set/Get Size (for save command).
; Can not be more than 1 MB real mode limit.
Cmd_Attrib: db "ATTRIB" ; Change attributes.
; "+/-" and "SHRA" are parameters of
; "attrib" like "attrib +shr".
; Also file or directory name is optional
; parameter after other parameters.
; If there is a valid file or directory name,
; attribute of the file or directory will be
; changed or new attributes will be set for
; "save" command.
; Examples: "attrib -shr", "attrib +s +h +r",
; "attrib +r-h-s-a","attrib +shr -a jo.sys".
Cmd_Mkdir: db "MKDIR" ; Create a sub directory.
; "mkdir <directory name>"
; the new directory will be created with
; normal+directory attribute.
; Directory buffer is 0000h:0700h (1 sector)
; as 1 cluster/sector, empty directory.
Cmd_Rmdir: db "RMDIR" ; Remove directory.
; "rmdir <directory name>"
; Removes specified directory.
; If specified directory is an empy directory
; with normal+directory attribute.
; Directory buffer is 0000h:0700h (1 sector)
; for checking of directory entries.
Cmd_Rename: db "RENAME" ; Rename specified file or directory
; (with normal attribute).
; "rename <file_name> <new_file_name>"
; This command does not change anything
; except name of specified file/directory.
Cmd_Default: db "DEFAULT" ; Loads command buffer with the default
; command line by "P2000.DEF" file or
; presentator's initial default command.
; (Initial default command is "dos" for
; this version.) 17 July 2000.
Msg_Bad_Name:
db "Bad command or file name !"
db 0Dh, 0Ah
db 0
S_File_Name:
db "PRESENTA.TOR"
db 0
Msg_NotFound:
db " not found !"
db 0Dh, 0Ah
db 0
CommandBuffer:
db 7 dup(0)
db 72 dup(20h)
db 0
Dir_File_Name:
db 11 dup (20h)
db 0
str_boot_bin:
db "MSDOS.BIN"
db 0
File_FClust:
dw 0
File_Size_L:
dw 0
File_Size_H:
dw 0
File_A_Byte:
db 0
print_directory proc near
mov si,offset nextline
push si
call proc_printmsg
mov si, offset Drive_Str
call proc_printmsg
pop si
push si
call proc_printmsg
pop si
call proc_printmsg
xor si,si
mov cx, word Ptr [DirEntries] ; Maximum dir entries
jump_from_file_info:
push ds
pop es
mov Byte Ptr [RetryCount],1
loop_loc_dir:
cmp Byte Ptr [RetryCount],0Fh ;16 entries = 512 bytes = 1 page
ja Pause_dir_scroll
push cx
push ds
mov cx,7000h
mov ds,cx
cmp Byte Ptr DS:[SI],00h ; Is it never used entry?
ja short loc_dir_cont
pop ds
pop cx
jmp loc_dir_ok
loc_dir_cont:
cmp Byte Ptr DS:[SI],0E5h ; Is it a deleted file?
je next_entry
mov bl,Byte Ptr DS:[SI]+0Bh
test bl,08h ; Is it a volume name or long name entry?
jnz next_entry
push bx
test bl,10h ; Is it a directory?
jz short loc_no_dir
push ds
push es
pop ds
push si
mov cx, 10
mov si, offset Type_Dir ; '<DIR> '
mov di, offset Dir_Or_FileSize
rep movsb ; move 10 bytes
pop si
pop ds
jmp short loc_attribute
loc_no_dir:
mov ax, Word Ptr DS:[SI]+1Ch ; File Size L
mov dx, Word Ptr DS:[SI]+1Eh ; File Size H
mov bp,9
loc_re_divide:
mov cx,10 ; 16 bit divisor
call Rx_Dos_Div32 ; 32 bit divide
add bl, '0' ; to make visible
mov Byte Ptr ES:[Dir_Or_FileSize][bp],bl
dec bp
cmp ax,0
ja short loc_re_divide
cmp dx,0
ja short loc_re_divide
loc_fill_space:
mov Byte Ptr ES:[Dir_Or_FileSize][bp],20h
cmp bp,0
jna short loc_attribute
dec bp
jmp short loc_fill_space
loc_attribute:
pop bx
mov word ptr ES:[File_Attribute], 2020h
mov word ptr ES:[File_Attribute]+2, 2020h
cmp bl,20h ; Is it an archive file?
jb short loc_pass_arch
mov Byte Ptr ES:[File_Attribute]+3,'A'
loc_pass_arch:
and bl,7
jz short loc_file_name
mov bh,bl
and bl,3
cmp bh,bl
jna short loc_pass_s
mov byte ptr ES:[File_Attribute], 'S'
loc_pass_s:
and bl,2
jz short loc_pass_h
mov byte ptr ES:[File_Attribute]+1, 'H'
loc_pass_h:
and bh,1
jz short loc_file_name
mov byte ptr ES:[File_Attribute]+2, 'R'
loc_file_name:
mov bx, word ptr DS:[SI]+18h ; Date
mov dx, word ptr DS:[SI]+16h ; Time
push si
mov cx, 8
mov di, offset File_Name
rep movsb ; move 8 bytes
mov Byte Ptr ES:[DI],20h
inc di
mov cx, 3
rep movsb ; move 3 bytes
Date_start:
mov ax, bx ; Date
and ax, 00011111b ; Day Mask
aam ; Q([AL]/10)->AH
; R([AL]/10)->AL
; [AL]+[AH]= Day as BCD
or ax, '00' ; Convert to ASCII
xchg al,ah
mov word ptr ES:[File_Day],ax
mov ax, bx
mov cl, 5
shr ax, cl ; shift right 5 times
and ax, 00001111b ; Month Mask
aam
or ax, '00'
xchg ah,al
mov word ptr ES:[File_Month],ax
mov ax, bx
mov cl, 9
shr ax, cl
and ax, 01111111b ; Result = Year - 1980
add ax, 1980
mov cl, 10
div cl ; Q -> AL, R -> AH
or ah, '0'
mov byte ptr ES:[File_Year]+3,ah
aam
xchg ah, al
or ah, '0' ; Convert to ASCII
mov byte ptr ES:[File_Year]+2,ah
aam
xchg al, ah
or ax, '00'
mov word ptr ES:[File_Year],ax
Time_start:
mov ax, dx ; Time
mov cl, 5
shr ax, cl ; shift right 5 times
and ax, 0000111111b ; Minute Mask
aam
or ax, '00'
xchg ah,al
mov word ptr ES:[File_Minute],ax
mov al, dh
shr al, 1
shr al, 1
shr al, 1 ; ax = hours
aam
or ax, '00'
xchg ah, al
mov word ptr ES:[File_Hour],ax
push es
pop ds
loc_show_line:
mov si, offset File_Name
mov cx, 2Eh
mov ah, 0Eh
mov bx, 07h
loop_loc_entry:
lodsb ; Load byte at DS:SI to AL
int 10h ; BIOS Service func ( ah ) = 0Eh
loop loop_loc_entry ; Write char as TTY
pop si
mov al,0Dh
int 10h
mov al,0Ah
int 10h
add Byte Ptr [RetryCount],1 ; 512 bytes = 16 entries
next_entry:
pop ds
pop cx
dec cx
add si,20h ; Next Dir Entry Offset
ja loop_loc_dir
loc_dir_ok:
mov si,offset nextline
call proc_printmsg
retn
Pause_dir_scroll:
mov Byte Ptr [RetryCount],1 ; Reset counter
xor ax,ax
int 16h
cmp al,1Bh
jne loop_loc_dir
retn
print_directory endp
loc_default_transaction:
mov si, offset Default_Command_File
call proc_convert_file_name
call proc_find_file
jc short loc_default_file_notfound
cmp word ptr [File_Size_H], 0
ja short loc_default_file_notfound
cmp word ptr [File_Size_L], 200h
ja short loc_default_file_notfound
mov ax, word ptr [File_FClust]
dec ax
dec ax
xor bx,bx
mov es,bx
mov word ptr [Counter], bx ; Max sectors to load ?
mov bl,Byte Ptr [bp][SecPerClust]
mul bx
add ax,Word Ptr [bp][DataArea1]
adc dx,Word Ptr [bp][DataArea2]
mov bx, 700h
mov cx, 1 ; Read 1 sector
call proc_read
jc short loc_default_file_notfound ; jc loc_failed
mov cx, 36
mov si, 700h
mov di, offset [CommandBuffer]+7
rep movsw ; to move command line to command buffer
mov byte ptr [CommandBuffer]+79, 0
loc_print_default_command:
mov si, offset [CommandBuffer]+7
call proc_printmsg
jmp loc_move_command ; Jump to command handling procedure
loc_default_file_notfound:
mov word ptr [CommandBuffer]+7,'od'; Default command = "dos"
mov byte ptr [CommandBuffer]+9,'s'
mov byte ptr [CommandBuffer]+10,0
jmp short loc_print_default_command
command_interpreter proc near
cmp_cmd_dir:
inc byte ptr [CmdNo]
mov cx,3
xor si,si
mov di, offset Cmd_Dir
get_char_dir:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne cmp_cmd_cd
loop get_char_dir
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call print_directory
retn
cmp_cmd_msdos:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Msdos
get_char_msdos:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_rxdos
loop get_char_msdos
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov ax, 'SM'
mov word ptr [str_boot_bin],ax
jmp short pass_define_fname
cmp_cmd_rxdos:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Rxdos
get_char_rxdos:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_trdos
loop get_char_rxdos
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov ax, 'XR'
mov word ptr [str_boot_bin],ax
jmp short pass_define_fname
cmp_cmd_trdos:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Trdos
get_char_trdos:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_central
loop get_char_trdos
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov ax, 'RT'
mov word ptr [str_boot_bin],ax
pass_define_fname:
mov si, offset str_boot_bin
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
jnc loc_load_msdos
mov si, offset str_boot_bin
call proc_printmsg
mov si, offset msg_notfound
call proc_printmsg
retn
loc_load_msdos:
call proc_load_msdos
retn
cmp_cmd_central:
inc byte ptr [CmdNo]
mov cx,7
xor si,si
mov di, offset Cmd_Central
get_char_central:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_mb
loop get_char_central
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
pass_define_sfname:
mov si, offset str_standalone
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
jnc loc_load_msdos
mov si, offset str_standalone
call proc_printmsg
mov si, offset msg_notfound
call proc_printmsg
retn
cmp_cmd_mb:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
cmp al, 'M'
jnz cmp_cmd_p
cmp ah, 'B'
jnz cmp_cmd_multix
mov ax, word ptr [CommandBuffer]+2
cmp ah, 20h
ja loc_cmd_failed
cmp al, '1'
ja loc_cmd_failed
cmp al, '0'
jnb short put_def_hd_val
or al,al
jnz loc_cmd_failed
mov al,30h
put_def_hd_val:
add al,50h
mov byte ptr [Hard_Disk],al
call proc_load_masterboot
retn
cmp_cmd_p:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
mov dx, word ptr [CommandBuffer]+2
cmp al, 'P'
jnz cmp_cmd_hd
cmp ah, 'T'
jz short loc_chk_pt
cmp dl, 20h
ja loc_cmd_failed
cmp ah, 0
jz short pass_conv_part_no
cmp ah,'0'
jb loc_cmd_failed
cmp ah,'4'
ja loc_cmd_failed
sub ah,'0'
pass_conv_part_no:
mov Byte Ptr [Partition],ah
call proc_load_masterboot
jc short pass_start_partition
call proc_start_partition
jc short pass_start_partition
jump_to_boot:
cmp word ptr [var_KBD], 'TR'
jnz short pass_jtb_reset_INT16h
mov di,58h
mov si, offset [var_INT16h_off]
movsw
movsw
pass_jtb_reset_INT16h:
mov si, offset nextline
call proc_printmsg
mov bp,7C00h
mov byte ptr [bp][DriveNumber],dl ; For second harddisk
jmp BP
pass_start_partition:
retn
loc_chk_pt:
cmp dl, 20h
ja short loc_pt_dh_check
mov dl, byte ptr [Hard_Disk]
sub dl, 50h
mov byte ptr [PT_Drive_Num], dl
jmp short pass_put_def_hdval
loc_pt_dh_check:
cmp dh, 20h
ja loc_cmd_failed
cmp dl, '1'
ja loc_cmd_failed
cmp dl, '0'
jb loc_cmd_failed
mov byte ptr [PT_Drive_Num],dl
add dl, 50h
mov byte ptr [Hard_Disk], dl
pass_put_def_hdval:
mov word ptr [PT_Drive_Num]-2, 'dh' ; may be "ep" before this
call proc_load_masterboot
jc short pass_print_ptable
call proc_print_ptable
pass_print_ptable:
retn
cmp_cmd_hd:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
cmp al, 'H'
jnz cmp_cmd_dos
cmp ah, 'D'
jnz cmp_cmd_hex
mov byte ptr [Partition], 0
mov ax, word ptr [CommandBuffer]+2
or ah,ah
jz short pass_chk_chr5
mov byte ptr [Partition],'D'
cmp ah,'D'
je short pass_A_check
mov byte ptr [Partition], 0
cmp ah, 'A' ; Active P. Loading : hd0a , hd1a
je short pass_A_Check
mov byte ptr [Partition], 'E'; 29 October 2000
cmp ah, 'E' ; Extended partition print
; support added. [ hd0e, hd1e ]
jne loc_cmd_failed
pass_A_check:
cmp byte ptr [CommandBuffer]+4, 20h
ja loc_cmd_failed
pass_chk_chr5:
cmp al, '1'
ja cmd_wrong_drv_name
cmp al, '0'
jnb short put_hd_def_val
or al,al
jnz cmd_wrong_drv_name
jmp short pass_put_hd_def_val
put_hd_def_val:
add al,50h
mov byte ptr [Hard_Disk],al
pass_put_hd_def_val:
call proc_load_masterboot
jc short pass_print_ptable ; Retn
mov al, byte ptr [Partition]
mov byte ptr [Partition],0
cmp al, 'D'
jb pass_loop_dos_partition
mov si, 8BEh
mov cx, 4
cmp al, 'E' ; 29 October 2000
je short loc_scan_ext_partition ; Show Extended DOS partition
; as partition table
xor al, al
loc_scan_dos_p:
inc al
mov byte ptr [Partition], al
cmp byte ptr [SI][ptFileSystemName], 06h
jz pass_loop_dos_partition
cmp byte ptr [SI][ptFileSystemName], 04h
jz pass_loop_dos_partition
cmp byte ptr [SI][ptFileSystemName], 1 ; DOS FAT12
jz pass_loop_dos_partition
cmp byte ptr [SI][ptFileSystemName], 0Eh ; WIN 95/98 FAT16
jz pass_loop_dos_partition
mov byte ptr [Partition],5
add si, 10h
loop loc_scan_dos_p
cmp byte ptr [Partition],5
jb pass_loop_dos_partition
mov si, offset Dos_P_Not_Found
loc_print_dos_p_not_found:
call proc_printmsg
retn
loc_scan_ext_partition:
cmp byte ptr [SI][ptFileSystemName], 05h
jz pass_scan_extd_partition
cmp byte ptr [SI][ptFileSystemName], 0Fh
jz pass_scan_extd_partition
add si, 10h
loop loc_scan_ext_partition
mov si, offset Ext_Dos_P_Not_Found
jmp short loc_print_dos_p_not_found
pass_scan_extd_partition:
mov dl, byte ptr [Hard_Disk]
mov bx, 700h
mov dh, byte ptr [SI][ptBeginHead]
mov cx, word ptr [SI][ptBeginSector]
mov ax, 0201h
int 13h
jc harddisk_error
mov word ptr [PT_Drive_Num]-2,'pe'
mov al, byte ptr [Hard_Disk]
sub al, 50h
mov byte ptr [PT_Drive_Num], al
call proc_print_ptable
retn
cmp_cmd_dos:
inc byte ptr [CmdNo]
mov cx,3
xor si,si
mov di, offset Cmd_Dos
get_char_dos:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne short cmp_cmd_win
loop get_char_dos
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov si, 8BEh
mov cx, 4
xor al, al
jmp loc_scan_dos_p
cmp_cmd_win:
inc byte ptr [CmdNo]
mov cx,3
xor si,si
mov di, offset Cmd_Win
get_char_win:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne short cmp_cmd_xenix
loop get_char_win
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov ah,07h
jmp loc_scan_nondos_p_begin
cmp_cmd_xenix:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Xenix
get_char_xenix:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne short cmp_cmd_unix
loop get_char_xenix
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov ah,02h
jmp loc_scan_nondos_p_begin
return_from_xp:
retn
cmp_cmd_unix:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Unix
get_char_unix:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne short cmp_cmd_linux
loop get_char_unix
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov ah,63h
jmp short loc_scan_nondos_p_begin
cmp_cmd_linux:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Linux
get_char_linux:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne short cmp_cmd_multix
loop get_char_linux
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov ah,83h
jmp short loc_scan_nondos_p_begin
cmp_cmd_multix:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Multix
get_char_multix:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne cmp_cmd_start
loop get_char_multix
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
call proc_load_masterboot
jc short return_from_xp ; retn
mov ah,0A1h
loc_scan_nondos_p_begin:
mov si, 8BEh
mov cx, 4
xor al, al
loc_scan_nondos_p:
inc al
mov byte ptr [Partition], al
cmp byte ptr [SI][ptFileSystemName], ah
jz short pass_loop_dos_partition
mov byte ptr [Partition],5
add si, 10h
loop loc_scan_nondos_p
cmp byte ptr [Partition],5
jb short pass_loop_dos_partition
mov si, offset Cmd_Xenix
cmp ah, 02h
jz short pass_multix_not_found
mov si, offset str_NTFS
cmp ah, 07h
jz short pass_multix_not_found
mov si, offset Cmd_Unix
cmp ah,63h
jz short pass_multix_not_found
mov si, offset Cmd_Linux
cmp ah,83h
jz short pass_multix_not_found
mov si, offset Cmd_Multix
pass_multix_not_found:
push si
mov si, offset nextline
call proc_printmsg
pop si
call proc_printmsg
mov si, offset Dos_P_Not_Found
add si, 5
call proc_printmsg
retn
pass_loop_dos_partition:
call proc_start_partition
jnc jump_to_boot
retn
cmp_cmd_cd:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
cmp ax, 'DC'
jne cmp_cmd_msdos
cmp byte ptr [CommandBuffer][+2],20h
ja loc_cmd_failed
mov si, 7
get_char_cd:
mov al, byte ptr [CommandBuffer][SI]
inc si
cmp al, 20h
je short get_char_cd
add si, 2
get_next_cd_char:
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jb loc_cmd_cd_return ; Without command parameters, only
; prints current drive and directory.
ja short get_first_cd_par
inc si
jmp short get_next_cd_char
get_first_cd_par:
mov word ptr [Cmd_Line_Pointer],si
mov ax, word ptr [CommandBuffer][SI]+3
cmp al, ':'
jne pass_drive_change
cmp ah, '.'
jz loc_cmd_failed
add word ptr [Cmd_Line_Pointer],4 ; Beginning of path
; on command line
mov ax, word ptr [CommandBuffer][SI]
mov bx, word ptr [Drive_Name]
mov word ptr [File_FClust], bx ; Old Drive_Name
and ax, 0DFDFh ; Capitalize
mov word ptr [Drive_Name], 'df'
cmp ax, 'DF'
jz short pass_drive_name
mov word ptr [Drive_Name], 'dh'
cmp ax, 'DH'
jz short pass_drive_name
mov word ptr [Drive_Name], 'dl'
cmp ax, 'DL'
jz short pass_drive_name
mov word ptr [Drive_Name], bx
cmd_wrong_drv_name:
mov si, offset nextline
call proc_printmsg
mov si, offset Msg_Wrong_Drv_Name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
pass_drive_name:
add si, 2
mov al, byte ptr [CommandBuffer][SI]
mov ah, byte ptr [Drive_Num]
mov byte ptr [File_A_Byte], ah ; Old Drive_Num
cmp word ptr [Drive_Name], 'dl' ; Extended p. (logical) disk
je short pass_cd_hd_fd_drive_num
mov byte ptr [Drive_Num], 30h ; "0"
cmp al, 30h
jz pass_drive_num
mov byte ptr [Drive_Num], 31h ; "1"
cmp al, 31h
jz pass_drive_num
jmp short pass_ext_dos_drive_num
pass_cd_hd_fd_drive_num:
cmp al, 30h ; "0"
jb short pass_ext_dos_drive_num
cmp al, 37h ; "7"
ja short pass_ext_dos_drive_num
mov byte ptr [Drive_Num], al
mov byte ptr [Hard_Disk], 80h
cmp al, 33h
jna short pass_inc_cd_disk_dl
inc byte ptr [Hard_Disk]
pass_inc_cd_disk_dl:
call proc_load_masterboot
int 13h
jnc short cd_load_extended_dos_partition
mov si, offset HdResetFailedMsg
call proc_printmsg
retn
pass_ext_dos_drive_num:
mov word ptr [Drive_Name], bx
mov byte ptr [Drive_Num], ah
jmp cmd_wrong_drv_name
cd_load_extended_dos_partition:
mov si, 8BEh
mov cx, 4
cd_find_extd_partition:
cmp byte ptr [SI][ptFileSystemName], 05h
jz short pass_find_extd_partition
cmp byte ptr [SI][ptFileSystemName], 0Fh
jz short pass_find_extd_partition
add si, 10h
loop cd_find_extd_partition
mov si, word ptr [File_FClust] ; Old Drive_Name
mov word ptr [Drive_Name], si
mov al, byte ptr [File_A_Byte] ; Old Drive_Num
mov byte ptr [Drive_Num], al
mov si, offset Ext_Dos_P_Not_Found
call proc_printmsg
retn
pass_find_extd_partition:
mov dl, byte ptr [Hard_Disk]
mov bx, word ptr [SI][ptStartSector]
mov word ptr [File_Size_L], bx ; Start sec of ext part. 1
mov bx, word ptr [SI][ptStartSector]+2
mov word ptr [File_Size_H], bx ; Start sec of ext part. 2
mov bx, 700h
mov dh, byte ptr [SI][ptBeginHead]
mov cx, word ptr [SI][ptBeginSector]
mov ax, 0201h
int 13h
jc harddisk_error
mov si, 8BEh
mov cl, 10h
mov al, byte ptr [Drive_Num]
sub al, 30h
cmp al, 3
jna short pass_inc_cd_ld_al
sub al, 4
pass_inc_cd_ld_al:
mul cl
add si, ax
cmp byte ptr [SI][ptFileSystemName], 06h
jz short pass_cd_check_valid_dos_p
cmp byte ptr [SI][ptFileSystemName], 04h
jz short pass_cd_check_valid_dos_p
cmp byte ptr [SI][ptFileSystemName], 1 ; DOS FAT12
jz short pass_cd_check_valid_dos_p
cmp byte ptr [SI][ptFileSystemName], 0Eh ; WIN 95/98 FAT16
jz short pass_cd_check_valid_dos_p
mov si, word ptr [File_FClust] ; Old Drive_Name
mov word ptr [Drive_Name], si
mov al, byte ptr [File_A_Byte] ; Old Drive_Num
mov byte ptr [Drive_Num], al
mov si, offset Logical_Drv_Not_valid
call proc_printmsg
retn
pass_cd_check_valid_dos_p:
mov ax, word ptr [SI][ptStartSector]
mov dx, word ptr [SI][ptStartSector]+2
add word ptr [File_Size_L], ax
adc word ptr [File_Size_H], dx
mov dl, byte ptr [Hard_Disk]
mov bx, 700h
mov dh, byte ptr [SI] [ptBeginHead]
mov cx, word ptr [SI] [ptBeginSector]
mov ax, 0201h
int 13h
jc harddisk_error
mov si, 8FEh
cmp word ptr [SI], 0AA55h
je short loc_it_is_a_ld_boot_sector
mov si, word ptr [File_FClust] ; Old Drive_Name
mov word ptr [Drive_Name], si
mov al, byte ptr [File_A_Byte] ; Old Drive_Num
mov byte ptr [Drive_Num], al
jmp it_is_not_boot_sec
loc_it_is_a_ld_boot_sector:
mov dl, byte ptr [Hard_Disk]
mov cx,100h
mov si,700h
mov di,7C00h
rep movsw
mov bp, 7C00h
mov ax, word ptr [File_Size_L]
mov si, word ptr [File_Size_H]
mov word ptr [bp][Hidden1], ax ; Warning ! Hidden Secs area
mov word ptr [bp][Hidden2], si ; changed... Saving that boot
; sector is dangerous !!!
; This made for adjusting
; displacement from beginning
; of the disk. For correct
; reading logical partition.
jmp cd_load_root_dir
pass_drive_num:
push bx
push ax
mov dl, byte ptr [Drive_Num]
sub dl, 30h
mov ax, word ptr [Drive_Name]
cmp ax, 'df'
jz short cd_reset_disk
add dl, 80h
cd_reset_disk:
xor ah,ah
int 13h
jnc short cd_load_masterboot
mov si, offset HdResetFailedMsg
call proc_printmsg
cd_return_from_err:
pop ax
pop bx
mov word ptr [Drive_Name], bx
mov byte ptr [Drive_num], ah
retn
cd_load_masterboot:
cmp dl, 80h
jb short cd_load_boot_sec
mov byte ptr [Hard_Disk], dl
call proc_load_masterboot
jnc short pass_cd_masterboot_err
jmp short cd_return_from_err
pass_cd_masterboot_err:
mov si, 8BEh
mov cx, 4
xor al, al
loc_scan_cd_dos_p:
inc al
mov byte ptr [Partition], al
cmp byte ptr [SI][ptFileSystemName], 06h
jz short pass_loop_cd_dos_p
cmp byte ptr [SI][ptFileSystemName], 04h
jz short pass_loop_cd_dos_p
cmp byte ptr [SI][ptFileSystemName], 1 ; DOS FAT12
jz short pass_loop_cd_dos_p
cmp byte ptr [SI][ptFileSystemName], 0Eh ; WIN 95/98 FAT16
jz short pass_loop_cd_dos_p
mov byte ptr [Partition],5
add si, 10h
loop loc_scan_cd_dos_p
cmp byte ptr [Partition],5
jb short pass_loop_cd_dos_p
mov si, offset Dos_P_Not_Found
call proc_printmsg
jmp short cd_return_from_err
pass_loop_cd_dos_p:
call proc_start_partition
jc short cd_return_from_err
pop ax
pop bx
jmp short cd_load_root_dir
cd_load_boot_sec:
xor dh, dh
mov ax, 0201h
mov cx, 1
mov bx, 700h
int 13h
jnc short pass_cd_boot_err
mov si, offset hdResetFailedMsg
call Proc_printmsg
jmp short cd_return_from_err
pass_cd_boot_err:
mov si, 700h
cmp word ptr [SI]+1FEh, 0AA55h
jne short loc_not_boot_sec
cmp word ptr [SI][FileSysType], 'AF'
jnz short loc_not_dos_disk
cmp byte ptr [SI][FileSysType]+2, 'T'
jnz short loc_not_dos_disk
mov cx,100h
mov si,700h
mov di,7C00h
rep movsw
pop ax
pop bx
cd_load_root_dir:
mov bp, 7C00h
mov byte ptr [bp][DriveNumber], dl ; For second disk
mov byte ptr [Current_Dir],0 ; Reset directory path
mov word ptr [Dir_Pointer],0 ; Reset position
mov si, word ptr [Cmd_Line_Pointer]
cmp byte ptr [CommandBuffer][SI], '/'
jne short pass_inc_cmd_line_pointer
inc word ptr [Cmd_Line_Pointer]
pass_inc_cmd_line_pointer:
call proc_fat_load ; Load FAT of new drive
jc loc_failed
call Proc_LoadRootDir ; Load root dir of new drive
jnc short pass_cd_load_root_dir
jmp loc_failed ; Error message and reboot
loc_cd_exit:
retn
loc_not_boot_sec:
mov si, offset nextline
call proc_printmsg
mov si, offset Not_boot_sec
loc_write_cd_boot_err:
call Proc_printmsg
jmp cd_return_from_err
loc_not_dos_disk:
mov si, offset Not_dos_disk
jmp short loc_write_cd_boot_err
pass_drive_change:
mov si, word ptr [Cmd_Line_Pointer]
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jne short pass_cd_dot_dir
cmp ah, 2Eh
je locate_previous_dir
cmp ah, 20h
jbe short loc_cd_exit
jmp loc_cmd_failed
pass_cd_dot_dir:
cmp al, '/'
jne short pass_cd_load_root_dir
inc word ptr [Cmd_Line_Pointer]
mov word ptr [Dir_Pointer],0
mov bp, 7C00h
call Proc_LoadRootDir
jc loc_failed
pass_cd_load_root_dir:
xor bp,bp
cd_perform_sub_dir:
mov cx, 12
cd_next_subdir_char:
mov si, word ptr [Cmd_Line_Pointer]
inc word ptr [Cmd_Line_Pointer]
mov al, byte ptr [CommandBuffer][SI]
cmp al, '/'
je short cd_scan_subdir
cmp al, 20h
jna short cd_scan_subdir
cmp al, 61h
jb short cd_pass_capitalize
cmp al, 7Ah
ja short cd_pass_capitalize
and al, 0DFh
cd_pass_capitalize:
mov byte ptr [S_File_Name][bp], al
inc bp
loop cd_next_subdir_char
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short cd_scan_subdir
cd_wrong_dir_name:
mov si, word ptr [Dir_Pointer]
mov word ptr [Current_Dir][SI],0
mov si, offset nextline
call proc_printmsg
mov si, offset Msg_Wrong_Dir_Name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cd_scan_subdir:
mov byte ptr [S_File_Name][bp],0 ; End of directory name
mov si, offset S_File_Name
cmp byte ptr [SI], 20h
jna loc_cmd_cd_return
cmp byte ptr [SI], 2Eh ; Dot is not valid as first char
je loc_cmd_failed
call proc_convert_file_name
push es
mov di, 7000h
mov es, di
xor di, di
mov cx, 800h
cd_loc_start_scan:
push cx
cmp byte ptr ES:[DI], 0
je short cd_dir_not_found
push di
mov cx, 11
mov si, offset Dir_File_Name
cd_loc_next_dir_char:
cmpsb
jne short cd_next_dir_search
loop cd_loc_next_dir_char
pop di
mov bl, byte ptr ES:[DI]+0Bh
and bl, 10h
jz short cd_dir_not_found
mov bx, word ptr ES:[DI]+1Ah ; First Cluster
pop cx
pop es
jmp short cd_locate_dir
cd_next_dir_search:
pop di
add di, 20h
pop cx
loop cd_loc_start_scan
push cx
cd_dir_not_found:
pop cx
pop es
mov si, word ptr [Dir_Pointer]
mov word ptr [Current_Dir][SI], 0
mov si, offset nextline
call Proc_Printmsg
mov si, offset S_File_Name
call Proc_Printmsg
mov si, offset Msg_NotFound
call Proc_Printmsg
retn
cd_locate_dir:
mov bp, 7C00h
mov word ptr [Register_AX], 3030h
cmp bx, 2 ; First cluster
jb loc_failed
push bx
mov cl, byte ptr [bp][SecPerClust]
mov ax, 80h ; 1 segment = 80h sectors
div cl ; Division without round up !
; Remain (AH) must be zero !
; cbw ; xor ah,ah
mov word ptr [Counter], ax ; # of clusters limit for read
mov bx, 7000h ; Destination is ES:BX
mov es, bx
xor bx, bx
pop cx ; First cluster
mov word ptr [Clust_Of_Dir], cx ; Save current dir's cluster
; number for other commands.
call proc_file_read
jc loc_failed
push ds
pop es
mov word ptr [DirEntries], 800h ; Max dir entries
mov cx,12
mov bp, word ptr [Dir_Pointer]
mov si, offset S_File_Name
mov di, offset Current_Dir
cmp bp, 0
jz short loc_cdir_next_char
add di, bp ; Current_Dir line/column
mov byte ptr [DI], '/'
inc di
inc bp
loc_cdir_next_char:
mov al, byte ptr [SI]
cmp al, 21h
jb short cd_pass_move_dir_name
movsb
inc bp
loop loc_cdir_next_char
cd_pass_move_dir_name:
mov word ptr [Dir_Pointer], bp
jmp pass_cd_load_root_dir
loc_cmd_cd_return:
; xor ax, ax
; mov es, ax ; ES must be 0 for cmdb reset
mov si, word ptr [Dir_Pointer]
mov byte ptr [Current_Dir][SI], 0 ; End of dir string ; End of dir string
mov si, offset nextline
call Proc_Printmsg
mov si, offset Drive_Str
call Proc_Printmsg
mov si, offset nextline
call Proc_Printmsg
exit_cd_previous_alone:
retn
locate_previous_dir:
inc si
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja short pass_space_zero_check
mov al, byte ptr [Current_Dir]
cmp al, 21h
jb short exit_cd_previous_alone
mov byte ptr [CommandBuffer][SI], 0FFh
jmp short pass_root_sign_check
pass_space_zero_check:
cmp al, '/'
jne loc_cmd_failed
inc si
pass_root_sign_check:
push si
push ds
pop es
mov si, offset Current_Dir
mov di, si
dec si
mov cx, 67
loop_scan_root_sign:
dec cx
inc si
mov al, byte ptr [SI]
cmp al, 21h
jb short stop_scan_root_sign
cmp al, '/'
jne short loop_scan_root_sign
mov di, si
inc di
loop loop_scan_root_sign
stop_scan_root_sign:
mov byte ptr [DI], 0 ; Cut last dir name of current dir path
pop si
cmp byte ptr [CommandBuffer][SI],0FFh
je short pass_move_cml_cd_prev ; No sub dirs from prev dir
mov cx, 66
add cx, offset Current_Dir
sub cx, di ; DI= Offset Current_Dir + Displacement (<=66)
mov bx, 79
sub bx, si
cmp cx, bx
jb short pass_change_cx_bx
mov cx, bx
pass_change_cx_bx:
add si, offset CommandBuffer
rep movsb
mov byte ptr [DI],0
pass_move_cml_cd_prev:
mov di, offset [CommandBuffer]+7
mov si, offset Current_Dir
mov word ptr [DI],'CD'
inc di
inc di
mov word ptr [DI], 2F20h
inc di
inc di
mov cx, 67
rep movsb
jmp cmp_cmd_cd
cmp_cmd_start:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Start
get_char_start:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_run
loop get_char_start
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_start_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'S'
jb short loop_scan_start_word
add si, 5
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna short loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_filename
push si
cmp al,30h
jb short loc_start_wrong_filename
mov cx,8
loop_start_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short pass_start_dot_control
jb short loc_start_wrong_filename
dec cx
jnz short loop_start_dot_control
jmp short loc_start_wrong_filename
pass_start_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
inc si
and al, 0DFh
mov bx, word ptr [CommandBuffer][SI]
and bx, 0DFDFh
cmp al, 'T'
jz short pass_start_bin_control
cmp al, 'B'
jz short pass_start_std_control
cmp al, 'S'
jz short pass_start_rts_control
cmp al, 'R'
jnz short loc_start_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp bx, 'ST'
jz short scan_file_name
jmp short loc_start_wrong_filename
pass_start_bin_control:
cmp bx, 'RO'
jz short scan_file_name
jmp short loc_start_wrong_filename
pass_start_std_control:
cmp bx, 'NI'
jz short scan_file_name
jmp short loc_start_wrong_filename
pass_start_rts_control:
cmp bx, 'DT'
jz short scan_file_name
loc_start_wrong_filename:
pop si
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_file_name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
mov si, offset msg_s_correct_file_names
call proc_printmsg
retn
loc_start_specify_filename:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_specify_file_name
call proc_printmsg
retn
loc_start_file_notfound:
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_notfound
call proc_printmsg
stc
retn
loc_file_size_big:
mov si, offset msg_big_file_size
call proc_printmsg
stc
retn
scan_file_name:
mov word ptr [Start_Pointer],bx ; File extension sign
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_scan_movsb:
movsb
dec cx
jz short pass_scan_file_name
cmp byte ptr [SI],2Eh
jnb short loop_scan_movsb
pass_scan_file_name:
mov si, offset S_File_Name
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
jc short loc_start_file_notfound
cmp word ptr [File_Size_H], 0
ja short loc_file_size_big
pass_scan_file_size_big:
mov cx, word ptr [File_FClust]
cmp cx, 2
jb loading_failed
cmp word ptr [Start_Pointer], 'NI' ; BIN file ?
jne short pass_prepare_bin_execution
mov word ptr [Start_Pointer], 7C0h
mov word ptr [Start_Jump_Off], 7C00h
start_load_file_and_jump_to_it:
xor dx,dx
mov es,dx
push cx
mov cx, 22h
mov si, 7BFCh
mov di, 6FCh
rep movsw
mov di, 740h
mov si, offset jump_from_p2000_to_740h
mov cx, offset cmp_cmd_run
sub cx, si
rep movsb
pop cx
mov bp, 700h
cmp word ptr [var_KBD], 'TR'
jnz short pass_start_reset_INT16h
mov di,58h
mov si, offset [var_INT16h_off]
movsw
movsw
pass_start_reset_INT16h:
mov es, word ptr [Start_Segment]
mov ax, 80h ; Max. 128 sectors
mov bl, byte ptr [bp][SecPerClust]
div bl
mov Word Ptr [Counter], ax
xor bx,bx
call proc_file_read
jc loc_failed
mov es, word ptr [Start_Pointer] ; 7C0h or 7E0h
mov cx, 0FFFFh
xor si, si
xor di, di
mov ds, word ptr [Start_Segment]
mov bx, 740h
jmp bx
pass_prepare_bin_execution:
mov word ptr [Start_Pointer],7E0h
mov word ptr [Start_Jump_Off], 7E00h
jmp short start_load_file_and_jump_to_it
jump_from_p2000_to_740h:
rep movsb
xor bx,bx
mov ds,bx
mov es,bx
Start_Far_Jump:
db 0EAh
Start_Jump_Off:
dw 0
Start_Jump_Seg:
dw 0
cmp_cmd_run:
inc byte ptr [CmdNo]
mov cx,3
xor si,si
mov di, offset Cmd_Run
get_char_run:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_load
loop get_char_run
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_run_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'R'
jb short loop_scan_run_word
add si, 3
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_run_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_run_filename
push si
cmp al,30h
jb short loc_run_wrong_filename
mov cx,8
loop_run_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short pass_run_dot_control
jb short loc_run_wrong_filename
dec cx
jnz short loop_run_dot_control
jmp short loc_run_wrong_filename
pass_run_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
inc si
and al, 0DFh
mov bx, word ptr [CommandBuffer][SI]
and bx, 0DFDFh
cmp al, 'C'
jz short pass_run_bin_control
cmp al, 'B'
jz short pass_run_std_control
cmp al, 'S'
jz short pass_run_rts_control
cmp al, 'R'
jnz short loc_run_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp bx, 'ST'
jz short r_scan_file_name
jmp short loc_run_wrong_filename
pass_run_bin_control:
cmp bx, 'MO'
jz short r_scan_file_name
jmp short loc_run_wrong_filename
pass_run_std_control:
cmp bx, 'NI'
jz short r_scan_file_name
jmp short loc_run_wrong_filename
pass_run_rts_control:
cmp bx, 'DT'
jz short r_scan_file_name
loc_run_wrong_filename:
pop si
mov si, offset msg_r_com
mov byte ptr [SI],'C'
mov byte ptr [SI]+2,'M'
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_file_name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
mov si, offset msg_s_correct_file_names
call proc_printmsg
mov si, offset msg_r_com
mov byte ptr [SI],'T'
mov byte ptr [SI]+2,'R'
retn
r_scan_file_name:
mov word ptr [Start_Pointer],bx ; File extension sign
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_r_scan_movsb:
movsb
dec cx
jz short pass_r_scan_file_name
cmp byte ptr [SI],2Eh
jnb short loop_r_scan_movsb
pass_r_scan_file_name:
mov si, offset S_File_Name
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
jc loc_start_file_notfound
mov dx, word ptr [File_Size_H]
and dx, dx
jz short pass_r_com_size_check
mov cx, word ptr [Start_Pointer]
cmp cx, 'MO'
je loc_file_size_big
cmp dx, 4
ja loc_file_size_big
pass_r_com_size_check:
mov cx, word ptr [File_FClust]
cmp cx, 2
jb loading_failed
mov es, word ptr [Start_Segment]
mov bp, 7C00h
mov ax, word ptr [Start_Pointer]
cmp ax, 'MO' ; COM file ?
jz short run_prepare_com_execution
mov word ptr [Start_Pointer], 0h
mov word ptr [Counter], 200h
mov bx, 0
call proc_file_read
mov es, word ptr [Start_Segment]
push es
pop ds
push ds
pop ss
mov sp, 0FFFCh
jmp dword ptr CS:[Start_Pointer]
run_prepare_com_execution:
mov word ptr [Start_Pointer], 0100h
mov Word Ptr [Counter], 80h
mov bx, 0100h
call proc_file_read
jump_prepare_execution: ; Only for "jump" command
xor bx, bx
mov es, bx
mov bx, word ptr ES:[80h] ; Int 20h Offset
mov word ptr [INT20h_Offset], bx
mov bx, word ptr ES:[82h] ; Int 20h Segment
mov word ptr [INT20h_segment], bx
mov si, offset Run_Com_INT20h_Handler
mov di, 80h
mov word ptr ES:[DI], si ; Temporary INT20h handler
mov si, ds
mov word ptr ES:[DI]+2, si ; Temporary INT20h handler
mov es, word ptr [Start_Segment] ; Program segment to run
push es
pop ds
cmp byte ptr CS:[CommandBuffer],'J' ; Is it "jump" command ?
jz short far_jump_to_address
push ds
pop ss
mov sp, 0FFFCh
xor bx,bx
mov word ptr ES:[BX], 20CDh ; INT 20h (CD20h) for "RET"
push es ; For far RETURN
push bx ; BX = offset
far_jump_to_address:
jmp dword ptr CS:[Start_Pointer]
Run_Com_INT20h_Handler:
push cs
pop ds
push ds
pop es
push es
pop ss
mov sp, 07BFAh
mov bp, 7C00h
cli
cld
cmp word ptr [var_KBD], 'TR'
jnz short pass_run_reset_INT16h
mov di,58h
mov si, offset [var_INT16h_off]
movsw
movsw
pass_run_reset_INT16h:
jmp start
cmp_cmd_load:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Load
get_char_load:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_show
loop get_char_load
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_load_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'L'
jb short loop_scan_load_word
add si, 4
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_load_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_load_filename
push si
cmp al, 2Eh
je short loc_load_wrong_filename
mov cx,8
loop_load_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short l_scan_file_name
cmp al,20h
jna short load_no_extension_of_filename
dec cx
jnz short loop_load_dot_control
cmp al,2Eh
je short l_scan_file_name
loc_load_wrong_filename:
pop si
loc_load_wrong_filename_j:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_file_name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
l_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb short loc_load_wrong_filename
cmp al, 2Eh
jz short loc_load_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz short loc_load_wrong_filename
cmp ah, 2Eh
jz short loc_load_wrong_filename
load_no_extension_of_filename:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_l_scan_movsb:
movsb
dec cx
jz short pass_l_scan_file_name
cmp byte ptr [SI],21h
jnb short loop_l_scan_movsb
mov byte ptr ES:[DI],0
pass_l_scan_file_name:
mov si, offset S_File_Name
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
jc loc_start_file_notfound
mov dx, word ptr [File_Size_H]
cmp dx, 4
ja loc_file_size_big
mov cx, word ptr [File_FClust]
cmp cx, 2
jb loading_failed
mov es, word ptr [Start_Segment]
mov bp, 7C00h
mov bx, word ptr [Start_Pointer]
mov word ptr [Counter], 200h
call proc_file_read
jc short end_of_load
mov al, byte ptr [CmdNo]
mov byte ptr [Status], al ; "show" will check it.
mov ax, word ptr [File_Size_L]
mov word ptr [Save_Size_L], ax ; For "save" command.
mov ax, word ptr [File_Size_H]
mov word ptr [Save_Size_H], ax ; For "save" command.
end_of_load:
retn
cmp_cmd_show:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Show
get_char_show:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_offset
loop get_char_show
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_show_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'S'
jb short loop_scan_show_word
add si, 4
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_show_filename:
inc si
dec cx
jz short pass_show_scan_file_name
cmp al,0Dh
jna short pass_show_scan_file_name
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_show_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_show_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short show_scan_file_name
cmp al,20h
jna short show_no_extension_of_filename
dec cx
jnz short loop_show_dot_control
cmp al,2Eh
jne loc_load_wrong_filename
show_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp ah, 2Eh
jz loc_load_wrong_filename
show_no_extension_of_filename:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_show_scan_movsb:
movsb
dec cx
jz short pass_loop_show_scan_movsb
cmp byte ptr [SI],21h
jnb short loop_show_scan_movsb
pass_loop_show_scan_movsb:
mov byte ptr ES:[DI],0
mov si, offset retn_to_show_scan_file_name
push si ;for near call !
jmp pass_l_scan_file_name
retn_to_show_scan_file_name:
jc short pass_show_file
jmp short loc_start_show_file
pass_show_scan_file_name:
cmp byte ptr [Status], 0 ; Is there a loaded file ?
je loc_start_specify_filename
mov si, offset nextline
call proc_printmsg
loc_start_show_file:
mov es, word ptr [Start_Segment]
mov si, word ptr [Start_Pointer]
mov di, word ptr [File_Size_L]
xor bp,bp
xor dx,dx
mov cx, 22
loop_show_file_char:
and cx, cx
jnz short pass_show_wait_for_key
xor ah,ah
int 16h
cmp al, 1Bh
jnz short pass_exit_show
jmp short pass_show_file
pass_exit_show:
mov cx, 20
pass_show_wait_for_key:
mov al, byte ptr ES:[SI]
cmp al, 0Dh
jnz short pass_show_dec_cx
dec cx
pass_show_dec_cx:
cmp al, 09h
jnz short pass_put_tab_space
mov al, 20h
pass_put_tab_space:
mov ah, 0Eh
mov bx, 07h
int 10h
compare_bp_bx_file_size:
inc si
jnz short pass_show_update_si_es
mov ax, es
add ax, 1000h
mov es, ax
pass_show_update_si_es:
cmp bp, di
jnb short check_dx_show_file
inc bp
jmp short loop_show_file_char
check_dx_show_file:
xor bp, bp
mov di, 0FFFFh
inc dx
cmp dx, word ptr [File_Size_H]
jna short loop_show_file_char
end_of_show_file:
push ds
pop es
pass_show_file:
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_offset:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Offset
get_char_offset:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_segment
loop get_char_offset
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_offset_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'O'
jb short loop_scan_offset_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_o_addr:
inc si
dec cx
jz short pass_offset_addr
cmp al,0Dh
jna short pass_offset_addr
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_o_addr
mov cl,4
xor di,di
loop_get_o_addr:
cmp al, 30h ; 0
jb short loc_wrong_address
cmp al, 39h ; 9
jna short pass_o_capitalize
cmp al, 41h ; A
jb short loc_wrong_address
cmp al, 46h ; F
jna short pass_o_capitalize
cmp al, 61h ; a
jb short loc_wrong_address
cmp al, 66h ; f
ja short loc_wrong_address
and al, 0DFh
pass_o_capitalize:
mov byte ptr [Offset_Addr][DI], al
inc si
mov al, byte ptr [CommandBuffer][SI]
inc di
dec cl
jnz short loop_get_o_addr
cmp al, 20h
jna short pass_o_h_control
and al, 0DFh
cmp al, 'H'
jnz short loc_wrong_address
pass_o_h_control:
mov dx, word ptr [Offset_Addr]
mov ax, word ptr [Offset_Addr]+2
call proc_binary ; Char to Binary converter
mov word ptr [Start_Pointer], ax
mov dx, word ptr [Segment_Addr]
mov ax, word ptr [Segment_Addr]+2
call proc_binary
mov word ptr [Start_Segment], ax
retn
pass_offset_addr:
mov al, byte ptr [Start_Pointer]
call proc_hex ; Binary to char converter
mov word ptr [Offset_Addr]+2, ax
mov al, byte ptr [Start_Pointer]+1
call proc_hex
mov word ptr [Offset_Addr], ax
mov al, byte ptr [Start_Segment]
call proc_hex
mov word ptr [Segment_Addr]+2, ax
mov al, byte ptr [Start_Segment]+1
call proc_hex
mov word ptr [Segment_Addr], ax
mov si, offset Msg_Loading_Address
call proc_printmsg
retn
loc_wrong_address:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_address
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_segment:
inc byte ptr [CmdNo]
mov cx,7
xor si,si
mov di, offset Cmd_Segment
get_char_segment:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_jump
loop get_char_segment
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 7
loop_scan_segment_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'E'
jb short loop_scan_segment_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_s_addr:
inc si
dec cx
jz short pass_offset_addr
cmp al,0Dh
jna pass_offset_addr
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_s_addr
mov cl,4
xor di,di
loop_get_s_addr:
cmp al, 30h ; 0
jb short loc_wrong_address
cmp al, 39h ; 9
jna short pass_s_capitalize
cmp al, 41h ; A
jb short loc_wrong_address
cmp al, 46h ; F
jna short pass_s_capitalize
cmp al, 61h ; a
jb short loc_wrong_address
cmp al, 66h ; f
ja short loc_wrong_address
and al, 0DFh
pass_s_capitalize:
mov byte ptr [Segment_Addr][DI], al
inc si
mov al, byte ptr [CommandBuffer][SI]
inc di
dec cl
jnz short loop_get_s_addr
cmp al, 20h
jna pass_o_h_control
and al, 0DFh
cmp al, 'H'
jnz loc_wrong_address
jmp pass_o_h_control
cmp_cmd_hex:
inc byte ptr [CmdNo]
mov si, 1
mov ax, word ptr [CommandBuffer][SI]
cmp ax, 'XE'
jne loc_cmd_failed
add si, 2
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov byte ptr [Printer_Hex], 0
mov cx, 60
add si, 8
loc_hex_p_control:
mov al, byte ptr [CommandBuffer][SI]
inc si
cmp al, '-'
jne short pass_hex_p_control
mov al, byte ptr [CommandBuffer][SI]
and al, 0DFh
cmp al, 'P'
jne short start_hex_write_char
inc byte ptr [Printer_Hex]
jmp short start_hex_write_char
pass_hex_p_control:
loop loc_hex_p_control
start_hex_write_char:
mov si, offset nextline
call proc_printmsg
mov es, word ptr [Start_Segment]
mov bp, word ptr [Start_Pointer]
mov cx, 78
jmp short pass_hex_wait_for_key
loop_hex_file_char:
xor ah,ah
int 16h
cmp al, 1Bh
jz pass_hex_file
mov al, 0Dh
mov ah, 0Eh
mov bx, 07h
int 10h
mov al, 0Ah
int 10h
pass_exit_hex:
mov cx, 78
pass_hex_wait_for_key:
mov ax, es
xchg ah,al
call proc_hex
push ax
mov ah, 0Eh
mov bx, 07h
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov ax, es
call proc_hex
push ax
mov ah, 0Eh
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov al, 'h'
int 10h
mov al, ':'
int 10h
mov ax,bp
xchg ah,al
call proc_hex
push ax
mov ah, 0Eh
mov bx, 07h
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov ax, bp
call proc_hex
push ax
mov ah, 0Eh
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov al, 'h'
int 10h
mov al, 20h
int 10h
mov al, 20h
int 10h
sub cx, 13
push es
push bp
loc_repeat_hex_write:
mov al, byte ptr ES:[BP]
call proc_hex
push ax
mov ah, 0Eh
int 10h
dec cx
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
dec cx
mov al, 20h
int 10h
inc bp
jnz short pass_hex_update_es
mov bp, es
add bp,1000h
mov es,bp
xor bp,bp
pass_hex_update_es:
dec cx
cmp cx, 12h
jnb short loc_repeat_hex_write
mov al, 20h
int 10h
mov cx, 10h
mov di, es
pop si ; pushed bp
pop es
cmp byte ptr [Printer_Hex], 0
jz short loop_hex_byte_write
loc_p_hex_byte_write:
mov al, byte ptr ES:[SI]
cmp al, 1Fh
ja short pass_non_printable_1
mov al, 20h
jmp short write_printable_byte
pass_non_printable_1:
cmp al, 7Fh
jb short write_printable_byte
mov al, 20h
write_printable_byte:
mov ah, 0Eh
int 10h
inc si
jnz short pass_update_p_hex_byte_es
mov si, es
add si,1000h
mov es, si
xor si,si
pass_update_p_hex_byte_es:
dec cx
jnz short loc_p_hex_byte_write
mov es, di
jmp loop_hex_file_char
loop_hex_byte_write:
push cx
mov al, byte ptr ES:[SI]
mov ah, 0Ah
; mov bx, 07h
mov cx, 1
int 10h
mov ah, 03h
int 10h
inc dl
mov ah, 02h
int 10h
pop cx
inc si
jnz short pass_update_hex_byte_es
mov si,es
add si,1000h
mov es,si
xor si,si
pass_update_hex_byte_es:
dec cx
jnz short loop_hex_byte_write
mov es, di
jmp loop_hex_file_char
pass_hex_file:
push ds
pop es
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_jump:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Jump
get_char_jump:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_sector
loop get_char_jump
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov es, word ptr [Start_Segment]
xor bx, bx
cmp byte ptr ES:[BX], 0
jne short pass_jump_initialization
mov word ptr ES:[BX], 20CDh ; Initial execution warranty !
pass_jump_initialization:
mov bx, offset call_return
push ds ; For far RETURN
push bx ; BX = return offset
jmp jump_prepare_execution
call_return:
retn
cmp_cmd_sector:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Sector
get_char_sector:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_device
loop get_char_sector
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_sector_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'S'
jb short loop_scan_sector_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_sec_addr:
inc si
dec cx
jz loc_show_device_reading_parameters
cmp al,0Dh
jna loc_show_device_reading_parameters
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_sec_addr
xor bp, bp
jmp short start_scan_sec_value
loop_get_sec_addr:
cmp al, 20h
jna short pass_get_sec_addr
start_scan_sec_value:
cmp al, 30h ; 0
jb loc_wrong_sector
cmp al, 39h ; 9
ja loc_wrong_sector
mov byte ptr [Decimal_Sector][bp], al
inc si
inc bp
cmp bp, 9
ja short check_last_sec_numeral
mov al, byte ptr [CommandBuffer][SI]
jmp short loop_get_sec_addr
check_last_sec_numeral:
cmp byte ptr [CommandBuffer][SI], 20h
ja loc_wrong_sector
pass_get_sec_addr:
mov cx, 11
sub cx, bp
xor al, al
d_sector_reset_remain:
mov byte ptr [Decimal_Sector][bp], al
inc bp
loop d_sector_reset_remain
mov cx, 10
mov bp, cx
loc_calculate_sec_step:
dec bp
cmp byte ptr [Decimal_Sector][bp], 30h
jnb short pass_loc_calculate_sec_step
loop loc_calculate_sec_step
pass_loc_calculate_sec_step:
mov cx, bp
xor bp, bp
mov word ptr [Device_Displacement], 0
mov word ptr [Device_Section], 0
cmp cx, 9
jz short loc_9_digit_sector_num
cmp cx, 8
jz short pass_mul_3B9ACA00
cmp cx, 7
jz short pass_mul_5F5E100
cmp cx, 6
jz pass_mul_989680
cmp cx, 5
jz pass_mul_F4240
cmp cx, 4
jz pass_mul_186A0
cmp cx, 3
jz pass_mul_2710
cmp cx, 2
jz pass_mul_3E8
cmp cx, 1
jz pass_mul_64
jmp pass_mul_0A
loc_9_digit_sector_num:
mov ax, 0CA00h ; DX_AX = (1000000000)hex
mov dx, 3B9Ah
xor bh, bh
mov bl, byte ptr [Decimal_Sector]
sub bl, 30h
call proc_mul32 ; Convert to hex value
and bx, bx
jnz loc_wrong_sector
mov word ptr [Device_Displacement], ax
mov word ptr [Device_Section], dx
inc bp
pass_mul_3B9ACA00:
mov ax, 0E100h ; DX_AX = (100000000)hex
mov dx, 5F5h
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
call proc_mul32 ; Convert to hex value
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc loc_wrong_sector
inc bp
pass_mul_5F5E100:
mov ax, 9680h ; DX_AX = (10000000)hex
mov dx, 98h
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
call proc_mul32 ; Convert to hex value
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc loc_wrong_sector
inc bp
pass_mul_989680:
mov ax, 4240h ; DX_AX = (1000000)hex
mov dx, 0Fh
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
call proc_mul32 ; Convert to hex value
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc loc_wrong_sector
inc bp
pass_mul_F4240:
mov ax, 86A0h ; DX_AX = (100000)hex
mov dx, 01h
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
call proc_mul32
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc loc_wrong_sector
inc bp
pass_mul_186A0:
mov ax, 2710h ; AX = (10000)hex
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
mul bx
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc loc_wrong_sector
inc bp
pass_mul_2710:
mov ax, 3E8h ; AX = (1000)hex
xor bh, bh
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
mul bx
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], dx
jc short loc_wrong_sector
inc bp
pass_mul_3E8:
mov ax, 64h ; AX = (100)hex
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
mul bl
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], 0
jc short loc_wrong_sector
inc bp
pass_mul_64:
mov ax, 0Ah ; AX = (10)hex
mov bl, byte ptr [Decimal_Sector][bp]
sub bl, 30h
mul bl
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], 0
jc short loc_wrong_sector
inc bp
pass_mul_0A:
xor ah, ah
mov al, byte ptr [Decimal_Sector][bp]
sub al, 30h
add word ptr [Device_Displacement], ax
adc word ptr [Device_Section], 0
jc short loc_wrong_sector
mov al, byte ptr [Device_Displacement]
call proc_hex ; Binary to char converter
mov word ptr [Displacement_Str]+2, ax
mov al, byte ptr [Device_Displacement]+1
call proc_hex
mov word ptr [Displacement_Str], ax
mov al, byte ptr [Device_Section]
call proc_hex
mov word ptr [Section_Str]+2, ax
mov al, byte ptr [Device_Section]+1
call proc_hex
mov word ptr [Section_Str], ax
mov si, offset Msg_Disk_Reading_Address
call proc_printmsg
retn
loc_wrong_sector:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_sector
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
loc_show_device_reading_parameters:
mov si, offset nextline
call proc_printmsg
mov si, offset Device_Name_Label
call proc_printmsg
mov ah, "f"
mov al, byte ptr [Device_Number]
cmp al, 80h
jb short pass_dev_hd_num_fix
sub al, 80h
mov ah, "h"
pass_dev_hd_num_fix:
add al, 30h
mov byte ptr [Device_Name]+2, al
mov al, "d"
xchg ah, al
mov word ptr [Device_Name], ax
mov si, offset Device_Name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
mov si, offset Decimal_Sector_Label
call proc_printmsg
mov ax, word ptr [Device_Displacement]
mov dx, word ptr [Device_Section]
mov bp, 9
loc_dev_rediv_startsec:
mov cx, 10
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [Decimal_Sector][bp],bl
cmp bp,0
jz short loop_find_first_sec_numeral
dec bp
and ax, ax
jnz short loc_dev_rediv_startsec
and dx, dx
jnz short loc_dev_rediv_startsec
loc_dev_fspc_startsec:
mov byte ptr [Decimal_Sector][bp], 30h
cmp bp,0
jna short loop_find_first_sec_numeral
dec bp
jmp short loc_dev_fspc_startsec
loop_find_first_sec_numeral:
cmp byte ptr [Decimal_Sector][bp], 30h
ja short pass_find_first_sec_numeral
inc bp
cmp bp, 9
jb short loop_find_first_sec_numeral
pass_find_first_sec_numeral:
mov si, offset Decimal_Sector
add si, bp
call proc_printmsg
mov si, offset nextline
call proc_printmsg
mov si, offset Decimal_Sector_Count_Label
call proc_printmsg
mov ax, word ptr [Device_Sector_Count]
xor dx, dx
mov bp, 2
loc_dev_rediv_secount:
mov cx, 10
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [Decimal_Sector_Count][bp],bl
cmp bp,0
jz short loop_find_first_secount_numeral
dec bp
and ax, ax
jnz short loc_dev_rediv_secount
and dx, dx
jnz short loc_dev_rediv_secount
loc_dev_fspc_secount:
mov byte ptr [Decimal_Sector_Count][bp], 30h
cmp bp,0
jna short loop_find_first_secount_numeral
dec bp
jmp short loc_dev_fspc_secount
loop_find_first_secount_numeral:
cmp byte ptr [Decimal_Sector_Count][bp], 30h
ja short pass_find_first_secount_numeral
inc bp
cmp bp, 2
jb short loop_find_first_secount_numeral
pass_find_first_secount_numeral:
mov si, offset Decimal_Sector_Count
add si, bp
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_device:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Device
get_char_device:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_count
loop get_char_device
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_device_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'D'
jb short loop_scan_device_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_dev_name:
inc si
dec cx
jz loc_show_device_reading_parameters
cmp al,0Dh
jna loc_show_device_reading_parameters
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_dev_name
mov ax, word ptr [CommandBuffer][SI]
mov bx, word ptr [Device_Name]
and ax, 0DFDFh ; Capitalize
mov word ptr [Device_Name], 'df'
cmp ax, 'DF'
jz short pass_device_name
mov word ptr [Device_Name], 'dh'
cmp ax, 'DH'
jz short pass_device_name
loc_wrong_device_name:
mov word ptr [Device_Name], bx
mov si, offset nextline
call proc_printmsg
mov si, offset Msg_Wrong_Device_Name
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
pass_device_name:
mov ax, word ptr [CommandBuffer][SI]+2
cmp ah, 20h
jna short pass_3Ah_check
cmp ah, ':'
jne short loc_wrong_device_name
pass_3Ah_check:
cmp al, '0'
jb short loc_wrong_device_name
cmp al, '1'
ja short loc_wrong_device_name
mov byte ptr [Device_Name]+2, al
xor ah, ah
sub al, 30h
cmp byte ptr [Device_Name], "h"
jnz short pass_fix_dev_hd_num
add al, 80h
pass_fix_dev_hd_num:
mov byte ptr [Device_Number], al
call proc_hex
mov word ptr [Device_Number_Str], ax
mov si, offset nextline
call proc_printmsg
mov si, offset Device_Name_Label
call proc_printmsg
mov si, offset Device_Number_Str
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_count:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Count
get_char_count:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_read
loop get_char_count
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_count_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'C'
jb short loop_scan_count_word
add si, 5
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_sec_count:
inc si
dec cx
jz loc_show_device_reading_parameters
cmp al,0Dh
jna loc_show_device_reading_parameters
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_sec_count
xor bp, bp
jmp short start_scan_scount_value
loop_get_sec_count:
cmp al, 20h
jna short pass_get_sec_count
start_scan_scount_value:
cmp al, 30h ; 0
jb loc_wrong_count
cmp al, 39h ; 9
ja loc_wrong_count
mov byte ptr [Decimal_Sector_Count][bp], al
inc si
inc bp
cmp bp, 2
ja short check_last_secount_numeral
mov al, byte ptr [CommandBuffer][SI]
jmp short loop_get_sec_count
check_last_secount_numeral:
cmp byte ptr [CommandBuffer][SI], 20h
ja loc_wrong_count
pass_get_sec_count:
mov cx, 4
sub cx, bp
xor al, al
sec_count_reset_remain:
mov byte ptr [Decimal_Sector_Count][bp], al
inc bp
loop sec_count_reset_remain
mov cx, 3
mov bp, cx
loc_calculate_count_step:
dec bp
cmp byte ptr [Decimal_Sector_Count][bp], 30h
jnb short pass_loc_calculate_count_step
loop loc_calculate_count_step
pass_loc_calculate_count_step:
mov cx, bp
xor bp, bp
mov word ptr [Device_Sector_Count], 0
cmp cx, 1
jb short loc_count_mul_1
ja short loc_count_mul_64
jmp short loc_count_mul_0A
loc_count_mul_64:
mov ax, 64h ; AX = (100)hex
mov bl, byte ptr [Decimal_Sector_Count]
sub bl, 30h
mul bl
mov word ptr [Device_Sector_Count], ax
cmp ax, 200h
ja short loc_wrong_count
inc bp
loc_count_mul_0A:
mov ax, 0Ah ; AX = (10)hex
mov bl, byte ptr [Decimal_Sector_Count][bp]
sub bl, 30h
mul bl
add word ptr [Device_Sector_Count], ax
cmp word ptr [Device_Sector_Count], 200h
ja short loc_wrong_count
inc bp
loc_count_mul_1:
xor ah, ah
mov al, byte ptr [Decimal_Sector_Count][bp]
sub al, 30h
add word ptr [Device_Sector_Count], ax
cmp word ptr [Device_Sector_Count], 200h
ja short loc_wrong_count
mov al, byte ptr [Device_Sector_Count]
call proc_hex ; Binary to char converter
mov word ptr [Device_Sector_Count_Str]+2, ax
mov al, byte ptr [Device_Sector_Count]+1
call proc_hex
mov word ptr [Device_Sector_Count_Str], ax
mov si, offset nextline
call proc_printmsg
mov si, offset Decimal_Sector_Count_Label
call proc_printmsg
mov si, offset Device_Sector_Count_Str
call proc_printmsg
end_of_count:
mov si, offset nextline
call proc_printmsg
retn
loc_wrong_count:
mov word ptr [Device_Sector_Count], 1
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_count
call proc_printmsg
jmp short end_of_count
cmp_cmd_read:
inc byte ptr [CmdNo]
mov cx, 4
xor si, si
mov di, offset Cmd_Read
get_char_read:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_write
loop get_char_read
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
loc_read_device_sectors:
mov cx, word ptr [Device_Sector_Count]
and cx, cx
jz short end_of_read
mov dl, byte ptr [Device_Number]
cmp dl, 80h
jnb short pass_fd_big_sec_num_check
cmp word ptr [Device_Section], 0
je short pass_fd_big_sec_num_check
mov word ptr [Register_AX], 3030h
jmp short loc_device_read_failed
loc_read_drive_is_not_ready:
mov si, offset HdResetFailedMsg
call proc_printmsg
retn
pass_fd_big_sec_num_check:
mov es, word ptr [Start_Segment]
mov bx, word ptr [Start_Pointer]
xor dh, dh
mov cx, 1
mov ax, 0201h
int 13h
jc short loc_read_drive_is_not_ready
call proc_dparam
jc short loc_device_read_failed
jump_to_disk_read_from_find:
mov es, word ptr [Start_Segment]
mov bx, word ptr [Start_Pointer]
mov ax, word ptr [Device_Displacement]
mov dx, word ptr [Device_Section]
mov cx, word ptr [Device_Sector_Count]
loc_read_one_sector:
push cx
mov cx, 1
call proc_read
pop cx
jc short loc_device_read_failed
loop loc_read_one_sector
mov cx, word ptr [Device_Sector_Count]
mov ax, word ptr [bp][BytesPerSec]
mul cx
mov word ptr [Save_Size_L], ax
mov word ptr [Save_Size_H], dx
end_of_read:
retn
loc_device_read_failed:
mov al, byte ptr [Hex_Sign]+3
push ax
mov byte ptr [Hex_Sign]+3, 0
mov si, offset trfailedmsg
call proc_printmsg
pop ax
mov byte ptr [Hex_Sign]+3, al
retn
cmp_cmd_write:
inc byte ptr [CmdNo]
mov cx, 5
xor si, si
mov di, offset Cmd_Write
get_char_write:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_edit
loop get_char_write
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
loc_write_device_sectors:
mov cx, word ptr [Device_Sector_Count]
and cx, cx
jz short end_of_write
mov dl, byte ptr [Device_Number]
cmp dl, 80h
jnb short pass_w_fd_big_sec_num_check
cmp word ptr [Device_Section], 0
je short pass_w_fd_big_sec_num_check
mov word ptr [Register_AX], 3030h
jmp short loc_device_read_failed
pass_w_fd_big_sec_num_check:
xor dh, dh
mov cx, 1
mov ax, 0401h ; Verify disk sectors
int 13h
jc loc_read_drive_is_not_ready
call proc_dparam
jc short loc_device_read_failed
mov si, offset msg_warning
call proc_printmsg
mov ax, 0E07h ; Beep sound
mov bx, 07h
int 10h
mov si, msg_ask_for_overwrite
call proc_printmsg
mov si, offset Device_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_write_yes_no
cmp al, 'n'
jz short loc_write_yes_no
cmp al, 1Bh
jz short return_from_write
cmp al, 'Y'
jz short loc_write_yes_no
cmp al, 'y'
jz short loc_write_yes_no
cmp al, 0Dh
jz short loc_write_status
jmp short loop_get_char
loc_write_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short loop_get_char
end_of_write:
retn
loc_write_status:
cmp byte ptr [Char_Input], 'N'
jb short loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
jb short return_from_write
mov es, word ptr [Start_Segment]
mov bx, word ptr [Start_Pointer]
mov ax, word ptr [Device_Displacement]
mov dx, word ptr [Device_Section]
mov cx, word ptr [Device_Sector_Count]
loc_write_one_sector:
push cx
mov cx, 1
call proc_write
pop cx
jc loc_device_read_failed
loop loc_write_one_sector
return_from_write:
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_edit:
inc byte ptr [CmdNo]
mov cx, 4
xor si, si
mov di, offset Cmd_Edit
get_char_edit:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_volume
loop get_char_edit
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
start_edit_write_char:
mov es, word ptr [Start_Segment]
mov bp, word ptr [Start_Pointer]
mov cx, 25
push cx
loop_edit_write_char:
mov si, offset nextline
call proc_printmsg
pop cx
dec cx
and cx, cx
jz pass_edit_write_char
push cx
mov cx, 78
mov ax, es
xchg ah,al
call proc_hex
push ax
mov ah, 0Eh
mov bx, 07h
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov ax, es
call proc_hex
push ax
mov ah, 0Eh
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov al, 'h'
int 10h
mov al, ':'
int 10h
mov ax,bp
xchg ah,al
call proc_hex
push ax
mov ah, 0Eh
mov bx, 07h
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov ax, bp
call proc_hex
push ax
mov ah, 0Eh
int 10h
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
mov al, 'h'
int 10h
mov al, 20h
int 10h
mov al, 20h
int 10h
sub cx, 13
push es
push bp
loc_repeat_edit_write:
mov al, byte ptr ES:[BP]
call proc_hex
push ax
mov ah, 0Eh
int 10h
dec cx
pop ax
xchg ah, al
mov ah, 0Eh
int 10h
dec cx
mov al, 20h
int 10h
inc bp
jnz short pass_edit_update_es
mov bp,es
add bp,1000h
mov es,bp
xor bp,bp
pass_edit_update_es:
dec cx
cmp cx, 12h
jnb short loc_repeat_edit_write
mov al, 20h
int 10h
mov cx, 10h
mov di, es
pop si ; pushed bp
pop es
loop_edit_byte_write:
push cx
mov al, byte ptr ES:[SI]
mov ah, 0Ah
; mov bx, 07h
mov cx, 1
int 10h
mov ah, 03h
int 10h
inc dl
mov ah, 02h
int 10h
pop cx
inc si
jnz short pass_update_edit_byte_es
mov si,es
add si,1000h
mov es,si
xor si,si
pass_update_edit_byte_es:
dec cx
jnz short loop_edit_byte_write
mov es, di
jmp loop_edit_write_char
pass_edit_write_char:
push ds
pop es
mov si, offset msg_hex_edit
call proc_printmsg
mov ah, 02h ; Set Cursor Position
mov bx, 07h
mov dx, 0Dh
int 10h
pass_update_cursor_position:
xor ah, ah
int 16h
cmp al, 0
jz edit_arrow_keys
cmp al, 0E0h
jz edit_arrow_keys
cmp al, 20h
jnz pass_space_arrow_conv
mov ah, 4Dh
jmp edit_arrow_keys
pass_space_arrow_conv:
cmp al, 1Bh
jz return_from_edit
cmp al, 0Dh
jz loc_update_bytes
push ax
mov ah, 08h
int 10h
pop cx
cmp al, 30h
jb short pass_update_cursor_position
cmp cl, "0"
jb short pass_update_cursor_position
cmp cl, "9"
jna short pass_edit_capitalize
cmp cl, "f"
ja short pass_update_cursor_position
and cl, 0DFh
cmp cl, "F"
ja short pass_update_cursor_position
cmp cl, "A"
jb short pass_update_cursor_position
pass_edit_capitalize:
mov al, cl
mov ah, 09h ; Write Character or Attribute
mov cx, 1 ; Cursor position is not changed
int 10h ; CX = Number of Repetitions
push ax
mov ah, 03h ; Return Cursor Position
int 10h
xor ah, ah
mov al, dl
sub al, 0Ch ; Position of the most left column
mov cl, 3
div cl
pop cx
sub cl, 30h
cmp cl, 9
jna short pass_edit_1_hex_correct
sub cl, 7
pass_edit_1_hex_correct:
push ax
cmp ah, 2
je short pass_locate_next_column
mov al, 10h
mul cl
push ax
inc dl
mov ah, 02h ; Set Cursor Position
int 10h
mov ah, 08h ; Return Character or Attribute
int 10h
dec dl
mov ah, 02h
int 10h
sub al, 30h
cmp al, 9
jna short pass_edit_2_hex_correct
sub al, 7
pass_edit_2_hex_correct:
pop cx
add al, cl
pop cx
push dx
mov dl, 62
add dl, cl
mov ah, 02h
int 10h
mov ah, 09h
mov cx, 1
int 10h
pop dx
mov ah, 02h
int 10h
jmp pass_update_cursor_position
pass_locate_next_column:
push cx
dec dl
mov ah, 02h ; Set Cursor Position
int 10h
mov ah, 08h ; Return Character or Attribute
int 10h
inc dl
mov ah, 02h
int 10h
mov cl, 10h
mul cl
pop cx
add al, cl
pop cx
push dx
mov dl, 62
add dl, cl
mov ah, 02h
int 10h
mov ah, 09h
mov cx, 1
int 10h
pop dx
mov ah, 02h
int 10h
jmp pass_update_cursor_position
return_from_edit:
mov ah, 02 ; Set Cursor Position
; mov bx, 07 ; BH = Video page
mov dx, 184Fh ; DH = Line # , DL = Column #
int 10h
mov si, offset nextline
call proc_printmsg
retn
edit_arrow_keys:
mov al, ah
mov ah, 03h ; Return Cursor Position
int 10h
cmp al, 4Dh
jnz short pass_edit_arrow_right
cmp dl, 59
jnb pass_update_cursor_position
inc dl
mov ah, 02h
int 10h
mov ah, 08h
int 10h
cmp al, 20h
jne short pass_edit_arrow_up
inc dl
jmp short pass_edit_arrow_up
pass_edit_arrow_right:
cmp al, 4Bh
jnz short pass_edit_arrow_left
cmp dl, 13
jna pass_update_cursor_position
dec dl
mov ah, 02h
int 10h
mov ah, 08h
int 10h
cmp al, 20h
jne short pass_edit_arrow_up
dec dl
jmp short pass_edit_arrow_up
pass_edit_arrow_left:
cmp al, 50h
jnz short pass_edit_arrow_down
cmp dh, 23
jnb pass_update_cursor_position
inc dh
jmp short pass_edit_arrow_up
pass_edit_arrow_down:
cmp al, 48h
jnz pass_update_cursor_position
cmp dh, 0
jna pass_update_cursor_position
dec dh
pass_edit_arrow_up:
mov ah, 02h
int 10h
jmp pass_update_cursor_position
loc_update_bytes:
push dx
push es
xor dh, dh
mov es, word ptr [Start_Segment]
mov si, word ptr [Start_Pointer]
mov cx, 24
loc_loop_edit_update_1:
push cx
mov cx, 16
mov dl, 0Dh
loc_loop_edit_update_2:
mov ah, 02h
int 10h
mov ah, 08h
int 10h
sub al, 30h
cmp al, 9
jna short pass_edit_3_hex_correct
sub al, 7
pass_edit_3_hex_correct:
mov bl, 10h
mul bl
push ax
inc dl
mov ah, 02h
mov bx, 07h
int 10h
mov ah, 08h
int 10h
mov bl, al
sub bl, 30h
cmp bl, 9
jna short pass_edit_4_hex_correct
sub bl, 7
pass_edit_4_hex_correct:
pop ax
add al, bl
mov byte ptr ES:[SI], al
mov bp, es
add si, 1
adc bp, 0
mov es, bp
inc dl
inc dl
loop loc_loop_edit_update_2
inc dh
pop cx
loop loc_loop_edit_update_1
mov bx, 07h
mov cl, 10h
mov dx, 183Eh
mov ah, 02h
int 10h
mov ah, 08h
int 10h
mov ah, "*"
cmp al, "*"
jne short pass_edit_fill_space
mov ah, 20h
pass_edit_fill_space:
mov al, ah
mov ah, 09h
mov cx, 10h
int 10h
pop es
pop dx
mov ah, 02h
int 10h
jmp pass_update_cursor_position
cmp_cmd_volume:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Volume
get_char_volume:
mov al, byte ptr [CommandBuffer]+[SI]
inc si
scasb
jne cmp_cmd_save
loop get_char_volume
mov al, byte ptr [CommandBuffer]+[SI]
cmp al,20h
ja loc_cmd_failed
mov bp, 7C00h
xor si, si
mov di, offset Disk_Name
mov cx, 11
loc_move_volume_label:
mov al, byte ptr [SI][bp][VolumeLabel]
mov byte ptr [DI], al
inc si
inc di
loop loc_move_volume_label
mov byte ptr [DI], 0
mov di, offset Disk_Serial
mov ax, word ptr [bp][VolumeId]+2
push ax
xchg ah,al
call proc_hex
mov word ptr [DI], ax
pop ax
call proc_hex
mov word ptr [DI]+2, ax
mov byte ptr [DI]+4, '-'
mov ax, word ptr [bp][VolumeID]
push ax
xchg ah,al
call proc_hex
mov word ptr [DI]+5, ax
pop ax
call proc_hex
mov word ptr [DI]+7, ax
mov si, offset Msg_VolumeLabel
call proc_printmsg
mov si, offset Msg_VolumeID
call proc_printmsg
mov si, offset nextline
call proc_printmsg
mov ax, word ptr [bp][Sectors]
and ax, ax
jnz short loc_volume_fat12
call proc_get_fspace_fat16
jmp short loc_convert_fspace_to_decimal
loc_volume_fat12:
call proc_get_fspace_fat12
loc_convert_fspace_to_decimal:
cmp word ptr [Counter], 200h
jb short pass_convert_fspace_byte
call proc_mul32 ; Input -> DX_AX = Free Sectors
; Output -> DX_AX in Bytes
pass_convert_fspace_byte:
mov bp, 10
mov cx, 10
loc_rediv_fspace_sectors:
call Rx_Dos_Div32
add bl, '0'
mov byte ptr [FreeSpace][bp], bl
dec bp
and ax, ax
jnz short loc_rediv_fspace_sectors
and dx, dx
jnz short loc_rediv_fspace_sectors
loc_fill_space_on_freespace_str:
mov byte ptr [FreeSpace][bp], 20h
cmp bp, 0
jna short pass_fill_space_on_freespace_str
dec bp
jmp short loc_fill_space_on_freespace_str
pass_fill_space_on_freespace_str:
mov si, offset Msg_FreeSpace
call proc_printmsg
mov si, offset FreeSpace
mov cx, 11
loc_erase_space:
cmp byte ptr [SI], 20h
jne short pass_loc_erase_space
inc si
loop loc_erase_space
pass_loc_erase_space:
call proc_printmsg
cmp word ptr [Counter], 200h
jb short pass_write_freespace_as_bytes
mov si, offset Msg_Bytes
call proc_printmsg
jmp short return_from_volume
pass_write_freespace_as_bytes:
mov si, offset Msg_Sectors
call proc_printmsg
return_from_volume:
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_save:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Save
get_char_save:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_erase
loop get_char_save
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov ax, word ptr [Save_Size_L]
or ax, word ptr [Save_Size_H]
jz loc_wrong_size
mov si, 6
loop_scan_save_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'S'
jb short loop_scan_save_word
add si, 4
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_save_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_save_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_save_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short s_scan_file_name
cmp al,20h
jna short save_no_extension_of_filename
dec cx
jnz short loop_save_dot_control
cmp al,2Eh
jne loc_load_wrong_filename
s_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp ah, 2Eh
jz loc_load_wrong_filename
save_no_extension_of_filename:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_s_scan_movsb:
movsb
dec cx
jz short pass_s_scan_file_name
cmp byte ptr [SI],21h
jnb short loop_s_scan_movsb
mov byte ptr ES:[DI],0
xor si, si
loop_s_scan_invfn_o:
mov cx, sizeInvFnChars
mov al, byte ptr [S_File_Name][SI]
cmp al, 21h
jb short pass_s_scan_file_name
cmp al, 'z'
ja short loc_save_wrong_filename
mov di, offset invalid_fname_chars
loop_s_scan_invfn_i:
scasb
je short loc_save_wrong_filename
loop loop_s_scan_invfn_i
inc si
cmp si, 12
jna short loop_s_scan_invfn_o
jmp short pass_s_scan_file_name
loc_save_wrong_filename:
push si
jmp loc_load_wrong_filename
invalid_fname_chars:
db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
db 5Bh, 5Ch, 5Dh, 5Eh, 60h
sizeInvFnChars equ ($ - invalid_fname_chars)
pass_s_scan_file_name:
mov word ptr [Register_AX], 3030h
call proc_fat_load ; FAT buffer refresh for
jc loc_failed ; safety
mov cx, word ptr [Clust_Of_Dir] ; Cluster # of current dir.
cmp cx, 2
jnb short loc_reload_sub_dir
call proc_loadrootdir ; Directory refresh for
jc loc_failed ; safety
jmp short loc_save_locate_file
loc_reload_sub_dir:
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_save_locate_file:
mov si, offset nextline
call proc_printmsg
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file ; output -> cx
; = dir_entry offset of the file
mov word ptr [DirEntries], cx
jnc short pass_save_dir_control
cmp bl, 0
jna short pass_loc_dir_exist
loc_save_dir_exist:
mov si, offset msg_dir_exist
call proc_printmsg
jmp short loc_cancel_save
pass_loc_dir_exist:
and cx, cx
jnz short pass_loc_no_space
; CX = File's dir entry pointer
mov si, offset msg_no_space_dir
call proc_printmsg
jmp short loc_cancel_save
; CX = File's dir entry pointer
pass_loc_no_space:
push ES
mov di, 7000h
mov es, di
xor di, di
repeat_e5h_location_check:
cmp byte ptr ES:[DI], 0E5h ; Locate new file entry
; on erased entry.
jz short pass_e5h_loop
add di, 20h
sub cx, 20h
ja short repeat_e5h_location_check
mov di, word ptr [DirEntries]
jmp short pass_replace_entry_pointer
pass_e5h_loop:
mov word ptr [DirEntries], di
pass_replace_entry_pointer:
mov cx, 11
mov si, offset Dir_File_Name
rep movsb ; DS:SI -> ES:DI
pop ES
jmp short pass_save_file_attr_check
pass_save_dir_control:
and byte ptr [File_A_Byte], 07h ; Attributes
jnz short loc_permission_denied
pass_save_file_attr_check:
mov ax, word ptr [bp][Sectors]
and ax, ax
jnz short scan_s_fat12_fspace
call proc_get_fspace_fat16
; Result : DX_AX = Free sectors , BX = Bytes per Sector
jmp short compare_fspace_fsize
loc_permission_denied:
mov si, offset Msg_Permission_Denied
call proc_printmsg
loc_cancel_save:
mov si, offset nextline
call proc_printmsg
retn
scan_s_fat12_fspace:
call proc_get_fspace_fat12
; Result : AX = Free sectors , BX = Bytes per Sector
compare_fspace_fsize:
mov cx, bx
cmp word ptr [File_FClust], 2
jb short pass_get_overwrite_freespace
push dx
push ax
mov ax, word ptr [File_Size_L]
mov dx, word ptr [File_Size_H]
add ax, cx
adc dx, 0
sub ax, 1
sbb dx, 0
call Rx_Dos_Div32
pop bx ; It was AX (Low word of File Size)
add ax, bx
pop bx ; It was DX (High word of File Size)
adc dx, bx
pass_get_overwrite_freespace:
and dx, dx
jnz short pass_freespace_check_for_save
push ax
mov ax, word ptr [Save_Size_L]
mov dx, word ptr [Save_Size_H]
add ax, cx
adc dx, 0
sub ax, 1
sbb dx, 0
call Rx_Dos_Div32
pop bx
sub bx, ax
jc short no_enough_freespace
pass_freespace_check_for_save:
cmp word ptr [File_FClust], 1
ja short loc_save_overwrite
mov si, offset msg_saveas
jmp short loc_start_save_msg
loc_save_overwrite:
mov si, offset msg_file_overwrite
loc_start_save_msg:
call proc_printmsg
mov si, offset Drive_Name
push si
mov byte ptr [SI]+3,0
call proc_printmsg
pop si
mov byte ptr [SI]+3, 0Dh
mov al, ':'
; mov ah, 0Eh
; mov bx, 07h
int 10h
mov al, '/'
int 10h
mov si, offset Current_Dir
call proc_printmsg
cmp byte ptr [Current_Dir], 21h
jb short pass_add_slash
mov al, '/'
int 10h
pass_add_slash:
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
save_loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_save_yes_no
cmp al, 'n'
jz short loc_save_yes_no
cmp al, 1Bh
jz short return_from_save
cmp al, 'Y'
jz short loc_save_yes_no
cmp al, 'y'
jz short loc_save_yes_no
cmp al, 0Dh
jz short loc_save_status
jmp short save_loop_get_char
no_enough_freespace:
mov si, offset msg_no_enough_space
call proc_printmsg
jmp short return_from_save
loc_save_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short save_loop_get_char
loc_save_status:
cmp byte ptr [Char_Input], 'N'
jb short save_loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
jb short return_from_save
mov si, offset nextline
call proc_printmsg
call proc_reset_file_clusters
mov cx, word ptr [Number_Of_Clusts]
call proc_find_first_free_clust ; output -> BX =
; first free cluster
cmp bx, 2
jnb short pass_loc_ffc_error
call proc_fat_load
jc loc_failed
jmp no_enough_freespace
return_from_save:
mov si, offset nextline
call proc_printmsg
retn
pass_loc_ffc_error:
mov ax, 7000h
mov es, ax
mov si, word ptr [DirEntries] ; File Entry Num
mov word ptr ES:[SI]+1Ah, bx ; First cluster
mov word ptr [File_FClust], bx
mov ax, word ptr [Save_Size_L]
mov dx, word ptr [Save_Size_H]
mov word ptr ES:[SI]+1Ch, ax ; File Size L
mov word ptr ES:[SI]+1Eh, dx ; File Size H
push ax
push dx
mov cx, word ptr [bp][BytesPerSec]
mov al, byte ptr [bp][SecPerClust] ; Max. 64 for MS-DOS
; Max. 128 for TR-DOS
xor ah, ah
mul cx
mov cx, ax
pop dx
pop ax
add ax, cx
adc dx, 0
sub ax, 1
sbb dx, 0
call Rx_Dos_Div32
mov cx, ax ; DX ignored ! (Maximum size !)
call proc_allocate_clusters ; Input -> cx = number of
; clusters to be allocated.
; Input -> [File_FClust] =
; First cluster of the file.
and cx, cx
jz short pass_c_allocation_error
call proc_fat_load
jc loc_failed
jmp no_enough_freespace
pass_c_allocation_error:
mov ah, 04h ; Return current date
int 1Ah
; CF = 1 -> Clock has stopped running.
; CH = Century in BCD
; CL = Year in BCD
; DH = Month in BCD
; DL = Day in BCD
mov al, ch
call proc_bcd_to_binary
mov ch, al
mov al, cl
call proc_bcd_to_binary
mov cl, al
mov al, dh
call proc_bcd_to_binary
mov dh, al
mov al, dl
call proc_bcd_to_binary
mov dl, al
xor bx, bx
sub ch, 19
jb short pass_adjust_date
mov al, 100
mul ch
add al, cl
sub al, 80 ; Number of years since 1980.
jb short pass_adjust_date
mov cl, 4
shl ax, cl
or al, dh ; Month
mov cl, 5
shl ax, cl
or al, dl ; Day
mov bx, ax ; Date
pass_adjust_date:
mov ah, 02h ; Return current time
int 1Ah
; CF = 1 -> Clock has stopped running.
; CH = Number of Hours in BCD
; CL = Minutes in BCD
; DH = Seconds in BCD
; DL = 00h -> Standard time
; 01h -> Daylight saving time
mov al, ch
call proc_bcd_to_binary
mov ch, al
mov al, cl
call proc_bcd_to_binary
mov dl, al
mov al, dh
call proc_bcd_to_binary
mov dh, al
mov al, ch ; Hours
; mov dl, cl
mov cl, 6
shl ax, cl
or al, dl ; Minutes
mov cl,5
shl ax, cl
shr dh, 1 ; Two seconds interval
or al, dh
mov dx, ax
mov ax, 7000h
mov es, ax
xor ax, ax
mov di, word ptr [DirEntries] ; File Entry Num
add di, 11
mov cl, byte ptr [Attributes]
mov byte ptr ES:[DI], cl
inc di
mov cx, 5
rep stosw
mov word ptr ES:[DI], dx ; Time
mov word ptr ES:[DI]+2, bx ; Date
mov cx, word ptr [bp][BytesPerSec]
mov al, byte ptr [bp][SecPerClust] ; Max. 64 for MS-DOS
; Max. 128 for TR-DOS
xor ah, ah
mul cx
mov cx, ax
mov ax, word ptr [Save_Size_L]
mov dx, word ptr [Save_Size_H]
add ax, cx
adc dx, 0
sub ax, 1
sbb dx, 0
call Rx_Dos_Div32
mov word ptr [Counter], ax ; File size
; in clusters
mov es, word ptr [Start_Segment]
mov bx, word ptr [Start_Pointer]
mov cx, word ptr [File_FClust]
call proc_file_write
jc loc_failed
cmp word ptr [Clust_Of_Dir], 0
jna short loc_save_root_dir
loc_save_sub_dir: ; NOTE: Number of clusters will be fixed for new entries.
mov bx, 7000h
mov es, bx
xor bx, bx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov cx, word ptr [Clust_Of_Dir]
call proc_file_write
jc loc_failed
jmp short loc_save_FATs
loc_save_root_dir:
call proc_save_root_dir
jc loc_failed
loc_save_FATs:
call proc_save_FATs
jc loc_failed
mov si, offset Msg_File_Done
call proc_printmsg
jmp return_from_save
cmp_cmd_erase:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Erase
get_char_erase:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_cluster
loop get_char_erase
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_erase_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'E'
jb short loop_scan_erase_word
add si, 5
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_erase_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_erase_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_erase_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short e_scan_file_name
cmp al,20h
jna short erase_no_extension_of_filename
dec cx
jnz short loop_erase_dot_control
cmp al,2Eh
jne loc_load_wrong_filename
e_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp ah, 2Eh
jz loc_load_wrong_filename
erase_no_extension_of_filename:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_e_scan_movsb:
movsb
dec cx
jz short pass_e_scan_file_name
cmp byte ptr [SI],21h
jnb short loop_e_scan_movsb
mov byte ptr ES:[DI],0
pass_e_scan_file_name:
mov word ptr [Register_AX], 3030h
mov bp, 7C00h ; bp must point start of boot sector
mov cx, word ptr [Clust_Of_Dir] ; Cluster # of current dir.
cmp cx, 2
jnb short pass_erase_reload_root_dir
call proc_loadrootdir
jc loc_failed
jmp short loc_erase_locate_file
pass_erase_reload_root_dir:
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_erase_locate_file:
mov si, offset nextline
call proc_printmsg
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file
jc loc_start_file_notfound
; CX = File's dir entry pointer ; CX = File's dir entry pointer
and byte ptr [File_A_Byte], 07h ; Attributes
jnz loc_permission_denied
mov word ptr [DirEntries], cx
mov si, offset msg_file_erase
call proc_printmsg
mov si, offset Drive_Name
push si
mov byte ptr [SI]+3,0
call proc_printmsg
pop si
mov byte ptr [SI]+3, 0Dh
mov al, ':'
; mov ah, 0Eh
; mov bx, 07h
int 10h
mov al, '/'
int 10h
mov si, offset Current_Dir
call proc_printmsg
cmp byte ptr [Current_Dir], 21h
jb short pass_erase_add_slash
mov al, '/'
int 10h
pass_erase_add_slash:
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
erase_loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_erase_yes_no
cmp al, 'n'
jz short loc_erase_yes_no
cmp al, 1Bh
jz return_from_save
cmp al, 'Y'
jz short loc_erase_yes_no
cmp al, 'y'
jz short loc_erase_yes_no
cmp al, 0Dh
jz short loc_erase_status
jmp short erase_loop_get_char
loc_erase_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short erase_loop_get_char
loc_erase_status:
cmp byte ptr [Char_Input], 'N'
jb short erase_loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
jb return_from_save
mov si, offset nextline
call proc_printmsg
call proc_fat_load
jc loc_failed
call proc_reset_file_clusters
mov ax, 7000h
mov es, ax
mov si, word ptr [DirEntries] ; File Entry Num
mov word ptr ES:[SI], 0E5h ; Erased file sign
cmp word ptr [Clust_Of_Dir], 0
jna loc_save_root_dir
jmp loc_save_sub_dir
cmp_cmd_cluster:
inc byte ptr [CmdNo]
mov cx,7
xor si,si
mov di, offset Cmd_Cluster
get_char_cluster:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_info
loop get_char_cluster
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_cluster_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'C'
jb short loop_scan_cluster_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_cluster_addr:
inc si
dec cx
jz short pass_cluster_addr
cmp al,0Dh
jna short pass_cluster_addr
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_cluster_addr
mov cl,4
xor di,di
loop_get_cluster_addr:
cmp al, 30h ; 0
jb short loc_wrong_cluster
cmp al, 39h ; 9
jna short pass_cluster_capitalize
cmp al, 41h ; A
jb short loc_wrong_cluster
cmp al, 46h ; F
jna short pass_cluster_capitalize
cmp al, 61h ; a
jb short loc_wrong_cluster
cmp al, 66h ; f
ja short loc_wrong_cluster
and al, 0DFh
pass_cluster_capitalize:
mov byte ptr [Cluster_addr][DI], al
inc si
mov al, byte ptr [CommandBuffer][SI]
inc di
dec cl
jnz short loop_get_cluster_addr
cmp al, 20h
jna short pass_cluster_h_control
and al, 0DFh
cmp al, 'H'
jnz short loc_wrong_cluster
pass_cluster_h_control:
mov dx, word ptr [Cluster_addr]
mov ax, word ptr [Cluster_addr]+2
call proc_binary ; Char to Binary converter
mov word ptr [Cluster], ax
pass_cluster_addr:
mov si, offset nextline
call proc_printmsg
mov bp, 7C00h
mov ax, word ptr [bp][Sectors]
and ax, ax
jnz short pass_get_fat16_noc
call proc_get_fspace_fat16
jmp short pass_get_fat12_noc
loc_wrong_cluster:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_cluster
call proc_printmsg
pass_find_fat16_next_cluster:
mov word ptr [Cluster],0
end_of_clust:
mov si, offset nextline
call proc_printmsg
retn
pass_get_fat16_noc:
call proc_get_fspace_fat12
pass_get_fat12_noc:
mov ax, word ptr [Cluster]
cmp ax, 2
jb get_ff_cluster
cmp ax, word ptr [Number_Of_Clusts]
ja get_ff_cluster
loc_show_next_cluster:
call proc_hex ; Binary to char converter
mov word ptr [Cluster_addr]+2, ax
mov al, byte ptr [Cluster]+1
call proc_hex
mov word ptr [Cluster_addr], ax
mov si, offset str_cluster
call proc_printmsg
xor ch,ch
mov ax, word ptr [Cluster]
dec ax
dec ax
mov cl, byte ptr [bp][SecPerClust]
mul cx
add ax, word ptr [bp][DataArea1]
adc dx, word ptr [bp][DataArea2]
mov di,9
loc_clust_rediv_startsec:
mov cx,10
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [Decimal_Sector][DI],bl
cmp di,0
jz short loop_find_cl_first_sec_numeral
dec di
and ax, ax
jnz short loc_clust_rediv_startsec
and dx, dx
jnz short loc_clust_rediv_startsec
loc_clust_fspc_startsec:
mov byte ptr [Decimal_Sector][DI],30h
cmp di,0
jna short loop_find_cl_first_sec_numeral
dec di
jmp short loc_clust_fspc_startsec
loop_find_cl_first_sec_numeral:
cmp byte ptr [Decimal_Sector][DI],30h
ja short pass_find_cl_first_sec_numeral
inc di
cmp di,9
jb short loop_find_cl_first_sec_numeral
pass_find_cl_first_sec_numeral:
mov si, offset Triple_Space
call proc_printmsg
mov si, offset Decimal_Sector_Label
call proc_printmsg
mov si, offset Decimal_Sector
call proc_printmsg
mov si, word ptr [Cluster]
cmp word ptr [bp][Sectors],0
ja short find_fat12_next_cluster
mov ax, 8000h
mov es, ax
; cmp word ptr [Cluster],0FFF0h
; jnb short pass_find_fat16_next_cluster
add si, si
jnc short pass_cl_update_es
mov ax, 9000h
mov es, ax
pass_cl_update_es:
mov ax, word ptr ES:[SI]
jmp short pass_find_fat12_next_cluster
find_fat12_next_cluster:
; cmp word ptr [Cluster],0FF0h
; jnb short pass_find_fat16_next_cluster
mov ax, si
add si, si
add si, ax
shr si, 1
mov ax, word ptr ES:[SI]
jnc short cluster_num_even
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
cluster_num_even:
and ah, 0Fh
pass_find_fat12_next_cluster:
mov word ptr [Cluster], ax
call proc_hex
mov word ptr [Cluster_addr]+2, ax
mov al, byte ptr [Cluster]+1
call proc_hex
mov word ptr [Cluster_addr], ax
mov si, offset Triple_Space
call proc_printmsg
mov si, offset str_next
call proc_printmsg
mov si, offset str_cluster
call proc_printmsg
xor ah,ah
int 16h
cmp al, 1Bh
je end_of_clust
mov ax, word ptr [Cluster]
cmp ax, word ptr [Number_Of_Clusts]
ja pass_find_fat16_next_cluster
cmp ax, 2
jb pass_find_fat16_next_cluster
push ax
mov si, offset nextline
call proc_printmsg
pop ax
jmp loc_show_next_cluster
get_ff_cluster:
mov al, byte ptr [Number_Of_Clusts]
call proc_hex
mov word ptr [Cluster_addr]+2, ax
mov al, byte ptr [Number_Of_Clusts]+1
call proc_hex
mov word ptr [Cluster_addr], ax
mov si, offset msg_number_of_clust
call proc_printmsg
mov si, offset Cluster_addr
call proc_printmsg
mov si, offset nextline
call proc_printmsg
; mov cx, word ptr [Number_of_Clusts]
call proc_find_first_free_clust
mov word ptr [Cluster], bx
mov al, bl
call proc_hex
mov word ptr [Cluster_Addr]+2,ax
mov al, bh
call proc_hex
mov word ptr [Cluster_Addr], ax
mov si, offset str_firstfree
call proc_printmsg
mov si, offset str_cluster
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_info:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Info
get_char_info:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_find
loop get_char_info
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_info_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'I'
jb short loop_scan_info_word
add si, 4
mov cx, 60
sub cx, si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_info_filename:
inc si
dec cx
jz loc_drive_info
cmp al,0Dh
jna loc_drive_info
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_info_filename
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_info_scan_movsb:
movsb
dec cx
jz short pass_info_scan_file_name
cmp byte ptr [SI],21h
jnb short loop_info_scan_movsb
mov byte ptr ES:[DI],0
pass_info_scan_file_name:
mov si, offset S_File_Name
call proc_convert_file_name
mov si, offset nextline
call proc_printmsg
call proc_find_file
; CX, DI = Dir entry offset
; BX = First cluster of the file
; or (BL) directory attributes
and bx, bx
jz loc_start_file_notfound
mov si, 7000h
add di, 20h ; Dir entry offset + 32
mov es, si
mov si, word ptr ES:[DI]
push di
push si
mov si, offset end_of_info
push si ; Return address/offset (for "retn")
mov word ptr ES:[DI], 0
mov si, cx ; Dir entry offset
mov cx, 1
jmp jump_from_file_info ; jump into proc "print_directory"
end_of_info:
mov si, 7000h
mov es, si
pop si
pop di
mov word ptr ES:[DI], si
mov ax, word ptr [File_FClust]
mov word ptr [Cluster], ax
call proc_hex
mov word ptr [Cluster_Addr]+2, ax
mov al, byte ptr [Cluster]+1
call proc_hex
mov word ptr [Cluster_Addr], ax
mov si, offset str_first_cluster
call proc_printmsg
jmp return_from_info
loc_drive_info:
mov ax, word ptr [Drive_Name]
mov word ptr [str_info_drv_name], ax
mov al, byte ptr [Drive_Num]
mov byte ptr [str_info_drv_name]+2, al
mov si, 7C03h
mov di, offset str_oemname
mov cx, 4
rep movsw
mov cx, 8
mov di, offset str_oemname
loop_scan_str_oemname:
cmp byte ptr [DI], 0
jne short pass_i_str_oemname
mov byte ptr [DI], 20h
pass_i_str_oemname:
inc di
loop loop_scan_str_oemname
mov si, 7C0Bh
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_bytespersec]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_bytespersec], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_secperclust], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_ressectors]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_ressectors], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_fats], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_rootdirents]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_rootdirents], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_sectors]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_sectors], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_media], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_fatsecs]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_fatsecs], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_secpertrack]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_secpertrack], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_heads]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_heads], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_hidden1]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_hidden1], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_hidden2]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_hidden2], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_hugesec1]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_hugesec1], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_hugesec2]+2, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_hugesec2], ax
add si, 2
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_drivenumber], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_reserved1], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_bootsignature], ax
inc si
mov al, byte ptr [SI]
call proc_hex
mov word ptr [val_volumeid]+6, ax
mov al, byte ptr [SI]+1
call proc_hex
mov word ptr [val_volumeid]+4, ax
mov al, byte ptr [SI]+2
call proc_hex
mov word ptr [val_volumeid]+2, ax
mov al, byte ptr [SI]+3
call proc_hex
mov word ptr [val_volumeid], ax
add si, 4
mov di, offset str_volumelabel
mov cx, 11
rep movsb
mov cx, 4
mov di, offset str_filesystype
rep movsw
mov cx, 19
mov di, offset str_volumelabel
loop_scan_str_volumelabel:
cmp byte ptr [DI], 0
jne short pass_i_str_volumelabel
mov byte ptr [DI], 20h
pass_i_str_volumelabel:
inc di
loop loop_scan_str_volumelabel
mov si, offset msg_drive_info
call proc_printmsg
return_from_info:
mov si, offset nextline
call proc_printmsg
end_of_find_info:
retn
cmp_cmd_find:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Find
get_char_find:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_size
loop get_char_find
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_find_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'F'
jb short loop_scan_find_word
add si, 4
mov cx, 60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_find_parameter:
inc si
dec cx
jz short end_of_find_info
cmp al, 0Dh
jna short end_of_find_info
mov ax, word ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_find_parameter
cmp al, '-'
jnz pass_disk_binary_check
cmp ah, 'b'
jnz pass_disk_binary_check
add si, 2
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jnz loc_wrong_parameter
search_first_binary_char:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja short loc_get_binary_number
cmp al, 0Dh
jz loc_wrong_parameter
loop search_first_binary_char
jmp short end_of_find_info
loc_get_binary_number:
mov word ptr [Counter], si
repeat_check_binary_chars:
cmp al, '0'
jb loc_wrong_parameter
cmp al, '9'
jna short pass_alfanumeral_check
cmp al, 'f'
ja loc_wrong_parameter
and al, 0DFh
cmp al, 'F'
ja loc_wrong_parameter
cmp al, 'A'
jb loc_wrong_parameter
mov byte ptr [CommandBuffer][SI], al ; Capitalize
pass_alfanumeral_check:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short pass_repeat_binary_char_check
cmp al, 'h'
jz short pass_repeat_binary_char_check
loop repeat_check_binary_chars
pass_repeat_binary_char_check:
mov ax, si
sub ax, word ptr [Counter]
push ax
mov cl, 2
div cl
pop cx
mov si, word ptr [Counter]
mov di, 8
cmp ah, 0
jna short loc_even_binary_byte
xor dx, dx
xor ah, ah
mov al, byte ptr [CommandBuffer][SI]
call proc_binary
mov byte ptr [CommandBuffer][DI],al
inc si
inc di
dec cx
loc_even_binary_byte:
xor dx, dx
mov ax, word ptr [CommandBuffer][SI]
call proc_binary
mov byte ptr [CommandBuffer][DI], al
add si, 2
inc di
dec cx ; dec cx + loop => cx = cx - 2
loop loc_even_binary_byte
mov byte ptr [CommandBuffer][DI], 0
mov si, 8
sub di, 7
mov word ptr [Counter], di
jmp short jump_from_binary_find_cfg
pass_disk_binary_check:
push si
loop_scan_last_byte_of_parameter:
inc si
dec cx
jz short pass_scan_parameter
mov al, byte ptr [CommandBuffer][SI]
cmp al, 0Dh
ja short loop_scan_last_byte_of_parameter
pass_scan_parameter:
inc si
mov word ptr [Counter], si
pop si
sub word ptr [Counter], si
jump_from_binary_find_cfg:
add si, offset CommandBuffer
mov word ptr [Boot_Sec_Params], si
mov es, word ptr [Start_Segment]
mov di, word ptr [Start_Pointer]
mov word ptr [INT20h_Segment], es
mov word ptr [INT20h_Offset], di
repeat_find_compare_str:
mov cx, word ptr [Counter]
push di
repe cmpsb
pop di
and cx, cx
jnz short pass_string_found
mov word ptr [Start_Segment], es
mov word ptr [Start_Pointer], di
mov byte ptr [Printer_Hex], 0
mov si, offset return_from_find_show_hex
push si
jmp start_hex_write_char
pass_string_found:
inc di
jnz short pass_update_find_es
mov bx, es
add bx, 1000h
jc short end_of_find
mov es, bx
pass_update_find_es:
mov si, word ptr [Boot_Sec_Params]
jmp short repeat_find_compare_str
return_from_find_show_hex:
mov es, word ptr [Start_Segment]
mov di, word ptr [Start_Pointer]
xor ah, ah
int 16h
cmp al, 1Bh
jnz short pass_string_found
end_of_find:
mov ax, word ptr [INT20h_Segment]
mov word ptr [Start_Segment], ax
mov ax, word ptr [INT20h_Offset]
mov word ptr [Start_Pointer], ax
retn
loc_wrong_parameter:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_cmd_par
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_size:
inc byte ptr [CmdNo]
mov cx,4
xor si,si
mov di, offset Cmd_Size
get_char_size:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_attrib
loop get_char_size
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_size_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'S'
jb short loop_scan_size_word
add si, 4
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_size_numerals:
inc si
dec cx
jz loc_show_saving_size
cmp al,0Dh
jna loc_show_saving_size
mov al, byte ptr [CommandBuffer][SI]
cmp al,20h
jna short loop_scan_size_numerals
xor bp, bp
jmp short start_scan_saving_size
loop_get_size_numerals:
cmp al, 20h
jna short pass_get_size_numerals
start_scan_saving_size:
cmp al, 30h ; 0
jb loc_wrong_size
cmp al, 39h ; 9
ja loc_wrong_size
mov byte ptr [Decimal_Size][bp], al
inc si
inc bp
cmp bp, 6
ja short check_last_size_numeral
mov al, byte ptr [CommandBuffer][SI]
jmp short loop_get_size_numerals
check_last_size_numeral:
cmp byte ptr [CommandBuffer][SI], 20h
ja loc_wrong_size
pass_get_size_numerals:
mov cx, 8
sub cx, bp
mov al, 20h
f_size_reset_remain:
mov byte ptr [Decimal_Size][bp], al
inc bp
loop f_size_reset_remain
mov cx, 7
mov bp, cx
loc_calculate_size_step:
dec bp
cmp byte ptr [Decimal_Size][bp], 30h
jnb short pass_loc_calculate_size_step
loop loc_calculate_size_step
pass_loc_calculate_size_step:
mov cx, bp
xor bp, bp
mov word ptr [Hex_Size1], 0
mov word ptr [Hex_Size2], 0
cmp cx, 6
jz short loc_7_digit_size
cmp cx, 5
jz short pass_size_mul_F4240
cmp cx, 4
jz short pass_size_mul_186A0
cmp cx, 3
jz short pass_size_mul_2710
cmp cx, 2
jz short pass_size_mul_3E8
cmp cx, 1
jz pass_size_mul_64
jmp pass_size_mul_0A
loc_7_digit_size:
mov ax, 4240h ; DX_AX = (1000000)hex
mov dx, 0Fh
xor bh, bh
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
call proc_mul32 ; Convert to hex value
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], dx
jc loc_wrong_size
inc bp
pass_size_mul_F4240:
mov ax, 86A0h ; DX_AX = (100000)hex
mov dx, 01h
xor bh, bh
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
call proc_mul32
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], dx
jc loc_wrong_size
inc bp
pass_size_mul_186A0:
mov ax, 2710h ; AX = (10000)hex
xor bh, bh
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
mul bx
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], dx
jc short loc_wrong_size
inc bp
pass_size_mul_2710:
mov ax, 3E8h ; AX = (1000)hex
xor bh, bh
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
mul bx
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], dx
jc short loc_wrong_size
inc bp
pass_size_mul_3E8:
mov ax, 64h ; AX = (100)hex
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
mul bl
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], 0
jc short loc_wrong_size
inc bp
pass_size_mul_64:
mov ax, 0Ah ; AX = (10)hex
mov bl, byte ptr [Decimal_Size][bp]
sub bl, 30h
mul bl
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], 0
jc short loc_wrong_size
inc bp
pass_size_mul_0A:
xor ah, ah
mov al, byte ptr [Decimal_Size][bp]
sub al, 30h
add word ptr [Hex_Size1], ax
adc word ptr [Hex_Size2], 0
mov ax, word ptr [Hex_Size1]
mov dx, word ptr [Hex_Size2]
cmp dx, 10h
ja short loc_wrong_size
jb short pass_size_1MB_limit_check
and ax, ax
jnz short loc_wrong_size
pass_size_1MB_limit_check:
mov word ptr [Save_Size_L], ax
mov word ptr [Save_Size_H], dx
jmp short loc_show_saving_size
loc_wrong_size:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_size
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
loc_show_saving_size:
mov si, offset nextline
call proc_printmsg
mov si, offset Str_Size
call proc_printmsg
mov ax, word ptr [Save_Size_L]
mov dx, word ptr [Save_Size_H]
mov byte ptr [Multi_Byte], "s"
cmp ax, 1
ja short pass_multi_byte_check
and dx, dx
jnz short pass_multi_byte_check
mov byte ptr [Multi_Byte], 0
pass_multi_byte_check:
mov bp, 6
loc_size_rediv:
mov cx, 10
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [Decimal_Size][bp],bl
cmp bp,0
jz short loop_find_first_size_numeral
dec bp
and ax, ax
jnz short loc_size_rediv
and dx, dx
jnz short loc_size_rediv
loc_size_fspc:
mov byte ptr [Decimal_Size][bp], 30h
cmp bp,0
jna short loop_find_first_size_numeral
dec bp
jmp short loc_size_fspc
loop_find_first_size_numeral:
cmp byte ptr [Decimal_Size][bp], 30h
ja short pass_find_first_size_numeral
inc bp
cmp bp, 6
jb short loop_find_first_size_numeral
pass_find_first_size_numeral:
mov si, offset Decimal_Size
add si, bp
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
cmp_cmd_attrib:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_attrib
get_char_attrib:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_mkdir
loop get_char_attrib
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov word ptr [Attr_Chars], 0
mov si, 6
loop_scan_attrib_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'A'
jb short loop_scan_attrib_word
add si, 6
mov cx, 60
sub cx, si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_attrib_params:
inc si
dec cx
jz loc_show_attributes
cmp al,0Dh
jna loc_show_attributes
mov ax, word ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_attrib_params
cmp al, '-'
ja loc_cmd_failed
je short loc_attr_space
cmp al, '+'
jne loc_cmd_failed
loc_attr_space:
cmp ah, 20h
ja short pass_attr_space
jb loc_cmd_failed
loc_attr_space_inc:
inc si
mov ah, byte ptr [CommandBuffer][SI]+1
jmp short loc_attr_space
pass_attr_space:
and ah, 0DFh
cmp ah, 'S'
ja loc_cmd_failed
jb short pass_attr_system
mov ah, 04h ; System
jmp short pass_attr_archive
pass_attr_system:
cmp ah, 'H'
ja short pass_attr_hidden
jb short pass_attr_read_only
mov ah, 02h ; Hidden
jmp short pass_attr_archive
pass_attr_hidden:
cmp ah, 'R'
ja loc_cmd_failed
jb short pass_attr_read_only ; Read only
mov ah, 01h
jmp short pass_attr_archive
pass_attr_read_only:
cmp ah, 'A'
jne short loc_chk_attr_enter
mov ah, 20h ; Archive
pass_attr_archive:
cmp al, '-'
jnz short pass_reducing_attributes
or byte ptr [Attr_Chars], ah
jmp short loc_change_attributes_inc
pass_reducing_attributes:
or byte ptr [Attr_Chars]+1, ah
loc_change_attributes_inc:
inc si
mov ah, byte ptr [CommandBuffer][SI]+1
cmp ah, 20h
jb short pass_change_attr
je short loc_change_attributes_inc
cmp ah, '-'
ja short loc_chk_next_attr_char1
je short loc_chk_next_attr_char0
cmp ah, '+'
jne short loc_chk_next_attr_char1
loc_chk_next_attr_char0:
inc si
mov ax, word ptr [CommandBuffer][SI]
jmp short pass_attr_space
loc_chk_next_attr_char1:
cmp byte ptr [CommandBuffer][SI], '-'
ja short pass_attr_space
jmp short loc_attr_file
loc_chk_attr_enter:
cmp ah, 0Dh
jne loc_cmd_failed
pass_change_attr:
mov al, byte ptr [Attr_Chars]
not al
and byte ptr [Attributes], al
mov al, byte ptr [Attr_Chars]+1
or byte ptr [Attributes], al
loc_show_attributes:
mov si, offset nextline
call proc_printmsg
mov word ptr [Attr_Chars], 'ON'
mov word ptr [Attr_Chars]+2, 'MR'
mov word ptr [Attr_Chars]+4, 'LA'
mov si, offset Attr_Chars
mov al, byte ptr [Attributes]
test al, 04h
jz short pass_put_attr_s
mov word ptr [SI], 0053h ; S
inc si
pass_put_attr_s:
test al, 02h
jz short pass_put_attr_h
mov word ptr [SI], 0048h ; H
inc si
pass_put_attr_h:
test al, 01h
jz short pass_put_attr_r
mov word ptr [SI], 0052h ; R
inc si
pass_put_attr_r:
cmp al, 20h
jb short pass_put_attr_a
mov word ptr [SI], 0041h ; A
pass_put_attr_a:
mov si, offset Str_Attributes
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
loc_attr_file:
mov cx, 79
sub cx, si
loop_scan_attr_filename:
inc si
dec cx
jz loc_cmd_failed
cmp al,0Dh
jna loc_cmd_failed
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_attr_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_attr_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short attr_scan_file_name
cmp al,20h
jna short attr_no_extension_of_filename
dec cx
jnz short loop_attr_dot_control
cmp al,2Eh
jne loc_load_wrong_filename
attr_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp ah, 2Eh
jz loc_load_wrong_filename
attr_no_extension_of_filename:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_attr_scan_movsb:
movsb
dec cx
jz short loc_attr_reload_dir
cmp byte ptr [SI],21h
jnb short loop_attr_scan_movsb
mov byte ptr ES:[DI],0
loc_attr_reload_dir:
mov word ptr [Register_AX], 3030h
mov bp, 7C00h ; bp must point start of boot sector
cmp word ptr [Clust_Of_Dir], 2 ; Cluster # of current dir.
jnb short pass_attr_reload_root_dir
call proc_loadrootdir
jc loc_failed
jmp short loc_attr_locate_file
pass_attr_reload_root_dir:
mov cx, word ptr [Clust_Of_Dir]
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_attr_locate_file:
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file
cmp bx, 2 ; BX = Attribute of the dir or
; first cluster of the file.
jb short loc_attr_file_notfound
; CX = File's dir entry pointer ; CX = File's dir entry pointer
mov word ptr [DirEntries], cx
call proc_fat_load
jc loc_failed
mov ax, 7000h
mov es, ax
mov si, word ptr [DirEntries] ; File Entry Num
mov ah, byte ptr ES:[SI]+0Bh
mov al, byte ptr [Attr_Chars]
not al
and ah, al
mov al, byte ptr [Attr_Chars]+1
or ah, al
; mov byte ptr [Attributes], ah ; For save command
mov byte ptr ES:[SI]+0Bh, ah ; Attributes
cmp word ptr [Clust_Of_Dir], 0
ja short loc_attr_save_sub_dir
call proc_save_root_dir
jc loc_failed
return_from_attrib:
mov si, offset Msg_File_Done
call proc_printmsg
mov si, offset nextline
call proc_printmsg
retn
loc_attr_save_sub_dir:
mov bx, 7000h
mov es, bx
xor bx, bx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov cx, word ptr [Clust_Of_Dir]
call proc_file_write
jc loc_failed
jmp short return_from_attrib
loc_attr_file_notfound:
mov si, offset nextline
call proc_printmsg
jmp loc_start_file_notfound
cmp_cmd_mkdir:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Mkdir
get_char_mkdir:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_rmdir
loop get_char_mkdir
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_mkdir_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'M'
jb short loop_scan_mkdir_word
add si, 5
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_mkdir_dirname:
inc si
dec cx
jz loc_md_specify_dirname
cmp al,0Dh
jna loc_md_specify_dirname
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_mkdir_dirname
push si
cmp al, 2Eh
je short loc_wrong_dirname
mov cx,8
loop_mkdir_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short mkdir_scan_dir_name
cmp al,20h
jna short md_no_extension_of_dirname
dec cx
jnz short loop_mkdir_dot_control
cmp al,2Eh
jne short loc_wrong_dirname
mkdir_scan_dir_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb short loc_wrong_dirname
cmp al, 2Eh
jz short loc_wrong_dirname
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz short loc_wrong_dirname
cmp ah, 2Eh
jz short loc_wrong_dirname
md_no_extension_of_dirname:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_md_scan_movsb:
movsb
dec cx
jz short pass_md_scan_dir_name
cmp byte ptr [SI],21h
jnb short loop_md_scan_movsb
mov byte ptr ES:[DI],0
xor si, si
loop_md_scan_invfn_o:
mov cx, sizeInvFnChars
mov al, byte ptr [S_File_Name][SI]
cmp al, 21h
jb short pass_md_scan_dir_name
cmp al, 'z'
ja short loc_md_wrong_dirname
mov di, offset invalid_fname_chars
loop_md_scan_invfn_i:
scasb
je short loc_md_wrong_dirname
loop loop_md_scan_invfn_i
inc si
cmp si, 12
jna short loop_md_scan_invfn_o
jmp short pass_md_scan_dir_name
loc_md_specify_dirname:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_specify_dir_name
call proc_printmsg
retn
loc_wrong_dirname:
pop si
loc_md_wrong_dirname:
mov si, offset nextline
call proc_printmsg
mov si, offset msg_wrong_dir_name
call proc_printmsg
return_from_mkdir:
mov si, offset nextline
call proc_printmsg
retn
pass_md_scan_dir_name:
mov word ptr [Register_AX], 3030h
call proc_fat_load ; FAT buffer refresh for
jc loc_failed ; safety
mov cx, word ptr [Clust_Of_Dir] ; Cluster # of current dir.
cmp cx, 2
jnb short loc_md_reload_sub_dir
call proc_loadrootdir ; Directory refresh for
jc loc_failed ; safety
jmp short loc_md_locate_directory
loc_md_reload_sub_dir:
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_md_locate_directory:
mov si, offset nextline
call proc_printmsg
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file ; output -> cx
; = dir_entry offset of the file
mov word ptr [DirEntries], cx
jnc short loc_mkdir_file_exist
cmp bl, 0
jna short pass_loc_md_dir_exist
mov si, offset msg_dir_exist
call proc_printmsg
jmp short loc_cancel_mkdir
pass_loc_md_dir_exist:
and cx, cx
jnz short pass_loc_md_no_space
; CX = File's dir entry pointer
mov si, offset msg_no_space_dir
call proc_printmsg
jmp short loc_cancel_mkdir
; CX = File's dir entry pointer
pass_loc_md_no_space:
push ES
mov di, 7000h
mov es, di
xor di, di
md_repeat_e5h_location_check:
cmp byte ptr ES:[DI], 0E5h ; Locate new file entry
; on erased entry.
jz short pass_md_e5h_loop
add di, 20h
sub cx, 20h
ja short md_repeat_e5h_location_check
mov di, word ptr [DirEntries]
jmp short pass_md_replace_entry_pointer
pass_md_e5h_loop:
mov word ptr [DirEntries], di
pass_md_replace_entry_pointer:
mov cx, 11
mov si, offset Dir_File_Name
rep movsb ; DS:SI -> ES:DI
pop ES
mov ax, word ptr [bp][Sectors]
cmp ax, 0
ja short scan_md_fat12_fspace
call proc_get_fspace_fat16
; Result : DX_AX = Free sectors , BX = Bytes per Sector
jmp short loc_compare_md_fspace
loc_mkdir_file_exist:
mov si, offset msg_file_exist
call proc_printmsg
loc_cancel_mkdir:
mov si, offset nextline
call proc_printmsg
retn
scan_md_fat12_fspace:
call proc_get_fspace_fat12
; Result : AX = Free sectors , BX = Bytes per Sector
loc_compare_md_fspace:
and dx, dx
jnz short pass_md_freespace_check
mov dl, byte ptr [bp][SecPerClust]
cmp ax, dx
jb short md_no_enough_freespace
pass_md_freespace_check:
mov si, offset msg_create_dir
call proc_printmsg
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
mkdir_loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_mkdir_yes_no
cmp al, 'n'
jz short loc_mkdir_yes_no
cmp al, 1Bh
jz return_from_mkdir
cmp al, 'Y'
jz short loc_mkdir_yes_no
cmp al, 'y'
jz short loc_mkdir_yes_no
cmp al, 0Dh
jz short loc_mkdir_status
jmp short mkdir_loop_get_char
md_no_enough_freespace:
mov si, offset msg_no_enough_space
call proc_printmsg
jmp return_from_mkdir
loc_mkdir_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short mkdir_loop_get_char
loc_mkdir_status:
cmp byte ptr [Char_Input], 'N'
jb short mkdir_loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
jb return_from_mkdir
mov si, offset nextline
call proc_printmsg
call proc_reset_file_clusters
mov cx, word ptr [Number_Of_Clusts]
call proc_find_first_free_clust ; output -> BX =
; first free cluster
cmp bx, 2
jnb short pass_loc_md_ffc_error
call proc_fat_load
jc loc_failed
jmp md_no_enough_freespace
pass_loc_md_ffc_error:
mov ax, 7000h
mov es, ax
mov si, word ptr [DirEntries] ; File Entry Num
mov word ptr ES:[SI]+1Ah, bx ; First cluster
mov word ptr [File_FClust], bx
xor ax, ax
mov word ptr ES:[SI]+1Ch, ax
mov word ptr ES:[SI]+1Eh, ax
mov cx, 1
call proc_allocate_clusters ; Input -> cx = number of
; clusters to be allocated.
; Input -> [File_FClust] =
; First cluster of the file.
and cx, cx
jz short pass_md_c_allocation_error
call proc_fat_load
jc loc_failed
jmp md_no_enough_freespace
pass_md_c_allocation_error:
mov ah, 04h ; Return current date
int 1Ah
; CF = 1 -> Clock has stopped running.
; CH = Century in BCD
; CL = Year in BCD
; DH = Month in BCD
; DL = Day in BCD
mov al, ch
call proc_bcd_to_binary
mov ch, al
mov al, cl
call proc_bcd_to_binary
mov cl, al
mov al, dh
call proc_bcd_to_binary
mov dh, al
mov al, dl
call proc_bcd_to_binary
mov dl, al
xor bx, bx
sub ch, 19
jb short pass_md_adjust_date
mov al, 100
mul ch
add al, cl
sub al, 80 ; Number of years since 1980.
jb short pass_md_adjust_date
mov cl, 4
shl ax, cl
or al, dh ; Month
mov cl, 5
shl ax, cl
or al, dl ; Day
mov bx, ax ; Date
pass_md_adjust_date:
mov ah, 02h ; Return current time
int 1Ah
; CF = 1 -> Clock has stopped running.
; CH = Number of Hours in BCD
; CL = Minutes in BCD
; DH = Seconds in BCD
; DL = 00h -> Standard time
; 01h -> Daylight saving time
mov al, ch
call proc_bcd_to_binary
mov ch, al
mov al, cl
call proc_bcd_to_binary
mov dl, al
mov al, dh
call proc_bcd_to_binary
mov dh, al
mov al, ch ; Hours
; mov dl, cl
mov cl, 6
shl ax, cl
or al, dl ; Minutes
mov cl,5
shl ax, cl
shr dh, 1 ; Two seconds interval
or al, dh
mov dx, ax
mov ax, 7000h
mov es, ax
xor ax, ax
mov di, word ptr [DirEntries] ; File Entry Num
add di, 11
mov byte ptr ES:[DI], 10h ; Directory Attribute
inc di
mov cx, 5
rep stosw
mov word ptr ES:[DI], dx ; Time
mov word ptr ES:[DI]+2, bx ; Date
xor bx, bx
mov es, bx
mov bx, 700h ; Empty directory buffer
mov di, bx
xor ax, ax
mov cx, 100h
rep stosw ; Fill ZEROs.
xor CH,CH
mov CL,Byte Ptr [bp][SecPerClust]
cmp CL, 1
jna short pass_write_dir_multi_sectors
mov ax, word ptr [File_FClust]
mov Word Ptr [Register_AX],3030h
dec AX
dec AX
mul CX
add AX,Word Ptr [bp][DataArea1]
adc DX,Word Ptr [bp][DataArea2]
; Linear address of the cluster
add AX,1
adc DX,0
jc loc_failed
dec CL
write_next_dir_sector:
mov bx, 700h
push cx
mov cl, 1
call proc_write
pop CX
jc loc_failed
loop write_next_dir_sector
pass_write_dir_multi_sectors:
mov si, word ptr [DirEntries]
mov di, 7000h
push ds
mov ds, di
mov di, 700h
push di
mov cx, 10h
rep movsw
pop di
mov byte ptr ES:[DI], 2Eh
inc di
mov ax, 2020h
mov cx, 5
rep stosw
push es
pop ds
mov si, 700h
mov di, 720h
push di
mov cx, 10h
rep movsw
pop di
mov word ptr [DI], 2E2Eh
pop ds
mov cx, word ptr [Clust_Of_Dir]
mov word ptr ES:[DI]+1Ah, cx ; First cluster of parent dir
mov ax, word ptr [File_FClust]
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
mov Word Ptr [Register_AX],3030h
mov CL,1
mov bx, 700h
call proc_write
jc loc_failed
cmp word ptr [Clust_Of_Dir], 0
jna loc_save_root_dir
jmp loc_save_sub_dir
cmp_cmd_rmdir:
inc byte ptr [CmdNo]
mov cx,5
xor si,si
mov di, offset Cmd_Rmdir
get_char_rmdir:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_rename
loop get_char_rmdir
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_rmdir_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'R'
jb short loop_scan_rmdir_word
add si, 5
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_rmdir_dirname:
inc si
dec cx
jz loc_md_specify_dirname
cmp al,0Dh
jna loc_md_specify_dirname
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_rmdir_dirname
push si
cmp al, 2Eh
je loc_wrong_dirname
mov cx,8
loop_rmdir_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al,2Eh
jz short rd_scan_dir_name
cmp al,20h
jna short rd_no_extension_of_dirname
dec cx
jnz short loop_rmdir_dot_control
cmp al,2Eh
jne loc_wrong_dirname
rd_scan_dir_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_wrong_dirname
cmp al, 2Eh
jz loc_wrong_dirname
inc si
mov ax, word ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_wrong_dirname
cmp ah, 2Eh
jz loc_wrong_dirname
rd_no_extension_of_dirname:
pop si
add si, offset CommandBuffer
mov di, offset S_File_Name
mov cx,12
loop_rd_scan_movsb:
movsb
dec cx
jz short pass_rd_scan_dir_name
cmp byte ptr [SI],21h
jnb short loop_rd_scan_movsb
mov byte ptr ES:[DI],0
pass_rd_scan_dir_name:
mov word ptr [Register_AX], 3030h
mov bp, 7C00h ; bp must point start of boot sector
mov cx, word ptr [Clust_Of_Dir] ; Cluster # of current dir.
cmp cx, 2
jnb short pass_rmdir_reload_root_dir
call proc_loadrootdir
jc loc_failed
jmp short loc_rmdir_locate_directory
pass_rmdir_reload_root_dir:
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_rmdir_locate_directory:
mov si, offset nextline
call proc_printmsg
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file ; output -> cx
; = dir_entry offset of the file
mov word ptr [DirEntries], cx
jnc loc_mkdir_file_exist
test bl, 10h
jnz short loc_rd_dir_exist
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_notfound
call proc_printmsg
jmp return_from_mkdir
loc_rd_dir_exist:
and bl, 07h ; Attributes
jnz loc_permission_denied
mov ax, word ptr [File_FClust]
loc_rd_next_entry_buf:
mov word ptr [Cluster], ax
xor ch, ch
mov cl, byte ptr [bp][SecPerClust]
mov word ptr [Counter], cx
mov Word Ptr [Register_AX],3030h
dec AX
dec AX
mul CX
add AX,Word Ptr [bp][DataArea1]
adc DX,Word Ptr [bp][DataArea2]
; Linear address of the cluster
xor bx, bx
mov es, bx
loc_next_sector_of_cclust:
mov bx, 700h
mov cl, 1
call proc_read
jc loc_failed
mov cx, 10h
mov di, 700h
loc_check_rd_dir_entry:
mov al, byte ptr ES:[DI]
add di, 20h
cmp al, 0
je short loc_msg_remove_dir
cmp al, 0E5h
je short pass_rd_entry_dot_control
cmp al, 2Eh
jne short loc_dir_not_empty
pass_rd_entry_dot_control:
loop loc_check_rd_dir_entry
dec word ptr [Counter]
ja short loc_next_sector_of_cclust
mov ax, 8000h
mov es, ax
cmp word ptr [bp][Sectors], 0
jna short find_rd_fat16_next_cluster
find_rd_fat12_next_cluster:
mov ax, word ptr [Cluster]
mov si, ax
add si, si
add si, ax
shr si, 1
mov ax, word ptr ES:[SI]
jnc short rd_cluster_num_even
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
rd_cluster_num_even:
and ah, 0Fh
cmp ax, 0FF0h
jnb short loc_msg_remove_dir
jmp loc_rd_next_entry_buf
find_rd_fat16_next_cluster:
mov si, word ptr [Cluster]
add si, si
jnc short pass_rd_clust_update_es
mov ax, 9000h
mov es, ax
pass_rd_clust_update_es:
mov ax, word ptr ES:[SI]
cmp ax, 0FFF0h
jnb short loc_msg_remove_dir
jmp loc_rd_next_entry_buf
loc_dir_not_empty:
mov si, offset msg_dir_not_empty
call proc_printmsg
jmp return_from_mkdir
loc_msg_remove_dir:
mov si, offset msg_remove_dir
call proc_printmsg
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
rmdir_loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_rmdir_yes_no
cmp al, 'n'
jz short loc_rmdir_yes_no
cmp al, 1Bh
jz return_from_mkdir
cmp al, 'Y'
jz short loc_rmdir_yes_no
cmp al, 'y'
jz short loc_rmdir_yes_no
cmp al, 0Dh
jz short loc_rmdir_status
jmp short rmdir_loop_get_char
loc_rmdir_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short rmdir_loop_get_char
loc_rmdir_status:
cmp byte ptr [Char_Input], 'N'
jb short rmdir_loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
jb return_from_mkdir
mov si, offset nextline
call proc_printmsg
call proc_fat_load
jc loc_failed
call proc_reset_file_clusters
mov ax, 7000h
mov es, ax
mov si, word ptr [DirEntries] ; File Entry Num
mov word ptr ES:[SI], 0E5h ; Erased file sign
cmp word ptr [Clust_Of_Dir], 0
jna loc_save_root_dir
jmp loc_save_sub_dir
cmp_cmd_rename:
inc byte ptr [CmdNo]
mov cx,6
xor si,si
mov di, offset Cmd_Rename
get_char_rename:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne cmp_cmd_tr
loop get_char_rename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_cmd_failed
mov si, 6
loop_scan_rename_word:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 'R'
jb short loop_scan_rename_word
add si, 6
mov cx,60
sub cx,si
mov al, byte ptr [CommandBuffer][SI]
loop_scan_rename_filename:
inc si
dec cx
jz loc_start_specify_filename
cmp al,0Dh
jna loc_start_specify_filename
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
jna short loop_scan_rename_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_rename_dot_control:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 2Eh
jz short rename_scan_file_name
cmp al, 20h
jna short rename_no_extension_of_filename
dec cx
jnz short loop_rename_dot_control
cmp al, 2Eh
jne loc_load_wrong_filename
rename_scan_file_name:
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp al, 20h
jna short rename_no_extension_of_filename
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp al, 20h
jna short rename_no_extension_of_filename
inc si
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja loc_load_wrong_filename
rename_no_extension_of_filename:
mov cx, si
pop si
sub cx, si ; CX = Number of filename characters.
add si, offset CommandBuffer
mov di, offset S_File_Name
rep movsb
loc_rename_scan_new_file_name:
mov byte ptr ES:[DI],0
cmp byte ptr [SI],20h
jb loc_start_specify_filename
ja loc_load_wrong_filename_j
mov cx, offset CommandBuffer
add cx, 79
sub cx, si
loop_scan_rnew_filename:
inc si
mov al, byte ptr [SI]
dec cx
jz loc_start_specify_filename
cmp al, 0Dh
jna loc_start_specify_filename
cmp al, 20h
jna short loop_scan_rnew_filename
push si
cmp al, 2Eh
je loc_load_wrong_filename
mov cx,8
loop_rnew_dot_control:
inc si
mov al, byte ptr [SI]
cmp al, 2Eh
jz short loc_rnew_scan_file_name
cmp al, 20h
jna short rename_no_ext_of_new_filename
dec cx
jnz short loop_rnew_dot_control
cmp al, 2Eh
jne loc_load_wrong_filename
loc_rnew_scan_file_name:
inc si
mov al, byte ptr [SI]
cmp al, 21h
jb loc_load_wrong_filename
cmp al, 2Eh
jz loc_load_wrong_filename
inc si
mov ax, word ptr [SI]
cmp al, 2Eh
jz loc_load_wrong_filename
cmp ah, 2Eh
jz loc_load_wrong_filename
rename_no_ext_of_new_filename:
pop si
mov di, offset File_Name
mov cx,12
loop_rename_scan_new_file_movsb:
movsb
dec cx
jz short pass_rename_scan_new_filename
cmp byte ptr [SI],21h
jnb short loop_rename_scan_new_file_movsb
mov byte ptr ES:[DI],0
pass_rename_scan_new_filename:
xor si, si
loop_rename_scan_invfn_o:
mov cx, sizeInvFnChars
mov al, byte ptr [File_Name][SI]
cmp al, 21h
jb short loc_rename_start_scan_file
cmp al, 'z'
ja loc_load_wrong_filename_j
mov di, offset invalid_fname_chars
loop_rename_scan_invfn_i:
scasb
je loc_load_wrong_filename_j
loop loop_rename_scan_invfn_i
inc si
cmp si, 12
jna short loop_rename_scan_invfn_o
loc_rename_start_scan_file:
mov word ptr [Register_AX], 3030h
call proc_fat_load ; FAT buffer refresh for
jc loc_failed ; safety
mov cx, word ptr [Clust_Of_Dir] ; Cluster # of current dir.
cmp cx, 2
jnb short loc_rn_reload_sub_dir
call proc_loadrootdir ; Directory refresh for
jc loc_failed ; safety
jmp short loc_rename_locate_file
loc_rn_reload_sub_dir:
push cx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov bx, 7000h
mov es, bx
xor bx, bx
pop cx
call proc_file_read ; Read directory to buffer, again.
jc loc_failed ; We have no chance to continue !
; Because, directory buffer
; may be damaged.
loc_rename_locate_file:
mov si, offset nextline
call proc_printmsg
mov si, offset S_File_Name
call proc_convert_file_name
call proc_find_file ; output -> cx
; = dir_entry offset of the file
mov word ptr [DirEntries], cx
jnc short pass_rn_file_notfound
test bl, 10h
jnz short pass_rn_file_notfound
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_notfound
call proc_printmsg
retn
pass_rn_file_notfound:
and bl, 07h ; Attributes
jnz loc_permission_denied
mov si, offset File_Name
call proc_convert_file_name
call proc_find_file
jnc loc_mkdir_file_exist
cmp bl, 0
ja loc_save_dir_exist
mov si, offset msg_rename
call proc_printmsg
mov si, offset S_File_Name
call proc_printmsg
mov si, offset msg_as
call proc_printmsg
mov si, offset File_Name
call proc_printmsg
mov si, offset msg_yes_no
call proc_printmsg
mov byte ptr [Char_Input], 0
rename_loop_get_char:
xor ah,ah
int 16h
cmp al, 'N'
jz short loc_rename_yes_no
cmp al, 'n'
jz short loc_rename_yes_no
cmp al, 1Bh
jz short return_from_rename
cmp al, 'Y'
jz short loc_rename_yes_no
cmp al, 'y'
jz short loc_rename_yes_no
cmp al, 0Dh
jz short loc_rename_status
jmp short rename_loop_get_char
loc_rename_yes_no:
mov byte ptr [Char_Input], al
mov ah, 09h
mov bx, 07h
mov cx, 1
int 10h
jmp short rename_loop_get_char
loc_rename_status:
cmp byte ptr [Char_Input], 'N'
jb short rename_loop_get_char
mov al, byte ptr [Char_Input]
mov byte ptr [Char_Input], 0
and al, 0DFh
cmp al, 'Y'
je short loc_rename_write_new_file_name
return_from_rename:
mov si, offset nextline
call proc_printmsg
retn
loc_rename_write_new_file_name:
mov bx, 7000h
mov es, bx
mov di, word ptr [DirEntries] ; File Entry Num
mov si, offset Dir_File_Name
mov cx, 11
rep movsb
cmp word ptr [Clust_Of_Dir], 0
jna short loc_rename_write_root_dir
xor bx, bx
mov ax, 80h
mov cl, byte ptr [bp][SecPerClust]
div cl
; cbw
mov word ptr [Counter], ax
mov cx, word ptr [Clust_Of_Dir]
call proc_file_write
jc loc_failed
jmp short loc_done_rename
loc_rename_write_root_dir:
call proc_save_root_dir
jc loc_failed
loc_done_rename:
mov si, offset nextline
call proc_printmsg
mov si, offset Msg_File_Done
call proc_printmsg
jmp short return_from_rename
cmp_cmd_tr:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
cmp ax, 'RT'
jne short cmp_cmd_en
cmp byte ptr [CommandBuffer][+2],20h
ja loc_cmd_failed
cmp word ptr [var_KBD], 'EN'
jnz short loc_return_from_kbd
call proc_trq_kbd
mov word ptr [var_KBD], 'TR'
loc_return_from_kbd:
retn
cmp_cmd_en:
inc byte ptr [CmdNo]
mov ax, word ptr [CommandBuffer]
cmp ax, 'NE'
jne short cmp_cmd_ver
cmp byte ptr [CommandBuffer][+2],20h
ja short loc_cmd_failed
cmp word ptr [var_KBD], 'TR'
jnz short loc_return_from_kbd
; xor di, di
; mov es, di
mov di, 58h
mov si, offset var_INT16h_off
movsw
movsw
mov word ptr [var_KBD], 'EN'
retn
cmp_cmd_ver:
inc byte ptr [CmdNo]
mov cx, 3
xor si,si
mov di, offset Cmd_Ver
get_char_ver:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short cmp_cmd_build
loop get_char_ver
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja short loc_cmd_failed
loc_p2000_info:
mov si, offset Msg_P2000_Version
call proc_printmsg
retn
cmp_cmd_build:
inc byte ptr [CmdNo]
mov cx, 5
xor si,si
mov di, offset Cmd_Build
get_char_build:
mov al, byte ptr [CommandBuffer][SI]
inc si
scasb
jne short loc_cmd_failed
loop get_char_build
mov al, byte ptr [CommandBuffer][SI]
cmp al, 20h
ja short loc_cmd_failed
mov si, offset Msg_Build
call proc_printmsg
retn
loc_cmd_failed:
mov si, offset nextline
call proc_printmsg
mov si, offset Msg_Bad_Name
call proc_printmsg
retn
command_interpreter endp
proc_find_file proc near
push es
mov di,7000h
mov es, di
xor di, di
; mov ds, di
cmp word ptr [Clust_Of_Dir], 0 ; Is it root directory ?
ja short pass_root_directory_limit
; mov bp, 7C00h
mov cx, word ptr [bp][RootDirEnts] ; Number of entries of root dir.
jmp short loc_start_scan
pass_root_directory_limit:
mov cx, 800h
loc_start_scan:
push cx
xor bx, bx ; For "info" command (If bx > 0 it is a file or directory)
cmp byte ptr ES:[DI], 0
je short loc_file_not_found
push di
mov cx, 11
mov si, offset Dir_File_Name
loc_next_char:
cmpsb
jne short next_file_search
loop loc_next_char
pop di
mov bx, word ptr ES:[DI]+1Ah ; First Cluster
mov word ptr [File_FClust], bx
mov bl, byte ptr ES:[DI]+0Bh
test bl, 10h
jnz short loc_not_a_file ; It is a directory
mov byte ptr [File_A_Byte], bl ; Attributes
mov ax, word ptr ES:[DI]+1Ch
mov word ptr [File_Size_L], ax
mov dx, word ptr ES:[DI]+1Eh
mov word ptr [File_Size_H], dx
pop cx
pop es
mov cx, di ; Directory entry offset of the file
clc
retn
next_file_search:
pop di
add di,20h
; jc loc_file_not_found
pop cx
loop loc_start_scan
push cx
loc_file_not_found:
mov word ptr [File_FClust], 0
loc_not_a_file:
mov word ptr [File_Size_L], 0
mov word ptr [File_Size_H], 0
; mov byte ptr [File_A_Byte], 0
pop cx
pop es
mov cx, di ; First free entry (or dir entry offset of the sub dir)
stc
retn
proc_find_file endp
proc_convert_file_name proc near
push ds
pop es
mov cx, 11
mov al, 20h
mov di, offset Dir_File_Name
repz stosb
mov al, 2Eh ; dot
mov cx, 12
; mov si, offset S_File_Name ; SI must point name of searched file
mov di, offset Dir_File_Name
cmp byte ptr [SI], 2Eh
jz short pass_dot_space
loc_get_fchar:
mov al, byte ptr [SI]
cmp al, 61h
jb short pass_name_capitalize
cmp al, 7Ah
ja short pass_name_capitalize
and al, 0DFh
mov byte ptr [SI], al
pass_name_capitalize:
cmp al, 21h
jb short stop_convert_file
cmp al, 2Eh
jne short pass_dot_space
add_space:
cmp cx, 4
jna short inc_and_loop
mov byte ptr [DI], 20h
inc di
dec cx
jmp short add_space
pass_dot_space:
mov byte ptr [DI], al
inc di
inc_and_loop:
inc si
loop loc_get_fchar
stop_convert_file:
mov byte ptr [SI],0
retn
proc_convert_file_name endp
proc_load_msdos proc near
xor bp,bp
mov es,bp
mov ds,bp
mov bp,7C00h
pass_num_of_clusts:
mov Word Ptr [Register_AX],3030h
; mov bx, word ptr [File_FCLust] ; Already it has cluster #
; cmp bx,2
; jb short loading_failed
mov ax,bx
dec ax
dec ax
xor bx,bx
mov es,bx
mov word ptr [Counter], bx ; Max sectors to load ?
mov bl,Byte Ptr [bp][SecPerClust]
mul bx
add ax,Word Ptr [bp][DataArea1]
adc dx,Word Ptr [bp][DataArea2]
mov bx, 700h
push bp
push bx
mov cx, 1 ; Read 1 sector
call proc_read
pop si
pop di
jc short loading_failed
mov cx, word ptr [SI] ; EB3C -> JMP +3E
movsw
xchg ch,cl
xor ch,ch
add si,cx ; 702h + 3Ch
add di,cx
mov bx, 200h
sub bx, cx
mov cx,bx
rep movsb ; msdos bootstrap code
cmp word ptr [var_KBD], 'TR'
jnz short pass_plmsdos_reset_INT16h
mov di,58h
mov si, offset [var_INT16h_off]
movsw
movsw
pass_plmsdos_reset_INT16h:
jmp BP
loading_failed:
mov word ptr Register_AX, 3030h
mov si, offset trfailedmsg
call proc_printmsg
stc
retn
proc_load_msdos endp
proc_load_masterboot proc near
mov dl, Byte ptr [Hard_Disk]
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
mov byte ptr [Hard_Disk], 80h ; Reset default hd value
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, 8FEh
cmp word ptr [SI],0AA55h
jnz short loc_not_masterboot
retn
loc_not_masterboot:
mov si, offset not_masterboot
call proc_printmsg
stc
retn
proc_load_masterboot endp
proc_start_partition proc near
mov si, 8BEh ; 700h+1BEh, beginning of partition table
cmp byte ptr [Partition],0
ja short pass_active_partition
mov cx, 4
loc_next_partition:
cmp byte ptr [SI], 80h
jz short loc_this_partition
add si,10h
loop loc_next_partition
return_with_error:
mov si, offset No_Active_Part
call proc_printmsg
stc
retn
pass_active_partition:
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, 700h
mov dh, byte ptr [SI] [ptBeginHead]
mov cx, word ptr [SI] [ptBeginSector]
mov ax, 0201h
int 13h
jc harddisk_error
mov si, 8FEh
cmp word ptr [SI], 0AA55h
jnz short it_is_not_boot_sec
mov dl, byte ptr [Hard_Disk]
mov cx,100h
mov si,700h
mov di,7C00h
rep movsw
retn
it_is_not_boot_sec:
mov si, offset nextline
call proc_printmsg
mov si, offset Not_boot_sec
call proc_printmsg
stc
retn
proc_start_partition endp
proc_print_ptable proc near
mov si, offset P_Table_Header
call proc_printmsg
mov cx,4
mov bl,'0'
mov si, 8AEh
loc_next_p_entry:
inc bl
add si, 10h
mov byte ptr [P_Number], bl
mov al, byte ptr [SI][ptBootable]
call proc_hex
mov word ptr [P_Status], ax
mov al, byte ptr [SI][ptBeginHead]
call proc_hex
mov word ptr [Begin_Head], ax
mov al, byte ptr [SI][ptBeginSector]
call proc_hex
mov word ptr [Begin_Sec], ax
mov al, byte ptr [SI][ptBeginCylinder]
call proc_hex
mov word ptr [Begin_Cyl], ax
mov al, byte ptr [SI][ptFileSystemName]
call proc_hex
mov word ptr [FS_ID], ax
mov al, byte ptr [SI][ptEndHead]
call proc_hex
mov word ptr [End_Head], ax
mov al, byte ptr [SI][ptEndSector]
call proc_hex
mov word ptr [End_Sec], ax
mov al, byte ptr [SI][ptEndCylinder]
call proc_hex
mov word ptr [End_Cyl], ax
push cx
push bx
mov ax, word ptr [SI][ptStartSector]
mov dx, word ptr [SI][ptStartSector]+2
mov bp, 8
mov cx, 10
loc_rediv_startsec:
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [P_Start_Sec][bp],bl
dec bp
and ax, ax
jnz short loc_rediv_startsec
and dx, dx
jnz short loc_rediv_startsec
loc_fspc_startsec:
mov byte ptr [P_Start_Sec][bp],20h
cmp bp,0
jna short loc_conv_psectors
dec bp
jmp short loc_fspc_startsec
print_p_entry:
mov si, offset Partition_Table
call proc_printmsg
pop si
pop bx
pop cx
dec cx
jnz loc_next_p_entry
retn
loc_conv_psectors:
mov ax, word ptr [SI][ptSectors]
mov dx, word ptr [SI][ptSectors]+2
mov bp, 8
; mov cx, 10
loc_rediv_psectors:
call Rx_Dos_Div32
add bl,'0'
mov byte ptr [P_Sectors][bp],bl
dec bp
and ax, ax
jnz short loc_rediv_psectors
and dx, dx
jnz short loc_rediv_psectors
loc_fspc_psectors:
mov byte ptr [P_Sectors][bp],20h
cmp bp,0
jna short loc_filesys_str
dec bp
jmp short loc_fspc_psectors
loc_filesys_str:
mov bl, byte ptr [SI][ptFileSystemName]
push si
cmp bl, 7
ja short loc_non_dos_fs
mov al, 0Bh
mul bl
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
jmp short print_p_entry
loc_non_dos_fs:
mov si, offset FS_WIN_32
cmp bl, 0Bh
jz short loc_move_fsname
cmp bl, 0Ch
jz short loc_move_fsname
mov si, offset FS_WIN_P
cmp bl, 0Eh
jz short loc_move_fsname
mov si, offset FS_WIN_EXT
cmp bl, 0Fh
jz short loc_move_fsname
mov si, offset FS_SCO
cmp bl, 63h
jz short loc_move_fsname
mov si, offset FS_Linux
cmp bl, 83h
jz short loc_move_fsname
mov si, offset FS_LinuxSwap
cmp bl, 82h
jz short loc_move_fsname
mov si, offset FS_TR
mov si, offset FS_LinuxExt
cmp bl, 85h
jz short loc_move_fsname
cmp bl, 0A1h
jz short loc_move_fsname
mov si, offset FS_Others
jmp short loc_move_fsname
proc_print_ptable endp
;###############################################################
;# From (hex) character to binary (byte) converter #
;# #
;# Input -> AX = last 2 bytes of hex. number/address (word) #
;# DX = fist 2 bytes of hex. number/address (word) #
;# Output -> AX = binary number/address (word) #
;# #
;# Input -> DX_AX = (DL*4096)+(DH*256)+(AL*16)+AH (hex. chars) #
;# Output -> AX = (AH*16)+AL (binary number) #
;# #
;# (c) Erdogan Tan 1999 #
;###############################################################
proc_binary proc near
cmp al, 'A'
jb short pass_binary_fix_num_al1
sub al, 7
pass_binary_fix_num_al1:
cmp ah, 'A'
jb short pass_binary_fix_num_ah1
sub ah, 7
pass_binary_fix_num_ah1:
xchg ah, al
sub ax, '00' ; Convert char to hex. number
db 0D5h, 10h ; Undocumented instruction
; Adjust AX before BCD divide
; D5h, 10h -> undocumented "aad"
; AL = ( AH * N ) + AL
; AH = 0
; N = 10h
; (D5 followed by an immediate value N)
xchg dx, ax
cmp al, 'A'
jb short pass_binary_fix_num_al2
sub al, 7
pass_binary_fix_num_al2:
cmp ah, 'A'
jb short pass_binary_fix_num_ah2
sub ah, 7
pass_binary_fix_num_ah2:
xchg al, ah
sub ax, '00'
db 0D5h, 10h
mov ah, al
mov al, dl
retn
proc_binary endp
;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; 32 bit Multiply ;
;- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -;
; ;
; input -> DX_AX = 32 bit multiplier ;
; input -> BX = 16 bit number to be multiplied by DX_AX ;
; output -> BX_DX_AX = 48 bit (16+32 bit) result number ;
; ;
; (c) Erdogan TAN 1999 ;
;............................................................;
proc_mul32 proc near
push cx
mov cx, bx
mov bx, dx
mul cx
xchg ax, bx
push dx
mul cx
pop cx
add ax, cx
adc dx, 0
xchg bx, ax
xchg dx, bx
pop cx
retn
proc_mul32 endp
proc_dparam proc near
push dx
mov ah, 08h ; DL = Drive
int 13h
pop bx
jnc short dparam_no_error
xchg ah, al
call proc_hex
mov word ptr [Register_AX], ax
stc
retn
dparam_no_error:
mov dl, dh
xor dh, dh
inc dx
mov bp, offset Boot_Sec_Params
mov byte ptr [bp][DriveNumber], bl
and cl, 3Fh
xor ch, ch
mov word ptr [bp][SecPerTrack], cx
mov word ptr [bp][Heads], dx
mov ax, 200h
mov word ptr [bp][BytesPerSec], ax
mov dl, bl ; Drive Number
retn
proc_dparam endp
proc_write proc near
loop_loc_w0:
mov Byte Ptr [RetryCount],04h
loop_loc_w1:
push CX ; # of sectors to be written
push AX ; Linear sector #
push DX ; DX_AX = Linear address (sectors)
mov CX,Word Ptr [bp][SecPerTrack]
push BX
call RX_DOS_DIV32
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,0301h
int 13h ; BIOS Service func ( ah ) = 3
; Write 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_w_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_w_hex:
pop DX
pop AX
pop CX
jc short loc_w3
add AX,1
adc DX,0
jc short loc_w4
loc_w2:
add BX,Word Ptr [bp][BytesPerSec]
jnc short pass_w_next
push BX
mov BX, ES
add BX, 1000h
mov ES, BX
clc ; Return from F000 to 0 will be accepted.
pop BX
pass_w_next:
loop loop_loc_w0 ; Loop if CX > 0
retn
loc_w3:
dec Byte Ptr [RetryCount]
jnz short loop_loc_w1
loc_w4:
retn
proc_write endp
proc_get_fspace_fat12 proc near
push ax
mov ax, word ptr [bp][RootDirEnts]
mov bx, 20h
mul bx
mov bx, word ptr [bp][BytesPerSec]
add ax, bx
dec ax
div bx
mov dx, ax
pop ax
sub ax, dx
sub ax, word ptr [bp][ResSectors]
xor ch, ch
mov cl, byte ptr [bp][FATs]
loc_sub_fat12_secs:
sub ax, word ptr [bp][FATsecs]
loop loc_sub_fat12_secs
xor dx, dx
mov cl, byte ptr [bp][SecPerClust]
; add ax, cx
; dec ax
call Rx_Dos_Div32
mov cx, ax ; Number of Clusters
mov bx, 8000h
mov ES, bx
mov word ptr [Counter], 0
mov word ptr [Number_Of_Clusts], cx ; for other commands.
mov dx, 2
loc_scan_fat12_table:
mov si,dx
add si,si ; multiply cluster number by 3
add si,dx
shr si,1 ; and divide by 2
mov ax, word ptr ES:[SI]
jnc short loc_fat12_even
shr ax,1
shr ax,1
shr ax,1
shr ax,1
loc_fat12_even:
and ah, 0Fh ; mask off the highest 4 bits
cmp ax, 0
ja short pass_inc_number_of_free_cluster_fat12
inc word ptr [Counter]
pass_inc_number_of_free_cluster_fat12:
inc dx
loop loc_scan_fat12_table
mov ax, word ptr [Counter]
xor bh, bh
mov bl, byte ptr [bp][SecPerClust]
mul bx
mov bx, word ptr [bp][BytesPerSec]
mov word ptr [Counter], 200h ; Freespace unit is bytes
retn ; DX_AX = Free sectors
; DX has to be 0
; (FAT12 free space <= 32 MB)
proc_get_fspace_fat12 endp
proc_get_fspace_fat16 proc near
mov ax, word ptr [bp][HugeSec1]
mov dx, word ptr [bp][HugeSec2]
sub ax, word ptr [bp][ResSectors]
sbb dx, 0
xor ch, ch
mov cl, byte ptr [bp][FATs]
loc_sub_fat16_secs:
sub ax, word ptr [bp][FATsecs]
sbb dx, 0
loop loc_sub_fat16_secs
push dx
push ax
mov ax, word ptr [bp][RootDirEnts]
mov bx, 20h
mul bx
mov bx, word ptr [bp][BytesPerSec]
add ax, bx
dec ax
; DX = 0 (MS-DOS)
div bx
mov bx, ax
pop ax
sub ax, bx
pop dx
sbb dx, 0
mov cl, byte ptr [bp][SecPerClust]
add ax, cx
adc dx, 0
sub ax, 1
sbb dx, 0
call Rx_Dos_Div32
mov cx, ax ; Number of Clusters
mov word ptr [Number_Of_Clusts], cx ; for other commands.
mov bx, 8000h
mov ES, bx
mov word ptr [Counter], 0
mov si, 4
loc_scan_fat16_table:
mov bx, word ptr ES:[SI]
and bx, bx
jnz short pass_inc_number_of_free_cluster
inc word ptr [Counter]
pass_inc_number_of_free_cluster:
cmp si, 0FFFEh
jne short pass_scan_fat16_update_es
mov bx, 9000h
mov es, bx
pass_scan_fat16_update_es:
inc si
inc si
loop loc_scan_fat16_table
mov ax, word ptr [Counter]
xor bh, bh
mov bl, byte ptr [bp][SecPerClust]
mul bx
mov word ptr [Counter], 0 ; Freespace unit is sectors
cmp dx, 7Fh
ja short retn_from_get_fspace_fat16
mov bx, word ptr [bp][BytesPerSec]
cmp bx, 200h
jne short retn_from_get_fspace_fat16
mov word ptr [Counter], 200h ; Freespace unit is bytes
retn_from_get_fspace_fat16:
retn ; DX_AX = Free sectors
proc_get_fspace_fat16 endp
proc_reset_file_clusters proc near
mov cx, word ptr [File_FClust]
cmp cx, 2
jb short return_from_reset_file_clusts
cmp Word Ptr [bp][Sectors],0 ; Is it > 32M (FAT12 limit) ?
ja short Reset_FAT12Clusts
Reset_FAT16Clusts:
mov ax,8000h
mov si,cx
add si,cx ; 1 cluster pointer = 2 bytes
jnc short Reset_FAT16_c_clust
mov ax,9000h ; Second FAT buffer segment
Reset_FAT16_c_clust:
mov ES,ax
mov cx, Word Ptr ES:[si]
mov Word Ptr ES:[si], 0
cmp cx, 0FFF0h ; Clears CF if at end of file
jb short Reset_FAT16Clusts
retn
Reset_FAT12Clusts:
mov ax, 8000h
mov ES, ax
Reset_FAT12_next_clust:
mov si,cx ; Multiply by 3/2
add si,si
add si,cx
shr si,1
mov cx,Word Ptr ES:[si]
mov ax,cx
jnc short reset_nc_even
and ax,0Fh
shr cx,1 ; Needed for odd only
shr cx,1
shr cx,1
shr cx,1
jmp short pass_reset_nc_even
Reset_nc_even:
and ax,0F000h
pass_reset_nc_even:
mov word ptr ES:[SI],ax
and ch,0Fh
cmp cx,0FF0h
jb short Reset_FAT12_next_clust
return_from_reset_file_clusts:
retn
proc_reset_file_clusters endp
proc_find_first_free_clust proc near
; Input CX = Number of clusters
mov bx,2 ; Beginning Cluster
mov ax,8000h ; First FAT buffer segment
mov ES,ax
cmp Word Ptr [bp][Sectors],0 ; Is it > 32M (FAT12 limit) ?
ja short Find_FreeFAT12Clust
Find_FreeFAT16Clust:
mov si,bx
add si,bx ; 1 cluster pointer = 2 bytes
jnc short fffc_update_fat16_clust
mov ax,9000h ; Second FAT buffer segment
mov ES,ax
fffc_update_fat16_clust:
cmp Word Ptr ES:[si], 0
je short return_from_fffc
inc bx
loop Find_FreeFAT16Clust
mov bx,0
return_from_fffc:
retn
Find_FreeFAT12Clust:
mov si,bx ; Multiply by 3/2
add si,si
add si,bx
shr si,1
mov ax,Word Ptr ES:[si]
jnc short fffc_nc_even
shr ax,1 ; Needed for odd only
shr ax,1
shr ax,1
shr ax,1
fffc_nc_even:
and ah,0Fh
cmp ax,0
je short return_from_fffc
inc bx
loop Find_FreeFAT12Clust
mov bx,0
retn
proc_find_first_free_clust endp
proc_allocate_clusters proc near
mov bx, word ptr [File_FClust]
mov ax, bx
mov dx, 8000h
mov ES, dx
cmp Word Ptr [bp][Sectors],0 ; Is it > 32M (FAT12 limit) ?
ja short Alloc_check_FAT12_free_clust
Alloc_check_FAT16_free_clust:
dec cx
jnz short pass_retn_from_FAT16_clust_alloc
retn_from_fat16_clust_alloc:
mov si, bx
add si, bx
jnc short pass_inc_alloc_FAT16_buffer_seg
mov dx, 9000h
mov ES, dx
pass_inc_alloc_FAT16_buffer_seg:
mov word ptr ES:[SI], 0FFFFh
retn
pass_retn_from_FAT16_clust_alloc:
inc ax
cmp ax, word ptr [Number_of_Clusts]
ja short retn_from_FAT16_clust_alloc
mov si,ax
add si,ax
jnc short pass_alloc_check_FAT16_free_clust
mov dx,9000h
mov ES,dx
pass_alloc_check_FAT16_free_clust:
cmp Word Ptr ES:[SI],0
ja short pass_retn_from_FAT16_clust_alloc
Allocate_FAT16Clusts:
mov dx,8000h
mov si,bx
add si,bx
jnc short Alloc_fat16_next_pointer
mov dx,9000h
Alloc_fat16_next_pointer:
mov ES,dx
mov word ptr ES:[SI],ax
mov bx,ax
jmp short Alloc_check_FAT16_free_clust
Alloc_check_FAT12_free_clust:
dec cx
jnz pass_retn_from_FAT12_clust_alloc
retn_from_fat12_clust_alloc:
mov ax, 0FFFh
mov si, bx
add si, si
add si, bx
shr si, 1
mov dx, word ptr ES:[SI]
jnc short Alloc_FAT12_pclust_even
and dx, 0Fh
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
jmp short pass_alloc_FAT12_pclust_even
Alloc_FAT12_pclust_even:
and dx, 0F000h
pass_alloc_FAT12_pclust_even:
or ax, dx
mov word ptr ES:[SI], ax
retn
pass_retn_from_FAT12_clust_alloc:
inc ax
cmp ax, word ptr [Number_of_Clusts]
ja short retn_from_FAT12_clust_alloc
mov si, ax ; Multiply by 3/2
add si, si
add si, ax
shr si, 1
mov dx, Word Ptr ES:[SI]
jnc short Alloc_FAT12_c_even
shr dx, 1 ; Needed for odd only
shr dx, 1
shr dx, 1
shr dx, 1
Alloc_FAT12_c_even:
and dh, 0Fh
cmp dx, 0
ja short pass_retn_from_FAT12_clust_alloc
Allocate_FAT12Clusts:
push ax
mov si, bx ; Multiply by 3/2
add si, si
add si, bx
shr si, 1
mov dx, Word Ptr ES:[SI]
jnc short Alloc_FAT12_lc_even
and dx, 0Fh
shl ax, 1 ; Needed for odd only
shl ax, 1
shl ax, 1
shl ax, 1
jmp short pass_alloc_FAT12_lc_even
Alloc_FAT12_lc_even:
and dx, 0F000h
pass_alloc_FAT12_lc_even:
or ax, dx
mov word ptr ES:[SI], ax
pop ax
mov bx, ax
jmp short Alloc_check_FAT12_free_clust
proc_allocate_clusters endp
proc_nextwrite proc near
mov Word Ptr [Register_AX],3030h
push CX ; Save the cluster number
mov AX,CX
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_write
pop CX
retn
proc_nextwrite endp
proc_file_write proc near
call proc_nextwrite
jc short F_EndOfWrite
cmp Word Ptr [bp][Sectors],0 ; Is it > 32M (FAT12 limit) ?
jz short F_WriteFAT16Clust
jmp short F_WriteFAT12Clust
F_FAT16Next_Write:
call proc_nextwrite
jnc short F_WriteFAT16Clust
retn
F_WriteFAT16Clust:
dec word ptr [Counter]
cmp word ptr [Counter], 0
jna short F_EndOfWrite
push ES
mov si, 8000h ; First FAT buffer segment
mov ES,si
mov si,cx
add si,cx ; 1 cluster pointer = 2 bytes
jnc short F_w_updateclustno
mov cx, 9000h ; Second FAT buffer segment
mov ES,cx
F_w_updateclustno:
mov cx,Word Ptr ES:[si]
pop ES
cmp cx,0FFF0h ; Clears CF if at end of file
jnb short F_EndOfWrite
jmp short F_FAT16Next_write
F_FAT12Next_Write:
call proc_nextwrite
jnc short F_WriteFAT12Clust
retn
F_WriteFAT12Clust:
dec word ptr [Counter]
cmp word ptr [Counter], 0
jna short F_EndOfWrite
push ES
mov si,8000h
mov ES,si
mov si,cx ; Multiply by 3/2
add si,si
add si,cx
shr si,1
mov cx,Word Ptr ES:[si]
jnc short F_w_nc_even
shr cx,1 ; Needed for odd only
shr cx,1
shr cx,1
shr cx,1
F_w_nc_even:
pop ES
and ch,0Fh
cmp cx,0FF0h
jb short F_FAT12Next_Write
F_EndOfWrite:
retn
proc_file_Write endp
proc_save_fats proc near
xor ch, ch
mov cl, byte ptr [bp][FATs]
mov ax, word ptr [bp][Hidden1]
mov dx, word ptr [bp][Hidden2]
add ax, word ptr [bp][ResSectors]
adc dx, 0
loc_write_FAT_sectors:
push cx
mov cx, word ptr [bp][FATsecs]
mov bx, 8000h
mov es, bx
xor bx, bx
call proc_write
pop cx
jc loc_failed
loop loc_write_FAT_sectors
retn
proc_save_fats endp
proc_save_root_dir proc near
mov ax, 20h
mov cx, word ptr [bp][RootDirEnts]
mul cx
mov bx, word ptr [bp][BytesPerSec]
add ax, bx
dec ax
div bx
mov cx, ax ; Number of root directory sectors
mov ax, word ptr [RootDir1]
mov dx, word ptr [RootDir2]
mov bx, 7000h
mov es, bx
xor bx, bx
call proc_write
jc loc_failed
retn
proc_save_root_dir endp
proc_trq_kbd proc near
; xor BX,BX
; mov ES,BX
mov BP,58h
mov AX, offset INT16h_handler
mov DX, Word ptr ES:[BP]
cmp AX,DX
jnz short pass_INT16h_segment_ctrl
mov BX,DS
cmp Word ptr ES:[BP]+2,BX
jz short loc_tr_return
pass_INT16h_segment_ctrl:
mov word ptr ES:[BP],AX
mov Word Ptr [var_INT16h_off],DX
mov DX, Word ptr ES:[BP]+2
mov Word Ptr [var_INT16h_seg],DX
mov DX,DS
mov word ptr ES:[BP]+2,DX
; push DS
; pop ES
mov AX,1100h
mov BX,1000h
mov CX,1
mov DX,8Dh
mov BP,offset var1_193
int 10h ; BIOS Service func ( ah ) = 11h
; Screen function
mov DX,98h
mov BP,offset var1_183
int 10h ; BIOS Service func ( ah ) = 11h
; Screen function
mov CX,2
mov DX,0A6h
mov BP,offset var1_163
int 10h ; BIOS Service func ( ah ) = 11h
; Screen function
mov DX,9Eh
mov BP,offset var1_1A3
int 10h ; BIOS Service func ( ah ) = 11h
; Screen function
mov SI,offset var1_1eb
loc_tr_print:
lodsb ; Load byte at DS:SI to AL
and AL,AL
je short loc_tr_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_tr_print
loc_tr_return:
retn
var_KBD: dw 'EN'
var_INT16h_off: dw 0
var_INT16h_seg: dw 0
INT16h_handler:
or AH, 10h
cmp AH, 10h
jz short CS:loc_convert_char_codes
jmp Dword ptr CS:var_INT16h_off
loc_convert_char_codes:
pushf
call Dword ptr CS:var_INT16h_off
pushf
push AX
push ES
push SI
mov SI,40h
mov ES,SI
mov SI,17h
mov AL,Byte ptr ES:[SI]
and AL,08h ; BIOS DATA AREA
; Keyboard Status
pop SI
pop ES
pop AX
jz short loc_check_INT16h_AH
cmp AH,78h
jb short pass_right_alt_numbers
cmp AH,82h
ja short pass_right_alt_numbers
push SI
push AX
mov AL,82h
sub AL,AH
xor AH,AH
mov SI,offset data_right_alt_numbers
add SI,AX
pop AX
mov AL,Byte ptr CS:[SI]
pop SI
jmp short return_from_INT16h
data_right_alt_numbers:
db "\}][{"
dw 0
db "$#"
dw 0
dw 0
pass_right_alt_numbers:
cmp AH,10h
jnz short pass_alt_right_q
mov AL,"@"
jmp short pass_alt_right_ctrl
pass_alt_right_q:
cmp AH,1Bh
jnz short pass_alt_right_5Dh
mov AL,"~"
jmp short pass_alt_right_ctrl
pass_alt_right_5Dh:
cmp AH,2Bh
jnz short pass_alt_right_59h
mov AL,60h
jmp short pass_alt_right_ctrl
pass_alt_right_59h:
cmp AH,56h
jnz short pass_alt_right_ctrl
mov AL,"|"
pass_alt_right_ctrl:
jmp short return_from_INT16h
loc_check_INT16h_AH:
cmp AH,0
jna short return_from_INT16h
cmp AH,56h
jnz short pass_change_56h_ascii_codes
cmp AL,5Ch
jnz short pass_change_5Ch
mov AL,"<"
jmp short return_from_INT16h
pass_change_5Ch:
cmp AL,7Ch
jnz short return_from_INT16h
mov AL,">"
jmp short return_from_INT16h
pass_change_56h_ascii_codes:
cmp AH,35h
ja short return_from_INT16h
loc_change_al_by_xlat:
push DS
push CS
pop DS
push BX
mov BX,offset xlat_lookup_table
xlat
pop BX
pop DS
return_from_INT16h:
popf
IRET
var1_163 dw 3C66h, 3C00h, 0C066h
dw 0C0C0h, 0C6DEh, 3A66h
db 6 dup (0)
db 66h, 3Ch, 0
db ';fffff>'
db 6, 66h, 3Ch, 0
var1_183 db 18h, 18h, 0
db 3Ch
db 7 dup (18h)
db 3Ch
dd 0
var1_193 db 5 dup (0)
db 38h
db 5 dup (18h)
db 3Ch
dd 0
var1_1A3 dw 0
db 7Ch, 0C6h, 0C6h, 60h
db 38h, 0Ch
db 6, 0C6h, 0C6h, 7Ch, 18h, 38h
db 7 dup (0)
db 7Ch, 0C6h, 60h, 38h, 0Ch, 0C6h
db 7Ch, 18h, 38h, 0, 0
var1_1eb db 0Dh, 0Ah
db 'TšRK€E FONT YšKLEND˜...'
db 0Ah, 0Dh, 0h
xlat_lookup_table:
db 00h,01h,02h,03h,04h,05h,06h,07h,08h,09h,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
db 10h,11h,12h,13h,14h,15h,16h,17h,18h,19h,1Ah,1Bh,1Ch,1Dh,1Eh,1Fh
db 20h,21h,98h,5Eh,2Bh,25h,2Fh,69h,29h,3Dh,28h,5Fh,94h,2Ah,87h,2Eh
db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h,9Eh,9Fh,99h,2Dh,80h,3Ah
db 27h,41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh
db 50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,0A7h,2Ch,81h,26h,3Fh
db 22h,61h,62h,63h,64h,65h,66h,67h,68h,08Dh,6Ah,6Bh,6Ch,6Dh,6Eh,6Fh
db 70h,71h,72h,73h,74h,75h,76h,77h,78h,79h,7Ah,0A6h,3Bh,9Ah,82h,7Fh
db 80h,81h,82h,83h,84h,85h,86h,87h,88h,89h,8Ah,8Bh,8Ch,8Dh,8Eh,8Fh
db 90h,91h,92h,93h,94h,95h,96h,97h,98h,99h,9Ah,9Bh,9Ch,9Dh,9Eh,9Fh
db 0A0h,0A1h,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,0AAh,0ABh,0ACh
db 0ADh,0AEh,0AFh
db 0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h,0B8h,0B9h,0BAh,0BBh,0BCh
db 0BDh,0BEh,0BFh
db 0C0h,0C1h,0C2h,0C3h,0C4h,0C5h,0C6h,0C7h,0C8h,0C9h,0CAh,0CBh,0CCh
db 0CDh,0CEh,0CFh
db 0D0h,0D1h,0D2h,0D3h,0D4h,0D5h,0D6h,0D7h,0D8h,0D9h,0DAh,0DBh,0DCh
db 0DDh,0DEh,0DFh
db 0E0h,0E1h,0E2h,0E3h,0E4h,0E5h,0E6h,0E7h,0E8h,0E9h,0EAh,0EBh,0ECh
db 0EDh,0EEh,0EFh
db 0F0h,0F1h,0F2h,0F3h,0F4h,0F5h,0F6h,0F7h,0F8h,0F9h,0FAh,0FBh,0FCh
db 0FDh,0FEh,0FFh
proc_trq_kbd endp
proc_bcd_to_binary proc near
; 07/05/2000
; INPUT -> AL = BCD number
; OUTPUT -> AL = Binary (Hex) number
mov ah, al
shr ah,1
shr ah,1
shr ah,1
shr ah,1
and al, 00001111b
aad
retn
proc_bcd_to_binary endp
Hard_Disk: db 80h
Partition: db 0
HdResetFailedMsg: db 0Dh,0Ah
db "Drive is not ready !"
db 0Dh, 0Ah, 0h
Not_masterboot:
db 0Dh, 0Ah
db "MASTER"
Not_boot_sec:
db "BOOT ERROR : Not a valid boot sector !"
db 0Dh, 0Ah, 0h
Not_dos_disk:
db 0Dh, 0Ah
db "It is not a DOS disk !"
db 0Dh, 0Ah, 0h
No_Active_Part:
db 0Dh, 0Ah
db "Active partition not found !"
db 0Dh, 0Ah, 0h
Dos_P_Not_Found:
db 0Dh, 0Ah
db "DOS partition not found !"
db 0Dh, 0Ah, 0h
Ext_Dos_P_Not_Found:
db 0Dh, 0Ah
db "Extended DOS partition not found !"
db 0Dh, 0Ah, 0h
Ext_dos_not_boot:
db 0Dh, 0Ah
db "Extended DOS partition is not bootable !"
db 0Dh, 0Ah, 0h
Logical_Drv_Not_Valid:
db 0Dh, 0Ah
db "It is not a valid DOS logical drive !"
db 0Dh, 0Ah, 0h
P_Table_Header:
db 0Dh, 0Ah
db "PARTITION TABLE of hd"
PT_Drive_Num: db '0'
db 0Dh, 0Ah, 0Dh, 0Ah
db "PN S BH BS BC FS EH ES EC START SEC SECTORS FILE SYSTEM"
db 0Dh, 0Ah
db "-- --- --- --- --- --- --- --- --- --------- --------- -----------"
db 0Dh, 0Ah, 0h
Partition_Table:
db "p"
P_Number: db 0,20h
P_Status: dw 0
db "h "
Begin_Head: dw 0
db "h "
Begin_Sec: dw 0
db "h "
Begin_Cyl: dw 0
db "h "
FS_ID: dw 0
db "h "
End_Head: dw 0
db "h "
End_Sec: dw 0
db "h "
End_Cyl: dw 0
db "h "
P_Start_Sec: dd 0
dd 0
db " "
P_Sectors: dd 0
dd 0
db " "
P_FileSystem: db 11 dup(20h)
db 0Dh, 0Ah, 0h
FileSys_Names:
db " "
db "DOS FAT12 " ; 01h , DOS FAT12 (< 16 MB)
db "XENIX " ; 02h , (SCO) XENIX Partition
db "XENIX User " ; 03h , (SCO) XENIX User Partition
db "DOS FAT16 " ; 04h = FAT16 < 32MB
db "DOS EXT " ; 05h = Extended DOS Partition
db "DOS FAT16 " ; 06h = FAT16 > 32MB, CHS Mode
FS_NTFS: db "WINDOWS NT " ; 07h , WINDOWS 2000 NTFS Partition
FS_WIN_32: db "WIN4 FAT32 " ; OBh = FAT32 CHS, 0Ch = FAT32 LBA
FS_WIN_P: db "WIN4 FAT16 " ; 0Eh = FAT16, LBA Mode
FS_WIN_EXT: db "WIN4 EXT " ; 0Fh = Extented Partition, LBA Mode
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 "
Cmd_Line_Pointer:
dw 0
Dir_Pointer:
dw 0
Msg_Wrong_Drv_Name:
db "Wrong drive name !"
db 0
Msg_Wrong_Dir_Name:
db "Wrong directory name !"
db 0
Msg_Wrong_File_Name:
db "Wrong file name !"
db 0
Msg_Wrong_Cmd_Par:
db "Wrong command parameter !"
db 0
Msg_Wrong_Address:
db "Wrong address !"
db 0
Msg_Wrong_Sector:
db "Wrong sector number !"
db 0
Msg_Wrong_Count:
db "Wrong sector count !"
db 0
Msg_Wrong_Device_name:
db "Wrong device name !"
db 0
Msg_Wrong_Cluster:
db "Wrong cluster number !"
db 0
Msg_Wrong_Size:
db "Invalid size !"
db 0
Msg_Specify_File_Name:
db "You must specify a file name as command parameter !"
db 0Dh,0Ah,0
Msg_Specify_Dir_Name:
db "You must specify a directory name !"
db 0Dh,0Ah,0
Msg_S_Correct_File_Names:
db "* File names must be MS-DOS compatible."
db 0Dh, 0Ah
db "* File name extensions must be "
Msg_R_com: db "TOR, BIN, STD or RTS."
db 0Dh, 0Ah, 0
Msg_Big_File_size:
db "File has over size for loading (by this command) !"
db 0Dh,0Ah,0
Start_Pointer:
dw 0
Start_Segment:
dw 4000h
INT20h_Offset:
dw 0
INT20h_Segment:
dw 0
Msg_Loading_Address:
db 0Dh, 0Ah
db "Segment : "
Segment_Addr:
db "4000h"
db 20h
db 20h
db "Offset : "
Offset_Addr:
db 4 dup(30h)
db "h"
db 0Dh, 0Ah, 0
Device_Number:
db 0
Device_Displacement:
dw 0
Device_Section:
dw 0
Device_Sector_Count:
dw 1
Device_Name_Label:
db "Device : "
db 0
Device_Name:
db "fd0"
db 0
Device_Number_Str:
dw 0
db "h"
db 0
Decimal_Sector_Label:
db "Sector : "
db 0
Decimal_Sector:
db 11 dup (0)
Decimal_Sector_Count_Label:
db "Count : "
db 0
Decimal_Sector_Count:
db 30h, 30h, 31h
db 0
Device_Sector_Count_Str:
dd 0
db "h"
db 0
Msg_Disk_Reading_Address:
db 0Dh, 0Ah
db "Section : "
Section_Str:
db 4 dup(30h)
db "h"
db 20h
db 20h
db "Displacement : "
Displacement_Str:
db 4 dup(30h)
db "h"
db 0Dh, 0Ah, 0
Boot_Sec_Params:
db 64 dup (0)
Printer_Hex: db 0
Msg_VolumeLabel:
db 0Dh, 0Ah
db "Volume Label : "
Disk_Name: db 12 dup(0)
Msg_VolumeID:
db 0Dh, 0Ah
db "Serial Number : "
Disk_Serial: db 9 dup(0)
db 0Dh, 0Ah, 0
msg_warning:
db 0Dh, 0Ah
db "WARNING ! "
db 0
msg_ask_for_overwrite:
db "Are you sure of you want overwrite sector(s) on drive "
db 0
msg_hex_edit:
db "HEXADECIMAL EDITOR [ Press ENTER to update or ESC to exit. ]"
db 0
msg_freespace:
db "Free Space : "
db 0
FreeSpace: db 12 dup(20h)
db 0
msg_Bytes: db "bytes"
db 0
msg_Sectors:
db "sectors"
db 0
str_NTFS:
db "NTFS"
db 0
msg_Number_Of_Clust:
db "Number Of Clusters : "
db 0
Number_Of_Clusts: dw 0
Clust_Of_Dir: dw 0
Save_Size_L: dw 200h
Save_Size_H: dw 0
; Prev_Cmd: db 0
CmdNo: db 0FFh
Status: db 0
Triple_Space: db 20h
Double_Space: dw 2020h
db 0
Str_First_Cluster:
db "First "
Str_Cluster: db "Cluster : "
Cluster_Addr db 4 dup(30h)
db "h"
db 0
Cluster: dw 0
Str_Next db "Next "
db 0
Str_FirstFree: db "First Free "
db 0
Msg_File_Overwrite:
db "Overwrite "
db 0
Msg_File_Erase:
db "Erase "
db 0
Msg_Yes_No: db " (Yes/No) ? "
db 0
Msg_saveas:
db "Save"
Msg_as: db " as "
db 0
Msg_rename:
db "Rename "
db 0
Msg_Create_Dir:
db "Make directory "
db 0
Msg_Remove_Dir:
db "Remove directory "
db 0
Msg_no_enough_space:
db "Insufficient disk space !"
db 0
Msg_Dir_Exist:
db "Directory exists with same name !"
db 0
Msg_File_Exist:
db "File exists with same name !"
db 0
Msg_no_space_dir:
db "No entry space in directory !"
db 0
Msg_dir_not_empty:
db "Directory not empty !"
db 0
Msg_Permission_Denied:
db "Permission denied !"
db 0
Msg_File_Done:
db 0Dh, 0Ah
db "Done..."
db 0
Attributes: db 0
Str_Attributes:
db "Attributes : "
Attr_Chars: db "NORMAL"
db 0
Str_Size:
db "Size : "
db 0
Decimal_Size:
db 7 dup(0)
db 20h
db "byte"
Multi_Byte: dw 0
Hex_Size1:
dw 0
Hex_Size2:
dw 0
Msg_drive_info:
db 0Dh, 0Ah
db "TR-DOS DRIVE : "
str_info_drv_name: db "fd0"
db 0Dh, 0Ah
db 0Dh, 0Ah
db "OEM Name : "
str_oemname: db 8 dup(20h)
db 0Dh, 0Ah
db "Bytes Per Sector : "
val_bytespersec: dd 0
db "h"
db 0Dh, 0Ah
db "Sectors Per Cluster : "
val_secperclust: dw 0
db "h"
db 0Dh, 0Ah
db "Reserved Sectors : "
val_ressectors: dd 0
db "h"
db 0Dh, 0Ah
db "Number Of FATs : "
val_fats: dw 0
db "h"
db 0Dh, 0Ah
db "Root Directory Entries : "
val_rootdirents: dd 0
db "h"
db 0Dh, 0Ah
db "Total Sectors : "
val_sectors: dd 0
db "h"
db 0Dh, 0Ah
db "Media : "
val_media: dw 0
db "h"
db 0Dh, 0Ah
db "FAT Sectors : "
val_fatsecs: dd 0
db "h"
db 0Dh, 0Ah
db "Sectors Per Track : "
val_secpertrack: dd 0
db "h"
db 0Dh, 0Ah
db "Heads : "
val_heads: dd 0
db "h"
db 0Dh, 0Ah
db "Hidden Sectors : "
val_hidden2: dd 0
val_hidden1: dd 0
db "h"
db 0Dh, 0Ah
db "Total Sectors (Huge) : "
val_hugesec2: dd 0
val_hugesec1: dd 0
db "h"
db 0Dh, 0Ah
db "Drive Number : "
val_drivenumber: dw 0
db "h"
db 0Dh, 0Ah
db "Reserved Byte : "
val_reserved1: dw 0
db "h"
db 0Dh, 0Ah
db "Boot Signature : "
val_bootsignature: dw 0
db "h"
db 0Dh, 0Ah
db "Volume ID : "
val_volumeid: dd 0
dd 0
db 0Dh, 0Ah
db "Volume Label : "
str_volumelabel: db 11 dup(20h)
db 0Dh, 0Ah
db "File System : "
str_filesystype: db 8 dup (20h)
db 0Dh, 0Ah
db 0
Str_Standalone:
db "CENTRAL.BIN"
db 0
Default_Command_File:
db "P2000.DEF"
db 0
Msg_P2000_Version:
db 0Dh, 0Ah
db "TR-DOS Presentation 2000 Version: 1.1b"
db 0Dh, 0Ah
db "[ (c) Erdogan Tan - 1999 ]"
db 0Dh, 0Ah, 0
Msg_Build: db 0Dh, 0Ah
db "P2000.COM -> BUILD: 2000.12.17"
db 0Dh, 0Ah, 0
MagicBytes: db "417"
Char_Input: db 0
MagicWord: dw 01A1h
Present ends
end start