home *** CD-ROM | disk | FTP | other *** search
- ********************************************
- * MAKE USER NUMBER CHANGE *
- * *
- * SYNTAX: A>MAKE FILENAME.TYP 5 *
- * OR A>MAKE *.ASM 3 *
- * *
- * (ALLOWS ALL AMBIGOUS FILES FOR MULTI- *
- * PROCESSING OF FILES) *
- * *
- * PROGRAM DESIGNED TO ALLOW PROGRAMS TO *
- * BE CHANGED FROM ONE USER AREA TO ANOTHER*
- * THE USER NUMBER FOR A FILE IS STORED IN *
- * DIRECTORY ENTRY FOR THAT FILE IN THE DR *
- * (FIRST) BYTE IN ITS FCB. THIS PROGRAM *
- * ASSUMES THAT THE TRACK AND SECTOR ARE *
- * SET BY THE SEARCH FUNCTIONS AND USES A *
- * SIMPLE BIOS WRITE TO UPDATE THE DIREC- *
- * TORY. THIS PROGRAM DOES NOT COPY THE *
- * FILE INTO THE NEW USER NUMBER, ONLY *
- * CHANGE THE NUMBER FOR AN EXISTING FILE. *
- * IF YOUR BIOS DOES SOMETHING OTHER *
- * THAN THE STANDARD BIOS WRITE ROUTINE *
- * AS INDICATED IN THE CP/M DOCUMENTATION *
- * THEN THIS PROBABLY WON'T WORK. IT HAS *
- * BEEN CHECKED ONLY ON A THINKER TOYS 2D *
- * SO BEFORE YOU USE THIS PROGRAM, TEST *
- * IT ON A GARBAGE DISK THAT YOU DON'T *
- * MIND LOSING. *
- * *
- * VERSION 1.0 - 07/05/81 R.E.D. *
- * 1.1 - 07/15/81 R.E.D. *
- * *
- ********************************************
-
-
- ENTRY EQU 0005H ;BDOS ENTRY ADDRESS
- BUFFER EQU 80H ;DEFAULT CP/M BUFFER
- FCB EQU 5CH ;DEFAULT CP/M FCB
- TFCB EQU 6CH ;TEMPORY FCB
-
-
- ORG 0100H
-
- MAKE: LHLD ENTRY + 1 ;GET BDOS ADRESS
- MVI L,0 ;MAKE PAGE START
- SPHL ;SET UP STACK HERE
- LXI D,MAKMSG ;SIGN ON
- CALL PRNTLIN ; PRINT IT
- CALL VERSNO ; CHECK FOR 2.0 OR UP
- CPI ' ' ;AT LEAST 20
- JNC GOODVER ;JUMP IF VERSION OK
- LXI D,BADVER ; AND RETURN
- PRNRET: CALL PRNTLIN ;PRINT CONSOLE MESSAGE
- CPMRET: CALL CRLF ; CR/LF FOR END
- JMP 0000 ;SILENT RET REMOVED BECAUSE
- ;- DIRECTORY SUM CHECK
- ;- GETS MESSED UP DURING THIS
- ;- ROUTINE; SO YOU NEED WBOOT
- ;- TO UPDATE BDOS AFTERWARDS.
- ;
- ;CHOOSE NOT TO USE CR/LF ROUTINE BUT INCORPORATED
- ;CR/LF IN MESSAGE STRING
- ;
- ********************
- * CONSOLE MESSAGES *
- ********************
-
- MAKMSG: DB 0DH,0AH,'MAKE USER CHANGE - Ver. 1.1',0DH,0AH,'$$$'
- BADVER: DB 0DH,0AH,'Requires CP/M version 2.0 or higher.',0DH,0AH
- DRVERR: DB 0DH,0AH,'Drive select error',0DH,0AH,'$$$'
- BADSEC: DB 0DH,0AH,'Bad Sector Write Error',0DH,0AH,'$$$'
- ROMSG: DB 0DH,0AH,'Drive is set to R/O',0DH,0AH,'$$$'
- USRMSG: DB 0DH,0AH,'User must be 0-15',0DH,0AH,'$$$'
- FROMSG: DB ' is R/O',0DH,0AH,'$$$'
- SYSMSG: DB ' is SYS',0DH,0AH,'$$$'
- EQUMSG: DB ' = $$$'
-
- WRITE: JMP 0000 ;VECTOR TO BIOS WRITE ROUTINE
- ;FILLED IN LATER
- WRTOK: DB 0 ;FLAG FOR CHANGE REQUIRING WRITE
- ;SET IF CHANGE TO DIRECTORY MADE
- AMBFIL: ;FCB FOR MATCH ANYTHING FILE
- DB '????????????????',0,0,0
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0
-
- USERNO: DB 0 ;STORAGE FOR NEW USER NUMBER
- ;OBTAINED FROM TFCB
- DIRCODE:DB 0 ;STORAGE FOR DIRECTORY CODE
- ;PROVIDED BY BDOS IN ACCUM
- DBOFF: DW 00 ;ADDRESS FOR CURRENT FCB
- ;IN THE BUFFER STARTING AT 80H
- ;CREATED BY (32 * DIRCODE + BUFFER
- ;ADDRESS) 32 BYTES PER DIR ENTRY
- DRVNO: DB 00 ;STORAGE FOR SELECTED DRIVE NUMBER
- ;PROVIDED BY FCB DR BYTE(1ST BYTE)
- ;AND CONFIRMED BY BDOS IF NEEDED
- GOODVER:LXI H,0 ;CLEAR STORAGE LOCATIONS IN MEMORY
- MOV A,H ;JUST TO ENSURE THEIR CONTENTS
- STA USERNO ;NOT REALLY NEEDED BUT WHY NOT
- STA WRTOK
- STA DRVNO
- STA DIRCODE
- SHLD DBOFF
- LHLD 0001 ;GET WBOOT ADDR (BASE OF BIOS + 3)
- ;ADDRESS WRITTEN THERE BY CP/M
- LXI D,27H ;OFFSET FOR JUMP TO BIOS WRITE
- ;SECTOR ROUTINE (BASE OF BIOS + 2AH)
- DAD D ;COMPUTE ADDRESS FOR WRITE ROUTINE
- SHLD WRITE + 1 ; LOAD OUR VECTOR WITH THIS ADDRESS
- ;NOW A JUMP TO WRITE SHOULD WRITE
- ;A SECTOR BACK TO THE DISK
- LXI H,TFCB + 1 ;GET THE NEW USER NUMBER
-
- ***************************
- * GET THE NEW USER NUMBER *
- * FROM THE TEMP FCB AT 6CH*
- * AND CONVERT IT FROM *
- * ASCII TO BINARY *
- ***************************
-
- GETURS: LXI B,0BH ;COUNTER TO LOOK AT ALL OF TFCB
- ; SOMEONE MIGHT TYPE SEVERAL SPACES
- MVI E,0 ;E WILL RECORD THE NUMBER OF
- ; CHARACTERS OTHER THEN BLANKS
- ; SO THAT WE CAN CHECK IF TFCB
- ; HAS ALL BLANKS (ERROR)
- NUM1: MOV A,M ;GET BYTE FROM TFCB
- CPI 20H ;IGNORE BLANKS
- JZ NUM2 ; IF ' ' THAN JUMP AND DCR COUNT
- INX H ;ELSE UPDATE POINTERS
- INR E ;NOT A BLANK SO INCR COUNTER
- SUI 30H ;MAKE BINARY FROM ASCII
- CPI 0AH ;MUST BE NUMERIC
- JNC USRERR ; REPORT ERROR AND RETURN
- MOV D,A ;SAVE NUMBER FOR LATER
- MOV A,B ;GET TOTAL THUS FAR
- RLC ;MULT BY 10 / ROTATE IT
- RLC ; TO THE NEXT DECIMAL DIGIT
- RLC ;ROTATES DOUBLE;
- ADD B ;2,4,8; NOW ADD 9TH & 10TH
- ADD B
- ADD D ;AND ADD CURRENT DIGIT
- MOV B,A ;SAVE THE TOTAL FOR NEXT LOOP
- NUM2: DCR C ;DCR TFCB COUNTER
- JNZ NUM1 ; AND LOOP UNTIL COUNTER = 0
- CPI 0 ;MUST BE AT LEAST 1
- JZ USRERR ; ELSE REPORT ERROR IF ALL BLANKS
- MOV A,B ;GET TOTAL BINARY USER NUMBER
- CPI 10H ;IS IT GREATER THAN 15?
- JNC USRERR ;REPORT ERROR IF > 15
- CPI 0 ;BUT MUST BE 0 OR GREATER
- JC USRERR ;SO JUMP IF LESS THAN ZERO
- STA USERNO ;SAVE USER NUMBER FOR LATER
- LDA FCB ;GET FCB DRIVE NUMBER (1ST BYTE)
- CPI 0 ;CHECK FOR DEFAULT DRIVE (0)
- JZ DEFAULT ;JUMP IF DEFAULT ELSE SUBTRACT 1
- SBI 01 ; TO CONVERT INTO BDOS USABLE
- ; DRIVE NUMBER A=0,B=1,C=2
- STA DRVNO ;SAVE DRIVE NUMBER FOR LATER
- JMP RDONLY
- DEFAULT:MVI C,19H ;BDOS GET DRIVE NUMBER FUNCTION
- CALL ENTRY ;GET DRIVE NUMBER
- STA DRVNO ;SAVE THE ACTUAL DRIVE NUMBER
- ;
- ; CHECK DRIVE FOR READ ONLY STATUS - DO THIS BEFORE SELECTING
- ; DRIVE BECAUSE SELECTION WILL VOID R/O STATUS
- ;
- RDONLY: MVI C,1DH ;BDOS R/O VECTOR FUNCTION
- CALL ENTRY ;DO IT
- LDA DRVNO ;GET THE DRIVE NUMBER BACK
- ADI 02 ;INCREMENT COUNT TO
- ; ROTATE VECTOR BIT TO CARRY
- MOV C,A ;SET UP ROTATE
- SHIFT: DCR C ;CHECK FOR END
- JZ CHECK ;CHECK CARRY IF FINISHED
- MOV H,A ;ELSE GET FIRST BYTE
- ORA A ;CLEAR CARRY
- RAR ;SHIFT IT
- MOV H,A ;AND PUT IT BACK
- MOV A,L ;GET NEXT BYTE
- RAR ;SHIFT IT
- MOV L,A ;PUT IT BACK
- JMP SHIFT ;LOOP FOR MORE
- CHECK: JC ROERR ;JUMP IF CARRY SET
- LDA DRVNO ;GET DRIVE NUMBER
- MOV E,A ;SET UP FOR BDOS CALL; MOVE
- ;DRIVE NUMBER TO E
- MVI C,0EH ;BDOS SELECT DISK FUNCTION
- CALL ENTRY ;DO IT LOGIC IS MESSED UP HERE
- ;CAUSE DEFAULT DRIVE IS RESELECTED.
- ;IT IS NEEDED IF OTHER THAN DEFAULT
- ;TO SELECT THE DRIVE BUT I CHOOSE
- ;NOT TO MAKE THE CHECK AND SELECT
- ;THE DRIVE EVEN IF IT IS THE DEFAULT.
- LXI D,AMBFIL ;POINT TO MATCH ANY FILENAME.TYP
- MVI C,11H ;BDOS SEARCH FIRST FUNCTION
- CALL ENTRY ;DO IT
- STA DIRCODE ;SAVE DIRECTORY CODE
- CPI 0FFH ;SEE IF END OF ENTRIES
- JZ CPMRET ;RETURN IF END
- ;
- ; MAIN PROGRAM FUNCTION LOOP
- ;
- LOOP: LDA DIRCODE ;GET THE DIRECTORY CODE
- ADD A ;OFFSET BY 32 BYTES PER ENTRY
- ADD A
- ADD A
- ADD A
- ADD A
- MOV E,A ;PREPARE FOR OFFSET COMPUTATION
- MVI D,00 ;CLEAR HIGH BYTE
- LXI H,BUFFER ;GET BUFFER ADDRESS
- DAD D ;COMPUTE OFFSET INTO BUFFER
- SHLD DBOFF ;SAVE THE ADDRESS INTO THE BUFFER
- XCHG ;SWAP
- LDAX D ;GET THE DR BYTE FOR THIS ENTRY
- CPI 0E5H ;SEE IF ERASED
- JZ INDIRCD ;JUMP TO DO NEXT ENTRY IF ERASED
- LXI H,USERNO ;POINT TO USER NUMBER
- CMP M ;SEE IF OLD AND NEW USER NUMBER
- ; ARE THE SAME
- JZ INDIRCD ;JUMP TO DO NEXT ENTRY
- ;
- COMPARE:LXI H,FCB+1 ;POINT TO FIRST CHARACTER
- ; OF FCB AT 5DH
- MVI C,0AH ;LOAD COUNT FOR COMPARE
- XCHG ;SWAP
- INX H ;INCR PAST DIRECTORY USER NUMBER
- CP1: LDAX D ;GET FCB FILE CHARACTER
- CPI '?' ;SEE IF ANYTHING MATCHES
- JZ MATCH ;JUMP PAST COMPARE IF '?'
- SUB M ;COMPARE THRU SUBTRACTION
- ANI 7FH ;CLEAR HIGH (FLAG) BIT
- ;WE'LL CHECK FLAGS LATER
- JNZ INDIRCD ;QUIT IF NO MATCH
- MATCH: INX D ;POINT TO NEXT CHARACTERS
- INX H
- DCR C ;DECREASE COUNT OF CHARACTERS
- JNZ CP1 ;LOOP UNTIL ZERO
- LHLD DBOFF ;GET OFFSET BUFFER ADDRESS
- XCHG ;SWAP
- LXI H,09 ;OFFSET TO t1 BYTE IN DIRECTORY
- DAD D ;COMPUTE ADDRESS
- MOV A,M ;GET THE CHARACTER
- RAL ;CHECK R/O FLAG IN CARRY
- JC FROERR ;PRINT FILE NAME, ERROR AND CONTINUE
- INX H ;OFFSET TO t2 BYTE IN DIRECTORY
- MOV A,M ;GET THIS CHARACTER
- RAL ;CHECK SYS FLAG IN CARRY
- JC SYSERR ;PRINT FILE NAME, ERROR AND CONTINUE
- LHLD DBOFF ;GET OFFSET ADDRESS
- LDA USERNO ;GET THE NEW USER NUMBER
- MOV M,A ;PUT NEW USER NUMBER IN DIRECTORY
- ;BUFFER ENTRY FCB BYTE 0
- LDA WRTOK ;GET WRITE FLAG
- INR A ;INCREASE FLAG
- STA WRTOK ;SAVE UPDATED FLAG
- CALL FILPRN ;PRINT THE FILE NAME
- LXI D,EQUMSG ;PRINT '='
- CAL╠ PRNTLI╬ ;DO IT
- LDA USERNO ;GET USER NUMBER
- CPI 09 ;SEE ONE OR TWO DIGIT USER NUMBER
- JNC DOUBLE ;JUMP IF TWO DIGITS
- SINGLE: ADI 30H ;ELSE CONVERT TO ASCII
- MOV E,A ;SET UP FOR OUTPUT
- CALL CHAROUT ;AND PRINT IT
- JMP INDIRCD ;JUMP FOR NEXT ENTRY
- DOUBLE: ADI 26H ;SUBTRACT 9 TO GET FIRST DIGIT
- ; AND ADD 30H TO MAKE ASCII.
- ; OR JUST ADD 26H TO DO BOTH...
- PUSH PSW ;SAVE THIS DIGIT AND PRINT '1'
- MVI E,'1' ;LOAD THE CHARACTER
- CALL CHAROUT ; AND PRINT IT
- POP PSW ;GET THE REMAINDER DIGIT
- MOV E,A ;SET UP FOT PRINT
- CALL CHAROUT ; AND DO IT
- INDIRCD:LDA DIRCODE ;GET THE DIRECTORY CODE
- INR A ;INCREASE IT ONE
- STA DIRCODE ;SAVE NEW KEY INTO BUFFER
- CPI 04 ;ONLY FOUR ENTRIES IN BUFFER
- JZ WRTBUF ;UPDATE BUFFER IF LAST ENTRY
- JMP LOOP ;ELSE LOOK AT REMAINDER OF BUFFER
- WRTBUF:LDA WRTOK ;GET WRITE FLAG - ANYTHING GREATER
- ; THAN ZERO MEANS A CHANGE WAS MADE
- CPI 0 ;CHECK FOR CHANGE MADE
- JZ SRNXT ;JUMP IF NO CHANGES MADE
- CALL WRTDE ;ELSE WRITE THE BUFFER BACK TO
- ; THE DIRECTORY
- XRA A ;ZERO ACCUM TO CLEAR WRITR FLAG
- STA WRTOK ;SAVE CLEARED FLAG
- SRNXT: LXI D,AMBFIL ;POINT TO ANY MATCH FCB
- MVI C,12H ;BDOS SEARCH NEXT FUNCTION
- CALL ENTRY ;DO IT
- CPI 0FFH ;SEE IF END OF ENTRIES
- JZ CPMRET ;AND RETURN IF NO MORE FILES
- CPI 0 ;LOOP UNTIL BUFFER IS UPDATED
- ;BY BDOS
- JNZ SRNXT ;JUMP UNTIL DIRCODE IS ZERO
- STA DIRCODE ;SAVE THE 0 IN DIRCODE
- JMP LOOP ; AND LOOP AGAIN
- RET ;END OF MAIN PROGRAM
-
- ******************
- * ERROR MESSAGES *
- ******************
-
- FROERR: CALL FILPRN ;PRINT THE FILE NAME
- LXI D,FROMSG ; AND R/O MESSAGE
- CALL PRNTLIN
- JMP INDIRCD ;AND CONTINUE
-
- SYSERR:CALL FILPRN ;PRINT THE FILE NAME
- LXI D,SYSMSG ; AND SYS MESSAGE
- CALL PRNTLIN
- JMP INDIRCD ;AND CONTINUE
-
- ROERR: LXI D,ROMSG ;PRINT DISK R/O
- JMP PRNRET ; AND END
-
- SECERR: LXI D,BADSEC ;PRINT BIOS SECTOR ERROR
- JMP PRNRET ; AND END
-
- USRERR: LXI D,USRMSG ;PRINT USER NUMBER ERROR
- JMP PRNRET ; AND END
-
- VERSNO: MVI C,0CH ;BDOS VERSION NUMBER FUNCTION
- JMP ENTRY
-
- PRNTLIN:MVI C,09H ;BDOS PRINT STRING FUNCTION
- JMP ENTRY
-
- CHAROUT:MVI C,06 ;BDOS DIRECT CONSOLE I/O
- JMP ENTRY
-
- CRLF: MVI E,0DH ;PRINT CR/LF
- CALL CHAROUT
- MVI E,0AH
- JMP CHAROUT
-
- FILPRN: CALL CRLF ;PRINT CR/LF
- LHLD DBOFF ;ADDRESS OF FILE FCB
- MVI C,0CH ;FILENAME.TYP CHAR COUNT
- INX H ;BYPASS DR BYTE
- FP1: PUSH B ;SAVE COUNT
- MVI A,4 ;CHECK FOR PERIOD POSITION
- CMP C
- JZ PERIOD ;PRINT PERIOD IF TIME
- MOV A,M ;IGNORE BLANKS
- CPI 20H
- JZ FP2 ;JUMP IF BLANK
- PUSH H
- MOV E,A
- CALL CHAROUT ;ELSE PRINT CHARACTER
- POP H
- FP2: POP B ;GET COUNT
- DCR C ;DCR COUNT
- INX H ;POINT TO NEXT CHAR
- JNZ FP1 ; LOOP UNTIL ZERO
- RET
- PERIOD: PUSH H ;SAVE THE ADDRESS
- MVI E,'.' ;PRINT THE PERIOD
- CALL CHAROUT
- POP H ;GET ADDRESS BACK
- POP B ;GET COUNT
- DCR C ;DCR COUNT
- JMP FP1
-
- WRTDE: LXI D,BUFFER ;SET DMA TO BUFFER
- MVI C,1AH ;BDOS SETDMA FUNCTION
- CALL ENTRY
- MVI C,1H ;SET BIOS WRITE TO DIRECTORY
- ;WRITE VICE 0=WRITE TO ALLOCATED
- ; 2=WRITE TO UNALLOCATED
- CALL WRITE ;BIOS WRITE
- ORA A ;CHECK FOR ERROR
- JNZ SECERR
- LXI D,BUFFER ;RESET BUFFER ADDRESS TO BUFFER
- MVI C,1AH ;BDOS SETDMA FUNCTION
- JMP ENTRY
-
- END
-