*####################################################################### * Program CD...Change Directory Utility * * Dr. David C. Wilcox * DCW Industries, Inc. * 5354 Palm Drive, La Canada, CA 91011 * 818/790-3844 * * February 14, 1986 *####################################################################### boot equ 00 *warm boot print equ 09 *print string current equ 25 *return current disk getusr equ 32 *get/set user chain equ 47 *chain to program tab equ 09 *horizontal tab lf equ 10 *line feed cr equ 13 *carriage return space equ 32 *ascii space upmask equ $5f *upper case mask maxuser equ 15 *maximum user number extral equ 10 *bytes in command leadin extrat equ 01 *bytes in command tail bdos equ $0002 *bdos entry point *####################################################################### * User selectable parameter...For consistency, you should change the * drive letter specification in the "usage:" message near the end of * this program. It is currently configured for 8 drives, A thru H. * ndrives equ 08 *number of drives in system * *####################################################################### * Special registers: * * a5 = address of dma buffer * a6 = address of 1st parsed FCB * d6 = number of characters in chain command string *####################################################################### * * Locate FCB and DMA (for portability) * link a6,#0 *mark stack frame move.l 8(a6),a0 *get base page address lea $80(a0),a5 *get address of DMA buffer lea $5c(a0),a6 *get address of 1st parsed file name * * Clear data registers * jsr clear * * Check for no parameters specified * cmpi.b #space,$1(a6) *is first character in fcb a space? bne start move.l #usage,d1 *if so, display instructions jsr pstring bra quit *and return to CP/M * * Get current drive * start: move.w #current,d0 *get current drive trap #bdos addi.b #'A',d0 *make it ascii movea.l #drive,a0 move.b d0,(a0) *and fill in drivespec for chain command * * Set selected drive * movea.l a6,a2 move.b 1(a2),d0 *point to first character in fcb addq #2,a2 *position for subsequent reads cmpi.b #'9',d0 ble digit *no drive specified andi.b #upmask,d0 *make it upper case subi.b #'A',d0 blt baddrv *illegal character cmpi.b #ndrives,d0 bge baddrv *illegal drive specified addi.b #'A',d0 *it's legit so make it ascii movea.l #drive,a0 *and save it move.b d0,(a0) * * Set selected user area * move.b (a2)+,d0 cmpi.b #space,d0 bne digit jsr udfault *no user area specified bra chainit digit: subi.b #'0',d0 blt badusr *non-digit cmpi.b #10,d0 bge badusr *non-digit move.b d0,d5 *save it in d5 addi.b #'0',d0 *make it ascii again movea.l #user,a0 *point to first digit of user number move.b d0,(a0) *in chain command string and save it move.b (a2),d0 cmpi.b #space,d0 bne twodig *two-digit user so we aren't done yet move.l #extral-1,d2 bra chainit twodig: subi.b #'0',d0 blt badusr *non-digit cmpi.b #10,d0 bge badusr *non-digit move.b d0,d4 *save it in d4 mulu #10,d5 *multiply tens digit x 10 add.b d5,d0 *add to units digit cmpi.b #maxuser,d0 *is it within allowable range? bgt badusr addi.b #'0',d4 *if so, make it ascii and movea.l #user+1,a0 *save it in chain command string move.b d4,(a0) move.l #extral,d2 * * Chain to program * chainit: move.b d2,d6 *compute total characters in addi.b #extrat,d6 *chain command string movea.l a5,a0 *point to the dma buffer move.b d6,(a0)+ *put total length in first byte movea.l #drive,a1 *transfer chain command string jsr movmem *including a trailing null move.b #extral,d2 *to the dma buffer movea.l #tail,a1 jsr movmem move.w #chain,d0 trap #bdos *and let the bdos do the rest *####################################################################### * Subroutines *####################################################################### * * Display drivespec error message * baddrv: move.l #drvmsg,d1 jsr pstring bra quit * * Display userspec error message * badusr: move.l #usrmsg,d1 jsr pstring bra quit * * Clear data registers * clear: clr.l d0 clr.l d1 clr.l d2 clr.l d3 clr.l d4 clr.l d5 clr.l d6 clr.l d7 rts * * Move d2 bytes from a1 to a0 * movmem: move.b (a1)+,(a0)+ subq #1,d2 bne movmem rts * * Display string on console * pstring: move.w #print,d0 trap #bdos rts * * Return to CP/M * quit: move.w #boot,d0 trap #bdos * * Put default user number in chain command string * udfault: move.w #$ff,d1 *get current user move.w #getusr,d0 trap #bdos move.b d0,d5 *save it in d5 subi.b #10,d0 *subtract 10 blt unit *negative => single digit user addi.b #'0',d0 *make it ascii movea.l #user+1,a2 move.b d0,(a2) *save it move.b #'1',-(a2) *put a one in tens digit move.b #extral,d2 *set the string length counter rts unit: addi.b #'0',d5 *make user number ascii movea.l #user,a2 *save it move.b d5,(a2) move.l #extral-1,d2 *set the string length counter rts *####################################################################### drive: dc.b 0 dc.b ':!USER ' user: dc.b 0,0 tail: dc.b 0 drvmsg: dc.b lf,cr,'Illegal drive specification',lf,cr,'$' usrmsg: dc.b lf,cr,'Illegal user specification',lf,cr,'$' usage: dc.b tab,'Correct usage:',tab,tab,'cd {drive}{user}',lf,cr dc.b lf,cr,tab,tab,'drive = letter between A and H' dc.b lf,cr,tab,tab,'user = integer between 0 and 15' dc.b lf,cr,lf,cr,'$' *####################################################################### end