@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.
Files changed (60) hide show
  1. package/README.md +20 -2
  2. package/dist/chunker.js +187 -0
  3. package/dist/embedder.js +250 -0
  4. package/dist/server.js +6 -1
  5. package/dist/server_tools.js +6 -5
  6. package/dist/vectordb.js +94 -35
  7. package/package.json +4 -8
  8. package/resources/audio/chipsfmpacpr1_en.md +209 -0
  9. package/resources/audio/chipsfmpacpr2_en.md +170 -0
  10. package/resources/audio/toc.json +12 -0
  11. package/resources/book--msx-top-secret-3/MTS3-Appendix-English-Upd2.pdf +0 -0
  12. package/resources/book--msx-top-secret-3/MTS3-Complete-English.pdf +0 -0
  13. package/resources/book--msx-top-secret-3/mts3-appendix-english-upd2.md +25863 -0
  14. package/resources/book--msx-top-secret-3/mts3-complete-english.md +44895 -0
  15. package/resources/book--msx2-technical-handbook/toc.json +1 -1
  16. package/resources/book--the-msx-red-book/Chapter1_Programmable_Peripheral_Interface.md +112 -0
  17. package/resources/book--the-msx-red-book/Chapter2_Video_Display_Processor.md +308 -0
  18. package/resources/book--the-msx-red-book/Chapter3_Programmable_Sound_Generator.md +168 -0
  19. package/resources/book--the-msx-red-book/Chapter4_ROM_BIOS.md +2528 -0
  20. package/resources/book--the-msx-red-book/Chapter5_ROM_BASIC_Interpreter.md +3975 -0
  21. package/resources/book--the-msx-red-book/Chapter6_Memory_Map.md +1963 -0
  22. package/resources/book--the-msx-red-book/Chapter7_Machine_Code_Programs.md +1238 -0
  23. package/resources/book--the-msx-red-book/Introduction.md +104 -0
  24. package/resources/book--the-msx-red-book/toc.json +38 -3
  25. package/resources/processors/toc.json +3 -3
  26. package/resources/processors/z80-undocumented.md +141 -0
  27. package/resources/programming/asm_develop_a_program_in_cartridge_rom.md +1881 -0
  28. package/resources/programming/toc.json +6 -0
  29. package/resources/sdcc/1_Introduction.md +199 -0
  30. package/resources/sdcc/2_Installing_SDCC.md +533 -0
  31. package/resources/sdcc/3_Using_SDCC.md +1758 -0
  32. package/resources/sdcc/4_Notes_on_supported_Processors.md +1638 -0
  33. package/resources/sdcc/5_Debugging.md +210 -0
  34. package/resources/sdcc/6_Tips_and_Support.md +258 -0
  35. package/resources/sdcc/7_SDCC_Technical_Data.md +489 -0
  36. package/resources/sdcc/8_Compiler_internals.md +477 -0
  37. package/resources/sdcc/toc.json +44 -2
  38. package/resources/system/how_to_detect_ram.md +14 -0
  39. package/resources/system/mrc_wiki_megarom_mappers.md +533 -0
  40. package/resources/system/the_memory.md +118 -0
  41. package/resources/system/toc.json +18 -0
  42. package/vector-db/__manifest/_transactions/0-675ee228-bffb-4636-80e5-cdfde25cc4fe.txn +2 -0
  43. package/vector-db/__manifest/_versions/18446744073709551614.manifest +0 -0
  44. package/vector-db/__manifest/_versions/latest_version_hint.json +1 -0
  45. package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/metadata.lance +0 -0
  46. package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_docs.lance +0 -0
  47. package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_invert.lance +0 -0
  48. package/vector-db/msxdocs.lance/_indices/37194b01-2a25-40d1-ac38-7fbe254df5ea/part_2_tokens.lance +0 -0
  49. package/vector-db/msxdocs.lance/_transactions/0-dd155672-40e6-4c6a-942f-7fcbe8c3dbd0.txn +0 -0
  50. package/vector-db/msxdocs.lance/_transactions/1-e7230cbd-ce8e-465c-9b85-b91443862427.txn +0 -0
  51. package/vector-db/msxdocs.lance/_versions/18446744073709551613.manifest +0 -0
  52. package/vector-db/msxdocs.lance/_versions/18446744073709551614.manifest +0 -0
  53. package/vector-db/msxdocs.lance/_versions/latest_version_hint.json +1 -0
  54. package/vector-db/msxdocs.lance/data/000100110110001011110001fc578141d296825d0bea11c95d.lance +0 -0
  55. package/resources/book--the-msx-red-book/the_msx_red_book.md +0 -10349
  56. package/resources/processors/z80-undocumented.tex +0 -5617
  57. package/resources/sdcc/lyx2md.py +0 -745
  58. package/resources/sdcc/sdccman.lyx +0 -81574
  59. package/resources/sdcc/sdccman.md +0 -5557
  60. package/vector-db/index.json +0 -1
@@ -0,0 +1,1238 @@
1
+ # 7. Machine Code Programs
2
+
3
+ This chapter contains a number of machine code programs to illustrate the use of MSX system resources. Although prepared with the ZEN Assembler they are designed t o run from BASIC and if necessary, may be entered in hex form using the loader shown below. The code should then be saved on cassette before any attempt is made to run it.
4
+
5
+ ```
6
+ 10 CLEAR 200,&HE000
7
+ 20 ADDR=&HE000
8
+ 30 PRINT RIGHT$ ("000"+HEX$(ADDR),4);
9
+ 40 INPUT D$
10
+ 50 POKE ADDR,VAL("&H"+D$)
11
+ 60 ADDR=ADDR+l
12
+ 70 GOTO 30
13
+ ```
14
+
15
+ All the programs start at address E000H and are entered at the same point. Unless stated otherwise no parameter need be passed to a program, execution may therefore be initiated with a simple `DEFUSR=&HE000:?USR(0)` statement.
16
+
17
+ <a name="keyboard_matrix"></a>
18
+ ## Keyboard Matrix
19
+
20
+ This program displays the keyboard matrix on the screen so that key depressions may be directly observed. The program may be terminated by pressing the CTRL and STOP keys. Note that spurious key depressions can be produced under certain circumstances if more than three or four keys are pressed at one time. This is a characteristic of all matrix type keyboards.
21
+
22
+ ```
23
+ ORG 0E000H
24
+ LOAD 0E000H
25
+
26
+ ; ******************************
27
+ ; * BIOS STANDARD ROUTINES *
28
+ ; ******************************
29
+
30
+ INITXT: EQU 006CH
31
+ CHPUT: EQU 00A2H
32
+ SNSMAT: EQU 0141H
33
+ BREAKX: EQU 00B7H
34
+
35
+ ; ******************************
36
+ ; * WORKSPACE VARIABLES *
37
+ ; ******************************
38
+
39
+ INTFLG: EQU 0FC9BH
40
+
41
+ ; ******************************
42
+ ; * CONTROL CHARACTERS *
43
+ ; ******************************
44
+
45
+ LF: EQU 10
46
+ HOME: EQU 11
47
+ CR: EQU 13
48
+
49
+ E000 CD6C00 MATRIX: CALL INITXT ; SCREEN 0
50
+ E003 3E0B MX1: LD A,HOME ;
51
+ E005 CDA200 CALL CHPUT ; Home Cursor
52
+ E008 AF XOR A ; A=KBD row
53
+ E009 F5 MX2: PUSH AF ;
54
+ E00A CD4101 CALL SNSMAT ; Read a row
55
+ E00D 0608 LD B,6 ; Eight cols
56
+ E00F 07 MX3: RLCA ; Select col
57
+ E010 F5 PUSH AF ;
58
+ E011 E601 AND 1 ;
59
+ E013 C630 ADD A,"0" ; Result
60
+ E015 CDA200 CALL CHPUT ; Display col
61
+ E018 F1 POP AF ;
62
+ E019 10F4 DJNZ MX3 ;
63
+ E01B 3E0D LD A,CR ; Newline
64
+ E01D CDA200 CALL CHPUT ;
65
+ E020 3E0A LD A,LF ;
66
+ E022 CDA200 CALL CHPUT ;
67
+ E025 F1 POP AF ; A=KBD row
68
+ E026 3C INC A ; Next row
69
+ E027 FE0B CP 11 ; Finished?
70
+ E029 20DE JR NZ,MX2 ;
71
+ E02B CDB700 CALL BREAKX ; CTRL-STOP
72
+ E02E 30D3 JR NC,MX1 ; Continue
73
+ E030 AF XOR A ;
74
+ E031 329BFC LD (INTFLG),A ; Clear possible STOP
75
+ E034 C9 RET ; Back to BASIC
76
+
77
+ END
78
+ ```
79
+
80
+ <a name="40_column_graphics_text"></a>
81
+ ## 40 Column Graphics Text
82
+
83
+ This program prints text on the [Graphics Mode](#graphics_mode) screen at forty characters per line. The string to be displayed is passed as the `USR` call parameter, for example `A$=USR("something")`. There us no need to open a GRP file beforehand, the only requirement of the program is that the screen be in the correct mode. The heart of the program is functionally equivalent to the [GRPPRT](#grpprt) standard routine but only the first six dot columns of a given character pattern are placed on the screen instead of eight. As the [GRPPRT](#grpprt) the pattern is placed at the current graphics position and the only control character recognised is ASCII CR (13) which functions as a combined CR, LF. Unlike the [GRPPRT](#grpprt) standard routine characters printed at negative coordinates, but which overlap the screen, will be correctly displayed. The program is currently set up to perform an auto linefeed after dot column 239, thus giving exactly forty characters per line. If required this may be changed, via the constant in the RMDCOL subroutine, so that the full width of the screen is usable.
84
+
85
+ ```
86
+ ORG 0E000H
87
+ LOAD 0E000H
88
+
89
+ ; ******************************
90
+ ; * BIOS STANDARD ROUTINES *
91
+ ; ******************************
92
+
93
+ RDSLT: EQU 000CH
94
+ CNVCHR: EQU 00ABH
95
+ MAPXYC: EQU 0111H
96
+ SETC: EQU 0120H
97
+
98
+ ; ******************************
99
+ ; * WORKSPACE VARIABLES *
100
+ ; ******************************
101
+
102
+ FORCLR: EQU 0F3E9H
103
+ ATRBYT: EQU 0F3F2H
104
+ CGPNT: EQU 0F91FH
105
+ PATWRK: EQU 0FC40H
106
+ SCRMOD: EQU 0FCAFH
107
+ GRPACX: EQU 0FCB7H
108
+ GRPACY: EQU 0FCB9H
109
+
110
+ ; ******************************
111
+ ; * CONTROL CHARACTERS *
112
+ ; ******************************
113
+
114
+ CR: EQU 13
115
+
116
+ E000 FE03 GFORTY: CP 3 ; String type?
117
+ E002 C0 RET NZ ;
118
+ E003 3AAFFC LD A,(SCRMOD) ; Mode
119
+ E006 FE02 CP 2 ; Graphics?
120
+ E008 C0 RET NZ ;
121
+ E009 EB EX DE,HL ; HL->Descriptor
122
+ E00A 46 LD B,(HL) ; B=String len
123
+ E00B 23 INC HL ;
124
+ E00C 5E LD E,(HL) ; Address LSB
125
+ E00D 23 INC HL ;
126
+ E00E 56 LD D,(HL) ; DE->String
127
+ E00F 04 INC B ;
128
+ E010 05 GF2: DEC B ; Finished?
129
+ E011 C8 RET Z ;
130
+ E012 1A LD A,(DE) ; A=Chr from string
131
+ E013 CD19E0 CALL GPRINT ; Print it
132
+ E016 13 INC DE ;
133
+ E017 18F7 JR GF2 ; Next chr
134
+ E019 F5 GPRINT: PUSH AF ;
135
+ E01A C5 PUSH BC ;
136
+ E01B D5 PUSH DE ;
137
+ E01C E5 PUSH HL ;
138
+ E01D FDE5 PUSH IY ;
139
+ E01F ED4BB7FC LD BC,(GRPACX) ; BC=X coord
140
+ E023 ED5BB9FC LD DE,(GRPACY) ; DE=Y coord
141
+ E027 CD39E0 CALL GDC ; Decode chr
142
+ E02A ED43B7FC LD (GRPACX),BC ; New X coord
143
+ E02E ED53B9FC LD (GRPACY),DE ; New Y coord
144
+ E032 FDE1 POP IY ;
145
+ E034 E1 POP HL ;
146
+ E035 D1 POP DE ;
147
+ E036 C1 POP BC ;
148
+ E037 F1 POP AF ;
149
+ E038 C9 RET ;
150
+
151
+ E039 CDAB00 GDC: CALL CNVCHR ; Check graphic
152
+ E03C D0 RET NC ; NC=Header
153
+ E03D 2007 JR NZ,GD2 ; NZ=Converted
154
+ E03F FE0D CP CR ; Carriage Return?
155
+ E041 2873 JR Z,GCRLF ;
156
+ E043 FE20 CP 20H ; Other control?
157
+ E045 D8 RET C ; Ignore
158
+ E046 6F GD2: LD L,A ;
159
+ E047 2600 LD H,0 ; HL=Chr code
160
+ E049 29 ADD HL,HL ;
161
+ E04A 29 ADD HL,HL ;
162
+ E04B 29 ADD HL,HL ; HL=Chr*8
163
+ E04C C5 PUSH BC ; X coord
164
+ E04D D5 PUSH DE ; Y coord
165
+ E04E ED5B20F9 LD DE,(CGPNT+1) ; Character set
166
+ E052 19 ADD HL,DE ; HL->Pattern
167
+ E053 1140FC LD DE,PATWRK ; DE->Buffer
168
+ E056 0608 LD B,8 ; Eight byte pattern
169
+ E058 C5 GD3: PUSH BC ;
170
+ E059 D5 PUSH DE ;
171
+ E05A 3A1FF9 LD A,(CGPNT) ; Slot ID
172
+ E05D CD0C00 CALL RDSLT ; Get pattern
173
+ E060 FB EI ;
174
+ E061 D1 POP DE ;
175
+ E062 C1 POP BC ;
176
+ E063 12 LD (DE),A ; Put in buffer
177
+ E064 13 INC DE ;
178
+ E065 23 INC HL ;
179
+ E066 10F0 DJNZ GD3 ; Next
180
+ E068 D1 POP DE ;
181
+ E069 C1 POP BC ;
182
+ E06A 3AE9F3 LD A,(FORCLR) ; Current colour
183
+ E06D 32F2F3 LS (ATRBYT),A ; Set ink
184
+ E070 FD2140FC LD IY,PATWRK ; IY->Patterns
185
+ E074 D5 PUSH DE ;
186
+ E075 2608 LD H,8 ; Max dot rows
187
+ E077 CB7A GD4: BIT 7,D ; Pos Y coord?
188
+ E079 202A JR NZ,GD8 ;
189
+ E07B CDBFE0 CALL BMDROW ; Bottom most row?
190
+ E07E 382B JR C,GD9 ; C=Y too large
191
+ E080 C5 PUSH BC ;
192
+ E081 2E06 LD L,6 ; Max dot cols
193
+ E083 FD7E00 LD A,(IY+0) ; A=Pattern row
194
+ E086 CB78 GD5: BIT 7,B ; Pos X coord
195
+ E088 2015 JR NZ,GD6 ;
196
+ E08A CDC8E0 CALL RMDCOL ; Rightmost col?
197
+ E08D 3815 JR C,GD7 ; C=X too large
198
+ E08F CB7F BIT 7,A ; Pattern bit
199
+ E091 280C JR Z,GD6 ; Z=0 Pixel
200
+ E093 F5 PUSH AF ;
201
+ E094 D5 PUSH DE ;
202
+ E095 E5 PUSH HL ;
203
+ E096 CD1101 CALL MAPXYC ; Map coords
204
+ E099 CD2001 CALL SETC ; Set pixel
205
+ E09C E1 POP HL ;
206
+ E09D D1 POP DE ;
207
+ E09E F1 POP AF ;
208
+ E09F 07 GD6: RLCA ; Shift pattern
209
+ E0A0 03 INC BC ; X=X+1
210
+ E0A1 2D DEC L ; Finished dot cols?
211
+ E0A2 20E2 JR NZ,GD5 ;
212
+ E0A4 C1 GD7: POP BC ; Initial X coord
213
+ E0A5 FD23 GD8: INC IY ; Next pattern byte
214
+ E0A7 13 INC DE ; Y=Y+1
215
+ E0A8 25 DEC H ; Finished dot rows?
216
+ E0A9 20CC JR NZ,GD4 ;
217
+ E0AB D1 GD9: POP DE ; Initial Y coord
218
+ E0AC 210600 LD HL,6 ; Step
219
+ E0AF 09 ADD HL,BC ; X=X+6
220
+ E0B0 44 LD B,H ;
221
+ E0B1 4D LD C,L ; BC=New X coord
222
+ E0B2 CDC8E0 CALL RMDCOL ; Rightmost col?
223
+ E0B5 D0 RET NC ;
224
+
225
+ E0B6 010000 GCRLF: LD BC,0 ; X=0
226
+ E0B9 210800 LD HL,8 ;
227
+ E0BC 19 ADD HL,DE ;
228
+ E0BD EB EX DE,HL ; Y=Y+8
229
+ E0BE C9 RET ;
230
+
231
+ E0BF E5 BMDROW: PUSH HL ;
232
+ E0C0 21BF00 LD HL,191 ; Bottom dot row
233
+ E0C3 B7 OR A ;
234
+ E0C4 ED52 SBC HL,DE ; Check Y coord
235
+ E0C6 E1 POP HL ;
236
+ E0C7 C9 RET ; C=Below screen
237
+
238
+ E0C8 E5 RMDCOL: PUSH HL ;
239
+ E0C9 21EF00 LD HL,239 ; Rightmost dot col
240
+ E0CC B7 OR A ;
241
+ E0CD ED42 SBC HL,BC ; Check X coord
242
+ E0CF E1 POP HL ;
243
+ E0D0 C9 RET ; C=Beyond right
244
+
245
+ END
246
+ ```
247
+
248
+ <a name="string_bubble_sort"></a>
249
+ ## String Bubble Sort
250
+
251
+ This program will sort the contents os a string Array into ascending alphabetic order. The location of the Array is passed as the `USR` call parameter, for example `V=USR(VARPRT(A$(0)))`. There are no restrictions on the size of the Array or on its contents but it must only have one dimension. The program is based on the classic bubble sort algorithm where string pairs are compared and their positions swapped if the second is smaller than the first. a 250 element Array of randomly generated stringswill be sorted in approximately 2.5 seconds. The equivalent BASIC program takes over six minutes.
252
+
253
+ ```
254
+ ORG 0E000H
255
+ LOAD 0E000H
256
+
257
+ E000 FE02 SORT: CP 2 ; Integer type?
258
+ E002 C0 RET NZ ;
259
+ E003 23 INC HL ; HL->DAC+1
260
+ E004 23 INC HL ; HL->DAC+2
261
+ E005 5E LD E,(HL) ; Address LSB
262
+ E006 23 INC HL ; HL->DAC+3
263
+ E007 56 LD D,(HL) ; Address MSB
264
+ E008 EB EX DE,HL ; HL->A$(0)
265
+ E009 E5 PUSH HL ;
266
+ E00A DDE1 POP IX ; IX->A$(0)
267
+ E00C DD7EF8 LD A,(IX-8) ; Array type
268
+ E00F FE03 CP 3 ; String Array?
269
+ E011 C0 RET NZ ;
270
+ E012 DD7EFD LD A,(IX-3) ; Dimension
271
+ E015 3D DEC A ; Single dimension?
272
+ E016 C0 RET NZ ;
273
+ E017 DD4EFE LD C,(IX-2) ;
274
+ E01A DD46FF LD B,(IX-1) ; BC=Element count
275
+ E01D C5 SR2: PUSH BC ;
276
+ E01E E5 PUSH HL ; HL->Dsc(N)
277
+ E01F 46 SR3: LD B,(HL) ; B=Len(N)
278
+ E020 23 INC HL ;
279
+ E021 5E LD E,(HL) ;
280
+ E022 23 INC HL ;
281
+ E023 E5 PUSH HL ;
282
+ E024 56 LD D,(HL) ; DE->String(N)
283
+ E025 23 INC HL ; HL->Dsc(N+1)
284
+ E026 4E LD C,(HL) ; C=Len(N+1)
285
+ E027 23 INC HL ;
286
+ E028 7E LD A,(HL) ;
287
+ E029 23 INC HL ;
288
+ E02A E5 PUSH HL ;
289
+ E02B 66 LD H,(HL) ;
290
+ E02C 6F LD L,A ; HL->String(N+1)
291
+ E02D EB EX DE,HL ; HL->(N),DE->(N+1)
292
+ E02E 04 INC B ;
293
+ E02F 0C INC C ;
294
+ E030 05 SR4: DEC B ; Remaining len(N)
295
+ E031 2B25 JR Z,NEXT ; Z=(N)<=(N+1)
296
+ E033 0D DEC C ; Remaining len(N+1)
297
+ E034 2808 JR Z,SWAP ; Z=(N+1)<(N)
298
+ E036 1A LD A,(DE) ; Chr from (N+1)
299
+ E037 BE CP (HL) ; Chr from (N)
300
+ E038 13 INC DE ;
301
+ E039 23 INC HL ;
302
+ E03A 28F4 JR Z,SR4 ; Same, continue
303
+ E03C 301A JR NC,NEXT ; NC=(N)<(N+1)
304
+ E03E E1 SWAP: POP HL ; HL->Dsc(N+1)
305
+ E03F D1 POP DE ; DE->Dsc(N)
306
+ E040 0603 LD B,3 ; Descriptor size
307
+ E042 1A SW2: LD A,(DE) ; Swap descriptors
308
+ E043 4E LD C,(HL) ;
309
+ E044 77 LD (HL),A ;
310
+ E045 79 LD A,C ;
311
+ E046 12 LD (DE),A ;
312
+ E047 1B DEC DE ;
313
+ E048 2B DEC HL ;
314
+ E049 10F7 DJNZ SW2 ;
315
+ E04B DDE5 PUSH IX ;
316
+ E04D E1 POP HL ; HL->A$(0)
317
+ E04E B7 OR A ;
318
+ E04F ED52 SBC HL,DE ; At Array start?
319
+ E051 3007 JR NC,NX2 ; NC=At start
320
+ E053 1B DEC DE ; Back up
321
+ E054 1B DEC DE ;
322
+ E055 EB EX DE,HL ; HL->Dsc(N-1_
323
+ E056 18C7 JR SR3 ; Go check again
324
+ E058 E1 NEXT: POP HL ; Lose junk
325
+ E059 E1 POP HL ;
326
+ E05A E1 NX2: POP HL ; HL->Dsc(N)
327
+ E05B C1 POP BC ; BC=Element count
328
+ E05C 23 INC HL ; Next descriptor
329
+ E05D 23 INC HL ;
330
+ E05E 23 INC HL ;
331
+ E05F 0B DEC BC ;
332
+ E060 78 LD A,B ;
333
+ E061 B1 OR C ; Finished?
334
+ E062 20B9 JR NZ,SR2 ;
335
+ E064 C9 RET ;
336
+
337
+ END
338
+ ```
339
+
340
+ <a name="graphics_screen_dump"></a>
341
+ ## Graphics Screen Dump
342
+
343
+ This program will dump the screen contents, in any mode, to the printer. When first activated via a `USR` call the program merely patches itself into the interrupt handler keyscan hook.
344
+
345
+ Once the program has installed itself it effectively becomes an extension of the interrupt handler and a screen dump may then be initiated from any part of the system simply by pressing the ESC key. If necessary the dump can be terminated by pressing the CTRL and STOP keys. An example of a [Graphics Mode](#graphics_mode) screen, in which all thirty-two sprites are active, is shown below:
346
+
347
+ The simplest method of generating a screen dump is to copy all the character codes from the Name Table to the printer. However this would only work in the two text modes, the sprites could not be displayed and the result would reflect the printer's internal character set rather than the VDP character set. The program therefore reproduces the screen as a 240/256x192 bit image on the printer in all modes, each point in the image being derived from the colour code of the corresponding point on the screen. No dot for colours 0 to 7 and a dot for colours 8 to 15.
348
+
349
+ The colour code for a given point is obtained by first examining the thirty-two sprites in sequence to determine whether any one overlaps it. If every sprite is transparent at the point then the character plane is examined. This is done by using the point coordinates to locate the corresponding entry in the Name Table then, via the character code, to isolate the relevant bit in the associated pattern. If the bit's colour code is found to be transparent the background plane colour is returned.
350
+
351
+ Note that the control code sequences used in the program are the Epson FX80 printer. These are marked in the listings in case another printer is to be used. One sequence is used to enter bit image mode at the start of a 240/256 byte line (each byte defines eight vertical dots) and one sequence is used to initiate a paper feed at the end of the line. The program is generally optimised for speed, rather than for minimal code, and takes about five seconds plus printer time to produce the 46,080/49,152 dots in the image.
352
+
353
+ ```
354
+ ORG 0E000H
355
+ LOAD 0E000H
356
+
357
+ ; ******************************
358
+ ; * BIOS STANDARD ROUTINES *
359
+ ; ******************************
360
+
361
+ RDVRM: EQU 004AH
362
+ CALATR: EQU 0087H
363
+ LPTOUT: EQU 00A5H
364
+
365
+ ; ******************************
366
+ ; * WORKSPACE VARIABLES *
367
+ ; ******************************
368
+
369
+ T32COL: EQU 0F3BFH
370
+ GRPNAM: EQU 0F3C7H
371
+ GRPCOL: EQU 0F3C9H
372
+ GRPCGP: EQU 0F3CBH
373
+ MLTNAM: EQU 0F3D1H
374
+ MLTCGP: EQU 0F3D5H
375
+ RG1SAV: EQU 0F3E0H
376
+ RG7SAV: EQU 0F3E6H
377
+ NAMBAS: EQU 0F922H
378
+ CGPBAS: EQU 0F924H
379
+ PATBAS: EQU 0F926H
380
+ ATRBAS: EQU 0F928H
381
+ SCRMOD: EQU 0FCAFH
382
+ HKEYC: EQU 0FDCCH
383
+
384
+ ; ******************************
385
+ ; * CONTROL CHARACTERS *
386
+ ; ******************************
387
+
388
+ CR: EQU 13
389
+ ESC: EQU 27
390
+
391
+ E000 3ACCFD ENTRY: LD A,(HKEYC) ; Hook
392
+ E003 FEC9 CP 0C9H ; Free to use?
393
+ E005 C0 RET NZ ;
394
+ E006 2112E0 LD HL,DUMP ; Where to go
395
+ E009 22CDFD LD (HKEYC+1),HL ; Redirect hook
396
+ E00C 3ECD LD A,0CDH ; CALL
397
+ E00E 32CCFD LD (HKEYC),A ;
398
+ E011 C9 RET ;
399
+
400
+ E012 FE3A DUMP: CP 3AH ; ESC key number?
401
+ E014 C0 RET NZ ;
402
+ E015 F5 PUSH AF ;
403
+ E016 C5 PUSH BC ;
404
+ E017 D5 PUSH DE ;
405
+ E018 E5 PUSH HL ;
406
+ E019 ED734FE2 LD (BRKSTK),SP ; For CTRL-STOP
407
+ E01D 0E00 LD C,0 ; C=Row
408
+ E01F 3AAFFC DU1: LD A,(SCRMOD) ; Mode
409
+ E022 B7 OR A ;
410
+ E023 21F000 LD HL,240 ; T40 Dots per row
411
+ E026 112B06 LD DE,6*256+40 ;
412
+ E029 2806 JR Z,DU2 ;
413
+ E02B 210001 LD HL,256 ; T32,GRP,MLT Dots
414
+ E02E 112008 LD DE,8*256+32 ;
415
+ E031 3E1B DU2: LD A,ESC ; ***** FX80 *****
416
+ E033 CD8DE0 CALL PRINT ; * *
417
+ E036 3E4B LD A,"K" ; * Bit mode *
418
+ E038 CD8DE0 CALL PRINT ; * *
419
+ E03B 7D LD A,L ; * Bytes LSB *
420
+ E03C CD8DE0 CALL PRINT ; * *
421
+ E03F 7C LD A,H ; * Bytes MSB *
422
+ E040 CD8DE0 CALL PRINT ; ****************
423
+ E043 0600 LD B,0 ; B=Column
424
+ E045 CD97E0 DU3: CALL CELL ; Do an 8x8 cell
425
+ E048 D5 PUSH DE ;
426
+ E049 C5 PUSH BC ;
427
+ E04A 2151E2 LD HL,CBUFF ; HL->Colours
428
+ E04D 42 LD B,D ; B=Dot cols (6 or 8)
429
+ E04E 110800 LD DE,8 ; CBUFF offset
430
+ E051 C5 DU4: PUSH BC ;
431
+ E052 E5 PUSH HL ;
432
+ E053 0608 LD B,8 ; B=Dot rows
433
+ E055 7E DU5: LD A,(HL) ; A=Colour code
434
+ E056 FE08 CP 8 ; Dark or light?
435
+ E058 3F CCF ; Light=Print dot
436
+ E059 CB11 RL C ; Build result
437
+ E05B 19 ADD HL,DE ; Next dot row
438
+ E05C 10F7 DJNZ DU5 ;
439
+ E05E 79 LD A,C ; 8 Vertical dots
440
+ E05F CD8DE0 CALL PRINT ;
441
+ E062 E1 POP HL ;
442
+ E063 C1 POP BC ;
443
+ E064 23 INC HL ; Next dot col
444
+ E065 10EA DJNZ DU4 ;
445
+ E067 C1 POP BC ;
446
+ E068 D1 POP DE ;
447
+ E069 04 INC B ; Next column
448
+ E06A 78 LD A,B ;
449
+ E06B BB CP E ; End of row?
450
+ E06C 20D7 JR NZ,DU3 ;
451
+ E06E 3E0D LD A,CR ; Head left
452
+ E070 CD8DE0 CALL PRINT ;
453
+ E073 3E1B LD A,ESC ; ***** FX80 *****
454
+ E075 CD8DE0 CALL PRINT ; * *
455
+ E078 3E4A LD A,"J" ; * Paper feed *
456
+ E07A CD8DE0 CALL PRINT ; * *
457
+ E07D 3E18 LD A,24 ; * 24/216= 1/9" *
458
+ E07F CD8DE0 CALL PRINT ; ****************
459
+ E082 0C INC C ; Next row
460
+ E083 79 LD A,C ;
461
+ E084 FE18 CP 24 ; Finished screen?
462
+ E086 2097 JR NZ,DU1 ;
463
+ E088 E1 DU6: POP HL ;
464
+ E089 D1 POP DE ;
465
+ E08A C1 POP BC ;
466
+ E08B F1 POP AF ;
467
+ E08C C9 RET ;
468
+
469
+ E08D CDA500 PRINT: CALL LPTOUT ; To printer
470
+ E090 D0 RET NC ; CTRL-STOP?
471
+ E091 ED7B4FE2 LD SP,(BRKSTK) ; Restore stack
472
+ E095 18F1 JR DU6 ; Terminate program
473
+
474
+ E097 C5 CELL: PUSH BC ;
475
+ E098 D5 PUSH DE ;
476
+ E099 E5 PUSH HL ;
477
+ E09A FDE5 PUSH IY ;
478
+ E09C 2151E2 LD HL,CBUFF ; For results
479
+ E09F 3E40 LD A,64 ;
480
+ E0A1 3600 CL1: LD (HL),0 ; Transparent
481
+ E0A3 23 INC HL ;
482
+ E0A4 3D DEC A ; Fill
483
+ E0A5 20FA JR NZ,CL1 ;
484
+ E0A7 3AAFFC LD A,(SCRMOD) ; Mode
485
+ E0AA B7 OR A ; T40?
486
+ E0AB F5 PUSH AF ;
487
+ E0AC C5 PUSH BC ;
488
+ E0AD C469E1 CALL NZ,SPRTES ; Sprites first
489
+ E0B0 C1 POP BC ;
490
+ E0B1 69 LD L,C ;
491
+ E0B2 2600 LD H,0 ; HL=Row
492
+ E0B4 29 ADD HL,HL ;
493
+ E0B5 29 ADD HL,HL ;
494
+ E0B6 29 ADD HL,HL ; HL=Row*8
495
+ E0B7 5D LD E,L ;
496
+ E0B8 54 LD D,H ; DE=Row*8
497
+ E0B9 29 ADD HL,HL ;
498
+ E0BA 29 ADD HL,HL ; HL=Row*32
499
+ E0BB F1 POP AF ; Mode
500
+ E0BC F5 PUSH AF ;
501
+ E0BD 2001 JR NZ,CL2 ; T40?
502
+ E0BF 19 ADD HL,DE ; HL=Row*40
503
+ E0C0 58 CL2: LD E,B ; DE=Column
504
+ E0C1 19 ADD HL,DE ;
505
+ E0C2 EB EX DE,HL ; DE=NAMTAB offset
506
+ E0C3 D602 SUB 2 ; Mode
507
+ E0C5 79 LD A,C ; A=Row
508
+ E0C6 010000 LD BC,0 ; BC=CGPTAB offset
509
+ E0C9 2A24F9 LD HL,(CGPBAS) ;
510
+ E0CC E5 PUSH HL ;
511
+ E0CD 2A22F9 LD HL,(NAMBAS) ;
512
+ E0D0 3819 JR C,CL4 ; C=T40 or T32
513
+ E0D2 200C JR NZ,CL3 ; NZ=MLT
514
+ E0D4 2ACBF3 LD HL,(GRPCGP) ; Else GRP
515
+ E0D7 E3 EX (SP),HL ;
516
+ E0D8 2AC7F3 LD HL,(GRPNAM) ;
517
+ E0DB E618 AND 18H ; Row MSBs
518
+ E0DD 47 LD B,A ; 1/3=2kB CGP offset
519
+ E0DE 180B JR CL4 ;
520
+ E0E0 2AD5F3 CL3: LD HL,(MLTCGP) ;
521
+ E0E3 E3 EX (SP),HL ;
522
+ E0E4 2AD1F3 LD HL,(MLTNAM) ;
523
+ E0E7 07 RLCA ; Row*2
524
+ E0E8 E606 AND 6 ;
525
+ E0EA 4F LD C,A ; 1/6=2B CGP offset
526
+ E0EB 19 CL4: ADD HL,DE ; HL->NAMTAB
527
+ E0EC CD4A00 CALL RDVRM ; Get chr code
528
+ E0EF 6F LD L,A ;
529
+ E0F0 2600 LD H,0 ; HL=Chr code
530
+ E0F2 29 ADD HL,HL ;
531
+ E0F3 29 ADD HL,HL ;
532
+ E0F4 29 ADD HL,HL ; HL=Chr*8
533
+ E0F5 09 ADD HL,BC ; GRP,MLT offsets
534
+ E0F6 EB EX DE,HL ; DE=CGPTAB offset
535
+ E0F7 FDE1 POP IY ; IY=CGPTAB base
536
+ E0F9 FD19 ADD IY,DE ; IY->Pattern
537
+ E0FB 2AC9F3 LD HL,(GRPCOL) ;
538
+ E0FE 19 ADD HL,DE ; HL->GRP colours
539
+ E0FF 0F RRCA ;
540
+ E100 0F RRCA ;
541
+ E101 0F RRCA ; Chr code/8
542
+ E102 E61F AND 1FH ;
543
+ E104 4F LD C,A ;
544
+ E105 0600 LD B,0 ;
545
+ E107 3AE6F3 LD A,(RG7SAV) ; T40 Colours
546
+ E10A 57 LD D,A ; D=T40 Colours
547
+ E10B E60F AND 0FH ;
548
+ E10D 5F LD E,A ; E=Background colour
549
+ E10E F1 POP AF ; Mode
550
+ E10F E5 PUSH HL ; STK->GRP Colours
551
+ E110 3D DEC A ;
552
+ E111 2008 JR NZ,CL5 ; Z=T32
553
+ E113 2ABFF3 LD HL,(T32COL) ;
554
+ E116 09 ADD HL,BC ; HL->T32 Colours
555
+ E117 CD4A00 CALL RDVRM ; Get T32 Colours
556
+ E11A 57 LD D,A ; D=T32 Colours
557
+ E11B 2151E2 CL5: LD HL,CBUFF ; Results
558
+ E11E 0608 LD B,8 ; Dot rows
559
+ E120 FDE5 CL6: PUSH IY ;
560
+ E122 E3 EX (SP),HL ; HL->Pattern
561
+ E123 CD4A00 CALL RDVRM ; Get pattern
562
+ E126 4F LD C,A ; C=Pattern
563
+ E127 E1 POP HL ;
564
+ E128 FD23 INC IY ; Next dot row
565
+ E12A 3AAFFC LD A,(SCRMOD) ; Mode
566
+ E12D D602 SUB 2 ;
567
+ E12F 3815 JR C,CL8 ; C=T40 or T32
568
+ E131 280C JR Z,CL7 ; Z=GRP
569
+ E133 51 LD D,C ; MLT Colours=Pattern
570
+ E134 0EF0 LD C,0F0H ; Dummy MLT pattern
571
+ E136 78 LD A,B ; Dot row
572
+ E137 FE05 CP 5 ; Cell halfway mark?
573
+ E139 280B JR Z,CL8 ;
574
+ E13B FD2B DEC IY ; Back up pattern
575
+ E13D 1807 JR CL8 ;
576
+ E13F E3 CL7: EX (SP),HL ; HL->GRP Colours
577
+ E140 CD4A00 CALL RDVRM ; Get colours
578
+ E143 57 LD D,A ; D=GRP Colours
579
+ E144 23 INC HL ; Next dot row
580
+ E145 E3 EX (SP),HL ; STK->GRP Colours
581
+ E146 C5 CL8: PUSH BC ;
582
+ E147 0608 LD B,8 ; Dot cols
583
+ E149 CB11 CL9: RL C ; Dot from pattern
584
+ E14B 34 INC (HL) ;
585
+ E14C 35 DEC (HL) ; Check CBUFF clear
586
+ E14D 200D JR NZ,CL12 ; NZ=Sprite above
587
+ E14F 7A LD A,D ; A=Colours
588
+ E150 3004 JR NC,CL10 ; NC=0 Pixel
589
+ E152 0F RRCA ;
590
+ E153 0F RRCA ;
591
+ E154 0F RRCA ;
592
+ E155 0F RRCA ; Select 1 colour
593
+ E156 E60F CL10: AND 0FH ;
594
+ E158 2001 JR NZ,CL11 ; Z=Transparent
595
+ E15A 7B LD A,E ; Use background
596
+ E15B 77 CL11: LD (HL),A ; Colour in CBUFF
597
+ E15C 23 CL12: INC HL ;
598
+ E15D 10EA DJNZ CL9 ; Next dot col
599
+ E15F C1 POP BC ;
600
+ E160 10BE DJNZ CL6 ; Next dot row
601
+ E162 E1 POP HL ;
602
+ E163 FDE1 POP IY ;
603
+ E165 E1 POP HL ;
604
+ E166 D1 POP DE ;
605
+ E167 C1 POP BC ;
606
+ E168 C9 RET ;
607
+
608
+ E169 78 SPRTES: LD A,B ; A=Column
609
+ E16A 07 RLCA ;
610
+ E16B 07 RLCA ;
611
+ E16C 07 RLCA ; A=X coord
612
+ E16D C607 ADD A,7 ; RH edge of cell
613
+ E16F 47 LD B,A ; B=X coord
614
+ E170 79 LD A,C ; A=Row
615
+ E171 07 RLCA ;
616
+ E172 07 RLCA ;
617
+ E173 07 RLCA ; A=Y coord
618
+ E174 C607 ADD A,7 ; Bottom of cell
619
+ E176 4F LD C,A ; C=Y coord
620
+ E177 AF XOR A ; Sprite number
621
+ E178 CD8700 SS1: CALL CALATR ; HL->Attributes
622
+ E17B 57 LD D,A ; D=Sprite number
623
+ E17C CD4A00 CALL RDVRM ; Get Sprite Y
624
+ E17F FED0 CP 208 ; Terminator?
625
+ E181 C8 RET Z ;
626
+ E182 D5 PUSH DE ;
627
+ E183 C5 PUSH BC ;
628
+ E184 CD8FE1 CALL SPRITE ; Do a sprite
629
+ E187 C1 POP BC ;
630
+ E188 F1 POP AF ;
631
+ E189 3C INC A ; Next sprite number
632
+ E18A FE20 CP 32 ; Done all?
633
+ E18C 20EA JR NZ,SS1 ;
634
+ E18E C9 RET ;
635
+
636
+ E18F 91 SPRITE: SUB C ; (SY-Y)
637
+ E190 2F CPL ; Make (Y-SY)
638
+ E191 FE27 CP 39 ; Possible overlap?
639
+ E193 D0 RET NC ;
640
+ E194 4F LD C,A ; C=(Y-SY)
641
+ E195 23 INC HL ;
642
+ E196 CD4A00 CALL RDVRM ; Get Sprite X
643
+ E199 5F LD E,A ;
644
+ E19A 78 LD A,B ; A=X coord
645
+ E19B 93 SUB E ;
646
+ E19C 5F LD E,A ; E=(X-SX)
647
+ E19D 9F SBC A,A ; Make 16 bit
648
+ E19E 57 LD D,A ; DE=(X-SX)
649
+ E19F 23 INC HL ;
650
+ E1A0 CD4A00 CALL RDVRM ; Get pattern#
651
+ E1A3 47 LD B,A ;
652
+ E1A4 23 INC HL ;
653
+ E1A5 CD4A00 CALL RDVRM ; Get EC & Colour
654
+ E1A8 CB7F BIT 7,A ; Early clock?
655
+ E1AA 2805 JR Z,SP1 ;
656
+ E1AC 212000 LD HL,32 ;
657
+ E1AF 19 ADD HL,DE ; Increase (X-SX)
658
+ E1B0 EB EX DE,HL ;
659
+ E1B1 14 SP1: INC D ;
660
+ E1B2 15 DEC D ; (X-SX)>255 or neg?
661
+ E1B3 C0 RET NZ ; NZ-Outside cell
662
+ E1B4 E60F AND 0FH ; Colour
663
+ E1B6 C8 RET Z ; Z=Transparent
664
+ E1B7 57 LD D,A ; D=Colour
665
+ E1B8 3AE0F3 LD A,(RG1SAV) ; Flags
666
+ E1BB DB4F BIT 1,A ; SIZE
667
+ E1BD 0F RRCA ; MAG
668
+ E1BE 3E08 LD A,8 ; Minimum size
669
+ E1C0 3001 JR NC,SP2 ;
670
+ E1C2 87 ADD A,A ; Double for MAG
671
+ E1C3 2800 SP2: JR Z,SP3 ;
672
+ E1C5 CB80 RES 0,B ; Change pattern#
673
+ E1C7 CB88 RES 1,B ;
674
+ E1C9 87 ADD A,A ; Double for SIZE
675
+ E1CA 6F SP3: LD L,A ; L=Sprite size
676
+ E1CB C606 ADD A,6 ; Allow cell size
677
+ E1CD B9 CP C ;
678
+ E1CE D8 RET C ; Sprite above
679
+ E1CF BB CP E ;
680
+ E1D0 D8 RET C ; Sprite to left
681
+ E1D1 79 LD A,C ;
682
+ E1D2 D607 SUB 7 ; (Y-SY) from top
683
+ E1D4 4F LD C,A ;
684
+ E1D5 7D LD A,L ; A=Sprite size
685
+ E1D6 2608 LD H,8 ; Max dot rows
686
+ E1D8 3800 JR C,SP5 ; C=Below cell top
687
+ E1DA 91 SUB C ; A=Dot row overlap
688
+ E1DB FE09 CP 9 ;
689
+ E1DD 3802 JR C,SP4 ;
690
+ E1DF 3E08 LD A,8 ;
691
+ E1E1 67 SP4: LD H,A ; H=Row overlap
692
+ E1E2 7B SP5: LD A,E ;
693
+ E1E3 D607 SUB 7 ; (X-SX) from cell LH
694
+ E1E5 5F LD E,A ;
695
+ E1E6 7D LD A,L ; A=Sprite size
696
+ E1E7 2E08 LD L,8 ; Max dot cols
697
+ E1E9 3808 JR C,SP7 ; C=Past cell LH
698
+ E1EB 93 SUB E ; A=Dot col overlap
699
+ E1EC FE09 CP 9 ;
700
+ E1EE 3802 JR C,SP6 ;
701
+ E1F0 3E08 LD A,8 ;
702
+ E1F2 6F SP6: LD L,A ; L=Col overlap
703
+ E1F3 FD2151E2 SP7: LD IY,CBUFF ; Results
704
+ E1F7 D5 SP8: PUSH DE ;
705
+ E1F8 CB79 BIT 7,C ; Reached sprite?
706
+ E1FA 2048 JR NZ,SP15 ;
707
+ E1FC E5 PUSH HL ;
708
+ E1FD FDE5 PUSH IY ;
709
+ E1FF CB7B SP9: BIT 7,E ; Reached sprite?
710
+ E201 2038 JR NZ,SP14 ;
711
+ E203 FD7E00 LD A,(IY+0) ; CBUFF
712
+ E206 B7 OR A ; Transparent?
713
+ E207 2032 JR NZ,SP14 ;
714
+ E209 C5 PUSH BC ;
715
+ E20A D5 PUSH DE ;
716
+ E20B E5 PUSH HL ;
717
+ E20C 3AE0F3 LD A,(RG1SAV) ; Flags
718
+ E10F 0F RRCA ; MAG
719
+ E210 3004 JR NC,SP10 ;
720
+ E212 CB39 SRL C ; (Y-SY)/2
721
+ E214 CB3B SRL E ; (X-SX)/2
722
+ E216 CB5B SP10: BIT 3,E ; (X-SX)>7?
723
+ E218 2804 JR Z,SP11 ;
724
+ E21A CB9B RES 3,E ; (X-SX)-8
725
+ E21C CBE1 SET 4,C ; (Y-SY)+16
726
+ E21E 68 SP11: LD L,B ;
727
+ E21F 2600 LD H,0 ; HL=Pattern#
728
+ E221 44 LD B,H ; BC=Y offset
729
+ E222 29 ADD HL,HL ;
730
+ E223 29 ADD HL,HL ;
731
+ E224 29 ADD HL,HL ; HL=Pattern*8
732
+ E225 09 ADD HL,BC ; Select dot row
733
+ E226 ED4B26F9 LD BC,(PATBAS) ;
734
+ E22A 09 ADD HL,BC ; HL->Pattern
735
+ E22B CD4A00 CALL RDVRM ; Get dot row
736
+ E22E 1C INC E ;
737
+ E22F 07 SP12: RLCA ; Select dot col
738
+ E230 1D DEC E ;
739
+ E231 20FC JR NZ,SP12 ;
740
+ E233 3003 JR NC,SP13 ; NC=0 Pixel
741
+ E235 FD7200 LD (IY+0),D ; Colour in CBUFF
742
+ E238 E1 SP13: POP HL ;
743
+ E239 D1 POP DE ;
744
+ E23A C1 POP BC ;
745
+ E23B FD23 SP14: INC IY ;
746
+ E23D 1C INC E ; Right a dot col
747
+ E23E 2D DEC L ; Finished cols?
748
+ E23F 20BE JR NZ,SP9 ;
749
+ E241 FDE1 POP IY ;
750
+ E243 E1 POP HL ;
751
+ E244 110800 SP15: LD DE,8 ;
752
+ E247 FD19 ADD IY,DE ;
753
+ E249 D1 POP DE ;
754
+ E24A 0C INC C ; Down a dot row
755
+ E24B 25 DEC H ; Finished?
756
+ E24C 20A9 JR NZ,SP8 ;
757
+ E24E C9 RET ;
758
+
759
+ E24F 0000 BRKSTK: DEFW 0 ; Break stack
760
+
761
+ ; ****************************
762
+ ; * This buffer holds the 64 *
763
+ ; * colour codes produced by *
764
+ ; * a cell scan: *
765
+ ; * *
766
+ ; * CCCCCCCC Bytes 00-07 *
767
+ ; * CCCCCCCC Bytes 08-15 *
768
+ ; * CCCCCCCC Bytes 16-23 *
769
+ ; * CCCCCCCC Bytes 24-31 *
770
+ ; * CCCCCCCC Bytes 32-39 *
771
+ ; * CCCCCCCC Bytes 40-47 *
772
+ ; * CCCCCCCC Bytes 48-55 *
773
+ ; * CCCCCCCC Bytes 56-64 *
774
+ ; * *
775
+ ; ****************************
776
+
777
+ E251 CBUFF: DEFS 64 ; Cell buffer
778
+
779
+ END
780
+ ```
781
+
782
+ <a name="character_editor"></a>
783
+ ## Character Editor
784
+
785
+ This program allows the MSX character patterns to be modified. When the program is first entered it copies the 2KB character set from its present location (usually the MSX ROM) to the CHRTAB buffer (E2A3H to EAA2H) and sets up the screen as shown below:
786
+
787
+ The program has two levels of operation, command and edit, with the RETURN key being used to toggle between them. In command mode the four arrow keys are used to select the character for editing. This is marked by a large cursor an is also displayed in magnified form on the right hand side of the screen. The "Q" key will quit the program and return to BASIC. The "A" key is used to adopt the character set, that is, to make it the system character set. When the character set is adopted it is copied to the highest part of memory (EB80H to F37FH) and its Slot ID and address placed in [CGPNT](#cgpnt).
788
+
789
+ In edit mode the four arrow keys are used to select the dot for editing, this is marked by a small cursor. The SPACE key will erase the current dot and the "." key set it. As the patter is modified the character menu on the left hand side of the screen is updated.
790
+
791
+ The character set in the CHRTAB may be saved on the cassette using a "BSAVE" statement and later re-loaded with a "BLOAD" statement. The ADOPT subroutine should be saved with the patterns and executed upon re-loading so that the system adopts the new character set. Alternatively the character set alone can be saved and its Slot ID and address placed in [CGPNT](#cgpnt) upon re-loading using BASIC statements. Note that altering the character patterns does not affect the operation of the MSX system un the slightest.
792
+
793
+ ```
794
+ ORG 0E000H
795
+ LOAD 0E000H
796
+
797
+ ; ******************************
798
+ ; * BIOS STANDARD ROUTINES *
799
+ ; ******************************
800
+
801
+ RDSLT: EQU 000CH
802
+ RDVRM: EQU 004AH
803
+ WRTVRM: EQU 004AH
804
+ FILVRM: EQU 0056H
805
+ INIGRP: EQU 0072H
806
+ CHSNS: EQU 009CH
807
+ CHGET: EQU 009FH
808
+ MAPXYC: EQU 0111H
809
+ FETCHC: EQU 0114H
810
+ RSLREG: EQU 0138H
811
+
812
+ ; ******************************
813
+ ; * WORKSPACE VARIABLES *
814
+ ; ******************************
815
+
816
+ GRPCOL: EQU 0F3D9H
817
+ FORCLR: EQU 0F3E9H
818
+ BAKCLR: EQU 0F3EAH
819
+ CGPNT: EQU 0F91FH
820
+ EXPTBL: EQU 0FCC1H
821
+ SLTTBL: EQU 0FCC5H
822
+
823
+ ; ******************************
824
+ ; * CONTROL CHARACTERS *
825
+ ; ******************************
826
+
827
+ CR: EQU 13
828
+ RIGHT: EQU 28
829
+ LEFT: EQU 29
830
+ UP: EQU 30
831
+ DOWN: EQU 31
832
+
833
+ E000 CDF6E0 CHEDIT: CALL INIT ; Cold start
834
+ E003 CDBDE0 CH1: CALL CHRMAG ; Magnify chr
835
+ E006 CDFEE1 CALL CHRXY ; Chr coords
836
+ E009 1608 LD D,8 ; Cursor size
837
+ E00B CD2FE2 CALL GETKEY ; Get command
838
+ E00E FE51 CP "Q" ; Quit
839
+ E010 C8 RET Z ;
840
+ E011 2103E0 LD HL,CH1 ; Set up return
841
+ E014 E5 PUSH HL ;
842
+ E015 FE41 CP "A" ; Adopt
843
+ E017 CA6EE2 JP Z,ADOPT ;
844
+ E01A FE0D CP CR ; Edit
845
+ E01C 281F JR Z,EDIT ;
846
+ E01E 0E01 LD C,1 ; C=Offset
847
+ E020 FE1C CP RIGHT ; Right
848
+ E022 2811 JR Z,CH2 ;
849
+ E024 0EFF LD C,0FFH ;
850
+ E026 FE1D CP LEFT ; Left
851
+ E028 280B JR Z,CH2 ;
852
+ E02A 0EF0 LD C,0F0H ;
853
+ E02C FE1E CP UP ; Up
854
+ E02E 2805 JR Z,CH2 ;
855
+ E030 0E10 LD C,16 ;
856
+ E032 FE1F CP DOWN ; Down
857
+ E034 C0 RET NZ ;
858
+ E035 3AA1E2 CH2: LD A,(CHRNUM) ; Current chr
859
+ E038 81 ADD A,C ; Add offset
860
+ E039 32A1E2 LD (CHRNUM),A ; New chr
861
+ E03C C9 RET ;
862
+
863
+ E03D CDE6E1 EDIT: CALL DOTXY ; Dot coords
864
+ E040 1602 LD D,2 ; Cursor size
865
+ E042 CD2FE2 CALL GETKEY ; Get command
866
+ E045 FE0D CP CR ; Quit
867
+ E047 C8 RET Z ;
868
+ E048 213DE0 LD HL,EDIT ; Set up return
869
+ E04B E5 PUSH HL ;
870
+ E04C 0100FE LD BC,0FE00H ; AND/OR masks
871
+ E04F FE20 CP " " ; Space
872
+ E051 2824 JR Z,ED3 ;
873
+ E053 0C INC C ; New OR mask
874
+ E054 FE2E CP "." ; Dot
875
+ E056 281F JR Z,ED3 ;
876
+ E058 FE1C CP RIGHT ; Right
877
+ E05A 2811 JR Z,ED2 ;
878
+ E05C 0EFF LD C,0FFH ; C=Offset
879
+ E05E FE1D CP LEFT ; Left
880
+ E060 280B JR Z,ED2 ;
881
+ E062 0EF8 LD C,0F8H ;
882
+ E064 FE1E CP UP ; Up
883
+ E066 2805 JR Z,ED2 ;
884
+ E068 0E08 LD C,8 ;
885
+ E06A FE1F CP DOWN ; Down
886
+ E06C C0 RET NZ ;
887
+ E06D 3AA2E2 ED2: LD A,(DOTNUM) ; Current dot
888
+ E070 81 ADD A,C ; Add offset
889
+ E071 E63F AND 63 ; Wrap round
890
+ E073 32A2E2 LD (DOTNUM),A ; New dot
891
+ E076 C9 RET ;
892
+ E077 CD1EE2 ED3: CALL PATPOS ; IY->Pattern
893
+ E07A 3AA2E2 LD A,(DOTNUM) ; Current dot
894
+ E07D F5 PUSH AF ;
895
+ E07E 0F RRCA ;
896
+ E07F 0F RRCA ;
897
+ E080 0F RRCA ;
898
+ E081 E607 AND 7 ; A=Row
899
+ E083 5F LD E,A ;
900
+ E084 1600 LD D,0 ; DE=Row
901
+ E086 FD19 ADD IY,DE ; IY->Row
902
+ E088 F1 POP AF ;
903
+ E089 E607 AND 7 ; A=Column
904
+ E08B 3C INC A ;
905
+ E08C CB08 ED4: RRC B ; AND mask
906
+ E08E CB09 RRC C ; OR mask
907
+ E090 3D DEC A ; Count columns
908
+ E091 20F9 JR NZ,ED4 ;
909
+ E093 FD7E00 LD A,(IY+0) ; A=Pattern
910
+ E096 A0 AND B ; Strip old bit
911
+ E097 B1 OR C ; New bit
912
+ E098 FD7700 LD (IY+0),A ; New pattern
913
+ E09B CDBDE0 CALL CHRMAG ; Update magnified
914
+
915
+ E09E CD1EE2 CHROUT: CALL PATPOS ; IY->Pattern
916
+ E0A1 CDFEE1 CALL CHRXY ; Get coords
917
+ E0A4 CDA3E1 CALL MAP ; Map
918
+ E0A7 0608 LD B,8 ; Dot rows
919
+ E0A9 D5 CO1: PUSH DE ;
920
+ E0AA E5 PUSH HL ;
921
+ E0AB 3E08 LD A,8 ; Dot cols
922
+ E0AD FD5E00 LD E,(IY+0) ; E=Pattern
923
+ E0B0 CDC4E1 CALL SETROW ; Set row
924
+ E0B3 E1 POP HL ; HL=CLOC
925
+ E0B4 D1 POP DE ; D=CMASK
926
+ E0B5 CDB8E1 CALL DOWNP ; Down a pixel
927
+ E0B8 FD23 INC IY ;
928
+ E0BA 10ED DJNZ CO1 ;
929
+ E0BC C9 RET ;
930
+
931
+ E0BD CD1EE2 CHRMAG: CALL PATPOS ; IY->Pattern
932
+ E0C0 0EBF LD C,191 ; Start X
933
+ E0C2 1E07 LD E,7 ; Start Y
934
+ E0C4 CDA3E1 CALL MAP ; Map
935
+ E0C7 0608 LD B,8 ; Dot rows
936
+ E0C9 0E05 CM1: LD C,5 ; Row mag
937
+ E0CB C5 CM2: PUSH BC ;
938
+ E0CC D5 PUSH DE ;
939
+ E0CD E5 PUSH HL ;
940
+ E0CE 0608 LD B,8 ; Dot columns
941
+ E0D0 FD7E00 LD A,(IY+0) ; A=Pattern
942
+ E0D3 07 CM3: RLCA ; Test bit
943
+ E0D4 F5 PUSH AF ;
944
+ E0D5 9F SBC A,A ; 0=00H, 1=FFH
945
+ E0D6 5F LD E,A ; E=Mag pattern
946
+ E0D7 3E05 LD A,5 ; Column mag
947
+ E0D9 CDC4E1 CALL SETROW ; Set row
948
+ E0DC CDAEE1 CALL RIGHTP ; Right a pixel
949
+ E0DF CDAEE1 CALL RIGHTP ; Skip grid
950
+ E0E2 F1 POP AF ;
951
+ E0E3 10EE DJNZ CM3 ;
952
+ E0E5 E1 POP HL ; HL=CLOC
953
+ E0E6 D1 POP DE ; D=CMASK
954
+ E0E7 C1 POP BC ;
955
+ E0E8 CDB8E1 CALL DOWNP ; Down a pixel
956
+ E0EB 0D DEC C ;
957
+ E0EC 20DD JR NZ,CM2 ;
958
+ E0EE CDB8E1 CALL DOWNP ; Skip grid
959
+ E0F1 FD23 INC IY ;
960
+ E0F3 10D4 DJNZ CM1 ;
961
+ E0F5 C9 RET ;
962
+
963
+ E0F6 100008 INIT: LD BC,2048 ; Size
964
+ E0F9 11A3E2 LD DE,CHRTAB ; Destination
965
+ E0FC 2A20F9 LD HL,(CGPNT+1) ; Source
966
+ E0FF C5 IN1: PUSH BC ;
967
+ E100 D5 PUSH DE ;
968
+ E101 3A1FF9 LD A,(CGPNT) ; Slot ID
969
+ E104 CD0C00 CALL RDSLT ; Read chr pattern
970
+ E107 FB EI ;
971
+ E108 D1 POP DE ;
972
+ E109 C1 POP BC ;
973
+ E10A 12 LD (DE),A ; Put in buffer
974
+ E10B 13 INC DE ;
975
+ E10C 23 INC HL ;
976
+ E10D 0B DEC BC ;
977
+ E10E 78 LD A,B ;
978
+ E10F B1 OR C ;
979
+ E110 20ED JR NZ,IN1 ;
980
+ E112 CD7200 CALL INIGRP ; SCREEN 2
981
+ E115 3AE9F3 LD A,(FORCLR) ; Colour 1
982
+ E118 07 RLCA ;
983
+ E119 07 RLCA ;
984
+ E11A 07 RLCA ;
985
+ E11B 07 RLCA ;
986
+ E11C 4F LD C,A ; C=Colour 1
987
+ E11D 3AEAF3 LD A,(BAKCLR) ; Colour 0
988
+ E120 B1 OR C ; Mix
989
+ E121 010018 LD BC,6144 ; Colour table size
990
+ E124 2AC9F3 LD HL,(GRPCOL) ; Colour table
991
+ E127 CD5600 CALL FILVRM ; Fill colours
992
+ E12A 210BB1 LD HL,177*256+11 ;
993
+ E12D 010AFF LD BC,0FFH*256+10 ;
994
+ E130 1E06 LD E,6 ;
995
+ E132 3E11 LD A,17 ;
996
+ E134 CD62E1 CALL GRID ; Draw chr grid
997
+ E137 210631 LD HL,49*256+6 ;
998
+ E13A 01BEAA LD BC,0AAH*256+190 ;
999
+ E13D 1E06 LD E,6 ;
1000
+ E13F 3E09 LD A,9 ;
1001
+ E141 CD62E1 CALL GRID ; Draw mag grid
1002
+ E144 213031 LD HL,49*256+48 ;
1003
+ E147 01BEFF LD BC,0FFH*256+190 ;
1004
+ E14A 1E06 LD E,6 ;
1005
+ E14C 3E02 LD A,2 ;
1006
+ E14E CD62E1 CALL GRID ; Draw mag box
1007
+ E151 AF XOR A ;
1008
+ E152 32A2E2 LD (DOTNUM),A ; Current dot
1009
+ E155 21A1E2 LD HL,CHRNUM ;
1010
+ E158 77 LD (HL),A ; Current chr
1011
+ E159 E5 IN2: PUSH HL ;
1012
+ E15A CD9EE0 CALL CHROUT ; Display chr
1013
+ E15D E1 POP HL ;
1014
+ E15E 34 INC (HL) ; Next chr
1015
+ E15F 20F8 JR NZ,IN2 ; Do 256
1016
+ E161 C9 RET ;
1017
+
1018
+ E162 F5 GRID: PUSH AF ;
1019
+ E163 C5 PUSH BC ;
1020
+ E164 E5 PUSH HL ;
1021
+ E165 CDA3E1 CALL MAP ; Map
1022
+ E168 C1 POP BC ; B=Len,C=Step
1023
+ E169 F1 POP AF ;
1024
+ E16A 5F LD E,A ; E=Pattern
1025
+ E16B F1 POP AF ; A=Count
1026
+ E16C F5 PUSH AF ;
1027
+ E16D D5 PUSH DE ;
1028
+ E16E E5 PUSH HL ;
1029
+ E16F F5 GR1: PUSH AF ;
1030
+ E170 C5 PUSH BC ;
1031
+ E171 D5 PUSH DE ;
1032
+ E172 E5 PUSH HL ;
1033
+ E173 78 LD A,B ; A=Len
1034
+ E174 CDC4E1 CALL SETROW ; Horizontal line
1035
+ E177 E1 POP HL ; HL=CLOC
1036
+ E178 D1 POP DE ; D=CMASK
1037
+ E179 CDB8E1 GR3: CALL DOWNP ; Down a pixel
1038
+ E17C 0D DEC C ; Done step?
1039
+ E17D 20FA JR NZ,GR3 ;
1040
+ E17F C1 POP BC ;
1041
+ E180 F1 POP AF ; A=Count
1042
+ E181 3D DEC A ; Done lines?
1043
+ E182 20EB JR NZ,GR1 ;
1044
+ E184 E1 POP HL ; HL=Initial CLOC
1045
+ E185 D1 POP DE ; D=Initial CMASK
1046
+ E186 F1 POP AF ; A=Count
1047
+ E187 F5 GR4: PUSH AF ;
1048
+ E188 C5 PUSH BC ;
1049
+ E189 D5 PUSH DE ;
1050
+ E18A E5 PUSH HL ;
1051
+ E18B 3E01 GR5: LD A,1 ; Line width
1052
+ E18D CDC4E1 CALL SETROW ; Thin line
1053
+ E190 CDB8E1 CALL DOWNP ; Down a pixel
1054
+ E193 10F6 DJNZ GR5 ; Vertical len
1055
+ E195 E1 POP HL ; HL=CLOC
1056
+ E196 D1 POP DE ; D=CMASK
1057
+ E197 CDAEE1 GR6: CALL RIGHTP ; Right a pixel
1058
+ E19A 0D DEC C ; Done step?
1059
+ E19B 20FA JR NZ,GR6 ;
1060
+ E19D C1 POP BC ;
1061
+ E19E F1 POP AF ; A=Count
1062
+ E19F 3D DEC A ; Done lines?
1063
+ E1A0 20E5 JR NZ,GR4 ;
1064
+ E1A2 C9 RET ;
1065
+
1066
+ E1A3 0600 MAP: LD B,0 ; X MSB
1067
+ E1A5 50 LD D,B ; Y MSB
1068
+ E1A6 CD1101 CALL MAPXYC ; Map coords
1069
+ E1A9 CD1401 CALL FETCHC ; HL=CLOC
1070
+ E1AC 57 LD D,A ; D=CMASK
1071
+ E1AD C9 RET ;
1072
+
1073
+ E1AE CB0A RIGHTP: RRC D ; Shift CMASK
1074
+ E1B0 D0 RET NC ; NC=Same cell
1075
+ E1B1 C5 RP1: PUSH BC ;
1076
+ E1B2 010800 LD BC,8 ; Offset
1077
+ E1B5 09 ADD HL,BC ; HL=Next cell
1078
+ E1B6 C1 POP BC ;
1079
+ E1B7 C9 RET ;
1080
+
1081
+ E1B8 23 DOWNP: INC HL ; CLOC down
1082
+ E1B9 7D LD A,L ;
1083
+ E1BA E607 AND 7 ; Select pixel row
1084
+ E1BC C0 RET NZ ; NZ=Same cell
1085
+ E1BD C5 PUSH BC ;
1086
+ E1BE 01F800 LD BC,00F8H ; Offset
1087
+ E1C1 09 ADD HL,BC ; HL=Next cell
1088
+ E1C2 C1 POP BC ;
1089
+ E1C3 C9 RET ;
1090
+
1091
+ E1C4 C5 SETROW: PUSH BC ;
1092
+ E1C5 47 LD B,A ; B=Count
1093
+ E1C6 CD4A00 SE1: CALL RDVRM ; Get old pattern
1094
+ E1C9 4F SE2: LD C,A ; C=Old
1095
+ E1CA 7A LD A,D ; A=CMASK
1096
+ E1CB 2F CPL ; AND mask
1097
+ E1CC A1 AND C ; Strip old bit
1098
+ E1CD CB03 RLC E ; Shift pattern
1099
+ E1CF 3001 JR NC,SE3 ; NC=0 Pixel
1100
+ E1D1 B2 OR D ; Set 1 Pixel
1101
+ E1D2 05 SE3: DEC B ; Finished?
1102
+ E1D3 280C JR Z,SE4 ;
1103
+ E1D5 CB0A RRC D ; CMASK right
1104
+ E1D7 30F0 JR NC,SE2 ; NC=Same cell
1105
+ E1D9 CD4D00 CALL WRTVRM ; Update cell
1106
+ E1DC CDB1E1 CALL RP1 ; Next cell
1107
+ E1DF 18E5 JR SE1 ; Start again
1108
+ E1E1 CD4D00 SE4: CALL WRTVRM ; Update cell
1109
+ E1E4 C1 POP BC ;
1110
+ E1E5 C9 RET ;
1111
+
1112
+ E1E6 3AA2E2 DOTXY: LD A,(DOTNUM) ; Current dot
1113
+ E1E9 F5 PUSH AF ;
1114
+ E1EA E607 AND 7 ; Column
1115
+ E1EC 07 RLCA ;
1116
+ E1ED 4F LD C,A ; C=Col*2
1117
+ E1EE 07 RLCA ; A=Col*4
1118
+ E1EF 81 ADD A,C ; A=Col*6
1119
+ E1F0 C6BF ADD A,191 ; Grid atart
1120
+ E1F2 4F LD C,A ; C=X coord
1121
+ E1F3 F1 POP AF ;
1122
+ E1F4 E638 AND 38H ; Row*8
1123
+ E1F6 0F RRCA ;
1124
+ E1F7 5F LD E,A ; E=Row*4
1125
+ E1F8 0F RRCA ; A=Row*2
1126
+ E1F9 83 ADD A,E ; A=Row*6
1127
+ E1FA C607 ADD A,7 ; Grid start
1128
+ E1FC 5F LD E,A ; E=Y coord
1129
+ E1FD C9 RET ;
1130
+
1131
+ E1FE 3AA1E2 CHRXY: LD A,(CHRNUM) ; Current chr
1132
+ E201 F5 PUSH AF ;
1133
+ E202 CD14E2 CALL MULT11 ; Column*11
1134
+ E205 C60C ADD A,12 ; Grid start
1135
+ E207 4F LD C,A ; C=X coord
1136
+ E208 F1 POP AF ;
1137
+ E209 0F RRCA ;
1138
+ E20A 0F RRCA ;
1139
+ E20B 0F RRCA ;
1140
+ E20C 0F RRCA ;
1141
+ E20D CD14E2 CALL MULT11 ; Row*11
1142
+ E210 C608 ADD A,8 ; Grid start
1143
+ E212 5F LD E,A ; E=Y coord
1144
+ E213 C9 RET ;
1145
+
1146
+ E214 E60F MULT11: AND 0FH ;
1147
+ EF16 57 LD D,A ; D=N
1148
+ E217 07 RLCA ;
1149
+ E218 47 LD B,A ; B=N*2
1150
+ E219 07 RLCA ;
1151
+ E21A 07 RLCA ; A=N*8
1152
+ E21B 80 ADD A,B ;
1153
+ E21C 82 ADD A,D ; A=N*11
1154
+ E21D C9 RET ;
1155
+
1156
+ E21E 3AA1E2 PATPOS: LD A,(CHRNUM) ; Current chr
1157
+ E221 6F LD L,A ;
1158
+ E222 2600 LD H,0 ; HL=Chr
1159
+ E224 29 ADD HL,HL ;
1160
+ E225 29 ADD HL,HL ;
1161
+ E226 29 ADD HL,HL ; HL=Chr*8
1162
+ E227 EB EX DE,HL ; DE=Chr*8
1163
+ E228 FD21A3E2 LD IY,CHRTAB ; Patterns
1164
+ E22C FD19 ADD IY,DE ; IY->Pattern
1165
+ E22E C9 RET ;
1166
+
1167
+ E22F 0600 GETKEY: LD B,0 ; Cursor flag
1168
+ E231 C5 GE1: PUSH BC ; C=X coord
1169
+ E232 D5 PUSH DE ; E=Y coord
1170
+ E233 CD50E2 CALL INVERT ; Flip cursor
1171
+ E236 D1 POP DE ;
1172
+ E237 C1 POP BC ;
1173
+ E238 04 INC B ; Flip flag
1174
+ E239 21401F LD HL,8000 ; Blink rate
1175
+ E23C CD9C00 GE2: CALL CHSNS ; Check KEYBUF
1176
+ E23F 2007 JR NZ,GE3 ; NZ=Got key
1177
+ E241 2B DEC HL ;
1178
+ E242 7C LD A,H ;
1179
+ E243 B5 OR L ;
1180
+ E244 20F6 JR NZ,GE2 ;
1181
+ E246 18E9 JR GE1 ; Time for cursor
1182
+ E248 CB40 GE3: BIT 0,B ; Cursor state
1183
+ E24A C450E2 CALL NZ,INVERT ; Remove cursor
1184
+ E24D C39F00 JP CHGET ; Collect character
1185
+
1186
+ E250 D5 INVERT: PUSH DE ;
1187
+ E251 CDA3E1 CALL MAP ; Map coords
1188
+ E254 F1 POP AF ; A=Cursor size
1189
+ E255 47 LD B,A ; B=Rows
1190
+ E256 5F LD E,A ; E=Cols
1191
+ E257 D5 IV1: PUSH DE ;
1192
+ E258 E5 PUSH HL ;
1193
+ E259 CD4A00 IV2: CALL RDVRM ; Old pattern
1194
+ E25C AA XOR D ; Flip a bit
1195
+ E25D CD4D00 CALL WRTVGM ; Put it back
1196
+ E260 CDAEE1 CALL RIGHTP ; Right a pixel
1197
+ E263 1D DEC E ;
1198
+ E264 20F3 JR NZ,IV2 ;
1199
+ E266 E1 POP HL ; HL=CLOC
1200
+ E267 D1 POP DE ; D=CMASK
1201
+ E268 CDB8E1 CALL DOWNP ; Down a pixel
1202
+ E26B 10EA DJNZ IV1 ;
1203
+ E26D C9 RET ;
1204
+
1205
+ E26E 010008 ADOPT: LD BC,2048 ; Size
1206
+ E271 1180EB LD DE,0EB80H ; Destination
1207
+ E274 ED5320F9 LD (CGPNT+1),DE ;
1208
+ E278 21A3E2 LD HL,CHRTAB ; Source
1209
+ E27B EDB0 LDIR ; Copy up high
1210
+ E27D CD3801 CALL RSLREG ; Read PSLOT reg
1211
+ E280 07 RLCA ;
1212
+ E281 07 RLCA ;
1213
+ E282 E603 AND 3 ; Select Page 3
1214
+ E284 4F LD C,A ;
1215
+ E285 0600 LD B,0 ; BC=Page 3 PSLOT#
1216
+ E287 21C1FC LD HL,EXPTBL ; Expanders
1217
+ E28A 09 ADD HL,BC ;
1218
+ E28B CB7E BIT 7,(HL) ; PSLOT expanded?
1219
+ E28D 280E JR Z,AD1 ; A=Normal
1220
+ E28F 21C5FC LD HL,SLTTBL ; Secondary regs
1221
+ E292 09 ADD HL,BC ;
1222
+ E293 7E LD A,(HL) ; A=Secondary reg
1223
+ E294 07 RLCA ;
1224
+ E295 07 RLCA ;
1225
+ E296 07 RLCA ;
1226
+ E297 07 RLCA ;
1227
+ E298 E60C AND 0CH ; A=Page 3 SSLOT#
1228
+ E29A B1 OR C ; Mix Page 3 PSLOT#
1229
+ E29B CBFF SET 7,A ; A=Slot ID
1230
+ E29D 321FF9 AD1: LD (CGPNT),A ;
1231
+ E2A0 C9 RET ;
1232
+
1233
+ E2A1 00 CHRNUM: DEFB 0 ; Current chr
1234
+ E2A2 00 DOTNUM: DEFB 0 ; Current dot
1235
+ E2A3 CHRTAB: DEFS 2048 ; Patterns to EAA2H
1236
+
1237
+ END
1238
+ ```