* PrtWi.s
*
* Source für a68k
*
* PrinWin1.0 ist © 1991 von:
*   Lutz Brueckner
*   Glockseestraße 3A
*   3000 Hannover 1
*   Tel.: 0511/15199 (Voice)
*   ZNet:L.BRUECKNER@A-LINK-H.ZER
*   Fido: 2:240/1
*
* PrtWi1.0 und PrtWi1.0.s sind PublicDomain!
* Programm, Source und Doc dürfen von jedem kopiert und weitergegeben
* werden, solange dies nicht mit der Absicht geschieht, Profit zu
* erwirtschaften.
*
* Anregungen, konstruktive Kritik und Glückwünsche/Danksagungen nehme
* ich gern entgegen.
*
*                       Lutz


*DEBUG = 1

* Library-Offsets
_LVODisable      = -120  ;exec
_LVOEnable       = -126
_LVOForbid       = -132
_LVOPermit       = -138
_LVOAddIntServer = -168
_LVORemIntServer = -174
_LVOAllocMem     = -198
_LVOFreeMem      = -210
_LVOFindName     = -276
_LVOFindTask     = -294
_LVOWait         = -318
_LVOSignal       = -324
_LVOAllocSignal  = -330
_LVOFreeSignal   = -336
_LVOGetMsg       = -372
_LVOReplyMsg     = -378
_LVOWaitPort     = -384
_LVOCloseLibrary = -414
_LVOOpenDevice   = -444
_LVOCloseDevice  = -450
_LVODoIO         = -456
_LVOOpenLibrary  = -552
_LVOBltBitMap    = -30   ;gfx
_LVOInitBitMap   = -390
_LVOAllocRaster  = -492
_LVOFreeRaster   = -498
_LVOIntuiTextLength = -330  ;intuition
_LVOAutoRequest  = -348
_LVOAllocRemember = -396
_LVOFreeRemember = -408
_LVOOpen         = -30   ;dos
_LVOClose        = -36
_LVOWrite        = -48
_LVOCreateProc   = -138
_LVOUnLoadSeg    = -156
_LVODelay        = -198

* Offsets für die Variablen,auf die
* indirekt über a5 zugegriffen wird
DosBase     = 0
IntuiBase   = 4
GfxBase     = 8
MyTask      = 12
OutHandle   = 16
CtrlFlag    = 20
AltFlag     = 21
MySignal    = 22
IOStdReq    = 24
PrtMsgPort  = 28
StartStack  = 32
TxHeight    = 36
TxWidth     = 38
Window      = 40
CharData    = 44
CharLoc     = 48
LoChar      = 52
HiChar      = 53
CharModulo  = 54
CharCount   = 56
LineNr      = 58
BitOffset   = 60
ByteOffset  = 62
PlanePtr    = 64
PlaneWidth  = 68
PlaneHeight = 70
ValTable    = 72
MemKey      = 76
OutBuffer   = 80
OutBufSize  = 84
WBMessage   = 86
Segment     = 90

VarStackSize = 94

  IFND DEBUG
   SECTION 1
  ENDIF
* wenn WB-Start:  Message holen
* wenn CLI-Start: Detaching
* Libs öffnen, etc.
Start:
  LEA     VarStack,a5
  MOVE.W  #-1,MySignal(a5)
  MOVEA.L 4,a6
  IFND DEBUG
   SUBA.L  a1,a1
   JSR     _LVOFindTask(a6)
   MOVEA.L d0,a1
   TST.L   $ac(a1)
   BNE.S   FromCLI
   LEA     $5c(a1),a0
   MOVEA.L a0,a2
   JSR     _LVOWaitPort(a6)
   MOVEA.L a2,a0
   JSR     _LVOGetMsg(a6)
   MOVE.L  d0,WBMessage(a5)
  ENDIF
FromCLI:
  LEA     IntuiName(pc),a1
  MOVEQ   #0,d0
  JSR     _LVOOpenLibrary(a6)
  MOVE.L  d0,IntuiBase(a5)
  BNE.S   IA_GoOn
  JMP     Over
IA_GoOn:
  LEA     DosName(pc),a1
  MOVEQ   #0,d0
  JSR     _LVOOpenLibrary(a6)
  MOVE.L  d0,DosBase(a5)
  BEQ     IA_Error
  LEA     GfxName(pc),a1
  MOVEQ   #0,d0
  JSR     _LVOOpenLibrary(a6)
  MOVE.L  d0,GfxBase(a5)
  BEQ.S   IA_Error
  IFD DEBUG
   BRA  ToMain
  ENDIF
  IFND DEBUG
   TST.L   WBMessage(a5)
   BNE.S   ToMain
   MOVE.L  #MyName,d1
   MOVEQ   #0,d2
   LEA     Start(pc),a0
   MOVE.L  -4(a0),d3
   CLR.L   -4(a0)
   MOVE.L  d3,Segment(a5)
   MOVE.L  #3000,d4
   MOVEA.L DosBase(a5),a6
   JSR     _LVOCreateProc(a6)
   MOVEQ   #0,d0
   RTS
  ENDIF
ToMain:
  JMP     Main
IA_Error:
  MOVEQ   #2,d0
  JSR     DoAutoRequest
  JMP     Over
DosName:
  dc.b "dos.library",0
IntuiName:
  dc.b "intuition.library",0
GfxName:
  dc.b "graphics.library",0
  EVEN

  IFND DEBUG
   SECTION 2
  ENDIF
Main:
  LEA     VarStack,a5
  MOVE.L  sp,StartStack(a5)
  MOVEA.L 4,a6
  JSR     _LVOForbid(a6)
  MOVEA.L $196(a6),a0
  LEA     MyName(pc),a1
  JSR     _LVOFindName(a6)
  TST.L   d0
  BNE     AlreadyInstalled
  MOVEA.L $1a4(a6),a0
  LEA     MyName(pc),a1
  JSR     _LVOFindName(a6)
  TST.L   d0
  BNE     AlreadyInstalled
  JSR     _LVOPermit(a6)
  SUBA.L  a1,a1
  JSR     _LVOFindTask(a6)
  MOVE.L  d0,MyTask(a5)
  MOVEQ   #-1,d0
  JSR     _LVOAllocSignal(a6)
  MOVE.W  d0,MySignal(a5)
  BMI     Over
  LEA     InstallText(pc),a0
  BSR     ShowText

* Warten auf Signal vom Interrupt
MainLoop:
  MOVEA.L 4,a6
  JSR     _LVODisable(a6)
  LEA     MyInterrupt(pc),a1
  MOVEQ   #3,d0
  JSR     _LVOAddIntServer(a6)
  MOVE.W  MySignal(a5),d1
  MOVEQ   #0,d0
  BSET    d1,d0
  JSR     _LVOWait(a6)
  MOVEQ   #3,d0
  LEA     MyInterrupt(pc),a1
  JSR     _LVORemIntServer(a6)
  JSR     _LVOEnable(a6)
  TST.B   AltFlag(a5)
  BNE.S   PrintTheWindow
  TST.B   CtrlFlag(a5)
  BNE     RemoveMe
  BRA.S   MainLoop

* <Alt>+<PrtSc> wurden gedrückt
PrintTheWindow:
  MOVE.B  #0,AltFlag(a5)
  BSR     OpenPrinter
  BSR     GetTheWin
  BSR     GetCharValues
  BSR     PrintTop
  BSR.S   PrintIt
  BSR     PrintBottom
PTW_Over:
  BSR     ClosePrinter
  BSR     FreeMem
  BSR     FreeRaster
  BRA.S   MainLoop

* Window nach Zeichen absuchen
* und die gefundenen drucken
PrintIt:
  MOVE.W  PlaneHeight(a5),d7
  SUB.W   TxHeight(a5),d7
  MOVEQ   #0,d3
PI_Loop1:
  MOVEA.L OutBuffer(a5),a0
  MOVE.W  PlaneWidth(a5),d6
  LSL.W   #3,d6
  SUB.W   TxWidth(a5),d6
  MOVEQ   #0,d1
  MOVEQ   #0,d2
PI_Loop2:
  MOVE.L  d3,d0
  BSR     TestForChar
  BPL.S   PI_GetChar
  ADDQ.W  #1,d2
  CMPI.W  #8,d2
  DBEQ    d6,PI_Loop2
  BNE.S   PI_GoOn1
  MOVEQ   #0,d2
  ADDQ.W  #1,d1
  DBRA    d6,PI_Loop2
PI_GoOn1:
  CMPA.L  OutBuffer(a5),a0
  BNE.S   WriteLine
  ADDQ.W  #1,d3
  DBRA    d7,PI_Loop1
PI_Over:
  RTS
PI_GetChar:
  ADD.B   LoChar(a5),d0
  MOVE.B  d0,(a0)+
  LSL.W   #3,d1
  ADD.W   d2,d1
  ADD.W   TxWidth(a5),d1
  EXT.L   d1
  ROR.L   #3,d1
  MOVE.L  d1,d2
  SWAP    d2
  ROL.W   #3,d2
  SUB.W   TxWidth(a5),d6
  BHI     PI_Loop2
WriteLine:
  MOVE.B  #$a,(a0)+
  MOVE.B  #0,(a0)
  BSR     GetOutLen
  TST.W   d0
  BEQ.S   WL_NoLine
  BSR     PrintOutBuffer
  ADD.W   TxHeight(a5),d3
  SUB.W   TxHeight(a5),d7
  BMI     PI_Over
  BRA     PI_Loop1
WL_NoLine:
  ADDQ.W  #1,d3
  DBRA    d7,PI_Loop1
  BRA     PI_Over

* Zeichen in OutBuffer zählen
* <- d0 = Anzahl Zeichen
GetOutLen:
  MOVEA.L OutBuffer(a5),a0
  MOVEQ   #0,d0
GOL_Loop1:
  ADDQ.L  #1,d0
  CMPI.B  #$a,(a0)+
  BEQ.S   GOL_NoLine
  CMPI.B  #' ',-1(a0)
  BEQ.S   GOL_Loop1
GOL_Loop2:
  ADDQ.L  #1,d0
  CMPI.B  #$a,(a0)+
  BNE.S   GOL_Loop2
  RTS
GOL_NoLine:
  CMP.W   OutBufSize(a5),d0
  BEQ.S   GOL_EmptyLine
  MOVEQ   #0,d0
  RTS
GOL_EmptyLine:
  MOVEA.L OutBuffer(a5),a0
  MOVE.B  #$a,(a0)
  MOVEQ   #1,d0
  RTS

* prüfen ob sich an der aktuellen
* Position im Window ein
* ASCII-Zeichen befindet
* -> d0 = LineNr
*    d1 = ByteOffset
*    d2 = BitOffset
* <- d0 = Nr des Zeichens
*         -1 wenn kein Character
TestForChar:
  MOVEM.L a0-a4/d1-d7,-(sp)
  MOVE.W  d0,d5
  SUBQ.W  #7,d2
  NEG.W   d2
  MOVE.W  d2,d4
  MULU    PlaneWidth(a5),d5
  EXT.L   d1
  ADD.L   d1,d5
  MOVEA.L PlanePtr(a5),a0
  ADDA.L  d5,a0
  MOVEQ   #0,d5
  MOVEQ   #1,d3
  MOVE.W  TxWidth(a5),d7
  SUBQ.W  #1,d7
TFC_Loop1:
  MOVEA.L a0,a1
  MOVE.W  TxHeight(a5),d6
  SUBQ.W  #1,d6
TFC_Loop2:
  BTST    d4,(a1)
  BEQ.S   TFC_GoOn1
  ADD.L   d3,d5
TFC_GoOn1:
  ADDA.W  PlaneWidth(a5),a1
  ADDQ.L  #1,d3
  DBRA    d6,TFC_Loop2
  SUBQ.W  #1,d4
  DBMI    d7,TFC_Loop1
  BPL.S   TFC_GoOn2
  MOVEQ   #7,d4
  ADDQ.L  #1,a0
  DBRA    d7,TFC_Loop1
TFC_GoOn2:
  MOVEA.L ValTable(a5),a0
  MOVE.W  CharCount(a5),d7
  SUBQ.W  #1,d7
TFC_Loop3:
  CMP.L   (a0)+,d5
  BEQ.S   ValFound
TFC_GoOn3:
  DBRA    d7,TFC_Loop3
  MOVEQ   #-1,d0
  MOVEM.L (sp)+,a0-a4/d1-d7
  RTS

* akt. Position pixelweise mit den
* Font-Daten vergleichen
ValFound:
  MOVEM.L a0/d0-d2/d5/d7,-(sp)
  SUBA.L  ValTable(a5),a0
  SUBQ.L  #4,a0
  MOVE.L  a0,d3
  MOVEA.L CharLoc(a5),a1
  ADD.W   d3,a1
  LSR.W   #2,d3
  MOVEQ   #0,d4
  MOVE.W  (a1),d4
  ROR.L   #3,d4
  MOVE.L  d4,d5
  SWAP    d5
  ROL.W   #3,d5
  SUBQ.W  #7,d5
  NEG.W   d5
  MULU    PlaneWidth(a5),d0
  ADD.L   d1,d0
  MOVE.W  d2,d1
  MOVEA.L CharData(a5),a0
  ADDA.W  d4,a0
  MOVEA.L PlanePtr(a5),a1
  ADDA.L  d0,a1
  MOVE.W  TxWidth(a5),d7
  SUBQ.W  #1,d7
VF_Loop1:
  MOVEA.L a0,a2
  MOVEA.L a1,a3
  MOVE.W  TxHeight(a5),d6
  SUBQ.W  #1,d6
VF_Loop2:
  BTST    d5,(a2)
  BEQ.S   VF_GoOn1
  BTST    d1,(a3)
  BEQ.S   VF_NotEqual
  BRA.S   VF_GoOn2
VF_GoOn1:
  BTST    d1,(a3)
  BNE.S   VF_NotEqual
VF_GoOn2:
  ADDA.W  CharModulo(a5),a2
  ADDA.W  PlaneWidth(a5),a3
  DBRA    d6,VF_Loop2
  SUBQ.W  #1,d5
  BPL.S   VF_GoOn3
  MOVEQ   #7,d5
  ADDQ.L  #1,a0
VF_GoOn3:
  SUBQ.W  #1,d1
  BPL.S   VF_GoOn4
  MOVEQ   #7,d1
  ADDQ.L  #1,a1
VF_GoOn4:
  DBRA    d7,VF_Loop1
  MOVEM.L (sp)+,a0/d0-d2/d5/d7
  MOVE.L  d3,d0
  MOVEM.L (sp)+,a0-a4/d1-d7
  RTS
VF_NotEqual:
  MOVEM.L (sp)+,a0/d0-d2/d5/d7
  BRA     TFC_GoOn3

* Obere Begrenzung drucken
PrintTop:
  MOVEA.L OutBuffer(a5),a0
  MOVEA.L Window(a5),a1
  MOVEA.L $20(a1),a1
  MOVE.W  OutBufSize(a5),d0
  SUBQ.W  #4,d0
  BMI.S   PT_Over
  MOVE.W  #'--',(a0)+
PT_Loop1:
  MOVE.B  (a1)+,(a0)+
  DBEQ    d0,PT_Loop1
  BNE.S   PT_GoOn
  SUBQ.W  #1,a0
  MOVEQ   #'-',d1
PT_Loop2:
  MOVE.B  d1,(a0)+
  DBRA    d0,PT_Loop2
PT_GoOn:
  MOVE.B  #$a,(a0)+
  BSR     GetOutLen
  BSR     PrintOutBuffer
PT_Over:
  RTS

* Untere Begrenzung drucken
PrintBottom:
  MOVEA.L OutBuffer(a5),a0
  MOVE.W  OutBufSize(a5),d0
  SUBQ.W  #2,d0
  BMI.S   PB_Over
  MOVEQ   #'-',d1
PB_Loop:
  MOVE.B  d1,(a0)+
  DBRA    d0,PB_Loop
  MOVE.B  #$a,(a0)+
  BSR     GetOutLen
  BSR     PrintOutBuffer
PB_Over:
  RTS

* Window- und Font-Konstanten ermitteln
* Plane[0] des Windows in eigene Plane
* kopieren
* Buffer für Druckerausgabe allozieren
GetTheWin:
  MOVEA.L 4,a6
  JSR     _LVOForbid(a6)
  MOVEA.L IntuiBase(a5),a6
  MOVEA.L $34(a6),a3
  MOVE.L  a3,Window(a5)
  BEQ     GTW_Error
  MOVE.W  8(a3),d1
  MOVE.B  $36(a3),d7
  ADD.B   $38(a3),d7
  EXT.W   d7
  SUB.W   d7,d1
  MOVE.W  $a(a3),d2
  MOVE.B  $37(a3),d6
  ADD.B   $39(a3),d6
  EXT.W   d6
  SUB.W   d6,d2
  MOVE.W  d2,PlaneHeight(a5)
  LEA     MyBitMap(pc),a0
  MOVEQ   #1,d0
  MOVEA.L GfxBase(a5),a6
  JSR     _LVOInitBitMap(a6)
  LEA     MyBitMap(pc),a0
  MOVE.W  (a0),PlaneWidth(a5)
  MOVE.W  8(a3),d0
  SUB.W   d7,d0
  MOVE.W  $a(a3),d1
  SUB.W   d6,d1
  JSR     _LVOAllocRaster(a6)
  LEA     MyBitMap(pc),a0
  MOVE.L  d0,$8(a0)
  BEQ     GTW_NoMem
  MOVE.L  d0,PlanePtr(a5)
  MOVEA.L $32(a3),a0
  MOVEA.L 4(a0),a0
  MOVE.W  4(a3),d0
  MOVE.B  $36(a3),d1
  EXT.W   d1
  ADD.W   d1,d0
  MOVE.W  6(a3),d1
  MOVE.B  $37(a3),d2
  EXT.W   d2
  ADD.W   d2,d1
  LEA     MyBitMap(pc),a1
  MOVEQ   #0,d2
  MOVEQ   #0,d3
  MOVE.W  8(a3),d4
  SUB.W   d7,d4
  MOVE.W  $a(a3),d5
  SUB.W   d6,d5
  MOVE.B  #$c0,d6
  MOVEQ   #1,d7
  SUBA.L  a2,a2
  JSR     _LVOBltBitMap(a6)

  MOVEA.L $32(a3),a0
  MOVE.W  $3a(a0),TxHeight(a5)
  MOVE.W  $3c(a0),TxWidth(a5)
  MOVEA.L $34(a0),a1
  MOVE.L  a1,d0
  BEQ     GTW_BadWin
  TST.B   $16(a1)
  BNE     GTW_BadWin
  MOVE.L  $22(a1),CharData(a5)
  MOVE.L  $28(a1),CharLoc(a5)
  MOVE.B  $20(a1),LoChar(a5)
  MOVE.B  $21(a1),HiChar(a5)
  MOVEQ   #0,d0
  MOVE.B  $21(a1),d0
  SUB.B   $20(a1),d0
  ADDQ.B  #1,d0
  MOVE.W  d0,CharCount(a5)
  MOVE.W  $26(a1),CharModulo(a5)

  MOVE.W  PlaneWidth(a5),d0
  LSL.W   #3,d0
  EXT.L   d0
  DIVU    TxWidth(a5),d0
  MOVE.L  d0,d1
  SWAP    d1
  TST.W   d1
  BEQ.S   GTW_GoOn1
  ADDQ.W  #1,d0
GTW_GoOn1:
  MOVE.W  d0,OutBufSize(a5)
  EXT.L   d0
  LEA     MemKey(a5),a0
  MOVE.L  #$10001,d1
  MOVEA.L IntuiBase(a5),a6
  JSR     _LVOAllocRemember(a6)
  MOVE.L  d0,OutBuffer(a5)
  BEQ.S   GTW_NoMem
  MOVEA.L 4,a6
  JSR     _LVOPermit(a6)
  RTS
GTW_Error:
  ADDQ.L  #4,sp
  MOVEA.L 4,a6
  JSR     _LVOPermit(a6)
  BRA     PTW_Over
GTW_NoMem:
  MOVEQ   #0,d0
  BSR     DoAutoRequest
  BRA.S   GTW_Error
GTW_BadWin:
  MOVEQ   #1,d0
  BSR     DoAutoRequest
  BRA.S   GTW_Error

FreeRaster:
  LEA     MyBitMap(pc),a0
  TST.L   8(a0)
  BEQ.S   FR_Over
  MOVEA.L GfxBase(a5),a6
  MOVE.W  (a0),d0
  LSL.W   #3,d0
  MOVE.W  2(a0),d1
  MOVEA.L 8(a0),a0
  MOVE.L  #0,8(a0)
  JSR     _LVOFreeRaster(a6)
FR_Over:
  RTS

* Hash-Werte der einzelnen Zeichen
* aus den Font-Daten berechnen und
* in ValTable merken
GetCharValues:
  MOVE.W  CharCount(a5),d0
  MOVE.W  d0,d7
  EXT.L   d0
  LSL.L   #2,d0
  MOVE.L  #$10001,d1
  LEA     MemKey(a5),a0
  MOVEA.L IntuiBase(a5),a6
  JSR     _LVOAllocRemember(a6)
  MOVE.L  d0,ValTable(a5)
  BEQ     GCV_NoMem
  MOVEA.L d0,a2
  MOVEA.L CharLoc(a5),a3
  SUBQ.W  #1,d7
GCV_Loop1:
  MOVEQ   #0,d0
  MOVEQ   #1,d2
  MOVEA.L CharData(a5),a4
  MOVEQ   #0,d4
  MOVE.W  (a3)+,d4
  ROR.L   #3,d4
  ADD.W   d4,a4
  SWAP    d4
  ROL.W   #3,d4
  MOVEQ   #7,d1
  SUB.W   d4,d1
  MOVE.W  (a3)+,d6
  SUBQ.W  #1,d6
  BMI.S   GCV_GoOn2
GCV_Loop2:
  MOVEA.L a4,a0
  MOVE.W  TxHeight(a5),d5
  SUBQ.W  #1,d5
GCV_Loop3:
  BTST    d1,(a0)
  BEQ.S   GCV_GoOn1
  ADD.L   d2,d0
GCV_GoOn1:
  ADDA.W  CharModulo(a5),a0
  ADDQ.L  #1,d2
  DBRA    d5,GCV_Loop3
  SUBQ.W  #1,d1
  DBMI    d6,GCV_Loop2
  BPL.S   GCV_GoOn2
  MOVEQ   #7,d1
  ADDQ.L  #1,a4
  DBRA    d6,GCV_Loop2
GCV_GoOn2:
  MOVE.L  d0,(a2)+
  DBRA    d7,GCV_Loop1
  RTS
GCV_NoMem:
  MOVEQ   #0,d0
  BSR     DoAutoRequest
  ADDQ.L  #4,sp
  BRA     PTW_Over

FreeMem:
  MOVEA.L IntuiBase(a5),a6
  TST.L   MemKey(a5)
  BEQ.S   FM_Over
  LEA     MemKey(a5),a0
  MOVEQ   #-1,d0
  JSR     _LVOFreeRemember(a6)
  MOVE.L  #0,MemKey(a5)
FM_Over:
  RTS

* printer.device öffnen
OpenPrinter:
  MOVEA.L IntuiBase(a5),a6
  MOVE.L  #$10001,d1
  MOVEQ   #48+34,d0
  LEA     MemKey(a5),a0
  JSR     _LVOAllocRemember(a6)
  MOVE.L  d0,IOStdReq(a5)
  BEQ.S   OP_NoMem
  ADDI.L  #48,d0
  MOVEA.L d0,a4
  MOVE.L  d0,PrtMsgPort(a5)
  MOVEA.L 4,a6
  MOVEQ   #-1,d0
  JSR     _LVOAllocSignal(a6)
  TST.L   d0
  BMI.S   OP_NoDev
  MOVE.B  #4,$8(a4)
  MOVE.B  d0,$f(a4)
  MOVE.L  $114(a6),$10(a4)
  LEA     PrtName(pc),a0
  MOVEA.L IOStdReq(a5),a1
  MOVE.L  a4,$e(a1)
  MOVEQ   #0,d0
  MOVEQ   #0,d1
  JSR     _LVOOpenDevice(a6)
  TST.L   d0
  BNE.S   OP_NoDev
  RTS
OpenPrinterError:
  ADDQ.L  #4,sp
  BRA     PTW_Over
OP_NoMem:
  MOVEQ   #0,d0
  BSR     DoAutoRequest
  BRA.S   OpenPrinterError
OP_NoDev:
  MOVEQ   #3,d0
  BSR     DoAutoRequest
  MOVEA.L IOStdReq(a5),a0
  CLR.L   $14(a0)
  BRA.S   OpenPrinterError

* printer.device schließen
ClosePrinter:
  MOVEA.L 4,a6
  MOVE.L  IOStdReq(a5),d0
  BEQ.S   CP_NoDev
  MOVEA.L d0,a1
  TST.L   $14(a1)
  BEQ.S   CP_FreeSig
  JSR     _LVOCloseDevice(a6)
CP_FreeSig:
  MOVEA.L PrtMsgPort(a5),a0
  MOVEQ   #0,d0
  MOVE.B  $f(a0),d0
  BEQ.S   CP_NoDev
  JSR     _LVOFreeSignal(a6)
CP_NoDev:
  CLR.L   IOStdReq(a5)
  RTS

* Inhalt von OutBuffer drucken
* -> d0 = Länge
PrintOutBuffer:
  MOVEA.L 4,a6
  MOVEA.L IOStdReq(a5),a1
  MOVEA.L a1,a2
  MOVE.L  d0,d2
  MOVE.L  d0,$24(a1)
  MOVE.L  OutBuffer(a5),$28(a1)
  MOVE.W  #3,$1c(a1)
  JSR     _LVODoIO(a6)
  CMP.L   $20(a2),d2
  BNE.S   POB_Error
  RTS
POB_Error:
  MOVEQ   #4,d0
  BSR     DoAutoRequest
  ADDQ.L  #4,sp
  BRA     PTW_Over
* CON: öffnen, Text ausgeben,
* warten, CON: schließen
* -> a0 = Zeiger auf String
ShowText:
  MOVEA.L a0,a3
  MOVEA.L DosBase(a5),a6
  MOVE.L  #ConName,d1
  MOVE.L  #1006,d2
  JSR     _LVOOpen(a6)
  MOVE.L  d0,d4
  BEQ     Over
  MOVE.B  (a3)+,d3
  MOVE.L  a3,d2
  MOVE.L  d4,d1
  JSR     _LVOWrite(a6)
  MOVE.L  #200,d1
  JSR     _LVODelay(a6)
  MOVE.L  d4,d1
  JSR     _LVOClose(a6)
  RTS
ConName:
  dc.b "CON:50/50/298/30/PrtWi 1.0  ©1991 Lutz Brückner",0
InstallText:
  dc.b 25,"  PrtWi wird installiert",$a
RemoveText:
  dc.b 22,"  PrtWi wird entfernt",$a
NotTwiceText:
  dc.b 30,"PrtWi ist bereits installiert",$a
  EVEN

* Requester ausgeben
* -> d0 = RequesterNummer
DoAutoRequest:
  LEA     ReqParTab(pc),a4
  LSL.W   #2,d0
  MOVEA.L 0(a4,d0.w),a4
  MOVEA.L (a4),a0
  MOVEA.L IntuiBase(a5),a6
  JSR     _LVOIntuiTextLength(a6)
  MOVE.L  d0,d2
  ADDI.L  #60,d2
  MOVEA.L $34(a6),a0
  CMPA.L  #0,a0
  BEQ.S   DAR_Over
  MOVEA.L $32(a0),a3
  MOVE.W  $3a(a3),d3
  EXT.L   d3
  LSL.L   #3,d3
  MOVEA.L (a4)+,a1
  MOVEA.L (a4)+,a2
  MOVEA.L (a4)+,a3
  MOVE.L  (a4)+,d0
  MOVE.L  (a4)+,d1
  JSR     _LVOAutoRequest(a6)
DAR_Over:
  RTS
ReqParTab:
  dc.l ReqPara_0,ReqPara_1
  dc.l ReqPara_2,ReqPara_3,ReqPara_4
ReqPara_0:
  dc.l    BodyText_0,0,AhaText,0,$20
ReqPara_1:
  dc.l    BodyText_1,0,AhaText,0,$20
ReqPara_2:
  dc.l    BodyText_2,0,AhaText,0,$20
ReqPara_3:
  dc.l    BodyText_3,0,AhaText,0,$20
ReqPara_4:
  dc.l    BodyText_4,0,AhaText,0,$20

BodyText_0:
  dc.b    0,1,0,0
  dc.w    10,10
  dc.l    0,Text_0,0
BodyText_1:
  dc.b    0,1,0,0
  dc.w    10,10
  dc.l    0,Text_1,0
BodyText_2:
  dc.b    0,1,0,0
  dc.w    10,10
  dc.l    0,Text_2,0
BodyText_3:
  dc.b    0,1,0,0
  dc.w    10,10
  dc.l    0,Text_3,0
BodyText_4:
  dc.b    0,1,0,0
  dc.w    10,10
  dc.l    0,Text_4,0
AhaText: dc.b    0,1,0,0
  dc.w    5,3
  dc.l    0,Aha,0
Text_0:
  dc.b "PrtWi: Nicht genug Speicher!",0
Text_1:
  dc.b "PrtWi: Schlechtes Fenster!",0
Text_2:
  dc.b "PrtWi: Initialisierungsfehler!",0
Text_3:
  dc.b "PrtWi: Kein printer.device!",0
Text_4:
  dc.b "PrtWi: Druck abgebrochen!",0
Aha: dc.b    "Aha",0
  EVEN

* PrtWI ist bereits installiert
AlreadyInstalled:
  JSR     _LVOPermit(a6)
  LEA     NotTwiceText(pc),a0
  BSR     ShowText
  BRA.S   Over

* PrtWi entfernen
RemoveMe:
  LEA     RemoveText(pc),a0
  BSR     ShowText

* Aufräumen und Prg verlassen
Over:
  MOVEA.L StartStack(a5),sp
  MOVEA.L 4,a6
  MOVE.W  MySignal(a5),d0
  BMI.S   CloseIntui
  EXT.L   d0
  JSR     _LVOFreeSignal(a6)
CloseIntui:
  TST.L   IntuiBase(a5)
  BEQ.S   CloseGfx
  MOVEA.L IntuiBase(a5),a1
  JSR     _LVOCloseLibrary(a6)
CloseGfx:
  TST.L   GfxBase(a5)
  BEQ.S   ReplyWBMsg
  MOVEA.L GfxBase(a5),a1
  JSR     _LVOCloseLibrary(a6)
ReplyWBMsg:
  TST.L   WBMessage(a5)
  BEQ.S   DosReturn
  JSR     _LVOForbid(a6)
  MOVE.L  WBMessage(a5),a1
  JSR     _LVOReplyMsg(a6)
  BRA.S   CloseDos
DosReturn:
  JSR     _LVOForbid(a6)
  MOVE.L  Segment(a5),d1
  BEQ.S   CloseDos
  MOVEA.L DosBase(a5),a6
  JSR     _LVOUnLoadSeg(a6)
CloseDos:
  TST.L   DosBase(a5)
  BEQ.S   Exit
  MOVEA.L 4,a6
  MOVEA.L DosBase(a5),a1
  JSR     _LVOCloseLibrary(a6)
Exit:
  MOVEQ   #0,d0
  RTS

* Der Ports-Interrupt wird jedesmal
* ausgeführt, wenn eine Taste
* gedrückt wird
Interrupt:
  LEA     VarStack,a5
  MOVE.B  $bfec01,d0
  NOT.B   d0
  ROR.B   #1,d0
  CMPI.B  #$5d,d0
  BEQ.S   PrtScrPushed
  CMPI.B  #$63,d0
  BEQ     CtrlPushed
  BCLR    #0,d0
  CMPI.B  #$64,d0
  BEQ.S   AltPushed
  MOVE.B  #0,AltFlag(a5)
  MOVE.B  #0,CtrlFlag(a5)
IntOver:
  MOVEQ   #0,d0
  RTS
AltPushed:
  MOVE.B  #1,AltFlag(a5)
  MOVE.B  #0,CtrlFlag(a5)
  BRA.S   IntOver
CtrlPushed:
  MOVE.B  #1,CtrlFlag(a5)
  MOVE.B  #0,AltFlag(a5)
  BRA.S   IntOver
PrtScrPushed:
  CMPI.W  #0,CtrlFlag(a5)
  BEQ.s   IntOver
  MOVE.B  $BFED01,d0    ;ICR löschen
  ORI.B   #$40,$BFEE01  ;CRA SPMODE:=1
  MOVEA.L 4,a6
  MOVE.W  MySignal(a5),d1
  MOVEQ   #0,d0
  BSET    d1,d0
  MOVEA.L MyTask(a5),a1
  JSR     _LVOSignal(a6)
  ANDI.B  #$BF,$BFEE01  ;CRA SPMODE:=0
  MOVEQ   #0,d0
  RTS
MyInterrupt:
  dc.l 0
  dc.l 0
  dc.b 2
  dc.b 5
  dc.l MyName
  dc.l 0
  dc.l Interrupt
MyBitMap:
  ds.b 12
PrtName:
  dc.b "printer.device",0
MyName:
  dc.b "PrtWi",0

  IFND DEBUG
   SECTION 3,BSS
  ENDIF
  IFD DEBUG
   BSS
  ENDIF
VarStack:
  ds.b VarStackSize
  END

