Hello, Guest the thread was called16k times and contains 159 replays

last post from FeralChild at the

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

  • And I've got some good news:

    - sending commands to drive seems to work
    - turnaround mechanism seems to work now
    - receiving bytes from the drive seems to work too :)

    Not tested yet:
    - sending normal bytes (not commands)
    - EOI (end of stream)

    Time to add proper disk support for all these OPEN / CLOSE / CHKIN / CHRIN / CHROUT routines now :)

  • Some features of the LOAD command :) Special handling of the second parameter starts at 256 - this was done mainly for testing, I'm not sure if it's going to stay, or if the syntax won't change here.

    Unfortunately, some of my recent fixes broke IEC for some devices - doesn't work with JiffyDOS drive ROMs anymore (what's interesting, still works with SD2IEC) or Ultimate 64 software IEC.

    BTW, currently 3 flavours of the ROMs can be created - generic one (screenshots), Mega65 (fancy banner) or Ultimate 64 (did some experimentation with their Ultimate DOS interface, code is disabled for now).

  • 1. Paul, what is your plan for de-duplication of code (printf, etc.) between BASIC and KERNAL? I thought about a 'private' jumptable within KERNAL, so that BASIC could access the routines there. For the start, it could be placed in some fixed address, eventually we could extract it's location from the map file and pass it in some script-geterated .s file to BASIC (this way KERNAL would be a precondition for building BASIC).

    2. I really don't like this '61436 BYTES FREE' feature...
    - it's using free memory area starting from $2A7 (compatibility problem)
    - it's complicated and slow: for every BASIC program memory read/write we have bank switching, NMI workaround, even disabling IRQs (I'm afraid TI variable won't like it); good that we at least have optimized memory copy
    I've got another idea - 51199 BYTES FREE (MEMSIZ pushed to $CFFF). Less, but still quite a lot, and with the following advantages:
    - no special handling for memory write needed (read: as fast as original, less maintenance burden)
    - for memory read, we would need much smaller peek_under_rom routine, without all the interrupt-related mess, possibly switching RAM/ROM only when needed; with helper code in RAM of 3 bytes only: LDA ($xx), Y + RTS; this should be much more compatible, we could put it in some poorly documented temporary area (maybe even store/restore original content using the CPU stack)
    - since we would probably have I/O available all the time, we could consider using REU to speed-up shift_mem_up and shift_mem_down routines
    - one more advantage: we could switch between 38911 (MEMSIZ at $9FFF - original behavior) / 47103 (MEMSIZ at $BFFF - the 4KB area above BASIC still free) / 51199 (MEMSIZ at $CFFF) models easily at run time; we could simply extend the NEW / CLR commands to accept optional numeric parameter 0 / 1 / 2 and (if parameter given) switch the memory model

  • For 1, this sounds ok to me.

    For 2, I am happy to have different variants, as I think sometimes people care more about having a bigger program versus faster BASIC. Also, when we make a native BASIC for the MEGA65, the speed and other things are not such a problem. How hard is it to have it selectable at compile time?


  • For 2. - I looked again in Ophis manual, I think we could use parametric macros for this purpose. We could have, for example, 3 directories, exactly one would have to be included to the build:

    ,memmodel_38k - for standard C64 behaviour - max speed and compatibility, lowest memory available
    ,memmodel_50k - a compromise, BASIC memory up to I/O space; I think we could try to put helper code where CHRGET resides in RAM - this model won't be compatible with BASIC extensions nevertheless, so we don't need CHRGET :)

    ,memmodel_60k - current solution

    I'm going to try when I have some more time. I need to finally make this IEC code compatible with non-standard drive ROMs.

  • Also, while I think of it, take a look at KickAss, and tell me if you think it would be a better assembler for this?

    (We would still use the crazy program that does the pick-and-place and merges the individual fragment files together).

    The reason being, is that we are looking to move much of the existing MEGA65 assembly stuff over to KickAss, and also

    use KickC for the hypervisor, and having everything in a more common framework would be nice. But I am also okay with

    sticking with Ophis, if you prefer.


  • Interesting. I thought, ca65 will be preferred, once I also managed to make KS (... hyppo) compiled with CA65 which worked on the Nexys4 board with the M65 bitstream without problem. Yes, the label file stuff was a problem that Ophis could generated something CA65 couldn't. I would be quite interested to see the ideas/benefits to choose KickAss, especially since I don't know anything on that, so it would be a great lesson for me, I guess :) Honestly, I hate java in general, but surely that's a minor point (though I hope it's possible to compile it to a regular sane app with a java->native compiler lke gcj).

  • Part of the interest in using KickAss, is that KickC is MUCH nicer than CC65 for what we want to do. It is only a subset of C, but has a bunch of nice things for 6502, and generates much more efficient (and readable!) code. It should also be easy to get the map file out of it, I believe. My goal is that Hyppo can actually be in 99% of KickC, instead of Assembler, which will make it much easier to write, debug and maintain.


  • I see. Though I am not sure, any C compiler generated code can be near as fast and short than a good, hand written asm code, which can be important for the hypervisor because of the limited hypervisor RAM space. But anyway, sounds interesting :) And since I don't know anything too much about KickC or KickAsm, also a good excuse to have a look.

  • Due to my holiday (and also an immense heat that takes away my energy) I progress very slowly now - nevertheless:

    - STOP+RESTORE is working (this was already merged upstream), it tries to silence extra SIDs too - most likely this will end up being configurable during compile time, especially due to these insane 8+ SID configurations the Ultimate 64 users are playing with

    - PAL/NTSC detection done (video system shown on the startup banner), DOS Wedge (@<drive_number>, @<command>, @$, @$<params>, @) also works - both merged some time ago

    - I finally managed to get the IEC code to work if the drive has JiffyDOS installed. Reason found by accident, when I stopped looking for the bug and started cleaning up the code :) It seems the SD2IEC projects' JiffyDOS implementation has quite nicely commented code, there might be detailed enough to add JiffyDOS to our ROMs :D

    - Kernal interrupt handling got improved... including a slightly extended BRK handler. Attached screenshot shows a crash of the FB64 (a well known file browser) - it clearly tried to call LINPRT (unofficial routine in BASIC ROM), which is not implemented (or, rather - implemented, but with incompatible parameter handling and in the wrong place) and the location contains $00 (which is a BRK opcode). Two official Kernal routines already went to their original locations, I won't be surprised if we end up with a jumptable very close to the original one... maybe with the exception of SETTMO :P

    - not counting the tape and RS-232 support, the Kernal is mostly complete now... the big missing are SAVE and pseudo-IEC devices 0 and 3, plus some minor bits

    @Paul, is the decision to use KickAss final? Ophis limitations (especially lack of conditional compilation) start to be problematic for me, I might start the transition after I handle the similarities in current code.

  • hey there.

    i dont to narrow your work but i think it can simplified a bit... so i only try to help.

    in https://github.com/MEGA65/open…asic/basic_execute_line.s

    lines 60-65 can simplified so

    1. ldx #<basic_current_statement_ptr
    2. ldy #0
    3. jsr peek_under_roms
    4. ;;cmp #$00
    5. beq basic_end_of_line

    and here the subroutine in line 85-117 (not realy bether my version so i think)

    then the subroutine in line 136-144 (but here im not sure)

    so far my 2 cents.

    i find this project very interesting and i hope i can summit another code snipets to shorten a bit of the basic rom size

    and give more space for other things. i will take a look to another .s files ^^


    Edit: yeah i see alot of

    1. jsr anywhere
    2. cmp #$00
    3. beq +

    so far i see the jsr's always gives a returnvalue in A+Carry back, so all the cmp #$00 can be revoved (commended).

  • @Paul - the framework is not going anywhere, I'm going to adapt it too.

    @Haubitze - I have just checked, removing the cmp #$00 after jsr peek_under_roms is not a good idea - I have just tried it within basic_execute_line.s (lines 60-65) and as a result a simple program:

    1. 10 LOAD"$",8
    2. RUN

    didn't load the disk directory any more. These under ROM routines are really tricky (I don't fully understand them yet) - but feel free to experiment.

  • oh okay, i dont know that and i haven'd take a look to peek_under_roms.

    but here https://github.com/MEGA65/open…master/c64/basic/printf.s i see the function printf_printhexbyte:

    i use another implementation and think (if i count right) it is a bit shorter. so here my version.

    i also see that the kernal has also this printf.s source and its almost the same code if i see it right, so why not use a kernal call and delete it from basic?

    edit: i see the peek_under_roms_routine: and idont know why removing cmp #$00 causes this load bug that you discripe. it saves the status register and restores it. so idk

  • Something is not exactly right,

    1. lda #$20
    2. jsr printf_printhexbyte

    prints out 2Q instead of 20.

    [EDIT] I know what's wrong, after you pull the .A back from the stack you have to zero the high nibble, for example by and #$0F. Thanks for the idea - it's still 6 bytes saved, pushed the commit to my working branch. Thank you!

    Regarding peek_under_roms - here is the answer:

    1. peek_under_roms_routine:
    2. php ;; <- pushes CPU status register to stack
    3. stx peek_under_roms+pa-peek_under_roms_routine+1
    4. jsr memmap_allram
    5. pa: lda ($00),y
    6. jsr memmap_normal
    7. plp ;; <- restores status register; whatever was present in N/Z flags after lda is now gone
    8. rts

    Yes, some code is duplicated between BASIC and Kernal, and this is going to be fixed at some moment. Problem: BASIC needs to know precise Kernal address to call. One solution is to put the Kernal 'printf' routines under predetermined address, but this is not really elegant. It would be better to pass the addresses to BASIC during the compilation - but this would require build system changes. Since we are switching to different assembler - not much sense to do it now.

  • hm i think now i understand it right, if make it so

    1. ldy #$00
    2. jsr peek_under_roms_routine
    3. beq +

    it will pass (untested)

    if i make it so

    1. ldy #$00
    2. iny
    3. jsr peek_under_roms_routine
    4. beq +

    it will not pass. i haven'd a testsuite so if you can, can you proof it?

    so i think it has to do with the last lda/adc/sbc/inc/dec opcode (A/Y/X variants also).

    so yeah i think it is a bit tricky to see the big pikture with this peek_under_roms_routine.