Changeset 212


Ignore:
Timestamp:
Nov 3, 2010, 1:16:19 PM (9 years ago)
Author:
mulligan
Message:

Refactored main emulator loop to improve clarity. Debugging serial I/O
now.

Location:
Deliverables/D4.1
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Deliverables/D4.1/ASMInterpret.ml

    r209 r212  
    107107  serial_epsilon_out: epsilon option;
    108108  serial_epsilon_in: epsilon option;
     109
     110  io_epsilon: epsilon;
    109111
    110112  serial_v_in: [`Eight of byte | `Nine of (BitVectors.bit * byte) ] option;
     
    250252  serial_epsilon_out = None;
    251253  serial_k_out = None;
     254
     255  io_epsilon = 5;
    252256
    253257  clock = 0;
     
    12831287              else
    12841288                status)
     1289;;
     1290
     1291let timers status ticks =
     1292  (* DPM: Clock/Timer code follows. *)
     1293  match bits_of_byte status.tmod with
     1294    | (g1,c1,b1,b2),(g0,c0,b3,b4) ->
     1295      let status =
     1296        (if g0 then
     1297          if get_bit status.p3 2 then
     1298            if c0 then
     1299              if status.previous_p1_val && not $ get_bit status.p3 4 then
     1300                timer0 status b1 b2 ticks
     1301              else
     1302                status
     1303            else
     1304              timer0 status b1 b2 ticks
     1305          else
     1306            status
     1307        else
     1308          timer0 status b1 b2 ticks) in
     1309      (* Timer 1 follows. *)
     1310      let status =
     1311        (if g1 then
     1312           if get_bit status.p1 3 then
     1313             if c1 then
     1314               if status.previous_p3_val && not $ get_bit status.p3 5 then
     1315                 timer1 status b3 b4 ticks
     1316               else
     1317                 status
     1318             else
     1319               timer1 status b3 b4 ticks
     1320           else
     1321             status
     1322         else
     1323            timer1 status b3 b4 ticks) in
     1324    status
     1325;;
     1326
     1327let serial_port_input status in_cont =
     1328    (* Serial port input *)
     1329      match in_cont with
     1330        Some (`In(time, line, epsilon, cont)) when get_bit status.scon 4 ->
     1331          (let status =
     1332            (match line with
     1333              `P1 b ->
     1334                 if status.clock >= time then
     1335                   { status with p1 = b; p1_latch = b; }
     1336                 else
     1337                   status
     1338            | `P3 b ->
     1339                 if status.clock >= time then
     1340                   { status with p3 = b; p3_latch = b; }
     1341                 else
     1342                   status
     1343            | `SerialBuff (`Eight b) ->
     1344                 let sm0 = get_bit status.scon 7 in
     1345                 let sm1 = get_bit status.scon 6 in
     1346                   (match (sm0, sm1) with
     1347                     (false, false) ->
     1348                       (* Mode 0: shift register.  No delay. *)
     1349                       if status.clock >= time then
     1350                         { status with scon = set_bit status.scon 0 true;
     1351                                       io   = cont;
     1352                                       sbuf = b }
     1353                       else
     1354                         status
     1355                   | (false, true) ->
     1356                       (* Mode 1: 8-bit UART *)
     1357                       (* Explanation: 8 bit asynchronous communication.  There's a delay (epsilon)
     1358                          which needs taking care of.  If we're trying to communicate at the same time
     1359                          an existing communication is occurring, we assert false (else claus of first
     1360                          if). *)
     1361                       if status.serial_epsilon_in = None && status.serial_v_in = None then
     1362                         if status.clock >= time then
     1363                           (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
     1364                           if get_bit status.scon 5 then
     1365                             assert false (* really: crash! *)
     1366                           else
     1367                             { status with serial_epsilon_in = Some (epsilon + time);
     1368                                           serial_v_in       = Some (`Eight b) }
     1369                         else
     1370                           (* Warning about incomplete case analysis here, but safe as we've already tested for
     1371                              None. *)
     1372                           let Some e = status.serial_epsilon_in in
     1373                           let Some v = status.serial_v_in in
     1374                             if status.clock >= e then
     1375                               match v with
     1376                                 `Eight v' ->
     1377                                   { status with sbuf = v';
     1378                                                 serial_v_in = None;
     1379                                                 serial_epsilon_in = None;
     1380                                                 scon = set_bit status.scon 0 true;
     1381                                                 io = cont }
     1382                               | _ -> assert false (* trying to read in 9 bits instead of 8 *)
     1383                             else
     1384                               status
     1385                       else
     1386                         assert false
     1387                   | (true, false) | (true, true) ->
     1388                       assert false (* only got eight bits on the line when in 9 bit mode *))
     1389             | `SerialBuff (`Nine (b,b')) ->
     1390                 let sm0 = get_bit status.scon 7 in
     1391                 let sm1 = get_bit status.scon 6 in
     1392                   match(sm0, sm1) with
     1393                     (false, false) | (false, true) -> assert false
     1394                   | (true, false)  | (true, true) ->
     1395                       (* Modes 2 and 3: 9-bit UART *)
     1396                       (* Explanation: 9 bit asynchronous communication.  There's a delay (epsilon)
     1397                          which needs taking care of.  If we're trying to communicate at the same time
     1398                          an existing communication is occurring, we assert false (else claus of first
     1399                          if). *)
     1400                       if status.serial_epsilon_in = None && status.serial_v_in = None then
     1401                         if status.clock >= time then
     1402                           (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
     1403                           if get_bit status.scon 5 then
     1404                             assert false (* really: crash! *)
     1405                           else
     1406                             { status with serial_epsilon_in = Some (epsilon + time);
     1407                                           serial_v_in       = Some (`Nine (b, b')) }
     1408                         else
     1409                           (* Warning about incomplete case analysis here, but safe as we've already tested for
     1410                              None. *)
     1411                           let Some e = status.serial_epsilon_in in
     1412                           let Some v = status.serial_v_in in
     1413                             if status.clock >= e then
     1414                               match v with
     1415                                 `Nine (v, v') ->
     1416                                    let scon' = set_bit status.scon 0 true in
     1417                                      { status with sbuf = v';
     1418                                                    serial_v_in = None;
     1419                                                    serial_epsilon_in = None;
     1420                                                    scon = set_bit scon' 2 b;
     1421                                                    io = cont }
     1422                               | _ -> assert false (* trying to read in 8 bits instead of 9 *)
     1423                             else
     1424                               status
     1425                       else
     1426                         assert false)
     1427           in
     1428             { status with io = cont })
     1429       | _ -> status
     1430;;
     1431
     1432let serial_port_output status out_cont =
     1433  (* Serial port output *)
     1434    (let status = { status with serial_epsilon_out = Some (status.clock + status.io_epsilon);
     1435                                serial_v_out = Some (`Eight status.sbuf);
     1436                                serial_k_out = Some (snd (out_cont (status.clock + status.io_epsilon) (`SerialBuff (`Eight status.sbuf)))) } in
     1437    match status.serial_epsilon_out with
     1438      Some s ->
     1439        if status.clock >= s then
     1440          match status.serial_k_out with
     1441            None -> assert false (* correct? *)
     1442          | Some k' -> { status with io = k';
     1443                                     scon = set_bit status.scon 1 true; }
     1444        else
     1445          status
     1446     | _ -> assert false)
     1447;;
    12851448
    12861449let execute1 status =
     
    15731736           status
    15741737  | `NOP -> status) in
    1575   (* DPM: Clock/Timer code follows. *)
    1576   match bits_of_byte status.tmod with
    1577 (*  | (_,true,_,_),_ -> assert false
    1578   | _,(true,_,_,_) -> assert false
    1579   | _,(_,true,_,_) -> assert false*)
    1580   | (g1,c1,b1,b2),(g0,c0,b3,b4) ->
    1581       let status =
    1582         (if g0 then
    1583           if get_bit status.p3 2 then
    1584             if c0 then
    1585               if status.previous_p1_val && not $ get_bit status.p3 4 then
    1586                 timer0 status b1 b2 ticks
    1587               else
    1588                 status
    1589             else
    1590               timer0 status b1 b2 ticks
    1591           else
    1592             status
    1593         else
    1594           timer0 status b1 b2 ticks) in
    1595       (* Timer 1 follows. *)
    1596       let status =
    1597         (if g1 then
    1598            if get_bit status.p1 3 then
    1599              if c1 then
    1600                if status.previous_p3_val && not $ get_bit status.p3 5 then
    1601                  timer1 status b3 b4 ticks
    1602                else
    1603                  status
    1604              else
    1605                timer1 status b3 b4 ticks
    1606            else
    1607              status
    1608          else
    1609             timer1 status b3 b4 ticks) in
    1610       (* Serial port code now follows *)
    1611       let in_cont, `Out out_cont = status.io in
    1612       let status =
    1613         (* Serial port input *)
    1614           (match in_cont with
    1615             Some (`In(time, line, epsilon, cont)) when get_bit status.scon 4 ->
    1616               (let status =
    1617                 (match line with
    1618                   `P1 b ->
    1619                      if status.clock >= time then
    1620                        { status with p1 = b; p1_latch = b; }
    1621                      else
    1622                        status
    1623                 | `P3 b ->
    1624                      if status.clock >= time then
    1625                        { status with p3 = b; p3_latch = b; }
    1626                      else
    1627                        status
    1628                 | `SerialBuff (`Eight b) ->
    1629                      let sm0 = get_bit status.scon 7 in
    1630                      let sm1 = get_bit status.scon 6 in
    1631                        (match (sm0, sm1) with
    1632                          (false, false) ->
    1633                            (* Mode 0: shift register.  No delay. *)
    1634                            if status.clock >= time then
    1635                              { status with scon = set_bit status.scon 0 true;
    1636                                            io   = cont;
    1637                                            sbuf = b }
    1638                            else
    1639                              status
    1640                        | (false, true) ->
    1641                            (* Mode 1: 8-bit UART *)
    1642                            (* Explanation: 8 bit asynchronous communication.  There's a delay (epsilon)
    1643                               which needs taking care of.  If we're trying to communicate at the same time
    1644                               an existing communication is occurring, we assert false (else claus of first
    1645                               if). *)
    1646                            if status.serial_epsilon_in = None && status.serial_v_in = None then
    1647                              if status.clock >= time then
    1648                                (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
    1649                                if get_bit status.scon 5 then
    1650                                  assert false (* really: crash! *)
    1651                                else
    1652                                  { status with serial_epsilon_in = Some (epsilon + time);
    1653                                                serial_v_in       = Some (`Eight b) }
    1654                              else
    1655                                (* Warning about incomplete case analysis here, but safe as we've already tested for
    1656                                   None. *)
    1657                                let Some e = status.serial_epsilon_in in
    1658                                let Some v = status.serial_v_in in
    1659                                  if status.clock >= e then
    1660                                    match v with
    1661                                      `Eight v' ->
    1662                                        { status with sbuf = v';
    1663                                                      serial_v_in = None;
    1664                                                      serial_epsilon_in = None;
    1665                                                      scon = set_bit status.scon 0 true;
    1666                                                      io = cont }
    1667                                    | _ -> assert false (* trying to read in 9 bits instead of 8 *)
    1668                                  else
    1669                                    status
    1670                            else
    1671                              assert false
    1672                        | (true, false) | (true, true) ->
    1673                            assert false (* only got eight bits on the line when in 9 bit mode *))
    1674                  | `SerialBuff (`Nine (b,b')) ->
    1675                      let sm0 = get_bit status.scon 7 in
    1676                      let sm1 = get_bit status.scon 6 in
    1677                        match(sm0, sm1) with
    1678                          (false, false) | (false, true) -> assert false
    1679                        | (true, false)  | (true, true) ->
    1680                            (* Modes 2 and 3: 9-bit UART *)
    1681                            (* Explanation: 9 bit asynchronous communication.  There's a delay (epsilon)
    1682                               which needs taking care of.  If we're trying to communicate at the same time
    1683                               an existing communication is occurring, we assert false (else claus of first
    1684                               if). *)
    1685                            if status.serial_epsilon_in = None && status.serial_v_in = None then
    1686                              if status.clock >= time then
    1687                                (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
    1688                                if get_bit status.scon 5 then
    1689                                  assert false (* really: crash! *)
    1690                                else
    1691                                  { status with serial_epsilon_in = Some (epsilon + time);
    1692                                                serial_v_in       = Some (`Nine (b, b')) }
    1693                              else
    1694                                (* Warning about incomplete case analysis here, but safe as we've already tested for
    1695                                   None. *)
    1696                                let Some e = status.serial_epsilon_in in
    1697                                let Some v = status.serial_v_in in
    1698                                  if status.clock >= e then
    1699                                    match v with
    1700                                      `Nine (v, v') ->
    1701                                         let scon' = set_bit status.scon 0 true in
    1702                                           { status with sbuf = v';
    1703                                                         serial_v_in = None;
    1704                                                         serial_epsilon_in = None;
    1705                                                         scon = set_bit scon' 2 b;
    1706                                                         io = cont }
    1707                                    | _ -> assert false (* trying to read in 8 bits instead of 9 *)
    1708                                  else
    1709                                    status
    1710                            else
    1711                              assert false)
    1712                in
    1713                  { status with io = cont })
    1714            | _ -> status) in
    1715              status
    1716 (* DPM: fixme *)
    1717 (*
    1718            (* Serial port output *)
    1719            let status =
    1720              (let status = { status with serial_epsilon_out = Some (status.clock + status.io_epsilon);
    1721                                          serial_v_out = Some (`Eight status.sbuf);
    1722                                          serial_k_out = Some (snd (out_cont (status.clock + status.io_epsilon) (`SerialBuff (`Eight status.sbuf)))) } in
    1723                if status.clock >= status.serial_epsilon_out then
    1724                  match status.serial_k_out with
    1725                    None -> assert false (* correct? *)
    1726                  | Some k' -> { status with io = k';
    1727                                             scon = set_bit status.scon 1 true; }
    1728                else
    1729                  status) in
    1730            { status with previous_p1_val = get_bit status.p3 4; previous_p3_val = get_bit status.p3 5 }
    1731 *)
     1738  let status = timers status ticks in
     1739  let in_cont, `Out out_cont = status.io in
     1740  let status = serial_port_input status in_cont in
     1741  let status = serial_port_output status out_cont in
     1742    { status with previous_p1_val = get_bit status.p3 4;
     1743                  previous_p3_val = get_bit status.p3 5 }
    17321744;;
    17331745
  • Deliverables/D4.1/ASMInterpret.mli

    r209 r212  
    7474  serial_epsilon_in: epsilon option;
    7575
     76  io_epsilon: epsilon;
     77
    7678  serial_v_in: [`Eight of byte | `Nine of (BitVectors.bit * byte) ] option;
    7779  serial_v_out: [`Eight of byte | `Nine of (BitVectors.bit * byte) ] option;
  • Deliverables/D4.1/Test.hex

    r210 r212  
    22:0300610002000397
    33:0500030012006480FE04
    4 :0A00640078087508052690000022B8
     4:0A006400780575050FD69000002204
    55:06003700E478FFF6D8FD9D
    66:080015007900E94400601B7A48
Note: See TracChangeset for help on using the changeset viewer.