Quelltext /~heha/messtech/kreuzt.zip/M21.ASM

	IDEAL
	MODEL	SMALL,PASCAL
	P286
wo	equ	word
by	equ	byte
macro LD r1,r2
	push	r2
	pop	r1
endm

;Ansteuerung von bis zu 6 Kreuztischen mit je 3 2-Strang-Schrittmotoren
;im Ministep-Betrieb (mit Sinustabelle)
;und - wie gehabt - mit grauenhafter Schrittweitenanpassung.
; Die Leutchen haben sich offenbar allesamt keinen Kopf gemacht,
; dabei ist es doch gar nicht soo schwer (s. vielzitierte Diplomarbeit)


public Stepper_Freq, Stepper_Startup, Stepper_Isub, Stepper_StepWidth
public Stepper_Power, Stepper_Boost, Stepper_Set, Stepper_Move
public Stepper_Step, Stepper_Arrived, Stepper_Steps

struc T3D
 X	dd	?
 Y	dd	?
 Z	dd	?
ends T3D

extrn Stepper_Distance:T3D:6, Stepper_Position:T3D:6
extrn Stepper_EndsMask:Byte:6, Stepper_EndsPol:Byte:6
extrn Stepper_CheckBreak:Byte
extrn Stepper_Port:Word:6, Stepper_Phase:T3D:6
extrn Stepper_SinTab:Word:256
extrn Stepper_Disabled:Byte:6

DATASEG

Stepper_Delay	dd	?
Stepper_WaitVal	dd	?

CODESEG

db	' (c)1992 LLT GmbH, Mnchen/BRD '

;
;                              SUBROUTINE
;

proc Div32
	push	cx si di bp
	xor	bp,bp
	xor	si,si
	xor	di,di
	mov	cx,33
@@l1:
	rcl	bp,1
	rcl	si,1
	sub	bp,bx
	sbb	si,di
	jnc	@@1
	add	bp,bx
	adc	si,di
@@1:
	cmc
	rcl	ax,1
	rcl	dx,1
	loop	@@l1
	pop	bp di si cx
	ret
endp Div32


;
;                              SUBROUTINE
;

proc Stepper_Startup far
	cld
	LD	es,ds
	xor	ax,ax			;Variablen ausnullen
	lea	di,[Stepper_Port]
	mov	cx,6
	rep	stosw
	lea	di,[Stepper_Distance.X]
	mov	cx,6*6
	rep	stosw
	lea	di,[Stepper_Position.X]
	mov	cx,6*6
	rep	stosw
	lea	di,[by Stepper_Phase.X]
	mov	cx,6*6
	rep	stosw
	lea	di,[Stepper_EndsPol]
	mov	cx,3
	rep	stosw
	lea	di,[Stepper_Disabled]
	mov	cx,3
	rep	stosw

	mov	ax,3F3Fh
	lea	di,[Stepper_EndsMask]
	mov	cx,3
	rep	stosw
	push	ds
	 LD	ds,cs			;igitt!!
	 lea	si,[CS_SinTab]
	 lea	di,[Stepper_SinTab]
	 mov	cx,256
	 rep	movsw		;Sinustabelle ins Datensegment kopieren
	pop	ds
	mov	[Stepper_CheckBreak],0
	xor	dx,dx
	xor	cx,cx
	xor	ax,ax
	mov	es,ax
	mov	di,46Ch		;Timer-Zelle ansteuern
	mov	al,[es:di]
@@l1:	cmp	al,[es:di]	;Warten auf Wechsel
	je	@@l1
	mov	al,[es:di]	;Neuer Zhlerstand
@@l2:	cmp	al,[es:di]	;Warten auf Wechsel und mitzhlen
	loopz	@@l2
	jnz	@@1		;Raus!
	inc	dx		;Obere 16 bit
	jns	@@l2		;solange positiv, sonst berlauf
@@1:
	mov	ax,cx
	neg	ax
	mov	bx,55
	call	Div32
	mov	bx,dx
	mov	cx,1000
	mul	cx
	mov	[wo LOW Stepper_WaitVal],ax
	mov	[wo HIGH Stepper_WaitVal],dx
	mov	ax,bx
	mul	cx
	add	[wo HIGH Stepper_WaitVal],ax
	ret
endp Stepper_Startup


;
;                              SUBROUTINE
;

proc SetPhaseFree
	lodsw			;Portadresse holen
	or	ax,ax		;Gltig?
	jz	@@e		;Raus!
	mov	dx,ax
	add	dx,4
	xor	ax,ax
	out	dx,ax
	sub	dx,2
	out	dx,ax
	sub	dx,2
	out	dx,ax
@@e:	ret
endp SetPhaseFree


;
;                              SUBROUTINE
;

proc Stepper_Isub far
	lea	si,[Stepper_Port]
	call	SetPhaseFree
	call	SetPhaseFree
	call	SetPhaseFree
	call	SetPhaseFree
	call	SetPhaseFree
	call	SetPhaseFree
	ret
endp Stepper_Isub


;
;                              SUBROUTINE
;

proc Stepper_Freq far
;arg @@Hz:Word
	mov	bx,sp
	mov	bx,[ss:bx+4]
	or	bx,bx
	jz	@@e		;Null=Fehler
	mov	ax,[wo LOW Stepper_WaitVal]
	mov	dx,[wo HIGH Stepper_WaitVal]
	call	Div32
	mov	[wo LOW Stepper_Delay],1
	mov	[wo HIGH Stepper_Delay],1
	mov	cx,ax
	or	cx,dx
	jz	@@e
	or	ax,ax
	jnz	@@1
	inc	ax
@@1:	mov	[wo LOW Stepper_Delay],ax
	inc	dx
	mov	[wo HIGH Stepper_Delay],dx
@@e:	ret	2
endp Stepper_Freq

label CS_SinTab word
	dw	07F00h,07F03h,07F06h,07E09h,07E0Ch,07E10h,07E13h,07E16h
	dw	07D19h,07C1Ch,07C1Fh,07B22h,07A25h,07928h,0782Bh,0772Eh
	dw	07430h,07333h,07236h,07139h,0703Ch,06F3Fh,06B40h,06A43h
	dw	06A47h,06849h,0654Bh,0644Eh,06351h,05F52h,05F56h,05C58h
	dw	05A5Ah,0585Ch,0565Fh,0525Fh,05163h,04E64h,04B65h,04968h
	dw	0476Ah,0436Ah,0406Bh,03F6Fh,03C70h,03971h,03672h,03373h
	dw	03074h,02E77h,02B78h,02879h,0257Ah,0227Bh,01F7Ch,01C7Ch
	dw	0197Dh,0167Eh,0137Eh,0107Eh,00C7Eh,0097Eh,0067Fh,0037Fh
	dw	0007Fh,0837Fh,0867Fh,0897Eh,08C7Eh,0907Eh,0937Eh,0967Eh
	dw	0997Dh,09C7Ch,09F7Ch,0A27Bh,0A57Ah,0A879h,0AB78h,0AE77h
	dw	0B074h,0B373h,0B672h,0B971h,0BC70h,0BF6Fh,0C06Bh,0C36Ah
	dw	0C76Ah,0C968h,0CB65h,0CE64h,0D163h,0D25Fh,0D65Fh,0D85Ch
	dw	0DA5Ah,0DC58h,0DF56h,0DF52h,0E351h,0E44Eh,0E54Bh,0E849h
	dw	0EA47h,0EA43h,0EB40h,0EF3Fh,0F03Ch,0F139h,0F236h,0F333h
	dw	0F430h,0F72Eh,0F82Bh,0F928h,0FA25h,0FB22h,0FC1Fh,0FC1Ch
	dw	0FD19h,0FE16h,0FE13h,0FE10h,0FE0Ch,0FE09h,0FF06h,0FF03h
	dw	0FF00h,0FF83h,0FF86h,0FE89h,0FE8Ch,0FE90h,0FE93h,0FE96h
	dw	0FD99h,0FC9Ch,0FC9Fh,0FBA2h,0FAA5h,0F9A8h,0F8ABh,0F7AEh
	dw	0F4B0h,0F3B3h,0F2B6h,0F1B9h,0F0BCh,0EFBFh,0EBC0h,0EAC3h
	dw	0EAC7h,0E8C9h,0E5CBh,0E4CEh,0E3D1h,0DFD2h,0DFD6h,0DCD8h
	dw	0DADAh,0D8DCh,0D6DFh,0D2DFh,0D1E3h,0CEE4h,0CBE5h,0C9E8h
	dw	0C7EAh,0C3EAh,0C0EBh,0BFEFh,0BCF0h,0B9F1h,0B6F2h,0B3F3h
	dw	0B0F4h,0AEF7h,0ABF8h,0A8F9h,0A5FAh,0A2FBh,09FFCh,09CFCh
	dw	099FDh,096FEh,093FEh,090FEh,08CFEh,089FEh,086FFh,083FFh
	dw	000FFh,003FFh,006FFh,009FEh,00CFEh,010FEh,013FEh,016FEh
	dw	019FDh,01CFCh,01FFCh,022FBh,025FAh,028F9h,02BF8h,02EF7h
	dw	030F4h,033F3h,036F2h,039F1h,03CF0h,03FEFh,040EBh,043EAh
	dw	047EAh,049E8h,04BE5h,04EE4h,051E3h,052DFh,056DFh,058DCh
	dw	05ADAh,05CD8h,05FD6h,05FD2h,063D1h,064CEh,065CBh,068C9h
	dw	06AC7h,06AC3h,06BC0h,06FBFh,070BCh,071B9h,072B6h,073B3h
	dw	074B0h,077AEh,078ABh,079A8h,07AA5h,07BA2h,07C9Fh,07C9Ch
	dw	07D99h,07E96h,07E93h,07E90h,07E8Ch,07E89h,07F86h,07F83h
label CS_SinTab2 word
	dw	0FF7Fh,0FFFFh,07FFFh,07F7Fh

;
;                              SUBROUTINE
;

proc Stepper_StepWidth far
arg @@stw:Byte
	mov	bl,[@@stw]
	and	bl,7Fh
	jnz	@@1
	lea	si,[CS_SinTab2]
	lea	di,[Stepper_SinTab]
	mov	cx,100h
	xor	bx,bx
	LD	es,ds
@@l1:	mov	ax,[cs:bx+si]
	stosw
	add	bx,2
	and	bx,6
	loop	@@l1
	ret
@@1:
	mov	dl,80h
@@l2:	shr	dl,1
	shr	bl,1
	jnz	@@l2
	sub	dh,dh
	add	dx,dx
	lea	si,[CS_SinTab]
	sub	bx,bx
	mov	cx,100h
	lea	di,[Stepper_SinTab]
	LD	es,ds
@@l3:	mov	ax,[cs:bx+si]
	stosw
	add	bx,dx
	and	bx,1FEh
	loop	@@l3
	ret
endp Stepper_StepWidth


;
;                              SUBROUTINE
;

proc Stepper_Arrived far
	xor	si,si
	xor	di,di
@@l1:
	mov	bx,di
	mov	dx,[Stepper_Port+bx+di]
	or	dx,dx		;Portadresse vorhanden?
	jnz	@@do		;ja, untersuchen
@@cont:
	add	si,6*2		;Nchster Kreuztisch
	inc	di
	cmp	di,6
	jc	@@l1
	mov	ax,1
	ret
@@do:
	mov	ch,[Stepper_Disabled+di]
	test	ch,3
	jnz	@@noX
	mov	ax,[(wo LOW Stepper_Distance.X)+si]
	or	ax,[(wo HIGH Stepper_Distance.X)+si]
	jz	@@noX
	xor	ax,ax
	ret
@@noX:
	test	ch,0Ch
	jnz	@@noY
	mov	ax,[(wo LOW Stepper_Distance.Y)+si]
	or	ax,[(wo HIGH Stepper_Distance.Y)+si]
	jz	@@noY
	xor	ax,ax
	ret
@@noY:
	test	ch,30h
	jnz	@@noZ
	mov	ax,[(wo LOW Stepper_Distance.Z)+si]
	or	ax,[(wo HIGH Stepper_Distance.Z)+si]
	jz	@@noZ
	xor	ax,ax
	ret
@@noZ:
	jmp	@@cont
endp Stepper_Arrived


;
;                              SUBROUTINE
;

proc Stepper_Steps far
endp
proc Stepper_Step far
	push	bp
	xor	bp,bp
	xor	si,si		;SI "zeigert" in Zwlferschritten
	xor	di,di		;DI "zeigert" in Einerschritten
@@l1:
	mov	bx,di		;BX+DI "zeigert" in Zweierschritten
	mov	dx,[Stepper_Port+bx+di]
	or	dx,dx		;Portadresse des Kreuztisches okay?
	jnz	@@1		;dann Motor ansteuern!
@@l2:
	add	si,6*2		;Nchster Kreuztisch
	inc	di
	cmp	di,6		;Letzter Kreuztisch?
	jc	@@l1
	or	bp,bp
	jz	@@e		;Nicht warten
	xor	di,di
	mov	es,di
	mov	al,[es:di]	;Was will der Typ wohl mit /0-IntVec?
	mov	cx,[wo LOW Stepper_Delay]
	mov	dx,[wo HIGH Stepper_Delay]
@@l3:	cmp	al,[es:di]
	loopz	@@l3		;etwas warten!
	dec	dx
	jnz	@@l3		;Und noch etwas warten!
@@e:	mov	ax,bp		;AX<>0 liefern, wenn Bewegung erfolgte
	pop	bp
	ret
@@1:
	in	al,dx
;Endschalter in Bits 0..5
	xor	al,[Stepper_EndsPol+di]		;Polaritt
	and	al,[Stepper_EndsMask+di]	;Maske
	mov	cl,al
	or	cl,[Stepper_Disabled+di]
	mov	ax,[(wo LOW Stepper_Distance.X)+si]
	mov	bx,[(wo HIGH Stepper_Distance.X)+si]
	or	ax,bx		;Entfernung Null?
	jz	@@X_cont	;Nichts (mehr) tun
	or	bh,bh
	jns	@@X_neg		;Negativ schreiten
	test	cl,2		;Endschalter "+" bettigt?
	jnz	@@X_0		;ja, anhalten
	add	[(wo LOW Stepper_Distance.X)+si],1
	adc	[(wo HIGH Stepper_Distance.X)+si],0
	sub	[(wo LOW Stepper_Position.X)+si],1
	sbb	[(wo HIGH Stepper_Position.X)+si],0
	inc	[(by Stepper_Phase.X)+si]
	jmp	@@X_pos
@@X_0:
	mov	[(wo LOW Stepper_Distance.X)+si],0
	mov	[(wo HIGH Stepper_Distance.X)+si],0
	jmp	@@X_cont
@@X_neg:
	test	cl,1		;Endschalter "-" bettigt?
	jnz	@@X_0		;ja, anhalten
	sub	[(wo LOW Stepper_Distance.X)+si],1
	sbb	[(wo HIGH Stepper_Distance.X)+si],0
	add	[(wo LOW Stepper_Position.X)+si],1
	adc	[(wo HIGH Stepper_Position.X)+si],0
	dec	[(by Stepper_Phase.X)+si]
@@X_pos:
	inc	bp			;Oben: Nicht warten
	mov	bl,[(by Stepper_Phase.X)+si]
	sub	bh,bh
	add	bx,bx
	mov	ax,[Stepper_SinTab+bx]
	out	dx,ax
@@X_cont:
	add	dx,2
	mov	ax,[(wo LOW Stepper_Distance.Y)+si]
	mov	bx,[(wo HIGH Stepper_Distance.Y)+si]
	or	ax,bx
	jz	@@Y_cont
	or	bh,bh
	jns	@@Y_neg
	test	cl,8
	jnz	@@Y_0
	add	[(wo LOW Stepper_Distance.Y)+si],1
	adc	[(wo HIGH Stepper_Distance.Y)+si],0
	sub	[(wo LOW Stepper_Position.Y)+si],1
	sbb	[(wo HIGH Stepper_Position.Y)+si],0
	inc	[(by Stepper_Phase.Y)+si]
	jmp	@@Y_pos
@@Y_0:
	mov	[(wo LOW Stepper_Distance.Y)+si],0
	mov	[(wo HIGH Stepper_Distance.Y)+si],0
	jmp	@@Y_cont
@@Y_neg:
	test	cl,4
	jnz	@@Y_0
	sub	[(wo LOW Stepper_Distance.Y)+si],1
	sbb	[(wo HIGH Stepper_Distance.Y)+si],0
	add	[(wo LOW Stepper_Position.Y)+si],1
	adc	[(wo HIGH Stepper_Position.Y)+si],0
	dec	[(by Stepper_Phase.Y)+si]
@@Y_pos:
	inc	bp
	mov	bl,[(by Stepper_Phase.Y)+si]
	sub	bh,bh
	add	bx,bx
	mov	ax,[Stepper_SinTab+bx]
	out	dx,ax
@@Y_cont:
	add	dx,2
	mov	ax,[(wo LOW Stepper_Distance.Z)+si]
	mov	bx,[(wo HIGH Stepper_Distance.Z)+si]
	or	ax,bx
	jz	@@Z_cont
	or	bh,bh
	jns	@@Z_neg
	test	cl,20h
	jnz	@@Z_0
	add	[(wo LOW Stepper_Distance.Z)+si],1
	adc	[(wo HIGH Stepper_Distance.Z)+si],0
	sub	[(wo LOW Stepper_Position.Z)+si],1
	sbb	[(wo HIGH Stepper_Position.Z)+si],0
	inc	[(by Stepper_Phase.Z)+si]
	jmp	@@Z_pos
@@Z_0:
	mov	[(wo LOW Stepper_Distance.Z)+si],0
	mov	[(wo HIGH Stepper_Distance.Z)+si],0
	jmp	@@Z_cont
@@Z_neg:
	test	cl,10h
	jnz	@@Z_0
	sub	[(wo LOW Stepper_Distance.Z)+si],1
	sbb	[(wo HIGH Stepper_Distance.Z)+si],0
	add	[(wo LOW Stepper_Position.Z)+si],1
	adc	[(wo HIGH Stepper_Position.Z)+si],0
	dec	[(by Stepper_Phase.Z)+si]
@@Z_pos:
	inc	bp
	mov	bl,[(by Stepper_Phase.Z)+si]
	xor	bh,bh
	add	bx,bx
	mov	ax,[Stepper_SinTab+bx]
	out	dx,ax
@@Z_cont:
	jmp	@@l2
endp Stepper_Step


;
;                              SUBROUTINE
;

proc Stepper_Move far
	cmp	[Stepper_CheckBreak],0
	jne	@@2
@@l1:
	call	Stepper_Step
	or	ax,ax		;War Bewegung erfolgt?
	jnz	@@l1		;Ja, noch 'ne Runde!
	ret			;fertig
@@2:
	xor	ax,ax
	mov	es,ax
	mov	[by es:471h],0	;CTRL-Break-Flag lschen
@@l2:
	call	Stepper_Step
	or	ax,ax		;War Bewegung erfolgt?
	jz	@@e		;nein, fertig
	cmp	[by es:471h],0	;CTRL-Break gedrckt?
	je	@@l2		;nein, weitermachen
	LD	es,ds
	xor	ax,ax
	lea	di,[Stepper_Distance.X]
	mov	cx,6*6
	rep	stosw		;Alle Entfernungen lschen - HALT
@@e:	ret
endp Stepper_Move


;
;                              SUBROUTINE
;

proc SetPhaseCurrent
	mov	ax,0
	jnz	@@free		;Stromlos, wenn Z=1
	mov	bl,[(by Stepper_Phase.X)+si]
	sub	bh,bh
	add	bx,bx
	mov	ax,[Stepper_SinTab+bx]
@@free:
	out	dx,ax
	add	dx,2		;nchstes Port
	add	si,4		;nchste Phase
	ret
endp SetPhaseCurrent

label CS_Mul12 word
	dw	0000h,000Ch,0018h,0024h,0030h,003Ch

;
;                              SUBROUTINE
;

proc Stepper_Set far
arg @@Card:Word, @@Flags:Byte
iset:	dec	[@@Card]		;Card ist 1-basiert
	mov	si,[@@Card]
	mov	bx,si
	add	bx,bx			;*2
	mov	dx,[Stepper_Port+bx]
	or	dx,dx			;Keine Portadresse?
	jz	@@e			;raus!
	mov	cl,[@@Flags]
	mov	[Stepper_Disabled+si],cl
	mov	si,[cs:CS_Mul12+bx]
	test	cl,3
	call	SetPhaseCurrent
	test	cl,0Ch
	call	SetPhaseCurrent
	test	cl,30h
	call	SetPhaseCurrent
@@e:	ret
endp Stepper_Set

label Magic2 byte
	db	3Fh,3Ch,33h,30h,0Fh,0Ch,03h,00h

proc Stepper_Power far
arg @@Card:Word, @@Flags:Byte
	mov	bl,[@@Flags]
	and	bx,7
	mov	al,[cs:Magic2+bx]
	mov	[@@Flags],al
	jmp	iset
endp Stepper_Power

;
;                              SUBROUTINE
;

proc SetPhaseCurr2
	jz	@@NoOut
	mov	bl,[(by Stepper_Phase.X)+si]
	sub	bh,bh
	add	bx,bx
	mov	ax,[Stepper_SinTab+bx]
	out	dx,ax
@@NoOut:
	add	dx,2
	add	si,4
	ret
endp SetPhaseCurr2

label CS_Magic3 byte
	db	00h,03h,0Ch,0Fh,30h,33h,3Ch,3Fh

;
;                              SUBROUTINE
;

proc Stepper_Boost far
arg @@Card:Word, @@Flags:Byte
	dec	[@@Card]
	mov	si,[@@Card]
	mov	bx,si
	add	bx,bx
	mov	dx,[Stepper_Port+bx]
	or	dx,dx
	jz	@@e
	mov	cl,[Stepper_Disabled+si]
	not	cl
	mov	si,[cs:CS_Mul12+bx]
	mov	bl,[@@Flags]
	and	bx,7
	and	cl,[cs:CS_Magic3+bx]
	test	cl,3
	call	SetPhaseCurr2
	test	cl,0Ch
	call	SetPhaseCurr2
	test	cl,30h
	call	SetPhaseCurr2
@@e:	ret
endp Stepper_Boost

	end
Vorgefundene Kodierung: UTF-80