Insert sortAssembler/MC68020

Here is a gem describing Insert sort. It is designed for the Motorola CPU series. The original text was written by Carl-Henrik Skårstedt (this mail address is very likely to be out of date). If found this text on the Internet and it originally comes from something called How To Code. I do not have the original archive so I do not know about any copyright notices. However, only parts of the origial article was used.
The code was written for the Amiga, but I think that it will work on any MC68k CPU (with some modifications as noted in the text below). I have removed and reorganized parts of the text. It still does not cover the algorithm completely, but it's easy to find a text on the Internet.

To do this, you have to select a wordlength for the sorting-table (checklist) and a size of the checklist.
The wordlength depends on the number of entries you have, and the size of every entry. Normally, it's convienient to use WORDS. The size of the checklist is the range of values to sort. If you, for example, know that your values lies within 512-1023 you can first decrease every z-value by 512, and then lsr' it once, which will give you a checklist size of 256 words.
You will also need a second buffer to put your sorted data in, this 2ndBUF will be like a copy of the original list but with the entries sorted.
For this method I only present an algorithm, it's easier to see how it works from that than from some strange text.

Algorithm:Now, your data is nicely sorted in the list 2ndBUF, the original list is left as it was. (ENTRYSIZE is the size of the entry, so if you have x,y,z coordinates in words, your size is 3 words=6 bytes.)
* it begins with creating a list and then stores the ADDRESSES of the
* sorted data in 2ndBUF.
* This sorts all lists, just specify offset to weight (word) and
* size of each entry. You don't need any pre-formatting.
* note that you HAVE TO change a line if you want this to work
* on 68000.. I've got a scaled index at one point. replace it
* with the lines after the semicolon.
*    __   .
*  /( |( )|\/ '(|)
* /  )|(|\|/\   |)

WghtOffs=4
EntrySize=6

InsertSort
                ;(a5=start of data
                ; a4=start of checklist
                ; a3=start of 2ndBUF
                ; d0 is lowest value of entries
                ; d1 is highest value
                ; d2 is number of entries

                movem.l a4/a5,-(a7)

                sub.w   d0,d1           ; max size of checklist this sort.
                subq.w  #1,d2
                subq.w  #1,d1           ; Dbf-loops...

                move.w  d1,d3           ; clear used entries
.ClearChecklist clr.w   (a4)+
                dbf     d3,.ClearCheckList

                move.w  d2,d3           ; transform...
.Transform      sub.w   d0,WghtOffs(a5)
                addq.w  #EntrySize,a5
                dbf     d3,.Transform

                movem.l	(a7),a4/a5

                move.w  d2,d3           ; Insert next line instead for
.AddisList      move.w  WghtOffs(a5),d0 ; 68000 compatibility...
                addq.w  #4,(a5,d0.w*2)  ; add.w d0,d0 addq.w #4,(a5,d0.w)
                addq.w  #EntrySize,a5
                dbf     d3,.AddisList

                moveq   #-4,d0          ; #-lwdsize
.GetMemPos      add.w   d0,(a4)
                move.w  (a4)+,d0
                dbf     d1,.GetMemPos

                movem.l (a7)+,a4/a5
.PutNewList     move.w  WghtOffs(a5),d0
                move.w  (a4,d0.w),d0
                move.l  a5,(a3,d0.w)
                addq.w  #EntrySize,a5
                dbf     d2,.PutNewList

                ; In this case you have a list of ADDRESSES to
                ; each object. I made it this way to
                ; make it more flexible (you maybe have more
                ; data in each entry than me?).

                rts
Gem writer: Carl-Henrik Skårstedt
last updated: 1998-03-16