Skip to main content
gamedev.net
🔒 Locked

DIR function

Started by Kryptus Dec 24, 2004 at 2:57 AM 2 replies 800+ views
Original Post
Kryptus
Kryptus
I've spent the last few weeks programming a similar OS to MS-DOS in assembly. I've implemented many functions such as DATE, TIME, CLS, VER, HELP, etc. but I've been trying to get my DIR function working. All it does it error or loop forever. I don't know if many of you actually use assembly but I don't want any C++ answers because my OS is made in pure assembly. The code I currently have for my bootloader is below and I was told that I can edit parts of it to make the DIR function. Can anyone tell me which parts? I've been trying for days to get this working but I just can't! I use NASM. I hope there's someone out there who can help me...

; ----------------------------------------------------------------------------------------------------
; NAME: COMMAND_DIR
; DESC: Displays a list of files and subdirectories in a directory.
; ----------------------------------------------------------------------------------------------------
COMMAND_DIR
	; Reset the floppy drive
	XOR AX, AX							; Set AX to 0
	INT 0x13							; Use the BIOS interrupt 0X13

	; Find the size of the root directory on the volume
	XOR CX, CX							; Set CX to 0
	XOR DX, DX							; Set DX to 0
	MOV AX, 0x0020							; Set AX to the 0x0020 (32)
	MUL WORD [MaxRootEntries]					; Multiply AL by MaxRootEntries
	DIV WORD [BytesPerSector]					; Divide AX by BytesPerSector
	XCHG AX, CX							; Swap the AX and CX register values

	; Find the location of the root directory on the volume
	MOV AL,	BYTE [TotalFATs]					; Move the value of TotalFATs to AL
	MUL WORD [SectorsPerFAT]					; Multiply AL by SectorsPerFAT
	ADD AX, WORD [ReservedSectors]					; Add AX and ReservedSectors
	MOV WORD [DataSector], AX					; Move AX into DataSector
	ADD WORD [DataSector], CX					; Add DataSector and CX

	; Read root directory into memory
	MOV BX, 0x0200
	CALL READSECTORS

	; Browse root directory for binary image
	MOV CX, WORD [MaxRootEntries]					; 224
	MOV DI, 512

.LOOP:
	PUSH CX								; Push CX into the stack
	MOV CX, 11							; Look for an 11 character name
	MOV SI, FileName						; Image name to find
	PUSH DI								; Push DI into the stack
	REP CMPSB							; Test if there is a match
	POP DI								; Pop DI out of the stack
	JE LOADFAT							; Have we found the file?
	POP CX								; Pop CX out of the stack
	ADD DI, 32							; Move to the next directory entry
	LOOP .LOOP							; Loop this procedure
	JMP FAILURE

LOADFAT:
	; Save starting cluster of boot image
	ENDL
	MOV DX, WORD [DI + 0x001A]
	MOV WORD [Cluster], DX
	; Compute size of FAT
	XOR AX, AX
	MOV AL, BYTE [TotalFATs]
	MUL WORD [SectorsPerFAT]
	MOV CX, AX
	; Compute the location of FAT
	MOV AX, WORD [ReservedSectors]
	; Read FAT into memory
	ENDL
	MOV AX, 0x050
	MOV ES, AX
	MOV BX, 0x0000
	PUSH BX

LOADIMAGE:
	MOV AX, WORD [Cluster]
	POP BX
	CALL CLUSTER2LBA
	XOR CX, CX
	MOV CL, BYTE [SectorsPerCluster]
	CALL READSECTORS
	PUSH BX
	; Compute next cluster
	MOV AX, WORD [Cluster]
	MOV CX, AX
	MOV DX, AX
	SHR DX, 0x0001
	; Divide by two
	ADD CX, DX
	MOV BX, 0x0200
	ADD BX, CX
	MOV DX, WORD [BX]
	TEST AX, 0x0001
	JNZ .ODD_CLUSTER

.EVEN_CLUSTER:
	AND DX, 0X0FFF
	JMP .DONE

.ODD_CLUSTER:
	SHR DX, 0x0004

.DONE:
	MOV WORD [Cluster], DX
	CMP DX, 0x0FF0
	JB LOADIMAGE

DONE:
	ENDL
	PUSH WORD 0x0050
	PUSH WORD 0x0000

	ENDL
	CALL SHELL

FAILURE:
	ENDL
	PRINT strFailure
	CALL SHELL

DIR

CLUSTER2LBA

	SUB AX, 0x0002
	XOR CX, CX
	MOV CL, BYTE [SectorsPerCluster]
	MUL CX
	ADD AX, WORD [DataSector]

RET

; ----------------------------------------------------------------------------------------------------
; NAME: READSECTORS
; DESC: Reads the sectors from a floppy disk
; ----------------------------------------------------------------------------------------------------
READSECTORS

.MAIN:
	MOV DI, 0x0005							; Retry only a maximum of 5 times

.SECTORLOOP:
	PUSH AX								; Push AX into the stack
	PUSH BX								; Push BX into the stack
	PUSH CX								; Push CX into the stack
	CALL LBA2CHS

	MOV AH, 0x02							; Read floppy disk data into memory
	MOV AL, 0x01							; Read 1 sector
	MOV CH, BYTE [CylinderNumber]					; Move CylinderNumber into CH
	MOV CL, BYTE [SectorNumber]					; Move SectorNumber into CL
	MOV DH, BYTE [HeadNumber]					; Move HeadNumber into DH
	MOV DL, BYTE [DriveNumber]					; Move DL into DriveNumber
	INT 0x13							; Use BIOS interrupt 0x13

	JNC .SUCCESS							; Jump if not carry to .SUCCESS

	DEC DI
	POP CX
	POP BX
	POP AX

	JNZ .SECTORLOOP

	;INT 0x18

.SUCCESS:
	POP CX								; Pop CX from the stack
	POP BX								; Pop BX from the stack
	POP AX								; Pop AX from the stack
	ADD BX, WORD [BytesPerSector]
	INC AX								; Incremenet AX by 1
	LOOP .MAIN

RET

LBA2CHS

	XOR DX, DX							; Set DX to 0
	DIV WORD [SectorsPerTrack]					; Divide AX by SectorsPerTrack
	INC DL								; Increment DX by 1
	MOV BYTE [SectorNumber], DL					; Move the sector number into DL
	XOR DX, DX							; Set DX to 0
	DIV WORD [NumHeads]						; Divide AX by NumHeads
	MOV BYTE [HeadNumber], DL					; Move the head number into DX
	MOV BYTE [CylinderNumber], AL					; Move the cylinder number into AL

RET

Drew_Benton
Drew_Benton
Well I have this assembly book I found an example in, tell me if this helps.
The code is to change the directory:
PROGY_DIR DB '\PROGRA~1',0...LEA DX, PROGY_DIR      ; Point to directory nameMOV AH, 3BH            ; Change the directoryINT 21HJNC OKAY               ; Was it successful?...                    ; error if we get here...OKAY:                  ; all is fine here


I have 6 assembly books and that was the only example I could find with directories. You may need to use [google] as well. What exactly do you need functions for?

- Drew
Kryptus
Kryptus
The DIR function in DOS doesn't change directories. Sorry I'll rephrase. I need code to list all the files in the root directory on a floppy disk. That's what code I need and my initial attempt is the code I first submitted.

Oh and I don't want any DOS related commands like INT 21h because my OS is standalone and only "looks" like DOS. It runs off the BIOS interrupts.
Dmytry
Dmytry
obviously you have some bug, but it is extremely hard to spot bugs in assembly. I'm affraid, probably only you can spot bugs in your code..

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.