.TITLE 'IN MEMORY SHELL-metzner sort' .sbttl 'from KILOBAUD april 1981 p164' ; .remark 'For fixed length records stored in memory Put no. of records in n1 and m1. The length of each record is stored at k1, and the starting address at j1. Start sort by calling location "entry". To change to descending sort change the instruction at neq: to DAH.' ; n1: .word 0 ; number of records m1: .word 0 ; ..same here k1: .word 0 ; length of records j1: .word 0 ; starting address of strings i1: .word 0 ; ptr ml1: .word 0 ; ptr dj1: .word 0 ; ptr di1: .word 0 ;ptr ; entry: lhld j1 ; get start address push h ; ..save lhld k1 ; get length push h ; ..it too div: xra a ; m1=m1/2 lhld m1 mov a,h rar mov h,a mov a,l rar mov l,a shld m1 ; save new m1 ; ora h ; check if done jnz ndon pop b ; finished pop d ; ..so return ret ; ...now ; ; set k1=n1-m1 ; ndon: xchg ; m1 to de lhld n1 mov a,l sub e mov l,a mov a,h sbb d mov h,a shld k1 lxi h,1 ; set and save i=j=1 shld j1 shld i1 ; ; calc & save addr offset = m1*i1 ; dcr l pop b ; length of str=i1 push b ; ..put it back lp1: dad d dcx b mov a,b ora c jnz lp1 shld ml1 ; xchg ; calc & save d(j), d(i), d(i+m) pop b pop h push h push b lp2: shld dj1 shld di1 xchg dad d xchg ; HL has d(i), DE has d(i+m) ; ; compare strings and switch ; cp1: pop b ; len of string=l1 push b lp3: ldax d ; compare each byte sub m jnz neq ; not equal inx h ; if =, then next byte inx d dcx b mov a,b ora c jnz lp3 jmp nsw ; if done, don't switch ; ; change next instruction to jc for descending ; neq: jnc nsw ; if d(i)k ; nsw: lhld j1 inx h ; save new j=old j+1 shld j1 shld i1 xchg lhld k1 mov a,l sub e mov a,h sbb d jc div ; if j>k goto beginning and ; ..divide m1 ; ; calc new d(j), d(i) ; lhld dj1 pop d push d dad d ; new d(j)=old d(j+1) xchg lhld ml1 xchg jmp lp2 ; ; that all folks ; .end entry