; Umschaltung der Baudrate im EUROTNC3+ ; ; Autor: Jürgen Petri DD4FG ; Web: eurotnc.de ; ; ########### Das hier freigegebene Programm, kann für alle frei genutzt und verändert werden. ############# PX=16C505 ;PX=16f877 if PX==16C505 list p=16C505 include "p16C505.inc" __CONFIG _MCLRE_ON&_CP_ON&_WDT_OFF&_IntRC_OSC_RB4EN __IDLOCS 1234h #define RAM_POWER PORTB,0 ; + Pin für das Ram #define BANK_EPROM PORTB,1 #define SERI PORTB,2 #define RESET PORTB,3 #define RESET_OUT PORTB,4 #define TASTER PORTB,5 #define RESET_LED PORTC,4 #define SELECT_E PORTC,5 #define SCHALT_BIT 000CH,0 #define RES_BIT 000CH,1 ; Antwortbit bei serieller Übertragung #define RES_OK 000CH,2 #define UP_BIT 000CH,3 ; Ausgang Leuchtdiode Reset #define START_NEW 000CH,6 ; Kennbit für Z80 neustart #define ENTPRELL 000DH #define TEMP 000EH #define COUNT 000FH #define COUNT1 0010H #define COUNT2 0011H #define BAUD_REG 0012H ; Speicher für aktuelle Baudrate #define BUFFER 0013H #define BUFFER1 0014H #define EPROM_REG 0015H ; Speicher für Eprom Einstellungen #define RAM_TEST1 0016H ; Test Speicherzelle1 #define RAM_TEST2 0017H ; Test Speicherzelle2 else ;##################################################################### include "p16f877.inc" list P=16f877 __CONFIG _WDT_OFF&_PWRTE_ON&_XT_OSC&_CP_OFF __IDLOCS 1234h #define RAM_POWER PORTB,0 ; + Pin für das Ram #define BANK_EPROM PORTB,1 #define SERI PORTB,2 #define RESET PORTB,3 #define RESET_OUT PORTB,4 #define TASTER PORTB,5 #define RESET_LED PORTC,4 ; Ausgang Leuchtdiode Reset #define SELECT_E PORTC,5 #define SCHALT_BIT 000CH,0 #define RES_BIT 000CH,1 ; Antwortbit bei serieller Übertragung #define RES_OK 000CH,2 #define UP_BIT 000CH,3 #define START_NEW 000CH,6 ; Kennbit für Z80 neustart #define ENTPRELL 002DH #define TEMP 002EH #define COUNT 002FH #define COUNT1 0030H #define COUNT2 0031H #define BAUD_REG 0032H ; Speicher für aktuelle Baudrate #define BUFFER 0033H #define BUFFER1 0034H #define EPROM_REG 0035H ; Speicher für Eprom Einstellungen #define RAM_TEST1 0036H ; Test Speicherzelle1 #define RAM_TEST2 0037H ; Test Speicherzelle2 #define LED PORTE,0 endif #define BLINK 0007H ; Anzahl der Blinkdurchgänge org 0000H ;movlw 7Ch ; Wert nur für Fenster Version if PX==16C505 movwf OSCCAL movlw b'00011000' movwf STATUS movlw B'11111111' OPTION else movlw B'11111110' banksel TRISD movwf TRISD ;movlw B'11111001' ;WDT einschalten ;movwf OPTION_REG banksel PORTD bcf LED endif clrf 000CH ;-------- goto ANF TAB1 movf BAUD_REG,W andlw B'00000111' addwf PCL,F retlw B'00011111' retlw B'00000001' ; 1k2 retlw B'00000010' ; 2k4 retlw B'00000100' retlw B'00001000' retlw B'00010000' ; 9k6 retlw B'00000000' retlw B'00000000' ;#################################################################### DELAY movlw .255 movwf BUFFER ;---------------- DELAY2 decfsz TEMP,F goto DELAY2 ; ;btfss RESET ;goto SLEEP_MODE ; ;--------------- Zustand des Tasters abfragen ---------------------- ; btfss TASTER ; Test ob Taster gedrückt goto SCHALTER6 ; JMP wenn nicht movf ENTPRELL,W xorlw .100 ; ENTPRELL Register auf max Wert testen btfsc 3,2 goto SCHALTER7 ; Abbrechen wenn ENTPRELL Register max erreicht hat ;--------------- incf ENTPRELL,F ; ENTPRELL Register um 1 erhöhen btfsc SCHALT_BIT ; Test ob Taster bereits betätigt wurde goto SCHALTER7 ; Abbrechen wenn ja ;--------------- movf ENTPRELL,W xorlw .90 ; Test ob Schaltschwelle erreicht btfss 3,2 goto SCHALTER7 ;--------------- bsf UP_BIT bsf SCHALT_BIT goto SCHALTER7 SCHALTER6 decfsz ENTPRELL,F goto SCHALTER7 incf ENTPRELL,F bcf SCHALT_BIT SCHALTER7 ;--------------------------------------------------------------------- btfsc UP_BIT retlw 00 ; Abbruch wenn Taster erneut betätigt wurde ; decfsz BUFFER,F goto DELAY2 retlw 00 ;#################################################################### INIT_EPROM movlw 0055H movwf RAM_TEST1 movlw 0082H movwf RAM_TEST2 ;-------------- bcf EPROM_REG,0 ; Bank1 selectieren bcf EPROM_REG,1 ; Eprom1 selectieren ; movlw B'00000001' ; Default Wert für Baudrate movwf BAUD_REG ; ins Register laden ; retlw 00 ;----------------------------------------------------- EPROM_INC incf EPROM_REG,F ; Eprom Einstellungen ändern wenn ja bsf START_NEW ; Neustart Bit setzen bcf UP_BIT ;------------ movlw BLINK movwf COUNT1 ; Anzahl nachladen wie oft die LEDs blinken sollen EPROM_SET clrf BUFFER1 btfsc EPROM_REG,1 ; Eprom Einstellungen übernehmen bsf BUFFER1,5 ; für Portausgabe ;---------------- rlf EPROM_REG,W andlw B'00000110' ;----------- addwf PCL,F movlw B'00010000' ; Host Mode LED 1 ist invertiert! goto E_SET movlw B'00010011' ; KISS goto E_SET movlw B'00010101' ; TheNet KISS goto E_SET movlw B'00011001' ; TheNet Term E_SET iorwf BUFFER1,F ; BUFFER1 als Ausgaberegister speichern retlw 00 ; ;################################################################## TIMER movlw .30 movwf COUNT ;----------- TIMER1 clrf TEMP TIMER2 ;btfss RESET ;goto SLEEP_MODE decfsz TEMP,F goto TIMER2 decfsz COUNT,F goto TIMER2 retlw 00 ;################################################################## SEND movf BAUD_REG,W ; Gespeicherte Daten Der Baudrate andlw B'00000011' ; dem zu sendenden Byte iorlw 0050H ; zufügen movwf BAUD_REG ;--------------- bcf RES_BIT ; response bit löschen bcf RES_OK ; btfss SERI ; Test ob Leitung High retlw 00 ; wenn nicht warten abbruch da BUSY ;--------------- SEND2 bcf SERI movlw B'11101000' TRIS PORTB bcf SERI movlw .255 ; Start Verzögerung movwf TEMP SEND4 nop decfsz TEMP,F ; Pause lang Low (Start Signal) goto SEND4 ;---------------- movf BAUD_REG,W ; Baudbit für die Übertragung nach movwf TEMP movlw .8 movwf COUNT ; 8 Durchgänge laden SEND8 rrf TEMP,F nop nop ;---------------- bsf SERI btfsc STATUS,C call SEND18 ;---------------- call SEND19 ;---------------- bcf SERI btfss STATUS,C call SEND18 ;---------------- decfsz COUNT,F goto SEND8 ;------------------------------------------------------------------- ; ;-------------- ; Port auf Empfang setzen bsf SERI ; Port kurz auf High setzen, dann auf Empfang movlw B'11101100' TRIS PORTB ; auf Empfang schalten und Antwort abwarten ;-------------- bsf COUNT,5 ; Auf 16 durchgänge setzen ; ;nop SEND14 btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren goto SEND25 ; btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren ; goto SEND25 ; btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren ; goto SEND25 ; btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren ; goto SEND25 ; btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren ; goto SEND25 ; btfss SERI ; Auf evtl. Antwort (LOW) syncronisieren ; goto SEND25 decfsz COUNT,F goto SEND14 ;---------------------- SEND18 goto SEND19 SEND19 goto SEND20 SEND20 retlw 00 ; Abbruch wenn keine Antwort kam ;-------------- SEND25 bsf RES_BIT SEND30 btfss SERI ; warten auf H (Antwortbit) goto SEND30 clrf BUFFER SEND32 incfsz BUFFER,F ; Auswertung H btfsc SERI ;goto SEND35 goto SEND32 SEND35 comf BUFFER,F SEND34 incf BUFFER,F ; Auswertung L btfss SERI ;goto SEND36 goto SEND34 SEND36 btfss BUFFER,7 bsf RES_OK retlw 00 ;-------------- ;##################################################################### ; Test ob Z80 Software anläuft RESPONSE movlw B'00010000' ; Power LED blinken lassen xorwf PORTC,F ; bcf RESET_OUT ;------------- bcf SELECT_E btfsc EPROM_REG,1 ; Eprom selektieren bsf SELECT_E ;------------- bcf BANK_EPROM btfsc EPROM_REG,0 ; Bank selektieren bsf BANK_EPROM ;------------- btfss BUFFER1,0 ; nur wenn 1. Soft nicht erkannt wird bcf RAM_POWER ; RAM löschen call TIMER1 call TIMER1 bsf RAM_POWER call TIMER1 ;------------- bsf RESET_OUT call TIMER1 call TIMER1 RES_0 ;goto RES_0 ;------------- movlw .40 movwf BUFFER1 RES_1 call TIMER movlw B'00001100' ; Test ob Status und connect LED ausgeschaltet werden andwf PORTC,W btfsc STATUS,Z retlw 01 decfsz BUFFER1,F goto RES_1 bcf STATUS,Z retlw 00 ; ;##################################################################### EPROM_RECALL bcf SELECT_E btfsc EPROM_REG,1 ; Eprom selektieren bsf SELECT_E ;------------- bcf BANK_EPROM btfsc EPROM_REG,0 ; Bank selektieren bsf BANK_EPROM retlw 00 ;##################################################################### ANF ;btfss RESET ;goto ANF ; bcf RESET_OUT movlw B'11101100' ; tris PORTB ; ;bsf RESET_LED ; Nach Reset, Leuchtdiode einschalten bsf RAM_POWER ; Pin auf H setzen für RAM Versorgungsspamnnung ; movlw B'11000000' ; LEDs Port C schalten tris PORTC ; movlw B'00011110' ; alle LEDs leuchten lassen movwf PORTC ;-------------- clrf COUNT ; warten ;clrwdt call TIMER1 call TIMER1 call TIMER1 ; movlw B'11001111' ; LEDs Port C hochomig schalten außer RESET-LED tris PORTC ; und Eprom select bcf RESET_LED ; Reset LED noch nicht leuchten lassen ; call TIMER1 call TIMER1 ;#################################################################### ;# nach Beendigung der SLEEP-MODE alte Baudrate wieder laden # ;#################################################################### ; RECALL bcf STATUS,0 ; Carry Bit löschen dev. Zustand movf RAM_TEST1,W ; Test 1. Ramspeicherzelle xorlw 0055H btfss STATUS,2 bsf STATUS,0 ; Bei Fehler Carry Bit als ERRORBIT setzen ;------------- movf RAM_TEST2,W xorlw 0082H ; Test 2. Ramspeicherzelle btfss STATUS,2 bsf STATUS,0 ; Bei Fehler Carry Bit als ERRORBIT setzen ;------------- btfsc STATUS,0 ; Wenn Errorbit gesetzt Grundeinstellungen laden call INIT_EPROM ; Wenn keine Daten mehr im RAM Grundeinst. laden ;------------- call EPROM_RECALL ;---------------------- movlw .10 movwf COUNT1 ; Error Zähler voreinstellen ;-------------- RE2 call TIMER ; RECALL 1. Versuch call SEND ; Daten übertragen btfsc RES_OK ; Test ob Aussendung ankam goto RE_OK ; Abbruch wenn alles OK decfsz COUNT1,F goto RE2 ;---------------------- movlw .1 movwf BAUD_REG movlw .10 movwf COUNT1 ; Error Zähler voreinstellen ;-------------- RE4 call TIMER ; RECALL 2. Versuch mit Baudrate 1 call SEND ; Daten übertragen btfsc RES_OK ; Test ob Aussendung ankam goto RE_OK ; Abbruch wenn alles OK decfsz COUNT1,F goto RE4 ;---------------------- ;########### Z80 Reset freigeben und Test ob Soft anspricht ########## ; RE_OK ; bsf BUFFER1,0 ; Kennbit für 1 Durchgang setzen (kein RAM Res.) ; RE_OK2 movlw B'11001111' ; LEDs Port C hochomig schalten außer RESET-LED tris PORTC ; und Eprom select ; call RESPONSE ; 1. Test ob eingestellte Soft anspricht btfsc STATUS,Z goto MAIN0 ;--------------------- TheNet Test bsf EPROM_REG,1 ; 2. Epromsockel selektieren bsf EPROM_REG,0 ; Protokollmode aktivieren (bei TheNet) call RESPONSE ; 2. Test ob eingestellte Soft anspricht btfsc STATUS,Z goto MAIN0 ;--------------------- Host Mode Test bcf EPROM_REG,1 ; 1. Epromsockel selektieren bcf EPROM_REG,0 ; Bank 1 selektieren call RESPONSE ; 3. Test ob eingestellte Soft anspricht btfsc STATUS,Z goto MAIN0 ;--------------------- bcf EPROM_REG,1 ; 1. Epromsockel selektieren bsf EPROM_REG,0 ; Bank 2 KISS aktivieren call RESPONSE ; 4. Test ob eingestellte Soft anspricht btfsc STATUS,Z goto MAIN0 ;--------------------- goto RE_OK2 ; ;#################################################################### ; MAIN0 movlw B'11001111' ; LEDs Port C hochomig schalten außer RESET-LED tris PORTC ; und Eprom select bsf RESET_LED ; RESET_LED leuchten lassen bsf RESET_OUT ; Reset für Z80 Kern freigeben MAIN bcf UP_BIT ;--------------------- MAIN2 call DELAY ; Schalter abfragen ;btfss RESET ;goto SLEEP_MODE btfss UP_BIT goto MAIN2 goto DISP ;------------------------------------------------------------------ ; MAIN5 incf BAUD_REG,F ; Eine Baudrate nach oben schalten bsf COUNT1,4 ; Fehlerdurchgänge auf 8 begrenzen ;--------------------- MAIN6 call TIMER call SEND ; Daten übertragen btfsc RES_BIT ; Test ob Aussendung ankam goto MAIN10 ; JMP wenn ja ;--------------------- ; ; Bei Fehler, decfsz COUNT1,F ; Fehlerdurchgasreg. verringern goto MAIN6 ; und erneut versuchen ;-------------- ; ; Wenn Durchg. überschritten decf BAUD_REG,F ; Aktion rückgängig machen goto MAIN0 ; und Abbruch ;------------------------------------------------------------------ MAIN10 btfss RES_OK goto MAIN5 ; bei Fehler, übertragene Variable erhöhen ;-------------- ; und nochmal übertragen ; ;##################### Variable durch LEDs anzeigen ############### ; ; DISP bcf UP_BIT ; Wenn Übertragung ausgef. UP_BIT zurücksetzen ;----------------- movlw .6 ; Zeitcounter Wert bis Z-80 Reset (Softwechsel) movwf COUNT2 ; laden ;----------------- clrf BUFFER1 ; btfsc EPROM_REG,1 ; gesetzte Eprom Pins von PORTC übernehmen bsf BUFFER1,5 ;------------ call TAB1 xorlw B'00000001' ; DCD LED invertiert ansteuern iorwf BUFFER1,F ;---------------- movlw B'11000000' ; LEDs Port C schalten tris PORTC ;---------------- movlw .7 movwf COUNT1 ; Anzahl wie oft die LEDs blinken sollen ;---------------- ; DISP8 clrf TEMP ; alle LEDs dunkel schalten btfsc EPROM_REG,1 ; Eprom Einstellungen übernehmen bsf TEMP,5 bsf TEMP,0 ; DCD LED ist bei high aus! movf TEMP,W movwf PORTC ; Werte LED's + Epromeinst. ausgeben ;---------------- ; call DELAY ; Warten und Taster abfragen ; ;----------- btfsc UP_BIT ; Test op Taster erneut betät. wurde goto MAIN5 ; JMP wenn ja ;---------------- movlw .6 ; wenn Taster dauer gedrückt, btfss SCHALT_BIT ; count2 nicht nachladen movwf COUNT2 ;---------------- decfsz COUNT2,F goto DISP10 goto RESET_MODE ;---------------------------------------------------------- DISP10 movf BUFFER1,W ; Ausgew. Kanal anzeigen movwf PORTC ;---------------- call DELAY ;----------- btfsc UP_BIT ; Test op Taster erneut betät. wurde goto MAIN5 ; JMP wenn ja ;---------------- btfss SCHALT_BIT ; Blinken beibehalten wenn Taster dauernd gedrückt wird decfsz COUNT1,F goto DISP8 ;---------------- goto MAIN0 ; ;#################################################################### ;# RESET des Z80 Kerns und Möglichkeit der Bankumschaltung # ;#################################################################### RESET_MODE ; bcf PORTC,0 ; DCD LED leuchtet bei LOW! movlw B'00011110' ; Bei erreichen der Reset Mode, alle LED's iorwf PORTC,F ; leuchten lassen und warten bis RES6 call DELAY ; btfsc SCHALT_BIT ; Taster wieder losgelassen wird goto RES6 ; zurück wenn Taster immnoch gedrückt wird ;---------------------- movlw BLINK movwf COUNT1 ; Anzahl wie oft die LEDs blinken sollen ;---------------------- bcf START_NEW ; Kennbit für Neustart zurücksetzen bcf UP_BIT ;----------------------------------------------------------------- RES8 ; call EPROM_SET ; Eprom Einstellung als LED Maske holen in BUFFER1 ; movlw B'11100000' ; alle LEDs dunkel schalten andwf PORTC,F bsf PORTC,0 ; DCD LED ist bei high aus! ;---------------- ; call DELAY ; Warten und Taster abfragen ; ;--------------- btfsc UP_BIT ; Test op Taster erneut betät. wurde call EPROM_INC ; wenn ja, Eprom Step um 1 erhöhen ;---------------------------------------------------------------- movf BUFFER1,W ; Ausgew. Kanal anzeigen movwf PORTC ;---------------- call DELAY ;----------- btfsc UP_BIT ; Test op Taster erneut betät. wurde call EPROM_INC ; wenn ja, Eprom Step um 1 erhöhen ;---------------- decfsz COUNT1,F goto RES8 ;--------------------------------------------------------------- btfss START_NEW goto MAIN0 ; Wenn Werte nicht geändert worden, abbruch ;----------------------- RESET bei geänderten Werten ----------- ; ; bcf RESET_OUT ; Reset des Z-80 Kerns einleiten clrf COUNT call TIMER1 ; warten call TIMER1 call TIMER1 ; bcf RAM_POWER ; RAM Versorgungsspannung abschalten call TIMER1 ; warten call TIMER1 call EPROM_RECALL ; neue Eprom Einstellungen laden call TIMER1 bsf RAM_POWER ; RAM Versorgungsspannung wieder einschalten ; call TIMER1 bsf RESET_OUT ; Z-80 Kern wieder anlaufen lassen goto MAIN0 ;#################################################################### ; SLEEP_MODE movlw B'11111111' ; LEDs Port C hochomig schalten tris PORTC ; bcf RESET_OUT movlw B'11101100' ; Port B hochomig schalten tris PORTB movlw B'00000001' movwf PORTB ; bsf RAM_POWER movlw B'00000001' ; movf PORTB,W ; Port lesen "WICHTIG" ; andlw B'11110111' ; RB3 (RESET PIN) als 0 einlesen ;------------------ movlw b'01111111' ; Sleep reset freigeben ;----------------- if PX!=16C505 banksel OPTION_REG movwf OPTION_REG banksel PORTB else OPTION endif ;----------------- ;sleep ; ;#################################################################### end