home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1995 November
/
PCWK1195.iso
/
inne
/
podstawy
/
dos
/
format
/
fdform18.exe
/
FDREAD.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-07-21
|
25KB
|
477 lines
page 68,129
IFIS286 MACRO cp,i
IFIDN <CP>,</$G+>
ENDM
IFIS88 MACRO cp,i
IFIDN <CP>,</$G->
ENDM
IFNDEF CPU
%out No CPU defined for Assembly, defaulting to 286
CPU EQU </$G+>
ENDIF
IFIS286 %CPU
.286
ENDIF
title fdread - lesen von disketten aller formate
.radix 10
startadr equ 0ff80h
cseg segment use16 word public 'code'
assume cs:cseg,ds:nothing,es:nothing,ss:nothing
org 0
lex equ offset end_hdr-offset int13_2
lex2 equ (lex+15)/16
lex3 equ offset begin-offset start
lex4 equ (lex3+15)/16
int13_2 label dword ;HMA Einsprung INT13
int13_2ofs dw entry ;Offset-Teil
int13_2seg dw ? ;Segment-Teil
xms label dword ;Speicher für XMS-Einsprungaddresse
xms_ofs dw ?
xms_seg dw ?
.286 ;Der folgende Teil wird nur bei 286+ relevant
int13_1 proc far ;INT-09 Handler
pusha ;Alle Register retten
mov ah,7 ;Code für A20 testen
call dword ptr xms ;Rufe XMS-Manager auf
dec ax ;Ist A20 enabled (Ja: AX=1)
jz ret1 ;Wenn, ja ist hier alles erledigt
mov ah,5 ;Code für A20 local enablen
call dword ptr xms ;Rufe XMS-Manager auf
ret1: popa ;Alle Register wiederherstellen
jmp int13_2 ;Führe den eigentlichen Handler aus
int13_1 endp
.8086
end_hdr:
org startadr
start:
IFIS286 %CPU
even
.286
ENDIF
old13 label dword ;Speicherung des alten Interrupt 13
old13_ofs dw ? ;Offset-Teil
old13_seg dw ? ;Segment-Teil
oldsec db ?
entry proc far
push ax ;AX retten
or ah,ah ;Wurde Funktion 0 RESET aufgerufen?
jz donothing ;Ja, dann Ende
cmp ah,4 ;Wurde Funktion über 4 aufgerufen?
ja donothing ;Ja, dann Ende
cmp dl,3
ja donothing
push bx ;...Register...
push ds ;...retten
IFIS286 %CPU
push 0
ELSE
xor bx,bx
push bx
ENDIF
pop ds
lds bx,ds:[78h] ;Disk-Parameter Tabelle in DS:BX
mov al,ds:[bx+4]
mov oldsec,al
mov byte ptr ds:[bx+4],1Bh ;Setze auf maximal 25 Sektoren/Spur
IFIS286 %CPU
or ch,ch ;Track 0 ?
jz exit ;Ja, dann Ende
ENDIF
pop ds ;Alle...
pop bx ;...Register...
pop ax ;...zurückholen.
push ax ;AX für später speichern
pushf ;Flags pushen da INT-CALL
call old13 ;Alten INT 13 aufrufen
IFIS286 %CPU
jnc okexit ;Kein Fehler, dann Ende
pop ax ;Hole uns AX zurück
push ds ;Speichere...
push bx ;...DS & BX
push 40h ;BIOS-Data Segment...
pop ds ;...nach DS
mov bx,90h ;Beginn der Drive-Tabelle
add bl,dl ;Offset des Laufwerks
cmp ch,43 ;Track>43
ja nodstep ;Ja, dann niemals DSTEP
xor byte ptr ds:[bx],20h ;invertiere das Stepper-Bit
jmp short stepend ;Ende vom Stepping
nodstep: and byte ptr ds:[bx],0dfh ;Kein Double-Stepping
stepend: pop bx ;Hole BX und..
pop ds ;...DS zurück
jmp short endrout2 ;Routine zu Ende
exit: pop ds ;Hole alle benutzten...
pop bx ;...Register...
pop ax ;...wieder zurück
endrout2: pushf
endrout: call old13 ;Springe an den alten Interrupt 13
push ax
ENDIF
okexit: push ax
push bx
push ds
IFIS286 %CPU
push 0
ELSE
xor bx,bx
push bx
ENDIF
pop ds
lds bx,ds:[78h] ;Disk-Parameter Tabelle in DS:BX
mov al,oldsec
mov ds:[bx+4],al
pop ds
pop bx
pop ax
inc sp ;Werfe den...
inc sp ;...gesicherten AX weg
ret 2 ;Und Ende mit original Flags
donothing: pop ax
jmp old13
entry endp
begin:
cseg ends
iseg segment use16 para public 'code'
assume cs:iseg,ds:iseg ;Assembler die...
assume es:cseg,ss:sseg ;...Segment Register mitteilen
umbok dw ?
loadseg dw cseg
begin2:
push cs ;
pop ds ;DS=CS
mov dx,offset texthallo ;Begruessungstext in DX
mov ah,9 ;Ausgabe...
int 21h ;...über DOS
mov ah,30h ;Hole...
int 21h ;...die DOS-Version
xchg ah,al ;AH und AL vertauschen
cmp ax,314h ;Ist es mindestens DOS 3.20
jae versionok ;Ja, Ok
mov dx,offset textdosbad ;Sonst leider Pech
mov ah,9 ;Und Meldung...
int 21h ;...ausgeben
mov ax,4c04h ;Fehlernummer 4
int 21h ;Und Ende
include cputest.asm
versionok:
IFIS286 %CPU
call MachineCheck
cmp ax,1
jnz cpuok
mov dx,offset textlp
mov ah,9
int 21h
ENDIF
cpuok: mov ah,51h ;Hole den PSP...
int 21h ;...in BX
push bx ;Speichern für später
push bx ;Und auch in...
pop ds ;...DS
mov es,ds:[2ch] ;Environment in ES
mov ah,49h ;Und freigeben,...
int 21h ;...da wir es nicht brauchen
pop es ;PSP nun in ES
mov bx,6 ;Größe des Blocks auf...
mov ah,4ah ;Minimum von 6*16 Bytes...
int 21h ;...=6 Paragraphen ändern
mov ax,cseg ;CSEG...
mov es,ax ;...in ES
mov ax,cs ;Mal schauen,
cmp ax,0a000h ;ob High-Load Versuch
jb nohi ;Nein, dann ok.
mov dx,offset hitext ;Sonst Meldung...
mov ah,9 ;...ausgeben...
int 21h ;...über DOS
mov ax,4c02h ;Programm mit Fehler 2...
int 21h ;...beenden
nohi: mov ah,30h ;So, noch mal die DOS-Version...
int 21h ;...in AX
cmp al,9 ;Ist es OS/2
jbe noos_2 ;Nein, dann weiter
mov dx,offset os2text ;Sonst Falsche DOS-Version...
mov ah,9 ;...ausgeben
int 21h
mov ax,4c03h ;Programm mit Fehler 3
int 21h ;beenden
nohma: jmp nohma2 ;Hilfssprung
noxms: jmp noxms2
noos_2: cmp al,5 ;Ist es mindestens DOS5?
jb nohma ;Nein, dann ohne HMA
mov ax,4300h ;Mal sehen,...
int 2fh ;...ob ein XMS-Treiber da ist?
cmp al,80h ;Nein?
jnz noxms ;Dann keine HMA
.286 ;Wenn XMS da, dann auch mindestens 80286
assume es:nothing,ds:cseg
push es ;Sichere ES
push cseg ;Das CSEG...
pop ds ;in DS
mov ax,4310h ;Wir...
int 2fh ;...holen wir uns die...
mov xms_ofs,bx ;...Far-Call-Adresse...
mov xms_seg,es ;...und speichern sie ab
pop es ;ES restaurieren
mov ax,4a01h ;Suche nach freien Bytes...
int 2fh ;...in der HMA
cmp di,startadr ;Sind genug Bytes frei?
ja nohma ;Nein, dann ohne HMA
mov dx,offset texthma ;Aha, wir können in die HMA laden
assume ds:iseg
push ds ;Speichere DS
push cs ;Und lade DS...
pop ds ;...mit CS
mov ah,9 ;So nun Text...
int 21h ;...über DOS ausgeben
pop ds ;DS wiederherstellen
assume ds:cseg,es:cseg
mov ax,4a02h ;Wir benötigen einige Bytes aus der HMA
mov bx,offset 0-startadr ;Anzahl in BX
int 2fh ;Und reservieren
mov ax,offset startadr ;Damit die startadr immer gleichbleibt...
sub ax,di ;...müssen wir das Segment...
shr ax,4 ;...entsprechend anpassen
not ax ;Noch mal negieren
mov es,ax ;Und in ES schreiben
mov si,startadr ;SI und DI
mov di,si ;beide auf Startadr
mov cx,offset begin-start;Anzahl der Bytes
cld ;Direction Bit auf forward
rep movsb ;Und Block in die HMA bewegen
push cseg ;Das CSEG...
pop ds ;In DS
mov ds:int13_2seg,es ;Und das neue HMA-Segment abspeichern
push es ;Jetzt wieder das alte...
pop ds ;...in DS
assume es:nothing,ds:cseg
mov ax,3513h ;Alter INT13-Handler...
int 21h ;...in ES:BX
mov old13_seg,es ;Und...
mov old13_ofs,bx ;...abspeichern
push cseg
pop ds
mov dx,lex2
push dx ;Merke die benötigten Paragraphen
mov ah,10h ;XMS-Call 10 (Request-UMB)
call xms ;Rufe XMS-Driver
pop cx ;Benötigte Paragraphen in CX
cmp ax,1 ;Ist was schiefgelaufen?
jnz noumb ;Ja, dann machen wirs ohne UMB
mov loadseg,bx ;Speichere das HMA-Segment
cmp dx,cx ;Vergleiche benötigte und erhaltene Paragraphen
jb toosmall ;UMB-Block zu klein?
mov dx,offset textumb ;Text, daß die 48 Bytes Einsprung im UMB liegen
jmp short notsmall ;Und Sprung
toosmall: mov dx,bx ;Ok, war zu klein
mov ah,11h ;Dann werfen wir ihn wieder weg
call xms ;Aufrufen
noumb: mov ax,5800h ;Da es im UMB nicht ging, versuchen wirs mit DOS
int 21h ;Erstmal die alte Allocation-Strategy in AX
push ax ;Abspeichern
mov ax,5802h ;Alten UMB Link State...
int 21h ;...in AX
push ax ;Abspeichern
mov ax,5803h ;Jetzt UMBs linken
mov bx,1
int 21h
mov bx,81h ;Neue Strategie. So klein wie möglich,...
mov ax,5801h ;...aber zuerst im High-Memory suchen.
int 21h
mov bx,lex2 ;Länge des Einsprungs
mov ah,48h ;DOS-Call: Speicher anfordern
int 21h
mov loadseg,ax ;Segment abspeichern
dec ax ;Auf den MCB des Segments zeigen
mov ds,ax ;Und in DS
mov word ptr ds:[1],8 ;Auf System-Block, damit er nicht verschwindet
pop bx ;UMB-Link State restaurieren
xor bh,bh ;BH muss 0 sein für DOS 5
mov ax,5803h ;Und über DOS...
int 21h ;...wieder installieren
pop bx ;Memory-Allocation Strategy restaurieren
mov ax,5801h ;Setze Allocation-Strategy
xor bh,bh ;Auch hier BH=0!!!
int 21h ;So und installieren
mov dx,offset textdos5 ;Text-laden
notsmall: push iseg ;Install-Segment...
pop ds ;in DS
assume ds:iseg
mov ah,9 ;Text über DOS...
int 21h ;ausgeben
cld ;Direction Flag auf forward
xor si,si ;SI und DI sind immer 0
mov di,si
mov es,loadseg ;Das Ladesegment in ES (DOS oder UMB)
push cseg ;Code-Segment...
pop ds ;...in DS
assume ds:cseg
mov cx,offset end_hdr ;Anzahl der Bytes (48)
rep movsb ;Und verschieben
push es ;Ladesegment auch...
pop ds ;in DS
mov ax,2513h ;Neuen INT13-Handler...
mov dx,offset int13_1 ;installieren
int 21h
stdexit: mov ax,4c00h ;Programm erfolgreich...
int 21h ;...beendet
.8086
nohma2: mov ax,4300h ;Mal sehen,...
int 2fh ;...ob ein XMS-Treiber da ist?
cmp al,80h ;Nein?
jnz noxms3 ;Dann auch kein UMB
.286 ;Wenn XMS da, dann auch mindestens 80286
assume es:nothing,ds:cseg
push cseg
pop ds
mov ax,4310h ;Wir...
int 2fh ;...holen wir uns die...
mov xms_ofs,bx ;...Far-Call-Adresse...
mov xms_seg,es ;...und speichern sie ab
mov dx,lex4
push dx ;Merke die benötigten Paragraphen
mov ah,10h ;XMS-Call 10 (Request-UMB)
call xms ;Rufe XMS-Driver
pop cx ;Benötigte Paragraphen in CX
cmp ax,1 ;Ist was schiefgelaufen?
noxms3: jnz noxms2 ;Ja, dann machen wirs ohne UMB
mov cs:loadseg,bx ;Ladesegment abspeichern
cmp dx,cx ;Vergleiche benötigte und erhaltene Paragraphen
jb toosmall2 ;UMB-Block zu klein?
mov dx,offset textumb2 ;Text, daß in UMB geladen wird.
.8086 ;Hier kommen auch unsere XT-Freunde wieder hin.
loadgem: mov ax,iseg
mov ds,ax
mov ah,9
int 21h
mov ax,cseg ;CSEG...
mov ds,ax ;...in DS
assume es:nothing,ds:cseg
mov ax,3513h ;Alter INT16-Handler...
int 21h ;...in ES:BX
mov old13_seg,es ;Und...
mov old13_ofs,bx ;...abspeichern
mov bx,cs:loadseg ;Ladesegment in BX
sub bx,startadr/16 ;So Startadr abziehen, damit Offset=startadr
jc schade ;Wenn Überlauf, dann können wir nicht laden
push bx ;Neues Ladesegment
pop es ;in ES
mov di,startadr ;DI und SI...
mov si,di ;...auf startadr
cld ;Vorwärts verschieben
mov cx,lex3 ;Länge in CX
mov ax,cseg ;Code-Segment...
mov ds,ax ;...in DS
rep movsb ;Und verschieben
push es ;Das neue Segment...
pop ds ;...auch in DS
assume ds:cseg,es:cseg
mov dx,offset entry ;Neuer INT09 Einsprung...
mov ax,2513h ;...in DS
int 21h ;Installieren
jmp stdexit ;Und normal beenden
toosmall2: mov dx,bx ;Ok, war zu klein
mov ah,11h ;Dann werfen wir ihn wieder weg
call xms ;Aufrufen
noxms2: mov ax,5800h ;Alte Speicherzuweisungsstrategie...
int 21h ;...in AX
push ax ;Speichern für später
mov ax,5802h ;UMB Link-State...
int 21h ;in AX
push ax ;Speichern für später
mov ax,5803h ;UMB-Link-State...
mov bx,1 ;...auf on...
int 21h ;setzen
mov bx,81h ;Erstmal High-Memory absuchen
jnc dos5 ;Alles klar, dann weiter
mov bx,1 ;Oh, Uralt-DOS <= 4, dann kein High-Memory
dos5: mov ax,5801h ;Setze die...
int 21h ;...Speicherzuweisungsstrategie
mov bx,lex4 ;Länge des residenten Teils in Paragraphen
mov ah,48h ;anfordern von DOS
int 21h
mov cs:loadseg,ax ;Und erstmal abspeichern
dec ax ;Auf MCB vom Segment zeigen
mov ds,ax ;Und ins DS
mov word ptr ds:[1],8 ;Jetzt als System markieren, damits reserviert bleibt
pop bx ;UMB-Link State restaurieren
xor bh,bh ;BH immer 0, sonst flippt DOS 5 aus.
mov ax,5803h ;Und den alten State...
int 21h ;...über DOS wiederherstellen
pop bx ;Alte Speicherzuweisungsstrategie wieder vom Stack
mov ax,5801h ;Funktion Setze Speicherzuweisungsstrategie
xor bh,bh ;Auch hier BH wieder auf 0
int 21h ;Und restaurieren
mov dx,offset textconv ;Kleine Meldung
jmp loadgem ;Und dann laden, wie bei UMB
schade: mov dx,offset textfzk ;Tja zuviel Speicher unterhalb 640 kB
mov ax,iseg ;Offset in DX
mov ds,ax ;Segment in DS
mov ah,9 ;Funktion: Textstring ausgeben
int 21h ;Und über DOS ausgeben.
mov ax,4c03h ;Mit Errorlevel 3...
int 21h ;beenden.
IFIS286 %CPU
texthallo db 'FDREAD/286 - (c) Christoph Hochstätter - Version 1.8',10,10,13,"$"
textlp db 'This program requires at least a 286 processor.',10,13,"$"
db 'Use FDR88 instead.',10,13,"$"
ELSE
texthallo db 'FDREAD/88 - (c) Christoph Hochstätter - Version 1.8',10,10,13,"$"
ENDIF
hitext db 'Do not load this program high!!!',10,13,"$"
os2text db 'This program has no effect in the (in)compatibilitybox of OS/2.',10,13,"$"
texthma db 'FDREAD installed in the HMA.',10,13,"$"
texthmasmall db 'Not enough space in the HMA.',10,13,"$"
textumb db 'INT 13 entry loaded in a UMB.',10,13,"$"
textdos5 db 'INT 13 entry loaded in a DOS-Block.',10,13,"$"
textumb2 db 'FDREAD completely loaded in a UMB.',10,13,"$"
textconv db 'FDREAD loaded in a DOS-block.',10,13,"$"
textdosbad db 'DOS 3.20 or higher required.',10,13,"$"
textfzk db 'Too MUCH memory available.',10,13,"$"
iseg ends
sseg segment use16 word stack 'stack'
dw 1024 dup(?) ;2 kB Stack sollte genügen
sseg ends
end begin2