Hat halt jeder seinen eigenen Stil - kann man nicht drüber streiten...
Ich hab versucht, daß verständlich zu dokumentieren.
Bei kleinen Controllern und Projekten verwende ich gern reservierte Rechenregister, und erspare mir das hin- und herkopieren ins/vom SRAM - insbesondere was zeitkritischere Sachen betrifft. Du hast ja 32 davon. Allerdings muß man aufpassen, daß man die später nicht woanders (aus versehen) doch verwendet. Und nur die oberen lassen sich für Operationen mit Immediates verwenden (LDI usw).
In einigen Punkten ist das ganze allerdings etwas inkonsequent:
-den Oversampling-Zähler kann man mit demselben Aufwand auch als Abwärts-Zähler realisieren (dann ist man nicht mehr an 8fach gebunden) - da hatte ich mich in die Idee mit dem schieben verbissen.
-in der Überlauf-ISR des Timers (also bei OCRA) brauch ich eigentlich nach dem sichern des SREG R16 nicht mehr sichern, da es in der ISR selbst nicht verwendet wird.
-Da ich Register reserviere, sollte ich grundsätzlich alle(!) Register nicht mit Rnn ansprechen, sondern auch dort nur neue Namen vergeben - eben um versehentliche Verwendung eines reservierten Registers zu vermeiden (also zB alle nicht reservierten Register mit RRnn (Rechenregister nn) benamsen, und im Programm konsequent diese Namen verwenden)
Noch ein paar Anmerkungen:
-das ganze ist nur mit'nem Editor getippt - sind also sicher noch diverse Fehler zu finden
-wo der verwendete Rx-Pin festzulegen ist, hab ich kommentiert - ist 'ne Konstante (ich hab erstmal B3 verwendet)
-ebenso Baudrate und MCU-Frequenz, können in gewissen Grenzen angepaßt werden - allerdings läuft der Timer derzeit fest mit Prescaler=1 bis 249 oder so (hatte es irgendwo mal ausgerechnet), mehr als 255 darf für den 8bitter nicht rauskommen, klar; weniger als ... 50 - 100oder so (aus dem Bauch heraus) sollten es auch nicht sein, da die Timer-ISR ja jedesmal abgearbeite werden muß (hier sollte man nochmal die unterschiedlichen Fälle durchgehen, und die etwa benötigten Takte ermitteln. Hier würde es dann Sinn machen, beim Compilieren den Wert von T0Ov (Timer0-Overflow) mit #if zu prüfen, und ggf 'ne Warnung bzw 'nen #error zu schmeissen
-wo ich den Rampenzähler für softPWM einbauen würde, hab ich dokumentiert. Der Zähler wird dann mit 8facher Baudrate inkrementiert. Die Ansteuerung des Beinchens selbst würde ich dann ins Hauptprogramm (main) legen.
-HW-PWM (Kanal B) wird bei der Initialisierung des Timers bereits mitaktiviert - allerdings beschreibe ich das Vergleichsregister (OCR0B) nicht. Auch das würde ich in die main legen, da:
-in der Timer ISR wird, falls ein komplettes Bit empfangen wurde, und dieses das Stopbit war geprüft, ob das vorherige Paritätsbit stimmte. Wenn nicht, wird mit SBIS (muß SBIS sein, stand falsch im Code) eine Instruktion übersprungen, Diese eine Instruktion muß also das empfangene Byte freigeben. Dazu würde ich ein weiteres Rechenregister (der Tiny13 hat ja kein GPIOR0) reservieren, und dort ein Bit als neues-Byte-empfangen-Flag (NewByteRecievedFlag - NBRF...
9) setzen (SBR/ORI - ist derselbe Opcode. cave!: nur obere 16 Rechenregister)
-Dieses Flag dann in der main pollen, ist es gesetzt, löscht Du es, wartest ggf bis OSR 0 ist, und liest das RecByte aus. OSR=0->RecByte lesen sollte atomar erfolgen, also Interrupts kurz abschalten. In etwa so:
NBRF pollen, wenn gesetzt
NBRF löschen
Einsprungpunkt: Interrupts unterdrücken
OSR=0? (TST - manipuliert Z)
RecByte in ein Arbeitsregister kopieren(MOV)
Interrupts freigeben
bei Z=1 zurück zum Einsprungpunkt BRZS
im Arbeitsregister steht jetzt das zuletzt empfangene Byte bereit, in den Interrupts kann nebenbei ein weiteres neues Byte empfangen werden
-bei einem Paritätsfehler wird einfach das Flag nicht gesetzt - Achtung: wenn ein korrektes Byte empfangen wurde, Aber in der main zuviel Zeit verplempert wird, kann es theoretisch passieren, daß Du erst auf das Flag reagierst, wenn OSR bereits wieder ungleich 0 ist (wenn ein weiteres Byte ankommt). Dann wartest Du ja das weitere Byte ab, was ggf falsch sein kann. Ich denk nochmal drüber nach. Vielleicht bei der Flankendetektion das NBRF selbst löschen, und dafür in der main das OSR nicht prüfen.
-Die Kontrolle auf ein Fehlerhaftes Startbit ist auch noch nicht drin - der Zweig ist leer.
-Die Anzahl der Stopbits (Hi-Pegel) ist egal - nach dem ersten idlet der Empfang bis zur ersten fallenden Flanke rum - wielange das auch immer dauert.
btw Branches auf Zero-Flag heißen BRNE/BREQ - nicht BRZC/BRZS... schade eigentlich... beim Carry gibts ja auch mehrere Mnemonics (mit demselben Opcode).
Wenn Du das ganze irgendwann via dWire testen willst, mußt Du aber auch das ankommende Bit-Telegramm antsprechend Deiner Haltepunkte anhalten, oder? Ich würde das erstmal durch den Simulator laufen lassen, und zu den jeweiligen Zeiten das Pin-Register-Bit des Rx-Pins manipulieren.