12 posts / 0 new
Last post
C128 BASIC wedge information wanted

Hello,
for my project the "Cassiopei" I'm trying to port the BASIC wedge I've written for the C64 to work on the C128.
Although this may not sound too difficult, I'm struggling, as basic 2 (C64) is not the same as basic7 (C128) so difference in ROM routines and pointers make it hard for me to find out where my problem really is. Most wedge examples you see use the chrget method. And although it is possible to make a wedge using this method only and implement functions (a=!adc,1 where the !adc,1 returns a value to basic so basic can put in into variable named a) I prefer not to.
So on the C64 I used the IGONE and IEVAL vectors to intercept basic commands. On the C64 this works great, and although the C128 appears to have these same vectors, the code I've writen doesn't work. So there is a difference. What I'm looking for is information about wedges for the C128. I'm sure that there is an article somewhere describing this, but on the internet I failed to find it. I also browsed through several magazines but I could not find it (perhaps I overlooked).
So in short... is there anybody out there with information regarding wedges on the C128?
Kind regards, Jan Derogee

Congradulations for using

Congradulations for using IGONE.  That is the correct way to do it.  I've seen implementations use cheap hacks like CHRGET and IERROR instead.
 
The trick is, you must put the code in CommonRAM, below $400.  This is because the ROM does not invoke a specific Bank before it jumps to IGONE (only after) so any memory configuration would be active... in other words, if the vector points above $400 then your code will randomly crash, depending on which Bank is actually active.
 
There isn't much free room below $400, so you probably want to write a short "jump code" like:
.03E4  STA $FF03
.03E7  JMP MyGone
and then point iGone to $3e4.  That example (5 bytes) sets BANK 14 (the STA $FF03) which gives Bank 0 RAM plus all System ROMs (but no I/O).  This is probably what you want, unless you need to call I/O routines in the KERNAL.  In that case, you would want to add 2 bytes and use:
.03E4  LDX #0
.03E6  STX $FF00
.03E9  JMP MyGone
That example (7 bytes) instead sets BANK 15, which gives Bank 0 RAM, all Systems ROMs except font, and I/O registers.
There are 12 bytes available from $3e4 ~ $3ef, so you could use 2 of the short version (one for IGONE and another for IEVAL), or one short version and one long version, but there aren't enough bytes for two long versions.
 
You may be interested in looking at the source code of BASIC 7.80 which patches IGONE and IEVAL (and some others, I think).  It is a bit of overkill for what you are trying to do, as it remaps ALL existing keywords in order to make the many graphic-related commands and functions work with the 80-column screen... but hopefully it will give a concrete and more complete version than I can post here.  (You can find a discussion forum here.)
 
As far as finding the routines in ROM, get a good book about the C128 (the BASIC in particular) such as Commodore 128 Book 2 - BASIC 7.0 Internals, which you should be able to find at Bombjack.


I'm kupo for Kupo nuts!

Re: Congratulations for using

Hydrophilic wrote:

> You may be interested in looking at the source code of BASIC 7.80...

I keep forgetting to tell C= people of your achievement. :)

On the road,
Robert Bernardo
Fresno Commodore User Group
http://www.dickestel.com/fcug.htm

Hello Hydrophilic, thanks for

Hello Hydrophilic, thanks for your tips, I'll give them a try.
Kind regards, Jan D.
 

Hello Hydrophilic,

Hello Hydrophilic,
a small break-through as my IGONE part of the program seems to be working.... BUT for some reason it only works in PROGRAM mode and not in DIRECT mode.
I expected it to work in both modes as it does on the C64, but for some reason the C128 is different or I must forget something, any suggestions?
Kind regards, Jan D.

Direct-mode BASIC extensions

Off the top of my head, it sounds like it should work... but I do recall BASIC doing some nasty tricks to implement error trapping, which is similar to the nasty hack used to implement THEN / ELSE.
 

In the case of THEN / ELSE, BASIC will actually by-pass its own vector (iGone) which will cause many additions to BASIC to fail with those keywords... I'm sure anybody experienced using any BASIC extension will probably remember the trick is to include a colon ( : ) after THEN / ELSE before the new command.  This forces to BASIC to use the normal/proper code path (through iGone).
 
Anyway, regarding direct mode, here is a super simple test... it does not require any code changes or a re-build :) :)  Simply begin your direct-mode command with a colon.  Then (hopefully) your new command(s) will work correctly.
 
If that fixes the problem, it means you'll have to patch iMain.  This is very simple code.  It does this:

  1. Reads a line of text from the console into $200
  2. Checks for a (line) number at the beginning
  3. Crunches the (remainder) of the text at $200
  4. If a line number was found, the crunched version is saved in program RAM
  5. If a line number was not found, it executes the crunched tokens at $200

So if inserting a colon made your new commands magically start working in direct mode, then you need to fix step 5.  I imagine it ignores iGone like THEN / ELSE.
 
Sorry I forgot to mention iMain before... I patched it in my code for multiple reasons and forgot about it...
 
Also, I think iMain is always (?) called in Bank 14, so you shouldn't (hopefully) don't need a short "jump routine" in Common RAM like with iGone.  This because there wouldn't be a good place to put it.  I would test it without the the jump in Common RAM... if you do need a "jump routine" then one place is at $13e.  This is just above the cassette error-pass log, and below the normal BASIC CPU stack use (which in theory starts at $163).  The area between $13e ~ $163 is "slack space" to allow for internal use by BASIC and system IRQs.  Using a 5-byte jump code would still leave 32 bytes of slack space so it should be safe (I never had a problem with it).
 
BASIC 8 (IFRC) does a similar trick with a jump in Common RAM but they put it lower, inside the cassette error-log, which means after you load / open (or simply search) for a file from cassette, BASIC 8 may crash :(  I don't own a cassette, so I don't know if it would always crash (I don't really know how the error-log works)
 
Another (bad/desperate) place in Common RAM is at $2be which is the code for CMPFAR.  Neither BASIC nor the KERNAL uses CMPFAR.  However, the built-in MONITOR uses CMPFAR for its Compare (C) and Hunt (H) commands, as I recall.  Some other software loaded by the user might use it too, although I know of no such software.
 
So anyway, hopefully iMain will work without JMP in Common RAM, but if you need it, $13e is the address I recommend to use (assuming no room remains at $3E4 ~ $3EF).
 


I'm kupo for Kupo nuts!

thanks for the info, I'll

thanks for the info, I'll give it a try soon.
my code is making great progress. I found a website describing some very important routines and how to use them, for a reference to anyone with the ambitions to write their own C128 routines to work with BASIC see the website: http://rvbelzen.tripod.com/128intpt (this website contains translated information from a famous german magazine).

the : trick works

Hello. The : trick works, for now that will be sufficient as I encounter some strange effects some of my new BASIC commands. So I need to fix them first, but the tip you gave was great and it should help me out eventually. Thanks for the info.

stupid me...

hello,
well the problem in my wedge, that took me the whole day to figure out, was caused by a simple memory layout problem. Something called banking. Because all my code worked I did not realize that banking was an issue. But, that is not entirely true, because although I did no crash, there was a problemin my code anyway.
I was accessing $DC0D to check the status of the interrupt flag of the read signal from the tape, but because a kernal routine called earlier had switched the system intoa different memory configuration (i find the name bank a little confusing), I could not see the IO and my routine exitted on a basis of the wrong information, causing all sorts of strange unexplainable problems. So I checked every shackle in the chains of my program ending in only one conclusion... I can't see $DC0D. Now I know why and the problem is easily fixed. So to anyone who reads this, be aware of changes in memory configuration when you call a kernal routine that processes variables. A thing obvious to experienced C128 programmers, a huge pitfall for me. The nice things about this method of learning is that it really sticks into my mind... Now I can concentrate on my real wedge problems.

Glad you were able to figure

Glad you were able to figure that out.  There are only a few KERNAL routines which change the bank (memory configuration), but many of them require I/O registers to be active... in other words you have to (well, may need to) change the bank before calling the routine.  But either way, knowing what memory configuration is active at any point in your code is important for both C64 and C128 programming... it is just that C128 routinely switches configurations while it is infrequent (less troublesome) on the C64.
 
Glad the colon trick helped.  It sounds like you are almost ready...
 
Oh I just thought of something... does your code use any of the cassette code in the ROM?  I was concerned because I know some ROM upgrades, like JiffyDOS totally replace the casette code to make room for the disk fast-loader (and other things).


I'm kupo for Kupo nuts!

Cassiopei and Jiffy-DOS

The Cassiopei is a device connected to the cassette port, if you use it in a system that has no diskdrive then the cassetteport is the only way to load the program (the fastloader) that controls the cassiopei. And for that the ROM routines are used. Because when you switch on the computer you type load and press play on tape. And when Jiffy-DOS is installed, that functionality is gone.
The only way to bypass this is to make the Cassiopei work in combination with a diskdrive or other storage device. So that only the fastloading functionality of the Cassiopei would be used. This means that the fastloader ittself would be stored onto a disk and needs to be loaded from that disk in order to use the Cassiopei. However this is (currently) not suported, simply because it is beyond the scope of using the Cassiopei as the only IO-device on the computer. Perhaps in the future, in the mean time disable Jiffy-DOS. For those who want to play a .TAP file game... they allways need to disable Jiffy-DOS because .TAP files are images of a real tape and therefore must be played like a tape.
So in short, the Cassiopei is not compatible with Jiffy-DOS

Thanks for explaining that.  

Thanks for explaining that.   JiffyDOS is a big deal for C64, but not very important for C128... unless you are stuck with only a standard (slow) serial bus device.


I'm kupo for Kupo nuts!

Log in or register to post comments