sd:getting_stuff_done_in_assembly_language
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| sd:getting_stuff_done_in_assembly_language [2026/06/01 02:48] – appledog | sd:getting_stuff_done_in_assembly_language [2026/06/01 14:44] (current) – appledog | ||
|---|---|---|---|
| Line 123: | Line 123: | ||
| </ | </ | ||
| - | === Moving right along | + | === Random Numbers |
| - | We're not going to provide examples of other basic stuff too much, but we will show you this demo program | + | Random numbers are really useful. Here, we demonstrate the xorshift generator |
| <codify armasm> | <codify armasm> | ||
| + | ; Example 4: Random Numbers | ||
| + | |||
| .address $C000 | .address $C000 | ||
| Line 170: | Line 172: | ||
| ; ============================================================================ | ; ============================================================================ | ||
| - | ; AH=00h - Random Number | + | ; AH=00h - Random Number |
| ; Input: | ; Input: | ||
| - | ; Output: B = random 16-bit | + | ; Output: |
| - | ; Notes: | + | ; Notes: |
| - | ; | + | |
| ; ============================================================================ | ; ============================================================================ | ||
| Line 201: | Line 202: | ||
| ; ============================================================================ | ; ============================================================================ | ||
| - | == Terminal | + | === Putting It All Together: Menus |
| + | The engine for all these games we love such as Bard's Tale, Ulima, Nethack, King's quest, Alice in wonderland, Maniac Mansion, all were based on text engines. If the engine is good, a modicum of graphics will suffice. The big deal with retro games is that it's all about the gameplay, and the graphics serve the gameplay. What people miss in today' | ||
| + | |||
| + | The first thing you need to do is write some menus. Fundamentally printing the menus is easy, but you may wish to color the title of the menus, so you will need to learn how to do colored text. Also, you want to do input validation, so let's work on that too. | ||
| + | |||
| + | First, colored text. it's exactly the same as writing normal text, except you write a color byte. Here, i've added a special function to change the default color text is written in TTY mode. You can also set the color of text at an X and Y location, but that can become tedious because you have to do it character by character. | ||
| + | |||
| + | <codify armasm> | ||
| + | ; Example 5: Menus and Colored Text | ||
| + | |||
| + | .address $C000 | ||
| + | |||
| + | start: | ||
| + | ; Clear screen. | ||
| + | LDAH $10 | ||
| + | INT $10 | ||
| + | |||
| + | ; Set cursor position to X=0, Y=10. | ||
| + | LDX #0 | ||
| + | LDY #10 | ||
| + | LDAH $15 ; set cursor position | ||
| + | INT $10 | ||
| + | |||
| + | LDAH $50 ; Set teletype text default color | ||
| + | LDAL $2F ; color data in AL: BG=2, FG=F (here, orange) | ||
| + | INT $10 | ||
| + | |||
| + | LDBLX @str_menu_title | ||
| + | LDAH $66 ; BASIC IO_PUTSTRING | ||
| + | INT 0x05 | ||
| + | |||
| + | LDAH $50 ; Set teletype text default color | ||
| + | LDAL $29 ; color data default for mode 1 | ||
| + | INT $10 | ||
| + | |||
| + | LDBLX @str_menu | ||
| + | LDAH $66 ; BASIC IO_PUTSTRING | ||
| + | INT 0x05 | ||
| + | |||
| + | LDAH $02 ; blocking getkey | ||
| + | INT 0x10 | ||
| + | |||
| + | RET | ||
| + | |||
| + | |||
| + | str_menu_title: | ||
| + | | ||
| + | |||
| + | str_menu: | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | == Major Concept: The Cursor | ||
| Before we proceed, it's nice to be able to completely control the terminal. That means, instead of relying solely on PRINT and INPUT we have character level control. | Before we proceed, it's nice to be able to completely control the terminal. That means, instead of relying solely on PRINT and INPUT we have character level control. | ||
| Line 215: | Line 273: | ||
| <codify armasm> | <codify armasm> | ||
| + | ; Example 6: The Cursor | ||
| + | |||
| .address $C000 | .address $C000 | ||
| Line 262: | Line 322: | ||
| </ | </ | ||
| - | == Writing the game engine | + | === Keeping Track Yourself |
| - | The engine for all these games we love such as Bard's Tale, Ulima, Nethack, King's quest, Alice in wonderland, Maniac Mansion, all were based on text engines. If the engine is good, a modicum of graphics will suffice. The big deal with retro games is that it's all about the gameplay, and the graphics serve the gameplay. What people miss in today' | + | In a game, you don't really need the cursor. So instead of using a teletyle print function and calling INT $10, AH=$16, you can just give the values you want for your game screen. Here' |
| - | === Menus | + | <codify armasm> |
| - | The first thing you need to do is write some menus. Fundamentally printing the menus is easy, but you may wish to color the title of the menus, so you will need to learn how to do colored text. Also, you want to do input validation, so let's work on that too. | + | ; Example 7: put_ccxy |
| - | First, colored text. it's exactly the same as writing normal text, except you write a color byte. Here, i've added a special function to change the default color text is written in TTY mode. You can also set the color of text at an X and Y location, but that can become tedious because you have to do it character by character. | ||
| - | |||
| - | <codify armasm> | ||
| .address $C000 | .address $C000 | ||
| start: | start: | ||
| - | ; Clear screen. | ||
| - | LDAH $10 | ||
| - | INT $10 | ||
| - | |||
| - | ; Set cursor position to X=0, Y=10. | ||
| LDX #0 | LDX #0 | ||
| LDY #10 | LDY #10 | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| + | |||
| + | ; put_ccxy(B, X, Y, C) | ||
| + | ; Put Character and Color at X, T | ||
| + | ; INPUT: | ||
| + | ; B -- ascii code | ||
| + | ; X -- x location on screen | ||
| + | ; Y -- y location on screen | ||
| + | ; C -- hi nibble (BG) and low niblle | ||
| + | ; | ||
| + | put_ccxy: | ||
| + | ; Write character in AL at X, Y | ||
| + | LDAH $11 | ||
| INT $10 | INT $10 | ||
| - | | + | |
| - | LDAH $66 ; | + | ; Input: |
| - | INT 0x05 | + | LDAH $13 |
| - | + | ||
| - | LDAH $50 | + | |
| - | LDAL $29 ; color data default for mode 1 | + | |
| INT $10 | INT $10 | ||
| - | |||
| - | LDBLX @str_menu | ||
| - | LDAH $66 ; BASIC IO_PUTSTRING | ||
| - | INT 0x05 | ||
| - | |||
| - | LDAH $02 ; blocking getkey | ||
| - | INT 0x10 | ||
| RET | RET | ||
| - | |||
| - | |||
| - | str_menu_title: | ||
| - | | ||
| - | |||
| - | str_menu: | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| - | | ||
| </ | </ | ||
| Line 345: | Line 387: | ||
| <codify armasm> | <codify armasm> | ||
| + | ; Example 8: DEFCHAR | ||
| + | |||
| .address $C000 | .address $C000 | ||
| Line 365: | Line 409: | ||
| .bytes " | .bytes " | ||
| .bytes " | .bytes " | ||
| + | </ | ||
| + | |||
| + | Unfortunately, | ||
| + | |||
| + | === Using this concept in Mode 3 | ||
| + | Now, interestingly enough, you can translate this graphics technique directly into Mode 3. First, let's adapt BASIC' | ||
| + | |||
| + | ; ---------------------------------------------------------------------------- | ||
| + | ; AH=61h -- stamp_char -- render a glyph onto mode-3, transparent background | ||
| + | ; | ||
| + | ; | ||
| + | ; | ||
| + | ; CL = foreground color (only looks at low nibble) | ||
| + | ; | ||
| + | ; glyph source = VM1_CHAR_ROM ($01E000) | ||
| + | ; ---------------------------------------------------------------------------- | ||
| + | |||
| + | We'll toss in some fancy arrow key movement and a q for quit key, to spice things up: | ||
| + | |||
| + | <codify armasm> | ||
| + | ; Example 9: stamp_char | ||
| + | |||
| + | .address $C000 | ||
| + | |||
| + | start: | ||
| + | ; Switch to mode 3 | ||
| + | LDA $4003 ; 40h = set mode, 3 = mode 3 | ||
| + | INT $10 | ||
| + | |||
| + | ; Clear screen | ||
| + | LDAH $20 | ||
| + | INT $10 | ||
| + | |||
| + | LDX #0 | ||
| + | LDY #0 | ||
| + | |||
| + | loop: | ||
| + | ; draw an ' | ||
| + | LDAL #' | ||
| + | LDAH $61 ; stamp char | ||
| + | LDC #9 ; dark blue | ||
| + | INT $18 | ||
| + | |||
| + | LDAH $02 ; blocking getkey | ||
| + | INT 0x10 | ||
| + | |||
| + | LDAH $60 ; erase char | ||
| + | LDC #0 ; black background | ||
| + | INT $18 | ||
| + | |||
| + | CMP AL, #' | ||
| + | JZ @exit | ||
| + | CMP AL, #' | ||
| + | JZ @exit | ||
| + | |||
| + | CMP AL, #128 | ||
| + | JZ @move_left | ||
| + | CMP AL, #129 | ||
| + | JZ @move_down | ||
| + | CMP AL, #130 | ||
| + | JZ @move_up | ||
| + | CMP AL, #131 | ||
| + | JZ @move_right | ||
| + | |||
| + | JMP @loop | ||
| + | |||
| + | move_left: | ||
| + | DEC X | ||
| + | DEC X | ||
| + | JNN @loop ; if X didn't go negative, just continue. | ||
| + | |||
| + | LDX #0 ; Don't allow X to go below 0. | ||
| + | JMP @loop | ||
| + | |||
| + | move_right: | ||
| + | INC X | ||
| + | INC X | ||
| + | CMP X, #312 | ||
| + | JNC @loop | ||
| + | |||
| + | ; C is set if X was >= 312 | ||
| + | LDX #311 | ||
| + | JMP @loop | ||
| + | |||
| + | |||
| + | move_up: | ||
| + | DEC Y | ||
| + | DEC Y | ||
| + | JNN @loop ; if Y didn't go negative, just continue. | ||
| + | |||
| + | LDY #0 | ||
| + | JMP @loop | ||
| + | |||
| + | move_down: | ||
| + | INC Y | ||
| + | INC Y | ||
| + | CMP Y, #191 | ||
| + | JNC @loop | ||
| + | |||
| + | LDY #191 | ||
| + | JMP @loop | ||
| + | |||
| + | exit: | ||
| + | ; Switch back to mode 1 | ||
| + | LDA $4001 | ||
| + | INT $10 | ||
| + | RET | ||
| + | </ | ||
| + | |||
| + | === Multi-Color Character Graphics in Mode 3 | ||
| + | The way to do multicolor graphics is to use different tiles for each color component. For example, you can have one tile with the blue pixels and the other tile with the yellow pixels. When you draw the tiles on top of each other, it will produce a multicolor effect. | ||
| + | |||
| + | == Music | ||
| + | Randomly, in the middle of nowhere, we will explain to you; yes, you can play music in your game. Our PLAY statement is multi-voice; | ||
| + | |||
| + | <codify BASIC> | ||
| + | 10 PLAY "XV1 MN W5 XP3000 O4 L4 T180" | ||
| + | 15 PLAY "XV2 MN W5 XP3500 O3 L4 T180" | ||
| + | 20 PLAY "XV1 F1" | ||
| + | 25 PLAY "XV2 R1" | ||
| + | 30 PLAY "XV1 A4. B-8 > C4 C4 <" | ||
| + | 35 PLAY "XV2 R1" | ||
| + | 40 PLAY "XV1 B-4 A4 G4 F4" | ||
| + | 45 PLAY "XV2 R1" | ||
| + | 50 PLAY "XV1 > C2 C4. C8 <" | ||
| + | 55 PLAY "XV2 R2 F4. F8" | ||
| + | 60 PLAY "XV1 > C4 D2 C4 <" | ||
| + | 65 PLAY "XV2 F4 < B-2 A4" | ||
| + | 70 PLAY "XV1 B-4 A4 G4 G4" | ||
| + | 75 PLAY "XV2 B-4 F4 > C4 C4" | ||
| + | 80 PLAY "XV1 A1" | ||
| + | 85 PLAY "XV2 < F1" | ||
| + | </ | ||
| + | |||
| + | Now you may wonder, why incorporate a BASIC example? Here, we can use BASIC to quickly test musical ideas. When it's time to put them into a game, we do this: | ||
| + | |||
| + | <codify armasm> | ||
| + | ; Example 10: Music | ||
| + | |||
| + | .address $C000 | ||
| + | |||
| + | LDELM @fair_phyllis | ||
| + | LDAH $52 ; Play Song | ||
| + | INT $11 | ||
| + | RET | ||
| + | |||
| + | fair_phyllis: | ||
| + | .bytes "XV1 MN W5 XP3000 O4 L4 T180" | ||
| + | .bytes "XV2 MN W5 XP3500 O3 L4 T180" | ||
| + | .bytes "XV1 F1 " | ||
| + | .bytes "XV2 R1 " | ||
| + | .bytes "XV1 A4. B-8 > C4 C4 < " | ||
| + | .bytes "XV2 R1 " | ||
| + | .bytes "XV1 B-4 A4 G4 F4 " | ||
| + | .bytes "XV2 R1 " | ||
| + | .bytes "XV1 > C2 C4. C8 < " | ||
| + | .bytes "XV2 R2 F4. F8 " | ||
| + | .bytes "XV1 > C4 D2 C4 < " | ||
| + | .bytes "XV2 F4 < B-2 A4 " | ||
| + | .bytes "XV1 B-4 A4 G4 G4 " | ||
| + | .bytes "XV2 B-4 F4 > C4 C4 " | ||
| + | .bytes "XV1 A1 " | ||
| + | .bytes "XV2 < F1", 0 | ||
| </ | </ | ||
sd/getting_stuff_done_in_assembly_language.1780282132.txt.gz · Last modified: by appledog
