[Home]MK14 Notes

HomePage | RecentChanges | Preferences

Here are a few notes on the Science Of Cambridge MK14

I had one which I think is the one on Grant Searle's site.


There is an emulator for it and here are some notes on getting a cross assembler to work.

I have written a def file to allow me to use rcasm ( asm.exe ) with Paul Robson's emulator MK14.exe.

I have zipped up the dev directory which can be downloaded. http://www.dougrice.plus.com/mk14/dev.zip

My attempt to get a javaScript version running in a web browser. It is a port of Paul Robson's DOS version.


This page captures notes on how I got there.

Many thanks to Paul Robson and others.

You can run Paul's Emulator under DosBox. To build the source code , I needed to TurboC installed and opened with DosBox.

NOTE:(01/10/2017) Paul's Emulator has a bug in that it treats JMPS with offsets of 0x80 in the same way as other instructions that use the contents of E as the offset. This is a bug. Karen Orton's MK14 software has the same bug ( see her post on 17th Feb 2014, 4:06 pm on http://www.vintage-radio.net/forum/showthread.php?t=92999 Unfortuntely the original Monitor has a line with a JZ 80 that prevents the GO from executing the user's code

 0161   107F E4 03       Gock:	xri	03			; check for term
 0162   1081 98 80       	jz 	GoOut			; error if no term

I have a version that uses SDL called mk14_src_sdl_1.zip at

 http://www.dougrice.plus.com/mk14/mk14_src_sdl.zip  . 

Also: https://github.com/doug-h-rice/virtual_mk14

This is a mash up of Paul Robsob's Dos version and Tommy Thorn's Nascom 2 emulator. See my wiki page on this wiki.

I installed SDL1.2.5 on my Raspberry Pi using the instructions on the SDL website. There is a later version of SDL. my port needs more work to use this.

Download SDL1.2 Simple DirectMedia Layer - Homepage https://www.libsdl.org/ Simple DirectMedia Layer is a cross-platform development library. SDL officially supports Windows, Mac OS X, Linux, iOS, and Android. ‎SDL version 2.0.5 (stable) ‎SDL Wiki ‎SDL 1.2 ‎License

Useful Links

 http://www.robsons.org.uk/archive/members.aol.com/mk14emu/index.htm - Paul Robson's MK14 emulator and info
 http://www.elf-emulation.com/rcasm.html - Assember which can be modified to compile SC/MP
 http://bellard.org/tcc/ - Tiny C used to rebuild rcasm to allow for address inc feature of SC/MP

Other sites and links:-


 http://s400081762.websitehome.co.uk/paulRobson/index.htm - copy of paul's site



A reproduction:-


My attempt to get a javaScript version running in a web browser


Dosbox:- DOSBox is a DOS-emulator that uses the SDL-library which makes DOSBox very easy to port to different platforms.


Turbo C:-



Another SC/MP emulator ( not MK14 ) https://sourceforge.net/projects/scmp-emulator/

running with Paul Robson's MK14 emulator

Download the emulator from:


I found WK14 and MK14 worked. You may need to use DOS box on 64 bit systems or linux to run this.

run using:


Some very simple hex to type in to the MK 14. It works out 0xAA xor 0x55 which equals 0x FF. It stores the result in memory just after the return to the monitor.

Z 0F22 T

Z 0F21 M
C4 M
E4 M
55 M
C8 M
02 M
;now go an execute
Z 0F22
you should read:
0F29 FF

The code assembled using rcasm or asm:

   32 0f22:             
   33 0f22:             	; load accumulator with 0xAA eor with 0x55 and store 
   34 0f22: c4 aa       	ldi	0aah
   35 0f24: e4 55       	xri	055h
   36 0f26:             	
   37 0f26: c8 02       	st	2 (0)
   38 0f28:             	; return to the monitor
   39 0f28: 3f          	xppc	3
   40 0f29:             
   41 0f29:             
   42 0f29:             	; next code is overwritten by result.

Other examples: MK14 scmp code

A test: test4.asm

This code is a dabble to see if I can write to the MK14 screen. It does very little but could be used as a frame work.

In my zip file there is build_test4.bat that uses tools to assemble and run.

The MK14 had inputs and outputs.


run emulator loading text4.hex using:

  mk14 test4.hex

run the code from 0F20.

Press '8','9','0','a' to increment a value.

SC/MP assembler

I found an assembler that I could get to understand SC/MP machine code.


 rcasm test4.asm -l -h -t

I needed to write a definition file for the SC/MP chip used in the MK14.


I coded up the def file for the SC/MP chip and it may need further work.

Save the definitions below into a file call 8060.def http://www.dougrice.plus.com/mk14/8060.def

A test and some SC/MP notes from Paul Robson's website

; Dabble with SC/MP. 
; Author doug rice
; usage: ./rcasm test3.asm -l -h -t
; use simulator:-
; This code puts a constant onto the hex display


;	 v5=key
;	 v6=rnd
;        v7+0100h

 LD 1
 LD 41(2)
 LD @41(2)
 LD 42

#ifdef blockcomment

;Instruction Set

;m is the mode bit. If 1 the instruction is auto-indexed, if 0 it is indexed. pp refers to a pointer register, P0..P3

;If mpp is 100 (you can't auto index on the program counter), this is immediate mode. 
;The data is in the next byte ( ). There is, of course, no store immediate. 

;Double Byte Instructions
;LD/LDI 	11000mpp dddddddd 	18/10 	AC := (EA)
;ST 	11001mpp dddddddd 	18/10 	(EA) := ACOR
;AND/ANI 	11010mpp dddddddd 	18/10 	AC := AC & (EA)
;OR/ORI 	11011mpp dddddddd 	18/10 	AC := AC | (EA)
;XOR/XRI 	11100mpp dddddddd 	18/10 	AC := AC ^ (EA)
;DAD/DAI (1) 	11101mpp dddddddd 	23/15 	AC,CYL := AC+(EA)+CY/L, base 10
;ADD/ADI 	11110mpp dddddddd 	19/11 	AC,CYL := AC+(EA)+CY/L
;CAD/CAI (2) 	11111mpp dddddddd 	20/12 	AC,CYL := AC+~(EA)+CY/L
;ILD 	101010pp dddddddd 	22 	AC,(EA) := (EA)+1
;DLD 	101110pp dddddddd 	22 	AC,(EA) := (EA)-1
;JMP 	100100pp dddddddd 	9 	PC := EA
;JP 	100101pp dddddddd 	9/11 	if AC > 0 PC := EA
;JZ 	100110pp dddddddd 	9/11 	if AC = 0 PC := EA
;JNZ 	100111pp dddddddd 	9/11 	if AC <> 0 PC := EA
;DLY 	10001111 dddddddd 	(3) 	Delay 

;Assembler notes
;Double byte instructions are represented as follows :-
;Immediate 	ldi 4Ch 	(immediate mode)
;Indexed 	ld 41(0) 	EAC := 42 + P0
;Auto Indexed 	ld @4(1) 	EAC := P1 then P1 := P1 + 4
;Direct 		ld 42h 	EAC := 42 (see below) ;


ISP-8A/600 single-chip 8-bit n-channel Microprocessor (SC/MP 2)

This is extracted from the National Semiconductor Data Sheet dated March 1977. Specific details are available via email (autismuk@aol.com). Special thanks to Grant Searle for copying his documentation on the SC/MP and MK14

Hardware notes

Whilst an SC/MP can address 64k , it does so rather ineffectively. Pointers do not wrap around above 4k, and there is no A12-A15 bus lines. They are multiplexed onto the data lines instead.

The SC/MP has a single interrupt input, which is also connected to the 'Sense A' line.

Internal Registers

Accumulator (A)

The accumulator is a standard 8 bit register. It is used in most data manipulation operations. Unlike most modern CPUs, the 'test & jump' operations do not operate on a 'flag register' but on the actual value in the accumulator itself.

Extension (E)

The extension register provides a further 8 bit register. ALU operations are possible using this register as an operand, and it can also be used in indexing to provide a 2-level index register. The Extension register also has the facility to shift data in and out to hardware pins using the SIO command.

Status (S)

The status register provides storage for arithmetic, control and software status flags. There are 3 'output' flags which connect directly to pins on the IC, called F0,F1 and F2. There are two input flags , Sense A and Sense B, also connecting to the IC. Sense A has a dual function, as the interrupt line. The other 3 flags are system status flags

Bit 	Function 	Notes
0 	F0 	Output Line
1 	F1 	Output Line
2 	F2 	Output Line
3 	IE 	Interrupt Enable (set to 1 when enabled)
4 	SA 	Input Line, causes interrupt when SA = 1 and IE = 1
5 	SB 	Input Line
6 	OV 	Overflow on Add, or Complement and Add instructions
7 	CY/L 	Carry / Link bit

On the MK14, cassette out is connected to F0, and cassette in to SIN. An interrupt is raised when IE = 1 and SA = 1

Program Counter (P0)

The program counter register P0 is a 16 bit program counter. It will not increment the 4 upper bits automatically, so an increment from 0FFF would go to 0000.

IMPORTANT: The SC/MP "fetch" is backwards. It increments the program counter, then fetches the instruction. This means that if you wish to 'jump' by setting the Program Counter, you must set it to one less than the actual address. This also means in the ROM at 0000 the first byte isn't used. The PC is set to 0000 on reset, then incremented, then fetched, so the first instruction is at 0001.

Pointer Registers (P1,P2,P3)

These are functionally equivalent to the Program Counter, except that they aren't used for the fetch/execute routines. They are all 16 bit. If Interrupts are being used, P3 contains the address of the routine. (an interrupt call just does XPPC 3 and clears IE)

Addressing Modes

The following address modes are available :-

PC Relative/Indexed

These are functionally equivalent. The effective address is the current value of the PC or pointer register added to the displacement, which can range from -128..127. If the displacement is -128 then the displacement value used is in the Extension register.

Because of the backwards fetch/execute cycle most offsets are one out from what you might expect. This is because when the address is calculated the Program Counter still points at the displacement byte, not the next instruction.

0010 C0 04 This instruction is load indexed on 0 (the program counter). The effective address is 15 (the address of the displacement added to the displacement)


The data is in the next byte. There is no 'effective address' as such.

Auto Indexed

This is like the indexing mode except that the pointer register is pre-decremented or post-incremented by the displacement - if the displacement is -2 the pointer register has 2 subtracted before the data is fetched, if it is +2 it has 2 added after.

Instruction Set

m is the mode bit. If 1 the instruction is auto-indexed, if 0 it is indexed. pp refers to a pointer register, P0..P3

If mpp is 100 (you can't auto index on the program counter), this is immediate mode. The data is in the next byte ( ). There is, of course, no store immediate.

Double Byte Instructions

LD/LDI 	11000mpp dddddddd 	18/10 	AC := (EA)
ST 	11001mpp dddddddd 	18/10 	(EA) := ACOR
AND/ANI 	11010mpp dddddddd 	18/10 	AC := AC & (EA)
OR/ORI 	11011mpp dddddddd 	18/10 	AC := AC | (EA)
XOR/XRI 	11100mpp dddddddd 	18/10 	AC := AC ^ (EA)
DAD/DAI (1) 	11101mpp dddddddd 	23/15 	AC,CYL := AC+(EA)+CY/L, base 10
ADD/ADI 	11110mpp dddddddd 	19/11 	AC,CYL := AC+(EA)+CY/L
CAD/CAI (2) 	11111mpp dddddddd 	20/12 	AC,CYL := AC+~(EA)+CY/L
ILD 	101010pp dddddddd 	22 	AC,(EA) := (EA)+1
DLD 	101110pp dddddddd 	22 	AC,(EA) := (EA)-1
JMP 	100100pp dddddddd 	9 	PC := EA
JP 	100101pp dddddddd 	9/11 	if AC > 0 PC := EA
JZ 	100110pp dddddddd 	9/11 	if AC = 0 PC := EA
JNZ 	100111pp dddddddd 	9/11 	if AC <> 0 PC := EA
DLY 	10001111 dddddddd 	(3) 	Delay

(1) DAD and DAI are decimal add instructions. These do not affect the overflow

(2) CAD and CAI are complement and add instructions, these are used to subtract.

(3) Delays for 13 + 2 * AC + 2 * dddddddd + 2^9 * dddddddd cycles. (13-131,593), AC is set to -1 afterwards.

Single Byte Instructions

lde 	01000000 	6 	AC := E
xae 	00000001 	7 	AC <-> E
ane 	01010000 	6 	AC := AC & E
ore 	01011000 	6 	AC := AC | E
xre 	01100000 	6 	AC := AC ^ E
dae 	01101000 	11 	AC := AC + E + CY/L base 10 
ade 	01101000 	7 	AC := AC + E + CY/L
cae 	01111000 	8 	AC := AC + ~E + CY/L
xpal 	001100pp 	8 	AC <-> P.Low
xpah 	001101pp 	8 	AC <-> P.High
xppc 	011111pp 	7 	P <-> P0
sio 	00011001 	5 	Sout := E0,E := E >> 1, E7 := Sin
sr 	00011100 	5 	AC := AC >> 1
srl 	00011101 	5 	AC := AC >> 1,AC7 := CY/L
rr 	00011110 	5 	rotate right AC
rrl 	00011111 	5 	rotate right AC,CY/L
halt 	00000000 	8 	Pulse 'H' (doesn't stop the CPU)
ccl 	00000010 	5 	CY/L := 0
scl 	00000011 	5 	CY/L := 1
dint 	00000100 	6 	IEN := 0
ien 	00000101 	6 	IEN := 1
csa 	00000110 	5 	AC := S
cas 	00000111 	6 	S := AC (not SA or SB)
nop 	00001000 	5 	no operation

Assembler notes

Double byte instructions are represented as follows :-

Immediate 	ldi 4Ch 	(immediate mode)
Indexed 	ld 41(0) 	EAC := 42 + P0
Auto Indexed 	ld @4(1) 	EAC := P1 then P1 := P1 + 4
Direct 	ld 42h 	EAC := 42 (see below)

There is no actual 'direct' mode. It is converted by the assembler into a PC-relative instruction.

Because of the pre-increment fetch problem, TASM in its normal form will assemble data references one out. So if you are going to use a data area, do it as follows :-

    define the DatPtr macro as #define DatPtr(a) ((a)+1)
    allocate variables by address if they are being used in direct mode MyVar .equ DatPtr(0FE0h)

This will 'fudge' TASM by fixing the value so it can assemble properly. However it is not then possible to use this address by putting it into a Pointer Register and using indexing.

"Calls" via xppc need to be done with the address - 1, again. To call to address 0F40 use the following code :-

    ldi 0Fh
    xpah 1
    ldi 3Fh
    xpal 1
    xppc 1

This will make the PC equal to 0F3Fh , and P1 equal to the address of the XPPC command after it has been executed. The prefetch increment makes the address 'correct'. On return (via XPPC 1 again) the prefetch increment before the next instruction will fix the program counter correctly.

Go back


RCASM enhancements

The COSMAC emulation was fun as well. See this http://www.donnelly-house.net/programming/cdp1802/simelf/ for a really good emulator.

The COSMAC ELF website has an assembler rcasm see - http://www.elf-emulation.com/rcasm.html

Unfortunately it calculates relative addresses incorrectly for SC/MP so I have added \E rule which I use in 8060.def to allow for this.

 \D calculates a relative offset which is okay for jumps but is -1 out for LD and ST 
 \E calculates a relative offset which is okay for LD and ST direct

 8060.def uses \E

I have used the duck.asm example in the MK14 manual to verify the assembler generated the correct hex.

To Build RCASM renamed to ASM.exe:-

I used TinyCC http://bellard.org/tcc/

 set up a directory called dev at the same level as include and examples.

 download rcasm from  http://www.elf-emulation.com/rcasm.html

 Unpack using 7.zip and copy source code into dev.

 In directory dev, try and build using ..\tcc *.c

 If this works, replace asmcmds.c  with http://www.dougrice.plus.com/mk14/asmcmds.c

 Now you can use 8060.def ( http://www.dougrice.plus.com/mk14/8060.def )

 ..\tcc *.c

this produces asm.exe instead of rcasm.exe

To assemble:-

 .\asm test4.asm -h

to run:-

 MK14 test4.hex

type 0f20 G

I have zipped up the dev directory which can be downloaded. http://www.dougrice.plus.com/mk14/dev.zip


Having an assembler makes using the MK14 emulator easier. It was hard work hand compiling assembler and retyping it in, only to crash it due to a typo.

If you wish you can still type in the hex.

PostScript - Cosmac Elf

The COSMAC emulation was fun as well.

See this http://www.donnelly-house.net/programming/cdp1802/simelf/ for a really good emulator.

In the summer of 1977 I studied the COSMAC and have the handbook purchased from Henry's radio.

Until now I have never been able to run any code.

It does not have a subroutine call stack.

The COSMAC ELF website is worth a visit see - http://www.elf-emulation.com/rcasm.html

HomePage | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited October 1, 2017 9:04 pm by dougrice.plus.com