'                        ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
'                  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
'            ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
'       ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
' °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
'³       Molnar \ Kucalaba Productions' Sound Blaster Music Format v1.1      ³
'³                  Instrument Creator (c) copyright 1996                    ³
'³                                                                           ³
'³                       Programmed by Luke Molnar.                          ³
'³                                                                           ³
'³   This version (1.1) now includes a Wave Form bar, which lets you hear    ³
'³ a fuller range of sounds from the current instrument but does NOT go in   ³
'³                        the instrument file.                               ³
'³                                                                           ³
'³  This program is an Adlib/SoundBlaster MIDI-like Instrument creator.  It  ³
'³   was mainly programmed to satisfy our curiosity on the subject of MIDI   ³
'³  instruments, and it was programmed in one night.  Even if this program   ³
'³  has no relevance to anything we do in the future, it is still somewhat   ³
'³ fun to screw around with.  Right now we plan on incorporating this into   ³
'³  our not-yet started MK Jamz Orchestrator, which will produce MIDI-like   ³
'³           files that use instruments created with this program.           ³
'³                                                                           ³
'³   Since you are bored enough to read this, you must have a lot of free    ³
'³   time on your hands.  So why not spend it doing something useful, like   ³
'³   visiting our WWW and FTP sites?  At least you can download TONS of      ³
'³            top notch QBasic source while you are bored.                   ³
'³                                                                           ³
'³   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿   ³
'³   ³        WWW : http://members.aol.com/mkwebsite/index.html          ³   ³
'³   ³                                                                   ³   ³
'³   ³            FTP : ftp://members.aol.com/blood225/                  ³   ³
'³   ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ   ³
'³                                                                           ³
'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
' °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
'       ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
'            ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
'                  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
'                        ßßßßßßßßßßßßßßßßßßßßßßßßßßßßß

DECLARE SUB GetPress ()
DECLARE SUB DragWave ()
DECLARE SUB UpdateWaveForm (NewX%)
DECLARE SUB PlayNote (X$)
DECLARE SUB SetIns (Channel%)
DECLARE SUB SBInit ()
DECLARE SUB ClearBars ()
DECLARE SUB UpdateSel ()
DECLARE SUB AssignValues ()
DECLARE SUB IORoutine (Flag%)
DECLARE SUB Convert (X$)
DECLARE SUB SBPlay (freq%, Duration%, Octave%, waveform%)
DECLARE SUB PlayFunkyMusic ()
DECLARE SUB MouseHide ()
DECLARE SUB MouseStatus (lb%, rb%, xMouse%, yMouse%)
DECLARE SUB DragTheBars (ActiveBar%)
DECLARE SUB UpdateTheBar (ActiveBar%)
DECLARE SUB Font (Text$, XStart%, ystart%, xscale%, Yscale%, Style%, Clr%)
DECLARE SUB MouseDriver (ax%, bx%, cx%, dx%)
DECLARE SUB MouseShow ()
DECLARE SUB Init ()
DECLARE SUB LoadIns (FileName$, Array AS ANY)
DECLARE SUB WriteIns (FileName$)
DECLARE SUB WriteReg (reg%, value%)
DECLARE SUB SetStereo (OnOff%)
DECLARE FUNCTION MouseWaveInRange% ()
DECLARE FUNCTION TheyClickedWave% ()
DECLARE FUNCTION Legalize$ (FileName$)
DECLARE FUNCTION lnput$ (L%, Row%, Col%)
DECLARE FUNCTION TheyClickedFiles% ()
DECLARE FUNCTION TheyClickedExit% ()
DECLARE FUNCTION TheyClickedSave% ()
DECLARE FUNCTION TheyClickedLoad% ()
DECLARE FUNCTION TheyClickedTest% ()
DECLARE FUNCTION MouseIsOnBar% ()
DECLARE FUNCTION MouseDragIsInRange% ()
DECLARE FUNCTION MouseInit% ()


SBInit

TYPE InsType
 MMult AS INTEGER
 MLevel AS INTEGER
 MAttack AS INTEGER
 MSustain AS INTEGER
 CMult AS INTEGER
 CLevel AS INTEGER
 Cattack AS INTEGER
 CSustain AS INTEGER
END TYPE

TYPE BarType
 x1 AS INTEGER
 x2 AS INTEGER
 CurY AS INTEGER
END TYPE

DIM SHARED zoroctave, dur%, byte%, Sbpla, Wave% ' Keeps value through CALLs
zoroctave = 800: dur% = 10: byte% = &H29: Wave% = &H2

DIM SHARED Bars(1 TO 9) AS BarType
DIM SHARED CurrentIns AS InsType
DIM SHARED FontBuf(0) AS STRING * 10368
DIM SHARED Back%(5000)
DIM SHARED lb%, rb%, X%, y%
DIM SHARED mouse$: mouse$ = SPACE$(57)
FOR i% = 1 TO 57:  READ a$:  h$ = CHR$(VAL("&H" + a$))
MID$(mouse$, i%, 1) = h$: NEXT i%
DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B
DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53
DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F
DATA 8B,5E,06,89,17,5D,CA,08,00
RESTORE
ms% = MouseInit%
IF NOT ms% THEN
  PRINT "Mouse not found"
  END
END IF

Init


DO
 MouseStatus lb%, rb%, X%, y%

 SELECT CASE lb%
  CASE -1:
          IF TheyClickedTest THEN PlayFunkyMusic
          IF TheyClickedLoad THEN IORoutine 1
          IF TheyClickedSave THEN IORoutine 2
          IF TheyClickedFiles THEN
             MouseHide
             CLS
             FILES "*.ins"
             GetPress
             Init
          END IF
          IF TheyClickedExit THEN EXIT DO
          IF MouseIsOnBar% THEN DragTheBars (MouseIsOnBar%)
          IF TheyClickedWave THEN DragWave
  END SELECT

LOOP

CLS
SCREEN 0
SYSTEM

SUB AssignValues
Bars(1).CurY = CurrentIns.MMult + 120
Bars(2).CurY = CurrentIns.MLevel + 120
Bars(3).CurY = CurrentIns.MAttack + 120
Bars(4).CurY = CurrentIns.MSustain + 120
Bars(5).CurY = CurrentIns.CMult + 120
Bars(6).CurY = CurrentIns.CLevel + 120
Bars(7).CurY = CurrentIns.Cattack + 120
Bars(8).CurY = CurrentIns.CSustain + 120
END SUB

SUB ClearBars
FOR Bar% = 1 TO 8
 LINE (Bars(Bar%).x1, Bars(Bar%).CurY)-(Bars(Bar%).x2, Bars(Bar%).CurY + 2), 0, BF
NEXT
END SUB

SUB DragTheBars (ActiveBar%)
MouseHide
DO UNTIL lb% <> -1
 MouseStatus lb%, rb%, X%, y%
 IF MouseDragIsInRange THEN UpdateTheBar (ActiveBar%)
LOOP
MouseShow
END SUB

SUB DragWave
MouseHide
DO UNTIL lb% <> -1
 MouseStatus lb%, rb%, X%, y%
 IF MouseWaveInRange THEN UpdateWaveForm (X%)
LOOP
MouseShow
END SUB

SUB Font (Text$, XStart%, ystart%, xscale%, Yscale%, Style%, Clr%)

px% = XStart%  ' physical x and physical y
py% = ystart%

LHeight% = Yscale% * 8
Optimize% = 63 \ LHeight% ' Any constant math operations done multipe times
                          ' in the main loop should, well, not be done
                          ' in the main loop.


' Instead of wasting our time with all this MID$ garbage to access bytes in
' font buffer, we'll just take a PEEK directly at them.
DEF SEG = VARSEG(FontBuf(0))

 FOR h% = 1 TO LEN(Text$)
  FPtr% = 81 * (ASC(MID$(Text$, h%, 1)) - 1) - 1
  FOR X% = 0 TO 8
   FOR y% = 0 TO 8

    Col% = PEEK(VARPTR(FontBuf(0)) + FPtr%)
    FPtr% = FPtr% + 1
    IF Col% THEN
     SELECT CASE Style%
      ' If you desire a y scale factor greater than 8, you
      ' must change the division to higher precision...very slow.
      ' Or, you could find a way around it.
      CASE 1:
            IF Yscale% = 1 THEN
              PSET (px% + .4 * py%, py%), Clr%
            ELSE
             FOR sx% = px% TO px% + xscale%
              FOR sy% = py% TO py% + Yscale%
               PSET (sx% + .4 * sy%, sy%), Clr%
              NEXT
             NEXT
            END IF
      CASE 2:
            IF Yscale% = 1 THEN
              PSET (px%, py%), Clr%
            ELSE
             FOR sx% = px% TO px% + xscale%
              FOR sy% = py% TO py% + Yscale%
               PSET (sx%, sy%), Clr%
              NEXT
             NEXT
            END IF
     END SELECT
    END IF
    py% = py% + Yscale%
   NEXT
  px% = px% + xscale%
  py% = ystart%
  NEXT
 NEXT h%
DEF SEG
END SUB

SUB GetPress
DO
 MouseStatus lb%, rb%, X%, y%
LOOP UNTIL INKEY$ <> "" AND lb% <> 0 OR rb% <> 0
END SUB

SUB Init
OPEN "basefont.dat" FOR BINARY AS #1
 IF LOF(1) < 2 THEN
  PRINT "Font file not found!"
  CLOSE
  KILL "basefont.dat"
  SYSTEM
 ELSE
  GET #1, , FontBuf(0)
 END IF
CLOSE
LoadIns "standard.ins", CurrentIns
CLS
SCREEN 12
PAINT (0, 0), 7, 1
Font "M \ K Instrument Creator v1.1", 50, 5, 2, 4, 1, 0
LINE (50, 1)-(587, 45), 0, B
Font " Modulator  Carrier ", 0, 60, 2, 2, 2, 8
Font "Multiple  Level  Attack  Sustain    Multiple  Level  Attack  Sustain", 5, 90, 1, 1, 2, 0
LINE (310, 80)-(310, 390), 0
LINE (0, 390)-(640, 390), 0
LINE (0, 80)-(640, 80), 0
LINE (269, 399)-(351, 431), 15, B
LINE (270, 400)-(350, 430), 0, BF
Font "Test", 276, 400, 2, 3, 2, 10
LINE (179, 399)-(261, 431), 15, B
LINE (180, 400)-(260, 430), 0, BF
Font "Load", 186, 400, 2, 3, 2, 10
LINE (359, 399)-(441, 431), 15, B
LINE (360, 400)-(440, 430), 0, BF
Font "Save", 366, 400, 2, 3, 2, 10
LINE (79, 399)-(171, 431), 15, B
LINE (80, 400)-(170, 430), 0, BF
Font "*.INS", 82, 400, 2, 3, 2, 10
LINE (449, 399)-(531, 431), 15, B
LINE (450, 400)-(530, 430), 0, BF
Font "Exit", 456, 400, 2, 3, 2, 10
Font "Wave Form", 88, 431, 1, 2, 1, 0
LINE (235, 450)-(385, 470), 0, BF
LINE (234, 449)-(386, 471), 15, B
LINE (357, 436)-(375, 446), 15, B
Bars(1).x1 = 20
Bars(1).x2 = 45
Bars(2).x1 = 105
Bars(2).x2 = 130
Bars(3).x1 = 170
Bars(3).x2 = 195
Bars(4).x1 = 250
Bars(4).x2 = 275
Bars(5).x1 = 350
Bars(5).x2 = 375
Bars(6).x1 = 430
Bars(6).x2 = 455
Bars(7).x1 = 495
Bars(7).x2 = 520
Bars(8).x1 = 570
Bars(8).x2 = 595
Bars(9).x1 = 450
Bars(9).x2 = 470
Bars(9).CurY = Wave% + 234
AssignValues
FOR X% = 1 TO 8
 LINE (Bars(X%).x1, 120)-(Bars(X%).x2, 375), 0, BF
 LINE (Bars(X%).x1 - 1, 119)-(Bars(X%).x2 + 1, 376), 15, B
NEXT
UpdateSel
UpdateWaveForm Bars(9).CurY
MouseShow
END SUB

SUB IORoutine (Flag%)
' Flag% = 1 --> Load  2--> Save
MouseHide
GET (170, 215)-(470, 265), Back%

 LINE (170, 215)-(470, 265), 15, B
 LINE (171, 216)-(469, 264), 0, BF
 
  IF Flag% = 1 THEN
   Text$ = "Load Instrument named..."
  ELSE
   Text$ = "Save Instrument as..."
  END IF

Font Text$, 172, 215, 1, 2, 2, 12

FileName$ = lnput$(39, 172, 235)

PUT (170, 215), Back%, PSET

IF FileName$ = "ABORT MISSION!" THEN
 MouseShow
 EXIT SUB ' (If user pressed escape)
END IF

FileName$ = Legalize$(FileName$)


IF Flag% = 1 THEN
 ClearBars
 LoadIns FileName$, CurrentIns
 AssignValues
 UpdateSel
ELSE
 WriteIns FileName$
END IF
MouseShow
END SUB

FUNCTION Legalize$ (FileName$)
IF INSTR(FileName$, ".") = 0 THEN
 FileName$ = FileName$ + ".INS"
END IF
IF LEN(FileName$) > 8 AND INSTR(FileName$, ".") = 0 THEN
 FileName$ = RIGHT$(FileName$, 8) + ".INS"
END IF
IF LEN(FileName$) < 1 THEN
 FileName$ = "NONAME.INS"
END IF
Legalize$ = FileName$
END FUNCTION

FUNCTION lnput$ (L%, Row%, Col%)
Orow% = Row%
txt$ = ""

FOR Times% = 1 TO L%
 Font "_", Row% + Times% * 8 - 10, Col% + 4, 1, 2, 2, 7
NEXT

DO
ax$ = INKEY$
SELECT CASE ax$
 CASE CHR$(8):  IF LEN(txt$) > 0 THEN txt$ = LEFT$(txt$, LEN(txt$) - 1)
                IF Orow% < Row% THEN Row% = Row% - 8
                LINE (Row%, Col%)-(Row% + 8, Col% + 19), 0, BF
 CASE " ":  Row% = Row% + 8: txt$ = txt$ + " "
 CASE CHR$(13): lnput$ = txt$: EXIT FUNCTION
 CASE CHR$(27): lnput$ = "ABORT MISSION!": EXIT FUNCTION
 CASE ELSE:
            IF LEN(txt$) < L% AND LEN(ax$) = 1 THEN
             txt$ = txt$ + ax$
             Font ax$, Row%, Col%, 1, 2, 2, 11
             Row% = Row% + 8
            END IF

END SELECT
LOOP
END FUNCTION

SUB LoadIns (FileName$, Array AS InsType)
OPEN FileName$ FOR BINARY AS #1
 IF LOF(1) < 2 THEN
  BEEP
  CLOSE
  KILL FileName$
  EXIT SUB
 END IF
 GET #1, , Array
CLOSE #1
SetIns 1
END SUB

FUNCTION MouseDragIsInRange%
 IF y% >= 120 AND y% < 370 THEN MouseDragIsInRange% = 1
END FUNCTION

DEFLNG A-Z
SUB MouseDriver (ax%, bx%, cx%, dx%)
  DEF SEG = VARSEG(mouse$)
  mouse% = SADD(mouse$)
  CALL Absolute(ax%, bx%, cx%, dx%, mouse%)
END SUB

SUB MouseHide
 ax% = 2
 MouseDriver ax%, 0, 0, 0
END SUB

FUNCTION MouseInit%
  ax% = 0
  MouseDriver ax%, 0, 0, 0
  MouseInit% = ax%
END FUNCTION

DEFSNG A-Z
FUNCTION MouseIsOnBar%
FOR Times% = 1 TO 8
 SELECT CASE X%
   CASE Bars(Times%).x1 TO Bars(Times%).x2:
                                        
           SELECT CASE y%
             CASE Bars(Times%).CurY TO Bars(Times%).CurY + 3: MouseIsOnBar = Times%: EXIT FUNCTION
           END SELECT
            
 END SELECT
NEXT
END FUNCTION

DEFLNG A-Z
SUB MousePut (X%, y%)
  ax% = 4
  cx% = X%
  dx% = y%
  MouseDriver ax%, 0, cx%, dx%
END SUB

SUB MouseRange (x1%, y1%, x2%, y2%)
  ax% = 7
  cx% = x1%
  dx% = x2%
MouseDriver ax%, 0, cx%, dx%
  ax% = 8
  cx% = y1%
  dx% = y2%
  MouseDriver ax%, 0, cx%, dx%
END SUB

SUB MouseShow
  ax% = 1
  MouseDriver ax%, 0, 0, 0
END SUB

SUB MouseStatus (lb%, rb%, xMouse%, yMouse%)
  ax% = 3
  MouseDriver ax%, bx%, cx%, dx%
  lb% = ((bx% AND 1) <> 0)
  rb% = ((bx% AND 2) <> 0)
  xMouse% = cx%
  yMouse% = dx%
END SUB

DEFSNG A-Z
FUNCTION MouseWaveInRange%
'IF y% >= 450 AND y% <= 470 THEN
 IF X% >= 235 AND X% <= 385 THEN MouseWaveInRange% = 1
'END IF
END FUNCTION

SUB PlayFunkyMusic
PlayNote "CDEFGAB"
END SUB

SUB PlayNote (X$)

FOR Lop% = 1 TO LEN(X$)

  Temp$ = MID$(X$, Lop%, 1)
  
   SELECT CASE Temp$
      CASE "D"
        WriteReg &HA0 + Channel%, &H81
        WriteReg &HB0 + Channel%, &H21 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "E"
        WriteReg &HA0 + Channel%, &HB0
        WriteReg &HB0 + Channel%, &H21 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "F"
        WriteReg &HA0 + Channel%, &HCA
        WriteReg &HB0 + Channel%, &H21 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "F#"
        WriteReg &HA0 + Channel%, &HE5
        WriteReg &HB0 + Channel%, &H21 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "G"
        WriteReg &HA0 + Channel%, &H2
        WriteReg &HB0 + Channel%, &H22 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "A"
        WriteReg &HA0 + Channel%, &H41
        WriteReg &HB0 + Channel%, &H22 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "B"
        WriteReg &HA0 + Channel%, &H87
        WriteReg &HB0 + Channel%, &H22 + 16
        WriteReg &HE0 + Channel%, Wave%
      CASE "C"
        WriteReg &HA0 + Channel%, &HAE
        WriteReg &HB0 + Channel%, &H22 + 16
        WriteReg &HE0 + Channel%, Wave%
    END SELECT

 TIME! = TIMER + .1
 DO
 LOOP UNTIL TIMER >= TIME!

 WriteReg &HB0 + 0, 0
 
NEXT

END SUB

DEFINT Z
SUB SBInit
   FOR z% = 1 TO &HF5
     CALL WriteReg(z%, 0)
   NEXT z%
END SUB

DEFSNG Z
SUB SetIns (Channel%)
' SetIns() : Sets the current channel specs to the specified instrument
Channel% = Channel% - 1
WriteReg &H20 + Channel%, CurrentIns.CMult  'Plays carrier note at specified octave ch. 1
WriteReg &H23 + Channel%, CurrentIns.MMult  'Plays modulator note at specified octave ch. 1
WriteReg &H40 + Channel%, CurrentIns.CLevel   'Set carrier total level to softest ch. 1
WriteReg &H43 + Channel%, CurrentIns.MLevel   'Set modulator level to loudest ch. 1
WriteReg &H60 + Channel%, CurrentIns.Cattack  'Set carrier attack and decay ch. 1
WriteReg &H63 + Channel%, CurrentIns.MAttack  'Set modulator attack and decay ch. 1
WriteReg &H80 + Channel%, CurrentIns.CSustain 'Set carrier sustain and release ch. 1
WriteReg &H83 + Channel%, CurrentIns.MSustain 'Set modulator sustain and release ch. 1
END SUB

FUNCTION TheyClickedExit%
IF X% >= 450 AND X% <= 530 THEN
 IF y% > 400 AND y% <= 430 THEN TheyClickedExit% = 1
END IF
END FUNCTION

FUNCTION TheyClickedFiles%
 IF X% >= 80 AND X% <= 170 THEN
  IF y% >= 400 AND y% <= 430 THEN TheyClickedFiles% = 1
 END IF
END FUNCTION

FUNCTION TheyClickedLoad%
IF X% >= 180 AND X% <= 260 THEN
 IF y% > 400 AND y% <= 430 THEN TheyClickedLoad% = 1
END IF
END FUNCTION

FUNCTION TheyClickedSave%
IF X% >= 360 AND X% <= 440 THEN
 IF y% > 400 AND y% <= 430 THEN TheyClickedSave% = 1
END IF
END FUNCTION

FUNCTION TheyClickedTest%
 IF X% >= 270 AND X% <= 350 THEN
  IF y% >= 400 AND y% <= 430 THEN TheyClickedTest% = 1
 END IF
END FUNCTION

FUNCTION TheyClickedWave%
 IF y% >= 450 AND y% <= 470 THEN
  IF X% >= Bars(9).CurY AND X% <= Bars(9).CurY + 3 THEN TheyClickedWave% = 1
 END IF
END FUNCTION

SUB UpdateSel
FOR Bar% = 1 TO 8
 LINE (Bars(Bar%).x1, Bars(Bar%).CurY)-(Bars(Bar%).x2, Bars(Bar%).CurY + 2), 13, BF
NEXT
END SUB

SUB UpdateTheBar (ActiveBar%)
LINE (Bars(ActiveBar%).x1, Bars(ActiveBar%).CurY)-(Bars(ActiveBar%).x2, Bars(ActiveBar%).CurY + 2), 0, BF
Bars(ActiveBar%).CurY = y%
LINE (Bars(ActiveBar%).x1, Bars(ActiveBar%).CurY)-(Bars(ActiveBar%).x2, Bars(ActiveBar%).CurY + 2), 13, BF
SELECT CASE ActiveBar%
 CASE 1: CurrentIns.MMult = Bars(ActiveBar%).CurY - 120
 CASE 2: CurrentIns.MLevel = Bars(ActiveBar%).CurY - 120
 CASE 3: CurrentIns.MAttack = Bars(ActiveBar%).CurY - 120
 CASE 4: CurrentIns.MSustain = Bars(ActiveBar%).CurY - 120
 CASE 5: CurrentIns.CMult = Bars(ActiveBar%).CurY - 120
 CASE 6: CurrentIns.CLevel = Bars(ActiveBar%).CurY - 120
 CASE 7: CurrentIns.Cattack = Bars(ActiveBar%).CurY - 120
 CASE 8: CurrentIns.CSustain = Bars(ActiveBar%).CurY - 120
END SELECT
SetIns 1
END SUB

SUB UpdateWaveForm (NewX%)
 LINE (Bars(9).CurY, Bars(9).x1)-(Bars(9).CurY + 2, Bars(9).x2), 0, BF
 Bars(9).CurY = NewX%
 LINE (Bars(9).CurY, Bars(9).x1)-(Bars(9).CurY + 2, Bars(9).x2), 9, BF
 Wave% = (NewX% - 234) / 3
 X$ = STR$(Wave%)
 LINE (358, 437)-(374, 445), 0, BF
 Font X$, 350, 437, 1, 1, 2, 15
END SUB

SUB WriteIns (FileName$)
OPEN FileName$ FOR BINARY AS #1
 PUT #1, , CurrentIns
CLOSE #1
END SUB

DEFINT A-Z
SUB WriteReg (reg%, value%)
OUT &H228, reg     '388h = address/status port, 389h = dataport
  FOR X = 0 TO 5   ' This tells the SB what register we want to write to

    a = INP(&H388) ' After we write to the address port we must wait 3.3ms
  NEXT X
                                                          
OUT &H229, value   ' Send the value for the register to 389h
  FOR X = 0 TO 34  ' Here we must also wait, this time 23ms
    a = INP(&H388)
  NEXT X

END SUB

