ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSAVE0-2 A861ÿÿÿÿÿÿÿÿSAVE0-2 CMD2 ÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿ; PROGRAM: SAVE0.A86 ; VERSION: 1.02 ; DATE: 15 October 1984 ; AUTHOR: Charlie Godet-Ceraolo ; 2610 Glenwood Road ; Brooklyn, NY 11210 ; ; DESCRIPTION: A utility to provide the same function as the ; SAVE 0 command of CP/M2.2 for CP/M86. It doesn't ; save anything, it just creates a zero length file ; in the disk directory. Intended mainly for use ; with MCAT-86 to put disk-ids in the directory. ; ; USE: ASM86 SAVE0 $PZSZ ; GENCMD SAVE0 DATA[M200] ;------------------------------------------------------------ Release EQU 1 Version EQU 02 FALSE EQU 0 TRUE EQU NOT FALSE ; ; cpm86 equates ; ConIn EQU 1 ConOut EQU 2 ; write console character ReadConBuf EQU 10 ; read console buffer ResetDisk EQU 13 DeleteF EQU 19 ; erase file MakeF EQU 22 ; create file ; ; Ascii equates ; TAB EQU 09H CR EQU 0DH LF EQU 0AH Space EQU ' ' Ascii_Zero EQU '0' EOS EQU 0H ; DSEG ; image of CP/M86's basepage ; BASEPAGE EQU $ RB 5CH FCB EQU $ ; default fcb FCBDN RB 1 FCBFN RB 8 FCBFT RB 1 FCBQ RB 1 RB 1 FCBEX RB 1 FCBS1 RB 1 FCBS2 RB 1 FCBRC RB 1 FCB2 EQU $ ; second fcb FCB2DN RB 1 FCB2FN RB 8 FCB2FT RB 3 RB 4 FCBCR RB 1 FCBRNO RW 1 FCBR2 RB 1 BUFF RB 80H ; default buffer Buf_End EQU $ ; mark end of buffer ; CSEG ; SAVE0: MOV DX,DS MOV SS,DX MOV SP,Offset LOCAL_STACK CLD ; direction flag = increment MOV SI,Offset SignOn CALL MsgOut ; ; check for a command-line, prompt and cycle if none ; CMP BUFF,0 JNE got_name MOV Cycle_Flag,TRUE ; Cycle: CALL CrLf MOV SI,Offset FileMsg ; display prompt CALL MsgOut CALL Get_Name JC Real_Exit ; CF = no name MOV SI,Offset Line ; parse the line MOV DI,Offset FCB ; into the fcb CALL ParseF ; got_name: MOV DI,Offset FCBFN ; no wildcards allowed CALL CheckWild JNC no_wild MOV SI,Offset NoWildMsg CALL MsgOut JMPS Cycle_exit no_wild: CALL Disk_Reset ; allows changing disk CALL Delete_File ; so we don't get two CALL Create_File ; do it CMP AL,0FFH ; was there room? JNE Cycle_exit ; yes, continue MOV SI,Offset NoRoomMsg ; nope, tell 'em and CALL MsgOut ; and leave JMP Real_Exit Cycle_exit: CMP Cycle_Flag,TRUE ; if false, we exit JE Cycle ; else do another ; Real_Exit: MOV CL,0 MOV DL,0 CALL BDOS ; ; SUBROUTINES ; ; DI --> fcb to scan for wildcard ; Returns CF Set if wildcard, else CF clear ; CheckWild: MOV AL,'?' MOV CX,11 REPNE SCASB JE bad CLC RET bad: STC RET ; Disk_Reset: MOV CL,ResetDisk CALL BDOS RET ; Delete_File: MOV DX,Offset FCB MOV CL,DeleteF CALL BDOS RET ; Create_File: MOV DX,Offset FCB MOV CL,MakeF CALL BDOS RET ; Get_Name: MOV MaxLine,20 ; max input 20 chars CALL Clear_Line ; zero fill the buffer MOV DX,Offset LineBuffer MOV CL,ReadConBuf ; get a reply CALL BDOS CALL CrLf CMP LineLength,0 ; emptyp line? JE no_name CLC RET no_name: STC RET ; ; Entry: SI --> string, DI --> fcb ; ParseF: LODSB ; strip leading spaces CMP AL,Space JE ParseF ; and tabs CMP AL,Tab JE ParseF DEC SI ; adjust for one too many MOV AL,1[SI] ; check for colon CMP AL,':' JNE bf_nd ; if none, supply default LODSB CALL To_Upper AND AL,0001$1111B ; make a number INC SI ; point past ':' JMPS bf_sd bf_nd: XOR AL,AL bf_sd: STOSB ; store drive code MOV CX,8 ; move chars until '.' or 0 CALL bf_gt bf_nt: MOV CX,3 ; mov/fill extension CALL bf_gt MOV AH,0 ; zero fill rest of fcb MOV CX,24 CALL bf_ft RET ; bf_gt: LODSB CALL To_Upper OR AL,AL JE bf_sft CMP AL,'*' JE bf_qft CMP AL,'.' JE bf_sft STOSB LOOP bf_gt bf_skip: LODSB CALL To_Upper OR AL,AL JZ gt_ret CMP AL,'.' JE gt_ret JMPS bf_skip gt_ret: RET ; bf_qft: MOV AH,'?' CALL bf_ft JMPS bf_skip bf_ft: PUSH AX MOV AL,AH REP STOSB POP AX RET bf_sft: MOV AH,' ' JMPS bf_ft ; To_Upper: CMP AL,'a' JB tu_exit CMP AL,'z' JA tu_exit SUB AL,'a'-'A' tu_exit: RET ; ; zero fills the line buffer, saves all ; Clear_Line: PUSH AX PUSH CX PUSH DI MOV DI,Offset Line MOV CX,LENGTH Line MOV AL,0 REP STOSB POP DI POP CX POP AX RET ; ; Print null-terminated string pointed to by SI, saves all ; MsgOut: PUSH AX PUSH SI msgloop: LODSB ; get a character OR AL,AL ; machine zero? JZ msgexit ; yes, exit CALL Char_Out ; print it JMPS msgloop ; get another msgexit: POP SI POP AX RET ; CrLf: PUSH AX MOV AL,CR CALL Char_Out MOV AL,LF CALL Char_Out POP AX RET ; ; Send character in AL to console ; Char_Out: PUSH BX PUSH DX PUSH CX MOV CL,ConOut MOV DL,AL CALL BDOS POP CX POP DX POP BX RET ; BDOS: PUSH ES INT 224 POP ES RET ; DSEG $ ; ; initialized data ; DB '(c) 1984 Charlie Godet-Ceraolo' SignOn DB 'SAVE0 v' DB Release + Ascii_Zero,'.' DB (Version/10) + Ascii_Zero DB (Version MOD 10) + Ascii_Zero DB CR,LF UseMsg DB CR,LF DB TAB,'USAGE: SAVE0 [FileName]',CR,LF DB TAB,'Creates an (empty) named entry in the directory.' DB CR,LF DB TAB,'If no filename is given on the command line' DB CR,LF DB TAB,'the program will prompt for one.',CR,LF DB TAB,'Entering only a to the prompt' DB ' will exit the program.',CR,LF DB TAB,'Filename MUST be unambiguous.',CR,LF DB TAB,'The disk system is reset before attempting' DB ' to create the entry.' DB CR,LF,EOS NoWildMsg DB CR,LF,TAB,'Wildcards are NOT allowed.' DB CR,LF,EOS FileMsg DB 'Save0: ',EOS NoRoomMsg DB CR,LF,'Directory Full',CR,LF,EOS Cycle_Flag DB FALSE ; ; uninitialized data ; IF (Offset $ - Offset BASEPAGE) MOD 2 NE 0 RB 1 ; make sure all is even ENDIF RB 100 ; 100 bytes for stack LOCAL_STACK EQU $ LineBuffer EQU $ MaxLine RB 1 LineLength RB 1 Line RB 20 ; END +3ŒÚŽÒ¼ü¾è€>€uÆ©ÿ辎èèdr6¾¿\èw¿]è.s¾nèëëè.è1è7<ÿu ¾–èÖé€>©ÿt¼±²èï°?¹ ò®tøÃùñ èÝú\±èÔú\±èËÃÆ臺± èºèœ€>tøÃùì< tû< t÷NŠD<:u ¬èQ$Fë2Àª¹è¹è ´¹è*ìè0 Àt(<*t<.t ªâí¬è Àt<.tëòô?èëêPŠÄóªXô ëõ to the prompt will exit the program. Filename MUST be unambiguous. The disk system is reset before attempting to create the entry. Wildcards are NOT allowed. Save0: Directory Full