Repository navigation
firmware: run C128 BASIC programs in 128 mode on a C128, and add Exit to C128 BASIC - #96
Conversation
…xit to C128 BASIC On a C128 the menu runs in C64 mode, so a C128 BASIC program loaded today lands in C64 RAM and cannot run. A small function ROM, polled by the C128 kernal, now streams the program to $1C01 and types RUN. Its ID asks for the late call from PHOENIX, which BASIC's cold start makes after its NEW, so the program survives. A PRG is taken for one when it loads at $1C01 and its first line link points just past that line's end; an empty one returns to C128 BASIC.
… to C128 BASIC is in Utilities
… comments that restate the code
4f26168 to
e15aa57
Compare
SensoriumEmbedded
left a comment
There was a problem hiding this comment.
Thank you for the ability to run C128 BASIC programs in 128 mode, and for Exit to C128 BASIC, it's great to have C128 programs launch the way a C128 owner expects! :)
I reviewed this merged onto current main (ac24701) and built both targets. There's nothing I'd like you to change before merging.
Memory: no RAM1 code (ITCM) on either target, and free for local variables is unchanged on both. DTCM content grows 48 bytes on TR+ and 56 on TR (the new Utilities entry and its name), inside the current alignment step, and flash grows about 2 KB.
Hardware tested
On a TR+ with this PR merged onto main, along with your TR+ and TR tests on an NTSC C128. All passed:
- NTSC C64:
- Exit to C128 BASIC refuses with "C128 BASIC needs a C128" and stays in the menu.
$1C01programs (plain BASIC, a SYS line with machine code after it, and a.P00) still load in C64 mode.- A
$0801program still runs.
- NTSC C128, 40 columns:
- The same
$1C01files, launched from SD, reset into 128 mode, land at$1C01and RUN. - Exit to C128 BASIC comes up in empty BASIC 7.0.
- The
$0801program still runs in C64 mode. - A reset returns to the TR menu each time.
- The same
- NTSC C128, other launch paths:
- A hot key.
- Power-up autolaunch from
autolaunch.txt, with the 40/80 key up and down.
- NTSC C128, 40/80 key down:
- Exit to C128 BASIC, and a remote launch, both come up on the 80-column screen and RUN.
Hardware testing: Just to document. I'll hit these at some point, not a request or requirement! :)
- PAL C128
- Exit to C128 BASIC from the TR menu on a TR
- A
$1C01program extracted from a D64 - C128D, or a C128 with JiffyDOS or an internal function ROM
Thank you!
|
Coming in a little late with this review, but there's a case I think might need considering in a next update. Lightly edited from Claude...
For vdrive, I will look into a C128-mode-aware version in due course. |
On a C128, a C128 BASIC program launched from the TeensyROM now runs in 128 mode instead of loading into C64 mode, where it cannot run. A C64 program launches as before. The Utilities menu also gets Exit to C128 BASIC, which restarts a C128 in 128 mode with no cartridge, as a power-on would.
How a program is recognized
A PRG is treated as C128 BASIC when it loads at
$1C01and its first line link points just past a zero byte inside the file, which is how a tokenized BASIC 7.0 program starts. Anything else, including a$1C01file whose link doesn't check out, takes the existing C64 path. The menu reports whether the host is a C128, so a C64 still gets the C64 path even for a$1C01program. An empty program (link$0000) means "just start C128 BASIC": that's the Exit to C128 BASIC menu item, a 4-bytec128basic.prg. On a C64 it is refused with "C128 BASIC needs a C128".This runs where a
.prglaunch is already decided (DriveDirLoad.ino), so it covers every entry point: the TR menu, remote launch, the host app's file list, NFC, hot keys and autolaunch.How it runs
StartC128Prg()resets the C128 into a 1.25 KB function ROM (Source/C64/C128PrgBoot/) that the C128 KERNAL finds at power-on through its ID byte$FF, the one that runs after BASIC's own cold start. The ROM copies a small loader to$1300. The loader streams the program from the TeensyROM's stream register to$1C01, switching the MMU between I/O and all-RAM for each byte. It then sets the end of BASIC text and putsRUNand a return in the keyboard buffer. Before restarting BASIC it tells the firmware to drop the ROM (rCtlVanishROM), so a later reset gives a plain C128. Programs up to$FF00fit, so the end of BASIC text goes as high as 59392.The boot ROM is copied out of flash through a pointer the optimizer cannot see through. A plain
memcpyof the wholePROGMEMarray made GCC keep a second copy in.rodata, which on Teensy is DTCM, and on the TR+ that cost a 4 KiB step of free-for-locals.Verification
npm test: 364 pass. New host tests cover the classifier and the launch path (Source/Teensy/tests/c128-prg.test.jscompiles the realC128Prg.inoagainst stubs), and the loader in a 6502 model (tools/c128/c128prgboot-run.test.mjs).PLAY);GRAPHIC 5) runs on the VDC;Memory
Main image, Docker linux/amd64, Teensyduino 1.61.0,
origin/main(ac24701) vs this branch:The TR's +64 bytes of RAM1 code are a codegen change in
LoadFile. It doesn't cross an ITCM bank, so free-for-locals is unchanged.Review
Each commit was reviewed at
mediumorlow, and the branch got a finalhighpass. That pass found the DTCM copy described above, and its fix is folded into the commit it reviewed.