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)

Immediate

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 :-

  1. define the DatPtr macro as #define DatPtr(a) ((a)+1)
  2. 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 :-

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