Files
mazegame/engine/src/dos.c
T

1247 lines
28 KiB
C

// ____________________________
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄ ▄▄▄
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ██ █ ██ █ ▀█▄
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ██▄▀ ▀█▄▀ ▄▄█▀
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘
// by Guillaume 'Aoineko' Blanchard under CC BY-SA license
//─────────────────────────────────────────────────────────────────────────────
// MSX-DOS routines handler
//
// References:
// - http://map.grauw.nl/resources/dos2_environment.php
//─────────────────────────────────────────────────────────────────────────────
#include "dos.h"
#include "bios.h"
#if ((DOS_USE_VALIDATOR) || (DOS_USE_ERROR_HANDLER))
// Backup of the last error value
u8 g_DOS_LastError;
#endif
#if (DOS_USE_UTILITIES)
// Backup of the last file info block
DOS_FIB g_DOS_LastFIB;
// Current time
DOS_Time g_DOS_Time;
#endif
#if (DOS_USE_ERROR_HANDLER)
// Pointer to the error handler
void* g_DOS_ErrorHandler;
// Stack pointer for the error handler
void* g_DOS_ErrorStack;
#endif
// Macro to call BDOS with stack backup
#if (DOS_USE_ERROR_HANDLER)
#define BACKUP_STACK ld (_g_DOS_ErrorStack), sp
#else
#define BACKUP_STACK
#endif
//=============================================================================
// MSX-DOS 1 FUNCTIONS
//=============================================================================
#if (DOS_USE_BIOSCALL)
//-----------------------------------------------------------------------------
// Function : Reads the value of an address in another slot
// Input : A - ExxxSSPP Slot-ID
// │ ││└┴─ Primary slot number (00-11)
// │ └┴─── Secondary slot number (00-11)
// └──────── Expanded slot (0 = no, 1 = yes)
// HL - Address to read
// Output : A - Contains the value of the read address
// Registers: AF, C, DE
// Remark : Can be call directly from MSX-DOS
// This routine turns off the interupt, but won't turn it on again
u8 DOS_InterSlotRead(u8 slot, u16 addr) __NAKED
{
slot; // A
addr; // DE
__asm
ex de, hl
call R_RDSLT
ret
__endasm;
}
// Function : Writes a value to an address in another slot
// Input : A - ExxxSSPP Slot-ID
// │ ││└┴─ Primary slot number (00-11)
// │ └┴─── Secondary slot number (00-11)
// └──────── Expanded slot (0 = no, 1 = yes)
// HL - Address
// E - Value
// Registers: AF, BC, D
// Remark : Can be call directly from MSX-DOS
// This routine turns off the interupt, but won't turn it on again
void DOS_InterSlotWrite(u8 slot, u16 addr, u8 value)
{
slot; // A
addr; // DE
value; // (SP+4)
__asm
ld iy, #4
add iy, sp
ld l, e
ld h, d
ld e, 0(iy)
call R_WRSLT
__endasm;
}
//-----------------------------------------------------------------------------
// Function : Executes inter-slot call.
// Input : IY - High byte with slot ID, see RDSLT
// IX - The address that will be called
// Remark : Can be call directly from MSX-DOS
// Variables can never be given in alternative registers or IX and IY
void DOS_InterSlotCall(u8 slot, u16 addr)
{
slot; // A
addr; // DE
__asm
push ix
ld l, #0
ld h, a
push hl
pop iy
push de
pop ix
call R_CALSLT
ei // because CALSLT do DI
pop ix
__endasm;
}
#endif // (DOS_USE_BIOSCALL)
#if (DOS_USE_ERROR_HANDLER)
// void DOS_ErrorHandler() __NAKED
// {
// __asm
// _dos_errorhandler_start:
// // Backup error code
// ld a, c ;// Get error code
// or a, #0x70 ;// Add marker so 0 is no error
// ld (_g_DOS_LastError), a ;// Save the error code
// // Restore stack pointer and C frame counter
// ld sp, (_g_DOS_ErrorStack) ;// Restore stack pointer
// pop ix
// ret
// _dos_errorhandler_end:
// _g_DOS_ErrorHandlerSize::
// .db _dos_errorhandler_end - _dos_errorhandler_start
// __endasm;
// }
// extern const u8 g_DOS_ErrorHandlerSize;
//-----------------------------------------------------------------------------
// Install the DOS error handler in RAM (page 3).
void DOS_InstallErrorHandler(callback cb, u8 size)
{
// Install error handler to memory
void* ptr = Mem_HeapAlloc(size);
Mem_Copy(*((const void **)&cb), ptr, size);
g_DOS_ErrorHandler = ptr;
Poke16(M_DISKVE, (u16)&g_DOS_ErrorHandler);
}
#endif // (DOS_USE_ERROR_HANDLER)
//-----------------------------------------------------------------------------
// Call a BDOS function
void DOS_Call(u8 func) __NAKED
{
func; // A
__asm
push ix
ld c, a
call BDOS
pop ix
ret
__endasm;
}
//-----------------------------------------------------------------------------
// Exit program and return to DOS
void DOS_Exit0() __NAKED
{
__asm
ld c, #DOS_FUNC_TERM0
jp BDOS
__endasm;
}
//-----------------------------------------------------------------------------
// Input character
c8 DOS_CharInput() __NAKED
{
__asm
push ix
ld c, #DOS_FUNC_CONIN
call BDOS
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Output character
void DOS_CharOutput(c8 chr) __NAKED
{
chr; // A
__asm
push ix
ld e, a
ld c, #DOS_FUNC_CONOUT
call BDOS
pop ix
ret
__endasm;
}
//-----------------------------------------------------------------------------
// The characters of the string will be output. The string is terminated by "$" (ASCII 24h).
void DOS_StringOutput(const c8* str) __NAKED
{
str; // HL
__asm
push ix
ex de, hl
ld c, #DOS_FUNC_STROUT
call BDOS
pop ix
ret
__endasm;
}
#if (DOS_USE_FCB)
//-----------------------------------------------------------------------------
// Set transfer address
void DOS_SetTransferAddr(void* data) __NAKED
{
data; // HL
__asm
push ix
// FCB pointer
ex de, hl
//
ld c, #DOS_FUNC_SETDTA
call BDOS
pop ix
ret
__endasm;
}
//-----------------------------------------------------------------------------
// Get free space on disk
u16 DOS_GetFreeSpace(u8 drive) __NAKED
{
drive; // HL
__asm
push ix
ld e, a
ld c, #DOS_FUNC_ALLOC
call BDOS
pop ix
ex de, hl
ret
__endasm;
}
//-----------------------------------------------------------------------------
// Open file
// The unopened FCB must contain a drive which may be zero to indicate the current drive and a filename and extension which may be ambiguous.
// The current directory of the specified drive will be searched for a matching file and if found it will be opened.
// Matching entries which are sub-directories or system files will be ignored, and if the filename is ambiguous then the first suitable matching entry will be opened.
u8 DOS_OpenFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Open file
ld c, #DOS_FUNC_FOPEN
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Create file
u8 DOS_CreateFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Create file
ld c, #DOS_FUNC_FMAKE
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Close file
u8 DOS_CloseFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Close file
ld c, #DOS_FUNC_FCLOSE
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Delete file
u8 DOS_DeleteFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Sequential read
ld c, #DOS_FUNC_FDEL
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Sequential read
u8 DOS_SequentialReadFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Sequential read
ld c, #DOS_FUNC_RDSEQ
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Sequential write
u8 DOS_SequentialWriteFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
// Sequential write
ld c, #DOS_FUNC_WRSEQ
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Random block write
u8 DOS_RandomBlockWriteFCB(DOS_FCB* stream, u16 records) __NAKED
{
stream; // HL
records; // DE
__asm
push ix
// FCB pointer
ex de, hl
// Write random block
ld c, #DOS_FUNC_WRBLK
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Random block read
u16 DOS_RandomBlockReadFCB(DOS_FCB* stream, u16 records) __NAKED
{
stream; // HL
records; // DE
__asm
push ix
// FCB pointer
ex de, hl
// Read random block
ld c, #DOS_FUNC_RDBLK
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
ex de, hl // DE becomes actual number of records read
pop ix
ret // return value in DE
__endasm;
}
//-----------------------------------------------------------------------------
// Search the first file matched with wildcard
u8 DOS_FindFirstFileFCB(DOS_FCB* stream) __NAKED
{
stream; // HL
__asm
push ix
// FCB pointer
ex de, hl
ld c, #DOS_FUNC_SFIRST
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Search the second and after the second file matched wildcard
u8 DOS_FindNextFileFCB() __NAKED
{
__asm
push ix
ld c, #DOS_FUNC_SNEXT
BACKUP_STACK
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a
#endif
pop ix
ret // return value in A
__endasm;
}
#endif // (DOS_USE_FCB)
//=============================================================================
// MSX-DOS 2 FUNCTIONS
//=============================================================================
#if ((TARGET == TARGET_DOS2) || (TARGET == TARGET_DOS2_MAPPER))
#if (DOS_USE_HANDLE)
//-----------------------------------------------------------------------------
// Open file handle
u8 DOS_OpenHandle(const c8* path, u8 mode) __NAKED // Stack: 3 bytes
{
path; // HL
mode; // SP[2]
__asm
pop iy // Retreive return address
// path
ex de, hl
// flags
dec sp // Adjust Stack-pointer
pop af
// call
ld c, #DOS_FUNC_OPEN // DOS routine
call BDOS
// check error
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fopen_ok
ld a, #HANDLE_INVALID // Return invalid file handle
jp fopen_end
#endif
fopen_ok:
ld a, b
fopen_end:
jp (iy) // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Create file handle
u8 DOS_CreateHandle(const c8* path, u8 mode, u8 attr) __NAKED // Stack: 4 bytes
{
path; // LH
mode; // SP[2]
attr; // SP[3]
__asm
pop iy // Retreive return address
// path
ex de, hl
// attrib
pop bc
// flags
ld a, c
// call
ld c, #DOS_FUNC_CREATE // DOS routine
call BDOS
// check error
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fcreat_ok
ld a, #HANDLE_INVALID // Return invalid file handle
jp fcreat_end
#endif
fcreat_ok:
ld a, b
fcreat_end:
jp (iy) // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Close file handle
u8 DOS_CloseHandle(u8 file) __NAKED
{
file; // A
__asm
ld b, a // File handle
ld c, #DOS_FUNC_CLOSE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Ensure file handle
u8 DOS_EnsureHandle(u8 file) __NAKED
{
file; // A
__asm
ld b, a // File handle
ld c, #DOS_FUNC_ENSURE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Duplicate file handle
u8 DOS_DuplicateHandle(u8 file) __NAKED
{
file; // A
__asm
ld b, a // File handle
ld c, #DOS_FUNC_DUP // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fdupl_ok
ld a, #HANDLE_INVALID // Return invalid file handle
jp fdupl_end
#endif
fdupl_ok:
ld a, b
fdupl_end:
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Read from file handle
u16 DOS_ReadHandle(u8 file, void* buffer, u16 size) __NAKED // Stack: 4 bytes
{
file; // A
buffer; // DE
size; // SP[2:3]
__asm
// Get file handle
ld b, a
// Get buffer address
// Already in DE
// Get bytes count
pop iy // Retreive return address
pop hl
// call
ld c, #DOS_FUNC_READ // DOS routine
call BDOS
ex de, hl // Put result in DE
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fread_end
ld e, #0xFF
ld d, e
#endif
fread_end:
jp (iy) // return DE
__endasm;
}
//-----------------------------------------------------------------------------
// Write to file handle
u16 DOS_WriteHandle(u8 file, const void* buffer, u16 size) __NAKED // Stack: 4 bytes
{
file; // A
buffer; // DE
size; // SP[2:3]
__asm
pop iy // Retreive return address
// handle
ld b, a
// buffer
// Already in DE
// bytes
pop hl
// call
ld c, #DOS_FUNC_WRITE // DOS routine
call BDOS
ex de, hl // Put result in DE
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fwrite_end
ld e, #0xFF
ld d, e
#endif
fwrite_end:
jp (iy) // return DE
__endasm;
}
//-----------------------------------------------------------------------------
// Move file handle pointer
u32 DOS_SeekHandle(u8 file, i32 offset, u8 mode) __NAKED __CALLEE // Stack: 7 bytes
{
file; // A
offset; // SP[2:5]
mode; // SP[6]
__asm
pop iy // Retreive return address
// handle
ld b, a
// offset (32bit)
pop hl
pop de
// mode
dec sp // Adjust Stack-pointer
pop af
// call
ld c, #DOS_FUNC_SEEK // DOS routine
call BDOS
// return
ex de, hl // DE:HL => HL:DE
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, flseek_end
ld e, #0xFF
ld d, e
ld l, e
ld h, e
#endif
flseek_end:
jp (iy) // return HL:DE
__endasm;
}
//-----------------------------------------------------------------------------
// Delete file or subdirectory
u8 DOS_DeleteHandle(u8 file) __NAKED
{
file; // A
__asm
ld b, a
ld c, #DOS_FUNC_HDELETE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Rename file or subdirectory
u8 DOS_RenameHandle(u8 file, const c8* path) __NAKED
{
file; // A
path; // DE
__asm
ex de, hl
ld b, a
ld c, #DOS_FUNC_HRENAME // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Move file or subdirectory
u8 DOS_MoveHandle(u8 file, const c8* path) __NAKED
{
file; // A
path; // DE
__asm
ex de, hl
ld b, a
ld c, #DOS_FUNC_HMOVE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Set file attributes
u8 DOS_SetAttributeHandle(u8 file, u8 attr) __NAKED
{
file; // A
attr; // L
__asm
ld b, a
ld a, #1 // A==1 => Set attributes
ld c, #DOS_FUNC_HATTR // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fsetattr_ok
ld a, #0xFF // Return invalid attribute
ret
#endif
fsetattr_ok:
ld a, l
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get file attributes
u8 DOS_GetAttributeHandle(u8 file) __NAKED
{
file; // A
__asm
ld b, a
xor a // A==0 => Get attributes
ld c, #DOS_FUNC_HATTR // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, fgetattr_ok
ld a, #0xFF // Return invalid attribute
ret
#endif
fgetattr_ok:
ld a, l
ret // Return value in A
__endasm;
}
#endif // (DOS_USE_HANDLE)
//-----------------------------------------------------------------------------
// Get disk parameters
u8 DOS_GetDiskParam(u8 drv, DOS_DiskParam* param) __NAKED
{
drv; // A
param; // DE
__asm
push ix
ld l, a
ld c, #DOS_FUNC_DPARM // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
pop ix
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Terminate with error code
void DOS_Exit(u8 err) __NAKED
{
err; // A
__asm
ld b, a
ld c, #DOS_FUNC_TERM
jp BDOS
__endasm;
}
//-----------------------------------------------------------------------------
// Explain error code
void DOS_Explain(u8 err, c8* str) __NAKED
{
err; // A
str; // DE
__asm
push ix
ld b, a
ld c, #DOS_FUNC_EXPLAIN
call BDOS
pop ix
ret
__endasm;
}
#if (DOS_USE_UTILITIES)
//-----------------------------------------------------------------------------
// Find first entry
DOS_FIB* DOS_FindFirstEntry(const c8* filename, u8 attr) __NAKED // Stack: 3 bytes
{
filename; // HL
attr; // SP[2]
__asm
pop iy // Retreive return address
// filename
ex de, hl
// attribute
dec sp // Adjust Stack-pointer
pop bc
// file info block
push ix // Backup frame pointer
ld ix, #_g_DOS_LastFIB
// call
ld c, #DOS_FUNC_FFIRST // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
// check error
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, find1st_ok
ld e, #0
ld d, e
jp find1st_end
#endif
find1st_ok:
ld de, #_g_DOS_LastFIB
find1st_end:
pop ix // Restore frame pointer
jp (iy) // return DE
__endasm;
}
//-----------------------------------------------------------------------------
// Find next entry
DOS_FIB* DOS_FindNextEntry() __NAKED
{
__asm
// file info block
push ix // Backup frame pointer
ld ix, #_g_DOS_LastFIB
// call
ld c, #DOS_FUNC_FNEXT // DOS routine
call BDOS
// check error
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
or a
jp z, findnxt_ok
ld e, #0
ld d, e
jp findnxt_end
findnxt_ok:
ld de, #_g_DOS_LastFIB
findnxt_end:
pop ix // Restore frame pointer
ret // return DE
__endasm;
}
//-----------------------------------------------------------------------------
// Delete file or subdirectory
u8 DOS_Delete(const c8* path) __NAKED
{
path; // HL
__asm
ex de, hl
ld c, #DOS_FUNC_DELETE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Rename file or subdirectory
u8 DOS_Rename(const c8* path, const c8* newPath) __NAKED
{
path; // HL
newPath; // DE
__asm
ex de, hl
ld c, #DOS_FUNC_RENAME // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Move file or subdirectory
u8 DOS_Move(const c8* path, const c8* newPath) __NAKED
{
path; // HL
newPath; // DE
__asm
ex de, hl
ld c, #DOS_FUNC_MOVE // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Set file attributes
u8 DOS_SetAttribute(const c8* path, u8 attr) __NAKED
{
path; // HL
attr; // SP[2]
__asm
pop iy // Retreive return address
// path
ex de, hl
// flags
pop hl
dec sp // Adjust Stack-pointer
// call
ld a, #1 // A==1 => Set attributes
ld c, #DOS_FUNC_ATTR // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
// check error
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, setattr_ok
ld a, #0xFF // Return invalid attribute
jp setattr_end
#endif
setattr_ok:
ld a, l
setattr_end:
jp (iy) // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get file attributes
u8 DOS_GetAttribute(const c8* path) __NAKED
{
path; // HL
__asm
ex de, hl
xor a // A==0 => Get attributes
ld c, #DOS_FUNC_ATTR // DOS routine
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
or a
jp z, getattr_ok
ld a, #0xFF // Return invalid attribute
ret
#endif
getattr_ok:
ld a, l
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get current directory
u8 DOS_GetDirectory(u8 drive, const c8* path) __NAKED
{
drive; // A
path; // DE
__asm
ld b, a
ld c, #DOS_FUNC_GETCD
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Change current directory
u8 DOS_ChangeDirectory(const c8* path) __NAKED
{
path; // HL
__asm
ex de, hl
ld c, #DOS_FUNC_CHDIR
call BDOS
#if (DOS_USE_VALIDATOR)
ld (_g_DOS_LastError), a // Store last error code
#endif
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get current date and time
const DOS_Time* DOS_GetTime() __NAKED
{
__asm
// Get date
ld c, #DOS_FUNC_GDATE
call BDOS
ld (#_g_DOS_Time+0), hl
ld (#_g_DOS_Time+2), de
ld (#_g_DOS_Time+4), a
// Get time
ld c, #DOS_FUNC_GTIME
call BDOS
ld (#_g_DOS_Time+5), hl
ld a, d
ld (#_g_DOS_Time+7), a
// return
ld de, #_g_DOS_Time
ret // return DE
__endasm;
}
#endif // (DOS_USE_UTILITIES)
#endif // ((TARGET == TARGET_DOS2) || (TARGET == TARGET_DOS2_MAPPER))
//-----------------------------------------------------------------------------
// Get MSX-DOS version number
//
// Parameters: C = 6FH (_DOSVER)
// Results: A = Error (always zero)
// BC = MSX-DOS kernel version
// DE = MSXDOS2.SYS version number
u8 DOS_GetVersion(DOS_Version* ver) __NAKED
{
ver; // HL
__asm
push ix
push hl
ld c, #DOS_FUNC_DOSVER
call BDOS
pop hl
pop ix
or a
ret nz
#if ((TARGET == TARGET_DOS2) || (TARGET == TARGET_DOS2_MAPPER))
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
#endif
ld a, b
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Select disk drive number
//
// Parameters: C = 0EH (_SELDSK)
// E = Drive number. 0=A: 1=B: etc.
// Results: L=A = Number of drives (1...8)
// This function simply selects the specified drive as the default drive. The current drive is also stored at address 0004h for CP/M compatibility.
// The number of drives available is returned in register A but this will not include the RAM disk.
u8 DOS_SelectDrive(u8 drive) __NAKED
{
drive; // A
__asm
ld c, #DOS_FUNC_SELDSK
ld e, a
push ix
call BDOS
pop ix
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get a bit field of all available disk drives
//
// Parameters: C = 18H (_LOGIN)
// Results: HL = Login vector
// This function returns a bit set in HL for each drive which is available, bit-0 of L corresponding to drive "A:".
// Up to eight drives ("A:" to "H:") are supported by the system currently, so register H will usually be zero on return.
u8 DOS_AvailableDrives() __NAKED __FASTCALL
{
__asm
ld c, #DOS_FUNC_LOGIN
push ix
call BDOS
pop ix
ret // Return value in L
__endasm;
}
//-----------------------------------------------------------------------------
// Get current disk drive number
//
// Parameters: C = 19H (_CURDRV)
// Results: L=A = Current drive (0=A: etc)
// This function just returns the current drive number.
u8 DOS_GetCurrentDrive() __NAKED
{
__asm
ld c, #DOS_FUNC_CURDRV
push ix
call BDOS
pop ix
ret // Return value in A
__endasm;
}
//-----------------------------------------------------------------------------
// Get given disk information
//
// Parameters: C = 1BH (_ALLOC)
// E = Drive number (0=current, 1=A: etc)
// Results: A = Sectors per cluster
// BC = Sector size (always 512)
// DE = Total clusters on disk
// HL = Free clusters on disk
// IX = Pointer to DPB
// IY = Pointer to first FAT sector
// This function returns various information about the disk in the specified drive. It is not compatible with CP/M which uses this function number to return the address of an allocation vector.
// Note that unlike MSX-DOS 1, only the first sector of the FAT may be accessed from the address in IY, and the data there will only remain valid until the next MSX-DOS call.
void DOS_GetDiskInfo(u8 drive, DOS_DiskInfo* info) __NAKED
{
drive; // A
info; // DE
__asm
push de
ld c, #DOS_FUNC_ALLOC
ld e, a
push ix
call BDOS
pop ix
pop iy // Get structure pointer
ld 0(iy), a // Sectors per cluster
ld 1(iy), c // Sector size (low byte)
ld 2(iy), b // Sector size (high byte)
ld 3(iy), e // Total clusters (low byte)
ld 4(iy), d // Total clusters (high byte)
ld 5(iy), l // Free clusters (low byte)
ld 6(iy), h // Free clusters (high byte)
ret
__endasm;
}