Hello, Guest the thread was called3.3k times and contains 99 replays

last post from FeralChild at the

Work is underway to make open-source replacement ROMs for the C64

  • That's how I understand this code. To be honest, I'm completely uninterested in developing this mechanism further - I'm going to support it in the code I'll write, but I'm going to make it completely optional (selectable at compile time). You will have something like:


    Code
    1. ldy #0
    2. .if (CONFIG_MEMMODEL_60K) {
    3. ldx #<basic_current_statement_ptr
    4. jsr peek_under_roms
    5. cmp #$00
    6. } else { // CONFIG_MEMMODEL_38K
    7. lda (basic_current_statement_ptr), Y
    8. }


    For this, I have to switch the project to Kick Assembler first, with Ophis there is no chance to write anything that readable.

  • can you get the state of X? if so you can delete the cmp but you have to swap beq with bne and bne with beq i think.

    i know it is not much always 2bytes but the sum will make thedifference.


    in your bsp i see

    Code
    1. ldx #<basic_current_statement_ptr ;set falgs, eg N=0,Z=1,C=?
    2. jsr peek_under_roms ;store flags and restore it, eg N=0,Z=1,C=?
    3. cmp #$00 ; if X=0 then ? NO here is A the COMPERATOR, sets the flags new! eg N=1,Z=0,C=0


    oh yeah now i see A is the comperator and it will be set in peek_under_roms, so yeah it is not removable.

    all cmp #$00 after a jsr peek_under_roms have to implement. now im not sure how many cmp #$00 i see without that subroutinecall^^


    salute


    PS: cmp #$00 after a jsr peek_under_roms closed ;D so good work it was my fault ;/

  • Unless someone else steps in, useable BASIC won't happen anytime soon. I rather think about creating a hybrid Kernal ROM, with bytes up to $E4D2 taken from the Commodore implementation - this should allow us to run the original BASIC ROM, which would make it easy to write some kind of test suite.

    But I must admit that some BASIC mechanisms might be interesting to implement. Like floating points - I wonder whether it would be feasible to alter the original format a little, one bit might tell us whether the number is a floating point, or an integer. This way we could make the code such as FOR I = 1 TO 1000 : (do something) : NEXT actually operate on integers, which would be way faster. I also think that string storage could be a little bit different too, using double-linked lists (like with BASIC 3.5 and above) - garbage collection would just fly, and I don't think in reality we would lose any compatibility.

  • Hello,

    Unless someone else steps in, useable BASIC won't happen anytime soon. I rather think about creating a hybrid Kernal ROM, with bytes up to $E4D2 taken from the Commodore implementation - this should allow us to run the original BASIC ROM, which would make it easy to write some kind of test suite.

    But I must admit that some BASIC mechanisms might be interesting to implement. Like floating points - I wonder whether it would be feasible to alter the original format a little, one bit might tell us whether the number is a floating point, or an integer. This way we could make the code such as FOR I = 1 TO 1000 : (do something) : NEXT actually operate on integers, which would be way faster. I also think that string storage could be a little bit different too, using double-linked lists (like with BASIC 3.5 and above) - garbage collection would just fly, and I don't think in reality we would lose any compatibility.

    So the framework actually has support for building such a hybrid open-KERNAL + C= BASIC combined ROM. This makes a lot of sense for testing. But of course we can't publish such a ROM, as it will still have the C= copyright BASIC in there.


    As for different number formats etc, I don't have a problem with whatever format we use. It's more important that we get something working, rather than get hung up about the particular format. It is probably also easier to start with an integer only BASIC, and then add floating point after. Also those horrible trigonometric and exponential functions can be added as absolute last thing. There was someone who was expressing some interest in implementing all that, but I can't remember who.


    Paul.

  • I have just received a video, which shows the custom Kernel in action loading and running SMB.

    Here is the link


    It is absolutely amazing to see, that most c64 stuff is running out-of-the-box on the MEGA65 !!!

  • It probably completely takes over the machine, that's why. Try to boot GEOS. Or try to run some game written in BASIC and compiled with Blitz!. Incredible amount of games doesn't work yet.

    BTW, regarding this framework... I'm in the process of rewriting it in C++, most of the work is already done https://github.com/FeralChild6…s/tree/build_segment_tool


    It's going to be more flexible, more user-friendly, more structured, better integrated with KickAss, etc. The most important change is the new algorithm - based on a knapsack problem solution (dynamic programming - as suggested in one of Paul's comments). In short:

    1. If we have a routine large enough that it fits only in the largest gap - place it there (and repeat the check)

    2. Drop all the gaps which are smaller than the smallest routine - they are useless

    3. Select the smallest gap, for the next step select all the routines that can fit in
    4. Fill the selected gap in as tight as possible using the mentioned algorithm; it intentionally prefers using larger routines, to give more opportunities for other gaps
    5. Drop what is left from the gap (forget it), we won't fit anything in any more
    6. If we have more routines to place, go back to point 1.

    We can probably change points 3 and 4 to consider more than 1 gap at once, I think the knapsack problem solving algorithm can be adapted - but it's definitely not necessary for now: https://pastebin.com/mN99L1uN - for current code it's able to fill-in gaps within Kernal ROM to the last byte :) And the algorithm works fast.

  • Oh yes. Sorry if this can be misunderstood. YES it runs on Open-ROMs, that's why i posted it here.

    Thanks Paul !

  • Haubitze - There is one problem with your routine to print hex number - on a real C64 it is only safe to use when interrupts are disabled. Contrary to 65C02, 65CE02, 4510 and 65816, the 6502/6510 does not clear D flag on entering the interrupt (and how will Mega65 behave in C64 mode, I don’t know). Moreover, it seems that C64 ROMs do not execute CLD on interrupts neither (http://forum.6502.org/viewtopic.php?f=2&t=1752) - I noticed lack of CLD in our interrupt routines recently, I was aware that it’s unsafe, and added it - but I’m not sure whether it won’t cause problems in the future, for example when handling the RS-232 we might need every cycle. I haven’t decided yet, most likely your routine will end up as optional (I have started working on the configuration system, so that builds can be customized to some degree).

  • Today is a big day - the current unofficial snapshot (https://github.com/FeralChild64/open-roms/tree/master/bin) is finally able to load files using JiffyDOS protocol - at least from the VICE-emulated 1541 dive :) It's, unfortunately, not too fast, for now only about twice as fast as the original Commodore IEC - that's because JiffyDOS contains specially optimized LOAD loop, which my implementation currently lacks. But the protocol itself seems to be working and that's important.

    There were other improvements done recently too:
    - official Kernal API is quite complete now; besides RS-232 and limited tape support, the only (I think) missing functionality is a pseudo-IEC device #3 (text screen)
    - RUN/STOP key, HELP keys, and function keys are programmable (at compile time); for now I've programmed F1/F3/F5/F7 with functions similar to Final series cartridges
    - the HELP key... the C128 keyboard support seems to be working under VICE; Mega65 keyboard might work, but the code is completely untested (and F9-F14 keys are programmable too!)
    - RUN/STOP terminates quote mode - I always liked this functionality of my BlackBox cartridges :)
    - there is a simple Turbo Tape 64 compatible loader, can be accessed either by loading from device #7 (like on Final cartridges), or using <left_arrow>L (Black Box v3 and v8 cartridges I was using as a child had it implemented this way); supports LOAD only - no SAVE, no VERIFY, no sequential files; I'm not going to implement them, I consider tape as a legacy medium; loading files saved in normal Commodore format is not implemented yet

    ------

    Now... anyone knows how to use 32kb 1541 drive ROMs on VICE? Neither S-JiffyDOS ROM, nor the DolphinDOS works for me, I only get a blinking let after trying to access the disk (yes, would like to have DolphinDOS supported too).


  • I'll definitely still focus on Kernal in the near future. My personal TODO list for the Kernal (items marked as '(distant future)' will probably be done only after BASIC reaches certain maturity level):


    1. IEC/IEEE-488


    - test/finish the JiffyDOS - we really need the optimized LOAD loop (I'm considering blanking the screen during loading, SJLOAD does this and is faster than original JiffyDOS ROM), and working SD2IEC is a must for me (I haven't tested it yet) - once these are done, I'm going to merge my changes upstream

    - reverse engineer and implement DolphinDOS protocol (both serial and parallel); blocking point: I can't get it to work under VICE, not yet sure why

    - support CIA 1/2 burst mod - burst is the 'Commodore way', so I would like to have it supported

    - (distant future) Mega65 should be fast enough to implement the burst protocol in software

    - (distant future) native support for IEEE-488 cartridges


    2. RS-232


    - integrate UP9600 driver - already started working on this, but it's a little bit more complicated than I initially thought

    - integrate UP2400 driver

    - support the ACIA mod - Mega65 is going to implement ACIA, I see Gideon is working on ACIA for Ultimate64, so it's probably THE way to provide device #2


    3. Tape


    - add LOAD support for normal (non-turbo) tapes

    - (distant future) implement tape speed calibration in our turbo tape implementation

    - (distant future) try to autodetect file format (normal/turbo) while looking for synchronization sequence


    4. Screen editor


    - there are quite a lot of well-known SYS addresses (already provided stubs), we should support them

    - fancy Mega65 logo display crashes under XEMU - investigate why

    - (distant future) possibly implement some implement C128/C65 features (style TAB-handling, ESC sequences, etc.) using mega65 extra RAM


    5. Compatibility


    - pseudo-IEC device #3 should be supported

    - GEOS (including MP3) should boot; it's autostart code is nasty, it overrides the CPU stack

    - more file browsers should work, not just FB64; FIBR is most likely the next candidate

    - test more games


    6. Misc


    - Mega65 has extra ROM, we should move some parts of Kernal (where it won't hurt the performance too much) to it and utilize the 'far JSR' Mega65 feature

    - we need to provide user-friendly Kernal patcher, so that people can use our Kernal features with original CBM BASIC

    - (distant future) rethink the RAM-under-ROM support concept - IMHO for Mega65 the best option would be to leave the '38911 BASIC bytes' for BASIC text, but store all the variables in Mega65 extra RAM

  • Almost two months has passed since I published my TODO list, time for a small update:


    1. IEC/IEEE-488 - JiffyDOS and DolphinDOS work now, we can even support both at the same time. Still TODO:


    - support CIA 1/2 burst mod - burst is the 'Commodore way', so I would like to have it supported

    - (distant future) Mega65 specific burst protocol support - I see the C65 has special registers for it

    - (distant future) native support for IEEE-488 cartridges


    SpeedDOS protocol should be doable too, it looks similar to DolphinDOS - but I don't think it's worth the effort.


    2. RS-232 - for now on hold, TODO:


    - integrate UP9600 driver - already started working on this, but it's a little bit more complicated than I initially thought

    - integrate UP2400 driver

    - support the ACIA mod - Mega65 is going to implement ACIA, I see Gideon is working on ACIA for Ultimate64, so it's probably THE way to provide device #2


    3. Tape - LOAD works for normal/turbo, as devices 1 (for normal) / 7 (for turbo - Final Cartridge / Action Replay compatible), there are visual 'stripes' effects (for both normal and turbo), there is a simple '←L' support in BASIC, turbo loads up to 250 blocks (can store bytes under I/O) and gives audio effects, there is a save system autodetection (type, for example, '←L', and don't worry whether it is normal/turbo program), both systems auto-adjust reading speed for slight tape speed variations, many of the features are configurable at compile time, there are some special options for cassette adapter users (so that the code does not try to stop tape motor after file name is displayed, and detects pressed play button by arriving pulses - not by a button sense bit). On Mega65 the tape support can go to it's extra ROM, taking VERY little space in the $E000-$FFFF block - but this is really untested (XEMU does not emulate tape).


    TODO (new item):


    - (distant future) for Mega65 add a simple head alignment utility, we've got plenty of ROM space there


    4. Screen editor - rework/bugfixing/optimization done since the last update. Still TODO:


    - there are still several well-known SYS addresses which are not supported yet (but less than 2 months ago)

    - (distant future) implement some C128/C65 features (80 columns, style TAB-handling, ESC sequences, etc.) and 80 columns mode


    5. Compatibility - some fixes done (mainly due to screen editor rework), but TODO list is still valid:


    - pseudo-IEC device #3 should be supported

    - GEOS (including MP3) should boot; it's autostart code is nasty, it overrides the CPU stack

    - more file browsers should work, not just FB64; FIBR is most likely the next candidate

    - test more games


    6. Misc - added infrastructure to use Mega65 extra ROM, decided to use MAP/EOM; it's emulated by XEMU, tested, and more flexible than 'far JSR with mapping' feature. It's slower - but for many routines it doesn't really matter. For now it is used for tape code and Kernal initialization routines (which is about 1.4 KB of code...)


    Still TODO:


    - move even more code to extra ROM: BASIC interpreter initialization and startup banner printing, tokenization, error message display, LIST command, all BASIC strings, DOS Wedge - these won't hurt performance in a visible way (to consider: parts of IEC code for standard protocol)

    - we need to provide user-friendly Kernal patcher, so that people can use our Kernal features with original CBM BASIC

    - (distant future) rethink the RAM-under-ROM support concept - IMHO for Mega65 the best option would be to leave the '38911 BASIC bytes' for BASIC text, but store all the variables in Mega65 extra RAM


    -----


    Nevertheless, I have enough of the I/O for some time, started working on floating-point support. They are not that hard to implement as I though. I optimize for speed, probably that's the reason why my routines are often slightly longer than CBM ones (other possibility - they used separate subroutines for some code). That means sometimes the original location will only contain a compatibility 'JMP' - which won't even be used internally (jumping directly to the real address saves a few cycles). For SQR/EXP/LOG I hope to use faster and more precise routines published on Codebase64. For other transitionals (like SIN) I plan to use polynomial approximation (like original ROMs), but with some advancements, like splitting the domain and using different polynomials for different parts - CORDIC method is out of question, it requires too much temporary space in RAM (common problem with many 'better' routines, for example the ultra-fast floating point multiplication requires 2KB of space for precalculated constants).


    I expect that for C64 we will have to drop some rarely used BASIC features (not enough space...), for Mega65 - well, we've got plenty of ROM space there :D

  • Excellent news.


    That's amazing what you have achieved !

    So you have built in TurboTape ? when using 7 ? Did i understand this correct ?

    Nice news for the Datasette users i suppose.

    we need to provide user-friendly Kernal patcher, so that people can use our Kernal features with original CBM BASIC

    - (distant future) rethink the RAM-under-ROM support concept - IMHO for Mega65 the best option would be to leave the

    Looking forward to it !


    GEOS with mp3 support. those news sound amazing


    Thank you very much !!!

  • GEOS is still on my TODO list, it doesn't boot yet.

    > So you have built in TurboTape ? when using 7 ? Did i understand this correct ?


    Right, for loading turbo the default is LOAD"",7 - it's Kernal level implementation, if turbo is compiled-in, everything trying to load from device #7 will load TurboTape64 format. If you compile-in a 'tape wedge' into BASIC, then you have a shortcut for this, ←L - I know several turbos (both cartridge-based and standalone) that uses this syntax. And, finally, if you compile-in autodetect feature, both LOAD"",7 and LOAD"",1 work - and both will load normal/turbo, depending what they find on the tape.

    With original ROMs the autodectect wouldn't be easy to implement - you would probably have to reimplement the whole normal system loading code. How it works?
    - AFAIK the original ROM uses interrupts for reading from tape, it setups the CIA to generate interrupt as soon as pulse is detected, than the time from previous pulse is measured - see IRQTMP description in Compute's Mapping the Commodore 64
    - Michael Steil wrote a minimal (normal) tape loader (see article on his blog), where he used different method - he sets the timer A to countdown from 7 to 0, and timer B to count the timer A underflows; when the impulse arrives, it checks how much underflow timer B counted; resolution is 8 cycles here, this matches the TAP file format resolution
    - probably most turbo loaders uses different technique (see example on Codebase64 by enthusi/Onslaught) - they setup timer B and when it runs off they check whether the pulse has been registered - iof yes, it is interpreted as short, if not - as long

    At the beginning my turbo was mostly a clone of enthusi/Onslaught example, and my normal loader was based on a description on Michael Steil blog. And then the code evolved - I finally decided to set the CIA timer A to countdown from 3 to 0, and timer B to count underflows to gain more precision without loosing a single byte of the ROM space (in practice the measurement is never really precise, as several CPU cycles pass between each check whether the pulse arrived or not; I hope with Mega65 48MHz mode we will achieve measurement precision not possible on original C64) and used such setting for reading BOTH normal and turbo formats - this way if they are both compiled it, they can share some code. Now, the timer B counts down from $FF to about:

    - $CD - turbo, short pulse
    - $B1 - turbo, long pulse
    - $A5 - normal, short pulse
    - $7D - normal, medium pulse
    - $A5 - normal, long pulse

    These are average values measured under VICE on a TAP files recorded under VICE too. In reality, we compare the pulse length to the threshold located in the middle (this threshold is being constantly adapted depending on the measured pulse lengths, to adjust for tape speed differences due to imperfect mechanisms, tape being stretched over time, etc.). Note: the longer the pulse, the smaller the value :)

    Both normal and turbo loaders start by looking for a so called synchronization signals - for normal this is a long series of short pulses ($A5), for turbo this is a series of bytes $02 (which are coded as 6 short pulses, $CD, one long pulse, $B1, and again one short pulse). I haven't even tried to distinguish the normal short pulse ($A5) from turbo long pulse ($B1), this would probably be unreliable. But it's perfectly feasible to distinguish turbo short pulses (7/8 of turbo synchronization sequence are $CD pulses), from normal short pulses ($A5, the only ones in normal format synchronization signal) - so before we start looking for synchronization, we first run the format detection (we are loosing a short period of synchronization signals, but that's not a problem, they are long enough to allow for some tolerance).

    But that's not all - if we are already looking for turbo tape synchronization, but instead we are finding only pulses longer from $CD - well, either someone saved a sequence of $FF bytes (on turbo each is coded as 8 long pulses, $B1 ones), or this is not a turbo tape file - so we go back to detection routine.

    Similarly, the normal synchronization routine looks for 'foreign pulses' - if it finds something much shorter than normal system short pulses, it goes back to format detection routine too.

    -----

    In fact, I'm considering some changes (setup the CIA timer A to count from 2, not from 3, to achieve more precision), but this would need code adaptation in several places. Maybe someday.