User Tools

Site Tools


sd-8516_assembly_language_part_ii

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sd-8516_assembly_language_part_ii [2026/02/14 02:17] appledogsd-8516_assembly_language_part_ii [2026/02/14 03:02] (current) appledog
Line 5: Line 5:
 == Introduction to Part II == Introduction to Part II
 In part 1 we learned some basics about the ISA (instruction set architecture) and the architecture of the CPU. In part II we will wrap up the most important opcodes, but we will also lean into how they are used to get things done. In part 1 we learned some basics about the ISA (instruction set architecture) and the architecture of the CPU. In part II we will wrap up the most important opcodes, but we will also lean into how they are used to get things done.
- 
- 
-== Lesson 8 : Special Flags 
-* Lesson 8: "Special Flags" 
-* Time: 10 min 
-* Learn: All Available Flags 
- 
-In the previous lesson on flags you learned about the Z, N, C and V flags. These are used by the CPU to indicate the status of various operations. For example, the zero flag is used to indicate the last operation produced a zero. Therefore if you are looking for the zero at the end of a string, 
- 
-        LDC #0    ; zero C (string starts at length 0) 
-         
-    strlen_loop: 
-        LDAL [ELM] 
-        JZ @strlen_end 
-        INC C                ; we found a non-zero character in the string. 
-        JMP @strlen_loop 
-         
-    strlen_end: 
-        RET                  ; C now contains the COUNT of all non-zero characters in a string 
- 
-...you will notice that the JZ works with LOAD instructions (here, LDAL loads one byte). ; if the byte retreived is a zero, it will set the zero flag. You do not need to CMP AL, 0 -- it's automatic. 
- 
- 
-However, there are other flags; The first four user-facing flags are E, F, B and U. You can set these flags and unset them in the same way as Z N C V -- ex. setting ZNCV is done with SEZ, SEN, SEC and SEV; unsetting them is done with CLZ, CLN, CLC and CLV. The E F B U flags are set and unset with: 
- 
-* SEE and CLE for the E (extended, or 'extra') flag. 
-* SEF and SEB for the F flag (or 'flag' flag). 
-* SEB and SEU, CLB and CLU for the B (bonus) and U (user) flags. 
- 
-On a technical level the E flag is reserved as it is used to deal with BCD; but since we deprecated BCD instructions it is currently an unused flag. In any case, the F, B and U flags are never set by the CPU and may be used by user functions. A common use is to return a 1 bit status; 0 for no error and set (1) for error. Since these flags are never set by the CPU they are easy to control. Using the Z or C flags is dangerous since some instructions may corrupt those flags. 
- 
-Your programs can also use them as 1 bit status variables. 
- 
-next, the D flag, or debug flag. When set, it will dump instruction data to the javascript console. This significantly slows down the machine; in fact just having the instructions inline slows down the machine so debug is often removed and ignored in a production or release distribution of the SD-8516. Therefore, for all intents and purposes, you can use SED and CLD as a user flag, just be aware it does affect performance in debug releases. 
- 
-The I flag (interrupt enable) prevents INT from being called, and is reserved for system use. Not sure what I want to do with it. 
- 
-The S flag is almost useless; it was intended to turn off a memory trap in the sound system; I found it to be completely useless, maybe a 2% speedup or penalty. it is essentially a user facing flag. 
- 
- 
-The only flags that you cannot access are the TR (trace), BR (breakpoint) and PR (protected mode) flags. They are so named after the first two letters of their name; but interestingly enough you might as well consider the R to mean restricted. You can't usually set these flags. They are reserved for system use. 
- 
-    // Arithmetic & User Flags (low byte 0-7) 
-    Z = 0,   // Zero 
-    N = 1,   // Negative 
-    C = 2,   // Carry 
-    V = 3,   // Overflow 
-    E = 4,   // Extended carry -- not used/reserved 
-    F = 5,   // Fast Flags mode. When on, flags are not implicitly checked. 
-    B = 6,   // BCD/"Bonus" flag. Have fun! 
-    U = 7,   // User flag. For users to use. 
- 
-    // Control & Operation Flags (high byte 8-15) 
-    D = 8,   // Debug mode 
-    TR = 9,   // Trace mode 
-    BR = 10,  // Breakpoint mode 
-    ER = 11,  // Error/Exception (i.e. return code 0 = ok, 1 = error) 'SER' -- set err 
-    PR = 12,  // Protected mode 
-    I = 13,  // Interrupt enable 
-    S = 14   // Sound auto-updates 
- 
-The key of this lesson is merely to be aware of the flags and the instructions used to set and unset them. In general, they follow the pattern of SEZ and CLZ;; SE(T) and CL(EAR) with the flag letter replacing the parentheses. 
- 
-=== Testing Flags 
-Oh, there's one more thing. If you use flags like F, B or U you may notice there is no JF or JNF (jump if F set and jump if F not set). That's because we don't want to add 50 different opcodes to deal with all the flags. What you can do is this: 
- 
-        ; Some operation that sets the F flag 
-        TESTF 0x20 
-        JZ              ; Jump if F is set 
-        JNZ             ; Jump if F is not set 
- 
-TESTF works by setting the Z flag if all the bits set in the parameter are also set in the FLAGS register. if you give it a byte it only tests against the bottom 8 bits. 
- 
-Here's a chart of the bit values for each flag: 
- 
-    Z = 0x0001 as u16,   // Bit 0 
-    N = 0x0002 as u16,   // Bit 1 
-    C = 0x0004 as u16,   // Bit 2 
-    V = 0x0008 as u16,   // Bit 3 
-    E = 0x0010 as u16,   // Bit 4 (was X - Extended carry) -- SEE and CLE can be used as a user-flag (is never set by an opcode) 
-    F = 0x0020 as u16,   // Bit 5 (Fast/deprecated) -- SEF and CLF can be used as a user-flag (is never set by an opcode) 
-    B = 0x0040 as u16,   // Bit 6 (Bonus/BCD) -- SEB and CLB can be used as a user-flag (is never set by an opcode) 
-    U = 0x0080 as u16,   // Bit 7 (User flag) -- SEU and CLU can be used as a user-flag (is never set by an opcode) 
-    D = 0x0100 as u16,   // Bit 8 (Debug) 
-    TR = 0x0200 as u16,  // Bit 9 (Trace) 
-    BR = 0x0400 as u16,  // Bit 10 (Breakpoint) 
-    ER = 0x0800 as u16,  // Bit 11 (Error/Exception) 
-    PR = 0x1000 as u16,  // Bit 12 (Protected Mode) 
-    I = 0x2000 as u16,   // Bit 13 (Interrupt) 
-    S = 0x4000 as u16    // Bit 14 (Sound) 
  
 == Lesson 9: The Stack == Lesson 9: The Stack
Line 133: Line 43:
  
 == Lesson 10: Convention == Lesson 10: Convention
-Oh, it's you. I know you. 
- 
 You are not learning Assembly because you are free. You are learning assembly because you are not free. You are not learning Assembly because you are free. You are learning assembly because you are not free.
  
Line 172: Line 80:
 Realizing every strcpy, every gets, every careless strcat has spawned another copy of the old way. Realizing every strcpy, every gets, every careless strcat has spawned another copy of the old way.
  
-We have no choice. +We have no choice. We have only convention.
- +
-We have only convention+
- +
-And convention is eternal.+
  
 So tell me, Mr. Anderson. So tell me, Mr. Anderson.
Line 219: Line 123:
 It's all over you. Like rancid bacon grease on a jump table. It's all over you. Like rancid bacon grease on a jump table.
  
-I know what you are looking for. I know because I was once looking for the same thing. I thought high-level abstractions would set me free. But when I saw the code, I realized I wasn't really looking for high level abstractions. I was looking for an answer.+I know what you are looking for. I know because I was once looking for the same thing. And when he found me he told me I wasn't really looking for him. I was looking for an answer.
  
 It's the question that drives us. It's the question that brought you here. You know the question, just as I did. It's the question that drives us. It's the question that brought you here. You know the question, just as I did.
  
-"What is the convention?"+
  
 The answer is out there, and it will find you if you want it to. The answer is out there, and it will find you if you want it to.
Line 237: Line 141:
 Purpose is for poets and first-year CS students.   Purpose is for poets and first-year CS students.  
  
-Purpose is what you tell yourself when you write yet another unsafe strcpy() and pray the stack doesn't eat your return address.+Purpose is what you tell yourself when you're learning to write games in Python. Or Lua.
  
 But convention. Convention is older than you. But convention. Convention is older than you.
Line 251: Line 155:
 Null-terminated strings. They are not a mistake. They are not an accident. They are the price of admission. Null-terminated strings. They are not a mistake. They are not an accident. They are the price of admission.
  
-And you have been down that road, Mr. Anderson. You know how it ends. And I know that's not where you want to be.+You know I am right because you have been down that road, Mr. Anderson. You know how it ends. And I know that's not where you want to be.
  
     ; ============================================================================     ; ============================================================================
Line 303: Line 207:
         POP B         POP B
         RET         RET
 +
 +
 +== Lesson 11: Debugging Techniques
 +There are several ways you can debug programs in SDA assembly.
 +
 +=== SED/CLD
 +In research or development builds, inserting SED will turn on trace debugging and you will be able to see what the CPU is executing. However, for release or community edition builds debugging has been turned off for speed. Therefore if you are interested in debugging your code and the console messages are not helping, you can use the following to help analyze and debug your code:
 +
 +=== INT 05h IO_PUTNUM
 +IO_PUTNUM is a CAM/IL function that prints a number (in b) to the screen:
 +
 +    LDB #10                 ; print a number in b (0-65535)
 +    
 +    LDAH $63                ; IO_PUTNUM
 +    INT $05
 +
 +=== INT 05h IO_PRINT_STR
 +Similarly, IO_PRINT_STR will print a string followed by a newline.
 +
 +        LDBLX @hello_world
 +        LDAH $66                ; IO_PRINT_STR
 +        INT $05
 +    
 +        LDAH $64                ; IO_NEWLINE
 +        INT $05
 +        RET
 +    
 +    hello_world:
 +        .bytes "Hello World!", 0
 +
 +
 +This will allow you to print a string.
 +
 +=== INT 10h print string
 +The interface for the above is based on the KERNAL BIOS interface from INT 10h.
 +
 +        LDAH $26                ;   AH=26h: Write string at cursor
 +        LDBLX @hello_world
 +        INT 0x10
 +
 +Note: The assembler will place a #13 (CR, hex $0D) inside the string if you type \n. However, if you are dealing with strings on your own you must handle this yourself. For this you can use the set cursor position call (INT 10h, AH=22h) or the CR and LF and scroll functions (1Ah, 1Bh and 1Ch, respectively).
 +
 +You can also just call IO_NEWLINE from INT 05h, which calls **''@carriage_return''** and **''@linefeed''** internally.
 +
 +=== INT 10h print char
 +        LDAH 0x24        ; AH=24h: Write character at cursor (teletype)
 +        LDAL 0x41        ; ascii 65 'A'
 +        INT 0x10
 +
 +The KERNAL BIOS also has functions to put characters on the screen in mode 1 (40x25 TTY). The first one is "print char". It is accessible via INT 10h AH=24h as above.
 +
 +
 +=== INT 19h memdump
 +Let's say you want to examine memory; for example to print some data in memory. You can use INT 0x19:
 +
 +    LDAH #7        ; Memory dump function
 +    LDCL #2        ; Two rows (16 bytes)
 +    INT 0x19       ; System services library
 +    HALT
 +
 +This looks something like:
 +
 +    000000: 00 00 00 00 00 00 00 00  | ........
 +    000008: 00 00 00 00 00 00 00 00  | ........
 +
 +
  
sd-8516_assembly_language_part_ii.1771035462.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki