;************************** ;* File Operations Demo * ;* Read File from Harddisc* ;* 2010 H.V.Viehof * ;* Assembled with A86 * ;************************** ;________________ ; ; Stapelsegment : ;________________ stack segment stack word 'stack' dw 160 dup (?) stack ends ;_________________ ; ; Programmsegment: ;_________________ code segment public word 'prog' main: mov bx, offset Intro ; Text anzeigen call Message call GetName ; Unterprog. Dateinamen eingeben cmp al, 01b ; ist es die ESC Taste? jnz >X1 mov ax, 04c00 ; Ruecksprung zu DOS int 021 X1: mov bx, offset CRLF call Display call OpenFile ; Unterprog. Datei oeffnen jnc >X2 ; Oops, ein Fehler trat auf... jmp Fehler X2: call ReadFile ; Unterprog. Datei lesen und danach schliessen mov ax, seg datafix mov ds, ax mov ax, seg imgdata mov es, ax mov bx, offset IsBmp call Message mov ax, es: [offset FileBuffer + 2] ; Dateigroesse call DezOut mov bx, offset breite call Message mov ax, es: [offset FileBuffer + 18] call DezOut mov bx, offset hoehe call Message mov ax, es: [offset FileBuffer + 22] call DezOut mov bx, offset farbe call Message mov ax, es: [offset FileBuffer + 28] call DezOut mov ah, 1 ; Die Bilddaten wurden angezeigt und int 021 ; auf Tastendruck auch das Bild... mov ax, 012 int 010 ;------------------------------------------------------ ; Bildaufbau ;------------------------------------------------------ mov ax, seg imgdata ; Segment des Datenpuffers mov ds, ax ; nach ds mov es, 0a000 ; es zeigt aufs Videoram mov si, ds: w [offset FileBuffer + 10] ; Anfang der Bilddaten add si, 12 ; der Korrekturfaktor ist erforderlich mov dx, 0 mov ax, ds: w [offset FileBuffer + 22] ; Bildhoehe mov bx, 80 ; x Bildschirmzeilenlaenge = mul bx ; mov di, ax ; Startposition der ersten Bildzeile unten mov ax, ds: w [offset FileBuffer + 18] ; Bildbreite in Pixeln shr ax, 3 ; / 8 = Bildbreite in Bytes ;----------- P00: test ax, 3 ; Korrektur der Bildbreite (Zeilenlaenge) jz >P0 ; ist es ein Ganzahliges Vielfaches von 4? inc ax ; inkrementieren bis Bedingung erfuellt jmp P00 ;----------- P0: mov bp, ax ; zwischenspeichern in BP mov bx, 80 ; gesamte Bildschirmbreite = 80 Bytes sub bx, ax ; Bildschirmbreite - Bildbreite = BX mov dx, 0 ; dx als Zeilenzaehler P1: mov cx, 0 ; cx als Pixelzaehler P2: mov al, ds: b [si] ; aus dem Datenpuffer laden inc si ; Pufferzeiger + 1 mov es: b [di], al ; ins Videoram schreiben inc di ; Schreibzeiger + 1 inc cx ; Pixelzaehler + 1 cmp cx, bp ; berechnetes Zeilenende erreicht? jnz P2 ; falls nicht: weitermachen! clc ; (besser das carry loeschen) sub di, bp ; Schreibzeiger auf Anfang sub di, 80 ; und eine Zeile tiefer (hoeher) positionieren inc dx ; Zeilenzaehler + 1 cmp dx, ds: w [offset FileBuffer + 22] ; Zeilenzaehler = Bildhoehe ? jnz P1 ; nein? dann weiter mov ah, 1 ; das Bild ist fertig, warten auf Tastendruck int 021 mov ax, 3 int 010 jmp main ;------------------------------------------------------ Message: mov ax, seg datafix ; Textmeldungen darstellen mov ds, ax Display: mov dl, ds: [bx] ; Zeichen an Position [bx] laden cmp dl, 0 je >A2 mov ah, 2 int 021 inc bx jmp Display A2: ret Fehler: mov bx, offset Error ; Ein Errorhandler falls Datei nicht gefunden call Message jmp main GetName: mov ax, seg datavar ; Extrasegment initialisieren mov es, ax mov di, offset Filename cld X10: mov ah, 1 ; Int 021 Funktion 1: Zeichen von der Tastatur lesen int 021 and ax, 0ff ; nur das in al wird benötigt cmp al, 01b ; ist es die ESC Taste? jz ret ; Sprung zum geplanten Programmende cmp al, 0d ; ist es die Enter Taste? jz JumpOut ; dann ist das hier fertig stosb ; im Namenspuffer speichern jmp X10 ; Und naechstes Zeichen holen JumpOut: mov al,0 ; Schlusszeichen setzen stosb ret OpenFile: mov ax, seg datavar ; Datensegment der Variablen / Hildfsspeicherzellen mov ds, ax xor al, al ; al = 0 die Datei wird nur lesend verwendet mov dx, OFFSET Filename ; dx zeigt auf den Dateinamen mov ah, 03D int 021 ; Datei oeffnen mov ds: FileHandle, ax ; und Dateihandle sichern ret ReadFile: mov ax, seg imgdata ; Datensegment / Dateiinhalt festlegen mov ds, ax mov dx, OFFSET FileBuffer mov ax, seg datavar ; Datensegment / Dateiinhalt festlegen mov es, ax S1: mov bx, es: FileHandle ; Handle nach BX mov cx, 512 ; Der Datenpuffer hat zwar Platz fuer 64000 Zeichen mov ah, 03F ; aber DOS/FAT16 liest nur 512 WIN/FAT33/NTFS wuerden 4096 akzeptieren int 021 ; Daten Lesen add dx, ax ; Pufferzeiger + Anzahl gelesener Bytes cmp ax, 0 jne S1 ; solange ax != 0 naechsten Datensatz lesen CloseFile: mov ah, 03E mov bx, es: FileHandle int 021 ; Datei schliessen ret DezOut: mov bx, 10 mov cx, 0 ; cx wird als Zaehler gebraucht X11: xor dx ,dx ; dx loeschen div bx ; dx:ax durch bx (10) teilen add dl, 030 ; dem divisionsrest 30h hinzuaddieren push dx ; auf den stapel legen inc cx ; Durchlaufzaehler erhoehen cmp ax, 0 ; ist ax schon 0? jnz X11 ; nicht? dann das ganze noch einmal... Ruecksprung nach X1 mov al, 020 ; evtl. werden Leerzeichen gebraucht X13: cmp cx, 5 ; 5 Stellen insgesammt? jz >X12 ; gut, dann kann das Ergebniss in den Ausgabepuffer push ax ; andernfalls: ein Leerzeichen davor inc cx ; Zaehler erhoehen jmp X13 ; und noch einmal... X12: pop dx ; Ok, die Zahl wird einmal rumgedreht: dx vom Stapel holen mov ah, 2 ; und dl auf Bildschirm ausgenben int 021 ; loop X12 ; schreibzeiger erhoehen bis Durchlaufzaehler = 0 mov dl, 020 ; und ein Leerzeichen int 021 ; dahinter ret code ends ;_______________ ; ; Datensegmente: ;_______________ datafix segment public word 'daten' Intro db 0a,0d db "*******************************************************************",0a,0d db "* Bitmap - Liest eine .bmp Datei im aktuellen Arbeitsverzeichniss *",0a,0d db "* und stellt diese dar. Dateinamen eingeben - Datei lesen *",0a,0d db "* Beenden mit (C) 2010 Heinz Volker Viehof *",0a,0d db "*******************************************************************",0a,0d db 0a,0d,0a,0d db " Eingabe: ",0 Error db 0a, 0d, "<<< Datei nicht gefunden! >>>" CRLF db 0a,0d,0 IsBmp db " ist eine Datei, mit einer Laenge von: ", 0 breite db " Bytes", 0a, 0d, " Die Breite in Pixeln betraegt: ",0 hoehe db 0a, 0d, " Die Hoehe in Pixeln betraegt: ",0 farbe db 0a, 0d, " Die Farbtiefe betraegt: ",0 datafix ends datavar segment public word 'daten' FileHandle dw ? Filename DB 128 dup (?) datavar ends imgdata segment public word 'daten' FileBuffer DB 0ffff dup (?) imgdata ends end