@nataliapc/mcp-openmsx 1.1.15 → 1.2.3

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 (216) hide show
  1. package/README.md +84 -37
  2. package/dist/server.js +101 -40
  3. package/dist/utils.js +42 -2
  4. package/dist/vectordb.js +61 -0
  5. package/package.json +8 -3
  6. package/resources/audio/msx-midi.md +872 -0
  7. package/resources/audio/psg_registers.md +281 -0
  8. package/resources/audio/sound_cartridge_scc.md +123 -0
  9. package/resources/audio/sound_cartridge_scci.md +250 -0
  10. package/resources/audio/toc.json +8 -4
  11. package/resources/book--msx2-technical-handbook/toc.json +1 -1
  12. package/resources/msx-dos/MSX-DOS_2_Environment_Variables.md +1368 -0
  13. package/resources/msx-dos/MSX-DOS_File_extensions.md +154 -0
  14. package/resources/msx-dos/toc.json +13 -0
  15. package/resources/msx-unapi/toc.json +2 -2
  16. package/resources/others/keyboard_matrices.md +243 -0
  17. package/resources/others/toc.json +6 -0
  18. package/resources/programming/asm_callbios.md +79 -0
  19. package/resources/programming/asm_docopy.md +115 -0
  20. package/resources/programming/asm_fast_loops.md +200 -0
  21. package/resources/programming/asm_getslot.md +143 -0
  22. package/resources/programming/asm_interrupts.md +202 -0
  23. package/resources/programming/asm_load_screen.md +240 -0
  24. package/resources/programming/asm_mult_div_shifts.md +487 -0
  25. package/resources/programming/asm_raminpage1.md +56 -0
  26. package/resources/programming/asm_vdp_detection.md +78 -0
  27. package/resources/programming/asm_vdp_routines.md +343 -0
  28. package/resources/programming/asm_z80_routines_collection.md +810 -0
  29. package/resources/programming/basic_wiki/ABS().md +36 -0
  30. package/resources/programming/basic_wiki/AND.md +71 -0
  31. package/resources/programming/basic_wiki/ASC().md +38 -0
  32. package/resources/programming/basic_wiki/ATN().md +36 -0
  33. package/resources/programming/basic_wiki/AUTO.md +39 -0
  34. package/resources/programming/basic_wiki/BASE().md +147 -0
  35. package/resources/programming/basic_wiki/BEEP.md +27 -0
  36. package/resources/programming/basic_wiki/BIN$().md +36 -0
  37. package/resources/programming/basic_wiki/BLOAD.md +63 -0
  38. package/resources/programming/basic_wiki/BSAVE.md +61 -0
  39. package/resources/programming/basic_wiki/CALL.md +391 -0
  40. package/resources/programming/basic_wiki/CALL_ADJUST.md +40 -0
  41. package/resources/programming/basic_wiki/CALL_IMPOSE.md +28 -0
  42. package/resources/programming/basic_wiki/CALL_OPTIONS.md +26 -0
  43. package/resources/programming/basic_wiki/CALL_PAUSE.md +119 -0
  44. package/resources/programming/basic_wiki/CALL_PCMPLAY.md +60 -0
  45. package/resources/programming/basic_wiki/CALL_PCMREC.md +70 -0
  46. package/resources/programming/basic_wiki/CDBL().md +36 -0
  47. package/resources/programming/basic_wiki/CHR$().md +51 -0
  48. package/resources/programming/basic_wiki/CINT().md +36 -0
  49. package/resources/programming/basic_wiki/CIRCLE.md +51 -0
  50. package/resources/programming/basic_wiki/CLEAR.md +39 -0
  51. package/resources/programming/basic_wiki/CLOAD.md +27 -0
  52. package/resources/programming/basic_wiki/CLOAD?.md +31 -0
  53. package/resources/programming/basic_wiki/CLOSE.md +44 -0
  54. package/resources/programming/basic_wiki/CLS.md +51 -0
  55. package/resources/programming/basic_wiki/COLOR.md +143 -0
  56. package/resources/programming/basic_wiki/COLOR=.md +93 -0
  57. package/resources/programming/basic_wiki/COLOR_SPRITE$().md +83 -0
  58. package/resources/programming/basic_wiki/COLOR_SPRITE().md +85 -0
  59. package/resources/programming/basic_wiki/CONT.md +23 -0
  60. package/resources/programming/basic_wiki/COPY.md +215 -0
  61. package/resources/programming/basic_wiki/COPY_SCREEN.md +61 -0
  62. package/resources/programming/basic_wiki/COS().md +37 -0
  63. package/resources/programming/basic_wiki/CSAVE.md +35 -0
  64. package/resources/programming/basic_wiki/CSNG().md +36 -0
  65. package/resources/programming/basic_wiki/CSRLIN.md +33 -0
  66. package/resources/programming/basic_wiki/DATA.md +47 -0
  67. package/resources/programming/basic_wiki/DEFDBL.md +40 -0
  68. package/resources/programming/basic_wiki/DEFINT.md +40 -0
  69. package/resources/programming/basic_wiki/DEFSNG.md +40 -0
  70. package/resources/programming/basic_wiki/DEFSTR.md +40 -0
  71. package/resources/programming/basic_wiki/DEF_FN.md +49 -0
  72. package/resources/programming/basic_wiki/DEF_USR.md +33 -0
  73. package/resources/programming/basic_wiki/DELETE.md +49 -0
  74. package/resources/programming/basic_wiki/DIM.md +59 -0
  75. package/resources/programming/basic_wiki/DRAW.md +77 -0
  76. package/resources/programming/basic_wiki/ELSE.md +45 -0
  77. package/resources/programming/basic_wiki/END.md +32 -0
  78. package/resources/programming/basic_wiki/EOF().md +36 -0
  79. package/resources/programming/basic_wiki/EQV.md +76 -0
  80. package/resources/programming/basic_wiki/ERASE.md +35 -0
  81. package/resources/programming/basic_wiki/ERL.md +34 -0
  82. package/resources/programming/basic_wiki/ERR.md +143 -0
  83. package/resources/programming/basic_wiki/ERROR.md +145 -0
  84. package/resources/programming/basic_wiki/EXP().md +38 -0
  85. package/resources/programming/basic_wiki/FIELD.md +48 -0
  86. package/resources/programming/basic_wiki/FIX().md +44 -0
  87. package/resources/programming/basic_wiki/FN.md +61 -0
  88. package/resources/programming/basic_wiki/FOR...NEXT.md +80 -0
  89. package/resources/programming/basic_wiki/FRE().md +66 -0
  90. package/resources/programming/basic_wiki/GET_DATE.md +60 -0
  91. package/resources/programming/basic_wiki/GET_TIME.md +34 -0
  92. package/resources/programming/basic_wiki/GOSUB.md +41 -0
  93. package/resources/programming/basic_wiki/GOTO.md +41 -0
  94. package/resources/programming/basic_wiki/HEX$().md +36 -0
  95. package/resources/programming/basic_wiki/IF...GOTO...ELSE.md +55 -0
  96. package/resources/programming/basic_wiki/IF...THEN...ELSE.md +50 -0
  97. package/resources/programming/basic_wiki/IMP.md +83 -0
  98. package/resources/programming/basic_wiki/INKEY$.md +65 -0
  99. package/resources/programming/basic_wiki/INP().md +33 -0
  100. package/resources/programming/basic_wiki/INPUT$().md +51 -0
  101. package/resources/programming/basic_wiki/INPUT.md +93 -0
  102. package/resources/programming/basic_wiki/INSTR().md +44 -0
  103. package/resources/programming/basic_wiki/INT().md +44 -0
  104. package/resources/programming/basic_wiki/INTERVAL.md +57 -0
  105. package/resources/programming/basic_wiki/KEY().md +51 -0
  106. package/resources/programming/basic_wiki/KEY.md +254 -0
  107. package/resources/programming/basic_wiki/LEFT$().md +39 -0
  108. package/resources/programming/basic_wiki/LEN().md +36 -0
  109. package/resources/programming/basic_wiki/LET.md +68 -0
  110. package/resources/programming/basic_wiki/LINE.md +74 -0
  111. package/resources/programming/basic_wiki/LINE_INPUT.md +79 -0
  112. package/resources/programming/basic_wiki/LIST.md +58 -0
  113. package/resources/programming/basic_wiki/LLIST.md +43 -0
  114. package/resources/programming/basic_wiki/LOAD.md +56 -0
  115. package/resources/programming/basic_wiki/LOCATE.md +67 -0
  116. package/resources/programming/basic_wiki/LOG().md +36 -0
  117. package/resources/programming/basic_wiki/LPOS().md +31 -0
  118. package/resources/programming/basic_wiki/LPRINT.md +46 -0
  119. package/resources/programming/basic_wiki/MAXFILES.md +39 -0
  120. package/resources/programming/basic_wiki/MERGE.md +54 -0
  121. package/resources/programming/basic_wiki/MID$().md +72 -0
  122. package/resources/programming/basic_wiki/MOD.md +39 -0
  123. package/resources/programming/basic_wiki/MOTOR.md +46 -0
  124. package/resources/programming/basic_wiki/NEW.md +27 -0
  125. package/resources/programming/basic_wiki/NOT.md +61 -0
  126. package/resources/programming/basic_wiki/OCT$().md +36 -0
  127. package/resources/programming/basic_wiki/ON...GOSUB.md +45 -0
  128. package/resources/programming/basic_wiki/ON...GOTO.md +42 -0
  129. package/resources/programming/basic_wiki/ON_ERROR_GOTO.md +61 -0
  130. package/resources/programming/basic_wiki/ON_INTERVAL_GOSUB.md +54 -0
  131. package/resources/programming/basic_wiki/ON_KEY_GOSUB.md +56 -0
  132. package/resources/programming/basic_wiki/ON_SPRITE_GOSUB.md +41 -0
  133. package/resources/programming/basic_wiki/ON_STOP_GOSUB.md +56 -0
  134. package/resources/programming/basic_wiki/ON_STRIG_GOSUB.md +70 -0
  135. package/resources/programming/basic_wiki/OPEN.md +103 -0
  136. package/resources/programming/basic_wiki/OR.md +75 -0
  137. package/resources/programming/basic_wiki/OUT.md +35 -0
  138. package/resources/programming/basic_wiki/PAD().md +110 -0
  139. package/resources/programming/basic_wiki/PAINT.md +66 -0
  140. package/resources/programming/basic_wiki/PDL().md +53 -0
  141. package/resources/programming/basic_wiki/PEEK().md +44 -0
  142. package/resources/programming/basic_wiki/PLAY().md +58 -0
  143. package/resources/programming/basic_wiki/PLAY.md +196 -0
  144. package/resources/programming/basic_wiki/POINT.md +52 -0
  145. package/resources/programming/basic_wiki/POKE.md +51 -0
  146. package/resources/programming/basic_wiki/POS().md +36 -0
  147. package/resources/programming/basic_wiki/PRESET.md +61 -0
  148. package/resources/programming/basic_wiki/PRINT.md +179 -0
  149. package/resources/programming/basic_wiki/PSET.md +82 -0
  150. package/resources/programming/basic_wiki/PUT_KANJI.md +93 -0
  151. package/resources/programming/basic_wiki/PUT_SPRITE.md +143 -0
  152. package/resources/programming/basic_wiki/READ.md +45 -0
  153. package/resources/programming/basic_wiki/REM.md +42 -0
  154. package/resources/programming/basic_wiki/RENUM.md +78 -0
  155. package/resources/programming/basic_wiki/RESTORE.md +52 -0
  156. package/resources/programming/basic_wiki/RESUME.md +45 -0
  157. package/resources/programming/basic_wiki/RETURN.md +47 -0
  158. package/resources/programming/basic_wiki/RIGHT$().md +39 -0
  159. package/resources/programming/basic_wiki/RND().md +51 -0
  160. package/resources/programming/basic_wiki/RUN.md +56 -0
  161. package/resources/programming/basic_wiki/SAVE.md +65 -0
  162. package/resources/programming/basic_wiki/SCREEN.md +164 -0
  163. package/resources/programming/basic_wiki/SET_ADJUST.md +66 -0
  164. package/resources/programming/basic_wiki/SET_BEEP.md +76 -0
  165. package/resources/programming/basic_wiki/SET_DATE.md +103 -0
  166. package/resources/programming/basic_wiki/SET_PAGE.md +52 -0
  167. package/resources/programming/basic_wiki/SET_PASSWORD.md +75 -0
  168. package/resources/programming/basic_wiki/SET_PROMPT.md +61 -0
  169. package/resources/programming/basic_wiki/SET_SCREEN.md +100 -0
  170. package/resources/programming/basic_wiki/SET_SCROLL.md +55 -0
  171. package/resources/programming/basic_wiki/SET_TIME.md +83 -0
  172. package/resources/programming/basic_wiki/SET_TITLE.md +87 -0
  173. package/resources/programming/basic_wiki/SET_VIDEO.md +49 -0
  174. package/resources/programming/basic_wiki/SGN().md +38 -0
  175. package/resources/programming/basic_wiki/SIN().md +36 -0
  176. package/resources/programming/basic_wiki/SOUND.md +188 -0
  177. package/resources/programming/basic_wiki/SPACE$().md +38 -0
  178. package/resources/programming/basic_wiki/SPC().md +34 -0
  179. package/resources/programming/basic_wiki/SPRITE$().md +50 -0
  180. package/resources/programming/basic_wiki/SPRITE.md +31 -0
  181. package/resources/programming/basic_wiki/SQR().md +32 -0
  182. package/resources/programming/basic_wiki/STICK().md +70 -0
  183. package/resources/programming/basic_wiki/STOP.md +70 -0
  184. package/resources/programming/basic_wiki/STR$().md +37 -0
  185. package/resources/programming/basic_wiki/STRIG().md +82 -0
  186. package/resources/programming/basic_wiki/STRING$().md +42 -0
  187. package/resources/programming/basic_wiki/SWAP.md +62 -0
  188. package/resources/programming/basic_wiki/TAB().md +38 -0
  189. package/resources/programming/basic_wiki/TAN().md +36 -0
  190. package/resources/programming/basic_wiki/TIME.md +59 -0
  191. package/resources/programming/basic_wiki/TROFF.md +21 -0
  192. package/resources/programming/basic_wiki/TRON.md +39 -0
  193. package/resources/programming/basic_wiki/USR().md +66 -0
  194. package/resources/programming/basic_wiki/VAL().md +36 -0
  195. package/resources/programming/basic_wiki/VARPTR().md +50 -0
  196. package/resources/programming/basic_wiki/VDP().md +103 -0
  197. package/resources/programming/basic_wiki/VPEEK().md +46 -0
  198. package/resources/programming/basic_wiki/VPOKE.md +48 -0
  199. package/resources/programming/basic_wiki/WAIT.md +38 -0
  200. package/resources/programming/basic_wiki/WIDTH.md +76 -0
  201. package/resources/programming/basic_wiki/XOR.md +72 -0
  202. package/resources/programming/basic_wiki/_toc.json +871 -0
  203. package/resources/programming/dos_error_handling.md +85 -0
  204. package/resources/programming/toc.json +51 -36
  205. package/resources/programming/vdp_commands_speed.md +147 -0
  206. package/resources/programming/vdp_programming_faq.md +55 -0
  207. package/resources/programming/vdp_programming_tutorial.md +390 -0
  208. package/resources/programming/vdp_screensplit_programming_guide.md +166 -0
  209. package/resources/programming/vdp_scrolling_on_msx.md +124 -0
  210. package/resources/programming/vdp_the_yjk_screen_modes.md +227 -0
  211. package/resources/programming/vdp_v9938_vram_timings.md +539 -0
  212. package/resources/programming/vdp_v9938_vram_timings_part_2.md +281 -0
  213. package/resources/sdcc/toc.json +1 -1
  214. package/vector-db/index.json +1 -0
  215. /package/resources/msx-unapi/{Ethernet_UNAPI_specification_1.1.md → Ethernet_UNAPI_specification_1_1.md} +0 -0
  216. /package/resources/msx-unapi/{MSX_UNAPI_specification_1.1.md → MSX_UNAPI_specification_1_1.md} +0 -0
@@ -0,0 +1,872 @@
1
+ # MSX-MIDI
2
+
3
+ From MSX Datapack Vol. 3
4
+ Translated by Laurens Holst
5
+
6
+ ## Chapter 1: About MSX-MIDI
7
+
8
+ With MSX-MIDI, MIDI functionality and BASIC extensions were added to MSX-MUSIC to enable it to use MIDI. Unlike MSX-MUSIC, there is no BIOS. Non-BASIC MSX-MIDI programs directly access the hardware from the I/O ports.
9
+
10
+ MSX-MIDI can be both built into the machine body, or an external cartridge. MSX MIDI is only available to MSX turbo R and later.
11
+
12
+ It can not be used on MSX, MSX2 and MSX2+. It can also be used on FPGA OCM-PLD machines through the joystick port, or on any MSX machine with a MIDI interface cartridge.
13
+
14
+ MSX-MIDI is organized as follows:
15
+
16
+ #### MIDI interface
17
+
18
+ |||
19
+ |:--|:--|
20
+ |8251|MIDI data communication IC|
21
+ |8253 or 8254|Baud rate generator and timer IC|
22
+
23
+ These ICs can be accessed through the I/O ports.
24
+
25
+ #### MSX-MIDI ROM (16K bytes)
26
+
27
+ In case it is built-in, it is placed in the same slot as the MSX-Music (slot 0-2, page 1).
28
+
29
+ In case it is an external cartridge, it is included on the cartridge.
30
+
31
+ When the BASIC extensions are used, it is initialized to use external cartridge's MSX-MIDI instead of the built-in MSX-MUSIC.
32
+
33
+ ## Chapter 2: Hardware
34
+
35
+ Between internal or external MSX-MIDI, the hardware configuration and access methods and such is different.
36
+
37
+ What follows is a description of the MSX MIDI hardware configuration.
38
+
39
+ Additionally, regardless of whether timer IC 8253 or 8254 is used, it will henceforth be referred to as "8253".
40
+
41
+ ### 2.1 Block Diagram
42
+
43
+ The MSX-MIDI hardware is organised as follows:
44
+
45
+ ```
46
+ 8251
47
+ MIDI IN +--------+ +-----+
48
+ ---->| RTS|-------------------------->| AND |-----+
49
+ | RXRDY|-------------------------->| | |
50
+ MIDI OUT | DSR|<----------------+ +-----+ |
51
+ <----| DTR|-----------+ +------------------+ +-->+----+
52
+ +--------+<------+ | | | OR |--> INT
53
+ | +-------+ | +-->+----+
54
+ 8253 | | +-----+ | |
55
+ +--------+ |500KHz +------>| AND |--+--+
56
+ 4 MHz --+-->| TIMER0 |----+ +--->| |
57
+ | +--------+ +-----+ | +-----+
58
+ | | TIMER1 |<---+---->|S FF|--+
59
+ | +--------+ | +->|R |
60
+ +-->| TIMER2 |----+ | +-----+
61
+ +--------+ |
62
+ 0EAh Write
63
+ ```
64
+ Figure 4.1 MSX-MIDI block diagram
65
+
66
+
67
+ ### 2.2 Internal MIDI interface
68
+
69
+ The I/O ports of the built-in MSX-MIDI interface are assigned as follows:
70
+
71
+ #### 8251 interface (address 0E8H, 0E9H)
72
+
73
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
74
+ |:--|:--|:--|:--|:--|:--|:--|:--|:--|
75
+ |**0E8H** (Read)|RXD7|RXD6|RXD5|RXD4|RXD3|RXD2|RXD1|RXD0|
76
+ |**0E8H** (Write)|TXD7|TXD6|TXD5|TXD4|TXD3|TXD2|TXD1|TXD0|
77
+
78
+ |||
79
+ |:--|:--|
80
+ |RXD7-RXD0|8251 receive data|
81
+ |TXD7-TXD0|8251 transmit data|
82
+
83
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
84
+ |:--|:--|:--|:--|:--|:--|:--|:--|:--|
85
+ |**0E9H** (Read)|DSR|BRK|FE|OE|PE|EMPT|RRDY|TRDY|
86
+
87
+ ||||
88
+ |:--|:--|:--|
89
+ |DSR|8253 timer interrupt flag|(1=interrupt occurs)|
90
+ |BRK|8251 break code detection|(1=detected)|
91
+ |FE|8251 frame error flag|(1=error occurs)|
92
+ |OE|8251 overrun error flag|(1=error occurs)|
93
+ |PE|8251 parity error flag|(1=parity error occurs)|
94
+ |EMPT|8251 transmit buffer status|(1=transmit buffer empty)|
95
+ |RRDY|8251 receive buffer status|(1=data available)|
96
+ |TRDY|8251 transmit status|(1=transmission possible)|
97
+
98
+ |**0E9H** (Write)|b7|b6|b5|b4|b3|b2|b1|b0|
99
+ |:--|:--|:--|:--|:--|:--|:--|:--|:--|
100
+ |Mode|S2|S1|EP|PEN|L2|L1|B2|B1|
101
+ |Command|EH|IR|RIE|ER|SBRK|RE|TIE|TEN|
102
+
103
+ |||
104
+ |:--|:--|
105
+ |EH|Normally set to 0|
106
+ |IR|Normally set to 0|
107
+ |RIE|MIDI IN interrupt enable|(1=enable, 0=disable)
108
+ |ER|Error reset|(1=reset error flag, 0=no operation)|
109
+ |SBRK|Normally set to 0|
110
+ |RE|MIDI IN receive enable|(1=enable, 0=disable)|
111
+ |TIE|8253 timer (counter #2) interrupt enable|(1=enable, 0=disable)|
112
+ |TEN|MIDI OUT transmit enable|(1=enable, 0=disable)|
113
+
114
+ For 8251 command / mode register writes, a recovery time of at most 16 clock ticks (at 3.579545MHz) is necessary. When writing to the command / mode register continuously, please insert a wait to allow the 8251 to reinitialise.
115
+
116
+ By writing 00H, 00H, 00H, 40H to I/O port 0E9H, the 8251 is reset. It will no longer function as MIDI if an incorrect mode value is configured, so after a reset always set it to a specific value.
117
+
118
+ For more information, please see the [sample program](#42-sample-program).
119
+
120
+ #### 8253 OUT2 latch pin signal (address 0EAH, 0EBH)
121
+
122
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
123
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
124
+ |**0EAH** (Write)|-|-|-|-|-|-|-|-|
125
+
126
+ - Reading address 0EAH is invalid
127
+ - Address 0EBH is an image of 0EAH
128
+
129
+ The interrupt from counter #2 is released by writing any data to address 0EAH.
130
+
131
+ #### 8253 Interface (address 0ECH-0EFH)
132
+
133
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
134
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
135
+ |**0ECH** (R/W)|CT07|CT06|CT05|CT04|CT03|CT02|CT01|CT00|
136
+ |**0EDH** (R/W)|CT17|CT16|CT15|CT14|CT13|CT12|CT11|CT10|
137
+ |**0EEH** (R/W)|CT27|CT26|CT25|CT24|CT23|CT22|CT21|CT20|
138
+ |**0EFH** (Read)|-|-|-|-|-|-|-|-|
139
+ |**0EFH** (Write)|SC1|SC0|RW1|RW0|M2|M1|M0|BCD|
140
+
141
+ |||
142
+ |:--|:--|
143
+ |CT07-CT00|Counter #0|
144
+ |CT17-CT10|Counter #1|
145
+ |CT27-CT20|Counter #2|
146
+ |SC1, SC0|Counter select, command select|
147
+ |RW1, RW0|Counter read-write mode|
148
+ |M2, M1, M0|Counter mode|
149
+ |BCD|Binary / BCD count select|
150
+
151
+ The function of each counter is as follows:
152
+ - **Counter #0:** Is used as the 8251's baud rate generator. A 4 MHz clock signal is input to the CLK pin. For the 8251, it must be configured to transmit a baud rate clock of 500 KHz (divided by 8). Use mode 3 (square wave divide-by-N mode).
153
+ - **Counter #1:** Can be used as general-purpose counter. The output of counter #2 is input to the CLK pin.
154
+ - **Counter #2:** Used as a periodic interrupt to the CPU (used by BASIC for 5 ms interval interrupts). Normally, mode 2 (divide-by-N mode) is used. OUT2 pin goes low, and through the latch circuit a CPU interrupt is generated. A 4 MHz clock is input to the CLK pin.
155
+
156
+ ### 2.3 External MIDI Interface
157
+
158
+ The external MSX-MIDI interface's I/O port address can be changed by setting a value to I/O port 0E2H.
159
+
160
+ #### MIDI interface configuration (address 0E2H, 0EAH)
161
+
162
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
163
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
164
+ |**0E2H** (Write)|EN|-|-|-|-|-|-|E8|
165
+
166
+ |||
167
+ |:--|:--|
168
+ |EN|MIDI interface usage allow / denyInitial value is 1 (0=allow, 1=deny)|
169
+ |E8|8251 address configurationInitial value is 1 (1=address 0E0H,0E1H 0=address 0E8H,0E9H)
170
+
171
+ Set bit E8 to 0, and the external cartridge MIDI interface's I/O ports change from 0E2H to 0EAH, becoming compatible with the internal MIDI interface. Also, the 8251's I/O address becomes 0E8H and 0E9H.
172
+
173
+ Set bit E8 to 1 and the 8251 interface addresses will be 0E0H and 0E1H, and access to the cartridge's I/O ports 0ECH-0EFH will be prohibited. Additionally, the 8253's timer interrupt is also inhibited.
174
+
175
+ #### 8251 interface (address 0E0H, 0E1H)
176
+
177
+ (in case E8 bit is 1)
178
+
179
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
180
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
181
+ |**0E0H** (Read)|RXD7|RXD6|RXD5|RXD4|RXD3|RXD2|RXD1|RXD0|
182
+ |**0E0H** (Write)|TXD7|TXD6|TXD5|TXD4|TXD3|TXD2|TXD1|TXD0|
183
+
184
+ |||
185
+ |:--|:--|
186
+ |RXD7-RXD0|8251 receive data|
187
+ |TXD7-TXD0|8251 transmit data|
188
+
189
+ ||b7|b6|b5|b4|b3|b2|b1|b0|
190
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
191
+ |**0E1H** (Read)|DSR|BRK|FE|OE|PE|EMPT|RRDY|TRDY|
192
+
193
+ ||||
194
+ |:--|:--|:--|
195
+ |DSR|8253 timer interrupt flag|(1=interrupt occurs)|
196
+ |BRK|8251 break code detection|(1=detected)|
197
+ |FE|8251 frame error flag|(1=error occurs)|
198
+ |OE|8251 overrun error flag|(1=error occurs)|
199
+ |PE|8251 parity error flag|(1=parity error occurs)|
200
+ |EMPT|8251 transmit buffer status|(1=transmit buffer empty)|
201
+ |RRDY|8251 receive buffer status|(1=data available)|
202
+ |TRDY|8251 transmit status|(1=transmission possible)|
203
+
204
+ |**0E1H** (Write)|b7|b6|b5|b4|b3|b2|b1|b0|
205
+ |:--|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
206
+ |Mode|S2|S1|EP|PEN|L2|L1|B2|B1|
207
+ |Command|EH|IR|RIE|ER|SBRK|RE|TIE|TEN|
208
+
209
+ ||||
210
+ |:--|:--|:--|
211
+ |EH|Normally set to 0||
212
+ |IR|Normally set to 0||
213
+ |RIE|MIDI IN interrupt enable|(1=enable, 0=disable)|
214
+ |ER|Error reset|(1=reset error flag, 0=no operation)|
215
+ |SBRK|Normally set to 0||
216
+ |RE|MIDI IN receive enable|(1=enable, 0=disable)|
217
+ |TIE|8253 timer (counter #2) interrupt enable|(1=enable, 0=disable)|
218
+ |TEN|MIDI OUT transmit enable|(1=enable, 0=disable)|
219
+
220
+ ### 2.4 Method to distinguish internal from external type
221
+
222
+ In case bit 0 of MAIN ROM address 002EH is 1, the MSX-MIDI is internal.
223
+
224
+ In models whose MAIN ROM version number (002DH) is 03H or more, the features of the MSX-MIDI can be used with an external cartridge.
225
+
226
+ In the internal type and the external type, the hook is different.
227
+
228
+ This distinction is important in order to create an application. For hooks, please see 3.2 "Hooks" and chapter 4 "Application development".
229
+
230
+ To make the distinction between internal type and external type, examine the string starting at MSX MIDI ROM address 4018H.
231
+
232
+ Table 4.1 String to distinguish MSX-MIDI
233
+
234
+ |Address|Internal|External|
235
+ |:--|:-:|:-:|
236
+ |4018H|41H (A)|??H (?)|
237
+ |4019H|50H (P)|??H (?)|
238
+ |401AH|52H (R)|??H (?)|
239
+ |401BH|4CH (L)|??H (?)|
240
+ |401CH|4FH (O)|4DH (M)|
241
+ |401DH|50H (P)|49H (I)|
242
+ |401EH|4CH (L)|44H (D)|
243
+ |401FH|4CH (L)|49H (I)|
244
+
245
+ In external cartridges, the 4 unspecified bytes at 4018H are different for each manufacturer. The data at 401CH consists of "MIDI".
246
+
247
+ ### 2.5 Method to detect presence of MIDI interface
248
+
249
+ The presence or absence of the MIDI interface can be determined in the following manner:
250
+
251
+ 1. In case MAIN ROM address 002EH bit 0 is 1, the MIDI interface is internal.
252
+ 2. In case the MAIN ROM version number (002DH) is 03H or more, look for a slot which contains the following in 401CH-401FH: `DB "MIDI"`. If it exists, the external cartridge is inserted.
253
+ 3. When the above cases do not apply, since there is no MIDI interface, the MIDI function can not be used.
254
+ 4. In case the ROM version number is 02H or less, the MIDI interface can not be used.
255
+
256
+ ## Chapter 3: Interrupts
257
+
258
+ ### 3.1 Interrupts in BASIC
259
+
260
+ 1/60 sec (NTSC) or 1/50 sec (PAL) interrupts have been used for the MSX-MUSIC, but in the MSX-MIDI BASIC extensions 5 ms interrupts from the 8253 are used.
261
+
262
+ ### 3.2 Hooks
263
+
264
+ The MSX turbo R built-in MSX-MIDI's hooks are as follows:
265
+
266
+ Table 4.2 Internal MSX-MIDI hooks
267
+
268
+ |Address|Name|Former name|Content|
269
+ |:-:|:--|:--|:--|
270
+ |0FF75H|H.MDIN|H.OKNORM|MIDI IN interrupt|
271
+ |0FF93H|H.MDTM|H.FRQINT|8253 timer interrupt|
272
+
273
+ In case of external cartridge, because these hooks can not be used, please use H.KEYI. Usage details are described in chapter 4 "Application Development".
274
+
275
+ Table 4.3 External MSX-MIDI hooks
276
+
277
+ |Address|Name|
278
+ |0FD9AH|H.KEYI|
279
+
280
+ ## Chapter 4: Application Development
281
+
282
+ ### 4.1 Notes regarding application development
283
+
284
+ When creating an application program that supports MSX-MIDI, please note the following points:
285
+
286
+ 1. The hooks are different depending on whether MIDI is built-in or external. When setting up a hook, please check if the type is internal or external.
287
+ 2. When enabling interrupts, such as after MIDI interface initialization, because there is a possibility that the interrupt flag has already been set, the interrupt flag must be reset. Interrupt flags are as follows:
288
+
289
+ - Table 4.4 MIDI interface interrupt flags
290
+
291
+ |Interrupt type|Interrupt distinction|Interrupt clear method|
292
+ |:--|:--|:--|
293
+ |Timer|Bit 7 (DSR) of 0E9H or 0E1H|Write any value to 0EAH|
294
+ |MIDI IN|Bit 0 (RRDY) of 0E9H or 0E1H|Read 0E8H with IN instruction|
295
+
296
+ 3. With the external cartridge, other interrupts besides MIDI IN and 8253 timer also come from H.KEYI. Therefore, the interrupt handling routine must detect what kind of interrupt the current interrupt is.
297
+ - Whether or not it is a MIDI IN interrupt can be checked in bit 1 of I/O port address 0E9H.
298
+ - Whether or not it is an interrupt from the 8253 timer can be checked in bit 7 of I/O port address 0E9H.
299
+ 4. At the shortest, the MIDI IN receive interrupt occurs at 320 µs intervals. When calling an interrupt handling routine from the hook with the RST 30H instruction, the inter-slot call takes time to process and will not complete in time for 320 µs interval reception. For that reason, set up interrupts as follows:
300
+ - Place the interrupt handling routine in page 3
301
+ - Jump from the hook to the interrupt handling routine with the JP instruction
302
+
303
+ ### 4.2 Sample program
304
+
305
+ For MIDI interface and hook set up / tear down, please refer to the next sample program (THRU.MAC):
306
+
307
+ ```
308
+ ;
309
+ ; thru.mac
310
+ ;
311
+ ;
312
+ ; thru.com gets data from MIDI IN port
313
+ ; and send them out to MIDI OUT port.
314
+ ;
315
+ .z80
316
+ cseg
317
+ ;
318
+ ; BIOS entry
319
+ ;
320
+ rdslt equ 000ch ;read slot
321
+ calslt equ 001ch ;call slot
322
+ doscal equ 0005h ;dos call
323
+ ;
324
+ ; character code
325
+ ;
326
+ lf equ 0ah ;line feed
327
+ cr equ 0dh ;carrige return
328
+ esc equ 1bh ;escape sequence
329
+ ;
330
+ ; MIDI interface I/O
331
+ ;
332
+ setcart equ 0e2h ;MIDI cartridge setting
333
+ UARTsend equ 0e8h ;8251 data transmit
334
+ UARTrecv equ 0e8h ;8251 data receive
335
+ UARTcmd equ 0e9h ;8251 command/mode register
336
+ UARTstat equ 0e9h ;8251 status
337
+ tm_int equ 0eah ;timer interrupt flag off
338
+ timer0 equ 0ech ;8253 counter #0
339
+ timer2 equ 0eeh ;8253 counter #2
340
+ tm_cmd equ 0efh ;8253 command
341
+ ;
342
+ ; hooks
343
+ ;
344
+ h.oknorm equ 0ff75h
345
+ h.mdin equ h.oknorm ;Hook for MIDI IN
346
+ h.frqint equ 0ff93h
347
+ h.mdtm equ h.frqint ;Hook for 8253 timer
348
+ h.keyi equ 0fd9ah ;Hook for 8253 timer
349
+
350
+ ;
351
+ ; Set hooks
352
+ ;
353
+ setmidi:
354
+ call chkmidi ;Have I MIDI interface ?
355
+ jp c,nomidi ; No
356
+ di
357
+ jr z,setho2 ;MIDI interface is not built in
358
+ ;
359
+ ; Setting for built-in MIDI interface
360
+ ;
361
+ ld hl,h.mdtm ;save hook (8253 timer)
362
+ ld de,hoksvt ;set address to save area
363
+ push hl ;save hook address
364
+ call copy5 ;copy old hook
365
+ ld hl,hokmdt ;set address to new hook data
366
+ pop de ;get hook address
367
+ call copy5 ;set new hook
368
+ ;
369
+ ld hl,h.mdin ;save hook (MIDI IN)
370
+ ld de,hoksvt+5 ;set address to save area
371
+ push hl ;save hook address
372
+ call copy5 ;copy old hook
373
+ ld hl,hokmdi ;set address to new hook data
374
+ pop de ;get hook address
375
+ call copy5 ;set new hook
376
+ jr inimdp
377
+ ;
378
+ ; Setting for MIDI cartridge
379
+ ;
380
+ setho2:
381
+ xor a
382
+ out (setcart),a ;set cartridge as same as built-in I/F
383
+ ld hl,h.keyi ;save hook
384
+ ld de,hoksvt ;set address to save area
385
+ push hl ;save hook address
386
+ call copy5 ;copy old hook
387
+ ld hl,hokmdc ;set address to new hook data
388
+ pop de ;get hook address
389
+ call copy5 ;set new hook
390
+ xor a
391
+ out (setcart),a ;set MIDI cartridge I/O
392
+ jr inimdp
393
+ ;
394
+ ; Here when no MIDI interface.
395
+ ; Print message and return to DOS.
396
+ ;
397
+ nomidi:
398
+ ld de,msg0
399
+ ld c,9
400
+ call doscal
401
+ ret
402
+ msg0: db cr,lf,'MIDI interface is not found.$'
403
+
404
+ copy5:
405
+ ld bc,5
406
+ ldir
407
+ ret
408
+ ;
409
+ ; Hook Definition
410
+ ;
411
+ hokmdi: ;hook for MIDI IN
412
+ jp midiin
413
+ ret
414
+ ret
415
+ hokmdt: ;hook for 8253timer
416
+ jp mdtmin
417
+ ret
418
+ ret
419
+ hokmdc: ;hook for MIDI cartridge
420
+ jp mdintr
421
+ ret
422
+ ret
423
+
424
+ ;
425
+ ; Initialize MIDI Interface
426
+ ;
427
+ inimdp:
428
+ ;
429
+ ; MIDI baud rate generater
430
+ ;
431
+ ld a,00010110b ;8253 Control Word
432
+ ; |||||||+----- Binary Count
433
+ ; ||||+++------ Mode 3 :Rate Generater (Square Wave)
434
+ ; ||++--------- LSB Read/Load
435
+ ; ++----------- Counter #0 for Baud Rate Generater of 8251
436
+ ;
437
+ out (tm_cmd),a
438
+ ld a,8 ; Set Counter. 4MHz / 8 = 500KHz
439
+ out (timer0),a ; Set 8253 Counter (LSB)
440
+ ;
441
+ ; 5msec timer
442
+ ;
443
+ ld a,10110100b ;8253 Control Word
444
+ ; |||||||+----- Binary Count
445
+ ; ||||+++------ Mode 2 :Rate Generater
446
+ ; ||++--------- 2bytes Read/Load
447
+ ; ++----------- Counter #2 for 5msec timer
448
+ ;
449
+ out (tm_cmd),a
450
+ ld hl,20000
451
+ ld a,l ;
452
+ out (timer2),a ; Set 8253 Counter (LSB)
453
+ ld a,h
454
+ out (timer2),a ; Set 8253 Counter (MSB)
455
+ ;
456
+ ; Initialize 8251
457
+ ;
458
+ xor a ; Reset 8251
459
+ out (UARTcmd),a ; Set 0
460
+ call waits
461
+ out (UARTcmd),a ; Set 0
462
+ call waits
463
+ out (UARTcmd),a ; Set 0
464
+ call waits
465
+ ld a,40h
466
+ out (UARTcmd),a ; Set 40h
467
+ call waits
468
+ ;
469
+ ; Set 8251
470
+ ;
471
+ ld a,01001110b ;8251 MODE Instruction
472
+ ; ||||||++----- Baud Rate :*16 ( 500KHz/16 = 31.25KHz )
473
+ ; ||||++------- Character Length : 8bits
474
+ ; ||++--------- Parity Disable
475
+ ; ++----------- Stop Bit : 1bit
476
+ ;
477
+ out (UARTcmd),a
478
+ call waits
479
+ ld a,00100111b ;8251 COMMAND Instruction
480
+ ; |||||||+----- Transmit : Enable
481
+ ; ||||||+------ ~DTR = LOW : 8253timer enable
482
+ ; |||||+------- Receive : Enable
483
+ ; ||||+-------- Send Break Character : Normal
484
+ ; |||+--------- Error Reset : No Operation
485
+ ; ||+---------- ~RTS = LOW : MIDI IN enable
486
+ ; |+----------- No Operation
487
+ ; +------------ No Operation
488
+ ;
489
+ ld (cmdsv),a ;save command
490
+ out (UARTcmd),a
491
+ in a,(UARTrecv) ;interrupt flag reset
492
+ xor a
493
+ out (tm_int),a
494
+ ld de,msg1 ;print message
495
+ ld c,9
496
+ call doscal
497
+ ei
498
+ jp main
499
+
500
+ msg1: db cr,lf,'MIDI interface and hooks are set',cr,lf,'$'
501
+
502
+ ;
503
+ ; main routine
504
+ ;
505
+ ; Get data from buffer and print it.
506
+ ; If overrun error, then print '*'.
507
+ ;
508
+ main:
509
+ ld hl,mdbuf ;set pointer
510
+ ld (putp),hl
511
+ ld (getp),hl
512
+ main1:
513
+ call getdat ;get MIDI IN data
514
+ in a,(UARTstat)
515
+ and 00010000b ;overrun error ?
516
+ jr z,main2 ;no
517
+ ld de,msg2
518
+ ld c,9
519
+ call doscal ;print '*'
520
+ ld a,(cmdsv) ;8251 command
521
+ or 00010000b ;reset 8251
522
+ out (UARTcmd),a ;reset 8251 error flag
523
+ main2:
524
+ ld c,0bh ;console check
525
+ call doscal
526
+ or 0 ;is there any input ?
527
+ jr z,main1 ;no , loop again
528
+ jp rstmidi
529
+
530
+ msg2: db cr,lf,'*',cr,lf,'$'
531
+ ;
532
+ ; Get data from buffer
533
+ ;
534
+ getdat:
535
+ ld hl,(getp)
536
+ ld de,(putp)
537
+ scf
538
+ ccf
539
+ sbc hl,de ;no data in buffer ?
540
+ ret z ;no data , then ret
541
+ ld hl,(getp)
542
+ ld a,(hl) ;get data from buffer
543
+ ld c,a
544
+ getda0:
545
+ in a,(UARTstat) ;get 8251 status
546
+ and 1 ;can I transmit ?
547
+ jr z,getda0 ;no , check again
548
+ ld a,c
549
+ out (UARTsend),a ;MIDI OUT
550
+ cp 0f8h ;if it is 'f8'(MIDI sync timing clock)
551
+ jr z,getda2 ; then not print it
552
+ cp 0feh ;if it is 'fe'(active sensing)
553
+ jr z,getda2 ; then not print it
554
+ cp 80h ;is it data-byte ?
555
+ jr c,getda1 ;yes , skip
556
+ push af ;if it is status-byte ,...
557
+ ld de,msg3
558
+ ld c,9
559
+ call doscal ; then delete a line
560
+ pop af
561
+ getda1:
562
+ call prnbyt ;print it
563
+ getda2:
564
+ ld hl,(getp)
565
+ inc hl ;increment 'getp' pointer
566
+ ld de,bufend
567
+ push hl
568
+ scf
569
+ ccf
570
+ sbc hl,de ;end of buffer ?
571
+ pop hl
572
+ jr nz,getda3 ;no
573
+ ld hl,mdbuf
574
+ getda3:
575
+ ld (getp),hl ;save pointer
576
+ ret
577
+ msg3: db esc,'M$'
578
+
579
+ ;
580
+ ; Print 1byte data (hex)
581
+ ;
582
+ prnbyt:
583
+ push af
584
+ srl a
585
+ srl a
586
+ srl a
587
+ srl a ;shift 4 bits
588
+ call prnby2 ;print HIGH
589
+ pop af
590
+ and 0fh
591
+ call prnby2 ;print LOW
592
+ ld e,' ' ;print out space
593
+ ld c,2
594
+ call doscal ;dos call 02h = console print out
595
+ ret
596
+ prnby2:
597
+ cp 10 ; [a] < 10 ?
598
+ jr c,prnby3 ; yes , jump
599
+ add a,'A'-10-'0' ; adjust data ('A'~'F')
600
+ prnby3:
601
+ add a,'0'
602
+ ld e,a ;[e] = character code
603
+ ld c,2
604
+ call doscal ;dos call 02h = console print out
605
+ ret
606
+
607
+ ;
608
+ ; Reset MIDI interface and reset hooks
609
+ ;
610
+ rstmidi:
611
+ di
612
+ ; Reset 8251
613
+ ; RTS = HIGH : MIDI IN disable
614
+ ; DTR = HIGH : 8253timer disable
615
+ ld a,00000001b ;8251 COMMAND Instruction
616
+ ; |||||||+----- Transmit : Enable
617
+ ; ||||||+------ ~DTR = High
618
+ ; |||||+------- Receive : Disable
619
+ ; ||||+-------- Send Break Character : Normal
620
+ ; |||+--------- Error Reset : No Operation
621
+ ; ||+---------- ~RTS = High
622
+ ; |+----------- No Operation
623
+ ; +------------ No Operation
624
+ ;
625
+ out (UARTcmd),a
626
+
627
+ call chkmd2
628
+ jr z,rstmd1 ;if not built-in , then jump
629
+ ;
630
+ ; Reset built-in MIDI interface
631
+ ;
632
+ ld de,h.mdtm ;restore hook
633
+ ld hl,hoksvt ;save area
634
+ call copy5
635
+ ld de,h.mdin
636
+ ld hl,hoksvt+5 ;save area
637
+ call copy5
638
+ jr rstmd2
639
+ ;
640
+ ; Reset MIDI cartridge
641
+ ;
642
+ rstmd1:
643
+ ld de,h.keyi ;restore hook
644
+ ld hl,hoksvt ;save area
645
+ call copy5
646
+ rstmd2:
647
+ ei
648
+ ld de,msg4 ;print message
649
+ ld c,9
650
+ call doscal
651
+ ret
652
+
653
+ msg4: db cr,lf,'MIDI interface and hooks are reset$'
654
+
655
+ ;
656
+ ; Interrupt routin
657
+ ;
658
+
659
+ ;
660
+ ; For MIDI cartridge
661
+ ;
662
+ mdintr:
663
+ in a,(UARTstat) ;MIDI IN ?
664
+ and 00000010B
665
+ jr z,mdint1 ;no
666
+ call intr_in ;yes
667
+ jr mdintr ;MIDI IN check again
668
+ mdint1:
669
+ in a,(UARTstat) ;8253 timer ?
670
+ and 10000000B
671
+ call nz,intr_time ;yes
672
+ jp hoksvt
673
+
674
+ ;
675
+ ; For built-in MIDI interface
676
+ ;
677
+ ; MIDI IN
678
+ midiin:
679
+ in a,(UARTstat) ;MIDI IN ?
680
+ and 00000010B
681
+ jr z,midin1 ;no
682
+ call intr_in ;yes
683
+ jr midiin ;MIDI IN check again
684
+ midin1:
685
+ ei
686
+ jp hoksvt+5
687
+
688
+ ; 5msec timer
689
+ mdtmin:
690
+ in a,(UARTstat) ;8253 timer ?
691
+ and 10000000B
692
+ call nz,intr_time ;yes
693
+ jp hoksvt
694
+
695
+ ;
696
+ ; MIDI IN interrupt
697
+ ;
698
+ intr_in:
699
+ in a,(UARTrecv) ;read MIDI IN data and reset interrupt flag
700
+ ld hl,(putp)
701
+ ld (hl),a ;save to buffer
702
+ inc hl ;increment 'putp'
703
+ ld de,bufend ;
704
+ push hl
705
+ sbc hl,de ;buffer end ?
706
+ pop hl
707
+ jr nz,mdin2 ;no, jump
708
+ ld hl,mdbuf
709
+ mdin2:
710
+ ld (putp),hl ;set 'putp'
711
+ ret
712
+ ;
713
+ ; timer interrupt
714
+ ;
715
+ intr_time:
716
+ ld a,(cmdsv) ;check timer interrupt enable or not.
717
+ and 00000010b ;enable ?
718
+ ret z ;no
719
+ xor a
720
+ out (tm_int),a ;reset interrupt flag
721
+ ret
722
+
723
+ ;
724
+ ; Check MIDI interface
725
+ ; Return : [CF]=1 no MIDI interface
726
+ ; : [CF]=0 , [ZF]=1 found MIDI cartridge
727
+ ; : [CF]=0 , [ZF]=0 MIDI interface is built in
728
+ ;
729
+ ver_id1 equ 002dh ;MAIN ROM Version ID
730
+ ver_id2 equ 002eh ;MIDI interface ID
731
+ exptbl equ 0fcc1h ;slot expanded table
732
+ chkmidi:
733
+ ld a,(exptbl)
734
+ ld hl,ver_id1
735
+ call rdslt ;read Main ROM version ID
736
+ cp 3
737
+ ret c ;MSX1,MSX2,MSX2+ return
738
+ call chkmd2 ;read MIDI interface ID
739
+ ret nz ;MIDI interface is built in
740
+ ld b,4
741
+ chkro1:
742
+ push bc ;save counter
743
+ ld a,4
744
+ sub b ;primary slot number
745
+ ld c,a ;save
746
+ ld hl,exptbl
747
+ ld a,c
748
+ add a,l ;set exptbl
749
+ ld l,a
750
+ ld a,(hl)
751
+ and 10000000B ;expanded ?
752
+ jr z,chkro3 ;no
753
+ ld b,4 ;number of expanded slots
754
+ chkro2: ;search expanded slot
755
+ push bc
756
+ ld a,00100100B
757
+ sub b ;001000nnB
758
+ rlc a
759
+ rlc a ;1000nn00B
760
+ or c ;1000nnmmB = slot address
761
+ call chkid ;check MIDI ID
762
+ pop bc
763
+ jr z,chkroy ;found MIDI ID
764
+ djnz chkro2 ;next expanded slot
765
+ pop bc
766
+ jr chkro4 ;next slot
767
+ chkro3: ;search primary slot
768
+ ld a,c ;set slot address
769
+ call chkid ;check MIDI ID
770
+ pop bc
771
+ jr z,chkroz ;found MIDI ID
772
+ chkro4:
773
+ djnz chkro1 ;search next slot
774
+ scf ;no MIDI ID
775
+ ret
776
+ chkroy:
777
+ pop bc
778
+ chkroz:
779
+ xor a ;set Z flag, reset Cy flag
780
+ ret
781
+
782
+ ;
783
+ ; Is MIDI interface built in ?
784
+ ; Return : [ZF]=1 built in
785
+ ; : [ZF]=0 not built in
786
+ ;
787
+ chkmd2:
788
+ ld a,(exptbl)
789
+ ld hl,ver_id2
790
+ call rdslt ;read MIDI interface ID
791
+ and 1 ;set Zflag
792
+ ret
793
+
794
+ ;
795
+ ; Check MIDI ID
796
+ ;
797
+ ; Entry :[A]=slot address
798
+ ; Return:Z flag is set if MIDI ID is found
799
+ ;
800
+ id_string: db 'MIDI'
801
+ id_address equ 401ch ;MIDI ID address
802
+ chkid:
803
+ push bc
804
+ ld de,id_string
805
+ ld hl,id_address
806
+ ld b,4 ;length of id_string
807
+ chkid1:
808
+ push af
809
+ push bc
810
+ push de
811
+ call rdslt ;read data
812
+ pop de
813
+ pop bc
814
+ ld c,a ;save data
815
+ ld a,(de) ;get char
816
+ cp c ;same ?
817
+ jr nz,chkid2 ;no
818
+ pop af ;restore slot address
819
+ inc de ;next char
820
+ inc hl
821
+ djnz chkid1 ;check next char
822
+ pop bc ;restore environment
823
+ xor a ;I found ID
824
+ ret
825
+ chkid2:
826
+ pop af ;restore slot address
827
+ pop bc ;restore environment
828
+ xor a
829
+ inc a ;worng ID
830
+ ret
831
+
832
+ ;
833
+ ; Wait routine
834
+ ;
835
+ stimec equ 0e6h ;system timer clear
836
+ stimeh equ 0e7h ;system timer High
837
+ waits:
838
+ push af
839
+ push bc
840
+ ld c,1
841
+ out (stimec),a ;clear timer
842
+ waitlp:
843
+ in a,(stimeh) ; get counter
844
+ cp c
845
+ jr c,waitlp ; loop
846
+ pop bc
847
+ pop af
848
+ ret
849
+
850
+ ;
851
+ ; Workarea definition
852
+ ;
853
+ hoksvt: ds 10 ;hook save area
854
+ cmdsv: ds 1 ;8251 command save area
855
+ getp: ds 2 ;pointer for getting MIDI data
856
+ putp: ds 2 ;pointer for putting MIDI data
857
+ mdbuf: ds 128 ;buffer for MIDI IN
858
+ bufend equ $ ;end of buffer
859
+
860
+ ; end
861
+ ```
862
+
863
+ ## Chapter 5: BASIC Extensions
864
+
865
+ _[TODO]_
866
+
867
+
868
+ ~Grauw
869
+ © 2025 MSX Assembly Page. MSX is a trademark of MSX Licensing Corporation.
870
+
871
+
872
+