• R/O
  • SSH
  • HTTPS

mdr: Commit


Commit MetaInfo

Revision105 (tree)
Time2023-10-17 06:28:27
Authormateuszviste

Log Message

added MDR_OPL_TIMER_ functions

Change Summary

Incremental Difference

--- trunk/inc/mdr/opl.h (revision 104)
+++ trunk/inc/mdr/opl.h (revision 105)
@@ -70,6 +70,12 @@
7070 unsigned char conn; /* Synthesis type: 0=FM / 1=Additive */
7171 };
7272
73+enum MDR_OPL_TIMER {
74+ MDR_OPL_TIMER_80US = 2,
75+ MDR_OPL_TIMER_320US = 3
76+};
77+
78+
7379 /* frequency groups, to be used with mdr_opl_noteon() and mdr_opl_notebend().
7480 * There are 7 frequency groups to choose from. Each group supports a different
7581 * span of frequencies. Higher groups have wider spans, but at the cost of larger
@@ -207,4 +213,29 @@
207213 * playback quality. */
208214 unsigned short mdr_opl_imf_play(void *imf, unsigned short imflen, unsigned short clock);
209215
216+
217+/*****************************************************************************
218+ * OPL TIMER FUNCTIONS *
219+ *****************************************************************************/
220+
221+/* configures and starts a timer given type so it emits a tick every count
222+ * periods. Two timer types are available:
223+ * MDR_OPL_TIMER_80US - with a period of 80us
224+ * MDR_OPL_TIMER_320US - with a period of 320us
225+ * count may range from 0 to 255, but 0 means "256 periods".
226+ *
227+ * You may use only one timer at a time.
228+ *
229+ * EXAMPLE: setting up MDR_OPL_TIMER_80US with a count of 25 would make the
230+ * timer tick exactly every 2ms (25 * 80us). */
231+void mdr_opl_timer_set(enum MDR_OPL_TIMER timertype, unsigned char count);
232+
233+/* returns 1 if timer tick occured, 0 otherwise. After a tick has been
234+ * returned, this function will return 0 until next tick.
235+ *
236+ * it is important to note that there is no way to know whether one tick
237+ * passed since last time, or more, so it is up to you to make sure you call
238+ * this function fast enough. */
239+unsigned char mdr_opl_timer_tick(void);
240+
210241 #endif
--- trunk/opl/opltimer.c (nonexistent)
+++ trunk/opl/opltimer.c (revision 105)
@@ -0,0 +1,97 @@
1+/*
2+ * OPL2/OPL3 Timers
3+ *
4+ * This file is part of the Mateusz' DOS Routines (MDR): http://mdr.osdn.io
5+ * Published under the terms of the MIT License, as stated below.
6+ *
7+ * Copyright (C) 2015-2023 Mateusz Viste
8+ *
9+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10+ * of this software and associated documentation files (the "Software"), to
11+ * deal in the Software without restriction, including without limitation the
12+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
13+ * sell copies of the Software, and to permit persons to whom the Software is
14+ * furnished to do so, subject to the following conditions:
15+ *
16+ * The above copyright notice and this permission notice shall be included in
17+ * all copies or substantial portions of the Software.
18+ *
19+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25+ * IN THE SOFTWARE.
26+ */
27+
28+
29+/* the OPL2 hardware features two high-resolution timers:
30+ *
31+ * timer 1: 12.5 kHz
32+ * this is an 8-bit clock that counts forward at a rate of 12.5 kHz (ie. a
33+ * single step duration is 80us). It takes the value preset in register 02,
34+ * increments it until it overflows and sets the 7th bit of the status register
35+ * (flag 0x40 in reg 1).
36+ *
37+ * timer 2: 3.125 kHz
38+ * Same as timer 1, but with a different frequency (each step duration is
39+ * 320 us), preset register is register 03 and overflow sets the 6th bit of the
40+ * status register (flag 0x20 in reg 1).
41+ *
42+ * Resetting the "timer overflow" flag in the status register is done by
43+ * writing 0x80 to register 04. This resets both Timer 1 and Timer 2.
44+ *
45+ * To initialize (start) Timer 1, write 0x41 to register 04.
46+ * To initialize (start) Timer 2, write 0x22 to register 04.
47+ *
48+ * Because the timer overflow reset flag is shared by the two timers, it is
49+ * highly impractical to use both timers at the same time.
50+ */
51+
52+#include <conio.h> /* inp() */
53+
54+#include <mdr/opl.h>
55+
56+
57+/* configures and starts a timer given type so it emits a tick every count
58+ * periods. Two timer types are available:
59+ * MDR_OPL_TIMER_80US - with a period of 80us
60+ * MDR_OPL_TIMER_320US - with a period of 320us
61+ * count may range from 0 to 255, but 0 means "256 periods".
62+ *
63+ * You may use only one timer at a time.
64+ *
65+ * EXAMPLE: setting up MDR_OPL_TIMER_80US with a count of 25 would make the
66+ * timer tick exactly every 2ms (25 * 80us). */
67+void mdr_opl_timer_set(enum MDR_OPL_TIMER timertype, unsigned char count) {
68+ /* stop the timers */
69+ mdr_opl_regwr(4, 0);
70+
71+ /* reset timer's flags */
72+ mdr_opl_regwr(4, 0x80);
73+
74+ if (timertype == MDR_OPL_TIMER_80US) {
75+ mdr_opl_regwr(2, 256 - count); /* preset val into reg 02 (timer1) */
76+ mdr_opl_regwr(4, 0x41); /* start the timer */
77+ } else {
78+ mdr_opl_regwr(3, 256 - count); /* preset val into reg 03 (timer2) */
79+ mdr_opl_regwr(4, 0x22); /* start the timer */
80+ }
81+}
82+
83+
84+/* returns 1 if timer tick occured, 0 otherwise. After a tick has been
85+ * returned, this function will return 0 until next tick.
86+ *
87+ * it is important to note that there is no way to know whether one tick
88+ * passed since last time, or more, so it is up to you to make sure you call
89+ * this function fast enough. */
90+unsigned char mdr_opl_timer_tick(void) {
91+ /* read status register, is T1 or T2 flag ON? No = abort early */
92+ if ((inp(0x388) & 0x60) == 0) return(0);
93+
94+ /* flag set = reset the timer and return 1 */
95+ mdr_opl_regwr(4, 0x80);
96+ return(1);
97+}
Show on old repository browser