7+͈C:)=_gDBDIR ASM8DBDIR CMD;&DBDIR DOCaASCIIDECCMDh+6 -:vvG:v!v64n!xv owOo!v4o<552vx!v2vviKgKqo.og!v5po:vSo!xv5bo!v5bo!v5bo=<.otoK.o:v͈C!voG~wogxړo>OxGͳGÆooÆo page 58 ; dbdir.asm ; ; ; THIS PROGRAM WILL ... ; produce a directory list on the ; console and will be called from dBASEII. ; - Mike Kelly ; ; 08-20-82 v1.0 written ; ; 08-22-82 v1.0 updated ; 08-30-82 v1.1 Add routine to load the program to upper memory ; when it has been assembled in lower memory. To ; do this requires adding a base number (offset) ; to all labels and variables so that after the ; move to upper memory, all addresses will have ; been adjusted properly. ; 09-20-82 v1.2 Changed routine to add function byte to ; select which function of this routine. ; Expanded routine to add set user function. ; ; Function: ; 00h = alter user number ; 01h = show directory ; 01-20-83 v1.3 Added seperator between filenames in display. ; ; ; global tcmd,tfcb,bldfcb,loop1,prtit global srchnxt,end global linecnt,diroffset,prtfn global srchfrst,prtspace,prtdot,prtcrlf global nohit,findme,notfound,count global function,setusr,showdir,badfunc global badbyte,user,usrmsg ; ;SYSTEM EQUATES ; cr equ 0dh ;carriage return lf equ 0ah ;line feed esc equ 1bh ;escape exitcpm equ 0 ;warmboot exit point base equ 0 ;find wboot jmp address at rst0 dumyadr equ 0 tfcb equ 5ch ;default fcb tcmd equ 80h ;default command line and DBA addr tbuf equ 80h ;default buffer bdos equ 5 ;CP/M function calls entry point entsize equ 13 ;bytes per sorted directory entry ; ; includes: 1-2 for user number ; ; 3-13 for fn,ft (no period) pagesize equ 20 ;# of lines to print on a page dirsect equ 26 ;# of sectors in directory track tpa equ 100h dbasetop equ 00400h ;free memory above dBASEII (a400h-a000h) dbload equ 00500h ;load asm. routine here x equ 0a000h ;offset to add to all labels and ; variables ; ; aseg org tpa ; ; ;this routine will move the code at ; ; 400h to a400h ; ld hl,st1 ;from address ld de,x+dbasetop ;to address ld bc,fini1-st1 ;length ldir ;move it ; ; ;this routine will move the code at ; ; 500h to a500h ; ld hl,start ;from address ld de,x+dbload ;to address ld bc,fini-start ;length ldir ;do the move ; jp x+start ;then jump to the newly moved code ; jp exitcpm ; org dbasetop ;put variables here ; st1: ;start of variables ; function: db 01h ;function byte ; ; 0 = set user ; ; 1 = show directory findme: db '???????????' ;directory entry to look for userno: db 00h ;user number drive: db 00h ;drive to search junk: db 'end of storage used by dbdir' ; fini1: ;end of variables ; ; org dbload ; ; start: ld (x+oldstack),sp ;save current stack pointer ld sp,x+stack ;set stack pointer to my stack ; push psw ;save the world push bc push de push hl ; ld a,(x+function) ;get function cp 00h ;=00h then set user jp z,x+setusr cp 01h ;=01h then show directory jp z,x+showdir jp x+badfunc ;bad function passed ; setusr: call x+user ld de,x+usrmsg call x+sout call bdos jp x+end ; showdir: ld de,x+dirmsg ;print signon msg call x+sout ld bc,0000h ;init count ld (x+count),bc ; call x+setdma ;set dma to addr of tbuf(80h) call x+bldfcb call x+srchfrst ;get 1st entry jp z,x+nohit ;=z,no entry found call x+prtit loop1: call x+srchnxt ;get n+1 entry jp z,x+end ;=z,all done call x+prtit ;print the entry jp x+loop1 ;loop til done ; bldfcb: ld a,(x+drive) ;get drive byte ld (tfcb),a ;put in fcb ; ld hl,x+findme ;sending addr (search string) ld de,tfcb+1 ;receiving addr ld bc,000bh ;count of 11 ldir ;do move ret ; prtit: ld a,(x+count) ;check how many entries have cp 05h ; printed-only 5 per line call z,x+prtcrlf inc a ;up count ld (x+count),a ; ld hl,tbuf+1 ;addr of buffer ld bc,(x+diroffset) ;offset into directory entry ld b,00h add hl,bc ld bc,000bh ;count of 11 ; call x+prtspace ;format print of each entry ld bc,0008h call x+prtfn call x+prtdot ld bc,0003h call x+prtfn call x+prtgate ret ; prtspace: ld e,' ' call x+conout ret ; prtgate: ld e,'|' call x+conout ret ; prtdot: ld e,'.' call x+conout ret ; prtcrlf: ld de,x+crlf call x+sout xor a ;put zero in A ld (x+count),a ;zero out count ret ; prtfn: ld e,(hl) ;get a char call x+conout ;print it inc hl ;point to next char dec c ;dec count ret z ;return if done jp x+prtfn ;loop til done ; nohit: ld de,x+notfound call x+sout jp x+end ; badfunc: ld de,x+badbyte call x+sout jp x+end ; end: pop hl ;put the world back as you pop de ; found it pop bc pop psw ld sp,(x+oldstack) ;dont forget the stack ret ;ret, not jp to 0 ; ; ; ; conin: ld c,1 call bdos ret conout: push psw push bc push de push hl ld c,2 call bdos pop hl pop de pop bc pop psw ret dirin: ld c,6 ld e,0ffh call bdos cp 00h ;=00h, then char not ready jp z,x+dirin ; will want to wait for it ret sout: ld c,9 ;write string to console call bdos ret ; setdma: ld c,1ah ;set dma addr to 80h ld de,tbuf call bdos ret user: ld a,(x+userno) ;set user number ld e,a ld c,20h call bdos ret ; srchfrst: ;do search first call x+user ;alter user # ; ld c,11h ;bdos search 1st ld de,tfcb ;de with addr of fcb call bdos push psw ;save A register and z flag add a,a ;adjust A to get offset to add a,a ; the found entry add a,a add a,a add a,a ld (x+diroffset),a ;save the offset pop psw ;get the original value of A inc a ;to detect 0ffh ret ; srchnxt: ;do search next ; ; will only set srcheof flag ; ; when have checked all users ld c,12h call bdos push psw ;save A register and z flag add a,a ;adjust A to get offset to add a,a ; the found entry add a,a add a,a add a,a ld (x+diroffset),a ;save the offset pop psw ;get the original value of A inc a ;to detect 0ffh ret ; ; ; ; Variables ; count: db 00h,00h linecnt: db 00h ;count of # of lines printed ; init at 2 for heading diroffset: db 00h ;offset into directory entry ; ; returned by bdos search, ; ; incremented by 32, max. ; ; should be 255 ; dirmsg: db cr,lf db 'dBASEII directory routine' db cr,lf db 'Version 1.3 ' db '01-20-83' db cr,lf db '$' notfound: db '++ Entry not found ++' db '$' usrmsg: db cr,lf db 'User number has been altered' db cr,lf db '$' badbyte: db '++ Invalid function passed ++' db cr,lf db '$' anykey: db ' ' db 'Press any key to continue' db cr db '$' crlf: db cr,lf db '$' stktop: ds 64 ;top of stack stack: ds 1 ;stack oldstack: ;saves old stack pointer dw 0000h junk2: db 'after old stack' ; fini: end * * dbdir.cmd * * This command module is used to display the directory * of a disk while in dBASE. This is accomplished by * calling an assembler routine that has been loaded * into memory, prior to executing dBASE, at hex * location A500. This routine uses variables which * reside at hex location A400. They are 1)search string * (11-bytes used to do directory search, initially set * to "???????????", which will return the whole directory) * 2) user number (1-byte, initially set to zero, which * indicates the user number to do the directory search * for; can be from 0-F). * - Mike Kelly * * * 08-19-82 v1.0 written * 08-19-82 v1.0 updated * 09-19-82 v1.1 Added routine to implement a function * byte to be passed to the assembler * routine. Function 00h will alter * the user number, function 01h will * show the directory. * * set echo off set talk off set colon off * erase store 57344+1024 to e400 store 40960+1024 to a400 store 40960+1280 to a500 store a500 to addrdir store a400 to addrfunc store addrfunc+1 to addrsearch store addrfunc+12 to addrusr store addrfunc+13 to addrdrv store '3,68,73,82,0' to dir store 59162 to e71a store '0123456789ABCDEF' to hextbl store 'B' to drive1 store 0 to userno store '????????.???' to findme store ' !"#$%&' +; chr(39) +; '()' +; '*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`' +; 'abcdefghijklmnopqrstuvwxyz{|}~' to asciitbl * erase store t to badrv store t to badusr store t to badstr do while badusr .or. badstr .or. badrv @ 1,0 say 'dBASEII Directory display' @ 3,0 say 'Enter User number to use (0-15) ===>'; get userno; picture '99' @ 5,0 say 'Enter the Disk Drive to search' @ 6,0 say ' A: or B: ===>'; get drive1; picture '!' @ 8,0 say 'Enter type of search to do' @ 9,0 say ' ie. ????????.??? will display entire directory' @ 10,0 say ' ????????.CMD will display all files with' @ 11,0 say ' CMD as a file type' @ 13,0 say ' Enter search string ===>'; get findme; picture '!!!!!!!!!!!!' * read * if userno < 0 .or.; userno > 15 store t to badusr @ 22,0 say 'ERROR - the user number must be from 0 to 15' else store f to badusr @ 22,0 endif userno * * if drive1 = 'A' .or.; drive1 = 'B' store f to badrv @ 21,0 say ' ' else store t to badrv @ 21,0 say 'ERROR - the selected drive must be A: or B:' endif drive1 * * store @('.',findme) to dotpos * if dotpos = 0 store t to badstr @ 23,0 say 'ERROR - search string not appropriate ' else store f to badstr @ 23,0 say ' ' endif findme * enddo badusr/badstr * * take the '.' out of the search string * store $(findme,1,dotpos-1)+$(findme,dotpos+1,len(findme)-dotpos); to stringin * * convert ascii to decimal (value returned in "stringout") * do asciidec * * poke the function (01h = show dir) * poke addrfunc,1 * * poke in search string to memory * poke addrsearch,&stringout * * convert the user number 0-15 to 0-F * store $(hextbl,userno+1,1) to stringin * * convert ascii to decimal * do asciidec * * now make the user number hex 0-F binary * store val(stringout)-48 to num1 store str(num1,2) to stringout * * poke in the user number * * poke addrusr,&stringout * * convert ascii to decimal * store drive1 to stringin * do asciidec * * now make drive 0-F binary * store val(stringout)-64 to num1 store str(num1,2) to stringout * * poke the drive to memory * poke addrdrv,&stringout * * set up the call address to the assembler routine that * has been pre-loaded into high memory at addrdir * set call to addrdir store 'dummy' to adress * * do the call * erase call return  The DBDIR routines demonstrate how to call an assembler subroutine from dBASEII. There are a number of restrictions! Briefly, you can load an assembler routine above location A400 hex, as long as you don't do any sorts!!!!! You have available to you the memory space from A400 hex to the top of your TPA (on mine it is E400 hex, on a 64K system). The following files are required: - dbdir.cmd - asciidec.cmd - dbdir.asm The .asm file is Z80 code which was assembled using M80/L80, and does a not very efficient method of getting the directory entries, but it works. Hope this helps explain a not too well documented command in dBASE. Any comments concerning these routines can be left on this BBS, and if you make any wonderous enhancements, and would like to share them, please leave them on this BBS also. Mike Kelly 02/25/83 * * asciidec.cmd * * This command module will convert an ascii string to * a string of decimal numbers seperated by commas which * can then be used in a poke command. * * ie. if the input string is 'DIR' * the output string will be '68,73,82' * * To use this routine: * 1) put string to be converted in a memory variable * called "stringin" * 2) call this routined by using the dBASEII * command "DO asciidec" * 3) the converted string will be returned in * a memory variable called "stringout" * - Mike Kelly * * written v1.0 08-23-82 * updated v1.0 08-23-82 * * set echo off set talk off * * translate table * from hex 20 thru hex 7E * * store ' !"#$%&' +; chr(39) +; '()' +; '*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`' +; 'abcdefghijklmnopqrstuvwxyz{|}~' to asciitbl * * * convert ascii to decimal * * store stringin to param store 31 to base store ' ' to dstring store 0 to pointer * do while pointer