[MSX-C] Q&A official thread

Страница 10/56
3 | 4 | 5 | 6 | 7 | 8 | 9 | | 11 | 12 | 13 | 14 | 15

By Grauw

Ascended (9156)

Аватар пользователя Grauw

04-09-2015, 15:55

JaviLM wrote:

Note that there is no RET because it won't get executed anyway. When you do a HALT the CPU freezes at that point, and only wakes up to run the interrupt routines.

That’s not correct… Execution will continue after the halt once an (any) interrupt has occurred, so the ret will be executed. (Unless interrupts were disabled (di) of course, in which case it hangs the computer.) Nevertheless, as I said, halt is not the right tool to use to achieve vsync.

AxelStone wrote:

It seems better solution that mine. I've read thay "JIFFY is same thing as TIME in BASIC". How can we do that in C?

Yes, JIFFY is the 16-bit value at address FC9EH. See Sylvester’s example.

By AxelStone

Prophet (2744)

Аватар пользователя AxelStone

04-09-2015, 16:07

Definitively JIFFY solution is the best. Since it works as TIME in BASIC, you can handle the desired fps of your game simply looping this variable. For example:

vertscr() {
	TINY i;
	for(i=0;i<212;i++){
		JIFFY=0;
		wrtvdp(VREG23,i);
		/* Wait for interrupt */
		while (JIFFY<2) {}
	}
}

We waits for 2 cycles of VDP, this is, we are setting the game at 30fps instead of 60fps.

By Sylvester

Champion (433)

Аватар пользователя Sylvester

04-09-2015, 19:16

ok, an other question, how can I show a directory listing in C. Because there are no opendir, readdir and closedir functions available.

By AxelStone

Prophet (2744)

Аватар пользователя AxelStone

05-09-2015, 01:50

Sylvester wrote:

ok, an other question, how can I show a directory listing in C. Because there are no opendir, readdir and closedir functions available.

It's true, they don't exists, I didn't find anything to use in Bios too. Perhaps we need to invoke MSX-DOS functions? Is there any way?

By anonymous

incognito ergo sum (109)

Аватар пользователя anonymous

05-09-2015, 08:35

Sylvester wrote:

ok, an other question, how can I show a directory listing in C. Because there are no opendir, readdir and closedir functions available.

I don't know about this, yet. Worst case scenario: we have to make a function using MSX-DOS(2)'s system calls, which we have seen already isn't complicated.

I'll find out in a few days.

By AxelStone

Prophet (2744)

Аватар пользователя AxelStone

05-09-2015, 12:26

JaviLM wrote:

I don't know about this, yet. Worst case scenario: we have to make a function using MSX-DOS(2)'s system calls, which we have seen already isn't complicated.

I'll find out in a few days.

Hi JaviLM, we have talked about wrap MSX-DOS2 mapper functions to use in MSX-C, but really we have not seen an usage example still. I'm reading bdosfunc.h file and it has a lot values defined and a few functions at the end. For example:

#define _FORMAT (TINY)0x67 /* Format disk */

We have defined the following functions: bdosh(), call(), bdos(), calla(), bios(), callxx(). Since #defines are defining TINY values (this is, char), I suposse that correct functions to use are:
char bdos(c)
char c;
int bdosh(c)
char c;

Both of them are expecting a char parameter, so a call to MSX-DOS format function could be:

bdos(_FORMAT);

It's that right? Since we are talking about MSX-DOS(2) call functions, it should be a good moment to see how we can wrap mapper functions to use in MSX-C Wink

Once again, thanks.

By Grauw

Ascended (9156)

Аватар пользователя Grauw

05-09-2015, 14:07

Note that mapper functions aren’t accessed through the BDOS (5H) calls, but in stead through a jump table whose address can be determined with an EXTBIO (FFCAH) call. See the DOS2 environment documentation. Directory listing functions are accessed through the BDOS though.

By AxelStone

Prophet (2744)

Аватар пользователя AxelStone

05-09-2015, 14:47

Grauw wrote:

Note that mapper functions aren’t accessed through the BDOS (5H) calls, but in stead through a jump table whose address can be determined with an EXTBIO (FFCAH) call. See the DOS2 environment documentation. Directory listing functions are accessed through the BDOS though.

It's strange, bdos syntax don't adjust to the docs you attach. Take for example _FORMAT function. If we use bdos function of MSX-C, the syntax is:

Quote:

char bdos(c)
char c;

You only passes a char as parameter. However in your page, it's supossed to operate with registers:

Quote:

3.83 FORMAT A DISK (67H)
Parameters: C = 67H (_FORMAT)
B = Drive number (0=>current, 1=>A:)
A = 00H => return choice string
01H...09H => format this choice
0AH...FDH => illegal
FEH, FFH => new boot sector
HL = Pointer to buffer (if A=1...9)
DE = Size of buffer (if A=1...9)
Results: A = Error
B = Slot of choice string (only if A=0 on entry)
HL = Address of choice string (only if A=0 on entry)

What function of MSX-C should be the correct? Thanks.

By anonymous

incognito ergo sum (109)

Аватар пользователя anonymous

05-09-2015, 16:53

AxelStone wrote:

Hi JaviLM, we have talked about wrap MSX-DOS2 mapper functions to use in MSX-C, but really we have not seen an usage example still.

Challenge accepted! :-)

By anonymous

incognito ergo sum (109)

Аватар пользователя anonymous

07-09-2015, 17:28

AxelStone wrote:

Hi JaviLM, we have talked about wrap MSX-DOS2 mapper functions to use in MSX-C, but really we have not seen an usage example still.

Sylvester wrote:

ok, an other question, how can I show a directory listing in C. Because there are no opendir, readdir and closedir functions available.

Let me try and answer both at the same time.

How to encapsulate and use MSX-DOS2 system calls in MSX~C

Let's look at a couple of MSX-DOS2 system calls: _FFIRST (040h) and _FNEXT (041h). To see what they do, check Grauw's function reference (this link).

_FFIRST takes these parameters:

  • Register DE contains the address of a C string containing a filename pattern ("*.*", "FILE*.*", "a:\tmp\", etc)
  • Register B contains a bitmask that defines what kind of files/directories this system call will find.
  • Register IX contains the address of an empty File Info Block, that will be updated with the file's details, if any file matches

To run this system call from MSX-DOS2 first we put the registers in a struct of type XREG, and then call callxx(). callxx() fills the XREG struct with the values returned by the system call. This is how I encapsulated this call in MSX-C in my tests:

VOID	_ffirst(pattern, fib, regs)
char	*pattern;
FIB	*fib;
XREG	*regs;
{
	regs->bc = SEARCH_MASK | (unsigned)_FFIRST;
	regs->de = (unsigned)pattern;
	regs->ix = (unsigned)fib;
	callxx(BDOS, regs);
}

The parameters for _ffirst() are:

  • A pointer to a string containing the file pattern
  • A pointer to a File Info Block that will be filled with information about the file
  • A pointer to an XREGS struct so we can inspect the result from the main program

_FNEXT is a bit simpler:

  • Register B contains a bitmask that defines what kind of files/directories this system call will find.
  • Register IX contains the address of the File Info Block that resulted from calling _FFIRST.

I’ve implemented it like this:

VOID	_fnext(fib, regs)
FIB	*fib;
XREG	*regs;
{
	regs->bc = SEARCH_MASK | (unsigned)_FNEXT;
	regs->ix = (unsigned)fib;
	callxx(BDOS, regs);
}

How to read directories in MSX-C

To show how this works, I’ve written a very basic implementation of opendir() that just prints the list of files found on the screen. A more serious version would return a pointer to an array of structs describing the files, but for demonstration purposes this will be enough.

Here’s the full program:

#include <stdio.h>
#include <bdosfunc.h>

#define	S_RO		0x01
#define	S_HIDDEN	0x02
#define	S_SYSTEM	0x04
#define	S_VOLUME	0x08
#define	S_DIRECT	0x10
#define	S_ARCHIV	0x20
/* reserved		0x40 */
#define	S_DEVICE	0x80

#define	SEARCH_MASK	(unsigned)((S_RO|S_HIDDEN|S_SYSTEM|S_DIRECT) * 256)

VOID	_ffirst(pattern, fib, regs)
char	*pattern;
FIB	*fib;
XREG	*regs;
{
	regs->bc = SEARCH_MASK | (unsigned)_FFIRST;
	regs->de = (unsigned)pattern;
	regs->ix = (unsigned)fib;
	callxx(BDOS, regs);
}

VOID	_fnext(fib, regs)
FIB	*fib;
XREG	*regs;
{
	regs->bc = SEARCH_MASK | (unsigned)_FNEXT;
	regs->ix = (unsigned)fib;
	callxx(BDOS, regs);
}

VOID	opendir(pattern)
char	*pattern;
{
	FIB		fib;
	BOOL		done;
	XREG		regs;

	/* Make sure the whole FIB is set to 0			*/
	memset(&fib, (char)0, sizeof(FIB));

	/* Search for first entry */
	_ffirst(pattern, &fib, &regs);

	if (!(regs.af & 0xff00)) {
		/* Found at least one matching file	*/
		printf("Found: %s\n", fib.name);

		/* Look for more matches		*/
		done = FALSE;

		while(!done) {
			_fnext(&fib, &regs);
			if (regs.af & 0xff00) {
				done = TRUE;
			} else {
				printf("Found: %s\n", fib.name);
			}
		}
	}
}

char	main(argc, argv)
int	argc;
char	*argv[];
{
	if (argc < 2) {
		printf("Usage: opendir \n");
		exit(0);
	}

	printf("Pattern: %s\n", argv[1]);
	opendir(argv[1]);
}

Compile it with this script:

cf opendir
cg -k opendir
m80 =opendir/z
rem del %1.mac
l80 a:\msxc\lib\ck,opendir,a:\msxc\lib\mlib/s,a:\msxc\lib\clib/s,a:\msxc\lib\crun/s,a:\msxc\lib\cend,opendir/n/y/e:xmain


This will generate a program called OPENDIR.COM. Run it with a parameter to list files and directories:

  • OPENDIR a:¥
  • OPENDIR *.COM
  • OPENDIR *.*
Страница 10/56
3 | 4 | 5 | 6 | 7 | 8 | 9 | | 11 | 12 | 13 | 14 | 15