.MODEL SMALL .STACK 20H .CODE MAIN: PUSH CX PUSH DX PUSH BX PUSH SI PUSH DI PUSH DS PUSH ES JMP OVERDATA BUFFER DB 512 DUP (?) ASK_DRIVE DB 13, 10, "DRIVE? $" ASK_HEAD DB 13, 10, "HEAD? $" ASK_CYLINDER DB 13, 10, "CYLINDER? $" ASK_SECTOR DB 13, 10, "SECTOR? $" ASK_FILE DB 13, 10, "FILE? $" THE_FILE DB 20 DUP (?) THE_FILE_END DB "$" OVERDATA: MOV DX, OFFSET ASK_FILE ;Ask for file MOV AX, SEG ASK_FILE MOV DS, AX MOV AH, 9 INT 21H MOV DI, OFFSET THE_FILE MOV BH, 0 ;Graphics page 0 GET_FILE: MOV AH, 0 ;Get a key INT 16H CMP AL, 13 ;See if 'enter' key JZ GOT_FILE MOV AH, 0EH ;Echo char to screen INT 10H CMP AL, 8 ;See if 'backspace' JZ BACKSPACE MOV BYTE PTR [DI], AL ;Set byte of file name INC DI ;Increment DI, to get ready 4 next key BACK_FROM_BACKSPACE: JMP GET_FILE BACKSPACE: DEC DI JMP BACK_FROM_BACKSPACE GOT_FILE: INC DI MOV BYTE PTR [DI], 0 OPEN_FILE: MOV DX, OFFSET THE_FILE ;Offset and seg of file_name MOV AX, SEG THE_FILE MOV DS, AX MOV AL, 2 ;Open for read/write (00000010xB) MOV AH, 3DH INT 21H MOV BX, AX ;Mov file handle into BX PUSH BX ;Push BX b/c read sector uses it a an ;offset pointer to the buffer JC CHECK_ERROR JMP READ_SECTOR CHECK_ERROR: CMP AX, 2 JNZ DONE MOV CX, 0 MOV AH, 3CH INT 21H JC DONE JMP OPEN_FILE READ_SECTOR: CALL GET_DRIVE PUSH DX ;Save drive val so it isn't overwritten CALL GET_HEAD ;by the offset address used POP DX ;Now pop the dx back out and store the MOV DH, AL ;val of the Head from AL to DH PUSH DX ;Then repush to save it again CALL GET_CYLINDER CALL GET_SECTOR CALL RESET_DRIVE POP DX ;Pop DX for value of head and drive MOV BX, OFFSET BUFFER ; ES:BX pointer to buffer MOV AX, SEG BUFFER MOV ES, AX MOV AL, 1 ;Read 1 sector MOV AH, 2 INT 13H ;Read... JC CLOSE_FILE WRITE: MOV DX, OFFSET BUFFER ;Prepare to write from buffer (DS:DX) MOV AX, SEG BUFFER MOV DS, AX MOV CX, 512 ;512 = 1 sector POP BX ;Get file handle and PUSH BX ;Restore it for file close MOV AH, 40H INT 21H CLOSE_FILE: POP BX MOV AH, 3EH INT 21H DONE: POP ES POP DS POP DI POP SI POP BX POP DX POP CX MOV AX, 4C00H INT 21H GET_DRIVE: MOV DX, OFFSET ASK_DRIVE ;Prompt for drive MOV AX, SEG ASK_DRIVE MOV DS, AX MOV AH, 9 INT 21H MOV AH, 00 ;Read input INT 16H MOV AH, 0EH ;Echo ASCII in AL MOV BH, 0 INT 10H CMP AL, 65 ;If char is 'A' or 'a' (ASC 65 & 97) JZ ITS_A ;then return with DL = 0 CMP AL, 97 JZ ITS_A MOV DL, 128 ;Else return with DL = 128 for RET ;Hard Drive ITS_A: MOV DL, 0 RET GET_HEAD: MOV DX, OFFSET ASK_HEAD MOV AX, SEG ASK_HEAD MOV DS, AX MOV AH, 9 INT 21H MOV AH, 00H INT 16H MOV AH, 0EH ;Echo ASCII in AL MOV BH, 0 INT 10H SUB AL, 48 ;ASCII VAL OF '1' IS 49 & 49 - 48 = 1 ;Didn't mov AL into dl yet b/c this value ;needed special attention (see read_sector) RET GET_CYLINDER: MOV DX, OFFSET ASK_CYLINDER MOV AX, SEG ASK_HEAD MOV DS, AX MOV AH, 9 INT 21H MOV AH, 0 INT 16H MOV AH, 0EH ;Echo ASCII in AL MOV BH, 0 INT 10H SUB AL, 48 MOV CH, AL RET GET_SECTOR: MOV DX, OFFSET ASK_SECTOR MOV AX, SEG ASK_SECTOR MOV DS, AX MOV AH, 9 INT 21H MOV AH, 0 INT 16H MOV AH, 0EH ;Echo ASCII in AL MOV BH, 0 INT 10H SUB AL, 48 MOV CL, AL RET RESET_DRIVE: POP DX ;Pop DL=drive b/c this is already stored PUSH DX ;For buffered sector read. Then RePush MOV AH, 0 INT 13H RET