News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Storing 16bit numbers in memory..how?

Started by IndyUK, 16:14, 21 December 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

IndyUK

Hi All,
I've got my small assembly program working where I control a pixel around the screen and check for the x/y pos when it hits the screen border. The method that I've adopted is to keep things afloat in the DE/HL registers. That's all fine, however, I would prefer to start saving values in memory and retrieving as and when required. I've got the following test code which works fine up to 255 but not greater than that.
org &4000

ld de,320

ld (xpos),de

inc de

ld de,(xpos)

ret

xpos: defb 2

I obviously haven't grasped something yet because I just can't get things to work. Searched around but not found any examples. Can anybody show what I'm doing wrong?
Thanks

Docent

Quote from: IndyUK on 16:14, 21 December 18
Hi All,
I've got my small assembly program working where I control a pixel around the screen and check for the x/y pos when it hits the screen border. The method that I've adopted is to keep things afloat in the DE/HL registers. That's all fine, however, I would prefer to start saving values in memory and retrieving as and when required. I've got the following test code which works fine up to 255 but not greater than that.
org &4000

ld de,320

ld (xpos),de

inc de

ld de,(xpos)

ret

xpos: defb 2

I obviously haven't grasped something yet because I just can't get things to work. Searched around but not found any examples. Can anybody show what I'm doing wrong?
Thanks

use defw instead of defb. defb defines storage for a byte a not for a word.

AMSDOS

DEFW is just one part of it which is used to store 16bit numbers, retrieval takes a bit more code, but the 1st part of your code is correctly storing, you just need to remember that 16bit numbers use 2 bytes. I find a Scientific Calculator is useful for this in Base-N mode, otherwise it's PRINT HEX$(PEEK(lobyte));HEX$(PEEK(hibyte)) in BASIC.

This is my little example:


org &4000

ld de,320 ;; de = 320
ld (xpos),de ;; store into xpos

ld hl,xpos ;; address of xpos label

ld e,(hl) ;; store contents of HL @ xpos into E
inc hl ;; increase HL+1 to xpos+1
ld d,(hl) ;; store contents of HL @ xpos+1 into D

ld a,e
call &bb5a
ld a,d
call &bb90

ret

xpos: defw 0


I put a little example on the end of that, so if you compile that, change to PEN 2 in MODE 1, CALL &4000 will display an '@' character in PEN 2 before returning to PEN 1.
The reason for that is when the value 320 is transformed into a 2 byte hexadecimal number, it becomes &140, &40 is stored into the E register and &01 into the D.
* 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

Docent

Quote from: AMSDOS on 08:26, 22 December 18
DEFW is just one part of it which is used to store 16bit numbers, retrieval takes a bit more code, but the 1st

This is not true - retrieval takes the same amount of code. You can do both 'ld (xpos), de' and 'ld de, (xpos)' and you'll get the expected results - store the contents of de into memory at xpos, xpos+1 and retrieve memory contents at xpos, xpos+1 into de.
You can replace the following code in your example

...
ld hl,xpos ;; address of xpos label

ld e,(hl) ;; store contents of HL @ xpos into E
inc hl ;; increase HL+1 to xpos+1
ld d,(hl) ;; store contents of HL @ xpos+1 into D
...


with single ld de, (xpos)




AMSDOS

#4
For a single spot in memory you can do that certainly, I'm usually gathering a series of 16-bit data, which usually for that I have a place in memory which points to that information.


@IndyUK - Here's my Assembly routine which is using PLOT to draw lines around the screen, I've also put in the checks to test the edge of the screen. What I've done to get the line across the entire screen is to use:



ld hl,(xpos)
inc hl
ld (xpos),hl


for example.


If it something like:


ld hl,xpos
inc (hl)


then only 1 byte is updated before reaching it's threshold and emerging back on the other side.

Anyway, this is what I came up with:


   org &8000

   ld b,9
   ld c,b
   call &bc38      ;; border 9

   ld a,1
   call &bc0e      ;; mode 1

   ld hl,320      ;; initial position
   ld (xpos),hl      ;; for xpos
   
   ld hl,200      ;; initial position
   ld (ypos),hl      ;; for ypos
   
   ld a,1
   call &bbde      ;; graphics pen 1

   call plot      ;; draw plot centre of screen

.mainloop
   ld a,1
   call &bb1e      ;; test right arrow key
   call nz,moveright   ;; if found move right

   ld a,8
   call &bb1e      ;; test left arrow key
   call nz,moveleft   ;; if found move left

   ld a,0         
   call &bb1e      ;; test up arrow key
   call nz,moveup      ;; if found move up

   ld a,2
   call &bb1e      ;; test down arrow key
   call nz,movedown   ;; if found move down

   ld a,18
   call &bb1e      ;; test if enter/return pressed
   jr z,mainloop      ;; jump to main loop if not found
   ret         ;; else exit to BASIC

.moveright
   ld hl,(xpos)      ;; check if value of xpos
   ld de,638      ;; equals right side of screen
   and a
   sbc hl,de
   jr z,rghtedgefnd   ;; if true jump to right edge found (rghtedgefnd)

   ld hl,(xpos)     
   inc hl         ;; otherwise increase value of xpos
   ld (xpos),hl

   call plot      ;; and plot it's new position.

.rghtedgefnd
   ret         ;; before returning to main loop

.moveleft
   ld hl,(xpos)
   ld de,0
   and a
   sbc hl,de
   jr z,lftedgefnd

   ld hl,(xpos)
   dec hl
   ld (xpos),hl

   call plot

.lftedgefnd
   ret

.moveup   
   ld hl,(ypos)
   ld de,398
   and a
   sbc hl,de
   jr z,topedgefnd

   ld hl,(ypos)
   inc hl
   ld (ypos),hl

   call plot

.topedgefnd
   ret

.movedown
   ld hl,(ypos)
   ld de,0
   and a
   sbc hl,de
   jr z,btmedgefnd

   ld hl,(ypos)
   dec hl
   ld (ypos),hl

   call plot

.btmedgefnd
   ret

.plot
   ld hl,(xpos)
   ex hl,de      ;; xpos data goes into de register.
   ld hl,(ypos)
   call &bbea      ;; plot xpos,ypos
   ret

.xpos   defw 0
.ypos   defw 0

* 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

IndyUK

Docent/AMSDOS
Thanks guys for the pointers and advise. I thought I was missing something.
AMSODOS - Thank you for the example of moving a pixel around the screen and storing the x/y pos in memory. It was so amazing to see how your code was similar to mine. I did see in yours some quicker ways of checking the screen boundary, which I would like to use if it's ok with you(?)
Thanks

AMSDOS

Absolutely!  :) And if you need to alter the boundary, the value assigned to DE is the one to change.

I've also made some adjustments to that routine I posted above, so it now works with a Sprite Driver out of my Assembly Language book, if you're interested in that, I can post it as well, though that only needs a 8-bit data checker. Might be worth posting the original program too just to show how I transformed it from a simple Move a Single Multicoloured Image across the screen, to an interactive Moving a Single Multicoloured Image anywhere onscreen, though perhaps for another thread?
* 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