Jump to content
IGNORED

DLI Action! problem.


kensu

Recommended Posts

I incorporated a modified verison of the DLI routine from this Action! program into a character set redefiniton program I'd previously written, which draws six rows of Breakout-style bricks. This actually works, but it only changes the color of rows 3-6, no matter how I modify it, I can't get the first two rows to change.

Those lines do have DLI enabled, but the Playfield Color 1 (0) is only changed starting with the third line.

 

DEFINE RTI="$40",
       PHA="$48",
       PLA="$68",
       TXA="$8A",
       TAX="$AA",
       TYA="$98",
       TAY="$A8",
       JMP="$4C"
BYTE CHBAS = $2F4,
PMBASE = $D407, RAMTOP=$6A, NMIEN=$D40E,
COLP0=$D016,WSYNC=$D40A, COUNT=[0]
CARD SDLSTL=560,
VDSLST=512
BYTE ARRAY COLTABLE(0) = [$42 $74 $C4 $18 $00 $0E]
BYTE ARRAY DLIST

PROC DLINT()
 BYTE DUM
 [PHA TXA PHA TYA PHA]
DUM=COLTABLE(COUNT)  

 WSYNC=1
 COLP0=DUM
 COUNT ==+ 1
 IF COUNT=6
  THEN COUNT=0
 FI
 [PLA TAY PLA TAX PLA RTI]

PROC INIT_GR()
 GRAPHICS(1)
 SETCOLOR(0,2,10)
 SETCOLOR(1,5,12)
 SETCOLOR(2,0,0)
RETURN

PROC DLSETUP()
 BYTE I
 INIT_GR()
 NMIEN=$40
 DLIST=SDLSTL
 VDSLST=DLINT
 FOR I = 6 TO 11
 DO
  DLIST(I)=134
 OD
 NMIEN=$C0
RETURN

PROC CHANGE_CHARSET()
	BYTE ARRAY NC0 = [255 128 128 128 128 128 128 255 255 1 1 1 1 1 1 255 ]
	CARD MEMTOP
	MEMTOP = RAMTOP - 8
	MEMTOP = MEMTOP * 256    
	ZERO(MEMTOP,512)
	MOVEBLOCK(MEMTOP,57344,512)
	MOVEBLOCK(MEMTOP+8,NC0,16)
	CHBAS = MEMTOP/256

RETURN

PROC MAIN()
	CARD SAVMSC=$58
	BYTE I
	CHANGE_CHARSET()
	DLSETUP()
	FOR I = 0 to 120 STEP 2
	DO
		POKE(SAVMSC+I,1)
		POKE(SAVMSC+I+1,2)
	OD
	
	DO OD
RETURN

(for some reason I can't edit the code portion, Change_Charset() and DLsetp() are in the wrong order in the main procedure)

 

A couple of additional questions for Action! experts. Why is count set to [0] instead of 0? I'm beginning to understand that anything in brackets is not actually an array, but some sort of machine code instruction, but I'm not clear on why it's done this way (if you remove the brackets there's a different result.)

Also, why is Coltable dimensionalzed with a size of 0? This is the only example I've seen where an inline array declaration dimensionalizes the array, much less saying it's empty when it has a size of 6.

Edited by kensu
Link to comment
Share on other sites

Hmm, the Graphics 1 (for BASIC and Action!) display list is:

      112 112 112 70 128 157 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

adr    0    1    2    3   4    5    6 7 8 9 1011121314151617181920

Bacially the first 6 of those 6s are turned into 134 (6 with bit 7 set). 
So if I wanted it to start on the first line, I would want to change offset 5, but that's actually the high component of the address of the beginning of the screen buffer. So what do I do in this case?

Also, if it starts on offset 6, which would be the first line of the screen, why are the first two lines the original color, instead of just the first line? As I recall, aren't there two mode lines per row?

Link to comment
Share on other sites

If you want the first line to change, you set the DLI on the 3rd "8 blank lines", so change the above

to 112 112 240 70 128 157 etc....

you can also set a DLI on the LMS instruction, change the 70 to 198 

so in your example, the numbers would be

 

112 112 240 198 128 157 86 86 86 86 6 6 6 6 6 etc....

DLI HERE ^    ^               ^   ^   ^  ^ 

that would give you a colour change for the first 6 lines.

 

This is from the Hardware Manual, it shows all possibilities.

 

image.thumb.png.ccc46e4cc065f9ba40d907f31700559b.png

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

I don't have ACTION, but wrote a small assembler routine to simulate what your trying to do, I'm switching COLBK

just to see the colours, changed the table a little just to add colours to each line and then turn the screen black, so an extra DLI at the end.

 

As you changing character colours, you don't need to do this.

 

image.thumb.png.4dfb168f99238e5ae749bcc5a88ff72c.png

Here's the actual display list in memory

 

image.png.f78b1a69ae0ebc112f53a97572f4fafd.png

Edited by TGB1718
Link to comment
Share on other sites

21 minutes ago, E474 said:

I'm not an ACTION hacker,  so it's not clear how to do this, but a display list can't cross a 1K boundary without a JMP instruction (IIRC), so you need to make sure it avoids a 1K boundary, or takes this into account.

From the code, it looks like Action is using the OS to open the screen, so the display list is located in a good position and

not crossing a 1K boundary, I think the issue is as I have described, a DLI on the last blank line and on the LMS instruction followed

by 4 more "normal" lines with DLI set.

 

16 hours ago, kensu said:

Hmm, the Graphics 1 (for BASIC and Action!) display list is:

      112 112 112 70 128 157 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

i.e. display list is at $9D60 just in front of the screen which is at $9D80

Link to comment
Share on other sites

Ok, so I just learnt some Action :)

 

Here's your fixed code:-

Highlighted bit is all you need to change, not sure if you meant to have $00 as the 5th

byte in your colour table as it will be black so you can't see it, unless your background is some other colour.

 

DEFINE RTI="$40",
      PHA="$48",
       PLA="$68",
       TXA="$8A",
       TAX="$AA",
       TYA="$98",
       TAY="$A8",
       JMP="$4C"
BYTE CHBAS = $2F4,
PMBASE = $D407, RAMTOP=$6A, NMIEN=$D40E,
COLP0=$D016,WSYNC=$D40A, COUNT=[0]
CARD SDLSTL=560,
VDSLST=512
BYTE ARRAY COLTABLE(0) = [$42 $74 $C4 $18 $00 $0E]
BYTE ARRAY DLIST

PROC DLINT()
 BYTE DUM
 [PHA TXA PHA TYA PHA]
DUM=COLTABLE(COUNT)  

 WSYNC=1
 COLP0=DUM
 COUNT ==+ 1
 IF COUNT=6
  THEN COUNT=0
 FI
 [PLA TAY PLA TAX PLA RTI]

PROC INIT_GR()
 GRAPHICS(1)
 SETCOLOR(0,2,10)
 SETCOLOR(1,5,12)
 SETCOLOR(2,0,0)
RETURN

PROC DLSETUP()
 BYTE I
 INIT_GR()
 NMIEN=$40
 DLIST=SDLSTL
 VDSLST=DLINT
 DLIST(2)=240
 DLIST(3)=198
 FOR I = 6 TO 9
 DO
  DLIST(I)=134
 OD

 NMIEN=$C0
RETURN

PROC CHANGE_CHARSET()
       BYTE ARRAY NC0 = [255 128 128 128 128 128 128 255 255 1 1 1 1 1 1 255 ]
       CARD MEMTOP
       MEMTOP = RAMTOP - 8
       MEMTOP = MEMTOP * 256    
       ZERO(MEMTOP,512)
       MOVEBLOCK(MEMTOP,57344,512)
       MOVEBLOCK(MEMTOP+8,NC0,16)
       CHBAS = MEMTOP/256

RETURN

PROC MAIN()
       CARD SAVMSC=$58
       BYTE I
       CHANGE_CHARSET()
       DLSETUP()
       FOR I = 0 TO 120 STEP 2
       DO
               POKE(SAVMSC+I,1)
               POKE(SAVMSC+I+1,2)
       OD

       DO OD
RETURN

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

23 hours ago, kensu said:

Why is count set to [0]

As far as I can see, it shouldn't be. It should be set to just 0. The code uses it as a variable, but count[0] sets up an array. Not sure about Action! but in some languages you would be incrementing the array pointer by doing things like count=count+1. that would be bad. Remove the brackets is my advice.

Edited by danwinslow
Link to comment
Share on other sites

3 hours ago, TGB1718 said:

From the code, it looks like Action is using the OS to open the screen, so the display list is located in a good position and

not crossing a 1K boundary, I think the issue is as I have described, a DLI on the last blank line and on the LMS instruction followed

by 4 more "normal" lines with DLI set.

 

i.e. display list is at $9D60 just in front of the screen which is at $9D80

Hi @TGB1718,

 

   Thanks, my bad for not reading the code properly; I got bitten by this bug (crossing a 1K boundary) a couple of weeks ago, so am probably over-sensitive to it.

Link to comment
Share on other sites

7 hours ago, danwinslow said:

As far as I can see, it shouldn't be. It should be set to just 0. The code uses it as a variable, but count[0] sets up an array. Not sure about Action! but in some languages you would be incrementing the array pointer by doing things like count=count+1. that would be bad. Remove the brackets is my advice.

That's very strange, if you remove the brackets it will loop through the colors in a different order (3,4,5,0,1,2). 

I think what's happening here is similar to what happens when you use something like "Byte x=$FF" where it sets up the variable as a direct reference to that spot in memory without having to do any dereferncing with the ^. In this case it seems to be using Action's memory allocation routine to find a free spot in memory and then assigning that variable as a reference to it. I still don't understand why it has a different result from just a normal assignment....

I wish we could ask the author of the original example, but this code is from 1984, if they were still around I doubt they'd remember why they did it that way.

 

Link to comment
Share on other sites

It would appear that INT COUNT=0 sets COUNT (or any other variable) to be a pointer the that memory location.

I just tried setting COUNT=88, then printed COUNT and the result was 40000 i.e. the screen address

likewise setting COUNT to 560 have the result 39968 which would equate to the display list location.

So without the [] it creates a pointer to a memory location.

 

doing INT COUNT[0,1,2,3] generates a compile error

 

Link to comment
Share on other sites

11 hours ago, danwinslow said:

Interesting. So when he removed the brackets he got a pointer to location 0? Surprised he didn't crash. Thanks for the explanation.

It might be Zero Page address zero, which I think is clear for variable use. I wonder why it always has a starting value of 3?

This also explains a lot of weird issues I've been running into with Action!, and why I couldn't really understand how dereferncing of variables worked. Action appears to be much closer to the metal than I thought, and just using my knowledge of C wasn't enough.

 

Link to comment
Share on other sites

Count = 0 sets the address of Count to absolute address zero, which would also be zero page zero. Since this location is unused after powerup, no crash occurs. However it means the value of Count is undetermined, it will be whatever was last deposited at 0. So if it was say 57, the DUM assignment on the first pass becomes DUM = COLTABLE(57) which probably is junk as far as colour goes. It will keep on being junk until it loops back around to zero. Action! does not initialize variables unless you tell it to do so. The fact that it always seems to be three is strictly coincidence, whatever is using $00 just happens to always leave a 3 in it when it is done.

 

Count = [0] says to initialize Count to zero, thus the loop operates correctly.

Link to comment
Share on other sites

16 hours ago, TGB1718 said:

@kensu we have digressed a bit, but all good fun, however you haven't said if the solution to your original

question has provided a fix for your issue.

Yep, worked like a charm, I pinned a Thanks trophy to the message with the code that fixed it. Thanks!

Link to comment
Share on other sites

Have to thank @kensu for raising this topic, I had never heard of action bitd, so had a look at it because of this

post, been playing just to see what it's like and although it's a bit "quirky" it's certainly producing fast code, although

a quick look shows it really need an optimiser, it seems full of this sort of code:-

22C3  JMP 22C6        4C C622
22C6  STA 22C2        8D C222

 

299D  JMP 29A0        4C A029
29A0  LDA 299B        AD 9B29

 

29C2  JMP 29C5        4C C529
29C5  LDA #00         A900

 

I gave it a try using player/missile graphics example from De-Re Atari but put a movement routine in a VB

overall quite impressed so far.

 

One little criticism, having to define a procedure/function in your code before you call it, if you define it

somewhere after the call to it, it errors during the compile, so you have to move it. 

PMGVBI1.ACT

Link to comment
Share on other sites

1 hour ago, TGB1718 said:

Have to thank @kensu for raising this topic, I had never heard of action bitd, so had a look at it because of this

post, been playing just to see what it's like and although it's a bit "quirky" it's certainly producing fast code, although

a quick look shows it really need an optimiser, it seems full of this sort of code:-

22C3  JMP 22C6        4C C622
22C6  STA 22C2        8D C222

 

299D  JMP 29A0        4C A029
29A0  LDA 299B        AD 9B29

 

29C2  JMP 29C5        4C C529
29C5  LDA #00         A900

 

I gave it a try using player/missile graphics example from De-Re Atari but put a movement routine in a VB

overall quite impressed so far.

 

One little criticism, having to define a procedure/function in your code before you call it, if you define it

somewhere after the call to it, it errors during the compile, so you have to move it. 

PMGVBI1.ACT 1.38 kB · 0 downloads

What you are seeing is a deliberate design decision. It allows for the redirection of procedures. For example, the manual shows how to replace the Error function. So in code you see:

 

Proc Error(byte rc)

which becomes as you see

Error JMP Erro2

Error2 STA rc

 

so you define your own proc

Proc MyError(byte rc)

 

but now you can do

Error = MyError

 

which changes Error thusly

Error JMP MyError

Error2 STA rc

 

so any call to Error is redirected to your MyError procedure.

 

The way to turn this off is to use the '*' keyword:

 

Proc Error=*(byte rc)

and now it becomes

Error code starts here

 

Note that using * also disables the storing of any passed parameters, so you must do it yourself:

Proc MyError=*(byte rc)

MyError STA rc

 

Action! is a 1 pass compiler so things must be declared before they are used. By using the assignment of functions ability though you can call functions before they are defined.

 

Proc Dummy()

RETURN

 

Proc Dosomething()

  Dummy()

RETURN

 

Proc TheRealProc()

  dowork

return

 

Proc Main

 Dummy=TheRealProc

return

 

I think this is all talked about in the Action! runtime manual. Also see the articles at Ken Squiggle's page

https://ksquiggle.neocities.org/action/online

 

 

 

 

  • Like 3
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...