Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stepping towards a multi-target compiler #82

Open
neilsf opened this issue Nov 17, 2019 · 14 comments
Open

Stepping towards a multi-target compiler #82

neilsf opened this issue Nov 17, 2019 · 14 comments
Milestone

Comments

@neilsf
Copy link
Owner

neilsf commented Nov 17, 2019

The compiler is currently targeted to C64 only. Many users have already suggested that it should be possible to compile XC=BASIC programs to other platforms e.g Plus/4, C16, VIC-20, BBC Micro, the upcoming X16, and others.

This task requires involvement of developers who are familiar with the new target systems.

Here is a brief explanation of the current library system for reference. The compiler includes the following libraries in the intermediate assembly source:

  • lib/nucleus.asm - Not really a library, but a bunch of pseudo-op definitions. The compiler translates the program to these pseudo-ops. This file is always included.
  • lib/stdlib.asm - The standard library containing routines required for I/O, random numbers and memory setup. This file is always included.
  • lib/strings.asm - Library containing the string handling routines. Included only if strings are used in the program.
  • lib/mem.asm - Library containing the memory manipulation routines. Included only if commands like MEMSET, MEMSHIFT, etc. are used in the program.
  • lib/opt.asm - This is again rather a set of macros required by the optimizer.

For the future I envision a library structure something similar to the following:

lib/
  c64/
    stdlib.asm
  plus4/
    stdlib.asm
  vic20/
    stdlib.asm
  nucleus.asm
  strings.asm
  mem.asm
  opt.asm

Meaning that all platform-agnostic libraries go to the library root and and all platform-specific libraries go to their own dir.

The following steps are required (in a nutshell):

  1. Move all platform-specific code from the nucleus to the standard library or another library. Strings and memory libraries are (should be) already platform-agnostic. It is possible that we will need to exclude floating point ops to a separate library as well.
  2. Check the compiler's source - it should not include any platform-specific code in the assembly source.
  3. Write the standard libraries for each platform - DEVELOPERS, DEVELOPERS, DEVELOPERS!
  4. Add a PRAGMA directive that instructs the compiler which platform to target to.
  5. Test
  6. Happiness

Please add your thoughts and/or let me know if you can help in coding. Thanks.

@Majikeyric
Copy link
Collaborator

Majikeyric commented Nov 17, 2019

I can help with C16 (CPlus/4 = C16 with 64K) and VIC20. Their architecture is not so different than the C64.
The VIC20 can have multiple memory configurations (not expanded, +3K and >=+8K ) maybe it would be better with the PRAGMA directive to select one of the 3 memory configurations for VIC20.
according to the memory configuration selected, the start address of basic programs and the addresses of the screen and colors locations are differents.
With the VIC20 you can't bank out BASIC or KERNAL, there is no mechanism like the C64 with $01 register. the biggest contiguous chunk of memory available will be 28K ($1000-$7fff) with the >=+8K configuration. There could be 8KB of more RAM but they are located after CHARGEN and IOs areas in memory (at $a000-$bfff)

With the CPlus/4, BASIC+KERNAL are located at $8000-$FCFF, they take half of the memory. they can be banked out to access ram under but they are only banked out simultaneously.
CPlus/4 can access all ram, when C16 ram is located at $0000-$3fff

@neilsf
Copy link
Owner Author

neilsf commented Nov 17, 2019

Thanks!

To tell the truth, there is no upper memory limit check currently. As long as DASM compiles the intermediate code (I think up until $FFFF), no error will occur. So this is again another task - to set up some limit check depending the platform and configuration (using PRAGMA as you suggest).

Are BASIC/KERNAL floating point routines in Plus/4, C16 and VIC20 the same? XC=BASIC does not have its own floating point library, it just uses the FP routines in BASIC/KERNAL (temporarily banking it in for the calculations).

The rest seems okay, I think I'll start with separating the nucleus and the libs and when it's done I'll ask you to do the other platforms.

@Majikeyric
Copy link
Collaborator

FP routines in CPlus/4 and VIC20 should be at different addresses but work like the C64.

@neilsf
Copy link
Owner Author

neilsf commented Nov 21, 2019

Hi @Majikeyric

I have created a new branch feature/multiarch. It contains all the necessary changes for you to start working on the c16 and vic-20 platforms.

Let me provide you some basic information. The lib directory now contains subdirs for each platform. In each platform subdir you'll find:

  • psregs.asm - this defines the ZP addresses that are reserved for the XC=BASIC runtime. Maybe you'll leave it as it is if its okay for your platforms.
  • fpaddr.asm - this defines the BASIC FP routine addresses - may require changing.
  • stdlib.asm - this is the most important, the library that has to be implemented for each system. Please take the one in the c64 dir for reference. You must implement all constants, macros and subroutines that are found in this file.

(I wasn't sure if I should make 1 or 2 dirs for c16 and plus/4, we can discuss this later.)

There's a new PRAGMA directive that looks like this:

pragma target = "c16"
pragma target = "c64"
pragma target = "cplus4"
pragma target = "vic20"

This tells the compiler which platform to compile to. Defaults to "c64".

I have only did a couple of tests (you'll find it in tests/multiarch.bas) but it seems to be working so far - I mean no regression at least.

It is worth noting that whenever you change a file in the lib directory, xcbasic64 must be recompiled. You'll need the dmd compiler and the dub package manager for this purpose. The command to recompile is dub build --force.

Please contact me in email (feketecsaba [at] gmail) if you need to discuss the details.

Thank you so much and welcome aboard! I'm very excited about this new feature as it opens the door to other retro worlds!

PS. Some addresses are still hard-coded, e. g $0400 and $0801. We'll have to discuss these...

@Majikeyric
Copy link
Collaborator

Majikeyric commented Nov 22, 2019

Thanks for the info ! I'm excited too helping porting XCBASIC to other platforms I love (with the C64!).
I must launch the "dub build --force" command at the root of feature/multiarch ?
I get errors... I have installed dmd2 and there is the dub.exe in its bin directory. I suppose it's ok

@Majikeyric
Copy link
Collaborator

Majikeyric commented Nov 22, 2019

The VIC20 implementation is complete there are a lot of similarities with the C64.
I can't do a "push upsteam", I get an authentication failed error, I don't know why....

BUT there are 3 different memory configurations for VIC20. So I don't how you can deal with it.
unexpanded:
basic start: $1001
highest ram address : $1fff
screen: $1e00
colors: $9600

3K expansion:
basic start: $0401
highest ram address : $1fff
screen: $1e00
colors: $9600

8K expansion and more:
basic start: $1201
highest ram address : $7fff
screen: $1000
colors: $9400

some remarks:

The STDLIB_MEMSETUP SUBROUTINE is not required as there is no bank switching on VIC20 so I just let a RTS if you call it anyway.

STDLIB_RND SUBROUTINE
I knew this RND routine, there is an errror, a missing CLC
see http://sleepingelephant.com/ipw-web/bulletin/bb/viewtopic.php?f=2&t=2304
(first post from Kweepa)

The current device number is probably hardcoded ? ($BA)
$BA is ok for VIC20 but it is $AE for C16/+4

$02fe-$02ff location to store USR function return address should be ok on VIC20/C16+4

Does XCBASIC check when C64 code is located at $a000-$bfff ? and how does it manage the BASIC banking-in in this case ?

There will a bit more complex case with C+4, as ROMs (BASIC+KERNAL) are located at $8000-$ffff and can only be turned on/off at once, not separately.
For the CPU to read RAM at that location, the complete ROM (BASIC+KERNAL) must be disabled involving the IRQs to be disabled as well.
if code is located above $8000 it can't access BASIC and KERNAL routines directly from there.

EDIT
maybe it could be solved using IRQ/KERNAL/BASIC calls wrappers allowing to use 64K RAM permanently. code below should be located < $8000.

IRQ call :

bintr
STA $FF3E ;enables ROM
STA *+11 ;saves AC
LDA #>rintr
PHA
LDA #<rintr
PHA
PHP
LDA #0
PHA
TXA
PHA
TYA
PHA
JMP ($314) ;ROM IRQ handler
rintr
STA $FF3F ;turn RAM on
RTI

You should place bintr address to $fffe.

KERNAL/BASIC calls:

SEI
STA $FF3E ;enables ROM
jsr xxxx
STA $FF3F ;turn RAM on
CLI
RTS

@neilsf
Copy link
Owner Author

neilsf commented Nov 24, 2019

Thanks for the info ! I'm excited too helping porting XCBASIC to other platforms I love (with the C64!).
I must launch the "dub build --force" command at the root of feature/multiarch ?
I get errors... I have installed dmd2 and there is the dub.exe in its bin directory. I suppose it's ok

On Windows you have a DUB command line launcher in your start menu. Run it and cd to the project root. Then issue the command and it should run fine. It creates the xcbasic64.exe which you should copy to the bin directory. What errors do you get?

@neilsf
Copy link
Owner Author

neilsf commented Nov 24, 2019

BUT there are 3 different memory configurations for VIC20.

I think I'll add a PRAGMA for this. Now I see that it's very important to make BASIC start and screen addresses variable...

I'll move on to your other questions a bit later, my weekend is busy, sorry.

@neilsf
Copy link
Owner Author

neilsf commented Nov 24, 2019

I can't do a "push upsteam", I get an authentication failed error, I don't know why....

I added you as a collaborator now, maybe this will solve it.

@neilsf
Copy link
Owner Author

neilsf commented Nov 24, 2019

Does XCBASIC check when C64 code is located at $a000-$bfff ? and how does it manage the BASIC banking-in in this case ?

It is not checked at all :-( To be honest I think this is a minor issue now as BASIC is only banked in for floating point routines. If the program doesn't use floats then BASICIN/BASICOUT will only be called on the program start/end. Three options I can see now for fixing this:

  • If the program uses floats and code goes beyond $a000, display an error and stop compilation.
  • Extract FP routines from ROM to a separate library and load it to RAM instead of using ROM. This was actually my first idea but I dropped it because I had license concerns. I think BASIC ROM (and parts of it) has a protected license.
  • Use a different FP library (Woz FP routines maybe)

+1 idea: drop floats and use fixed point.

@neilsf
Copy link
Owner Author

neilsf commented Nov 24, 2019

STDLIB_RND SUBROUTINE
I knew this RND routine, there is an errror, a missing CLC

Can you please fix and also add a reference in a comment. I think I forgot to add credits/reference. Thanks

@neilsf neilsf added this to the Version 2.3 milestone Nov 24, 2019
@neilsf
Copy link
Owner Author

neilsf commented Nov 25, 2019

I have pushed some code change that gives us these new PRAGMAs:

pragma vic20_memsetup = "default" : rem can be "default", "3k" or "8k"
pragma c64_screen_memory = $0400 : rem can be any value

CHARAT and TEXTAT now takes into account the above settings. I have difficulties with testing on VIC-20, TEXTAT is yet buggy in some situations. I haven't yet tested on Plus/4 at all.

P.S. @Majikeyric would you like to join the XC=BASIC Slack channel where we can discuss the details? I can send you an invitation. Or do you have any other preferred communication method?

@Majikeyric
Copy link
Collaborator

CHARAT and TEXTAT now takes into account the above settings. I have difficulties with testing on VIC-20, TEXTAT is yet buggy in some situations. I haven't yet tested on Plus/4 at all.

the VIC20 screen by default at startup has 23 rows and 22 columns (but it can be changed by writing to registers).
to get screen dimensions in real time:
lda $9002
and #$7f
sta columns
lda $9003
lsr
and #$3f
sta rows

I haven't completely implemented C16/Plus/4 yet

P.S. @Majikeyric would you like to join the XC=BASIC Slack channel where we can discuss the details? I can send you an invitation. Or do you have any other preferred communication method?

yes sure! and yes I like Slack! :)

@neilsf
Copy link
Owner Author

neilsf commented Nov 25, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants