Handscanner für den Atari ST sind immer noch selten für nennenswert weniger als 4 „Schumänner“ zu haben. Anscheinend mangelt es in diesem Marktsegment etwas an Konkurrenz. Die ist jedoch bei der PC-Peripherie knallhart. Was liegt also näher, als die Anschaffung eines PC-Handscanners und eine entsprechende Anpassung an den Atari ST?
Sonderangebot einer großen HiFi- und Computerkette in Mülheim/Ruhr: Beim Preis von 125 DM für einen Marstek M 105 (abgesehen von einem leicht zu ergänzenden DIP-Schalter, baugleich mit den Typen M 105 Plus, M 800, M 800 Plus, siehe Literaturhinweis) mit PC-Interface schlage ich zu. Beim Auspacken der Neuerwerbung stellt sich allerdings recht schnell Ernüchterung ein: Das 37seitige „Handbuch“ enthält hauptsächlich Angaben zur Bedienung des mitgelieferten Programms; Informationen zum Datentransfer zwischen Handscanner und PC suche ich leider vergeblich. Die Firma Marstek in Neuss kann meine Neugier ebenfalls nicht befriedigen. Sie vertreibt das taiwanische Erzeugnis nur und deutet an, daß der Hersteller selbst sich wahrscheinlich über Anschlußbelegung und Ablauf der Datenübertragung am 8poligen Scanner-Stecker nicht äußern wird.
Marstek bietet jedoch ein preislich attraktives ST-Interface an. Ich erstehe es für ca. 110 DM - ohne (optional erhältliches) 12V-Netzteil, da ich bereits ein geeignetes besitze - inkl. Software und Versandkosten direkt bei der Firma. Das beiliegende Software-Paket, „DAATAscan Professional“ ist brauchbar und beinhaltet die üblichen Möglichkeiten wie Scannen, Abspeichern (wahlweise im Degas- oder IMG-Format), Laden, Invertieren, Spiegeln, Drehen von Bildern, allein Dithering
ist hiermit nicht möglich, wenn auch im englischen Manual Gegenteiliges behauptet wird. Auch mit Druckertreibern ist das Paket nicht eben üppig ausgestattet: Wie zu erwarten, wird mein Star LC 24-10 ^ nicht speziell unterstützt, so daß die ausgedruckten Grafiken alles andere als maßstäblich sind. Naja, die Treiber für den Star fehlen oft auch bei wesentlich teureren „Weichwaren“ - und was erwartet man bei Gesamtkosten von nicht einmal 240,- DM für Scanner, Interface und Programm?
Nun: In dem 24seitigen Manual für die ST-Software steht „natürlich“ wieder nichts über den Datenaustausch zwischen dem in den ROM-Port des ST zu steckenden, ca. 9x3x5 (BxHxT) großen, „DAATAscan-PANDAAL“-Adapter und dem Rechner. Offensichtlich möchte Marstek den werten Kunden auf käufliche Programme festnageln. Was bleibt mir also anderes übrig, als „DAATAscan“ etwas näher unter die Lupe zu nehmen, möchte ich doch später einmal den Scanner auch für die Erstellung eigener EAN(Bar-)-Code- und OCR-Software verwenden.
Gesagt, getan. Hier die Ergebnisse meiner Analyse, die durch ein kleines Demonstrationsprogrämmchen, das lediglich den SM-124-Monitor füllt (eine Anpassung an Farbmonitore mag der engagierte Leser bitte selbst vornehmen, das würde hier den Rahmen sprengen), etwas veranschaulicht werden: Wie bei allen Geräten, die an den ROM-Port angeschlossen werden, verbietet es sich auch hier, auf den ROM-Port zu schreiben, was allenfalls zu einem Bombenhagel führte. Die Richtung vom ST zum Scanner, die für die Synchronisation beider Geräte zweifellos erforderlich ist, wird deshalb über das Lesen von gewissen Speicherstellen realisiert. Da Adreßleitungen letztendlich eine Untergruppe der Datenleitungen sind (zwar nur in eine Richtung, aber immerhin), genügt es also, wenn man ein Byte/Wort/Doppel wort „ausliest“ und den somit erhaltenen Müll im Datenregister einfach ignoriert.
Prinzipiell läuft die Sache folgendermaßen ab:
Es werden nacheinander so viele Bytes eingelesen, wie es die gewünschte Bildbreite erfordert, höchstens aber so viele, daß die Scan-Breite des Geräts nicht überschritten wird.
Wie dieser Aufstellung leicht zu entnehmen ist, kennt das Interface zwei Register:
Bit | |
---|---|
0-7 | Scanline-Daten |
8 | Data Strobe, gesetzt, wenn anliegende Daten gültig |
9 | End of Line, gesetzt, wenn Zeilenende erreicht |
Bit | |
---|---|
0 | Carriage Return, hierdurch wird der Scanner an den Zeilenanfang gesetzt. |
1 | Scanner on, Beleuchtung und übrige Stromversorgung einschalten. Zwar sind Kombinationen möglich, es ist jedoch wenig sinnvoll, für CR nur Bit 0 zu setzen (wer’s mag, kann selbstverständlich auch seine Briefe in den ausgeschalteten Computer eingeben). |
Die nicht aufgeführten Bits am Interface sind offensichtlich nicht belegt.
Unter BASIC z.B. lassen sich die grundlegenden Dinge durchaus nachvollziehen. Zeitweilige Datentransferraten von ca. 111 KByte/ sec verbieten jedoch auch in Assembler eine ausschweifende Programmierung, so daß wir hier über Hochsprachen schon nicht mehr zu diskutieren brauchen. Daß die Interrupts beim Einlesen ebenfalls ausgeschaltet werden müssen, versteht sich nun von selbst. Wie das Listing zeigt, weicht die Praxis in zwei bedeutenden Punkten von der bislang behandelten Theorie ab:
Erstens benötigt der Scanner nach jedem „Wagenrücklauf" (CR) eine kleine Verschnaufpause, in der er üblicherweise nur „Schrott“ sendet. Aus diesem Grunde ist die Warteschleife first_wt eingebaut. Der Wert in D4 ist empirisch ermittelt, andere Werte können ebenfalls korrekt sein (ausprobieren!).
Zweitens wiederholt das Gerät in einigen Auflösungsstufen (wohl aus übertragungstechnischen Gründen) die gleichen Daten ein- bis dreimal (siehe Tabelle). Diese Wiederholungs-Bytes müssen natürlich wieder ausgefiltert werden, möchte man nicht seltsam verzerrte Bilder erhalten. Deshalb wird nicht jedes Byte aus der tstbusy-Schleife auch in den Bildschirm geschrieben.
Auflösung [dpi] | Scanline-Breite [Bytes] | davon verwertbare Bytes | Anzahl der Wiederholungs-Bytes / verwertbarem Byte |
---|---|---|---|
100 | 208 | 52 | 3 |
200 | 208 | 104 | 1 |
300 | 156 | 156 | 0 |
400 | 208 | 208 | 0 |
500 | 260 | 260 | 0 |
600 | 312 | 312 | 0 |
700 | 364 | 364 | 0 |
800 | 416 | 416 | 0 |
Alle Werte empirisch ermittelt, also ein Ergebnis von Versuchen.
; Programm zum probeweisen Einlesen und
; Abbilden der Daten auf einen SM 124
; vom Handscanner Marstek M 105
;
; Assembler: Profimat (Data Becker),
; relozierbar zu assemblieren. Nicht ausdrücklich
; mit einem Extender versehene Operatoren beziehen
; sich auf den Datentyp "Wort".
;
; Autor: Thomas Maurer
; (c) MAXON Computer GmbH 1993
;
text
; Auflösung eingeben
eingabe pea info(pc) ; GEMDOS-PRINT-LINE
move #9,-(sp)
trap #1
addq.l #6,sp
move #1,-(sp) ; CONIN
trap #1
addq.l #2,sp
cmpi.b #'1’,d0 ; Überprüfung auf
bcs eingabe ; Bereichsüberschrei-
cmpi.b #'9',d0 ; tung bei der Ein-
bcc eingabe ; gabe,
andi #$f,d0 ; Zahlwert maskieren
move d0,d7 ; und sichern,
lea jtable(pc),a0 ; Anzahl der
subq #1,d0 ; Schrottbytes in
move.b 0(a0,d0),d0 ; einem Datenpaket
move d0,datajump ; aus Tabelle, ab-
; hängig von der
; Auflösung,
pea meld(pc) ; Meldung ausgeben
move #9,-(sp) ; GEMDOS
trap #1 ; PRINT-
addq.l #6,sp ; LINE
clr.l -(sp) ; Supervisormodus
move #$20,-(sp) ; modus einschalten
trap #1
addq.l #6,sp
move.l d0,ssp_save
move sr,save_sr ; SR retten
ori #$700,sr ; Interrupts aus,
; die würden hier nur
; stören.
; Register vorbesetzen:
; A6 : Scanner CR
; A5 : Scanner Read data/status
; A4 : Schreibzeiger VRAM
; d1 : 8, für NOT BUSY
lea $fb3000,a6
lea $fafffe,a5
moveq #8,d1
move.l $44e,a4 ; logical screenbase
move #80,d3 ; Bildschirm-Byte-
; breite des SW-
; Monitors.
moveq #51,d0 ; Scanline-Breite
; Breite in Bytes bei
; 100 dpi.
mulu d7,d0 ; * Auflösung / 100
; = verwertbarer An-
; teil der Scanline
; in Bytes,
cmpi #81,d0 ; Mehr als 80 Bytes/
bcs.s ok ; Scanline sind nicht
moveq #80,d0 ; darstellbar.
ok sub d0,d3 ; Gewünschte Breite
; des Bildes (Bytes)
; = Differenz zum
; nächsten Zeilen-
; anfang.
subq #1,d0 ; für DBRA
move d0,b_breite
move #399,line_num ; 400 Zeilen
move $fb2000,d0 ; Scanner ein,d0: Schrott.
move line_num,d6 ; Anzahl der zu
; scannenden Linien.
; Es folgen nun die elementaren
; Lesestrukturen
cr move (a6),d0 ; CR auf Scanner aus-
; geben, d0: Schrott.
first_rd move (a5),d0 ; Das erste Datenbyte
btst d1,d0 ; der jeweiligen Scan-
beq first rd ; line ist Schrott,
moveq #20,d4 ; Scanner muß sich
first_wt dbra d4,first wt ; erst einmal "beruhigen".
move b_breite,d7 ; Bytebreite der
; Scanline exclusive
; Schrottbytes
waitbusy move datajump(pc),d4 ; Anzahl der
; Schrottbytes in
; jedem Datenpaket
tstbusy move (a5),d0 ; Datenregister
btst d1,d0
beq tstbusy ; Scanner busy
dbra d4,tstbusy ; war Schrott, also
; noch einmal
not d0 ; verwertbares Byte des Daten-
; pakets invertieren, da Weiß
; vom Scanner einem gesetzten
; Bit entspricht, bei ATARI
; dies aber einen schwarzen
; Punkt erzeugt.
move.b d0,(a4)+ ; Ab in den Bildschirm
dbra d7,waitbusy ; Nächstes Datenpaket
adda d3,a4 ; Differenz zur nächsten
; Bildschirmzeile ergänzen,
wait_le btst #1,(a5) ; Warten auf das Ende
beq wait_le ; der Scannerzeile,
dbra d6,cr ; zur nächsten Seile
move $fb0000,d0 ; Scanner aus.
move save_sr(pc),sr ; Statusregister
; restaurieren
move.l ssp_save(pc),-(sp) ; Supervisor-
move #$20,-(sp) ; modus
trap #1 ; ausschalten
addq.l #6,sp
clr -(sp) ; GEMDOS TERM
trap #1
data
info dc.b $1b,'E' ; clear screen
dc.b 'Scannen mit Marstek M 105 in '
dc.b 'allen 8 Auflösungsstufen',$d,$a
dc.b '-------------------------------'
dc.b '-----------------------', $d, $a, $a
dc.b 'Auflösung eingeben;',$d,$a,$a
dc.b ' (1) - (8) für (1)00'
dc.b 'bis (8)00 dpi',$d,$a,0
meld dc.b $1b,'E' ; clear screen
dc.b 'Vor dem Scannen bitte die einge-'
dc.b 'stellte Auflösung am Scanner '
dc.b 'selbst uberprüfen.',$d,$a
dc.b 'Sie muß mit der gerade eingege-'
dc.b 'benen übereinstimmen.',$d,$a,$a
dc.b 'Es kann losgehen!’,0
jtable dc.b 3,1,0,0,0,0,0,0
bss
datajump ds.w 1 ; Anzahl der Schrottbytes je
; Datenpaket
ssp_save ds.l 1 ; alter Stackpointer
save_sr ds.w 1 ; altes Statusregister
b_breite ds.l 1 ; tatsächliche Bildbreite
line_num ds.l 1 ; Anzahl der Bildzeilen
end