A big ton of refactoring. Basically split up Mail.elm into a hand full smaller (more manageable) files.
This commit is contained in:
parent
8d0aded26f
commit
c4a54ee2e4
3357
out/js/elm.js
3357
out/js/elm.js
File diff suppressed because it is too large
Load Diff
1274
src/Main.elm
1274
src/Main.elm
File diff suppressed because it is too large
Load Diff
107
src/PC/Defaults.elm
Normal file
107
src/PC/Defaults.elm
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
module PC.Defaults exposing (..)
|
||||||
|
|
||||||
|
import Array exposing (Array)
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.UActions exposing (..)
|
||||||
|
|
||||||
|
|
||||||
|
initalModel : PC_Model
|
||||||
|
initalModel =
|
||||||
|
{ pc = initialPC
|
||||||
|
, uCodes = initialUCodes
|
||||||
|
}
|
||||||
|
|
||||||
|
initialPC : PC
|
||||||
|
initialPC =
|
||||||
|
{ ram = initialRam
|
||||||
|
, dataBus = 0
|
||||||
|
, addressBus = 0
|
||||||
|
, instructionReg = 0
|
||||||
|
, programmCounter = 0
|
||||||
|
, uCounter = 0
|
||||||
|
, accumulator = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
initialRam : Array (Int, String)
|
||||||
|
initialRam = Array.fromList
|
||||||
|
[ (100005, "LoadA #005") -- 000 -- LoadA #005
|
||||||
|
, (300000, "IncA") -- 001 -- IncA
|
||||||
|
, (200005, "StoreA #005") -- 002 -- StoreA #005
|
||||||
|
, (400000, "JMP #000") -- 003 -- JMP #000
|
||||||
|
, (0,"") -- 004
|
||||||
|
, (5,"val") -- 005
|
||||||
|
, (0, "") -- 006
|
||||||
|
, (0, "") -- 007
|
||||||
|
, (0, "") -- 008
|
||||||
|
, (0, "") -- 009
|
||||||
|
, (0, "") -- 010
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initialUCodes : Array UAction
|
||||||
|
initialUCodes = Array.fromList
|
||||||
|
[ UA_ProgrammCounter2AddressBus -- 000
|
||||||
|
, UA_Ram2DataBus -- 001
|
||||||
|
, UA_DataBus2InstructionReg -- 002
|
||||||
|
, UA_ProgrammCounterIncrement -- 003
|
||||||
|
, UA_InstructionReg2UCounter -- 004
|
||||||
|
, UA_Nothing -- 005
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing -- 009
|
||||||
|
|
||||||
|
-- 010 LOADA
|
||||||
|
, UA_InstructionReg2AddressBus -- 010
|
||||||
|
, UA_Ram2DataBus -- 011
|
||||||
|
, UA_DataBus2Accumulator -- 012
|
||||||
|
, UA_ResetUCounter -- 013
|
||||||
|
, UA_Nothing -- 014
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing -- 019
|
||||||
|
|
||||||
|
-- 020 STOA
|
||||||
|
, UA_Accumulator2DataBus -- 020
|
||||||
|
, UA_InstructionReg2AddressBus -- 021
|
||||||
|
, UA_DataBus2Ram -- 022
|
||||||
|
, UA_ResetUCounter -- 023
|
||||||
|
, UA_Nothing --024
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing -- 029
|
||||||
|
|
||||||
|
-- 030 INCA
|
||||||
|
, UA_AccumulatorIncrement -- 030
|
||||||
|
, UA_ResetUCounter -- 031
|
||||||
|
, UA_Nothing -- 032
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing -- 039
|
||||||
|
|
||||||
|
-- 040 JMP
|
||||||
|
, UA_InstructionReg2ProgrammCounter -- 040
|
||||||
|
, UA_ResetUCounter -- 041
|
||||||
|
, UA_Nothing -- 042
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing
|
||||||
|
, UA_Nothing -- 049
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
96
src/PC/Helpers.elm
Normal file
96
src/PC/Helpers.elm
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
module PC.Helpers exposing (..)
|
||||||
|
|
||||||
|
import Array exposing (Array)
|
||||||
|
import Http exposing (..)
|
||||||
|
|
||||||
|
-- Convert a number from 42 to 0042
|
||||||
|
-- number : (Prefered positive) whole number
|
||||||
|
-- length : positive whole number
|
||||||
|
-- Please note that only 0 are added. The number will not be shortend!
|
||||||
|
addLeadingZero : Int -> Int -> String
|
||||||
|
addLeadingZero number length =
|
||||||
|
let
|
||||||
|
num_str = String.fromInt number
|
||||||
|
in
|
||||||
|
(String.fromList <| List.repeat (length - String.length num_str) '0'
|
||||||
|
)
|
||||||
|
++ num_str
|
||||||
|
|
||||||
|
|
||||||
|
-- Get the value at a given position in a List.
|
||||||
|
-- For performance reasons it might be better
|
||||||
|
-- to use an Array instead.
|
||||||
|
valueAt : Int -> List a -> Maybe a
|
||||||
|
valueAt pos list = List.head <| List.drop pos list
|
||||||
|
|
||||||
|
|
||||||
|
-- Change the value at a given position in a List.
|
||||||
|
-- If your pos is greater than the length of
|
||||||
|
-- the list, then the rest is filled with the
|
||||||
|
-- default element.
|
||||||
|
overwriteAt : a -> Int -> a ->List a -> List a
|
||||||
|
overwriteAt default pos newVal list =
|
||||||
|
let
|
||||||
|
len = List.length list
|
||||||
|
in
|
||||||
|
if pos == 0 then
|
||||||
|
newVal :: list
|
||||||
|
else if pos > len then
|
||||||
|
list ++
|
||||||
|
(List.repeat (pos-len) default) ++
|
||||||
|
[newVal]
|
||||||
|
else
|
||||||
|
let
|
||||||
|
before = List.take pos list
|
||||||
|
after = List.drop (pos+1) list
|
||||||
|
in
|
||||||
|
before ++ [newVal] ++ after
|
||||||
|
|
||||||
|
overwriteAt_Arr : a -> Int -> a -> Array a -> Array a
|
||||||
|
overwriteAt_Arr default pos newVal list =
|
||||||
|
let
|
||||||
|
len = Array.length list
|
||||||
|
in
|
||||||
|
if pos == 0 then
|
||||||
|
Array.append (Array.fromList [newVal]) list
|
||||||
|
else if pos > len then
|
||||||
|
Array.append list
|
||||||
|
<| Array.append (Array.repeat (pos-len) default)
|
||||||
|
<| Array.fromList [newVal]
|
||||||
|
else
|
||||||
|
Array.set pos newVal list
|
||||||
|
|
||||||
|
|
||||||
|
-- Prints Http Errors into something readable
|
||||||
|
printHttpError : Http.Error -> String
|
||||||
|
printHttpError err =
|
||||||
|
case err of
|
||||||
|
Http.BadUrl str -> "Bad Url: " ++ str
|
||||||
|
Http.Timeout -> "Timeout"
|
||||||
|
Http.NetworkError -> "Network Error"
|
||||||
|
Http.BadStatus num -> "Bad Status: " ++ String.fromInt num
|
||||||
|
Http.BadBody str -> "Bad Body: " ++ str
|
||||||
|
|
||||||
|
|
||||||
|
seperateInstructionsEntry : Int -> (Int, Int)
|
||||||
|
seperateInstructionsEntry i =
|
||||||
|
let
|
||||||
|
instruction = i // 100000
|
||||||
|
address = i - instruction*100000
|
||||||
|
in
|
||||||
|
(instruction, address)
|
||||||
|
|
||||||
|
|
||||||
|
valueAtRam : Int -> Array (Int, String) -> (Int, String)
|
||||||
|
valueAtRam pos arr =
|
||||||
|
case Array.get pos arr of
|
||||||
|
Just a -> a
|
||||||
|
Nothing -> (0, "")
|
||||||
|
|
||||||
|
|
||||||
|
changeAtRam : Int -> Int -> Array (Int, String) -> Array (Int,String)
|
||||||
|
changeAtRam pos newVal list =
|
||||||
|
let
|
||||||
|
(_,comment) = valueAtRam pos list
|
||||||
|
in
|
||||||
|
overwriteAt_Arr (0, "") pos (newVal, comment) list
|
112
src/PC/JSON.elm
Normal file
112
src/PC/JSON.elm
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
module PC.Json exposing ( pcModelDecoder
|
||||||
|
, pcModelEncoder
|
||||||
|
, tuple2Decoder
|
||||||
|
, tuple2Encoder
|
||||||
|
)
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import Maybe
|
||||||
|
import Array exposing (Array)
|
||||||
|
|
||||||
|
import Json.Encode as JE exposing (Value)
|
||||||
|
import Json.Decode as JD exposing (Decoder)
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.UActions exposing (..)
|
||||||
|
|
||||||
|
|
||||||
|
-- ##########################################################
|
||||||
|
-- Decoders
|
||||||
|
-- ##########################################################
|
||||||
|
|
||||||
|
pcModelDecoder : Decoder PC_Model
|
||||||
|
pcModelDecoder =
|
||||||
|
JD.map2
|
||||||
|
PC_Model
|
||||||
|
(JD.field "pc" pcDecoder)
|
||||||
|
(JD.field "uCodes" uCodeDecoder)
|
||||||
|
|
||||||
|
|
||||||
|
pcDecoder : Decoder PC
|
||||||
|
pcDecoder =
|
||||||
|
JD.map7
|
||||||
|
PC
|
||||||
|
(JD.field "ram" <| JD.array <| tuple2Decoder JD.int JD.string)
|
||||||
|
(JD.field "dataBus" JD.int)
|
||||||
|
(JD.field "addressBus" JD.int)
|
||||||
|
(JD.field "instructionReg" JD.int)
|
||||||
|
(JD.field "programmCounter" JD.int)
|
||||||
|
(JD.field "uCounter" JD.int)
|
||||||
|
(JD.field "accumulator" JD.int)
|
||||||
|
|
||||||
|
uCodeDecoder : Decoder (Array UAction)
|
||||||
|
uCodeDecoder =
|
||||||
|
JD.array <| JD.map uActionDecoder JD.string
|
||||||
|
|
||||||
|
uActionDecoder : String -> UAction
|
||||||
|
uActionDecoder str =
|
||||||
|
Maybe.withDefault UA_Nothing <| string2uAction str
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tuple2Decoder : Decoder a -> Decoder b -> Decoder (a,b)
|
||||||
|
tuple2Decoder enc1 enc2 =
|
||||||
|
JD.map2 Tuple.pair
|
||||||
|
(JD.index 0 enc1)
|
||||||
|
(JD.index 1 enc2)
|
||||||
|
|
||||||
|
-- ##########################################################
|
||||||
|
-- ##########################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- ##########################################################
|
||||||
|
-- Encoders
|
||||||
|
-- ##########################################################
|
||||||
|
|
||||||
|
pcModelEncoder : PC_Model -> Value
|
||||||
|
pcModelEncoder model =
|
||||||
|
JE.object
|
||||||
|
[ ( "pc" , pcEncoder model.pc )
|
||||||
|
, ( "uCodes" , uCodesEncoder model.uCodes )
|
||||||
|
]
|
||||||
|
|
||||||
|
pcEncoder : PC -> Value
|
||||||
|
pcEncoder pc =
|
||||||
|
JE.object
|
||||||
|
[ ( "addressBus" , JE.int pc.addressBus )
|
||||||
|
, ( "dataBus" , JE.int pc.dataBus )
|
||||||
|
, ( "instructionReg" , JE.int pc.instructionReg )
|
||||||
|
, ( "programmCounter" , JE.int pc.programmCounter )
|
||||||
|
, ( "uCounter" , JE.int pc.uCounter )
|
||||||
|
, ( "accumulator" , JE.int pc.accumulator )
|
||||||
|
, ( "ram" , ramEncoder pc.ram )
|
||||||
|
]
|
||||||
|
|
||||||
|
ramEncoder : Array (Int, String) -> Value
|
||||||
|
ramEncoder arr =
|
||||||
|
JE.array
|
||||||
|
(tuple2Encoder JE.int JE.string)
|
||||||
|
arr
|
||||||
|
|
||||||
|
uCodesEncoder : Array UAction -> Value
|
||||||
|
uCodesEncoder uActions =
|
||||||
|
JE.array encodeSingleuCode uActions
|
||||||
|
|
||||||
|
encodeSingleuCode : UAction -> Value
|
||||||
|
encodeSingleuCode action =
|
||||||
|
let
|
||||||
|
uCode = uAction2UCode action
|
||||||
|
in
|
||||||
|
JE.string uCode.id
|
||||||
|
|
||||||
|
|
||||||
|
tuple2Encoder : (a -> Value) -> (b -> Value) -> (a,b) -> Value
|
||||||
|
tuple2Encoder encA encB (valA, valB) =
|
||||||
|
JE.list identity [ encA valA, encB valB ]
|
||||||
|
|
||||||
|
-- ##########################################################
|
||||||
|
-- ##########################################################
|
||||||
|
-- Done.
|
28
src/PC/PC.elm
Normal file
28
src/PC/PC.elm
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
module PC.PC exposing (..)
|
||||||
|
|
||||||
|
import Html exposing (Html)
|
||||||
|
--import Json.Encode as JE
|
||||||
|
import Json.Decode as JD
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.Defaults exposing (..)
|
||||||
|
import PC.Helpers exposing (..)
|
||||||
|
import PC.Update exposing (..)
|
||||||
|
import PC.View exposing (..)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
update : PC_Msg -> PC_Model -> (PC_Model, PC_AfterUpdateAction)
|
||||||
|
update = pc_update
|
||||||
|
|
||||||
|
|
||||||
|
view : PC_Model -> Html PC_Msg
|
||||||
|
view = pc_view
|
||||||
|
|
||||||
|
init : PC_Model
|
||||||
|
init = initalModel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
78
src/PC/Types.elm
Normal file
78
src/PC/Types.elm
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
module PC.Types exposing (..)
|
||||||
|
|
||||||
|
import Array exposing (Array)
|
||||||
|
|
||||||
|
pcModelVersion = "3"
|
||||||
|
|
||||||
|
type alias PC_Model =
|
||||||
|
{ pc : PC
|
||||||
|
, uCodes : Array UAction
|
||||||
|
}
|
||||||
|
|
||||||
|
type alias PC =
|
||||||
|
{ ram : Array (Int, String)
|
||||||
|
, dataBus : Int
|
||||||
|
, addressBus : Int
|
||||||
|
, instructionReg : Int
|
||||||
|
, programmCounter : Int
|
||||||
|
, uCounter : Int
|
||||||
|
, accumulator : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
type alias UCode =
|
||||||
|
{ variant : UAction
|
||||||
|
, id : String
|
||||||
|
, action : PC -> PC
|
||||||
|
, label : String
|
||||||
|
}
|
||||||
|
|
||||||
|
type UAction
|
||||||
|
= UA_Accumulator2DataBus
|
||||||
|
| UA_AccumulatorDecrement
|
||||||
|
| UA_AccumulatorIncrement
|
||||||
|
| UA_DataBus2Accumulator
|
||||||
|
| UA_DataBus2InstructionReg
|
||||||
|
| UA_DataBus2Ram
|
||||||
|
| UA_InstructionReg2AddressBus
|
||||||
|
| UA_InstructionReg2ProgrammCounter
|
||||||
|
| UA_InstructionReg2UCounter
|
||||||
|
| UA_ProgrammCounterIncrement
|
||||||
|
| UA_InstructionReg2ProgrammCounterIfAccEq0
|
||||||
|
| UA_Ram2DataBus
|
||||||
|
| UA_ResetUCounter
|
||||||
|
| UA_ProgrammCounter2AddressBus
|
||||||
|
| UA_Nothing
|
||||||
|
|
||||||
|
|
||||||
|
-- To make it easier to understand everything has name convention
|
||||||
|
-- PM_ -> PC_Msg in general
|
||||||
|
-- PM_B_ -> for a Button
|
||||||
|
-- PM_C_ -> for a Checkbox
|
||||||
|
-- PM_F_ -> for a TextField
|
||||||
|
type PC_Msg
|
||||||
|
= PM_B_UCycleStep
|
||||||
|
| PM_B_InstructionStep
|
||||||
|
| PM_B_Reset
|
||||||
|
| PM_B_RamAddBelow
|
||||||
|
| PM_B_CuAddBelow
|
||||||
|
| PM_F_RamEditInstr Int String
|
||||||
|
| PM_F_RamEditAddress Int String
|
||||||
|
| PM_F_RamEditComment Int String
|
||||||
|
| PM_F_CuEditAction Int String
|
||||||
|
| PM_F_CuInstrRegEditAddr String
|
||||||
|
| PM_F_CuInstrRegEditInstr String
|
||||||
|
| PM_F_CuProgCounterEdit String
|
||||||
|
| PM_F_CuUCounterEdit String
|
||||||
|
| PM_F_EditAddressBus String
|
||||||
|
| PM_F_EditDataBus String
|
||||||
|
| PM_F_AluEdit String
|
||||||
|
| PM_ManualStep UAction
|
||||||
|
|
||||||
|
|
||||||
|
-- Tells main what is supposed
|
||||||
|
-- to happen after a update
|
||||||
|
type PC_AfterUpdateAction
|
||||||
|
= PUA_Nothing -- Do nothing
|
||||||
|
| PUA_Storage -- Update localStorage
|
||||||
|
| PUA_Scroller -- Scroll to value
|
||||||
|
| PUA_Storage_And_Scroller -- Update localStorage and scroll to values
|
163
src/PC/UActions.elm
Normal file
163
src/PC/UActions.elm
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
module PC.UActions exposing ( uCodes
|
||||||
|
, uAction2Label
|
||||||
|
, string2uAction
|
||||||
|
, uAction2UCode )
|
||||||
|
|
||||||
|
import Array exposing (Array)
|
||||||
|
import Tuple
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.Helpers exposing (..)
|
||||||
|
|
||||||
|
uCodes : List UCode
|
||||||
|
uCodes =
|
||||||
|
[ UCode UA_Accumulator2DataBus "acc2db" actAccumulator2DataBus "Acc -> DataBus"
|
||||||
|
, UCode UA_AccumulatorDecrement "accDec" actAccumulatorDecrement "Acc --"
|
||||||
|
, UCode UA_AccumulatorIncrement "accInc" actAccumulatorIncrement "Acc ++"
|
||||||
|
, UCode UA_DataBus2Accumulator "db2acc" actDataBus2Accumulator "DataBus -> Acc"
|
||||||
|
, UCode UA_DataBus2InstructionReg "db2ir" actDataBus2InstructionReg "DataBus -> InstReg"
|
||||||
|
, UCode UA_DataBus2Ram "db2ram" actDataBus2Ram "DataBus -> Ram"
|
||||||
|
, UCode UA_InstructionReg2AddressBus "ir2ab" actInstructionReg2AddressBus "InstReg -> AddrBus"
|
||||||
|
, UCode UA_InstructionReg2ProgrammCounter "ir2pc" actInstructionReg2ProgrammCounter "InstReg -> ProgCount"
|
||||||
|
, UCode UA_InstructionReg2UCounter "ir2uc" actInstructionReg2UCounter "InstReg -> µCounter"
|
||||||
|
, UCode UA_ProgrammCounterIncrement "pcInc" actProgrammCounterIncrement "ProgCounter ++"
|
||||||
|
, UCode UA_Ram2DataBus "ram2db" actRam2DataBus "Ram -> DataBus"
|
||||||
|
, UCode UA_ResetUCounter "ucReset" actResetUCounter "µCounter = 0"
|
||||||
|
, UCode UA_ProgrammCounter2AddressBus "pc2ab" actProgrammCounter2AddressBus "ProgCounter -> AddrBus"
|
||||||
|
, UCode UA_Nothing "n" (\s -> s) "Empty"
|
||||||
|
, UCode UA_InstructionReg2ProgrammCounterIfAccEq0
|
||||||
|
"ir2pciacceq0" actInstructionReg2ProgrammCounterIfAccEq0 "Acc == 0 => InstReg -> ProgCounter"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
-- #######################################################################################
|
||||||
|
-- ACTIONS
|
||||||
|
-- #######################################################################################
|
||||||
|
|
||||||
|
actRam2DataBus : PC -> PC
|
||||||
|
actRam2DataBus pc =
|
||||||
|
let
|
||||||
|
ab =
|
||||||
|
pc.addressBus
|
||||||
|
|
||||||
|
db =
|
||||||
|
Tuple.first <| valueAtRam ab pc.ram
|
||||||
|
in
|
||||||
|
{ pc | dataBus = db }
|
||||||
|
|
||||||
|
|
||||||
|
actDataBus2InstructionReg : PC -> PC
|
||||||
|
actDataBus2InstructionReg pc =
|
||||||
|
{ pc | instructionReg = pc.dataBus }
|
||||||
|
|
||||||
|
|
||||||
|
actResetUCounter : PC -> PC
|
||||||
|
actResetUCounter pc =
|
||||||
|
{ pc | uCounter = 0 }
|
||||||
|
|
||||||
|
|
||||||
|
actInstructionReg2UCounter : PC -> PC
|
||||||
|
actInstructionReg2UCounter pc =
|
||||||
|
-- Multiply by ten, because every instruction is 10 uCodes long
|
||||||
|
let
|
||||||
|
(instruction, address) = seperateInstructionsEntry pc.instructionReg
|
||||||
|
in
|
||||||
|
{ pc | uCounter = instruction * 10}
|
||||||
|
|
||||||
|
|
||||||
|
actInstructionReg2AddressBus : PC -> PC
|
||||||
|
actInstructionReg2AddressBus pc =
|
||||||
|
let
|
||||||
|
(instruction, address) = seperateInstructionsEntry pc.instructionReg
|
||||||
|
in
|
||||||
|
{ pc | addressBus = address }
|
||||||
|
|
||||||
|
|
||||||
|
actInstructionReg2ProgrammCounter : PC -> PC
|
||||||
|
actInstructionReg2ProgrammCounter pc =
|
||||||
|
let
|
||||||
|
(instruction, address) = seperateInstructionsEntry pc.instructionReg
|
||||||
|
in
|
||||||
|
|
||||||
|
{ pc | programmCounter = address }
|
||||||
|
|
||||||
|
|
||||||
|
actProgrammCounterIncrement : PC -> PC
|
||||||
|
actProgrammCounterIncrement pc =
|
||||||
|
{ pc | programmCounter = pc.programmCounter + 1 }
|
||||||
|
|
||||||
|
|
||||||
|
actProgrammCounter2AddressBus : PC -> PC
|
||||||
|
actProgrammCounter2AddressBus pc =
|
||||||
|
{ pc | addressBus = pc.programmCounter }
|
||||||
|
|
||||||
|
actInstructionReg2ProgrammCounterIfAccEq0 : PC -> PC
|
||||||
|
actInstructionReg2ProgrammCounterIfAccEq0 pc =
|
||||||
|
if pc.accumulator == 0 then
|
||||||
|
let
|
||||||
|
(_,addr) = seperateInstructionsEntry pc.instructionReg
|
||||||
|
in
|
||||||
|
{ pc | programmCounter = addr }
|
||||||
|
else
|
||||||
|
pc
|
||||||
|
|
||||||
|
actDataBus2Accumulator : PC -> PC
|
||||||
|
actDataBus2Accumulator pc =
|
||||||
|
{ pc | accumulator = pc.dataBus }
|
||||||
|
|
||||||
|
|
||||||
|
actAccumulator2DataBus : PC -> PC
|
||||||
|
actAccumulator2DataBus pc =
|
||||||
|
{ pc | dataBus = pc.accumulator }
|
||||||
|
|
||||||
|
|
||||||
|
actAccumulatorIncrement : PC -> PC
|
||||||
|
actAccumulatorIncrement pc =
|
||||||
|
{ pc | accumulator = pc.accumulator + 1 }
|
||||||
|
|
||||||
|
|
||||||
|
actAccumulatorDecrement : PC -> PC
|
||||||
|
actAccumulatorDecrement pc =
|
||||||
|
{ pc | accumulator = pc.accumulator - 1 }
|
||||||
|
|
||||||
|
|
||||||
|
actDataBus2Ram : PC -> PC
|
||||||
|
actDataBus2Ram pc =
|
||||||
|
let
|
||||||
|
newRam =
|
||||||
|
changeAtRam pc.addressBus pc.dataBus pc.ram
|
||||||
|
in
|
||||||
|
{ pc | ram = newRam }
|
||||||
|
|
||||||
|
|
||||||
|
-- #################################################################
|
||||||
|
-- Helpers
|
||||||
|
-- #################################################################
|
||||||
|
|
||||||
|
uAction2Label : UAction -> String
|
||||||
|
uAction2Label variant =
|
||||||
|
let
|
||||||
|
filtered_list = List.filter (\u -> u.variant == variant ) uCodes
|
||||||
|
in
|
||||||
|
case List.head filtered_list of
|
||||||
|
Just uCode -> uCode.label
|
||||||
|
Nothing -> "IDK"
|
||||||
|
|
||||||
|
uAction2UCode : UAction -> UCode
|
||||||
|
uAction2UCode variant =
|
||||||
|
let
|
||||||
|
filtered_list = List.filter (\u -> u.variant == variant ) uCodes
|
||||||
|
in
|
||||||
|
case List.head filtered_list of
|
||||||
|
Just uCode -> uCode
|
||||||
|
Nothing -> UCode UA_Nothing "n" (\s -> s) "Empty"
|
||||||
|
|
||||||
|
string2uAction : String -> Maybe UAction
|
||||||
|
string2uAction str =
|
||||||
|
let
|
||||||
|
filtered_list = List.filter (\u -> u.id == str) uCodes
|
||||||
|
in
|
||||||
|
case List.head filtered_list of
|
||||||
|
Just uCode -> Just uCode.variant
|
||||||
|
_ -> Nothing
|
||||||
|
|
246
src/PC/Update.elm
Normal file
246
src/PC/Update.elm
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
module PC.Update exposing (pc_update)
|
||||||
|
|
||||||
|
import Array exposing (Array)
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.UActions exposing (..)
|
||||||
|
import PC.Defaults exposing (..)
|
||||||
|
import PC.Helpers exposing (..)
|
||||||
|
|
||||||
|
|
||||||
|
pc_update : PC_Msg -> PC_Model -> (PC_Model, PC_AfterUpdateAction)
|
||||||
|
pc_update msg model =
|
||||||
|
case msg of
|
||||||
|
PM_B_UCycleStep ->
|
||||||
|
( uStepPC model
|
||||||
|
, if model.pc.uCounter == 0 then PUA_Storage_And_Scroller
|
||||||
|
else PUA_Scroller
|
||||||
|
)
|
||||||
|
|
||||||
|
PM_B_InstructionStep ->
|
||||||
|
( executeInstruction model
|
||||||
|
, PUA_Storage_And_Scroller )
|
||||||
|
|
||||||
|
|
||||||
|
PM_B_Reset ->
|
||||||
|
( { model | pc = { initialPC | ram = model.pc.ram } }
|
||||||
|
, PUA_Storage_And_Scroller )
|
||||||
|
|
||||||
|
PM_B_RamAddBelow ->
|
||||||
|
let
|
||||||
|
old_pc = model.pc
|
||||||
|
new_pc = {old_pc | ram = Array.append old_pc.ram <| Array.fromList [(0, "")]}
|
||||||
|
in
|
||||||
|
({model | pc = new_pc}
|
||||||
|
, PUA_Storage)
|
||||||
|
|
||||||
|
PM_B_CuAddBelow ->
|
||||||
|
({model | uCodes = Array.append model.uCodes <| Array.repeat 10 UA_Nothing}
|
||||||
|
, PUA_Storage)
|
||||||
|
|
||||||
|
PM_F_RamEditAddress addr may_int ->
|
||||||
|
case String.toInt may_int of
|
||||||
|
Just int ->
|
||||||
|
let
|
||||||
|
(inst,_) = seperateInstructionsEntry ( Tuple.first <| valueAtRam addr model.pc.ram )
|
||||||
|
new_val = inst * 100000 + int
|
||||||
|
old_pc = model.pc
|
||||||
|
new_pc = { old_pc | ram = (changeAtRam addr new_val old_pc.ram) }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> (model, PUA_Nothing)
|
||||||
|
|
||||||
|
PM_F_RamEditInstr addr may_int ->
|
||||||
|
case String.toInt may_int of
|
||||||
|
Just int ->
|
||||||
|
let
|
||||||
|
(_,address) = seperateInstructionsEntry ( Tuple.first <| valueAtRam addr model.pc.ram )
|
||||||
|
new_val = int * 100000 + address
|
||||||
|
old_pc = model.pc
|
||||||
|
new_pc = { old_pc | ram = (changeAtRam addr new_val old_pc.ram) }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
|
||||||
|
PM_F_RamEditComment addr str ->
|
||||||
|
let
|
||||||
|
(val, _) = valueAtRam addr model.pc.ram
|
||||||
|
old_pc = model.pc
|
||||||
|
new_pc = { old_pc | ram = overwriteAt_Arr (0,"") addr (val, str) old_pc.ram }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
|
||||||
|
PM_F_CuEditAction addr may_action ->
|
||||||
|
case string2uAction may_action of
|
||||||
|
Just action ->
|
||||||
|
let
|
||||||
|
newCode = Array.set addr action model.uCodes
|
||||||
|
in
|
||||||
|
({ model | uCodes = newCode }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
|
||||||
|
PM_F_CuInstrRegEditAddr text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
(instr,_) = seperateInstructionsEntry old_pc.instructionReg
|
||||||
|
new_pc = { old_pc | instructionReg = instr * 100000 + int }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_CuInstrRegEditInstr text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
(_,addr) = seperateInstructionsEntry old_pc.instructionReg
|
||||||
|
new_pc = { old_pc | instructionReg = int * 100000 + addr }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_CuProgCounterEdit text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
new_pc = { old_pc | programmCounter = int }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_CuUCounterEdit text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
new_pc = { old_pc | uCounter = int }
|
||||||
|
in
|
||||||
|
( { model | pc = new_pc }, PUA_Storage_And_Scroller )
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_EditAddressBus text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
new_pc = { old_pc | addressBus = int }
|
||||||
|
in
|
||||||
|
( { model | pc = new_pc }, PUA_Storage_And_Scroller )
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_EditDataBus text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
new_pc = { old_pc | dataBus = int }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
PM_F_AluEdit text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
new_pc = { old_pc | accumulator = int }
|
||||||
|
in
|
||||||
|
({ model | pc = new_pc }, PUA_Storage)
|
||||||
|
_ -> ( model, PUA_Nothing )
|
||||||
|
|
||||||
|
|
||||||
|
PM_ManualStep action ->
|
||||||
|
let
|
||||||
|
instruction = getAction action
|
||||||
|
new_model = { model | pc = instruction model.pc }
|
||||||
|
in
|
||||||
|
( new_model, PUA_Storage_And_Scroller )
|
||||||
|
|
||||||
|
-- ###############################################################################
|
||||||
|
-- ###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- ###############################################################################
|
||||||
|
-- Update Helpers
|
||||||
|
-- ###############################################################################
|
||||||
|
|
||||||
|
-- Practically a part of uStepPC but sepeated for manual mode
|
||||||
|
getAction : UAction -> (PC -> PC)
|
||||||
|
getAction uAction =
|
||||||
|
let
|
||||||
|
possible_instructions =
|
||||||
|
List.filter (\u -> u.variant == uAction) uCodes
|
||||||
|
in
|
||||||
|
case List.head possible_instructions of
|
||||||
|
Just uCode ->
|
||||||
|
uCode.action
|
||||||
|
_ ->
|
||||||
|
(\s -> s)
|
||||||
|
|
||||||
|
|
||||||
|
uStepPC : PC_Model -> PC_Model
|
||||||
|
uStepPC model =
|
||||||
|
let
|
||||||
|
uCounter =
|
||||||
|
model.pc.uCounter
|
||||||
|
|
||||||
|
may_code : Maybe UAction
|
||||||
|
may_code = Array.get uCounter model.uCodes
|
||||||
|
--valueAt uCounter model.uCodes
|
||||||
|
in
|
||||||
|
case may_code of
|
||||||
|
Just code ->
|
||||||
|
let
|
||||||
|
-- code :: UAction
|
||||||
|
old_pc = model.pc
|
||||||
|
temp_pc = { old_pc | uCounter = uCounter + 1 }
|
||||||
|
|
||||||
|
uCode = uAction2UCode code
|
||||||
|
f = uCode.action
|
||||||
|
new_pc = f temp_pc
|
||||||
|
in
|
||||||
|
{ model | pc = new_pc }
|
||||||
|
|
||||||
|
|
||||||
|
--let
|
||||||
|
-- possible_instructions =
|
||||||
|
-- List.filter (\s -> Tuple.first s == action) uCodeMaps
|
||||||
|
--in
|
||||||
|
--case List.head possible_instructions of
|
||||||
|
-- Just ( name, instruction ) ->
|
||||||
|
-- let
|
||||||
|
-- old_pc =
|
||||||
|
-- model.pc
|
||||||
|
|
||||||
|
-- new_pc =
|
||||||
|
-- { old_pc | uCounter = old_pc.uCounter + 1 }
|
||||||
|
-- in
|
||||||
|
-- { model | pc = instruction new_pc }
|
||||||
|
|
||||||
|
-- _ ->
|
||||||
|
-- let
|
||||||
|
-- old_pc =
|
||||||
|
-- model.pc
|
||||||
|
|
||||||
|
-- new_pc =
|
||||||
|
-- { old_pc | uCounter = 0 }
|
||||||
|
-- in
|
||||||
|
-- { model | pc = new_pc }
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
model
|
||||||
|
|
||||||
|
|
||||||
|
executeInstruction : PC_Model -> PC_Model
|
||||||
|
executeInstruction model =
|
||||||
|
let
|
||||||
|
new_model = uStepPC model
|
||||||
|
in
|
||||||
|
if new_model.pc.uCounter == 0 then
|
||||||
|
uStepPC new_model
|
||||||
|
else
|
||||||
|
executeInstruction new_model
|
||||||
|
|
||||||
|
|
||||||
|
-- ###############################################################################
|
||||||
|
-- ###############################################################################
|
||||||
|
-- Done.
|
381
src/PC/View.elm
Normal file
381
src/PC/View.elm
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
module PC.View exposing (pc_view)
|
||||||
|
|
||||||
|
import Html exposing (Html, button, div, h1, p, text)
|
||||||
|
import Html.Attributes as HAttr exposing (class, classList, value)
|
||||||
|
import Html.Events as HEvent exposing (onClick, onInput)
|
||||||
|
import Html.Lazy exposing (lazy)
|
||||||
|
import Array exposing (Array)
|
||||||
|
import Json.Decode as JD
|
||||||
|
|
||||||
|
import PC.Types exposing (..)
|
||||||
|
import PC.UActions exposing (..)
|
||||||
|
import PC.Helpers exposing (..)
|
||||||
|
|
||||||
|
pc_view : PC_Model -> Html PC_Msg
|
||||||
|
pc_view model = div []
|
||||||
|
[ div
|
||||||
|
[ class "grid-fullwidth", class "grid-addressbus" ]
|
||||||
|
[ lazy viewAddressBus model ]
|
||||||
|
, lazy viewRam model
|
||||||
|
, lazy viewCu model
|
||||||
|
, lazy viewAlu model
|
||||||
|
, div
|
||||||
|
[ class "grid-fullwidth", class "grid-databus" ]
|
||||||
|
[ lazy viewDataBus model ]
|
||||||
|
]
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- RAM
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
viewRam : PC_Model -> Html PC_Msg
|
||||||
|
viewRam model =
|
||||||
|
div [ class "section", class "ram" ]
|
||||||
|
[ h1 [ class "header" ] [ text "RAM" ]
|
||||||
|
, div [ class "arrow", class "down", class "top"] [ div [] [] , div [] [] ]
|
||||||
|
, div [ class "scroller" ]
|
||||||
|
[ Html.table [ class "" ]
|
||||||
|
[ Html.thead [ class "head" ]
|
||||||
|
[ Html.tr []
|
||||||
|
[ Html.th [ class "address" ] [ text "Addr" ]
|
||||||
|
, Html.th [] [ text "Value" ]
|
||||||
|
, Html.th [] [ text "Comment" ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, lazy viewRamContent model
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, drawArrow Bottom Down UA_Ram2DataBus "Ram -> DataBus"
|
||||||
|
, drawArrow Bottom Up UA_DataBus2Ram "DataBus -> Ram"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewRamContent : PC_Model -> Html PC_Msg
|
||||||
|
viewRamContent model =
|
||||||
|
let
|
||||||
|
--indexedRam =
|
||||||
|
-- List.indexedMap Tuple.pair <| Array.toList model.pc.ram
|
||||||
|
|
||||||
|
ram2table : Int -> (Int, String) -> Html PC_Msg
|
||||||
|
ram2table id entry =
|
||||||
|
let
|
||||||
|
(val,comment) = entry
|
||||||
|
|
||||||
|
(instruction, address) = seperateInstructionsEntry val
|
||||||
|
in
|
||||||
|
Html.tr
|
||||||
|
[ classList [ ( "current", id == model.pc.addressBus ) ] ]
|
||||||
|
[ Html.td [ class "num" ] [ text (addLeadingZero id 3) ]
|
||||||
|
, Html.td [ class "num " ]
|
||||||
|
[ Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.value <| addLeadingZero instruction 3
|
||||||
|
, onInput <| PM_F_RamEditInstr id
|
||||||
|
, class "ram-entry"
|
||||||
|
, class "instruction"
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.value <| addLeadingZero address 5
|
||||||
|
, onInput <| PM_F_RamEditAddress id
|
||||||
|
, class "ram-entry"
|
||||||
|
, class "address"
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
, Html.td[ class "comment" ]
|
||||||
|
[ Html.input
|
||||||
|
[ HAttr.type_ "text"
|
||||||
|
, HAttr.value comment
|
||||||
|
, onInput <| PM_F_RamEditComment id ]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
in
|
||||||
|
Html.tbody []
|
||||||
|
((Array.toList <| Array.indexedMap ram2table model.pc.ram)
|
||||||
|
++
|
||||||
|
[ Html.tr []
|
||||||
|
[ Html.td [] []
|
||||||
|
, Html.td []
|
||||||
|
[ button
|
||||||
|
[ onClick PM_B_RamAddBelow ]
|
||||||
|
[ text "Add Entry"]
|
||||||
|
]
|
||||||
|
, Html.td [][]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- Control Unit
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
viewCu : PC_Model -> Html PC_Msg
|
||||||
|
viewCu model =
|
||||||
|
let
|
||||||
|
( instrRegInst, instrRegAddr ) = seperateInstructionsEntry model.pc.instructionReg
|
||||||
|
in
|
||||||
|
div [ class "section", class "cu" ]
|
||||||
|
[ drawArrow Top Up UA_InstructionReg2AddressBus "InstR -> AddrB"
|
||||||
|
, drawArrow Top Up UA_ProgrammCounter2AddressBus "ProgCounter -> AddrB"
|
||||||
|
--, div [ class "arrow", class "up", class "top"]
|
||||||
|
-- [ div [ class "button" ]
|
||||||
|
-- [ Html.a [ onClick (PM_ManualStep ActInstructionReg2AddressBus)] [ text "InstR -> AddrB" ]]
|
||||||
|
-- , div [] []
|
||||||
|
-- ]
|
||||||
|
--, div [ class "arrow", class "up", class "top", class "arrow2"]
|
||||||
|
-- [ div [ class "button" ]
|
||||||
|
-- [ Html.a [ onClick (PM_ManualStep ActProgrammCounter2AddressBus)] [ text "ProgCounter -> AddrB" ]]
|
||||||
|
-- , div [] []
|
||||||
|
-- ]
|
||||||
|
|
||||||
|
|
||||||
|
, h1 [ class "header" ] [ text "Control Unit" ]
|
||||||
|
, p []
|
||||||
|
[ div [class "input-row"]
|
||||||
|
[ Html.label [ HAttr.for "cu-progcounter" ] [ text "Programm Counter:" ]
|
||||||
|
, button
|
||||||
|
[ onClick <| PM_ManualStep UA_InstructionReg2ProgrammCounter ]
|
||||||
|
[ text "InstRA -> " ]
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "cu-progcounter"
|
||||||
|
, value (addLeadingZero model.pc.programmCounter 3)
|
||||||
|
, onInput PM_F_CuProgCounterEdit
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
|
||||||
|
, div [class "input-row"]
|
||||||
|
[ Html.label [ HAttr.for "cu-instrReg" ] [ text "Instruction Register:" ]
|
||||||
|
, div []
|
||||||
|
[ Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "cu-instrReg"
|
||||||
|
, class "instruction"
|
||||||
|
, value (addLeadingZero instrRegInst 3)
|
||||||
|
, onInput PM_F_CuInstrRegEditInstr
|
||||||
|
] []
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "cu-instrReg"
|
||||||
|
, class "address"
|
||||||
|
, value (addLeadingZero instrRegAddr 5)
|
||||||
|
, onInput PM_F_CuInstrRegEditAddr
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
, div [class "input-row"]
|
||||||
|
[ Html.label [ HAttr.for "cu-uCounter" ] [ text "µCode Counter:" ]
|
||||||
|
, button
|
||||||
|
[ onClick <| PM_ManualStep UA_InstructionReg2UCounter
|
||||||
|
]
|
||||||
|
[ text "IntrRI ->" ]
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "cu-uCounter"
|
||||||
|
, value (addLeadingZero model.pc.uCounter 4)
|
||||||
|
, onInput PM_F_CuUCounterEdit
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
|
, div [ class "scroller" ]
|
||||||
|
[ viewCuUCode model
|
||||||
|
]
|
||||||
|
--, div [ class "arrow", class "up"]
|
||||||
|
-- [ div [ class "button" ]
|
||||||
|
-- [ Html.a [ onClick (MsgManualStep ActDataBus2InstructionReg) ] [ text "DB -> InstR" ]]
|
||||||
|
-- , div [] []
|
||||||
|
-- ]
|
||||||
|
, drawArrow Bottom Up UA_DataBus2InstructionReg "DB -> InstR"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewCuUCode : PC_Model -> Html PC_Msg
|
||||||
|
viewCuUCode model =
|
||||||
|
Html.table []
|
||||||
|
[ Html.thead [ class "head" ]
|
||||||
|
[ Html.tr []
|
||||||
|
[ Html.th [ class "address" ] [ text "µCounter" ]
|
||||||
|
, Html.th [] [ text "µCode" ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, lazy viewCuUCodeContent model
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewCuUCodeContent : PC_Model -> Html PC_Msg
|
||||||
|
viewCuUCodeContent model =
|
||||||
|
let
|
||||||
|
list2table : Int -> UAction -> Html PC_Msg
|
||||||
|
list2table id code =
|
||||||
|
Html.tr
|
||||||
|
[ classList [ ( "current", id == model.pc.uCounter ), ("empty", code == UA_Nothing) ] ]
|
||||||
|
[ Html.td [ class "num" ] [ text (addLeadingZero id 4) ]
|
||||||
|
, Html.td [] [ viewCuInstrSelect id code ]
|
||||||
|
]
|
||||||
|
|
||||||
|
in
|
||||||
|
Html.tbody []
|
||||||
|
((Array.toList <| Array.indexedMap list2table model.uCodes)
|
||||||
|
++
|
||||||
|
[ Html.tr []
|
||||||
|
[ Html.td [] []
|
||||||
|
, Html.td []
|
||||||
|
[ button
|
||||||
|
[ onClick PM_B_CuAddBelow ]
|
||||||
|
[ text "Add Entry"]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
viewCuInstrSelect : Int -> UAction -> Html PC_Msg
|
||||||
|
viewCuInstrSelect id current =
|
||||||
|
let
|
||||||
|
info2option uCode =
|
||||||
|
Html.option
|
||||||
|
[ HAttr.selected (uCode.variant == current)
|
||||||
|
, HAttr.value uCode.id ]
|
||||||
|
[ text uCode.label ]
|
||||||
|
listOptions = List.map info2option uCodes
|
||||||
|
in
|
||||||
|
Html.select
|
||||||
|
[ HEvent.on "change" ( JD.map (PM_F_CuEditAction id) selectCuValueDecoder) ]
|
||||||
|
listOptions
|
||||||
|
|
||||||
|
viewInstrEntry : Int -> Html PC_Msg
|
||||||
|
viewInstrEntry i =
|
||||||
|
let
|
||||||
|
(instruction, address) = seperateInstructionsEntry i
|
||||||
|
in
|
||||||
|
text ( (addLeadingZero instruction 3) ++ " " ++ (addLeadingZero address 5) )
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- ALU
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
viewAlu : PC_Model -> Html PC_Msg
|
||||||
|
viewAlu model =
|
||||||
|
div [ class "section", class "alu" ]
|
||||||
|
[ h1 [ class "header" ] [ text "ALU" ]
|
||||||
|
, p []
|
||||||
|
[ Html.label [ HAttr.for "alu-accumulator" ] [ text "Accumulator:" ]
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "alu-accumulator"
|
||||||
|
, value (addLeadingZero model.pc.accumulator 8)
|
||||||
|
, onInput PM_F_AluEdit
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
, p []
|
||||||
|
[ button [ onClick <| PM_ManualStep UA_AccumulatorIncrement ] [ text "Acc ++" ]
|
||||||
|
, button [ onClick <| PM_ManualStep UA_AccumulatorDecrement ] [ text "Acc --" ]
|
||||||
|
]
|
||||||
|
, drawArrow Bottom Up UA_DataBus2Accumulator "DB -> ALU"
|
||||||
|
, drawArrow Bottom Down UA_Accumulator2DataBus "ALU -> DB"
|
||||||
|
--, div [ class "arrow", class "up"]
|
||||||
|
-- [ div [ class "button" ]
|
||||||
|
-- [ Html.a [ onClick (MsgManualStep ActDataBus2Accumulator)] [ text "DB -> ALU" ]]
|
||||||
|
-- , div [] []
|
||||||
|
-- ]
|
||||||
|
--, div [ class "arrow", class "down"]
|
||||||
|
-- [ div [ class "button" ]
|
||||||
|
-- [ Html.a [ onClick (MsgManualStep ActAccumulator2DataBus)] [ text "ALU -> DB" ]]
|
||||||
|
-- , div [] []
|
||||||
|
-- ]
|
||||||
|
]
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- Busses
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
viewDataBus : PC_Model -> Html PC_Msg
|
||||||
|
viewDataBus model =
|
||||||
|
div [ class "databus" ]
|
||||||
|
[ Html.span [ class "label" ] [ text "Databus" ]
|
||||||
|
, Html.span []
|
||||||
|
[ Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, value (addLeadingZero model.pc.dataBus 8)
|
||||||
|
, onInput PM_F_EditDataBus
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewAddressBus : PC_Model -> Html PC_Msg
|
||||||
|
viewAddressBus model =
|
||||||
|
div [ class "addressbus" ]
|
||||||
|
[ Html.span [ class "label" ] [ text "Addressbus" ]
|
||||||
|
, Html.span []
|
||||||
|
[ Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, value (addLeadingZero model.pc.addressBus 3)
|
||||||
|
, onInput PM_F_EditAddressBus
|
||||||
|
] []
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- Helpers
|
||||||
|
-- #####################################################################
|
||||||
|
|
||||||
|
type Arrow_Pos = Top | Bottom
|
||||||
|
type Arrow_Dir = Up | Down
|
||||||
|
|
||||||
|
drawArrow : Arrow_Pos -> Arrow_Dir -> UAction -> String -> Html PC_Msg
|
||||||
|
drawArrow pos dir act str =
|
||||||
|
div
|
||||||
|
[ HAttr.classList
|
||||||
|
[ ("arrow", True)
|
||||||
|
, ("top", pos == Top)
|
||||||
|
, ("up", dir == Up)
|
||||||
|
, ("down", dir == Down)]
|
||||||
|
]
|
||||||
|
[ div [ class "button" ]
|
||||||
|
[ Html.a
|
||||||
|
[ onClick (PM_ManualStep act) ]
|
||||||
|
[ text str ]
|
||||||
|
]
|
||||||
|
, div [] []
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
selectCuValueDecoder : JD.Decoder String
|
||||||
|
selectCuValueDecoder =
|
||||||
|
JD.field "target" ( JD.field "value" JD.string)
|
||||||
|
|
||||||
|
|
||||||
|
-- #####################################################################
|
||||||
|
-- #####################################################################
|
||||||
|
-- Done.
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user