Easytizer - ein Videodigitizer im Selbstbau Teil 2

Nachdem Sie mit Sicherheit den Aufbau der Easytizer-Hardware erfolgreich absolviert haben, können Sie nun das 'harte’ Werkzeug aus der Hand legen und das ’weiche’ Werkzeug zur Hand nehmen. Dieser Artikel soll Ihnen zum Einen die genaue Ansteuerung des Easytizers nahebringen, und zum Anderen eine flexible Assemblerroutine vorstellen, die Sie z. B. in Ihre eigene Software einbringen können.

Ein kurzer Rückblick

Nachdem sich der letzte Beitrag ausführlich mit der Hardware des Easytizers beschäftigt hat, wird der Easytizer in diesem zweiten und letzten Teil ausschließlich aus dem Blickpunkt der Software betrachtet. Zum Einen wird die Programierung auf Maschinenebene erläutert, und zum Anderen wird eine flexible Assemblerroutine vorgestellt, die Sie in Ihre eigene Software einbinden können, wie hier zum Beispiel in ein GFA-Basic Programm. So bleibt es letztendlich ihrer Phantasie überlassen, ob der Easytizer eine kleine und sinnvolle Ergänzung ihres Zeichenprogramms, oder eine ’Animationsmaschine’ wird.

Ein wenig Wiederholung

Die Ansteuerung der Easytizer-Hardware wurde im vorigen Artikel bereits beschrieben, doch soll dies kurz wiederholt werden. Durch die Easytizer-Hardware wird der ROM-Bereich von $FB0000-$FBFFFF belegt. In diesem 64K Block wiederholen sich periodisch die Register des Easytizers, über die der Datenaustausch mit dem Rechner stattfindet. Da das Schreiben in diesem Bereich nicht möglich ist, (sonst 2 Bömbchen - Busfehler) Betriebszustände der Hardware jedoch durch den Rechner manipulierbar sein sollen, wird einfach der Zugriff auf ganz bestimmte Register als Ausgabe interpretiert. Außerdem sollten nur Wortzugriffe oder Bytezugriffe auf geraden Adressen stattfinden, da sich die Hardware sonst nicht ansprechen läßt.

$FB00C0 SRO, nur Wort:
In diesem Register sind 16 Bildpunkte des niederwertigen Teils der Bildinformation (Bitplane 0) verfügbar. Der Inhalt dieses Registers stammt aus einem Schieberregister, in welches alle 4 Microsekunden die 16 Bildpunkte der momentan über den Spaltenzähler eingestellten Spalte übertragen werden. Ein Zugriff auf diese Register bewirkt gleichzeitig ein Zurücksetzen der LWF-Flagge im Statusregister.

$FB0002 SRI, nur Wort:
Wie oben, jedoch der höherwertige Teil der Bildinformation (Bitplane 1). Beide Register sind so organisiert, daß sie direkt mit dem Bildspeicher des Atari korrespondieren, und deshalb nur zum richtigen Zeitpunkt an die richtige Stelle des Bildspeichers kopiert werden müssen, damit auf dem Monitor das digitalisierte Abbild des Videosignals entsteht.

$FB0004 INZ, Wort/Byte:
Ein Zugriff auf dieses Register inkre-mentiert den sog. ’Spaltenzähler’, mit dem kontrolliert wird, welche von vier Spalten zu 16 Bildpunkten in die oben genannten Register übertragen werden. Die gelesenen Daten enthalten hier keine Information, nur der Zugriff zählt. Es sind vier Zugriffe nötig, um die Spalte 16 Bildpunkte nach rechts zu rücken.

$FB0006 LZ, Wort/Byte:
Ein Zugriff auf dieses Register löscht den Spaltenzähler. Damit ist die am weitesten links liegende Spalte eingestellt.

$FB0008 STATUS, Wort/Byte:
Status-Register, das über Synchronsignale im Easytizer Auskunft gibt. Von 16 Bits werden lediglich vier benutzt:

Bit 15: LWF
Diese Flagge wird gesetzt, wenn ein neues Langwort aus den Schieberegistern IC1-IC4 in die intern nachgeschalteten Register übertragen wurde und wird durch einen Zugriff auf SRO und am Anfang einer Zeile gelöscht. Zweck dieser Flagge ist es, eine Synchronisation zwischen Rechner und Videosignal zu ermöglichen. Aus Zeitgründen ist es jedoch nur möglich, am Anfang einer Zeile auf den Spaltentakt zu Synchronisieren. Probleme ergeben sich jedoch nicht, da die Taktfrequenz des ATARI-ST (genau 8 Mhz) ein Vielfaches des Spaltentaktes (genau 250 Khz) ist und bei richtigem 'Timing’ der Software keine Zeitverschiebungen auftreten.

Bit 14: CSYNC
Das pure, positive Synchronsignal, über ein Monoflop um etwa 7,8 Microsekunden verlängert, das ebenfalls zur Synchronisation des Rechners mit dem Videosignal dient.

Bit 13: VSYNC
Dieses Bit wird für etwa 160 Microsekunden Dauer während eines Rasterwechsels aktiv.

Bit 12: TASTE
Dieses Bit wird bei gedrückter 'Schnappschuss-Taste' aktiv.

Das Zeitproblem:

Obwohl der ATARI-ST nicht einer der müdesten Rechner ist, kann er ohne DMA (Speicherdirektzugriff) oder ähnliche Hardwareintensive Einrichtungen nicht ohne Weiteres die, bei der Videobildverarbeitung anfallenden, Datenmengen in Echtzeit aufnehmen. Deshalb mußte der Datenberg in vier kleinere, verdaulichere Portionen aufgeteilt werden. Also wurde eine Videozeile in vier Spalten zu je 16 Bildpunkten aufgeteilt, die sich im Abstand von 64 Bildpunkten wiederholen. Natürlich erkauft man sich keinen Vorteil ohne Nachteile, denn um das vollständige Videobild in den Rechner zu übertragen, benötigt man jetzt die vier- bzw. achtfache Zeit (80/160 ms). Somit muß die Software nur noch im Abstand von 4 Microsekunden ein Langwort aus dem Easytizer an die richtige Stelle des Bildspeichers transportieren.

Der Punkttakt beträgt 16 Mhz (62.5 ns/Punkt), also würde ohne eine Spalteneinteilung die Spaltenfrequenz, also die Frequenz, mit der jeweils 16 neue Bildpunkte in den Schieberregistern bereitstehen, genau 1 Mhz (16 Mhz/16 Bildpunkte) betragen. Abgesehen davon, daß sich mit dieser Frequenz kein softwaremäßiger Datentransfer mehr abwickeln läßt, ergibt sich noch ein weiteres Problem: Das Zeitfenster, das unweigerlich beim Synchronisieren mit dem Spaltentakt entsteht, würde größer sein, als der Spaltenabstand. Das sogenannte Zeitfenster kommt dadurch zustande, daß der Zustand dieses Bits periodisch in einem bestimmten Zeitabstand (hier 2.5 Microsekunden) abgetastet wird und daher, daß beide Vorgänge asynchron zueinander ablaufen, es zu einer maximalen 'Streuung' kommen kann, die der Abtastzeit entspricht. Dieses Zeitfenster (oder auch Phasenstreuung) beträgt mit allen Programmiertricks etwa 2.5us, also liegt man mit 4 Microsekunden Spaltenabstand (Spaltenfrequenz 250 Khz) auf der sicheren Seite.

Praktische Möglichkeiten des Easytizers

Der Easytizer ist in seinen Anwendungen nicht durch die Grafikmöglichkeiten des ATARI-ST beschränkt, weshalb es möglich ist, ein Bild mit 640 ★ 200 Punkten und 4 Graustufen direkt inden Bildspeicher zu digitalisieren, aber auch mit einer Auflösung von 768 ★ 600 Punkten und vier Graustufen zu digitalisieren, wenn es auch nicht direkt sichtbar wird. Anwendungen. die nur eine Graustufe (monochrome Bilder) erfordern, kann der Easytizer genauso erfüllen, wie Anwendungen, in denen vier Graustufen nötig sind. Alle Möglichkeiten werden von dem Assemblermodul Easysoft unterstützt, auf das später genauer eingegangen werden soll.

Falls Sie, aus welchen Gründen auch immer, nicht dieses Assemblermodul benutzen wollen, sondern Ihre eigene Software zur Ansteuerung des Easytizers schreiben wollen, sei Ihnen so viel gesagt: Es soll Ihnen keine Information über den Easytizer vorenthalten werden, jedoch können wir hier auch nicht auf jede Einzelheit ausführlich eingehen und deshalb soll sich der Artikel auf die Benutzung der Easytizer-Routinen konzentrieren. Wir bieten Ihnen das hier abgedruckte Assemblermodul an, mit dessen Möglichkeiten wohl jede Anwendung abgedeckt werden kann.

Der Grafikaufbau des ST

soll hier kurz angeschnitten werden, da er unmittelbar in Verbindung mit dem Easytizer steht. Der Grafikspeicher des ST besteht aus einem Spei-. aerblock, der eine bis vier Bildebenen umfaßt. Die Anzahl der Bildebenen (Bitplanes) bestimmt die Anzahl der möglichen Farben pro Bildpunkt und hängt von der eingestellten Auflösung ab. So ist es in der monochromen Auflösung nur eine Bildebene, in der mittleren Auflösung sind es zwei und in der niedrigeren sind es vier Bildebenen. In der monochromen Auflösung bilden 40 Speicherworte eine komplette Bildschirmzeile, wobei das Wort mit der niedrigsten Adresse, die am weitesten links liegenden Bildpunkte beinhaltet. Ein Wort (Wort = 16 Bits) bestimmt die Farbe (hier: hell/dunkel) von jeweils 16 Bildpunkten, und zwar ist Bit 15 eines Speicherwortes dem am weitesten links liegenden Bildpunkt zugeordnet. Nach jeweils 40 Speicherworten fängt eine neue Zeile an. In anderen Auflösungen gilt dies auch, mit der Ausnahme, daß jeweils zwei bzw. vier aufeinanderfolgende Worte zu 16 Bildpunkten zusammengefaßt werden, und dadurch zwei bzw. vier Bits pro Bildpunkt und damit entsprechend mehr Farben pro Bildpunkt möglich werden. Genau in diesem Format sind auch die Speicherworte vom Easytizer verfügbar, und müssen deshalb nur noch zur richtigen Zeit an die richtige Stelle in den Bildspeicher kopiert werden.

Bild 1: Digitalisierung mit vier Graustufen in mittlerer Auflösung

Die Ansteuerung des Easytizers

ist aus Geschwindigkeitsgründen nur auf Maschinenebene möglich.

Ein Assemblerprogramm, das den Easytizer ansteuert (auch Easysoft) sollte nach folgenden Schritten ablaufen:

  1. Löschen des Spaltenzählers.
  2. Den Bildwechsel des Videosignals abwarten. (Bit VSYNC im Statusregister)
  3. Bis zur gewünschten ersten Zeile des Videosignals warten.
  4. Synchronisation mit den Schieberregistern über das Bit LWF im Statusregister.
  5. Die Spalte der Bildinformation aus den Schieberegistern an die entsprechende Position des Bildspeichers übertragen.
  6. 4 Microsekunden warten, bis die nächste Spalte in die Schieberegister übertragen ist.
  7. Ab Schritt 5 solange wiederholen, bis alle Spalten einer Zeile übertragen sind.
  8. Ab Schritt 4 solange wiederholen, bis alle Zeilen des Ffalbbildes übertragen sind.
  9. Spaltenzähler durch viermaligen Zugriff auf Register INZ auf die nächste Spalte einstellen.
  10. Ab Schritt 2 solange wiederholen, bis alle Spalten übertragen sind.
  11. Fertig.

Verzweifeln sie nicht, denn all diese Bitzwirbeleien nimmt Ihnen das Programmodul EASYSOFT ab, ohne das Sie sich je mit Assemblerprogrammierung auseinandersetzen müssen. Fiier wird die Benutzung der EASYSOFT-Routinen aus GFA-Basic heraus beschrieben, doch läßt sich das genausogut für ’C’ oder Pascal realisieren.

EASYSOFT - find’ ich gut

In Listing 1 sehen Sie die EASYSOFT-Routinen abgedruckt. Es werden 3 Funktionen bereitgestellt; die Parameterübergabe erfolgt nach ’C’-Konventionen auf dem Stack. Die Routinen sind vollständig PC-Relativ (Program Counter) geschrieben und damit an jeder Stelle des Speichers lauffähig.

; EASYSOFT - Die Assemblerroutine zur Ansteuerung der EASYTIZER Hardware.
; Dieser Quellcode sollte mit Profimat assembliert werden,
; wobei weder PC-Relativer noch relozierbarer Code erzeugt werden darf.
; Das Programmmodul ist voellig Lageunabhaengig und bertoetigt keinen weiteren 
; Speicher ausser seiner Eigenlaenge.
; Parameteruebergabe auf dem Stack nach C-Konventionen.
; Raymund Hofmann 21/9/87

ilabel tos\tos.l

h_sr0 = $fb8000 
h_sr1 = $fb8002 
h_inz = $fb8004 
h_lz = $fb8006 
hstatus = $fb8008

b_lwf = 7 
b_csync = 6 
b_vsync = 5 
b_taste = 4

funkt = 0 
xweite = 2 
yweite = 4 
interl = 6 
bplanes = 8 
anfang = 10 
adresse = 12

trabant = 5
nil = $23330444

einsprung:
    lea einsprung(pc),a6    ;   Basisadresse
    lea 4(sp),a5            ;   Pararaeterbasis
    move.l a5,parbase(a6)   ;   Sichern
    tst.w funkt(a5)         ;   Welche Funktion ?
    beq.s v_foto
    cmp.w #1, funkt(a5)     ;   Taste ?
    beq.s taste

    lea h_status,a0         ;   Testen auf Videosignal
    move.b (a0),d0
    and.b #%01000000,d0     ;   Csync-Bit herausfiltern
    move.w #100,d1          ;   Zeitlimit
\testv move.b (a0),d2
    and.b #%01000000,d2
    eor.b d0,d2             ;   Hat das Bit seinen Zustand behalten ? 
    dbne d1,\testv          ;   JA
    moveq #0,d0
    cmp.w #-1,d1            ;   Timeout
    beq.s \kvid             ;   Ja - Kein Videosignal
    moveq #1,d0 
\kvid   rts

taste   moveq #0,d0
    btst #b_taste,h_status ;    Taste gedrueckt ?
    beq.s ntast 
    moveq #1,d0 
ntast   rts

v_foto IKBDWS ikbdstp(pc),#0    ;   Ikbd zum Schweigen bringen
    move.w #1000,d0 
\zeit   nop
    dbra d0,\zeit           ;   2 ms warten
    SUPEXEC easy(pc)        ;   Im Supervisormodus  ausf.
    IKBDWS ikbdsta(pc) ,#0  ;   Redeverbot aufheben
    moveq #0,d0             ;   Immer fehlerfrei
    rts                     ;   Rueckkehr

easy    move.l parbase(pc),a5   ;   Parameterliste
    move sr,save_sr(a6)     ;   Statusregister retten
    ori #$0700,sr           ;   Interrupts ausmaskieren
    st flagge(aö)           ;   Flagge setzen
    lea h_sr0,a0            ;   Niederwertige Bitebene
    lea h_sr1,a1            ;   Höherwertige Bitebene
    lea h_status,a2         ;   Statusregister
    moveq #b_csync,d0       ;   Synchronisations-Bit
    clr.w d2                ;   Spalte im Bildspeicher
    moveq #12,d1            ;   maximal 12*64 Bildpunkte
    sub.w xweite(a5),d1
    bpl.s \ugok             ;   gross genug
    clr.w d1                ;   Loeschen
\ugok   cmp.w #11,d1        ;   Zu gross ?
    bls.s \ogok             ;   Nein
    moveq #11,d1            ;   Ja
\ogok   move.w d1,d3
    mulu #sprung2-sprung1,d1; mal Laenge des Programmteils 
    lea sprung1(pc),a3      ;   Adresse des 1.Programmteils
    add.w d1,a3             ;   plus Verschiebung
    move.l a3,spadr+2(a6)   ; in den JMP-Befehl einsetzen 
    mulu #sprung4-sprung3,d3; mal Laenge 
    lea sprung3(pc),a3 
    add.w d3,a3
    move.l a3,spadr2+2(a6)  ;   in 2. JMP-Befehl einsetzen

1bild btst #b_vsync,(a2)    ;   Bildwechsel aktiv ?
    bne.s 1bild             ;   ja
    tst.w h_1z              ;   Spaltenzaehler loeschen
    move.w xweite(a5),d1    ; Horizontale Aufloesung
    lsl.w #3,d1             ;   *8=Bytes pro Spalte
    moveq #0,d7             ;   Halbbildzaehler
bildper move.l adresse(a5),a3   ;   Adresse des Bildspeichers
    adda.w d2,a3            ; Spaltenposition aufaddieren
\wartbw btst #b_vsync,(a2)  ; Warten auf den Bildwechsel
    beq.s \wartbw

    moveq #trabant,d4       ;   Trabantenzaehler
\whics  btst d0,(a2)        ;   Csync high?
    beq.s \whics            ;   Nein
\wlocs  btst d0,(a2)        ;   Csync low ?
    bne.s \wlocs            ;   Nein
\messen moveq #100,d5 
\mslp   btst d0,(a2)
    dbne d5,\mslp           ; D6 dekrementieren, sol. low
    cmp.w #100-16,d5        ; Lowzeit > 40 microsec ?
    bcs.s \weiter
    subq.w #1,d4            ; Ein Trabant weniger ...
    bra.s \wlocs

\weiter btst d0,(a2)        ;   Csync low   ?
    bne.s \weiter           ;   Nein
    move.w anfang(a5),d5    ;   1. Zeile
\zeil   btst d0,(a2)        ;   komplette   Zeile   abwarten
    beq.s \zeil 
\wzhi   btst d0,(a2)
    bne.s \wzhi
    dbra d5,\zeil           ;   Bis zur ersten Zeile
\syncbj btst d0,(a2) 
    bne.s \syncbj

    tst.w bplanes(a5)       ; 2 Bildebenen ?
    bne zweibe

; Dieser Teil uebernimmt das Einlesen von einer Bildebene

einbe   move.w yweite(a5),d5    ;   Zeilenzahl
    tst.w interl(a5)        ;   Interlace   aus ?
    bne.s \iaus
    lsr.w #1,d5             ; /2 , da Interlace
\iaus   subq #1,d5
    tst.w d4                ; Welches Halbbild angesagt ?
    beq.s waz1              ;   1. Halbbild vorgezogen
    add.w d1,a3             ;   Ungerade Zeilen
    tst.w interl(a5)        ;   Interlace aus ?
    bne 1bild               ; Ja, dann 2. Halbbild nicht
                            ; auswerten
wazl btst d0,(a2)           ; Auf Anfang der Zeile warten
    beq.s wazL 
\synreg tst.b (a2)
    bpl.s \synreg 
    tst.w (a0) 
    tst.l (a0) 
    tst.l (a0) 
    tst.l (a0)
spadr jmp nil               ; Adresse kommt spaeter

sprung1 move.w (a1),(a3)    ; 1. Spalte
    add.w #8,a3 
    tst.w (a0)
    sprung2 move.w (a1),(a3)    ; 2. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 3. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 4. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 5. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 6. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 7. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 8. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 9. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 10. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 11. Spalte
    add.w #8,a3 
    tst.w (a0)
    move.w (a1),(a3)        ; 12. Spalte
    add.w #8,a3
    tst.w interl(a5)        ; Interlace ?
    bne.s \ioff             ; Nein
    add.w d1,a3             ; Eine Zeile weiterspringen
\ioff dbra d5,waz1          ; Und nächste Zeile einlesen
    addq.w #1,d7            ; Halbbildzaehler
    btst #0,d7              ; Vollbildperiode ?
    bne.s \nvoll
    tst.w h_inz             ; inkr. Spaltenzaehler
    tst.w h_inz 
    tst.w h_inz 
    tst.w h_inz
    addq.w #2,d2            ; 2 Bytes pro Spalte
\nvoll  cmp.w #8,d7         ; Bild Vollstaendig ?
    bne bildper             ; Noch nicht
ende    move.w save sr(pc),sr
    rts

; Dieser Teil uebernimmt das Einlesen von zwei Bildebenen

zweibe  move.w yweite(a5),d5    ; Zeilenzahl
    tst.w interl(a5)    ;   Ohne Interlace ?
    bne.s \intl         ;   Nein
    lsr.w #1,d5         ;   /2 , da Interlace
\intl   subq #1,d5
    tst.w d4            ; Welches Halbbild ist angesagt ?
    beq.s waz2
    cmp.w #1,interl(a5) ;   Interlace-Modus 1 ?
    beq bildper
    cmp.w 02,interl(a5) ;   Interlace-Modus 2 ?
    beq \spezial        ; Ja, dann beide Halbbilder
                        ; nutzen
    add.w d1,a3         ; Ungerade Zeilen
    add.w d1,a3 
    bra.s waz2
\spezial tst.b flagge(a6)   ;   Spezial Modus
    beq.s waz2          ; Schon synchronisiert
    clr.b flagge(a6)    ; Jetzt wird Synchronisiert
    bra bildper         ; Nur mit 1. Halbbild anfangen

waz2 btst d0,(a2)       ; Auf Anfang der Zeile warten
    beq.s waz2 
\synreg tst.b (a2)
    bpi.s \synreg 
    nop
    tst.l (a0) 
    tst.l (a0) 
    tst.l (a0)
spadr2 jmp nil          ; Adresse kommt spaeter
sprung3 move.l (a0),(a3)    ; 1. Spalte
    add.w #16,a3        ; Offset in naechste Spalte
sprung4 move.l (a0),(a3)    ;   2.  Spalte
    add.w #16,a3
    move.l (a0),(a3)    ; 3. Spalte
    add.w #16,a3
    move.l (a0),(a3)    ; 4. Spalte
    add.w #16,a3
    move.l (a0),(a3)    ; 5. Spalte
    add.w #16,a3
    move.l (a0),(a3)    ; 6. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 7. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 8. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 9. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 10. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 11. Spalte
    add.w #16,a3
    move.l  (a0),(a3)   ; 12. Spalte
    add.w #16,a3
    tst.w interl(a5)    ; Interlace aus ?
    bne.s \iaus         ; Ja, dann Zeile nicht
                        ; ueberspringen 
    add.w d1,a3         ; Eine Zeile weiterspringen
    add.w d1,a3
\iaus dbra d5,waz2      ; Und naechste Zeile einlesen
    addq.w #1,d7        ; Halbbildzaehler
    tst.w interl(a5)    ; Interlace aus ?
    beq.s \inaus        ; Nein
    addq.w #1,d7        ; Ja, nur 4 Halbbilder
\inaus  btst #0,d7      ;   Vollbildperiode ?
    bne.s \nvoll
    tst.w h_inz         ; inkr. Spaltenzaehler
    tst.w h_inz 
    tst.w h_inz 
    tst.w h_inz
    addq.w #4,d2        ; 4 Bytes pro Spalte
\nvoll  cmp.w #8,d7     ; Bild Vollstaendig ?
    bcs bildper         ; Noch nicht
    bra ende

; Datenbereich

ikbdstp dc.b $13 
ikbdsta dc.b $11 
flagge dc.w 0

parbase dc.l 0

save_sr dc.w 0 
        end

Listing 1: Der Easysoft-Quelltext sollte mit Profimat assembliert werden.

' Minitizer/Easytizer
' Eine Demonstration zur Anwendung der Easysoft-Routinen.
' Die Easysoft-Routinen werden aus den DATA Zeilen in
Easy$ geladen und von da wie eine C-Funktion aufgerufen 
' ST-Computer 11/87
' Raymund Hofmann   9/87

' Standard Programmkopf
For I%=1 To 34
    Read A%
    Header$=Header$+Chr$(A%)
Next I%
Void Xbios(&H6,L:Varptr(Header$)+2)
Repeat
    Read A%
    B%=B%+A%
    Easy$=Easy$+Chr$(A%)
Until A%=-1
Read A%
If A%<>(B%+1)
    Alert 1,"Fehler in den Data-|Zeilen.","O.K.",Dummi
    End
Endif
Easytizer%=Varptr(Easy$)
' Hauptschleife
'
'
Do
    @Dmenu
    Repeat
        In$=Inkey$
    Until Not In$=""
    @Udmenu
    Menu%=Instr(1,"DTLSE",Upper$(In$))
    On Menu% Gosub Digi,Trigger,Laden,Sichern,Ende 
Loop
'
'
'
Procedure Digi
    If C:Easytizer%(2)=l
        Void C:Easytizer%(0,Xmax/64,Ymax,Res,Res,50,L:Xbios(&H3)) 
    Else
        Alert 1,"Kein Videosignal.",1,"O.K.",Dummi 
    Endif 
Return
'
'
'
Procedure Trigger 
    If C:Easytizer%(2)=1 
        Do
            Void C:Easytizer%(0,Xmax/64,Ymax,Res,Res,50,L:Xbios(&H3))
            Exit If Inkey$=Chr$(13) Or C:Easytizer%(1)=1 
        Loop 
    Else
        Alert 1,"Kein Videosignal.",1,"O.K.".Dummi 
    Endif 
Return
'
'
'
Procedure Laden
    Fileselect  "LADEN.pi3",Dat$
    If Not Dat$=""
        Get 0,0,Xmax-1,Ymax-1,Bild$
        Hd2$=Left$(BildS,6)
        Bild$=Space$(32034)
        Bload Dat$,Varptr(Bild$)
        Header$=Left$(Bild$,34)
        Bild$=Hd2$+Right$(Bild$,32000)
        Put 0,0,Bild$
        Void Xbios(&H6,L:Varptr(Header$)+2)
    Endif
Return
'
'
'
Procedure Sichern
    Fileselect "\*.*","SICHERN.pic",Dat$
    Get 0,0,Xmax-1,Ymax-1,Bild$ 
    If Not Dat$=""
        Header$=Chr$(0)+Chr$(Res)+Right$(Header$,32)
        Open "O",#1,Dat$
        Print #1,Header$;
        Print #1,RightS(Bild$,32000);
        Close #1 
    Endif
    Put 0,0,Bild$ 
Return 
End
'
'
'
Procedure Ende 
    End 
Return
'
'
'
Procedure Dmenu 
    Deffill 1,0,0 
    @Haufl
    X1=0.27*Xmax
    Y1=0.74*Ymax
    X2=0.73*Xmax
    Y2=0.9*Ymax
    Get X1,Y1,X2,Y2,Save$
    Prbox X1,Y1,X2,Y2 
    Texty=Y1+Ymax/25 
    Deftext 1,16
    Text X1+50,Texty,"Minitizer/Easytizer"
    Deftext 1,0
    Text X1+16,Texty+Ymax/20,"D - Digitalisieren L - Laden" 
    Text X1+16,Texty+Ymax/10,"T - Trigger   S - Sichern"
Return
'
'
'
Procedure Udmenu 
    Put X1,Y1,Save$
Return
'
'
'
Procedure Haufl 
    Res=2-Xbios(&H4)
    If Res=0 
        Xmax=640 
        Ymax=400 
    Else
        Xmax=640
        Ymax=200
    Endif
Return
' Die Farbpalette 
'
'
Data &H00,&H00
Data &H00,&H00,&H03,&H33,&H05,&H55,&H07,&H77
Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
' Easysoft Routinen
' Entspricht dem Assembler Programm (Listing 1)
'
Data 77,250,255,254,75,239,0,4,45,77 
Data 2,232,74,109,0,0,103,64,12,109 
Data 0,1,0,0,103,40,65,249,0,251 
Data 128,8,16,16,192,60,0,64,50,60 
Data 0,100,20,16,196,60,0,64,177,2 
Data 86,201,255,246,112,0,178,124,255,255 
Data 103,2,112,1,78,117,112,0,8,57 
Data 0,4,0,251,128,8,103,2,112,1 
Data 78,117,72,122,2,144,63,60,0,0 
Data 63,60,0,25,78,78,80,143,48,60 
Data 3,232,78,113,81,200,255,252,72,122 
Data 0,30,63,60,0,38,78,78,92,143 
Data 72,122,2,107,63,60,0,0,63,60 
Data 0,25,78,78,80,143,112,0,78,117 
Data 42,122,2,90,64,238,2,236,0,124 
Data 7,0,80,238,2,230,65,249,0,251 
Data 128,0,67,249,0,251,128,2,69,249 
Data 0,251,128,8,112,6,66,66,114,12 
Data 146,109,0,2,106,2,66,65,178,124 
Data 0,11,99,2,114,11,54,1,194,252 
Data 0,8,71,250,0,162,214,193,45,75 
Data 1,106,198,252,0,6,71,250,1,126 
Data 214,195,45,75,2,84,8,18,0,5 
Data 102,250,74,121,0,251,128,6,50,45 
Data 0,2,231,73,126,0,38,109,0,12 
Data 214,194,8,18,0,5,103,250,120,5 
Data 1,18,103,252,1,18,102,252,122,100 
Data 1,18,86,205,255,252,186,124,0,84 
Data 101,4,83,68,96,234,1,18,102,252 
Data 58,45,0,10,1,18,103,252,1,18 
Data 102,252,81,205,255,246,1,18,102,252 
Data 74,109,0,8,102,0,0,204,58,45 
Data 0,4,74,109,0,6,102,2,226,77 
Data 83,69,74,68,103,8,214,193,74,109 
Data 0,6,102,138,1,18,103,252,74,18 
Data 106,252,74,80,74,144,74,144,74,144 
Data 78,249,35,51,4,68,54,145,214,252 
Data 0,8,74,80,54,145,214,252,0,8 
Data 74,80,54,145,214,252,0,8,74,80 
Data 54,145,214,252,0,8,74,80,54,145 
Data 214,252,0,8,74,80,54,145,214,252 
Data 0,8,74,80,54,145,214,252,0,8 
Data 74,80,54,145,214,252,0,8,74,80 
Data 54,145,214,252,0,8,74,80,54,145 
Data 214,252,0,8,74,80,54,145,214,252 
Data 0,8,74,80,54,145,214,252,0,8 
Data 74,109,0,6,102,2,214,193,81,205 
Data 255,130,82,71,8,7,0,0,102,26 
Data 74,121,0,251,128,4,74,121,0,251 
Data 128,4,74,121,0,251,128,4,74,121 
Data 0,251,128,4,84,66,190,124,0,8 
Data 102,0,254,246,70,250,0,232,78,117 
Data 58,45,0,4,74,109,0,6,102,2 
Data 226,77,83,69,74,68,103,40,12,109 
Data 0,1,0,6,103,0,254,212,12,109 
Data 0,2,0,6,103,0,0,8,214,193 
Data 214,193,96,14,74,46,2,230,103,8 
Data 66,46,2,230,96,0,254,182,1,18 
Data 103,252,74,18,106,252,78,113,74,144 
Data 74,144,74,144,78,249,35,51,4,68 
Data 38,144,214,252,0,16,38,144,214,252 
Data 0,16,38,144,214,252,0,16,38,144 
Data 214,252,0,16,38,144,214,252,0,16 
Data 38,144,214,252,0,16,38,144,214,252 
Data 0,16,38,144,214,252,0,16,38,144 
Data 214,252,0,16,38,144,214,252,0,16 
Data 38,144,214,252,0,16,38,144,214,252 
Data 0,16,74,109,0,6,102,4,214,193 
Data 214,193,81,205,255,150,82,71,74,109 
Data 0,6,103,2,82,71,8,7,0,0 
Data 102,26,74,121,0,251,128,4,74,121

Listing 2: Ein Beispielprogramm zur Ansteuerung der Easysoft-Routinen in GFA-Basic. Das Progrämmchen überträgt das, in den Data-Zeilen enthaltene, Maschinenprogramm in einen String, um es dann auszuführen. Als Bildformat wird das DEGAS-Format angenommen. Beide Programme sind auch auf der Diskette zu diesem Heft erhältlich.

Funktion ():

Aufruf:

Void C: Easytizer%(0, Xw, Yw, Int, Bpi, Pos, L: Adresse)

Parameter:

Xw:
Breite des Digitaliserten Bildausschnitts, die in n/64 Bildpunkten angegeben werden muß. Minimal kann Xw eins werden, wobei nur mit einer Breite von 64 Bildpunkten digitalisiert wird. Maximalwert für Xw ist 12, wobei in einer Breite von 768 Bildpunkten digitalisiert wird.

Yw:
Anzahl der Zeilen, die ab Pos digitalisiert werden. Sofern Int gleich 0 ist (Interlace erlaubt), dürfen Yw plus Pos nicht mehr als 600 betragen, da ein Videobild nur etwa 600 sichtbare Zeilen überträgt. Ist Int jedoch größer 0, dann dürfen Yw plus Pos nicht mehr als 300 betragen.

Int:
Bestimmt den Interlace-Modus. Wenn Int = 0 ist, werden beide Halbbilder (gerade und ungerade Zeilen) des Videosignals ausgewertet. Bei Int = 1 wird jedoch nur noch ein Halbbild zur Auswertung herangezogen, wodurch das digitalisierte Bild um den Faktor 2 Vertikal gestaucht erscheint. Int = 2 ist ein Sonderfall, der nur gilt, falls Bpi = 1 (2 Bildebenen) ist. Dieser Modus ist nur zu gebrauchen für Videosignalquellen, die in beiden Halbbildern die gleiche Information übertragen, also nur 312 Zeilen haben, ist aber doppelt so schnell (80 ms) da jetzt eine komplette Bildperiode nur noch halb so groß ist.

Für Int > 1 gilt, daß das digitalisierte Bild halb so hoch erscheint, was jedoch in mittlerer Auflösung durchaus sinnvoll ist.

Bpl:
Gibt die Anzahl der Bildebenen (Graustufen) an. Zwei Werte sind zugelassen:

Bpl = 0: Wählt eine Bildebene aus (Monochrom).

Bpl = 1: Wählt zwei Bildebenen aus (4-Graustufen/mittlere Auflösung).

Pos:
Bestimmt die Zeile, ab der angefangen wird, die mit Yw spezifizierte Anzahl von Zeilen zu digitalisieren. Falls Int = 0 ist, muß dieser Wert, durch zwei geteilt werden.

Adresse:
Die Adresse des Bildspeichers, in den das digitalisierte Bild übertragen wird.

Der Zweck dieser Routine (Funktion 0)
Digitalisieren eines Videosignals mit verschiedenen Optionen in einen Speicherabschnitt, welcher dem Aufbau des Atari-ST Bildschirmspeichers entspricht. Der nötige freie Speicher berechnet sich zu: Speicher in Bytes = Xw8Yw*(Bpl+1).

Zeitbedarf: Normal 160 mS oder 80 mS falls Int = 2 und Bpl =1.

Funktion 1:

Aufruf:
Wert = C:Easytizer%(1)

Parameter:
Wert wird 1, falls die Schnappschuß-Taste gedrückt ist.

Zweck der Funktion 1
In Wert wird der Zustand der Schnappschuß-Taste zurückgegeben.

Funktion 2:

Aufruf:
Wert = C:Easytizer%(2)

Parameter:
Wert wird 1, wenn ein Videosignal anliegt.

Zweck der Funktion 2
Prüfen, ob ein Videosignal anliegt, da Funktion 0 solange blockiert, wie kein Videosignal anliegt.

Einige Beispiele für Funktionsaufrufe
Gesetzt den Fall, Sie wollen in mittlerer Auflösung ein Videosignal von einer 312-Zeilen-Kamera mit einer Auflösung von 640*200 direkt in den Bildspeicher digitalisieren, dann könnte das folgendermaßen geschehen:

Void C: Easytizer%(0,10,200,2,1,50,L: Xbios (&H3))

Der Ausdruck ’L:Xbios (&H3)’ gibt lediglich die Adresse des logischen Bildspeichers zurück.

Oder Sie wollen in hoher Auflösung ein normales Videosignal mit 625 Zeilen direkt in den Bildspeicher digitalisieren:

Void C: Easytizer%(0,10,400,0,0,50,L: Xbios(&H3))

Oder Sie wollen nicht direkt in den Bildspeicher digitalisieren, aber mit maximaler Auflösung (768 ★ 600) und 4 Graustufen arbeiten, z. B. für Bildverarbeitungszwecke:

Void C: Easytizer%(0,12,600,0,1,3,Freispeicher%)

Wobei in Freispeicher% die Adresse eines 115200 Byte großen Speicherblocks enthalten sein muß.

In Listing 2 ist ein kleines GFA-BASIC Programm abgedruckt, welches das Digitalisieren und Sichern (Speichern im Degas-Format) eines Bildes erlaubt und gleichzeitig die Anwendung der EASYSOFT-Routinen zeigt.

Bild 2: Das Menü der über die Redaktion erhältlichen Software.

Außerdem ist eine Software über die Redaktion verfügbar, die weit über das hinausgeht, was sich in einer Zeitschrift veröffentlichen läßt. Einen kleinen Vorgeschmack bietet Bild 2, in dem das Menü dieser Software zu sehen ist.

Wir hoffen, daß Sie mit dem Easytizer viele interessante Anwendungen erschließen können.

Korrekturen zu Teil 1

Leider hatten sich im Teil 1 zum Easytizer (ST Computer Nr. 10/87 Seite 58 und 59) folgende Fehler eingeschlichen:

Schließlich wurde noch verschwiegen, daß „ST1" drei Lötstifte, die für künftige Erweiterungen vorgesehen sind, vorerst nicht benötigt werden und deshalb weggelassen werden können.

(RA)

Hinweis!

Im Zusammenhang mit einigen Videorecordern hat sich gezeigt, daß das Bild evtl, nicht ruhig steht. Grund dafür ist ein pegelmäßig zu starker Farbburst, den leider manche Recorder erzeugen. Abhilfe schafft folgende Änderung: C36=100 pF ; R11 = 8K2 Ohm


Stefan Höhn


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]