News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Implementing an Array in ASM from a Languages perspective.

Started by AMSDOS, 09:39, 08 November 20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS


Trying to understand Array's from an Assembly perspective has been rather tricky when coding through another Language and BASIC has different ways of handling array's from a single cell containing a word, which can be broken down to single letters by using MID$ for example, though I've been looking at the other sort which are used to hold DATA.


With ASM it's all about Memory, so I thought I'll use BASIC to create a MEMORY array and POKE the data that way, this following example fills a 20x25 area with a Solid Block, Randomly selects a Blank Spot and then Prints it out, hardly exciting, but it works:


100 MODE 0:DEFINT a-z:INK 0,11:INK 1,26
110 MEMORY &9FFF
120 FOR y=1 TO 25
130   FOR x=1 TO 20
140     POKE &9FEB+(y*20)+x,143
150   NEXT x
160 NEXT y
170 x=(RND*20)+1:y=(RND*25)+1:POKE &9FEB+(y*20)+x,32
180 FOR y=1 TO 25
190   FOR x=1 TO 20
200     LOCATE x,y:PRINT CHR$(PEEK(&9FEB+(y*20)+x));
210   NEXT x
220 NEXT y
230 END



When I get to the Assembly, I wrote a routine to Calculate from the arrays address  (.caladr), which takes the width of the array+1 to store a base address, though soon realised from a Language perspective, I could precalculate that and store the base address and not need any additional instructions or Loops.
In the past when I've written something in Assembly, it's had a simple variable pointing to the array, the variable counts through the array, though forever changes the position within the Array.
From a Language perspective the Base Address needed to be fixed with the Loop working out where in the Array the position reached. I thought this would be important so the array could be altered just like when BASIC can alter a certain place. For that to happen I wrote 2 small routines, the initial routine acts by Adding the width from within a Loop to work out the row and the second adding column position, once those have been reached, I have the position within the Array based on the positions of the Loops.



org &8000


ld a,0
call &bc0e
ld a,0
ld b,11
ld c,b
call &bc32
ld a,1
ld b,26
ld c,b
call &bc32


;; Setup Memory array and place base address to memory.


ld hl,array
ld b,21
.caladr
dec hl
djnz caladr
ld (adary),hl


;; Fill the array with Blocks


ld a,1
ld (num1),a
ld b,a
ld c,25
.forlp1
push bc
ld a,1
ld (num2),a
ld b,a
ld c,20
.forlp2
push bc


ld hl,(adary)


ld a,(num1)
ld de,19
call yoffset


ld a,(num2)
call xoffset


ld a,143
ld (hl),a


pop bc


ld a,(num2)
inc a
ld (num2),a
ld b,a
ld a,c
cp b
jr nc.forlp2


pop bc
ld a,(num1)
inc a
ld (num1),a
ld b,a
ld a,c
cp b
jr nc,forlp1


;; Select Random Position in 20x25 Array


call rnd
ld b,20
call mod
inc a
ld (num2),a


call rnd
ld b,25
call mod
inc a
ld (num1),a


ld a,(num1)
ld de,19
call yoffset


ld a,(num2)
call xoffset


ld a,32
ld (hl)),a


;; Draw 20x25 Array


ld a,1
ld (num1),a
ld b,a
ld c,25
.forlp3
push bc
ld a,1
ld (num2),a
ld b,a
ld c,20
.forlp4
push bc


ld a,(num2)
ld h,a
ld a,(num1)
ld l,a
call &bb75


ld hl,(adary)


ld a,(num1)
ld de,20
call yoffset

ld a,(num2)
call xoffset


ld a,(hl)
call &bb5a


pop bc
ld a,(num2)
inc a
ld (num2),a
ld b,a
ld a,c
cp b
jp nc,forlp4


pop bc
ld a,(num1)
inc a
ld (num1),a
ld b,a
ld a,c
cp b
jp nc,forlp3


call &bb18
ret


.yoffset
ld b,a
.caly
add hl,de
djnz caly
ret


.xoffset
ld b,a
.calx
inc hl
djnz calx
ret


.rnd
ld hl,(seed)
ld a,r
ld d,a
ld e,a
add hl,de
xor l
add a
xor h
ld l,a
ld (seed),hl
ret


.mod
sub b
jr nc,mod
add a,b
ret


.seed
defw 0


.num1 defb 0
.num2 defb 0
.adary defw 0


org &a000


.array defb 0



For a bit of Fun, I played around with a Square Box with some Grumbles outside the Square Box:



org &8000


ld a,0
call &bc0e
ld a,0
ld b,11
ld c,b
call &bc32
ld a,1
ld b,26
ld c,b
call &bc32


;; Setup Memory array and place base address to memory.


ld hl,array
ld b,21
.caladr
dec hl
djnz caladr
ld (adary),hl


;; Draw 20x3 Array


ld a,1
ld (num1),a
ld b,a
ld c,3
.forlp3
push bc
ld a,1
ld (num2),a
ld b,a
ld c,20
.forlp4
push bc


ld a,(num2)
ld h,a
ld a,(num1)
ld l,a
call &bb75


ld hl,(adary)


ld a,(num1)
ld de,20
call yoffset

ld a,(num2)
call xoffset


ld a,(hl)
call &bb5a


pop bc
ld a,(num2)
inc a
ld (num2),a
ld b,a
ld a,c
cp b
jp nc,forlp4


pop bc
ld a,(num1)
inc a
ld (num1),a
ld b,a
ld a,c
cp b
jp nc,forlp3


call &bb18
ret


.yoffset
ld b,a
.caly
add hl,de
djnz caly
ret


.xoffset
ld b,a
.calx
inc hl
djnz calx
ret


.num1 defb 0
.num2 defb 0
.adary defw 0


org &a000


.array defb 143,143,143,143,143,143,143,143,225,225,225,225,225,225,225,225,225,225,225,225
       defb 143,032,032,032,032,032,032,032,225,225,225,225,225,225,225,225,225,225,225,225
       defb 143,143,143,143,143,143,143,143,225,225,225,225,225,225,225,225,225,225,225,225
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

zhulien

have you considered linked lists as an alternative internal implementation ?  there ate pros and cons of each


linked list can be up to 4mb on cpc but commonly up to 576kb with each element potentially being up to 16kb (minus a small header)


i can give you code for this if you like...


an array likely will need to be in a single chunk...


a linked list you have to traverse to get to element x... An array has direct access.


for traversals there isnt to much difference


an array removing an element quickly an be hard, linked list it is a couple of pointers...


again i can give full linked list code (rsx's) for dktronics ram including multiface

AMSDOS

Unfortunately, I haven't got enough examples to understand the fundamentals of Linked Lists.

A guy once gave me a scrap piece of paper of Python code, which had that, which I was able to translate to BASIC using an Array there and apart from that I've only at an Beginners Level using Python myself.

For now, I don't see the need as I seem to be grasping at straws when dealing with Arrays, for example the code above works fine for 2D Array within the bounds of a Byte, if it were to become a 1D Array with a Range exceeding 255, 'yoffset' & 'xoffset' won't work, but I think it's because I haven't implemented Double Byte Loops. The other thing I could consider are statements like 'let i(num)=ab[no,x,y]', so an Integer Variable will contain the Address of a particular array at a certain position, I would have the language pre-calculate, so 'yoffset' or 'xoffset' aren't needed, making it more direct and faster in line with Assembly.

At the moment I've only been looking at Byte Sized Array too, I have some Assembly examples which use Double Bytes, which will come into play if I get around to the Graphics side of things.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

I was worried I was going to have a problem sorting out where the aditional operators go and in what order while tackling this next problem, eventually I added more variables and search for 2 operators '+' and '-' and reports what was found and I also slipped in variable 'a', which will become variable 't' in my language to return a value that will slip in the relevant MC. It can probably be improved, though it's been a frustrating 2 day code-a-thon to eventually that this working with all operators in their correct order, though this was the tough one since both variables come into play with the array and either can have an plus or minus, lines 100..280 are the tests with lines 2000..2060 the handler.




100 c$="let b(0)=ab[1,b(1)+1,b(2)-1]"
110 GOSUB 2000:PRINT a
120 c$="let b(0)=ab[1,b(1)+1,b(2)]"
130 GOSUB 2000:PRINT a
140 c$="let b(0)=ab[1,b(1)+1,b(2)+1]"
150 GOSUB 2000:PRINT a
160 c$="let b(0)=ab[1,b(1)-1,b(2)+1]"
170 GOSUB 2000:PRINT a
180 c$="let b(0)=ab[1,b(1)-1,b(2)]"
190 GOSUB 2000:PRINT a
200 c$="let b(0)=ab[1,b(1),b(2)+1]"
210 GOSUB 2000:PRINT a
220 c$="let b(0)=ab[1,b(1),b(2)-1]"
230 GOSUB 2000:PRINT a
240 c$="let b(0)=ab[1,b(1)-1,b(2)-1]"
250 GOSUB 2000:PRINT a
260 c$="let b(0)=ab[1,b(1),b(2)]"
270 GOSUB 2000:PRINT a
280 END
2000 p1=INSTR(c$,","):a1=INSTR(p1,c$,"+"):p2=INSTR(p1+1,c$,","):a2=INSTR(p2,c$,"+"):p3=INSTR(c$,","):a3=INSTR(p3,c$,"-"):p4=INSTR(p1+1,c$,","):a4=INSTR(p4,c$,"-")
2010 a=0:IF a1=0 AND a2=0 AND a3=0 AND a4=0 THEN RETURN
2020 IF (a1>0) AND ((a1<>a2) OR (a2=0)) THEN IF MID$(c$,a1,1)="+" THEN a=a+(1*4):PRINT"+ found"
2030 IF (a3>0) AND ((a3<>a4) OR (a4=0)) THEN IF MID$(c$,a3,1)="-" THEN a=a+(1*3):PRINT"- found"
2040 IF (a4>0) THEN IF MID$(c$,a4,1)="-" THEN a=a+(2*3):PRINT"- found 2nd":RETURN
2050 IF (a2>0) THEN IF MID$(c$,a2,1)="+" THEN a=a+(2*4):PRINT"+ found 2nd":RETURN
2060 RETURN
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod