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