perkin.org.uk - A node.js-powered 8-bit CPU - part four









Search Preview

A node.js-powered 8-bit CPU - part four

perkin.org.uk
Jonathan Perkin about me · rss · twitter · github
.org.uk > perkin.org.uk

SEO audit: Content analysis

Language Error! No language localisation is found.
Title A node.js-powered 8-bit CPU - part four
Text / HTML ratio 38 %
Frame Excellent! The website does not use iFrame solutions.
Flash Excellent! The website does not have any flash contents.
Keywords cloud » = data sixclock var address SmartOS byte packages low bus Jan Dec part CPU clock pin shift numbers Jun
Keywords consistency
Keyword Content Title Description Headings
» 52
= 25
data 23
sixclock 20
var 18
address 13
Headings
H1 H2 H3 H4 H5 H6
2 5 0 0 0 0
Images We found 3 images on this web page.

SEO Keywords (Single)

Keyword Occurrence Density
» 52 2.60 %
= 25 1.25 %
data 23 1.15 %
sixclock 20 1.00 %
var 18 0.90 %
address 13 0.65 %
SmartOS 13 0.65 %
byte 12 0.60 %
packages 10 0.50 %
low 10 0.50 %
bus 10 0.50 %
Jan 9 0.45 %
Dec 9 0.45 %
part 9 0.45 %
CPU 9 0.45 %
clock 9 0.45 %
pin 8 0.40 %
shift 7 0.35 %
numbers 7 0.35 %
Jun 7 0.35 %

SEO Keywords (Two Word)

Keyword Occurrence Density
2013 » 18 0.90 %
on the 15 0.75 %
2012 » 14 0.70 %
the 6309 13 0.65 %
the data 12 0.60 %
2011 » 11 0.55 %
data bus 8 0.40 %
need to 8 0.40 %
for the 8 0.40 %
from the 8 0.40 %
is the 7 0.35 %
it is 7 0.35 %
Read in 6 0.30 %
to be 6 0.30 %
we can 6 0.30 %
we need 6 0.30 %
Jun 2011 6 0.30 %
goes to 6 0.30 %
that we 6 0.30 %
sixclock Read 6 0.30 %

SEO Keywords (Three Word)

Keyword Occurrence Density Possible Spam
the data bus 7 0.35 % No
Jan 2013 » 6 0.30 % No
we need to 6 0.30 % No
sixclock Read in 6 0.30 % No
Jun 2011 » 6 0.30 % No
on the 6309 5 0.25 % No
8bit CPU part 5 0.25 % No
A nodejspowered 8bit 5 0.25 % No
nodejspowered 8bit CPU 5 0.25 % No
for var i 4 0.20 % No
» A nodejspowered 4 0.20 % No
= i < 4 0.20 % No
» pkgsrc on 4 0.20 % No
i = i 4 0.20 % No
var i = 4 0.20 % No
Dec 2013 » 4 0.20 % No
2013 » A 4 0.20 % No
2013 » pkgsrc 3 0.15 % No
this point we 3 0.15 % No
that we can 3 0.15 % No

SEO Keywords (Four Word)

Keyword Occurrence Density Possible Spam
A nodejspowered 8bit CPU 5 0.25 % No
nodejspowered 8bit CPU part 5 0.25 % No
for var i = 4 0.20 % No
var i = i 4 0.20 % No
i = i < 4 0.20 % No
» A nodejspowered 8bit 4 0.20 % No
2013 » A nodejspowered 4 0.20 % No
Dec 2013 » A 4 0.20 % No
on the data bus 3 0.15 % No
At this point we 3 0.15 % No
is the opcode for 3 0.15 % No
a byte of data 3 0.15 % No
» pkgsrc on SmartOS 3 0.15 % No
2013 » pkgsrc on 3 0.15 % No
Shift a byte of 2 0.10 % No
Feb 2013 » SmartOS 2 0.10 % No
First we need to 2 0.10 % No
the shift register board 2 0.10 % No
ADDD with an immediate 2 0.10 % No
shiftoutlddbytes sixclock Read in 2 0.10 % No

Internal links in - perkin.org.uk

about me
About Me
rss
Jonathan Perkin
Reducing RAM usage in pkgin
Reducing RAM usage in pkgin
Building packages at scale
Building packages at scale
A node.js-powered 8-bit CPU - part four
A node.js-powered 8-bit CPU - part four
A node.js-powered 8-bit CPU - part three
A node.js-powered 8-bit CPU - part three
A node.js-powered 8-bit CPU - part two
A node.js-powered 8-bit CPU - part two
A node.js-powered 8-bit CPU - part one
A node.js-powered 8-bit CPU - part one
MDB support for Go
MDB support for Go
Distributed chrooted pkgsrc bulk builds
Distributed chrooted pkgsrc bulk builds
pkgsrc on SmartOS - creating new packages
pkgsrc on SmartOS - creating new packages
Installing SVR4 packages on SmartOS
Installing SVR4 packages on SmartOS
SmartOS is Not GNU/Linux
SmartOS is Not GNU/Linux
SmartOS development preview dataset
SmartOS development preview dataset
pkgsrc on SmartOS - fixing broken builds
pkgsrc on SmartOS - fixing broken builds
pkgsrc on SmartOS - zone creation and basic builds
pkgsrc on SmartOS - zone creation and basic builds
Multi-architecture package support in SmartOS
Multi-architecture package support in SmartOS
Solaris portability - cfmakeraw()
Solaris portability - cfmakeraw()
Solaris portability - flock()
Solaris portability - flock()
SmartOS and the global zone
SmartOS and the global zone
Setting up Samba on SmartOS
Setting up Samba on SmartOS
Creating local SmartOS packages
Creating local SmartOS packages
7,000 binary packages for OSX Lion
7,000 binary packages for OSX Lion
9,000 packages for SmartOS and illumos
9,000 packages for SmartOS and illumos
Goodbye Oracle, Hello Joyent!
Goodbye Oracle, Hello Joyent!
SmartOS global zone tweaks
SmartOS global zone tweaks
Automated VirtualBox SmartOS installs
Automated VirtualBox SmartOS installs
iptables script for Debian / Ubuntu
iptables script for Debian / Ubuntu
New site design
New site design
Set up anonymous FTP upload on Oracle Linux
Set up anonymous FTP upload on Oracle Linux
Kickstart Oracle Linux in VirtualBox
Kickstart Oracle Linux in VirtualBox
Kickstart Oracle Linux from Ubuntu
Kickstart Oracle Linux from Ubuntu
Last day at MySQL
Last day at MySQL
Installing OpenBSD with softraid
Installing OpenBSD with softraid
Create VirtualBox VM from the command line
Create VirtualBox VM from the command line
Creating chroots for fun and MySQL testing
Creating chroots for fun and MySQL testing
Graphing memory usage during an MTR run
Graphing memory usage during an MTR run
Fix input box keybindings in Firefox
Fix input box keybindings in Firefox
How to lose weight
How to lose weight
How to fix stdio buffering
How to fix stdio buffering
Fix Firefox URL double click behaviour
Fix Firefox URL double click behaviour
SSH via HTTP proxy in OSX
SSH via HTTP proxy in OSX
How to build MySQL releases
How to build MySQL releases
ZFS and NFS vs OSX
ZFS and NFS vs OSX
pkgsrc on Solaris
pkgsrc on Solaris
Jumpstart from OSX
Jumpstart from OSX
Set up local caching DNS server on OSX 10.4
Set up local caching DNS server on OSX 10.4

Perkin.org.uk Spined HTML


A node.js-powered 8-bit CPU - part four Jonathan Perkin well-nigh me · rss · twitter · github A node.js-powered 8-bit CPU - part four Dec 04, 2013 tags: 8-bit, homebrew, nodejs This post is part four of a series, the other posts misogynist are Part one - introduction and GPIO Part two - shift registers Part three - the CPU In part two we synthetic a spin using shift registers whereby we could write a byte of data and then read it when in. In part three we booted a 6309 CPU and ran it with a hard-coded operation on the data bus. In this final post, we will put the two together so that we can write wrong-headed data onto the data bus and then read when any results. First, we need to introduce one increasingly 7400-series IC, the 74HC14 hex inverter. Inverters These are really simple chips, all they do is take input on a pin, and then output the opposite onto flipside pin. The “A”s are input and “Y”s are output. So, inputting a 0 into 1A/Pin1 results in a 1 stuff output from 1Y/Pin2. No need for any clocks, just power, and we have 6 converters available. Hooking It All Up Ok, let’s connect everything up. Here’s what we need to do: Connect the two specie boards together, with the shift register workbench whilom the CPU board. The specie boards have tongue and groove joints for a snug fit. Wire up +5V and ground rails between the two so that they both have power from a single source. Wire up the D0-D7 data bus from the 6309 to the data bus on the shift register workbench - it is easiest to vaccinate them in just unelevated the untried LEDs. The GPIO pins from the Raspberry Pi are unfluctuating as follows: GPIO17/Pin11 goes to Q on the 6309. GPIO18/Pin12 goes to E on the 6309. GPIO21/Pin13 goes to STCP on the 74HC595. GPIO22/Pin15 goes to DS on the 74HC595. GPIO23/Pin16 goes to Q7 on the 74HC165. GPIO24/Pin18 goes to RESET on the 6309. There are 4 increasingly connections we need to make, which is where the 74HC14 comes in. RW On The 6309 The RW pin on the 6309 denotes whether from the 6309’s point of view the bus is stuff written to or read from. When high, the 6309 is reading, and when low, it is writing. We can use this full-length to automatically switch the OE (“output enable”) pin on the 74HC595 on or off, so that when the 6309 is reading OE is enabled, and when it is writing OE is disabled, leaving the data bus well-spoken for the 6309s data. In this way the bus can be shared between devices. However, we cannot connect them directly, as the logic is the wrong way virtually - we want OE to be low when RW is upper and vice versa. So, we use the 74HC14, and by connecting them through pins 1A and 1Y on the 74HC14, we get the logic we want. PL On The 74HC165 The final connection we need to make is a way to trigger the 74HC165 to read from the data bus, so that we can get data when into the Raspberry Pi. The solution for this is to wire the 74HC165’s PL pin to clock E on the 6309. This isn’t immediately obvious, but is unswayable by shielding reading of the 6309’s datasheet. The quality of the image unelevated isn’t great, but it shows when data from the 6309 is valid. The part we are interested in is the “Data” line, and the timing when the data is readable is the time between the Q clock going low and the E clock going low. So, for my design, I have hooked up the PL pin to the inverse (again, going through the 74HC14 to capsize the logic) of the Q clock, using pins 2A and 2Y. This way, whenever Q goes low, the 74HC165 reads whatever is on the data bus at that time, and if this happens to be at a point when we want to grab data from the 6309, it should be valid at that point in time and we then just need to shift the data out of the 74HC165 surpassing the next Q clock when the data will be replaced. The finished boards should squint something like this: The 74HC14 is at the top left, with the orange and white jumper wires used for the inverted connections. Software At this point we are washed-up with the hardware, and can move to software. First we need to come up with a program, and for this I have chosen a very simple one - add two numbers together and return the result. The lawmaking is below. ; ; Add two 16-bit numbers (doubles) together. The final version will winnow ; wrong-headed numbers on the writ line, but for now we nonflexible lawmaking two numbers ; which helps us to understand the opcodes. ; LDD #$04 ; Load 4 into the D register (D=4) ADDD #$05 ; Add 5 to D and save the result (D=D+5) STD $B6B7 ; Store the value of D to write 0xB6B7 By using asm6809.pl and od we can squint at what the instruction opcodes need to be. $ asm6809.pl -o 6309-adder 6309-adder.s $ od -t x1 6309-adder 0000000 cc 00 04 c3 00 05 fd b6 b7 0000011 From this we can determine: 0xcc is the opcode for LDD with an firsthand value. 0xc3 is the opcode for ADDD with an firsthand value. 0xfd is the opcode for STD to store at an extended address. An firsthand value is one that is used as-is for the data, rather than stuff an write containing the data. An extended write is where a full write is specified, rather than an offset.Variegatedaddressing modes result in variegated opcodes, as the instruction needs to do variegated things. Now that we have our opcodes, we need to find out how many cycles each of them take to complete. As we are nonflexible coding every clock trundling in this set up, it is hair-trigger that we read and write data at exactly the right time. The weightier reference I’ve found for the 6809/6309 is here and it gives the number of bytes and clock cycles for every instruction. At this point we have all the information required, and it is a Simple Matter Of Programming. My script to add two wrong-headed numbers using the 6309 going via the shift registers for input and output is below. The comments inline hopefully explain exactly what is happening. var rpio = require('rpio'); /* * The two numbers to add together from writ line arguments. */ var num1 = parseInt(process.argv[2], 10); var num2 = parseInt(process.argv[3], 10); /* * Set up our pin mappings and configure them. */ var pin = { 'clockQ': 11, 'clockE': 12, 'clockS': 13, 'write': 15, 'read': 16, 'reset': 18, } rpio.setOutput(pin.clockQ); rpio.setOutput(pin.clockE); rpio.setOutput(pin.clockS); rpio.setOutput(pin.write); rpio.setInput(pin.read); rpio.setOutput(pin.reset); // Start everything low. rpio.write(pin.clockQ, 0); rpio.write(pin.clockE, 0); rpio.write(pin.clockS, 0); rpio.write(pin.write, 0); rpio.write(pin.reset, 0); /* * Clocks - 'sixclock' for the 6309, 'shiftclock' for the shift registers. */ var sixclock = function () { rpio.write(pin.clockQ, 1); rpio.write(pin.clockE, 1); rpio.write(pin.clockQ, 0); rpio.write(pin.clockE, 0); } var shiftclock = function () { rpio.write(pin.clockS, 1); rpio.write(pin.clockS, 0); } /* * Shift a byte of data out to the 74HC595. */ var shiftout = function (data) { // Convert the hex to a binary string var shit = String("00000000" + data.toString(2)).slice(-8); bits.split('').forEach(function (bit) { rpio.write(pin.write, bit); shiftclock(); }); shiftclock(); } /* * Shift a byte of data in from the 74HC165, returning as a hex value. */ var shiftin = function () { var inbyte = ""; for (var i = 0; i < 8; i++) { inbyte += rpio.read(pin.read); shiftclock(); } return String("00" + parseInt(inbyte, 2).toString(16)).slice(-2); } /* * Convert a 16-bit number to an variety of two 8-bit hexadecimals. */ var dec2hex16 = function (number) { var num = String("0000" + number.toString(16)).slice(-4); return [parseInt(num.slice(0,2), 16), parseInt(num.slice(2,4), 16)]; } /* * Initialise the 6309, starting with 10 cycles with the RESET line held lanugo * to well-spoken all state. We then run for 3 cycles without RESET - one to load in * the RESET, and two to get the tweedle ready. * * The number of cycles required here was unswayable by experimentation. */ for (var i = 0; i < 10; i++) { sixclock(); } rpio.write(pin.reset, 1); for (var i = 0; i < 3; i++) { sixclock(); } /* * At this point we are ready to read in the first address. The 6309's RESET * vector is at $FFFE-$FFFF, which is the hardcoded location where it reads * the first write from. * * We provide the starting write of $1020, though it is somewhat arbitrary, * and we could use any write except for $FFF0-$FFFF which is reserved. */ shiftout(0x10); sixclock(); // Load write from $FFFE shiftout(0x20); sixclock(); // Load write from $FFFF /* * Jump to the first write (0x1020) that we input.Withoutthat we can * start to input our first instruction. */ sixclock(); /* * LDD our first number. */ var lddbytes = dec2hex16(num1); shiftout(0xcc); sixclock(); // LDD firsthand shiftout(lddbytes[0]); sixclock(); // Read in num1's upper byte shiftout(lddbytes[1]); sixclock(); // Read in num1's low byte /* * ADDD our second number. ADDD with an firsthand is a 4 trundling * instruction so we have an spare clock at the end. */ var adddbytes = dec2hex16(num2); shiftout(0xc3); sixclock(); // ADDD firsthand shiftout(adddbytes[0]); sixclock(); // Read in num2's upper byte shiftout(adddbytes[1]); sixclock(); // Read in num2's low byte sixclock(); // Clock to perform ADDD operation /* * STD the result to an wrong-headed memory location, in this specimen we have * chosen write $C880 but it is irrelevant as we ignore it. * * STD extended is a 6 clock instruction, with the two byte result misogynist * on the data bus during cycles 5 and 6. */ shiftout(0xfd); sixclock(); // STD extended shiftout(0xc8); sixclock(); // Read in $C8 upper byte shiftout(0x80); sixclock(); // Read in $80 low byte sixclock(); // Clock operation sixclock(); byte1 = shiftin(); // Write upper byte to memory sixclock(); byte2 = shiftin(); // Write low byte to memory /* * We are done, output the calculation. */ console.log("%d + %d = %d", num1, num2, parseInt("0x" + byte1 + byte2, 16)); /* * Reset the CPU to be nice, and to well-spoken the LEDs. Four clocks towards to be * unbearable to well-constructed the reset. */ rpio.write(pin.reset, 0); for (var i = 0; i < 4; i++) { sixclock(); } We can run the program as follows. # node 6309-adder.js 1 2 1 + 2 = 3 The output appears to be the correct answer. We now have a fully functioning co-processor tying to our Raspberry Pi ;) Of course, there are some limitations. As we are dealing with 16-bit numbers, we can overflow: # node 6309-adder.js 32768 32767 32768 + 32767 = 65535 # node 6309-adder.js 32768 32768 32768 + 32768 = 0 However, subtracting support for that and executing wrong-headed instructions is left as an exercise for the reader! Hopefully this was interesting. It has certainly been very useful for me to learn exactly what is going on at the hardware level, and I’d strongly encourage anyone involved in software minutiae to do likewise - it gives you a new appreciation for the operations involved in running your code. Share this post on Twitter, HackerNews, Facebook or Google+ All Posts 16 Jul 2015 » Reducing RAM usage in pkgin 03 Mar 2015 » pkgsrc-2014Q4: LTS, signed packages, and increasingly 06 Oct 2014 » Building packages at scale 04 Dec 2013 » A node.js-powered 8-bit CPU - part four 03 Dec 2013 » A node.js-powered 8-bit CPU - part three 02 Dec 2013 » A node.js-powered 8-bit CPU - part two 01 Dec 2013 » A node.js-powered 8-bit CPU - part one 21 Nov 2013 » MDB support for Go 30 Jul 2013 » What's new in pkgsrc-2013Q2 24 Jul 2013 » Distributed chrooted pkgsrc zillion builds 07 Jun 2013 » pkgsrc on SmartOS - creating new packages 15 Apr 2013 » What's new in pkgsrc-2013Q1 19 Mar 2013 » Installing SVR4 packages on SmartOS 27 Feb 2013 » SmartOS is Not GNU/Linux 18 Feb 2013 » SmartOS minutiae preview dataset 17 Jan 2013 » pkgsrc on SmartOS - fixing wrenched builds 15 Jan 2013 » pkgsrc on SmartOS - zone megacosm and vital builds 10 Jan 2013 » Multi-architecture package support in SmartOS 09 Jan 2013 » Solaris portability - cfmakeraw() 08 Jan 2013 » Solaris portability - flock() 06 Jan 2013 » pkgsrc-2012Q4 illumos packages now misogynist 23 Nov 2012 » SmartOS and the global zone 24 Oct 2012 » Setting up Samba on SmartOS 10 Oct 2012 » pkgsrc-2012Q3 packages for illumos 23 Aug 2012 » Creating local SmartOS packages 10 Jul 2012 » 7,000 binary packages for OSX Lion 09 Jul 2012 » 9,000 packages for SmartOS and illumos 07 May 2012 » Goodbye Oracle, Hello Joyent! 13 Apr 2012 » SmartOS global zone tweaks 12 Apr 2012 » Automated VirtualBox SmartOS installs 30 Mar 2012 » iptables script for Debian / Ubuntu 20 Feb 2012 » New site diamond 11 Jan 2012 » Set up unrecognized FTP upload on Oracle Linux 09 Jan 2012 » Kickstart Oracle Linux in VirtualBox 09 Jan 2012 » Kickstart Oracle Linux from Ubuntu 22 Dec 2011 » Last day at MySQL 15 Dec 2011 » Installing OpenBSD with softraid 21 Sep 2011 » Create VirtualBox VM from the writ line 14 Sep 2011 » Creating chroots for fun and MySQL testing 30 Jun 2011 » Graphing memory usage during an MTR run 29 Jun 2011 » Fix input box keybindings in Firefox 24 Jun 2011 » How to lose weight 23 Jun 2011 » How to fix stdio buffering 13 Jun 2011 » Serving multiple DNS search domains in IOS DHCP 13 Jun 2011 » Fix Firefox URL double click behaviour 20 Apr 2011 » SSH via HTTP proxy in OSX 09 Nov 2010 » How to build MySQL releases 29 Apr 2010 » 'apt-get' and 5,000 packages for Solaris10/x86 16 Sep 2009 » ZFS and NFS vs OSX 12 Sep 2009 » pkgsrc on Solaris 09 Dec 2008 » Jumpstart from OSX 31 Dec 2007 » Set up local caching DNS server on OSX 10.4