Code: Select all
'' --------------------------------------------------------------------
'' ### DISK VIEWER (R) ###
'' (CL) 2008 by DOS386 | Public Domain | ABUSE at your own risk !!!
'' DOS only !!! | Requires a recent DOS kernel (FreeDOS, EDR-DOS)
'' --------------------------------------------------------------------
#include "dos/go32.bi" '' DPMI stuff declarations
type UINT32 as UINTEGER
type UINT8 as UBYTE
type PUINT8P as UBYTE PTR
declare sub SECTEX (BYVAL AS UINT32, BYVAL AS UINT32)
DIM SHARED AS UINT32 DDS , LTB , STB
DIM SHARED AS PUINT8P MYBUF
DIM SHARED AS UINT32 VGN32MYBUF, VGN32MYPOS, VGN32SEC
DIM SHARED AS STRING VGSLINE1, VGSLINE2
DIM SHARED AS UINT8 AA
'' --------------------------------------------------------------------
'' Init GO32
DDS = _go32_info_block.selector_for_linear_memory
LTB = _go32_info_block.linear_address_of_transfer_buffer
MYBUF=ALLOCATE(512)
VGN32MYBUF=CAST(UINT32,MYBUF)
? HEX$(VGN32MYBUF) : ?
VGN32SEC=0
DO
? "Sector: " + STR$(VGN32SEC) + " | [SPACE] -> next | [P] -> previous | [ESC] -> ???" : ?
SECTEX (VGN32SEC,VGN32MYBUF)
VGN32MYPOS=0
DO
IF ((VGN32MYPOS AND 15)=0) THEN
VGSLINE1=HEX$(VGN32MYPOS)+" : " : VGSLINE2=" "
IF LEN(VGSLINE1)=4 THEN VGSLINE1="00" + VGSLINE1
IF LEN(VGSLINE1)=5 THEN VGSLINE1="0" + VGSLINE1
ENDIF
AA=PEEK(VGN32MYBUF+VGN32MYPOS)
VGN32MYPOS=VGN32MYPOS+1
IF (AA<16) THEN
VGSLINE1=VGSLINE1 + "0"
ENDIF
VGSLINE1=VGSLINE1 + HEX$(AA) + " "
IF ((AA<32) OR (AA>126)) THEN AA=46
VGSLINE2=VGSLINE2+CHR$(AA)
IF ((VGN32MYPOS AND 15)=0) THEN ? VGSLINE1+VGSLINE2
IF (VGN32MYPOS=512) THEN EXIT DO
LOOP
?
DO
AA=ASC(INKEY$)
IF (AA=112) THEN AA=80 '' UCASE$("P")
IF ((AA=27) OR (AA=32) OR (AA=80)) THEN EXIT DO
LOOP
IF (AA=27) THEN EXIT DO
IF (AA=32) THEN VGN32SEC=VGN32SEC+1
IF ((AA=80) AND (VGN32SEC<>0)) THEN VGN32SEC=VGN32SEC-1
LOOP
END
'' --------------------------------------------------------------------
SUB SECTEX (BYVAL VLN32SEC AS UINT32, BYVAL VLN32ADDR AS UINT32)
'' Logical disk "absolute" sector read - INT $21/$7305
''
'' IN: ???
'' OUT: ???
''
'' Memory: 0: $32 bytes INT $31 | $32: $0E bytes wasted
'' $40: 6 bytes "packet" | $46: $0A bytes wasted
'' $50: 1.5 KiB stack | $650: buffer
''
'' Uses globals: LTB (linear addr of buffer) and DDS (ZERO-based selector)
ASM
mov edi,[LTB] '' For clear (2 KiB) and INT (based on ES, size=$32)
mov eax,[DDS]
push eax
pop es '' !!! Trashing ES
cld
xor eax,eax '' For DPMI simulant INT $31 and clearing
xor ecx,ecx '' &
mov ch,2 '' & MOVNTQ ECX,512
push edi
rep stosd '' [ES:EDI] ZERO'izing 2 KiB | side effect: ECX==0
pop edi
mov ah,3 '' @ For DPMI simulant INT $31 / $0300 see far below
mov bl,0x21 '' @ BL=$21 | Don't touch AX and BX below
mov bh,0 '' @ BH=0 (crap flags)
dec ecx
mov [es:edi+0x18],ecx '' CX / ECX = $FFFF
inc ecx '' !!! see below
mov cx,0x7305 '' % "absolute" thing
mov [es:edi+0x1C],cx '' % AX
mov ecx,edi '' @ Linear
shr ecx,4 '' @ To segment | high 16 bits==0
add ecx,4 '' @ Skip $32 -> $40 bytes | high 16 bits ==0
mov [es:edi+0x24],cx '' @ Segment address of "packet" (OFF***=0)
inc ecx '' @ Now + $50
mov [es:edi+0x30],cx '' @ SS
add ecx,0x60 '' @ Now + $0650 | Buffer starts $610 bytes after
mov [es:edi+0x48],cx '' @ Buffer segment address in "packet" (OFF***=0)
mov dh,6 '' & 1.5 KiB stack
mov [es:edi+0x2F],dh '' & SP high byte
mov dl,3 '' Drive "C:"
mov [es:edi+0x14],dl '' DL
mov edx,[VLN32SEC]
mov [es:edi+0x40],edx '' Sector number
mov dl,1
mov [es:edi+0x44],dl '' Amount of sectors
pushf
pop edx
mov [es:edi+0x20],dl '' FLAGS 16-bit only, we poke only 8-bit
xor ecx,ecx '' MOVNTQ ECX,0
int 0x31 '' AX==$0300 | BX==$21 see far above
mov edi,[LTB] '' Again ??? Required ???
mov eax,[DDS]
push eax
pop es '' !!! Trashing ES
cld
mov bl,[es:edi+0x20] '' FLAGS
shr bl,1 '' Now we have it in flag (C)
jnc xx1 '' OK
ud2
xx1: mov esi,[VLN32ADDR] '' & Our destination, but for now in ESI !!!
xchg esi,edi '' & Fix ^^^ it
add esi,0x0650 '' & Skip DPMI simulant structure + more garbage
push ds '' @ non-ZERO
push es '' @ ZERO | SWAP DS,ES | No "XCHG DS,ES" :-(
pop ds '' @ ZERO
pop es '' @ non-ZERO
xor ecx,ecx '' & MOVNTQ ECX, $80
mov cl,0x80 '' & -> $0200 bytes
rep movsd '' [ES:EDI]<-[DS:ESI] | ESI and EDI trashed
push es '' @
pop ds '' @ Crucial !!!
END ASM
END SUB
'' --------------------------------------------------------------------
'' INT $21 / $7305
'' FreeDOS, EDR-DOS (Windaube95) - FAT32 - EXTENDED ABSOLUTE DISK READ/WRITE
'' AX = $7305
'' CX = $FFFF
'' DL = drive number (1=A:, etc.)
'' SI = read/write mode flags (see #01791)
'' Bitfields for Extended Absolute Disk Read/Write mode flags:
'' Bit(s) Description (Table 01791)
'' 0 direction (0=read, 1=write)
'' 12-1 reserved (0)
'' 14-13 write type (should be 00 on reads)
'' 00 unknown data
'' 01 FAT data
'' 10 directory data
'' 11 file data
'' 15 reserved (0)
'' Format of disk read packet:
'' DS:BX -> disk I/O packet (see #02548 at INT 25)
'' Offset Size Description (Table 02548)
'' 0 DWORD sector number
'' 4 WORD number of sectors to read
'' 6 DWORD transfer address OFF:SEG ???
'' Return: CF clear if successful
'' CF set on error
'' AX = error code
'' Note: one can not specify the default drive (DL=0) for this function.
'' --------------------------------------------------------------------
'' INT $31 / $0300
'' $00 DWORD EDI
'' $04 DWORD ESI
'' $08 DWORD EBP
'' $0C DWORD reserved (0)
'' $10 DWORD EBX
'' $14 DWORD EDX
'' $18 DWORD ECX
'' $1C DWORD EAX
'' $20 WORD flags
'' $22 WORD ES
'' $24 WORD DS
'' $26 WORD FS
'' $28 WORD GS
'' $2A WORD IP
'' $2C WORD CS
'' $2E WORD SP
'' $30 WORD SS
'' $32 END :-)
'' --------------------------------------------------------------------
FYI: It's a NEW 32-bit DOS example / "application"
Lacks:
- no write
- only 1 sector per call
- no disk size overflow check (at least sector 0 underflow is checked)
- lousy error handling
Should work with any intact DPMI host or extender (D3X, WDOSX, HDPMI32, CWSDPMI (?) ).
So if someone wants to code a disk editor (no big need, we have WDe disk editor by Ben Cadieux and HDEDIT by Japheth ), or a Defrag (big need, FreeDOS DEFRAG still doesn't really work), this is the starting point ;-)
EDIT : enhanced thread subject