SH101 style sequencer as ruby UniMIDI script

I came across a youtube video which shows an Axoloti set up to emulate an SH101 style sequencer being trigged by an incoming note.

I had not seen this style of sequencer before, and was interested in the patterns that can be generated particularly when you have say a 7 step sequence that has 8 triggers per bar, so the resulting pattern kind of slides around the main rhythm.

Since I don’t yet have an Axoloti I put toget a UniMIDI script to get the same result. I use this with my Electribe 2 Sampler, which is connected via USB to my Macbook running the script.

On the E2S I have a pattern set up as follows:
Part 1 – this is set so Osc = ‘Audio In Mono’ – which makes it effectively muted. The E2S sequencer has every step to this part off. Keys pressed on this part get sent out on Midi Channel 1.

Part 2 – this is set to one of the built in wave forms (not a sample). Also, the ‘AMP EG’ must be selected with a highish decay/release value. The E2S sequencer has every step to this part off. The decay/release is needed because the incoming notes will have a not off immediately after the note on, so the actual audible duration depends on the decay time. This is also why samples don’t work too well, the envelope generator only works how it needs to for the built in waveforms.

Parts 3-15 – Set up with whatever Osc and pattern you like.

Part 16 – this is set so Osc = ‘Audio In Mono’ – which makes it effectively muted. Any note sent on this channel (e.g. via the E2S sequenver) will act as a trigger for the SH101 style sequencer.

To use:

Set up the E2S as above. Then go to ‘part 1′ and press the ‘IFX on’ button so it lights red. This puts the SH101 script into ‘record mode’. Any notes you play on part 1 in this mode get added to the sequence (and also echoed back on Channel 2). Press ‘IFX On’ again (so light goes off) to put the SH101 sequencer into ‘play’ mode. Now go to ‘part 16′ and turn on/off whatever steps you want to trigger a note. Press play.

Going to ‘part 1′ and pressing another note key while in play mode will transpose the current sequence.

—-

!– HTML generated using hilite.me –>

#!/usr/bin/ruby

dir = File.dirname(File.expand_path(__FILE__))
$LOAD_PATH.unshift dir + "/../lib"

require "unimidi"

IN_CHANNEL=1
TRIGGER_CHANNEL=16
OUT_CHANNEL=2
REC_MODE_CC=0x68	#on my electribe 2, this is triggered by pressing the 'IFX ON' button.

DEBUG_LEVEL=1	#0=silent,1=major events, 2=all events

@input = UniMIDI::Input.gets
@output = UniMIDI::Output.gets

@rec_mode=false
@seq_length=0
@seq=[]
@seq_ptr=0
@transpose_amount=0

def debug_log (s,level)
	puts s unless level>DEBUG_LEVEL
end
def execute_status(s)
	debug_log("#{"%2X" % s[0]},#{s[1]},#{s[2]}",2)
	if ((s[0])==0xb0+IN_CHANNEL-1) && (s[1]==REC_MODE_CC)then
		new_rec_mode=(s[2]>64)
		if (@rec_mode==false) && (new_rec_mode==true) then
			@seq=[]
			@seq_length=0
			@seq_ptr=0
		end

		@rec_mode=new_rec_mode
		debug_log("REC_MODE: #{@rec_mode}",1)
	end

	if (s[0]==0x90+IN_CHANNEL-1) && (s[2]>1)then #it's a note-on event on input channel

		if (@rec_mode) then
			@seq[@seq_length]=s[1]
			@seq_length+=1
			@output.puts(0x8F+OUT_CHANNEL, s[1],  64) #echo so can hear what was just played
			@output.puts(0x8F+OUT_CHANNEL, s[1],  0) #immediate note off 

			debug_log("added note - seq length #{@seq_length}",1)
		end

		if (!@rec_mode) && (@seq_length>0) && (IN_CHANNEL!=TRIGGER_CHANNEL) then # not recording or a trigger so do a transpose
			@transpose_amount=s[1]-@seq[0]
			debug_log("transpose amount now - #{@transpose_amount}",1)
		end

	end
	if (s[0]==0x90+TRIGGER_CHANNEL-1) && (s[2]>1)then #it's a note-on event on trigger channel
		if (!@rec_mode) then
			if @seq_length>1 then
				debug_log( "play note - seq ptr #{@seq_ptr}",1)
				@output.puts(0x8F+OUT_CHANNEL, @seq[@seq_ptr]+@transpose_amount,  64)
				@output.puts(0x8F+OUT_CHANNEL, @seq[@seq_ptr]+@transpose_amount,  0) #immediate note off 
				@seq_ptr+=1
				@seq_ptr=0 if @seq_ptr==@seq_length
			else
				debug_log("skipping - no sequence",1)
			end

		end

	end

end

status=[]

begin	

	loop do 	

				m = @input.gets_data
				m.each do |b|
					next if b==0xf8	#ignore clock beats
					if (b<0x80) then
						status<<b
					else
						status=[b]
					end					

					if status.length==3 then
						execute_status(status)
						cmd_byte=status[0]#keep original first byte for short form commands
						status=[cmd_byte]
					end
				end
	end
ensure
	@output.puts(0xAF+OUT_CHANNEL, 0x7B, 0) #all notes off
end
Posted in Uncategorized | Comments Off

Applesoft Disassembly

I went looking for a disassembly of Applesoft.
The best one I found was the S-C DocuMentor Applesoft listing which has meaningful labels and comments, but was a little cumbersome to peruse as it was spread over multiple files and lacked hyperlink crossreferences.

So I have created a consolidated and cross-linked version.

the ruby script I used to create this is:

html="<PRE>"
$<.each_line do |line|
 line.gsub!('<','&lt;')
 if line=~/^....-.{21} [J|B]...([A-Z]\S+)\s/
 dest_label=$1
 line[31,dest_label.length]="<a href=\##{dest_label}>#{dest_label}</a>"
 end

 if (!line.include?(" .EQ ") && (line=~/^.{20}([A-Z]\S+)\s/))
 this_label=$1
 line[20,this_label.length]="<b><a name='#{this_label}' id='#{this_label}'>#{this_label}</a></b>"
 end
 line[15,4]="" if line[15,4]=~/\d\d\d\d/
 html+="#{line}" unless line=~/^\s+SAVE /
end
html+="</PRE>"
puts html
Posted in apple ii, vintage | Comments Off

ip65 project page recovered

The ip65 project page (http://ip65.sourceforge.net/) seems to have dropped off the interwebs. It is back now.

Posted in c64, vintage | Comments Off

Kipper BASIC updates

Goog from CommodoreServer.com reported a couple of bugs in Kipper BASIC which I have fixed in version 1.21

The bugs were

  • Any UDP broadcast anywhere on the LAN (say, a DHCP client booting up, or the  ‘Host Announcements’ every Windows machine sends every few minutes) would result in TCPSEND or POLL reporting an error
  • If you had a variable (say X%) and you added a constant to it that happened to be the same as the current value of that variable (i.e. you had  X% =X%+7 when X% was already 7) you got a completely bogus number.
Posted in Uncategorized | Comments Off

peekbot is back

I’ve turned on peekbot again, although I have disabled the ‘screendump’ feature (which would render a text file using the default font and screen colours from whatever system the text file appeared to originate from) – I think this was causing most of the crashes last time I had peekbot running.

I am also running peekbot via mongrel, on a non-standard port, although I have mod_rewrite rules in place such that any old links should get directed to the right spot.

 

Posted in Uncategorized | Comments Off

More classic computer footage from the MIT Vault

I’ve been poking around some more in the film archive at MIT that I found “Making Electrons Count” and a few other items caught my attention.

First is a news report from 1951 showing the WHIRLWIND computer being used to solve some differential equations that would be very tedious to compute by hand (e.g. determining remaining fuel, height and velocity of a rocket as it is launched). Output to an oscilloscope and a flexowriter is shown, as well as some very early electronic music. 6 minutes long.

MIT Tech TV

Then there is a talk from 1985 reflecting on 40 years of computing, covering the transition from computers being batch-mode number crunching machines, where any single programmer would be allowed a short window every few days in which they could attempt to run their program, into “time-sharing” data processing machines, in which multiple users could be constantly interacting with, allowing for (amongst other things) ‘on-line’ programming. It is hard to comprehend what the act of developing and debugging a program would be like when you would only be allowed 1 attempt to run it every 3 days.

This film is 90 minutes long, but the main speaker (who appears about 7 minutes in, after a somewhat boring introduction from the MC) is very engaging and uses photos and other props to entertain and inform.

MIT Tech TV

Posted in vintage | Comments Off

Ancient I/O & Making Electrons Count

The RPC-4000 (like many computers of the same vintage) used a device called a Friden Flexowriter for input and output. This device was a combination typewriter, printer and paper tape reader & writer.

Input to the RPC-4000 could be done either by typing on the keyboard, or reading a paper tape. Output from the RPC-4000 would be printed to the flexowriter.

The character set used by the RPC-4000 is essentially the Flexowriter character set. It uses 6-bit codes, allowing for 64 characters, as opposed the 128 characters in 7-bit ASCII. However the flexowriter had a typewriter mechanism that allowed for shifting between upper and lower case, and there are codes in the character set that select which case to use for printing of subsequent characters.

The Flexowriter character set also has some ‘control codes’, similar to the control codes that make up the first 32 ASCII characters. Nowadays most of these control codes are long since obsolete, since they relate to long dead media like 80 column punch cards, paper tape or magnetic tape reels.

While looking for the definition of some of the Flexowriter control codes referenced in the RPC-4000 documentation, I stumbled across ‘Making Electrons Count‘ – a documentary made in the early 1950s about the MIT “Whirlwind” digital computer facility. It is 20 minutes long, the first 10 minutes or so are a breathless description of the wonders of digital computers and the bright future they would bring us.

The 2nd half I found eye-opening; it tells the story of someone with a complex maths problem to solve, and the journey they go on to program the Whirlwind to solve it, which includes digesting a thick tome on “PROGRAMMING: Statement; Mathematical Analysis; Flow Diagram; Code; Tape Preparation; Computing; Debugging; Interpreting Results.”, attending a 2 week programming course, several interactions with Flexowriters, and a 4:00am visit to the “Night Typist”.

As well as the video itself, I also came across a nice commentary on it that gives a lot of useful context to the technology and techniques captured in the film.

Posted in vintage | Comments Off

On the trail of a Real Programmer

Coders of a certain vintage will be familiar with the story of Mel, the Real Programmer in which Ed Nather (writing in 1983) relates his experience from 20 years previously in attempting to patch a BlackJack program written by his ex-colleague (Mel Kaye) for the ancient RPC-4000 computer, and how the complexity of the code he had to work through left him so impressed with Mel’s familiarity with the inner workings of the computer that he abandoned the attempt to patch the code and even 20 years later, he still held Mel as the archetype of a “Real Programmer”.

I first came across the story on a BBS sometime the early 90s, at a time when I was just starting to become competent with x86 assembly code, and self-modifying code was a pretty fascinating idea, as was extreme performance optimisation.

Then recently I came across the Mel story again, and went looking to see what (if anything) of the legendary machines and codes had made their way into the retro-computing archives across the net. The ‘holy grail’ would be a copy of the original BlackJack program with the back-to-front cheat option, and major bragging rights would come from being able to make the patch that Ed Nather had given up looking to make.

I’m not there yet.

What I have found so far is:

From looking at the opcodes in the programming manual, I believe that the loop in question must have been based around opcode 21 “COMPARE MEMORY GREATER”, with the eventual ‘overflow’ to opcode 22 (TEST MINUS).

I don’t know what sort of work this loop would have been doing, although given the program documentation clearly states program execution starts at 00000, and that is also where (in the story) control is eventually transferred to once the loop exits, the loop must have been some kind of post-game cleanup, ready to re-start.

So my current theory is

  • the data stored in the upper memory locations is the card deck, (stored initially perhaps as numbers 1..52)
  • as cards were “dealt” they were marked as such by (e.g.) setting the sign bit
  • the loop without apparent exit is going through the pack removing the ‘dealt’ marker, prior to being shuffled at the start of a new game.

It is apparent that Ed’s memory was not completely accurate; not completely surprising given the 20 year gap from when the events occurred until when they were documented. He mentions the clue that helped him understand the way the loop exited as being the fact that the index register bit was set even though Mel never used the index register, and says this index register bit is “between the address and the operation code in the instruction word”. However reference manual is clear that the index register bit is the least significant bit, and in fact the opcode bits (0..4) are adjacent to the data address bits (5..16). I can’t see any way the index bit could have been part of the loop/overflow.

Posted in Uncategorized, vintage | Comments Off

copy of Acorn MOS annotated disassembly

These were zipped at The BBC Lives!

The BBC Micro Operating System ( a series that first published on Micronet between April and October 1991 )

Acorn MOS 1.2 Disassembly part 1 (VDU fonts & contstants : $C000 – $C4BF)
Acorn MOS 1.2 Disassembly part 2 (OSWRCH : $C4C0 – $CA38)
Acorn MOS 1.2 Disassembly part 3 (misc graphics routines : $CA39 – $D4BC)
Acorn MOS 1.2 Disassembly part 4 (D4BD – $DB10)
Acorn MOS 1.2 Disassembly part 5 ($DB11 -$DEFE – possibly incomplete file? )
Acorn MOS 1.2 Disassembly part 6 ($E114 – $E6AF)
Acorn MOS 1.2 Disassembly part 7 ($E6B0 – $EAD8)
Acorn MOS 1.2 Disassembly part 8 ($EAD9 – $F134)
Acorn MOS 1.2 Disassembly part 9 ($F135 – $F9B3)
Acorn MOS 1.2 Disassembly part 10 ($F9B4 – $FFFF)

Posted in vintage | Comments Off

peekbot update

I added some new decoders to peekbot

Also, the symbols table used by the disassembler has been extended to allow for decoding of functions that are all called via a single address (e.g. the BBC has a routine called OSBYTE which is accessed via $FFF4, but has hundreds of different sub-functions which can be selected via different values of A,X & Y registers). Only immediate loads in the vicinity of the JSR are interepreted (e.g. LDA #$01/ JSR $FFF4).

Posted in vintage | Comments Off