Skip to content

Commit f9be16b

Browse files
authored
v2.1.0 final (#33)
* Add UNAPI RAM Helper compatible mapper support routines (#34) * "Get cluster information" function call, and improvements to EMUFILE (#35) * Cleanup/fix C tools compilation (#36) * Post-RC1 fixes and changes (#61) * Fix: using bad address of emulation work area in disk emulation mode.
1 parent 6ecd074 commit f9be16b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+24607
-23653
lines changed

docs/DRIVER.ASM

+2
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,8 @@ DEV_STATUS:
663663
; be write protected or write enabled is not considered
664664
; to be read-only.
665665
; bit 2: 1 if the LUN is a floppy disk drive.
666+
; bit 3: 1 if this LUN shouldn't be used for automapping.
667+
; bits 4-7: must be zero.
666668
;+8 (2): Number of cylinders
667669
;+10 (1): Number of heads
668670
;+11 (1): Number of sectors per track

docs/Nextor 2.1 Driver Development Guide.md

+36-6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
[4.2.8. CHGBNK (7FD0h)](#428-chgbnk-7fd0h)
4444

45+
[4.2.9 PROMPT (41E8h)](#429-prompt-41e8h)
46+
4547
[4.3. The driver header](#43-the-driver-header)
4648

4749
[4.3.1. DRV_SIGN (4100h)](#431-drv_sign-4100h)
@@ -102,9 +104,11 @@
102104

103105
[5. Change history](#5-change-history)
104106

105-
[5.1. v2.1.0 beta 2](#51-v210-beta-2)
107+
[5.1. v2.1.0 final](#51-v210-final)
108+
109+
[5.2. v2.1.0 beta 2](#52-v210-beta-2)
106110

107-
[5.2. v2.1.0 beta 1](#52-v210-beta-1)
111+
[5.3. v2.1.0 beta 1](#53-v210-beta-1)
108112

109113

110114
## 1. Introduction
@@ -490,6 +494,25 @@ Output: -
490494
Corrupts: AF
491495
```
492496

497+
#### 4.2.9 PROMPT (41E8h)
498+
499+
Starting with Nextor kernel 2.1.0 you can call the PROMPT routine to display a "Insert disk for drive X: and strike a key when ready" message and wait for the user to press a key. This routine is available at address 41E8h in the main bank, and you can invoke it using [CALLB0](#423-callb0-403fh) as follows:
500+
501+
```
502+
PROMPT: equ 41E8h
503+
CODE_ADD: equ 0F1D0h
504+
CALLB0: equ 403Fh
505+
506+
ld hl,PROMPT
507+
ld (CODE_ADD),hl
508+
call CALLB0
509+
```
510+
511+
The following work area is used by this routine:
512+
513+
* The zero-based drive number is taken from TARGET, at address F33Fh.
514+
* The H.PROMPT hook at address F24Fh is called with the zero-based drive number in A before the routine is executed.
515+
493516
### 4.3. The driver header
494517

495518
The driver header is the first part of a Nextor driver. It contains some information that helps Nextor to identify the driver and determine its type.
@@ -613,7 +636,7 @@ Please note also the following:
613636
614637
#### 4.4.4. DRV_BASSTAT (4139h)
615638
616-
This is the entry for the BASIC extended statements ("CALLs") handler. It works the same way as the standard handlers (see [MSX2 Technical Handbook, chapter 2](https://github.com/Konamiman/MSX2-Technical-Handbook/blob/master/md/Chapter2.md), for details), except that if the handled statements have parameters, the MSX BIOS routine CALBAS (needed to invoke the MSX BASIC interpreter helper routines) can't be used directly; instead, it must be invoked via [the CALLB0 entry](#423-callb0-403fh) in kernel page 0.
639+
This is the entry for the BASIC extended statements ("CALLs") handler. It works the same way as the standard handlers (see [MSX2 Technical Handbook, chapter 2, "Expansion of CMD command"](https://github.com/Konamiman/MSX2-Technical-Handbook/blob/master/md/Chapter2.md), and [MSX2 Technical Handbook, chapter 5, "Developing Cartridge Software"](https://github.com/Konamiman/MSX2-Technical-Handbook/blob/master/md/Chapter5.md) for details), except that if the handled statements have parameters, the MSX BIOS routine CALBAS (needed to invoke the MSX BASIC interpreter helper routines) can't be used directly; instead, it must be invoked via [the CALLB0 entry](#423-callb0-403fh) in kernel page 0.
617640
618641
If the driver does not handle BASIC extended statements, it must simply set the carry flag and return.
619642
@@ -977,7 +1000,8 @@ The information to be returned is a 12 byte block with the following structure:
9771000
bit 0: 1 if the medium is removable
9781001
bit 1: 1 if the medium is read only
9791002
bit 2: 1 if the logical unit is a floppy disk drive
980-
bits 3-7: Unused, must be zero
1003+
bit 3: 1 if the logical unit should not be used for automapping
1004+
bits 4-7: Unused, must be zero
9811005
+8 (2): Number of cylinders
9821006
+10 (1): Number of heads
9831007
+11 (1): Number of sectors per track
@@ -1020,12 +1044,18 @@ This section contains the change history for the different versions of Nextor. O
10201044
10211045
This list contains the changes for the 2.1 branch only. For the change history of the 2.0 branch see the _[Nextor 2.0 Driver Development Guide](../../../blob/v2.0/docs/Nextor%202.0%20Driver%20Development%20Guide.md#5-change-history)_ document.
10221046
1023-
### 5.1. v2.1.0 beta 2
1047+
### 5.1. v2.1.0 final
1048+
1049+
- [LUN_INFO](#464-lun_info-4169h) can now return a flag indicating that the device/LUN should not be used for automapping.
1050+
1051+
- Added the [PROMPT](#429-prompt-41e8h) routine.
1052+
1053+
### 5.2. v2.1.0 beta 2
10241054
10251055
- **BREAKING CHANGE:** The address of CODE_ADD, used by [the CALLB0 routine](#423-callb0-403fh), has changed to F1D0h (it was F84Ch).
10261056
10271057
- Fix: there was Nextor kernel code in the 1K free area in pages 0 and 3, so putting anything here caused problems, e.g. DOS 1 mode didn't work.
10281058
1029-
### 5.2. v2.1.0 beta 1
1059+
### 5.3. v2.1.0 beta 1
10301060
10311061
Added the "User is requesting reduced drive count" flag to the input of [the DRV_INIT routine](#443-drv_init-4136h) and [the DRV_CONFIG routine](#448-drv_config-4151h).

docs/Nextor 2.1 Programmers Reference.md

+201-26
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,23 @@
5252

5353
[3.13. Enable or disable the Z80 access mode for a driver (_Z80MODE, 7Dh)](#313-enable-or-disable-the-z80-access-mode-for-a-driver-_z80mode-7dh)
5454

55+
[3.14. Get information for a cluster on a FAT drive (_GETCLUS, 7Eh)](#314-get-information-for-a-cluster-on-a-fat-drive-_getclus-7eh)
56+
5557
[4. New error codes](#4-new-error-codes)
5658

5759
[5. Extended mapper support routines](#5-extended-mapper-support-routines)
5860

59-
[5.1. BLK_ALLOC: Allocate a memory block](#51-blk_alloc-allocate-a-memory-block)
61+
[5.1: CALL_MAP: Call a routine in a mapped RAM segment](#51-call_map-call-a-routine-in-a-mapped-ram-segment)
62+
63+
[5.2: RD_MAP: Read a byte from a RAM segment](#52-rd_map-read-a-byte-from-a-ram-segment)
64+
65+
[5.3: CALL_MAPI: Call a routine in a mapped RAM segment, with inline routine identification](#53-call_mapi-call-a-routine-in-a-mapped-ram-segment-with-inline-routine-identification)
66+
67+
[5.4: WR_MAP: Write a byte to a RAM segment](#54-wr_map-write-a-byte-to-a-ram-segment)
6068

61-
[5.2. BLK_FREE: Free a memory block](#52-blk_free-free-a-memory-block)
69+
[5.5. The UNAPI RAM Helper discovery procedure](#55-the-unapi-ram-helper-discovery-procedure)
70+
71+
[5.6. Breaking change notice](#56-breaking-change-notice)
6272

6373
[6. Other features](#6-other-features)
6474

@@ -629,6 +639,91 @@ Note that the Z80 access mode is enabled or disabled for a whole driver, affecti
629639

630640
The Z80 access mode applies to MSX-DOS drivers only. Nextor will never change the CPU when accessing drive-based and device-based drivers.
631641

642+
643+
### 3.14. Get information for a cluster on a FAT drive (_GETCLUS, 7Eh)
644+
645+
```
646+
Parameters: C = 7EH (_GETCLUS)
647+
A = Drive number (0=default, 1=A: etc.)
648+
DE = Cluster number
649+
HL = Pointer to a 16 byte buffer
650+
Results: A = Error code
651+
```
652+
653+
This function fills a user buffer with information related to a given cluster number for a given drive,
654+
provided that the drive is mapped to a FAT12 or FAT16 filesystem. This function, in combination with
655+
[RDDRV](#33-read-absolute-sectors-from-drive-_rddrv-73h) and [WRDRV](#34-write-absolute-sectors-to-drive-_wrdrv-74h),
656+
can be useful for tools that perform low-level disk manipulation such as defragmenters.
657+
658+
The information returned in the buffer is as follows:
659+
660+
* +0: FAT sector number that contains the entry for the cluster (2 bytes)
661+
* +2: Offset in the FAT sector where the entry for the cluster is located (0-511) (2 bytes)
662+
* +4: First data sector number the cluster refers to (4 bytes)
663+
* +8: Value of the FAT entry for the cluster (2 bytes)
664+
* +10: Size of a cluster in sectors for the drive (1 byte)
665+
* +11: Flags (1 byte)
666+
* bit 0: set if the drive is FAT12
667+
* bit 1: set if the drive is FAT16
668+
* bit 2: set if the FAT entry for the cluster is an odd entry (FAT12 only)
669+
* bit 3: set if the cluster is the last one of a file
670+
* bit 4: set if the cluster is free
671+
* bits 5-7: unused, always zero
672+
* +12-+15: Unused, always zero
673+
674+
If the drive is neither FAT12 nor FAT16, this function will return a .NDOS error; this means that either
675+
the FAT12 flag or the FAT16 flag will always be set if the function returns no error. Note however that this might not
676+
be true in future versions of Nextor (in case that support for other FAT variants is added), therefore
677+
you should always check both flags and not assume that one being clear means that the other one is set.
678+
679+
If the supplied cluster number doesn't exist in the specified drive, an .ICLUS error will be returned.
680+
Note that 0 and 1 are always invalid cluster numbers (the bytes for these entries in the first FAT sector are unused).
681+
682+
The value of the FAT entry for the cluster has the usual meaning in a FAT filesystem:
683+
684+
* 0 means that the cluster is free
685+
* 0FF8h-0FFFh for FAT 12 and FFF8h-FFFFh for FAT16 mean that the cluster is the last one of a file
686+
* Other value is the number of the next cluster where the data for a file continues
687+
688+
For convenience, the "cluster is free" and "cluster is the last one of a file" flags are provided so that
689+
the first two cases can be easily detected without checking the value of the FAT entry itself.
690+
691+
FAT entries for FAT12 can be even or odd, as indicated by the "entry is odd" flag. The value is stored differently in each case;
692+
if "X" is the value of "offset in the FAT sector" and "peek(X)" is the byte value stored in X, then the value is:
693+
694+
* For even entries: `peek(X) + ((peek(X+1) and &HF) * 256)`
695+
* For odd entries: `((peek(X) \ 16) and &HF) + (peek(X+1) * 16)`
696+
697+
For convenience here's a diagram showing an example of FAT12 even and odd entries, based on the one present at
698+
[MSX2 Technical Handbook, chapter 3](https://github.com/Konamiman/MSX2-Technical-Handbook/blob/master/md/Chapter3.md):
699+
700+
```
701+
|4 bits |4 bits |
702+
FAT -----------------
703+
start address ->| F 0 | Media ID
704+
|---------------|
705+
+1 | F F | dummy entry
706+
|---------------|
707+
+2 | F F | dummy entry
708+
|---------------|
709+
+3 | 1 2 | Entry for cluster 2 : offset = 3, value = 412h (even entry)
710+
|---------------|
711+
+4 | 3 | 4 | Entry for cluster 3 : offset = 4, value = 563h (odd entry)
712+
|---------------|
713+
+5 | 5 6 |
714+
|---------------|
715+
+6 | 7 | 8 | Entry for cluster 4 : offset = 6, value = 978h (even entry)
716+
|---------------|
717+
+7 | | 9 |
718+
---------
719+
```
720+
721+
For FAT16 entries it's much simpler: these are stored in the byte at the specified offset and the next one in little endian, so `peek(X) + (256 * peek(X+1))`.
722+
723+
Note that if the offset in the FAT sector is 511, then the entry is split between the last byte in "FAT sector number that contains the entry" and the first byte of the next sector.
724+
This can happen on FAT12 only.
725+
726+
632727
## 4. New error codes
633728

634729
New error codes are defined to handle error conditions when managing the new features of Nextor. These errors are returned in MSX-DOS 1 mode as well by the new functions supported in this mode.
@@ -659,46 +754,126 @@ An attempt to open or alter a mounted file, or to perform any other disallowed o
659754

660755
Attempt to mount a file that is smaller than 512 bytes or larger than 32 MBytes.
661756

757+
* Invalid cluster number (.ICLUS, 0B0h)
758+
759+
The cluster number supplied to the [_GETCLUS](#314-get-information-for-a-cluster-on-a-fat-drive-_getclus-7eh) function doesn't exist in the drive.
760+
662761

663762
## 5. Extended mapper support routines
664763

665-
The original MSX-DOS 2 mapper support routines have been extended with two new functions that allow the allocation of small blocks of memory (from 1 to 16378 bytes) within an allocated or TPA segment. Entries for these functions are available as an extension of the mapper support routines jump table whose address can be obtained by using extended BIOS. The names and locations in the jump table of these new routines are:
764+
The original MSX-DOS 2 mapper support routines (see "5. Mapper support routines" in [MSX-DOS 2 Program Interface Specification](https://github.com/Konamiman/Nextor/blob/v2.1/docs/DOS2-PIS.TXT))
765+
have been extended with four new routines that allow reading data, writing data and calling routines placed in another RAM segment; they work
766+
much like the existing routines RD_SEG, WR_SEG, CAL_SEG and CALLS but they accept a pair of slot number + RAM segment number as input instead of only the RAM segment number.
767+
These routines are compatible with the [UNAPI RAM helper specification](https://github.com/Konamiman/MSX-UNAPI-specification/blob/master/docs/MSX%20UNAPI%20specification%201.1.md#4-the-ram-helper),
768+
including the extended BIOS based discovery mechanism; this means that any application program that relies on the presence of the UNAPI RAM helper will work out of the box
769+
with Nextor, without needing to first install a standalone helper.
770+
771+
The names and locations of these routines in the mapper support routines jump table is as follows:
666772

667773
```
668-
+30h: BLK_ALLOC
669-
+33h: BLK_FREE
774+
+30h: CALL_MAP
775+
+33h: RD_MAP
776+
+36h: CALL_MAPI
777+
+39h: WR_MAP
670778
```
671779

672-
Both routines work on the memory that is switched on page 2 at the moment of calling them. It may be an explicitly allocated segment, a TPA segment, or even non-mapped RAM: they will work on any writable memory that is visible on page 2. However a segment will be assumed to be switched on page 2 for documentation purposes.
673780

674-
Following is the description of these routines.
781+
### 5.1: CALL_MAP: Call a routine in a mapped RAM segment
675782

676-
### 5.1. BLK_ALLOC: Allocate a memory block
783+
* Input:
784+
* IYh = Slot number
785+
* IYl = Segment number
786+
* IX = Target routine address (must be a page 1 address)
787+
* AF, BC, DE, HL = Parameters for the target routine
788+
* Output:
789+
* AF, BC, DE, HL, IX, IY = Parameters returned from the target routine
677790

678-
```
679-
Entry: HL = Required size (1 to 16378 bytes)
680-
Returns: On success:
681-
HL = Address of the allocated block (always a page 2 address)
682-
A = 0 and Z set
683-
On error (not enough free space on segment):
684-
HL = 0
685-
A = .NORAM and Z reset
686-
```
791+
The routine will be called by switching the specified slot and segment in page 1, therefore the routine address must be in page 1 as well.
687792

688-
This routine tries to allocate a memory block of the specified size on the segment currently switched on page 2, and returns the address of the allocated block if it succeeds, or a "Not enough memory" error if not. The segment must have been previously initialized by calling the BLK_FREE routine with HL=0, otherwise the result is unpredictable.
689793

690-
### 5.2. BLK_FREE: Free a memory block
794+
### 5.2: RD_MAP: Read a byte from a RAM segment
691795

692-
```
693-
Entry: HL = Address of the allocated block as returned by BLK_ALLOC,
694-
or 0 to initialize the segment
695-
```
796+
* Input:
797+
* A = Slot number
798+
* B = Segment number
799+
* HL = Address to be read from (higher two bits will be ignored)
800+
* Output:
801+
* A = Data read from the specified address
802+
* F, BC, DE, HL, IX, IY preserved
803+
804+
805+
### 5.3: CALL_MAPI: Call a routine in a mapped RAM segment, with inline routine identification
806+
807+
* Input:
808+
* AF, BC, DE, HL = Parameters for the target routine
809+
* Output:
810+
* AF, BC, DE, HL, IX, IY = Parameters returned from the target routine
811+
812+
The routine is to be called as follows:
813+
814+
CALL CALLSEG
815+
816+
CALLSEG:
817+
CALL <address of CALL_MAPI>
818+
DB &Bmmeeeeee
819+
DB <segment number>
820+
;no RET is needed here
821+
822+
where
823+
824+
* `mm` is the mapper slot, as an index (0 to 3) in the mapper variables table provided by the standard mapper support routines
825+
(see "5.2 Mapper variables and routines" in [MSX-DOS 2 Program Interface Specification](https://github.com/Konamiman/Nextor/blob/v2.1/docs/DOS2-PIS.TXT)).
826+
827+
* `eeeeee` is the routine to be called, as an index (0 to 63) of a jump table that starts at address 4000h of the segment. That is, 0 means 4000h, 1 means 4003h, 2 means 4006h, etc.
828+
829+
The way to specify the mapper slot and the segment number is weird, but it allows to pack the entire call in five bytes. This allows to use this routine with hooks in the same way
830+
it's usually done with the BIOS routine CALLF.
831+
832+
833+
### 5.4: WR_MAP: Write a byte to a RAM segment
834+
835+
* Input:
836+
* A = Slot number
837+
* B = Segment number
838+
* E = Byte to write
839+
* HL = Address to be written to (higher two bits will be ignored)
840+
* Output:
841+
* A = Data readed from the specified address
842+
* F, BC, DE, HL, IX, IY preserved
843+
844+
845+
### 5.5. The UNAPI RAM Helper discovery procedure
846+
847+
Nextor implements the UNAPI RAM Helper discovery procedure in order to make these new mapper support routines compatible with the already existing
848+
[UNAPI RAM Helper specification](https://github.com/Konamiman/MSX-UNAPI-specification/blob/master/docs/MSX%20UNAPI%20specification%201.1.md#4-the-ram-helper).
849+
For reference, the discovery procedure is repeated here:
850+
851+
> To check for the presence of a RAM helper, and to obtain the address of its routines, EXTBIO (0FFCAh) must be called with DE=2222h, HL=0, and A=FFh. If the RAM helper is not installed, then HL=0
852+
> at output; otherwise the following register values will be returned:
853+
>
854+
> * HL = Address of a jump table in page 3
855+
> * BC = Address of the reduced mappers table in page 3 (zero if not provided)
856+
> * A = Number of entries in the jump table
857+
858+
In the case of Nextor the following applies:
859+
860+
* HL will point to the location of CALL_MAP (offset +30h from the start of the mapper support routines jump table).
861+
* BC will always be returned as zero (the reduced mappers table is mandatory for UNAPI RAM Helpers only when the mapper support routines are not present).
862+
* A will always be 4 (in the MSX UNAPI specification it's 3 since the WR_MAP routines is not defined - this is a non-breaking change).
863+
864+
865+
### 5.6. Breaking change notice
866+
867+
In versions of Nextor older than 2.1.0, including the alphas and betas of 2.1.0, the mapper support routines jump table area that is now used for the RD_MAP, WR_MAP, CALL_MAP and CALL_MAPI
868+
entry points was used for two different routines that are not available anymore, BLK_ALLOC and BLK_FREE; this represents a breaking change and existing applications making use of them
869+
will need changes.
696870

697-
This routine frees a memory block on the segment currently switched on page 2. The specified address must be a block address previously returned by the BLK_ALLOC routine on the same segment, otherwise the result is unpredictable. The freed space will become available for new allocations.
871+
Although not used by Nextor anymore, the source code of these removed routines is kept as part of the Nextor code base
872+
(at [source/kernel/bank4/bkalloc.mac](https://github.com/Konamiman/Nextor/blob/v2.1/source/kernel/bank4/bkalloc.mac)).
873+
This way, if you have an application that makes use of these routines you can simply incorporate the code from that file to your application and call the routines directly.
698874

699-
All the state information about allocated and free blocks is stored on the segment itself, Nextor does not store any internal information about block memory allocation. This means that when all the allocated blocks on a given segment are no longer needed, it is not needed to explicitly free all blocks one by one; instead, the segment may be overwritten with any other data, the segment itself may be freed, or (in case of TPA segments) application may terminate directly.
875+
You can read the documentation for the removed routines in [the Programmers Reference for Nextor 2.0](https://github.com/Konamiman/Nextor/blob/v2.0/docs/Nextor%202.0%20Programmers%20Reference.md#5-extended-mapper-support-routines).
700876

701-
When called with HL=0, this routine initializes the segment currently switched on page 2 for block memory allocation. It is necessary to do this once before performing any block allocation on the segment. Also, this is useful on segments that already have allocated blocks, as a fast way to free all blocks at once.
702877

703878
## 6. Other features
704879

0 commit comments

Comments
 (0)