Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 21:41 20 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : EDUC-8 Microcomputer - glass version

Author Message
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1116
Posted: 07:23am 15 Apr 2022
Copy link to clipboard 
Print this post

Around August 1974, Electronics Australia started a monthly series on the design and construction of a simple microcomputer called the EDUC-8. It was conceived and designed from the ground up by then then Editor, Jim Rowe.

Loosely based on the instruction set of the DEC PDP-8, it was one of the first hobby microcomputers. Built entirely from 74xx series of TTL chips, it was a fully functioning microcomputer. My brother and I built one and last I heard from him, it is still operational.

In an attempt to re-live some of those days, I have created a "glass" version of EDUC-8 - that is, a simulator written in MMB4W (it should also run on a CMM2 but untested at this time).

For anyone interested, a copy of the code is included below. It is still a work-in-progress as I have not implemented any of the IOT instructions. If anyone wants to get more deeply into the program, you will need to obtain a copy of the full manual "EDUC-8 An Educational Microcomputer" by Jamison Rowe. It may no longer be in print but I could perhaps copy parts if anyone is interested (I will try to contact Jim Rowe or EA/Silicon Chip to determine the status of the book).

To actually get something out of the program, the following is a taster!
Start by installing the latest MMB4W and run.

you should see the MMBasic sign-on prompt.

Enter the following at the prompt:-

>OPTION KEYBOARD US
>OPTION DEFAULT FONT 2
>OPTION DEFAULT PATH "C:\Users\yourloginname\Desktop"
>OPTION LIST

... should now give you ...

OPTION Default mode 9,1024x768
OPTION Default Font 2,1
OPTION Default path C:\Users\yourusername\Desktop
OPTION Keyboard US

Current display 38,85

.. so now

>load "educ-8-5a.bas"

>run

.. and you should see an Educ-8 front panel with all switches off - start by entering an initial load address using the mouse to operate the relavent switches.-

000 LOAD

enter the following in the switches, clicking DEPOSIT after each new instruction
(see page 47 of EDUC-8 book)

710  DEPOSIT
110  DEPOSIT
111 DEPOSIT
312 DEPOSIT
500 DEPOSIT
721 DEPOSIT
.. now for the data
010  LOAD
002 DEPOSIT
004 DEPOSIT


000 LOAD

.. clicking EXAMINE will step through the memory

.. clicking RUN will step through the program, which is

START:    CLA              710  ' clear accumulator
         TAD A            110  ' two's comp add loc &O010 to AC
         TAD B            111  ' two's comp add loc &O011 to AC
         DCA C            312  ' store result in &O012 and clear AC
         JMP START        500  ' jump back to loc &O000
         HLT              721  ' halt

A:           002
B:           004
C:           should end up with 006 in here

To exit the program, any keyboard key will drop you back to the MMB4W prompt. If the program is running and you click outside the MMB4W widow and then try to return to the running program it will crash unless you click on the MMB4W header first (I use the GUI AREA command for switches hence the out of bounds error).

Single/Continuous and Slo/Fst work however none of the IOT instructions have been implemented yet.

Enjoy,
Doug.


' Educ-8 Microcomputer - simulation in MMB4W 5.07.03b8
' Original hardware and concept: Copyright Jim Rowe, Electronics Australia
' Adaption for MMBasic: Copyright Doug Pankhurst
' MMBasic: Copyright Geoff Graham, Peter Mather
Dim version$ = "Version: 5a Created: 15:09 16/4/22" '
Option explicit

' Educ-8 registers
' - all utilize the low order 8 bits only
Dim PCReg% ' Program Counter
Dim MAReg% ' Memory address register 8 bits
Dim MBReg% ' Memory buffer register 8 bits
Dim INReg% ' Instruction register
Dim ACReg% ' Accumulator 8 bits
Dim OCReg% ' Operation code register - bits 5,6,7
Dim OAReg% ' Operand address register bits 0 - 3
DIM PGReg% ' page address reg high order 4 bits of MA
'----------------------------------------------------------------
' Memory RAM
Dim RAM_Mem%(128)  ' longstring array of 1024 bytes used as RAM
' - use LONGSTRING SETBYTE nbr%,data to store value from 0 to 255
' - use LGETBYTE nbr% to return value from longstring
'-------------------
' State flags
Dim LoadFlag%     = 0 '
Dim DepositFlag%  = 0  '
Dim ExamineFlag%  = 0 '
Dim FetchFlag%    = 0  '
Dim DeferFlag%    = 0  '
Dim ExecuteFlag%  = 0  '
Dim RunFlag%      = 0  ' Run/halt flag - 1 = run, 0 = halt
DIM SingContFlag% = 0  ' single or cont - 0=single=halt after each inst
DIM SloFstFlag%   = 0
DIM IAFlag%       = 0  ' direct/indirect address flag
'--------------------------------------------------------------------
' IOT device flags and buffers
' Note: The Educ-8 is the DTE, whatever device is connected is the DCE
DIm D0CTS% ' clear to send from input device 0
DIM D1CTS% '                          device 1
DIM D0IPBuf% ' input buffer device 0
DIM D1IPBuf%
DIM D0RTS% ' ready to send to output device 0
DIM D1RTS%
DIM D0OPBuf ' output buffer for device 0
DIM D1OPBuf%
' actual pin assignments for CMM2/Picomite - define as needed
' device 0
CONST D0CTS_Pin     = 1   ' input - flag from device that it is ready to receive
CONST D0RTS_Pin     = 2   ' output - flag to device EDUC-8 is ready to send
CONST D0DataIn_Pin  = 3' input - receive port
CONST D0DataOut_Pin = 4' output - send port
' device 1
CONST D1CTS_Pin     = 5
CONST D1RTS_Pin     = 6
CONST D1DataIn_Pin  = 7
CONST D1DataOut_Pin = 8
'------------------------------------------------------------------------
' Arithmetic flags
Dim CarryFlag%    = 0 ' accumulator carry flag - 1 = carry
Dim ZeroFlag%     = 0 ' accumulator zero flag - 1 = zero

' misc
Dim B4Mask% = &B1111     ' mask direct address bits 0-3
Dim B8Mask% = &B11111111 ' mask low order 8 bits
Dim B15Mask% = &B111111111111111 ' mask low order 15 bits
Dim OCMask% = &B11100000 ' mask in opcode bits 5,6,7
DIM OAMask% = &B1111 ' mask in operand address bits
DIM PGMask% = &B11110000 ' mask in Page address in MBReg
' note these bits are also used for different purposes
' in operate and IOT microinstructions

Dim DataSw% 'low order 8 bits equate to data switch 0 thru 7
Dim Sw_Reg%  ' low order 15 bits equate to switches left to right

Dim i,j  'general purpose counters
'--------------------------------------
' front panel 15 switches, 0 thru 14
' data switches d0 thru d7 - 0 = off, any other value = on
Dim s7%,s6%,s5%,s4%,s3%,s2%,s1%,s0%
' control switches
Dim s8%  ' load address - mom - 0 = off, 1 = load address
Dim s9%  ' deposit - mom - 0 = off, 1 = deposit data
Dim s10% ' examine - mom - 0 = off, 1 = examine memory
Dim s11% ' run - mom - 0 = off, 1 = run
Dim s12% ' halt - mom - 0 = off, 1 = halt
Dim s13% ' single/continuous - 1 = single, 0 = continuous
Dim s14% ' slow/fast - 0 = slow, 1 = fast
Dim sw_num% ' switch number 0 thru 14, right to left
'---------------------------------------
' Static switch display shape parameters
' - x offset from top left of screen for 15 switches
'Dim sw_xtl%(14) = (20,60,100,140,180,220,260,300,420,460,500,620,660,700,740)
Dim sw_xtl%(14) = (300,260,220,180,140,100,60,20,420,460,500,620,660,700,740)
' y offset from top left of screen
Dim sw_ytl% = 220
'............
' switches - actual switch x and y co-ordinates
' on/off switches - off position
Dim xbar_onf% = 7    ' on and off bar x offset
Dim ybar_of% = 223   ' off bar y pos (absolute)
Dim w_onf_bar% = 24  ' on and off bar width
Dim h_onf_bar% = 3   ' on and off bar height
' polygon x co-ordinates  - starts top left, add per switch
Dim dsx_of%(3) = (6,32,37,1)
' polygon y co-ordinates (absolute) - starts top left
Dim dsy_of%(3) = (222,222,245,245)

' on/off switches - on position for on/off and momentary switches
Dim xbar_on% = 7    ' on bar x pos
Dim ybar_on% = 264  ' on bar y pos (abs)
' polygon x co-ordinates  - starts top left, add per switch
Dim mdsx_on%(3) = (1,37,32,6)    ' polygon x positions - starts top left
' polygon y co-ordinates (absolute) - starts top left
Dim mdsy_on%(3) = (245,245,268,268)  ' polygon x positions - starts top left

' momentary switches - off position
Dim mxbar_of% = 5
Dim mybar_of% = 245
Dim w_mbar_of% = 28
Dim h_mbar_of% = 4
' polygon x co-ordinates  - starts top left, add per switch
Dim msx_of%(5) = (1,37,34,34,4,4)
' polygon y co-ordinates  - starts top left, add per switch
Dim msy_of%(5) = (240,240,246,249,249,246)

' momentary switches on position
' - same as for on/off switches
'------------------------------
' arrays to hold static switch parameters
Dim stype%(14) = (0,0,0,0,0,0,0,0,1,1,1,1,1,0,0) ' 0=on/off, 1=mom
Dim scol(14)
' pre-define switch colours
For i = 0 to 7  ' data switches D7 thru D0
 scol(i) = rgb(130,130,150)
Next i
scol(8) = rgb(0,0,250)      ' Load
scol(9) = rgb(250,0,250)    ' Deposit
scol(10) = rgb(130,160,130) ' Examine
scol(11) = rgb(0,250,0)     ' Run
scol(12) = rgb(250,0,0)     ' Halt
scol(13) = rgb(250,150,150) ' Single/Continuous
scol(14) = rgb(150,250,250) ' Slow/Fast

' per switch variables
Dim sw_col    ' switch colour
Dim sw_type%  ' switch type - 0 = on/off, 1 = momentary
Dim sw_stat%  ' switch status - 0 = off, 1 = on (operated)
'----------------------------
' GUI setup
' constants for area ctrls - equate to bits(-1) in SwReg%
CONST SD7 = 8 'SwReg% bit 7
CONST SD6 = 7
CONST SD5 = 6
CONST SD4 = 5
CONST SD3 = 4
CONST SD2 = 3
CONST SD1 = 2
CONST SD0 = 1 ' SwReg% bit 0
CONST SLoad   = 9  'SwReg% bit 8
CONST SDep    = 10
CONST SExam   = 11
CONST SRun    = 12
CONST SHalt   = 13
CONST SSinCon = 14
CONST SFstSlo = 15 ' SwReg% bit 14

'--------------------------------------
' pre set some registers for initialise
PCReg% = 0 ' program counter
MAReg% = 0 ' memory addr register
MBReg% = 0 ' memory buffer register
ACReg% = 0 ' accumulator
PGReg% = 0 ' page register
INReg% = 0 ' instruction register

' preset some switch parameters
Sw_Reg% = &b000000000000000
'.........

' Start of main program
INITIALISE:
Init_Display ' draw all static user interface

' GUI area defines for mouse click on switches
' - must be after initialise
GUI Area SD7,20,220,38,50
GUI Area SD6,60,220,338,350
GUI Area SD5,100,220,38,50
GUI Area SD4,140,220,38,50
GUI Area SD3,180,220,38,50
GUI Area SD2,220,220,38,50
GUI Area SD1,260,220,38,50
GUI Area SD0,300,220,38,50
GUI Area SLoad,420,220,38,50
GUI Area SDep,460,220,38,50
GUI Area SExam,500,220,38,50
GUI Area SRun,620,220,38,50
GUI Area SHalt,660,220,38,50
GUI Area SSinCon,700,220,38,50
GUI Area SFstSlo,740,220,38,50
GUI Interrupt M_ClkDn,M_ClkUp

MAIN:
' start of state machine
RunFlag% = 0

Do while inkey$ = ""
 ' main program loop, broken out by Halt instruction, Halt key, or Sing/Cont = Sing
 Do While RunFlag% = 1
text 0,340,"Enter run loop"
   Fetch        ' get instruction pointed to by PCReg
   If SloFstFlag% = 0 Then
     Pause 500
   Else
'     Pause 50
   Endif
   ExecuteInst  ' execute it
   If SloFstFlag% = 0 Then
     Pause 500
   Else
'      Pause 50
   Endif
   If (SingContFlag% = 0) Then
     RunFlag% = 0
   Endif
 Text 0,340,"Thru main loop"
 LOOP

 If LoadFlag% then
   ACReg% = 0  ' for clean start
   LoadAddr
   Draw_Sw (sw_num%)
   Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
   ClearBit (Sw_Reg%,8)
   LoadFlag% = 0
 Endif

 If DepositFlag% then
   Deposit
   Draw_Sw (sw_num%)
   Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
   PCReg% = PCReg% + 1 ' now pointing to next mem location
   ClearBit (Sw_Reg%,9)
   DepositFlag% = 0

 Endif

 If ExamineFlag% then
   Examine
   Draw_Sw (sw_num%)
   Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
   Draw_OCLEDs (OCReg%)
   PCReg% = PCReg% + 1 ' now pointing to next mem location
   ClearBit (Sw_Reg%,10)
   ExamineFlag% = 0
 Endif
Loop

'debug
Text 0,360,version$ + "End program"
print
End

'-------------------------------------------------
' Operational subs and functions
Sub Fetch
 FetchFlag% = 1
 ExecuteFlag% = 0
 MAReg% = PCReg% AND B8Mask%
 PGReg% = PCReg% AND PGMask%
 INReg% = LGETBYTE (RAM_Mem%(),PCReg%)
 MBReg% = LGETBYTE (RAM_Mem%(),MAReg%)
 OCReg% = MBReg% AND OCMask% ' opcode bits 5,6,7
 OAReg% = MBReg% AND OAMask% ' lo order 4 bits - mem addr of operand
 PCReg% = (PCReg% + 1) AND B8Mask%
'  Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
'  Draw_OCLEDs (OCReg%)
 Draw_SFlags
End Sub

SUB ExecuteInst
 Local opcode%
 FetchFlag% = 0
 ExecuteFlag% = 1
 opcode% = OCReg% >> 5 ' move OC to lo 3 bits
 If opcode% < 6 then
   IAFlag% = GetBit%(MBReg%,4) ' indirect address flag
 endif
 Select Case opcode%
 ' codes 0 thru 5 and memory reference instructions
   Case 0
     Do_AND
   Case 1
     Do_TAD
   Case 2
     Do_ISZ
   Case 3
     Do_DCA
   Case 4
     Do_JMS
   Case 5
     Do_JMP
   ' operate microinstructions  
   Case 6    ' now further decode operate microinstructions
     Do_OPM
   ' I/O microinstructions  
   Case 7    'now further decode IOT microinstructions
     Do_IOT  ' IOT microinstructionsOCReg% =
 end select
 Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
 Draw_OCLEDs (OCReg%)
 Draw_SFlags
 If SingContFlag% = 0 then
   RunFlag% = 0
 Endif
end sub

' memory reference instructions
' enter with
Sub Do_AND
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get data from direct address location
 If IAFlag%  = 1 then ' indirect address, get address pointed to lo order 4 bits
   MAReg% = MBReg%  ' load indirect address into MAReg
   MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' then get indirect data
 endif    ' direct address - just use low order 4 bits
 ACReg% = B8Mask% AND (ACReg% AND MBReg%)
 If ACReg% = 0 Then
   ZeroFlag% = 0
 Else
   ZeroFlag% = 1
 Endif
 CarryFlag% = 0
End Sub

Sub Do_TAD
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get data from direct address location
 If IAFlag%  = 1 then ' indirect address, get address pointed to lo order 4 bits
   MAReg% = MBReg%  ' load indirect address into MAReg
   MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' then get indirect data
 endif    ' direct address - just use low order 4 bits
 ACReg% = ACReg% + MBReg%
 If (ACReg% AND &Hffffffffffffff00) <> 0 then
   CarryFlag% = 1
 Else
   CarryFlag% = 0
 Endif
END SUB

SUB Do_ISZ ' increment and skip if zero
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get data from direct address location
 If IAFlag% = 1 then ' indirect address, get address pointed to by lo order 4 bits
   MAReg% = MBReg%  ' load indirect address into MAReg
   MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' then get indirect data
 endif    ' direct address - just use low order 4 bits
 ACReg% = MBReg% ' get data from mem, inc and store back
 ACReg% = ACReg% + 1
 MBReg% = ACReg% '
 Longstring SETBYTE RAM_Mem%(),MAReg%,MBReg%
 If (B8Mask% AND ACReg%) = 0 Then
   ZeroFlag% = 0
   CarryFlag% = 1
 Else
   ZeroFlag% = 1
   PCReg% = PCReg% + 1 ' skip next instruction
   CarryFlag% = 0
 Endif
END SUB

Sub Do_DCA ' deposit and clear AC
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get data from direct address location
 If IAFlag% = 1 then ' indirect address, get address pointed to by lo order 4 bits
   MAReg% = MBReg%  ' load indirect address into MAReg
   MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' then get indirect data
 endif    ' direct address - just use low order 4 bits
 Longstring SETBYTE RAM_Mem%(),MAReg%,ACReg%
 ACReg% = 0
 CarryFlag% = 0
 ZeroFlag% = 0
END SUB

SUB Do_JMS ' jump to subroutine
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 MBReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get indirect address
 If IAFlag% = 1 then ' indirect address, get address pointed to by lo order 4 bits
   MAReg% = MBReg%  ' load indirect address into MAReg
 endif    ' direct address - just use low order 4 bits
 Longstring SETBYTE RAM_Mem%(),MAReg%,PCReg% ' store return addr in 1st sub location
 PCReg% = MAReg% + 1
END SUB

SUB Do_JMP
 MAReg% = PGReg% OR OAReg% ' MAReg now 8 bit pointer to direct address
 If IAFlag%  = 1 then ' indirect address, get address pointed to lo order 4 bits
   MAReg% = LGETBYTE(RAM_Mem%(),MAReg%) ' get data from indirect address
 endif    ' direct address - just use low order 4 bits
 PCReg% = MAReg%  ' target address
END SUB
' end of memory instructions
'--------------------------------
' operate microinstructions - opcodes 7xx
SUB Do_OPM
 Local i%,tmpb7%,tmpb0%
 Local opcode%
 opcode% = MBReg% AND &B11111' get OC lo 5 bits ( the xx part)
 Select Case opcode%
   Case 0  ' NOP
     ' - do nothing - fall into next instruction
   Case 1  'IAC - inc AC by 1
     ACReg% = ACReg% + 1
     If (ACReg% AND &Hffffffffffffff00) <> 0 then
       CarryFlag% = 1
       ACReg% = ACReg% AND B8Mask%  ' back to lo order 8 bits
     Else
       CarryFlag% = 0
     Endif    
   Case 2  ' RAL - rotate AC 1 bit left, b7 -> b0,b1-b6 <- 1 place
     tmp_b7% = GetBit%(ACReg%,7)
     ACReg% = ACReg% << 1
     If tmp_b7% = 0 then
       ClearBit(ACReg%,0)
     else
       SetBit(ACReg%,0)
     Endif
     If (ACReg% AND &Hffffffffffffff00) <> 0 then
       CarryFlag% = 1
       ACReg% = ACReg% AND B8Mask%  ' back to lo order 8 bits
     Else
       CarryFlag% = 0
     Endif    
   
   Case 3  ' NOP
     ' - do nothing - fall into next instruction
   Case 4  ' CMA - invert all bits in AC
     ACReg% = B8Mask% AND (INV(ACReg%))
     If ACReg% = 0 then
       ZeroFlag% = 1
     Else
       ZeroFlag% = 0
     Endif    
   
   Case 5  ' CMA then IAC - comliment then increment AC - form 2s comp
     ' do CMA first
     ACReg% = B8Mask% AND (INV(ACReg%))
     If ACReg% = 0 then
       ZeroFlag% = 1
     Else
       ZeroFlag% = 0
     Endif
     ' then IAC
     ACReg% = ACReg% + 1
     If (ACReg% AND &Hffffffffffffff00) <> 0 then
       CarryFlag% = 1
       ACReg% = ACReg% AND B8Mask%  ' back to lo order 8 bits
     Else
       CarryFlag% = 0
     Endif  
   Case 6  ' NOP
     ' - do nothing - fall into next instruction    
   Case 7  ' NOP
     ' - do nothing - fall into next instruction    
   Case 8  ' CLA - clear AC to 0
     ACReg% = 0
     ZeroFlag% = 1
   Case 9  '  CLA then IAC - clear AC then add 1 - ie. set AC = 1
     ' first CLA
     ACReg% = 0
     ' then IAC
     ACReg% = ACReg% + 1
     CarryFlag% = 0
     ZeroFlag% = 0
   Case 10  ' NOP
     ' - do nothing - fall into next instruction    
   case 11  ' NOP
     ' - do nothing - fall into next instruction    
   Case 12  ' CLA then CMA - clear AC then invert AC  - ie. set AC = -1
     ' first CLA - AC = 0
     ACReg% = 0
     ' then CMA - AC now all 1s - = -1
     ACReg% = B8Mask% AND (INV(ACReg%))
     CarryFlag% = 0
     ZeroFlag% = 0
   Case 13  ' NOP
     ' - do nothing - fall into next instruction    
   Case 14  ' NOP
     ' - do nothing - fall into next instruction    
   Case 15  ' NOP
     ' - do nothing - fall into next instruction    
   Case 16  '' NOP
     ' - do nothing
   Case 17 ' HLT
     RunFlag% = 0
     ClearBit (Sw_Reg%,12)
     ClearBit (Sw_Reg%,11)
   Case 18  ' RAR - rotate AC 1 bit right
     tmp_b0% = GetBit%(ACReg%,0)
     ACReg% = B8Mask% AND (ACReg% >> 1)
     If tmp_b0% = 1 then
       SetBit (ACReg%,7)
     Else
       ClearBit (ACReg%,7)
     Endif
   Case 19  ' NOP
     ' - do nothing - fall into next instruction    
   Case 20  ' SMA - skip on minus AC - ie. if AC a neg num (bit 7 = 1), skip next inst
     If GetBit%(ACReg%,7) = 1 Then
       PCReg% = PCReg% + 1
     Endif    
   Case 21  ' NOP
     ' - do nothing - fall into next instruction    
   Case 22  ' NOP
     ' - do nothing - fall into next instruction    
   Case 23  ' NOP
     ' - do nothing - fall into next instruction    
   Case 24  ' SZA - skip on zero AC - ie. if AC = 0, skip next instruction
     If ACReg% = 0 then
       ZeroFlag% = 0
       PCReg% = PCReg% + 1
     endif
   Case 25  ' NOP
     ' - do nothing - fall into next instruction    
   Case 26  ' NOP
     ' - do nothing - fall into next instruction    
   Case 27  ' NOP
     ' - do nothing - fall into next instruction    
   Case 28  ' SZA then SMA - skip next instruction if AC is minus or zero
     If (GetBit%(ACReg%,7) = 1) OR (ACReg% = 0) Then
       PCReg% = PCReg% + 1
     Endif    
   Case 29  ' NOP
     ' - do nothing - fall into next instruction    
   Case 30  ' NOP
     ' - do nothing - fall into next instruction    
   case 31  ' NOP
     ' - do nothing - fall into next instruction    
 End Select
END SUB

SUB Do_IOT ' input/output instructions - 6xx
 Local SkipFlag%,ShiftFlag%,ResDevFlag%,Device%,DevIO%
 Local opcode%
 SkipFlag% = GetBit%(MBReg%,0)
 ShiftFlag% = GetBit%(MBReg%,1)
 ResDevFlag% = GetBit%(MBReg%,2)
 Device% = GetBit%(MBReg%,3)
 DevIO% = GetBit%(MBReg%,4)
 opcode% = MBReg% AND &B11111' get OC lo 5 bits ( the xx part)
 
 Select Case opcode%
   Case 1  ' &O01 SKF device 0
     
   CASE 9  ' &O11 SKF device 1
   
   CASE 17 ' &O21 SDF device 0
   
   CASE 25 ' &O31 SDF device 1
   
   CASE 2  ' &O02 KRS device 0
   
   CASE 10 ' &O12 KRS device 1
   
   CASE 18 ' &O22 LDS device 0
   
   CASE 26 ' &O32 LDS device 1
   
   CASE 4  ' &O04 RKF device 0
   
   CASE 12 ' &O14 RKF device 1
   
   CASE 20 ' &O24 RDF device 0
   
   CASE 28 ' &O34 RDF device 1

   CASE 6  ' &O06 KRB (KRS + RKF) device 0
   
   CASE 14 ' &O16 KRB (KRS + RKF) device 1
   
   CASE 22 ' &O26 LDB (LDS + RDF) device 0
   
   CASE 30 ' &O36 LDB (LDS + RDF) device 1
   
 End select
END SUB


Sub LoadAddr
 Local i%
 PCReg% = Sw_Reg% AND B8Mask%
 MAReg% = PCReg%
 MBReg% = 0
End Sub

Sub Deposit
 Local t_byte$
 MAReg% = PCReg% AND B8Mask%
 MBReg% = Sw_Reg% AND B8Mask%
 OCReg% = MBReg% AND OCMask%
 Longstring Setbyte RAM_Mem%(),MAReg%,MBReg%
End Sub

Sub Examine
 Local i%
 MAReg% = PCReg% AND B8Mask%
 MBReg% = LGETBYTE (RAM_Mem%(),MAReg%)
 INReg% = MBReg%
 OCReg% = MBReg% AND OCMask%
End Sub
 
Sub SetClearFlags
 Local i%
End Sub

'-------------------------------------------------
' Interrupts
Sub M_ClkDn
 local a
 sw_num% = Mouse(ref)-1 ' turn ctrl number to bit number
 ToggleBit (Sw_Reg%,sw_num%)
 Select Case sw_num%
   CASE 14   ' Slow/FGetBit%1
     SloFstFlag% = GetBit%(Sw_Reg%,sw_num%)
   CASE 13   ' single/continuous switch
     SingContFlag% = GetBit%(Sw_Reg%,sw_num%)
   Case 12   ' Halt switch
     RunFlag% = 0
     ClearBit (Sw_Reg%,sw_num%) ' halt bit
     ClearBit (Sw_Reg%,11) ' also run bit
   Case 11   ' Run switch
     RunFlag% = GetBit%(Sw_Reg%,sw_num%)
   Case 10   ' Examine switch
     ExamineFlag% = GetBit%(Sw_Reg%,sw_num%)
   Case 9    ' Deposit switch
     DepositFlag% = GetBit%(Sw_Reg%,sw_num%)
   Case 8    ' Load switch
     LoadFlag% = GetBit%(Sw_Reg%,sw_num%)
 End Select
 Draw_Sw (sw_num%)
End Sub

Sub M_ClkUp
 sw_num% = Mouse(LASTref)-1 ' turn ctrl number to bit number
 If (sw_num% > 7 ) and (sw_num% < 13) then
   pause 300
   ClearBit (Sw_Reg%,sw_num%)
   Draw_Sw (sw_num%)
 Endif
End Sub
'-------------------------------------------------
'Subroutines

' Initialise display - only called once at startup
'  but safer here and uses local variables
Sub Init_Display
 Local i,j,x,d 'counting variables
 Local SwBitMsk%
 CLS
 Colour RGB(black),RGB(white)
 RBox 0,0,799,300,,RGB(white),RGB(white) ' face
 Text 20,0,"EA EDUC-8+ MICROCOMPUTER",,4,2
 Box  20,30,318,150,,RGB(80,80,80),RGB(80,80,80)
 Font 1
 Text 342,38,"PC"
 Text 342,68,"MA"
 Text 342,98,"MB"
 Text 342,128,"AC"
 text 342,158,"IN"
 Box  420,30,80,150,,RGB(80,80,80),RGB(80,80,80)
 Text 390,38,"AND"
 Text 390,68,"TAD"
 Text 390,98,"ISZ"
 Text 390,128,"DCA"
 TEXT 376,158,"CARRY"
 Text 503,38,"OPR"
 Text 503,68,"IOT"
 Text 503,98,"JMP"
 Text 503,128,"JMS"
 TEXT 503,158,"ZERO"
 Box  700,30,80,150,,RGB(80,80,80),RGB(80,80,80)
 Text 670,38,"RUN"
 Text 656,68,"FETCH"
 Text 656,98,"DEFER"
 Text 663,128,"EXEC"
 ' now switch labels
 Text 422,193,"LOAD"
'  Text 422,206,"ADDR"
 Text 468,193,"DEP"
 Text 502,193,"EXAM"
 Text 626,193,"RUN"
 Text 666,193,"HALT"
 Text 706,193,"SING"
 Text 746,193,"SLOW"
 Text 706,206,"CONT"
 Text 746,206,"FAST"

 ' draw bit numbers
 x = 35
 For d = 7 To 0 Step -1
   Text x,192,Str$(d)
     x = x + 40
 Next d

 ' draw opcode lines
 Line 20,212,137,212,4,RGB(black)
 Line 140,212,217,212,4,RGB(black)  
 Line 220,212,338,212,4,RGB(black)

 'draw momentary action indicators
 Triangle 421,206,457,206,439,216,RGB(black),RGB(black)
 Triangle 461,206,497,206,479,216,RGB(black),RGB(black)
 Triangle 501,206,536,206,518,216,RGB(black),RGB(black)
 Triangle 620,206,656,206,638,216,RGB(black),RGB(black)
 Triangle 661,206,694,206,677,216,RGB(black),RGB(black)

 ' draw switches
 Sw_Reg% = Sw_Reg% AND B15Mask%

 For sw_num% = 0 to 14
   Draw_Sw sw_num%
 Next sw_num%

 ' draw LEDs
 Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%)
 Draw_OCLEDs (OCReg%)
 Draw_SFlags

End Sub
'----------------------------
' Subroutine to draw switches
Sub Draw_Sw sw_num%
 Local sxtl%       'top left x pos of switch sw_num%
 Local w_sb% = 38 ' width of switch box
 Local h_sb% = 50 ' height of switch box
 Local sx%(3) ' array holding 4 polygon points for switch when off
 Local mx%(5) ' array holding 6 polygon points for mom sw when off
 Local mdx%(3)' array holding 4 polygon points for all switches when on
 Local x
 Local SwBit% = &B000000000000001
 Local SwBitMsk% = &B100000000000000
 ' set per switch parameters
 sw_type% = stype%(sw_num%)
 sw_col = scol(sw_num%)
 sw_stat% = Sw_Reg% AND (SwBit% << sw_num%)
' calculate switch x top left position based on switch number
 sxtl% = sw_xtl%(sw_num%)
' blank out switch
 box sxtl%,sw_ytl%,w_sb%,h_sb%,,rgb(black),rgb(black)
 ' now paint actual switch
 if sw_stat% = 0 then ' is in the off position
   if sw_type% = 0 then  'is an on/off style switch
     for x = 0 to 3 ' build actual polygon points - on/off sw = off
       sx%(x) = sw_xtl%(sw_num%) + dsx_of%(x)
     next x
     polygon 4,sx%(),dsy_of%(),sw_col,sw_col
     box sxtl%+xbar_onf%,ybar_of%,w_onf_bar%,h_onf_bar%,,rgb(white),rgb(white)
   else  ' is a momentary style switch, then special off position
     for x = 0 to 5 ' build actual polygon points - mom sw = off
       mx%(x) = sw_xtl%(sw_num%) + msx_of%(x)
     next x
     polygon 6,mx%(),msy_of%(),sw_col,sw_col
     box sxtl%+mxbar_of%,mybar_of%,w_mbar_of%,h_mbar_of%,,rgb(white),rgb(white)
   endif
 else ' is in the on position - same for on/off and momentary
     for x = 0 to 3' build actual polygon points - both types = on
       mdx%(x) = sw_xtl%(sw_num%) + mdsx_on%(x)
     next x
   polygon 4,mdx%(),mdsy_on%(),sw_col,sw_col
   box sxtl%+xbar_onf%,ybar_on%,w_onf_bar%,h_onf_bar%,,rgb(white),rgb(white)
 endif
End Sub
'---------------------------
' Draw register LEDs
Sub Draw_RegLEDs (PCReg%,MAReg%,MBReg%,ACReg%,INReg%)
 Local pc_temp%,ma_temp%,mb_temp%,ac_temp%,in_temp%
 Local x%,y%,i%
 x% = 40
 y% = 43
 pc_temp% = PCReg% AND B8Mask%
 ma_temp% = MAReg% AND B8Mask%
 mb_temp% = MBReg% AND B8Mask%
 ac_temp% = ACReg% AND B8Mask%
 in_temp% = INReg% AND B8Mask%
 For i% = 7 To 0 Step -1
   If GetBit%(pc_temp%,i%) then
     Circle x%,y%,6,1,,RGB(black),RGB(red)
   Else
     Circle x%,y%,6,1,,RGB(black),RGB(80,80,80)
   EndIf
   If GetBit%(ma_temp%,i%) then
     Circle x%,y%+30,6,1,,RGB(black),RGB(red)
   Else
     Circle x%,y%+30,6,1,,RGB(black),RGB(80,80,80)
   EndIf
   If GetBit%(mb_temp%,i%) Then
     Circle x%,y%+60,6,1,,RGB(black),RGB(red)
   Else
     Circle x%,y%+60,6,1,,RGB(black),RGB(80,80,80)
   EndIf
   If GetBit%(ac_temp%,i%) Then
     Circle x%,y%+90,6,1,,RGB(black),RGB(red)
   Else
     Circle x%,y%+90,6,1,,RGB(black),RGB(80,80,80)
   EndIf
   If GetBit%(in_temp%,i%) Then
     Circle x%,y%+120,6,1,,RGB(black),RGB(red)
   Else
     Circle x%,y%+120,6,1,,RGB(black),RGB(80,80,80)
   EndIf
   x% = x% + 40
 Next i%
End Sub
'---------------------
' Draw the opcode LEDs
Sub Draw_OCLEDs (OCReg%)
 Local oc_temp%,x%,y%
 ' high order 3 bits shifted to 3 low order bits
 oc_temp% = (OCReg% AND OCMask%) \ 32
 x% = 438
 y% = 43
 ' Memory reference instructions
 If oc_temp% = 0 then  'AND
   Circle x%,y%,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If oc_temp% = 1 then  'TAD
   Circle x%,y%+30,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+30,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If oc_temp% = 2 then  'ISZ
   Circle x%,y%+60,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+60,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If oc_temp% = 3 then  ' DCA
   Circle x%,y%+90,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+90,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If CarryFlag% = 1 Then  ' Carry
   Circle x%,y%+120,6,1,,RGB(black),RGB(RED)
 Else
   Circle x%,y%+120,6,1,,RGB(black),RGB(80,80,80)
 Endif  
 If oc_temp% = 5 then  ' JMP
   Circle x%+40,y%+60,6,1,,RGB(black),RGB(red)
 Else
   Circle x%+40,y%+60,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If oc_temp% = 4 then  ' JMS
   Circle x%+40,y%+90,6,1,,RGB(black),RGB(red)
 Else
   Circle x%+40,y%+90,6,1,,RGB(black),RGB(80,80,80)
 Endif
 ' Operate Microinstructions - OPR
 If oc_temp% = 7 then  ' OPR
   Circle x%+40,y%,6,1,,RGB(black),RGB(red)
 Else
   Circle x%+40,y%,6,1,,RGB(black),RGB(80,80,80)
 Endif
 ' Input/Output transfer instructions - IOT
 If oc_temp% = 6 then  ' IOT
   Circle x%+40,y%+30,6,1,,RGB(black),RGB(red)
 Else
   Circle x%+40,y%+30,6,1,,RGB(black),RGB(80,80,80)
 Endif
   If ZeroFlag% = 1 Then  ' Zero
   Circle x%+40,y%+120,6,1,,RGB(black),RGB(RED)
 Else
   Circle x%+40,y%+120,6,1,,RGB(black),RGB(80,80,80)
 Endif
End Sub
'-----------------
' Draw state flags
Sub Draw_SFlags
 Local x%,y%
 x% = 718
 y% = 43
 ' Operational state flags
 If RunFlag% = 1 then
   Circle x%,y%,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If FetchFlag% = 1 then
   Circle x%,y%+30,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+30,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If DeferFlag% = 1 then
   Circle x%,y%+60,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+60,6,1,,RGB(black),RGB(80,80,80)
 Endif
 If ExecuteFlag% = 1 then
   Circle x%,y%+90,6,1,,RGB(black),RGB(red)
 Else
   Circle x%,y%+90,6,1,,RGB(black),RGB(80,80,80)
 Endif
End Sub
'-----------------------------------------------
' Misc subs and functions
' Bit manipulation routines
Function GetBit%  (arg1%,arg2%)
 Local reg%,bitnum%,resultbit%
 reg% = arg1%
 bitnum% = arg2%
 resultbit% = reg% AND (&B1 << bitnum%)
 If resultbit% <> 0 then
   GetBit% = 1
 Else
   GetBit% = 0
 Endif
End Function

Sub SetBit (arg1%,arg2%)
 Local reg%,bitnum%,bitmask%
 reg% = arg1%
 bitnum% = arg2%
 arg1% = reg% OR (&B1 << bitnum%)
End Sub

Sub ClearBit (arg1%,arg2%)
 Local reg%,bitnum%
 reg% = arg1%
 bitnum% = arg2%
 reg% = reg% AND (B15Mask% AND (INV(&b1 << bitnum%)))
 arg1% = reg%
End Sub

Sub ToggleBit (arg1%,arg2%)
 Local reg%,bitnum%,tbit%
 reg% = arg1%
 bitnum% = arg2%
 tbit% = GetBit% (reg%,bitnum%)
 If tbit% = 0 then
    reg% = reg% OR (&B1 << bitnum%)
 Else
   reg% = reg% AND (B15Mask% AND (INV(&B1 << bitnum%)))
 Endif
 arg1% = reg%
End Sub

... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 2006
Posted: 09:21am 15 Apr 2022
Copy link to clipboard 
Print this post

For many years I pronounced it as E-DUCK 8 until I realised it was EDUCATE.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1116
Posted: 11:35am 15 Apr 2022
Copy link to clipboard 
Print this post

An animated gif showing educ-8 in operation.

Educ-8-5b.zip
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 622
Posted: 11:11am 17 Apr 2022
Copy link to clipboard 
Print this post

 I wondered about the EDUC8, that gif really demonstrates
the idea well. Any photos of the actual EDUC8 ?

I have wondered about building a small demonstration computer, built up using microcontrollers to emulate individual sections, eg have one just being a CPU, others doing ALU, memory access,  buss control, etc. It would be quite a task though.
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1116
Posted: 11:30am 17 Apr 2022
Copy link to clipboard 
Print this post

Thanks zietfest,

The front panel of the Educ-8 is identical to my 'glass' version. The one my brother and I built is with him in WA - I will try to arrange some pics.

I looked at a Picomite emulation but found it beyond my abilities so elected to go the 'glass' version, being a fully software emulation.

I have almost completed a 'glass' reader/punch for storeing/loading programs and a KSR teletype for interaction. Will post more as I go.

The great thing about the Educ-8 is that there is no ther system available today that you can enter basic instructions like ADD, STORE, JUMP etc. in binary form. 'Computer literate youngsters (and I use the phrase advisedly) these days, while being totally at home with their smartphones/tablets etc.  really have no idea how the underlying computer works at the metal level.
Doug.
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
IanT

Senior Member

Joined: 29/11/2016
Location: United Kingdom
Posts: 116
Posted: 08:10am 18 Apr 2022
Copy link to clipboard 
Print this post

I used to be able to toggle in the boot loader of the PDP-8 from memory. All in Octal - and I've never been quite happy working with Hexadecimal ever since...

All gone now, except that 7402 was the Halt instruction!  :-)

Regards,

IanT
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 622
Posted: 09:19am 18 Apr 2022
Copy link to clipboard 
Print this post

Found a writeup on EDUC-8 on Wiki - quite eye opening !!
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8298
Posted: 02:00pm 18 Apr 2022
Copy link to clipboard 
Print this post

I raise you a Kenbak-1  (although I'm pretty sure it wasn't a kit)

https://en.wikipedia.org/wiki/Kenbak-1
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
al18
Senior Member

Joined: 06/07/2019
Location: United States
Posts: 231
Posted: 04:21pm 18 Apr 2022
Copy link to clipboard 
Print this post

https://adwaterandstir.com/ offers replica Kenbak and Altair 8800  computer kits for sale. I bought and built the Altair 8800 replica  - the kit was high quality and the computer was up and running quickly.  No troubleshooting needed.
 
KD5ZXG
Regular Member

Joined: 21/01/2022
Location: United States
Posts: 53
Posted: 07:35am 19 Apr 2022
Copy link to clipboard 
Print this post

Raise you my father's 1973 PDP8E (20MHz nothing but instruction set copied from DEC)

Missing the memory core and none of DEC's schematics match.
All documentation was shredded by his 2nd wife.
Edited 2022-04-19 17:47 by KD5ZXG
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8298
Posted: 07:52am 19 Apr 2022
Copy link to clipboard 
Print this post

Shame about that. It's very pretty though. He did a lovely job of that front panel. :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Tinine
Guru

Joined: 30/03/2016
Location: United Kingdom
Posts: 1646
Posted: 08:09am 19 Apr 2022
Copy link to clipboard 
Print this post

  KD5ZXG said  
All documentation was shredded by his 2nd wife.


Did he video-tape it over their wedding video or something?  
 
KD5ZXG
Regular Member

Joined: 21/01/2022
Location: United States
Posts: 53
Posted: 07:02pm 19 Apr 2022
Copy link to clipboard 
Print this post

Psycho erasing all evidence her victim ever lived. First thing to do after a successful murder. Fortunately I was watching the curb for trash and salvaged his front panel. At least three of this cursed design were built, and all ended horribly via wives. Jim Ferguson of Xerox 820 and Big Board fame. I don't remember the other. Trying to make it work again probably not a good idea.

Front panel was made with assistance from Bill Romans who still lives last I spoke with him a decade ago. He never built a whole machine and has no documentation. So owning the inactive panel alone appears safe.
Edited 2022-04-20 05:10 by KD5ZXG
 
William Leue
Guru

Joined: 03/07/2020
Location: United States
Posts: 405
Posted: 07:07pm 19 Apr 2022
Copy link to clipboard 
Print this post

LOL, panky! There must be something in the water :-) I just published my "glass" version of a different tiny computer, the SAP1.

-Bill
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8298
Posted: 07:49pm 19 Apr 2022
Copy link to clipboard 
Print this post

I once started work on a "new wave" Kenbak1. It was written in GCBASIC on a PIC chip, with every I/O pin used because the lights and switches were all multiplexed to keep the number of pins down. It never got completed, although a lot of the logic was done. The documentation for that machine is extremely good.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
al18
Senior Member

Joined: 06/07/2019
Location: United States
Posts: 231
Posted: 12:54am 20 Apr 2022
Copy link to clipboard 
Print this post

Mick,
You may want to check out the link I posted above. He also sells a smaller nanoKenbak based on the Atmega328p - though it’s out of stock at the moment. Probably due to the shortage of Atmega328p - looking at 4 month to 16 month lead time.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8298
Posted: 05:51am 20 Apr 2022
Copy link to clipboard 
Print this post

Oh, I wouldn't buy one. The fun was in attempting to replicate the logic of the Kenbak1  as GCBASIC routines. If I were to try again I'd use something running MMBasic as it's much faster to develop with. GCBASIC is brilliant, but it's a compiler.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025