Jump to content
  • 0
ZeroByte

pre-R49 cc65 question

Question

I'm trying working to make a quick pull request to fix the YM2151 clock frequency on github (still gotta figure out how that works using the command line but not asking that here) and so I recompiled my AdLib emulation demo to see that the playback pitch is correct with my setting - but my program doesn't run because waitvsync() seems broken in cc65 on the main branch....

I don't want to update cc65 yet because I don't want to mess with cc65 at the moment because I don't want to inadvertently break my ability to write for R38 until R39 is official. Does anyone know what breaks about waitvsync() in "R39" and what a workaround might be?

I did load one of my BASIC programs that plays music, and it's correct pitch on that, and poking a concert A into the YM produced the correct pitch, so I'm already convinced, but I wanted to hear music play back correctly before making the decision to submit my pull request.

Share this post


Link to post
Share on other sites

Recommended Posts

  • 0
Posted (edited)

It's broken for two reasons:

  1. The RAM banking method changed (my version of cc65 still uses the VIA banking method)
  2. The address in BANK 0 for the jiffy timer changed to 0xa043

waitvsync() just waits for that value to change, as the kernal inc's it during each vblank IRQ from VERA.

Here's a myvsync() routine to fix it until such time as cc65 is updated:

#define time (*(uint8_t *) 0xa043)
#define rambank (*(uint8_t *) 0x0000)

static void myvsync()
{
    uint8_t b,j; // bank, jiffy
    b = rambank;
    rambank = 0;
    j = time;
    while (time==j) {};
    rambank=b;
}

 

Edited by ZeroByte
added what my workaround code is
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, ZeroByte said:

The address in BANK 0 for the jiffy timer changed to 0xa043

Hm, wondering why it is reading the internal variable directly and depending on its location, rather than using RDTIM kernal call?

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, desertfish said:

Hm, wondering why it is reading the internal variable directly and depending on its location, rather than using RDTIM kernal call?

Probably because it only takes around 6 cycles per loop to just CPA $a043 ; BEQ -

doing a kernal call would take tons more time. I totally get why you're not supposed to use Kernal stuff directly, but a function like this kind of makes sense, and some time in the future, the kernal will be pretty much stabilized and not change anymore except if someone wants to tinker with their system.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
17 minutes ago, ZeroByte said:

Probably because it only takes around 6 cycles per loop to just CPA $a043 ; BEQ -

doing a kernal call would take tons more time. I totally get why you're not supposed to use Kernal stuff directly, but a function like this kind of makes sense, and some time in the future, the kernal will be pretty much stabilized and not change anymore except if someone wants to tinker with their system.

Yep!  We want waitvsync() to stop waiting, after a VSYNC, as soon as it's conveniently possible.  The ideal method would "plug" into the interrupt vector, but that way is more complex.  And, it might interfere with other interrupt handlers.  I chose to make the function small and benign.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

True about the performance, but the kernal call would not require changes when the rom is rebuilt . Choice depends on what you value more in your use case of course !

Share this post


Link to post
Share on other sites
  • 0

I branched the cc65 repo and started changing the cx16 lib. It now works with Invaderz and Brixx and both would now run on R39.

In case anyone wants to check it out:
https://github.com/AndyMt/cc65

I'll do some more testing myself before creating a pull request.

  • Like 3

Share this post


Link to post
Share on other sites
  • 0
6 hours ago, AndyMt said:

I branched the cc65 repo and started changing the cx16 lib.

It's really going to be the viability of the cc65 tool chain that dictates when I migrate, so this is good news.

Share this post


Link to post
Share on other sites
  • 0
14 hours ago, AndyMt said:

I branched the cc65 repo and started changing the cx16 lib. It now works with Invaderz and Brixx and both would now run on R39.

Annnnnnnd it's gone!

Looks like the RTC is going to be supported now and the timej variable isn't being set in the same way - or at least the location your mod for waitvsync() uses doesn't work for me with a fresh download of the rom and emulator....

Share this post


Link to post
Share on other sites
  • 0
35 minutes ago, ZeroByte said:

Annnnnnnd it's gone!

Looks like the RTC is going to be supported now and the timej variable isn't being set in the same way - or at least the location your mod for waitvsync() uses doesn't work for me with a fresh download of the rom and emulator....

I'm seeing a different value for the `.timer` address in kernal.sym than either of you with my build of the x16-rom repo on the master branch: `A03D` versus  `A043` or `A041` in Andy's repo.  There may be too many moving parts at this point between the rom and cc65's cx16.lib.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
6 minutes ago, ChrisL said:

master branch: `A03D` versus  `A043` or `A041` in Andy's repo.

I just found it a few minutes ago myself. I'm going to keep using my own C rendition of this function myvsync() until R39 is finalized - I am not having trouble with anything else at the moment, so I'm going to stand pat on my copy of cc65 until R39 has been out long enough for the cc65 gurus to patch that up to match.

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, ChrisL said:

I'm seeing a different value for the `.timer` address in kernal.sym

Thanks - maybe I should use the Kernal function to get the timer value for the moment. Even though that's less efficient.

Share this post


Link to post
Share on other sites
  • 0
5 hours ago, ZeroByte said:

fresh download of the rom and emulator

Do you happen to have a Windows build of the latest r39? I could not get this to compile, I have neither Mac nor Linux machine.

Share this post


Link to post
Share on other sites
  • 0

I've updated my Repo so now waitvsync() uses RDTIM instead of the TIMER memory address. This makes it compatible with more ROM versions, but also a bit slower. I'll change this back as soon as the TIMER address has settled.

My cc65 repository: https://github.com/AndyMt/cc65

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
4 hours ago, AndyMt said:

I've updated my Repo so now waitvsync() uses RDTIM instead of the TIMER memory address. This makes it compatible with more ROM versions, but also a bit slower. I'll change this back as soon as the TIMER address has settled.

My cc65 repository: https://github.com/AndyMt/cc65

This is working for me now, thanks! 

It looks like there's a known issue with joysticks (https://github.com/commanderx16/x16-rom/issues/194) but I think there will also need to be updates to the joystick constants in cx16.h as they are for NES rather than SNES.  The cc65 joystick driver may need updates as well; it assumes 2 joysticks where there can now be up to 4 SNES controllers. 

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
15 minutes ago, ChrisL said:

but I think there will also need to be updates to the joystick constants in cx16.h as they are for NES rather than SNES.

The existing routine should work so long as the locations it reads values from have not changed. The SNES pad will work in NES mode - A, X, L, and R are inop in this mode, and B->NES A, Y->NES B. Start, Select, and D-Pad are identical.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
38 minutes ago, ChrisL said:

The cc65 joystick driver may need updates as well; it assumes 2 joysticks where there can now be up to 4 SNES controllers. 

Almost certainly, as the controllers were moved from VIA#2 to VIA#1. I haven't looked into this at all as I don't have a game controller to test this with. Keyboard emulation works in the emu, though, I don't know how that's done.

Share this post


Link to post
Share on other sites
  • 0

I'm not testing with an actual controller either, just with the keyboard emulation and am seeing weird results, so I'll need to chase further.  It may or may not be related to the above issue I mentioned.

Share this post


Link to post
Share on other sites
  • 0
On 4/5/2021 at 8:31 AM, AndyMt said:

I branched the cc65 repo and started changing the cx16 lib. It now works with Invaderz and Brixx and both would now run on R39.

In case anyone wants to check it out:
https://github.com/AndyMt/cc65

I'll do some more testing myself before creating a pull request.

Don't bother with a PR.  We won't update until R39 is released officially.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0
On 4/6/2021 at 9:32 AM, ChrisL said:

It looks like there's a known issue with joysticks (https://github.com/commanderx16/x16-rom/issues/194), but I think there will also need to be updates to the joystick constants in cx16.h, as they are for NES rather than SNES.  The cc65 joystick driver may need updates as well; it assumes 2 joysticks where there can now be up to 4 SNES controllers. 

Those constants are for cc65's joystick driver.  The Commander version uses the KERNAL function joystick_get.  The driver knows the difference between NES and SNES.  The "standard" driver always uses buttons A and B as fire buttons 1 and 2.

If someone feels that other buttons are more convenient as the fire buttons, then more joystick drivers can be added to the library.

Share this post


Link to post
Share on other sites
  • 0

I’m trying to use joystick.h with no success. I’m working with cc65 pulled about a month ago, and R38

i included joystick.h and just did a call to joy_load_driver(std_joy) and built to see if it would compile. Nope. The ca65 pass fails, saying illegal addressing mode - it is building as JMP($FFsomething) but ca65 doesn’t like the indirect mode.

Share this post


Link to post
Share on other sites
  • 0
14 hours ago, ZeroByte said:

I’m trying to use joystick.h with no success. I’m working with cc65 pulled about a month ago, and R38

i included joystick.h and just did a call to joy_load_driver(std_joy) and built to see if it would compile. Nope. The ca65 pass fails, saying illegal addressing mode - it is building as JMP($FFsomething) but ca65 doesn’t like the indirect mode.

Could you post some of the program code? I wrote a program containing nothing but a call to joy_load_driver, and it compiled.

Share this post


Link to post
Share on other sites
  • 0
14 hours ago, ZeroByte said:

ca65 doesn’t like the indirect mode.

Are you building with "-t cx16"? Indirect absolute mode definitely works with jmp if you do

Share this post


Link to post
Share on other sites
  • 0

Yeah. I even cc65’d it to a .s so I could go see the actual asm file, which is how I found out what command it was mad about. I am running the compiler with -t cx16

i decided that for now, I’m just going to use the kernvars on bank0 as they’re the same in R38 and R39, and circle back to the cc65 joystick routines after R39 releases and cc65 updates.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use