News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

ASM Basics IRC Class - Logs in First Post!

Started by Scyzer, August 27, 2010, 11:37:06 AM

Previous topic - Next topic

P.JBoy

LSR does not bring the carry back into the high bit, but ROR does
...

JAM

Sadiztyk
P.JBoy
I see...
What about first example?

LDA #$0005
LSR   ;A=0002
ASL   ;A=0004


To get $0005, should there be ROL instead of ASL, right? Or could it be compensated like this?
LDA #$0005
LSR   ;A=0002 Zero bit lost, Carry:set
ASL   ;A=0004 Carry:clear
ADD #$0000   ;A=A+1 if Carry is set

If I understand correctly, after performing LSR carry will set, but will clear after performing ASL because highest bit was zero, so, I guess, it will not work...

; 0000 0000 0000 0101|(C)
; →
; 0000 0000 0000 0010|1
; ←
; 0000 0000 0000 0100|0

In general, carry flag acts like "bit 16" when doing ASL and like "bit -1" when doing LSR, right?

P.JBoy


LDA #5
LSR; A=2, carry set
ROL; A=5, carry reset


That's pretty much the only way without branches
...

Qactis

Logs went to 404 Land :(

Any more classes planned?

Cadarot

Quote from: Qactis on May 13, 2011, 08:49:08 PM
Logs went to 404 Land :(

Any more classes planned?
They still exist. Looks like Sadi moved the files around but forgot update the first post.

Lesson 1    The basics about how the RAM works, and very simple ASM codes using LDA and STA.

Lesson 2    Comparing addresses and values with each other, and branching. Also goes into using a RAM address as a timer.

Lesson 3    Loading selective bits within addresses, and modifying selective bits.

Lesson 4    Multiplication and division. The basic use of the X and Y registers as an index.


Source: Sadiztyk's Tank

JAM

I have a question. Too noobish to ask at Engine Works.
I know how to set a word constants (!NameOfConst = #$value). Is it ever possible to set a single byte constants and use them later by DB commands?

Scyzer

#81
Yes you can. When you set a label by using !, you can set it to any value or string of values, and XKas will replace them when compiling.

EG

!Stuff = #$8000
!LongStuff = $7EC200,X
!LessStuff = $40
!LotsOfStuff = $1020,$3040

LDA !Stuff = LDA #$8000 = A9 00 80
STA !LongStuff = STA $7EC200,X = 9F 00 C2 7E
DB !LessStuff = DB $40 = 40
DW !LotsOfStuff = DB $1020,$3040 = 20 10 40 30

JAM

Oh, I see. Thanks for explaination.
It wasn't working for me because I've declared single byte values incorrectly, like !Const = #$40

Charmander106

What I am trying to do is to take one of the pointers in a room that points to my code, which is a check to see if Samus has gravity suit equiped, if not it would run a timer that would drain her energy.

My problem is I do not know how to do this unfortunately....

DSO

#84

lorom
org $8FEC00 ;(whatever's freespace in your hack)
LDA $09A2
BIT #$0020
BEQ Gravity
LDA $05D5
CMP #$0003 ;or however many frames you want between damage
BPL one:
DEC $09C2
INC $05D5
Gravity:
RTS
one:
STZ $05D5
DEC $09C2
DEC $09C2
RTS

If gravity is not equipped, this setup will do 1 damage 3 out of 4 frames then 2 damage on the 4th frame. I think you can figure it out and edit it to your needs just by looking at it.

Charmander106

Thank you for the help.

Though I already had my own code, just wanted to know how to get it to point to my code. Sorry if my post was not clear enough....

But thanks anyways, really appreciate it.

DSO

I use the FX2 pointer, which runs a routine every frame located at whatever pointer you give it in bank $8F.

monktroid

#87
Hey Scyzer, thanks for the awesome tuts. very insightful.

apologies for resurrecting a very old thread!

I'm just scratching my head a little about one thing in lesson 4 where you discuss using index X to jump to a table of values.  (The context, just to refresh your memory is: the water will rise by a greater speed the higher the number of screens samus is within a room)  thus you get samus' height in rooms (using LSR a bunch of times until you've divided her pixel height by 256).  You then pass that to your table of values.

TABLE:
   DW $0001
   DW $0002
   DW $0003
   DW $0004

you basically use the above a bit like a switch is used in a high level language.  but you mention that the address to load from increases by 2 (Presumably because each address is 2 bytes).   Ergo my question:

why use DW ...
when you could use DB and have each address in the table take up 1 byte?  No need to abstract the division to Samus' height/128. 

Have I completely misunderstood or is there a reason why DW is preferred/required that I don't understand?

PHOSPHOTiDYL

#88
The address would be a 2-byte pointer to a location in bank, so dw??

Quote58

I believe monktroid was wondering about the table of values from 0-4, not the jump table below it.
There are obviously more efficient ways to make the code in those lessons, but the point was to make sure people understood what was going on, so it had to be as clear as it could be. Much of the time it is better to use 8bit tables, but the lessons hadn't explained the different cpu modes iirc. Having a linear table of small values wouldn't be used normally anyway, that'd be a waste of space. However I would imagine they introduced the 0-4 table with DW primarily because they could then show you could replace the entries with routine addresses and use it as a jump table as well.

Only had a quick glance at the file, but that's what it looked like to me.

monktroid

Thanks guys, I think I understand

It's more I wasn't sure if I'd understood the exercise correctly. 
In summary am I correct in saying the following statements:

i. the value in accumulator that is passed to index X is "Samus' height in screens" (in this instance a number between 0 and 3)
ii. the values in the table are stored in "words" (16 bit addresses) that each take up 2 bytes; therefore, given:

TABLE:
   DW $0001 ; index 0
   DW $0002 ; index 1
   DW $0003 ; index 2
   DW $0004 ; index 3

iii. if Samus is at pixel height 800 (ie. in screen 2) and we want to load (for the sake of argument) index 2 we would need to divide samus' height by 128 (which gives us 6)


monktroid

I wanted to add since I've been doing some more reading around and learning, the following resource is indispensable and probably worth reading before doing Scyzer's tutorials:

https://wiki.superfamicom.org/snes/show/Jay%27s+ASM+Tutorial

monktroid

Quote from: PHOSPHOTiDYL on March 12, 2017, 09:58:31 PM
The address would be a 2-byte pointer to a location in bank, so dw??

from what I can surmise in what I've read elsewhere on the 65816's architecture, the transfer from one register to another is always a 16 -bit action.  Therefore it'd be kind of pointless not to perform the action in 16 bit.