;	TERMA.M		Assembly routines for TERM.C
;			SIO interrupt processing
;	08 Jan 1988	A.Herrmann

	.Z80

; SERVICE is the outer "shell" around the C interrupt service routine intsvc.
; It saves all registers and calls intsvc. (Remember that further interrupts
; are automatically disabled.)
; Upon return from intsvc, SERVICE restores the registers and reenables 
; interrupts.

SERVICE::
	PUSH AF
	PUSH BC
	PUSH DE
	PUSH HL
	PUSH IX
	PUSH IY
	LD HL,2		;invoke C function
	CALL INTSVC##	;(external)
	POP IY
	POP IX
	POP HL
	POP DE
	POP BC
	POP AF
	EI
	RETI


; SWAPVEC swaps the old and new interrupt vector in the BIOS.
; It is called as an ECO C-function whose equivalent is the following:

;	void swapvec(old,new,adr)
;	int (**old)(), (*new)(), (**adr)();
;	{
;		register (**temp)();
;
;		temp = *adr;
;		*adr = new;
;		*old = temp;
;	}

; Unfortunately, interrupts must be disabled during this
; which can't be done in C. That's why we need the assembly routine.
; Note: SWAPVEC uses the external code at $RTNV## to return a void value;
; 	this is a distinct feature of the ECO-C compiler.


SWAPVEC::
	ADD HL,SP	;administration for function entry
	PUSH HL
	LD IX,4
	ADD IX,SP
	LD L,(IX+0)	;*old
	LD H,(IX+1)
	LD C,(IX+2)	;new
	LD B,(IX+3)
	LD E,(IX+4)	;*adr (=vector table address)
	LD D,(IX+5)
	PUSH DE
	POP IY
	DI		;disable interrupts while swapping vectors
	LD E,(IY+0)	;current vector
	LD D,(IY+1)
	LD (IY+0),C	;new vector
	LD (IY+1),B
	EI
	LD (HL),E	;put old vector back
	INC HL
	LD (HL),D
	JP $RTNV##	;return void (external)


	END
