|
Forum Index : Microcontroller and PC projects : EDUC-8 Microcomputer - glass version
| Author | Message | ||||
| panky Guru Joined: 02/10/2012 Location: AustraliaPosts: 1116 |
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" 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: AustraliaPosts: 2006 |
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: AustraliaPosts: 1116 |
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: AustraliaPosts: 622 |
I wondered about the EDUC8, that gif really demonstratesthe 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: AustraliaPosts: 1116 |
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 KingdomPosts: 116 |
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: AustraliaPosts: 622 |
Found a writeup on EDUC-8 on Wiki - quite eye opening !! |
||||
| Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 8298 |
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 StatesPosts: 231 |
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 StatesPosts: 53 |
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 KingdomPosts: 8298 |
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 KingdomPosts: 1646 |
Did he video-tape it over their wedding video or something? |
||||
| KD5ZXG Regular Member Joined: 21/01/2022 Location: United StatesPosts: 53 |
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 StatesPosts: 405 |
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 KingdomPosts: 8298 |
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 StatesPosts: 231 |
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 KingdomPosts: 8298 |
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 |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |