home *** CD-ROM | disk | FTP | other *** search
- ;
- ;
- ; *****************
- ; * *
- ; * 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 [<section-name>]
- ;
- ; 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 <section-name>" 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:
- ;
- ; <name>,sep,<description>,null,user,drive
- ;
- ; where <name> is the section name
- ; sep is a binary 1 used to terminate the match test
- ; <description> 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 <name> 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.