Jump to content
IGNORED

Surviving warm start


Recommended Posts

I'm writing a program that uses a VBI routine, I want the program to survive a warm start which would

mean re-initialising the VBI routine as part of the warm start.

 

My program is run from the DOS prompt mainly with SDX (Incognito or U1M)

The program does what I want until I press reset.

 

I've had a look at addresses $2E0 and $2E1 after the program has loaded and they are not

set to $00,$06 as I expected.

 

Is there another way to survive a warm start

 

I'm using MAC65 as my assembler

 

I've tried the following

*=$600

; My code here to set VBI routine

INIT  LDA #0; Prog Init Address

.

.

.

.

RTS

VB ...... ; VB code here

.

JMP XITVBV

*=$2E0

.WORD INIT

Link to comment
Share on other sites

Just found an example in De-Re-Atari by stealing the DOS vector at locations $C and $D, the code

steals the DOS vector, but the address in $C and $D don't change which seems wierd, does SDX reset these locations if they change ?

0000            0130     *=  $0600
                0140     .INCLUDE #D:HEADER.M65
                0100 ; UPDATE 09/07/2020
                2800     .OPT LIST
                2810     .ENDIF 
0600 200306     0150 INITDOS JSR TEMPADR ; WILL CHANGE WHEN INIT RUNS
0603 4C1606     0155 TEMPADR JMP SETPORT

 

then my code here

 

and this from De Re-Atari, this code does run due to the $2E2 init address as the address for

the JSR TEMPADR changes to the valuse originally in $C and $D ($2A, $9), but $C and $D

also still have $2A and $9 in them ??? as set by SDX

 

06DF            1110     *=  $2000
2000 A50C       1120 GETDOS LDA DOSINI
2002 8D0106     1130     STA INITDOS+1
2005 A50D       1140     LDA DOSINI+1
2007 8D0206     1150     STA INITDOS+2
200A A900       1160     LDA #INITDOS&255
200C 850C       1170     STA DOSINI
200E A906       1180     LDA #INITDOS/256
2010 850D       1190     STA DOSINI+1
2012 60         1200     RTS 
2013            1220     *=  $02E0
02E0 0306       1230     .WORD TEMPADR
02E2 0020       1240     .WORD GETDOS

 

Edited by TGB1718
Update
Link to comment
Share on other sites

The $2E0-3 locations are just used by Dos or a loader during the load.  There's no obligation for a Dos to take your Run address and ensure your program reruns after a warmstart.

 

The only ways for a Ram based program to start again after warmstart are CASINI (2,3) DOSINI ($C,$D) and DOSVEC ($A,$B)

 

If your program is to be permanently in control until the user turns off then you could just steal one of those vectors.  The order of calling is CASINI then DOSINI.

DOSVEC is only run if there's no cartridge present or if called by the user typing DOS.

The expectation normally is that you return from CASINI and DOSINI but for a game there's not a need.

 

In the modern day it's usually desirable that a game or demo just coldstarts when you press Reset so the user can preserve Ramdisks.  Or alternately returns to a usable Dos environment.  Use ESC as an alternate soft reset method.

With CASINI/DOSINI you want to set the flag in location 9 - bit 0 means tape has booted, bit 1 means disk has booted.  To preserve a Dos you'd want to save the old DOSINI vector then call it if there was a DOS present (bit 2 of 9 = 1)

If you want to give the user a way to soft coldstart then you could allow Shift+Reset, then just test for the Shift key in your warmstart code, jump to $E477 if it's being held.

  • Like 1
Link to comment
Share on other sites

Many thanks for that information, I didn't set the flag in location 9, also, I might change the code to use CASINI instead.

 

The software I'm writing is a keyboard handler which allows me to use any USB keyboard on my 800 and 130XE, so if I need to use

RESET, I need to re-initialise the VBI

Link to comment
Share on other sites

Just used CASINI, still get the same result, code not working after reset. I checked location 9 after loading my code

and it's set to 1, my code sets it to 2, as it's being set back to 1, pressing reset does not use my code vector set at locations 2 and 3

which have been set correctly to $00,$06.

 

So I put my software on a bootable .ATR and loaded that with SDX disabled on my 800 and hey presto the code works as

intended, my USB keyboard still works after a reset.

 

So it looks like SDX is doing something to those vectors and flags after my program has loaded, a BUG maybe ??

 

I certainly isn't working the way it should.

 

In a nutshell SDX is resetting locations $2E0,$2E1,$2E2,$2E3 and $9 back to their previous values after they have been set

by my program, I would assume it's doing some processing before returning to the command prompt.

 

2000 A902       1150 GETDOS LDA #2
2002 8509       1160     STA BOOT
2004 A900       1170     LDA #INITDOS&255
2006 8502       1180     STA CASINI
2008 A906       1190     LDA #INITDOS/256
200A 8503       1200     STA CASINI+1
200C 60           1210     RTS 
200D               1220     *=  $02E2
02E2 0020       1240     .WORD GETDOS

Edited by TGB1718
Update
Link to comment
Share on other sites

Location 9 gets altered during boot so if you set it too early it might end up with the wrong value.

 

Note that it holds the flag for tape as well as disk (and both set is valid).

In your code you should OR in the bit value, don't just set the value as a constant.

e.g. LDA 9

ORA #2

STA 9

if you're using CASINI.

 

Assuming you have a disk based DOS active, then yep, the flag should = 1.

Link to comment
Share on other sites

Just modified the code, but SDX keeps setting $9 back to 1.

 

I'm not currently loading this during boot, just manually when the DOS prompt appears.

 

1 hour ago, David_P said:

Have you consulted the excellent SpartaDos X programmer's manual at: http://sdx.atari8.info/sdx_files/4.49/SDX449_Programming_Guide_EN.pdf

Yes, there is nothing there that I can find concerning this. The only mention of DOSINI is in an application CAD.SYS which I'm not using.

It appears DOSVEC is used internally by SDX:-

 

"Several SD variables are available to programmers to allow easy access to the command line for applications and utilities.

This data table is referredto as COMTAB and is pointed to by the OS variable DOSVEC at memory location 10 ($0A).! 

Link to comment
Share on other sites

2 hours ago, David_P said:

Page 53 discusses TSR routines and how to add them to the queue.

Many thanks for that, at least I know there's a mechanism available, unfortunately

it doesn't explain how to make the call, it says

Such TSR programs can be registered using S_ADDIZ. In the AX registers (LSB and MSB
respectively)
 

 

But it doesn't explain how you make the call in your program, I assume there is a vector somewhere in SDX,

but I searched and can't find any other references to S_ADDIZ.

 

I found a utility in the SDX toolkit and the symbol equates to this:- S_ADDIZ    $A03F

but no examples of how to use this

Link to comment
Share on other sites

Here are some code snippets. First shows reset protection in native SDX relocatable driver. Second shows a means of obtaining symbol values from a non-SDX, non-relocatable binary.

 

The third and last method is the easiest, and is the one used by The Last Word; simply stealing DOSINI, but calling what DOSINI pointed to as part of your RESET handler. The original contents of DOSINI are restored before the program terminates (by jumping indirectly through DOSVEC).


S_ADDIZ  SMB 'S_ADDIZ' ; add entry to reset queue

...

	lda reset_hand_p
	ldx reset_hand_p+1
	jsr s_addiz ; attempt to install reset handler in queue
	bcc rhok
	jsr printf
	.byte 'Reset table full',155,0
rhok


...



reset_hand_p
	.word reset_hand


**********************************************************************


jcar_sw 	equ	$7fa
jcar_old	equ	$7fd
JFSymbol	equ	$7EB

	lda #$ff
	jsr jcar_sw	; turn on SDX cartridge
	lda #< symbol
	ldx #> symbol
	jsr JFSymbol
	sta ptr1
	stx ptr1+1
	jsr jcar_old	; restore SDX cart ROM to original state

symbol
	.byte 'SYMBOL  ',0	; 8 bytes, space padded, NUL terminated



**********************************************************************

	lda $0c
	sta warm+1
	lda $0d
	sta warm+2
	lda #< warm
	sta $0c
	lda #> warm
	sta $0d


Warm
	jsr $ffff	; execute original DOSINI code (restore original contents before exit to DOS)
	; do what you need to do every time reset is pressed here
	rts

I wouldn't use SDX-specific methods unless your program mandates the use of SDX, or is capable of dynamically configuring itself to the host DOS.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

21 hours ago, flashjazzcat said:

I wouldn't use SDX-specific methods unless your program mandates the use of SDX

Thanks for the information and examples, the reason I'm having problems is that SDX doesn't conform to expected rules where

"stealing" DOSVEC, or DOSINI or CASINI remain in force, SDX is reverting them back to it's values, although CASINI

does keep my address, it changes to BOOT flag at $9 back to 1, so on reset it doesn't vector through CASINI.

 

In example 1, thats the approach I was looking to do, but I don't know the address for s_addiz, it's not documented where

this is.

 

I used a call to $7eb to find s_addiz which it did, but when I look for the address to jump through in the symbol table 

the address makes no sense and there's nothing there, maybe I have to turn on the SDX cartridge first to get the correct data (thanks for that address).

 

Not sure the last example would work for me as the only part of my code thats running is in a VBI routine, after loading, my program goes

back to the command prompt, after that I can use the normal keyboard if needed or I can use a USB keyboard as if it was the 800's

normal keyboard. I just need to run the VBI init routine on reset.

 

What I've done seems to work on every DOS I've tried, even disk based Sparta Dos, but not SDX on Incognito.

Link to comment
Share on other sites

28 minutes ago, TGB1718 said:

Thanks for the information and examples, the reason I'm having problems is that SDX doesn't conform to expected rules where

"stealing" DOSVEC, or DOSINI or CASINI remain in force, SDX is reverting them back to it's values, although CASINI

does keep my address, it changes to BOOT flag at $9 back to 1, so on reset it doesn't vector through CASINI.

This is odd, since The Last Word does nothing but point DOSINI at its own reset handler as shown above, and it remains reset protected.

30 minutes ago, TGB1718 said:

maybe I have to turn on the SDX cartridge first to get the correct data (thanks for that address).

Yes: this is exactly what jcar_sw is doing in the example, and the SDX ROM will almost certainly need to be enabled in the same way before calling the address obtained by jfsymbol.

 

34 minutes ago, TGB1718 said:

Not sure the last example would work for me as the only part of my code thats running is in a VBI routine, after loading, my program goes

back to the command prompt, after that I can use the normal keyboard if needed or I can use a USB keyboard as if it was the 800's

normal keyboard. I just need to run the VBI init routine on reset.

It should work, but you will need to install a small piece of resident code (TSR) above MEMLO which is reset-proof in the manner described, and which reinstates you VB service routine each time reset is pressed.

36 minutes ago, TGB1718 said:

What I've done seems to work on every DOS I've tried, even disk based Sparta Dos, but not SDX on Incognito.

Do you have a binary I can run and look at with the Altirra debugger?

Link to comment
Share on other sites

@flashjazzcat I have a few more thing to try before I send a binary if thats ok, however I've been doing

a lot of reading through the manual and found some really good information, but key elements are missing

e.g. the addresses of the functions themselves, so I started looking through the toolkit ATR and found

 

what looks like all the info I need but it's in Polish on the toolkit disk under UTILS\PROGRAMM.ING

 

There are several files that detail system calls, unfortunately I can't understand most of it.

 

Do you know of any english versions of those files

 

thanks

 

 

Link to comment
Share on other sites

4 hours ago, TGB1718 said:

There are several files that detail system calls, unfortunately I can't understand most of it.

 

Do you know of any english versions of those files

Yes there are a lot of useful looking tools there, but sadly I know of no English versions. FA.COM is the 'Fast Assembler' which allows compilation of SDX native binaries on the A8, but the last I heard, there were a few unresolved bugs.

 

Your best bet remains the SDX Programming guide, which is available in English on the SDX Upgrade Project site. If you wish to write tools and drivers specifically aimed at SDX, I heartily recommend using MADS and making the jump to relocatable SDX binaries.

  • Like 1
Link to comment
Share on other sites

On 7/10/2020 at 6:01 PM, TGB1718 said:

the code

steals the DOS vector, but the address in $C and $D don't change which seems wierd, does SDX reset these locations if they change

When a program terminates, SDX checks if the DOSINI vector ($0c/$0d) has changed, which means that some TSR wants to be initialized after reset. The new value of that vector is then registered in the init queue, and the original address is restored. Your mistake was checking "if the vector changed" instead of just checking, if the program works as intended.

 

17 hours ago, TGB1718 said:

key elements are missing

e.g. the addresses of the functions themselves

The functions pointed to by symbols have no fixed addresses, this is why the documentation does not list them. This is the whole purpose of the symbols, by the way...

Link to comment
Share on other sites

4 hours ago, drac030 said:

Your mistake was checking "if the vector changed" instead of just checking, if the program works as intended.

 

Hi, many thanks for you comments, however I was only checking the vectors as my program stopped, was trying to figure

out why it wasn't being re-initialized.

 

I've been doing some testing on Altirra, and my VBI route stops after a reset, but not when booting disk based DOS's

.

 

2000 A900       1100 GETDOS LDA #INITDOS&255
2002 850C       1110     STA DOSINI
2004 A906       1120     LDA #INITDOS/256
2006 850D       1130     STA DOSINI+1
2008 EEAC06     1135     INC X1 ; FOR DEBUG
200B 60         1140     RTS 
200C            1150     *=  $02E2
                1160 ;   .WORD TEMPADR
02E2 0020       1170     .WORD GETDOS
 

This code sets the vectors, the INC X1 is just to prove this code runs which it does.

 

The following code runs when loaded, but on reset, I want the ports set and the VBI restored.

 

0600 4C1306     0150 INITDOS JMP SETPORT
0603 000000     0160 KEY .BYTE 0,0,0
0606 000000     0170 KY  .BYTE 0,0,0
0609 A907       0180 SETVB LDA #7
060B A206       0190     LDX #VB/256
060D A02C       0200     LDY #VB&255
060F 205CE4     0210     JSR SETVBV
0612 60         0220     RTS 
0613 AE02D3     0230 SETPORT LDX PACTL
0616 A938       0240     LDA #56     ; SET BIT 2 TO 0
0618 8D02D3     0250     STA PACTL   ; TO SET BITS
                0260 ; 7=OUT 4-6=IN
061B A988       0270     LDA #$88    ; 10001000
061D 8D00D3     0280     STA PORTA
0620 8E02D3     0290     STX PACTL
0623 A988       0300     LDA #$88
0625 8D00D3     0310     STA PORTA   ; SET ACK HIGH
0628 200906     0320     JSR SETVB
062B 60         0330     RTS 

062C 20BF06     0340 VB  JSR WAIT0
062F AD00D3     0350     LDA PORTA

.

.

.

.

.

etc.

4 hours ago, drac030 said:

The functions pointed to by symbols have no fixed addresses, this is why the documentation does not list them. This is the whole purpose of the symbols, by the way...

I thought as much, however I can't find any examples of how to extract the symbol and use the recieved data to call the

routines. Just need a pointer(excuse the pun) on how to successfully extract a symbol and then use the resulting data.

 

I've also tried the code snippets @flashjazzcat kindly supplied, but still no joy

 

Link to comment
Share on other sites

This RTC driver for Sparta 3.x variants uses DOSINI to reset protect itself, and if you add 'jmp GotHardware' immediately after '.proc Start' to bypass the host DOS checks, it will install at MEMLO under SDX and the code at '.proc resetHandler' is executed every time system reset is pressed:

 

ultd.s

 

I realise the vast majority of the code may be surplus to requirements, but the method of manipulating DOSINI does work. In your 'resetHandler', you can readjust the VBI vector to suit your needs every time system reset is pressed. If it's set up as shown, 'resetHander' will be executed every time.

Link to comment
Share on other sites

Had a look at the code, but can't really make any sense of it, I've never used MADS, I did download it, but

it's no real help.

 

I tried all sorts today but nothing works, I even had the VBI routine itself push the reset vector back into $C & $D

which it did, but on reset, the vector was changed back by SDX, in a nutshell SDX is broken in this area I'm just

going to "NOT" press reset.

 

I think any "normal" program, one that doesn't go back to the command prompt will survive a warm start if

you intercept the DOS vector, but think the problem lies in the fact if I return to the command prompt and

in that situation SDX resets the vectors.

 

Maybe if I could get some info on using S_ADDIZ & S_LOOKUP, again total lack of useful information on using these,

I did email the SDX team, but got no reply.

 

I had S_LOOKUP work without an error flag, but what addresss is returned in the A and X registers and how do you use it,

I thought it pointed to the SYMBOL that you looked up and you could access the structure to get the call address, but when

I look at the data at that address (address +0 to address+$C) the data made no sense.

Link to comment
Share on other sites

Hi!

2 hours ago, TGB1718 said:

Had a look at the code, but can't really make any sense of it, I've never used MADS, I did download it, but

it's no real help.

 

I tried all sorts today but nothing works, I even had the VBI routine itself push the reset vector back into $C & $D

which it did, but on reset, the vector was changed back by SDX, in a nutshell SDX is broken in this area I'm just

going to "NOT" press reset.

 

I don't really understand this problem, as I just tried my E accelerator https://github.com/dmsc/e-accelerator/blob/master/src/efast.asm and it survives reset ok in SDX 4.48

 

I just do the normal thing, install my reset handler in DOSINI and on reset I reinstall the handler and jump to the old DOSINI value.

 

Have Fun!

 

  • Like 1
Link to comment
Share on other sites

22 hours ago, TGB1718 said:

think the problem lies in the fact if I return to the command prompt and

in that situation SDX resets the vectors

As I said already, resetting the vectors is intended. Actually bytes 9,a,b,c,d (boot?, dosvec, dosini) are always reset to defaults on program termination (among many other things). As I said as well, if dosini was changed, its new value gets copied to the init queue, actually the same which you want to update with S_ADDIZ.

 

But I found out why it does not work for you: it only works in SDX, when the memlo is raised simultaneously. If memlo is raised, SDX assumes that a "legacy" TSR has been installed, so it checks dosini, and if it is changed too, its value is copied to the init (S_ADDIZ) queue. If memlo is not changed, this phase is skipped.

 

Now your program is on page 6 and does not change memlo, so SDX does not register the changed dosini. This looks like a bug and should be fixed.

 

S_ADDIZ is described in the Programming Guide. S_LOOKUP is too, but it is not very useful for you, as the procedure leaves its results in the structure SYMBOL which requires the previous knowledge of the SYMBOL value. Chicken and egg. The procedure you need is jfsymbol, please search the Prog. Guide PDF for the information on it.

 

Edited by drac030
  • Like 1
Link to comment
Share on other sites

4 minutes ago, drac030 said:

But I found out why it does not work for you: it only works in SDX, when the memlo is raised simultaneously

Many thanks, I was begining to think it was me ? , I nearly changed my program to load at as higher address, but

thought that would be a bit daft, if only I had !!!

 

I will do what you suggest and place my program in the free area pointed to by MEMLO and adjust, fingers crossed

it will work as expected.

 

Once again, many thanks (I feel my headache ? going)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...