@nataliapc/mcp-openmsx 1.2.10 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/chunker.js +187 -0
- package/dist/embedder.js +250 -0
- package/dist/server.js +6 -1
- package/dist/server_tools.js +6 -5
- package/dist/vectordb.js +94 -35
- package/package.json +4 -8
- package/resources/audio/chipsfmpacpr1_en.md +209 -0
- package/resources/audio/chipsfmpacpr2_en.md +170 -0
- package/resources/audio/toc.json +12 -0
- package/resources/book--msx-top-secret-3/MTS3-Appendix-English-Upd2.pdf +0 -0
- package/resources/book--msx-top-secret-3/MTS3-Complete-English.pdf +0 -0
- package/resources/book--msx-top-secret-3/mts3-appendix-english-upd2.md +25863 -0
- package/resources/book--msx-top-secret-3/mts3-complete-english.md +44895 -0
- package/resources/book--msx2-technical-handbook/toc.json +1 -1
- package/resources/book--the-msx-red-book/Chapter1_Programmable_Peripheral_Interface.md +112 -0
- package/resources/book--the-msx-red-book/Chapter2_Video_Display_Processor.md +308 -0
- package/resources/book--the-msx-red-book/Chapter3_Programmable_Sound_Generator.md +168 -0
- package/resources/book--the-msx-red-book/Chapter4_ROM_BIOS.md +2528 -0
- package/resources/book--the-msx-red-book/Chapter5_ROM_BASIC_Interpreter.md +3975 -0
- package/resources/book--the-msx-red-book/Chapter6_Memory_Map.md +1963 -0
- package/resources/book--the-msx-red-book/Chapter7_Machine_Code_Programs.md +1238 -0
- package/resources/book--the-msx-red-book/Introduction.md +104 -0
- package/resources/book--the-msx-red-book/toc.json +38 -3
- package/resources/processors/toc.json +3 -3
- package/resources/processors/z80-undocumented.md +141 -0
- package/resources/programming/asm_develop_a_program_in_cartridge_rom.md +1881 -0
- package/resources/programming/toc.json +6 -0
- package/resources/sdcc/1_Introduction.md +199 -0
- package/resources/sdcc/2_Installing_SDCC.md +533 -0
- package/resources/sdcc/3_Using_SDCC.md +1758 -0
- package/resources/sdcc/4_Notes_on_supported_Processors.md +1638 -0
- package/resources/sdcc/5_Debugging.md +210 -0
- package/resources/sdcc/6_Tips_and_Support.md +258 -0
- package/resources/sdcc/7_SDCC_Technical_Data.md +489 -0
- package/resources/sdcc/8_Compiler_internals.md +477 -0
- package/resources/sdcc/toc.json +44 -2
- package/resources/system/how_to_detect_ram.md +14 -0
- package/resources/system/mrc_wiki_megarom_mappers.md +533 -0
- package/resources/system/the_memory.md +118 -0
- package/resources/system/toc.json +18 -0
- package/vector-db/__manifest/_transactions/0-675ee228-bffb-4636-80e5-cdfde25cc4fe.txn +2 -0
- package/vector-db/__manifest/_versions/18446744073709551614.manifest +0 -0
- package/vector-db/__manifest/_versions/latest_version_hint.json +1 -0
- package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/metadata.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_docs.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_invert.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_tokens.lance +0 -0
- package/vector-db/msxdocs.lance/_transactions/0-dd155672-40e6-4c6a-942f-7fcbe8c3dbd0.txn +0 -0
- package/vector-db/msxdocs.lance/_transactions/1-e7230cbd-ce8e-465c-9b85-b91443862427.txn +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551613.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551614.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/latest_version_hint.json +1 -0
- package/vector-db/msxdocs.lance/data/000100110110001011110001fc578141d296825d0bea11c95d.lance +0 -0
- package/resources/book--the-msx-red-book/the_msx_red_book.md +0 -10349
- package/resources/processors/z80-undocumented.tex +0 -5617
- package/resources/sdcc/lyx2md.py +0 -745
- package/resources/sdcc/sdccman.lyx +0 -81574
- package/resources/sdcc/sdccman.md +0 -5557
- package/vector-db/index.json +0 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# SDCC Compiler User Guide
|
|
2
|
+
|
|
3
|
+
## Compiler internals
|
|
4
|
+
|
|
5
|
+
### The anatomy of the compiler
|
|
6
|
+
|
|
7
|
+
*This is an excerpt from an article published in Circuit Cellar Magazine inAugust 2000**. It's outdated (the compiler is much more efficient now and user/developer friendly), but pretty well exposes the guts of it all.*
|
|
8
|
+
|
|
9
|
+
The current version of SDCC can generate code for Intel 8051 and Z80 MCU. It is fairly easy to retarget for other 8-bit MCU. Here we take a look at some of the internals of the compiler.
|
|
10
|
+
|
|
11
|
+
Parsing Parsing
|
|
12
|
+
|
|
13
|
+
Parsing the input source file and creating an AST (Annotated Syntax Tree Annotated syntax tree). This phase also involves propagating types (annotating each node of the parse tree with type information) and semantic analysis. There are some MCU specific parsing rules. For example the intrinsic named address spaces are MCU specific: While there may be an __xdata intrinsic named address space for 8051 there none for z80. SDCC has MCU specific intrinsic named address spacess, i.e. __xdata will be treated as a named address space when parsing 8051 C code but will be treated as a C identifier when parsing z80 code.
|
|
14
|
+
|
|
15
|
+
Generating iCode iCode
|
|
16
|
+
|
|
17
|
+
Intermediate code generation. In this phase the AST is broken down into three-operand form (iCode). These three operand forms are represented as doubly linked lists. ICode is the term given to the intermediate form generated by the compiler. ICode example section shows some examples of iCode generated for some simple C source functions.
|
|
18
|
+
|
|
19
|
+
Optimizations Optimizations.
|
|
20
|
+
|
|
21
|
+
Bulk of the target independent optimizations is performed in this phase. The optimizations include constant propagation, common sub-expression elimination, loop invariant code movement, strength reduction of loop induction variables and dead-code elimination.
|
|
22
|
+
|
|
23
|
+
Live range analysis Live range analysis
|
|
24
|
+
|
|
25
|
+
During intermediate code generation phase, the compiler assumes the target machine has infinite number of registers and generates a lot of temporary variables. The live range computation determines the lifetime of each of these compiler-generated temporaries. A picture speaks a thousand words. ICode example sections show the live range annotations for each of the operand. It is important to note here, each iCode is assigned a number in the order of its execution in the function. The live ranges are computed in terms of these numbers. The from number is the number of the iCode which first defines the operand and the to number signifies the iCode which uses this operand last.
|
|
26
|
+
|
|
27
|
+
Register Allocation Register allocation
|
|
28
|
+
|
|
29
|
+
The register allocation determines the type and number of registers needed by each operand. In most MCUs only a few registers can be used for indirect addressing. In case of 8051 for example the registers R0 & R1 can be used to indirectly address the internal ram and DPTR to indirectly address the external ram. The compiler will try to allocate the appropriate register to pointer variables if it can. ICode example section shows the operands annotated with the registers assigned to them. The compiler will try to keep operands in registers as much as possible; there are several schemes the compiler uses to do achieve this. When the compiler runs out of registers the compiler will check to see if there are any live operands which is not used or defined in the current basic block being processed, if there are any found then it will push that operand and use the registers in this block, the operand will then be popped at the end of the basic block.
|
|
30
|
+
|
|
31
|
+
There are other MCU specific considerations in this phase. Some MCUs have an accumulator; very short-lived operands could be assigned to the accumulator instead of a general-purpose register.
|
|
32
|
+
|
|
33
|
+
Code generation
|
|
34
|
+
|
|
35
|
+
Figure II gives a table of iCode iCode operations supported by the compiler. The code generation involves translating these operations into corresponding assembly code for the processor. This sounds overly simple but that is the essence of code generation. Some of the iCode operations are generated on a MCU specific manner for example, the z80 port does not use registers to pass parameters so the SEND and RECV iCode operations will not be generated, and it also does not support JUMPTABLES.
|
|
36
|
+
|
|
37
|
+
Figure II
|
|
38
|
+
|
|
39
|
+
| iCode status collapsed iCode | Operands | Description | C Equivalent |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| '!' | IC_LEFT() IC_RESULT() | NOT operation | IC_RESULT =! IC_LEFT; |
|
|
42
|
+
| '~' | IC_LEFT() IC_RESULT() | Bitwise complement of | IC_RESULT = ~IC_LEFT; |
|
|
43
|
+
| ROT | IC_LEFT() IC_RIGHT() IC_RESULT() | Rotate | IC_RESULT = (IC_LEFT << IC_RIGHT) | (IC_LEFT >> (sizeof(IC_LEFT)*8-IC_RIGHT)); |
|
|
44
|
+
| UNARYMINUS | IC_LEFT() IC_RESULT() | Unary minus | IC_RESULT = - IC_LEFT; |
|
|
45
|
+
| IPUSH | IC_LEFT() | Push the operand onto stack | NONE |
|
|
46
|
+
| IPOP | IC_LEFT() | Pop the operand from the stack | NONE |
|
|
47
|
+
| CALL | IC_LEFT() IC_RESULT() | Call the function represented by IC_LEFT | IC_RESULT = IC_LEFT(); |
|
|
48
|
+
| PCALL | IC_LEFT() IC_RESULT() | Call via function pointer | IC_RESULT = (*IC_LEFT)(); |
|
|
49
|
+
| RETURN | IC_LEFT() | Return the value in operand IC_LEFT | return IC_LEFT; |
|
|
50
|
+
| LABEL | IC_LABEL() | Label | IC_LABEL: |
|
|
51
|
+
| GOTO | IC_LABEL() | Goto label | goto IC_LABEL(); |
|
|
52
|
+
| '+' | IC_LEFT() IC_RIGHT() IC_RESULT() | Addition | IC_RESULT = IC_LEFT + IC_RIGHT |
|
|
53
|
+
| '-' | IC_LEFT() IC_RIGHT() IC_RESULT() | Subtraction | IC_RESULT = IC_LEFT - IC_RIGHT |
|
|
54
|
+
| '*' | IC_LEFT() IC_RIGHT() IC_RESULT() | Multiplication | IC_RESULT = IC_LEFT * IC_RIGHT; |
|
|
55
|
+
| '/' | IC_LEFT() IC_RIGHT() IC_RESULT() | Division | IC_RESULT = IC_LEFT / IC_RIGHT; |
|
|
56
|
+
| '%' | IC_LEFT() IC_RIGHT() IC_RESULT() | Modulus | IC_RESULT = IC_LEFT % IC_RIGHT; |
|
|
57
|
+
| '<' | IC_LEFT() IC_RIGHT() IC_RESULT() | Less than | IC_RESULT = IC_LEFT < IC_RIGHT; |
|
|
58
|
+
| '>' | IC_LEFT() IC_RIGHT() IC_RESULT() | Greater than | IC_RESULT = IC_LEFT > IC_RIGHT; |
|
|
59
|
+
| EQ_OP | IC_LEFT() IC_RIGHT() IC_RESULT() | Equal to | IC_RESULT = IC_LEFT == IC_RIGHT; |
|
|
60
|
+
| AND_OP | IC_LEFT() IC_RIGHT() IC_RESULT() | Logical and operation | IC_RESULT = IC_LEFT && IC_RIGHT; |
|
|
61
|
+
| OR_OP | IC_LEFT() IC_RIGHT() IC_RESULT() | Logical or operation | IC_RESULT = IC_LEFT || IC_RIGHT; |
|
|
62
|
+
| '^' | IC_LEFT() IC_RIGHT() IC_RESULT() | Exclusive OR | IC_RESULT = IC_LEFT ^ IC_RIGHT; |
|
|
63
|
+
| '|' | IC_LEFT() IC_RIGHT() IC_RESULT() | Bitwise OR | IC_RESULT = IC_LEFT | IC_RIGHT; |
|
|
64
|
+
| BITWISEAND | IC_LEFT() IC_RIGHT() IC_RESULT() | Bitwise AND | IC_RESULT = IC_LEFT & IC_RIGHT; |
|
|
65
|
+
| LEFT_OP | IC_LEFT() IC_RIGHT() IC_RESULT() | Left shift | IC_RESULT = IC_LEFT << IC_RIGHT |
|
|
66
|
+
| RIGHT_OP | IC_LEFT() IC_RIGHT() IC_RESULT() | Right shift | IC_RESULT = IC_LEFT >> IC_RIGHT |
|
|
67
|
+
| GET_VALUE_ AT_ ADDRESS | IC_LEFT() IC_RESULT() | Indirect fetch | IC_RESULT = (*IC_LEFT); |
|
|
68
|
+
| POINTER_SET | IC_RIGHT() IC_RESULT() | Indirect set | (*IC_RESULT) = IC_RIGHT; |
|
|
69
|
+
| '=' | IC_RIGHT() IC_RESULT() | Assignment | IC_RESULT = IC_RIGHT; |
|
|
70
|
+
| IFX | IC_COND IC_TRUE IC_LABEL | Conditional jump. If true label is present then jump to true label if condition is true else jump to false label if condition is false | if (IC_COND) goto IC_TRUE; Or If (!IC_COND) goto IC_FALSE; |
|
|
71
|
+
| ADDRESS_OF | IC_LEFT() IC_RESULT() | Address of | IC_RESULT = &IC_LEFT(); |
|
|
72
|
+
| JUMPTABLE | IC_JTCOND IC_JTLABELS | Jump to list of labels depending on the value of JTCOND | Switch statement |
|
|
73
|
+
| CAST | IC_RIGHT() IC_LEFT() IC_RESULT() | Cast types | IC_RESULT = (typeof IC_LEFT) IC_RIGHT; |
|
|
74
|
+
| SEND | IC_LEFT() | This is used for passing parameters in registers; move IC_LEFT to the next available parameter register. | None |
|
|
75
|
+
| RECV | IC_RESULT() | This is used for receiving parameters passed in registers; Move the values in the next parameter register to IC_RESULT | None |
|
|
76
|
+
| (some more have been added) | | | see f.e. gen51Code() in src/mcs51/gen.c |
|
|
77
|
+
| (some more have been added) | | | see f.e. gen51Code() in src/mcs51/gen.c |
|
|
78
|
+
|
|
79
|
+
In the original article Figure II was announced to be downloadable on *Circuit Cellar* 's web site. ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2000/121/dutta.ZIP
|
|
80
|
+
|
|
81
|
+
ICode Example iCode
|
|
82
|
+
|
|
83
|
+
This section shows some details of iCode. The example C code does not do anything useful; it is used as an example to illustrate the intermediate code generated by the compiler.
|
|
84
|
+
|
|
85
|
+
1. __xdata int * p;
|
|
86
|
+
2. int gint;
|
|
87
|
+
3. /* This function does nothing useful. It is used
|
|
88
|
+
4. for the purpose of explaining iCode */
|
|
89
|
+
5. short function (__data int *x)
|
|
90
|
+
6. {
|
|
91
|
+
7. short i=10; /* dead initialization eliminated */
|
|
92
|
+
8. short sum=10; /* dead initialization eliminated */
|
|
93
|
+
9. short mul;
|
|
94
|
+
10. int j;
|
|
95
|
+
11. while (*x) *x++ = *p++;
|
|
96
|
+
12. sum = 0;
|
|
97
|
+
13. mul = 0;
|
|
98
|
+
14. /* compiler detects i,j to be induction variables */
|
|
99
|
+
15. for (i = 0, j = 10; i < 10; i++, j--) {
|
|
100
|
+
16. sum += i;
|
|
101
|
+
17. mul += i * 3; /* this multiplication remains */
|
|
102
|
+
18. gint += j * 3; /* this multiplication changed to addition */
|
|
103
|
+
19. }
|
|
104
|
+
20. return sum+mul;
|
|
105
|
+
21. }
|
|
106
|
+
|
|
107
|
+
In addition to the operands each iCode contains information about the filename and line it corresponds to in the source file. The first field in the listing should be interpreted as follows:
|
|
108
|
+
*Filename(linenumber: iCode Execution sequence number: ICode hash table key: loop depth of the iCode).*
|
|
109
|
+
Then follows the human readable form of the ICode operation. Each operand of this triplet form can be of three basic types a) compiler generated temporary b) user defined variable c) a constant value. Note that local variables and parameters are replaced by compiler generated temporaries. Live ranges Live range analysis are computed only for temporaries (i.e. live ranges are not computed for global variables). Registers Register allocation are allocated for temporaries only. Operands are formatted in the following manner:
|
|
110
|
+
*Operand Name [lr live-from: live-to] { type information } [registers allocated].*
|
|
111
|
+
As mentioned earlier the live ranges are computed in terms of the execution sequence number of the iCodes, for example
|
|
112
|
+
the iTemp0 is live from (i.e. first defined in iCode with execution sequence number 3, and is last used in the iCode with sequence number 5). For induction variables such as iTemp21 the live range computation extends the lifetime from the start to the end of the loop.
|
|
113
|
+
The register allocator used the live range information to allocate registers, the same registers may be used for different temporaries if their live ranges do not overlap, for example r0 is allocated to both iTemp6 and to iTemp17 since their live ranges do not overlap. In addition the allocator also takes into consideration the type and usage of a temporary, for example itemp6 is a pointer to near space and is used as to fetch data from (i.e. used in GET_VALUE_AT_ADDRESS) so it is allocated a pointer register (r0). Some short lived temporaries are allocated to special registers which have meaning to the code generator e.g. iTemp13 is allocated to a pseudo register CC which tells the back end that the temporary is used only for a conditional jump the code generation makes use of this information to optimize a compare and jump ICode.
|
|
114
|
+
There are several loop optimizations Loop optimization performed by the compiler. It can detect induction variables iTemp21(i) and iTemp23(j). Also note the compiler does selective strength reduction Strength reduction, i.e. the multiplication of an induction variable in line 18 (gint = j * 3) is changed to addition, a new temporary iTemp17 is allocated and assigned a initial value, a constant 3 is then added for each iteration of the loop. The compiler does not change the multiplication Multiplication in line 17 however since the processor does support an 8 * 8 bit multiplication.
|
|
115
|
+
Note the dead code elimination Dead-code elimination optimization eliminated the dead assignments in line 7 & 8 to I and sum respectively.
|
|
116
|
+
|
|
117
|
+
Sample.c (5:1:0:0) _entry($9):
|
|
118
|
+
|
|
119
|
+
Sample.c(5:2:1:0) proc _function [lr0:0]{function short}
|
|
120
|
+
|
|
121
|
+
Sample.c(11:3:2:0) iTemp0 [lr3:5]{_near * int}[r2] = recv
|
|
122
|
+
|
|
123
|
+
Sample.c(11:4:53:0) preHeaderLbl0($11):
|
|
124
|
+
|
|
125
|
+
Sample.c(11:5:55:0) iTemp6 [lr5:16]{_near * int}[r0]:= iTemp0 [lr3:5]{_near * int}[r2]
|
|
126
|
+
|
|
127
|
+
Sample.c(11:6:5:1) _whilecontinue_0($1):
|
|
128
|
+
|
|
129
|
+
Sample.c(11:7:7:1) iTemp4 [lr7:8]{int}[r2 r3] = @[iTemp6 [lr5:16]{_near * int}[r0]]
|
|
130
|
+
|
|
131
|
+
Sample.c(11:8:8:1) if iTemp4 [lr7:8]{int}[r2 r3] == 0 goto _whilebreak_0($3)
|
|
132
|
+
|
|
133
|
+
Sample.c(11:9:14:1) iTemp7 [lr9:13]{_far * int}[DPTR]:= _p [lr0:0]{_far * int}
|
|
134
|
+
|
|
135
|
+
Sample.c(11:10:15:1) _p [lr0:0]{_far * int} = _p [lr0:0]{_far * int} + 0x2 {short}
|
|
136
|
+
|
|
137
|
+
Sample.c(11:13:18:1) iTemp10 [lr13:14]{int}[r2 r3] = @[iTemp7 [lr9:13]{_far * int}[DPTR]]
|
|
138
|
+
|
|
139
|
+
Sample.c(11:14:19:1) *(iTemp6 [lr5:16]{_near * int}[r0]):= iTemp10 [lr13:14]{int}[r2 r3]
|
|
140
|
+
|
|
141
|
+
Sample.c(11:15:12:1) iTemp6 [lr5:16]{_near * int}[r0] = iTemp6 [lr5:16]{_near * int}[r0] + 0x2 {short}
|
|
142
|
+
|
|
143
|
+
Sample.c(11:16:20:1) goto _whilecontinue_0($1)
|
|
144
|
+
|
|
145
|
+
Sample.c(11:17:21:0)_whilebreak_0($3):
|
|
146
|
+
|
|
147
|
+
Sample.c(12:18:22:0) iTemp2 [lr18:40]{short}[r2]:= 0x0 {short}
|
|
148
|
+
|
|
149
|
+
Sample.c(13:19:23:0) iTemp11 [lr19:40]{short}[r3]:= 0x0 {short}
|
|
150
|
+
|
|
151
|
+
Sample.c(15:20:54:0)preHeaderLbl1($13):
|
|
152
|
+
|
|
153
|
+
Sample.c(15:21:56:0) iTemp21 [lr21:38]{short}[r4]:= 0x0 {short}
|
|
154
|
+
|
|
155
|
+
Sample.c(15:22:57:0) iTemp23 [lr22:38]{int}[r5 r6]:= 0xa {int}
|
|
156
|
+
|
|
157
|
+
Sample.c(15:23:58:0) iTemp17 [lr23:38]{int}[r7 r0]:= 0x1e {int}
|
|
158
|
+
|
|
159
|
+
Sample.c(15:24:26:1)_forcond_0($4):
|
|
160
|
+
|
|
161
|
+
Sample.c(15:25:27:1) iTemp13 [lr25:26]{char}[CC] = iTemp21 [lr21:38]{short}[r4] < 0xa {short}
|
|
162
|
+
|
|
163
|
+
Sample.c(15:26:28:1) if iTemp13 [lr25:26]{char}[CC] == 0 goto _forbreak_0($7)
|
|
164
|
+
|
|
165
|
+
Sample.c(16:27:31:1) iTemp2 [lr18:40]{short}[r2] = iTemp2 [lr18:40]{short}[r2] + ITemp21 [lr21:38]{short}[r4]
|
|
166
|
+
|
|
167
|
+
Sample.c(17:29:33:1) iTemp15 [lr29:30]{short}[r1] = iTemp21 [lr21:38]{short}[r4] * 0x3 {short}
|
|
168
|
+
|
|
169
|
+
Sample.c(17:30:34:1) iTemp11 [lr19:40]{short}[r3] = iTemp11 [lr19:40]{short}[r3] + iTemp15 [lr29:30]{short}[r1]
|
|
170
|
+
|
|
171
|
+
Sample.c(18:32:36:1:1) iTemp17 [lr23:38]{int}[r7 r0]= iTemp17 [lr23:38]{int}[r7 r0]- 0x3 {short}
|
|
172
|
+
|
|
173
|
+
Sample.c(18:33:37:1) _gint [lr0:0]{int} = _gint [lr0:0]{int} + iTemp17 [lr23:38]{int}[r7 r0]
|
|
174
|
+
|
|
175
|
+
Sample.c(15:36:42:1) iTemp21 [lr21:38]{short}[r4] = iTemp21 [lr21:38]{short}[r4] + 0x1 {short}
|
|
176
|
+
|
|
177
|
+
Sample.c(15:37:45:1) iTemp23 [lr22:38]{int}[r5 r6]= iTemp23 [lr22:38]{int}[r5 r6]- 0x1 {short}
|
|
178
|
+
|
|
179
|
+
Sample.c(19:38:47:1) goto _forcond_0($4)
|
|
180
|
+
|
|
181
|
+
Sample.c(19:39:48:0)_forbreak_0($7):
|
|
182
|
+
|
|
183
|
+
Sample.c(20:40:49:0) iTemp24 [lr40:41]{short}[DPTR] = iTemp2 [lr18:40]{short}[r2] + ITemp11 [lr19:40]{short}[r3]
|
|
184
|
+
|
|
185
|
+
Sample.c(20:41:50:0) ret iTemp24 [lr40:41]{short}
|
|
186
|
+
|
|
187
|
+
Sample.c(20:42:51:0)_return($8):
|
|
188
|
+
|
|
189
|
+
Sample.c(20:43:52:0) eproc _function [lr0:0]{ ia0 re0 rm0}{function short}
|
|
190
|
+
|
|
191
|
+
Finally the code generated for this function:
|
|
192
|
+
|
|
193
|
+
.area DSEG (DATA)
|
|
194
|
+
|
|
195
|
+
_p::
|
|
196
|
+
|
|
197
|
+
.ds 2
|
|
198
|
+
|
|
199
|
+
_gint::
|
|
200
|
+
|
|
201
|
+
.ds 2
|
|
202
|
+
|
|
203
|
+
; sample.c 5
|
|
204
|
+
|
|
205
|
+
; — — — — — — — — — — — — — — —-
|
|
206
|
+
|
|
207
|
+
; function function
|
|
208
|
+
|
|
209
|
+
; — — — — — — — — — — — — — — —-
|
|
210
|
+
|
|
211
|
+
_function:
|
|
212
|
+
|
|
213
|
+
; iTemp0 [lr3:5]{_near * int}[r2] = recv
|
|
214
|
+
|
|
215
|
+
mov r2,dpl
|
|
216
|
+
|
|
217
|
+
; iTemp6 [lr5:16]{_near * int}[r0]:= iTemp0 [lr3:5]{_near * int}[r2]
|
|
218
|
+
|
|
219
|
+
mov ar0,r2
|
|
220
|
+
|
|
221
|
+
;_whilecontinue_0($1):
|
|
222
|
+
|
|
223
|
+
00101$:
|
|
224
|
+
|
|
225
|
+
; iTemp4 [lr7:8]{int}[r2 r3] = @[iTemp6 [lr5:16]{_near * int}[r0]]
|
|
226
|
+
|
|
227
|
+
; if iTemp4 [lr7:8]{int}[r2 r3] == 0 goto _whilebreak_0($3)
|
|
228
|
+
|
|
229
|
+
mov ar2,@r0
|
|
230
|
+
|
|
231
|
+
inc r0
|
|
232
|
+
|
|
233
|
+
mov ar3,@r0
|
|
234
|
+
|
|
235
|
+
dec r0
|
|
236
|
+
|
|
237
|
+
mov a,r2
|
|
238
|
+
|
|
239
|
+
orl a,r3
|
|
240
|
+
|
|
241
|
+
jz 00103$
|
|
242
|
+
|
|
243
|
+
00114$:
|
|
244
|
+
|
|
245
|
+
; iTemp7 [lr9:13]{_far * int}[DPTR]:= _p [lr0:0]{_far * int}
|
|
246
|
+
|
|
247
|
+
mov dpl,_p
|
|
248
|
+
|
|
249
|
+
mov dph,(_p + 1)
|
|
250
|
+
|
|
251
|
+
; _p [lr0:0]{_far * int} = _p [lr0:0]{_far * int} + 0x2 {short}
|
|
252
|
+
|
|
253
|
+
mov a,#0x02
|
|
254
|
+
|
|
255
|
+
add a,_p
|
|
256
|
+
|
|
257
|
+
mov _p,a
|
|
258
|
+
|
|
259
|
+
clr a
|
|
260
|
+
|
|
261
|
+
addc a,(_p + 1)
|
|
262
|
+
|
|
263
|
+
mov (_p + 1),a
|
|
264
|
+
|
|
265
|
+
; iTemp10 [lr13:14]{int}[r2 r3] = @[iTemp7 [lr9:13]{_far * int}[DPTR]]
|
|
266
|
+
|
|
267
|
+
movx a,@dptr
|
|
268
|
+
|
|
269
|
+
mov r2,a
|
|
270
|
+
|
|
271
|
+
inc dptr
|
|
272
|
+
|
|
273
|
+
movx a,@dptr
|
|
274
|
+
|
|
275
|
+
mov r3,a
|
|
276
|
+
|
|
277
|
+
; *(iTemp6 [lr5:16]{_near * int}[r0]):= iTemp10 [lr13:14]{int}[r2 r3]
|
|
278
|
+
|
|
279
|
+
mov @r0,ar2
|
|
280
|
+
|
|
281
|
+
inc r0
|
|
282
|
+
|
|
283
|
+
mov @r0,ar3
|
|
284
|
+
|
|
285
|
+
; iTemp6 [lr5:16]{_near * int}[r0] =
|
|
286
|
+
|
|
287
|
+
; iTemp6 [lr5:16]{_near * int}[r0] +
|
|
288
|
+
|
|
289
|
+
; 0x2 {short}
|
|
290
|
+
|
|
291
|
+
inc r0
|
|
292
|
+
|
|
293
|
+
; goto _whilecontinue_0($1)
|
|
294
|
+
|
|
295
|
+
sjmp 00101$
|
|
296
|
+
|
|
297
|
+
; _whilebreak_0($3):
|
|
298
|
+
|
|
299
|
+
00103$:
|
|
300
|
+
|
|
301
|
+
; iTemp2 [lr18:40]{short}[r2]:= 0x0 {short}
|
|
302
|
+
|
|
303
|
+
mov r2,#0x00
|
|
304
|
+
|
|
305
|
+
; iTemp11 [lr19:40]{short}[r3]:= 0x0 {short}
|
|
306
|
+
|
|
307
|
+
mov r3,#0x00
|
|
308
|
+
|
|
309
|
+
; iTemp21 [lr21:38]{short}[r4]:= 0x0 {short}
|
|
310
|
+
|
|
311
|
+
mov r4,#0x00
|
|
312
|
+
|
|
313
|
+
; iTemp23 [lr22:38]{int}[r5 r6]:= 0xa {int}
|
|
314
|
+
|
|
315
|
+
mov r5,#0x0A
|
|
316
|
+
|
|
317
|
+
mov r6,#0x00
|
|
318
|
+
|
|
319
|
+
; iTemp17 [lr23:38]{int}[r7 r0]:= 0x1e {int}
|
|
320
|
+
|
|
321
|
+
mov r7,#0x1E
|
|
322
|
+
|
|
323
|
+
mov r0,#0x00
|
|
324
|
+
|
|
325
|
+
; _forcond_0($4):
|
|
326
|
+
|
|
327
|
+
00104$:
|
|
328
|
+
|
|
329
|
+
; iTemp13 [lr25:26]{char}[CC] = iTemp21 [lr21:38]{short}[r4] < 0xa {short}
|
|
330
|
+
|
|
331
|
+
; if iTemp13 [lr25:26]{char}[CC] == 0 goto _forbreak_0($7)
|
|
332
|
+
|
|
333
|
+
clr c
|
|
334
|
+
|
|
335
|
+
mov a,r4
|
|
336
|
+
|
|
337
|
+
xrl a,#0x80
|
|
338
|
+
|
|
339
|
+
subb a,#0x8a
|
|
340
|
+
|
|
341
|
+
jnc 00107$
|
|
342
|
+
|
|
343
|
+
00115$:
|
|
344
|
+
|
|
345
|
+
; iTemp2 [lr18:40]{short}[r2] = iTemp2 [lr18:40]{short}[r2] +
|
|
346
|
+
|
|
347
|
+
; iTemp21 [lr21:38]{short}[r4]
|
|
348
|
+
|
|
349
|
+
mov a,r4
|
|
350
|
+
|
|
351
|
+
add a,r2
|
|
352
|
+
|
|
353
|
+
mov r2,a
|
|
354
|
+
|
|
355
|
+
; iTemp15 [lr29:30]{short}[r1] = iTemp21 [lr21:38]{short}[r4] * 0x3 {short}
|
|
356
|
+
|
|
357
|
+
mov b,#0x03
|
|
358
|
+
|
|
359
|
+
mov a,r4
|
|
360
|
+
|
|
361
|
+
mul ab
|
|
362
|
+
|
|
363
|
+
mov r1,a
|
|
364
|
+
|
|
365
|
+
; iTemp11 [lr19:40]{short}[r3] = iTemp11 [lr19:40]{short}[r3] +
|
|
366
|
+
|
|
367
|
+
; iTemp15 [lr29:30]{short}[r1]
|
|
368
|
+
|
|
369
|
+
add a,r3
|
|
370
|
+
|
|
371
|
+
mov r3,a
|
|
372
|
+
|
|
373
|
+
; iTemp17 [lr23:38]{int}[r7 r0]= iTemp17 [lr23:38]{int}[r7 r0]- 0x3 {short}
|
|
374
|
+
|
|
375
|
+
mov a,r7
|
|
376
|
+
|
|
377
|
+
add a,#0xfd
|
|
378
|
+
|
|
379
|
+
mov r7,a
|
|
380
|
+
|
|
381
|
+
mov a,r0
|
|
382
|
+
|
|
383
|
+
addc a,#0xff
|
|
384
|
+
|
|
385
|
+
mov r0,a
|
|
386
|
+
|
|
387
|
+
; _gint [lr0:0]{int} = _gint [lr0:0]{int} + iTemp17 [lr23:38]{int}[r7 r0]
|
|
388
|
+
|
|
389
|
+
mov a,r7
|
|
390
|
+
|
|
391
|
+
add a,_gint
|
|
392
|
+
|
|
393
|
+
mov _gint,a
|
|
394
|
+
|
|
395
|
+
mov a,r0
|
|
396
|
+
|
|
397
|
+
addc a,(_gint + 1)
|
|
398
|
+
|
|
399
|
+
mov (_gint + 1),a
|
|
400
|
+
|
|
401
|
+
; iTemp21 [lr21:38]{short}[r4] = iTemp21 [lr21:38]{short}[r4] + 0x1 {short}
|
|
402
|
+
|
|
403
|
+
inc r4
|
|
404
|
+
|
|
405
|
+
; iTemp23 [lr22:38]{int}[r5 r6]= iTemp23 [lr22:38]{int}[r5 r6]- 0x1 {short}
|
|
406
|
+
|
|
407
|
+
dec r5
|
|
408
|
+
|
|
409
|
+
cjne r5,#0xff,00104$
|
|
410
|
+
|
|
411
|
+
dec r6
|
|
412
|
+
|
|
413
|
+
; goto _forcond_0($4)
|
|
414
|
+
|
|
415
|
+
sjmp 00104$
|
|
416
|
+
|
|
417
|
+
; _forbreak_0($7):
|
|
418
|
+
|
|
419
|
+
00107$:
|
|
420
|
+
|
|
421
|
+
; ret iTemp24 [lr40:41]{short}
|
|
422
|
+
|
|
423
|
+
mov a,r3
|
|
424
|
+
|
|
425
|
+
add a,r2
|
|
426
|
+
|
|
427
|
+
mov dpl,a
|
|
428
|
+
|
|
429
|
+
; _return($8):
|
|
430
|
+
|
|
431
|
+
00108$:
|
|
432
|
+
|
|
433
|
+
ret
|
|
434
|
+
|
|
435
|
+
### A few words about basic block successors, predecessors and dominators
|
|
436
|
+
|
|
437
|
+
Successors are basic blocks Basic blocks that might execute after this basic block.
|
|
438
|
+
Predecessors are basic blocks that might execute before reaching this basic block.
|
|
439
|
+
Dominators are basic blocks that WILL execute before reaching this basic block.
|
|
440
|
+
|
|
441
|
+
[basic block 1]
|
|
442
|
+
|
|
443
|
+
if (something)
|
|
444
|
+
|
|
445
|
+
[basic block 2]
|
|
446
|
+
|
|
447
|
+
else
|
|
448
|
+
|
|
449
|
+
[basic block 3]
|
|
450
|
+
|
|
451
|
+
[basic block 4]
|
|
452
|
+
|
|
453
|
+
a) succList of [BB2] = [BB4], of [BB3] = [BB4], of [BB1] = [BB2,BB3]
|
|
454
|
+
|
|
455
|
+
b) predList of [BB2] = [BB1], of [BB3] = [BB1], of [BB4] = [BB2,BB3]
|
|
456
|
+
|
|
457
|
+
c) domVect of [BB4] = BB1... here we are not sure if BB2 or BB3 was executed but we are SURE that BB1 was executed.
|
|
458
|
+
|
|
459
|
+
## Acknowledgments
|
|
460
|
+
|
|
461
|
+
http://sdcc.sourceforge.net/#Who
|
|
462
|
+
|
|
463
|
+
*Thanks to all the other volunteer developers who have helped with coding, testing, web-page creation, distribution sets, etc. You know who you are:-)*
|
|
464
|
+
|
|
465
|
+
*Thanks to Sourceforge http://sourceforge.net/ which has hosted the project since 1999 and donates significant download bandwidth.*
|
|
466
|
+
|
|
467
|
+
*Also thanks to all SDCC Distributed Compile Farm members for donating CPU cycles and bandwidth for snapshot builds.
|
|
468
|
+
|
|
469
|
+
This document was initially written by Sandeep Dutta and updated by SDCC developers.
|
|
470
|
+
|
|
471
|
+
All product names mentioned herein may be trademarks Trademarks of their respective companies.
|
|
472
|
+
|
|
473
|
+
Alphabetical index
|
|
474
|
+
|
|
475
|
+
To avoid confusion, the installation and building options for SDCC itself (chapter 2) are not part of the index.
|
|
476
|
+
|
|
477
|
+
LatexCommand printindex type "idx" name "Index" literal "true"
|
package/resources/sdcc/toc.json
CHANGED
|
@@ -3,11 +3,53 @@
|
|
|
3
3
|
"description": "",
|
|
4
4
|
"toc": [
|
|
5
5
|
{
|
|
6
|
-
"title": "SDCC Compiler User Guide",
|
|
7
|
-
"uri": "msxdocs://sdcc/
|
|
6
|
+
"title": "SDCC Compiler User Guide: Introduction",
|
|
7
|
+
"uri": "msxdocs://sdcc/1_Introduction",
|
|
8
8
|
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
9
9
|
"description": "Comprehensive user guide for SDCC (Small Device C Compiler), a free open source ISO C11/C17 compiler suite targeting 8-bit microcontrollers including 8051, Z80, R800, STM8, and PIC architectures. This manual provides essential information about compiler installation, usage, programming techniques, data types, memory models, optimization strategies, and MCU-specific development practices for embedded systems programming."
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
"title": "SDCC Compiler User Guide: Installing SDCC",
|
|
13
|
+
"uri": "msxdocs://sdcc/2_Installing_SDCC",
|
|
14
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
15
|
+
"description": "Installation guide covering building SDCC on Linux/Unix and Windows. Details configure options, install paths, port enable/disable flags, and compiler version selection."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"title": "SDCC Compiler User Guide: Using SDCC",
|
|
19
|
+
"uri": "msxdocs://sdcc/3_Using_SDCC",
|
|
20
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
21
|
+
"description": "Practical usage guide covering C standard compliance, command-line options, data types, storage classes, memory models, and per-port deviations. Explains compiler/linker invocation and source-level features for embedded targets."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "SDCC Compiler User Guide: Notes on supported Processors",
|
|
25
|
+
"uri": "msxdocs://sdcc/4_Notes_on_supported_Processors",
|
|
26
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
27
|
+
"description": "Processor-specific notes for the MCS51, Z80/Z180, and other supported ports. Covers SFR access, bankswitching, startup code, and per-architecture features and limitations."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"title": "SDCC Compiler User Guide: Debugging",
|
|
31
|
+
"uri": "msxdocs://sdcc/5_Debugging",
|
|
32
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
33
|
+
"description": "Overview of debugging strategies for embedded code, from simulators and on-target monitors to ICEs and hardware debuggers. Details the SDCDB source-level debugger and the --debug build flow with .adb/.cdb files."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"title": "SDCC Compiler User Guide: Tips and Support",
|
|
37
|
+
"uri": "msxdocs://sdcc/6_Tips_and_Support",
|
|
38
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
39
|
+
"description": "Practical tips for generating efficient code, including data-type selection, integer promotion pitfalls, and porting code between compilers. Includes support resources and good embedded programming practices."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"title": "SDCC Compiler User Guide: SDCC Technical Data",
|
|
43
|
+
"uri": "msxdocs://sdcc/7_SDCC_Technical_Data",
|
|
44
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
45
|
+
"description": "Technical reference on SDCC's standard and MCU-specific optimizations, such as common subexpression elimination, dead-code elimination, and loop optimizations. Covers register allocation and code-generation internals."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"title": "SDCC Compiler User Guide: Compiler internals",
|
|
49
|
+
"uri": "msxdocs://sdcc/8_Compiler_internals",
|
|
50
|
+
"external_url": "https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/doc/sdccman.lyx?format=raw",
|
|
51
|
+
"description": "Walkthrough of the compiler architecture: parsing to AST, iCode intermediate generation, optimizations, live-range analysis, register allocation, and code generation. Explains how SDCC retargets to 8-bit MCUs like 8051 and Z80."
|
|
52
|
+
},
|
|
11
53
|
{
|
|
12
54
|
"title": "SDCC 4.5.0 Release Notes",
|
|
13
55
|
"uri": "https://sourceforge.net/p/sdcc/wiki/SDCC%204.5.0%20Release/",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# How to detect the RAM
|
|
2
|
+
|
|
3
|
+
This page was last modified 14:10, 3 October 2020 by Gdx.
|
|
4
|
+
|
|
5
|
+
Source: https://www.msx.org/wiki/How_to_detect_the_RAM
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
When a disk system is present, main RAM slot ID can be read from following addresses:
|
|
10
|
+
|
|
11
|
+
* F341h = Slot ID of Main-RAM on page 0000h~3FFFh
|
|
12
|
+
* F342h = Slot ID of Main-RAM on page 4000h~7FFFh
|
|
13
|
+
* F343h = Slot ID of Main-RAM on page 8000h~BFFFh
|
|
14
|
+
* F344h = Slot ID of Main-RAM on page C000h~FFFFh
|