Original Post
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