Jump to content
therealbountybob

DLI Not Keeping Registers Issues / Adding 3rd DLI problem

Recommended Posts

Help me out here guys, I posted about this before but in the end I must have got lucky and worked around it...

 

My game "Block on Legs: First Steps" has a DLI at the top for the game window and another for the lower status bars. [And works fine before this]

 

The vast majority of my code runs in a main loop ***outside*** of the VBI

 

I've added a routine to move and hopefully animate a block of characters ("CD" on the screenshot), this uses the X register to track position in the object's table and significantly it loads the memory addresses for their desinations. The game is crashing after this is enabled!

 

I figured this is X register not being remembered by the VBI/DLI routines and confirmed this by displaying X on the status bar in my movement routine, it seems to have "random" values rather than 1-30 as I would expect in the loop.

 

I displayed a marker on the status bar (fom the DLI code) so I can see both DLIs are completing (well it's right before the restore registers).

 

On the 2nd screenshot you can also see some corruption on the PMG routine which also uses X register. I was also [separate from the above problem] looking at having more DLIs for coloured sections but that ran into similar issues [3rd screenshot].

 

Am I doing something fundamentally wrong?

1901385268_BOLTest.png.afef15e6a3870dae599cd3c8e451dfb6.png1670114855_BOLTest1.png.bc36c11887796562f66511f60791d9c7.png1767709981_DLITest2.png.6a2b1b613307ee6351f07c7cee069548.png

:dunce:

 

Here's the code (cut down):

 

630 VBICODE          
720      CLD         ; force
730 ;
740 ; force to DLI1 at top of screen
750 ;
760      LDA # <DLICODE ; new DLI
770      STA VDSLST  ; default "RTI"
780      LDA # >DLICODE
790      STA VDSLST+1
850 ;
1220 VBICODEGAME
2270 ;
2280 QVBICODE
2300     JMP XITVBV
---------------------------------------
2530 DLICODE
2540 ; DLI #1 top section - game screen
2550 ;
2560 ; store registers
2570     PHA
2580     TXA
2590     PHA
2600     TYA
2610     PHA

3580 ; point to 2nd dli for low bar
3590     LDA # <DLICODE2
3600     STA VDSLST
3610     LDA # >DLICODE2
3620     STA VDSLST+1

4000 ; dli code here - colours, chset, pmg pos. etc
4010 ; NOTE: code uses X register

4570 ; restore registers
4580     PLA
4590     TAY
4600     PLA
4610     TAX
4620     PLA
4630 ;
4640     RTI
---------------------------------------
4840 DLICODE2
4850 ; 2nd dli - Bottom status bar
4860 ;
4870 ; store registers
4880     PHA
4890     TXA
4900     PHA
4910     TYA
4920     PHA

5000 ; dli code here - colours etc

5570 ; restore registers
5580     PLA
5590     TAY
5600     PLA
5610     TAX
5620     PLA
5630 ;
5640     RTI

 

Edited by therealbountybob
more detail

Share this post


Link to post
Share on other sites

hard to tell without the full code...

 

the only things I see from a quick browse (but I'm guessing you just didn't paste those bits)

 

1. you're not saving/restoring registers in the VBi

2.you're not setting the VDSLST register in DLICODE2

 

So the problem is likely somewhere else

  • Like 1

Share this post


Link to post
Share on other sites

Hi,

 

   Have you tried commenting out all the code between saving the registers and restoring the registers - maybe just use an increment border color register to see if the DLIs are being triggered correctly?

  • Like 1

Share this post


Link to post
Share on other sites

Does it happen immediately or after a while?  One time, I had an issue where it would cause corrupted frames occasionally.  It turned out that I was using a JSR without a matching RTS and it was filling up the stack...  Playsoft found that error for me.  I don't know how he found it that fast.

 

Not that you are asking about this but just about every DLI example that I have seen from the early days uses routines like this:

2570     PHA ; 3 cycles (4 for PLA)
2580     TXA  ; 2 cycles
2590     PHA ; 3 cycles
2600     TYA ; 2 cycles
2610     PHA ; 3 cycles

= 13 cycles per frame and 5 bytes

 

Personally, I prefer:

STA ATemp ; 4 cycles

STA Xtemp ; 4 cycles

STA Ytemp ; 4 cycles

= 12 cycles and 9 bytes for non-ZP and 9 cycles and 6 bytes if ATemp, Xtemp and Ytemp are ZP.  (obviously, you have to LDX xtemp, LDA Atemp and LDY Ytemp before exiting...

 

Also, I don't know if you are using Y inside of your DLI.  A comment says "; NOTE: code uses X register"  You could save 11 cycles per DLI if you don't use Y because you wouldn't need to restore it using TYA, PHA and PLA, TAY

 

I would also try to make sure the two DLIs are close enough together where one would fall through to "; restore registers" and the other would branch to it and save some memory (but costing 2 cycles).  I also save off Y last and restore it first so that the DLIs that don't use Y skip the Y part of the restore.

 

Of course, I haven't completed anything in 3 years so my advice may be worth less than the price I am charging you for it.  I am always amazed that you manage to get an ABBUC entry submitted every year!

  • Like 1

Share this post


Link to post
Share on other sites

Thanks for the quick replies (everyone) ;) - (Rob we cross posted)

 

1 hour ago, rensoup said:

hard to tell without the full code...

 

the only things I see from a quick browse (but I'm guessing you just didn't paste those bits)

 

1. you're not saving/restoring registers in the VBi

2.you're not setting the VDSLST register in DLICODE2

 

So the problem is likely somewhere else

1. I am not - should I be?! As well as what I have already in the DLI?

2. I am not - should I be?! With only two DLIs I figured the VBI would reset the first DLI?

If I add more DLIs then I need to point to the next one each time?

 

Edited by therealbountybob

Share this post


Link to post
Share on other sites

Debugger in Altirra can help a lot here.  Various ways to do it.

 

One way is BA R D40F which should break anytime a VBI or DLI occurs.  Then you can step through and ensure stuff like:

- check X register value is the same on entry and after exit.

- for DLIs, the right one is called at the right time.

- other stuff like running too long and the subsequent one corrupting something.

  • Like 1

Share this post


Link to post
Share on other sites

Would you mind posting a copy of the xex with the problem? I'd like to try to run it through Omnivore 2 with the emulator rewind capability that I'm still working on. (It remembers all history so you can go look at previous frames and do sort-of post-mortem debugging.)

Share this post


Link to post
Share on other sites
3 hours ago, therealbountybob said:

1. I am not - should I be?! As well as what I have already in the DLI?

2. I am not - should I be?! With only two DLIs I figured the VBI would reset the first DLI?

If I add more DLIs then I need to point to the next one each time?

Well I'm not sure 😃

 

you're using VDSLST which I guess is a shadow register or something ? so you have the OS running ?

 

For the php/plp sequence in the VBI maybe the OS is doing that for you ?

 

I've only used VBI/DLIs without the OS. For that you set the NMI directly (equivalent of VDSLST I suppose).

 

To me it makes sense to set the VBI again in the last DLI because they both share the NMI vector but I don't know what sort of trickery happens when the OS is running

 

In any case, given how little code there is, it's worth a try... or post an simple working test?

Edited by rensoup

Share this post


Link to post
Share on other sites

From what I can see his VB code is using the system exit routine which will do the right thing.

Nice use of CLD there, decimal mode interfering with things is something I encountered in the 400/800 days.  They fixed it with the XL OS but you'd still want to do it to cater for the older machines.

 

  • Like 2

Share this post


Link to post
Share on other sites
17 hours ago, rensoup said:

1. I am not - should I be?! As well as what I have already in the DLI?

2. I am not - should I be?! With only two DLIs I figured the VBI would reset the first DLI?

If I add more DLIs then I need to point to the next one each time?

1. Like Rybags said, seems you're good.

2. Ok I think I understand what the OS does now... it has a single NMI handler which checks the interrupt source ( VBi, reset ) So setting the VBi handler again in the DLi handler is not necessary.

 

As for adding more DLis and setting a new handler each time, you don't have to, it's just more efficient (usually).

Edited by rensoup

Share this post


Link to post
Share on other sites
14 hours ago, Rybags said:

Debugger in Altirra can help a lot here.  Various ways to do it.

 

One way is BA R D40F which should break anytime a VBI or DLI occurs.  Then you can step through and ensure stuff like:

- check X register value is the same on entry and after exit.

- for DLIs, the right one is called at the right time.

- other stuff like running too long and the subsequent one corrupting something.

That would work, but it would be easier to go into Debug > Verifier and enable the "Interrupt handler register corruption" and "Recursive NMI execution" checks.

 

  • Like 2

Share this post


Link to post
Share on other sites

 

11 hours ago, phaeron said:

That would work, but it would be easier to go into Debug > Verifier and enable the "Interrupt handler register corruption" and "Recursive NMI execution" checks.

Altirra: Is there anything it can't do?

Share this post


Link to post
Share on other sites

Sorry for the delay, you might not be surprised that it was my code causing X not to be tracked properly, then there was another error caused by the data values in my table, then another when I added loads of debug displays so the first part is resolved, I have 2 stage "animated" character blocks moving over the playfield, launching, moving horizontally and turning :)

329560532_BOLSS1.png.859b7adbd1e01784f34a1d474aa454f7.png1479303800_BOLSS2.png.3d3bd9c74d09b5b52facb3476aa4338c.png

Not had any luck with adding the third DLI: I added a blank line on the High Score Table screen about half way and toggle it active from the title screen, when you view the HSC screen it crashes and goes to Debug in altirra however if you ignore it and undo the pause you can see the screen correcly shows the 3 DLIs. There is not much code running in the DLI sections I've tried various things but not cracked it:

blue = vbi section points to DLI1

light green = 1st DLI points to DLI2

dark green = 2nd DLI points to DLI3

purple = third DLI

536437915_BOLHSC1.png.6c9bf92bdc86aae80639e5b56900140f.png72374795_BOLHSC2.png.f79498f33b88f0649b673083f0fd7560.png

Altirra> .dumpdlist (after the crash and continue - screenshot with purple bottom section)
  9904:      mode 7 @ 3800
  9907:      blank 8
  9908:      blank 4
  9909:      mode 2
  990A:      blank 6
  990B:      mode 6
  990C:      blank 3
  990D:      mode 6
  990E:      blank 3
  990F:      mode 6
  9910:      blank 3
  9911:      mode 6
  9912:      blank 2
  9913:      mode 6
  9914:      blank 3
  9915:      mode 6
  9916:      blank 3
  9917:      mode 6
  9918:      blank 3
  9919:      blank.i 1
  991A:      mode 6
  991B:      blank 3
  991C:      mode 6
  991D:      blank 3
  991E:      mode 6
  991F:      blank 3
  9920:      blank 7
  9921:      blank.i 1
  9922:      blank 3
  9923:      mode 2 @ 9000
  9926:      blank 3
  9927:      mode 2
  9928:      waitvbl 9900

 

Share this post


Link to post
Share on other sites
1 hour ago, MaPa said:

You have only 2 DLIs in your DLIST (two instruction with DLI bit set).

that was after the crash - here's the original dump from the working screen with two DLIs (9930, 9921) I've toggled 9919 to $80 from the title screen to test the third one.

Altirra> .dumpdlist
  9900:      blank 8
  9901:      blank 1
  9902:      blank 8
  9903:      blank.i 1
  9904:      mode 7 @ 3800
  9907:      blank 8
  9908:      blank 4
  9909:      mode 2
  990A:      blank 6
  990B:      mode 6
  990C:      blank 3
  990D:      mode 6
  990E:      blank 3
  990F:      mode 6
  9910:      blank 3
  9911:      mode 6
  9912:      blank 2
  9913:      mode 6
  9914:      blank 3
  9915:      mode 6
  9916:      blank 3
  9917:      mode 6
  9918:      blank 3
  9919:      blank 1
  991A:      mode 6
  991B:      blank 3
  991C:      mode 6
  991D:      blank 3
  991E:      mode 6
  991F:      blank 3
  9920:      blank 7
  9921:      blank.i 1
  9922:      blank 3
  9923:      mode 2 @ 9000
  9926:      blank 3
  9927:      mode 2
  9928:      waitvbl 9900

 

Share this post


Link to post
Share on other sites

I made a separate test program, kept the dlist, minimised the vbi/dli code, and just put it on the screen and an infinite loop. Tested on the Atari from DOS option M (had MAC/65 cart in) code at $6000

 

on the DOS2.5 ATR  "DLI3TEST.M65" is the main program, I have put DLI3 to point to DLI1 but that made no difference.

DIR.png.0bdaa1f5bf3dd18f93f80940f67aec1f.png

THREE DLIS TEST.ATR

Left screenshot 2 DLIs (green) right one three DLIs - the purple should be on the bottom bar area but takes over the whole screen, maybe that is a clue - clearly there is something I am missing. (black lines are from my phone camera/tv)

 

768942186_TwoDLIs.jpg.087285b06ad596060c101b2d91f54117.jpg28194298_ThreeDLIs.jpg.68accb67227105661ec077bd9dc4fda4.jpg

Share this post


Link to post
Share on other sites

I can't replicate what you have there - do you have the binary ?  I've just loaded this thing into Mac65 and ran it @ $6000 - gives a flash then returns to DDT.

Run at from Dos just crashes.

Share this post


Link to post
Share on other sites

From MAC/65

LOAD #D:DLI3TEST.M65

ASM

DOS

M

6000

I've just tried it on altirra using MAC/65 on disk and yes it does just flash and then crash as it ends up at an incorrect memory location, *this is the problem*. On the Atari you see the screenshots above. I guess the crash will return to DDT too.

Share this post


Link to post
Share on other sites

This is going to cause major problems:

 

Capture.PNG.3d10b07f920d5e89f5ee56d8ba2c8de1.PNG

 

Accumulator is not saved to the stack; LSB of return address is pulled off the stack before RTI instruction; machine crashes.

  • Like 2

Share this post


Link to post
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.

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...