programming-examples/assembly/This is a simple litte assembler program that cleans out.asm
2019-11-15 12:59:38 +01:00

218 lines
10 KiB
NASM

;* This is a simple litte assembler program that cleans out *
;* the documents folder in the start menu. *
;* This is version 1.2 *
;* There's no command line switches and stuff. *
;* It gives NO messages if everything goes allright. *
;* It check for a environment variable called CLEANDIR and CD:s *
;* down to that dir if the variable is found. If not it uses *
;* the default WINDOWS\RECENT directory and deletes(UNLINKS) *
;* EVERYTHING it finds there, and CD:s back to where it started *
;* from. *
;************************************************************************
;some euqates for readability
kbd equ 16h ;keyboard irq
msdos equ 21h ;MSDOS irq
reset equ 0dh ;disk reset
dfopen equ 0fh ;open disk file
dfclose equ 10h ;close disk file
searchf equ 11h ;search first
searchn equ 12h ;search next
seqread equ 14h ;sequential disk read
seqwrite equ 15h ; " " write
getdisk equ 19h ;get current disk(default)
setdta equ 1ah ;set disk transfer area address
setdir equ 3bh ;set current directory
createf equ 3ch ;create file with handle
openf equ 3dh ;open file with handle
closef equ 3eh ;close file with handle
readf equ 3fh ;read from file with handle
writef equ 40h ;write to file with handle
unlink equ 41h ;UNLINK(delete file)
getdir equ 47h ;get current directory
allocmem equ 48h ;allocate memory
freemem equ 49h ;free memory
changebs equ 4ah ;change block size
findfirst equ 4eh ;find first file
findnext equ 4fh ;find next file
exit equ 4c00h ;msdos exit
envir equ 2ch ;offset ENVIRONMENT block
[BITS 16] ;NASM STUFF !?
[ORG 100h]
mov ax,cs ;get code segment
mov ds,ax ;use it now
mov [comseg],ds
mov [extseg],es
;************************ setup and preparing ***************************
main:
mov ah,setdta ;set our DTA-area
mov dx,mydta ;buffer for it
int msdos ;call dos
mov ah,getdisk ;get default drive
int msdos ;call dos
add al,41h ;drive in al, make it ASCII
mov byte [curdir],al ;fill buffer with name (A:..etc)
mov byte [path],al ;and default path
mov word [curdir+1],":\" ;copy separator to path
mov si,curdir ;pointer path buffer
add si,3 ;offset doscall part
mov ah,getdir ;get current dir
mov dl,0 ;0 = default
int msdos ;call dos
jnc diskok ;ok
mov bx,errt0 ;could not find current dir ?? If You
jmp errout ;get an error here You probably have
diskok: ;forgot to turn on Your computer.
call getenv ;check out if any ENV var
cmp dx,-1 ;was it there
je findfile ;yeahh
mov dx,path ;noo way, use default path
mov ah,setdir ;cd down
int msdos ;call dos
jnc findfile ;all ok
mov bx,errt1 ;error
jmp errout ;skip
;*************************** the delete file loop ***********************
findfile:
mov ah,findfirst ;see if the files out there
mov cx,0fh ;all files
mov dx,files ;our NULL terminated filname(*.*)
int msdos ;do the stuff
jnc delit ;all ok, must delete first file
jmp goback ;error, CD back and skip
found: ;found something
mov dx,files ;files (*.*)
mov ah,findnext ;the function
int msdos ;call dos
jc goback ;no more files, quit
delit:
mov ah,unlink ;UNLINK (delete) file
mov dx,mydta ;pointer Disk Transfer Area
add dx,30 ;offset Filename
int msdos ;delete it
jnc found ;deleted ok
mov bx,errt2 ;could not delete it ????
call write ;let us know
mov bx,mydta ;show wich file
add bx,30 ;offset filename in DTA
call write ;write out filename
mov bx,linefeed ;linefeed
jmp errout ;and skip
goback:
mov ah,setdir ;CD back to origin
mov dx,curdir ;path to dir
int msdos ;do it
jnc quit ;all ok, proceed
mov bx,errt1 ;error, get text
;*************************** errorexit ***********************
errout: call write ;show errormessage
quit:
xor eax,eax ;clean out that
mov ax,exit ;MS-DOS successful exit
int msdos ;back to the operating system
;***************** get ENVIRONMENT var if any *****************
getenv:
push es ;now check if there's any
push ds ;environment variable
mov es,[es:+2Ch] ;ES:DI points at environment
xor di,di ;which is paragraph-aligned
floop:
cmp byte [es:di],0 ;if we got 2 zeroes in a row
jne goon ;we are at the end of the ENV
cmp byte [es:di+1],0 ;variables
je eout
goon:
equal: cmp byte [es:di],'C' ;is it our variable ?
jne flop
inc byte di
cmp byte [es:di],'L'
jne flop
inc byte di
cmp byte [es:di],'E'
jne flop
inc byte di
cmp byte [es:di],'A'
jne flop
inc byte di
cmp byte [es:di],'N'
jne flop
inc byte di
cmp byte [es:di],'D'
jne flop
inc byte di
cmp byte [es:di],'I'
jne flop
inc byte di
cmp byte [es:di],'R'
jne flop
sign: inc byte di ;dump the R
inc byte di ;dump the =
mov ax,es ;make DS:DX point to string we found
mov ds,ax
mov si,di
mov bx,si
mov dx,bx
mov ah,setdir ;func Set Current Directory(CD)
int msdos ;do it
jnc envok ;all ok, proceed
mov dx,0 ;clear flag (use default dir)
jmp eout ;return
flop: inc byte di ;next byte
cmp byte [es:di],0 ;a 0 ?
jne flop ;noo
inc byte di ;yeahh, dump it
jmp floop ;check if two
envok: mov dx,-1
eout: pop ds
pop es
ret
;*************************************************************************
;* Writes out the NULL terminated text supplied in BX. *
;* OR writes out data,BX and size,CX if called at lwrite. *
;*************************************************************************
write: pusha
mov si,bx ;copy to SI
mov cx,0 ;clear count
wloop: lodsb ;load AL with SI
cmp al,0 ;end of line ?
je lwrite ;yeahh
inc cx ;no, incrase byte count
jmp wloop ;test next byte
lwrite: mov dx,bx ;text address in DX
mov bx,1 ;filehandle standard output = 1
mov ah,writef ;MS-DOS writefile with handle is 040
int msdos ;write buffer to standard output
popa
ret ;done
;************************ DATA and BSS stuff ***************************
comseg: dw 0
extseg: dw 0
utext: db "XXX",13,10,0
errt0: db "Could not find current directory !",13,10,0
errt1: db "Directory not found.",13,10,0
errt2: db "Could not delete ",0
path: db " :\WINDOWS\RECENT",0 ;default path without DRIVE
files: db "*.*",0
linefeed: db 13,10,0
mydta times 128 db 0 ;use 128 bytes as DTA NASM stuff !
curdir times 68 db 0 ;use 64 + 4 bytes for current dir
END