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