GB Programming: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
>44HyXpert
m (Text replacement - "(\bld(?:|i|l|d|h) (?:.+, ?)?)\((.+)\)" to "$1[$2]")
Line 396: Line 396:
|Store value of register B into register D.
|Store value of register B into register D.
|-
|-
|''ld ($8325), a''
|''ld [$8325], a''
|Store the value of register A into memory address $8325.
|Store the value of register A into memory address $8325.
|}
|}
Line 448: Line 448:
To access the memory location pointed to by HL, just do... (hl)! It's the same with BC and DE.
To access the memory location pointed to by HL, just do... (hl)! It's the same with BC and DE.


So, to retrieve the value at memory address $6511 into register A : ''ld a, ($6511)''
So, to retrieve the value at memory address $6511 into register A : ''ld a, [$6511]''


And to store the value of register C into the memory pointed to by HL : ''ld (hl), c''
And to store the value of register C into the memory pointed to by HL : ''ld [hl], c''


Remember to refer to the chart above for the legal LD combinations.
Remember to refer to the chart above for the legal LD combinations.


Obviously, ''ld ($6511), a'' will overwrite the previous value stored here. But ''ld ($6511), hl'' will store a 16-bit value, which is a word long, that is two bytes long! So, not only will ($6511) be overwritten, but ($6512) too! Always be very careful about the memory you're touching. Otherwise, stuff like the [[ZZAZZ glitch]] happen.
Obviously, ''ld [$6511], a'' will overwrite the previous value stored here. But ''ld [$6511], hl'' will store a 16-bit value, which is a word long, that is two bytes long! So, not only will ($6511) be overwritten, but ($6512) too! Always be very careful about the memory you're touching. Otherwise, stuff like the [[ZZAZZ glitch]] happen.


For those wondering, ''ld a, ($6511)'' leaves ($6511) untouched.
For those wondering, ''ld a, [$6511]'' leaves ($6511) untouched.


==Flags==
==Flags==
Line 525: Line 525:
A : Nowhere :D To multiply, you must write your own routines! However, a nice lil' trick : to do A <- A*2, simply ''add a, a''! To do A <- A*3, do ''ld b, a'', ''add a, a'', ''add a, b'' (you can swap B with any other register, of course). I'll leave you A <- A*4, A*5, A*6 and A*7 as an exercise.
A : Nowhere :D To multiply, you must write your own routines! However, a nice lil' trick : to do A <- A*2, simply ''add a, a''! To do A <- A*3, do ''ld b, a'', ''add a, a'', ''add a, b'' (you can swap B with any other register, of course). I'll leave you A <- A*4, A*5, A*6 and A*7 as an exercise.


For the rest of the tutorial, you'll see some text prefixed by a ";". These are comments, and are NOT part of the code. This line : "ld (hl), a ; Store the mon's ID" will be interpreted as "ld (hl), a". Everything following a ";" is ignored.
For the rest of the tutorial, you'll see some text prefixed by a ";". These are comments, and are NOT part of the code. This line : "ld [hl], a ; Store the mon's ID" will be interpreted as "ld [hl], a". Everything following a ";" is ignored.


Also, the Game Boy's CPU as four very specific instructions :
Also, the Game Boy's CPU as four very specific instructions :
{| class="wikitable"
{| class="wikitable"
|ld (hli), a
|ld [hli], a
|Equivalent to ''ld (hl), a'' then ''inc hl''.
|Equivalent to ''ld [hl], a'' then ''inc hl''.
|-
|-
|ld (hld), a
|ld [hld], a
|Equivalent to ''ld (hl), a'' then ''dec hl''.
|Equivalent to ''ld [hl], a'' then ''dec hl''.
|-
|-
|ld a, (hli)
|ld a, [hli]
|Equivalent to ''ld a, (hl)'' then ''inc hl''.
|Equivalent to ''ld a, [hl]'' then ''inc hl''.
|-
|-
|ld a, (hld)
|ld a, [hld]
|Equivalent to ''ld a, (hl)'' then ''dec hl''.
|Equivalent to ''ld a, [hl]'' then ''dec hl''.
|}
|}
These are often used to operate on cHunks of memory.
These are often used to operate on chunks of memory.


===Overflow===
===Overflow===
Line 558: Line 558:
Because two hex digits mean one byte, $D3, as well as $61, is a byte. Since $D3 and H are leftmost in both cases, ld hl, $D361 is actually a shorter form of ld h, $D3 then ld l, $61.
Because two hex digits mean one byte, $D3, as well as $61, is a byte. Since $D3 and H are leftmost in both cases, ld hl, $D361 is actually a shorter form of ld h, $D3 then ld l, $61.


Let's say the following instruction is ld ($2315), hl. Applying the same logic would mean H's value would be stored at ($2315), and L's would be at ($2316). However, you just lost THE GAME; because the z80 is a "little-endian" processor, L's value (the "little-end") is stored first, at ($2315). So ($2315) is $61, and ($2316) is $D3.
Let's say the following instruction is ld [$2315], hl. Applying the same logic would mean H's value would be stored at ($2315), and L's would be at ($2316). However, you just lost THE GAME; because the z80 is a "little-endian" processor, L's value (the "little-end") is stored first, at ($2315). So ($2315) is $61, and ($2316) is $D3.


Stop here, and remember this until it becomes natural to you. Because this "little-endian"ness is very tricky for beginners. It is ''very'' important when working with memory.
Stop here, and remember this until it becomes natural to you. Because this "little-endian"ness is very tricky for beginners. It is ''very'' important when working with memory.
Line 573: Line 573:
<pre>
<pre>
ld hl, $C303
ld hl, $C303
ld a, ($C001)
ld a, [$C001]
ld b, 3
ld b, 3
add a, b
add a, b
ld c, 0
ld c, 0
sbc hl, bc
sbc hl, bc
ld (hl), a
ld [hl], a
inc hl
inc hl
ld b, (hl)
ld b, [hl]
sub a, b
sub a, b
inc (hl)
inc (hl)
inc hl
inc hl
ld (hl), b
ld [hl], b
ld bc, 9
ld bc, 9
add hl, bc
add hl, bc
ld (hl), a
ld [hl], a
ld ($C00B), hl
ld [$C00B], hl
</pre>
</pre>


Line 633: Line 633:
To push register DE :
To push register DE :
<pre>
<pre>
ld hl, ($C000) ; Retrieve stack pointer
ld hl, [$C000] ; Retrieve stack pointer
ld (hl), e ; Push the low-order byte
ld [hl], e ; Push the low-order byte
inc hl ; Move stack pointer
inc hl ; Move stack pointer
ld (hl), d ; Repeat
ld [hl], d ; Repeat
inc hl
inc hl
ld ($C000), hl ; Save stack pointer
ld [$C000], hl ; Save stack pointer
</pre>
</pre>
To pop into register DE :
To pop into register DE :
<pre>
<pre>
ld hl, ($C000) ; Retrieve stack pointer
ld hl, [$C000] ; Retrieve stack pointer
dec hl ; Move stack pointer
dec hl ; Move stack pointer
ld d, (hl) ; Pop the high-order byte
ld d, [hl] ; Pop the high-order byte
dec hl ; Repeat
dec hl ; Repeat
ld e, (hl)
ld e, [hl]
ld ($C000), hl ; Save stack pointer
ld [$C000], hl ; Save stack pointer
</pre>
</pre>


Line 678: Line 678:
|<pre>
|<pre>
dec sp
dec sp
ld (sp), h
ld [sp], h
dec sp
dec sp
ld (sp), l
ld [sp], l
</pre>
</pre>
|-
|-
|POP HL
|POP HL
|<pre>
|<pre>
ld l, (sp)
ld l, [sp]
inc sp
inc sp
ld h, (sp)
ld h, [sp]
inc sp
inc sp
</pre>
</pre>
Line 696: Line 696:
<pre>
<pre>
push af
push af
ld a, ($C000)
ld a, [$C000]
pop de
pop de
</pre>
</pre>
Line 810: Line 810:
Example :
Example :
<pre>
<pre>
ld a, (hl)
ld a, [hl]
cp $63
cp $63
jr z, placeItems
jr z, placeItems
Line 817: Line 817:
jr someplace
jr someplace
placeItems:
placeItems:
ld b, (hl)
ld b, [hl]
</pre>
</pre>
If (hl) equals $63, execution jumps to placeItems.
If (hl) equals $63, execution jumps to placeItems.
Line 1,054: Line 1,054:
ld hl, $C303 ; Now H = $C3 and L = $03
ld hl, $C303 ; Now H = $C3 and L = $03


ld a, ($C001) ; A = $03
ld a, [$C001] ; A = $03


ld b, 3 ; B = $03
ld b, 3 ; B = $03
Line 1,064: Line 1,064:
sbc hl, bc ; HL = HL - (BC + C flag) = $C303 - ($0300 + $00) = $C003
sbc hl, bc ; HL = HL - (BC + C flag) = $C303 - ($0300 + $00) = $C003


ld (hl), a ; (HL) = ($C003) <- A = $06
ld [hl], a ; (HL) = ($C003) <- A = $06


inc hl ; HL = $C004
inc hl ; HL = $C004


ld b, (hl) ; B = (HL) = ($C004) = $DE
ld b, [hl] ; B = (HL) = ($C004) = $DE


sub a, b ; A = A - B = $06 - $DE = $06 + (-$DE) = $06 + ($21 + $01) = $28, C flag = 0
sub a, b ; A = A - B = $06 - $DE = $06 + (-$DE) = $06 + ($21 + $01) = $28, C flag = 0
Line 1,078: Line 1,078:
inc hl ; HL = $C005
inc hl ; HL = $C005


ld (hl), b ; (HL) = B = $DE
ld [hl], b ; (HL) = B = $DE


ld bc, 9 ; B = $00, C = $09
ld bc, 9 ; B = $00, C = $09
Line 1,084: Line 1,084:
add hl, bc ; HL = HL + BC = $C005 + $0009 = $C00E
add hl, bc ; HL = HL + BC = $C005 + $0009 = $C00E


ld (hl), a ; (HL) = ($C00E) = A = $28
ld [hl], a ; (HL) = ($C00E) = A = $28


ld ($C00B), hl ; ($C00B) = L = $0E, and ($C00C) = H = $C0
ld [$C00B], hl ; ($C00B) = L = $0E, and ($C00C) = H = $C0


Initial values :
Initial values :