home *** CD-ROM | disk | FTP | other *** search
File List | 1989-06-01 | 15.3 KB | 487 lines |
- **********************************************************
- * *
- * ASCII-Hardcopy Commodore Amiga *
- * *
- * für K-Seka-Assembler *
- * *
- * Copyright (C) 1989 by Peter Woop und Toolbox *
- * *
- **********************************************************
-
- *---- Offsets für Library-Aufrufe -----------------------*
-
- ExecBase = 4
-
- AllocMem = -198 ; Exec
- FreeMem = -210
- FindTask = -294
- SetTaskPri = -300
- OpenLibrary = -408
- CloseLibrary = -414
-
- Open = -30 ; Dos
- Close = -36
- Write = -48
- Delay = -198
-
- *---- Programmstart -------------------------------------*
-
- start:
-
- move.l ExecBase,a6
-
- *---- Eigene Taskpriorität auf -20 setzen ---------------*
-
- sub.l a1,a1 ; Eigenen Task finden
- jsr FindTask(a6)
-
- move.l d0,a1 ; Zeiger auf eigenen Task
- move.b #-20,d0 ; Priorität auf -20
- jsr SetTaskPri(a6)
-
- *---- Benötigte Libraries öffnen ------------------------*
-
- lea intname,a1
- jsr OpenLibrary(a6)
- move.l d0,intbase ; Basisadresse retten
- beq error_intlib ; Fehler => Programmende
-
- lea dosname,a1
- jsr OpenLibrary(a6)
- move.l d0,dosbase ; Dito
- beq error_doslib
-
- *---- PRT: für Druckerausgabe öffnen --------------------*
-
- move.l dosbase,a6 ; Achtung: Printer.Device und
- ; andere Druckerfiles müssen
- ; vorhanden sein !
- move.l #prt,d1 ; Zeiger auf Filenamen (PRT:)
- move.l #1006,d2 ; Modus: New
- jsr Open(a6) ; Printer öffnen
- move.l d0,prt_hd ; Handle retten
- beq error_prtdev ; Fehler => Libs zu, Ende
-
- *---- Maustasten abfragen -------------------------------*
-
- test_key:
-
- cmp.b #$39,$bfec01 ; Control-Taste gedrückt ?
- bne.s test_key ; Nein => Warten
-
- btst #6,$bfe001 ; Linke Maustaste ?
- beq.s start_hardcopy ; Ja => Los geht's
- btst #10,$dff016 ; Rechts ?
- bne.s test_key ; Nein => Wieder warten
-
- bra program_end ; Programm beenden
-
- start_hardcopy:
-
- cmp.b #$39,$bfec01 ; Control noch gedrückt ?
- beq.s start_hardcopy
-
- *---- Handle des aktuellen Windows suchen ---------------*
-
- move.l intbase,a6 ; Zeiger auf aktuelles
- move.l 52(a6),window_hd ; Window-Handle suchen
-
- *---- Das Window betreffende Daten besorgen -------------*
-
- move.l window_hd,a0
- move.l 50(a0),a0 ; Zeiger auf Window-Rastport
- move.l 4(a0),bitmap ; Bitmap-Struktur
- move.l 52(a0),a0 ; TextFont-Struktur
-
- move 38(a0),modulo ; Bytes pro Zeichensatz-Zeile
- move.l 34(a0),data ; Zeiger auf Zeichendaten
-
- *---- Erstes Byte des Windows berechnen -----------------*
-
- move.l bitmap,a0 ; Bytes pro Zeile
- move.l (a0),bytes_per_line
- ; Anzahl der Bytes pro Zeile
- move.l 8(a0),a1 ; Adresse der 1. Bitplane
-
- move.l window_hd,a0
- move.b 55(a0),d0 ; Oberen Window-Rahmen nach d0
- ext d0 ; Auf Wort erweitern
- add 6(a0),d0 ; Window-Y-Position addieren
- mulu bytes_per_line,d0 ; Multipliziere mit Bytes
- add.l d0,a1 ; Offset zur Bitplane dazu
- move.b 54(a0),d0 ; Linken Window-Rahmen nach d0
- ext d0
- add 4(a0),d0 ; Plus X-Position
- move d0,d1 ; Wert wird gleich gebraucht
- lsr #3,d0 ; Durch 8 teilen
- ext.l d0 ; Auf Langwort bringen
- add.l d0,a1 ; Zeiger auf erstes Byte
- move.l a1,window_pointer ; speichern
-
- moveq #8,d0 ; Berechnen, um wieviele Bits
- and #7,d1 ; die Daten später zum Ver-
- sub d1,d0 ; gleich gerollt werden müssen
- move d0,bits_to_shift ; Merken
-
- move.l 32(a0),window_title
- ; Zeiger auf Window-Namen
-
- *---- Anzahl der Zeichen in X- und Y-Richtung -----------*
-
- move.l window_hd,a0 ; Zeiger auf Window-Struktur
- move.b 54(a0),d1 ; Durch Rand (links/rechts)
- add.b 56(a0),d1 ; benutze Pixel berechnen
- ext d1 ; Auf Word erweitern
- move 8(a0),d0 ; Window-Breite nach d0
- sub d1,d0 ; Rand-Pixel abziehen
- lsr #3,d0 ; Durch 8 teilen, um auf
- move d0,chars_per_line ; Anzahl der Zeichen zu kommen
-
- move.b 55(a0),d1 ; Rand (oben/unten) berechnen
- add.b 57(a0),d1
- ext d1
- move 10(a0),d0 ; Window-Höhe nach d0
- sub d1,d0 ; Auch Rand abziehen
- lsr #3,d0 ; und durch 8 teilen
- move d0,lines ; Ergibt Anzahl der Textzeilen
-
- *---- Exakte Zeichen-Positionen ermitteln ---------------*
-
- moveq #0,d0 ; Spaltenzähler zuerst auf 0
-
- loop_00:
-
- move.l d0,buffer_d0
- move lines,d1 ; Anzahl der zu testenden
- lsl #3,d1 ; Zeilen nach d1
- subq #8,d1
-
- loop_01:
-
- move.l window_pointer,a0 ; Adresse der Windowdaten
- add.l d0,a0 ; Spalten-Offset addieren
-
- *---- 8 Words des Windows in Puffer lesen ---------------*
-
- lea character_buff,a1 ; Hier kommen die Daten hin
- moveq #7,d7 ; 8 Schleifendurchläufe
- move.l a0,-(sp) ; a0 auf Stack, wird verändert
-
- loop_02:
-
- move.b (a0),d2 ; Acht Words vom Bildschirm
- rol #8,d2 ; byteweise in Puffer
- move.b 1(a0),d2 ; schreiben
- move d2,(a1)+
- add bytes_per_line,a0 ; Nächste Bildschirmzeile
- dbra d7,loop_02
- move.l (sp)+,a0 ; Alten Wert nach a0
-
- *---- Testen, ob irgendwo im Puffer ein Zeichen ---------*
-
- moveq #0,d7 ; Zähler für Shift auf Null
-
- loop_03:
-
- move.l data,a2 ; Zeiger auf Zeichensatzdaten
- moveq #1,d6 ; Erste Zeichennummer nach d5
- ; (Leerzeichen nicht testen)
-
- loop_04:
-
- lea character_buff,a1 ; Zeiger auf Puffer
- moveq #7,d5 ; Wieder 8 Durchläufe
- move.l d6,-(sp) ; Zeichennummer auf Stack
-
- loop_05:
-
- move (a1)+,d2 ; Byte aus Puffer mit Byte
- cmp.b (a2,d6.w),d2 ; im Zeichengenerator ver-
- bne.s character_wrong ; gleichen, Fehler => Runter
- add modulo,d6 ; Nächstes Byte des Charakters
- dbra d5,loop_05
- move.l (sp)+,d6 ; Zeichennummer restaurieren
-
- *---- Zweideutige Zeichen nicht akzeptieren -------------*
-
- cmp #7,d6 ; Hochkomma ?
- beq.s character_bad ; Weiter nach Zeichen suchen
- cmp #12,d6 ; Komma ?
- beq.s character_bad
- cmp #14,d6 ; Punkt ?
- beq.s character_bad
-
- *---- Zeichen im Window gefunden ------------------------*
-
- character_found: ; Position eines Charakters
- ; im Window festgestellt
- tst d7 ; Ist Shift-Wert 0 ?
- bne.s d7_not_zero ; Nein => Werst lassen
-
- moveq #8,d7 ; Wert auf 8 setzen
-
- d7_not_zero:
-
- move d7,bits_to_shift ; Anzahl der Shifts merken
-
- *---- Adresse des ersten Window-Charakters berechnen ----*
-
- move.l a0,d0 ; Berechnete Position nach d0
- sub.l window_pointer,d0 ; Anfangsposition abziehen
- divu bytes_per_line,d0 ; Durch Zeilen-Bytes teilen
- swap d0 ; Divisions-Rest von er-
- sub d0,a0 ; rechneter Adresse abziehen
- swap d0 ; Y-Position nach d0
- and #248,d0 ; Untere 3 Bits ausmaskieren
- mulu bytes_per_line,d0 ; Mit Zeilen-Bytes malnehmen
- sub.l d0,a0 ; Wert von berechneter Adres-
- move.l a0,window_pointer ; se abziehen und speichern
-
- bra print_window_name ; Jetzt geht's richtig los
-
- character_wrong:
-
- move.l (sp)+,d6 ; Zeichennummer auch hier
-
- character_bad:
-
- move d6,$dff182 ; Farbregister 1 flashen
-
- addq #1,d6 ; vom Stack und 1 addieren
- cmp #96,d6 ; Schon 96 Zeichen durch ?
- ble.s loop_04 ; Nein => Nächstes testen
-
- lea character_buff,a1 ; 8 Worte im Speicher
- moveq #7,d5 ; einmal nach rechts rollen
-
- loop_06:
-
- ror (a1)+ ; Word (a1) einmal nach rechts
- dbra d5,loop_06
-
- addq #1,d7 ; Shiftzähler plus Eins
- cmp #8,d7 ; 8 mal geshiftet ?
- ble loop_03 ; Nein => Wieder hoch
-
- add bytes_per_line,d0 ; Nächste Windowzeile abtasten
- dbra d1,loop_01 ; Noch nicht fertig => Loop
- move.l buffer_d0,d0 ; Offset wiederherstellen
- addq #1,d0 ; und um Eins erhöhen
- cmp chars_per_line,d0 ; Alle Spalten durch ?
- blt loop_00 ; Noch nicht => Auch hoch
-
- bra program_end ; Nichts gefunden => Programm
- ; beenden (Ziemlich selten)
-
- *---- Window und zugehörigen Titel ausdrucken -----------*
-
- print_window_name:
-
- move.l dosbase,a6
- move.l prt_hd,d1 ; Zeiger auf Printer-Handle
- move.l #titl_data,d2 ; String "Dump of window: "
- moveq #16,d3 ; Länge 16 Bytes
- jsr Write(a6)
-
- tst.l window_title ; Hat Window einen Titel ?
- beq.s no_window_title ; Nein, dann keinen ausgeben
-
- move.l window_title,a0 ; Pointer auf Windowtitel
- moveq #0,d3 ; Zähler für Text-Länge
-
- count_title_chars:
-
- addq #1,d3 ; Zähler++
- tst.b (a0)+ ; Ende (Nullbyte) erreicht ?
- bne.s count_title_chars ; Nein => Weiterzählen
-
- move.l prt_hd,d1 ; Fensternamen ausdrucken
- move.l window_title,d2
- jsr Write(a6)
-
- no_window_title:
-
- bsr into_next_line ; Zweimal Zeilenvorschub
- bsr into_next_line
-
- *---- Hier beginnt der eigentliche Ausdruck -------------*
-
- moveq #0,d5 ; Zähler für Y-Position
- move lines,d3
-
- y_loop:
-
- *---- Zeile abtasten, auswerten und ausdrucken ----------*
-
- lea line_buff,a5 ; Zeiger auf Zeilenpuffer
- moveq #0,d4 ; Zähler für X-Position
-
- x_loop:
-
- move.l window_pointer,a0 ; Zeiger auf Bitplane nach a0
- add.l d4,a0 ; Charakter-Position addieren
- add.l d5,a0 ; Zeilenoffset auch dazu
-
- *---- Einzelnen Buchstaben vom Bildschirm lesen ---------*
-
- lea character_buff,a1 ; Speicher für gelesene Daten
- move bytes_per_line,d7 ; d7 wird nachher pro Zeile
- subq #1,d7 ; dazuaddiert
- ext.l d7 ; Wort auf Long erweitern
- move bits_to_shift,d6 ; Wie weit shiften (nach d6)
- moveq #7,d0 ; Ein Zeichen hat 8 Zeilen
-
- character_loop:
-
- move.b (a0)+,d1 ; Higher-Byte des Wortes lesen
- rol #8,d1 ; 8 Bits nach links schieben
- move.b (a0),d1 ; Jetzt Lower-Byte lesen
- ror d6,d1 ; Char-Daten ins untere Byte
- move.b d1,(a1)+ ; schieben und in Tabelle
- add.l d7,a0 ; d7 addieren
- dbra d0,character_loop ; Nächste Zeile lesen
-
- *---- Buchstaben mit Zeichengenerator vergleichen -------*
-
- moveq #0,d1 ; Nummer des zu vergleichenden
- ; Zeichens nach d1
-
- compare_loop_01:
-
- lea character_buff,a1 ; Unsere gelesenen Daten
- move.l data,a2 ; Zeiger auf momentan
- add.l d1,a2 ; getestetes Zeichen nach a2
- moveq #7,d0 ; Auch hier wieder 8 Zeilen
-
- compare_loop_02:
-
- move.b (a1)+,d2 ; Gelesene Zeile mit entspre-
- cmp.b (a2),d2 ; chender im Generator testen
- bne.s character_false ; Falsch => Sprung runter
- add modulo,a2 ; Sonst nächste Zeile nehmen
- dbra d0,compare_loop_02
- add.b #32,d1 ; 32 addieren
- cmp.b #127,d1 ; Wenn Zeichen über 127 noch-
- bmi.s number_ok ; mals 32 addieren, da Zeichen
- add.b #32,d1 ; 128 bis 159 nicht vorhanden
-
- number_ok:
-
- move.b d1,(a5)+ ; ASCII-Wert in Puffer legen
- bra.s character_identified
-
- character_false:
-
- addq #1,d1 ; Nächstes Zeichen testen
- cmp #192,d1 ; Schon alle abgetestet ?
- blt.s compare_loop_01 ; Nein => Weitermachen
- move.b #32,(a5)+ ; Sonst Zeichen nicht erkannt
- ; => Durch Space ersetzen
-
- character_identified:
-
- addq #1,d4 ; Weitere Zeichen der Zeile
- cmp chars_per_line,d4 ; auswerten, bis Zeilenende
- blt.s x_loop ; Noch 'ne Runde
-
- *---- Zeile, Chr(10), Chr(13) ausdrucken ----------------*
-
- move d3,-(sp)
- move.l dosbase,a6 ; Zeilenpuffer auf Drucker
- move.l prt_hd,d1 ; ausgeben
- move.l #line_buff,d2 ; Zeiger auf Puffer
- move chars_per_line,d3 ; Auszugebende Zeichen
- ext.l d3
- jsr Write(a6) ; Los geht's
-
- bsr into_next_line ; Druckkopf in nächste Zeile
- move (sp)+,d3
-
- *---- Nächste Zeile des Windows -------------------------*
-
- cmp.b #$39,$bfec01 ; Control-Taste ?
- beq test_key ; Ja => Ausdruck abbrechen
-
- move bytes_per_line,d4 ; Wert zum Addieren errechnen
- lsl #3,d4
- ext.l d4
- add.l d4,d5 ; Offset um d4 erhöhen
- dbra d3,y_loop
-
- bra test_key ; Wieder auf Taste warten
-
- *---- Libraries und PRT: wieder schließen ---------------*
-
- program_end:
-
- move.l dosbase,a6
- move.l prt_hd,d1
- jsr Close(a6)
-
- error_prtdev:
-
- move.l ExecBase,a6
- move.l dosbase,a1
- jsr CloseLibrary(a6)
-
- error_doslib:
-
- move.l intbase,a1
- jsr CloseLibrary(a6)
-
- *---- Programmende --------------------------------------*
-
- error_intlib:
-
- rts
-
- *---- Chr(10) und Chr(13) zum Drucker schicken ----------*
-
- into_next_line:
-
- move.l dosbase,a6
- move.l prt_hd,d1
- move.l #crlf_data,d2
- moveq #2,d3
- jsr Write(a6)
- rts
-
- *---- Variablen und Definitionen ------------------------*
-
- intname: dc.b "intuition.library",0
- intbase: dc.l 0
-
- dosname: dc.b "dos.library",0
- dosbase: dc.l 0
-
- prt: dc.b "PRT:",0
- even
- prt_hd: dc.l 0
-
- crlf_data: dc.b 10,13 ; LF + CR
- titl_data: dc.b "Dump of window: ",0
- even
-
- window_hd: dc.l 0
- window_pointer: dc.l 0
- window_title: dc.l 0
-
- bitmap: dc.l 0
- textfont: dc.l 0
-
- modulo: dc.w 0
- data: dc.l 0
- bits_to_shift: dc.w 0
-
- bytes_per_line: dc.w 0
- chars_per_line: dc.w 0
- lines: dc.l 0
-
- buffer_d0: dc.l 0
- character_buff: blk.w 8,0
- line_buff: blk.b 128,0
-
- end
-
- *--------------------------------------------------------*