vc64web / virtualc64web

vc64web - Commodore C64 Emulator for iPad iPhone Android and the Web with CSDb access for thousands of demos at your fingertip.
https://vc64web.github.io/doc/about.html
GNU General Public License v3.0
43 stars 4 forks source link

migrating to virtual C64 v4.0 #72

Closed mithrendal closed 3 years ago

mithrendal commented 3 years ago

progress on migrating vc64web to v4 core

mithrendal commented 3 years ago

current status: emulation core compiles without errors 😍

this paves the way for a WASM vAmiga Emulation Core

THIS is so great !!!

now only in the wasm_SDL_wrapper has some 58 naughty errors left ... due to API changes ... 58 errors left -- see above current compile log

I will do the easy ones ... but some variables vanished completely like PAL_RASTERLINES ... is there a replacment ?

mithrendal commented 3 years ago

I reduced the 58 to 32 by guessing what to do when it was easy guessable ...

now only these 32 are left ...


mainsdl.cpp:99:18: error: use of undeclared identifier 'PAL_RASTERLINES'
int emu_height = PAL_RASTERLINES; //284
                 ^
mainsdl.cpp:105:22: error: use of undeclared identifier 'PAL_RASTERLINES'
int clipped_height = PAL_RASTERLINES -12 -24 -2*eat_border_height; //248
                     ^
mainsdl.cpp:278:38: error: no member named 'screenBuffer' in 'VICII'
  Uint8 *texture = (Uint8 *)c64->vic.screenBuffer();
                            ~~~~~~~~ ^
mainsdl.cpp:450:14: error: no member named 'emulateGrayDotBug' in 'VICII'
    c64->vic.emulateGrayDotBug=false;
    ~~~~~~~~ ^
mainsdl.cpp:519:19: error: no member named 'prepareToInsert' in 'Drive'
  selected_drive->prepareToInsert();
  ~~~~~~~~~~~~~~  ^
mainsdl.cpp:546:12: error: no member named 'prepareToEject' in 'Drive'
    drive->prepareToEject();
    ~~~~~  ^
mainsdl.cpp:552:12: error: no member named 'prepareToInsert' in 'Drive'
    drive->prepareToInsert();
    ~~~~~  ^
mainsdl.cpp:560:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:560:38: error: 'userSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                                     ^
Emulator/C64.h:224:15: note: declared private here
    Snapshot *userSnapshot = NULL;
              ^
mainsdl.cpp:570:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:570:38: error: 'userSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                                     ^
Emulator/C64.h:224:15: note: declared private here
    Snapshot *userSnapshot = NULL;
              ^
mainsdl.cpp:578:17: error: no member named 'takeUserSnapshot' in 'C64'; did you mean 'latestUserSnapshot'?
  wrapper->c64->takeUserSnapshot();
                ^~~~~~~~~~~~~~~~
                latestUserSnapshot
Emulator/C64.h:562:15: note: 'latestUserSnapshot' declared here
    Snapshot *latestUserSnapshot();
              ^
mainsdl.cpp:585:17: error: no member named 'setTakeAutoSnapshots' in 'C64'
  wrapper->c64->setTakeAutoSnapshots(enable == 1);
  ~~~~~~~~~~~~  ^
mainsdl.cpp:590:17: error: no member named 'restoreAutoSnapshot' in 'C64'
  wrapper->c64->restoreAutoSnapshot(nr);
  ~~~~~~~~~~~~  ^
mainsdl.cpp:597:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:597:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:603:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:603:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:608:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:608:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:614:24: error: no member named 'numAutoSnapshots' in 'C64'; did you mean 'signalAutoSnapshot'?
  return wrapper->c64->numAutoSnapshots();
                       ^~~~~~~~~~~~~~~~
                       signalAutoSnapshot
Emulator/C64.h:503:10: note: 'signalAutoSnapshot' declared here
    void signalAutoSnapshot() { setControlFlags(RL_AUTO_SNAPSHOT); }
         ^
mainsdl.cpp:614:10: error: cannot initialize return object of type 'size_t' (aka 'unsigned long') with an rvalue of type 'void'
  return wrapper->c64->numAutoSnapshots();
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mainsdl.cpp:619:24: error: no member named 'suspendAutoSnapshots' in 'C64'
  return wrapper->c64->suspendAutoSnapshots();
         ~~~~~~~~~~~~  ^
mainsdl.cpp:624:24: error: no member named 'resumeAutoSnapshots' in 'C64'; did you mean 'requestAutoSnapshot'?
  return wrapper->c64->resumeAutoSnapshots();
                       ^~~~~~~~~~~~~~~~~~~
                       requestAutoSnapshot
Emulator/C64.h:557:10: note: 'requestAutoSnapshot' declared here
    void requestAutoSnapshot();
         ^
mainsdl.cpp:631:17: error: no member named 'setWarpLoad' in 'C64'
  wrapper->c64->setWarpLoad(on == 1);
  ~~~~~~~~~~~~  ^
mainsdl.cpp:647:20: error: use of undeclared identifier 'PAL_RASTERLINES'
  clipped_height = PAL_RASTERLINES -10 -24 -2*eat_border_height; //248
                   ^
mainsdl.cpp:678:77: error: non-const lvalue reference to type 'C64' cannot bind to a value of unrelated type 'C64 *'
    wrapper->c64->expansionport.attachCartridge( Cartridge::makeWithCRTFile(wrapper->c64,(CRTFile::makeWithBuffer(blob, len))));
                                                                            ^~~~~~~~~~~~
Emulator/Cartridges/Cartridge.h:133:44: note: passing argument to parameter 'c64' here
    static Cartridge *makeWithCRTFile(C64 &c64, CRTFile *file);
                                           ^
mainsdl.cpp:694:19: error: no member named 'loadFromSnapshotSafe' in 'C64'; did you mean 'loadFromSnapshot'?
    wrapper->c64->loadFromSnapshotSafe(Snapshot::makeWithBuffer(blob, len));
                  ^~~~~~~~~~~~~~~~~~~~
                  loadFromSnapshot
Emulator/C64.h:567:10: note: 'loadFromSnapshot' declared here
    void loadFromSnapshot(Snapshot *snapshot);
         ^
mainsdl.cpp:723:34: error: use of undeclared identifier 'MSG_READY_TO_RUN'
        wrapper->c64->putMessage(MSG_READY_TO_RUN);
                                 ^
mainsdl.cpp:799:3: error: unknown type name 'JoystickEvent'
  JoystickEvent code;
  ^
mainsdl.cpp:882:23: error: no member named 'setModel' in 'SIDBridge'
    wrapper->c64->sid.setModel(MOS_6581);
    ~~~~~~~~~~~~~~~~~ ^
mainsdl.cpp:886:23: error: no member named 'setModel' in 'SIDBridge'
    wrapper->c64->sid.setModel(MOS_8580);  
    ~~~~~~~~~~~~~~~~~ ^
32 errors generated.

any advice @dirkwhoffmann ?

dirkwhoffmann commented 3 years ago

In v4.0, all constants have been cleaned up. They are now in C64Constants.h.

The replacement for PAL_RASTERLINES is TEX_HEIGHT and the replacement for NTSC_WIDTH is TEX_WIDTH (defined at the very end).

//
// Timing parameters
//

// Clock frequency in Hz
static const long PAL_CLOCK_FREQUENCY      = 985249;
static const long NTSC_CLOCK_FREQUENCY     = 1022727;
static const long PAL_CYCLES_PER_SECOND    = PAL_CLOCK_FREQUENCY;
static const long NTSC_CYCLES_PER_SECOND   = NTSC_CLOCK_FREQUENCY;

//
// Screen parameters
//

// Pixel aspect ratios
static const double PAL_ASPECT_RATIO       = 0.9365;
static const double NTSC_ASPECT_RATIO      = 0.7500;

// Horizontal parameters (measured in cycles)
static const long HBLANK_CYCLES_LEFT       = 13;
static const long BORDER_CYCLES_LEFT       = 4;
static const long CANVAS_CYCLES            = 40;
static const long BORDER_CYCLES_RIGHT      = 4;
static const long HBLANK_CYCLES_RIGHT_PAL  = 2;
static const long HBLANK_CYCLES_RIGHT_NTSC = 4;

// Derived values
static const long PAL_CYCLES               = 63;   // 13 + 4 + 40 + 4 + 2
static const long NTSC_CYCLES              = 65;   // 13 + 4 + 40 + 4 + 4

// Horizontal parameters (measured in pixels)
static const long HBLANK_PIXELS_LEFT       = 104;
static const long BORDER_PIXELS_LEFT       = 32;
static const long CANVAS_PIXELS            = 320;
static const long BORDER_PIXELS_RIGHT      = 32;
static const long HBLANK_PIXELS_RIGHT_PAL  = 16;
static const long HBLANK_PIXELS_RIGHT_NTSC = 32;

// Derived values
static const long FIRST_VISIBLE_PIXEL      = 104;  // 104
static const long VISIBLE_PIXELS           = 384;  //       32 + 320 + 32
static const long PAL_PIXELS               = 504;  // 104 + 32 + 320 + 32 + 16
static const long NTSC_PIXELS              = 520;  // 104 + 32 + 320 + 32 + 32

// Width and height of the emulator texture
static const long TEX_HEIGHT               = 312;  // PAL height
static const long TEX_WIDTH                = 520;  // NTSC width

// Vertical parameters
static const long FIRST_VISIBLE_LINE       = 16;
mithrendal commented 3 years ago

just to double check PAL_RASTERLINES was 284 before ...

//! @brief    Number of drawn rasterlines per frame in PAL mode
static const uint16_t PAL_RASTERLINES = 284; // 35 + 200 + 49

and now TEX_HEIGHT is 312 ...

its brother the NTSC_PIXELS is still there I do not need to change its name

but the value is also different

NTSC_PIXELS was //! @brief Number of drawn pixels per rasterline in NTSC mode static const uint16_t NTSC_PIXELS = 428; // 55 + 320 + 53

and now its value is 520

static const long FIRST_VISIBLE_PIXEL      = 104;  // 104
static const long VISIBLE_PIXELS           = 384;  //       32 + 320 + 32
static const long PAL_PIXELS               = 504;  // 104 + 32 + 320 + 32 + 16
static const long NTSC_PIXELS              = 520;  // 104 + 32 + 320 + 32 + 32

why do I not use PAL_PIXELS in main_sdl.cpp instead of NTSC_PIXELS ?

I should use TEX_WIDTH right ? But still this is much higher than NTSC_PIXELS which I used in v3.4 for the width

dirkwhoffmann commented 3 years ago

This is because the texture size has changed in v4.0. The new version got a DMA debugger similar to the one in vAmiga which required the texture size to be bumped up. I guess you use the constants for texture sizes, too. In this case, you need to use the new values TEX_WIDTH and TEX_HEIGHT.

mithrendal commented 3 years ago

only 29 errors left ... 🤓

mainsdl.cpp:278:38: error: no member named 'screenBuffer' in 'VICII'
  Uint8 *texture = (Uint8 *)c64->vic.screenBuffer();

mainsdl.cpp:519:19: error: no member named 'prepareToInsert' in 'Drive'
  selected_drive->prepareToInsert();
  ~~~~~~~~~~~~~~  ^
mainsdl.cpp:546:12: error: no member named 'prepareToEject' in 'Drive'
    drive->prepareToEject();

mainsdl.cpp:882:23: error: no member named 'setModel' in 'SIDBridge'
    wrapper->c64->sid.setModel(MOS_6581);

mainsdl.cpp:723:34: error: use of undeclared identifier 'MSG_READY_TO_RUN'
        wrapper->c64->putMessage(MSG_READY_TO_RUN);

mainsdl.cpp:694:19: error: no member named 'loadFromSnapshotSafe' in 'C64'; did you mean 'loadFromSnapshot'?
    wrapper->c64->loadFromSnapshotSafe(Snapshot::makeWithBuffer(blob, len));

what is the replacement ?

dirkwhoffmann commented 3 years ago

No more prepareToXXX() needed*. Just insert the disk 😎.

'*' = Assuming no programming mistakes. BTW, did I tell you that the v4.0 core is beta? 🙄

dirkwhoffmann commented 3 years ago

There is no replacement for loadFromSnapshotSafe. You need to wrap it with suspend/ resume:

Here is an example how it is used in flash(AnyFile *):

bool
C64::flash(AnyFile *file)
{
    bool result = true;

    suspend();
    switch (file->type()) {

        case FILETYPE_BASIC_ROM:
            file->flash(mem.rom, 0xA000);
            break;

        case FILETYPE_CHAR_ROM:
            file->flash(mem.rom, 0xD000);
            break;

        case FILETYPE_KERNAL_ROM:
            file->flash(mem.rom, 0xE000);
            break;

        case FILETYPE_VC1541_ROM:
            file->flash(drive8.mem.rom);
            file->flash(drive9.mem.rom);
            break;

        case FILETYPE_V64:
            loadFromSnapshot((Snapshot *)file);
            break;

        default:
            assert(false);
            result = false;
    }
    resume();
    return result;
}
dirkwhoffmann commented 3 years ago

SID is now configured via the standard config method

C64::configure(ConfigOption option, long value)

The config option is OPT_SID_REVISION.

dirkwhoffmann commented 3 years ago

Why do you send a message MSG_READY_TO_RUN? It was supposed to come from the emulator 😳.

mithrendal commented 3 years ago

Why do you send a message MSG_READY_TO_RUN? It was supposed to come from the emulator 😳.

when I remember correctly it was to be able to also start without drive rom ... the core code did not sent this message when drive rom was missing, so I had to put the message from the wrapper...

dirkwhoffmann commented 3 years ago

The v4.0 core can start without a Drive Rom 😎. It will simply disconnect the drive if no Drive Rom is present.

mithrendal commented 3 years ago

JoystickEvent is now GamePadAction ?

BTW: only 23 errors left ...

dirkwhoffmann commented 3 years ago

Yes, exactly.

 // Triggers a joystick event
 void trigger(GamePadAction event);
mithrendal commented 3 years ago

now only 19 errors left ...

mainsdl.cpp:278:38: error: no member named 'screenBuffer' in 'VICII'
  Uint8 *texture = (Uint8 *)c64->vic.screenBuffer();
                            ~~~~~~~~ ^
mainsdl.cpp:560:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:560:38: error: 'userSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                                     ^
Emulator/C64.h:224:15: note: declared private here
    Snapshot *userSnapshot = NULL;
              ^
mainsdl.cpp:570:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:570:38: error: 'userSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->userSnapshot(nr);
                                     ^
Emulator/C64.h:224:15: note: declared private here
    Snapshot *userSnapshot = NULL;
              ^
mainsdl.cpp:578:17: error: no member named 'takeUserSnapshot' in 'C64'; did you mean 'latestUserSnapshot'?
  wrapper->c64->takeUserSnapshot();
                ^~~~~~~~~~~~~~~~
                latestUserSnapshot
Emulator/C64.h:562:15: note: 'latestUserSnapshot' declared here
    Snapshot *latestUserSnapshot();
              ^
mainsdl.cpp:585:17: error: no member named 'setTakeAutoSnapshots' in 'C64'
  wrapper->c64->setTakeAutoSnapshots(enable == 1);
  ~~~~~~~~~~~~  ^
mainsdl.cpp:590:17: error: no member named 'restoreAutoSnapshot' in 'C64'
  wrapper->c64->restoreAutoSnapshot(nr);
  ~~~~~~~~~~~~  ^
mainsdl.cpp:597:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:597:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:603:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:603:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:608:50: error: called object type 'Snapshot *' is not a function or function pointer
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^
mainsdl.cpp:608:38: error: 'autoSnapshot' is a private member of 'C64'
  Snapshot *snapshot = wrapper->c64->autoSnapshot(nr);
                                     ^
Emulator/C64.h:223:15: note: declared private here
    Snapshot *autoSnapshot = NULL;
              ^
mainsdl.cpp:614:24: error: no member named 'numAutoSnapshots' in 'C64'; did you mean 'signalAutoSnapshot'?
  return wrapper->c64->numAutoSnapshots();
                       ^~~~~~~~~~~~~~~~
                       signalAutoSnapshot
Emulator/C64.h:503:10: note: 'signalAutoSnapshot' declared here
    void signalAutoSnapshot() { setControlFlags(RL_AUTO_SNAPSHOT); }
         ^
mainsdl.cpp:614:10: error: cannot initialize return object of type 'size_t' (aka 'unsigned long') with an rvalue of type 'void'
  return wrapper->c64->numAutoSnapshots();
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mainsdl.cpp:619:24: error: no member named 'suspendAutoSnapshots' in 'C64'
  return wrapper->c64->suspendAutoSnapshots();
         ~~~~~~~~~~~~  ^
mainsdl.cpp:624:24: error: no member named 'resumeAutoSnapshots' in 'C64'; did you mean 'requestAutoSnapshot'?
  return wrapper->c64->resumeAutoSnapshots();
                       ^~~~~~~~~~~~~~~~~~~
                       requestAutoSnapshot
Emulator/C64.h:557:10: note: 'requestAutoSnapshot' declared here
    void requestAutoSnapshot();
         ^
mainsdl.cpp:678:77: error: non-const lvalue reference to type 'C64' cannot bind to a value of unrelated type 'C64 *'
    wrapper->c64->expansionport.attachCartridge( Cartridge::makeWithCRTFile(wrapper->c64,(CRTFile::makeWithBuffer(blob, len))));
                                                                            ^~~~~~~~~~~~
Emulator/Cartridges/Cartridge.h:133:44: note: passing argument to parameter 'c64' here
    static Cartridge *makeWithCRTFile(C64 &c64, CRTFile *file);
                                           ^
19 errors generated.

what has happened here ?

before in v3.4 Cartridge::makeWithCRTFile(C64 c64, CRTFile file)

now in v4 static Cartridge makeWithCRTFile(C64 &c64, CRTFile file);

dirkwhoffmann commented 3 years ago

The v4.0 core doesn't distinguish between auto-snapshots and user-snapshots any more. There are just snapshots, all stored at the same place 😬.

mithrendal commented 3 years ago

I put a ifdev around each snapshot API call in the mainsdl.cpp ... lets repair the snapshots later ... first lets get the emulator up and running ...

now only 2 errors left ...😍

mainsdl.cpp:280:38: error: no member named 'screenBuffer' in 'VICII'
  Uint8 *texture = (Uint8 *)c64->vic.screenBuffer();
                            ~~~~~~~~ ^
mainsdl.cpp:714:77: error: non-const lvalue reference to type 'C64' cannot bind to a value of unrelated type 'C64 *'
    wrapper->c64->expansionport.attachCartridge( Cartridge::makeWithCRTFile(wrapper->c64,(CRTFile::makeWithBuffer(blob, len))));
                                                                            ^~~~~~~~~~~~
Emulator/Cartridges/Cartridge.h:133:44: note: passing argument to parameter 'c64' here
    static Cartridge *makeWithCRTFile(C64 &c64, CRTFile *file);
                                           ^
2 errors generated.
dirkwhoffmann commented 3 years ago

There are two textures now (VICII.h):

    // Returns the currently stable textures
    void *stableEmuTexture();
    void *stableDmaTexture();

If you want, you can display DMA usage in the web version, too.

mithrendal commented 3 years ago

only one left I ignore it for now, out comment it and start the emu 🤤🤤🤤

mainsdl.cpp:714:77: error: non-const lvalue reference to type 'C64' cannot bind to a value of unrelated type 'C64 *'
    wrapper->c64->expansionport.attachCartridge( Cartridge::makeWithCRTFile(wrapper->c64,(CRTFile::makeWithBuffer(blob, len))));
                                                                            ^~~~~~~~~~~~
Emulator/Cartridges/Cartridge.h:133:44: note: passing argument to parameter 'c64' here
    static Cartridge *makeWithCRTFile(C64 &c64, CRTFile *file);
                                           ^
1 error generated.
dirkwhoffmann commented 3 years ago

only one left I ignore it for now, out comment it and start the emu 🤤🤤🤤

Bring it on! Who needs cartridges? 😂

mithrendal commented 3 years ago

but I did not patched the SDL Stuff into C64.cpp ...😬

mithrendal commented 3 years ago
constructing C64 ...
(index):691 [0] (  0,  0) 0000 C64: updateVicFunctionTable (dmaDebug: 0)
(index):672 adding a listener to C64 message queue...
(index):672 vC64 message=MSG_PAL, data=0
(index):691 Calling stub instead of sigaction()
(index):691 Calling stub instead of sigaction()
vC64.js:1920 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
(index):672 set SID to freq= 44100
(index):672 v4 wrapper calls run on c64->run() method
(index):672 vC64 message=MSG_READY_TO_RUN, data=0
(index):672 after run ...
jquery-3.5.0.min.js:2 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
(index):672 try to create 2d renderer
vC64.js:6136 [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
vC64.js:6136 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
vC64.js:6136 [Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
(index):672 got software renderer ...
(index):672 Size changed: 484, 276
(index):672 vC64 message=MSG_ALWAYS_WARP_ON, data=0
(index):672 Size changed: 484, 278
(index):672 Size changed: 484, 278
(index):672 vC64 message=MSG_READY_TO_RUN, data=0
vC64.js:9850 [Violation] 'setTimeout' handler took 1241ms
[Violation] Forced reflow while executing JavaScript took 52ms
2

look look it is the new one (index):672 v4 wrapper calls run on c64->run() method it says v4 wrapper

black screen ... I guess something is wrong ... the last thing it said to us was MSG_READY_TO_RUN hmmm

maybe I should not be so lazy and give it the SDL compatibility patch no ?

grafik

dirkwhoffmann commented 3 years ago

Try to call dump() for the C64 object multiple times in a row. It prints some debug info:

void
C64::_dump() {
    msg("C64:\n");
    msg("----\n\n");
    msg("              Machine type : %s\n", vic.isPAL() ? "PAL" : "NTSC");
    msg("         Frames per second : %f\n", vic.getFramesPerSecond());
    msg("     Rasterlines per frame : %d\n", vic.getRasterlinesPerFrame());
    msg("     Cycles per rasterline : %d\n", vic.getCyclesPerLine());
    msg("             Current cycle : %llu\n", cpu.cycle);
    msg("             Current frame : %d\n", frame);
    msg("        Current rasterline : %d\n", rasterLine);
    msg("  Current rasterline cycle : %d\n", rasterCycle);
    msg("              Ultimax mode : %s\n\n", getUltimax() ? "YES" : "NO");
    msg("\n");
}

The current cycle should change if it is running. Also call isRunning() directly to see if it is running.

mithrendal commented 3 years ago

it is not yet running has to implant first the SDL thread management into C64.cpp which is quite different to the native pthread methods ... maybe better to abstract threading and move thread logic out of the core ?

BTW: there is no threadCleanup(void* thisC64) anymore ... ?

dirkwhoffmann commented 3 years ago

There is a threadTerminatedfunction:

//
// Emulator thread
//

void 
threadTerminated(void* thisC64)
{
    assert(thisC64 != NULL);

    // Inform the C64 that the thread has been canceled
    C64 *c64 = (C64 *)thisC64;
    c64->threadDidTerminate();
}

This function calls threadDidTerminate() on the c64 object which does the cleanup.

mithrendal commented 3 years ago

ok I will take it ... I take everything ...

BTW: the current output ... it does not really start yet despite the fact that the SDL stuff is already in


constructing C64 ...
(index):1 [0] (  0,  0) 0000 C64: updateVicFunctionTable (dmaDebug: 0)
(index):1 adding a listener to C64 message queue...
(index):1 vC64 message=MSG_PAL, data=0
vC64.js:1 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
(index):1 set SID to freq= 44100
(index):1 v4 wrapper calls run on c64->run() method
(index):1 vC64 message=MSG_READY_TO_RUN, data=0
(index):1 C64 (memory location: 0x15f5070)
(index):1 
(index):1 C64:
(index):1 ----
(index):1 
(index):1               Machine type : PAL
(index):1          Frames per second : 50.124593
(index):1      Rasterlines per frame : 312
(index):1      Cycles per rasterline : 63
(index):1              Current cycle : 0
(index):1              Current frame : 0
(index):1         Current rasterline : 0
(index):1   Current rasterline cycle : 1
(index):1               Ultimax mode : NO
2
(index):1 
(index):1 is running = 0
(index):1 after run ...
(index):1 try to create 2d renderer
(index):1 got software renderer ...
(index):1 Size changed: 484, 276
(index):1 vC64 message=MSG_ALWAYS_WARP_ON, data=0
2
(index):1 Size changed: 484, 278
(index):1 vC64 message=MSG_READY_TO_RUN, data=0
2
(index):1 wasm_run
[Violation] Forced reflow while executing JavaScript took 38ms
(index):1 load file=chargen_pxlfont_2.3.rom len=4096, header bytes= 0, 3c, 66
(index):1 Loaded ROM image chargen_pxlfont_2.3.rom.
(index):1 detected rom_type=char_rom.
(index):1 load file=kernal_generic.rom len=8192, header bytes= 4c, b2, a6
(index):1 Failed to read ROM image file kernal_generic.rom
(index):1 load file=basic_generic.rom len=8192, header bytes= 94, e3, b7
(index):1 Loaded ROM image basic_generic.rom.
(index):1 detected rom_type=basic_rom.
(index):1 load file=basic_generic.rom len=8192, header bytes= 94, e3, b7
(index):1 Loaded ROM image basic_generic.rom.
(index):1 detected rom_type=basic_rom.
(index):1 load file=kernal_generic.rom len=8192, header bytes= 4c, b2, a6
(index):1 Failed to read ROM image file kernal_generic.rom
(index):1 load file=chargen_pxlfont_2.3.rom len=4096, header bytes= 0, 3c, 66
(index):1 Loaded ROM image chargen_pxlfont_2.3.rom.
(index):1 detected rom_type=char_rom.
(index):1 vC64 message=MSG_KERNAL_ROM_LOADED, data=0

dirkwhoffmann commented 3 years ago

OK, let's debug it step by step.

When run() is called, isReady() is called afterwards:

bool
C64::isReady(ErrorCode *error)
{
    if (!hasRom(ROM_BASIC) || !hasRom(ROM_CHAR) || !hasRom(ROM_KERNAL)) {
        if (error) *error = ERR_ROM_MISSING;
        return false;
    }

    if (hasMega65Rom(ROM_BASIC) && hasMega65Rom(ROM_KERNAL)) {
        if (strcmp(mega65BasicRev(), mega65KernalRev()) != 0) {
            if (error) *error = ERR_ROM_MEGA65_MISMATCH;
            return false;
        }
    }

    return true;
}

I guess, this methods returns false. Maybe it's an ERR_ROM_MEGA65_MISMATCHerror? No? 🤔

mithrendal commented 3 years ago

hm I just double checked the implanted code ... should be complete now ...

I guess, this methods returns false. Maybe it's an ERR_ROM_MEGA65_MISMATCHerror? No? 🤔

ok I will load the orig roms ...

and I will try to debug into the please draw one frame thing ...

mithrendal commented 3 years ago

@dirkwhoffmann

image

the fact that I set -s INITIAL_MEMORY=512MB -s TOTAL_STACK=256MB and also did your hint in row 41

 // Flash Rom data
    //u8 rom[size];
    u8 *rom = new u8[size];

and outcommented row 98

 void applyToPersistentItems(T& worker)
    {
        worker

        & state
        & baseState;
       /* &  rom*/;
    }

but Easyflash is still not loading and the above screenshot make me believe that it is in an infinity loop or something like that ... look at the stacktrace it is always jumping from 813 to 646 and 813 and 646 and so on...

same picture in firefox after loading easyflash

image

and for the completeness chrome

grafik

the mentioned line 473 in chromes output in vc64_ui.js is just the catch of the load_cartridge


    } catch(e) {
        console.log(e);    //<--- Line 473
    }
mithrendal commented 3 years ago

hi dirk, I saw that in the oscillator we got now this new time function "clock_gettime" for other platforms ...


u64
Oscillator::nanos()
{
#ifdef __MACH__    
    return abs_to_nanos(mach_absolute_time());
#else

    struct timespec ts;
    (void)clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec * 1000000000 + ts.tv_nsec;

#endif
}

I just tested this else case under emscripten ... and it delivered weird jumps in the values ... then I altered the nanos method to go with the time function which I used in emscripten before ... and compared here are the results ...

u64
Oscillator::nanos()
{
#ifdef __MACH__

    return abs_to_nanos(mach_absolute_time());

#elif __EMSCRIPTEN__

    struct timespec ts;
    (void)clock_gettime(CLOCK_MONOTONIC, &ts);
    u64 xxx = ts.tv_sec * 1000000000 + ts.tv_nsec;
    printf("clock_gettime=%llu  ...  ems_get_now()=%llu\n",xxx, (uint64_t)(emscripten_get_now()*1000000.0));
    return (uint64_t)(emscripten_get_now()*1000000.0);

#else

    struct timespec ts;
    (void)clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec * 1000000000 + ts.tv_nsec;

#endif
}

clock_gettime=18446744072961598144  ...  ems_get_now()=136691000000 
clock_gettime=18446744073053598144  ...  ems_get_now()=136783000000 
clock_gettime=18446744073146598144  ...  ems_get_now()=136876000000 
clock_gettime=18446744073241598144  ...  ems_get_now()=136972000000 
clock_gettime=18446744073333598144  ...  ems_get_now()=137063000000 
clock_gettime=18446744073425598144  ...  ems_get_now()=137155000000 
clock_gettime=18446744073518598144  ...  ems_get_now()=137248000000 
clock_gettime=18446744073611598144  ...  ems_get_now()=137341000000 
clock_gettime=18446744073704598144  ...  ems_get_now()=137434000000 
clock_gettime=87046528  ...  ems_get_now()=137526000000 
clock_gettime=181046528  ...  ems_get_now()=137620000000 
clock_gettime=273046528  ...  ems_get_now()=137712000000 
clock_gettime=367046528  ...  ems_get_now()=137806000000 
clock_gettime=459046528  ...  ems_get_now()=137898000000 
clock_gettime=552046528  ...  ems_get_now()=137991000000 
clock_gettime=645046528  ...  ems_get_now()=138084000000 
clock_gettime=738046528  ...  ems_get_now()=138177000000 
clock_gettime=831046528  ...  ems_get_now()=138270000000 
clock_gettime=924046528  ...  ems_get_now()=138363000000 
clock_gettime=1017046528  ...  ems_get_now()=138456000000 
clock_gettime=1110046528  ...  ems_get_now()=138549000000 
clock_gettime=1202046528  ...  ems_get_now()=138642000000 
clock_gettime=1295046528  ...  ems_get_now()=138734000000 
clock_gettime=1388046528  ...  ems_get_now()=138827000000 
clock_gettime=1481046528  ...  ems_get_now()=138920000000 
clock_gettime=1573046528  ...  ems_get_now()=139013000000 
clock_gettime=1667046528  ...  ems_get_now()=139106000000 
clock_gettime=1759046528  ...  ems_get_now()=139198000000 
clock_gettime=1852046528  ...  ems_get_now()=139291000000 
clock_gettime=1945046528  ...  ems_get_now()=139384000000 
clock_gettime=2038046528  ...  ems_get_now()=139477000000

what do you think ? it seems ems_get_now() is not jumping ... both are only at milliseconds precision ...

dirkwhoffmann commented 3 years ago

Interesting. We should find out the standard way to read nanos in Linux. Likely, this method will work fine with Emscripten, too. We definitely need to avoid those jumps, because they will screw up audio.

mithrendal commented 3 years ago

just compared falcon patrol 2 intro and fps on 3.4 and 4.0 core in vc64web on my old mbp2007 machine

Core 3.4

time[ms]=1013.000000, audio_samples=45056, frames [executed=50, rendered=45]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=43]
time[ms]=1004.000000, audio_samples=43008, frames [executed=50, rendered=49]
time[ms]=1001.000000, audio_samples=45056, frames [executed=51, rendered=40]
time[ms]=1019.000000, audio_samples=45056, frames [executed=50, rendered=46]
time[ms]=1013.000000, audio_samples=45056, frames [executed=52, rendered=42]
time[ms]=1014.000000, audio_samples=43008, frames [executed=50, rendered=37]
time[ms]=1021.000000, audio_samples=45056, frames [executed=51, rendered=25]
time[ms]=1005.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1001.000000, audio_samples=45056, frames [executed=50, rendered=35]
time[ms]=1032.000000, audio_samples=45056, frames [executed=51, rendered=39]
time[ms]=1002.000000, audio_samples=43008, frames [executed=51, rendered=36]
time[ms]=1001.000000, audio_samples=45056, frames [executed=48, rendered=40]
time[ms]=1011.000000, audio_samples=45056, frames [executed=53, rendered=37]
time[ms]=1042.000000, audio_samples=45056, frames [executed=51, rendered=40]
time[ms]=1000.000000, audio_samples=45056, frames [executed=51, rendered=36]
time[ms]=1001.000000, audio_samples=43008, frames [executed=50, rendered=41]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=38]
time[ms]=1004.000000, audio_samples=43008, frames [executed=49, rendered=39]
time[ms]=1001.000000, audio_samples=45056, frames [executed=51, rendered=32]

compared to 4.0 Core


time[ms]=1020.000000, audio_samples=45056, frames [executed=39, rendered=29]
time[ms]=1025.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1007.000000, audio_samples=45056, frames [executed=51, rendered=31]
time[ms]=1035.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1000.000000, audio_samples=45056, frames [executed=51, rendered=26]
time[ms]=1005.000000, audio_samples=43008, frames [executed=49, rendered=34]
time[ms]=1028.000000, audio_samples=47104, frames [executed=53, rendered=28]
time[ms]=1004.000000, audio_samples=43008, frames [executed=49, rendered=35]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=27]
time[ms]=1004.000000, audio_samples=43008, frames [executed=50, rendered=35]
time[ms]=1019.000000, audio_samples=45056, frames [executed=51, rendered=27]
time[ms]=1014.000000, audio_samples=45056, frames [executed=51, rendered=34]
time[ms]=1092.000000, audio_samples=47104, frames [executed=51, rendered=22]
time[ms]=1005.000000, audio_samples=40960, frames [executed=53, rendered=9]
time[ms]=1024.000000, audio_samples=49152, frames [executed=53, rendered=33]
time[ms]=1070.000000, audio_samples=47104, frames [executed=51, rendered=27]
time[ms]=1014.000000, audio_samples=45056, frames [executed=54, rendered=27]
time[ms]=1053.000000, audio_samples=45056, frames [executed=50, rendered=27]
time[ms]=1017.000000, audio_samples=45056, frames [executed=53, rendered=35]
time[ms]=1020.000000, audio_samples=45056, frames [executed=46, rendered=23]
time[ms]=1019.000000, audio_samples=45056, frames [executed=56, rendered=31]
time[ms]=1027.000000, audio_samples=45056, frames [executed=48, rendered=26]
time[ms]=1018.000000, audio_samples=45056, frames [executed=55, rendered=29]
time[ms]=1036.000000, audio_samples=45056, frames [executed=49, rendered=20]
time[ms]=1006.000000, audio_samples=45056, frames [executed=53, rendered=31]
time[ms]=1014.000000, audio_samples=45056, frames [executed=50, rendered=30]
time[ms]=1018.000000, audio_samples=45056, frames [executed=52, rendered=33]
time[ms]=1005.000000, audio_samples=43008, frames [executed=50, rendered=23]
time[ms]=1033.000000, audio_samples=47104, frames [executed=52, rendered=34]
time[ms]=1036.000000, audio_samples=45056, frames [executed=51, rendered=22]
time[ms]=1001.000000, audio_samples=43008, frames [executed=51, rendered=33]
time[ms]=1003.000000, audio_samples=45056, frames [executed=50, rendered=18]
time[ms]=1010.000000, audio_samples=45056, frames [executed=51, rendered=31]
time[ms]=1006.000000, audio_samples=45056, frames [executed=49, rendered=16]
time[ms]=1048.000000, audio_samples=45056, frames [executed=53, rendered=22]
time[ms]=1006.000000, audio_samples=45056, frames [executed=51, rendered=14]
time[ms]=1030.000000, audio_samples=45056, frames [executed=52, rendered=28]
time[ms]=1020.000000, audio_samples=45056, frames [executed=49, rendered=15]
time[ms]=1002.000000, audio_samples=43008, frames [executed=53, rendered=28]
time[ms]=1004.000000, audio_samples=43008, frames [executed=50, rendered=17]

the old core is giving us better values ... is it maybe my fault ? Maybe I have not outcommented some not needed stuff fro emscripten or is the new core more demanding ?

dirkwhoffmann commented 3 years ago

The core itself is pretty much the same. One bigger change is the increased texture size. Could it be related to that?

mithrendal commented 3 years ago

Yes ... that could be ... I try to play a bit with -O3 to bring values up again ... since I compile file by file we can also selectively compile certain components with -O3, which are the hotspots ? I bet CPU no?

an -O3 build of core 4.0


time[ms]=1049.000000, audio_samples=47104, frames [executed=41, rendered=21]
time[ms]=1002.000000, audio_samples=45056, frames [executed=49, rendered=32]
time[ms]=1019.000000, audio_samples=43008, frames [executed=50, rendered=38]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=35]
time[ms]=1018.000000, audio_samples=45056, frames [executed=49, rendered=32]
time[ms]=1015.000000, audio_samples=45056, frames [executed=53, rendered=32]
time[ms]=1001.000000, audio_samples=43008, frames [executed=50, rendered=44]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=34]
time[ms]=1018.000000, audio_samples=45056, frames [executed=50, rendered=46]
time[ms]=1007.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1028.000000, audio_samples=45056, frames [executed=50, rendered=46]
time[ms]=1018.000000, audio_samples=45056, frames [executed=52, rendered=37]
time[ms]=1002.000000, audio_samples=43008, frames [executed=50, rendered=47]
time[ms]=1009.000000, audio_samples=45056, frames [executed=51, rendered=34]
time[ms]=1024.000000, audio_samples=45056, frames [executed=51, rendered=44]
time[ms]=1002.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1002.000000, audio_samples=43008, frames [executed=48, rendered=39]
time[ms]=1002.000000, audio_samples=45056, frames [executed=52, rendered=43]
time[ms]=1043.000000, audio_samples=45056, frames [executed=51, rendered=36]
lost sync target=921, total_executed=912
time[ms]=1017.000000, audio_samples=45056, frames [executed=43, rendered=34]
time[ms]=1040.000000, audio_samples=45056, frames [executed=51, rendered=38]
time[ms]=1021.000000, audio_samples=45056, frames [executed=52, rendered=40]
time[ms]=1028.000000, audio_samples=47104, frames [executed=50, rendered=33]
time[ms]=1022.000000, audio_samples=45056, frames [executed=53, rendered=37]
time[ms]=1008.000000, audio_samples=43008, frames [executed=50, rendered=43]
time[ms]=1006.000000, audio_samples=45056, frames [executed=51, rendered=33]
time[ms]=1032.000000, audio_samples=45056, frames [executed=51, rendered=38]
time[ms]=1013.000000, audio_samples=45056, frames [executed=51, rendered=42]
time[ms]=1019.000000, audio_samples=45056, frames [executed=51, rendered=36]
time[ms]=1013.000000, audio_samples=45056, frames [executed=52, rendered=47]
time[ms]=1020.000000, audio_samples=45056, frames [executed=50, rendered=35]
time[ms]=1001.000000, audio_samples=43008, frames [executed=51, rendered=47]
time[ms]=1012.000000, audio_samples=45056, frames [executed=50, rendered=38]
time[ms]=1004.000000, audio_samples=45056, frames [executed=51, rendered=47]
time[ms]=1000.000000, audio_samples=43008, frames [executed=50, rendered=34]
time[ms]=1004.000000, audio_samples=45056, frames [executed=50, rendered=51]
time[ms]=1003.000000, audio_samples=43008, frames [executed=49, rendered=33]
time[ms]=1002.000000, audio_samples=45056, frames [executed=52, rendered=49]
time[ms]=1025.000000, audio_samples=45056, frames [executed=51, rendered=37]
time[ms]=1007.000000, audio_samples=45056, frames [executed=51, rendered=44]
time[ms]=1019.000000, audio_samples=45056, frames [executed=50, rendered=36]
time[ms]=1002.000000, audio_samples=43008, frames [executed=51, rendered=42]
time[ms]=1003.000000, audio_samples=45056, frames [executed=50, rendered=31]
time[ms]=1014.000000, audio_samples=45056, frames [executed=51, rendered=51]
time[ms]=1018.000000, audio_samples=45056, frames [executed=51, rendered=33]
time[ms]=1020.000000, audio_samples=45056, frames [executed=51, rendered=43]
time[ms]=1052.000000, audio_samples=45056, frames [executed=51, rendered=30]
time[ms]=1002.000000, audio_samples=45056, frames [executed=52, rendered=46]
time[ms]=1029.000000, audio_samples=45056, frames [executed=51, rendered=29]
time[ms]=1003.000000, audio_samples=45056, frames [executed=51, rendered=43]

looks not to shabby with -O3 anymore

mithrendal commented 3 years ago

I tested several disks ... it seems the optimisation bug which prevented us from using -O3 with v3.4 core and made us step back to -O2 is no longer in the v4 core ... as the disks seem to work fine with -O3... 😅

mithrendal commented 3 years ago

as snapshots from the old v3.4 core are no longer compatible with the brand new v4 core I have to guide the users some how and tell them that their old albums are no longer loadable ...

grafik

by drawing a text on the old snapshots ... and also when they are clicking on a old snapshot to run it ... we show a message that these snapshots have become no longer usable ...

they will hate us 🙈

mithrendal commented 3 years ago

auto snapshots are back 😎

grafik

this is the replacement for the removed auto_snapshot feature from the v4 Core ... its implementation is now in the javascript UI wrapper which is a better place for that feature anyway because it does not belong to the core

var auto_snaps= new RingBuffer(5);
var auto_snap_interval=null;
function set_take_auto_snapshots(on) {
    if(on == false && auto_snap_interval != null)
    {
        clearInterval(auto_snap_interval);
        auto_snap_interval=null;
    }
    else if(on && auto_snap_interval == null)
    {
        auto_snap_interval=setInterval(() => {
            if(is_running())
            {
                wasm_halt();
                wasm_take_user_snapshot(); 
                wasm_run();
                var snapshot_json= wasm_pull_user_snapshot_file();

                var snap_obj = JSON.parse(snapshot_json);
                var snapshot_buffer = new Uint8Array(Module.HEAPU8.buffer, snap_obj.address, snap_obj.size);

                //snapshot_buffer is only a typed array view therefore slice, which creates a new array with byteposition 0 ...
                auto_snaps.push(snapshot_buffer.slice(0,snap_obj.size));

                console.log(`auto_snaps count = ${auto_snaps.length}`);
            }
        }, 5000);
    }
}
mithrendal commented 3 years ago

lets continue here ...

I spotted another bug on my side

    c64->configure(OPT_SID_ENABLE, 1);
    c64->configure(OPT_SID_ADDRESS, 1, 0x400);

the first statement had an error too ... see no true or false ...

both statements are corrected now and I also start counting from 0

    c64->configure(OPT_SID_ENABLE, 0, true);
    c64->configure(OPT_SID_ADDRESS, 0, 0xd400);
    c64->sid.dump();

I do call these configs before I startup the main c64 component... e.g. before C64 is running

I dump the sid right after configure and what makes me wonder is that the sid adress is different form the memory location in the picture below...

grafik

in the end still no sound and when switching revision it still complains that it is not running ... but emulation in general is running (only no sound)

mithrendal commented 3 years ago

You need to embed the call in a suspend() / resume() block

hmm what does that mean ? I tried this but no success ...


extern "C" void wasm_halt()
{
  printf("wasm_halt\n");
  wrapper->c64->pause();
}

extern "C" void wasm_run()
{
  printf("wasm_run\n");
  wrapper->c64->run();

  wrapper->c64->configure(OPT_SID_ENABLE, 0, true);
  wrapper->c64->configure(OPT_SID_ADDRESS, 0, 0xd400);
  wrapper->c64->sid.dump();
}
dirkwhoffmann commented 3 years ago

There was a small bug in the debug() statement. I've committed an update to the dev branch.

dirkwhoffmann commented 3 years ago

Don't map SID 0 to D400. The build-in SID spans the whole SID range. In other words: When no other SID is found, SID 0 is used.

Just change

wrapper->c64->configure(OPT_SID_ENABLE, 0, true);
wrapper->c64->configure(OPT_SID_ADDRESS, 0, 0xd400);

to

wrapper->c64->configure(OPT_SID_ENABLE, 1, true);
wrapper->c64->configure(OPT_SID_ADDRESS, 1, 0xd420);
dirkwhoffmann commented 3 years ago

hmm what does that mean ? I tried this but no success ...

The assert complains that it is running. Execute the config code before calling run().

mithrendal commented 3 years ago

The assert complains that it is running. Execute the config code before calling run().

Ah I see ... I thought it was the opposite ... (I thought it complained that it was not running) ... I repaired that in the following way


extern "C" void wasm_set_sid_model(unsigned SID_Model)
{
  bool wasRunning=false;
  if(wrapper->c64->isRunning()){
    wasRunning= true;
    wrapper->c64->pause();
  }
  if(SID_Model == 6581)
  {
    wrapper->c64->configure(OPT_SID_REVISION, MOS_6581);
  }
  else if(SID_Model == 8580)
  {
    wrapper->c64->configure(OPT_SID_REVISION, MOS_8580);  
  }
  if(wasRunning)
  {
    wrapper->c64->run();
  }
}

I also merged in the other new recent changes ... now no exception ... no complaining ... debug output is also cleaner now ...

but still no sound output ... I have to debug the copyMono() method ...

dirkwhoffmann commented 3 years ago

I have to debug the copyMono() method ...

Strange enough. copyMono looks pretty muck OK (however, it's never been executed in real-life since all Macs are stereo these days). Maybe it's easiest to dump out the copied sound samples via printf in copyMono...

mithrendal commented 3 years ago

all is zero copyMono[2048]: 0,0,0,0,0,0,0,... copyMono[2048]: 0,0,0,0,0,0,0,... copyMono[2048]: 0,0,0,0,0,0,0,...

I shortened the output

here is the code:


void MyAudioCallback(void*  thisC64,
                       Uint8* stream,
                       int    len)
{
    C64 *c64 = (C64 *)thisC64;

    int n = len /  sizeof(float);
    c64->sid.copyMono((float *)stream, n);
    printf("copyMono[%d]: ", n);
    for(int i=0; i<n; i++)
    {
      printf("%hhu,",stream[i]);
    }
    printf("\n");

    sum_samples += n;
}
dirkwhoffmann commented 3 years ago

Maybe it's related to volume control. Please check volume, volumeDelta, and targetVolume

mithrendal commented 3 years ago

void
SIDBridge::copyMono(float *target, size_t n)
{
    stream.lock();

    // Check for a buffer underflow
    if (stream.count() < n) handleBufferUnderflow();

    printf("volume.current=%ud, volume.target=%ud, volume.delta=%ud\n",volume.current, volume.target, volume.delta);
    // Copy sound samples
    stream.copyMono(target, n, volume.current, volume.target, volume.delta);

    stream.unlock();
}

grafik

dirkwhoffmann commented 3 years ago

Strange. Let's try this: Can you insert a printf in ReSID::poke and remove the "//" before the debug statement in ReSID::execute?

void 
ReSID::poke(u16 addr, u8 value)
{
    sid->write(addr, value);
}

u64
ReSID::execute(u64 cycles)
{
    // Don't ask SID to compute samples for a time interval greater than 1 sec
    assert(cycles <= PAL_CYCLES_PER_SECOND);

    // debug("Executing ReSID %p for %lld cycles\n", this, cycles);

    reSID::cycle_count delta_t = (reSID::cycle_count)cycles;
    int numSamples = 0;

    // Let reSID compute some sound samples
    while (delta_t) {
        numSamples += sid->clock(delta_t, samples + numSamples,
                                 SIDBridge::sampleBufferSize - numSamples);
    }

    assert(numSamples >= 0);
    return (u64)numSamples;
}
mithrendal commented 3 years ago

void 
ReSID::poke(u16 addr, u8 value)
{
    printf("poking %u\n", value);
    sid->write(addr, value);
}

u64
ReSID::execute(u64 cycles)
{
    // Don't ask SID to compute samples for a time interval greater than 1 sec
    assert(cycles <= PAL_CYCLES_PER_SECOND);

    debug("Executing ReSID %p for %lld cycles\n", this, cycles);

    reSID::cycle_count delta_t = (reSID::cycle_count)cycles;
    int numSamples = 0;

grafik

engine seem to run ... but no smoke ...

dirkwhoffmann commented 3 years ago

OK, good, SID is breathing and has pulse.

Now, let's insert some printfs here (e.g., values ch0 to ch3).

void
SIDBridge::execute(u64 numCycles)
{
    if (numCycles == 0) return;

    // Check for a buffer underflow
    if (signalUnderflow) {
        signalUnderflow = false;
        handleBufferUnderflow();
    }

    //
    // Synthesize samples
    //

    u64 numSamples;

    switch (config.engine) {

        case ENGINE_FASTSID:

            // Run the primary SID (which is always enabled)
            numSamples = fastsid[0].execute(numCycles);

            // Run all other SIDS (if any)
            if (config.enabled > 1) {
                for (int i = 1; i < 4; i++) {
                    if (isEnabled(i)) {
                        u64 numSamples2 = fastsid[i].execute(numCycles);
                        assert(numSamples2 == numSamples);
                    }
                }
            }
            break;

        case ENGINE_RESID:

            // Run the primary SID (which is always enabled)
            numSamples = resid[0].execute(numCycles);

            // Run all other SIDS (if any)
            if (config.enabled > 1) {
                for (int i = 1; i < 4; i++) {
                    if (isEnabled(i)) {
                        u64 numSamples2 = resid[i].execute(numCycles);
                        if (numSamples2 != numSamples) {
                            warn("SID sample mismatch %d %d\n", numSamples, numSamples2);
                            _dump(0);
                            _dump(1);
                            assert(false);
                        }
                    }
                }
            }
            break;

        default:
            assert(false);
    }

    //
    // Mix channels
    //

    stream.lock();

    // Check for buffer overflow
    if (stream.free() < numSamples) {
        handleBufferOverflow();
    }

    // Convert sound samples to floating point values and write into ringbuffer
    for (unsigned i = 0; i < numSamples; i++) {

        float ch0, ch1, ch2, ch3, l, r;

        ch0 = (float)samples[0][i] * vol[0];
        ch1 = (float)samples[1][i] * vol[1];
        ch2 = (float)samples[2][i] * vol[2];
        ch3 = (float)samples[3][i] * vol[3];

        // Compute left channel output
        l =
        ch0 * (1 - pan[0]) + ch1 * (1 - pan[1]) +
        ch2 * (1 - pan[2]) + ch3 * (1 - pan[3]);

        // Compute right channel output
        r =
        ch0 * pan[0] + ch1 * pan[1] +
        ch2 * pan[2] + ch3 * pan[3];

        // Apply master volume
        l *= config.volL;
        r *= config.volR;

        stream.write(SamplePair { l, r } );
    }

    stream.unlock();
}