Free Pascal with initial MSX-DOS support

بواسطة PascalDragon

Supporter (9)

صورة PascalDragon

06-06-2020, 20:16

In the last few weeks I've familiarized myself a bit with MSX, MSX-DOS and Z80 and managed to start initial support for a MSX-DOS target in Free Pascal (only as a cross compiler as FPC is definitly too heavy to run on MSX). Please note that this is highly experimental and in its initial state.That said a simple HelloWorld program like the following does work already:

program tmsx;

{$MEMORY 1024,1024}

begin
  Writeln('Hello World');
end.

Compiled with (on Windows):

.\compiler\ppcrossz80.exe -n -viwn -Furtl\units\z80-msxdos -CX -XX -Tmsxdos -otmsx.com tmsx.pp

And then run inside OpenMSX running Nextor.

The compiler currently generates rather verbose code and you need to take care yourself that you don't link in more code than can fit into the TPA (including heap and stack). But at least with -CX -XX smart linking is enabled which means that code (and data) that is not used is not included in the final binary.

I've written up some more details (including differences to TP 3.0) on the Free Pascal Wiki.

Login أوregister لوضع تعليقاتك

بواسطة Manuel

Ascended (16696)

صورة Manuel

06-06-2020, 21:51

Wow, that looks pretty cool. I do wonder, although you are using MSX-DOS2 (which would be good to mention more clearly, as MSX-DOS2 does need extra hardware on your MSX to run, unless you have a turboR), you say that stuff like MkDir isn't supported. But that's one of the main features of MSX-DOS2, the support for subdirectories. So I wonder what's going wrong there... How is that stuff implemented? I'd say you need an MSX-DOS2 specific implementation.

Anyway, if there's something we can do to help you regarding MSX, please let us know.

بواسطة PascalDragon

Supporter (9)

صورة PascalDragon

06-06-2020, 22:56

For now I've restricted it to MSX-DOS 2 (which is mentioned in the Overview on the Wiki), because it is easier to implement most functionality without special handling, because if I understand this right then DOS calls like Write to File Handle are only available in MSX-DOS 2 and without these one would need to differentiate between e.g. the console (call Console Output) or files (call Sequential Write (FCB)), something that I don't want to do while the code generator is in its current state (not to mention that it would mean larger binary size).

And the mentioned page also answers your other question: I'm aware that MSX-DOS 2 supports directories (I've used that myself in the emulator), but what it does not seem to support is a DOS call to create one or to change the current directory or drive, which buffled me even more. I'd be very happy if you'd tell me differently however.

The necessary calls to interact with the operating system are already target specific. For example the low level functions to interact with files are in the sysfile.inc include file and those for directories are in the sysdir.inc include file. While the former are all implemented (except for do_truncate, do reduce the size of a file) the latter are all dummied out, because I've not yet found a suitable implementation for them (as mentioned above).

بواسطة Manuel

Ascended (16696)

صورة Manuel

07-06-2020, 00:01

E.g. see this list: http://map.grauw.nl/resources/dos2_functioncalls.php

I did see you mentioned MSX-DOS version 2, but IMHO it should be mentioned much more prominently. E.g. this thread says "MSX-DOS", not "MSX-DOS 2". It's a huge difference :)

بواسطة rolandve

Master (218)

صورة rolandve

07-06-2020, 08:53

Looks great, the part where the compiler leaves out unused stuff, is really great. Both TP3 and ASCII C keep the unused code which can really bloat a program if you develop stuff e create test routines, variables you will not use on a later date etc.

Mixing MSX-DOS2 and DOS can be confusing, is the second DOS MSX-DOS1 or just an abbreviation? MSX-DOS2 function 5Ah is change current directory. 44h is Create_fileHandle and if you want to create a subdirectory you will need to supply the attributes with the directory flag set

Something for my wishlist perhaps. TP has two very useful arrays: mem[unsigned integer] and port[unsigned byte] that give direct access to the memory addresses and ports. mem[10000]:=0 is equivalent to poke 10000,0 and port[$A8],0 is the equivalent to out $A8,0 (z80 assembly) while byte:=port[$a9] is the equivalent of in (z80 assembly). Allowing direct access to ports is very useful, because, for example, they allow us to address the VDP (or any other port device) directly, so you can write to the display much faster than through BIOS.

بواسطة PascalDragon

Supporter (9)

صورة PascalDragon

07-06-2020, 10:19

Manuel wrote:

I did see you mentioned MSX-DOS version 2, but IMHO it should be mentioned much more prominently. E.g. this thread says "MSX-DOS", not "MSX-DOS 2". It's a huge difference Smile

Well, my long term plan is to support MSX-DOS 1 as well. Whether I'll be able to support it with the same RTL or one needs to enable it with a special compiler option needs to be seen (e.g. for the Amiga target support for the really old Amiga versions requires a recompile of the RTL with a special define as well).

rolandve wrote:

Looks great, the part where the compiler leaves out unused stuff, is really great. Both TP3 and ASCII C keep the unused code which can really bloat a program if you develop stuff e create test routines, variables you will not use on a later date etc.

More precisely it's the linker and not the compiler. FPC can use the linker provided by SDCC as well as its own internal linker and that will work for both cases.

rolandve wrote:

Mixing MSX-DOS2 and DOS can be confusing, is the second DOS MSX-DOS1 or just an abbreviation? MSX-DOS2 function 5Ah is change current directory. 44h is Create_fileHandle and if you want to create a subdirectory you will need to supply the attributes with the directory flag set

Do you know the feeling of not seeing the forest due to all the trees? I've read through the list that Manuel had linked (and I had linked as well) multiple times while working on getting this target working but do you think I've noticed the Get Current Directory and Change Current Directory calls? No, of course I did not... *facepalm* So think you for the hint and also for the one about creating a subdirectory. That will allow me to implement more. Smile

rolandve wrote:

Something for my wishlist perhaps. TP has two very useful arrays: mem[unsigned integer] and port[unsigned byte] that give direct access to the memory addresses and ports. mem[10000]:=0 is equivalent to poke 10000,0 and port[$A8],0 is the equivalent to out $A8,0 (z80 assembly) while byte:=port[$a9] is the equivalent of in (z80 assembly). Allowing direct access to ports is very useful, because, for example, they allow us to address the VDP (or any other port device) directly, so you can write to the display much faster than through BIOS.

The mem array is already provided. See here.

The ports are on my ToDo list, I first need to implement two intrinsics so that the compiler can freely pick the register that is used together with IN and OUT. For how it's going to be implemented see the include for i8086. Thanks to the inline directive of the getter and setter and the use of the intrinsic the compiler will be able to completly inline the assembler directive without any call involved. ;)

بواسطة rolandve

Master (218)

صورة rolandve

07-06-2020, 11:03

I know the feeling: somewhere in this pile of documentation, you'll find the answer but where... Happy that you can continue Smile Skipping call's is a great performance improvement. Do you have plans to add MSX specific functions like screen, width, line, etc, etc. TP3 doesn't support MSX specific functions, so a lot of code in pascal boil's down to assembly, jumping to BIOS functions or performing loops on variables type string[xx] sending that data through the BIOS.

بواسطة pgimeno

Master (188)

صورة pgimeno

07-06-2020, 13:40

Wow, that was fast! Kudos for the achievement!

بواسطة PascalDragon

Supporter (9)

صورة PascalDragon

07-06-2020, 14:48

PascalDragon wrote:

The ports are on my ToDo list, I first need to implement two intrinsics so that the compiler can freely pick the register that is used together with IN and OUT. For how it's going to be implemented see the include for i8086. Thanks to the inline directive of the getter and setter and the use of the intrinsic the compiler will be able to completly inline the assembler directive without any call involved. ;)

Ports are now implemented as well. The following code:

var
  b: Byte;
  p: Byte;
begin
  b := port[$2e];
  port[$2e] := b;
  p := $2e;
  b := port[p];
  port[p] := b;
end.

will compile to this:

	.area _CODE
main::
PASCALMAIN::
; [tmsx.pp]
; [4] begin
		push	ix
		ld	ix,#0
		add	ix,sp
		call	fpc_initializeunits
; [5] b := port[$2e];
		in	a,(46)
		ld	(U_$P$TMSX_$$_B),a
; [6] port[$2e] := b;
		ld	a,(U_$P$TMSX_$$_B)
		out	(46),a
; [7] p := $2e;
		ld	a,#46
		ld	(U_$P$TMSX_$$_P),a
; [8] b := port[p];
		ld	a,(U_$P$TMSX_$$_P)
		ld	c,a
		in	a,(c)
		ld	(U_$P$TMSX_$$_B),a
; [9] port[p] := b;
		ld	a,(U_$P$TMSX_$$_B)
		ld	b,a
		ld	a,(U_$P$TMSX_$$_P)
		ld	c,a
		out	(c),b
; [10] end.
		call	fpc_do_exit

As you can see, no calls related to the ports. ;)

rolandve wrote:

I know the feeling: somewhere in this pile of documentation, you'll find the answer but where... Happy that you can continue :) Skipping call's is a great performance improvement. Do you have plans to add MSX specific functions like screen, width, line, etc, etc. TP3 doesn't support MSX specific functions, so a lot of code in pascal boil's down to assembly, jumping to BIOS functions or performing loops on variables type string[xx] sending that data through the BIOS.

It would make sense to add MSX specific functionality (probably in a MSX unit). How much I'll do, I don't know, but that is the nice part about Open Source: you can contribute as well. ;) Though in FPC most MSX related functions will boil down to assembly as well, but the user of these functions does not have to deal with the details. :)

pgimeno wrote:

Wow, that was fast! Kudos for the achievement!

Well, popolony2k had asked on one of our mailing lists, but then there was no sign of him anymore, so I thought I'd go into the initiative and start at least a MSX-DOS (2) port. A pure MSX port (without DOS) would be a next potential step. And I'm really intrigued by Symbos as well.

بواسطة Giangiacomo Zaffini 2

Master (211)

صورة Giangiacomo Zaffini 2

07-06-2020, 16:22

I understand that something is happening for good on FreePascalCompiler for Z80 and MSX.
Have PascalDragon open a thread of discussion about that on Lazarus forum for FPC?

بواسطة PascalDragon

Supporter (9)

صورة PascalDragon

07-06-2020, 16:59

I think most people that are interested in FPC on MSX will be found here, especially those that have experience in using Turbo Pascal. Also I usually don't start new forum threads on the Lazarus forum about new targets, normally I simply post an announcement to the mailing lists and that's it (though this time I haven't done this yet, maybe I should change that Wink ). But if someone is interested in starting a discussion on the Lazarus forum, be my guest.