// ____________________________ // ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄ ▄▄▄ // ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ██ █ ██ █ ▀█▄ // █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ██▄▀ ▀█▄▀ ▄▄█▀ // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ // 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; }