0890     .TAB 17,23,40
0900     .TITLE "Black Box: Ausschnitt des Druckertreibers"
0910     .SET 0,4    ;(1-4)        ,0   Byte und .SByte Listing Format
0920     .SET 1,0    ;(1-31)       ,0   Linker Rand
0930     .SET 2,125  ;(40-132)     ,80  Maximale Zeilenl{nge
0940     .SET 3,12   ;(0-255)      ,12  Zeichen f}r Formfeed vor "Page"
0950     .SET 4,66   ;(28-255)     ,66  Anzahl der Zeilen - Seite
0960     .SET 5,0    ;(0-255)      ,0   Leerzeichen zw. Semikolon und Text
0970     .SET 6,0    ;($0000-$FFFF),0   Offset:PC+Offset
0980 ;
0990     .PAGE "         Sytem Equates"
1000 *************************************************************************
1010 *                                                                       *
1020 *            Black Box: Ausschnitt des Druckertreibers                  *
1030 *                                                                       *
1040 *            Quelltext reassembliert von: Erhard P}tz                   *
1050 *                                    (c): November 1994                 *
1060 *                                                                       *
1070 *            Angaben ohne Gew{hr.                                       *
1080 *                                                                       *
1090 *************************************************************************
1100 ;
1110 ;System page zero equates
1120 ;
1130 POKMSK = $10
1140 BRKKEY = $11
1150 RTCLOK = $12
1160 BUFRLO = $32    Die Adresse des Druckerpuffers, im DCB in $0304-$0305,
1170 BUFRHI = $33    wird in Seite 0 kopiert.         
1180 BFENLO = $34    Y wird gerettet. Z{hlt von 0 bis dem Wert in $0308.
1190 BFENHI = $35    BFENHI wird zusammen mit CRETRY {hnlich BUFRLO f}r die
1200 CRETRY = $36    Pufferadresse des XE-RAM Spoolers genutzt.
1210 DRETRY = $37
1220 SOUNDR = $41
1230 CRITIC = $42
1240 ;
1250 ;Seite 2
1260 ;
1270 PDVMSK = $0247
1280 ;
1290 ;Seite 3  -  Der Device Control Block  (DCB)
1300 ;
1310 DDEVIC = $0300
1320 DUNIT = $0301
1330 DCOMND = $0302
1340 DBUFLO = $0304
1350 DBUFHI = $0305
1360 DBYTLO = $0308
1370 ;
1380 ;Die Hardwareregister: Der VIA der Black Box
1390 ;
1400 CENTSTAT = $D170 R     Bit 4: BUSY (H), Bit 5: FAULT (L)
1410 CENTDATA = $D171 W     Datenausgabe an die Centronics-Schnittstelle (inv)
1420 DDRB =  $D172   R-W   Datenrichtungsregister. 0=Input, 1=Output.
1430 DDRA =  $D173   R-W   Datenrichtungsregister. 0=Input, 1=Output.
1440 T1C_L = $D174   ;     R: Low counter  W: Low latch
1450 T1C_H = $D175   R-W   High counter
1460 T1L_L = $D176   R-W   Low latch
1470 T1H_L = $D177   R-W   High latch
1480 T2C_L = $D178   ;     R: Low counter  W: Low latch
1490 T2H_L = $D179   R-W   High counter
1500 SR  =   $D17A   R-W   Schieberegister      
1510 ACR =   $D17B   R-W   Auxillary Control Register
1520 CENT_CLK = $D17C R-W   Peripheral Control Register (PCR)
1530 IFR =   $D17D   R-W   Interrupt Flag Register
1540 IER =   $D17E   R-W   Interrupt Enable Register
1550 DRA =   $D17F   R-W   Port A ohne Handshake
1560 ;
1570 ;Adressen des Parallelen Busses
1580 ;
1590 RAMPAGE = $D1BC R-W   Black Box. Seitennummer des aktiven RAM. 
1600 PBIBANK = $D1FF R-W   Eigentlich PDVS, aber die BB nutzt das anders
1610 ;
1620 ;I-O Baugruppen
1630 ;
1640 AUDF4 = $D206   W     POKEY
1650 AUDC4 = $D207   W
1660 AUDCTL = $D208  W
1670 IRQST = $D20E   R
1680 IRQEN = $D20E   W
1690 SKCTL = $D20F   W
1700 PORTB = $D301   R-W   PIA
1710 WSYNC = $D40A   W     ANTIC
1720 ;
1730 ;End of system equates
1740 ;
1750 ;External reference equates
1760 ;
1770 BB_RAM = $D600  Banked Memory, $D600 - $D6FF.
1780 BB_03 = $D680
1790 BB_BADR = $D688
1800 BB_BSIZ = $D690
1810 BB_CFG1 = $D6ED Nur wenn Seite $F5 gew{hlt ist!
1820 BB_CFG2 = $D6EE Nur wenn Seite $F5 gew{hlt ist!
1830 BB_01 = $DA55
1840 BB_02 = $DE6F
1850 ;End of external references
1860     .PAGE "         Das eigentliche Programm"
1870     *=  $D800
1880 ;
1890     .WORD $734E ;Pr}fsumme
1900     .BYTE $00   ;Version Nr. 0
1910     .BYTE $80   ;ID 1 = 128
1920     .BYTE $00   ;Geraetetyp
1930 PDIOV JMP IOV   ;$D84B
1940 PDIRQ JMP IRQV  ;$D84A
1950     .BYTE $91   ;ID 2 = 145
1960     .BYTE $00   ;Ger{tename
1970 ;
1980     .WORD IRQV  ;OPEN     Alle Eintr{ge in dieser Treibertabelle
1990     .WORD IRQV  ;CLOSE    zeigen auf RTS. Sie werden offenbar
2000     .WORD IRQV  ;GET      nicht genutzt. Das sie hier stehen ist
2010     .WORD IRQV  ;PUT      aber durch die Busdefinitionen vorgegeben.
2020     .WORD IRQV  ;STATUS
2030     .WORD IRQV  ;SPECIAL
2040     JMP INIT    ;$D842
2050 ;
2060 SEL_ROM STX PBIBANK ;$D1FF Auswahlreg
2070     RTS 
2080 ;
2090     BRK 
2100     CLC 
2110     JMP BB_01   ;$DA55
2120 ;
2130     JMP BB_02   ;$DE6F
2140 ;
2150     SEC 
2160     JSR $DA54
2170     LDX #$02
2180     BNE SEL_ROM unbedingt -> 
2190 ;
2200 RAM_MISC PHA 
2210     LDA #$FE
2220     BNE SEL_RAM
2230 RAM_MCFG PHA 
2240     LDA #$F5
2250     BNE SEL_RAM
2260 RAM_NORM PHA 
2270     LDA #$FF
2280 SEL_RAM STA RAMPAGE
2290     PLA 
2300     RTS 
2310 ;
2320 INIT LDA PDVMSK ;$0247
2330     ORA #$08
2340     STA PDVMSK  ;$0247
2350 IRQV RTS 
2360 ;
2370 IOV JSR RAM_MCFG
2380     LDA BB_CFG1 Ist der Druckerport der BB eingeschalten?
2390     AND #$20
2400     BEQ EXIT    Nein ->
2410     LDA DDEVIC  Soll der Drucker angesprochen werden?
2420     CMP #$40
2430     BNE EXIT    Nein ->
2440     LDA BB_CFG1 Alle Druckernummern aktiv?
2450     AND #$08
2460     BNE IOV_1   Ja ->
2470     LDA BB_CFG1 Nein, nur einer von 0-7
2480     AND #$07
2490     CLC 
2500     ADC #$01
2510     CMP DUNIT   Ist er es?
2520     BEQ IOV_1   Ja ->
2530 EXIT CLC 
2540     JMP RAM_NORM
2550 ;
2560 IOV_1 LDA CENTSTAT Meldet der Drucker 'ERROR'?
2570     AND #$20
2580     BEQ EXIT    Ja ->
2590     LDA DBUFLO
2600     STA BUFRLO
2610     LDA DBUFHI
2620     STA BUFRHI
2630     LDA BRKKEY  Wurde BREAK gedr}ckt?
2640     BNE NOTBRK  Nein ->
2650     DEC BRKKEY  L|schen
2660     BNE ERR_BRK Break abort ->
2670 ;
2680 NOTBRK LDA DCOMND Status Kommando?
2690     CMP #$53
2700     BNE WRITE   Nein ->
2710     LDY #$03
2720 :01 LDA PSTAT_TAB,Y
2730     STA (BUFRLO),Y
2740     DEY 
2750     BPL :01     Alle 4 Bytes ->
2760 ;
2770 NO_ERR LDY #$01 Status ok
2780     .BYTE $2C
2790 ERR_NAK LDY #$8B
2800     .BYTE $2C
2810 ERR_WP LDY #$90
2820     .BYTE $2C
2830 ERR_BRK LDY #$80
2840 ;
2850     LDA SOUNDR  I-O Sound an?
2860     BEQ GO_EXIT Nein ->
2870     JSR RAM_MCFG
2880     LDA BB_CFG1 I-O Sound unterdr}ckt?
2890     BPL GO_EXIT Ja ->
2900     LDA #$00
2910     STA AUDF4
2920     STA AUDC4   Lautst{rke 0
2930 GO_EXIT SEC 
2940     JMP RAM_NORM
2950 ;
2960 PSTAT_TAB .BYTE $80,$28,$1F,$00
2970 ;
2980 WRITE CMP #$57  Daten schreiben?
2990     BNE ERR_NAK Nein. Dann unbekanntes Kommando ->
3000     LDA SOUNDR  I-O Sound erlaubt?
3010     BEQ WR_1    Nein ->
3020     LDA BB_CFG1 I-O Sound erlaubt?
3030     BPL WR_1    Nein ->
3040     LDA #$03    Nur Tastatur
3050     STA SKCTL
3060     LDA #$00    Basisfrequenz 64 KHz
3070     STA AUDCTL
3080     LDA #$A4    Lautst{rke 4, reiner Ton
3090     STA AUDC4
3100     LDA #$30    Tonh|he
3110     STA AUDF4
3120 WR_1 LDY A$00
3130 WR_2 LDA (BUFRLO),Y Zeichen aus dem Puffer lesen
3140     CMP #$9B    Ist es EOL
3150     BNE WR_3    Nein ->
3160     LDA A$0D    Sende CR
3170     JSR WR_4
3180     BCS ERR_WP
3190     JSR RAM_MCFG
3200     LDA BB_CFG1 Linefeed erzeugen?
3210     AND #$10
3220     BEQ WR_X    Nein ->
3230     LDA #$0A    Sende LF
3240     JSR WR_4
3250     BCS ERR_WP
3260 WR_X JMP NO_ERR
3270 ;
3280 WR_3 STY BFENLO Y retten
3290     JSR WR_4    Daten ausgeben-puffern
3300     BCS ERR_WP
3310     LDY BFENLO  Pufferende erreicht?
3320     INY 
3330     CPY DBYTLO
3340     BCC WR_2    Nein ->
3350     BCS NO_ERR  Ja ->
3360 ;
3370 WR_4 EOR #$FF   Daten invertieren
3380     TAX         ins X-Register legen
3390     JSR RAM_MCFG
3400     LDA BB_CFG2 Ist der Druckerspooler erlaubt?
3410     BMI SPOOL_1
3420     JMP WR_5
3430 ;
3440 SPOOL_1 PHA 
3450     JSR CHK_RAM Test, ob ver{ndert, ggf. resetten
3460     LDA RTCLOK+1 Timeout-Routine, ca. 50 Sekunden
3470     ADC #$0A
3480     TAY 
3490 SPOOL_2 LDA BB_BSIZ+1 Ist der Puffer noch voll?
3500     CMP #$EE
3510     BCC SPOOL_3 Nein ->
3520     LDA #$00
3530     STA CRITIC
3540     CLI 
3550     CPY RTCLOK+1 Zeit vorbei?
3560     BNE SPOOL_2 Nein ->
3570     PLA 
3580     SEC 
3590     RTS         Timeout ->
3600 ;
3610 SPOOL_3 PLA 
3620     ASL A       Spooler Bit
3630     ASL A       XE-BB Bit
3640     SEI 
3650     BCS XE_RAM
3660 ;
3670     LDY BB_BADR Hier wird das RAM der Black Box benutzt 
3680     LDA BB_BADR+1
3690     STA RAMPAGE
3700     TXA 
3710     STA BB_RAM,Y Datenwort im Ram der Black Box speichern
3720     JSR RAM_MISC
3730 SPOOL_4 INC BB_BSIZ Pufferl{nge. Wird beim Interrupt dekremtiert.
3740     BNE SPOOL_5
3750     INC BB_BSIZ+1
3760 SPOOL_5 CLI 
3770     INC BB_BADR
3780     BNE SPOOL_X
3790     INC BB_BADR+1
3800     LDA BB_BADR+1 Das RAM der Black Box ab $EE00 ist gesprerrt
3810     CMP #$EE    Also wird das XE-Ram auch nur soweit
3820     BCC SPOOL_X genutzt.
3830     LDA #$00    Danach gehts von vorne los.
3840     STA BB_BADR+1
3850 SPOOL_X CLC 
3860     RTS 
3870 ;
3880 XE_RAM LDA #$00 Hier wird die aktuelle Pufferadresse
3890     STA BFENHI  von 0-65535 in die Banknummer (0-3)
3900     STA DRETRY  und den Adressbereich ($4000-$7FFF)
3910     LDA BB_BADR+1 umgerechnet
3920     ASL A
3930     ROL DRETRY  Die oberen 2 Bits nach DRETRY
3940     ASL A       Dabei geht Bit 7 des AKKUS verloren
3950     ROL DRETRY
3960     SEC         Statt Bit 7 wird Bit 6 gesetzt
3970     ROR A
3980     LSR A
3990     STA BFENHI+1
4000     LDY DRETRY  Banknummer als Index
4010     LDA PORTB
4020     PHA 
4030     AND #$E3
4040     ORA XE_TAB,Y Tabellenwert lesen
4050     STA PORTB
4060     LDY BB_BADR
4070     TXA 
4080     STA (BFENHI),Y Datenwort puffern
4090     PLA 
4100     STA PORTB
4110     JMP SPOOL_4 ;$D95A
4120 ;
4130 XE_TAB .BYTE $E3,$E7,$EB,$EF
4140 BB_TAB .BYTE $50,$73,$70,$6F
4150     .BYTE $6F,$6C,$65,$72
4160 ;
4170 CHK_RAM JSR RAM_MISC
4180     LDY #$07
4190 CHK_1 LDA BB_03,A,X ;$D680 sind die 8 Werte vorhanden
4200     CMP BB_TAB,Y
4210     BNE RAM_INI ;$D9C5 Fehler ->
4220     DEY 
4230     BPL CHK_1   ;$D9B9 Noch ok, weiter ->
4240     RTS 
4250 ;
4260 RAM_INI SEI 
4270     LDY #$07
4280 :02 LDA BB_TAB,Y Testwerte eintragen
4290     STA BB_03,Y ;$D680
4300     LDA #$00
4310     STA BB_BADR,Y Setzte Pufferanfang auf Null
4320     STA BB_BSIZ,Y Pufferlaenge ist auch Null (noch keine Daten drin)
4330     DEY 
4340     BPL :02
4350     STA T1L_L   Timer 1 erzeugt den Interrupt f}r den Spooler.
4360     STA T1C_L   Er wird mit dem Wert $2800 = 10240 geladen.
4370     LDA #$28    Timer 1 teilt den Systemtakt von 1.77 Mhz durch      
4380     STA T1H_L   diesen wert, was etwa 173 Interrupts pro Sekunde
4390     STA T1C_H   ergibt. Das entspraeche etwa 1400 Bd!!!
4400     LDA #$C0    Timer 1 Interrupt einschalten.
4410     STA IER
4420     RTS 
4430 ;
4440 WR_ERR SEC 
4450     RTS 
4460 ;
4470     EOR #$FF
4480     TAX 
4490 WR_5 LDA #$FF
4500     STA DDRA    Port A alle Bits als Ausgang
4510     LDY #$08
4520     STY BFENHI+1
4530     STY BFENHI  ;$0035
4540     LDA IRQST   Wurde BREAK gedrueckt?
4550     BMI WR_6    Nein ->
4560     LDA POKMSK  Ja, zuruecksetzen
4570     STA IRQEN
4580     SEC 
4590     RTS 
4600 ;
4610 WR_6 LDA CENTSTAT Teste Drucker 'ERROR'
4620     AND #$20
4630     BEQ WR_ERR  Fehler ->
4640     LDA CENTSTAT Teste Drucker 'BUSY'
4650     AND #$10
4660     BEQ WR_7    Bereit ->
4670 ;
4680     STA WSYNC   Timeout-Routine 8^3*145 + 8^3 + 8^2 
4690     DEY         entspricht ca. 42 ms BUSY-Timeout?
4700     BNE WR_6
4710     DEC BFENHI+1
4720     BNE WR_6
4730     DEC BFENHI
4740     BNE WR_6
4750     BEQ WR_ERR
4760 ;
4770 WR_7 STX CENTDATA ;$D171
4780     LDX #$04    Warte auf jeden Fall 2+(4x5)+2+2 = 26 Zyklen
4790 WR_8 DEX        Das entspricht bei 1.77 MHz 26 x 0.56 = 14.6 us
4800     BPL WR_8    Beim EPL-5200 reichen aber 0.5 us
4810     LDA CENT_CLK 'STROBE' aktiv LO
4820     AND #$DF    Durch das PCR wird CB2 auf Low gesetzt (% 110X XXXX)
4830     STA CENT_CLK
4840     LDX #$10    Warte 2+(16*5)+2+2 = 86 Zyklen = 48.6 us
4850 WR_9 DEX        Beim EPL-5200 reichen hier auch 0.5 us
4860     BPL WR_9    Warte ->
4870     ORA #$20    'STROBE' zur}cksetzen
4880     STA CENT_CLK Durch das PCR wird CB2 auf High gesetzt (% 111X XXXX)
4890 WR_A LDA CENTSTAT Drucker 'ERROR'?
4900     AND #$20
4910     BEQ WR_ERR  Ja ->
4920     LDA CENTSTAT Drucker 'BUSY'?
4930     AND #$10
4940     BNE WR_OK   Nein ->
4950     DEX 
4960     BMI WR_A    Ja, noch 127 mal testen, danach von ok ausgehen.
4970 WR_OK CLC 
4980     RTS 
4990 ;
5000     .END