This page's trying to cover SC-61860's machine language used on most Sharp pocket computers (series PC-12??, PC-13??, PC-14?? and PC-2500)
Some french words :
Cette page est uniquement en anglais car je n'ai
le temps de créer qu'une seule
documentation, et puis, je fais beaucoup moins de fautes dans la langue de Shakespear. L'anglais n'est pas très
recherché (car c'est le mien ;-D).
Please note : in this page
&xx stands for 8 bits
hexadecimal values,
&xxxx a 16 bits
hexadecimal value or external RAM address,
$xx means for an
internal RAM 8 bits address.
The SC-61860 is a 8 bits CPU based on CMOS
technology used by most 80' Sharp Pocket computer :
PC-12??, 13?? and 14??. PC-15??, PC-1600 and all 4
bits powered pocket are excluded.
In fact this CPU should really called a 'Micro
Controller' as it contains also some part of
the LCD drivers (it's why it has so many pins).
It has also 8k of ROM embedded, named the
"internal ROM", which is different
between PC models, and 96 bytes internal
memory. Notez bien : the internal ram is very very
faster than the external one. Using this memory save
lof of CPU cycles, and as the system clock is very slow,
it will improve noticeably critical stuffs.
|
|
|
IX, DX, IXL, DXL, IY, DY, IYS, DYS).
CLA (&23) should be called LDS).
(dp) is not the register d).
|
indexes is the official name of these registers
but, in fact they are used mainly for repeated
instructions. J is always set to '1' so
instructions using this register are almost used for
16 bits manipulations (EXBD, ...?).
|
|
Even if all bytes of the internal memory should be considered as a 'general use register', K,L,M,N have some special instructions to use them : INC? and DEC?.Please also note that many mnemonics have 'M' in there names. It stand for (P), only INCM and DECM use directly the M register.
|
| bits | Connector | Pine # | I/O | Name : sharp (standard) |
|---|---|---|---|---|
| 0 | SIO | 14 | O | ER (DTR) |
| 1 | SIO | 4 | O | RS (RTS) |
| 2 | SIO | 11 | O | RR (DSR) |
| 3 | SIO | 3 | I | RD (RxD) |
| 4 | SIO | 5 | I | CS (CTS) |
| 5 | SIO | 8 | I | CD (CD) |
| 6 | SD | 8 | I | Din |
| 7 | SD | 9 | I | Ack |
| bits | Connector | Pine # | I/O | Name : sharp (standard) |
|---|---|---|---|---|
| 0 | n/a | n/a | Memory protected the memory can't be read, always return the upper byte of it own address : LIDP &253f; LDD -> &25
| |
| 1 | SD | 4 | O | Busy |
| 2 | SD | 5 | O | Dout |
| bits | Name | Comment # |
|---|---|---|
| 0 | Display | Display ON (1)/OFF (0) |
| 1 | Reset | Reset counter (see TEST) |
| 2 | HLT | Stop the CPU (wake up when the 512ms counter rise) |
| 3 | OFF | Power off the machine |
| 4 | BZ1 | Signal High |
| 5 | BZ2 | Sound activated |
| 6 | BZ3 | Xin activated |
Some instructions can compute BCD numbers but, unlike mathematical processing unit of moderns CPU, they use normals registers in the "internal working memory".
So, in this memory, some groups of 8 bytes are commonly used for BCD computation by ROM functions :
This memory hold temporary objects :
The stack start at $5b and increases downward. In fact, there is no real limit on stack expention and no check is done.
Unlike most other systems, the CPU stack is not intensively used.
For exemple, on 68000 systems, stacks are used to reserve working area, to pass parameters between functions, to store scrach registers and to store program environment when an interruption occurs, ...
On SC61860's machine this stack is only used to stock return address of sub routines and eventually, to save some registers. And as this CPU doesn't have any interrupts capability, a very small stack is enough.
LIr n : r <- #n
LII n (&00), LIJ n (&01), LIA n (&02), LIB n (&03),
LIP n (&12), LIQ n (&13)
LIDP nn (&10), LIDL n (&11)
For small values, LIP n can be shorted by LP n, coded in only one byte (LP 3F - &80 - to LP 3F - &BF -)
LDr : A <- r
LDP (&20),
LDQ (&21),
LDR (&22),
and
LDD (&57) : A <- (DP)
LDM (&59) : A <- (P)
STr : r <- A
STP (&30),
STQ (&31),
STR (&32),
and
STD (&52) : (DP) <- A
Please note : STM doesn't exist. Use EXAM instead.
MVW (&08) : [(P++) <- (Q++)] * I
MVB (&0A) : [(P++) <- (Q++)] * J (as J is usualy 1, perfect for 16 bits move)
MVWD (&18) : [(P++) <- (DP++)] * I
MVBD (&1A) : [(P++) <- (DP++)] * J (as J is usualy 1, perfect for 16 bits move)
MVDM (&53) : (DP) <- (P)
MVMD (&55) : (P) <- (DP)
DATA (&35) : [(P++) <- ({B,A}++);] * I
This instruction is the ONLY ONE for reading protected memory (i.e. first 8k ROM).
EXW (&09) : [(P++) <-> (Q++)] * I
EXB (&0B) : [(P++) <-> (Q++)] * J (as J is usualy 1, perfect for 16 bits move)
EXWD (&19) : [(P++) <-> (DP++)] * I
EXBD (&1B) : [(P++) <-> (DP++)] * J (as J is usualy 1, perfect for 16 bits move)
EXAB : A <-> B (&DA)
EXAM : A <- (P) (&DB)
INCr : r <- r+1DECr : r <- r-1INCP and DECP don't modify anything but P).
INCI (&40),
DECI (&41),
INCJ (&C0),
DECJ (&C1),
INCA (&42),
DECA (&43),
INCB (&C2),
DECB (&C3),
INCK (&48),
DECK (&49),
INCL (&C8),
DECL (&C9),
INCM (&4A),
DECM (&4B),
INCN (&CA),
DECN (&CB),
INCP (&50),
DECP (&51)
Ir : r <- r+1; DP <- rDr : r <- r-1; DP <- r
IX (&04),
DX (&05),
IY (&06),
DY (&07),
X and Y registers allow blocs memory moves using following instructions :
IXL (&24): X <- X+1; DP <- X; A <- (DP)DXL (&25): X <- X-1; DP <- X; A <- (DP)IYS (&26): Y <- Y+1; DP <- Y; (DP) <- ADYS (&27): Y <- Y-1; DP <- Y; (DP) <- ASo the following listing are equivalent
| Normal listing | Optimized listing |
{start_loop}
IX
LDD
IY
STD
DECI
JRNZ {start_loop}
|
{start_loop}
IXL
IYS
DECI
JRNZ {start_loop}
|
|---|
| Adding | Subtracting | ||||
|---|---|---|---|---|---|
| Binary | |||||
|
|
| ||||
| code | ANLogical AND | ORLogical OR | TSTest | CPCompare |
opIA nA <- A op #n
| &64 | &65 | &66 | &67 |
opIM n(P) <- (P) op #n
| &60 | &61 | &62 | &63 |
opID n(P) <- (P) op #n
| &D4 | &D5 | &D6 | &D7 |
opMA n(P) <- (P) op #n
| &46 | &47 | &C6 | &C7 |
for all operations,
Z=1 if the result is null or Z=0 otherwise.
C is only affected by an CP instuction.
|
| |||||||||||||||
| ||||||||||||||||
JRP n (&2C): PC <- PC + #nJRM n (&2D): PC <- PC - #nJP nn (&79): PC <- #nn
For relative jump, JRP and JRM, the reference is the address of the argument. So
JRP 01 does nothing.JRM 01 is an infinit loop to itself.
JRcP n, JRcM n, JPc nn does the same thing but with a condition :
|
|
CALL nn (&78): (R-1,R) <- PC; R <- R-2; PC <- #nnRTN (&37): PC <- (R-1,R); R <- R+2
CALL saves the current PC value and jump to a sub routine. RTN ends this sub routine and returns to the saved PC value (PC is now on the instruction following the CALL).
CAL 00 n (&E0) to CAL 1F n (&E0) does the same thing but saves one byte and some CPU cycle and are reserved for function in the first 8k memorie (the internal ROM).
CASE1 nb rtn@drCASE2 val1 @dr1 val2 @dr2 ... valn @drn def@dr
|
Using theses instructions, it is very very easy to call a sub routine associated to a value of A (same as
|
|
PUSH (&34): (R) <- A; R <- R-1POP (&5B): A <- (R); R <- R+1
LOOP n (&2F): (R) <- (R)-1; if c=0 then PC <- PC + 1 - #n else PC <- PC + 2; R <- R+1LEAVE (&D8): (R) <- 0
With these instructions, a loop can be easily made, and LEAVE is an easy way to exit from a loop.
How to use LOOP |
|
LIA 5
PUSH
LIB 0
{lbl}
INCB
LOOP {lbl}
LIDP &6c30
EXAB
STD
RTN
|
02 05 34 03 00 C2 2F 03 10 6C 30 DA 52 37 |
| (&6C30) => 6 | |
|---|---|
INA (&4C): A <- PortAOUTA (&5D): PortA <- ($5c)
|
INB (&CC): A <- PortBOUTB (&5D): PortB <- ($5d)
|
OUTF (&5F): PortF <- ($5e)OUTC (&DF): PortC <- ($5f)
|
FILM (&1E): [(P) <- A; P++] * IFILD (&1F): [(DP) <- A; DP++] * I
SL (&5A): Shift A leftSR (&5D): Shift A Right
|
|
SLW (&1D): Shift 4 bits left starting P and on I bytes.([SHIFT4LEFT(P); P <- P-1] * I)
SRW (&1C): Shift 4 bits right starting P and on I bytes.([SHIFT4RIGHT(P); P <- P+1] * I)
WAIT n (&4E): Wait 6 + n cyclesNOPW (&4D): Wait 2 cyclesNOPT (&CE): Wait 3 cyclesCUP (&4F): Wait if xin is not highCDN (&6F): Wait if xin is not low
d <- I; repeat d--; until (d==&ff or Xin=condition);
TEST n (&6B)
This instruction acts as if we TS a system port of the CPU.
|
|
SWP (&58): Swap A7-4, A3-0 (LIA &ab; SWP => A=&ba).
SC (&D0): C=1, Z=1
RC (&D1): C=0, Z=1
Hum, I realy don't know what should be the useness of such instructions ;-D
READ (&56): A <- (PC + 1)
READM (&54): (P) <- (PC + 1)
WRIT (&D3): ????