Skip to content

Commit a44c1ea

Browse files
authoredApr 23, 2024··
Fix un-rendered tags (#106)
* <sup>, <sub>, <kbd> and <u>
1 parent 414ee68 commit a44c1ea

13 files changed

+30
-30
lines changed
 

‎content/affine.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ INLINE s32 lu_cos(uint theta)
630630
{ return sin_lut[((theta>>7)+128)&0x1FF]; }
631631
```
632632
633-
Now, note the angle range: 0-10000h. Remember you don't *have* to use 360 degrees for a circle; in fact, on computers it's better to divide the circle in a power of two instead. In this case, the angle is in 2^16^ parts for compatibility with BIOS functions, which is brought down to a 512 range inside the look-up functions.
633+
Now, note the angle range: 0-10000h. Remember you don't *have* to use 360 degrees for a circle; in fact, on computers it's better to divide the circle in a power of two instead. In this case, the angle is in 2<sup>16</sup> parts for compatibility with BIOS functions, which is brought down to a 512 range inside the look-up functions.
634634
635635
### Initialization
636636

‎content/asm.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ It is also possible to load/store bytes and halfwords. The opcodes for loads are
738738

739739
All the things you can do with `ldr/str`, you can do with the byte and halfword versions as well: PC-relative, indirect, pre/post-indexing it's all there … with one exception. The signed-byte load (`ldsb`) and _all_ of the halfword loads and stores cannot do shifted register-loads. Only `ldrb` has the complete functionality of the word instructions. The consequence is that signed-byte or halfword arrays may require extra instructions to keep the offset and index in check.
740740

741-
Oh, one more thing: alignment. In C, you could rely on the compiler to align variables to their preferred boundaries. Now that you're taking over from the compiler, it stands to reason that you're also in charge of alignment. This can be done with the ‘.align _n_’ directive, with aligns the next piece of code or data to a 2^n^ boundary. Actually, you're supposed to properly align code as well, something I'm taking for granted in these snippets because it makes things easier.
741+
Oh, one more thing: alignment. In C, you could rely on the compiler to align variables to their preferred boundaries. Now that you're taking over from the compiler, it stands to reason that you're also in charge of alignment. This can be done with the ‘.align _n_’ directive, with aligns the next piece of code or data to a 2<sup>n</sup> boundary. Actually, you're supposed to properly align code as well, something I'm taking for granted in these snippets because it makes things easier.
742742

743743
<pre><code class="language-armasm hljs"> mov r2, #1
744744
@ Byte loads
@@ -1032,7 +1032,7 @@ Bit-operations like `orr` or `and` don't affect it because they operate purely o
10321032

10331033
You may find it odd that `-cc` is the code for unsigned higher than. As mentioned, a comparison is essentially a subtraction, but when you subtract, say 7−1, there doesn't really seem to be a carry here. The key here is that subtractions are infact forms of additions: 7−1 is actually 7+0xFFFFFFFF, which would cause an overflow into the carry bit. You can also thing of subtractions as starting out with the carry bit set.
10341034

1035-
The overflow flag indicates _signed_ overflow (the carry bit would be unsigned overflow). Note, this is _not_ merely a sign change, but a sign change the wrong way. For example, an addition of two positive numbers _should_ always be positive, but if the numbers are big enough (say, 2^30^, see {@tbl:overflow}) then the results of the lower 30 bits may overflow into bit 31, therefore changing the sign and you'll have an incorrect addition. For subtraction, there can be a similar problem. Short of doing the full operation and checking whether the signs are correct, there isn't a simple way of figuring out what counts as overflow, but fortunately you don't have to. Usually overflow is only important for signed comparisons, and the condition mnemonics themselves should provide you with enough information to pick the right one.
1035+
The overflow flag indicates _signed_ overflow (the carry bit would be unsigned overflow). Note, this is _not_ merely a sign change, but a sign change the wrong way. For example, an addition of two positive numbers _should_ always be positive, but if the numbers are big enough (say, 2<sup>30</sup>, see {@tbl:overflow}) then the results of the lower 30 bits may overflow into bit 31, therefore changing the sign and you'll have an incorrect addition. For subtraction, there can be a similar problem. Short of doing the full operation and checking whether the signs are correct, there isn't a simple way of figuring out what counts as overflow, but fortunately you don't have to. Usually overflow is only important for signed comparisons, and the condition mnemonics themselves should provide you with enough information to pick the right one.
10361036

10371037
<div class="lblock">
10381038
<table id="tbl:overflow">
@@ -1098,7 +1098,7 @@ DivSafe:
10981098
bx lr
10991099
```
11001100

1101-
The numerator and denominator will be in registers r0 and r1, respectively. The `cmp` checks whether the denominator is zero. If it's not, no branch is taken, the swi 6 is executed and the function returns afterwards. If it is zero, the `beq` will take the code to `.Ldiv_bad`. The two instructions there set r0 to either INT_MAX (2^31^−1 = 0x7FFFFFFF) or INT_MIN (−2^31^ = 0x80000000), depending on whether r0 is positive or negative. If it's a little hard to see that, `mvn` inverts bits, so the first line after `.Ldiv_bad` sets r0 to INT_MAX. The second line we've seen before: ‘`r0, asr #31`’ does a sign-extension in to all other bits, giving 0 or −1 for positive and negative numbers, respectively, giving INT_MAX− −1 = INT_MIN for negative values of r0. Little optimizing tricks like these decide if you're fit to be an assembly programmer; if not you could just as well let the compiler do them, because it does know. (It's where I got the ‘`asr #31`’ thing from in the first place.)
1101+
The numerator and denominator will be in registers r0 and r1, respectively. The `cmp` checks whether the denominator is zero. If it's not, no branch is taken, the swi 6 is executed and the function returns afterwards. If it is zero, the `beq` will take the code to `.Ldiv_bad`. The two instructions there set r0 to either INT_MAX (2<sup>31</sup>−1 = 0x7FFFFFFF) or INT_MIN (−2<sup>31</sup> = 0x80000000), depending on whether r0 is positive or negative. If it's a little hard to see that, `mvn` inverts bits, so the first line after `.Ldiv_bad` sets r0 to INT_MAX. The second line we've seen before: ‘`r0, asr #31`’ does a sign-extension in to all other bits, giving 0 or −1 for positive and negative numbers, respectively, giving INT_MAX− −1 = INT_MIN for negative values of r0. Little optimizing tricks like these decide if you're fit to be an assembly programmer; if not you could just as well let the compiler do them, because it does know. (It's where I got the ‘`asr #31`’ thing from in the first place.)
11021102

11031103
Now in this case I used a branch, but in truth, it wasn't even necessary. The non-branch part consists of one instruction, and the branched part of two, so using conditional instructions throughout would have been both shorter and faster:
11041104

@@ -1834,7 +1834,7 @@ The directives you'd use for data will generally tell you what the datatypes are
18341834

18351835
A very important and sneaky issue is alignment. **You** are responsible for aligning code and data, not the assembler. In C, the compiler did this for you and the only times you might have had problems was with [alignment mismatches](bitmaps.html#ssec-data-align) when casting, but here both code _and_ data can be misaligned; in assembly, the assembler just strings your code and data together as it finds it, so as soon as you start using anything other than words you have the possibility of mis-alignments.
18361836

1837-
Fortunately, alignment is very easy to do: ‘`.align `_`n`_’ aligns to the next 2^n^ byte boundary and if you don't like the fact that _n_ is a power here, you can also use ‘`.balign `_`m`_’, which aligns to _m_ bytes. These will update the current location so that the next item of business is properly aligned. Yes, it applies to the _next_ item of code/data; it is not a global setting, so if you intend to have mixed data-sizes, be prepared to align things often.
1837+
Fortunately, alignment is very easy to do: ‘`.align `_`n`_’ aligns to the next 2<sup>n</sup> byte boundary and if you don't like the fact that _n_ is a power here, you can also use ‘`.balign `_`m`_’, which aligns to _m_ bytes. These will update the current location so that the next item of business is properly aligned. Yes, it applies to the _next_ item of code/data; it is not a global setting, so if you intend to have mixed data-sizes, be prepared to align things often.
18381838

18391839
Here are a few examples of how these things would work in practice. Consider it standard boilerplate material for the creation and use of symbols.
18401840

‎content/bitmaps.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ In {@fig:link-sm} you can find a bitmap of one of the game characters that made
2020

2121
A bitmap is little more than a *w*×*h* matrix of colors (or color-indices), where *w* is the number of columns (the width) and *h* the number of rows (the height). A particular pixel can be referred to with a coordinate pair: (*x**y*). By the way, the y-axis of the GBA points *down*, not up. So pixel (0, 0) is in the top-left corner. In memory, the lines of the bitmap are laid out sequentially, so that the following rule holds: in a *w×h* bitmap, the pixel (*x, y*) is the (*w×y + x*)-th pixel. This is true for all C matrices, by the way.
2222

23-
{*@fig:link-big} shows how this works. This is a *w*=24 by *h*=24 bitmap, at 8bpp (8 <span class="underline">B</span>its <span class="underline">P</span>er <span class="underline">P</span>ixel (=1 byte)). The numbers in yellow indicate the memory locations; you can count them for yourself if you don't believe me. The first pixel, (0, 0), can be found at location 0. The *last* pixel of the *first* row (23, 0) is at *w*−1 (=23 in this case). The first pixel of the second row (0, 1) is at *w* (=24) etc, etc, till the last pixel at *w×h*−1.
23+
{*@fig:link-big} shows how this works. This is a *w*=24 by *h*=24 bitmap, at 8bpp (8 <u>B</u>its <u>P</u>er <u>P</u>ixel (=1 byte)). The numbers in yellow indicate the memory locations; you can count them for yourself if you don't believe me. The first pixel, (0, 0), can be found at location 0. The *last* pixel of the *first* row (23, 0) is at *w*−1 (=23 in this case). The first pixel of the second row (0, 1) is at *w* (=24) etc, etc, till the last pixel at *w×h*−1.
2424

2525
<div class="cblock">
2626
<table id="fig:link-big">
@@ -835,7 +835,7 @@ Potential problems during compilation or linking:
835835

836836
Data alignment is about the ‘natural’ memory addresses of variables. It is often beneficial to have a variable of a certain length to start at an address divisible by that length. For example, a 32-bit variable likes to be put at addresses that are a multiple of 4. Processors themselves also have certain preferred alignments. Addressing will work faster if you stick to their native types and alignment (say, 32-bit everything for 32-bit CPUs). For PCs it is not required to do any of this, it'll just run slower. For RISC systems, however, things *must* be aligned properly or data gets mangled.
837837

838-
In most cases, the compiler will align things for you. It will put all halfwords on even boundaries and words on quad-byte boundaries. As long as you stick to the normal programming rules, you can remain completely oblivious to this alignment stuff. Except that you *won't* always stick to the rules. In fact, C is a language that allows you to break the rules whenever you feel like it. It trusts you to know what you're doing. Whether that trust is always justified is another matter <span class="kbd">:P</span>
838+
In most cases, the compiler will align things for you. It will put all halfwords on even boundaries and words on quad-byte boundaries. As long as you stick to the normal programming rules, you can remain completely oblivious to this alignment stuff. Except that you *won't* always stick to the rules. In fact, C is a language that allows you to break the rules whenever you feel like it. It trusts you to know what you're doing. Whether that trust is always justified is another matter <kbd>:P</kbd>
839839

840840
The best example of breaking the rules is pointer casting. For example, most graphics converters will output the data as `u16` arrays, so you can copy it to VRAM with a simple `for` loop. You can speed up copying by roughly 160% if you copy by words (32-bit) rather than halfwords (16-bit). Run the *[txt_se2](text.html#ssec-demo-se2)* demo and see for yourself. All you have to do for this is one or two pointer casts, as shown here.
841841

@@ -1045,4 +1045,4 @@ This chapter also discussed a few things about handling data, a very important t
10451045

10461046
Before continuing with further chapters, this may be a good time to do some experimenting with data: try changing the data arrays and see what happens. Look at the different data interpretations, different casts, and maybe some intentional errors as well, just to see what kinds of problems you might face at some point. It's better to make mistakes early, while programs are still short and simple and you have less potential problems.
10471047

1048-
Or not, of course <span class="kbd">:P</span>. Maybe it's worth waiting a little longer with that; or at least until we've covered basic input, which allows for much more interesting things than just passive images.
1048+
Or not, of course <kbd>:P</kbd>. Maybe it's worth waiting a little longer with that; or at least until we've covered basic input, which allows for much more interesting things than just passive images.

‎content/edmake.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Be sure that the devkitARM and msys bin directories are in the system path, or c
5353

5454
I never really knew about PN until it started coming with devkitARM, but it looks really good. I haven't used it that much myself, but only because I am still content with context. That said, PN is probably the better editor, and as it may come with the toolchain, chances are you'll have it already.
5555

56-
For all its benefits, I should say this though: by default, it seems to ignore the desktop color scheme. This may not sound like a big deal, but because the background color defaulted to a hard white, I literally couldn't even look at the thing for more than a minute. When I first tried to fix this in the options, it seemed that you could only change this on a type-by-type basis instead of globally. Took me a while to figure out I'd been looking in the wrong place <span class="kbd">:P</span> all along. Look under Tools-\>Options-\>Styles, not under Tools-\>Options-\>Schemes.
56+
For all its benefits, I should say this though: by default, it seems to ignore the desktop color scheme. This may not sound like a big deal, but because the background color defaulted to a hard white, I literally couldn't even look at the thing for more than a minute. When I first tried to fix this in the options, it seemed that you could only change this on a type-by-type basis instead of globally. Took me a while to figure out I'd been looking in the wrong place <kbd>:P</kbd> all along. Look under Tools-\>Options-\>Styles, not under Tools-\>Options-\>Schemes.
5757

5858
To add commands for makefiles, go to Tools-\>Options-\>Tools (@fig:pn-make), and select the ‘Make’. Then add 2 commands for ‘make build’ and ‘make clean’
5959

‎content/fixed.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ This is actually a subset of the scaling problems of multiplication and division
372372

373373
One way of covering for the extra scale is not to correct after the multiplication, but before it; though you will lose some accuracy in the process. A good compromise would be to right-shift both operands by half the full shift.
374374

375-
Fixed divisions have a similar problem called underflow. As a simple example of this, consider what happens in integers division *a*/*b* if *b*\>*a*. That's right: the result would be zero, even though a fraction would be what you would like. To remedy this behaviour, the numerator is scaled up by *M* first (which may or may not lead to an overflow problem <span class="kbd">:P</span>).
375+
Fixed divisions have a similar problem called underflow. As a simple example of this, consider what happens in integers division *a*/*b* if *b*\>*a*. That's right: the result would be zero, even though a fraction would be what you would like. To remedy this behaviour, the numerator is scaled up by *M* first (which may or may not lead to an overflow problem <kbd>:P</kbd>).
376376

377377
As you can see, the principles of fixed-point math aren't that difficult or magical. But you do have to keep your head: a missed or misplaced shift and the whole thing crumbles. If you're working on a new algorithm, consider doing it with floats first (preferably on a PC), and convert to fixed-point only when you're sure the algorithm itself works.
378378

‎content/lab.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ void foo()
9898

9999
Note that I intend the routine to be in IWRAM (and compiled as ARM code) because it's so **very f%#\$@\*g slow**! Or perhaps I shouldn't say slow, just costly.
100100

101-
Think of how a basic sort works. You have *N* elements to sort. In principle, each of these has to be checked with every other element, so that the routine's speed is proportional to *N*^2^, usually expressed as *O*(*N*^2^), where the *O* stands for order of magnitude. For sorting, *O*(*N*^2^) is bad. For example, when *N*=128, you would be looking at 16k checks. Times the number of cycles that the actual checks and updates would take. Not pleasant.
101+
Think of how a basic sort works. You have *N* elements to sort. In principle, each of these has to be checked with every other element, so that the routine's speed is proportional to *N*<sup>2</sup>, usually expressed as *O*(*N*<sup>2</sup>), where the *O* stands for order of magnitude. For sorting, *O*(*N*<sup>2</sup>) is bad. For example, when *N*=128, you would be looking at 16k checks. Times the number of cycles that the actual checks and updates would take. Not pleasant.
102102

103-
Fortunately, there are faster methods, you'd want at least an *O*(*N*·log~2~(*N*)) for sorting algorithms, and as you can see from the aforementioned wiki, there are plenty of those and shellsort is one of them. Unfortunately, even this can be quite expensive. Again, with *N*=128 this is still about 900, and you can be sure the multiplier can be high, as in 80+. With ARM+IWRAM, I can manage to bring that down to 20-30, and a simple exercise in assembly gives me an acceptable 13 to 22 × *N*·log~2~(*N*).
103+
Fortunately, there are faster methods, you'd want at least an *O*(*N*·log<sub>2</sub>(*N*)) for sorting algorithms, and as you can see from the aforementioned wiki, there are plenty of those and shellsort is one of them. Unfortunately, even this can be quite expensive. Again, with *N*=128 this is still about 900, and you can be sure the multiplier can be high, as in 80+. With ARM+IWRAM, I can manage to bring that down to 20-30, and a simple exercise in assembly gives me an acceptable 13 to 22 × *N*·log<sub>2</sub>(*N*).
104104

105105
:::note The Big O Notation
106106

‎content/log.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ I think that'll be all then.
6767

6868
### Feb 2007 (v1.3b)
6969

70-
As every programmer knows, you're supposed to write down the changes you make while making them. As every programmer also knows, this has a tendency to be forgotten <span class="kbd">\^\_\^;;</span>. I probably missed a few things here.
70+
As every programmer knows, you're supposed to write down the changes you make while making them. As every programmer also knows, this has a tendency to be forgotten <kbd>\^\_\^;;</kbd>. I probably missed a few things here.
7171

7272
Text:
7373

@@ -106,7 +106,7 @@ Code:
106106

107107
- ![new](./img/log/bul_new.png) libtonc: yet another Great Renaming. Among other things: The leading underscore for zero-#defines are gone. I thought it was a good way if guarding against potential unsafe operations, but they just look too weird to use. And there was much rejoicing. Some macros have lots their `_ON` prefix when it's obvious that that's what they do. OAM structs are now `OBJ_ATTR` and `OBJ_AFFINE` and supporting functions are now prefixed `obj_` and `obj_aff_`. `BGAFF_EX` is now `BG_AFFINE` and used in most affine BG functions. A complete list can be found in `tonc_legacy.h`, which you can #include to keep compatibility with older code.
108108

109-
- ![new](./img/log/bul_new.png) projects: the structure of the projects hierarchy has been altered. The demos have been categorized as basic, extended or advanced, which correspond with the tonc-text parts. Basic demos are simpler, with simple makefiles. They are completely self-sufficient, which should help learning the ropes. The extended demos have more complete makefiles and make use of libtonc. The advanced demos have devkitPro-like makefiles. As much as I'd like to, the actual DKP templates don't quite suit my purposes (sorry, Dave <span class="kbd">:P</span>) so I rolled my own. The advanced demos also make use of assembly files for data.
109+
- ![new](./img/log/bul_new.png) projects: the structure of the projects hierarchy has been altered. The demos have been categorized as basic, extended or advanced, which correspond with the tonc-text parts. Basic demos are simpler, with simple makefiles. They are completely self-sufficient, which should help learning the ropes. The extended demos have more complete makefiles and make use of libtonc. The advanced demos have devkitPro-like makefiles. As much as I'd like to, the actual DKP templates don't quite suit my purposes (sorry, Dave <kbd>:P</kbd>) so I rolled my own. The advanced demos also make use of assembly files for data.
110110

111111
The project folders also contain `.pnproj` files, which can be opened and run from Programmer's Notepad.
112112

@@ -117,7 +117,7 @@ Code:
117117
### Jul 23, 2006 (v1.2.4)
118118

119119
- ![new](./img/log/bul_new.png) Added a rather long chapter on [ARM/Thumb assembly](asm.html). This is still a draft version, though. Most of the content is there, but I still need to reshuffle sections and spell/grammer check the whole thing.
120-
- And yet more spell fixes <span class="kbd">\>\_\<</span>.
120+
- And yet more spell fixes <kbd>\>\_\<</kbd>.
121121

122122
### Jun 3, 2006 (v1.2.3)
123123

@@ -178,10 +178,10 @@ More non-final updates. Quite a lot actually.
178178

179179
### Jan 27, 2006 (v1.1)
180180

181-
Heh, so that wasn't not the final update after all <span class="kbd">:P</span>.
181+
Heh, so that wasn't not the final update after all <kbd>:P</kbd>.
182182

183183
- Added a little note to [setup](setup.html) on how to get rid of them useless directories that MSVC 6.0 insists on creating all the time.
184-
- ![fix](./img/log/bul_excl.png) Fixed devkitARM URL and revision. (don't know why I bother with that, though, as there will be a new version the second I post this. Gawddammit, Dave, quit it! <span class="kbd">\>\_\<</span>)
184+
- ![fix](./img/log/bul_excl.png) Fixed devkitARM URL and revision. (don't know why I bother with that, though, as there will be a new version the second I post this. Gawddammit, Dave, quit it! <kbd>\>\_\<</kbd>)
185185
- ![upgrade](./img/log/bul_upgr.png) More code in the text. At least for the earlier pages.
186186
- Two new chapters: one on [Text system fundamentals](text.html) and [producing beeps](sndsqr.html). The latter isn't quite finished yet, but should be enough to get you going. There are 5 new demos that go with these: 4 for text, one for sound.
187187
- ![swap](./img/log/bul_swap.png) More name changes. This time in demo-names only, though, so don't worry there.
@@ -243,13 +243,13 @@ I'm sorry if any of these changes causes you any inconvenience, but I think it's
243243
- ![fix](./img/log/bul_excl.png) Fixed a window control macros (forgot some shifts). Should work properly now. Should.
244244
- Added `geom.h|.c` to the library, as I intend to use points and rectangles more often. Also added `ABS`, `SGN` and `SWAP` macros.
245245
- All multiboot demos (i.e., all of them) now have the extension `mb.gba` to indicate them as such.
246-
- Renamed `key_pressed()` to `key_hit()`, which should cause less confusion about what the function actually does (thank's\^H\^Hs for the name Dark Angel (see? The apostrophe occurs almost automatically <span class="kbd">:(</span> ).
246+
- Renamed `key_pressed()` to `key_hit()`, which should cause less confusion about what the function actually does (thank's\^H\^Hs for the name Dark Angel (see? The apostrophe occurs almost automatically <kbd>:(</kbd> ).
247247

248248
I'm working on a nice text system right now. If anyone has any requests I'll see what I can do.
249249

250250
### June 27, 2004 (v0.99.3)
251251

252-
Ahhh, home at last, where I have a proper computer and Kink-FM blasting through my stereo, excccellent! <span class="kbd">=)</span>
252+
Ahhh, home at last, where I have a proper computer and Kink-FM blasting through my stereo, excccellent! <kbd>=)</kbd>
253253

254254
- ![upgrade](./img/log/bul_upgr.png) Added `-Map` and `-Wl` command-line options to the [flags list](makefile.html#sec-flags).
255255
- ![swap](./img/log/bul_swap.png) Moved the graphics data that is only used once into the demo-folder where they are used; the gfx directory now only has shared graphics in it.
@@ -261,7 +261,7 @@ Ahhh, home at last, where I have a proper computer and Kink-FM blasting through
261261

262262
- ![upgrade](./img/log/bul_upgr.png) I made a lot of changes to `mode7d`; all the real mode 7 code is now in separate files so using it in other projects is easier now. Though mode7ex.htm still needs a lot of work, you can find most of the text in draft-form in [m7theory.zip](../files/m7theory.zip). Yes, it's a Word document; yes, I know that sucks; yes, I will convert it to html when I the text is stable and understandable (please tell me what I need to change in this respect); and yes, I will do this conversion manually, since Word should be allowed to approach HTML to within 500 yards. Perhaps more.
263263
- ![fix](./img/log/bul_excl.png) Made some minor fixes to the [matrix](matrix.html) page. Silly me, I got the cross-product definition all wrong.
264-
- ![upgrade](./img/log/bul_upgr.png) Added info on `REG_P1CNT` to the [keypad](keys.html) page. Yet another thing which only this site covers <span class="kbd">:)</span>.
264+
- ![upgrade](./img/log/bul_upgr.png) Added info on `REG_P1CNT` to the [keypad](keys.html) page. Yet another thing which only this site covers <kbd>:)</kbd>.
265265

266266
Devving on a P2-300 with 24MB RAM: VBA runs at 50% (and 23% for mode7d) and minimizing a window takes a few seconds. Man, this sucks.
267267

‎content/matrix.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ This is the simplest case of an inverse. And, yup, that's a determinant as the d
14561456
14571457
### Algebraic properties of matrices {#ssec-mat-props}
14581458
1459-
**A** and **B** are M×N matrices; **C** is N×P; **D** and **E** are N×N. **e**~i~ are the column vectors of **E**. _c_ is a scalar.
1459+
**A** and **B** are M×N matrices; **C** is N×P; **D** and **E** are N×N. **e**<sub>i</sub> are the column vectors of **E**. _c_ is a scalar.
14601460
14611461
<div class="lblock">
14621462
<table cellpadding=2 cellspacing=0>

‎content/mode7.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ And yes, the minus sign is correct for a counter-clockwise rotation (**R** is de
358358
</math>
359359
</table>
360360

361-
that is, <span class="underline">one</span> translation and <span class="underline">one</span> transformation. We have to combine the pre- and post-translations to make it work. We've seen this before in eq 4 in the [affine background page](affbg.html#sec-aff-ofs), only with different names. Anyway, what you need is:
361+
that is, <u>one</u> translation and <u>one</u> transformation. We have to combine the pre- and post-translations to make it work. We've seen this before in eq 4 in the [affine background page](affbg.html#sec-aff-ofs), only with different names. Anyway, what you need is:
362362

363363
<table id="eq-aff-ofs">
364364
<tr>

‎content/numbers.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ For this reason, in 1999, the IEC began to recommend a separate set of binary pr
164164

165165
In itself, binary isn't so difficult, it's just that the numbers are so large! The solution for this given above was using commas to divide them into groups of four. There is a better solution, namely hexadecimal.
166166

167-
Hexadecimal is the name for the base-16 system, also known as <dfn>hex</dfn>. That an abbreviation exists should tell you something about its prevalence. As you should be able to guess by now, there are 16 symbols in hex. This presents a small problem because we only have 10 symbols associated with numbers. Rather than invent new symbols, the first letters of the alphabet are used, so the sequence becomes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. Hex is more concise than binary. In fact, since 16 is 2^4^, you can exactly fit four bits into one hex digit, so hex is exactly 4 times as short as binary. This is also why I used groups of four earlier on. If you know the powers of 2, then you automatically know the powers of 16 too, but rather than decompose numbers into powers of 16, it's often easier to go to binary first, make groups and convert those to hex.
167+
Hexadecimal is the name for the base-16 system, also known as <dfn>hex</dfn>. That an abbreviation exists should tell you something about its prevalence. As you should be able to guess by now, there are 16 symbols in hex. This presents a small problem because we only have 10 symbols associated with numbers. Rather than invent new symbols, the first letters of the alphabet are used, so the sequence becomes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. Hex is more concise than binary. In fact, since 16 is 2<sup>4</sup>, you can exactly fit four bits into one hex digit, so hex is exactly 4 times as short as binary. This is also why I used groups of four earlier on. If you know the powers of 2, then you automatically know the powers of 16 too, but rather than decompose numbers into powers of 16, it's often easier to go to binary first, make groups and convert those to hex.
168168

169169
<div class="lblock">
170170
<table>
@@ -1141,7 +1141,7 @@ OR and XOR are only very rarely used in their arithmetic form, but the shifts an
11411141
</table>
11421142
</div>
11431143

1144-
And now for my final trick of the day, let's take a closer look at the most basic of arithmetic operations, addition. The addition of 2 bits to be precise, and the truthtable of that can be found in table 12 below. If you've paid attention so far (well done! I didn't think anyone would make it this far <span class="kbd">:P</span>), there should be something familiar about the two columns that make up the result. The right column is just *a* XOR *b* and the left column is *a* AND *b*. This means that you can create a 1-bit adder with just an AND and a XOR port, electric components that can be found in any Radio Shack, or its local equivalent. String 8 of these together for an 8-bit adder, and you'll have yourself the foundation of an 8bit computer, cool huh?
1144+
And now for my final trick of the day, let's take a closer look at the most basic of arithmetic operations, addition. The addition of 2 bits to be precise, and the truthtable of that can be found in table 12 below. If you've paid attention so far (well done! I didn't think anyone would make it this far <kbd>:P</kbd>), there should be something familiar about the two columns that make up the result. The right column is just *a* XOR *b* and the left column is *a* AND *b*. This means that you can create a 1-bit adder with just an AND and a XOR port, electric components that can be found in any Radio Shack, or its local equivalent. String 8 of these together for an 8-bit adder, and you'll have yourself the foundation of an 8bit computer, cool huh?
11451145

11461146
<div class="lblock">
11471147
<table id="tbl:adder" class="table-data rules-groups" width=20%>

‎content/regobj.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ Finally, what I call my build macros. These piece together the various bit-flags
485485
```
486486
</div>
487487

488-
Instead of doing ORring the bitflags together yourself, you can use these and perhaps save some typing. The order of arguments maybe annoying to remember for some, and the amount of safety checking may be a bit excessive (gee, ya think?!?), but if the numbers you give them are constants the operations are done at compile time so that's okay, and sometimes they really can be helpful. Or not <span class="kbd">:P</span>. Like I said, I'm not forcing you to use them; if you think they're wretched pieces of code (and I admit they are) and don't want to taint your program with them, that's fine.
488+
Instead of doing ORring the bitflags together yourself, you can use these and perhaps save some typing. The order of arguments maybe annoying to remember for some, and the amount of safety checking may be a bit excessive (gee, ya think?!?), but if the numbers you give them are constants the operations are done at compile time so that's okay, and sometimes they really can be helpful. Or not <kbd>:P</kbd>. Like I said, I'm not forcing you to use them; if you think they're wretched pieces of code (and I admit they are) and don't want to taint your program with them, that's fine.
489489

490490
Note that with the exception of `bpp`, the arguments are all shifted by the macros, meaning that you should *not* use the `#define` flags from the lists, just small values like you'd use if they were separate variables rather than bits in a variable.
491491

@@ -684,11 +684,11 @@ The other step performed here is a call to `oam_init()`. This isn't strictly nec
684684

685685
The first thing to do (**point (1)**) is to store the sprite graphics in object VRAM. As I've already said a few times now, these graphics should be stored as 8×8-pixel tiles, not as a flat bitmap. For example, my sprite here is 64×64p in size, so to store it I've had to convert this to 8×8 separate tiles first. If you do *not* do this, your sprites will look very strange indeed.
686686

687-
Exactly where you put these tiles is actually not all that relevant (apart from the obvious, like mapping mode, and tile alignment, of course). Object VRAM works as a texture pool and has nothing to do with the screen directly. You store the tiles that you want to be available there, and it is by manipulating the OAM attributes that the system knows which tiles you want to use and where you want them. There is no reason why sprite 0 couldn't start at tile 42, or why multiple sprites couldn't use the same tiles. This is also why `OAMData`, which is sometimes used for object VRAM, is such a misnomer: object VRAM has nothing to do with OAM. *Nothing*! If your headers use this name for <span class="kbd">0601:0000</span>, or even <span class="kbd">0601:4000</span>, change it. Please. And be careful where you put things in the bitmap modes, as you can't use tiles 0-511 there.
687+
Exactly where you put these tiles is actually not all that relevant (apart from the obvious, like mapping mode, and tile alignment, of course). Object VRAM works as a texture pool and has nothing to do with the screen directly. You store the tiles that you want to be available there, and it is by manipulating the OAM attributes that the system knows which tiles you want to use and where you want them. There is no reason why sprite 0 couldn't start at tile 42, or why multiple sprites couldn't use the same tiles. This is also why `OAMData`, which is sometimes used for object VRAM, is such a misnomer: object VRAM has nothing to do with OAM. *Nothing*! If your headers use this name for <kbd>0601:0000</kbd>, or even <kbd>0601:4000</kbd>, change it. Please. And be careful where you put things in the bitmap modes, as you can't use tiles 0-511 there.
688688

689689
As I said, loading the sprites happens at **point (1)** in the code. If you paid attention to the [overview](objbg.html#ssec-img-cbb), you'll remember that `tile_mem[][]` is a two dimensional array, mapping charblocks and 4-bit tiles. You'll also remember that object VRAM is charblocks 4 and 5, so `&tile_mem[4][0]` points to the first tile in object VRAM. So I'm loading my boxed metroid into the first 64 tiles of object VRAM.
690690

691-
I am also loading its palette into the sprite palette. That's *sprite* palette (<span class="kbd">0500:0200</span>), not background palette. Load it to the wrong place and you won't see anything.
691+
I am also loading its palette into the sprite palette. That's *sprite* palette (<kbd>0500:0200</kbd>), not background palette. Load it to the wrong place and you won't see anything.
692692

693693
:::tip Finding tile addresses
694694

‎content/sndsqr.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ While the full range between 20 Hz and 20 kHz is audible, only a discrete set of
242242

243243
### Fourier transforms and the square wave {#ssec-fourier}
244244

245-
Fourier transformations are a way of going describing a function in the time domain as a distribution of frequencies called a <dfn>spectrum</dfn>. They're also one of the many ways that professors can scare the bejebus out of young, natural-science students. Don't worry, I'm sure you'll get through this section unscathed <span class="kbd">\>:)</span>. For well- to reasonably-behaved functions, you can rewrite them as series of *very* well-behaved functions such as polynomials, exponentials and also waves. For example, as a Fourier series, a function may look like {@eq:fser}.
245+
Fourier transformations are a way of going describing a function in the time domain as a distribution of frequencies called a <dfn>spectrum</dfn>. They're also one of the many ways that professors can scare the bejebus out of young, natural-science students. Don't worry, I'm sure you'll get through this section unscathed <kbd>\>:)</kbd>. For well- to reasonably-behaved functions, you can rewrite them as series of *very* well-behaved functions such as polynomials, exponentials and also waves. For example, as a Fourier series, a function may look like {@eq:fser}.
246246

247247
<!--
248248
f(x) = \frac{1}{2}A_0 + \sum_{n>0}A_m\cos(m{\omega}t) + \sum_{n>0}B_m\sin(m{\omega}t)
@@ -609,7 +609,7 @@ The register nomenclature seems particularly vexed when it comes to sound. There
609609

610610
“Oh great. This is going to be one of ‘tegel’ things isn't it? Where *you* think you've got something nice but different going, then later you revert to the standard terminology to conform with the rest of the world. Right?”
611611

612-
No, I'll stick to these names. Probably. Hopefully. … To be honest, I really don't know <span class="kbd">:P</span>. This is not really a big deal, though: you can easily switch between names with a few defines or search & replaces. Anyway, `REG_SNDxFREQ` contains frequency information and `REG_SNDxCNT` things like volume and envelope settings; in some cases, the bit layouts are even exactly the same. Apart from the sweep function of channel 1, it is exactly the same as channel 2.
612+
No, I'll stick to these names. Probably. Hopefully. … To be honest, I really don't know <kbd>:P</kbd>. This is not really a big deal, though: you can easily switch between names with a few defines or search & replaces. Anyway, `REG_SNDxFREQ` contains frequency information and `REG_SNDxCNT` things like volume and envelope settings; in some cases, the bit layouts are even exactly the same. Apart from the sweep function of channel 1, it is exactly the same as channel 2.
613613

614614
### Master sound registers {#ssec-snd-mstr}
615615

‎content/text.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ I could have stopped there, but the demo is actually just beginning. The thing a
855855

856856
#### Bouncy, bouncy, bouncy
857857

858-
The goal here is to let the letters drop from the top of the screen, the bounce up again when it hits a floor, but with a little less speed than before due to friction and what not. Physically, the falling part is done using a constant acceleration, _g_. Acceleration is the change in velocity, so the velocity is linear; velocity is the change in position, so the height is parabolic. At the bounce, we do an <dfn>inelastic collision</dfn>; in other words, one where energy is lost. In principle, this would mean that the difference between the squares of the velocities before and after the collision differ by a constant ( \|**v**~out~\|^2^ - \|**v**~in~\|^2^ = Q ). However, this would require a square root to find the new velocity, and I don't care for that right now so I'm just going to scrap the squares here. I'm sure there are situations where this is actually quite valid <kbd>:P</kbd>. As a further simplification, I'm doing a first-order integration for the position. With this, the basic code for movement becomes very simple
858+
The goal here is to let the letters drop from the top of the screen, the bounce up again when it hits a floor, but with a little less speed than before due to friction and what not. Physically, the falling part is done using a constant acceleration, _g_. Acceleration is the change in velocity, so the velocity is linear; velocity is the change in position, so the height is parabolic. At the bounce, we do an <dfn>inelastic collision</dfn>; in other words, one where energy is lost. In principle, this would mean that the difference between the squares of the velocities before and after the collision differ by a constant ( \|**v**<sub>out</sub>\|<sup>2</sup> - \|**v**<sub>in</sub>\|<sup>2</sup> = Q ). However, this would require a square root to find the new velocity, and I don't care for that right now so I'm just going to scrap the squares here. I'm sure there are situations where this is actually quite valid <kbd>:P</kbd>. As a further simplification, I'm doing a first-order integration for the position. With this, the basic code for movement becomes very simple
859859

860860
```c
861861
// 1D inelastic reflections

0 commit comments

Comments
 (0)
Please sign in to comment.