; ; ; ***************** ; * * ; * SECTION.ASM * ; * v1.1 * ; * * ; ***************** ; ; 06/27/82 by Ron Fowler, Westland, Michigan ; ; 08/09/83 adapt for CP/M+ by Dick Lieber, Chicago Illinois 312-326-4392 ; ; 04/20/84 adapted for CP/M+ with user numbers over 9 ; by James M. Scardelis, Director CP/M Plus Users' Group ; P.O. Box 295, Little Falls, NJ 07424-0295 ; ; This program is intended for RCPM systems where ; files are grouped into drive/user area by their ; classification. This program implements a naming ; convention, whereby a caller can move into a ; section by typing its name, rather than the random ; searching formerly needed. ; ; Syntax is: SECTION [] ; ; If section-name is omitted, a short list of ; available sections is printed. The special ; form "SECTION ?" prints the detailed description ; of each section. ; ; You have to fill in the sections table ; (located near the end of this program) for your ; particular system. ; ;----< Examples of use: >----- ; ; A0>SECTION ATARI ;changes drive/user to atari area ; B4>SECTION MBASIC ;changes drive/user to mbasic area ; A6>SECTION ;prints short list of sections ; A9>SECTION ? ;prints the detailed list ; false equ 0 ;define truth and falsehood true equ not false ; ; the following equates may be ; customized to your preference ; autodir equ 1 ;run directory command when new drive ;/user is selected. Only works with ;cp/m+ but will be ignored in 2.2 descol equ 15 ;column # where description begins ;(in detailed list) (should be greater ;than longest section name) (but small ;enuf so display is not too long) perlin equ 4 ;names printed per line in short list tabpos equ 8 ;tab stops (set mod tabpos) ;should be at least one greater than ;longest section name. turbo equ false ;set TRUE if you'er running TurboDOS ; ; o/s conventions ; cpbase equ 0 ;set to 4200H for Heath ccpdrv equ cpbase+4 ;ccp user/drive storage loc bdos equ cpbase+5 ;system entry point dfcb equ cpbase+5CH ;default file control block dbuf equ cpbase+80H ;default buffer tpa equ cpbase+100H ;base of transient program area coninf equ 1 ;system call, get console char conotf equ 2 ;system call, console output printf equ 9 ;system call, print cons string cstsf equ 11 ;system call, get console status version equ 12 ;system call, return version setdrv equ 14 ;system call, set/drive system call getdrv equ 25 ;system call, get drive # system call gsuser equ 32 ;system call, get/set user number chain equ 47 ;system call, chain to ccp command (cpm+ only) ; ; character definitions ; cr equ 13 ;carriage-return code lf equ 10 ;linefeed code ; ; code begins.... ; org tpa ; ; pbase: lxi h,0 ;save system stack dad sp shld spsave lxi sp,stack ;load local stack ; if not turbo ;cp/m, get drive # mvi c,getdrv ;get current drive # call bdos push psw ;save it sta newdrv ;two ways endif ; call sect ;perform the section function ; if not turbo ;turbodos doesn't need this stuff lda newdrv ;get newly logged drive mov b,a ;save for comparison pop psw ;get old logged drive cmp b ;did logged drive change? jnz cpbase ;then relog with warm boot endif ; lhld spsave ;else restore stack sphl ret ;to system... ; ; scan cmd line...if an arg exists, attempt to ; match it in the table. If no arg, dump a list ; of available sections. ; sect: lda dfcb+1 ;is there a cmd-line arg? cpi ' ' jz prnqk ;then go print sections out cpi '?' ;wants detailed list? jz prntbl ;then go do it lxi h,dbuf ;something there, scan to it scanbk: inx h ; ignoring blanks mov a,m cpi ' ' jz scanbk lxi d,table ;point de to the section table loop: push h ;save cmd line arg pointer eloop: ldax d ;test entry against table cpi 1 ;end of entry marker? jnz noend ;jump if not mov a,m ;yes, did user cmd terminate also? ora a jz match ;then declare a match jmp nomat ;else declare a mismatch noend: cmp m jnz nomat ;skip if no match inx h ;continue with comparison inx d jmp eloop ; ; here when an entry didn't match ; nomat: ldax d ora a ;entry terminator? inx d jnz nomat ;scan through it pop h ;restore cmd line arg pntr inx d ;end of entry, skip over user # inx d ;and drive ldax d ;end of table? ora a ;(terminated by 0) jnz loop ;go scan another if not ; ; here when no match can be found ; lxi d,matmsg ;print out no-match message mvi c,printf call bdos jmp prnqk ;go give short list ; ; here when a match is found ; match: xchg ;hl==> user # scmat: inx h ;scan past description mov a,m ;looking for terminating null ora a jnz scmat inx h ;skip over terminator mov a,m ;fetch user # sui '0' ;subtract ascii bias cpi 10 ;is it > 9? jc scmat2 ;no, so continue on sui 7 ;remove the rest scmat2: mov e,a inx h ;point hl to drive # push d ;save user # push h ;and pointer mvi c,gsuser ;set user number call bdos pop h ;restore pointer to drive mov a,m ;fetch drive sui 'A' ;subtract ascii bias sta newdrv ;set new logged drive pop d ;restore user number in e mov d,a ;save drive # mov a,e ;fetch user number rlc ;rotate to high nybble rlc rlc rlc ora d ;"or" in the drive sta ccpdrv ;save for ccp use ; ; if turbo ;if turbodos... push h mvi c,setdrv ;...have to set drive explicitly mov e,d ;get drive in e call bdos ;set the drive pop h ; endif ; pop d ;clear garbage from stack ; ; cpm+ stuff -- setting user/drive at 4 is an undocumented ; feature of cp/m 2.2, it has no effect on version 3 ; push h mvi c,version call bdos mvi a,30h ;version that supports chain cmp l pop d rnc ;all done if not cp/m+ ; ; move user/drive from table to default buffer ; lxi h,80h ldax d ;get drive mov m,a inx h dcx d ldax d ;get user cpi 'A' ; is it a letter? jc fin inx h ; yes, so move to second position in d/u spec. sui 17 ; subtract bias mov m,a ; save it dcx h ; go back to first position. mvi a,'1' ; first digit is always a one now. mov m,a ; put it there inx h ; and set H for next routine jmp fin2 ;and do it. fin: mov m,a fin2: inx h mvi m,':' ;to indicate user/drive request if autodir inx h mvi m,'!' ;command seperator inx h mvi m,'D' inx h mvi m,'I' inx h mvi m,'R' endif inx h mvi m,0 ;mark end of command buffer mvi c,chain mvi e,0 ;flag to make current drive/user ccp default call bdos ; ; message printed when match failed ; matmsg: db cr,lf,'++ Entry not found ++' db cr,lf,cr,lf,'$' matms2: db cr,lf,'Type "SECTION ?" for detailed list' db cr,lf,' of available sections.',cr,lf db cr,lf,'Type "SECTION " to log' db cr,lf,' into a particular section.' db cr,lf,'$' ; ; print "quick list" ; prnqk: lxi d,tblmsg mvi c,printf call bdos lxi h,table ;print abbreviated list qloop: mvi b,perlin ;get names-per-line counter qloop2: mov a,m ;end of table? ora a jz qkend ;then go print end msg call prathl ;else print the name qscan: mov a,m ;scan to description terminator inx h ;(this effectively ignores ora a ; the description) jnz qscan inx h ;skip over user # inx h ;and drive # dcr b ;count down line entry counter jnz qtab ;go tab if line not full call crlf ;else turn up new line jmp qloop ;and continue ; ; tab between entry names ; qtab: mvi a,' ' ;seperate names with tabs call type lda column ;get column # qsub: sui tabpos ;test tab position jz qloop2 ;continue if at a tab position jnc qsub ;convert mod tabpos jmp qtab ;keep tabbing ; qkend: call crlf ;do newline lxi d,matms2 ;print ending message mvi c,printf call bdos call crlf ret ; ; here to print out a list of available section numbers ; prntbl: lxi d,tblmsg ;print heading message mvi c,printf call bdos call crlf ;turn up new line lxi h,table prloop: mov a,m ;end-of-table? ora a rz ;then all done call prathl ;print the name tab: mvi a,'.' ;tab over with leader call type lda column ;get column cpi descol ;at description column yet? jc tab ;then keep tabbing call prathl ;print description inx h ;skip over user # inx h ;and drive number call crlf ;turn up new line jmp prloop ;and continue ; ; print message @hl until null or 01 binary ; prathl: mov a,m ;fetch char inx h ;point past it ora a ;null? rz ;then done cpi 1 ;1 also terminates rz call type ;nope, print it call break ;check for console abort jmp prathl ; ; test for request from console to stop (^C) ; break: push h ;save 'em all push d push b mvi c,cstsf ;get console sts request call bdos ora a ;anything waiting? jz brback ;exit if not mvi c,coninf ;there, is, get it call bdos cpi 'S'-64 ;got pause request? mvi c,coninf cz bdos ;then wait for another character cpi 'C'-64 ;got abort request? jz quit ;then go abort brback: pop b ;else restore and return pop d pop h ret ; ; request from console to abort ; quit: lxi d,qmesg ;tell of quit mvi c,printf call bdos lhld spsave ;get stack pointer sphl ret ; qmesg: db cr,lf,'++ Aborted ++',cr,lf,'$' ; ; turn up a new line on display ; crlf: mvi a,cr ;print a return call type mvi a,lf ;get lf, fall into type ; ; Routine to print char in A on console, ; while maintaining column number. ; type: push h ;save everybody push d push b mov e,a ;align char for printing push psw ;save char mvi c,conotf call bdos ;print it pop psw ;restore char lxi h,column ;bump column counter cpi lf ;linefeed doesn't chang column jz nochg inr m cpi cr ;carriage-return zeroes it jnz nochg ;skip if not cr mvi m,0 ;is, zero column nochg: pop b ;restore & return pop d pop h ret ; ; dump heading message ; tblmsg: db cr,lf,'Available sections are:',cr,lf,'$' ; ; ; variables ; spsave: dw 0 ;stack-pointer save column: db 0 ;current column # newdrv: db 0 ;new drive # to log ds 20 ;the stack ; stack equ $ ;define it ; ; ; ; ; SECTIONS TABLE (located at end for easy patching with DDT) ; ; This is the table that defines the sections. Entry format is: ; ; ,sep,,null,user,drive ; ; where is the section name ; sep is a binary 1 used to terminate the match test ; is a one-line-or-less comment printed when ; the list is dumped. Match testing terminates ; before this field. ; null is a binary 0 used to terminate the description ; user is the user number (0-15) of the section (ascii) ; drive is the drive (A-P) number of the section (ascii) ; ; the table ends with a of zero (binary). ; ; Note: be sure to make section names ALL-CAPS, because the ; CCP converts command-line arguments to capitals. The ; description may be in lower case, since it has nothing ; to do with the matching process. ; Also: although the drive and user # is in ascii (for convenience ; in setting up the table), be sure to use caps for the ; drive designation. No error checking is done on the values. ; table: DB 'ARCHIVE',1,'Archives - .LBR files',0,'1A' db 'ASSEM',1,'Assembly Language Sources',0,'3B' db 'BASIC',1,'BASIC Language Sources',0,'5B' db 'BIOS',1,'This system''s BIOS',0,'FB' db 'C',1,'C Language Sources',0,'9B' db 'CPPLUG',1,'CP/M Plus User''s Group Library - .LBR Files',0,'7B' db 'DBASE',1,'dBase II Sources and Database',0,'6B' db 'DOCS',1,'Documentation - .LBR Files',0,'8B' db 'GAMES',1,'Games - .LBR Files',0,'4B' db 'HDUTIL',1,'Hard Disk Utilities',0,'FA' db 'OTHER',1,'Whatever fails classification',0,'BB' db 'PASCAL',1,'PASCAL Language Sources',0,'2B' db 'PL/I',1,'PL/I Language Sources',0,'1B' db 'SYSTEMA',1,'System Files - No Access',0,'0A' db 'SYSTEMB',1,'System Files - No Access',0,'0B' db 'UPLOADS',1,'Recently Uploaded Software',0,'AB' db 0 ;<<== end of table ; ; -----< end of SECTIONS table>----- ; end pbase ;that's all.