
*
* Routinen zur Steuerung des GAL-Brenners
*
* assemblieren: as -n -c -d port.asm
*



GAL16V8		EQU	1		; GAL-Typ
GAL20V8		EQU	2

IC1		EQU	3		; IC-Nummer
IC3		EQU	0
IC4		EQU	1
IC5		EQU	2
IC6		EQU	0
IC7		EQU	1

ON		EQU	1		; für LED-Steuerung
OFF		EQU	0

PROG		EQU	1		; Edit-Mode für GAL
VERIFY		EQU	0



ciaaprb		EQU	$BFE101
ciaaddrb	EQU	$BFE301
ciabpra		EQU	$BFD000
ciabddra	EQU	$BFD200


	public	_InitParPort		; Parallel-Port initialisieren
	public	_RestoreParPort		; Parallel-Port restaurieren
	public	_InitGALer		; GALer initialisieren
	public	_WriteByte		; Byte in Schiebereg. schreiben
	public	_ReadByte		; Byte aus Schiebereg. lesen
	public	_SetGAL			; GAL-Type festlegen
	public	_VeditOn		; Edit-Spannung aufbauen
	public	_VeditOff		; Edit-Spannung abschalten
	public	_LED			; LED ansteuern
	public	_EnableVcc		; Vcc anlegen
	public	_DisableVcc		; Vcc abschalten
	public	_EnableVEdit		; Edit-Spannung anlegen
	public	_DisableVEdit		; Edit-Spannung abschalten
	public	_EnableOutput		; Ausgangs-Treiber aktivieren
	public	_DisableOutput		; Ausgangs-Treiber deaktiviern
	public	_SetRow			; Adresse an RAG0-RAG5 anlegen
	public	_SDIn			; Lege ein Bit an SDIn-Eingang
	public	_SDOut			; Bit vom SDOut-Ausgang holen
	public	_Clock			; Clock-Impuls an SCLK-Eingang
	public	_STRImpuls		; STR-Impuls erzeugen
	public	_EditMode		; setzt Bits für Edit-Mode
	public	_ExitEditMode		; Edit-Mode verlassen und Vcc weg
	public	_SetPV			; VERIFY oder PROG
	public	_SetVolt		; Edit-Spannung einstellen


	XDEF	_GALType
	XDEF	_outIC1
	XDEF	_outIC3
	XDEF	_outIC4
	XDEF	_outIC5

	XREF	_WaitForTimer

	XREF	_LVOForbid
	XREF	_LVOPermit

	XREF	_prog_volt

	cseg



* initialisiere den Parallel-Port
_InitParPort:
	move.b	ciaaddrb,cia_addrb		; Datenrichtung der CIAs
	move.b	ciabddra,cia_bddra		; merken

	move.b	#%11111111,ciaaddrb	; Datenleitungen auf Ausgang schalten
	and.b	#%11111110,ciabddra	; BUSY auf Eingang
	rts


* Parallel-Port restaurieren
_RestoreParPort:
	move.b	cia_addrb,ciaaddrb	; Datenrichtungen der CIAs restau-
					; rieren. Der Zustand der Ausgänge
	move.b	cia_bddra,d0		; wird nicht wieder hergestellt, da
	and.b	#%11111110,ciabddra	; sonst der angeschlossene GAL-Brenner
	and.b	#%00000001,d0		; ein unerwünchstes Signal empfangen
	or.b	d0,ciabddra		; könnte (z.B. Vcc oder VEdit anlegen)
	rts



* GALer initialisieren: alle Ausgänge von IC1 auf LOW (kein OutputEnable
* für IC3,4,5 aber Register-Inhalt von IC3,4,5 auf LOW stellen)
* Parameter: keine
_InitGALer:
	or.b	#%00001000,ciaaprb	; PD3=H: Adressdecoder deaktivieren!
	and.b	#%00001000,ciaaprb	; alle anderen Datenleitungen auf LOW
			; ACHTUNG!!!: PD3 darf nur auf LOW-Pegel gehen
			; (Adressdecoder aktiviert werden), wenn durch PD0 und
			; PD1 das IC, das angesprochen werden soll, bereits
			; selektiert ist. Ansonsten bekommt ein IC einen Takt-
			; impuls und beim nächsten Strobe liegen dann die
			; falschen Daten an.
	move.w	#IC1,-(sp)
	clr.w	-(sp)
	bsr	_WriteByte		; Ausgänge von IC1 auf LOW	
	addq.l	#4,sp			; Stack korrigieren
	move.w	#IC3,-(sp)
	clr.w	-(sp)
	bsr	_WriteByte		; Ausgänge von IC3 auf LOW	
	addq.l	#4,sp			; Stack korrigieren
	move.w	#IC4,-(sp)
	clr.w	-(sp)
	bsr	_WriteByte		; Ausgänge von IC4 auf LOW	
	addq.l	#4,sp			; Stack korrigieren
	move.w	#IC5,-(sp)
	clr.w	-(sp)
	bsr	_WriteByte		; Ausgänge von IC5 auf LOW	
	addq.l	#4,sp			; Stack korrigieren
	rts



* SetGAL:
* Setzte GAL-Type fest (GAL16V8, GAL20V8)
* Aufruf: SetGAL(type);
*
_SetGAL:
	move.w	4(sp),_GALType
	rts



* VeditOn:
* schaltet den Sperrwandler an (IC9); siehe auch VeditOff
* Auruf: VeditOn();
_VeditOn:
	move.w	#IC1,-(sp)
	or.w	#%00001,_outIC1		; Q1 von IC1 auf HIGH => VeditOn
	move.w	_outIC1,-(sp)
	bsr	_WriteByte		; IC1 setzen
	addq.l	#4,sp			; Stack korrigieren
	rts

* VeditOff:
* schaltet den Sperrwandler aus (IC9); siehe auch VeditOn
* Auruf: VeditOff();
_VeditOff:
	move.w	#IC1,-(sp)
	and.w	#%11111110,_outIC1	; Q1 von IC1 auf LOW => VeditOff
	move.w	_outIC1,-(sp)
	bsr	_WriteByte		; IC1 setzen
	addq.l	#4,sp			; Stack korrigieren
	rts


* EnableVEdit:
* schaltet die Edit-Spannung (+16.5V) auf Pin 2 oder Pin 4 vom Textool
* (abhänging vom eingestellten GAL-Typ)
* Aufruf: EnableVEdit();
_EnableVEdit:
	move.w	#IC1,-(sp)		; IC1 einstellen
	cmp.w	#GAL16V8,_GALType	; 16V8 eingestellt?
	bne.s	1$			; nein, dann wird 20V8 angenommen!
	moveq	#%00000100,d0		; Q3 von IC1 auf HIGH
	bra.s	2$
1$	moveq	#%00000010,d0		; Q2 von IC1 auf HIGH
2$	or.w	d0,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	rts


* DisableVEdit:
* schaltet die Edit-Spannung (+16.5V) an Pin 2 oder Pin 4 aus
* (abhänging vom eingestellten GAL-Typ)
* Aufruf: DisableVEdit();
_DisableVEdit:
	move.w	#IC1,-(sp)		; IC1 einstellen
	cmp.w	#GAL16V8,_GALType	; 16V8 eingestellt?
	bne.s	1$			; nein, dann wird 20V8 angenommen!
	move.w	#%11111011,d0		; Q3 von IC1 auf LOW
	bra.s	2$
1$	move.w	#%11111101,d0		; Q2 von IC1 auf low
2$	and.w	d0,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	rts




* LED:
* schaltet die LED aus bzw. an
* Aufruf: LED(ON/OFF);
_LED:
	cmp.w	#ON,4(sp)
	bne.s	2$
	or.w	#%01000000,_outIC1
	bra.s	1$
2$	and.w	#%10111111,_outIC1
1$	move.w	#IC1,-(sp)
	move.w	_outIC1,-(sp)
	bsr	_WriteByte		; IC1 setzen
	addq.l	#4,sp			; Stack korrigieren
	rts



* EnableVcc:
* schaltet die Spannungsversorgung ein; siehe auch DisableVcc
* bei GAL16V8: Pin22 vom Textool-Sockel
* bei GAL20V8: Pin24 vom Textool-Sockel
* Aufruf: EnableVcc();
_EnableVcc:
	movem.l	d0-d7/a0-a6,savereg	; Register retten
	move.l	#300000,-(sp)		; 300 ms warten
	jsr	_WaitForTimer		; 
	addq.l	#4,sp
	movem.l	savereg,d0-d7/a0-a6

	move.w	#IC1,-(sp)		; IC1 selektieren
	cmp.w	#GAL16V8,_GALType	; 16V8 eingestellt?
	bne.s	1$			; nein, dann wird 20V8 angenommen!!!
	moveq	#%00011000,d0		; Q4,5 von IC1 auf HIGH=>+5V an Pin22
	bra.s	2$
1$	moveq	#%00010000,d0		; Q5 auf HIGH => +5V an Pin 24	
2$	or.w	d0,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte		; IC1 setzen
	addq.l	#4,sp			; Stack korrigieren
	rts

* DisableVcc:
* schaltet die Spannungsversorgung aus; siehe auch EnableVcc
* bei GAL16V8: Pin22 vom Textool-Sockel
* bei GAL20V8: Pin24 vom Textool-Sockel
* Aufruf: DisableVcc();
_DisableVcc:
	movem.l	d0-d7/a0-a6,savereg	; Register retten
	move.l	#50000,-(sp)		; sicherheitshalber 50mS warten, bis
	jsr	_WaitForTimer		; das GAL die letzte Aktion richtig
	addq.l	#4,sp			; verdaut hat
	movem.l	savereg,d0-d7/a0-a6

	move.w	#IC1,-(sp)		; IC1 selektieren
	cmp.w	#GAL16V8,_GALType	; 16V8 eingestellt?
	bne.s	1$			; nein, dann wird 20V8 angenommen!!!
	move.w	#%11100111,d0		; Q4,5 von IC1 auf LOW
	bra.s	2$
1$	move.w	#%11101111,d0		; Q5 auf HIGH
2$	and.w	d0,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte		; IC1 setzen
	addq.l	#4,sp			; Stack korrigieren
	rts



* EnableOutput:
* OutputEnable-Eingang (OE) von IC3, IC4, IC5 auf HIGH
* Aufruf: EnableOutput();
_EnableOutput:
	move.w	#IC1,-(sp)
	or.w	#%00100000,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	rts

* DisableOutput:
* OutputEnable-Eingang (OE) von IC3, IC4, IC5 auf LOW
* Aufruf: DisableOutput();
_DisableOutput:
	move.w	#IC1,-(sp)
	and.w	#%11011111,_outIC1
	move.w	_outIC1,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	rts



* ReadByte:
* lese ein Byte aus dem IC "ICx", wobei ICx=IC6 (nur ein Bit) oder IC7 ist
* Aufruf: byte=ReadByte(IC);
* PD3 ist bereits HIGH (muß es auch!, siehe _InitGAL und Beschreibung zu PD3)
_ReadByte:
	clr.w	d0
	cmp.w	#IC6,4(sp)		; IC6 angesprochen?
	bne.s	IC7$			; nein, dann IC7$
	or.b	#%00000001,ciaaprb	; PD0 auf HIGH=>HIGH am Clk vom IC7
					; PD0 auf HIGH setzen=>IC6a selektiert

	movem.l	d0-d7/a0-a6,savereg	; Register retten
	move.l	#1,-(sp)		; 1 us warten
	jsr	_WaitForTimer		; erlaubt ist
	addq.l	#4,sp
	movem.l	savereg,d0-d7/a0-a6

	move.b	ciabpra,d0
	not.b	d0			; invertieren
	and.b	#%00000001,d0		; BUSY-Bit ausmaskieren
	bra.s	ready$			; Pin22 (über IC6) ist ausgelesen
IC7$

	and.b	#%11111110,ciaaprb	; PD3 ist HIGH=>Lesen möglich
	nop
	or.b	#%00000100,ciaaprb	; PD2 (Strobe) auf HIGH-> Daten werden
	and.b	#%11111011,ciaaprb	; vom Eingangsreg. in das Schiebereg.
					; übernommen. Dann PD2 wieder auf LOW.
					; PD3 ist auf HIGH=>Lesen ist möglich

	moveq	#7,d2			; Schleifenzähler
l$	rol.b	#1,d0
	move.b	ciabpra,d1		; BUSY-Bit holen
	and.b	#%00000001,d1		; BUSY-Bit ausmaskieren
	or.b	d1,d0			; BUSY-Bit in D0 eintragen
	and.b	#%11111110,ciaaprb	; PD0 auf LOW=>LOW am Clk-Eingang (IC7)
	or.b	#%00000001,ciaaprb	; PD0 auf HIGH=>HIGH am Clk-Eingang
					; ==> nächstes Bit steht am Ausgang
	nop
	nop
	and.b	#%11111110,ciaaprb	; PD0 auf LOW=>IC6b ist selektiert (=>lesen möglich)
	dbf	d2,l$			; 8 Bits auslesen
	not.b	d0			; invertieren
ready$	rts				; D0=Rückgabewert (gelesenes Byte)



* WriteByte:
* schreibt das Byte "byte" in das IC "IC", wobei IC=IC1, IC3, IC4 oder IC5
* sein kann
* zuerst wird das MSB übertragen!!!
* Aufruf: WriteByte(byte,IC)
_WriteByte:
	movem.l	d0-d3,savereg		; Register retten
	move.w	4(sp),d0		; Datenbyte nach D0
	move.w	6(sp),d1		; IC nach D1
				; geschriebenes Byte mitprotokolieren
	cmp.w	#IC1,d1
	bne.s	1$
	move.w	d0,_outIC1
	bra.s	cont$
1$	cmp.w	#IC3,d1
	bne.s	2$
	move.w	d0,_outIC3
	bra.s	cont$
2$	cmp.w	#IC4,d1
	bne.s	3$
	move.w	d0,_outIC4
	bra.s	cont$
3$	move.w	d0,_outIC5
cont$

	and.b	#%11111100,ciaaprb	; PD0 und PD1 setzen (IC aus-
	or.b	d1,ciaaprb		; wählen)
	and.b	#%11110111,ciaaprb	; Adressdecoder aktivieren

	moveq	#7,d3			; Schleifenzähler
	ror.b	#3,d0			; MSB nach D4 (Datenleitung)
loop$	move.b	d0,d2			; Datenbyte sichern
	and.b	#%00010000,d2		; Datenbit ausmaskieren
	or.b	d2,ciaaprb		; Datenbit (PD4) vom Par.-Port setzen

	or.b	#%00001000,ciaaprb	; Clock-Impuls durch PD3 geben
	and.b	#%11110111,ciaaprb	; LOW-HIGH Übergang

	and.b	#%11101111,ciaaprb	; Datenbit (PD4) auf LOW

	rol.b	#1,d0			; nächstniedrigeres Bit senden
	dbf	d3,loop$

	or.b	#%00001000,ciaaprb	; Adressdecoder wieder deaktivieren!!!
					; (sehr WICHTIG, siehe _InitGAL:)
	or.b	#%00000100,ciaaprb	; PD2 (Strobe) auf HIGH-> Daten werden
	and.b	#%11111011,ciaaprb	; vom Schieberegister in das Datenreg.
					; übernommen. Dann PD2 wieder auf LOW.
	movem.l	savereg,d0-d3
	rts


* SetRow:
* Adresse an RAG0-RAG5 anlegen
* Aufruf: SetRow(row);
* row:	  zu adressierende Zeile (0-63)
_SetRow:

				    ; RAG5 setzen (Pin bei 16 und 20V8 gleich)
	move.w	4(sp),d0		; row holen
	and.w	#$fe,_outIC5		; Bit0(=RAG5) löschen
	asr.b	#5,d0			; Bit0 von D0=RAG5
	or.w	d0,_outIC5		; RAG5=Bit von D0=> RAG5 gesetzt

	cmp.w	#GAL16V8,_GALType	; GAL16V8?
	bne.s	GAL20V8$		; nein, dann GAL20V8 annehmen
GAL16V8$			    ; RAG0 setzen
	move.w	4(sp),d0		; row holen
	and.w	#$ef,_outIC3		; Bit4(=RAG0) löschen
	and.w	#1,d0			; Bit0 von "row" ausmaskieren
	asl.b	#4,d0
	or.w	d0,_outIC3		; Bit4(=RAG0) setzen
				    ; RAG1-RAG4 setzen
	move.w	4(sp),d0		; row holen
	and.w	#$0f,_outIC4		; Bit4-7(=RAG1-RAG4) löschen
	and.w	#%00011110,d0		; Bit1-4 von "row" ausmaskieren
	asl.w	#3,d0			; an Bit4-7 schieben
	or.w	d0,_outIC4		; RAG1-RAG4 setzen
	bra.s	write$
GAL20V8$			    ; RAG0 für GAL20V8 setzen
 	move.w	4(sp),d0		; row holen
	and.w	#%11011111,_outIC3	; Bit5(=RAG0) löschen
	and.w	#1,d0			; Bit0 von "row" ausmaskieren
	asl.b	#5,d0
	or.w	d0,_outIC3		; Bit5(=RAG0) setzen
				    ; RAG4 setzen
	move.w	4(sp),d0		; row holen
	and.w	#%01111111,_outIC4	; Bit7(=RAG4) löschen
	and.w	#%00010000,d0		; Bit4 von "row" ausmaskieren
	asl.w	#3,d0
	or.w	d0,_outIC4		; Bit7(=RAG4) setzen
				    ; RAG1-RAG3 setzen
	move.w	4(sp),d0		; row holen
	and.w	#%11100011,_outIC4	; Bit2-4(=RAG1-RAG3) löschen
	and.w	#%00001110,d0		; Bit1-3 aus "row" ausmaskieren
	asl.w	#1,d0
	or.w	d0,_outIC4		; RAG1-RAG3 setzen

write$				    ; errechnete Werte in ICs schreiben
	move.w	#IC3,-(sp)
	move.w	_outIC3,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	move.w	#IC4,-(sp)
	move.w	_outIC4,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp

;	movem.l	d0-d7/a0-a6,savereg	; Register retten
;	move.l	#5,-(sp)		; 5 us warten bevor nächste Aktion
;	jsr	_WaitForTimer		; erlaubt ist
;	addq.l	#4,sp
;	movem.l	savereg,d0-d7/a0-a6

	rts



* SDIn:
* lege ein Bit an den SDIn-Eingang (Pin 11 vom Textool-Sockel)
* Aufruf: SDIn(bit);    bit: 0=LOW; 1=HIGH
_SDIn:
	move.w	4(sp),d0		; Bit holen
	asl.b	#2,d0			; an die richtige Stelle schieben
	and.w	#%11111011,_outIC5	; SDIn-Bit löschen
	or.w	d0,_outIC5		; Bit auf LOW oder HIGH setzen
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp
	rts


* SDOut:
* ein Bit aus dem SDOut-Ausgang lesen
* Pin 14 (GAL16V8), Pin 15 (GAL20V8) am Textool-Sockel
* Aufruf: bit=SDOut();
* bit: 0: SDOut-Pin ist LOW; 1: SDOut-Pin ist HIGH
_SDOut:
	move.w	#IC7,-(sp)		; ein Byte aus IC7 holen
	bsr	_ReadByte		; Bit0=Pin14, Bit1=Pin15
	addq.l	#2,sp
	cmp.w	#GAL16V8,_GALType	; GAL16V8 eingestellt?
	bne.s	1$			; nein, dann GAL20V8
	and.w	#1,d0			; Bit0 ausmaskieren
	bra.s	2$			; D0=Bit
				    ; GAL20V8
1$	asr.w	#1,d0			; SDOut-Bit an Bit-Pos. 0
	and.w	#1,d0
2$
	rts




* Clock:
* erzeuge Clock-Impuls (Low-High-Low-Übergang) am SCLK-Eingang (Pin 10
* vom Textool-Sockel
* Aufruf: Clock();
_Clock:
	movem.l	d0-d7/a0-a6,savereg	; Register retten

	or.w	#%00000010,_outIC5	; SCLK-Bit auf HIGH
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.w	#4,sp

;	move.l	#5,-(sp)		; 5 uS High-Impuls
;	jsr	_WaitForTimer
;	addq.l	#4,sp

	and.w	#%11111101,_outIC5	; SCLK-Bit auf LOW
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.w	#4,sp

;	move.l	#5,-(sp)		; 5 us warten bevor nächste Aktion
;	jsr	_WaitForTimer		; erlaubt ist
;	addq.l	#4,sp
	movem.l	savereg,d0-d7/a0-a6
	rts



* STRImpuls:
* setzt /STR-Eingang (Pin 13 am Textool-Socker) für die Dauer von "STRLength"
* auf LOW
* Aufruf: STRImpuls(long STRLength);
* STRLength: Dauer des Low-Impulses in Mikrosekunden (Langwort!)
_STRImpuls:
	movem.l	d0-d7/a0-a6,savereg	; Register retten

	move.l	4,a6
	jsr	_LVOForbid(a6)

	and.w	#%11110111,_outIC5	; STR-Pin auf LOW
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp

	cmp.l	#100,4(sp)		; bis ein Wert in ein IC getaktet wird
	bls.s	1$			; vergehen ca. 100us => keinen Timer
	move.l	4(sp),-(sp)		; Dauer des Impulses in Mikrosekunden
	jsr	_WaitForTimer		; Low-Impuls
	addq.l	#4,sp			; Stack korrigieren
1$

	or.w	#%00001000,_outIC5	; STR-Pin wieder auf HIGH
	move.w	#IC5,-(sp)
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp

	jsr	_LVOPermit(a6)

;	move.l	#5,-(sp)		; 5 us warten bevor nächste Aktion
;	jsr	_WaitForTimer		; erlaubt ist
;	addq.l	#4,sp

	movem.l	savereg,d0-d7/a0-a6	; Registerinhalte zurückholen
	rts


* SetPV:
* Legt am P/V-Pin den entsprechenden Pegel für "Programmieren" bzw.
* "Verify" an.
* Aufruf:  SetPV(mode);
* mode :   VERIFY (lesen, P/V low), PROG (schreiben, P/V high)
_SetPV:
	move.w	4(sp),d0		; mode holen
	cmp.w	#GAL16V8,_GALType	; GAL16V8?
	bne.s	1$			; nein, dann 1$
	move.w	#IC3,-(sp)		; IC3 setzen
	move.w	_outIC3,d1
	and.w	#%11111011,d1
	asl.b	#5,d0			; Mode-Bit zu Bit 5 schieben
	or.w	d0,d1
	move.w	d1,-(sp)		; P/V setzen
	bsr	_WriteByte
	addq.l	#4,sp
	bra.s	2$
1$	
	move.w	#IC3,-(sp)		; IC3 setzen
	move.w	_outIC3,d1
	and.w	#%11111101,d1
	asl.b	#6,d0			; Mode-Bit zu Bit 6 schieben
	or.w	d0,d1
	move.w	d1,-(sp)		; P,/V-Bit setzen
	bsr	_WriteByte
	addq.l	#4,sp
2$
;	movem.l	d0-d7/a0-a6,savereg	; Register retten
;	move.l	#5,-(sp)		; 5 us warten bevor nächste Aktion
;	jsr	_WaitForTimer		; erlaubt ist
;	addq.l	#4,sp
;	movem.l	savereg,d0-d7/a0-a6

	rts




* Edit-Mode:
* schaltet das GAL in den Edit-Mode; /STR auf HIGH; P/V auf LOW
* Aufruf: EditMode(mode);
* mode: PROG oder VERIFY (für Spannungseinstellung)
_EditMode:
	movem.l	d0-d7/a0-a6,savereg	; Register sichern


				    ; GAL-Typ auswählen
	cmp.w	#GAL16V8,_GALType   ; GAL16V8?
	bne.s	1$			; nein, dann 1$

	move.w	#IC3,-(sp)		; IC3, P/V auf LOW
	move.w	#%00000000,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp

	move.w	#IC4,-(sp)
	move.w	#%00000000,-(sp)	; IC4 initialisieren
	bsr	_WriteByte
	addq.l	#4,sp

	move.w	#IC5,-(sp)		; /STR auf HIGH
	move.w	#%00011000,-(sp)	; IC5 initialisieren
	bsr	_WriteByte
	addq.l	#4,sp
	bra.s	2$
1$				    ; GAL20V8
	move.w	#IC3,-(sp)		; IC3, P/V auf LOW
	move.w	#%00000000,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp

	move.w	#IC4,-(sp)
	move.w	#%00000000,-(sp)	; IC4 initialisieren
	bsr	_WriteByte
	addq.l	#4,sp

	move.w	#IC5,-(sp)		; /STR auf HIGH
	move.w	#%00101000,-(sp)	; IC5 initialisieren
	bsr	_WriteByte
	addq.l	#4,sp
2$

				    ; richtige Spannung auswählen
	cmp.w	#VERIFY,4(sp)		; Lesen?
	bne.s	3$			; nein, dann Programmieren!
	move.w	#4,-(sp)		; ja, dann 12.00 Volt einstellen
	bsr	_SetVolt
	addq.l	#2,sp
	bra.s	4$
3$
	move.w	_prog_volt,-(sp)	; Programmierspannung einstellen
	bsr	_SetVolt
	addq.l	#2,sp
4$		


	bsr	_VeditOn		; Edit-Spannung aufbauen
	move.l	#50000,-(sp)		; 50 ms warten, bis sich die
	jsr	_WaitForTimer		; Edit-Spannung aufgebaut hat
	addq.l	#4,sp
	bsr	_EnableOutput		; Bits anlegen
	bsr	_EnableVcc		; Vcc anlegen
	move.l	#100000,-(sp)		; Prellzeit der Relais überbrücken
	jsr	_WaitForTimer
	addq.l	#4,sp
	bsr	_EnableVEdit		; Edit-Spannung anlegen
				    ; GAL befindet sich jetzt im Edit-Mode
	move.l	#5,-(sp)		; 5 us warten bevor nächste Aktion
	jsr	_WaitForTimer		; erlaubt ist
	addq.l	#4,sp
	movem.l	savereg,d0-d7/a0-a6	; Registerinhalte zurückholen
	rts


* ExitEditMode:
* Schaltet zuerst VEdit und VCC ab, dann wird der Inhalt der ICs
* zurückgesetzt.
* Aufruf: ExitEditMode();
_ExitEditMode:
	movem.l	d0-d7/a0-a6,savereg	; Register sichern
	bsr	_DisableVEdit
	bsr	_DisableVcc
	bsr	_InitGALer
	bsr	_EnableOutput
	movem.l	savereg,d0-d7/a0-a6
	rts



* SetVolt:
* selektiert durch IC 10 und IC11 die gewünschte Spannung
* Aufruf: SetVolt(value);
* value:  0=16.50 Volt; 1=15.75 Volt; 2=14.5 Volt; 3=14.00 Volt; 4=12.00 Volt
*
_SetVolt:

	move.w	4(sp),d0		; Wert holen
	move.w	d0,d1			; Wert sichern

	move.w	#IC1,-(sp)
	and.w	#%00000001,d1
	rol.w	#7,d1
	and.w	#%01111111,_outIC1
	or.w	d1,_outIC1		; Q8 (Pin 11) von IC1 setzen
	move.w	_outIC1,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp			; Stack korrigieren

	move.w	#IC5,-(sp)
	and.w	#%00000110,d0
	rol.w	#5,d0
	and.w	#%00111111,_outIC5
	or.w	d0,_outIC5		; Q7 und Q8 von IC5 setzen
	move.w	_outIC5,-(sp)
	bsr	_WriteByte
	addq.l	#4,sp			; Stack korrigieren

	rts




	dseg

; Zwischenspeicher, um Register zu retten ohne den Stack zu benützen
savereg:	ds.l	15		; 8 Datenregister, 7 Adressregister

_outIC1:	dc.w	0
_outIC3:	dc.w	0
_outIC4:	dc.w	0
_outIC5:	dc.w	0
_GALType:	dc.w	0

cia_addrb:	dc.b	0
cia_bddra:	dc.b	0

	END
