

; NEC P6 - Druckertreiber 180 DPI [CRACK ART CAP]
; Umrechnung erfolgt auf ein 4*4 Raster / 1280*800 dots

; Untersttzung Processing-Anzeige


; Returnwert: (1=TRUE/0=FALSE)

; Copyright ½ Jan Borchers & Detlef R”ttger - Goslar, den 18.07.92

; Routine wie normales Programm mit Header assemblieren. (Kein INLINE!)




; Definition der CrackArt-šbergabe-Struktur

; Erweiterte šbergabeparameter ab Version 1.21 TT+

Version         EQU -2

NumberOfScreens EQU 0           ; w Anzahl der Arbeitsbildschirme (1-9)
CurScr          EQU 2           ; w Aktueller Arbeitsbildschirm (1-9)
CurScrAdr       EQU 4           ; l Startadresse des aktuellen Arbeitsbildschirms
CurPalAdr       EQU 8           ; l Startadresse der aktuellen Arbeitspalette

; Adressen der Arbeitsbildschirme fr eigenen Gebrauch.

WorkScrAdr_1    EQU 12          ; l Adresse des ersten Bildschirms
WorkScrAdr_2    EQU 16          ; l Adresse des zweiten Bildschirms
WorkScrAdr_3    EQU 20          ; l Adresse des dritten Bildschirms

BlockScrAdr     EQU 24          ; l Adresse des Blockbildschirms
BlockPalAdr     EQU 28          ; l Adresse der Blockfarbpalette
BlockMaskScrAdr EQU 32          ; l Adresse des Blockmasken-Bildschirms
; (vollfarbig, d.h. alle Planes sind gesetzt)
BlockW          EQU 36          ; w Breite des Blocks in Pixel
BlockH          EQU 38          ; w H”he des Blocks in Pixel

ScrAdr_1        EQU 40          ; l Startadresse des ersten Arbeitsbildschirms
ScrPalAdr_1     EQU 44          ; l Startadresse der ersten Arbeitspalette
ScrAdr_2        EQU 48
ScrPalAdr_2     EQU 52
ScrAdr_3        EQU 56
ScrPalAdr_3     EQU 60
ScrAdr_4        EQU 64
ScrPalAdr_4     EQU 68
ScrAdr_5        EQU 72
ScrPalAdr_5     EQU 76
ScrAdr_6        EQU 80
ScrPalAdr_6     EQU 84
ScrAdr_7        EQU 88
ScrPalAdr_7     EQU 92
ScrAdr_8        EQU 96
ScrPalAdr_8     EQU 100
ScrAdr_9        EQU 104
ScrPalAdr_9     EQU 108

; Erweiterte šbergabeparameter ab Version 1.20 TT+

CurSrcW         EQU 112
CurSrcH         EQU 114
CurPalColors    EQU 116
CurPalBits      EQU 118
BlockMode       EQU 120

; Erweiterte šbergabeparameter ab Version 1.21 TT+

Processing      EQU 122


; hier muž der Sprungbefehl zum Routinenanfang folgen. Direkt hinter diesem
; Befehl beginnt der Treiber-Header.

                bra       Init


                DC.B 'CADriver' ; Kennung Crack Art Driver

                DC.W $0101      ; Versionsnummer BCD-Format (1.00)
                DC.L $20081992  ; Erstellungsdatum BCD-Format (ddmmyyyy)

                DC.W 320        ; Eingabebreite in Ger„teeinheiten
                DC.W 200        ; Eingabeh”he
                DC.W 4          ; eingegebene Farbpalettenl„nge (2^n Eintr„ge)
                DC.W 9          ; eingegebene Farbtiefe (2^n Farben)
                DC.W 0          ; Eingabeaufl”sung horizontal (DPI)
                DC.W 0          ; Eingabeaufl”sung vertikal

; IO-Technik:
; 0 unbekannt
; 1 Bildschirm
; 2 Scanner
; 3 Video-Digitizer
; 4 Matrixdrucker
; 5 Laserdrucker
; 6 Plotter
; 7 Typenraddrucker

                DC.W 1          ; Technik Bildschirm

                DC.W 1280       ; Ausgabebreite in Ger„teeinheiten
                DC.W 800        ; Ausgabeh”he
                DC.W 1          ; ausgegebene Farbpalettenl„nge
                DC.W 1          ; ausgegebene Farbtiefe
                DC.W 180        ; Ausgabeaufl”sung horizontal (DPI)
                DC.W 180        ; Ausgabeaufl”sung vertikal

                DC.W 4          ; Technik Matrixdrucker

                DC.B 'Folley - Unlimited Greyscales   ' ; 32 Bytes Beschreibung

                DC.W 1          ; 1=Processing-Anzeige wird untersttzt

                DS.W 34         ; reserviert

; Hier folgt die Definition des Treiber-Icons, das im Hauptmen
; angezeigt wird.
; Soll kein Icon eingebunden werden, so sollten korrekterweise nach
; dem Flag-Word weitere 512 Bytes Freiraum folgen.

                DC.W 1          ; Flag (0=kein Icon / 1=Icon aktiv)

                DC.W $7fff,$8000,$ffff,$00,$ffff,$01,$fffe,$00
                DC.W $bfff,$7fff,$ffff,$00,$fffe,$fffd,$fffe,$00
                DC.W $d000,$7000,$e000,$00,$0a,$0e,$06,$00
                DC.W $e000,$6fff,$c000,$00,$06,$fff6,$02,$00
                DC.W $c7ff,$5fff,$c000,$00,$fff2,$fffa,$02,$00
                DC.W $cfff,$5fff,$c000,$00,$fffa,$fffa,$02,$00
                DC.W $cfff,$5fff,$c000,$00,$fffa,$fffa,$02,$00
                DC.W $cfff,$5fff,$c21b,$00,$ff5a,$feda,$f1e2,$00
                DC.W $cff3,$5ffd,$c713,$00,$95fa,$ff7a,$93e2,$00
                DC.W $cff5,$5ffd,$c793,$00,$f22a,$feba,$8762,$00
                DC.W $cff7,$5ffd,$c3d3,$00,$fcca,$fffa,$a602,$00
                DC.W $cff7,$5fff,$c3f3,$00,$ecfa,$fffa,$e602,$00
                DC.W $cef7,$5ffd,$c2f3,$00,$affa,$fefa,$a702,$00
                DC.W $cef5,$5ffd,$c273,$00,$abda,$ff7a,$87a2,$00
                DC.W $cef7,$5ffd,$c233,$00,$bfca,$fffa,$93e2,$00
                DC.W $cff7,$5fff,$c313,$00,$f6ca,$fffa,$f1c2,$00
                DC.W $ce76,$5fff,$c000,$00,$071a,$fffa,$02,$00
                DC.W $cfff,$5fff,$c000,$00,$fffa,$fffa,$02,$00
                DC.W $cfff,$5fff,$c07e,$7e,$fffa,$fffa,$3c02,$3c00
                DC.W $cff3,$5fff,$c033,$33,$e3fa,$fffa,$6202,$6200
                DC.W $cff7,$5fff,$c033,$33,$6efa,$fffa,$6002,$6000
                DC.W $cff7,$5fff,$c033,$33,$7ffa,$fffa,$7c02,$7c00
                DC.W $cffe,$5fff,$c03e,$3e,$67fa,$fffa,$6602,$6600
                DC.W $cff0,$5fff,$c030,$30,$eefa,$fffa,$6602,$6600
                DC.W $cff7,$5fff,$c030,$30,$eefa,$fffa,$6602,$6600
                DC.W $cfff,$5fff,$c078,$78,$fcfa,$fffa,$3c02,$3c00
                DC.W $cfc3,$5fff,$c000,$00,$e1fa,$fffa,$02,$00
                DC.W $cfff,$5fff,$c000,$00,$fff2,$fffa,$02,$00
                DC.W $e7ff,$6fff,$c000,$00,$ffe6,$fff6,$02,$00
                DC.W $d000,$7000,$e000,$00,$0a,$0e,$06,$00
                DC.W $ffff,$3fff,$ffff,$00,$fffc,$fffc,$fffe,$00
                DC.W $00,$4000,$8000,$00,$00,$00,$00,$00


Init:           movem.l   d1-a6,-(sp)   ; Register sichern

                move.w    #17,-(sp)     ; CPRNOS()
                trap      #1
                addq.l    #2,sp
                tst.l     d0
                beq       ExitFalse     ; Drucker busy

                movea.l   60(sp),a6     ; Strukturadresse holen


; Umwandlung des Plane-Formats in 1 Nibble pro Pixel

; Quelle: aktueller Bildschirm
; Ziel:   Arbeitsbildschirm 1

ToNibble:       movea.l   CurScrAdr(a6),a0
                movea.l   WorkScrAdr_1(a6),a1
                move.w    #3999,d0      ; 4000*16 pixel
ToNibble_0:     movem.w   (a0)+,d4-d7
                move.w    #3,d1
ToNibble_1:     move.w    #3,d2
ToNibble_2:     add.w     d7,d7
                addx.w    d3,d3
                add.w     d6,d6
                addx.w    d3,d3
                add.w     d5,d5
                addx.w    d3,d3
                add.w     d4,d4
                addx.w    d3,d3
                dbra      d2,ToNibble_2
                move.w    d3,(a1)+
                dbra      d1,ToNibble_1
                dbra      d0,ToNibble_0
                movea.l   WorkScrAdr_1(a6),a0 ; ab jetzt Quelle


; Umwandlung der Farbtabelle in Graustufen nach Folley
; Gewichtung rot/grn/blau je 30/59/11%

Folley:         movea.l   CurPalAdr(a6),a1
                movea.l   WorkScrAdr_2(a6),a2
                move.w    #15,d0
Folley_0:       move.w    (a1)+,d1      ; blau
                move.w    d1,d2
                lsr.w     #4,d2         ; grn
                move.w    d2,d3
                lsr.w     #4,d3         ; rot
                and.w     #7,d1
                and.w     #7,d2
                and.w     #7,d3
                mulu      #11,d1        ; blau 11%
                mulu      #59,d2        ; grn 59%
                mulu      #30,d3        ; rot  30%
                add.w     d2,d1
                add.w     d3,d1         ; Grauwert (0-700)
                move.w    d1,(a2)+
                dbra      d0,Folley_0
                movea.l   WorkScrAdr_2(a6),a1 ; Grauwertpalette


                lea       32(a1),a2     ; Fehlertabelle hinter Grauwerttabelle
                lea       2560(a2),a3   ; 24-Zeilen-Buffer hinter Fehlertabelle

                lea       InitPrinter(pc),a5 ; Drucker initialisieren
                bsr       OutMultiple   ; Bytefolge ausgeben
                beq       ExitFalse     ; bei Fehler raus

                bsr       ClearBuffer

                moveq     #0,d7         ; y

MainLoopY:      tst.l     Processing(a6) ; Processinganzeige verfgbar?
                beq.s     NoProcessing  ; nein
                movem.l   d0-d1/a0,-(sp) ; Register sichern
                move.l    d7,d0         ; aktuelle zeile
                move.l    #799,d1       ; zeilen gesamt (-1)
                movea.l   Processing(a6),a0 ; Processing-Routinenadresse
                jsr       (a0)          ; aufrufen
                movem.l   (sp)+,d0-d1/a0 ; register zurcksetzen
NoProcessing:
                moveq     #0,d6         ; x
                moveq     #0,d1         ; i (Fehler)

MainLoopX:      move.w    d6,d2
                move.w    d7,d3
                bsr       GetPixel      ; Farbwert * 2 in d0 zurck
                add.w     d0,d1         ; Grauwert i(0-700)

                move.w    d6,d2         ; x
                add.w     d2,d2         ; Offset Fehlerbuffer y-Richtung
                add.w     0(a2,d2.w),d1 ; Fehler addieren

                cmp.w     #350,d1       ; Fehlerschwelle berschritten
                blt.s     Main_0        ; Pixel setzen
                sub.w     #700,d1       ; Fehler wurde minimiert
                bra.s     Main_1

Main_0:         move.w    d6,d2         ; x
                add.w     d2,d2         ; *2
                add.w     d6,d2         ; x*3
                moveq     #0,d3
                move.w    d7,d3         ; y
                divu      #24,d3
                swap      d3
                lsr.w     #3,d3         ; y/8
                add.w     d3,d2         ; Byteoffset ziel
                move.w    d7,d3         ; y
                not.w     d3
                and.w     #7,d3         ; -> y=7-(y and 7)
                bset      d3,0(a3,d2.w) ; Pixel setzen

Main_1:         asr.w     #1,d1         ; i div 2  (Achtung! Negative Werte)
                move.w    d6,d2         ; x
                add.w     d2,d2         ; Offset Fehler-Zeilenbuffer y
                move.w    d1,0(a2,d2.w) ; yerr(x)=i

                addq.w    #1,d6
                cmpi.w    #1280,d6
                blt.s     MainLoopX

                addq.w    #1,d7
                moveq     #0,d0
                move.w    d7,d0
                divu      #24,d0
                swap      d0
                tst.w     d0
                bne.s     Main_2

                bsr.s     Print         ; 24 zeilen voll, drucken
                beq.s     ExitFalse
                bsr       ClearBuffer

Main_2:         cmpi.w    #800,d7       ; CHANGE
                blt       MainLoopY

                bsr.s     Print
                beq.s     ExitFalse


ExitTrue:       moveq     #1,d0         ; TRUE
                bra.s     Exit
ExitFalse:      moveq     #0,d0         ; FALSE
Exit:           movem.l   (sp)+,d1-a6
                rts


Print:          movem.l   d1-a6,-(sp)
                move.w    #255,-(sp)    ; CRAWIO()
                move.w    #6,-(sp)
                trap      #1
                addq.l    #4,sp
                movem.l   (sp)+,d1-a6
                cmp.l     #$01001b,d0   ; ESC
                beq.s     PrintFalse
                tst.l     d0
                bne.s     Print

                lea       CR(pc),a5     ; Wagenrcklauf
                bsr.s     OutMultiple
                beq.s     PrintFalse

                lea       Graphic180dpi(pc),a5 ; Grafikzeile beginnen
                bsr.s     OutMultiple
                beq.s     PrintFalse

                movea.l   a3,a5
                move.w    #3839,d1
Print_0:        clr.w     d0
                move.b    (a5)+,d0
                bsr.s     OutSingle
                beq.s     PrintFalse
                dbra      d1,Print_0

                lea       LineFeed(pc),a5
                bsr.s     OutMultiple
                beq.s     PrintFalse

PrintTrue:      moveq     #1,d0
                rts
PrintFalse:     moveq     #0,d0
                rts


OutSingle:      movem.l   d1-a6,-(sp)
                move.w    d0,-(sp)      ; Zeichen in d0
                move.w    #5,-(sp)      ; Printer Output
                trap      #1
                addq.l    #4,sp
                movem.l   (sp)+,d1-a6
                tst.l     d0
                rts


OutMultiple:    move.w    (a5)+,d0
                bmi.s     OutMultiple_0 ; ESC Sequenz beendet
                bsr.s     OutSingle     ; Zeichen ausgeben
                bne.s     OutMultiple   ; kein Fehler aufgetreten
OutMultiple_0:  tst.l     d0
                rts


ClearBuffer:    move.l    a3,-(sp)
                move.w    #959,d0
ClearBuffer_0:  clr.l     (a3)+
                dbra      d0,ClearBuffer_0
                movea.l   (sp)+,a3
                rts


; Farbnummer holen (nibbleweise)

GetPixel:       tst.w     d2            ; x
                bpl.s     GetPixel_0
                clr.w     d2
GetPixel_0:     tst.w     d3            ; y
                bpl.s     GetPixel_1
                clr.w     d3
GetPixel_1:     cmpi.w    #1280,d2
                blt.s     GetPixel_2
                move.w    #1279,d2
GetPixel_2:     cmpi.w    #800,d3
                blt.s     GetPixel_3
                move.w    #799,d3
GetPixel_3:
                lsr.w     #2,d2         ; div 4
                lsr.w     #2,d3         ; div 4

                move.w    d3,d0         ; y
                lsl.w     #2,d3
                add.w     d0,d3
                lsl.w     #5,d3         ; y * 160

                move.w    d2,d4         ; x
                lsr.w     #1,d2         ; div 2
                add.w     d2,d3         ; Offset ermitteln

                move.b    0(a0,d3.w),d0 ; Byte holen
                btst      #0,d4
                bne.s     GetPixel_4
                lsr.w     #4,d0
GetPixel_4:     and.w     #15,d0
                add.w     d0,d0         ; word-offset
                move.w    0(a1,d0.w),d0 ; Grauwert aus tabelle
                rts


                DATA
                EVEN

CR:             DC.W 13,-1
LineFeed:       DC.W 27,'J',24,-1
InitPrinter:    DC.W 27,'@',-1
Graphic180dpi:  DC.W 27,'*',39,0,5,-1


                END
