{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Times;}{\f5\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helvetica;}{\f6\fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Courier;}{\f7\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva;}{\f8\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Tms Rmn;}{\f9\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helv;}{\f10\froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;}{\f11\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}MS Sans Serif;}{\f12\froman\fcharset0\fprq2{\*\panose 00000000000000000000}New York;}{\f13\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}System;}{\f14\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f15\fswiss\fcharset0\fprq3{\*\panose 020b0604030504040204}Tahoma;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \f1\fs20\cgrid \snext0 Normal;}{\s1\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{\s2\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\i\f1\cgrid \sbasedon0 \snext0 heading 2;}{\s3\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 3;}{\s4\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\f1\cgrid \sbasedon0 \snext0 heading 4;}{\*\cs10 \additive Default Paragraph Font;}{\s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid \sbasedon0 \snext0 toc 1;}{\s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\adjustright \f2\fs16\cgrid \sbasedon0 \snext16 Code Example;}{\s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid \sbasedon0 \snext0 toc 2;}{\s18\li200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 3;}{\s19\li400\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 4;}{\s20\li600\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 5;}{\s21\li800\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 6;}{\s22\li1000\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 7;}{\s23\li1200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 8;}{\s24\li1400\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext0 toc 9;}{\s25\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \f1\fs20\cgrid \sbasedon0 \snext25 footer;}{\*\cs26 \additive \sbasedon10 page number;}}{\*\listtable{\list\listtemplateid-1\listsimple{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'01*;}{\levelnumbers;}}{\listname ;}\listid-2}}{\*\listoverridetable{\listoverride\listid-2\listoverridecount1{\lfolevel\listoverrideformat{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat0\levelold\levelspace0\levelindent360{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 }}\ls1}}{\*\revtbl {Unknown;}}{\info{\title MultiSound Software Developer's Kit}{\author Jens Puchert}{\operator Michael P. Costantino}{\creatim\yr1997\mo7\dy2\hr13\min54}{\revtim\yr1997\mo7\dy2\hr13\min54}{\version2}{\edmins1}{\nofpages3}{\nofwords15088}{\nofchars86004}{\*\company Voyetra/Turtle Beach}{\nofcharsws105618}{\vern71}}\ftnbj\aenddoc\lytprtmet\hyphcaps0\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \linex0\titlepg\sectdefaultcl {\footer \pard\plain \s25\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\pvpara\phmrg\posxo\posy0\adjustright \f1\fs20\cgrid {\field{\*\fldinst {\cs26 PAGE }}{\fldrslt {\cs26\lang1024 2}}}{\cs26 \par }\pard \s25\fi360\ri360\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright { \par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \nowidctlpar\widctlpar\adjustright \f1\fs20\cgrid {\b\fs72 Turtle Beach MultiSound Software Developer\rquote s Kit \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \qc\nowidctlpar\widctlpar\adjustright {\fs28 Version 2.0 \par }\pard \qc\nowidctlpar\widctlpar\adjustright {\fs28 06/25/97 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\page }{\field\fldedit{\*\fldinst { TOC \\o "1-3" }}{\fldrslt {\lang1024 \par Introduction\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885704 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885704 }}{\fldrslt {\lang1024 4}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885705 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885705 }}{\fldrslt {\lang1024 4}}}}}{\lang1024 \par What you need to use this kit\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885706 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885706 }}{\fldrslt {\lang1024 4}}}}}{\lang1024 \par What you need to have\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885707 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885707 }}{\fldrslt {\lang1024 5}}}}}{\lang1024 \par What is contained in this manual\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885708 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885708 }}{\fldrslt {\lang1024 5}}}}}{\lang1024 \par Notes on the sample applications\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885709 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885709 }}{\fldrslt {\lang1024 6}}}}}{\lang1024 \par Files included with the Toolkit\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885710 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885710 }}{\fldrslt {\lang1024 6}}}}}{\lang1024 \par Applicability:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885711 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885711 }}{\fldrslt {\lang1024 7}}}}}{\lang1024 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\lang1024 CHAPTER 1 - System Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885712 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885712 }}{\fldrslt {\lang1024 7}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Introduction\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885713 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885713 }}{\fldrslt {\lang1024 7}}}}}{\lang1024 \par Hardware Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885714 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885714 }}{\fldrslt {\lang1024 7}}}}}{\lang1024 \par }\pard\plain \s18\li200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid {\lang1024 MultiSound Classic:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885715 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885715 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par MultiSound Tahiti:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885716 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885716 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par MultiSound Monterey:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885717 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885717 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par MultiSound Pinnacle:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885718 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885718 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par MultiSound Fiji:\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885719 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885719 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Device Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885720 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885720 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par }\pard\plain \s18\li200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid {\lang1024 DSP Device\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885721 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885721 }}{\fldrslt {\lang1024 8}}}}}{\lang1024 \par MPU-401 Device\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885722 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885722 }}{\fldrslt {\lang1024 9}}}}}{\lang1024 \par Joystick Device\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885723 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885723 }}{\fldrslt {\lang1024 9}}}}}{\lang1024 \par EIDE Device\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885724 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885724 }}{\fldrslt {\lang1024 9}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Resource Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885725 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885725 }}{\fldrslt {\lang1024 9}}}}}{\lang1024 \par }\pard\plain \s18\li200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid {\lang1024 I/0 Port Usage\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885726 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885726 }}{\fldrslt {\lang1024 9}}}}}{\lang1024 \par DSP Host Port Interface Registers\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885727 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885727 }}{\fldrslt {\lang1024 11}}}}}{\lang1024 \par AT Bus Interface Control Registers\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885728 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885728 }}{\fldrslt {\lang1024 14}}}}}{\lang1024 \par Memory Addressing\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885729 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885729 }}{\fldrslt {\lang1024 17}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Software Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885730 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885730 }}{\fldrslt {\lang1024 17}}}}}{\lang1024 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\lang1024 CHAPTER 2 - Initializing the Hardware\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885731 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885731 }}{\fldrslt {\lang1024 18}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Overview\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885732 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885732 }}{\fldrslt {\lang1024 18}}}}}{\lang1024 \par }\pard\plain \s18\li200\nowidctlpar\widctlpar\tqr\tx8640\adjustright \fs20\cgrid {\lang1024 Reset the DSP\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885733 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885733 }}{\fldrslt {\lang1024 19}}}}}{\lang1024 \par Reset the Proteus (Classic Only)\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885734 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885734 }}{\fldrslt {\lang1024 19}}}}}{\lang1024 \par Load the DSP code\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885735 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885735 }}{\fldrslt {\lang1024 19}}}}}{\lang1024 \par Initialize the Shared Memory Area( SMA \}\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885736 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885736 }}{\fldrslt {\lang1024 20}}}}}{\lang1024 \par Set up the IRQ\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885737 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885737 }}{\fldrslt {\lang1024 20}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Example 01 - AUXVOL.C and INVOL.C\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885738 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885738 }}{\fldrslt {\lang1024 21}}}}}{\lang1024 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\lang1024 CHAPTER 3 - Using the MultiSound Queues\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885739 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885739 }}{\fldrslt {\lang1024 23}}}}}{\lang1024 \par CHAPTER 4 - Using Digital Audio\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885740 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885740 }}{\fldrslt {\lang1024 25}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Recording Audio\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885741 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885741 }}{\fldrslt {\lang1024 26}}}}}{\lang1024 \par Playing Audio\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885742 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885742 }}{\fldrslt {\lang1024 30}}}}}{\lang1024 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\lang1024 CHAPTER 5 - Using MIDI\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885743 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885743 }}{\fldrslt {\lang1024 31}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 MIDI Routing\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885744 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885744 }}{\fldrslt {\lang1024 32}}}}}{\lang1024 \par Proteus-only Section\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885745 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885745 }}{\fldrslt {\lang1024 33}}}}}{\lang1024 \par General Section\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885746 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885746 }}{\fldrslt {\lang1024 35}}}}}{\lang1024 \par }\pard\plain \s15\sb360\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\caps\f1\cgrid {\lang1024 CHAPTER 6 - Reference\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885747 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885747 }}{\fldrslt {\lang1024 36}}}}}{\lang1024 \par }\pard\plain \s17\sb240\nowidctlpar\widctlpar\tqr\tx8640\adjustright \b\fs20\cgrid {\lang1024 Registers\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc391885748 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc391885748 }}{\fldrslt {\lang1024 37}}}}}{\lang1024 \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid }}\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {\page {\*\bkmkstart _Toc391885704}Introduction{\*\bkmkend _Toc391885704} \par }\pard\plain \nowidctlpar\widctlpar\adjustright \f1\fs20\cgrid { \par This manual is provided as a technical reference for DOS based development using Turtle Beach Systems MultiSound Multimedia audio cards. It gives the user the capability to access all the features of the MultiSound through the DOS environment. It provides the assembled code for the DSP, and fully explains how to interact with that code. It provides descriptions of all the registers accessible from the HOST, and how to use them. This is accomplished by first going over the basics of how the card operates. Then the reader is walked through examples to show how the HOST is used to control the various features of the card. Finally this manual provides a reference section in the back for easy access to the information contained in this manual. \par \par }{\i Note: Although the documentation has been updated to reflect the third generation MultiSound cards, the sample code provided has not been updated yet. This will be done shortly. \par }\pard \nowidctlpar\widctlpar\adjustright {\i \par Note: This SDK is provided to the public as is. Turtle Beach will not provide customer support for this SDK, ie. do not expect us to answer detailed technical questions regarding the content of this document. If you find any of the information to be incorrect or have any suggestions regarding possible future corrections or enhancements please send a note to mailto:sdk@tbeach.com.}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885705}Overview{\*\bkmkend _Toc391885705} \par }\pard\plain \nowidctlpar\widctlpar\adjustright \f1\fs20\cgrid { \par This introduction provides useful information which you should review before attempting to use this manual. \par \par This overview covers the following topics: \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {What you should know before starting \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {What you need to have \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {The information this manual will provide you with \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {Some notes on using the sample applications \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {Conventions used by this manual \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {Additional notes (way at the end) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885706}What you need to use this kit{\*\bkmkend _Toc391885706} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par To start using this tool kit you will need have and understanding of the following things: \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {Advanced knowledge of the C programming language \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \li720\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This manual assumes that the reader is experienced with programming in C. This tool kit uses extensive port writing, IRQ handling, structures, queues and pointers. If you are not confident in your C we recommend that you review it before starting. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {Knowledge of digital audio and MIDI \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \li720\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This manual assumes a certain amount of knowledge on these topics. Although the discussion will not get too in depth, we make no attempt to explain MIDI and digital concepts in this manual. If you find yourself wanting to know more about a topic or just plain lost, check out the FURTHER READING section in the reference part of this manual. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885707}What you need to have{\*\bkmkend _Toc391885707} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par To effectively use this tool kit to create applications for the MultiSound card you will need the following items: \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {An IBM-PC Compatible \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \li720\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {MultiSound is designed for the ISA bus standard on IBM-PC compatibles. You will need one of these to use it. You will be able to use the card on a 286 (assuming you can find one) or better, however a 386 or better is recommended for dealing with digital audio. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {The MultiSound Audio Card- this includes the MultiSound "Classic", MultiSound Tahiti, and the Digital Audio Section of the MultiSound Monterey. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \li720\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {We assume you have one if you bought this kit. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {A C Compiler \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par All the sample source code was written to be compiled using Microsoft C 6.00A. Although we recommend using this compiler, any adept C compiler will work with modest modifications to the code. Please note that the output is a DOS executable. This may need to be set in your compiler options. \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {A line level audio source \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par To go through the tutorial and test the code, you will need a line level audio source (tape or CD player, mixer output, etc..). This will allow you to have something to check the recording with, as well as check the AUX input. \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {A MIDI Keyboard \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par To fully explore the capabilities of the MultiSound, it is suggested that the user have an external MIDI keyboard. The MultiSound MIDI cable will also be required. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885708}What is contained in this manual{\*\bkmkend _Toc391885708} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This manual is broken up into five sections. \par \par }{\b Introduction \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The introduction provides an overview of the tool kit. It tells the user what he will need to use the tool kit, as well as what knowledge he can expect to gain from it. \par \par }{\b CHAPTER 1 - System Overview \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This chapter goes over the hardware and software basics necessary to understand programming the MultiSound card. It also explains the data formats used in the demo code. \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b CHAPTER 2 - Initializing the Hardware \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This chapter covers how to initialize the MultiSound. This will be used in every application you write for the card. \par \par }{\b CHAPTER 3 - Using the MultiSound Queues \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This chapter gives the reader an overview of the event driven queue based software architecture used for programming the MultiSound. \par \par }{\b CHAPTER 4 - Using Digital Audio \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This chapter covers digital audio on the MultiSound. It takes the reader through examples for both playing and recording. \par \par }{\b CHAPTER 5 - Using MIDI \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This chapter covers MIDI usage on the MultiSound. Covered topics include receiving MIDI data, sending MIDI data, and directing MIDI data. \par \par }{\b CHAPTER 6 - Reference \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This section is provided as a quick reference for readers who already read this manual. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885709}Notes on the sample applications{\*\bkmkend _Toc391885709} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par All the source for the tutorial examples are contained on the included disk. The file MCONTROL.C is linked with every sample application. This file contains a series of functions and structures which are used to access the MultiSound. It should be remembered that these source files show only one approach to interfacing with the card. As with any programming task there is no absolute right. The important thing to understand when going through this manual is the low level interaction between the DSP and the HOST (IBM-PC compatible platform). \par \par When building the example programs using the Microsoft C compiler NMK utility, the MAKEFILEs have an associated parameter. The correct command line entry should be either of the following: \par \par \tab NMK makefilename DEBUG=NO \par - or - \par \tab NMK makefilename DEBUG=YES \par \par \tab DEBUG=YES will cause symbolic debug information to be added for use with the \par \tab Codeview debugger. \par \par When doing your own development you can use the functions contained in MCONTROL.C as we do in the examples. If this format does not suit your needs, there is enough information in this manual for you to be able to write your own low level code for the interaction with the hardware. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885710}Files included with the Toolkit{\*\bkmkend _Toc391885710} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab }{\b MCONTROL.C:}{ A library of functions written in Microsoft C which allow easy access to the features of the MultiSound. \par }\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab }{\b MCONTROL.H: }{Definitions and structures specific to the functional implementation in MCONTROL.C. \par }{\f3 \'b7}{\tab }{\b MSND_DSP.H: }{Definitions and constants specific to the Multi-Sound hardware. \par }{\f3 \'b7}{\tab }{\b DSPCODE.OBJ:}{ The assembled code for the DSP. This must be linked with the application and uploaded to the DSP. \par }{\f3 \'b7}{\tab }{\b DSPCODE.ASM: }{The PC-assembler compileable source for DSPCODE.OB J. \par }{\f3 \'b7}{\tab }{\b MSDSPERM.ASM & MSDSPINI.ASM: }{The output of the 56001 cross assembler converted to assembler files. These are included files in DSPCODE.ASM \par }{\f3 \'b7}{\tab }{\b MSNDINIT.BIN & MSNDPERM.REB: }{The output of the 56001 cross assembler. \par }\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab }{\b AUXVOL \\ AUXVOL.C \\ AUXVOL.EXE: }{The Microsoft C MAKEFILE, the PC source C code, and the executable for a simple auxiliary volume adjustment example. \par }\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab }{\b INVOL \\ INVOL.C \\ INVOL.EXE: }{A simple record input volume adjustment example. \par }{\f3 \'b7}{\tab }{\b RECORD \\ RECORD.C \\ RECORD.EXE: }{Example code for recording audio to the hard disk. \par }{\f3 \'b7}{\tab }{\b PLAY \\ PLAY.C \\ PLAY.EXE: }{Example code for playing audio from the hard disk. \par }{\f3 \'b7}{\tab }{\b PRESETS \\ PRESETS.C \\ PRESETS.EXE: }{Example code for uploading a file of presets to the Proteus. \par }{\f3 \'b7}{\tab }{\b PRODEMO \\ PRODEMO.C \\ PRODEMO.EXE: }{Example code for starting and stopping the internal Proteus demo sequence. \par }{\f3 \'b7}{\tab }{\b MIDIIN \\ MIDIIN.C \\ MIDIIN.EXE: }{Example code demonstrating receiving and transmitting of MIDI data. \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Redistribution of Turtle Beach's Software \par This developer's kit does not provide you with a license to distribute any of the contained software, including, but not limited to DSPCODE.OBJ, MCONTROL.C. Developers wishing to use these in specific applications can do so by requesting and returning the "MultiSound DSP OEM Licensing Agreement". \par \par Turtle Beach's policy on redistribution is simple. For a license fee of $1, we allow developers to distribute the above code modules along with their products, provided that MultiSound hardware is included in the target product. Since DSP_CODE. OBJ only works with MultiSound hardware, this is the only logical use of the code. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885711}Applicability:{\*\bkmkend _Toc391885711} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The MultiSound product line includes the original MultiSound (MultiSound "Classic"), as well as the MultiSound Tahiti, Monterey, Pinnacle, and Fiji sound cards. Where a section of information applies only to a specific card, we will make a note of it at the beginning of that section. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885712}CHAPTER 1 - System Overview{\*\bkmkend _Toc391885712} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885713}Introduction{\*\bkmkend _Toc391885713} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {This chapter deals with the ground floor of development for the MultiSound. It will take you through the hardware, explaining how you will communicate with the card. It goes over the registers accessible from the PC, and it covers the basics of the software setup used in the sample applications. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885714}Hardware Overview{\*\bkmkend _Toc391885714} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The original MultiSound (Classic) is a full length, 16 bit, AT compatible feature card that allows real-time digital signal processing to be performed on a PC. The DSP used by the MultiSound is the Motorola DSP 56001, running with a 40 MHz clock. At this speed the DSP is capable of performing 20 million instructions per second. \par \par Since then, the MultiSound card has evolved through 4 more models in 2 generations: MultiSound Tahiti/Monterey, and MultiSound Pinnacle/Fiji. While the DSP section of all those cards remains almost the same, the synthesizers have changed and other supporting auxiliary devices have been added. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885715}MultiSound Classic:{\*\bkmkend _Toc391885715} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The Classic is the first generation MultiSound card featuring 16 bit analog converters. The onboard synthesizer is a Proteus 1/XR which has 4 megabytes of sampled ROM, and has 384 preset sounds available. Externally the card has two analog inputs, one analog output, a MIDI port, and a game port. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885716}MultiSound Tahiti:{\*\bkmkend _Toc391885716} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The Tahiti is the second generation MultiSound card and supports an industry-standard WaveBlaster compatible MIDI daughterboard on a 26-pin header. It also features an 18 bit digital to analog converter. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885717}MultiSound Monterey:{\*\bkmkend _Toc391885717} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The Monterey is the combination of the Tahiti soundcard with Turtle Beach's Rio MIDI daughterboard. Rio programming information is not included in this document. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885718}MultiSound Pinnacle:{\*\bkmkend _Toc391885718} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The Pinnacle is the third generation MultiSound card that for the first time features Plug and Play compatible configuration, 20 bit analog converters, a microphone level input, an MPU-401 compatible interface to the synthesizer, an EIDE interface, and an optional daughterboard to facilitate digital I/O. The onboard synthesizer is based on the Kurzweil MA-1 synth engine and has access to 2 MB compressed GM patch set in ROM as well as up to 48 MB of optional sample RAM. The Pinnacle also uses the newer Motorola 56002 DSP, running externally at 11.2896 MHz and internally at 45.1584 MHz, yielding 22.5792 MIPS. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885719}MultiSound Fiji:{\*\bkmkend _Toc391885719} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The Fiji is the same card as the Pinnacle except it lacks the onboard synth and the EIDE interface. Just like the Pinnacle it can be upgraded with a MIDI daughterboard and the digital I/O daughterboard. \par \par In the following text we will refer to the various models as generation 1 (Classic), generation 2 (Tahiti/Monterey), and generation 3 (Pinnacle/Fiji) cards. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885720}Device Overview{\*\bkmkend _Toc391885720} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1440\clvertalt\cltxlrtb \cellx2902\clvertalt\cltxlrtb \cellx4364\clvertalt\cltxlrtb \cellx5826\clvertalt\cltxlrtb \cellx7288\clvertalt\cltxlrtb \cellx8750\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b device\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b Classic\cell Tahiti\cell Monterey\cell Pinnacle\cell Fiji\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1440\clvertalt\cltxlrtb \cellx2902\clvertalt\cltxlrtb \cellx4364\clvertalt\cltxlrtb \cellx5826\clvertalt\cltxlrtb \cellx7288\clvertalt\cltxlrtb \cellx8750\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DSP\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {MPU-401\cell -\cell -\cell -\cell X\cell -\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {joystick i/f\cell X\cell X\cell X\cell X\cell X\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {EIDE i/f\cell -\cell -\cell -\cell X\cell -\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b synth}{\cell Proteus\cell none\cell WaveFront\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {MASS[ies]\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {none\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1440\clvertalt\cltxlrtb \cellx2902\clvertalt\cltxlrtb \cellx4364\clvertalt\cltxlrtb \cellx5826\clvertalt\cltxlrtb \cellx7288\clvertalt\cltxlrtb \cellx8750\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b configuration\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DIP/DSP reg\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DIP/DSP reg\cell DIP/DSP reg\cell PnP/conf. reg\cell PnP/conf. reg\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885721}DSP Device{\*\bkmkend _Toc391885721} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The DSP device will be explained in detail during the following sections of this manual. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885722}MPU-401 Device{\*\bkmkend _Toc391885722} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The MPU-401 device provides a standard hardware interface to the Kurzweil MASS[ies] based synthesizer on the Pinnacle sound card. The MPU-401 interface is accessed through 2 consecutive 8 bit wide registers. A detailed explanation of the MPU-401 interface would go beyond the scope of this manual. For an in-depth explanation of these registers please refer to standard literature. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885723}Joystick Device{\*\bkmkend _Toc391885723} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The joystick device provides an interface to standard analog joysticks and gamepads with up to 2 axis and up to 4 buttons. The joystick interface is accessed through 2 consecutive I/O port locations that are mapped to the same register. A detailed explanation of the joystick interface would go beyond the scope of this manual. For an in-depth explanation of this register please refer to standard literature. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885724}EIDE Device{\*\bkmkend _Toc391885724} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The EIDE device provides an interface to standard EIDE devices, mostly CD-ROM\rquote s and other removable disk storage devices. The EIDE interface is accessed through 2 I/O port ranges, one 8 bytes wide and the other one 2 bytes wide. A detailed explanation of the EIDE interface would go beyond the scope of this manual. For an in-depth explanation of these registers please refer to standard literature. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885725}Resource Overview{\*\bkmkend _Toc391885725} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The DSP device of the MultiSound interfaces to the host PC system via three hardware resources: One or two I/0 port ranges, one interrupt, and one 32 KB window of shared upper memory. The location and usage of these resources is covered in the following paragraphs. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885726}I/0 Port Usage{\*\bkmkend _Toc391885726} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This section covers the I/0 port usage. It gives the names and locations of the registers. Note that the names given to the registers are defined in MSND_DSP.H using the same syntax. \par \par On the }{\b generation 1 and 2 cards}{ the DSP device occupies sixteen consecutive I/O ports, starting at one of eight pre-defined base addresses. The I/0 port address options and settings are covered in the MultiSound User's Guide under 'Installing the Hardware'. In this document, the I/0 base address will be referred to as "xx0", so HP_CVR would be referred to as xx1h, regardless of the base port selected. In other words, the addresses given are merely the offset from the base address that is selected by the on-board DIP switch. \par \par The first eight I/0 addresses are the host port interface registers of the Motorola DSP56001. The DSP host port interface controls the flow of data and exceptions between the DSP and the PC. The remaining eight addresses are the board information registers, and the AT bus interface control registers. \par \par The base address of the I/O port resource is configured through a block of three on-board DIP switches. The other resources (IRQ and upper memory block) are configured through 2 of the control registers which sit atop the DSP host interface registers. \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {On }{\b generation 3 cards}{ the DSP device occupies only 8 consecutive I/O ports which can be located anywhere throughout the ISA address space from 0x100 through 0x3F0 with the base address aligned at a boundary that is a multiple of 0x010. Configuration is possible either through Plug and Play or, if the card is in legacy mode, through configuration registers. These configuration registers occupy three additional consecutive I/O ports and are based on a block of 2 on-board jumpers. The three possible base addresses are 0x250, 0x260, and 0x270. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par The control registers used for configuration on the generation 1 and 2 boards have been replaced by the standard PnP registers or the configuration registers, respectively. The remaining control registers and the information registers have been moved into the DSP host interface. \par \par }{\b Equates for I/O Ports \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {PU = Power-up State \par R/W = Read/Write \par RO = Read Only \par WO = Write Only \par \par }{\b DSP Host Port Interface Registers: \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx723\clvertalt\cltxlrtb \cellx1914\clvertalt\cltxlrtb \cellx4935\clvertalt\cltxlrtb \cellx5781\clvertalt\cltxlrtb \cellx7242\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx0H\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HP_ICR\cell Interrupt Control Register\cell (R/W)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx723\clvertalt\cltxlrtb \cellx1914\clvertalt\cltxlrtb \cellx4935\clvertalt\cltxlrtb \cellx5781\clvertalt\cltxlrtb \cellx7242\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx1H\cell HP_CVR \cell Command Vector Register\cell (R/W)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx2H\cell HP_ISR\cell Interrupt Status Register\cell (RO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx3H \cell HP_IVR\cell Interrupt Vector Register\cell (R/W)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx4H \cell HP_INFO\cell Board Information Register\cell (RO)\cell 3}{\super rd}{ gen. only\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx4H\cell HP_CTL\cell Control Register\cell (WO)\cell 3}{\super rd}{ gen. only\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx5H \cell HP_RXH \cell Receive Data High Register\cell (RO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx6H \cell HP_RXM \cell Receive Data Middle Register\cell (RO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx7H \cell HP_RXL \cell Receive Data Low Register\cell (RO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx5H \cell HP_TXH \cell Transmit Data High Register\cell (WO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx6H \cell HP_TXM \cell Transmit Data Middle Register\cell (WO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx723\clvertalt\cltxlrtb \cellx1914\clvertalt\cltxlrtb \cellx4935\clvertalt\cltxlrtb \cellx5781\clvertalt\cltxlrtb \cellx7242\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx7H\cell HP_TXL\cell Transmit Data Low Register\cell (WO)\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {For more information on the use of these registers consult the DSP56000/DSP56001 Digital Signal Processor User's Manual from Motorola. Chapter 10 covers the 56001 host port in full detail. \par \par }{\b AT Bus Interface Control Registers (Write Only): \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2499\clvertalt\cltxlrtb \cellx5865\clvertalt\cltxlrtb \cellx7266\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx8H\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HP_MEMM\cell Shared Memory Mapping Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2499\clvertalt\cltxlrtb \cellx5865\clvertalt\cltxlrtb \cellx7266\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx9H\cell HP_IRQM\cell IRQ Mapping Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxAH\cell HP_DSPR\cell DSP Reset Control Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxBH\cell HP_PROR\cell Proteus Reset Control Register\cell 1}{\super st}{ gen. only\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxCH\cell HP_BLKS\cell Memory Block Select Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxDH\cell HP_WAIT\cell Extra Wait State Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxEH\cell HP_BITM\cell 8/16-bit Memory Mode Register\cell \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2499\clvertalt\cltxlrtb \cellx5865\clvertalt\cltxlrtb \cellx7266\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxFH\cell HP_RESERVED\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {(future use)\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }{\b Board Information Registers (Read Only): \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4935\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx8H\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPR_BLRC\cell Board Level R/C Timer Input\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4935\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xx9H\cell HPR_SPR1\cell (future use)\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxAH\cell HPR_SPR2\cell (future use)\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxBh\cell HPR_TCL0\cell TOPCAT Chip Level - Bit 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxCh\cell HPR_TCL1\cell TOPCAT Chip Level - Bit 1\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxDh\cell HPR_TCL2\cell TOPCAT Chip Level - Bit 2\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxEh\cell HPR_TCL3\cell TOPCAT Chip Level - Bit 3\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx693\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4935\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {xxFh\cell HPR_TCL4\cell TOPCAT Chip Level - Bit 4}{\f2 \cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f2 \row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885727}DSP Host Port Interface Registers{\*\bkmkend _Toc391885727} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The following section will cover the use of the Host Port registers. The Host Interface(HI) appears to the host processor as 8 bytes of static RAM. The HOST may access the interface asynchronously by using polling or interrupt-based techniques. The separate transmit and receive registers are double buffered to allow efficient data transfers to occur between the DSP CPU and the HOST CPU. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par The Hl appears to the HOST as an eight BYTE memory mapped peripheral device. The registers, listed above, will now be described in more detail. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Interrupt Control Register (base+0h) R/W \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The ICR is an 8 bit read/write register used by the HOST to control the Hl interrupts and flags. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {INIT\cell MC1\cell MC0\cell RES\cell HF1\cell HF0\cell TREQ\cell RREQ\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par INIT \par This bit is used to initialize the host interface hardware based on the value of the mode control bits. \par \par MC1-MC0 - Mode Control \par These bits will always be set to zero (interrupt mode). The other values are used to enable various DMA modes. \par \par RES \par This bit is reserved. \par \par HF[1:0] - Host Flags \par These bits indicate the status of the host flags in the Host Control Register. These can only be set by the DSP. \par \par TREQ - Transmit Interrupt Enable \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The TREQ bit controls the !HREQ pin for host transmit data transfers. TREQ is used to enable interrupt requests via the !HREQ pin when the transmit data register empty (TXDE) status bit is set in HP_ISR. When TREQ is cleared, these interrupts are disabled. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {RREQ - Receive Interrupt Enable \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The RREQ bit controls the !HREQ pin for host receive data transfers. RREQ is used to enable interrupt requests when the receive data register full (RXDF) status bit is set in HP_ISR. When RREQ is cleared, RXDF interrupts are disabled. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Command Vector Register (base+1h) R/W \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {HP_CVR is used by the host to cause the DSP to execute one of several possible vectored interrupts. The executable exceptions are listed in MCONTROL.H and in the reference section. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HC\cell RES\cell HV5\cell HV4\cell HV3\cell HV2\cell HV1\cell HV0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par HC - Host Command \par This bit is used by the host to handshake command exception execution. The host sets this bit high to request a host exception. The hardware clears this bit to acknowledge the receipt of the command. \par \par HV[5:0] - Host Command Vector \par The DSP will execute the exception handler defined by number written into these bits. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Interrupt Status Register (base+2h) RO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The ISR is an 8 bit read only register which is used by the HOST to read the status bits and flags of the Hl. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HREQ\cell DMAS\cell RES\cell HF3\cell HF2\cell TRDY\cell TXDE\cell RXDF\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par HREQ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The HREQ bit indicates the status of the external host request output pin !HREQ. When this bit is cleared it indicates that no host interrupts are being requested. When this bit is set it indicates that the external HREQ pin is set, and the DSP is currently interrupting the host processor. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DMAS - DMA Status \par This bit indicates the status of the DMA. It will always be set to zero indicating that DMA is disabled. \par \par RES \par This bit is reserved \par \par HF[3:2] - Host Flags \par This bits indicate the status of the host flags in the Host Control Register. These can only be set by the DSP. \par \par TRDY - Transmitter Ready \par This bit indicates that both the transmit (TXH,TXM,TXL) and the receive (TXH,TXM,TXL) registers are empty. When this bit is set, a data transfer from the host is guaranteed to be immediately transferred to the DSP side of the host interface. \par \par TXDE - Transmit Data Register Empty \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The TXDE bit indicates that the host transmit registers (TXH,TXM,TXL) are empty, and can be written to by the host. TXDE is cleared when the TXL register is written to by the host. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {RXDF - Receive Data Register Full \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The RXDF bit indicates that valid data is present in the host receive data registers (RXH, RXM, RXL) and can be read by the host. This bit is cleared when the RXL register is read by the HOST. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Interrupt Vector Register (base+3h) R/W \par }\pard\plain \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HI7\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HI6\cell HI5\cell HI4\cell HI3\cell HI2\cell HI1\cell HI0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par HI[7:0] - Interrupt Vector \par This register contains the exception command when the DSP interrupts the host. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Board Information Register (base+4h) RO \par }\pard\plain \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {This register contains the Xilinx code and board level revisions when the DSP is in RESET. It is implemented on 3}{\super rd}{ generation boards only. \par }{\b\i Note: This register is available with Xilinx code rev 1.18 and higher only. If an earlier version of the Xilinx code is used this register is reserved and always reads 0xFF. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {XVER3\cell XVER2\cell XVER1\cell XVER0\cell RES\cell BTYPE\cell BVER1\cell BVER0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {XVER[3:0] - Xilinx Version \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This value contains the Xilinx code revision. \par 1:1:1:1 - Xilinx version 1.15 or earlier \par 0:0:0:0 - not defined \par 0:0:0:1 - Xilinx version 1.18 (reported as 1.2) \par 0:0:1:0 - Xilinx version 1.3x \par 0:0:1:1 - Xilinx version 1.4x \par 0:1:0:0..1:1:1:0 - possible future revisions \par \par RES \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This bit is reserved and always reads as 1. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par BTYPE - Board Type \par This value contains the board type. \par 1 - Fiji [DSP + game port] (or early board without hardware information) \par 0 - Pinnacle [DSP + MPU-401 + game port + EIDE port] \par \par BVER[1:0] - Board Version \par This value contains the board level revision. The possible combinations of BTYPE and BVER are defined as follows: \par \par 1:1:1 - Fiji Rev A-B or Pinnacle Rev A-E (early boards without hardware information) \par \par 0:0:1 - Pinnacle Rev F (or modified early Pinnacles) \par 0:1:0 - Pinnacle Rev G \par 0:1:1 - Pinnacle Rev H \par 0:0:0 - Pinnacle Rev I \par \par 1:0:1 - Fiji Rev C \par 1:1:0 - Fiji Rev D}{\b \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {1:0:0 - Fiji Rev E}{\b \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Control Register (base+4h) WO \par }\pard\plain \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {This register contains various bits that were previously implemented in the AT Bus Interface Control Registers. It is implemented on 3}{\super rd}{ generation boards only. \par \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell /MEMEN\cell /DSPRST\cell BLKSEL\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par MEMEN - enable DSP shared memory window (active low) \par 0 - shared memory window is enabled (address decoded) \par 1 - shared memory window is disabled (address not decoded) \par }{\b\i Note: This function is available with Xilinx code rev 1.30 and higher only. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DSPRST - DSP Reset (active low) \par 0 - DSP is in reset \par 1 - DSP is running \par \par BLKSEL - Memory Block Select \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This port allows the PC to choose which of the two 32 KB blocks of DSP RAM is currently viewed in the shared RAM window. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - View DSP address X/P:4000h-7FFFh, Y:8000h-BFFFh \par 1 - View DSP address X/P:8000h-BFFFh, Y:4000h-7FFFh \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Receive Data Registers (base+5h, base+6h, base+7h) RO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The receive byte registers are viewed as 3 read only bytes from the host processor. These registers contain valid data when RXDF is set. This indicates to the host processor that the receive data registers are full, and can be read. Because reading RXL clears the RXDF bit, RXL is always the last byte read from these registers. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Transmit Data Registers (base+5h, base+6h, base+7h) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The transmit byte registers are viewed as 3 write only bytes from the host processor. Data may be written to these registers when the TXDE bit is set. Writing to TXL clears the TXDE bit, so TXL is always the last transmit register to be written to. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885728}AT Bus Interface Control Registers{\*\bkmkend _Toc391885728} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The following section will cover the use of additional control registers that exist on 1}{\super st}{ and 2}{\super nd}{ generation boards only. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Shared Memory Mapping Register (base+8h) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register controls the segment address of the shared RAM window in the PC's address space. The register is actually only 3 bits wide. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {SMAS2\cell SMAS1\cell SMAS0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {SMAS[2:0] - Shared Memory Selection \par Specifies the location of the shared upper memory block: \par \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1638\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4380\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_NONE\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0\cell Off/Not Mapped (PU)\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1638\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4380\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_B000\cell 1\cell B000H-B7FFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_C800\cell 2\cell C800H-CFFFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_D000\cell 3\cell D000H-D7FFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_NU\cell 4\cell not used\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_D800\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {5\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {D800H-DFFFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_E000\cell 6\cell E000H-E7FFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1638\clvertalt\cltxlrtb \cellx2064\clvertalt\cltxlrtb \cellx4380\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPMEM_E800\cell 7\cell E800H-EFFFH\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {IRQ Mapping Register (base+9h) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register controls which PC interrupt is used for the DSP host port. The register is actually only 3 bits wide. \par \par Note: Since the polarity of the host port and the PC interrupts are inverted, this map should only be written during an active host port interrupt. This is explained in the section 'Initializing the Hardware'. Not following the recommended method will result in unreliable PC behavior. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell IRQS2\cell IRQS1\cell IRQS0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {IRQS[2:0] - Interrupt Request Line Selection \par \par }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1533\clvertalt\cltxlrtb \cellx1959\clvertalt\cltxlrtb \cellx4365\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_NONE\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0\cell None/Not Mapped (PU)\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1533\clvertalt\cltxlrtb \cellx1959\clvertalt\cltxlrtb \cellx4365\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_5\cell 1\cell IRQ 5\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_7\cell 2\cell IRQ 7\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_9\cell 3\cell IRQ 9\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_10\cell 4\cell IRQ 10\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_11\cell 5\cell IRQ 11\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_12\cell 6\cell IRQ 12\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\cltxlrtb \cellx1533\clvertalt\cltxlrtb \cellx1959\clvertalt\cltxlrtb \cellx4365\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {HPIRQ_15\cell 7\cell IRQ 15\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {DSP Reset Control Register (base+0Ah) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register allows the DSP to be put into or taken out of RESET mode. The register is actually only 1 bit wide. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell }\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell DSPRST\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par DSPRST - DSP Reset \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - DSP is running \par 1 - DSP is in reset (PU) \par \par After a reset of the host computer, the host registers will be inactive. This is because the DSP is in reset mode. Writing a 0 to HP_DSPR allows the DSP out of reset mode. Writing a 1 to HP_DSPR puts the DSP back into reset. The reset on to reset off cycle should have a minimum time delay of 650 ns. This is normally not a problem because the time for the I/0 to take place on a standard bus will exceed 1 µs. The DSP is not very functional immediately after reset since it is waiting for program code to be uploaded through the host port. \par \par Note: This bit is implemented inversely compared to the DSPRST bit of HP_CTL. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Proteus Reset Control Register (base+0Bh) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register allows the Proteus subsystem to be put into or taken out of RESET mode. The register is actually only 1 bit wide. It is implemented on 1}{\super st}{ generation boards only. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell X\cell X\cell PRTRST\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par PRTRST - Proteus Reset \par 0 - Proteus is running \par 1 - Proteus is in reset (PU) \par }{\b \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {After a reset of the host computer, the Proteus subsystem will be inactive. This is because the Proteus is in reset mode. Writing a 0 to HP_PROR allows the Proteus out of reset mode. Writing a 1 to HP_PROR puts the Proteus back into reset. The reset on to reset off cycle should have a minimum time delay of 1 µs. After the reset, the user should wait 600 ms for the Proteus to complete its internal diagnostics. The Proteus is not fully functional immediately after reset since it is waiting for a complete set of presets to be uploaded (via MIDI SYSEX blocks). \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Memory Block Select Register (base+0Ch) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register allows the PC to choose which of the two 32 KB blocks of DSP RAM is currently viewed in the shared RAM window. The PC window segment is mapped based on HP_MEMM (as described above) and the RAM is addressed from offset OOOOH-7FFFH. The register is actually only 1 bit wide. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell X\cell X\cell BLKSEL\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {BLKSEL - Memory Block Select \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - View DSP address X/P:4000h-7FFFh, Y:8000h-BFFFh (PU) \par 1 - View DSP address X/P:8000h-BFFFh, Y:4000h-7FFFh \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {Extra Wait State Register (base+0Dh) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register allows one additional wait state to be added to PC memory accesses. The register is actually only 1 bit wide. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell X\cell X\cell 1WS\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par 1WS - One Wait State \par 0 - No added wait states (PU) \par 1 - One additional wait state \par \par On some clones, because of non-compliance with the ISA Bus specification, it is necessary to add one wait state to achieve proper host memory operation. \par \par }\pard\plain \s4\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel3\adjustright \b\f1\cgrid {8/16-bit Memory Mode Register (base+0Eh) WO \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This register allows the selection of either 8 or 16 bit PC memory accesses. The register is actually only 1 bit wide. \par }\pard \sl240\slmult0\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\trowd \trgaph108\trleft-108\trhdr \clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx999\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx2106\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx3213\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx4320\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx5427\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx6534\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx7641\clvertalt\clbrdrt\brdrs\brdrw15\brdrcf1 \clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \clcfpat16\clcbpat8\clshdng3000\cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {7\cell 6\cell 5\cell 4\cell 3\cell 2\cell 1\cell 0\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\trowd \trgaph108\trleft-108 \clvertalt\clbrdrl\brdrs\brdrw30\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx999\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx2106\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx3213\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx4320\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx5427\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx6534\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw15\brdrcf1 \cltxlrtb \cellx7641\clvertalt\clbrdrl\brdrs\brdrw15\brdrcf1 \clbrdrb\brdrs\brdrw15\brdrcf1 \clbrdrr\brdrs\brdrw30\brdrcf1 \cltxlrtb \cellx8730\pard \qc\nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {X\cell X\cell X\cell X\cell X\cell X\cell X\cell 8BM\cell }\pard \nowidctlpar\widctlpar\intbl{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\row }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par 8BM - 8 Bit Mode \par 0 - 16 bit mode (full bandwidth) (PU) \par 1 - 8 bit mode (appr. 25% reduction in bandwidth) \par \par On some clones, because of non-compliance with the ISA Bus specification, it is necessary to run the bus in 8-bit mode, to achieve proper host memory operation. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885729}Memory Addressing{\*\bkmkend _Toc391885729} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par MultiSound has 32K x 24 bits of memory. The DSP views this memory as one contiguous block. Since the DSP data bus is 24 bits wide and the PC data bus is 16 bits wide, the least significant 8 bits are not available from the PC bus side. The PC memory is addressed in 8 bit increments so 16K of DSP RAM appears as 32K of RAM on the PC side. This is why the memory block selector (see above) is needed. It also explains why the PC's window appears to be twice the size of the related DSP RAM. \par \par While all types of RAM accesses will work from the PC side, the most useful are word accesses since the DSP has no choice but to view the RAM in words. AII translation of the data is taken care of by the hardware. \par \par Note that this RAM is truly shared. If the PC is using the memory, the DSP will be put on hold during external bus cycles. \par \par This shared memory area (SMA) is used to buffer MIDI and audio data going both in and out, as well as holding the queuing structures. The memory map of the SMA is shown in the Technical Reference section of this manual. The usage of the individual locations will be explained as we proceed. For now just take a look at it, and note what kind of data is held there. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885730}Software Overview{\*\bkmkend _Toc391885730} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The demo code uses several typedefs, macros, structures, and unions. All of there definitions are contained in the file MCONTROL.H. Here we will briefly describe their utility. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {typedef unsigned char BYTE; \tab // an 8-bit unsigned variable declaration \par typedef unsigned int WORD; \tab // a 16-bit unsigned variable declaration \par typedef unsigned long DWORD;\tab // a 32-bit unsigned variable declaration \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The following macros are provided to make the code more readable. \par \par }{\b\ul HIWORD(I) LOWORD(I) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {These macros are used to extract WORDs from DWORDs. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Example: \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {HIHORD(Ox0000:FFFF) = Ox0000 \par LOWORD(Ox0000:FFFF) = OxFFFF \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }{\b HIBYTE(l) LOBYTE(l)}{ \par These macros are used to extract BYTEs from WORDs \par Example: \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {HIBYTE(OxOOFF)= Ox00 \par LOBYTE(OxOOFF)= OxFF \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }{\b MAKELONG(low,hi) MAKEWORD(low,hi) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {These macros are used to make a long from two WORDs or a WORD from two BYTEs. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Example: \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {MAKELONG(OxFFFF, Ox0000) = Ox0000:FFFF \par MAKEWORD(OxFF, Ox00) = OxOOFF \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }{\b PCTODSP_ OFFSET(w) PCTODSP_BASED(w) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {These macros are used to convert a PC offset address into an offset or a based address readable by the DSP. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Example: \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {PCTODSP_OFFSET(Ox2400) = Ox1200 \par PCTODSP_BASED(Ox2400) = Ox1200 + Ox4000 \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }{\b CLI STI}{ \par These macros are just their assembly equivalent, and are used to disable and re-enable interrupts. They are defined in MCONTROL.H as: \par }{\b _asm \{ cli \} }{and \par }{\b _asm \{ sti \} }{respectively. \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The structures and functions used in MCONTROL.C are described in the Technical Reference section of this manual. It is suggested that you scan through this section now to get an idea of the syntax used in the demo code. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par One thing that should always be remembered when writing code for the MultiSound is the domain of a variable. All references to addresses in the SMA (Shared Memory Area) are actually DSP WORD based pointers. To use one of these addresses from the host, the user must subtract from it the DSP base address (Ox4000 ), and multiply the value by two to get a BYTE based offset. Then this offset must be added to the hosts base address. \par \par When an SMA variable refers to an offset or size, the value is a WORD offset, or the size in WORDs. So when using these values from the host they must be multiplied by 2. \par When referring to bank 1 of the memory the base address of the DSP should be considered Ox8000. The macros above ( PCTODSP_OFFSET and PCTODSP_BASED ) do these domain conversions if the value refers to SMA bank 0, or the value is an offset. If you are dealing with bank 1 of the RAM you will have to add an additional Ox4000 to the DSP base address. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885731}CHAPTER 2 - Initializing the Hardware{\*\bkmkend _Toc391885731} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This chapter will take you through the steps necessary to initialize the hardware. Then it will step you through the example code AUXVOL.C and INVOL.C which will allow you to adjust the input volumes of the MultiSound. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885732}Overview{\*\bkmkend _Toc391885732} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par There are five basic steps necessary to initializing the hardware. They are as follows: \par }{\f3 \'b7}{\tab Reset DSP \par }{\f3 \'b7}{\tab Reset Proteus (Classic Only) \par }{\f3 \'b7}{\tab Load DSP Code \par }{\f3 \'b7}{\tab Initialize SMA \par }{\f3 \'b7}{\tab Set up the IRQ \par Each of these will be described in full in the following paragraphs. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885733}Reset the DSP{\*\bkmkend _Toc391885733} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The first step to initializing the card is resetting the DSP. This is accomplished using the HP_DSPR register as described in the I/O port usage section of this manual. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE ResetDSP() \par \{ \par \tab int nTimeOutCount = 20000; \par \par \tab outp( wBASEIO + HP_DSPR , HPDSPRESET_ON ); \par \tab outp( wBASEIO + HP_DSPR , HPDSPRESET_OFF ); \par \tab while(nTimeOutCount-- > 0) \par \tab \{ \par \tab \tab if( inp(wBASEIO + HP_CVR) == Oxl2 ) \par \tab \tab \{ \par \tab \tab \tab return(1); \par \tab \tab \} \par \tab \} \par \tab return(0); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par In this example the variable wBASEIO is equal to the I/0 base port address, and HP_DSPR is the offset of the host port DSP reset register as defined in MSND_DSP.H. This function simply writes to the HP_DSPR register to make the DSP go into reset. Then it writes to the register again to take it out of reset. Then it polls the HP_CVR register to check for success. If the variable nTimeOutCount decrements to zero, we return an error. The most frequent mistake which causes this function to return a failure is the improper setting of wBASEIO. This function is included in MCONTROL.C. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885734}Reset the Proteus (Classic Only){\*\bkmkend _Toc391885734} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This is basically the same as the DSP reset, only we are writing to the HP_PROR register instead of the HP_DSPR register. Below is the function in MCONTROL.C which accomplishes this task. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void ResetProteus( void ) \par \{ \par \tab outp( wBASEIO + HP_PROR , HPPRORESET_ON ); \par \tab GetTimeDelay( TIME_PRO_RESET ); \par \tab outp( wBASEIO + HP_PROR, HPPRORESET_OFF ); \par \tab GetTimeDelay( TIME_PRO_RESET_DONE ); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The only difference in this case is that some delay must be implemented to insure that the Proteus remains in reset for approximately 50 msec and that no data is sent to it within 650 msec after coming out of reset. This is accomplished using the function GetTimeDelay which is included in MCONTROL.C. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885735}Load the DSP code{\*\bkmkend _Toc391885735} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {The DSP code necessary for operating the MultiSound card is embedded in DSPCODE.OBJ. When compiling the example programs you must link your source file with this object file. The .ASM file for creating this object file is included on the distribution disk. \par \par The specifics of uploading the DSP code are not relevant to the material in this manual. We provide you with a function in MCONTROL.C which does this. Executing this function will upload the code to the DSP from the linked object file. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {UploadDSPCode(); \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par If you find linking with this object file makes your executable too large, the cross assembler output files are provided. These can be uploaded to the DSP using the functions }{\f2 uploadreb() }{and }{\f2 uploadbin() }{as shown below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {uploadreb("msndperm.reb"); \par uploadbin("msndinit.bin"); \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This transfers the files from the same directory as your program, so you must be certain that they are present for this method to work properly. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885736}Initialize the Shared Memory Area( SMA \}{\*\bkmkend _Toc391885736} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Once the DSP code is loaded, we have to set the SMA variables to their default values. The function InitializeSMA() in MCONTROL.C is used by the demo code to do this. This function sets the variables to their default values, as well as setting the SMA offsets to the appropriate pointer values based on the selected shared RAM base address. You may want to modify the values set in InitializeSMA depending on your specific application. You should take a look at this function now to see what kind of information is held in the SMA. \par \par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel2\adjustright \b\f1\fs20\cgrid {{\*\bkmkstart _Toc391885737}Set up the IRQ{\*\bkmkend _Toc391885737} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The functions SetupMsndlRQ() and SetlntMap( BYTE blRQ ) are provided to set up the Interrupt on the MultiSound. \par \par The SetlntMap function, called from within SetupMsndlRQ, sets up the interrupt value received from the MultiSound. Since the polarity of the host port and the PC interrupts are inverted, this map should only be written during an active host port interrupt. To do this, have the PC's 8259 interrupt controller disabled (or use }{\f2 CLI }{in PC assembler), then enable transmit interrupts on the host port. This will set the interrupt logic active (high), provided that the transmitter is empty (}{\f2 WaitTXDEmpty()}{ ). Write the desired HP_IRQM value, then disable the transmit interrupt on the host port. Finally, re-enable the interrupt on the PC's 8259 (or use }{\f2 STI }{in PC assembler). The function }{\f2 WaitTXDEmpty() }{is included in MCONTROL.C, and merely waits for the TXD register to be emptied of any current data. It returns true if the register clears and false if it times out waiting for it to clear. The source code for this function is listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE SetIntMap( BYTE bIrq ) \par \{ \par \tab if( WaitTXDEmpty() ) \par \tab \{ \par \tab \tab CLI;\tab // inline assembler \par \tab \tab outp( wBASEIO + HP_ICR , inp( wBASEI0 + HP_ICR ) | HPICR_TREQ ); \par \tab \tab outp( wBASEIO + HP_IRQM , bIrq ); \par \tab \tab outp( wBASEIO + HP_ICR, inp( wBASEIO + HP_ICR ) &}{\i ~}{HPICR_TREQ ); \par \tab \tab STI;\tab // inline assembler \par \tab \tab return(1) \par \tab \} \par \tab else \par \tab \tab return(0); \par \} \par \par BYTE WaitTXDEmpty() \par \{ \par \tab int nTimeOutCount = 20000; \par \tab while(nTimeOutCount-- > 0) \par \tab \{ \par \tab \tab if( inp(wBASEI0 + HP_ISR)&}{\i }{HPISR_TXDE ) \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \tab \{ \par \tab \tab \tab return(1); \par \tab \tab \} \par \tab \} \par \tab return(0);\tab // timed out! \par \} \par \par BYTE SetupMsndIRQ() \par \{ \par \tab WORD wGP;\tab \tab // to comply with MSC 7.00 _dos_getvect and _dos_setvect \par \tab if( SetIntMap( blrq ) == 0 ) \par \tab \tab return(0); \par \tab \par \tab if( nIRQValue > 7}{\i }{) \par \tab \{ \par \tab \tab wGP = nIRQValue + Ox68;\tab \tab // use second 8259 PIC \par \tab \tab outp(PIC2 + 1, ~( 1 << (nIRQValue - 8) &}{\i }{inp(PIC2 + 1))); \par \tab \} \par \tab else \par \tab \{ \par \tab \tab wGP = nIRQValue + 8;\tab // use first 8259 PIC \par \tab \tab outp( PICl + 1, ~( 1 << nIRQValue) & inp(PIC1 + 1)); \par \tab \} \par \tab nDSPSaveVect = _dos_getvect( bGP ); \par \tab _dos_setvect( bGP , int_handler ); \par \tab outp( wBASEIO + HP_ICR , inp(wBASEIO + HP_ICR ) | HPICR_RREQ ); \par \tab return(1); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par There is also a function ResetMsndlRQ() included in MCONTROL.C which restores the interrupt to its original value. This should be run in your exit code to ensure system integrity, unless you want to keep the board active. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885738}Example 01 - AUXVOL.C and INVOL.C{\*\bkmkend _Toc391885738} \par }\pard\plain \nowidctlpar\widctlpar\tx7200{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {We will now take the information we learned from above, and apply it to a simple application. This application, included on the disk, shows you how to set the auxiliary input volume of the MultiSound. \par \par Based on the preceding information we can write the entry and exit code for our first example as follows: \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {#include "montrol.h" \par #include "msnd_dsp.h" \par \par main() \par \{ \par \par \tab bMem\tab \tab = HPMEM_D000;\tab \tab // defined in msnd_dsp.h \par \tab bIrq\tab \tab = HPIRQ_10;\tab \tab \tab // defined in msnd_dsp.h \par \tab wIRQValue\tab = 10; \par \tab bBaseIO\tab \tab = HPIO_290;\tab \tab \tab // defined in msnd_dsp.h \par \tab pMEM.dw.h\tab = 0xD000; \par \tab pMEM.dw.l\tab = 0x0000; \par \tab wBASEIO\tab \tab = 0x290; \par \par \tab resetDSP(); \par \tab ResetProteus();\tab \tab \tab \tab // Classic only \par \tab uploadreb ("msndperm.reb"); \par \tab uploadbin ("msndinit.bin"); \par \tab initSMA(); \par \tab SetupMsndIRQ(); \par \par \tab . \par \tab . \par \tab application code \par \tab . \par \tab . \par \tab ResetMsndIRQ(); \par \tab exit(0); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Here we are using several global variables. These variables are defined in MCONTROL.H. The reason for defining these globally is that virtually all the functions will need access to one or more of these values. The variable pMEM is a union defined in MCONTROL.H. Its definition follows: \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {union mem_tag \{ \par \tab BYTE far *p; \par \tab struct dw_tag \{ \par \tab \tab WORD l; \par \tab \tab WORD h; \par \tab \tab \} dw; \par \tab \} pMEM; \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This union allows us to access the SMA either as a far pointer, a WORD offset, or the WORD describing the segment. The constants }{\f2 HPMEM_DOOO, HPIRQ_10, and HPIO_29O }{are the register values for the associated parameters and are defined in MSND_DSP.H. \par \par Now we will add the application code. We will allow the user to increase and decrease the volume using the'+' and '-' keys. This will be done using a while loop based on a termination flag (bTerminator ). The flag will be set when the user hits the 'q' key, and it will stop the program. The application loop that we will insert in the code will be as follows. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {while( !bTerminator ) \{ \par \tab if( kbhit() ) \{ \par \tab \tab switch ( getch() ) \{ \par \tab \tab \tab case 0x2B:\tab \tab // the '+' key \par \tab \tab \tab \tab SMA->bAuxPotPosLeft++; \par \tab \tab \tab \tab SMA->bAuxPotPosRight++; \par \tab \tab \tab \tab SetAuxVolume(); \par \tab \tab \tab \tab printf("Aux Volume = 0x%X\\n", SMA->bAuxPotPosLeft ); \par \tab \tab \tab \tab break; \par \par \tab \tab \tab case 0x2D:\tab \tab // the '-' key \par \tab \tab \tab \tab SMA->bAuxPotPosLeft++; \par \tab \tab \tab \tab SMA->bAuxPotPosRight++; \par \tab \tab \tab \tab SetAuxVolume(); \par \tab \tab \tab \tab printf("Aux Volume = 0x%X\\n", SMA->bAuxPotPosLeft ); \par \tab \tab \tab \tab break; \par \par \tab \tab \tab case 0x51:\tab \tab // upper or lower case 'Q' \par \tab \tab \tab case 0x71: \par \tab \tab \tab \tab printf("Terminating\\n"); \par \tab \tab \tab \tab bTerminator = 1; \par \tab \tab \tab \tab break; \par \par \tab \tab \tab \} \par \tab \tab \} \par \tab \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par As can be seen when the user requests that the volume be increased, the program responds by incrementing the SMA AUX volume variable while calling the function SetAuxVolume. The parameter GANG tells the function that the user wants both the left and right volumes adjusted. This function is included in MCONTROL.C. The portion of SetAuxVolume which tells the DSP that the volume has changed is listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE SetAuxVolume( BYTE bValue, BYTE bType ) \par \{ \par \tab . \par \tab . \par \tab . \par \tab SendHostWord( Ox00 , Ox00 , HDEXAR_AUX_SET_POTS ); \tab \par \tab SendDSPCommand(HDEX_AUX_REQ ); \par \tab . \par \tab . \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This function uses two other functions from MCONTROL.C. The first one loads the specific AUX request into the host port transmit registers. The code for }{\f2 SendHostWord }{is listed below. First the function calls }{\f2 WaitTXDEmpty()}{to wait for the transmit data registers to clear any data they currently contain. Then it loads them with the AUX request. If }{\f2 WaitTXDEmpty }{fails, the function returns }{\f2 FALSE}{. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE SendHostWord(BYTE bHi, BYTE bMid , BYTE bLow ) \par \{ \par \tab if( waitTXDE() ) \{ \par \tab \tab outp( wBASEIO + HP_TXH , bHi ); \par \tab \tab outp( wBASEIO + HP_TXM , bMid ); \par \tab \tab outp( wBASEIO + HP_TXL , bLow ); \par \tab \tab return(1); \par \tab \tab \} \par \tab return(0); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The next function, }{\b\f2 SendDSPCommand(), }{sends the HDEX_AUX_REQ exception to the DSP. This interrupts the DSP and tells it that there is an AUX request in the TXD registers. The value of bCommand tells the DSP which of its ISRs to execute. The function }{\b\f2 WaitHostClear() }{is similar to }{\b\f2 WaitTXDEmpty(), }{only it is waiting for the DSP to acknowledge that it is ready for another command. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE SendDSPCommand( BYTE bCommand ) \par \{ \par \tab if( WaitHostClear() ) \{ \par \tab \tab outp( wBASEIO + HP_CVR , bCommand ); \par \tab \tab return(1); \par \tab \} \par \tab return(0); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Now we have constructed all the elements of our first MultiSound application. All that is necessary is to compile it. The source for this program is on the included disk. Be sure enter the appropriate hardware settings into your code before compiling (i.e. }{\f2 wBASEIO, pMEM.p, and IRQ }{). If you are using the Microsoft C compiler, you can use the MAKEFILE included and run 'nmk' to compile the code. \par \par When you run the program be sure that you have a line level audio source hooked up to the auxiliary input. This will allow you to verify that the volume is actually changing. \par \par To adjust the record input level we only have to change the }{\b\f2 SetAuxVolume() }{function to }{\b\f2 SetlnVolume(), }{and change the SMA variables which are changed (}{\b\f2 SMA->blnPotPosLeft }{and }{\b\f2 SMA->bln-PotPosRight }{). }{\b\f2 SetInVolume() }{does the same thing as }{\b\f2 SetAuxVolume()}{only it sends the HDEXAR_SET_IN_POTS value to the TXD registers. The source code for this sample is called INVOL.C and is on the distribution disk. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885739}CHAPTER 3 - Using the MultiSound Queues{\*\bkmkend _Toc391885739} \par }\pard\plain \nowidctlpar\widctlpar\tx8640{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Now that we have laid the foundation for programming the MultiSound, the next step is to create an application which interacts with the DSP in real time. Before we can do that we must have a firm grasp on how the job queue system works in the MultiSound. \par \par The SMA contains 5 job queues. These are used to control the data for digital audio recording, digital audio playback, MIDI in, MIDI out, and DSP to host messages. Each of these queues has a structure associated with it, which is used for control of that particular queue. This structure is shown below, and is the foundation of the queue based system by which the host and the DSP interact. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {struct JobQueueStruct \{ \par \tab WORD wStart; \par \tab WORD wSize; \par \tab WORD wHead; \par \tab WORD wTail; \par \}; \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The 5 JobQueueStruct's are located in the SMA, since both the DSP and the host will need access to them. The wStart value will always be a DSP based pointer to an associated data buffer, of size wSize. Thus if the structure was for MIDI in data, wStart would be a pointer to an SMA buffer of size wSize where the DSP will write incoming MIDI data. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {To read data from this buffer, we would have to convert wStart from a DSP based pointer to a PC based pointer, and then add the offset of wHead. Note that when we call these values pointers we do not mean that they are addressed by the PC as pointers. We mean that they refer to addresses. The type of these variables as shown in the structure definition above is WORD. \par \par The head and tail values are used to keep track of the current location in the queue. No matter which way the information is going, data is always written to the tail of a queue, and read from the head. So if we were sending MIDI data, the host would write the data to the tail of the queue, and the DSP would read it from the head. On the other hand, if we were receiving MIDI data, the DSP would write incoming data to the tail, and the host would read that information off the head of the queue. \par \par Since any one queue will be used exclusively as either a read or write data channel, only one element of the structure has to be maintained by the host. For data out queues, the host will maintain the tail, and the DSP will maintain the head. Likewise for data in queues, the DSP will maintain the tail, and the host will maintain the head. The start and size parameters are constants which will only be set at initialization time. The names of the queue structures used in this text are listed below along with who controls each of the elements. \par \par }{\b DAPQ }{- Digital audio play job queue \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab Host owns wTail; DSP owns wHead \par \par }{\b DARQ }{- Digital audio record job queue \par \tab Host owns wTail; DSP owns wHead \par \par }{\b MODQ }{- MIDI out data job queue \par \tab Host owns wTail; DSP owns wHead \par \par }{\b MIDQ }{- MIDI in data job queue \par \tab DSP owns w Tail; Host owns wHead \par \par }{\b DSPQ }{- DSP to host messages job queue \par \tab DSP owns wTail; Host owns wHead \par }\pard \li864\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {For MIDI data and DSP messages the JobQueueStruct will point directly to the associated buffer where the information is stored. However for digital audio play and record, the process is not as direct. For these the JobQueueStruct points to a DAQueueDataStruct structure, which contains the pointer to the data buffer, as well as information on the type of audio data contained in that buffer. This structure is shown below, and is included in MCONTROL.H. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {struct DAQueueDataStruct \{ \par \tab WORD wStart; \par \tab WORD wSize; \par \tab WORD wFormat; \par \tab WORD wSampleSize; \par \tab WORD wChannels; \par \tab WORD wSampleRate; \par \tab WORD wIntMsg; \par \tab WORD wFlags; \par \}; \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par In this case of audio the job queue (DAPQ or DARQ) pointers refer to a buffer of three of the data queue structures. These structures in turn each have their own pointer (wStart) to the location of the actual audio data. For the case of playing audio there are 3 buffers of Ox2400 bytes in bank 0 of the SMA, each with an associated DAQueueDataStruct. For recording audio there are 3 buffers of Ox2000 bytes in bank 1 of the SMA. Again each of the record buffers has an associated DAQueueDataStruct. \par \par The other elements of the structure are used to control the audio format. The supported values are tabulated as follows. \par \par }{\f3 \'b7\tab }{wFormat\tab \tab \tab \tab - 1=PCM \par }{\f3 \'b7\tab }{wSampleSize\tab \tab \tab \tab - 16 bit/8 bit \par }{\f3 \'b7\tab }{wChannels\tab \tab \tab \tab - 1 = MONO; 2= STEREO \par }{\f3 \'b7\tab }{wSampleRate\tab \tab \tab \tab - 11025 Hz/22050 Hz/44100 Hz \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The remaining two values are for the host's use. Upon completion of a job the DSP will interrupt the host, and place the value wlntMsg into the DSP to host message queue. The last variable wFlags can be used to store any data that the user wants to have linked to a particular buffer of audio data. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par Note that in our discussion, we use a particular memory setup, however this is not hard-coded. The only areas that are hard coded are the job queues and the SMA control block (DAPQ, DARQ, MIDQ, MODQ, DSPQ). Thus you could set up your data buffers in any available area of the SMA and in any number of banks. \par \par Now that we have an overview of the queuing mechanism used by MultiSound we can start writing an application using them. Although the queue based system lends itself to audio multitasking (i.e. recording audio and sending MIDI simultaneously) this manual will only cover one task at a time. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885740}CHAPTER 4 - Using Digital Audio{\*\bkmkend _Toc391885740} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {MultiSound uses 16 bit Crystal A/D and D/A converters to interface with analog audio. These provide high quality conversions both to and from the digital domain. The A/D converter also provides us with some extra information. It has extra bits which allow us to check the amount a signal is dipping, and the DSP maintains a copy of the current peak value for the left and the right channel. For more information on these extra bits, see the SMA variables section in the reference section. \par \par This chapter will walk you through the sample record and play applications. Before doing this, you may want to review the memory map and the structure definitions in the reference section of this manual. Doing this will make understanding the process much easier. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885741}Recording Audio{\*\bkmkend _Toc391885741} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280\tx8640{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {We will use the foundation code we wrote in chapter 2 to start with. The first thing we need to add to this is a message handling system. As the DSP completes tasks from its job queues, it will interrupt the host and place messages, dependent on the particular task completed, in the DSPQ data buffer (pointed to by DSPQ->wStart). So when the host receives an interrupt from the DSP it will have read the messages from the location pointed to by DSP->wHead. Then it will have to increment DSP->wHead and compare it to DSP->wTail. This process will continue until all the messages have been read from the queue. \par \par Now we will start to write the Interrupt Service Routine (ISR). This manual assumes that you are familiar with writing an ISR. \par \par The following is a listing of the interrupt handler used by the example code in this tool kit. \par }\pard \li1440\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \li1440\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {**** check this code fragment ????? \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void _interrupt _far InterruptHandler() \par \{ \par \tab if( bIntFlag != 1 ) \{ \par \tab \tab bIntFlag = 1; \par \tab \tab if( bCurrBank ) outp( wBASEIO + HP_BLKS , HPBLKSEL_0 ); \par \tab \tab inp( wBASEIO + HP_RXL ); \par \tab \tab if( nIRQValue > 7) outp( PIC2 , EOI ); \par \tab \tab outp( PIC1 , EOI ); \par \par \tab \tab while( DSPQ->wTail != DSPQ->wHead ) \{ \par \tab \tab \tab if( ++pwHostHead >= ( pwHostQueue + HOSTQ_SIZE )) \par \tab \tab \tab \tab pwHostHead = pwHostQueue; \par \tab \tab \tab *pwHostHead = *( pwDSPQData + DSPQ->wHead ); \par \tab \tab \tab if( ++DSPQ->wHead > DSPQ->wSize ) DSPQ->wHead = 0x00; \par \tab \tab \tab \} \par \tab \tab if( bCurrBank ) outp( wBASEIO + HP_BLKS , HPBLKSEL_1 ); \par \tab \tab bIntFlag = 0; \par \tab \tab \} \par \} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The first thing we check on entry is the value of blntFlag. This is to make sure we are not nested in the ISR. If we are nested, we exit immediately. When this happens no data is lost. This is because we are already reading the data off the DSP message data queue. The DSP will write the message into the queue and advance DSPQ->wTail, and the host will continue to read messages until it reaches the tail. \par \par The next value we check is bCurrBank. This is a global variable which tracks which SMA bank the host is currently using. Since all the queue structures are stored in SMA bank 0, we have to ensure that we are looking at that bank while inside the ISR. We do this by writing, if necessary, to the HP_BLKS register as explained in CHAPTER 1. \par \par After we are definitely looking at the correct bank, we read the low receive register of the DSP host port. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {inp( wBASEIO + HP_RXL ); \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {This acts as an acknowledge to the DSP that the port has been read. The DSP will not be able to send any more information to the host until this register has been read. \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par After clearing the DSP and issuing the EOI (End Of Interrupt) to the PIC (Programmable Interrupt Controller) we can start to read the data off of the message queue. For this sample code we have set up another queue which we will refer to as pwHostQueue. The ISR merely transfers the new information from the SMA DSP message queue into pwHostQueue which is located in the PC's RAM. When the host exits from the ISR, it has its own queue of tasks to deal with. \par \par Once the host has read all the available information from the message queue (DSPQ->wHead = DSPQ->wTail ), it restores the previous state of the machine. To do this we restore the state of HP_BLKS, if neccessary, and reset blntFlag. \par \par Before we start writing the body of the program we must first initialize the DAQueueDataStructs. To do this we write a function to store the values we want in the structures. This function takes the bank number as a parameter. It sets the record parameters to those defined in the code (SAMPLE_RATE, BITS etc. ). We use the macro PCTODSP_BASED to convert the address for wStart to the DSP domain, and we have to add an additional Ox4000 because it is in SMA bank 1. The value of wlntMsg is set so the HIBYTE is HIMT_RECORD_DONE, and the LOBYTE is the bank number. Although we don't use it in this code, wFlags is set to the bank number. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void SetupRecordStruct( BYTE bBank ) \par \{\tab \par \tab CurDARQD->start = PCTODSPBASED((DWORD)(DAR_BUFF_SIZE * bBank )) + 0x4000; \par \tab CurDARQD->wSize = DAR_BUFF_SIZE; \par \tab CurDARQD->wFormat = PCM; \par \tab CurDARQD->wSampleSize = BITS; \par \tab CurDARQD->wChannels = CHANNELS; \par \tab CurDARQD->wSampleRate = SAMPLE_RATE; \par \tab CurDARQD->wIntMsg = HIMT_RECORD_DONE * 0x100 + bBank; \par \tab CurDARQD->wFlags = bBank + 1; \par \} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Now we have the framework for the application and the ISR to handle the interrupts from the DSP. All that remains is the processing of the DSP messages which will be stored in pwHostQueue. \par \par The main loop of our program is listed below. Basically it keeps checking for a difference between pwHostHead and pwHostTail until the termination flag bTerminator is set or the user hits a key. When the DSP interrupts the host, the ISR will increase pwHostTail. This will cause our program to execute EvalDSPMessage. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {while( !kbhit() && !bTerminator ) \{ \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab if( pwHostHead != pwHostTail ) \{ \par \tab \tab if( ++pwHostTail == (pwHostQueue + HOSTQ_SIZE)) \par \tab \tab \tab pwHostTail = pwHostOueue; \par \tab \tab EvalDSPMessage( *pwHostTail ); \par \} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par All the possible messages that can be received from the DSP are defined in the file MSND_DSP.H, and also listed in the reference section of this manual. \par \par These messages transmitted in TXH at interrupt time and also written to the DSPQ data buffer. For now we will only be concerned with HIMT_RECORD_DONE and HIMT_DSP \\ HIDSP_INT_RECORD_OVER. However we will write our }{\f2 EvaluateDSPMessage }{to include all messages to make the later examples easier. Our }{\f2 EvaluateDSPMessage }{is essentially just a large switch function with a case for every message we want to respond to. The skeleton for the code follows. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void EvalDSPMessage( WORD wMessage ) \par \{ \par \tab switch ( HIBYTE( wMessage ) ) \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \{ \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \tab case HIMT_PLAY_DONE: \par \tab \tab \tab switch ( LOBYTE( wMessage ) ) \par \tab \tab \tab \{ \par \tab \tab \tab \tab case 0x01:\tab \tab // this shows which buffer was completed \par \tab \tab \tab \tab case 0x02: \par \tab \tab \tab \tab case 0x00: \par \tab \tab \tab \tab \tab break; \par \par \tab \tab \tab \tab default: \par \tab \tab \tab \tab \tab break; \par \tab \tab \tab \} \par \tab \tab \tab break; \par \par \tab \tab case HIMT_DSP: \par \tab \tab \tab switch ( LOBYTE( wMessage ) )\tab // for your information - errors \par \tab \tab \tab \{ \par \tab \tab \tab \tab case HIDSP_INT_PLAY_UNDER: \par \tab \tab \tab \tab \tab break; \par \par \tab \tab \tab \tab case HIDSP_INT_RECORD_OVER: \par \tab \tab \tab \tab \tab break; \par \par \tab \tab \tab \tab case HIDSP_MIDI_IN_OVER: \par \tab \tab \tab \tab \tab break; \par \par \tab \tab \tab \tab case HIDSP_MIDI_OVERRUN_ERR: \par \tab \tab \tab \tab \tab break; \par \par \tab \tab \tab \tab default:\tab // unknown error \par \tab \tab \tab \tab \tab break; \par \tab \tab \tab \} \par \tab \tab \tab break; \par \par \tab \tab case HIMT_RECORD_DONE: \par \tab \tab \tab switch(LOBYTE( wMessage ))\tab // 0, 1, or 2 for which buffer \par \tab \tab \tab \tab \tab \tab \tab \tab \tab \tab // was completed \par \tab \tab \tab \{ \par \tab \tab \tab \tab default: \par \tab \tab \tab \tab \tab break; \par \tab \tab \tab \} \par \tab \tab \tab break; \par \par \tab \tab case HIMT_MIDI_IN_BYTE: \par \tab \tab \tab break; \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \tab default:\tab \tab // unknown Message! \par \tab \tab \tab \tab break; \par \tab \} \par \} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Using this framework, we just have to fill in the code appropriate to which messages we want to respond to. For the HIDSP_INT_RE-CORD_OVER message we will just increment a counter to track the number, if any, of overflows that happened during the record. The real work of this program is done under the HIMT_RECORD_DONE message. \par \par The first step is check the LOBYTE of the message to see if we are receiving a second message for the same buffer. If this is the case we do not perform any processing. Otherwise we set bLastBank to the current buffer. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {case HIMT_RECORD_DONE: \par \tab if( bLastBank != LOBYTE( wMessage ) ) \{ \par \tab \tab bLastBank = LOBYTE( wMessage ); \par \tab \tab . \par \tab \tab . \par \tab \} \par \tab break; \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The next step is to manage the job queue. We have to store the tail value, and increment it. When using the digital audio queues incrementing the tail means we have to make it point at the next DAQueueDataStruct. To do this we add the size of that structure to our stored value. If our new value is greater than the queue size, 3 elements, we will have to wrap the queue. To do this we just set the tail to zero. As a precaution we make sure that queue is not wrapping itself by comparing the head to the tail. If they are equal we have to wait until the DSP advances the head before we can advance the tail. Then we send the DSP a HDEX_RECORD_START exception so it will check the queue to see the update. Our new code looks like this. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {case HIMT_RECORD_DONE: \par \tab if( bLastBank != LOBYTE( wMessage ) ) \{ \par \tab \tab bLastBank = LOBYTE( wMessage ); \par \par \tab \tab wTemp = DARQ->wTail + (DARQ_STRUCT_SIZE/2); \par \par \tab \tab if( wTemp > DARQ->wSize ) \{ \par \tab \tab \tab wTemp = 0; \par \tab \tab \} \par \par \tab \tab while( wTemp == DARQ->wHead ); \par \tab \tab DARQ->wTail = wTemp; \par \tab \tab SendDSPCommand( HDEX_RECORD_START ); \par \tab \tab . \par \tab \tab . \par \par \tab \} \par \tab break; \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Now we have a buffer full of recorded digital audio data, and we have to copy it to a local buffer, and then write it to disk. First we get a pointer to the buffer where the data is located based on the LOBYTE of the DSP message sent to us. Since the record buffers are located in the SMA bank 1, getting the data is a little tricky. First we change the bank the host is looking at by writing to the HP_BLKS register. \par \par During this transition we can't have any interrupts so we disable them ( CLI ), and then reennable them when we are done ( STI ). Once we are looking at the correct bank, we can copy the data to our local buffer. Then we restore HP_BLKS so the host is looking at bank 0. We must disable interrupts for this transition as well. At last we write the data to disk. The code now looks like this. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {case HIMT_RECORD_DONE: \par \tab if( bLastBank != LOBYTE( wMessage ) ) \{ \par \tab \tab bLastBank = LOBYTE( wMessage ); \par \par \tab \tab wTemp = DARQ->wTail + (DARQ_STRUCT_SIZE/2); \par \par \tab \tab if( wTemp > DARQ->wSize ) \{ \par \tab \tab \tab wTemp = 0; \par \tab \tab \} \par \tab \tab // Wait if we are going to wrap the queue \par \tab \tab while( wTemp == DARQ->wHead ); \par \tab \tab DARQ->wTail = wTemp; \par \par \tab \tab SendDSPCommand( HDEX_RECORD_START ); \par \par \tab \tab pbCurRecordBuff = ( BYTE far *)( pMEM.p + bLastBank * DAR_BUFF_SIZE ); \par \par \tab \tab CLI; \par \tab \tab outp( wBASEIO + HP_BLKS , HPBLKSEL_1 ); \par \tab \tab bCurrBank = 1; \par \tab \tab STI; \par \par \tab \tab _fmemcpy( pbHostBuffer , pbCurRecordBuff , DAR_BUFF_SIZE ); \par \par \tab \tab CLI; \par \tab \tab outp( wBASEIO + HP_BLKS , HPBLKSEL_0 ); \par \tab \tab bCurrBank = 0; \par \tab \tab STI; \par \par \tab \tab fwrite( pbHostBuffer , sizeof( BYTE ) , DAR_BUFF_SIZE, f_point ); \par \tab \} \par \tab break; \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The only remaining task is taking care of the file opening, pre-loading the queue and file closing. Since these are straight forward it is left to the user to look at the final source code, included on the distribution disk, to see how this is accomplished. The only explanation left is the calibration of the analog to digital converters. The function CalibrateAD is provided in MCONTROL.C to accomplish this. The source for CalibrateAD is shown below. \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE CalibrateAD( WORD wSampleRate , BYTE bGndType ) \par \{ \par \tab SMA->wCalFreqAtoD = wSampleRate; \par \tab if( bGndType == AGND ) \par \tab \tab SMA->wCurrHostStatusFlags |= Ox0001; \par \tab else if( bGndType == SIGNAL ) \par \tab \tab SMA->wCurrHostStatusFlags &= ~(Ox0001); \par \par \tab SendHostWord( Ox00 , Ox00 , HDEXAR_CAL_A_TO_D ); \par \tab SendDSPCommand( HDEX AUX_REQ ); \par \par \tab // The actual time for the calibration is equal to \par \tab // 4096 / SAMPLE_RATE \par \tab // We will poll DCAL to wait until the calibration \par \tab // is complete \par \par \tab while( GetExtDSPBits() & ~( EXT_DSP_BIT_DCAL )); \par \} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par This function takes the recording sample rate and the calibration type desired as parameters and initiates the calibration of the MultiSound analog to digital converters. It sets or zeroes the AGND bit in SMA->wCurrHostStatusFlags depending on the bGndType parameter. Then it sets the sample rate in the SMA variable SMA->wCal-FreqAtoD. Next it puts the particular AUX request into TXL, and sends the HDEX_AUX REQ exception to the DSP. It finishes off by polling the AID DCAL bit of SMA->wExtDSPBits and waiting for it to drop to zero. GetExtDSPBits returns the valid value of SMA->wExtDSPBits by sending the required exception to the DSP to update those values. When DCAL clears, the A/D converters have completed their calibration. \par \par Now we have a fully functional recording program. The sample rate, bits per sample, and number of channels can be set using the defines in the beginning of the program. Next we will go over an example to play the audio we just recorded. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885742}Playing Audio{\*\bkmkend _Toc391885742} \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par To play audio is almost identical to recording the audio. We can use the same framework we used for recording. The only major change we have to make is the message response in EvalDSPMessage. Playing is actually easier since the play data buffers are in the same SMA bank as the queues, so we do not have to change our SMA window to access the data. \par \par The distribution disk contains the source in PLAY.C. If you take a look at it you will see that main routine is basically the same as in RECORD.C. Instead of setting up the DARQ structure, we set up the DAPQ structure, as well as the associated DAQueueDataStructs. Also you will note that we don't have to calibrate the converters. We change the entry code to pre load the buffers with audio data from our file. Then we only have to add a case to EvalDSPMessage. \par \par In PLAY.C when we get a bank empty message, we have to load a new buffer of information into the SMA play data buffer from the disk. As with recording the first step is to make sure we are not getting a repeated message. LOBYTE( wMessage ) will contain the buffer number which the DSP has just finished playing. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {case HIMT_PLAY_DONE: \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab if( bLastBank != LOBYTE( wMessage ) ) \{ \par \tab \tab bLastBank = LOBYTE( wMessage ); \par \tab \tab . \par \tab \tab . \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \tab . \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \} \par \tab break; \par }\pard\plain \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par To reduce the chance of data underflows, we always want to have all three SMA buffers filled with data. You will notice in the entry code that we preload all three buffers. However we only set the DAPQ as if two were loaded. So when we get an HIMT_PLAY_DONE message we just advance DAPQ->wTail, and the data is already there. Then we send the DSP exception so it will look at the queue. Before leaving we must advance our own pointers, and read the next buffer from the disk. So when we get the next HIMT_PLAY_DONE message our data is already loaded. Our final play done section now looks like this. \par \par }{\f2\fs16 case HIMT_PLAY_DONE: \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f2\fs16 \par \tab if( bLastBank != LOBYTE( wMessage ) ) \{ \par \tab \tab bLastBank = LOBYTE( wMessage ); \par \tab \tab CurDAQD->wSize = (WORD)lReadSize; \par \par \tab \tab if((DAPQ->wTail += PCTODSP_OFFSET(DAPQ_STRUCT_SIZE)) > DAPQ->wSize ) \{ \par \tab \tab \tab DAPQ->wTail = 0; \par \tab \tab \} \par \par \tab \tab SendDSPCommand( HDEX_PLAY_START ); \par \par \tab \tab if( ++CurDAQD > (LPDAQD)( pMEM.p + DAPQ_DATA_BUFF + 2*DAPQ_STRUCT_SIZE ) ) \par \tab \tab \tab CurDAQD = (LPDAQD)( pMEM.p + DAPQ_DATA_BUFF ); \par \tab \tab if( ( pbCurPlayBuff += DAP_BUFF_SIZE ) > (pMEM.p + 2*DAP_BUFF_SIZE)) \par \tab \tab \tab \tab \tab \tab pbCurPlayBuff = pMEM.p; \par \tab \tab lReadSize = fread( pbCurPlayBuff , sizeof( BYTE ) , DAP_BUFF_SIZE, f_point ); \par \tab \} \par \tab break; \par }{ \par }\pard \nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Now we have the ability to play and record audio through the MultiSound. As you modify this code, you can use the SMA->wCurrPlayVolLeft and SMA->wCurrPlayVolRight variables to adjust the out put volume of the audio. \par \par This completes our coverage of digital audio. The reference section should provide you with all the information you need to program the card once you understand the basic concepts explained in this chapter. It also provides a list of references for further reading on digital audio and PC programming. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885743}CHAPTER 5 - Using MIDI{\*\bkmkend _Toc391885743} \par }\pard\plain \nowidctlpar\widctlpar\tx9360{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {\tab \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {The MultiSound "Classic" has a Proteus 1/XR MIDI sound module on board. The Tahiti/Monterey do not have a synthesizer built onto the card. The Tahiti provides a "WaveBlaster" header, while the Monterey comes with the Rio daughtercard already attached to this header. The means of accessing the on-board MIDI port via software is the same for all three cards. Any information that is specific to one or the other (i.e. System Exclusive info) will be noted as such. Otherwise, when we mention the "on-board" MIDI port, it refers to the Proteus port on the MultiSound "Classic", and to the header port on the Tahiti or Monterey. \par \par This section will explain how to access the on-board MIDI port as well as the external MIDI port. If you are not familiar with MIDI you should consult one of the references at the back of this book. This manual assumes you are knowledgeable on the subject of MIDI. \par \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Like our work with audio on the MultiSound, MIDI is controlled via a queuing system. The MultiSound has two MIDI data buffers in the SMA. One is for transmitting MIDI data and the other is for receiving. To send MIDI, place the data you want to transmit into the MIDI out buffer at the tail, offset MODQ->wTail, and advance the tail so the DSP knows there is data in the buffer. Likewise when there is MIDI data coming in, the DSP will interrupt the host. When the host receives a HIMT_MIDI_IN_BYTE message it reads the MIDI byte from the head of the MIDI in data buffer, offset MIDQ->wHead. Several functions are contained in MCONTROL.C which ease the manipulation of MIDI data. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885744}MIDI Routing{\*\bkmkend _Toc391885744} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The MIDI routing on the MultiSound is programmable. This programming consists of three MIDI inputs and four MIDI outputs. When we refer to a patch setting in the manual we are really referring to a set of logical connections on board the MultiSound. The MIDI input and output connections are tabulated below. \par \par }{\b\ul MIDI Connections \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul Inputs\tab \tab \tab Outputs \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {DSP MIDI In\tab \tab \tab DSP MIDI Out \par On-board MIDI In\tab \tab On-board MIDI Out \par Ext MIDI In \tab \tab \tab Ext MIDI Out \par \par The easiest way to understand the patching is to realize that an output can only be connected to one input and an input can be connected to any number of outputs. This is because there is no MIDI merging capability within Multisound. When setting patches from the PC we are looking at the system from the DSP. This means if we select the external IN as our input device, we are connecting the 'Ext MIDI In' input to the 'DSP MlDI In' output. \par }\pard \qc\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {There are four bits which describe the possible MIDI connections. \par }\pard \qc\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab On-board Input ( PltoEI ) \par 0 - DSP Out - Default 1 - External In \par }{\f3 \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab DSP Input ( DltoEI ) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - On-board Out - Default 1 - External In \par }{\f3 \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab External Out ( EOtoDO ) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - On-board Out - Default 1 - DSP Out \par }{\f3 \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f3 \'b7}{\tab External Thru ( ETtoPO ) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {0 - DSP Out - Default 1 - External In \par \par Since these values can not be read from the PC, it is up to the programmer to keep a copy of their current values. To store this information in the same way it is sent as a patch change, we will correlate the 4 bits into a BYTE as follows: \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {BYTE MIDI \tab Map I/0 \par bit 0 - \tab DltoEI \par bit 1 - \tab PItoEI \par bit 2 - \tab 0 \par bit 3 - \tab 0 \par bit 4 - \tab ETtoPO \par bit 5 - \tab EOtoDO \par bit 6 - \tab 0 \par bit 7 - \tab 0 \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Changing the patch setting will be explained later. For now just realize that this is how to set up the BYTE for changing the patch. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885745}Proteus-only Section{\*\bkmkend _Toc391885745} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid {\b\i \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {Our first example will show how to start and stop the Proteus demo sequence. The important concepts to leam in this example are how to send MIDI data and how to route that MIDI data to the desired location. Starting and stopping the demo is accomplished by sending the on-baord MIDI port a sequence of system exclusive messages. We will start with the code framework used in chapter 2. Since we are only transmitting data it will not be necessary to respond to messages from the DSP. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par The system exclusive MIDI sequences for starting and stopping the proteus are included in PRODEMO.H. All we need to do is transmit these strings out through the MIDI port. But first we will set the MIDI out port to the Proteus. The function SetMidiOutPort in MCONTROL.C accomplishes this. In our main routine all we need to do is put in the following line: \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {SetMidiOutPort( MOP_PROTEUS ); \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The constant MOP_PROTEUS is actually a bit mask to select the Proteus for output. The other associated bit masks are listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {#define MOP_PROTEUS\tab Ox10 \par #define MOP_EXTOUT\tab \tab Ox32 \par #define MOP_EXTTHRU\tab Ox02 \par #define MOP_OUTMASK\tab Ox01 \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par You can easily select any of the three possible MIDI outs using these constants. MOP_OUTMASK is used inside of SetMidiOutPort to mask out the MIDI in setting so it remains unaffected. SetMidiOutPort gets the current out port in wCurrMIDIIOPatch, and masks the input values out. wCurrMIDIIOPatch is a global variable defined in MCONTROL.H which the host should use to maintain the value of the current MIDI patch. \par \par This new value is OR'd with the selected ports mask. Then the new value is written back to wCurrMIDIIOPatch. The source for this function is shown below. To make the actual connection change we have to put the patch change command into the MIDI out data buffer. This is done by first placing a OxFEOO into the queue, and then placing the new patch value into the queue. \par \par The function MODPortWrite actually does the writing of the data into the data buffer. This scheme for patch changing insures that all transmitted data will go to the correct place when a patch change occurs. Note that the BYTE for the patch change formulated above could be used instead of bNewMOP, if you by passed the masking logic code. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void SetMidiOutPort( BYTE bNewMOP ) \par \{ \par \tab BYTE bMASK; \par \par \tab bMASK = ( MOP_OUTMASK & LOBYTE( SMA->wCurrMIDIIOPatch ) ); \par \tab bNewMOP = ( bNewMOP | bMASK ); \par \par \tab SMA->wCurrMIDIIOPatch = MAKEWORD( bNewMOP , 0x00 ); \par \par \tab MODPortWrite( 0xFE00 );\tab // Flag to make sure Current Data is sent \par \tab \tab \tab \tab \tab \tab \tab \tab // out before changing patch \par \tab MODPortWrite( MAKEWORD( bNewMOP , 0xFF ) ); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Now that we know what we have to send we just need to know how to send it. For this task we will write the function MODPortWrite. This will have to take the data sent to it, write it into the MIDI out queue, and then update the MODQ structure so the DSP is aware of the data. The first thing the code must do is check to see if the queue is empty. If it is we set the blsEmpty flag. \par \par If the queue is empty we have to restart the DSP by sending it the HDEX_MIDI_OUT_DATA exception. This is done after we write the data into the MIDI out buffer. Next we advance a copy of MODQ->wTail and check to see if we are wrapping at the end of the buffer. Once we have the next tail offset in wTail, we check this value against MODQ->wHead. \par \par This protects from the case where the buffer is full and we are about to write over the head of the queue. Once we are sure we won't over run the queue we can perform the actual writing of the data into the buffer, and update MODQ->wTail. The code for this function is shown below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void MODPortWrite( WORD wMIDIData ) \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\{ \par \tab WORD wTail; \par \tab BYTE bIsEmpty; \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\tab if( MODQ->wHead == MODQ->wTail ) \par \tab \tab bIsEmpty = 1; \par \par \tab wTail = MODQ->wTail; \par \tab if( ++wTail > MODQ->wSize ) \par \tab \tab wTail = 0; \par \tab while( wTail == MODQ->wHead );\tab \tab // Wait if Buffer is full \par \par \tab *( pwMODQData + MODQ->wTail ) = wMIDIData; \par \par \tab MODQ->wTail = wTail; \par \par \tab if( bIsEmpty ) \par \tab \tab SendDSPCommand( HDEX_MIDI_OUT_START ); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par Now that we have the correct MIDI out patch set all we have to do is dump out the sequence to start the demo. This sequence is defined in PRODEMO.H and is pointed to by ProDemoMidiSequence. The convention in this manual is to terminate MIDI strings with a OxFF. This information is not sent over MIDI, it is merely used to signify to the host that it has reached the end of the string. We will use the same function we just went over, MODPortWrite, and just step through ProDemoMidiSequence writing the data to the queue. \par \par When we are done with the string, the Proteus demo will start to play. The program will then wait for the user to hit a key, and then send the sequence to stop the demo. The code for this is listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {main() \par \{ \par BYTE *szDataString; \par BYTE bMidiOutData; \par \par bIntFlag = 0; \par bMem = HPMEM_D000; \par bIrq = HPIRQ_10; \par nIRQValue = 10; \par pMEM.dw.h = 0xD000; \par pMEM.dw.l = 0x0000; \par wBASEIO = 0x3E0; \par \par ResetProteus(); \par resetdsp(); \par uploadreb ("msndperm.reb"); \par uploadbin ("msndinit.bin"); \par initSMA(); \par Setup56kIRQ(); \par \par SetMidiOutPort( MOP_PROTEUS ); \par \par szDataString = ProDemoMidiSequence; \par while ((bMidiOutData = *szDataString++) != 0xFF) \{ \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \tab MODPortWrite ( MAKEWORD( bMidiOutData , 0x00 ) ); \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \tab if( *szDataString == 0xF7 ) \{ \par \tab GetDelayTime( TIME_PRO_SYSEX ); \par \tab \} \par \} \par \par printf("Proteus demo is playing\\nHit Any Key To Stop...\\n"); \par while( !kbhit() ); \par getch(); \par \par szDataString = ProDemoStop; \par while ((bMidiOutData = *szDataString++) != 0xFF) \{ \par MODPortWrite ( MAKEWORD( bMidiOutData , 0x00 ) ); \par \tab if( *szDataString == 0xF7 ) \{ \par \tab \tab GetDelayTime( TIME_PRO_SYSEX ); \par \tab \} \par \} \par \par Reset56kIRQ(); \par exit(0); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par You will notice that we run the function GetDelayTime after every OxF7 we send to the Proteus. This is because OxF7 always signifies the end of a system exclusive message. After the Proteus receives a full system exclusive message it requires approximately 30 milliseconds before it can accept any valid data. The function GetDelayTime is included in MCONTROL.C and when executed does not return until the passed number of 1/100ths seconds have passed. \par \par The distribution disk also has the source for a program called PRESETS.C. This program operates the same way as PRODEMO.C the only difference is that the data is read from a file. PRESETS.C can be used to load the General MIDI patch set up to the Proteus under DOS. \par \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885746}General Section{\*\bkmkend _Toc391885746} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par In our next example we look at receiving MIDI data from an external source. In the case of receiving MIDI data we will have to process messages from the DSP. The framework for the code will look like our digital audio skeleton. We will have the host queue, and wait for the ISR to dump some data into it. When this happens we will respond by transmitting that data back out to the on-board MIDI port. \par \par Setting the MIDI in port works exactly like setting the MIDI out port, only the associated masks are different. The function SetMidilnPort is included in MCONTROL.C. The available masks for the input port are listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {#define MIP_EXTIN\tab \tab Ox01 \par #define MIP_PROTEUS\tab Ox00 \par #define MIP_INMASK\tab \tab Ox32 \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par As mentioned above our framework for this program remains the same as before. When we enter we have to set both of the desired MIDI patches, and then send the DSP commands to initiate its MIDI I/O routines. Once the initialization is complete our main loop looks just like the play and record routines. Here we wait for the ISR to dump information into the host queue. \par \par When data is received we execute EvalDSPMessage which as before is just a large switch statement. In the particular case of HIMT_MIDI_IN_BYTE, we will just call MidilnData(), the function which will manage the queue. The source code fragment for the main routine is listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {SetMidiOutPort( MOP_PROTEUS ); \par SetMidiInPort( MIP_EXTIN ); \par \par SendDSPCommand( HDEX_MIDI_IN_START ); \par SendDSPCommand( HDEX_MIDI_OUT_START ); \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {while( !kbhit() ) \{ \par \tab if( pwHostTail != pwHostHead ) \{ \par \tab \tab if( ++pwHostHead >= ( pwHostQueue + HOSTQ_SIZE )) \{ \par \tab \tab \tab pwHostHead = pwHostQueue; \par \tab \tab \tab printf("Wrapping Host Queue\\n"); \par \tab \tab \} \par \tab \tab EvalDSPMessage( *pwHostHead ); \par \tab \} \par \} \par SendDSPCommand( HDEX_MIDI_IN_STOP ); \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par The function MidilnData continues to call MIDPortRead until the MIDI in data buffer is empty. Every MIDI byte that it reads in is sent out using MODPortWrite. When a key is pressed on an external MIDI keyboard, the DSP will read the MIDI in data and write it into the MIDI in buffer, and interrupt the host. The host will then write that same byte out to the on-board MIDI port. The functions MidilnData and MIDPortRead are listed below. \par \par }\pard\plain \s16\nowidctlpar\widctlpar\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920\tx8280{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f2\fs16\cgrid {void MidiInData() \par \{ \par \tab WORD wMidiData; \par \tab while( MIDQ->wHead != MIDQ->wTail ) \{ \par \tab \tab wMidiData = MIDPortRead(); \par \tab \tab if( HIBYTE( wMidiData ) == 0x00 ) \{ \par \tab \tab \tab MODPortWrite( wMidiData ); \par \tab \tab \} \par \tab \tab printf( "%.2X " , LOBYTE( wMidiData ) ); \par \tab \} \par \} \par \par \par WORD MIDPortRead( void ) \par \{ \par \tab WORD wRetVal , wHead; \par \par \tab wHead = MIDQ->wHead; \par \tab if( ++wHead > MIDQ->wSize ) \par \tab \tab wHead = 0; \par \par \tab wRetVal = *( pwMIDQData + MIDQ->wHead ); \par \par \tab MIDQ->wHead = wHead; \par \par \tab return( wRetVal ); \par \} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par MIDPortRead operates similar to MODPortWrite. However instead of writing to the tail of the MIDI out buffer, here we are reading from the head of the MIDI in buffer. \par \par Note that although this program provides a good example of how to read and write MIDI data, it is not necessary to actually transfer everything through the DSP. To trigger the on-baord MIDI port from an external source all we would have to do is set bit 1 of the MIDI patch BYTE and send it to the DSP. This can be accomplished using the SetMidiPatch function in MCONTROL.C. Consult the reference section of this manual for more information on this function. \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {We have now covered the basics of the MultiSound. We have been able to both read and write audio and MIDI. If you have any further questions you may want to consult other books on PC programming, digital audio, or MIDI. \par \par }\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {{\*\bkmkstart _Toc391885747}CHAPTER 6 - Reference{\*\bkmkend _Toc391885747} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\outlinelevel1\adjustright \b\i\f1\cgrid {{\*\bkmkstart _Toc391885748}Registers{\*\bkmkend _Toc391885748} \par }\pard\plain \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright \f1\fs20\cgrid { \par }{\b\ul DSP Host Port Interface Registers \par }\pard \nowidctlpar\widctlpar\tx1440\tx2160\tx2880\tx3600\tx7200{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HP_ICR\tab \tab xx0H\tab \tab Interrupt Control Register \tab (R/W) \par }\pard \nowidctlpar\widctlpar\tx1440\tx2160\tx2880\tx3600\tx7200{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HP_CVR\tab \tab xx1H\tab \tab Command Vector Register\tab (R/W) \par HP_ISR\tab \tab xx2H\tab \tab Interrupt Status Register\tab (RO) \par HP_IVR\tab \tab xx3H\tab \tab Interrupt Vector Register\tab (R/W) \par HP_RXZ\tab \tab xx4H\tab \tab (a byte of zeros) \tab (RO) \par HP_RXH\tab \tab xx5H\tab \tab Rx Data High\tab (RO) \par HP_RXM\tab \tab xx6H\tab \tab Rx Data Middle\tab (RO) \par HP_RXL\tab \tab xx7H\tab \tab Rx Data Low\tab (RO) \par HP_TXN\tab \tab xx4H\tab \tab (not used)\tab (RO) \par HP_TXH\tab \tab xx5H\tab \tab Tx Data High\tab (RO) \par HP_TXM\tab \tab xx6H\tab \tab Tx Data Middle\tab (RO) \par HP_TXL\tab \tab xx7H\tab \tab Tx Data Low\tab (RO)}{\b \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b \par }{\b\ul AT Bus Interface Control Registers (Write Only) \par }{\b\f2 HP_MEMM\tab \tab xx8H\tab \tab Shared Memory Map Register \par HP_IRQM\tab \tab xx9H\tab \tab IRQ # Mapping Register \par HP_DSPR\tab \tab xxAH\tab \tab DSP Reset Control Register \par HP_PROR\tab \tab xxBH\tab \tab Proteus Reset Control Register \par HP_BLKS\tab \tab xxCH\tab \tab Memory Block Select Register \par HP_WAIT\tab \tab xxDH\tab \tab Extra Wait State Register \par HP_BITM\tab \tab xxEH\tab \tab 8/16-bit Memory Mode Register \par HP_RESERVED\tab \tab xxFH\tab \tab (future use)}{\b \par \par }{\b\ul Board Information Registers (Read Only)\tab \par }{\b\f2 HPR_BLRC \tab \tab xx8H\tab \tab Board Level R/C Timer Input \par HPR_SPR1 \tab \tab xx9H\tab \tab (future) \par HPR_SPR2 \tab \tab xxAH\tab \tab (future) \par HPR_TCLO \tab \tab xxBh\tab \tab TOPCAT Chip Level \tab - Bit 0 \par HPR_TCL1 \tab \tab xxCh\tab \tab \tab \tab \tab \tab - Bit 1 \par HPR_TCL2 \tab \tab xxDh\tab \tab \tab \tab \tab \tab - Bit 2 \par HPR_TCL3 \tab \tab xxEh\tab \tab \tab \tab \tab \tab - Bit 3 \par HPR_TCL4 \tab \tab xxFh\tab \tab \tab \tab \tab \tab - Bit 4}{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_MEMM (xx8H)\tab Value\tab \tab Shared Memory Map Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPMEM_NONE\tab 0 \tab \tab Off/Not Mapped\tab (PU) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPMEM_B000 \tab 1\tab \tab B000H-B7FFH \par HPMEM_C800 \tab 2 \tab \tab C800H-CFFFH \par HPMEM_D000 \tab 3 \tab \tab D000H-D7FFH \par HPMEM_NU \tab 4 \tab \tab not used \par HPMEM_D800 \tab 5 \tab \tab D800H-DFFFH \par HPMEM_EOOO \tab 6 \tab \tab E000H-E7FFH \par HPMEM_E8OO \tab 7 \tab \tab E800H-EFFFH \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_IRQM (xx9H)\tab Value \tab \tab IRQ # Mapping Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPIRQ_NONE \tab \tab 0 \tab \tab None/Not Mapped\tab (PU) \par HPIRQ_5 \tab \tab 1 \tab \tab IRQ #5 \par HPIRQ_7 \tab \tab 2 \tab \tab IRQ #7 \par HPIRQ_9 \tab \tab 3 \tab \tab IRQ #9 (2) \par HPIRQ_10 \tab \tab 4 \tab \tab IRQ #10 \par HPIRQ_11 \tab \tab 5 \tab \tab IRQ #11 \par HPIRQ_12 \tab \tab 6 \tab \tab IRQ #12 \par HPIRQ_15 \tab \tab 7 \tab \tab IRQ #15 \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_DSPR (xxAH)\tab Value\tab \tab DSP Reset Control Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPDSPRESET_OFF\tab 0 \tab \tab DSP is Running \par HPDSPRESET_ON\tab 1 \tab \tab DSP is in Reset\tab (PU) \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_PROR (xxBH)\tab Value\tab \tab Proteus Reset Control Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPPRORESET_OFF\tab 0 \tab \tab Proteus is Running \par HPPRORESET_ON \tab 1 \tab \tab Proteus is in Reset\tab (PU) \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_BLKS (xxCH)\tab Value\tab \tab Memory Block Select Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPBLKSEL 0 \tab \tab 0 \tab View 1st Block \par }\pard \li2160\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 \tab \tab X/P:4000H-7FFFH, Y:8000H-BFFFH \tab (PU) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPBLKSEL 1 \tab \tab 1 \tab View 2nd Block \par }\pard \li2160\nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 \tab \tab X/P:8000H-BFFFH, Y:4000H-7FFFH \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 (see the Motorola DSP Manual for descriptions of the X and Y data busses) \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_WAIT (xxDH)\tab Value\tab \tab Extra Wait State Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPWAITSTATE_0 \tab 0 \tab \tab No Added Wait States\tab (PU) \par HPWAITSTATE_1 \tab 1 \tab \tab One Additional Wait State \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul HP_BITM (xxEH) \tab Value\tab \tab 8/16-bit Memory Mode Register Values \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HPBITMODE_16 \tab 0 \tab \tab 16-bit mode (full bandwidth) \tab (PU) \par HPBITMODE_8 \tab 1 \tab \tab 8-bit mode (approx. 25% reduction) \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul Host to DSP exceptions \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HDEX PLAY_START\tab \tab \tab Start digital audio play \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HDEX_PLAY_STOP\tab \tab \tab Stop digital audio play \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HDEX_PLAY PAUSE\tab \tab \tab Pause digital audio play \par HDEX_PLAY_RESUME \tab \tab \tab Resume digital audio play \par HDEX_RECORD START \tab \tab Start digital audio record \par HDEX_RECORD_STOP \tab \tab \tab Stop digital audio record \par HDEX_MIDI IN_START \tab \tab Start MIDI in data \par HDEX_MIDI_IN_STOP \tab \tab Stop MIDI in data \par HDEX_MIDI_OUT_START\tab \tab Start MIDI out data \par HDEX_MIDI_OUT_STOP \tab \tab Stop MIDI out data \par HDEX_AUX_REQ\tab \tab \tab Auxiliary request in TXL \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul TXL values for aux requests \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HDEXAR_MIDI_MAP_lO \par HDEXAR CLEAR_PEAKS \par HDEXAR_IN SET_POTS \tab \tab Record input volume has changed \par HDEXAR_AUX SET POTS \tab \tab Aux input volume has changed \par HDEXAR_CAL_ATO_D\tab \tab \tab Calibrate A/D converter \par HDEXAR_RD_EXT_DSP_BITS}{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright { \par }{\b\ul DSP to HOST exceptions \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul Exceptions in TXH at interrupt time \par }{\b\f2 HIMT_PLAY_DONE\tab \tab \tab Digital audio play complete \par \tab \tab \tab \tab \tab TXM has bank number (0 - 2) \par HIMT_RECORD DONE \tab \tab \tab Digital audio record complete \par \tab \tab \tab \tab \tab TXM has bank number (0 - 2) \par HIMT_MIDI_IN_BYTE\tab \tab \tab MIDI input buffer has data \par HIMT_DSP\tab \tab \tab \tab DSP special event TXM has message \par }{ \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\ul TXM values for HIMT DSP \par }\pard \nowidctlpar\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\b\f2 HIDSP_INT_PLAY_UNDER \tab \tab DSP internal play buffer underflow \par HIDSP_INT_RECORD_OVER \tab \tab DSP internal record buffer overflow \par HIDSP_INPUT_CLIPPING \tab \tab Digital audio input data is clipping \par HIDSP_MIDI_IN_OVER \tab \tab MIDI input buffer overflow \par HIDSP_MIDI_OVERRUN_ERR \tab \tab MIDI data port over-run error}{\b\f2\ul \par }{\ul \par }{\b\ul Structures used in MCONTROL.C \par }{\b\f2 struct JobQueueStruct \{ \par \tab WORD wStart; \tab // Start Address: DSP word X based \par \tab WORD wSize; \tab // Queue size in words \par \tab WORD wHead; \tab // Current output offset \par \tab WORD wTail; \tab // Current input offset \par \}; \par \par There are five of these structures. Each of them controls a queue specific to one task. These are hard coded, and not movable. \par \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {\b\f2 DAPQ \tab Digital Audio Play Queue \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {\b\f2 DARQ \tab Digital Audio Record Queue \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {\b\f2 MODQ \tab MIDI Out Data Queue \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {\b\f2 MIDQ \tab MIDI In Data Queue \par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnindent360 {\pntxtb \'b7}}\ls1\adjustright {\b\f2 DSPQ \tab DSP to host message Queue \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 \par struct DAQueueDataStruct \{ \par \tab WORD wStart; \tab // dsp X:xxxx based buffer address \par \tab WORD wSize; \tab // # of bytes in buffer \par \tab WORD wFormat; \tab // data format (1 = PCM, 2 = future) \par \tab WORD wSampleSize; // # of bits per sample \par \tab WORD wChannels; \tab // 1 = mono, 2 = stereo, etc. \par \tab WORD wSampleRate; \tab // samples / sec.(ie. 44kHz = 44100) \par \tab WORD wIntMsg; \tab \tab // returned in TXH at int time \par \tab WORD wFlags; \tab \tab // available for user \par \}; \par \par }{There are two sets of three of these structures. Three for recording digital audio, and three for playing digital audio. Each one has an associated buffer where the actual audio data is held. These are not hard coded. You could set up any number of data buffers at any location addressable by the DSP. \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 struct SMAO_CommonData \{ \par \tab WORD wCurrPlayByte; \tab // Curr # of bytes played \par \tab WORD wCurrReeordBytes; \tab // Curr # of bytes recorded \par \tab WORD wCurrPlayVolLeft; \tab \tab // current wave output volume left \par \tab WORD wCurrPleyVolRight; \tab // current wave output volume right \par \tab WORD wUser_1; \par \tab WORD wUser_2; \par \tab WORD wUser_3; \par \tab WORD wUser_4; \par \tab DWORD dwUser_5; \par \tab DWORD dwUser_6; \par \tab WORD wUser_7; \par \tab WORD wReserved_A; \par \tab WORD wReserved_B; \par \tab WORD wReserved_C; \par \tab WORD wReserved_D; \par \tab WORD wReserved_E; \par \tab WORD wReserved_F; \par \tab WORD wReserved_G; \par \tab WORD wReserved_H; \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 \tab WORD wCurrDSPStatusFlags; \tab // current DSP status flags \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 \tab WORD wCurrHostStatusFlags;\tab // current Host status flags \par \tab WORD wCurrInputTagBits; \tab // current A/D tag beta \par \tab WORD wCurrLeftPeak; \tab \tab // current A/D left peak value \par \tab WORD wCurrRightPeak; \tab \tab // current A/D right peak value \par \tab WORD wExtDSPbits; \tab \tab // external DSP hardware bits \par \tab BYTE bExtHostbits; \tab \tab // external Host hardware bits \par \tab BYTE bBoardLevel; \tab \tab // NultiSound rev level \par \tab BYTE bInPotPosRight; \tab \tab // input pot setting (0-FF) \par \tab BYTE bInPotPosleft; \tab \tab // input pot setting (0-FF) \par \tab BYTE hAuxPotPosRight; \tab \tab // aux/CD pot setting (0-FF) \par \tab BYTE bAuxPotPosLeft; \tab \tab // aux/CD pot setting (0-FF) \par \tab BYTE bUser_8; \par \tab BYTE bUser_9; \par \tab BYTE bUser_10; \par \tab BYTE bUser_11; \par \tab STTE bUser_12; \par \tab BYTE bUser 13; \par \tab WORD wUser_14; \par \tab WORD wUser_l5; \par \tab WORD wCalFreqAtoD; \tab \tab // calibrate freq for a/d \par \tab WORD wUser_16; \par \tab WORD wUser_17; \par \}; \par \par This structure is mapped into SMA bank 0 at ( pMEM.p + Ox7F40 ) and is used to access data common to the host and the DSP. These are hard coded and are not movable. The variables named wUser are available for programming by you. \par \par }{\b\ul SMA Variable Explanations \par }{\b wCurrlnputTagBits \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {The input tag bits are used in setting the record input levels. The hi byte represents the left channel, and the low byte represents the right channel. The only valid bits for each of these bytes are the 3 low order ones. These are defined as follows: \par \par }{\b\ul INPUT LEVEL\tab \tab \tab \tab T2 \tab T1 \tab TO \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 1.375 x FS\tab \tab \tab \tab 1 \tab 1 \tab 1 \par 1.250 x FS to 1.375 x FS\tab 1 \tab 1 \tab 0 \par 1.125 x FS to 1.250 x FS\tab 1 \tab 0 \tab 1 \par 1.000 x FS to 1.125 x FS\tab 1 \tab 0 \tab 0 \par -1.006dB to 0.000 dB\tab \tab 0 \tab 1 \tab 1 \par -3.060dB to -1.006dB\tab \tab 0 \tab 1 \tab 0 \par -8.000dB to -3.060dB\tab \tab 0 \tab 0 \tab 1 \par -8.000dB\tab \tab \tab \tab 0 \tab 0 \tab 0}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b wCurrLeftPeak and wCurrRightPeak \par }\pard \nowidctlpar\widctlpar\adjustright {The DSP will maintain a copy of the peak value in the SMA variables wCurrLeftPeak and wCurrRightPeak. These values will be maintained until the "clear peaks aux" request is issued. \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {\b wCurrDSPStatusFIaps \par }\pard \nowidctlpar\widctlpar\adjustright {This word is used to track the status of several DSP functions. The following is a bitwise representation of the variable. \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 Bit 0 play underflow \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 Bit 1 record overflow \par Bit 2 play paused \par Bit 3 spare \par Bit 4 spare \par Bit 5 spare \par Bit 6 record active \par Bit 7 MIDI in active \par Bit 8-15 spare}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul wCurrHostStatusFlags \par }\pard \nowidctlpar\widctlpar\adjustright {The only active flag of this variable is Bit zero. This is used during an A/D calibration to determine whether to calibrate relative to the signal ground, or the AGND. \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 Bit 0 low = Signal Ground \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 Bit 0 hi = AGND}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul wExtDSPbits \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 Bit 0 \tab DCAL state \par Bit 1 \tab Ext. MIDI conn state \par Bit 2 \tab spare \par Bit 3-7 \tab MadDog chip level \par Bit 8-15 \tab spare}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul bExtHostbits Bit 0 (board level revision code bit) \par }\pard \nowidctlpar\widctlpar\adjustright {Bit 1 spare \par }\pard \nowidctlpar\widctlpar\adjustright {Bit 2 spare \par Bit 3-7 TopCat chip level \par \par Functions in MCONTROL.C \par \par }{\b\ul GetDelay Time \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void GetDelayTime( wDelayTime ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function is used as a processor independent delay. The parameter specifies the number of milliseconds to wait. The function does not return until the specified delay time has passed. \par \par parameters: \par }{\b\f2 WORD wDelayTime \par }\pard \nowidctlpar\widctlpar\adjustright {This value specifies the delay time in milliseconds required. \par }\pard \nowidctlpar\widctlpar\adjustright { \par The pre-defined constants are: \par }{\b\f2 TIME_PRO RESET_DONE \par }\pard \nowidctlpar\widctlpar\adjustright {The required wait time before the Proteus can receive valid data after exiting reset. \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 TIME_PRO SYSEX \par }\pard \nowidctlpar\widctlpar\adjustright {The required wait time before the Proteus can receive valid data after receiving a complete system exclusive message. \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 TIME_PRO_RESET \par }\pard \nowidctlpar\widctlpar\adjustright {The required time that the Proteus must remain in reset. \par }\pard \nowidctlpar\widctlpar\adjustright { \par return value: none \par \par }{\b\ul GetExtDSPbits \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: WORD GetExtDSPbits( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function is used to read the external DSP bits. It assures that the values are valid by telling the DSP to update the values before it returns. The function returns the value of \par SMA->wExtDSPBits. \par \par parameters: none \par \par return value: SMA->wExtDSPbits \par \par The significance of the bits of this variable are as follows. \par \par }{\b\f2 Bit 0 \tab DCAL state \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 Bit 1 \tab External MIDI connection state \par Bit 2 \tab spare \par Bit 3-7 \tab MadDog chip level \par Bit 8-15 \tab spare}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul InitializeSMA \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void InitializeSMA( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function initializes the SMA. It sets all variables to their default values, and initializes the host pointers to their respective positions based on the variable pMEM. \par \par parameters: none \par \par return value: none \par \par comments: Be sure that pMEM.p is initialized before executing this function. \par \par }{\b\ul InterruptHandler \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void _interrupt _far InterruptHandler() \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function handles interrupts from the MultiSound. It is set up by executing SetupMsndlRQ. When the MultiSound issues an interrupt, this handler reads the data off the DSP queue and transfers it into the host queue defined by pwHostQueue, pwHostHead, and pwHostTail. \par \par parameters: none \par \par return value: none \par \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul MIDPortRead \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: WORD MIDPortRead( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function reads a piece of MIDI data off of the MIDI in data queue from the currently set MIDI in port. It is usually executed in response to the MIDI_IN_DATA exception from the DSP. \par \par parameters: none \par \par return value: \par The word read from the MIDI in data queue. The la byte contains the MIDI data actually read at the port. \par \par }{\b\ul MODPortWrite \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void MODPortWrite( WORD wMidiData ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function writes the MIDI data passed in wMidiData into the MIDI out data queue. This data is sent out to the port currently defined as the MIDI out port. \par \par parameters: \par }{\b\f2 WORD wMidiData \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {The low byte of this parameter contains the MIDI data which is actually sent out the port. The high byte is used for host command messages. The valid values for the high byte are: \par \par }{\b\f2 Ox00 - \tab MIDI out data \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 OxFE - \tab Next Message is a patch change \par OxFF - \tab Patch Change Data \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {return value: none \par \par }{\b\ul ResetDSP \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE ResetDSP( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function initializes the DSP by putting it into reset, and then taking it back out. \par \par parameters: none \par \par return value: \par }{\b\f2 1 - \tab successful reset \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 2 - \tab DSP timed out in reset \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul ResetMsndlRQ \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE ResetMsndlRQ( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function restores the state of the machine to before SetupMsndlRQ was executed. It uses the global variable nDSPSaveVect to restore the Interrupt vector to its original state. \par \par parameters: none \par \par return value: \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 1 - \tab Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 2 - \tab Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul ResetProteus (Classic Only) \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void ResetProteus( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function initializes the Proteus by putting it into reset and then taking it out. It takes care of the necessary delays required for a valid reset. Data can be sent to the Proteus immediately after returning from this function. \par \par parameters: none \par \par return value: none \par \par }{\b\ul SendDSPCommand \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SendDSPCommand( BYTE bCommand ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function is used to send any of the valid exceptions to the DSPs CVR. \par \par parameters: \par }{\b\f2 BYTE bCommand \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {This value is the specific command, defined in MSND_DSP.H, which is to be issued to the DSP. Valid values are as follows. \par \par }{\b\f2 HDEX_PLAY_START \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 HDEX_PLAY_STOP \par HDEX_PLAY_PAUSE \par HDEX_PLAY_RESUME \par HDEX_RECORD_START \par HDEX_RECORD_STOP \par HDEX_MIDI_IN_START \par HDEX_MIDI IN_STOP \par HDEX_MIDI OUT_START \par HDEX_MIDI OUT_STOP \par HDEX_AUX_REQ}{ \par }\pard \li288\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {The HDEX_AUX_REQ is used to perform special tasks. The tasks available are listed below and defined in MSND_DSP.H. One of these values must be placed in the TXL register before issuing the HDEX_AUX_REQ command. \par }\pard \qc\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 HDEXAR_CLEAR_PEAKS \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 HDEXAR_IN_SET_POTS \par HDEXAR_AUX_SET_POTS \par HDEXAR_CAL_A_TO_D \par HDEXAR RD_EXT_DSP_BITS}{ \par }\pard \li288\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {return value: \par }{\b\f2 1 - \tab Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - \tab Failure \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul SendHostWord \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SendHostWord( BYTE bHi, BYTE bMid, BYTE bLow) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function sends a word of data to the DSP through the host port. Its most common use is in sending the DSP AUX requests, and uploading the DSP code. \par \par parameters: \par }{\b\f2 BYTE bHi - hi byte of the DSP word \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 BYTE bMid - middle byte of the DSP word \par BYTE bLow - low byte of the DSP word \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul SetAuxVolume \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SetAuxVolume( BYTE bVolume, BYTE bType ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function sets the auxiliary input volume pots. It also issues the commands to the DSP so it will update the newly set values. \par \par parameters: \par }{\b\f2 BYTE bValue \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {This parameter represents the new setting for the auxiliary input volume pot, the value stored in the SMA. The range of valid values runs from Ox00 to OxFF. \par \par BYTE bType \par This parameter specifies the which volume to update. The valid values are defined in MCONTROL.H. These are as follows: \par \par }{\b\f2 LEFT\tab -\tab Set the left aux volume to bValue \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 RIGHT-\tab Set the right aux volume to bValue \par GANG\tab -\tab Set both aux volumes to bValue \par NONE\tab -\tab Do not change SMA values, but send the update commands to the DSP \par }\pard \li2160\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul SetlnVolume \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SetlnVolume( BYTE bVolume, BYTE bType ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function sets the record input volume pots. It also issues the commands to the DSP so it will update the newly set values. \par \par parameters: \par }{\b\f2 BYTE bValue \par }\pard \nowidctlpar\widctlpar\adjustright {This parameter represents the new setting for the record input volume pot, the value stored in the SMA. The range of valid values runs from Ox00 to OxFF. \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 BYTE bType \par }\pard \nowidctlpar\widctlpar\adjustright {This parameter specifies the which volume to update. The valid values are defined in MCONTROL.H. These are as follows: \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 LEFT -\tab Set the left aux volume to bValue \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 RIGHT-\tab Set the right aux volume to bValue \par GANG -\tab Set both aux volumes to bValue \par NONE -\tab Do not change SMA values, but send the update commands to the DSP \par }\pard \li1152\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul SetlntMap \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SetlntMap( BYTE blrq ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function is used exclusively by SetupMsndIRQ and Re-setMsndlRQ, and is not recommended for customer use. \par \par parameters: \par }{\b\f2 BYTE bIrq \tab \par }\pard \nowidctlpar\widctlpar\adjustright {The new IRQ value \par }\pard \nowidctlpar\widctlpar\adjustright { \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul SetMidilnPort \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void SetMidilnPort( BYTE bNewMIP ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function changes the MIDI in port. It places the change in the MIDI out queue so there will be no questions as to where a certain piece of MIDI data will come from. \par \par parameters: \par }{\b\f2 BYTE bNewMIP \par }\pard \nowidctlpar\widctlpar\adjustright {This is the value for the new MIDI in port. The valid values are defined in MCONTROL.H and are as follows: \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 MIP EXTIN\tab \tab Receive MIDI in data from external connector \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 MIP PROTEUS\tab Receive MIDI in data from the Proteus \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {return value: none \par \par }{\b\ul SetMidiOutPort \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void SetMidiOutPort( BYTE bNewMOP ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function changes the MIDI out port. It places the change in the MIDI out queue so there will be no questions as to where a certain piece of MIDI data will be sent. \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {parameters: \par }{\b\f2 BYTE bNewMOP \par }\pard \nowidctlpar\widctlpar\adjustright {This is the value for the new MIDI out port. The valid values are defined in MCONTROL.H and are as follows: \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\f2 MOP_PROTEUS \tab Send MIDI out data to the Proteus (or on-board header) \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 MOP_EXTOUT \tab Send MIDI out data to external OUT \par MOP_EXTTHRU \tab Send MIDI out data to external THRU \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {return value: none \par \par }{\b\ul SetMidiPatch \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: void SetMidiPatch( BYTE bNewPatch ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function changes the MIDI patch setting to the one defined by bNewPatch. \par \par parameters: \par }{\b\f2 BYTE bNewPatch \par }\pard \nowidctlpar\widctlpar\adjustright {This is the value for the new MIDI patch. The elements of this BYTE are defined as follows: \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b Proteus Input ( PltoEI )\tab 0 - DSP Out (Default)\tab 1 - External In \par }\pard \nowidctlpar\widctlpar\adjustright {\b DSP Input ( DltoEI )\tab 0 - Proteus Out (Default) \tab 1 - External In \par External Out ( EOtoDO )\tab 0 - Proteus Out (Default) \tab 1 - DSP Out \par External Thru ( ETtoPO )\tab 0 - DSP Out (Detault) \tab 1 - External In \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {In the case of Tahiti and Monterey, the Proteus out refers to the on-board MIDI header. \par \par }{\b BYTE MIDI map I/0 \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {bit 0 - DttoEI \par bit 1 - PltoEI \par bit 2 - 0 \par bit 3 - 0 \par bit 4 - ETtoPO \par bit 5 - EOtoDO \par bit 6 - 0 \par bit 7 - 0 \par \par return value: none \par \par }{\b\ul SetupMsndlRQ \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE SetupMsndlRQ( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function sets up the interrupt handler for the MultiSound. It takes care of saving the state of the machine for you. Be sure not to change the value of nDSPSaveVect after executing this. \par \par }\pard \nowidctlpar\widctlpar\adjustright {parameters: none \par }\pard \nowidctlpar\widctlpar\adjustright { \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 2 - Failure}{\b \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul UploadBin \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE UploadBin( char szBinFileName ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function uploads the file MSNDINIT.BIN to the DSP through the host port. \par \par parameters: \par }{\b\f2 char *szBinFileName \par }\pard \nowidctlpar\widctlpar\adjustright {The full path and file name of MSNDINIT. BIN \par }\pard \nowidctlpar\widctlpar\adjustright { \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul UploadDSPCode \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE UploadDSPCode( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function uploads all the DSP code necessary to operate the MultiSound. It assumes that you have linked the DSPCODE object file with your executable program. \par \par parameters: none \par \par return value: \par }{\b\f2 1 - Success \par 0 - Failure}{ \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\b\ul UploadReb \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE UploadReb( char szRebFileName ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function uploads the file MSNDPERM.REB to the DSP through the SMA. \par \par parameters: \par }{\b\f2 char *szRebFileName \par }\pard \nowidctlpar\widctlpar\adjustright {The full path and file name of MSNDPERM.REB. \par }\pard \nowidctlpar\widctlpar\adjustright { \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul WaitHostClear \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE WaitHostClear( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {This function waits until the DSP issues the host clear flag. It is used to make sure the DSP will receive a command through the CVR when one is sent. \par \par parameters: none \par \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul WaitTXDEmpty \par }\pard \nowidctlpar\widctlpar\adjustright {syntax: BYTE WaitTXDEmpty( void ) \par }\pard \nowidctlpar\widctlpar\adjustright { \par This function waits for the DSP to read any current data out of the TXD registers. It is used to make sure that data sent through the host port will not be over written. \par \par parameters: none \par \par return value: \par }{\b\f2 1 - Success \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 0 - Failure \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul Proteus System Exclusive Messages (Classic Only) \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {\b Set master volume \par }\pard \nowidctlpar\widctlpar\adjustright {\f2 OxFO, Ox18, Ox04, Oxid, Ox14, Oxvv, OxF7 \par id = Ox00 \par vv = Volume value from Ox00 to Ox7F \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {\b Request master volume \par }\pard \nowidctlpar\widctlpar\adjustright {\f2 OxFO, Ox18, Ox04, Oxid, Ox16, OxF7 \par id = Ox00 \par }{ \par }\pard \nowidctlpar\widctlpar\adjustright {The Proteus will respond by sending the master volume string where vv will equal the current volume. \par \par }{\b Front panel data request \par }\pard \nowidctlpar\widctlpar\adjustright {OxFO, Ox18, Ox04, Oxid, Ox17, OxF7 \par }\pard \nowidctlpar\widctlpar\adjustright { \par The Proteus will respond with the following sequence \par OxFO Ox18 Ox04 Oxid Ox18 \par aa aa aa aa aa aa aa aa \par aa aa aa aa aa aa aa aa \par aa aa aa aa aa aa aa aa \par aa aa aa aa aa aa aa aa \par cc OL OxF7 \par \par where \par }\pard \nowidctlpar\widctlpar\adjustright {aa = 32 ASCII bytes representing the text on screen, top left to bottom right. There are a few non-ASCII special characters: \par }\pard \nowidctlpar\widctlpar\adjustright { \par aa = 00 = -2 \par aa = 01 = -1 \par aa = 7E = \endash \par cc = LCD cursor position \par ( 0 to 1F, 0=top left, 10=bottom left, 1F=bottom right ) \par OL = LED status bits \par \par bit 0: Master LED ( 0=off, 1=on ) \par bit 1: Edit LED ( 0=off, 1=on ) \par bits 2,3: Enter LED ( 0=off, 1=on, 2=flashing ) \par bits 4-7: unused, always 0 \par \par }{\b Front panel switch press \par }\pard \nowidctlpar\widctlpar\adjustright {OxFO Ox18 Ox04 id Ox19 Os OxF7 \par }\pard \nowidctlpar\widctlpar\adjustright {where \par Os = switch# \par 0: Master switch press and release \par 1: Edit switch press and release \par 2: Enter switch press and release \par 3: Rotary encoder decrement by one \par 4: Cursor switch press and release \par 5: Rotary encoder increment by one \par \par }{\b Start Proteus Demo \par }\pard \nowidctlpar\widctlpar\adjustright {1) Send Master switch press \par }\pard \nowidctlpar\widctlpar\adjustright {2) Send 16 rotary encoder increment \par 3) Send cursor switch press \par 4) Send enter switch press \par \par }{\b Stop Proteus Demo \par }\pard \nowidctlpar\widctlpar\adjustright {1) Send enter switch press \par }\pard \nowidctlpar\widctlpar\adjustright {2) Send cursor switch press \par 3) Send 16 rotary encoder decrement \par 4) Send master switch press \par \par }{\b\ul SMA memory map \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {Shared Memory Area }{\i I }{Bank 0 \par }{\b\f2 DAP buffer #1: \tab Ox0000 - Ox23FF \par }\pard \nowidctlpar\widctlpar\adjustright {\b\f2 DAP buffer #2: \tab Ox2400 - Ox47FF \par DAP buffer #3: \tab Ox4800 - Ox6BFF \par }\pard \qc\nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {\b 3 * DAP Queue Data Structures \par }\pard \nowidctlpar\widctlpar\adjustright {ORG Ox6COO \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\ul \tab \tab \tab Struct 1 \tab \tab Struct 2 \tab \tab Struct 3 \par }\pard \nowidctlpar\widctlpar\adjustright {wStart\tab \tab \tab ORG + 0x00 \tab \tab ORG + 0x10 \tab \tab ORG + 0x20 \par }\pard \nowidctlpar\widctlpar\adjustright {wSize\tab \tab \tab ORG + 0x02 \tab \tab ORG + 0x12 \tab \tab ORG + 0x22 \par wFormat\tab \tab ORG + 0x04 \tab \tab ORG + 0x14 \tab \tab ORG + 0x24 \par wSampleSize \tab \tab ORG + 0x06 \tab \tab ORG + 0x16 \tab \tab ORG + 0x26 \par wChannels\tab \tab ORG + 0x08 \tab \tab ORG + 0x18 \tab \tab ORG + 0x28 \par wSampleRate \tab \tab ORG + 0x0A \tab \tab ORG + 0x1A \tab \tab ORG + 0x2A \par wlntMsg\tab \tab ORG + 0x0C \tab \tab ORG + 0x1C \tab \tab ORG + 0x2C \par wFlags\tab \tab \tab ORG + 0x0E \tab \tab ORG + 0x1E \tab \tab ORG + 0x2E \par \par }{\b 3 * DAR Queue Data Structures \par }\pard \nowidctlpar\widctlpar\adjustright {ORG\tab Ox6C30 \par }\pard \nowidctlpar\widctlpar\adjustright { \par }{\ul \tab \tab \tab Struct 1 \tab \tab Struct 2 \tab \tab Struct 3 \par }\pard \nowidctlpar\widctlpar\adjustright {wStart\tab \tab \tab ORG + 0x00 \tab \tab ORG + 0x10 \tab \tab ORG + 0x20 \par }\pard \nowidctlpar\widctlpar\adjustright {wSize\tab \tab \tab ORG + 0x02 \tab \tab ORG + 0x12 \tab \tab ORG + 0x22 \par wFormat\tab \tab ORG + 0x04 \tab \tab ORG + 0x14 \tab \tab ORG + 0x24 \par wSampleSize \tab \tab ORG + 0x06 \tab \tab ORG + 0x16 \tab \tab ORG + 0x26 \par wChannels\tab \tab ORG + 0x08 \tab \tab ORG + 0x18 \tab \tab ORG + 0x28 \par wSampleRate \tab \tab ORG + 0x0A \tab \tab ORG + 0x1A \tab \tab ORG + 0x2A \par wlntMsg\tab \tab ORG + 0x0C \tab \tab ORG + 0x1C \tab \tab ORG + 0x2C \par wFlags\tab \tab \tab ORG + 0x0E \tab \tab ORG + 0x1E \tab \tab ORG + 0x2E \par \par MODQ Buffer \tab \tab 0x6C60 - 0x745F}{\i \par }\pard \nowidctlpar\widctlpar\adjustright {MIDQ Buffer\tab \tab 0x7460 - 0x785F \par }\pard \nowidctlpar\widctlpar\adjustright {DSPQ Buffer\tab \tab 0x7860 - 0x7DFF \par \par DAPQ->Start \tab \tab Ox7F00 \par DAPQ->Size \tab \tab Ox7F02 \par DAPQ->Head \tab \tab Ox7F04 \par DAPQ->Tail \tab \tab Ox7F06 \par \par DARQ->Start \tab \tab Ox7FO8 \par DARQ->Size \tab \tab Ox7FOA \par DARQ->Head \tab \tab Ox7FOC}{\i \par }\pard \nowidctlpar\widctlpar\adjustright {DARQ->Tail \tab \tab Ox7FOE}{\i \par \par }{MODQ->Start \tab \tab Ox7F10 \par }\pard \nowidctlpar\widctlpar\adjustright {MODQ->Size \tab \tab Ox7F12}{\i \par }\pard \nowidctlpar\widctlpar\adjustright {MODQ->Head \tab \tab Ox7F14 \par }\pard \nowidctlpar\widctlpar\adjustright {MODQ->Tail \tab \tab Ox7F16 \par \par MIDQ->Start \tab \tab Ox7F18 \par }\pard \nowidctlpar\widctlpar\adjustright {MIDQ->Size \tab \tab Ox7F1A \par }\pard \nowidctlpar\widctlpar\adjustright {MIDQ->Head \tab \tab Ox7F1C \par MIDQ->Tail\tab \tab Ox7F1E \par \par DSPQ->Start \tab \tab Ox7F20 \par DSPQ->Size \tab \tab Ox7F22 \par DSPQ->Head \tab \tab Ox7F24 \par DSPQ->Tail \tab \tab Ox7F26 \par \par wCurrPIayBytes\tab \tab Ox7F40\tab \tab // decrements with time}{\i \par }\pard \nowidctlpar\widctlpar\adjustright {wCurrRecordBytes\tab Ox7F42\tab \tab // decrements with time \par }\pard \nowidctlpar\widctlpar\adjustright {wCurrPlayVolLeft\tab Ox7F44 \par wCurrPlayVolRight\tab Ox7F46 \par wCurrInVolLeft\tab \tab 0x7F48 \par wCurrInVolRight\tab 0x7F4A \par \par HOST definable\tab Ox7F48 - Ox7F59 \par \par Reserved by DSP\tab Ox7F5A - Ox7F69 \par \par wCurrDSPStatusFlags\tab Ox7F6A }{\i \par }\pard \nowidctlpar\widctlpar\adjustright {wCurrHostStatusFlags\tab Ox7F6C \par }\pard \nowidctlpar\widctlpar\adjustright {wCurrlnputTagBits\tab Ox7F6E \par wCurrLeftPeak\tab \tab Ox7F70 \par wCurrRightPeak\tab Ox7F72 \par wExtDSPbits\tab \tab Ox7F74 \par bExtHostbits\tab \tab Ox7F76 \par bBoardLevel\tab \tab Ox7F77 \par blnPotPosRight\tab \tab Ox7F78 \par blnPotPosLeft\tab \tab Ox7F79 \par bAuxPotPosRight\tab Ox7F7A \par bAuxPotPosLeft\tab Ox7F7B \par \par HOST definable\tab Ox7F7C - Ox7F85 \par \par wCalFreqAtoD\tab \tab Ox7F86 \par \par HOST definable\tab Ox7F88 - Ox7F8B \par \par }{\b\ul Shared Memory Area }{\b\i\ul I }{\b\ul Bank 1 \par }\pard \nowidctlpar\widctlpar\adjustright { \par }\pard \nowidctlpar\widctlpar\adjustright {DAR Buffer #1 \tab \tab Ox0000 - Ox1FFF \par DAR Buffer #2 \tab \tab Ox2000 - Ox3FFF \par DAR Buffer #3 \tab \tab Ox4000 - Ox5FFF \par \par }\pard \nowidctlpar\widctlpar\adjustright {Reserved by DSP \tab Ox6000 - Ox7FFF \par }\pard \nowidctlpar\widctlpar\adjustright {\tab \par }{\b\ul Additional Notes \par }\pard \nowidctlpar\widctlpar\adjustright {The example programs now contain two makefiles. The original Microsoft makefiles remain unchanged. The second makefile is for people using the Borland C/C++ ver3.1 compiler. These files have the extension .MAK. \par }\pard \nowidctlpar\widctlpar\adjustright { \par There are now two header files for the examples. MCONTROL.H and PCONTROL.H. MCONTROL.H remains the same except for the addition of some functional prototypes. This file should only be used to include when compiling MCONTROL.C. PCONTROL.H is now used as the include in the example applications. It is basically the same as MCONTROL.H, only \par it defines all the global variables to be external. \par \par The function GetDelayTime used to be an assembly routine. This function has been rewritten in C to provide compatibility with the Borland compiler. \par \par The DSP code .ASM file has been changed so that the data now resides in the DATA segment rather than the CODE segment. This was done for compliance with the Borland 3.1 compiler. The source is provided for this OBJ in case you want to put the code in the code segment to \par discard it after uploading. \par \par \par All the sources have been compiled and tested using the Borland C/C++ ver3.1 compiler. If you are using a different version of the Borland compiler, you may need to modify the source code for successful compilation. \par }\pard \nowidctlpar\widctlpar\adjustright {\b\ul \par }}