Setjmp/longjmp
This message turned up in search, but its forum couldn’t be identified from the original transcript, so it may not be linked into its thread.
Here is the code for setjmp and longjmp that you had to rip out of
your program. Do you have the macro assembler? If not I can
assemble them and upload the .o files so they will be linkable.
In the C program: have
typedef int jmp_buf[13];
call with:
setjmp(environ); where environ is declared as a jmp_buf;
and
longjmp(environ,value); value is the value to be returned to the
caller of setjmp. An integer;
Assembler:
RORG 0
XDEF _setjmp
XDEF _longjmp
_setjmp: movea.l (sp)+,a1
movea.l (sp),a0
movem.l sp-a1/d7-d2,(a0)
moveq.l #0,d0
jmp (a1)
_longjmp: movea.l 4(sp),a0
move.l 8(sp),d0
movem.l (a0),sp-a1/d7-d2
jmp (a1)
END
That's it. Just assemble and link with the C code. The code for
alarm() wouldn't be much use because it traps into unix kernel code.
someone will have to come up with something else, an amiga anology.
GARY
Functions:
B – bulletins CO – conference
D – delete DL – data libraries
E – exit G x- go to page x
I – instructions
L – leave a message
M – previous menu
MI – membership information
NEW- new/changes
OFF- log off OP – set options
QS – quick scan R – read messages
R x- run SIG x RT – read thread
S – scan headers
SD – scan & display
SEN- send a message
SN – sub-topic names
SS – set sub-topic
T – go DISPLA U – user log
UST- current users
V – interests X – database
? x – explanation of function x
[70003,2443]
QSORT.ASM 12-Dec-85 8800 4
Keywords: ASSEMBLER UNIX QSORT
An implementation of the Unix ™ qsort() facility callable from assembler
or C. See QTEST.C for an example of how to use this. This file was
provided by Gary Sarff.
(R D T): rea
RORG 0
XDEF _qsort
* The qsort algorithm implemented in 68000 assembler.
* This routine implements the quick sort for any arbitrary data array of
* any arbitrary size. The sort is "in-place" in the array, no temporary
* space is needed aside from a little stack space. I have tried to keep
* this as close to the Unix conventions of qsort as possible. I don't
* think there are any bugs, but who knows.
* Gary Sarff 12/07/85 Compuserve PPN 70167,2216
*
* Calling convention/declaration from Lattice C programs is:
*
* void qsort((char *)base,nel,sizeof (*base),compar)
* unsigned int nel;
* int (*compar)();
*
* base points to the base element of the table to be sorted.
* nel is the number of elements in the table.
* compar is the name of the comparison function, which is called with two
* arguments that point to the elements being compared. The function
* must return an integer less than, equal to, or greater than zero
* according as the first argument is to be considered less than, equal to,
* or greater than the second.
* for example:
* suppose array is declared as:
* struct junk { int xpart;
* int ypart;
* char *message[20];
* } *array[10];
* Then array points to the first of ten identical structures like junk.
* say if we want to sort the array on the xpart then call qsort like:
* qsort((char *)array,10,sizeof(*array),compar);
* you should find sizeof(*array) to be 24 since array is a pointer to
* something of type junk and each thing is 24 bytes long.
*
* Notes: The pointer to the base table should be of type
* pointer-to-element, and cast to type pointer-to-character. The comparison
* function need not compare every byte, so arbitrary data may be contained in
* the elements in addition to the values being compared. In this case only
* compare the xparts of the two values passed (see below).
* Although declared as pointer-to-character, the value returned should be
* cast into type pointer-to-element.
*
* the compar function should be declared as (of course use any name you
* want as long as you pass the name to qsort.)
*
* int compar(first,second)
* and declare first and second as type pointer-to-element. They must be
* declared this way, not as pointer to char or something else, so then you
* can say:
* if (first->xpart < second->xpart) return (-1);
* if (first->xpart == second->xpart) return 0;
* if (first->xpart > second->xpart) return 1;
*
*————————————————————————–
*
_qsort:
link a6,#-4
move.l 20(a6),cmpaddr
move.l 16(a6),nel
move.l 16(a6),(sp)
move.l 12(a6),-(sp)
bsr.l unsgmul * multiply nel by sizeof elements
addq.l #4,sp
add.l 8(a6),d0
move.l d0,(sp)
move.l 8(a6),-(sp)
bsr.s qcont
unlk a6
rts
qcont:
link a6,#-4
movem.l d0/d5-d7/a2/a4-a5,-(sp)
move.l nel,d7
QL0:
move.l 12(a6),d0
sub.l 8(a6),d0
move.l d0,d5
cmp.l d7,d0
bls.l done1
move.l d7,d0
add.l d0,d0
move.l d0,(sp)
move.l d5,-(sp)
bsr.l unsgdiv
addq.l #4,sp
move.l d0,(sp)
move.l d7,-(sp)
bsr.l unsgmul
addq.l #4,sp
move.l d0,d5
move.l 8(a6),d0
add.l d5,d0
movea.l d0,a2
move.l a2,-4(a6)
movea.l 8(a6),a5
move.l 12(a6),d0
sub.l d7,d0
movea.l d0,a4
bra.s compout
comploop:
suba.l d7,a2
move.l a2,(sp)
move.l a5,-(sp)
bsr.l auxfunc
addq.l #4,sp
bra.s compout
complt:
move.l a2,(sp)
move.l a5,-(sp)
movea.l cmpaddr,a0
jsr (a0) * call the user provided compar function
addq.l #4,sp
move.l d0,d6
beq.s comploop
tst.l d6
bge.s compge
QL1: adda.l d7,a5
compout:
cmpa.l a2,a5
bcs.s complt
bra.s compge
move.l a4,(sp)
add.l d7,-4(a6)
move.l -4(a6),-(sp)
bsr.l auxfunc
addq.l #4,sp
bra.s compge
qloop1:
move.l a4,(sp)
add.l d7,-4(a6)
move.l -4(a6),-(sp)
move.l a5,-(sp)
bsr.l qdone
addq.l #8,sp
adda.l d7,a2
movea.l a2,a5
bra.s compge
QL2:
move.l a4,(sp)
move.l -4(a6),-(sp)
movea.l cmpaddr,a0
jsr (a0)
addq.l #4,sp
move.l d0,d6
beq.s compout
tst.l d6
ble.s seege
cmpa.l a2,a5
beq.s qloop1 * see if we have reached end of table
move.l a4,(sp)
move.l a5,-(sp)
bsr.l auxfunc
addq.l #4,sp
suba.l d7,a4
bra.s QL1
seege: suba.l d7,a4
compge:
cmpa.l -4(a6),a4
bhi.s QL2
cmpa.l a2,a5
bne QL3
move.l a2,d0
sub.l 8(a6),d0
move.l 12(a6),d1
sub.l -4(a6),d1
cmp.l d1,d0
blt.s QL4
move.l 12(a6),(sp)
move.l -4(a6),d0
add.l d7,d0
move.l d0,-(sp)
bsr.l qcont * recursive call with partition of table
addq.l #4,sp
move.l a2,12(a6)
bra.l QL0
QL4:
move.l a2,(sp)
move.l 8(a6),-(sp)
bsr.l qcont * recursive call with rest of table.
addq.l #4,sp
move.l -4(a6),d0
add.l d7,d0
move.l d0,8(a6)
bra.l QL0
QL3:
move.l a5,(sp)
suba.l d7,a2
move.l a2,-(sp)
move.l a4,-(sp)
bsr.s qdone
addq.l #8,sp
sub.l d7,-4(a6)
movea.l -4(a6),a4
bra.l compout
done1:
addq.l #4,sp
movem.l (sp)+,a5-a4/a2/d7-d5
unlk a6
rts
auxfunc:
link a6,#0
movem.l d6-d7/a4-a5,-(sp)
move.l nel,d6
movea.l 8(a6),a5
movea.l 12(a6),a4
moveloop:
move.b (a5),d7
move.b (a4),(a5)+
move.b d7,(a4)+
subq.l #1,d6
bne.s moveloop
movem.l (sp)+,a5-a4/d7-d6
unlk a6
rts
qdone:
link a6,#0
movem.l d6-d7/a3-a5,-(sp)
move.l nel,d6
movea.l 8(a6),a5
movea.l 12(a6),a4
movea.l 16(a6),a3
pivloop:
move.b (a5),d0
ext.w d0
ext.l d0
move.l d0,d7
move.b (a3),(a5)+
move.b (a4),(a3)+
move.b d7,(a4)+
subq.l #1,d6
bne.s pivloop
movem.l (sp)+,a5-a3/d7-d6
unlk a6
rts
CNOP 0,4
cmpaddr: DC.L 0
nel: DC.L 0
*
* support routines to do unsigned multiplication and division
*
unsgmul:
lea 4(sp),a0
move.w (a0)+,d0
move.l 8(sp),d1
mulu d1,d0
swap d1
mulu (a0),d1
add.w d1,d0
swap d0
clr.w d0
move.w (a0),d1
mulu 10(sp),d1
add.l d1,d0
move.l d0,-2(a0)
rts
unsgdiv:
lea 4(sp),a0
movem.l d2-d3,-(sp)
move.l (a0),d0
move.l d0,d2
move.l 16(sp),d1
move.l d1,d3
cmpi.l #$10000,d1
bge.s adjust
clr.w d0
swap d0
divu d1,d0
move.w d0,d3
move.w d2,d0
divu d1,d0
swap d0
move.w d3,d0
swap d0
bra.s fini
adjust:
lsr.l #1,d0
lsr.l #1,d1
cmpi.l #$10000,d1
bge.s adjust
divu d1,d0
andi.l #$FFFF,d0
move.l d3,d1
swap d1
mulu d0,d1
swap d1
clr.w d1
mulu d0,d3
add.l d3,d1
cmp.l d1,d2
bge.s fini
subq.l #1,d0
fini:
move.l d0,(a0)
movem.l (sp)+,d3-d2
rts
[70003,2443]
QTEST.C 12-Dec-85 1300 3
Keywords: QTEST C
This is a test program to demonstrate the use of QSORT.ASM. Provided by
Gary Sarff.
(R D T): rea
/*
A program to test the qsort "quick-sort" procedure called from Lattice
Gary Sarff 12/07/85 Compuserve PPN: 70167,2216
Compile this program with something similar to
copy qtest.c to ram:
copy qsort.o to ram:
:c/lc1 -i:include/ -i:include/lattice/ ram:qtest
:c/lc2 ram:qtest
:c/alink :lib/lstartup.obj,ram:test.o,ram:qsort.o library
:lib/lc.lib,:lib/amiga.lib to ram:test map nil:
when you run qtest it should produce
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Sorting…
Finished
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*/
#include <stdio.h>
extern qsort();
int array[] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; /* test array */
int compfunc(first,second)
int *second,*first;
{
if ((*first) < (*second)) return(-1);
else
if ((*first) == (*second)) return 0;
else
if ((*first) > (*second)) return 1;
}
main()
{
int i;
unsigned int arsize;
arsize=sizeof(array)/sizeof(int);
for (i=0;i < arsize; i++)
printf("%d ",array[i]);
printf("\nSorting…\n");
qsort(&array[0],arsize,sizeof(int),compfunc);
printf("finished\n");
for (i=0;i < arsize; i++)
printf("%d ",array[i]);
printf("\n");
}