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 -> let (new_model, reqAlert) = uStepPC model in ( new_model , if reqAlert == True then PUA_Alert else if model.pc.uCounter == 0 then PUA_Storage_And_Scroller else PUA_Scroller ) PM_B_InstructionStep -> let (new_model, reqAlert) = executeInstruction model in ( new_model , if reqAlert then PUA_Alert else 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, Bool) 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 if uCode.variant == UA_AlertUser then (model, True) else ({ model | pc = new_pc }, False) _ -> (model, False) executeInstruction : PC_Model -> (PC_Model, Bool) executeInstruction model = let (new_model, reqAlert) = uStepPC model in if new_model.pc.uCounter == 1 then (new_model, reqAlert) else if reqAlert then (new_model, True) else executeInstruction new_model -- ############################################################################### -- ############################################################################### -- Done.