Unix/ls: Difference between revisions

4,255 bytes added ,  4 years ago
Add 8080 assembly version
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
(Add 8080 assembly version)
Line 33:
</pre>
<br><br>
 
=={{header|8080 Assembly}}==
 
This program runs under CP/M and lists the current directory. CP/M does not return the
filenames in sorted order, so it has to do the sorting itself.
 
<lang 8080asm>dma: equ 80h
puts: equ 9h ; Write string to console
sfirst: equ 11h ; Find first matching file
snext: equ 12h ; Get next matching file
org 100h
;;; First, retrieve all filenames in current directory
;;; CP/M has function 11h (sfirst) and function 13h (snext)
;;; to return the first, and then following, files that
;;; match a wildcard.
lxi d,0 ; Amount of files
push d ; Push on stack
lxi h,fnames ; Start of area to save names
push h ; Push on stack
lxi d,fcb ; FCB that will match any file
mvi c,sfirst ; Get the first file
getnames: call 5 ; Call CP/M BDOS
inr a
jz namesdone ; FF = we have all files
dcr a ; Dir entry is at DMA+32*A
rrc ; Rotate 3 right, same as
rrc ; rotate 5 left, *32
rrc
adi dma+1 ; Add DMA offset + 1 (filename offset)
mov e,a ; Low byte of address
mvi d,0 ; High byte is 0
mvi b,8 ; Filename is 8 bytes
pop h ; Get pointer to name area
call memcpy ; Copy the name
mvi m,' ' ; Separate name and extension
inx h
mvi b,3 ; Extension is 3 bytes
call memcpy ; Copy the extension
mvi m,13 ; While we're at it, terminate
inx h ; the filename with \r\n
mvi m,10
inx h
pop d ; Get amount of files
inx d ; Increment it (we've added a file)
push d ; Put it back onto the stack
push h ; Put the name pointer on the stack too
mvi c,snext ; Go get the next file
jmp getnames
namesdone: pop h ; Terminate the file list with $
mvi m,'$' ; so it can be printed with function 9
;;; CP/M does not keep its directory in sorted order,
;;; so we need to sort the list of files ourselves.
;;; What follows is a simple insertion sort.
lxi d,1 ; DE (i) = 1
sortouter: pop h ; Get amount of files
push h
call cmpdehl ; i < length(files)?
jnc sortdone ; If not, we're done
push d ; push i; DE (j) = i
sortinner: push d ; push j
mov a,d ; j > 0?
ora e
jz sortinnerdone ; If not, inner loop is done
dcx d ; DE = j-1
call lookup ; HL = files[j-1]
push h ; push files[j-1]
inx d ; DE = j
call lookup ; HL = files[j]
pop d ; pop DE = files[j-1]
push d ; keep them across comparison
push h
call cmpentries ; A[j] >= A[j-1]?
pop h
pop d
jc sortinnerdone ; Then inner loop is done.
mvi b,12 ; Otherwise we should swap them
swaploop: ldax d ; Get byte from files[j-1]
mov c,m ; Get byte from files[j]
mov m,a ; files[j][x]=files[j-1][x]
mov a,c ; files[j-1][x]=files[j]-[x]
stax d
inx h ; Increment pointers
inx d
dcr b ; all 12 bytes done yet?
jnz swaploop ; if not, swap next byte
pop d ; DE = j
dcx d ; j = j-1
jmp sortinner
sortinnerdone: pop d ; pop j
pop d ; pop i
inx d ; i = i + 1
jmp sortouter
sortdone: pop h ; Remove file count from stack
;;; We're done sorting the list, print it.
lxi d,fnames ; Print the now sorted list of files
mvi c,puts
jmp 5
;;; Subroutine: compare entries under DE and HL
cmpentries: mvi b,12 ; Each entry has 12 relevant bytes.
cmploop: ldax d ; Get byte from entry DE
cmp m ; Compare with byte from entry HL
rnz ; If they differ, we know the ordering
inx h ; Increment both pointers
inx d
dcr b ; Decrement byte counter
jnz cmploop ; Compare next byte
ret
;;; Subroutine: look up filename entry (HL=DE*14+fnames)
lookup: push d ; Save entry number
mov h,d
mov l,e
dad h ; HL = HL' * 2
dad d ; HL = HL' * 3
dad h ; HL = HL' * 6
dad d ; HL = HL' * 7
dad h ; HL = HL' * 14
lxi d,fnames ; Offset
dad d ; Add the offset
pop d ; Restore entry number
ret
;;; Subroutine: compare DE and HL
cmpdehl: mov a,d
cmp h
rnz
mov a,e
cmp l
ret
;;; Subroutine: copy B bytes from DE to HL
memcpy: ldax d ; Get byte from source
mov m,a ; Store byte at destination
inx h ; Increment both pointers
inx d
dcr b ; Done yet?
jnz memcpy ; If not, copy next byte
ret
;;; File control block used to specify wildcard
fcb: db 0,'???????????' ; Accept any file
ds fcb+36-$ ; Pad the FCB out to 36 bytes
fnames:</lang>
 
 
=={{header|8th}}==
2,096

edits