Changeset 205


Ignore:
Timestamp:
Oct 22, 2010, 3:06:26 PM (9 years ago)
Author:
mulligan
Message:

Reworked handling of serial port input, and implemented remaining input modes.

Location:
Deliverables/D4.1
Files:
2 edited

Legend:

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

    r203 r205  
    4444        new continuation.
    4545*)
     46
     47type epsilon = int
     48
    4649type continuation =
    47   [`In of time * line * continuation] option *
     50  [`In of time * line * epsilon * continuation] option *
    4851  [`Out of (time -> line -> time * continuation)]
    4952
    5053let rec debug_continuation =
    51  (Some (`In (65536, (`SerialBuff (`Eight (vect_of_int 5 `Eight))), debug_continuation))), `Out (
     54 (Some (`In (1, (`SerialBuff (`Eight (vect_of_int 5 `Eight))), 0, debug_continuation))), `Out (
    5255  fun time line ->
    5356    let _ = prerr_endline <*> string_of_line $ line in
     
    5659(* no differentiation between internal and external code memory *)
    5760type status =
    58  { code_memory: WordMap.map;        (* can be reduced *)
    59    low_internal_ram: Byte7Map.map;
    60    high_internal_ram: Byte7Map.map;
    61    external_ram: WordMap.map;
    62 
    63    pc: word;
    64 
    65    (* sfr *)
    66    sp: byte;
    67    dpl: byte;
    68    dph: byte;
    69    pcon: byte;
    70    tcon: byte;
    71    tmod: byte;
    72    tl0: byte;
    73    tl1: byte;
    74    th0: byte;
    75    th1: byte;
    76    p1: byte;
    77    p1_latch: byte;
    78    scon: byte;
    79    sbuf: byte;
    80    ie: byte;
    81    p3: byte;
    82    p3_latch: byte;
    83    ip: byte;
    84    psw: byte;
    85    acc: byte;
    86    b: byte;
    87    t2con: byte;  (* 8052 only *)
    88    rcap2l: byte;  (* 8052 only *)
    89    rcap2h: byte;  (* 8052 only *)
    90    tl2: byte;  (* 8052 only *)
    91    th2: byte;  (* 8052 only *)
    92 
    93    previous_p1_val: bool;
    94    previous_p3_val: bool;
    95 
    96    clock: time;
    97    timer0: word;
    98    timer1: word;
    99    timer2: word;  (* can be missing *)
    100    expected_out_time: [ `None | `Now | `At of time ];
    101    io: continuation
    102  }
     61{
     62  (* Memory *)
     63  code_memory: WordMap.map;        (* can be reduced *)
     64  low_internal_ram: Byte7Map.map;
     65  high_internal_ram: Byte7Map.map;
     66  external_ram: WordMap.map;
     67
     68  (* Program counter *)
     69  pc: word;
     70
     71  (* SFRs *)
     72  sp: byte;
     73  dpl: byte;
     74  dph: byte;
     75  pcon: byte;
     76  tcon: byte;
     77  tmod: byte;
     78  tl0: byte;
     79  tl1: byte;
     80  th0: byte;
     81  th1: byte;
     82  p1: byte;
     83  scon: byte;
     84  sbuf: byte;
     85  ie: byte;
     86  p3: byte;
     87  ip: byte;
     88  psw: byte;
     89  acc: byte;
     90  b: byte;
     91  t2con: byte;   (* 8052 only *)
     92  rcap2l: byte;  (* 8052 only *)
     93  rcap2h: byte;  (* 8052 only *)
     94  tl2: byte;     (* 8052 only *)
     95  th2: byte;     (* 8052 only *)
     96
     97  (* Latches for the output lines *)
     98  p1_latch: byte;
     99  p3_latch: byte;
     100
     101  (* Fields for tracking the state of the processor. *)
     102 
     103  (* IO specific *)
     104  previous_p1_val: bool;
     105  previous_p3_val: bool;
     106
     107  serial_epsilon_out: epsilon option;
     108  serial_epsilon_in: epsilon option;
     109
     110  serial_v_in: [`Eight of byte | `Nine of (BitVectors.bit * byte) ] option;
     111  serial_v_out: [`Eight of byte | `Nine of (BitVectors.bit * byte) ] option;
     112
     113  io: continuation;
     114  expected_out_time: [ `None | `Now | `At of time ];
     115
     116  (* Timer and clock specific *)
     117  clock: time;
     118  timer0: word;
     119  timer1: word;
     120  timer2: word  (* can be missing *)
     121}
    103122
    104123(* Try to understand what DEC really does!!! *)
     
    223242  previous_p1_val = false;
    224243  previous_p3_val = false;
     244
     245  serial_v_in = None;
     246  serial_v_out = None;
     247  serial_epsilon_in = None;
     248  serial_epsilon_out = None;
    225249
    226250  clock = 0;
     
    15811605         else
    15821606            timer1 status b3 b4 ticks) in
    1583        (* Serial port code now follows *)
    1584          let in_cont, `Out out_cont = status.io in
    1585          let status =
    1586            (* Serial port input *)
    1587            (match in_cont with
    1588              Some (`In(time, line, cont)) when time >= status.clock && get_bit status.scon 4 ->
    1589                (let status =
    1590                  match line with
    1591                    `P1 b -> { status with p1 = b; p1_latch = b; }
    1592                  | `P3 b -> { status with p3 = b; p3_latch = b; }
    1593                  | `SerialBuff (`Eight b) ->
    1594                       let b7 = get_bit (status.scon) 7 in
    1595                         (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
    1596                         if b7 || get_bit status.scon 5 then
    1597                           assert false (* really: crash! *)
    1598                         else
    1599                           let status = { status with scon = set_bit status.scon 0 true } in
    1600                           let status = { status with sbuf = b } in
    1601                             status
     1607      (* Serial port code now follows *)
     1608      let in_cont, `Out out_cont = status.io in
     1609      let status =
     1610        (* Serial port input *)
     1611          (match in_cont with
     1612            Some (`In(time, line, epsilon, cont)) when get_bit status.scon 4 ->
     1613              (let status =
     1614                (match line with
     1615                  `P1 b ->
     1616                     if status.clock >= time then
     1617                       { status with p1 = b; p1_latch = b; }
     1618                     else
     1619                       status
     1620                | `P3 b ->
     1621                     if status.clock >= time then
     1622                       { status with p3 = b; p3_latch = b; }
     1623                     else
     1624                       status
     1625                | `SerialBuff (`Eight b) ->
     1626                     let sm0 = get_bit status.scon 7 in
     1627                     let sm1 = get_bit status.scon 6 in
     1628                       (match (sm0, sm1) with
     1629                         (false, false) ->
     1630                           (* Mode 0: shift register.  No delay. *)
     1631                           if status.clock >= time then
     1632                             { status with scon = set_bit status.scon 0 true;
     1633                                           io   = cont;
     1634                                           sbuf = b }
     1635                           else
     1636                             status
     1637                       | (false, true) ->
     1638                           (* Mode 1: 8-bit UART *)
     1639                           (* Explanation: 8 bit asynchronous communication.  There's a delay (epsilon)
     1640                              which needs taking care of.  If we're trying to communicate at the same time
     1641                              an existing communication is occurring, we assert false (else claus of first
     1642                              if). *)
     1643                           if status.serial_epsilon_in = None && status.serial_v_in = None then
     1644                             if status.clock >= time then
     1645                               (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
     1646                               if get_bit status.scon 5 then
     1647                                 assert false (* really: crash! *)
     1648                               else
     1649                                 { status with serial_epsilon_in = Some (epsilon + time);
     1650                                               serial_v_in       = Some (`Eight b) }
     1651                             else
     1652                               (* Warning about incomplete case analysis here, but safe as we've already tested for
     1653                                  None. *)
     1654                               let Some e = status.serial_epsilon_in in
     1655                               let Some v = status.serial_v_in in
     1656                                 if status.clock >= e then
     1657                                   match v with
     1658                                     `Eight v' ->
     1659                                       { status with sbuf = v';
     1660                                                     serial_v_in = None;
     1661                                                     serial_epsilon_in = None;
     1662                                                     scon = set_bit status.scon 0 true;
     1663                                                     io = cont }
     1664                                   | _ -> assert false (* trying to read in 9 bits instead of 8 *)
     1665                                 else
     1666                                   status
     1667                           else
     1668                             assert false
     1669                       | (true, false) | (true, true) ->
     1670                           assert false (* only got eight bits on the line when in 9 bit mode *))
    16021671                 | `SerialBuff (`Nine (b,b')) ->
    1603                       let b7 = get_bit (status.scon) 7 in
    1604                         (* waiting for eight bits *)
    1605                         if not b7 then
    1606                           assert false (* really: crash! *)
    1607                         else
    1608                           let status = { status with scon = set_bit status.scon 2 b } in
    1609                           let status = { status with sbuf = b' } in
    1610                             if (not $ get_bit status.scon 5) || b then
    1611                               { status with scon = set_bit status.scon 0 true }
    1612                             else
    1613                               status
     1672                     let sm0 = get_bit status.scon 7 in
     1673                     let sm1 = get_bit status.scon 6 in
     1674                       match(sm0, sm1) with
     1675                         (false, false) | (false, true) -> assert false
     1676                       | (true, false) | (true, true) ->
     1677                           (* Modes 2 and 3: 9-bit UART *)
     1678                           (* Explanation: 9 bit asynchronous communication.  There's a delay (epsilon)
     1679                              which needs taking care of.  If we're trying to communicate at the same time
     1680                              an existing communication is occurring, we assert false (else claus of first
     1681                              if). *)
     1682                           if status.serial_epsilon_in = None && status.serial_v_in = None then
     1683                             if status.clock >= time then
     1684                               (* waiting for nine bits, multiprocessor communication mode requires nine bits *)
     1685                               if get_bit status.scon 5 then
     1686                                 assert false (* really: crash! *)
     1687                               else
     1688                                 { status with serial_epsilon_in = Some (epsilon + time);
     1689                                               serial_v_in       = Some (`Nine (b, b')) }
     1690                             else
     1691                               (* Warning about incomplete case analysis here, but safe as we've already tested for
     1692                                  None. *)
     1693                               let Some e = status.serial_epsilon_in in
     1694                               let Some v = status.serial_v_in in
     1695                                 if status.clock >= e then
     1696                                   match v with
     1697                                     `Nine (v, v') ->
     1698                                        let scon' = set_bit status.scon 0 true in
     1699                                          { status with sbuf = v';
     1700                                                        serial_v_in = None;
     1701                                                        serial_epsilon_in = None;
     1702                                                        scon = set_bit scon' 2 b;
     1703                                                        io = cont }
     1704                                   | _ -> assert false (* trying to read in 8 bits instead of 9 *)
     1705                                 else
     1706                                   status
     1707                           else
     1708                             assert false)
    16141709               in
    16151710                 { status with io = cont })
    1616            | Some (`In(time, line, cont)) when time >= status.clock ->
    1617                (* DPM: if there's something on the line, we need to let the program know by setting SCON.4 *)
    1618                { status with scon = set_bit status.scon 4 true }
    16191711           | _ -> status) in
    16201712           (* Serial port output, part one *)
  • Deliverables/D4.1/Test.hex

    r203 r205  
    88:08008D001200648582088583DE
    99:0C00950009D003D0028A828B830200E5B0
    10 :0D00A100439840438920758DFD43878022E0
     10:0D00A100439850438920758DFD43878022D0
    1111:0800AE00AA82AB83C2998A9972
    1212:0400B6003099FD225E
Note: See TracChangeset for help on using the changeset viewer.