Using 'clear' from within machine code ...

A place to discuss everything Dragon related that doesn't fall into the other categories.
Post Reply
tjewell
Posts: 347
Joined: Mon Oct 19, 2009 4:58 pm
Location: Cambridge, England

Using 'clear' from within machine code ...

Post by tjewell »

Hi all - I'm tinkering with some old code I wrote some 30 years ago. It's an extension to basic, so I need it to behave nicely. It loads from $7000 upwards, but back in the day, I didn't want people to have to do a "CLEAR 100,&H6FFF" before loading (I wanted to make it easy), so I did it for them. So when you first execute the code, it writes values into $23 to $28 to set the top of basic, string space etc.

Is that enough? Do I also need to call a ROM routine to get the Dragon to notice? Is it even sensible? Given I will have just overwritten any strings that were sitting there, is it a bit like closing the door after the horse has bolted? What did m/c programs that needed to sit nicely with Basic used to do?

Thanks in advance, Tony.
pser1
Posts: 1665
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Using 'clear' from within machine code ...

Post by pser1 »

Hi Tony,
I think that if you fill these system variables on entry ($23,$25,$27) it should work
as long as you set the new stack under the new reserved string space and then go back to
basic by jumping to $8371
Ideally you should disable interrupts before changing variables and then enable them before
jumping to the Basic interpreter
It's just a question of try and pray ;-)
I would expect that this program simply installs itself (the add-on commands) and wants to
give control back to the interpreter ...

cheers
pere
tjewell
Posts: 347
Joined: Mon Oct 19, 2009 4:58 pm
Location: Cambridge, England

Re: Using 'clear' from within machine code ...

Post by tjewell »

Ah, good advice about the interrupts!

Normally, when I write a simple m/c routine, I just end it with an RTS. What happens differently if I call $8371 instead?

Cheers, Tony.
Sarah
Posts: 177
Joined: Wed Apr 13, 2011 3:36 pm
Contact:

Re: Using 'clear' from within machine code ...

Post by Sarah »

Unfortunately it isn't strictly safe to do what you wish as there's no getting away from the fact that loading before CLEAR might overwrite the stack and crash the system. You can make assumptions that'll work fine on a freshly powered up machine and/or decide not to care about memory that may or may not already contain graphics or BASIC but obviously if something like CLEAR 200, &H7100 is executed before loading then you run into trouble. Initially loading into lower memory and having your code safely relocate itself might be preferable however a two stage loading process that ensures the memory you need is reserved before loading something into it is probably the best option. Perhaps also worth considering calling the ROM routine to perform the CLEAR for you?
tjewell
Posts: 347
Joined: Mon Oct 19, 2009 4:58 pm
Location: Cambridge, England

Re: Using 'clear' from within machine code ...

Post by tjewell »

Thanks Sarah! I did have a nagging feeling this wasn't the safest or cleanest way of doing it.

I just stumbled across this thread - viewtopic.php?f=8&t=536 - and that's given me some good ideas on how to make this autorun, and behave itself too. Thanks for that too!
User avatar
tormod
Posts: 416
Joined: Sat Apr 27, 2013 12:06 pm
Location: Switzerland
Contact:

Re: Using 'clear' from within machine code ...

Post by tormod »

tjewell wrote:Hi all - I'm tinkering with some old code I wrote some 30 years ago. It's an extension to basic, so I need it to behave nicely. It loads from $7000 upwards, but back in the day, I didn't want people to have to do a "CLEAR 100,&H6FFF" before loading (I wanted to make it easy), so I did it for them. So when you first execute the code, it writes values into $23 to $28 to set the top of basic, string space etc.

Is that enough? Do I also need to call a ROM routine to get the Dragon to notice? Is it even sensible? Given I will have just overwritten any strings that were sitting there, is it a bit like closing the door after the horse has bolted? What did m/c programs that needed to sit nicely with Basic used to do?
To let BASIC clean up all its pointers you can call into the "NEW" routine. I did it like this in a loader for HDBDOS-in-RAM:

Code: Select all

* do a CLEAR 200, &H5FFE
        ldx  #$5FFE
        stx  <$27       ; end of "physical" RAM for BASIC
        leax -200,x
        stx  <$21       ; address of stack for BASIC
        tfr  x,s
* do a NEW to initialize other BASIC pointers
        jsr  $8417
* start your code
        jmp  $6002
Of course calling NEW won't cut it if you want to preserve any BASIC program the user already has loaded. Like Sarah mentions, it can also make sense to load your initial code to somewhere that is safely away from the stack, in case the user loads your program after using BASIC. For instance into a low graphical page, although that that moves around if you are using a DOS.
Ah, good advice about the interrupts!
The interrupt routines do not reference any BASIC variables or pointers, so I am not sure that would be necessary.
Normally, when I write a simple m/c routine, I just end it with an RTS. What happens differently if I call $8371 instead?
Jumping to $8371 (OK prompt) makes sense if you have changed the stack pointer and thus invalidated the return address that RTS would use. Otherwise RTS should be fine.
Post Reply