home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1989 / 08 / 68000 / amicopy.lst
Encoding:
File List  |  1989-06-01  |  15.3 KB  |  487 lines

  1.  **********************************************************
  2.  *                                                        *
  3.  *             ASCII-Hardcopy  Commodore Amiga            *
  4.  *                                                        *
  5.  *                   für K-Seka-Assembler                 *
  6.  *                                                        *
  7.  *      Copyright (C) 1989 by Peter Woop und Toolbox      *
  8.  *                                                        *
  9.  **********************************************************
  10.  
  11.  *---- Offsets für Library-Aufrufe -----------------------*
  12.  
  13.    ExecBase = 4
  14.  
  15.    AllocMem = -198           ; Exec
  16.    FreeMem = -210
  17.    FindTask = -294
  18.    SetTaskPri = -300
  19.    OpenLibrary = -408
  20.    CloseLibrary = -414
  21.  
  22.    Open = -30                ; Dos
  23.    Close = -36
  24.    Write = -48
  25.    Delay = -198
  26.  
  27.  *---- Programmstart -------------------------------------*
  28.  
  29.  start:
  30.  
  31.    move.l  ExecBase,a6
  32.  
  33.  *---- Eigene Taskpriorität auf -20 setzen ---------------*
  34.  
  35.    sub.l   a1,a1             ; Eigenen Task finden
  36.    jsr     FindTask(a6)
  37.  
  38.    move.l  d0,a1             ; Zeiger auf eigenen Task
  39.    move.b  #-20,d0           ; Priorität auf -20
  40.    jsr     SetTaskPri(a6)
  41.  
  42.  *---- Benötigte Libraries öffnen ------------------------*
  43.  
  44.    lea     intname,a1
  45.    jsr     OpenLibrary(a6)
  46.    move.l  d0,intbase        ; Basisadresse retten
  47.    beq     error_intlib      ; Fehler => Programmende
  48.  
  49.    lea     dosname,a1
  50.    jsr     OpenLibrary(a6)
  51.    move.l  d0,dosbase        ; Dito
  52.    beq     error_doslib
  53.  
  54.  *---- PRT: für Druckerausgabe öffnen --------------------*
  55.  
  56.    move.l  dosbase,a6        ; Achtung: Printer.Device und
  57.                              ; andere Druckerfiles müssen
  58.                              ; vorhanden sein !
  59.    move.l  #prt,d1           ; Zeiger auf Filenamen (PRT:)
  60.    move.l  #1006,d2          ; Modus: New
  61.    jsr     Open(a6)          ; Printer öffnen
  62.    move.l  d0,prt_hd         ; Handle retten
  63.    beq     error_prtdev      ; Fehler => Libs zu, Ende
  64.  
  65.  *---- Maustasten abfragen -------------------------------*
  66.  
  67.  test_key:
  68.  
  69.    cmp.b   #$39,$bfec01      ; Control-Taste gedrückt ?
  70.    bne.s   test_key          ; Nein => Warten
  71.  
  72.    btst    #6,$bfe001        ; Linke Maustaste ?
  73.    beq.s   start_hardcopy    ; Ja => Los geht's
  74.    btst    #10,$dff016       ; Rechts ?
  75.    bne.s   test_key          ; Nein => Wieder warten
  76.  
  77.    bra     program_end       ; Programm beenden
  78.  
  79.  start_hardcopy:
  80.  
  81.    cmp.b   #$39,$bfec01      ; Control noch gedrückt ?
  82.    beq.s   start_hardcopy
  83.  
  84.  *---- Handle des aktuellen Windows suchen ---------------*
  85.  
  86.    move.l  intbase,a6        ; Zeiger auf aktuelles
  87.    move.l  52(a6),window_hd  ; Window-Handle suchen
  88.  
  89.  *---- Das Window betreffende Daten besorgen -------------*
  90.  
  91.    move.l  window_hd,a0
  92.    move.l  50(a0),a0         ; Zeiger auf Window-Rastport
  93.    move.l  4(a0),bitmap      ; Bitmap-Struktur
  94.    move.l  52(a0),a0         ; TextFont-Struktur
  95.  
  96.    move    38(a0),modulo     ; Bytes pro Zeichensatz-Zeile
  97.    move.l  34(a0),data       ; Zeiger auf Zeichendaten
  98.  
  99.  *---- Erstes Byte des Windows berechnen -----------------*
  100.  
  101.    move.l  bitmap,a0         ; Bytes pro Zeile
  102.    move.l  (a0),bytes_per_line
  103.                              ; Anzahl der Bytes pro Zeile
  104.    move.l  8(a0),a1          ; Adresse der 1. Bitplane
  105.  
  106.    move.l  window_hd,a0
  107.    move.b  55(a0),d0         ; Oberen Window-Rahmen nach d0
  108.    ext     d0                ; Auf Wort erweitern
  109.    add     6(a0),d0          ; Window-Y-Position addieren
  110.    mulu    bytes_per_line,d0 ; Multipliziere mit Bytes
  111.    add.l   d0,a1             ; Offset zur Bitplane dazu
  112.    move.b  54(a0),d0         ; Linken Window-Rahmen nach d0
  113.    ext     d0
  114.    add     4(a0),d0          ; Plus X-Position
  115.    move    d0,d1             ; Wert wird gleich gebraucht
  116.    lsr     #3,d0             ; Durch 8 teilen
  117.    ext.l   d0                ; Auf Langwort bringen
  118.    add.l   d0,a1             ; Zeiger auf erstes Byte
  119.    move.l  a1,window_pointer ; speichern
  120.  
  121.    moveq   #8,d0             ; Berechnen, um wieviele Bits
  122.    and     #7,d1             ; die Daten später zum Ver-
  123.    sub     d1,d0             ; gleich gerollt werden müssen
  124.    move    d0,bits_to_shift  ; Merken
  125.  
  126.    move.l  32(a0),window_title
  127.                              ; Zeiger auf Window-Namen
  128.  
  129.  *---- Anzahl der Zeichen in X- und Y-Richtung -----------*
  130.  
  131.    move.l  window_hd,a0      ; Zeiger auf Window-Struktur
  132.    move.b  54(a0),d1         ; Durch Rand (links/rechts)
  133.    add.b   56(a0),d1         ; benutze Pixel berechnen
  134.    ext     d1                ; Auf Word erweitern
  135.    move    8(a0),d0          ; Window-Breite nach d0
  136.    sub     d1,d0             ; Rand-Pixel abziehen
  137.    lsr     #3,d0             ; Durch 8 teilen, um auf
  138.    move    d0,chars_per_line ; Anzahl der Zeichen zu kommen
  139.  
  140.    move.b  55(a0),d1         ; Rand (oben/unten) berechnen
  141.    add.b   57(a0),d1
  142.    ext     d1
  143.    move    10(a0),d0         ; Window-Höhe nach d0
  144.    sub     d1,d0             ; Auch Rand abziehen
  145.    lsr     #3,d0             ; und durch 8 teilen
  146.    move    d0,lines          ; Ergibt Anzahl der Textzeilen
  147.  
  148.  *---- Exakte Zeichen-Positionen ermitteln ---------------*
  149.  
  150.    moveq   #0,d0             ; Spaltenzähler zuerst auf 0
  151.  
  152.  loop_00:
  153.  
  154.    move.l  d0,buffer_d0
  155.    move    lines,d1          ; Anzahl der zu testenden
  156.    lsl     #3,d1             ; Zeilen nach d1
  157.    subq    #8,d1
  158.  
  159.  loop_01:
  160.  
  161.    move.l  window_pointer,a0 ; Adresse der Windowdaten
  162.    add.l   d0,a0             ; Spalten-Offset addieren
  163.  
  164.  *---- 8 Words des Windows in Puffer lesen ---------------*
  165.  
  166.    lea     character_buff,a1 ; Hier kommen die Daten hin
  167.    moveq   #7,d7             ; 8 Schleifendurchläufe
  168.    move.l  a0,-(sp)          ; a0 auf Stack, wird verändert
  169.  
  170.  loop_02:
  171.  
  172.    move.b  (a0),d2           ; Acht Words vom Bildschirm
  173.    rol     #8,d2             ; byteweise in Puffer
  174.    move.b  1(a0),d2          ; schreiben
  175.    move    d2,(a1)+
  176.    add     bytes_per_line,a0 ; Nächste Bildschirmzeile
  177.    dbra    d7,loop_02
  178.    move.l  (sp)+,a0          ; Alten Wert nach a0
  179.  
  180.  *---- Testen, ob irgendwo im Puffer ein Zeichen ---------*
  181.  
  182.    moveq   #0,d7             ; Zähler für Shift auf Null
  183.  
  184.  loop_03:
  185.  
  186.    move.l  data,a2           ; Zeiger auf Zeichensatzdaten
  187.    moveq   #1,d6             ; Erste Zeichennummer nach d5
  188.                              ; (Leerzeichen nicht testen)
  189.  
  190.  loop_04:
  191.  
  192.    lea     character_buff,a1 ; Zeiger auf Puffer
  193.    moveq   #7,d5             ; Wieder 8 Durchläufe
  194.    move.l  d6,-(sp)          ; Zeichennummer auf Stack
  195.  
  196.  loop_05:
  197.  
  198.    move    (a1)+,d2          ; Byte aus Puffer mit Byte
  199.    cmp.b   (a2,d6.w),d2      ; im Zeichengenerator ver-
  200.    bne.s   character_wrong   ; gleichen, Fehler => Runter
  201.    add     modulo,d6         ; Nächstes Byte des Charakters
  202.    dbra    d5,loop_05
  203.    move.l  (sp)+,d6          ; Zeichennummer restaurieren
  204.  
  205.  *---- Zweideutige Zeichen nicht akzeptieren -------------*
  206.  
  207.    cmp     #7,d6             ; Hochkomma ?
  208.    beq.s   character_bad     ; Weiter nach Zeichen suchen
  209.    cmp     #12,d6            ; Komma ?
  210.    beq.s   character_bad
  211.    cmp     #14,d6            ; Punkt ?
  212.    beq.s   character_bad
  213.  
  214.  *---- Zeichen im Window gefunden ------------------------*
  215.  
  216.  character_found:            ; Position eines Charakters
  217.                              ; im Window festgestellt
  218.    tst     d7                ; Ist Shift-Wert 0 ?
  219.    bne.s   d7_not_zero       ; Nein => Werst lassen
  220.  
  221.    moveq   #8,d7             ; Wert auf 8 setzen
  222.  
  223.  d7_not_zero:
  224.  
  225.    move    d7,bits_to_shift  ; Anzahl der Shifts merken
  226.  
  227.  *---- Adresse des ersten Window-Charakters berechnen ----*
  228.  
  229.    move.l  a0,d0             ; Berechnete Position nach d0
  230.    sub.l   window_pointer,d0 ; Anfangsposition abziehen
  231.    divu    bytes_per_line,d0 ; Durch Zeilen-Bytes teilen
  232.    swap    d0                ; Divisions-Rest von er-
  233.    sub     d0,a0             ; rechneter Adresse abziehen
  234.    swap    d0                ; Y-Position nach d0
  235.    and     #248,d0           ; Untere 3 Bits ausmaskieren
  236.    mulu    bytes_per_line,d0 ; Mit Zeilen-Bytes malnehmen
  237.    sub.l   d0,a0             ; Wert von berechneter Adres-
  238.    move.l  a0,window_pointer ; se abziehen und speichern
  239.  
  240.    bra     print_window_name ; Jetzt geht's richtig los
  241.  
  242.  character_wrong:
  243.  
  244.    move.l  (sp)+,d6          ; Zeichennummer auch hier
  245.  
  246.  character_bad:
  247.  
  248.    move    d6,$dff182        ; Farbregister 1 flashen
  249.  
  250.    addq    #1,d6             ; vom Stack und 1 addieren
  251.    cmp     #96,d6            ; Schon 96 Zeichen durch ?
  252.    ble.s   loop_04           ; Nein => Nächstes testen
  253.  
  254.    lea     character_buff,a1 ; 8 Worte im Speicher
  255.    moveq   #7,d5             ; einmal nach rechts rollen
  256.  
  257.  loop_06:
  258.  
  259.    ror     (a1)+             ; Word (a1) einmal nach rechts
  260.    dbra    d5,loop_06
  261.  
  262.    addq    #1,d7             ; Shiftzähler plus Eins
  263.    cmp     #8,d7             ; 8 mal geshiftet ?
  264.    ble     loop_03           ; Nein => Wieder hoch
  265.  
  266.    add     bytes_per_line,d0 ; Nächste Windowzeile abtasten
  267.    dbra    d1,loop_01        ; Noch nicht fertig => Loop
  268.    move.l  buffer_d0,d0      ; Offset wiederherstellen
  269.    addq    #1,d0             ; und um Eins erhöhen
  270.    cmp     chars_per_line,d0 ; Alle Spalten durch ?
  271.    blt     loop_00           ; Noch nicht => Auch hoch
  272.  
  273.    bra     program_end       ; Nichts gefunden => Programm
  274.                              ; beenden (Ziemlich selten)
  275.  
  276.  *---- Window und zugehörigen Titel ausdrucken -----------*
  277.  
  278.  print_window_name:
  279.  
  280.    move.l  dosbase,a6
  281.    move.l  prt_hd,d1         ; Zeiger auf Printer-Handle
  282.    move.l  #titl_data,d2     ; String "Dump of window: "
  283.    moveq   #16,d3            ; Länge 16 Bytes
  284.    jsr     Write(a6)
  285.  
  286.    tst.l   window_title      ; Hat Window einen Titel ?
  287.    beq.s   no_window_title   ; Nein, dann keinen ausgeben
  288.  
  289.    move.l  window_title,a0   ; Pointer auf Windowtitel
  290.    moveq   #0,d3             ; Zähler für Text-Länge
  291.  
  292.  count_title_chars:
  293.  
  294.    addq    #1,d3             ; Zähler++
  295.    tst.b   (a0)+             ; Ende (Nullbyte) erreicht ?
  296.    bne.s   count_title_chars ; Nein => Weiterzählen
  297.  
  298.    move.l  prt_hd,d1         ; Fensternamen ausdrucken
  299.    move.l  window_title,d2
  300.    jsr     Write(a6)
  301.  
  302.  no_window_title:
  303.  
  304.    bsr     into_next_line    ; Zweimal Zeilenvorschub
  305.    bsr     into_next_line
  306.  
  307.  *---- Hier beginnt der eigentliche Ausdruck -------------*
  308.  
  309.    moveq   #0,d5             ; Zähler für Y-Position
  310.    move    lines,d3
  311.  
  312.  y_loop:
  313.  
  314.  *---- Zeile abtasten, auswerten und ausdrucken ----------*
  315.  
  316.    lea     line_buff,a5      ; Zeiger auf Zeilenpuffer
  317.    moveq   #0,d4             ; Zähler für X-Position
  318.  
  319.  x_loop:
  320.  
  321.    move.l  window_pointer,a0 ; Zeiger auf Bitplane nach a0
  322.    add.l   d4,a0             ; Charakter-Position addieren
  323.    add.l   d5,a0             ; Zeilenoffset auch dazu
  324.  
  325.  *---- Einzelnen Buchstaben vom Bildschirm lesen ---------*
  326.  
  327.    lea     character_buff,a1 ; Speicher für gelesene Daten
  328.    move    bytes_per_line,d7 ; d7 wird nachher pro Zeile
  329.    subq    #1,d7             ; dazuaddiert
  330.    ext.l   d7                ; Wort auf Long erweitern
  331.    move    bits_to_shift,d6  ; Wie weit shiften (nach d6)
  332.    moveq   #7,d0             ; Ein Zeichen hat 8 Zeilen
  333.  
  334.  character_loop:
  335.  
  336.    move.b  (a0)+,d1          ; Higher-Byte des Wortes lesen
  337.    rol     #8,d1             ; 8 Bits nach links schieben
  338.    move.b  (a0),d1           ; Jetzt Lower-Byte lesen
  339.    ror     d6,d1             ; Char-Daten ins untere Byte
  340.    move.b  d1,(a1)+          ; schieben und in Tabelle
  341.    add.l   d7,a0             ; d7 addieren
  342.    dbra    d0,character_loop ; Nächste Zeile lesen
  343.  
  344.  *---- Buchstaben mit Zeichengenerator vergleichen -------*
  345.  
  346.    moveq   #0,d1             ; Nummer des zu vergleichenden
  347.                              ; Zeichens nach d1
  348.  
  349.  compare_loop_01:
  350.  
  351.    lea     character_buff,a1 ; Unsere gelesenen Daten
  352.    move.l  data,a2           ; Zeiger auf momentan
  353.    add.l   d1,a2             ; getestetes Zeichen nach a2
  354.    moveq   #7,d0             ; Auch hier wieder 8 Zeilen
  355.  
  356.  compare_loop_02:
  357.  
  358.    move.b  (a1)+,d2          ; Gelesene Zeile mit entspre-
  359.    cmp.b   (a2),d2           ; chender im Generator testen
  360.    bne.s   character_false   ; Falsch => Sprung runter
  361.    add     modulo,a2         ; Sonst nächste Zeile nehmen
  362.    dbra    d0,compare_loop_02
  363.    add.b   #32,d1            ; 32 addieren
  364.    cmp.b   #127,d1           ; Wenn Zeichen über 127 noch-
  365.    bmi.s   number_ok         ; mals 32 addieren, da Zeichen
  366.    add.b   #32,d1            ; 128 bis 159 nicht vorhanden
  367.  
  368.  number_ok:
  369.  
  370.    move.b  d1,(a5)+          ; ASCII-Wert in Puffer legen
  371.    bra.s   character_identified
  372.  
  373.  character_false:
  374.  
  375.    addq    #1,d1             ; Nächstes Zeichen testen
  376.    cmp     #192,d1           ; Schon alle abgetestet ?
  377.    blt.s   compare_loop_01   ; Nein => Weitermachen
  378.    move.b  #32,(a5)+         ; Sonst Zeichen nicht erkannt
  379.                              ; => Durch Space ersetzen
  380.  
  381.  character_identified:
  382.  
  383.    addq    #1,d4             ; Weitere Zeichen der Zeile
  384.    cmp     chars_per_line,d4 ; auswerten, bis Zeilenende
  385.    blt.s   x_loop            ; Noch 'ne Runde
  386.  
  387.  *---- Zeile, Chr(10), Chr(13) ausdrucken ----------------*
  388.  
  389.    move    d3,-(sp)
  390.    move.l  dosbase,a6        ; Zeilenpuffer auf Drucker
  391.    move.l  prt_hd,d1         ; ausgeben
  392.    move.l  #line_buff,d2     ; Zeiger auf Puffer
  393.    move    chars_per_line,d3 ; Auszugebende Zeichen
  394.    ext.l   d3
  395.    jsr     Write(a6)         ; Los geht's
  396.  
  397.    bsr     into_next_line    ; Druckkopf in nächste Zeile
  398.    move    (sp)+,d3
  399.  
  400.  *---- Nächste Zeile des Windows -------------------------*
  401.  
  402.    cmp.b   #$39,$bfec01      ; Control-Taste ?
  403.    beq     test_key          ; Ja => Ausdruck abbrechen
  404.  
  405.    move    bytes_per_line,d4 ; Wert zum Addieren errechnen
  406.    lsl     #3,d4
  407.    ext.l   d4
  408.    add.l   d4,d5             ; Offset um d4 erhöhen
  409.    dbra    d3,y_loop
  410.  
  411.    bra     test_key          ; Wieder auf Taste warten
  412.  
  413.  *---- Libraries und PRT: wieder schließen ---------------*
  414.  
  415.  program_end:
  416.  
  417.    move.l  dosbase,a6
  418.    move.l  prt_hd,d1
  419.    jsr     Close(a6)
  420.  
  421.  error_prtdev:
  422.  
  423.    move.l  ExecBase,a6
  424.    move.l  dosbase,a1
  425.    jsr     CloseLibrary(a6)
  426.  
  427.  error_doslib:
  428.  
  429.    move.l  intbase,a1
  430.    jsr     CloseLibrary(a6)
  431.  
  432.  *---- Programmende --------------------------------------*
  433.  
  434.  error_intlib:
  435.  
  436.    rts
  437.  
  438.  *---- Chr(10) und Chr(13) zum Drucker schicken ----------*
  439.  
  440.  into_next_line:
  441.  
  442.    move.l  dosbase,a6
  443.    move.l  prt_hd,d1
  444.    move.l  #crlf_data,d2
  445.    moveq   #2,d3
  446.    jsr     Write(a6)
  447.    rts
  448.  
  449.  *---- Variablen und Definitionen ------------------------*
  450.  
  451.  intname:        dc.b    "intuition.library",0
  452.  intbase:        dc.l    0
  453.  
  454.  dosname:        dc.b    "dos.library",0
  455.  dosbase:        dc.l    0
  456.  
  457.  prt:            dc.b    "PRT:",0
  458.                  even
  459.  prt_hd:         dc.l    0
  460.  
  461.  crlf_data:      dc.b    10,13         ; LF + CR
  462.  titl_data:      dc.b    "Dump of window: ",0
  463.                  even
  464.  
  465.  window_hd:      dc.l    0
  466.  window_pointer: dc.l    0
  467.  window_title:   dc.l    0
  468.  
  469.  bitmap:         dc.l    0
  470.  textfont:       dc.l    0
  471.  
  472.  modulo:         dc.w    0
  473.  data:           dc.l    0
  474.  bits_to_shift:  dc.w    0
  475.  
  476.  bytes_per_line: dc.w    0
  477.  chars_per_line: dc.w    0
  478.  lines:          dc.l    0
  479.  
  480.  buffer_d0:      dc.l    0
  481.  character_buff: blk.w   8,0
  482.  line_buff:      blk.b   128,0
  483.  
  484.                  end
  485.  
  486.  *--------------------------------------------------------*
  487.