-
Notifications
You must be signed in to change notification settings - Fork 3
/
ycpu.txt
2162 lines (1664 loc) · 96.9 KB
/
ycpu.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
YCPU Specification
Version 1.1
### Table of Contents ##########################################################
1. Introduction
1.A. Public Domain Dedication
2. Instruction Set Overview
3. Hardware Information
3.A. Registers
3.B. Supervisor/User Modes
3.C. Hardware Devices
3.D. Interrupts
3.E. Addressing Modes
3.F. Memory Management
3.G. Boot Sequence
3.H. The Real Time Clock
3.I. Switching Context
4. Instruction Set Description
4.A. Bit Patterns
4.B. ALU Instructions
4.C. Bit Shifting Instructions
4.D. Bit Testing Instructions
4.E. Branch Instructions
4.F. Increment Instructions
4.G. Jump & Call Instructions
4.H. Stack Instructions
4.I. Processor Function Instructions
### 1. Introduction ############################################################
The YCPU Specification describes a 16-bit processor architecture with a
comprehensive instruction set and features. These features include:
* eight general purpose 16-bit data/address registers;
* user/supervisor modes with different privileges and stack pointers;
* memory segmentation with resizable segments for code, stack, interrupts,
and two data segments;
* memory protection with not-present/read-only attributes;
* 28 bits of address space for memory access;
* real time clock with a programmable timer that raises interrupts;
* hardware bus that supports up to 15 devices with 24 bits of address space
each.
This document is made up of four sections. Each Section describes the YCPU
Specification in increasing detail.
This first Section includes a brief overview of the document and the public
domain dedication. In brief, the specification document is released to the
public domain, and anyone may use it for any purpose without permission or
attribution.
Section 2 gives a broad overview of the 58 instructions that you can use to
write programs for the YCPU. The instructions are divided by function into
groups: math (2.A.), increment (2.B.), bit-shifting (2.C.), bit-testing (2.D.),
branch (2.E.), jump (2.F.), stack (2.G.), and processor function (2.H.).
Section 3 describes the processor functions in great detail. Specifically, this
Section describes the processor's registers (3.A.), the supervisor/user
modes (3.B.), Hardware devices and input/output, (3.C.), interrupts and fault
states and how to handle them (3.D.), the six memory addressing modes (3.E.),
memory management and the use of segments (3.F.), the processor's boot
sequence (3.G.), the real time clock (3.H.), and how to switch context (3.I.).
Section 4 details how instructions are encoded into 16-bit program words, as
well as the exact function of every instruction, including how these functions
effect memory and flags.
This document includes syntax for a reference assembler that would encode
instructions and data for the YCPU. This syntax is used for example purposes
only, and might be different depending on the assembler used by the programmer.
These precepts are followed to describe the reference assembler syntax:
- Decimal numbers are indicated using numbers, and may be preceded by a
dash "-", which indicate a negative decimal number.
- Hexidecimal numbers are indicated by a prefix dollar sign character "$".
- The general purpose registers are named R0-R7. An alternate assembler
might use, for example, the register names A, B, C, D, W, X, Y, and Z.
- 8-bit operations are indicated by postfixing an instruction with the
characters ".8". Reference sections 2.A. and 3.E.3.
- The Extra Data Segment is referenced with the syntax ES[M]. Reference
section 3.E.2.
=== 1.A. Public Domain Dedication ==============================================
This document is dedicated to the public domain under the terms of the Creative
Commons Zero (CC0) waiver. All rights have been waived with regard to
copyright law, including all related and neighboring rights, to the extent
allowed by law.
You can copy, modify, and distribute this document, and use it to create
derivative works, even for commercial purposes, all without asking permission.
More information about CC0 waiver is available online at:
http://creativecommons.org/about/cc0
### 2. Instruction Set Overview ################################################
This Section contains a brief overview of all instructions that can be used when
programming the YCPU. For more information about specific processor functions,
reference Section 3., Hardware Information. For detailed information on how
these instructions are encoded, reference Section 4., Instruction Set
Description.
These instructions often change the value of the eight general purpose
registers. The reference assembler names for the general purpose registers are:
R0, R1, R2, R3, R4, R5, R6, and R7.
=== 2.A. Math Instructions ====================================================
At its heart, the YCPU is a fast math processor. It handles both signed and
unsigned multiply and divide instructions, and has a carry flag so that you can
chain 16-bit additions and subtractions. For more information about these
instructions, including when flags are set, reference 4.B.
The reference assembler format of math instructions is:
XXX R, M
XXX is the three-letter instruction code (ex. "ADC" or "MUL"). All math
instructions are either 8-bit or 16-bit. The default action is 16-bit
math. You can specify a 8-bit instruction by adding the text ".8" to
the end of XXX (ex. "ADC.8 RX, RY" or "MUL.8 RX, RY").
R is a register with the value of R0, R1, R2, R3, R4, R5, R6, or R7. R
designates the first operand of the math instruction, and is also the
destination of the result of the math instruction.
M is a register or memory location that designates the second operation of
the math operation. The following syntax may be used for M, which will
access memory with different addressing modes:
Addressing Mode Syntax Value is...
Immediate $1234 Value of Next Word
Absolute [$1234] Mem[Next Word]
Register RX Value of Register (R0 ... R7)
Indirect [RX] Mem[R]
Indirect Offset [RX,$1234] Mem[R + Next Word]
Indirect Indexed [RX,RX] Mem[R+R] At least one register
must be R4, R5, R6, or R7.
The math instructions are:
ADC R = R + M Adds M to R, with carry (if carry flag is set, add 1).
ADD R = R + M Adds M to R, ignoring carry.
AND R = R & M Bitwise and.
CMP R = R Compares R and M and sets flags based on results.
DIV R = R / M Unsigned division.
DVI R = R / M Signed division.
EOR R = R ^ M Bitwise exclusive or.
LOD R = M Sets R equal to value of M.
MDI R = R % M Signed modulus.
MLI R = R * M Signed multiply, 32-bit result: High 16-bits of result
are stored in R0. If R is R0, R0 will equal that low
16-bits of the result, and the high 16-bits are lost.
MOD R = R % M Unsigned moduls.
MUL R = R * M Unsigned multiply. As with MLI, the high 16-bits of the
the result are stored in R0, and may be overwritten.
NEG R = 0 - M Bitwise negation.
NOT R = !M Bitwise NOT.
ORR R = R | M Bitwise OR.
STO M = R Sets M equal to R.
SBC R = R - M Subtracts M from R, with carry.
SUB R = R - M Subtracts M from R, ignoring carry.
=== 2.B. Increment Instructions ===============================================
Increment instructions allow you to add or subtract small values from the
registers. These instructions are faster and smaller than math instructions.
For more information about increment instructions, reference 4.F.
The format of increment instructions is:
XXX R, V
XXX is the three-letter instruction code (ex. "ADI" or "MUL").
R is a register with the value of R0, R1, R2, R3, R4, R5, R6, or R7. R
designates the first operand of the math instruction, and is also the
destination of the result of the math instruction.
V is a value from 1 to 32.
The immediate instructions are:
ADI R = R + V Adds V to R.
SBI R = R - V Subtracts V from R.
NOTE: You can use "INC RX" as a subtitute for "ADI RX, 1", and "DEC RX" as a
substitute for "SBI RX, 1".
=== 2.C. Bit-shifting Instructions ============================================
The YCPU can shift bits in a general purpose register. Bits may be shifted left
or right. For more information about bit-shifting instructions, reference 4.C.
The format of Bit-shifting instructions is:
XXX R, V
XXX is the three-letter instruction code (ex. "ASL" or "ROL").
R is a register with the value of R0, R1, R2, R3, R4, R5, R6, or R7. R is
the register that will be shifted.
V is usually a value from 1-16, but can also be a register with the value
of R0, R1, R2, R3, R4, R5, R6, or R7. For more information about using
registers for bit-shifting instructions, reference 4.C.
The bit-shifting instructions are:
ASL Shifts all bits in R by V bits to the left.
Leftmost bits are set to 0.
ASR Shifts all bits in R by V bits to the right.
Rightmost bits are set to original value of bit 15.
LSL Shifts all bits in R by V bits to the left.
Leftmost bits are set to 0.
LSR Shifts all bits in R by V bits to the right.
Rightmost bits are set to 0.
RNL Rotates all bits in R by V bits to the left, not using carry bit.
RNR Rotates all bits in R by V bits to the right, not using carry bit.
ROL Rotates all bits in R by V bits to the left, through the carry bit.
ROR Rotates all bits in R by V bits to the right, through the carry bit.
NOTE: If you noticed that ASL and LSL are mathmatically equivalent, nice catch!
This is indeed the case - the processor treats these two instructions
identically.
=== 2.D. Bit-testing Instructions =============================================
The YCPU can test and effect single bits in a general purpose register. For more
information about bit-testing instructions, reference 4.D.
The format of Bit-testing instructions is:
XXX R, V
XXX is the three-letter instruction code (ex. "BTT" or "BTX").
R is a register with the value of R0, R1, R2, R3, R4, R5, R6, or R7. R is
the register that will be tested.
V is usually a value from 0-15, but can also be a register with the value
of R0, R1, R2, R3, R4, R5, R6, or R7. when V is a value, it is the index
of the bit that will be tested and maybe changed. When V is a register,
the lower 4 bits of the register's value are used as the index.
The bit-testing instructions are:
BTT Tests a bit in R. If the bit is clear, zero flag is cleared. If the
bit is set, zero flag is set.
BTC Tests a bit in R, and clears it. Equivalent to BTT, plus the bit
will be cleared after the instruction.
BTS Tests a bit in R, and sets it. Equivalent to BTT, plus the bit will
be set after the instruction.
BTX Tests a bit in R, and changes it. Equivalent to BTT, plus the bit
will be changed (if clear, it will be set after the instruction; if
it was set, it will be cleared).
=== 2.E. Branch Instructions ==================================================
The YCPU can use branch instructions to move around in the code based on the
condition of the flag bits in the processor status register (PS). These flags
are set by instructions as a result of executing an ALU, increment, bit
shifting, or bit testing instruction. For more information about the state
of bit flags, reference sections 4.B., 4.C., 4.D., and 4.F.
Each branch instruction defines a condition and an instruction offset. When a
branch instruction is executed, the YCPU checks the status of the flag bits in
PS. If the flag bits match the required condition of the branch instruction, the
YCPU will adjust its program counter (PC) register by the number of 16-bit words
indicated in the instruction offset.For more information about branch
instructions, reference 4.E.
The format of Branch instructions is:
XXX V
XXX is the three-letter instruction code (ex. "BCC" or "BUF").
V is a value from -128 to +127. This is the number of 16-bit words that
the PC register will be changed by.
The branch instructions are:
BCC Branch on unsigned fewer than - if carry flag in PS is clear.
BCS Branch on unsigned higher than or same - if carry flag in PS is set.
BNE Branch on not equal - if zero flag in PS is clear.
BEQ Branch on equal - if zero flag in PS is set.
BPL Branch on signed fewer than - if negative flag in PS is clear.
BMI Branch on signed higher than or same - if negative flag in PS set.
BVC Branch on no overflow - if overflow flag in PS is clear.
BVS Branch on overflow - if overflow flag in PS is set.
BUG Branch on unsigned greater than - if zero flag and carry flag set.
BSG Branch on signed greater than - if negative flag and carry flag set.
BAW Branch always.
=== 2.F. Jump Instructions =====================================================
You use jump instructions to continue executing the program at a new address.
The new address can be near or far (for more information about far jumps,
reference 3.F.4.). For more information about these instructions, reference 4.G.
The format of jump instructions is:
XXX M
XXX is the three-letter instruction code (ex. "JMP" or "JSR"). A jump or
call can be to a near address or far address. The default address type
is near. You can specify a far address by adding the text ".f" to
the end of XXX (ex. "JMP.F").
M is the value that PC will be set to when this instruction is executed.
Jump instructions use the same addressing modes as math instructions:
Addressing Mode Syntax Value is...
Immediate $1234 Value of Next Word
Absolute [$1234] Mem[Next Word]
Register RX Value of Register (R0 ... R7)
Indirect [RX] Mem[R]
Indirect Offset [RX,$1234] Mem[R + Next Word]
Indirect Indexed [RX,RX] Mem[R+R] At least one register
must be R4, R5, R6, or R7.
The jump instructions are:
JMP Unconditional jump to new address.
JSR Unconditional jump to new address, saves return address to stack.
Jump instructions are unconditional - they are always executed. Conditional
jumps may be created by the combination of a branch instruction and a jump
instruction, as indicated in this example:
; if carry is clear, continue with current instructions.
; if carry is set, jump to alternate instructions.
BCC 3 ; encoded as 1 bit-bit words
JMP $1234 ; encoded as 2 16-bit words
XXX ; <-- target of BCC with offset of ( 1 + 2 ) = 3
...
...
...
; at address $1234
XXX ; <-- target of JMP
=== 2.G. Stack Instructions ====================================================
You use stack instructions to push registers to the stack, or pop registers to
the stack. For more information about stack instructions, reference 4.H.
The format of stack instructions is:
XXX R{, R, R...}
XXX is the three-letter instruction code (ex. "PSH" or "POP").
R is either one register or a list of registers separated by commas.
The processor sequentially accesses the stack to push or pop each
specified register in a specific order (see 4.H.).
The stack Instructions are:
POP Pop values from the Stack into registers.
PSH Push values of registers onto the Stack.
In addition, you may use the STX instruction to directly modify the stack with
an immediate value. The format of the STX instruction is "STX V" where V is a
value from -128 to 127. Following this instruction, the stack will be modified
by the given number of 16-bit words relative to its previous value.
=== 2.H. Processor Functions ===================================================
The processor has a number of instructions that activate special functions.
These are described in brief here, more thoroughly in in Section 4.I., and in
great detail throughout Section 3. The processor function instructions are:
CLF [N][,C][,Z][,V] Clears the specified bits in the PS register. Any
combination of these flags is valid.
Exs: CLF Z (or) CLF C, V, Z (or) CLF N, V
HWQ V Sends a message of type V to the hardware bus.
Reference 3.C.
Ex. HWQ 1 (or) HWQ 128
LSG S Load segment register S from the stack.
Ex. LSG CS
RTI Return from interrupt handler. Reference 3.D.8.
RTS Return from subroutine - pops a value from the stack
and sets PC to that value.
SEF Sets the specified bits in the PS register. Same
parameter flags as CLF.
SLP Halts the processor until it receives an interrupt.
SSG S Save segment register S to the stack.
Ex. SSG DS
SWI Call software interrupt. Reference 3.D.3.
### 3. Hardware Information ####################################################
The YCPU is a 16-bit processor designed to be powerful without being complex. A
hobbyist can begin programming software knowing only the syntax of their
assembler of choice and the way the RESET interrupt functions. Experts and
developers of operating systems will enjoy the processor's many features and the
easy transfer between supervisor, user, and interrupt modes. This Section
describes the processor's functions in detail. We begin with a description of
the processor's memory model.
--- 3.1. MEMORY MODEL ----------------------------------------------------------
The YCPU's eight data/address registers are each 16-bit. This means that all
data handled by a single register can only address values between 0-65,536 when
unsigned, or -32,768 to 32,767 when signed. The processor does have several
instructions where two 16-bit operands combine to create a 32-bit results (for
example, multiplication). When this occurs, the 'high' 16-bits of the result
are stored in R0. The programmer has the choice to also store the low 16-bits
of the result in R0, which would overwrite the high bits, or choose a different
register for the destination of the low bits.
With regards to addresses, the 16-bit limit means that all logical addresses
can only address 64 kilobytes of memory at any time. However, using a memory
management unit (MMU), the processor can access multiple 64 kilobyte areas of
the processor at once. These areas are called 'segments'. For example, the
processor might read code from one segment while copying data from a second
segment to a third segment, while the stack pushed and pulled data from a fourth
segment, and interrupts are handled by code in a fifth segment.
Where segments are located in memory memory and how large they are is
contolled by the processor's segment registers. There are nine of these: four
describing the code, data, extra data, and stack segments for the processor's
supervisor mode, an identical four for the processor's user mode, and one
segment register that controls the segment used when the processor is handling
an interrupt.
--- 3.2. INSTRUCTION WIDTH: 16-BIT ---------------------------------------------
For most instructions, the only addressable unit of memory is a 16-bit word.
8-bit instructions are supported for any instruction that uses the "ALU" bit
pattern: Load, Store, Add, Subtract, Multiply, Divide, Bitwise And, Bitwise Or,
Bitwise Not, Bitwise Exclusive Or, Compare, and Negate. When executing 8-bit
instructions in registers, the upper 8-bits of memory are cleared and ignored.
When executing an 8-bit STOre operation, the processor will store only one byte,
and the second byte in the 16-bit word in memory will not be affected. When
executing an 8-bit load operation, the processor will load only the lower byte
at the address, and the upper 8-bits of the destination register will be
cleared.
For all other instructions there is no support for 8-bit maths. All other
instructions operate on 16-bit vales at all times.
--- 3.3. MEMORY ALIGNMENT ------------------------------------------------------
For 16-bit memory access, access is quickest when aligned to 2-byte boundaries,
and slower when accesses are unaligned. Thus, memory accesses from $0000 and
$0002 are faster than $0001 and $0003. For unaligned memory accesses, the YCPU
loads the two bytes for a 16-bit word in separate memory access cycles.
For 8-bit access, the YCPU loads only one 8-bit value. A single 8-bit load is
as fast as an aligned 16-bit load, regardless of alignment.
--- 3.4. REQUIRED HARDWARE -----------------------------------------------------
When the processor first powers on and each time it is RESET, it returns to a
known state described in 3.G. The processor then executes instructions located
in an on-board read only memory (ROM) chip. To access this chip, the processor
relies on a hardware bus (YBUS). Thus, to execute any instructions the processor
must be connected to a bus and a ROM chip. Of course, any useful work will
likely require random access memory (RAM) as well, but RAM is not required power
on the processor. Note that the amount of RAM and ROM available to the
processor is not known to the processor. However, a programmer can query the
amount of RAM/ROM with the instruction HWQ $03. For more information about this
query operation, see 3.C.1.
=== 3.A. Registers =============================================================
The processor uses eight general purpose registers for most instructions.
These registers are named R0, R1, R2, R3, R4, R5, R6, and R7. See 3.A.1.
The processor has four control registers. These change the flow of the
program. For more information, see 3.A.2. These are:
PC: Program Counter.
PS: Processor Status.
SP: Stack Pointer. The YCPU has separate stack pointers for user mode (USP)
and supervisor mode (SSP).
The processor also has access to 9 32-bit segment registers. Note that you
do not need to use these to write code, but they can be used for memory
management. Four of the segment registers are used for the code, data, extra
data, and stack segments accessed in Supervisor mode, and four for the
segments accessed in User mode. In addition, there is one Interrupt segment
register, the segment used during Interrupts. For more information,
see 3.F. Memory Management. The segment registers are:
CS: Code Segment. One for Supervisor (CSS), one for user mode (CSU).
DS: Data segment. One for Supervisor (DSS), one for user mode (DSU).
ES: Extra Data segment. One for Supervisor (ESS), one for user mode (ESU).
SS: Stack segment. One for Supervisor (SSS), one for user mode (SSU).
IS: Interrupt segment. Used in place of CS when bits I and M in PS are set.
--- 3.A.1. GENERAL PURPOSE REGISTERS -------------------------------------------
The processor has 8 general purpose 16-bit registers. These registers are used
as both data and address registers, are almost completely interchangeable
(orthogonal), and are directly referenced and modified by most instructions.
There are a few exceptions to general purpose register interchangeability.
* R0 is the destination of the high 16-bits of the result of MUL (multiply)
and MLI (signed multiply) instructions, which have 32-bit results. If R0 is
also the src/dest register, then the high 16-bits are lost, and R0 will
contain the low 16-bits after the instruction completes.
* Only registers R4 - R7 can be used as index registers for indirect indexed
memory addressing. Thus, when executing an instruction with this addressing
mode, at least one of the registers that are combined to create the memory
address must be R4, R5, R6, or R7:
Allowed: LOD R1, [R0, R4] ; one register is R4-R7. Valid.
Allowed: LOD R1, [R4, R5] ; both registers are R4-R7. Valid.
Disallowed: LOD R1, [R0, R2] ; neither register is R4-R7. Not valid.
--- 3.A.2. PROCESSOR CONTROL REGISTERS -----------------------------------------
The processor has five 16-bit processor control registers. Unlike the general
purpose registers, these are not accessible by most instructions. The five
processor control registers are PC, PS, SSP, and USP.
PC: The Program Counter. Contains the address of the next instruction to
execute. It is incremented by 2 after executing an opcode that does
not reference an immediate word value, by 4 after executing an opcode
that does reference an immediate word value, or by 8 after executing an
opcode that references three immediate word values. See 3.E.1. for more
information about immediate values.
PS: The Processor Status. This register serves two purposes: it contains
the state of processor features and modes, and also contains flags that are
set by ALU instructions. The bits are as follows:
FEDC BA98 7654 3210
SMHI QUVW .... NZCV
[S] - [S]upervisor Mode enabled.
[M] - [M]emory segmenting hardware enabled.
[H] - [H]ardware Interrupts enabled.
[I] - Processor handling [I]nterrupt, read code/immediate values
from IS instead of CS.
[Q] - HWI Re[Q]uest in process, blocks hardware interrupts.
[U] - Fault in [U]ser mode.
[V] - Segment Fault error bit 0. See 3.D.5.
[W] - Segment Fault error bit 1. See 3.D.5.
[N] - Last ALU instruction result was negative.
[Z] - Last ALU instruction result was Zero
[C] - Last ALU instruction result was Carry
[V] - Last ALU instruction result was Overflow
SP: The Stack Pointer is the address of the first full stack space. It is
decremented before a stack value is pushed onto the stack, and is
incremented after a stack value is popped from the stack. The stack
grows downward from its initial address, and should be initialized to
an address at (Stack Bottom + 1). Example: If SP is set to $0000, the
first pushed value will be at $fffe, and the first pulled value will
be read from $0000.
The processor has two different stack pointers - the Supervisor Stack
Pointer, or SSP, is used while the processor is in Supervisor mode, and
the User Stack Pointer, or USP, is used while the processor is not in
Supervisor mode.
=== 3.B. Supervisor/User Modes =================================================
Supervisor mode is enabled when the S bit in the PS register is set, which is
true on processor boot and whenever an interrupt is called. When the S status
bit is clear, the processor is in User mode.
In Supervisor mode, the processor:
* Can execute privileged opcodes.
* Can set and clear all bits in the process status register.
* Can read and write to all processor control registers.
* Can directly access the hardware bus with the HWQ instruction.
* Uses the Supervisor Stack Pointer (SSP) for stack instructions.
* Uses the Supervisor segment registers.
In User mode, the processor:
* Raises an 'Unprivileged Opcode' interrupt on executing privileged opcodes.
* Cannot set or clear any bits in the process status register.
* Cannot write to PS, but can read from it.
* Cannot directly access the hardware bus.
* Uses the User Stack Pointer (USP) for stack instructions.
* Uses the User segment registers.
=== 3.C. Hardware Devices ======================================================
The processor interfaces with hardware devices through a modular Hardware Bus.
This Hardware Bus can host up to 15 Devices in addition to the processor.
The processor communicates directly with devices executing a Hardware Query
instruction (See 3.C.1.), and can also address memory segments exposed by a
device (See 3.F.1.). Devices can request the processor's attention by raising a
hardware interrupt (See 3.D.2.).
Connected Hardware Devices may include input (keyboard, mouse, touch), output
(segment, character, and bitmap based displays, printers, dials, readouts),
storage (disk, hard drive), networking, additional memory, and interfaces for
hardware not directly connected to the Hardware Bus. A programmer can use the
HWQ $02 instruction to identify what Hardware Device is present in a given
Hardware Slot (See 3.C.1).
Device Slot 0 on the Hardware Bus refers to the YCPU itself. Software can
retrieve information about the YCPU by using the Hardware Query instruction to
query the Device in Slot 0.
Note that Hardware Devices can independently access the YCPU's active memory,
but only one device or the processor can access memory at once. Thus, while a
device is reading or writing memory, the processor is stalled.
--- 3.C.1. INTERACTING WITH HARDWARE -------------------------------------------
Software interacts with hardware using the HWQ (HardWare Query) instruction.
This instruction includes one immediate 8-bit operation index. The possible
indexes are (undefined operation indexes raise a 'UndefFault' interrupt):
HWQ Index Description
$00 Query number of devices connected
$01 Query device attached to bus in slot R0
$02 Send message to hardware device
$03 Get RAM/ROM amounts in R0-R3.
$80 Get RTC time
$82 Get RTC interrupt interval
$83 Set RTC interval
HWQ $00 - Query number of devices connected
Calling HWQ operation $00 will query the Bus for the number of connected
devices. The YCPU will store this value in R0.
HWQ $01 - Query device attached to bus in slot R0
Software can determine what device is present in each of the 16 Bus Slots by
calling HWQ operation $01 with the index of the Bus Slot to check in R0. If no
device is present, R0 will be set to "ERR_NO_DEVICE" ($ffff). If a device is
present, the registers of the YCPU will be set as follows:
R0: Device Type
R1: Manufacturer ID
R2: Device ID
R3: Device Flags
HWQ $02 - Send message to hardware device
Software can send messages to a Bus Device by calling HWQ operation $02. This
will send a two-word message, consisting of the words in R1 and R2, to the
Hardware Device in Bus Slot R0. If there is no hardware device in this Bus Slot,
there will be no effect. If there is an active Hardware Device in this Bus Slot,
one of several results will occur:
* If the device can instantly respond to the message, it will acknowledge the
message by setting R0 to "MSG_ACK" ($0001). R1 and R2 may also be used as
return parameters, if required by the device.
* If the device requires time to respond to the message, it will acknowledge
the message by setting R0 to "MSG_WAIT" ($0002). When the device is ready
to respond to the message, it will raise a Hardware Interrupt.
* If the device requires access to main memory, the processor will be halted
while the device reads/writes to memory. Generally, the memory read will
be based on the contents of R1 and R2. Software can send more than two
parameters to a device by using R1 or R2 as a pointer to memory. When the
device has completed its operation, it will set R0 to "MSG_ACK" ($0001).
* If the device encounters an error while responding to the message, it will
acknowledge the message by setting R0 to "MSG_ERROR" ($FFFF). R1 and R2
will remain unchanged.
HWQ $03 - Get RAM/ROM amounts in R0-R3.
Software can query the YBUS for the total amount of attached RAM and ROM by
calling HWQ operation $03. After this operation, the total amount of RAM will
be set in R0 and R1, with the high 16-bits set in R1, and the total amount of
ROM will be set in R2 and R3, with the high 16-bits set in R3. If no RAM
exists, both R0 and R1 will be set to “NO_MEMORY” ($FFFF). If no rom exists,
both R2 and R3 will be set to “NO MEMORY” ($FFFF).
Indexes $80, $82, and $83 are described in 3.H..
=== 3.D. Interrupts ============================================================
An interrupt is a signal that indicates that an event requires immediate
attention. Interrupts can be triggered by a hardware device, by software using
the SWI opcode, or when the processor encounters a fault state. Each type of
interrupt is identified by an index from 0 to 15.
When the processor receives an interrupt, it gets the address of the interrupt
handler for the type of interrupt received from the 'interrupt vector table',
a list of 16 16-bit values located at address $0000 in the Interrupt Segment. It
the sets PC to this value, and begins executing the code at this address.
--- 3.D.1. THE INTERRUPT VECTOR TABLE ------------------------------------------
There are 16 interrupts in the Interrupt Vector Table. The software interrupt
is raised by the instruction SWI, and the Hardware Interrupt is raised by a
hardware that asserts an interrupt request. All other interrupts are raised
by the processor itself on specified error states. The 16 interrupts are:
Idx Name Description
$0 Reset Raised when the processor's RESET line is pulled high.
The processor will follow the boot sequence (See 3.G.).
$1 Clock Raised when the processor's Real Time Clock ticks. The tick
rate can be set by writing to the RTC register.
$2 DivZeroFault Raised when the processor executes a division or modulus
opcode where the operand containing the denominator is zero.
$3 DoubleFault Raised when the processor faults while attempting to access
an interrupt handler (See 3.D.6.).
$4 StackFault Raised when the processor executes a POP or PSH instruction
that would access an address outside of the stack segment.
$5 SegFault Raised when the processor attempts to read from or write to
an address within a Segment that has been protected from
these instructions.
The V and W status bits in PS describe the error.
The first 16-bit word on the Stack contains the memory
address that the processor attempted to access.
$6 UnprivFault Raised when the processor attempts to execute a privileged
opcode while in User mode.
$7 UndefFault Raised when the processor attempts to execute an UNDEFINED
opcode.
$8 RESERVED Not currently used, never raised.
$9 RESERVED Not currently used, never raised.
$A RESERVED Not currently used, never raised.
$B RESERVED Not currently used, never raised.
$C HWI A device on the Hardware Bus has requested an interrupt.
The first 16-bit word on the Stack contains the bus index of
the requesting device.
$D BusRefresh Raised when the hardware on the bus has changed. Note that
all hardware ids at this point may be invalidated.
$E DebugQuery Raised when the processor's DEBUG line is pulled high.
$F SWI Raised by the SWI opcode.
--- 3.D.2. HARDWARE INTERRUPTS -------------------------------------------------
A device on the CPU's hardware bus may request the CPU's attention by asserting
an interrupt request (IRQ). While the Q status bit in PS is clear and the H
status bit in PS is set, the processor checks for IRQs before executing each
opcode. If a hardware device is asserting an IRQ when the processor checks, the
processor will push a 16-bit word containing the bus index of the first device
on the bus that is asserting an IRQ onto the stack as part of the hardware
interrupt. This bus index must be pulled from the stack before RTI is executed!
Note that devices in lower index slots in the hardware bus always have
priority over devices in higher index slots.
--- 3.D.3. SOFTWARE INTERRUPTS -------------------------------------------------
An interrupt may also be triggered by the SWI opcode. In this case, the
processor will raise the 'software interrupt' interrupt vector, and the code
at that interrupt must determine what function has been requested, based on the
contents of the registers.
Unlike hardware interrupts, software interrupts will be acknowledged
regardless of the status of the Q status bit
The H status bit only applies to hardware interrupts, and thus software
interrupts will be acknowledged by the CPU if the H status bit is clear.
--- 3.D.4. FAULT INTERRUPTS ----------------------------------------------------
For interrupts caused by an error condition, the U status bit in PS will be set
if the processor was in user mode when the fault occured, or clear if the
processor was in supervisor mode when the fault occured. Also, a 16-bit error
code will be pushed to the stack after PS and PC. This error code must be pulled
from the stack before RTI is executed!
The error code will be equal to the instruction word that caused the fault.
Interrupts designated as 'Faults' are:
- DivZeroFault ($02),
- DoubleFault ($03),
- StackFault ($04),
- SegFault ($05),
- UnPrivFault ($06), and
- UnDefFault ($07).
--- 3.D.5. SEGMENT FAULTS ------------------------------------------------------
When a segment fault is raised, the processor status bits V and W describe the
operation that caused the segment fault:
V W Segment Fault Type
0 0 Attempted access to segment that is not loaded. (P bit set)
0 1 Attempted write of write-protected memory.
1 0 Attempted access to address greater than the segment size.
1 1 UNDEFINED.
Note that writes to ROM memory will fail silently unless the MMU is enabled and
the write-protect bit is set, which will result in a segment fault with V = 0
and W = 1.
--- 3.D.6. FAULTS WHILE LOADING AN INTERRUPT HANDLER ---------------------------
It is possible that the processor may fault when attempting to load an interrupt
handler. This could happen if the interrupt segment is not present, or if the
interrupt vector address for a given interrupt is outside the size of the
interrupt segment. When this occurs, the processor will raise a DoubleFault
interrupt.
Note that because the DoubleFault interrupt will only occur when the processor
is already handling an interrupt, the U status bit in PC will always be clear,
regardless of whether the processor was in user mode when the original interrupt
occured.
If the processor fails to load the DoubleFault interrupt handler, it will enter
a "TripleFault" state and reset one clock cycle later. Note that "TripleFault" is
not an interrupt that can be handled by the programmer. There is no function to
recover from a TripleFault.
--- 3.D.7. THE INTERRUPT SEQUENCE ----------------------------------------------
When an interrupt is raised, the processor halts the current executing process.
It then executes the following sequence of operations:
1. Save the state of PS to a temporary register.
2. If this is Fault interrupt (See 3.D.4. for a list of fault interrupts):
If processor is in User mode, set the U status bit. If the
processor is in Supervisor mode, clear the U status bit.
3. Set the S and I status bits in PS. The processor is now in Supervisor
mode, and will read all instructions and immediate values from the
Interrupt Segment (IS), instead of the Code Segment (CS).
4. Push the saved PS to the Stack.
5. Push PC to the Stack.
6. If this is a hardware interrupt:
a. The Q status bit will be set. This blocks other hardware interrupts
from occurring while the current interrupt is being processed.
b. A 16-bit word containing the index of the device that raised the
interrupt is pushed to the Stack.
7. If this is a Segment Fault:
The V and W status bits are set as appropriate (See 3.D.5.).
8. If this is Fault interrupt (See 3.D.4. for a list of fault interrupts):
Push a 16-bit error code to the stack. The error code is equal to to the
instruction word that caused the Fault.
8. Set PC to IS[$0000 + (InterruptIndex * 2)].
9. Execution continues.
--- 3.D.8. RETURNING FROM AN INTERRUPT -----------------------------------------
When an interrupt handler ends, it should call RTI, which restores the values of
PS and PC from the stack. If an interrupt handler modifies a register or changes
the segment registers, it should save the state of the registers before doing
so, and restore the same before returning from the interrupt handler.
The RTI instruction follows this sequence:
1. Pop PC and PS from the Stack, restoring the value they had prior to the
interrupt.
2. Execution Continues.
=== 3.E. Addressing Modes ======================================================
Many instructions are register-only: they can take only data loaded in registers
as their source. ALU (including LOD and STO) and JMP/JSR instructions can access
memory using these six addressing modes:
Addressing Mode Syntax Value is...
Immediate $1234 Value of Next Word
Absolute [$1234] Mem[Next Word]
Register Rx Value of Register
Indirect [Rx] Mem[R]
Indirect Offset [Rx,$1234] Mem[R + Next Word]
Indirect Indexed [Rx,Rx] Mem[R+R] At least one of these registers must be
R4, R5, R6, or R7.
--- 3.E.1. IMMEDIATE VALUES ARE READ FROM THE CODE SEGMENT ---------------------
All immediate values are read from memory in the code segment (CS), and follow
immediately after the opcode describing the instruction referencing the code
segment.
--- 3.E.2. REFERENCING THE DATA AND EXTENDED DATA SEGMENT ----------------------
Normally, any address references to memory (with Absolute, Indirect, Indirect
Offset, or Indirect Indexed) will come from the address of memory within the
data segment (DS). This is implicit to the indirect addressing modes, but can
also be specified. The reference assembler syntax for accessing the DS is:
LOD R0, [r1] OR LOD R0, DS[r1]
These addressing modes also allow references to the extra data segment (ES).
This must be made explicit. The reference assembler syntax for accessing ES is:
LOD R0, ES[r1]
--- 3.E.3. BIT WIDTH OF INSTRUCTIONS -------------------------------------------
ALU instructions are by default 16 bits wide. Thus, all LOD instructions take
16 bits from memory, and ADD instructions operate on all 16 bits of memory.
There is an alternate 8-bit mode for ALU instructions (ADD, STO, LOD, etc.):
LOD.8 [$8000]
STO.8 [R4]
These alternate instructions will operate on only the lower 8-bits of a
register. 8-bit LOD instructions will load a single byte into memory from a
register. The high 8 bits of the destination register will be cleared. 8-bit STO
instructions will store the low 8 bits from the source register. If the
destination of the instruction is memory, only a single byte is stored in
memory. If the destination is another register, the lower 8 bits of memory are
stored, and the high 8 bits of the destination register are cleared.
=== 3.F. Memory Management =====================================================
Because the processor has a 16-bit logical address space, it can only address
$10000 (65,536) bytes of linear address space at a time. This limited address
space is augmented by the processor's integrated memory management unit (MMU)
that, when enabled, implements segmented memory and virtual address translation.
--- 3.F.1. THE SEGMENT REGISTERS -----------------------------------------------
The processor's Memory Management Unit allows access to segmented memory. There
are four segments available for access during normal program operation (the code
segment (CS), data segment and extra data segment (DS and ES), and the stack
segment (SS)), and a fifth segment (the Interrupt Segment (IS)) used as the code
segment when the processor is in Interrupt mode ('I' bit set in PS) and the
Memory Management Unit is enabled ('M' bit set in PS).
Each segment register is 32 bits in size:
$03 $02 $01 $00
FEDC BA98 7654 3210 FEDC BA98 7654 3210
ssss ssss AWPD bbbb bbbb bbbb bbbb bbbb
D - Hardware device flag:
0: Accesses to this segment will come from main memory.
1: Accesses to this segment will come from the hardware device at
the index equal to the upper four 'b' bits (0-15). Where these bits
are 0000, the accesses will come from the computer's onboard ROM
chip.
W - Write protection flag:
0: Write instructions to this segment will succeed.
1: Write-protected. Writing to this segment will fail and cause a
segment fault interrupt.
P - Not present flag:
If this bit is set, access to this segment will cause a segment fault.
A - Accessed flag:
This bit is set every time this segment is written to.
s - These bits determine the size of the segment. This value is left shifted
by 8 and incremented by 256 for a range of 256 - 2^16.
Examples:
s: $00 size = ($00 << 8 + $100); $00100 or 256 bytes
s: $7F size = ($7f << 8 + $100); $08000 or 32,768 bytes
s: $ff size = ($ff << 8 + $100); $10000 or 65,536 bytes