Bygonebytes

Introduction

I've added this new page to detail the progress of my Electron Sequencer. The sequencer will be used to trigger my SynTomII, SynBal and SynClap modules I completed a few years ago. I have already built a Raspberry Pi sequencer but since I unpacked my Acorn machines I thought I'd create a sequencer that is of the same time period as that of the SynDrum sound effects. The hardware setup has been detailed on the Acorn Revival 2019 page but to summarise it'll consist of an Electron with a Plus 1, a E2P second processor, Dual User Ports and a Pegasus Disc Interface. If I don't bother with a Save/Load function the DIsc Inteface can be removed. Possibly this is a sledgehammer to crack a nut but it'll be an interesting exercise.

There is still one circuit board to make, the SynDrum interface board which will include sixteen channel LED's to help with testing - it's quieter!. Most of the content here will be the progress of the program, I'll be programing in BASIC/Assembly language for the second processor which I'm very much a novice so it'll be a bit of a learning experience.

I'm going to break down the program into a number of elements so I can concentrate on just one at a time and build up from there. I've started this process by making sure I can read and write data between the second processor and the User Ports. In time I'll implement the following functionality:

  • Extend the write outputs from 8 to 16 bits (Channels).
  • Add a simple text based input system for sequence data.
  • Add some sort of display to follow the steps.
  • Add trigger output pulse width - fixed or variable.
  • Add play/stop keys.
  • Add sequence direction.
  • Look into using the Plus 1 analogue inputs to make tempo settings by potentiometer.
  • Add SAVing and LOADing of data
  • Put the program in an EPROM?

  • I may even add a short video or two as the sequencer takes shape.

    The Interface Board

    The interface board simply plugs into the User Port ports using ribbon cable and provides signal buffering and channel/step indications. I am using a 74C244 non-invering buffer but I may change this to 74C240 inverting buffer depending what data sense works for me in the program.




    While waitng for the board to arrive I thought I'd supercede it with an interface board that can be used to trigger my modular synth as well as the Syndrum. As the modular synth uses 12V for trigger and CV I could re-use my circuit from the Maplin/RPi interface to level shift the voltages from 5V to 12V. This new module is therefore a hybrid of the above and the RPi HAT. I will also include a CV out as per my other modular synth sequencer.. should be interesting..

    Meanwhile I'll complete the build of this first interface while waiting for the new board to arrive... and here is the board under test, this gives me confidence with the new board.




    The second Interface board design and layout which will be built as a module and fitted to the Modular Synth Rack.

    The Build

    Turning my attention to building the sequencer module and the final configuration of the Electron has me thinking what should my minimum Electron setup be? For instance I don't want to dedicate the Electron Disc Interface and drive to run just one program! There are two configurations I can use, The Electron/Plus1, ATI/Raspberry Pi and User Port or Electron/Plus1, Jafa 2nd Processor, User Port and ROM Cartridge. Firstly I had to get the program into a ROM and the simplest way to do this is by using a utility that copies the program and wraps it into ROM image to be called either by star command or Loading/Chaining.

    I looked back to a program called 'Prommer' that I had used to make the TV Pattern Generator ROM, the program was published in the June 1987 Micro User magazine, and can be used to put up to 16 programs into various sizes of ROM image. My program is a little over 8K so I would have to use a 16K image. Unfortunately it proved that Prommer doesn't support loading programs over the Tube interface, something I need for my program to run on the 2nd proccessor. I also looked at EPRUtils and again it doesn't work over the Tube. Finally I had success the the PRES MakeROM ROM which works well but with the slight draw back of using the ROM filing system - *ROM then CH."filename". It's not exactly what I wanted but it's the next best thing.

    Getting the Electron ready involved dragging out my old Microvitec monitor, another blast from the past! I can see from the picture size on the screen I'd been playing around with the horizontal and vertical scan at some point so I'll need to re-size that when I get a moment. There's not much space so the monitor will have to sit under the Synth and the Electron on top of the monitor. The Electron currently has the Rasbperry Pi 2nd processor plugged into the Advanced Tube Interface along with a User Port, I made up two User Ports to save swapping them out all the time. The E2P is still being used for testing but will be swapped in when I have everything ready.

    The Electron & E2P running the sequencer software.


    The Electron being setup under the Synth


    The Synth Interface in the 'Paintshop' and the initial assembly.

    An aside: I Switched on the Modular Synth yesterday and the Midimuso Interface didn't work which turned out to be a bad solder joint on a capacitor on the crystal circuit. The bad solder joint came about due to oxidisation on the legs of the capacitor which caused a dry joint (nothing to do with my bad soldering!). Then the perfect storm blew in..I had just set up the Midinuso for a final test only to watch the Raspberry Pi screen fade to black - that turned out to be an SD card failure so I had to rebuild a new card with OS and the Midi Controller program. Sorted now but I lost a few hours..


    The bare Synth Interface board and part populated mounted on module face plate.


    The Synth Interface board under test.


    The Module wiring complete, just one knob and labelling to complete it.

    The bench testing went well so I then installed it into the Modular Synth rack and that's when it went a bit downhill. For the CV connection to the synth the pulse width was too short for the oscillators to produce a sound, this was easily sorted by updating the program to produce longer pulses. So now in v1.03 the pulse widths depend on the tempo..I'll need to think carfully and set up the pulse width to suit both the drum effects and the CV/Triggers for the Synth.

    The downhill slope carried on with the interface to the E&MM drum effects. Although the interface works it doesn't take into account an easy change over between the RPi Sequencer and the Electron - different cabling. So to simply things I've added opto isolaters to the board, the same as the RPi sequencer, and now I'll be able to parallel up the seqencers with no cable changing required. Luckily there was plenty room on the board to accommodate the extra IC's.


    The second interface board design, V1.1, and the layout which is a direct replacement to the earlier board.

    The Software
    I slowly built up the software functions based on the list above and have listed the program below with some notes to help explain what each section does. Please remember that a second processor and dual user ports are required.

    Over the course of the last few weeks I've been constantly improving and fixing the odd bug in the software so each change has been explained in the Mod State list.

    Mode State:
    V1.00 - Initial version
    V1.01 - Added Step Editor
    V1.02 - Added Live Play
    V1.03 - 26/06/20 - Changed the way trigger pulses and tempo are handled. The pulse (trigger) and tempo were two different procedures where the pulse width was fixed and tempo variable now this has changed to one procedure and the pulse width varies with tempo. We'll see how it behaves once it is connected to the drum modules and synthesiser.
    V1.04 - 02/07/20 - Program now starts at the menu screen instead of jumping straight to editing, added sound to the line edit selection keys, fixed a bug with the line count in the line editor, improved the triggering of the live play and a major overhall of the screen layout - made some use of user defined characters to hide the techie numbering of the step data and to make the layout look better.

    How to use it:
    On starting the program you are taken to the opening screen. The following two screens show this and after data has been entered:



    The menu on the bottom right of the screen has the following options:

    1-Forward
    2-Reverse
    3-Random
    4-Live
    8-Step Edit
    9-Edit

    On selecting any option a dot will appear beside the chosen option as a reminder what has been selected.
    First we have to set up some trigger data, to do this press '9' and use the keys W to O for channels 1 to 8 and S to L for channels 9 to 16. When a key is pressed a 'block character' is displayed below the corresponding channel number and on pressing ENTER the data is entered onto the STEP 1 row. Continue to do this for all 16 steps and at this point the program will automatically switch back to the menu. Pressing SPACE at any time will also return you to the menu.

    Selecting one of the play options, 1 to 3, will start the sequence, the Step Count and Tempo will be displayed. Turning the tempo potentiometer will vary the play step rate. Pressing SPACE will stop the sequence ready for another menu selection.

    Pressing 4 will let you play live, each key press will immediately trigger the sound effect, again, pressing SPACE will stop live play and let you make another menu selection.

    Pressing 8 will select the option to edit from a particular step. Use the UP and DOWN cursor keys to select the Step No., the step count will increase or decrease for each press. A sound will be heard for each key press and on pressing the Right cursor key trigger data can be entered as before for the selected line. Pressing SPACE will take you out of Step Edit. As an experiment I added sound to the cursor key presses, I'll see if it's useful or just annoying.


    10 REM bygonebytes.co.uk (2020) ELK SEQUENCER V1.04
    20 IF HIMEM <&8000 THEN 30 ELSE 50
    30 PRINT"Switch on your Electron 2nd processor"
    40 END
    50 DIM Q% 100
    60 P%=Q%
    70 [OPT 0
    Note: Sets how much memory just above LOMEM to reserve for assembling the program. In this case 101 bytes.

    80 .init LDA #&93
    90 LDX #&B3
    100 LDY #&FF
    110 JSR &FFF4
    120 LDA #&93
    130 LDX #&B2
    140 LDY #&FF
    150 JSR &FFF4
    160 RTS
    Note: When called this initialises both ports to write out data.

    170 .write LDY &6000
    180 LDA #&93
    190 LDX #&B1
    200 JSR &FFF4
    210 LDY &6001
    220 LDA #&93
    230 LDX #&B0
    240 JSR &FFF4
    250 RTS
    Note: When called writes data from memory locations &6000 and &6001 out to the ports - I'll need to look at the Electron memory map to see if I can use a couple of locations below PAGE so re-allocation won't be required in the future.

    260 .zero LDY #&0
    270 LDA #&93
    280 LDX #&B1
    290 JSR &FFF4
    300 LDY #&0
    310 LDA #&93
    320 LDX #&B0
    330 JSR &FFF4
    340 RTS
    350 ]
    Note: When called puts all user port outputs to zero.

    360 CALL init:CALL zero
    Note: Intialise the ports and puts all outputs to zero.

    370 MODE 0
    380 @%=&00004
    390 VDU19,0,4;0;
    400 VDU23,1,0;0;0;0;
    410VDU23,224,255,255,255,255,255,255,255,0
    420VDU23,225,0,0,0,60,60,0,0,0
    430VDU23,226,255,128,128,128,128,128,128,128
    440VDU23,227,255,1,1,1,1,1,1,1
    450VDU23,228,1,1,1,1,1,1,1,255
    460VDU23,229,128,128,128,128,128,128,128,255
    470VDU23,230,128,128,128,128,128,128,128,128
    480VDU23,231,1,1,1,1,1,1,1,1
    490VDU23,232,255,0,0,0,0,0,0,0
    500VDU23,233,0,0,0,0,0,0,0,255
    510E$=CHR$(225):F$=CHR$(224)
    520*FX16,1
    530PROCdeclare
    540PROCdeclare1
    550PROCscreen
    560PROCgo
    570END
    Note: Sets the screen mode, sets the tabs, switches off the cursor, changes the screen background colour, switches off all analogue channels except channel 1, declares the variables, sets up user defined characters, draws the screen layout, and goes to the opening screen.

    580DEFPROCstep
    590IF S>16 S=0
    600
    610IF S=1 a1%=K1+K2+K3+K4+K5+K6+K7+K8
    620IF S=1 b1%=K9+K10+K11+K12+K13+K14+K15+K16
    630IF S=2 a2%=K1+K2+K3+K4+K5+K6+K7+K8
    640IF S=2 b2%=K9+K10+K11+K12+K13+K14+K15+K16
    650IF S=3 a3%=K1+K2+K3+K4+K5+K6+K7+K8
    660IF S=3 b3%=K9+K10+K11+K12+K13+K14+K15+K16
    670IF S=4 a4%=K1+K2+K3+K4+K5+K6+K7+K8
    680IF S=4 b4%=K9+K10+K11+K12+K13+K14+K15+K16
    690IF S=5 a5%=K1+K2+K3+K4+K5+K6+K7+K8
    700IF S=5 b5%=K9+K10+K11+K12+K13+K14+K15+K16
    710IF S=6 a6%=K1+K2+K3+K4+K5+K6+K7+K8
    720IF S=6 b6%=K9+K10+K11+K12+K13+K14+K15+K16
    730IF S=7 a7%=K1+K2+K3+K4+K5+K6+K7+K8
    740IF S=7 b7%=K9+K10+K11+K12+K13+K14+K15+K16
    750IF S=8 a8%=K1+K2+K3+K4+K5+K6+K7+K8
    760IF S=8 b8%=K9+K10+K11+K12+K13+K14+K15+K16
    770IF S=9 a9%=K1+K2+K3+K4+K5+K6+K7+K8
    780IF S=9 b9%=K9+K10+K11+K12+K13+K14+K15+K16
    790IF S=10 a10%=K1+K2+K3+K4+K5+K6+K7+K8
    800IF S=10 b10%=K9+K10+K11+K12+K13+K14+K15+K16
    810IF S=11 a11%=K1+K2+K3+K4+K5+K6+K7+K8
    820IF S=11 b11%=K9+K10+K11+K12+K13+K14+K15+K16
    830IF S=12 a12%=K1+K2+K3+K4+K5+K6+K7+K8
    840IF S=12 b12%=K9+K10+K11+K12+K13+K14+K15+K16
    850IF S=13 a13%=K1+K2+K3+K4+K5+K6+K7+K8
    860IF S=13 b13%=K9+K10+K11+K12+K13+K14+K15+K16
    870IF S=14 a14%=K1+K2+K3+K4+K5+K6+K7+K8
    880IF S=14 b14%=K9+K10+K11+K12+K13+K14+K15+K16
    890IF S=15 a15%=K1+K2+K3+K4+K5+K6+K7+K8
    900IF S=15 b15%=K9+K10+K11+K12+K13+K14+K15+K16
    910IF S=16 a16%=K1+K2+K3+K4+K5+K6+K7+K8
    920IF S=16 b16%=K9+K10+K11+K12+K13+K14+K15+K16
    930IF S=1 PROCconv:PRINTTAB(14,7)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    940IF S=1 PRINTTAB(8,24)"02"
    950IF S=2 PROCconv:PRINTTAB(14,8)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    960IF S=2 PRINTTAB(8,24)"03"
    970IF S=3 PROCconv:PRINTTAB(14,9)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    980IF S=3 PRINTTAB(8,24)"04"
    990IF S=4 PROCconv:PRINTTAB(14,10)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1000IF S=4 PRINTTAB(8,24)"05"
    1010IF S=5 PROCconv:PRINTTAB(14,11)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1020IF S=5 PRINTTAB(8,24)"06"
    1030IF S=6 PROCconv:PRINTTAB(14,12)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1040IF S=6 PRINTTAB(8,24)"07"
    1050IF S=7 PROCconv:PRINTTAB(14,13)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1060IF S=7 PRINTTAB(8,24)"08"
    1070IF S=8 PROCconv:PRINTTAB(14,14)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1080IF S=8 PRINTTAB(8,24)"09"
    1090IF S=9 PROCconv:PRINTTAB(14,15)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1100IF S=9 PRINTTAB(8,24)"10"
    1110IF S=10 PROCconv:PRINTTAB(14,16)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1120IF S=10 PRINTTAB(8,24)"11"
    1130IF S=11 PROCconv:PRINTTAB(14,17)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1140IF S=11 PRINTTAB(8,24)"12"
    1150IF S=12 PROCconv:PRINTTAB(14,18)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1160IF S=12 PRINTTAB(8,24)"13"
    1170IF S=13 PROCconv:PRINTTAB(14,19)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1180IF S=13 PRINTTAB(8,24)"14"
    1190IF S=14 PROCconv:PRINTTAB(14,20)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1200IF S=14 PRINTTAB(8,24)"15"
    1210IF S=15 PROCconv:PRINTTAB(14,21)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1220IF S=15 PRINTTAB(8,24)"16"
    1230IF S=16 PROCconv:PRINTTAB(14,22)D1$,D2$,D3$,D4$,D5$,D6$,D7$,D8$,D9$,D10$,D11$,D12$,D13$,D14$,D15$,D16$
    1240IF S=16 PRINTTAB(8,24)" "
    1250IF S=16 FOR L=14 TO 75:PRINTTAB(L,5)" ":NEXT
    1260IF S=16 PROCgo
    1270
    1280ENDPROC
    1290DEFPROCkeys
    1300
    1310FOR L=14 TO 75:PRINTTAB(L,5)" ":NEXT
    1320IF INKEY(-99) PROCgo
    1330IF INKEY(-34) K1=1 ELSE IF K1=1 THEN K1=1 ELSE K1=0
    1340IF INKEY(-35) K2=2 ELSE IF K2=2 THEN K2=2 ELSE K2=0
    1350IF INKEY(-52) K3=4 ELSE IF K3=4 THEN K3=4 ELSE K3=0
    1360IF INKEY(-36) K4=8 ELSE IF K4=8 THEN K4=8 ELSE K4=0
    1370IF INKEY(-69) K5=16 ELSE IF K5=16 THEN K5=16 ELSE K5=0
    1380IF INKEY(-54) K6=32 ELSE IF K6=32 THEN K6=32 ELSE K6=0
    1390IF INKEY(-38) K7=64 ELSE IF K7=64 THEN K7=64 ELSE K7=0
    1400IF INKEY(-55) K8=128 ELSE IF K8=128 THEN K8=128 ELSE K8=0
    1410IF INKEY(-82) K9=1 ELSE IF K9=1 THEN K9=1 ELSE K9=0
    1420IF INKEY(-51) K10=2 ELSE IF K10=2 THEN K10=2 ELSE K10=0
    1430IF INKEY(-68) K11=4 ELSE IF K11=4 THEN K11=4 ELSE K11=0
    1440IF INKEY(-84) K12=8 ELSE IF K12=8 THEN K12=8 ELSE K12=0
    1450IF INKEY(-85) K13=16 ELSE IF K13=16 THEN K13=16 ELSE K13=0
    1460IF INKEY(-70) K14=32 ELSE IF K14=32 THEN K14=32 ELSE K14=0
    1470IF INKEY(-71) K15=64 ELSE IF K15=64 THEN K15=64 ELSE K15=0
    1480IF INKEY(-87) K16=128 ELSE IF K16=128 THEN K16=128 ELSE K16=0
    1490IF INKEY(-74) PROCstep:S=S+1:PROCdeclare:FOR L=14 TO 75:PRINTTAB(L,5)" ":NEXT
    1500IF K1=1 PRINTTAB(14,5)F$
    1510IF K2=2 PRINTTAB(18,5)F$
    1520IF K3=4 PRINTTAB(22,5)F$
    1530IF K4=8 PRINTTAB(26,5)F$
    1540IF K5=16 PRINTTAB(30,5)F$
    1550IF K6=32 PRINTTAB(34,5)F$
    1560IF K7=64 PRINTTAB(38,5)F$
    1570IF K8=128 PRINTTAB(42,5)F$
    1580IF K9=1 PRINTTAB(46,5)F$
    1590IF K10=2 PRINTTAB(50,5)F$
    1600IF K11=4 PRINTTAB(54,5)F$
    1610IF K12=8 PRINTTAB(58,5)F$
    1620IF K13=16 PRINTTAB(62,5)F$
    1630IF K14=32 PRINTTAB(66,5)F$
    1640IF K15=64 PRINTTAB(70,5)F$
    1650IF K16=128 PRINTTAB(74,5)F$
    1660GOTO 1320
    1670ENDPROC
    Note: Data input - scans the keyboard, single steps through each step, each key press is indicated by a 'Block' below the channel number and stores the value for each key press. Press the SPACE bar at any time to come out of Editing mode.

    1680DEFPROCgo
    1690FOR L=25 TO 27:PRINTTAB(36,L)" ":NEXT
    1700PRINTTAB(74,26)" ":PRINTTAB(47,25)" ":PRINTTAB(74,25)" "
    1710IF INKEY(-49) PRINTTAB(36,25)E$:PROCforward
    1720IF INKEY(-50) PRINTTAB(36,26)E$:PROCback
    1730IF INKEY(-18) PRINTTAB(36,27)E$:PROCrandom
    1740IF INKEY(-22) PRINTTAB(74,25)E$:PROCline
    1750IF INKEY(-19) PRINTTAB(47,25)E$:PROClive
    1760IF INKEY(-39) S=1:PRINTTAB(74,26)E$:PROCkeys
    1770GOTO 1710
    1780ENDPROC
    Note: Start sequence or Editing.

    1790 DEFPROCforward
    1800 PROCst1:PROCst2:PROCst3:PROCst4:PROCst5:PROCst6:PROCst7: PROCst8:PROCst9:PROCst10:PROCst11:PROCst12:PROCst13:PROCst14: PROCst15:PROCst16
    1810 GOTO 1800
    1820 ENDPROC
    1830 DEFPROCback
    1840 PROCst16:PROCst15:PROCst14:PROCst13:PROCst12:PROCst11: PROCst10:PROCst9:PROCst8:PROCst7:PROCst6:PROCst5:PROCst4: PROCst3:PROCst2:PROCst1
    1850 GOTO 1840
    1860 ENDPROC
    1870 DEFPROCrandom
    1880 X=RND(16)
    1890 IF X=1 PROCst1
    1900 IF X=2 PROCst2
    1910 IF X=3 PROCst3
    1920 IF X=4 PROCst4
    1930 IF X=5 PROCst5
    1940 IF X=6 PROCst6
    1950 IF X=7 PROCst7
    1960 IF X=8 PROCst8
    1970 IF X=9 PROCst9
    1980 IF X=10 PROCst10
    1990 IF X=11 PROCst11
    2000 IF X=12 PROCst12
    2010 IF X=13 PROCst13
    2020 IF X=14 PROCst14
    2030 IF X=15 PROCst15
    2040 IF X=16 PROCst16
    2050 GOTO 1880
    2060 ENDPROC
    Note: Forward, Reverse and Random sequences.

    2070DEFPROCline
    2080SOUND 1,-15,100,1:S=0
    2090NOW=TIME:REPEAT UNTIL TIME-NOW>=10
    2100REM IF S>=16 S=16
    2110REM IF S<=1 S=1
    2120IF INKEY(-58) PROCup
    2130IF INKEY(-42) PROCdn
    2140IF INKEY(-122) SOUND 1,-15,148,1:PROCkeys
    2150IF INKEY(-99) PROCgo
    2160GOTO 2090
    2170ENDPROC
    Note: Select and Edit a Line.

    2180DEFPROCst1
    2190?&6000=a1%
    2200?&6001=b1%
    2210PRINTTAB(8,24)"01"
    2220PROCtempo
    2230IF INKEY(-99) PROCgo
    2240ENDPROC
    2250DEFPROCst2
    2260?&6000=a2%
    2270?&6001=b2%
    2280PRINTTAB(8,24)"02"
    2290PROCtempo
    2300IF INKEY(-99) PROCgo
    2310ENDPROC
    2320DEFPROCst3
    2330?&6000=a3%
    2340?&6001=b3%
    2350PRINTTAB(8,24)"03"
    2360PROCtempo
    2370IF INKEY(-99) PROCgo
    2380ENDPROC
    2390DEFPROCst4
    2400?&6000=a4%
    2410?&6001=b4%
    2420PRINTTAB(8,24)"04"
    2430PROCtempo
    2440IF INKEY(-99) PROCgo
    2450ENDPROC
    2460DEFPROCst5
    2470?&6000=a5%
    2480?&6001=b5%
    2490PRINTTAB(8,24)"05"
    2500PROCtempo
    2510IF INKEY(-99) PROCgo
    2520ENDPROC
    2530DEFPROCst6
    2540?&6000=a6%
    2550?&6001=b6%
    2560PRINTTAB(8,24)"06"
    2570PROCtempo
    2580IF INKEY(-99) PROCgo
    2590ENDPROC
    2600DEFPROCst7
    2610?&6000=a7%
    2620?&6001=b7%
    2630PRINTTAB(8,24)"07"
    2640PROCtempo
    2650IF INKEY(-99) PROCgo
    2660ENDPROC
    2670DEFPROCst8
    2680?&6000=a8%
    2690?&6001=b8%
    2700PRINTTAB(8,24)"08"
    2710PROCtempo
    2720IF INKEY(-99) PROCgo
    2730ENDPROC
    2740DEFPROCst9
    2750?&6000=a9%
    2760?&6001=b9%
    2770PRINTTAB(8,24)"09"
    2780PROCtempo
    2790IF INKEY(-99) PROCgo
    2800ENDPROC
    2810DEFPROCst10
    2820?&6000=a10%
    2830?&6001=b10%
    2840PRINTTAB(8,24)"10"
    2850PROCtempo
    2860IF INKEY(-99) PROCgo
    2870ENDPROC
    2880DEFPROCst11
    2890?&6000=a11%
    2900?&6001=b11%
    2910PRINTTAB(8,24)"11"
    2920PROCtempo
    2930IF INKEY(-99) PROCgo
    2940ENDPROC
    2950DEFPROCst12
    2960?&6000=a12%
    2970?&6001=b12%
    2980PRINTTAB(8,24)"12"
    2990PROCtempo
    3000IF INKEY(-99) PROCgo
    3010ENDPROC
    3020DEFPROCst13
    3030?&6000=a13%
    3040?&6001=b13%
    3050PRINTTAB(8,24)"13"
    3060PROCtempo
    3070IF INKEY(-99) PROCgo
    3080ENDPROC
    3090DEFPROCst14
    3100?&6000=a14%
    3110?&6001=b14%
    3120PRINTTAB(8,24)"14"
    3130PROCtempo
    3140IF INKEY(-99) PROCgo
    3150ENDPROC
    3160DEFPROCst15
    3170?&6000=a15%
    3180?&6001=b15%
    3190PRINTTAB(8,24)"15"
    3200PROCtempo
    3210IF INKEY(-99) PROCgo
    3220ENDPROC
    3230DEFPROCst16
    3240?&6000=a16%
    3250?&6001=b16%
    3260PRINTTAB(8,24)"16"
    3270PROCtempo
    3280IF INKEY(-99) PROCgo
    3290ENDPROC
    Note: 16 Step Trigger sequence

    3300 DEFPROCtempo
    3310 TEMP=ADVAL(1)
    3320 IF TEMP=0 THEN TEMP=256
    3330 PRINTTAB(19,24) TEMP DIV 256
    3340 CALLwrite
    3350 NOW%=TIME:REPEAT UNTIL TIME=NOW%+TEMP DIV 256
    3360 CALLzero
    3370 NOW%=TIME:REPEAT UNTIL TIME=NOW%+TEMP DIV 256
    3380 ENDPROC
    Note: This sets the tempo. The tempo is set with a potentiometer on analogue channel 0 (1).

    3390 DEFPROCdeclare
    3400 K1=0:K2=0:K3=0:K4=0:K5=0:K6=0:K7=0:K8=0
    3410 K9=0:K10=0:K11=0:K12=0:K13=0:K14=0:K15=0:K16=0
    3420 ENDPROC
    3430 DEFPROCdeclare1
    3440 a1%=0:b1%=0:a2%=0:b2%=0:a3%=0:b3%=0:a4%=0:b4%=0:a5%=0: b5%=0:a6%=0:b6%=0:a7%=0:b7%=0:a8%=0:b8%=0
    3450 a9%=0:b9%=0:a10%=0:b10%=0:a11%=0:b11%=0:a12%=0: b12%=0:a13%=0:b13%=0:a14%=0:b14%=0:a15%=0:b15%=0:a16%=0:b16%=0
    3460 S=0
    3470 ENDPROC
    Note: Declares the variables and sets them to 0.

    3480 DEFPROCscreen
    3490 PRINTTAB(33,0) "ELK SEQUENCER"
    3500 PRINTTAB(14,2) "W","E","R","T","Y","U","I","O","S","D","F","G","H","J","K","L"
    3510 PRINTTAB(14,3) "1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"
    3520 PRINTTAB(3,2) "KEY I/P"
    3530 PRINTTAB(3,3) "CHANNEL"
    3540 PRINTTAB(3,5) "STEP 01"
    3550 PRINTTAB(3,6) "STEP 02"
    3560 PRINTTAB(3,7) "STEP 03"
    3570 PRINTTAB(3,8) "STEP 04"
    3580 PRINTTAB(3,9) "STEP 05"
    3590 PRINTTAB(3,10) "STEP 06"
    3600 PRINTTAB(3,11) "STEP 07"
    3610 PRINTTAB(3,12) "STEP 08"
    3620 PRINTTAB(3,13) "STEP 09"
    3630 PRINTTAB(3,14) "STEP 10"
    3640 PRINTTAB(3,15) "STEP 11"
    3650 PRINTTAB(3,16) "STEP 12"
    3660 PRINTTAB(3,17) "STEP 13"
    3670 PRINTTAB(3,18) "STEP 14"
    3680 PRINTTAB(3,19) "STEP 15"
    3690 PRINTTAB(3,20) "STEP 16"
    3700 PRINTTAB(3,24)"STEP 01"
    3710PRINTTAB(25,24)CHR$(226)
    3720FOR L=26 TO 74:PRINTTAB(L,24)CHR$(232):NEXT
    3730PRINTTAB(75,24)CHR$(227)
    3740PRINTTAB(25,25)CHR$(230)
    3750PRINTTAB(75,25)CHR$(231)
    3760PRINTTAB(25,26)CHR$(230)
    3770PRINTTAB(75,26)CHR$(231)
    3780PRINTTAB(25,27)CHR$(230)
    3790PRINTTAB(75,27)CHR$(231)
    3800PRINTTAB(25,28)CHR$(229)
    3810FOR L=26 TO 74:PRINTTAB(L,28)CHR$(233):NEXT
    3820PRINTTAB(75,28)CHR$(228)
    3830PRINTTAB(26,25)"1-FORWARD"
    3840PRINTTAB(26,26)"2-REVERSE"
    3850PRINTTAB(26,27)"3-RANDOM"
    3860PRINTTAB(40,25)"4-LIVE"
    3870PRINTTAB(62,25)"8-STEP EDIT"
    3880PRINTTAB(62,26)"9-EDIT"
    3890PRINTTAB(14,24)"TEMPO"
    3900PRINTTAB(3,27)"bygonebytes":PRINTTAB(3,28)".co.uk 2020"
    3910 ENDPROC
    Note: Draws the basic screen layout.

    3920 DEFPROClive
    3930 IF INKEY(-34) PROCch1
    3940 IF INKEY(-35) PROCch2
    3950 IF INKEY(-52) PROCch3
    3960 IF INKEY(-36) PROCch4
    3970 IF INKEY(-69) PROCch5
    3980 IF INKEY(-54) PROCch6
    3990 IF INKEY(-38) PROCch7
    4000 IF INKEY(-55) PROCch8
    4010 IF INKEY(-82) PROCch9
    4020 IF INKEY(-51) PROCch10
    4030 IF INKEY(-68) PROCch11
    4040 IF INKEY(-84) PROCch12
    4050 IF INKEY(-85) PROCch13
    4060 IF INKEY(-70) PROCch14
    4070 IF INKEY(-71) PROCch15
    4080 IF INKEY(-87) PROCch16
    4090 IF INKEY(-99) PROCgo
    4100 GOTO 3930
    4110 ENDPROC
    4120DEFPROCch1
    4130a1%=1:PRINTTAB(14,5)F$
    4140PROCsnda
    4150ENDPROC
    4160DEFPROCch2
    4170a1%=2:PRINTTAB(18,5)F$
    4180PROCsnda
    4190ENDPROC
    4200DEFPROCch3
    4210a1%=4:PRINTTAB(22,5)F$
    4220PROCsnda
    4230ENDPROC
    4240DEFPROCch4
    4250a1%=8:PRINTTAB(26,5)F$
    4260PROCsnda
    4270ENDPROC
    4280DEFPROCch5
    4290a1%=16:PRINTTAB(30,5)F$
    4300PROCsnda
    4310ENDPROC
    4320DEFPROCch6
    4330a1%=32:PRINTTAB(34,5)F$
    4340PROCsnda
    4350ENDPROC
    4360DEFPROCch7
    4370a1%=64:PRINTTAB(38,5)F
    4380PROCsnda
    4390ENDPROC
    4400DEFPROCch8
    4410a1%=128:PRINTTAB(42,5)F$
    4420PROCsnda
    4430ENDPROC
    4440DEFPROCch9
    4450b1%=1:PRINTTAB(46,5)F$
    4460PROCsndb
    4470ENDPROC
    4480DEFPROCch10
    4490b1%=2:PRINTTAB(50,5)F$
    4500PROCsndb
    4510ENDPROC
    4520DEFPROCch11
    4530b1%=4:PRINTTAB(54,5)F$
    4540PROCsndb
    4550ENDPROC
    4560DEFPROCch12
    4570b1%=8:PRINTTAB(58,5)F$
    4580PROCsndb
    4590ENDPROC
    4600DEFPROCch13
    4610b1%=16:PRINTTAB(62,5)F$
    4620PROCsndb
    4630ENDPROC
    4640DEFPROCch14
    4650b1%=32:PRINTTAB(66,5)F$
    4660PROCsndb
    4670ENDPROC
    4680DEFPROCch15
    4690b1%=64:PRINTTAB(70,5)F$
    4700PROCsndb
    4710ENDPROC
    4720DEFPROCch16
    4730b1%=128:PRINTTAB(74,5)F$
    4740PROCsndb
    4750ENDPROC
    4760DEFPROCsnda
    4770b1%=0
    4780?&6000=a1%
    4790?&6001=b1%
    4800PROCtrig
    4810FOR L=14 TO 43:PRINTTAB(L,5)" ":NEXT
    4820ENDPROC
    4830DEFPROCsndb
    4840a1%=0
    4850?&6000=a1%
    4860?&6001=b1%
    4870PROCtrig
    4880FOR L=46 TO 75:PRINTTAB(L,5)" ":NEXT
    4890ENDPROC
    Note: Detects a channel key press and outputs a trigger pulse.

    4900DEFPROCconv
    4910IF K1>0 D1$=F$ ELSE D1$=E$
    4920IF K2>0 D2$=F$ ELSE D2$=E$
    4930IF K3>0 D3$=F$ ELSE D3$=E$
    4940IF K4>0 D4$=F$ ELSE D4$=E$
    4950IF K5>0 D5$=F$ ELSE D5$=E$
    4960IF K6>0 D6$=F$ ELSE D6$=E$
    4970IF K7>0 D7$=F$ ELSE D7$=E$
    4980IF K8>0 D8$=F$ ELSE D8$=E$
    4990IF K9>0 D9$=F$ ELSE D9$=E$
    5000IF K10>0 D10$=F$ ELSE D10$=E$
    5010IF K11>0 D11$=F$ ELSE D11$=E$
    5020IF K12>0 D12$=F$ ELSE D12$=E$
    5030IF K13>0 D13$=F$ ELSE D13$=E$
    5040IF K14>0 D14$=F$ ELSE D14$=E$
    5050IF K15>0 D15$=F$ ELSE D15$=E$
    5060IF K16>0 D16$=F$ ELSE D16$=E$
    5070ENDPROC
    5080DEFPROCup
    5090SOUND 1,-15,100,1
    5100S=S+1
    5110IF S>=16 S=16
    5120IF S<=9 PRINTTAB(7,24)" 0";S
    5130IF S>9 PRINTTAB(7,24)" ";S
    5140ENDPROC
    5150DEFPROCdn
    5160SOUND 1,-15,100,1
    5170S=S-1
    5180IF S<=1 S=1
    5190IF S<=9 PRINTTAB(7,24)" 0";S
    5200IF S>9 PRINTTAB(7,24)" ";S
    5210ENDPROC
    5220DEFPROCtrig
    5230CALLwrite
    5240NOW=TIME:REPEAT UNTIL TIME-NOW>10
    5250CALLzero
    5260ENDPROC
    Note: Procedures to convert trigger data numbers to User Defined Characters. Step Edit UP/Down procedures and Live Play Trigger pulse.

    Screen dumps showing how the layout developed.