home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol075
/
shellm.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
3KB
|
170 lines
.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)<d(i+m) don't switch
;
sw: push b ; switch bytes not equal
mov b,m
ldax d
mov m,a
mov a,b
stax d
inx h
inx d
pop b
dcx b
mov a,b
ora c
jnz sw
;
; strings switched, chk if i1-m1 < 1
;
lhld m1
mov a,h
cma
mov d,a
mov a,l
cma
mov e,a
lhld i1
dad d ; if i1-m1<1 then jump to same as
; ..no switch
jnc nsw
;
; calc new d(i), d(i+m)
;
inx h ; save new i1=i1-m
shld i1
lhld di1 ; old d(i)=new d(i+m)
xchg
lhld ml1 ; address offset
mov a,e ; new d(i)=old d(i)-offset
sub l
mov l,a
mov a,d
sbb h
mov h,a
shld di1 ; save new d(i)
jmp cp1 ; goto compare strings
;
; check for j>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