q3R.JMPSIO!SIOINTERF;;$C933 im alten: JMP SIO R#SIOINITQ><;;Cassettenmotor aus R PPACTL R!Q><;;CB2 auf HI, es wird kein RPPBCTL;;Kommando gesendet. RQ>R PSSKCTLRPSOUNDR;;I/O-Sound anR0PSKCTL;;%00000011 => Softwarereset des POKEYR:R3SIO@;;Damit die SIO den Stapel nicht verw}stet.R&STACKP;;$0318R'Q>;;Kein DVBL und nur ein Teil desR"PCRITIC;;IVBL wird bearbeitet.R4QDDEVIC;;Soll die Cassette angesprochen werden ?RR>`RHNOTCASET;;neinR!CASENT;;ja ->RNOTCASETQ>RPCASFLG;;nicht CassetteR1Q>;;Anzahl der Versuche, die ein Peripherie-R-PDRETRY;;ger{t zur Befehlsausf}hrung hat.R1COMMNDQ> ;;Anzahl der Versuche, ein KommandoRPCRETRY;;zu senden. R:COMFRMQ>4BD192;;Stelle die Baudrate auf 19200 Bd ein.!R PAUDF3"R Q>5BD192#R PAUDF4$R(,;;Ger{tekennung=Ger{t+Ger{tenummer-1%R QDDEVIC&R ODUNIT'RO>(R PCDEVIC)R'QDCOMND;;Kommando in Kommandopuffer*R PCCOMND+RQDAUX1;;ebenso AUX1,R PCAUX1-RQDAUX2;;und AUX2.R PCAUX2/R,0R%Q>4CDEVIC;;Pufferanfang = $023A1R PBUFRLO2R!O>;;Pufferl{nge = 4 Bytes3R PBFENLO4R Q>5CDEVIC5R PBUFRHI6R PBFENHI7R+Q>4;;CB2=Koomando auf LO. Die folgenden8R/PPBCTL;;gesendeten Bytes sind ein Kommando.9R4 SENDINIT;;Sende Puffer }ber serielle Schnittst.:R-QERRFLG;;Wird von WAIT gesetzt/geloescht.;RHBADCOM;;bei Fehler ->>R6BADCOM"CRETRY;;Nein, NAck oder Timeout, sende das?R6ICOMFRM;;Kommando erneut, wenn noch Versuche frei.@R!DERR1;;bei FehlerAR@ACKRECQDSTATS;;ACK wurde empfangen. Daten senden (Bit 7=HI)BR)IWAITCOMPL;;o. empfangen (Bit 6=HI) ?CR#Q> ;;Daten senden. 13 Versuche.DR PCRETRYER1 LDPNTR;;($32)=($0304), ($34)=($0304)+($0308)FR SENDINIT;;Sende PufferGR FDERR1;;NACK oder Timeout ->HR$WAITCOMPL STTMOT;;Setze TimeoutIRQ>JRPERRFLG;;Loesche FehlerflagKR3 WAITER;;Setze Timer, warte bis Daten empfangenLRFDERR;;Bei Timeout ->MR+*DSTATS;;Sind noch Daten zu empfangen ?NRKMODATA;;Ja ->OR QERRFLGPRHDERR1;;bei Fehler ->QRFRETURN;;unbedingtRR'MODATA LDPNTR;;Pufferzeiger <- DCBSR RECEIVE;;Empfange DatenTRDERRQERRFLGURFNOTERR;;Kein FehlerVRQTSTAT;;Status in Page 0WR PSTATUSXRNOTERRQSTATUSYRR>;;Status okZRFRETURN;;Ja ->[R-DERR1"DRETRY;;Nein. Noch Versuche frei ?\RGRETURN;;Nein]R!COMMND;;N{chster Versuch.^R0RETURN SENDDIS;;Sendeinterrupt ausschalten._RQ>`R PCRITICaR%STATUS;;Page 0 inbR$'DSTATS;;DCB und Flaggen setzen.cR:dR WAITQ>;;Loesche FehlerflageR PERRFLGfR,gRQ>4TEMP;;($32)=$023EhR PBUFRLOiRO>;;Pufferl{nge 1 BytejR PBFENLOkR Q>5TEMPlR PBUFRHImR PBFENHInR Q>;;Keine Pr}fsumme senden.oR PNOCKSMpR RECEIVE;;Lese 1 Byte.qR%>;;Operation erfolgreich.rR QSTATUSsRR>tRHNWOK;;Verzweige bei FehleruR QTEMPvRR> A;;Acknowledged.wR!FGOOD;;Kommando verstanden ->xRR> C;;CompleteyR/FGOOD;;Kommando abschliessend bearbeitet ->zRR> E;;Error{R+HNOTDER;;Fehler, keine Fehlermeldung ->|R)Q>DERROR;;Ja, Fehlermeldung empfangen}R PSTATUS~RHNWOK;;UnbedingtR0NOTDERQ>DNACK;;Ger{t hat nicht geantwortet.R PSTATUSRNWOKQSTATUS;;Timeout ?R R>TIMOUTRFBAD;;Ja ->RQ>R PERRFLGR HGOODR BAD%>RGOODQSTATUSR PTSTATR :;;EndeR$SENDQ>SUCCES;;Erfolg annehnmen.R PSTATUSR( SENDEN;;Setze Parameter f}r senden.R%>;;Loesche:R'CHKSUM;;Pr}fsumme,R%'CHKSNT;;Pr}fsumme gesendet Flag,R%'XMTDON;;Uebertragungsende Flag.R/Q@BUFRLO7;;Das erste Zeichen aus dem PufferRPSEROUT;;senden undRPCHKSUM;;Pr}fsumme setzen.R5NOTDONEQBRKKEY;;Wurde die BREAK-Taste gedr}ckt ?RHNTBRK0;;Nein ->R!BROKE;;Ja ->R2NTBRK0QXMTDON;;Ist die Uebertragung beendet ?RFNOTDONE;;Nein ->R* SENDDIS;;Ja, Sendebetrieb abschalten.R :;;EndeR9ISRODNC;;Interrupt Service Routine Output Data NeededR5;;Y auf den Stapel retten.R"#BUFRLO;;Zeiger um 1 erhoehen.R HNOWPROR #BUFRHIR)NOWPROQBUFRLO;;Pufferende erreicht ?R RBFENLOR QBUFRHIR SBFENHIRDNOTEND;;Nein ->R'QCHKSNT;;Pr}fsumme schon gesendet ?RHRELONE;;Ja ->RQCHKSUM;;Pr}fsumme senden.R PSEROUTR!Q>;;Pr}fsumme wurde gesendetRPCHKSNT;;Flag setzen.RHCHKDONE;;Unbedingt.R?RELONEQPOKMSK;;Uebertragungsendunterbrechung ermoeglichen.RL>R PPOKMSKR PIRQENRCHKDONE7;;Y & A vom Stapel.R?R7R 9;;FertigR7NOTEND%>;;N{chstes Zeichen aus dem Puffer senden.R Q@BUFRLO7R PSEROUTR,;;Neue Pr}fsumme berechnen.R OCHKSUMRO>;;Immer mit Uebertrag !R PCHKSUMR/!CHKDONE;;Ciao, bis zum n{chsten Interrupt.R;ISRXDQCHKSNT;;Interrupt Service Routine X-mission DoneR,FFOOEY;;Pr}fsumme noch nicht gesendet ->R+PXMTDON;;Uebertragungsende-Flag setzen.R7QPOKMSK;;Uebertragungsendunterbrechung ausschalten.RM>R PPOKMSKR PIRQENR FOOEY7R 9;;FertigRRECEIVEQ>R%CASFLG;;Cassette ?RHNOCLR;;Ja ->RPCHKSUM;;Loesche: Pr}fsummeR,NOCLRPBUFRFL;; Puffer-voll-FlagR*PRECVDN;; Empfang-beendet-FlagR Q>SUCCESR PSTATUSR! RECVEN;;Empfang ermoeglichenRQ><;;Kein KommandoR PPBCTLR*CHKTIMQBRKKEY;;Wurde BREAK gedr}ckt ?RHNTBRK1;;Nein ->R!BROKE;;Ja ->RNTBRK1QTIMFLG;;Timeout ?RFTOUT;;Nein ->RQRECVDN;;Empfang beendet ?RFCHKTIM;;Nein ->R:R"TOUTQ>TIMOUT;;Fehler: TimeoutR PSTATUSR:R9ISRSIRC;;Interrupt Service Routine Serial Input ReadyR5RQSKSTAT;;Eventueller FehlerR,PSKRES;;Zur}cksetzen des StatusregistersR,GNTFRAM;;Bit 7 = Framing Fehler. Nein ->R.%>FRMERR;;Fehler: Framing (Start-/Stopbit)R 'STATUSRNTFRAMM> R HNTOVRNR%>OVRRUN;;Fehler: UeberlaufR 'STATUSR!NTOVRNQBUFRFL;;Puffer voll ?RFNOTYET;;Nein ->R)QSERIN;;Dieses Byte ist die Pr}fsummeR%RCHKSUM;;Gleich der errechneten ?RFSRETRN;;Ja ->R&%>CHKERR;;Fehler: Pr}fsumme falschR 'STATUSR%SRETRNQ>;;Empfang abgeschlossenR PRECVDNR SUSUAL7R?R7R 9;;FertigRNOTYETQSERIN;;Byte lesenR%>R"P@BUFRLO7;;Im Puffer speichernR,R OCHKSUM;;Pr}fsumme errechnenRO>;;Mit Uebertrag !R PCHKSUMR"#BUFRLO;;Pufferzeiger erhoehenR HNTWRP1R #BUFRHIR!NTWRP1QBUFRLO;;Puffer voll ?R RBFENLOS QBUFRHIS SBFENHISDSUSUAL;;Nein ->S QNOCKSM;;Kommt PSumme noch ?SFGOON;;Ja ->SQ>SPNOCKSM;;LoeschenSFSRETRN;;UnbedingtS%GOONQ>;;Puffer-voll-Flag setzen S PBUFRFL SHSUSUAL;;Unbedingt S(LDPNTR,;;DCB Pufferzeiger in Seite 0 S1QDBUFLO;;($32)=($0304), ($34)=($0304)+($0308) S PBUFRLOS ODBYTLOS PBFENLOS QDBUFHIS PBUFRHIS ODBYTHIS PBFENHIS:SCASENTQDSTATS;;Lesen ?SICASRED;;Ja ->S$Q>4BD600;;Baudrate auf 600 Bit/sS PAUDF3S Q>5BD600S PAUDF4S! SENDEN;;Parameter einstellenS $PALNTSCS-%WIRGS9;;Kurze Pause zwischen Datens{tzenS$QDAUX2;;Bsp.: Open #1,8,128,"C:"SGSRTIR0;;Kurze Pause -> S,%WIRGL9;;Lange Pause (Dateien auf Cass.)!SSRTIR0$>;;Pause HI-Byte"S SETVBX;;Timer setzen#SQ>4;;Cassettenmotor an$S PPACTL%S:TIMIT0QTIMFLG;;Wurde der Mark-Ton die vorgeschriebene&S$HTIMIT0;;Zeit gesendet ? Nein ->'S& LDPNTR;;Lade Pufferzeiger mit DCB(S SEND;;Sende Pufferinhalt)S !CRETRN*SCASREDQ>;;Cassette+S PCASFLG,S $PALNTSC-S%RIRGS9;;Kurze Pause ?.S#QDAUX2;;Bsp. Open #1,4,128,"C:"/SGSRTIR1;;Ja ->0S%RIRGL9;;Lange Pause1SSRTIR1$>;;Pause HI-Byte2S SETVBX;;Timer setzen3SQ>4;;Motor an4S PPACTL5S(TIMIT1QTIMFLG;;Schleife bis Zeit um6S HTIMIT17S& LDPNTR;;Lade Pufferzeiger mit DCB8S STTMOT;;Timeout errechnen9S! SETVBX;;Timeout Timer setzen:S BEGIN;;Baudrate messen;S RECEIVE;;Lese Block>SQ><;;Motor aus?S PPACTL@S+SRTIR2!RETURN;;Bis zum n{chsten Block.AS8JTADRQ>;;Timer auf 0 gez{hlt => Pokey Interrupt =>BS*PTIMFLG;;Ansprung von JTADR durchs OS.CS:DS7SENDENQ>;;Vorherige Bus-Kontrollbits ausmaskierenES MSSKCTLFS,L> ;;Sende-und Empfangsfrequenz durch #4GS%DDEVIC;;Cassette ?HS)>`ISHNOTCAS;;Nein ->JS%L>;;Zweitonumtastverfahren (FSK)KS%>LOTONE;;MarkLS 'AUDF2MS%>HITONE;;SpaceNS 'AUDF1OS'NOTCASPSSKCTL;;Pokey programmierenPS PSKCTLQS1Q>;;Vorherige Bus-Interruptbits ausmaskierenRS MPOKMSKSS#L>;;SEROUT-Interrupt erlauben.TS !CONTINUS7RECVENQ>;;Vorherige Bus-Kontrollbits ausmaskierenVS MSSKCTLWS1L>;;Eingangstakt durch #3+4, asynchr. lesen.XS PSSKCTLYS PSKCTLZS3PSKRES;;Status-Reset: Serieller Port & Tastatur[S2Q>;;Vorherige Bus-Interrupt-Bits ausmaskieren\S MPOKMSK]S!L> ;;SERIN-Interrupt erlauben^SCONTINPPOKMSK_S PIRQEN`S1Q>(;;Takte #3 mit 1.77 MHz, #4 an #3 anh{ngenaS PAUDCTLbS$>;;SchleifecS%Q>;;Reiner Ton, halbe Lautst{rkedS%SOUNDR;;<>0 => I/O-SoundeSHNOISE1;;Ton ja ->fS%Q>;;Reiner Ton, keine Lautst{rkegS+NOISE1PAUDC19;;Alle 4 KontrollregisterhS0iS0jS INOISE1kSQ>lS#PAUDC3;;#3 auf jeden Fall leisemS %DDEVICnS)>`oS FCAS31pS*PAUDC1;;Wenn nicht Cassette, dann auchqSPAUDC2;;#1 und #2 leise.rS CAS31:sS SENDDIS4tS-Q>;;Serielle UnterbrechungsanforderungenuSMPOKMSK;;ausschalten.vS PPOKMSKwS PIRQENxS$>ySQ>zS&ZERITPAUDC19;;Alle Tonkan{le aus.{S0|S0}S IZERIT~S:SASTTMOTQDTIMLO;;Bsp.: 6s. Bit 7654 3210 C. Timeout umrechnen.S W?;;%0000 0110 -> C000 0011 0S W?;; -> 0C00 0001 1S?;;zwischensp.SM>?;;Bit 0-5 (vorher: 2-7)S$>;;X=HI=INT(DTIM/4) =1 (*256)SC;;%0C00 0001S W?;; -> 10C0 0000 1SM>;;Bit 6-7 (vorher: 0-1)S?;;Y=LO=64*(DTIM-HI*4)=128S(:;;(256+128)/60=6.4s (Bei NTSC !)SINTTAB ISRSIRS ISRODNS ISRXDSSENDINIT$>;;PauseSDELAY0%>S DELAY11S HDELAY1S0S HDELAY0S SEND;;Sende DatenS%>;;Setze Timeout f}r ACKS$>S*WAITER SETVBX;;Setze Timer1 auf JTADRS WAIT;;Warten auf das ACKSC;;NACK o. Timeout => Y=0S:S.COMPUTPTIMER2;;(VCOUNT) Letzte MesswerteS'TIMER2;;(RTCLOK+2)S ADJUST;;VCOUNT2 abstimmenS PTIMER2S QTIMER1S ADJUST;;VCOUNT1 abstimmenS PTIMER1S(QTIMER2;;Errechne VCOUNT UnterschiedS;S STIMER1SPTEMP1;;LOS+QTIMER2;;Errechne RTCLOK UnterschiedS;SSTIMER1S?;;HIS$PALNTSC;;Pal=0, NTSC=1SQ>;;LDA -#$83S;S SL04809SHITIMR,;;A=-#$83+(Y+1)*#$83S OL04809S1S IHITIMRS,SOTEMP1;;VCOUNT UnterschiedS?;;Accu rettenS$V?;;Teile Unterschied durch 4 undS$V?;;runde auf die n{chst niedrigeSV?;;gerade ganze Zahl ab.ST?S;SS>;;Bestimme TabellenindexS>SC;;Akku wieder zur}ckSM>;;Die unteren 3 BitS ?;;rettenSQ> S-DOINTP,;;Errechne InterpolationskonstanteSO> S1S)IDOINTP;;Fertig mit rechnen ? Nein ->S'%>;;Loesche AdditionskorrekturflagS;S*S>;;Stimme Interpolationskonstante abS IPLUSS1S PLUS,S/OPOKTAB9;;Konstante (LO) +Tabellenwert (LO)S PCBAUDLSC;;Konstante (HI) +S.OPOKTAB9;;Tabellenwert (HI) + UebertragS PCBAUDHS:S"ADJUSTR>|;;Groesser als 124 ?S GADJ1S;SS>|S:S ADJ1,S $PALNTSCS OL04879S:SX;SIX;Messung der Baudrate bei der asynchronen Daten}bertragung (Cassette)SX;S)BEGINQBRKKEY;;Wurde BREAK gedr}ckt ?SHNTBRK2;;Nein ->S!BROKE;;Ja ->S NTBRK2=S QTIMFLGSHOKTIM1;;Kein TimeotSFTOUT1;;TimeoutS0OKTIM1QSKSTAT;;Bit 4 ist eine HardwarekopieS M>;;des seriellen Eingangs.S-HBEGIN;;Start-Bit=LO noch nicht gesendet.S$PSAVIO;;Zustand des Bits sichernS%$VCOUNT;;LO-Anfangszeit speichernS%RTCLOK;;HI-S &TIMER1S'TIMER1S$>;;Zwei Durchg{ngeS &TEMP3S-%> ;;10 Bit (8 Daten-,1 Start-,1 Stopbit)SCOUNTQBRKKEYS FBROKESQTIMFLG;;Timeout ?SHOKTIMR;;Nein ->S TOUT1.S !TOUTS9OKTIMRQSKSTAT;;Lese seriellen Eingang $AA=%10101010SM>;;Bit 4S#RSAVIO;;Schon das n{chste Bit ?SFCOUNT;;Nein ->SPSAVIO;;SichernS1;;Bitz{hler vermindernSHCOUNT;;Noch nicht alle 10S"TEMP3;;Durchgangsz{hlerSGGOREAD;;Datenblock lesenSQVCOUNT;;HI-Messzeit nehmenS%RTCLOK;;LO-S COMPUT;;BerechnenS%> ;;Die 9 restlichen BitsTHCOUNT;;Unbedingt.T0GOREADQCBAUDL;;Pokey auf gemessene BaudrateTPAUDF3;;einstellen.T QCBAUDHT PAUDF4T Q>;;Softwarereset des PokeyTPSKCTL;;(Wenn Bit 0 & 1 =0)T QSSKCTLT PSKCTL T!Q>U;;Cassettenpuffer ab $03FD T'P@BUFRLO7;;Die ersten beiden Bytes= T3;;#$55=%01010101 T P@BUFRLO7 TQ>;;$55+$55=$AAT PCHKSUMT,TQBUFRLO;;Die ersten beidenTO>;;Bytes haben wirT PBUFRLO;;schon, der kommendeT$QBUFRHI;;Datenblock enth{lt nochT!O>;;den Blocktyp, 128 Daten-T%PBUFRHI;;bytes und die Pr}fsumme.T.T:T/BROKE SENDDIS;;IRQ's aus, Tonkan{le leise.TQ><;;Motor ausT PPACTLT"Q><;;CB2 auf HI, kein KommandoT PPBCTLT)Q>BRKABT;;Fehler: Abbruch durch BREAKT PSTATUST $STACKP;;Stapelzeiger zur}ck TB!T$"BRKKEY;;Nach Druck auf BREAK =0"T.#T !RETURN$T-SETVBXQ>4JTADR;;Nullwerden des Z{hlers 1%T"PCDTMA1;;erzeugt einen IRQ des&T#Q>5JTADR;;Pokey. Das OS springt'T'PCDTMA1;;dann indirekt JTADR an.(TQ>;;Vektor 1 setzen)T=*T1 SETVBV;;X=HI & Y=LO enthalten die Zeitwerte.+TQ>;;Timeout-Flag loeschen.,T PTIMFLG-T..T:/T1POKTAB ==C=;;Tabelle mit den Baudraten0T ===1T T===2T  ==e=3T ===4T u===5T*WIRGL =;;Langer IRG beim Schreiben6T&RIRGL x=d;;Langer IRG beim Lesen7T*WIRGS = ;;Kurzer IRG beim Schreiben8T&RIRGS  =;;Kurzer IRG beim Lesen9TL0480 =:TL0487 = ;TADisplay HandlerA