; 23.12.2002 19:59:29

#cpu = 89S53	; @24 MHz

#Const byte_per_pattern=04h

#Bit Empfang, Sendebusy
#Bit timer_ret
#Byte chan_1, chan_2, chan_3, chan_4
#Byte next_out, next_port_out
#Byte byte_nr, byte_pos

;Registervereinbahrungen:
;r7 ... aktuelle Position im Pattern


ajmp Initialisierung

Timer 0:	; Timer 0 Interrupt
	ajmp Timer 0 Interrupt

SINT:	; serieller Interrupt
	ajmp Serieller Interrupt

Initialisierung:

; Serieller Port
mov SCON, # D0h	; Modus 3, asynchron, 11 Bit, Baudrate Timer 1/2 Überlauf, Datenempfang freigeben
mov TMOD, # 20h	; Timer 1 Autoreloadmodus
mov TH1, # FDh	; Reloadwert für Baudrate 20833,33
setb TR1	; Timer 1 Start
orl TMOD, # 02h	; Timer 0 im 8-Bit Autoreload-Modus.
; Die Überlauffrequenz des Timer 0 beträgt 2000000 Hz, die Periodendauer 0,0005 ms.
mov TH0, # FFh	; Reloadwert

; Interrupts
setb ET0	; Timer 0 Interrupt freigeben
;setb PT0	; Priorität für Timer 0 Interrupt
setb ES	; seriellen Interrupt freigeben
setb EA	; globale Interruptfreigabe

mov byte_pos, #07h
mov byte_nr,#03h
mov dptr, #PatternTable

mov chan_1, #00h
mov chan_2, #20h
mov chan_3, #07h
mov chan_4, #17h

setb timer_ret
setb TR0	; Timer 0 läuft.

main:
	if bit Empfang then
		clr Empfang
		acall Serielle Daten auswerten
		mov r0,a
		anl a, #1fh
		mov r1, a
		mov a, r0		
		anl a, #c0h
		rl a
		rl a
		if a=#00h
			mov chan_1,r1
		elseif a=#01h
			mov chan_2, r1
		elseif a=#10h
			mov chan_3,r1
		elseif a=#11h
			mov chan_4,r1
		end if
	end if
	if bit timer_ret
		acall calc_pattern
	end if
jmp main

calc_pattern:
	;Channel 1 ermitteln
	mov a, chan_1	
	mov b, #byte_per_pattern
	mul ab
	add a,byte_nr 
	movc a, @a+dptr
	mov r0,byte_pos
	inc r0	
	for r0
		rl a
	next
	rr a
	anl a, #80h
	mov next_out, a
	;Channel 2
	mov a, chan_2
	mov b, #byte_per_pattern
	mul ab
	add a,byte_nr 
	movc a, @a+dptr
	mov r0, byte_pos
	inc r0	
	for r0
		rl a
	next
	rr a
	anl a, #80h
	rr a
	orl a, next_out
	mov next_out, a
	;Channel 3
	mov a, chan_3
	mov b, #byte_per_pattern
	mul ab
	add a,byte_nr 
	movc a, @a+dptr
	mov r0, byte_pos
	inc r0	
	for r0
		rl a
	next a
	rr a
	anl a, #80h
	rr a
	rr a
	orl a, next_out
	mov next_out, a
	;Channel 4
	mov a, chan_4
	mov b, #byte_per_pattern
	mul ab
	add a,byte_nr 
	movc a, @a+dptr
	mov r0, byte_pos
	inc r0	
	for r0
		rl a
	next a
	rr a
	anl a, #80h
	rr a
	rr a
	rr a
	orl a, next_out
	mov next_port_out, a
	clr timer_ret
ret

Serielle Daten auswerten:
	mov a, SBUF
	; weitere Befehle
ret

Sende:	; Sendewert in a
	jb Sendebusy, hier	; auf Sendefreigabe warten
	mov SBUF, a
	setb Sendebusy
ret

Timer 0 Interrupt:
	mov r6,a	
	mov a, next_port_out
	mov p1, a
	dec byte_pos	
	mov a, byte_pos
	if a=#ffh
		mov byte_pos, #07h
		dec byte_nr
		mov a, byte_nr
		if a=#ffh
			mov byte_nr,#03h
		end if
	end if
	setb timer_ret
	mov a, r6
reti

Serieller Interrupt:
	; Herkunft ermitteln
	if bit TI then	; Senden
		clr TI
		clr Sendebusy
	else	; Empfangen
		clr RI
		setb Empfang
	end if
reti

PatternTable:
DB ffh, ffh, ffh, ffh
DB ffh, ffh, ffh, feh
DB ffh, ffh, ffh, fch
DB ffh, ffh, ffh, f8h
DB ffh, ffh, ffh, f0h
DB ffh, ffh, ffh, e0h
DB ffh, ffh, ffh, c0h
DB ffh, ffh, ffh, 80h
DB ffh, ffh, ffh, 00h
DB ffh, ffh, feh, 00h
DB ffh, ffh, fch, 00h
DB ffh, ffh, f8h, 00h
DB ffh, ffh, f0h, 00h
DB ffh, ffh, e0h, 00h
DB ffh, ffh, c0h, 00h
DB ffh, ffh, 80h, 00h
DB ffh, ffh, 00h, 00h
DB ffh, feh, 00h, 00h
DB ffh, fch, 00h, 00h
DB ffh, f8h, 00h, 00h
DB ffh, f0h, 00h, 00h
DB ffh, e0h, 00h, 00h
DB ffh, c0h, 00h, 00h
DB ffh, 80h, 00h, 00h
DB ffh, 00h, 00h, 00h
DB feh, 00h, 00h, 00h
DB fch, 00h, 00h, 00h
DB f8h, 00h, 00h, 00h
DB f0h, 00h, 00h, 00h
DB e0h, 00h, 00h, 00h
DB c0h, 00h, 00h, 00h
DB 80h, 00h, 00h, 00h
DB 00h, 00h, 00h, 00h