Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Assembly question
#1
In assembly how do you know where to put data?

like say I wanted some arrays how would I know which address in RAM to place the variables?

Is it possible to access arrays created in zxbasic from assembly? how would I do that
Reply
#2
slenkar Wrote:In assembly how do you know where to put data?

like say I wanted some arrays how would I know which address in RAM to place the variables?

Is it possible to access arrays created in zxbasic from assembly? how would I do that
This is a... hard question... :| but here we go:
Arrays are just labels. Create a simple program with a DIM array and compile it with --asm and check for the result. After that label, some meta-data follows it, and finally, array cells. The metadata is the number of cells per dimension followed by a Cell Size. For example:
Code:
DIM myarray(2, 3) as Ubyte
Will generate the following ASM:
Code:
ZXBASIC_USER_DATA:  ; User declared global variables start here
_myarray:       ; Array LABEL
    DEFW 0001h  ; Number of dimensions minus 1, in this case 2 dimensions => 1
    DEFW 0004h  ; 2nd dimension size, that is 0, 1, 2, 3 => size 4
    DEFB 01h    ; Size of each cell. "As uByte " = 1
    DEFB 00h    ; Cell data (initialized to 0)
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
    DEFB 00h
The real size of this array is DIM myarray(0..2, 0..3) => 3 x 4 = 12 cells. Each cell is a byte, so 12 bytes.
The first dimension is not taken into account. So, for the compiler, the important information is the 2nd dimension and above.
  • The 1st number (Uinteger) is 0001h, and counts the total number of dimensions minus 1. So, in this case, myarray has 2 dimensions, so this number is 2 - 1 = 1.
  • The 2nd number is the 2nd dimension "range size", that is from 0 TO 3 = size 4.
You can access this data either calling the array subroutine ZX Basic uses (it's already linked with your program if you use any array), or calculate an array cell address on your own, and this is easy:
Array data starts at: ARRAY_LABEL + 3 + 2 * (n - 1), where n = Number of dimensions.
So in this case, the array data starts at:
_myarray + 3 + 2 * (2 - 1) = _myarray + 5
Reply
#3
thanks, I was thinking of translating my pathfinding into assembly to get some more speed
Reply
#4
You could read my tutorial for Berksman? It discusses things like where to place data for the map in an array within ZX Basic as one of the many topics I rambled on about randomly in passing while making a game....
Reply
#5
britlion Wrote:You could read my tutorial for Berksman? It discusses things like where to place data for the map in an array within ZX Basic as one of the many topics I rambled on about randomly in passing while making a game....
I was about to comment on it, but the link is not in the Wiki tutorials page. Can you add it, please?

Also was about to tell about the improvements you suggested for the Array management (some of them speed up the execution by 2x!). At the moment I have almost no time, and the little time I have for this is for... refactoring. The new ZX Basic will be a different, more robust and extensible compiler (I hope).
Reply
#6
slenkar Wrote:thanks, I was thinking of translating my pathfinding into assembly to get some more speed
What is the bottleneck? Maybe the A* / pathfinding algorithm?
Reply
#7
The bottleneck is probably trying to find the closest node,

I store the closest distance so I only look for the closest node when I have to. But its still kinda slow
Reply
#8
britlion Wrote:You could read my tutorial for Berksman? It discusses things like where to place data for the map in an array within ZX Basic as one of the many topics I rambled on about randomly in passing while making a game....


WHere is it again?
Reply
#9
It's listed in the wiki: <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZXBasic">http://www.boriel.com/wiki/en/index.php/ZXBasic</a><!-- m -->

Explicitly, this one is at: <!-- m --><a class="postlink" href="http://goo.gl/4jPd5">http://goo.gl/4jPd5</a><!-- m -->


Early on it talks about storing UDG data inside the code in safe places and accessing it. Then how to put the maze data into a DIM. Then a faster way - store the screen image instead, since it's way faster to put up as a screen$ type block. Then function fastHalfSquares is discussed, which contains a data table, as well as the code that accesses it - and so on.

Hope it helps!
Reply
#10
POKE UINTEGER 23675, @graphicsbank1

Does this poke the address of graphicsbank1 to RAM location 23675?


So the spectrum looks for UDG's at the address that 23675 points to?
Reply
#11
slenkar Wrote:POKE UINTEGER 23675, @graphicsbank1

Does this poke the address of graphicsbank1 to RAM location 23675?


So the spectrum looks for UDG's at the address that 23675 points to?
Yes, that's right. :roll:
Reply
#12
im trying to learn assembly, but keep getting strange results

this program for example
Quote:function FASTCALL downone() as ubyte
asm
INC HL
end asm
end function

function FASTCALL setup() as ubyte
asm
LD HL,16384
end asm
end function
'LD B,0

function FASTCALL drawthis() as ubyte
asm
LD A,128
LD (HL),A
end asm
end function

Dim res as String
setup()
for x=0 to 100
downone()
drawthis()
next


this is supposed to draw something to the screen 100 times
is the for next loop interfering with the assembly?
Reply
#13
how is it best to think of the spectrum screen memory?

as hex or binary?
Reply
#14
slenkar Wrote:how is it best to think of the spectrum screen memory?

as hex or binary?
From what I've read (and what I used for drawing) binary is better if you want to understand ZX Spectrum awkward screen memory addressing :roll:
Reply
#15
slenkar Wrote:im trying to learn assembly, but keep getting strange results

this program for example
Quote:function FASTCALL downone() as ubyte
asm
INC HL
end asm
end function

function FASTCALL setup() as ubyte
asm
LD HL,16384
end asm
end function
'LD B,0

function FASTCALL drawthis() as ubyte
asm
LD A,128
LD (HL),A
end asm
end function

Dim res as String
setup()
for x=0 to 100
downone()
drawthis()
next

this is supposed to draw something to the screen 100 times
is the for next loop interfering with the assembly?
Probably. From one basic instruction to another, *everything* can be destroyed in assembler (registers, etc).

ZX Basic uses memory (stack) to store temporary results from one instruction to another, but sometimes it realizes that two basic instructions together can be "operated" as a single instruction. And again, this new instruction can be packed with the next one as a single instruction, and so on. But once you insert an ASM block, this optimization is stopped.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)