diff --git a/docs/Nextor 2.1 Getting Started Guide.md b/docs/Nextor 2.1 Getting Started Guide.md index 940b2759..5de3d509 100644 --- a/docs/Nextor 2.1 Getting Started Guide.md +++ b/docs/Nextor 2.1 Getting Started Guide.md @@ -41,7 +41,7 @@ This section explains the steps needed to setup blueMSX in order to follow this a. Download the following files from [the lastest release of Nextor in GitHub](https://github.com/Konamiman/Nextor/releases/latest): -* Nextor kernel with Sunrise IDE driver. Please choose the file with _.SunriseIDE.emulators.ROM_ extension (the _.SunriseIDE.ROM_ version works but only recgonizes the slave IDE device in emulators). +* Nextor kernel with Sunrise IDE driver. Please choose the file with _.SunriseIDE.blueMSX.ROM_ extension (the _.SunriseIDE.ROM_ version works but only recognizes the slave IDE device in blueMSX), if you are using another emulator or a physical Sunrise IDE (or compatible) controller hardware you can use the file with _.SunriseIDE.ROM_ extension instead. * Nextor tools disk image (_tools.dsk.zip_). diff --git a/docs/Nextor 2.1 Programmers Reference.md b/docs/Nextor 2.1 Programmers Reference.md index 3e9bb8d0..4c1b332d 100644 --- a/docs/Nextor 2.1 Programmers Reference.md +++ b/docs/Nextor 2.1 Programmers Reference.md @@ -501,11 +501,14 @@ The partition type code returns information about the filesystem that the partit 0: None (the partition with the specified number does not exist) 1: FAT12 4: FAT16, smaller than 32MB (obsolete) -5: Extended (see below) +5: Extended (CHS) (see below) 6: FAT16 (CHS) 14: FAT16 (LBA) +15: Extended (LBA) ``` +**Note:** Prior to version 2.1.2, Nextor would only recognize a partition as extended if it had the partition type code 5 (extended CHS), and FDISK would use this code when creating extended partitions. Starting with Nextor 2.1.2, FDISK will use partition type code 15 (extended LBA) when creating extended partitions, and both 5 and 15 will be recognized as valid extended partition type codes when scanning existing partitions with `_GPART`. In the description below, "Extended" means "Either extended CHS or extended LBA". + There are many more partition type codes defined, but they refer to filesystems that can't be handled by Nextor so they are not listed here. A device can have up to four primary partitions, numbered 1 to 4. In order to accommodate more than four partitions, partition number 2 may be of a special type named "Extended". An extended partition is actually a container for more partitions; there is no limit in the number of extra partitions that a partition of type "Extended" can contain. Primary partitions 3 and 4 do not exist when partition 2 is extended. diff --git a/source/kernel/Makefile b/source/kernel/Makefile index 6692ca78..bd2a8e5c 100644 --- a/source/kernel/Makefile +++ b/source/kernel/Makefile @@ -8,7 +8,7 @@ # N80=/path/to/N80 make -VERSION := 2.1.1 +VERSION := 2.1.2 ifeq ($(strip $(N80)),) N80=N80 @@ -126,11 +126,11 @@ drivers/SunriseIDE/sunride.masteronly.bin: \ $(call assemble_as,drivers/SunriseIDE/sunride.asm,$$/sunride.masteronly.bin,--build-type abs --output-file-extension bin --define-symbols MASTER_ONLY,BAD_POPS) -### Sunrise IDE, ROM for emulators +### Sunrise IDE, ROM for blueMSX -ide-emu: drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.emulators.ROM +ide-emu: drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.blueMSX.ROM -drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.emulators.ROM: \ +drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.blueMSX.ROM: \ nextor_base.dat \ drivers/SunriseIDE/driver.bin \ drivers/SunriseIDE/chgbnk.bin \ @@ -146,11 +146,11 @@ drivers/SunriseIDE/driver.bin: \ $(call assemble,drivers/SunriseIDE/driver.mac,--build-type abs --output-file-extension bin) -### Sunrise IDE, ROM for emulators, master device only +### Sunrise IDE, ROM for blueMSX, master device only -ide-masteronly-emu: drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.MasterOnly.emulators.ROM +ide-masteronly-emu: drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.MasterOnly.blueMSX.ROM -drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.MasterOnly.emulators.ROM: \ +drivers/SunriseIDE/Nextor-$(VERSION).SunriseIDE.MasterOnly.blueMSX.ROM: \ nextor_base.dat \ drivers/SunriseIDE/drvmonly.bin \ drivers/SunriseIDE/chgbnk.bin \ diff --git a/source/kernel/bank2/val.mac b/source/kernel/bank2/val.mac index f9abb6f6..311d8675 100644 --- a/source/kernel/bank2/val.mac +++ b/source/kernel/bank2/val.mac @@ -8,20 +8,8 @@ INCLUDE ../const.inc RAMMOD -MBR_PSTART equ 01BEh ;Start of partition table in MBR -MBR_PSIZE equ 16 ;Size of partition table entry -POFF_TYPE equ 4 ;Offset of partition type in p. table entry -POFF_PSTART equ 8 ;Offset of partition start in p. table entry -POFF_PSIZE equ 12 ;Offset of partition size in p. table entry -PT_FAT12 equ 1 ;Partition type code for FAT12 -PT_FAT16_S equ 4 ;Partition type code for FAT16 (< 32M) -PT_EXT equ 5 ;Partition type code for extended partition -PT_FAT16 equ 6 ;Partition type code for FAT16 -PT_FAT16_L equ 14 ;Partition type code for FAT16 (LBA) -MBR_SIG equ 512-2 ;MBR signature offset in MBR (55h, AAh) MAXCLUS_FAT12 equ 4084 MAXCLUS_12BITS equ 4095 - ; ;----------------------------------------------------------------------------- ; diff --git a/source/kernel/bank4/partit.mac b/source/kernel/bank4/partit.mac index 94c0c441..82d9a154 100644 --- a/source/kernel/bank4/partit.mac +++ b/source/kernel/bank4/partit.mac @@ -23,7 +23,8 @@ POFF_PSTART equ 8 ;Offset of partition start in p. table entry POFF_PSIZE equ 12 ;Offset of partition size in p. table entry PT_FAT12 equ 1 ;Partition type code for FAT12 PT_FAT16_S equ 4 ;Partition type code for FAT16 (< 32M) -PT_EXT equ 5 ;Partition type code for extended partition +PT_EXT equ 5 ;Partition type code for extended partition (CHS) +PT_EXT_LBA equ 15 ;Partition type code for extended partition (LBA) PT_FAT16 equ 6 ;Partition type code for FAT16 PT_FAT16_L equ 14 ;Partition type code for FAT16 (LBA) @@ -205,7 +206,7 @@ DO_EXTPAR: ;--- If extended partition requested, first check that partition is actually extended ld a,(ix+POFF_TYPE) - cp PT_EXT + call IS_EXT_PART jp nz,UNEX_PART ld a,(ix+POFF_PSTART) ;Save the start sector number of the outer extended partition @@ -285,7 +286,7 @@ EXTP_NEXT: pop bc ld a,(ix+POFF_TYPE) - cp PT_EXT + call IS_EXT_PART jr nz,TPIY_UNEX_PART jr EXTP_LOOP @@ -1232,7 +1233,7 @@ AA_PX_DOEMU: AA_PX_NOEMU: ld a,b ;Partition type - cp PT_EXT + call IS_EXT_PART jr nz,AA_PX_NOEX ld a,(ix+AAD_CURR_PART_INDEX) or 80h @@ -3137,7 +3138,7 @@ MAP_SPECIFIC: MAP_DRV_UNK: ;Unknown change status: assume unchanged media. - ;If it has changed, the boot checksum checksum + ;If it has changed, the boot checksum ;mechanism will do the work of unassigning ;all other drives mapped to this device ;if necessary. @@ -3147,6 +3148,7 @@ MAP_DRV_UNK: MAP_DRV_CH: push hl push iy + push bc ld e,(hl) inc hl ld d,(hl) @@ -3156,6 +3158,7 @@ MAP_DRV_CH: ld d,(iy+2) ld e,(iy+3) call UNMAPALL + pop bc pop iy pop hl @@ -4169,7 +4172,7 @@ IDRVR_RET: DOSV1_2: xor a - ld b,a + ld bc,_DOSVER## ;Make B=0 and preserve C, some programs actually check it ret @@ -4505,7 +4508,7 @@ MAPDRV_NOP0: ld c,_GPART## call BASIC_DOS ld a,b - cp 5 ;Extended partition? + call IS_EXT_PART ;Extended partition? pop bc ld a,b @@ -4540,7 +4543,7 @@ MAPDRV_GOTPAR: ld a,b or a jp z,BASIC_ERR - cp 5 + call IS_EXT_PART jp z,BASIC_ERR ;"Invalid partition" error if non existing or extended partition ld e,c @@ -6278,5 +6281,16 @@ STRCOMP: inc de jr STRCOMP + +; Check if the partition type passed in A +; corresponds to a recognized extended partition type, +; return Z if so or NZ otherwise + +IS_EXT_PART: + cp PT_EXT + ret z + cp PT_EXT_LBA + ret + finish end diff --git a/source/kernel/bank5/fdisk.c b/source/kernel/bank5/fdisk.c index 42b50f8b..5d006fcf 100644 --- a/source/kernel/bank5/fdisk.c +++ b/source/kernel/bank5/fdisk.c @@ -841,7 +841,7 @@ byte GetDiskPartitionsInfo() DosCallFromRom(_GPART, REGS_ALL); error = regs.Bytes.A; if(error == 0) { - if(regs.Bytes.B == PARTYPE_EXTENDED) { + if(regs.Bytes.B == PARTYPE_EXTENDED || regs.Bytes.B == PARTYPE_EXTENDED_LBA) { extendedIndex = 1; } else { currentPartition->primaryIndex = primaryIndex; diff --git a/source/kernel/bank5/fdisk2.c b/source/kernel/bank5/fdisk2.c index 5a20b297..7fe7025c 100644 --- a/source/kernel/bank5/fdisk2.c +++ b/source/kernel/bank5/fdisk2.c @@ -415,7 +415,7 @@ int CalculateFatFileSystemParametersFat16(ulong fileSystemSizeInK, dosFilesystem clusterCount = dataSectorsCount >> sectorsPerClusterPower; sectorsPerFat = (clusterCount + 2) >> 8; - if(((clusterCount + 2) & 0x3FF) != 0) { + if(((clusterCount + 2) & 0xFF) != 0) { sectorsPerFat++; } @@ -515,7 +515,7 @@ int CreatePartition(int index) if(index != (partitionsCount - 1)) { tableEntry++; - tableEntry->partitionType = PARTYPE_EXTENDED; + tableEntry->partitionType = PARTYPE_EXTENDED_LBA; tableEntry->firstAbsoluteSector = nextDeviceSector; if(index == 0) { mainExtendedPartitionFirstSector = nextDeviceSector; diff --git a/source/kernel/bank6/partit.h b/source/kernel/bank6/partit.h deleted file mode 100644 index 07246075..00000000 --- a/source/kernel/bank6/partit.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __PARTIT_H -#define __PARTIT_H - -#include "types.h" - -#define MAX_PARTITIONS_TO_HANDLE 256 -#define MIN_DEVICE_SIZE_IN_K 10 -#define MIN_DEVICE_SIZE_FOR_PARTITIONS_IN_K 1024 -#define MIN_REMAINING_SIZE_FOR_NEW_PARTITIONS_IN_K 100 -#define MIN_PARTITION_SIZE_IN_K 100 -#define MAX_DEVICE_SIZE_FOR_DIRECT_FORMAT_IN_K 32768 -#define MAX_FAT16_PARTITION_SIZE_IN_M 2048 -#define MAX_FAT16_PARTITION_SIZE_IN_K ((ulong)MAX_FAT16_PARTITION_SIZE_IN_M * (ulong)1024) -#define MAX_FAT12_PARTITION_SIZE_IN_K 32768 -#define PARTITION_ALIGNMENT_IN_SECTORS 64 - -#define PARTYPE_UNUSED 0 -#define PARTYPE_FAT12 1 -#define PARTYPE_FAT16_SMALL 4 -#define PARTYPE_EXTENDED 5 -#define PARTYPE_FAT16 6 - -#define PSTATE_EXISTS 0 -#define PSTATE_ADDED 1 -#define PSTATE_DELETED 2 - -#define MAX_FAT12_CLUSTER_COUNT 4086 -#define MAX_FAT16_CLUSTER_COUNT 65526 -#define FAT12_ROOT_DIR_ENTRIES 112 -#define FAT16_ROOT_DIR_ENTRIES 240 -#define DIR_ENTRIES_PER_SECTOR (512 / 32) -#define MAX_FAT12_SECTORS_PER_FAT 12 -#define MAX_FAT16_SECTORS_PER_FAT 256 -#define FAT_COPIES 2 - -typedef struct { - byte primaryIndex; - byte extendedIndex; - byte partitionType; - ulong sizeInK; -} partitionInfo; - -typedef struct { - ulong x; - ulong totalSectors; - ulong dataSectors; - uint clusterCount; - uint sectorsPerFat; - byte sectorsPerCluster; - byte sectorsPerRootDirectory; - bool isFat16; -} dosFilesystemParameters; - -#endif //__PARTIT_H \ No newline at end of file diff --git a/source/kernel/drivers/MegaFlashRomSD/mfrsd.asm b/source/kernel/drivers/MegaFlashRomSD/mfrsd.asm index 63825574..29b6a0fb 100644 --- a/source/kernel/drivers/MegaFlashRomSD/mfrsd.asm +++ b/source/kernel/drivers/MegaFlashRomSD/mfrsd.asm @@ -68,10 +68,21 @@ CODE_ADD: equ 0F2EDh ; BIOS ENASLT: equ #24 +INITXT equ #6C CHGET equ #9f CHPUT equ #A2 ;Character output RSLREG: equ #138 -EXPTBL: equ #FCC1 +EXTROM equ #15F + +SDFSCR equ #185 +REDCLK equ #1F5 + +MSXVER equ #2D +LINL40 equ #F3AE +LINLEN equ #F3B0 +BDRCLR equ #F3EB +SCRMOD equ #FCAF +EXPTBL: equ #FCC1 SLTWRK: equ #FD09 ; SD @@ -357,12 +368,16 @@ DRV_TIMI: ;----------------------------------------------------------------------------- DRV_INIT: or a - jr nz,.secondExe ; Second execution + jr nz,.scrnSet ld hl,WORK_AREA_SIZE ;ld a,NUM_DRIVES ret ;Note that Cy is 0 (no interrupt hooking needed) +.scrnSet: + call USRSCRSET + jr nz,.secondExe ; Second execution + .secondExe: ld de,TXT_INFO call PRINT ; Driver info @@ -666,7 +681,7 @@ DEV_RW: ;ld hl,(#f9f0) ;inc hl - ;ld (#f9f0),hl ; Cuenta lecturas + ;ld (#f9f0),hl ; Count reads call SD_OFF ei @@ -677,6 +692,9 @@ DEV_RW: ret .ok: + ;A successful device access must reset the "device changed" flag + res BIT_SD_CHG,(ix+STATUS) + xor a ; Ok ret @@ -1322,7 +1340,7 @@ InitSD: ret c ; Timeout (card removed or damaged?) ret nz ; Command error - ;call GETWRK ; Ya deber�a tener en IX el workarea + ;call GETWRK ; Ya debería tener en IX el workarea res BIT_SDHC,(ix+STATUS) ; Set SDSC as default @@ -1461,7 +1479,7 @@ MMC_FOUND: ;----------------------------------------------------------------------------- ; Inicializa la SD y pone el modo SPI. -; Si no se hace as� falla en el FS-A1. +; Si no se hace así falla en el FS-A1. ; Aparentemente, si se escribe el CRC (#95) desde un registro falla. ;----------------------------------------------------------------------------- SD_INIT: @@ -1603,7 +1621,7 @@ SD_CMD: ld b,0 SD_CMD2: ld a,(de) - cp #ff ; Aqu� se podr�a mirar solo el bit 7? 0=ready + cp #ff ; Aquí se podría mirar solo el bit 7? 0=ready ccf ret nc @@ -2148,6 +2166,50 @@ PRINT: ;----------------------------------------------------------------------------- include "romdisk.asm" +;----------------------------------------------------------------------------- +; Restore screen parameters on MSX>=2 if they're not set yet +;----------------------------------------------------------------------------- +USRSCRSET: + ld a,(MSXVER) + or a + jr nz,.notMSX1 + +.MSX1: + ld a,(SCRMOD) + or a + ret + jp INITXT + +.notMSX1: + ld c,23h + ld ix,REDCLK + call EXTROM + and 1 + ld b,a + ld a,(SCRMOD) + cp b + jr nz,.restore + inc c + ld ix,REDCLK + call EXTROM + ld b,a + inc c + ld ix,REDCLK + call EXTROM + add a,a + add a,a + add a,a + add a,a + or b + ld b,a + ld a,(LINLEN) + cp b + ret z +.restore: + xor a + ld ix,SDFSCR + jp EXTROM + ;----------------------------------------------------------------------------- ; Strings ;----------------------------------------------------------------------------- @@ -2159,24 +2221,25 @@ endm TXT_INFO: db "MegaFlashROM SCC+ SD driver",13,10 VERSION_STRING %DRIVER_VERSION,%DRIVER_SUBVERSION - db "(c) Manuel Pazos 2013",13,10 + db "(c) 2013 Manuel Pazos",13,10 TXT_EMPTY: db 13,10,0 TXT_INIT: - db "SD card slot ",0 + db "SD Card slot ",0 TXT_ROMDSKOK: - db "ROM disk found.",13,10,0 + db "ROM Disk found.",13,10 + db 13,10,0 TXT_MMC: - db "MMC",13,10,0 + db " MMC",13,10,0 TXT_SD1x: - db "SDSC 1.x",13,10,0 + db " SDSC 1.x",13,10,0 TXT_SD2x: - db "SDSC 2.x",13,10,0 + db " SDSC 2.x",13,10,0 TXT_SDHC: - db "SDHC",13,10,0 + db " SDHC",13,10,0 IDX_TYPE: dw TXT_MMC diff --git a/source/kernel/drv.mac b/source/kernel/drv.mac index f7fc0ff0..6e430602 100644 --- a/source/kernel/drv.mac +++ b/source/kernel/drv.mac @@ -259,8 +259,6 @@ CAPSOFF: ret - - ALIGN 781Fh ;----------------------------------------------------------------------------- ; @@ -277,6 +275,18 @@ null_message: db "2 - Double side",13,10 db 0 + +; Moved here due to space constraints + +DO_DIRCALL: + pop ix + push bc + ld bc,DV_D0##-DIRCALL-3 + add ix,bc + pop bc + jp DO_CALBNK + + ;----------------------------------------------------------------------------- ; ; Entries for direct calls. @@ -292,13 +302,27 @@ DIRCALL: call DO_DIRCALL call DO_DIRCALL -DO_DIRCALL: - pop ix - push bc - ld bc,DV_D0##-DIRCALL-3 - add ix,bc - pop bc - jp DO_CALBNK + +; Process the output of DSKIO so that Cy is set +; if an error has been returned. + +DIO_SET_ERR_FLAG:: + push af + ld a,(KSLOT##) + or a + jr z,DIO_SET_ERR_FLAG_END + + ;Device-based: set Cy if error code is not 0 + pop af + or a + ret z + scf + ret + + ;Drive-based driver: result will already have Cy set on error +DIO_SET_ERR_FLAG_END: + pop af + ret ;----------------------------------------------------------------------------- @@ -478,14 +502,8 @@ DIO_RD_LOOP: push de ;with a simple call to the driver push hl - ld hl,($SECBUF##) - ld b,1 or a - - ld ix,DV_DSKIO## ;Or DEV_RW (they are at the same address) - ex af,af' - ld a,DV_BANK## - call CALBNK## + call DIO_DO_CALDRV jr nc,DIO_RD_OK pop hl ;On disk error, just return @@ -532,14 +550,8 @@ DIO_WR_LOOP: push bc push de - ld hl,($SECBUF##) - ld b,1 scf - - ld ix,DV_DSKIO## - ex af,af' - ld a,DV_BANK## - call CALBNK## + call DIO_DO_CALDRV jr nc,DIO_WR_OK pop de ;On disk error, just return @@ -562,6 +574,17 @@ DIO_WR_OK: ret +DIO_DO_CALDRV: + ld hl,($SECBUF##) + ld b,1 + + ld ix,DV_DSKIO## + ex af,af' + ld a,DV_BANK## + call CALBNK## + jp DIO_SET_ERR_FLAG + + ; Jump here when the transfer can be done in a single step ; (no page 1 involved) @@ -975,10 +998,6 @@ POP_CONV_ERR: CONV_ERR: or a ret z - ;jr c,CONVE2 - ;xor a - ;ret -CONVE2: push bc ld b,0 diff --git a/source/kernel/kvar.mac b/source/kernel/kvar.mac index fc17e8ba..b2db65d0 100644 --- a/source/kernel/kvar.mac +++ b/source/kernel/kvar.mac @@ -26,7 +26,7 @@ const SEC_DOS_VERSION_LOW,1 ;Minor version number, low nybble const MAIN_NEXTOR_VERSION,2 const SEC_NEXTOR_VERSION_HIGH,1 - const SEC_NEXTOR_VERSION_LOW,1 + const SEC_NEXTOR_VERSION_LOW,2 ;===== end mod DOS2.50 ; ; diff --git a/source/tools/C/Makefile b/source/tools/C/Makefile index 5b77090a..b797f648 100644 --- a/source/tools/C/Makefile +++ b/source/tools/C/Makefile @@ -11,7 +11,7 @@ define copy_to_bin cp $(1) ../../../bin/tools/$(2) endef -COMS := emufile.com fsize.com nexboot.com vsft.com +COMS := emufile.com fsize.com nexboot.com vsft.com eptcft.com c-tools: $(COMS) diff --git a/source/tools/C/crt0_msxdos_advanced.s b/source/tools/C/crt0_msxdos_advanced.s index 515a3751..e7b87a6f 100644 --- a/source/tools/C/crt0_msxdos_advanced.s +++ b/source/tools/C/crt0_msxdos_advanced.s @@ -129,7 +129,7 @@ cont: ld hl,#0x100 ; Termination code for DOS 2 was returned on L. ld c,#0x62 ;DOS 2 function for program termination (_TERM) - ld b,l + ld b,a call 5 ;On DOS 2 this terminates; on DOS 1 this returns... ld c,#0x0 jp 5 ;...and then this one terminates diff --git a/source/tools/C/eptcft.c b/source/tools/C/eptcft.c new file mode 100644 index 00000000..2bceadc0 --- /dev/null +++ b/source/tools/C/eptcft.c @@ -0,0 +1,416 @@ +/* Extended partition type code fix tool v1.0 + By Konamiman 11/2023 + + Compilation command line: + + sdcc --code-loc 0x180 --data-loc 0 -mz80 --disable-warning 196 + --no-std-crt0 crt0_msxdos_advanced.rel + eptcft.c + hex2bin -e com eptcft.ihx +*/ + + /* Includes */ + +#include +#include +#include +#include +#include +#include "strcmpi.h" +#include "asmcall.h" +#include "types.h" +#include "dos.h" +#include "partit.h" + + /* Defines */ + +#define PTYPE_EXTENDED_CHS 5 +#define PTYPE_EXTENDED_LBA 15 + + /* Strings */ + +const char* strTitle= + "Extended Partition Type Code Fix Tool v1.0\r\n" + "By Konamiman, 11/2023\r\n" + "\r\n"; + +const char* strUsage= + "Usage: eptcft : [fix|unfix] \r\n" + " eptcft [-] [fix|unfix] \r\n" + "\r\n" + "This tool checks the partition type code used by extended partitions\r\n" + "existing on a given device controlled by a Nextor driver.\r\n" + "If is specified, the device the drive is mapped to is used.\r\n" + "If is 0, the primary Nextor controller is used.\r\n" + "\r\n" + "Since Nextor 2.1.2 FDISK creates extended partitions with code 15\r\n" + "(extended LBA), in older Nextor versions FDISK uses code 5 (extended CHS)\r\n" + "for new extended partitions, which is incorrect.\r\n" + "\r\n" + "Adding \"fix\" will change the extended partitions that have code 5 to 15\r\n" + "in the device, adding \"unfix\" will do the opposite (might be needed for\r\n" + "old partition handling tools that assume code 5 for extended partitions).\r\n" + "Run without neither \"fix\" nor \"fix\" to see partition information.\r\n"; + +const char* strInvParam = "Invalid parameter"; +const char* strCRLF = "\r\n"; + + + /* Global variables */ + +byte ASMRUT[4]; +byte OUT_FLAGS; +Z80_registers regs; +Z80_registers regs2; +bool isNextor; +masterBootRecord* mbrBuffer = (masterBootRecord*)0x8000; +driveLetterInfo* dliBuffer = (driveLetterInfo*)0x8200; +driverInfo* driverInfoBuffer = (driverInfo*)0x8200; +char* stringBuffer = (char*)0x8000; +int driveNumber; //-1=No drive specified, 0=A:, etc +byte deviceNumber; +byte lunNumber; +byte slotNumber; +bool doFix; +bool doUnfix; +int chsPartitionsCount = 0; +int lbaPartitionsCount = 0; +void ReadOrWriteSector(bool write); +#define SECTOR_NUMBER_BUFFER 0x8200 + + + /* Some handy code defines */ + +#define PrintNewLine() printf(strCRLF) +#define StringIs(a, b) (strcmpi(a,b)==0) + + + /* Function prototypes */ + +void Terminate(const char* errorMessage); +void TerminateWithDosError(byte errorCode); +void CheckDosVersion(); +void ExtractParameters(char** argv, int argc); +void ProcessParameters(); +void DoDosCall(byte functionCode); +void ScanAndFixPartitions(); + +void print(char* s); + + + /* MAIN */ + +int main(char** argv, int argc) +{ + ASMRUT[0] = 0xC3; + print(strTitle); + + if(argc == 0) { + print(strUsage); + Terminate(null); + } + + CheckDosVersion(); + ExtractParameters(argv, argc); + ProcessParameters(); + ScanAndFixPartitions(); + Terminate(null); + return 0; +} + + + /* Functions */ + +void Terminate(const char* errorMessage) +{ + if(errorMessage != NULL) { + printf("\r\x1BK*** %s\r\n", errorMessage); + } + + regs.Bytes.B = (errorMessage == NULL ? 0 : 1); + DosCall(_TERM, ®s, REGS_MAIN, REGS_NONE); +} + + +void TerminateWithDosError(byte errorCode) +{ + regs.Bytes.B = errorCode; + DosCall(_TERM, ®s, REGS_MAIN, REGS_NONE); +} + + +void CheckDosVersion() +{ + regs.Bytes.B = 0x5A; + regs.Words.HL = 0x1234; + regs.UWords.DE = 0xABCD; + regs.Words.IX = 0; + DosCall(_DOSVER, ®s, REGS_ALL, REGS_ALL); + + if(regs.Bytes.B < 2 || regs.Bytes.IXh != 1) { + Terminate("This program is for Nextor only."); + } +} + + +void ExtractParameters(char** argv, int argc) +{ + int fixParamIndex; + + if(argv[0][1] == ':') { + driveNumber = (argv[0][0] | 32) - 'a'; + fixParamIndex = 1; + } + else { + if(argc < 2) { + Terminate(strInvParam); + } + driveNumber = -1; + + deviceNumber = argv[0][0]; + if(deviceNumber < '1' || deviceNumber > '7') { + Terminate(strInvParam); + } + deviceNumber -= '0'; + + if(argv[0][1] == '-') { + lunNumber = argv[0][2]; + if(lunNumber < '0' || lunNumber > '7') { + Terminate(strInvParam); + } + lunNumber -= '0'; - '0'; + } + else { + lunNumber = 1; + } + + slotNumber = argv[1][0]; + if(slotNumber < '0' || slotNumber > '3') { + Terminate(strInvParam); + } + slotNumber -= '0'; + + if(argv[1][1] == '-') { + if(argv[1][2] < '0' || argv[1][2] > '3') { + Terminate(strInvParam); + } + slotNumber += 0x80 + ((argv[1][2] - '0') << 2); + } + + fixParamIndex = 2; + } + + if(argc < fixParamIndex + 1) { + return; + } + + if(strcmpi(argv[fixParamIndex], "fix") == 0) { + doFix = true; + } + else if(strcmpi(argv[fixParamIndex], "unfix") == 0) { + doUnfix = true; + } + else { + Terminate(strInvParam); + } +} + + +void ProcessParameters() { + int i; + + if(driveNumber != -1) { + regs.Bytes.A = driveNumber; + regs.Words.HL = (int)dliBuffer; + DoDosCall(_GDLI); + + switch(dliBuffer->driveStatus) { + case 0: + Terminate("The specified drive is unassigned"); + break; + case 1: + break; + case 3: + Terminate("The specified drive is mapped to a mounted file"); + break; + case 4: + Terminate("The specified drive is mapped to the RAM disk"); + break; + default: + printf("The specified drive has unknown status: %i\r\n", dliBuffer->driveStatus); + TerminateWithDosError(1); + break; + } + + slotNumber = dliBuffer->driverSlotNumber; + deviceNumber = dliBuffer->deviceIndex; + lunNumber = dliBuffer->logicalUnitNumber; + + if(deviceNumber == 0) { + Terminate("The specified drive is mapped to a MSX-DOS controller"); + } + } + else if(slotNumber == 0) { + regs.Bytes.A = 1; //Primary Nextor controller + regs.Words.HL = (int)driverInfoBuffer; + DoDosCall(_GDRVR); + slotNumber = driverInfoBuffer->slot; + } + + regs.Bytes.A = 0; + regs.Bytes.D = slotNumber; + regs.Bytes.E = 0xFF; + regs.Words.HL = (int)driverInfoBuffer; + DoDosCall(_GDRVR); + for(int i=31; i>0; i--) { + if(driverInfoBuffer->driverName[i] != ' ') { + driverInfoBuffer->driverName[i+1] = '\0'; + break; + } + } + printf("Driver: %s v%i.%i.%i in slot ", driverInfoBuffer->driverName, driverInfoBuffer->versionMain, driverInfoBuffer->versionSec, driverInfoBuffer->versionRev); + if(slotNumber & 0x80) { + printf("%i-%i\r\n", slotNumber & 3, (slotNumber >> 2) & 3); + } + else { + printf("%i\r\n", slotNumber); + } + + regs.Bytes.A = slotNumber; + regs.Bytes.B = 0xFF; + regs.Words.DE = DEV_INFO; + regs.Words.HL = (int)®s2; + regs2.Bytes.A = deviceNumber; + regs2.Bytes.B = 2; //Device name string + regs2.Words.HL = (int)stringBuffer; + DoDosCall(_CDRVR); + if(regs2.Bytes.IXh == 0) { + for(int i=31; i>0; i--) { + if(stringBuffer[i] != ' ') { + stringBuffer[i+1] = '\0'; + break; + } + } + printf("Device %i, %s\r\n", deviceNumber, stringBuffer); + } + else { + printf("Device %i\r\n", deviceNumber); + } +} + +void DoDosCall(byte functionCode) +{ + DosCall(functionCode, ®s, REGS_ALL, REGS_ALL); + if(regs.Bytes.A != 0 && (functionCode != _GPART || regs.Bytes.A != _IPART)) { + TerminateWithDosError(regs.Bytes.A); + } +} + +void ScanAndFixPartitions() +{ + byte mainPartition; + byte extendedPartition; + byte partitionType; + + if(doFix) { + print("\r\nScanning and fixing partitions...\r\n\r\n"); + } + else if(doUnfix) { + print("\r\nScanning and unfixing partitions...\r\n\r\n"); + } + else { + print("\r\nScanning partitions...\r\n\r\n"); + } + + extendedPartition = 0; + while(true) { + regs.Bytes.A = slotNumber; + regs.Bytes.B = 0xFF; + regs.Bytes.D = deviceNumber; + regs.Bytes.E = lunNumber; + regs.Bytes.H = 0x82; //Main partition 2 plus the "get partition entry sector number" flag + regs.Bytes.L = extendedPartition; + DoDosCall(_GPART); + + if(regs.Bytes.A != 0) { + break; + } + + *((int*)(SECTOR_NUMBER_BUFFER)) = regs.Words.DE; + *((int*)(SECTOR_NUMBER_BUFFER+2)) = regs.Words.HL; + + ReadOrWriteSector(false); + + partitionType = mbrBuffer->primaryPartitions[1].partitionType; + if(partitionType == PTYPE_EXTENDED_CHS) { + chsPartitionsCount++; + if(doFix) { + partitionType = mbrBuffer->primaryPartitions[1].partitionType = PTYPE_EXTENDED_LBA; + ReadOrWriteSector(true); + } + } + else if(partitionType == PTYPE_EXTENDED_LBA) { + lbaPartitionsCount++; + if(doUnfix) { + partitionType = mbrBuffer->primaryPartitions[1].partitionType = PTYPE_EXTENDED_CHS; + ReadOrWriteSector(true); + } + } + else { + break; + } + + extendedPartition++; + } + + if(chsPartitionsCount == 0 && lbaPartitionsCount == 0) { + print("This device has no extended partitions.\r\n"); + return; + } + + if(doFix) { + if(chsPartitionsCount > 0) { + printf("%i partitions fixed\r\n(partition code changed from \"extended CHS\" to \"extended LBA\")\r\n", chsPartitionsCount); + } + else { + print("No partitions with partition code \"extended CHS\" found, nothing to fix.\r\n"); + } + } + else if(doUnfix) { + if(lbaPartitionsCount > 0) { + printf("%i partitions unfixed\r\n(partition code changed from \"extended LBA\" to \"extended CHS\")\r\n", lbaPartitionsCount); + } + else { + print("No partitions with partition code \"extended LBA\" found, nothing to fix.\r\n"); + } + } + else { + if(chsPartitionsCount > 0) { + printf("%i partitions found with code 5 (extended CHS)\r\n", chsPartitionsCount); + } + if(lbaPartitionsCount > 0) { + printf("%i partitions found with code 15 (extended LBA)\r\n", lbaPartitionsCount); + } + print("No changes made to any partition.\r\n"); + } +} + +void ReadOrWriteSector(bool write) { + regs.Bytes.A = slotNumber; + regs.Bytes.B = 0xFF; + regs.Words.DE = DEV_RW; + regs.Words.HL = (int)®s2; + regs2.Bytes.A = deviceNumber; + regs2.Bytes.C = lunNumber; + regs2.Flags.C = write ? 1 : 0; + regs2.Bytes.B = 1; //Read/write 1 sector + regs2.Words.HL = (int)mbrBuffer; + regs2.Words.DE = (int)SECTOR_NUMBER_BUFFER; + DoDosCall(_CDRVR); +} + +#define COM_FILE +#include "print_msxdos.c" +#include "printf.c" +#include "asmcall.c" +#include "strcmpi.c" diff --git a/source/tools/C/partit.h b/source/tools/C/partit.h index 774cdf54..f1f82233 100644 --- a/source/tools/C/partit.h +++ b/source/tools/C/partit.h @@ -20,6 +20,7 @@ #define PARTYPE_FAT12 1 #define PARTYPE_FAT16_SMALL 4 #define PARTYPE_EXTENDED 5 +#define PARTYPE_EXTENDED_LBA 15 #define PARTYPE_FAT16 6 #define PARTYPE_FAT16_LBA 0x0E diff --git a/source/tools/C/printf.c b/source/tools/C/printf.c index dc719838..0cd87eba 100644 --- a/source/tools/C/printf.c +++ b/source/tools/C/printf.c @@ -11,7 +11,7 @@ Supported format specifiers: %d or %i: signed int - %ud or %ui: unsigned int + %u: unsigned int %x: hexadecimal int %c: character %s: string @@ -20,7 +20,7 @@ Also if SUPPORT_LONG is defined: %l: signed long - %ul: unsigned long + %lu: unsigned long %lx: hexadecimal long */ @@ -160,7 +160,12 @@ static int format_string(const char* buf, const char *fmt, va_list ap) else if(theChar == 'x') { base = 16; } - else if(theChar != 'd' && theChar != 'i') { +#ifdef SUPPORT_LONG + else if(isLong) { + fmtPnt--; + } else +#endif + if(theChar != 'd' && theChar != 'i') { do_char_inc(theChar); continue; } diff --git a/source/tools/MAPDRV.MAC b/source/tools/MAPDRV.MAC index eb27d9e8..2d4fece9 100644 --- a/source/tools/MAPDRV.MAC +++ b/source/tools/MAPDRV.MAC @@ -7,6 +7,10 @@ ld_a_iyl macro FIB equ 3000h + ;Extended partition type codes +PT_EXT: equ 5 +PT_EXT_LBA: equ 15 + jp START ; ------------------------------------------------------------------------------- @@ -297,7 +301,9 @@ OK_GETCURMAP: jp nz,5 ld a,h - cp 5 ;Is extended? + cp PT_EXT ;Is extended? + jr z,IS_EXT_PART + cp PT_EXT_LBA jr z,IS_EXT_PART IS_PRIM_PART: