Hello, Guest the thread was called5.1k times and contains 106 replays

last post from Datasette at the

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

  • @gardners I've forked the project and started working on a DOS wedge:


    If I'm doing something really ugly, please tell me. I didn't touch 6510 assembler since my childhood. Plan: use it as a simple testing tool to fill-in gaps in the current Kernal IEC support.

    One question: are you planning any kind of compile-time configuration? Like: FEATURE_DOS_WEDGE=Y somewhere... I try to optimize code for size, but we might run out of ROM space at some point.

  • I'm planning to add a pre-processor, so that we can have #ifdef and friends for conditional compilation. One added trick is that we may want to select whole files on the basis of such things, so I'll probably add some facility for indicating inside a file which targets it is/isn't meant for, or which optional features it is/isn't needed for.

    As for CIOUT, the necessary code is implenented in LOAD, but hasn't been broken out into all of the necessary separate routines. You are welcome to do so, it shouldn't be too nasty a job, and it will be very helpful. Perhaps start by making the issue on github first, and then you can reference the issue in the commits as you refactor, so that we can trace what is going on?


  • I've just thought of a potential show stopper: If LOAD works properly, shouldn't it just load the data in the file to the address shown in the header? If that is the case, then clearly it isn't going to work with saved BASIC programs, which if memory serves are stored as data as they appear in memory. Although it will work just fine for assembly language programs.

    :: @Goatflakes added on 14 Jun ’19 · 01:26

    ^are store as they appear in memory, already tokenised

    :: @Goatflakes added on 14 Jun ’19 · 01:48

    I meant to say, it's not going to be able to LOAD BASIC programs written on any other machine or indeed KERNAL and BASIC ROM set than the one being developed, because it doesn't do any interpretation or tokenisation, it just places the bytes it sees after the two byte header, one after the other, to the address in memory as given by the little endian memory address stored in that header.

    :: @Goatflakes added on 14 Jun ’19 · 01:52

    That works for both machine language programs, BASIC and even things like sprites, because when a SAVE is done, it just defaults to saving the BASIC area of memory, where the commands are stored. But you also instruct it to save a different area of memory. In either case, this starting address is saved as a two byte header so it can be LOADED back, raw, into the memory address it came from.

  • It will take me a couple of days before I reach CIOUT. I also need SETNAM (not yet implemented), CLALL would be nice to have (I call it at the start of each @-command so that I'm sure I have free channels for opening), I need vectors under $031A (I want to be system friendly with my wedge, so that it has a chance to work with IDE64, RAMDOS, etc.), and who knows what more - well, even more 6502 assembler knowledge (I was never really good at it - I had very little literature on the topic, and no Turbo Assembler, only FC III and AR carts back in the day...).

    I think I'll just implement/test what's missing and then we will refactor the LOAD.

  • @Goatflakes - tokenization result has to be compatible between original ROM and this implementation, there is no other option.

    LOAD "filename",8,1 - loads data from disk to the location stored in the file (2 byte header)
    LOAD "filename", 8 - loads to the default location (on C64 standard is $0801, but this can be changed by modifying TEXTTAB variable in zero page), afterwards the pointers within BASIC program (single-linked list) are recreated, the 2 byte header is ignored in this case

    We have another problem: autostart software. It typically loads from well below $0400, overrides various vectors (so if ours are different than original ones, we will end with crash; that's the reason why autostart software disables most of the BASIC extensions, etc.). And we can't just ignore the bytes overriding vectors, as sometimes the autostart software contains slightly modified vectors, to point it's routines :/

    But my biggest concern are all these '*_under_rom' routines, which are placed in memory area reserved for use by the user, this is a disaster waiting to happen. IMHO the concept will have to be changed at some point, for example the peek could work in the following way:
    - peek from below BASIC ROM or in the $C000-$CFFF area - operate normally, o bank switching, no interrupt handling, etc.
    - peek from RAM under BASIC ROM ($A000-$BFFF) - handled by code located in KERNAL, should temporary disable BASIC ROM to perform the peek, no interrupt handling necessary
    - peek from RAM under KERNAL ROM or IO area ($D000-$FFFF) - code located in BASIC ROM should temporary disable KERNAL ROM to perform the peek, only this part should do the interrupt handling workaround

  • If something is written to the address of ROM, isn't it written ok, but a read will get the value in ROM until location 1 is changed to switch out the ROM, except if you configure the VIC-II to read from an address there, it always gets what's in RAM. Or at least that's how I understand it :P

  • We should make the _under_rom stuff optional via a #define / compilation option, so that it is easy to generate 38911 bytes free target where compatibility is more important, and the 60KB free variants for folks who want a better basic. Again, the joy of open-source is that we can make it easy for people to pick what they want.


  • @gardens, I've got some questions:

    1. Did you actually test the 'iec_tx_byte' and 'iec_rx_byte' routines?

    They look complete to me, but... Kernal 'open' routine also looked complete, but now I see that it requires some work - for example, support for the LAT / FAT / SAT tables is completely missing (I'm going to add it now). So far my work is 80% research, 5% writing code, 15% testing with 'printf' and Vice built-in monitor :)

    2. What will be your policy regarding merge requests? Do you expect me to run the similarity tool and add comments, or would you prefer to do it by yourself?

    3. Could we finally settle the license? LGPL is fine for me. If you are unsure, you can add a contribution policy - that we all allow you to release the code (with our contributions) under any OSI-aproved open-source license; that's also fine for me. But I would really prefer to have some proper license.

  • Hello,

    1. Yes, in so far as I got it to the point where I could LOAD programs. Note that VICE tries to get all clever pants and intercept points in the KERNAL for disk access unless you tell it not to, and of course it assumes it is patching a stock KERNAL. It would be great for someone to offer a patch for VICE to make it only do it when it detects an original ROM. And, yes, I realise that there is a lot of the finer points of the functions already written that need to be implemented, and I am glad that you are thinking about them. The limited time I had on hand to boot-strap this project meant that it just wasn't possible for me to do everything, but this is also why I am so glad that it is now no longer just me working on it :)

    2. Hmm.. This is a question I had not come to a firm answer on. The overall issue is to avoid any risk of copyright infringement. My current feeling is that a single pull-request each time, that includes the similarity strings documented, and perhaps with added documentation about the context in which they occurred that allows us to more rationally assess each contribution to the code base. It's a pain that we have to do this, but I think it is for the best. On that note, it probably makes sense for us to make a tool that allows us to show the similarities in context in both the original and our ROMs, so that we can argue for the reasonableness of each. We basically should have a "copyright infringement avoidance" review on every contribution from here in, including any further work that I do. How does that all sound?

    3. I completely agree and understand. As you and I are currently the complete set of contributors at the moment, and we are agreeance, we shall deem it to be the policy. I'll update the license file. I've forgotten that organisation that makes contributor agreements for projects, but we should use their thing to make one and include it in the project. Would you be willing to hunt that side of things down for me?

  • There was some controversy surrounding GPL v3, specifically the provision in it to disallow use the implementation any sort of digital rights management system. I'm not sure if this applies to LGPL as well, but it might be prudent to use some version 2 or perhaps a newer version of the LGPL that doesn't contain this contentious exception.

    Some have also criticised the GPL for being infectious, in that once you apply it, others can't take your work and then extend it, not matter if your work ends up being a very small part of the derived work, without being forced to use GPL for this derived work. Which is why many projects don't use it and instead use something more permissive like a Berkeley, MIT, Mozilla or Perl style "Artistic Licence".

    Of course these restrictions inherent in the GPL mean someone can't take your work, make a minor enhancement and then sell it commercially and are under no obligation to contribute that back, like what Cedega did with the Wine source by extending Wine with DirectX11 and selling it as a subscription product without any back contribution at all.

    This is a fundamental conflict I guess, and I have not seen a good compromise yet, and it isn't helped by somewhat extreme statements that have come out like Richard Stallman's statement that it was in breach of the GPL to even dynamically link non-GPL licence compatible code with GPL code. Specifically that dynamic linking supposedly creates a "derived work", and therefore it should be bound by the full terms of the original licence.


    I respect the man immensely, but that seems a rather extreme, strange, certainly not the conclusion most reach after reading it, not how GPL software is used in practice and something that is bound to be a nasty surprise for people using a GPL'd library.

    Again, I'm not sure if this applies the LGPL as well as the GPL.

    I have no objections to contributing under any licence, so long as I can reuse my own contributions elsewhere as I see fit, and as long as I don't unnecessarily burden people that might want to use my contribution to do whatever it is they see fit.

  • @gardners

    1. I fully understand you had to make shortcuts here and there, nothing wrong with that at the beginning of the project :)

    2. Well, some kind of "copyright infringement avoidance" review process in place is definitely a good idea :)

    3. I'm not really familiar with all this contribution-policy stuff, I just understand that there might be a need to re-license the code for some unforeseen reason, and contacting all the former contributors might be complicated, or even impossible. As for me, I agree my work to be used even under the non-advertising BSD license :)

    @Goatflakes - LGPL certainly avoids a lot of these problems, AFAIK it was created to be more suitable for stuff like libraries.

  • In the mean time... I think the low-level IEC support (iec_tx_byte, etc.) is incomplete; according to a description here: https://www.pagetable.com/?p=1135 there is a difference between sending a command (you have to manage the ATN line) and a data (there is no ATN step).

    That explains why I can't get Kernal OPEN routine to work.

    :: @FeralChild added on 17 Jun ’19 · 21:12

    One more thing - there are several routines in the IEC support code, that, in my opinion, setup the $DD00 wrongly. I would rather implement them as below - could you double check with me (I omitted the final RTS instructions)?

    lda $dd00
    ora #$30
    sta $dd00

    lda $dd00
    and #$0b
    ora #$DF
    sta $dd00

    lda $dd00
    and #$EF
    sta $dd00

    lda $DD00
    and #$CF
    sta $DD00

    LDA $DD00
    and #$40
    beq iec_wait_for_clock_assert

    LDA $DD00
    and #$40
    bne iec_wait_for_clock_release

    LDA $DD00
    and #$80
    bne iec_wait_for_data_release

  • It seems my proposals are wrong after all (at least the assert/release) - some bits of $DD00 are inversed! https://www.c64-wiki.com/wiki/CIA

    New things to try after work :)

    :: @FeralChild added on 19 Jun ’19 · 21:50

    [edit] Something starts working - the 1541 starts behaving according to https://www.pagetable.com/?p=1135 ; checked it's memory - address $0085 indeed contains the byte I intended to send :) Too tired to continue today...

    :: @FeralChild added on 21 Jun ’19 · 21:50

    [edit] Routine which transfers command to the floppy (on the 'TALK/LISTEN' layer) can now detect whether the drive actually exists. Turnaround still fails - probably it just has to be done under ATN - I'll check it, but not today.