From 4b80c3537d2bef017cc32077598077609c0c10bd Mon Sep 17 00:00:00 2001
From: izydorst <izydorst@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Date: Wed, 25 Dec 2002 03:27:50 +0000
Subject: [PATCH] removed jmpvec in favor of callax function

git-svn-id: svn://svn.cc65.org/cc65/trunk@1841 b7a2c559-68d2-44c3-8de9-860c34a00d81
---
 libsrc/geos/common/Makefile  |  2 +-
 libsrc/geos/common/_sys.s    | 79 ++++++++++++++++++++++++++++++
 libsrc/geos/common/atexit.s  | 81 +++++++++++++++++++++++++++++++
 libsrc/geos/runtime/Makefile |  2 +-
 libsrc/geos/runtime/condes.s | 93 ++++++++++++++++++++++++++++++++++++
 5 files changed, 255 insertions(+), 2 deletions(-)
 create mode 100644 libsrc/geos/common/_sys.s
 create mode 100644 libsrc/geos/common/atexit.s
 create mode 100644 libsrc/geos/runtime/condes.s

diff --git a/libsrc/geos/common/Makefile b/libsrc/geos/common/Makefile
index 575d4e1c1..af76a2cbc 100644
--- a/libsrc/geos/common/Makefile
+++ b/libsrc/geos/common/Makefile
@@ -11,7 +11,7 @@
 	@$(AS) -o $@ $(AFLAGS) $<
 
 C_OBJS	= _afailed.o abort.o perror.o
-S_OBJS	= copydata.o memcpy.o memset.o zerobss.o
+S_OBJS	= _sys.o atexit.o copydata.o memcpy.o memset.o zerobss.o
 
 all: $(C_OBJS) $(S_OBJS)
 
diff --git a/libsrc/geos/common/_sys.s b/libsrc/geos/common/_sys.s
new file mode 100644
index 000000000..e365315b5
--- /dev/null
+++ b/libsrc/geos/common/_sys.s
@@ -0,0 +1,79 @@
+;
+; void __fastcall__ _sys (struct regs* r);
+;
+; Ullrich von Bassewitz, 16.12.1998
+;
+;
+; The function could also export jmpvec as general purpose jump vector that
+; lies in the data segment so it's address may be patched at runtime.
+;
+
+  	.export		__sys
+	.importzp	ptr1
+
+
+__sys:	sta	ptr1
+	stx	ptr1+1	      	; Save the pointer to r
+
+; Fetch the PC and store it into the jump vector
+
+	ldy	#5
+	lda	(ptr1),y
+	sta	jmpvec+2
+	dey	
+	lda	(ptr1),y
+	sta	jmpvec+1
+
+; Get the flags, mask unnecessary bits and push them. Push a
+
+	dey
+	lda	(ptr1),y
+	and	#%11001011
+	pha
+	ldy	#0
+	lda	(ptr1),y
+	pha
+
+; Get and assign X and Y
+
+	iny
+	lda	(ptr1),y
+	tay
+	iny
+	lda	(ptr1),y
+	tay
+
+; Set a and the flags, call the machine code routine
+
+	pla
+	plp
+	jsr	jmpvec
+
+; Back from the routine. Save the flags and a
+
+	php
+	pha
+
+; Put the register values into the regs structure
+
+	tya
+	ldy	#2
+	sta	(ptr1),y
+	dey
+	txa
+	sta	(ptr1),y
+	dey
+	pla
+	sta	(ptr1),y
+	ldy	#3
+	pla
+	sta	(ptr1),y
+
+; Done
+
+	rts
+
+.data
+
+jmpvec:	jmp	$FFFF
+
diff --git a/libsrc/geos/common/atexit.s b/libsrc/geos/common/atexit.s
new file mode 100644
index 000000000..6852537e3
--- /dev/null
+++ b/libsrc/geos/common/atexit.s
@@ -0,0 +1,81 @@
+;
+; Ullrich von Bassewitz, 06.06.1998
+;
+; int atexit (void (*f) (void));
+;
+
+      	.export		_atexit
+       	.destructor	doatexit, 5
+	.import		__errno
+ 	.import	 	callax
+
+	.include	"errno.inc"
+
+; ---------------------------------------------------------------------------
+
+.proc	_atexit
+
+	ldy	exitfunc_index
+       	cpy    	#exitfunc_max		; Slot available?
+       	beq    	@Error			; Jump if no
+
+; Enter the function into the table
+
+	sta	exitfunc_table,y
+	iny
+	txa
+	sta	exitfunc_table,y
+	iny
+	sty	exitfunc_index
+
+; Done, return zero
+
+	lda	#0
+	tax
+	rts
+
+; Error, no space left
+
+@Error:	lda	#ENOSPC	      	; No space left
+      	sta	__errno
+      	ldx	#$00
+      	stx	__errno+1
+      	dex			; Make return value -1
+      	txa
+      	rts
+
+.endproc
+
+
+
+; ---------------------------------------------------------------------------
+
+.code
+
+.proc	doatexit
+
+       	ldy    	exitfunc_index		; Get index
+       	beq    	@L9	 		; Jump if done
+ 	dey
+ 	lda	exitfunc_table,y
+   	tax
+   	dey
+   	lda	exitfunc_table,y
+   	sty	exitfunc_index
+ 	jsr	callax			; Call the function (A/X)
+ 	jmp	doatexit     		; Next one
+
+@L9:	rts
+
+.endproc
+
+
+
+; ---------------------------------------------------------------------------
+
+.bss
+exitfunc_index:	.res	1	; Index into table, inc'ed by 2
+exitfunc_table:	.res	10	; 5 exit functions
+exitfunc_max	= <(* - exitfunc_table)
+
+
diff --git a/libsrc/geos/runtime/Makefile b/libsrc/geos/runtime/Makefile
index a3b1fd99a..ea0a2e087 100644
--- a/libsrc/geos/runtime/Makefile
+++ b/libsrc/geos/runtime/Makefile
@@ -11,7 +11,7 @@
 	@$(AS) -o $@ $(AFLAGS) $<
 
 C_OBJS	=
-S_OBJS	= call.o
+S_OBJS	= call.o condes.o
 
 all: $(C_OBJS) $(S_OBJS)
 
diff --git a/libsrc/geos/runtime/condes.s b/libsrc/geos/runtime/condes.s
new file mode 100644
index 000000000..82bac9e40
--- /dev/null
+++ b/libsrc/geos/runtime/condes.s
@@ -0,0 +1,93 @@
+;
+; Ullrich von Bassewitz, 20.11.2000
+;
+; CC65 runtime: Support for calling module constructors/destructors
+;
+; The condes routine must be called with the table address in a/x and the
+; size of the table in y. The current implementation limits the table size
+; to 254 bytes (127 vectors) but this shouldn't be problem for now and may
+; be changed later.
+;
+; libinit and libdone call condes with the predefined module constructor and
+; destructor tables, they must be called from the platform specific startup
+; code.
+
+       	.export	initlib, donelib, condes
+
+       	.import	__CONSTRUCTOR_TABLE__, __CONSTRUCTOR_COUNT__
+	.import	__DESTRUCTOR_TABLE__, __DESTRUCTOR_COUNT__
+	.import callax
+
+
+.code
+
+; --------------------------------------------------------------------------
+; Initialize library modules
+
+.proc	initlib
+
+	lda    	#<__CONSTRUCTOR_TABLE__
+	ldx    	#>__CONSTRUCTOR_TABLE__
+	ldy    	#<(__CONSTRUCTOR_COUNT__*2)
+	bne    	condes
+	rts
+
+.endproc
+
+
+; --------------------------------------------------------------------------
+; Cleanup library modules
+
+.proc	donelib
+
+	lda 	#<__DESTRUCTOR_TABLE__
+	ldx 	#>__DESTRUCTOR_TABLE__
+	ldy 	#<(__DESTRUCTOR_COUNT__*2)
+	bne 	condes
+	rts
+
+.endproc
+
+
+; --------------------------------------------------------------------------
+; Generic table call handler
+
+.proc	condes
+
+	sta   	getbyt+1
+	stx	getbyt+2
+	sty	index
+
+loop:	ldy	index
+     	beq	done
+	dey
+	jsr	getbyt
+	tax
+	dey
+	jsr	getbyt
+	sty	index
+	jsr	callax			; call function in A/X
+.ifpc02
+	bra	loop
+.else
+     	jmp	loop
+.endif
+
+done:	rts
+
+.endproc
+
+
+; --------------------------------------------------------------------------
+; Data. The getbyte routine is placed in the data segment cause it's patched
+; at runtime.
+
+.bss
+
+index:	.byte	0
+
+.data
+
+getbyt:	lda	$FFFF,y		; may not change X!
+	rts
+	rts		;!!! this byte will be lost (od65 can't even dump this .o)