Author |
Message |
|
pugboy
Active Member
Joined: 11 Apr 2007 Posts: 544
|
Posted: 03 Oct 2008 09:47:36 pm Post subject: |
|
|
For Wizard Script, I currently have the compiler set up to create variables by using saferam (appbackupscreen)
However, the program crashes when I try to use the variable... I also tried using the label form (varname: .db 2,0 [the 2 is whatever value]), but that also crashes...
What is the proper way to use variables in a Native Assembly program? |
|
Back to top |
|
|
magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110
|
Posted: 04 Oct 2008 12:01:40 am Post subject: |
|
|
I'm kind of confused. What's Wizard Script? Is it something you are writing, or some tool you are using?
Now, are you talking about creating TI variables in assembly code, or just storing data for your own program's use? If the latter, using db to define variable space should work, as should using safe ram.
Could you post the code that crashes? |
|
Back to top |
|
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 04 Oct 2008 03:52:48 pm Post subject: |
|
|
This is a simple example of using variables in assembly:
;define the variables
labelA = saferam1+0
labelB = labelA+1
labelC = labelB+1
;initialize variables
ld hl,labelA
ld (hl),20
ld hl,labelB
ld (hl),30
ld hl,labelC
ld (hl),25
;recall label
ld hl,labelA
ld a,(hl)
ld hl,labelB
ld e,(hl)
ld hl,labelC
ld b,(hl) |
|
Back to top |
|
|
pugboy
Active Member
Joined: 11 Apr 2007 Posts: 544
|
Posted: 04 Oct 2008 04:03:26 pm Post subject: |
|
|
I am creating a language that compiles into assembly (sort of like EzASM), and need to find out how to store variables.
The code that crashes:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
ld a,2
ld (hello),a
bcall(_ClrScrnFull)
ld de,hello*256+2
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
hello: .db 0,0
.end
.end
and also
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
hello .EQU appbackupscreen
ld a,2
ld (hello),a
bcall(_ClrScrnFull)
ld de,hello*256+2
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
.end
.end
|
|
Back to top |
|
|
magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110
|
Posted: 04 Oct 2008 06:24:00 pm Post subject: |
|
|
Okay. The problem lies in how you read variables back. If you use hello, that's actually just the address where the variable is stored. You must use indirection to access it:
Code: ld a, (hello)
Does that make sense? Hello is the memory address, so you tell the CPU to load a byte from the address hello (that's what indirection means, and it's represented by parentheses around the address) and store it in register a. |
|
Back to top |
|
|
darkstone knight
Advanced Member
Joined: 07 Sep 2008 Posts: 438
|
Posted: 05 Oct 2008 10:24:09 am Post subject: |
|
|
you didnt define "hello" before u compiled
thus, hello=0 |
|
Back to top |
|
|
magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110
|
Posted: 05 Oct 2008 10:30:50 am Post subject: |
|
|
Well, I think it was defined. The first time it was defined by making it a label pointing to a spot at the end of the program. The second time it was defined using a .equ statement. And finally, it was assembled, not compiled (sorry, pet peeve). |
|
Back to top |
|
|
pugboy
Active Member
Joined: 11 Apr 2007 Posts: 544
|
Posted: 05 Oct 2008 12:01:10 pm Post subject: |
|
|
So for the first example, change it to:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
ld a,2
ld (hello),a
bcall(_ClrScrnFull)
ld a,(hello)
ld de,a*256+2
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
hello: .db 0,0
.end
.end
and for the second use:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
hello .EQU appbackupscreen
ld a,2
ld (hello),a
bcall(_ClrScrnFull)
ld a,(hello)
ld de,a*256+2
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
.end
.end
Right? Or did I mess it up again? |
|
Back to top |
|
|
magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110
|
Posted: 05 Oct 2008 12:05:39 pm Post subject: |
|
|
Afraid that won't work, dude. You can't just multiply a register by a number like that. You could load a into (curCol), and 0 into (curRow), which would do what you want. But to be honest, I think you might want to read through 28 Days again. You seem to need some help with some fundamental concepts of assembly code... |
|
Back to top |
|
|
pugboy
Active Member
Joined: 11 Apr 2007 Posts: 544
|
Posted: 05 Oct 2008 07:58:46 pm Post subject: |
|
|
Seemed to work with EzASM, so I thought it would work for me XD |
|
Back to top |
|
|
cjgone Aw3s0m3
Active Member
Joined: 24 May 2006 Posts: 693
|
Posted: 05 Oct 2008 10:09:10 pm Post subject: |
|
|
Can't expect do do something that simple in assembly. :D
Math in asm is total hell when you wanna do something hard.
I'll attempt to explain some concerns. I don't want to undermine your knowledge with something to simple, 'cuz I know you already know asm generally.
Registers a,b,c,d,e,f,h,l are 8-bit registers. You can only store 0-255 in them.
Uh, you can combine them as in hl,de,bc for 16-bit values, aka 0-65535.
If you look at binary or hex, it makes it easier to understand I suppose. LEts store, 32455 in HL.. = $7EC7 in hex, so when you do "ld hl,32455", its doing "ld h,$7E" and "ld l,$C7".
Memory on the z80 calc extends from 0000-FFFF, 0-65535 bytes. You can use the 16-bit registers to access memory. Like, the first byte of the LCD = $9340, so
Code: ld hl,$9340
ld de,1
add hl,de; hl = $9340+1
ld a,(hl) ; (hl) = value at $9340+1 in mem...kinda confusing
--------------------------
Er, the damaged statement in your code is
Code: ld de,a*256+2
Okay, an assembler like TASM can parse literals, which are just numeric values.. like ld hl,5*10+4+3 or something. You cannot do that with registers. :[
You cannot interact 16-bit registers with 8-bit registers also. you can do something like
Code: ld a,32
ld d,0
ld e,a; same as ld de,a
;illegal statement
ld de,a
Oh and ld de,a*256+2, 256 is way outta bounds for an 8-bit registers.
I think the way to do this is erm...
Code: ld a,(hello)
ld l,a
ld h,0 ; ld hl,a
add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl
add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl ; okay add hl,hl is the same as times 2, every additional add statement is 2 ^ x for the number of adds, so i have 8 adds so 2^8 = 256, which is the value..mutiplication for powers of 2 is easy :D
ld de,2
add hl,de
ex de,hl;puts hl into de, de into hl, swap
I hope that helps. Sorry if it doesn't. Asm is definitely a tricky language. Explains why it took me about 3 years to make a simple game :P
I think the difference between mem and nonmem is a bit tricky. What you can do\not do with registers is also something that takes time. I had to look at the chart in 28 days for atleast a year to make sure all my load statements worked.
Last edited by Guest on 05 Oct 2008 10:12:57 pm; edited 1 time in total |
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 05 Oct 2008 10:55:18 pm Post subject: |
|
|
pugboy wrote: Seemed to work with EzASM, so I thought it would work for me XD
[post="127591"]<{POST_SNAPBACK}>[/post]
it probably uses a generalized register math routine, or it uses bcalls. |
|
Back to top |
|
|
calc84maniac
Elite
Joined: 22 Jan 2007 Posts: 770
|
Posted: 06 Oct 2008 06:59:06 am Post subject: |
|
|
Actually, how about you replace
Code: ld de,a*256+2
with
Code: ld d,a
ld e,2
|
|
Back to top |
|
|
tr1p1ea
Elite
Joined: 03 Aug 2003 Posts: 870
|
Posted: 06 Oct 2008 03:55:18 pm Post subject: |
|
|
From the looks of it, you are just wanting the 2 bytes at 'hello:' in de so you can set currow?
Code: ld de,(hello)
ld (currow),de
hello: .db 1,2
1 will be in 'e', 2 will be in 'd', and since its a 16-bit write, e will be in 'currow' and d will be in 'curcol' since those directly follow each other in RAM.
You dont need to shift them anywhere like some people do when they define constants in code:
Code: ld de,(4*256)+5; let assembler figure it out
ld de,1029; same as above
ld de,$0405; same as above
The most common reason people will do it the first way is because they are using both d/e for different things (like loop counters etc) and want to be able to change them easily. 1029 is the result of the calculation and $0405 is the hex representation. Basically its quicker/smaller to set a 16-bit register than to set two 8-bit ones seperately like so:
Code: ld d,4
ld e,5; de = (4*256)+5
What *256 really does is SHIFT 4 left 8 positions ie 4 << 8 to align it with the upper 8-bits. In binary 4 is %00000100 and 5 is %00000101, both 8-bit numbers. When you place them next to each other in 16-bits, the result is simply: %0000010000000101 - The only mathematical way to get the 8-bits that represent our 4 in such a position is to shift it across.
Thats probably a weird explanation, but i hope it helps. In conclusion, the working code should be:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
ld a,2
ld (hello),a
bcall(_ClrScrnFull)
ld de,(hello)
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
hello:
.db 0,0
.end
.end
This should write your text at y=2 (3rd row). If you wanted to set both and do a 16-bit write, *now* you could use the *256 trick since it will be a constant like so:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
ld de,(3*256)+2
ld (hello),de
bcall(_ClrScrnFull)
ld de,(hello)
ld (currow),de
ld hl,text0
bcall(_puts)
bcall(_getkey)
ret
text0:
.db "Test",0
hello:
.db 0,0
.end
.end
This will write the text at x=3, y=2.
Hope this helps! .
***** In case you were wondering *****
A quick run-down of why your code was crashing:
Code: .nolist
#include "ti83plus.inc"
#define ProgStart $9D95
.list
.org ProgStart - 2
.db t2ByteTok, tAsmCmp
ld a,2 ; a = 2
ld (hello),a ; set 1st byte at 'hello' to 2 (hello: .db 2,0)
bcall(_ClrScrnFull) ; clear screen
ld de,hello*256+2 ; this will not read the *bytes* pointed to by 'hello'
; rather it will take the label equate for 'hello'
; which will be something like $9DB4 (40372) * 256 + 2
; which is $B402 or 46082 when truncated to 16-bits
ld (currow),de ; now here it is going to set your y=$02 or 2
; and your x=$B4 or 180 which is WAAYY offscreen
bcall(_puts) ; write the text to an offscreen position = bad
bcall(_getkey) ; wait for a key
ret ; return
text0:
.db "Test",0
hello: .db 0,0
.end
.end
Last edited by Guest on 06 Oct 2008 04:18:09 pm; edited 1 time in total |
|
Back to top |
|
|
pugboy
Active Member
Joined: 11 Apr 2007 Posts: 544
|
Posted: 06 Oct 2008 06:44:46 pm Post subject: |
|
|
Thanks for the explanations everyone :D
For simplicity, I probably will stick to loading the variables into the Currow and col... |
|
Back to top |
|
|
|