home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / podstawy / dos / format / fdform18.exe / FDREAD.ASM < prev    next >
Assembly Source File  |  1991-07-21  |  25KB  |  477 lines

  1.              page      68,129
  2.  
  3. IFIS286      MACRO     cp,i
  4.              IFIDN     <CP>,</$G+>
  5.              ENDM
  6.  
  7. IFIS88       MACRO     cp,i
  8.              IFIDN     <CP>,</$G->
  9.              ENDM
  10.  
  11.              IFNDEF    CPU
  12.              %out      No CPU defined for Assembly, defaulting to 286
  13. CPU          EQU       </$G+>
  14.              ENDIF
  15.              IFIS286   %CPU
  16.              .286
  17.              ENDIF
  18.              title     fdread - lesen von disketten aller formate
  19.  
  20.              .radix    10
  21.  
  22. startadr     equ       0ff80h
  23.  
  24. cseg         segment   use16 word public 'code'
  25.              assume    cs:cseg,ds:nothing,es:nothing,ss:nothing
  26.  
  27.              org       0
  28.  
  29. lex          equ       offset end_hdr-offset int13_2
  30. lex2         equ       (lex+15)/16
  31. lex3         equ       offset begin-offset start
  32. lex4         equ       (lex3+15)/16
  33.  
  34. int13_2      label     dword                ;HMA Einsprung INT13
  35. int13_2ofs   dw        entry                ;Offset-Teil
  36. int13_2seg   dw        ?                    ;Segment-Teil
  37.  
  38. xms          label     dword                ;Speicher für XMS-Einsprungaddresse
  39. xms_ofs      dw        ?
  40. xms_seg      dw        ?
  41.  
  42.              .286                           ;Der folgende Teil wird nur bei 286+ relevant
  43. int13_1      proc      far                  ;INT-09 Handler
  44.              pusha                          ;Alle Register retten
  45.              mov       ah,7                 ;Code für A20 testen
  46.              call      dword ptr xms        ;Rufe XMS-Manager auf
  47.              dec       ax                   ;Ist A20 enabled (Ja: AX=1)
  48.              jz        ret1                 ;Wenn, ja ist hier alles erledigt
  49.              mov       ah,5                 ;Code für A20 local enablen
  50.              call      dword ptr xms        ;Rufe XMS-Manager auf
  51. ret1:        popa                           ;Alle Register wiederherstellen
  52.              jmp       int13_2              ;Führe den eigentlichen Handler aus
  53. int13_1      endp
  54.  
  55.              .8086
  56.  
  57. end_hdr:
  58.  
  59.              org       startadr
  60.  
  61. start:
  62.  
  63.              IFIS286   %CPU
  64.              even
  65.              .286
  66.              ENDIF
  67.  
  68. old13        label     dword                               ;Speicherung des alten Interrupt 13
  69. old13_ofs    dw        ?                                   ;Offset-Teil
  70. old13_seg    dw        ?                                   ;Segment-Teil
  71. oldsec       db        ?
  72.  
  73. entry        proc      far
  74.              push      ax                                  ;AX retten
  75.              or        ah,ah                               ;Wurde Funktion 0 RESET aufgerufen?
  76.              jz        donothing                           ;Ja, dann Ende
  77.              cmp       ah,4                                ;Wurde Funktion über 4 aufgerufen?
  78.              ja        donothing                           ;Ja, dann Ende
  79.              cmp       dl,3
  80.              ja        donothing
  81.              push      bx                                  ;...Register...
  82.              push      ds                                  ;...retten
  83.              IFIS286   %CPU
  84.              push      0
  85.              ELSE
  86.              xor       bx,bx
  87.              push      bx
  88.              ENDIF
  89.              pop       ds
  90.              lds       bx,ds:[78h]                         ;Disk-Parameter Tabelle in DS:BX
  91.              mov       al,ds:[bx+4]
  92.              mov       oldsec,al
  93.              mov       byte ptr ds:[bx+4],1Bh              ;Setze auf maximal 25 Sektoren/Spur
  94.              IFIS286   %CPU
  95.              or        ch,ch                               ;Track 0 ?
  96.              jz        exit                                ;Ja, dann Ende
  97.              ENDIF
  98.              pop       ds                                  ;Alle...
  99.              pop       bx                                  ;...Register...
  100.              pop       ax                                  ;...zurückholen.
  101.              push      ax                                  ;AX für später speichern
  102.              pushf                                         ;Flags pushen da INT-CALL
  103.              call      old13                               ;Alten INT 13 aufrufen
  104.              IFIS286   %CPU
  105.              jnc       okexit                              ;Kein Fehler, dann Ende
  106.              pop       ax                                  ;Hole uns AX zurück
  107.              push      ds                                  ;Speichere...
  108.              push      bx                                  ;...DS & BX
  109.              push      40h                                 ;BIOS-Data Segment...
  110.              pop       ds                                  ;...nach DS
  111.              mov       bx,90h                              ;Beginn der Drive-Tabelle
  112.              add       bl,dl                               ;Offset des Laufwerks
  113.              cmp       ch,43                               ;Track>43
  114.              ja        nodstep                             ;Ja, dann niemals DSTEP
  115.              xor       byte ptr ds:[bx],20h                ;invertiere das Stepper-Bit
  116.              jmp       short stepend                       ;Ende vom Stepping
  117. nodstep:     and       byte ptr ds:[bx],0dfh               ;Kein Double-Stepping
  118. stepend:     pop       bx                                  ;Hole BX und..
  119.              pop       ds                                  ;...DS zurück
  120.              jmp       short endrout2                      ;Routine zu Ende
  121. exit:        pop       ds                                  ;Hole alle benutzten...
  122.              pop       bx                                  ;...Register...
  123.              pop       ax                                  ;...wieder zurück
  124. endrout2:    pushf
  125. endrout:     call      old13                               ;Springe an den alten Interrupt 13
  126.              push      ax
  127.              ENDIF
  128. okexit:      push      ax
  129.              push      bx
  130.              push      ds
  131.              IFIS286   %CPU
  132.              push      0
  133.              ELSE
  134.              xor       bx,bx
  135.              push      bx
  136.              ENDIF
  137.              pop       ds
  138.              lds       bx,ds:[78h]                         ;Disk-Parameter Tabelle in DS:BX
  139.              mov       al,oldsec
  140.              mov       ds:[bx+4],al
  141.              pop       ds
  142.              pop       bx
  143.              pop       ax
  144.  
  145.              inc       sp                                  ;Werfe den...
  146.              inc       sp                                  ;...gesicherten AX weg
  147.              ret       2                                   ;Und Ende mit original Flags
  148.  
  149. donothing:   pop       ax
  150.              jmp       old13
  151.  
  152. entry        endp
  153.  
  154. begin:
  155.  
  156. cseg         ends
  157.  
  158. iseg         segment   use16 para public 'code'
  159.              assume    cs:iseg,ds:iseg      ;Assembler die...
  160.              assume    es:cseg,ss:sseg      ;...Segment Register mitteilen
  161.  
  162. umbok        dw        ?
  163. loadseg      dw        cseg
  164.  
  165. begin2:
  166.              push      cs                   ;
  167.              pop       ds                   ;DS=CS
  168.              mov       dx,offset texthallo  ;Begruessungstext in DX
  169.              mov       ah,9                 ;Ausgabe...
  170.              int       21h                  ;...über DOS
  171.              mov       ah,30h               ;Hole...
  172.              int       21h                  ;...die DOS-Version
  173.              xchg      ah,al                ;AH und AL vertauschen
  174.              cmp       ax,314h              ;Ist es mindestens DOS 3.20
  175.              jae       versionok            ;Ja, Ok
  176.              mov       dx,offset textdosbad ;Sonst leider Pech
  177.              mov       ah,9                 ;Und Meldung...
  178.              int       21h                  ;...ausgeben
  179.              mov       ax,4c04h             ;Fehlernummer 4
  180.              int       21h                  ;Und Ende
  181.  
  182.              include   cputest.asm
  183.  
  184. versionok:
  185.              IFIS286   %CPU
  186.              call      MachineCheck
  187.              cmp       ax,1
  188.              jnz       cpuok
  189.              mov       dx,offset textlp
  190.              mov       ah,9
  191.              int       21h
  192.              ENDIF
  193. cpuok:       mov       ah,51h               ;Hole den PSP...
  194.              int       21h                  ;...in BX
  195.              push      bx                   ;Speichern für später
  196.              push      bx                   ;Und auch in...
  197.              pop       ds                   ;...DS
  198.              mov       es,ds:[2ch]          ;Environment in ES
  199.              mov       ah,49h               ;Und freigeben,...
  200.              int       21h                  ;...da wir es nicht brauchen
  201.              pop       es                   ;PSP nun in ES
  202.              mov       bx,6                 ;Größe des Blocks auf...
  203.              mov       ah,4ah               ;Minimum von 6*16 Bytes...
  204.              int       21h                  ;...=6 Paragraphen ändern
  205.              mov       ax,cseg              ;CSEG...
  206.              mov       es,ax                ;...in ES
  207.              mov       ax,cs                ;Mal schauen,
  208.              cmp       ax,0a000h            ;ob High-Load Versuch
  209.              jb        nohi                 ;Nein, dann ok.
  210.              mov       dx,offset hitext     ;Sonst Meldung...
  211.              mov       ah,9                 ;...ausgeben...
  212.              int       21h                  ;...über DOS
  213.              mov       ax,4c02h             ;Programm mit Fehler 2...
  214.              int       21h                  ;...beenden
  215.  
  216. nohi:        mov       ah,30h               ;So, noch mal die DOS-Version...
  217.              int       21h                  ;...in AX
  218.              cmp       al,9                 ;Ist es OS/2
  219.              jbe       noos_2               ;Nein, dann weiter
  220.              mov       dx,offset os2text    ;Sonst Falsche DOS-Version...
  221.              mov       ah,9                 ;...ausgeben
  222.              int       21h
  223.              mov       ax,4c03h             ;Programm mit Fehler 3
  224.              int       21h                  ;beenden
  225.  
  226. nohma:       jmp       nohma2               ;Hilfssprung
  227. noxms:       jmp       noxms2
  228.  
  229. noos_2:      cmp       al,5                 ;Ist es mindestens DOS5?
  230.              jb        nohma                ;Nein, dann ohne HMA
  231.              mov       ax,4300h             ;Mal sehen,...
  232.              int       2fh                  ;...ob ein XMS-Treiber da ist?
  233.              cmp       al,80h               ;Nein?
  234.              jnz       noxms                ;Dann keine HMA
  235.              .286                           ;Wenn XMS da, dann auch mindestens 80286
  236.              assume    es:nothing,ds:cseg
  237.              push      es                   ;Sichere ES
  238.              push      cseg                 ;Das CSEG...
  239.              pop       ds                   ;in DS
  240.              mov       ax,4310h             ;Wir...
  241.              int       2fh                  ;...holen wir uns die...
  242.              mov       xms_ofs,bx           ;...Far-Call-Adresse...
  243.              mov       xms_seg,es           ;...und speichern sie ab
  244.              pop       es                   ;ES restaurieren
  245.              mov       ax,4a01h             ;Suche nach freien Bytes...
  246.              int       2fh                  ;...in der HMA
  247.              cmp       di,startadr          ;Sind genug Bytes frei?
  248.              ja        nohma                ;Nein, dann ohne HMA
  249.              mov       dx,offset texthma    ;Aha, wir können in die HMA laden
  250.              assume    ds:iseg
  251.              push      ds                   ;Speichere DS
  252.              push      cs                   ;Und lade DS...
  253.              pop       ds                   ;...mit CS
  254.              mov       ah,9                 ;So nun Text...
  255.              int       21h                  ;...über DOS ausgeben
  256.              pop       ds                   ;DS wiederherstellen
  257.              assume    ds:cseg,es:cseg
  258.              mov       ax,4a02h             ;Wir benötigen einige Bytes aus der HMA
  259.              mov       bx,offset 0-startadr ;Anzahl in BX
  260.              int       2fh                  ;Und reservieren
  261.              mov       ax,offset startadr   ;Damit die startadr immer gleichbleibt...
  262.              sub       ax,di                ;...müssen wir das Segment...
  263.              shr       ax,4                 ;...entsprechend anpassen
  264.              not       ax                   ;Noch mal negieren
  265.              mov       es,ax                ;Und in ES schreiben
  266.              mov       si,startadr          ;SI und DI
  267.              mov       di,si                ;beide auf Startadr
  268.              mov       cx,offset begin-start;Anzahl der Bytes
  269.              cld                            ;Direction Bit auf forward
  270.              rep       movsb                ;Und Block in die HMA bewegen
  271.              push      cseg                 ;Das CSEG...
  272.              pop       ds                   ;In DS
  273.              mov       ds:int13_2seg,es     ;Und das neue HMA-Segment abspeichern
  274.              push      es                   ;Jetzt wieder das alte...
  275.              pop       ds                   ;...in DS
  276.              assume    es:nothing,ds:cseg
  277.              mov       ax,3513h             ;Alter INT13-Handler...
  278.              int       21h                  ;...in ES:BX
  279.              mov       old13_seg,es         ;Und...
  280.              mov       old13_ofs,bx         ;...abspeichern
  281.              push      cseg
  282.              pop       ds
  283.              mov       dx,lex2
  284.              push      dx                   ;Merke die benötigten Paragraphen
  285.              mov       ah,10h               ;XMS-Call 10 (Request-UMB)
  286.              call      xms                  ;Rufe XMS-Driver
  287.              pop       cx                   ;Benötigte Paragraphen in CX
  288.              cmp       ax,1                 ;Ist was schiefgelaufen?
  289.              jnz       noumb                ;Ja, dann machen wirs ohne UMB
  290.              mov       loadseg,bx           ;Speichere das HMA-Segment
  291.              cmp       dx,cx                ;Vergleiche benötigte und erhaltene Paragraphen
  292.              jb        toosmall             ;UMB-Block zu klein?
  293.              mov       dx,offset textumb    ;Text, daß die 48 Bytes Einsprung im UMB liegen
  294.              jmp       short notsmall       ;Und Sprung
  295.  
  296. toosmall:    mov       dx,bx                ;Ok, war zu klein
  297.              mov       ah,11h               ;Dann werfen wir ihn wieder weg
  298.              call      xms                  ;Aufrufen
  299.  
  300. noumb:       mov       ax,5800h             ;Da es im UMB nicht ging, versuchen wirs mit DOS
  301.              int       21h                  ;Erstmal die alte Allocation-Strategy in AX
  302.              push      ax                   ;Abspeichern
  303.              mov       ax,5802h             ;Alten UMB Link State...
  304.              int       21h                  ;...in AX
  305.              push      ax                   ;Abspeichern
  306.              mov       ax,5803h             ;Jetzt UMBs linken
  307.              mov       bx,1
  308.              int       21h
  309.              mov       bx,81h               ;Neue Strategie. So klein wie möglich,...
  310.              mov       ax,5801h             ;...aber zuerst im High-Memory suchen.
  311.              int       21h
  312.              mov       bx,lex2              ;Länge des Einsprungs
  313.              mov       ah,48h               ;DOS-Call: Speicher anfordern
  314.              int       21h
  315.              mov       loadseg,ax           ;Segment abspeichern
  316.              dec       ax                   ;Auf den MCB des Segments zeigen
  317.              mov       ds,ax                ;Und in DS
  318.              mov       word ptr ds:[1],8    ;Auf System-Block, damit er nicht verschwindet
  319.              pop       bx                   ;UMB-Link State restaurieren
  320.              xor       bh,bh                ;BH muss 0 sein für DOS 5
  321.              mov       ax,5803h             ;Und über DOS...
  322.              int       21h                  ;...wieder installieren
  323.              pop       bx                   ;Memory-Allocation Strategy restaurieren
  324.              mov       ax,5801h             ;Setze Allocation-Strategy
  325.              xor       bh,bh                ;Auch hier BH=0!!!
  326.              int       21h                  ;So und installieren
  327.              mov       dx,offset textdos5   ;Text-laden
  328. notsmall:    push      iseg                 ;Install-Segment...
  329.              pop       ds                   ;in DS
  330.              assume    ds:iseg
  331.              mov       ah,9                 ;Text über DOS...
  332.              int       21h                  ;ausgeben
  333.              cld                            ;Direction Flag auf forward
  334.              xor       si,si                ;SI und DI sind immer 0
  335.              mov       di,si
  336.              mov       es,loadseg           ;Das Ladesegment in ES (DOS oder UMB)
  337.              push      cseg                 ;Code-Segment...
  338.              pop       ds                   ;...in DS
  339.              assume    ds:cseg
  340.              mov       cx,offset end_hdr    ;Anzahl der Bytes (48)
  341.              rep       movsb                ;Und verschieben
  342.              push      es                   ;Ladesegment auch...
  343.              pop       ds                   ;in DS
  344.              mov       ax,2513h             ;Neuen INT13-Handler...
  345.              mov       dx,offset int13_1    ;installieren
  346.              int       21h
  347. stdexit:     mov       ax,4c00h             ;Programm erfolgreich...
  348.              int       21h                  ;...beendet
  349.  
  350.              .8086
  351. nohma2:      mov       ax,4300h             ;Mal sehen,...
  352.              int       2fh                  ;...ob ein XMS-Treiber da ist?
  353.              cmp       al,80h               ;Nein?
  354.              jnz       noxms3               ;Dann auch kein UMB
  355.              .286                           ;Wenn XMS da, dann auch mindestens 80286
  356.              assume    es:nothing,ds:cseg
  357.              push      cseg
  358.              pop       ds
  359.              mov       ax,4310h             ;Wir...
  360.              int       2fh                  ;...holen wir uns die...
  361.              mov       xms_ofs,bx           ;...Far-Call-Adresse...
  362.              mov       xms_seg,es           ;...und speichern sie ab
  363.              mov       dx,lex4
  364.              push      dx                   ;Merke die benötigten Paragraphen
  365.              mov       ah,10h               ;XMS-Call 10 (Request-UMB)
  366.              call      xms                  ;Rufe XMS-Driver
  367.              pop       cx                   ;Benötigte Paragraphen in CX
  368.              cmp       ax,1                 ;Ist was schiefgelaufen?
  369. noxms3:      jnz       noxms2               ;Ja, dann machen wirs ohne UMB
  370.              mov       cs:loadseg,bx        ;Ladesegment abspeichern
  371.              cmp       dx,cx                ;Vergleiche benötigte und erhaltene Paragraphen
  372.              jb        toosmall2            ;UMB-Block zu klein?
  373.              mov       dx,offset textumb2   ;Text, daß in UMB geladen wird.
  374.  
  375.              .8086                          ;Hier kommen auch unsere XT-Freunde wieder hin.
  376. loadgem:     mov       ax,iseg
  377.              mov       ds,ax
  378.              mov       ah,9
  379.              int       21h
  380.              mov       ax,cseg              ;CSEG...
  381.              mov       ds,ax                ;...in DS
  382.              assume    es:nothing,ds:cseg
  383.              mov       ax,3513h             ;Alter INT16-Handler...
  384.              int       21h                  ;...in ES:BX
  385.              mov       old13_seg,es         ;Und...
  386.              mov       old13_ofs,bx         ;...abspeichern
  387.              mov       bx,cs:loadseg        ;Ladesegment in BX
  388.              sub       bx,startadr/16       ;So Startadr abziehen, damit Offset=startadr
  389.              jc        schade               ;Wenn Überlauf, dann können wir nicht laden
  390.              push      bx                   ;Neues Ladesegment
  391.              pop       es                   ;in ES
  392.              mov       di,startadr          ;DI und SI...
  393.              mov       si,di                ;...auf startadr
  394.              cld                            ;Vorwärts verschieben
  395.              mov       cx,lex3              ;Länge in CX
  396.              mov       ax,cseg              ;Code-Segment...
  397.              mov       ds,ax                ;...in DS
  398.              rep       movsb                ;Und verschieben
  399.              push      es                   ;Das neue Segment...
  400.              pop       ds                   ;...auch in DS
  401.              assume    ds:cseg,es:cseg
  402.              mov       dx,offset entry      ;Neuer INT09 Einsprung...
  403.              mov       ax,2513h             ;...in DS
  404.              int       21h                  ;Installieren
  405.              jmp       stdexit              ;Und normal beenden
  406.  
  407. toosmall2:   mov       dx,bx                ;Ok, war zu klein
  408.              mov       ah,11h               ;Dann werfen wir ihn wieder weg
  409.              call      xms                  ;Aufrufen
  410.  
  411. noxms2:      mov       ax,5800h             ;Alte Speicherzuweisungsstrategie...
  412.              int       21h                  ;...in AX
  413.              push      ax                   ;Speichern für später
  414.              mov       ax,5802h             ;UMB Link-State...
  415.              int       21h                  ;in AX
  416.              push      ax                   ;Speichern für später
  417.              mov       ax,5803h             ;UMB-Link-State...
  418.              mov       bx,1                 ;...auf on...
  419.              int       21h                  ;setzen
  420.              mov       bx,81h               ;Erstmal High-Memory absuchen
  421.              jnc       dos5                 ;Alles klar, dann weiter
  422.              mov       bx,1                 ;Oh, Uralt-DOS <= 4, dann kein High-Memory
  423. dos5:        mov       ax,5801h             ;Setze die...
  424.              int       21h                  ;...Speicherzuweisungsstrategie
  425.              mov       bx,lex4              ;Länge des residenten Teils in Paragraphen
  426.              mov       ah,48h               ;anfordern von DOS
  427.              int       21h
  428.              mov       cs:loadseg,ax        ;Und erstmal abspeichern
  429.              dec       ax                   ;Auf MCB vom Segment zeigen
  430.              mov       ds,ax                ;Und ins DS
  431.              mov       word ptr ds:[1],8    ;Jetzt als System markieren, damits reserviert bleibt
  432.              pop       bx                   ;UMB-Link State restaurieren
  433.              xor       bh,bh                ;BH immer 0, sonst flippt DOS 5 aus.
  434.              mov       ax,5803h             ;Und den alten State...
  435.              int       21h                  ;...über DOS wiederherstellen
  436.              pop       bx                   ;Alte Speicherzuweisungsstrategie wieder vom Stack
  437.              mov       ax,5801h             ;Funktion Setze Speicherzuweisungsstrategie
  438.              xor       bh,bh                ;Auch hier BH wieder auf 0
  439.              int       21h                  ;Und restaurieren
  440.              mov       dx,offset textconv   ;Kleine Meldung
  441.              jmp       loadgem              ;Und dann laden, wie bei UMB
  442.  
  443. schade:      mov       dx,offset textfzk    ;Tja zuviel Speicher unterhalb 640 kB
  444.              mov       ax,iseg              ;Offset in DX
  445.              mov       ds,ax                ;Segment in DS
  446.              mov       ah,9                 ;Funktion: Textstring ausgeben
  447.              int       21h                  ;Und über DOS ausgeben.
  448.              mov       ax,4c03h             ;Mit Errorlevel 3...
  449.              int       21h                  ;beenden.
  450.  
  451.              IFIS286   %CPU
  452. texthallo    db        'FDREAD/286 - (c) Christoph Hochstätter - Version 1.8',10,10,13,"$"
  453. textlp       db        'This program requires at least a 286 processor.',10,13,"$"
  454.              db        'Use FDR88 instead.',10,13,"$"
  455.              ELSE
  456. texthallo    db        'FDREAD/88 - (c) Christoph Hochstätter - Version 1.8',10,10,13,"$"
  457.              ENDIF
  458. hitext       db        'Do not load this program high!!!',10,13,"$"
  459. os2text      db        'This program has no effect in the (in)compatibilitybox of OS/2.',10,13,"$"
  460. texthma      db        'FDREAD installed in the HMA.',10,13,"$"
  461. texthmasmall db        'Not enough space in the HMA.',10,13,"$"
  462. textumb      db        'INT 13 entry loaded in a UMB.',10,13,"$"
  463. textdos5     db        'INT 13 entry loaded in a DOS-Block.',10,13,"$"
  464. textumb2     db        'FDREAD completely loaded in a UMB.',10,13,"$"
  465. textconv     db        'FDREAD loaded in a DOS-block.',10,13,"$"
  466. textdosbad   db        'DOS 3.20 or higher required.',10,13,"$"
  467. textfzk      db        'Too MUCH memory available.',10,13,"$"
  468.  
  469. iseg         ends
  470.  
  471. sseg         segment   use16 word stack 'stack'
  472.  
  473.              dw        1024 dup(?)              ;2 kB Stack sollte genügen
  474.  
  475. sseg         ends
  476.              end       begin2
  477.