blamaster,

so wie's PicNick in Basic geschrieben hat, hatte ich's auch gemeint. In Assembler sieht's ganz ähnlich aus. Nach ein bisschen Herumprobieren kam mir eine echte Sprungtabelle als die einfachste Methode (in Assembler) vor. Dann braucht man aber doppelt soviel Platz für die Tabelle, als wenn man Port- und Pin-Nummer in einem Byte kodiert ablegt. Es ist aber einfacher, über die Sprungtabelle direkt eine Auswertungsprozedur anzuspringen, als das gelesene Tabellenbyte zu dekodieren. Das kommt daher, dass man beim Atmel die Ports nur direkt (immediate) adressieren kann.

Zur Information hänge ich das Beispiel unten an.

mare_crisium

Code:
;*-----------------------------------
; BEISPIEL Tabelle_V01.asm
; Entwicklungsversion
;*-----------------------------------
;* 	Einbinden
;*

.device  ATmega8
.include "m8def.inc"

;*-----------------------------------
;* 	Definitionen
;*

.equ	PORTA = 0x1B


;*------------------------------------
;*	PROCEDURE TBL_CALL
;*
;* Die Prozedure TBL_JMP liest aus einer Sprung-
;* tabelle, die im Programmspeicher abgelegt 
;* ist, ein 2-Byte-Adresse aus. Sie wird als
;* Programmadresse angesprungen.
;
; Eingangsvariablen
;	zh:zl:  enhält den Zeiger auf die RAM-Adresse,
;	     an der die Sprungtabelle beginnt
;	r16: enthält den Index der Adresse, die 
;	     angesprungen werden soll
;
; Ausgangsvariablen
;	keine
;
; geänderte Register
;	zh,zl
;
; geänderte Ports
;	keine
;

TBL_CALL:
	push r17
	in r17,SREG
	push r17


	clr r17
	add zl,r16
	adc zh,r17
	add zl,zl
	adc zh,zh

	lpm r17,z+
	lpm zh,z
	mov zl,r17

	pop r17
	out SREG,r17
	pop r17

	ijmp	


/*------------------------------------ 

SPRUNGTABELLE


*/
//   0.0  0.1   0.2   0.3   0.4   0.5   0.6  0.7 
SPRUNG_TBL:
.dw SET_PORTA0,	RES_PORTA0						; ... usw.

//...

.dw SET_PORTC7,	RES_PORTC7


/*------------------------------------
	PROCEDURE EVAL_RS485

Die Prozedure EVAL_RS485 wertet ein Datenbyte aus,
das über die RS485 empfangen wurde. Das Datenbyte dient
als Zeiger in die Sprungtabelle SPRUNG_TBL. Die Einträge 
enthalten die Adresse je einer Prozedur, die an einem
bestimmten Port einen bestimmten Pin setzt oder zurücksetzt.

Eingangsvariablen
	r16: enthält den das Datenbyte, das 
	     ausgewertet werden soll

Ausgangsvariablen
	r16: enthält das ungeänderte Datenbyte

geänderte Register
	keine

geänderte Ports
	PORTA,PORTB,PORTC, je nach Datenbyte
*/


EVAL_RS485:
	push r16
	push zl
	in zl,SREG
	push zl
	push zh

	ldi zl,low(SPRUNG_TBL); zh:zl := Adresse der Tabelle
	ldi zh,high(SPRUNG_TBL)
	rcall TBL_CALL	; ausgewählte Prozedure anspringen

	pop zh
	pop zl
	out SREG,zl
	pop r16
	ret			;

/*------------------------------------
	PROZEDUREN SET_PORTA0/RES_PORTA0 bis SET_PORTC7/RES_PORTC7

Hier kommen die Prozeduren, die die ausgewählten Ports und
Pins ansprechen.

Eingangsvariablen
	keine

Ausgangsvariablen
	keine

geänderte Register
	keine

geänderte Ports
	PORTA,PORTB,PORTC, je nach Datenbyte
*/

SET_PORTA0:
	sbi PORTA,0
	ret

RES_PORTA0:
	cbi PORTA,0
	ret

// und so weiter

SET_PORTC7:
	sbi PORTC,7
	ret

RES_PORTC7:
	cbi PORTC,7
	ret

//------------------------