Changeset 104


Ignore:
Timestamp:
Sep 22, 2010, 3:17:36 PM (9 years ago)
Author:
mulligan
Message:

Significantly improved implementation of DA instruction: code reduced in
half.

File:
1 edited

Legend:

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

    r103 r104  
    878878       let cry, res = half_add b (vect_of_int 0 `Eight) in
    879879         set_arg8 status res d
     880   | `DEC d ->
     881       let b = get_arg_8 status d in
     882       let res,c,ac,ov = subb8_with_c b (vect_of_int 1 `Eight) false in
     883         set_arg8 status res d
     884   | `MUL (`A,`B) ->
     885       let acc = int_of_vect status.acc in
     886       let b = int_of_vect status.b in
     887       let prod = acc * b in
     888       let ov = prod > 255 in
     889       let l = vect_of_int (prod  mod 256) `Eight in
     890       let h = vect_of_int (prod / 256) `Eight in
     891       let status = { status with acc = l ; b = h } in
     892         (* DPM: Carry flag is always cleared. *)
     893         set_flags status false None ov
     894   | `DIV (`A,`B) ->
     895      let acc = int_of_vect status.acc in
     896      let b = int_of_vect status.b in
     897      if b = 0 then
     898        (* CSC: acc and b undefined! we leave them as they are... *)
     899        set_flags status false None true
     900      else
     901        let q = vect_of_int (acc / b) `Eight in
     902        let r = vect_of_int (acc mod b) `Eight in
     903        let status = { status with acc = q ; b = r } in
     904          set_flags status false None false
     905   | `DA `A ->
     906        let acc_upper_nibble, acc_lower_nibble = from_byte status.acc in
     907          if int_of_vect acc_lower_nibble > 9 or get_ac_flag status = true then
     908            let acc,cy,_,_ = add8_with_c status.acc (vect_of_int 6 `Eight) false in
     909            let acc_upper_nibble, acc_lower_nibble = from_byte acc in
     910            if int_of_vect acc_upper_nibble > 9 or cy = true then
     911              let acc_upper_nibble,cy,ac,ov = add8_with_c acc_upper_nibble (vect_of_int 6 `Four) false in
     912              let status = { status with acc = mk_byte acc_upper_nibble acc_lower_nibble } in
     913                set_flags status cy (Some ac) (get_ov_flag status)
     914            else
     915              status
     916          else
     917            status
    880918(*
    881    | DEC d ->
    882       let b = get_arg_8 status d in
    883       let res = dec b in
    884        set_arg8 status res d
    885  | MUL (`A,`B) ->
    886     let acc = int_of_byte status.acc in
    887     let b = int_of_byte status.b in
    888     let prod = acc * b in
    889     let ov = prod > 255 in
    890     let l = byte_of_int (prod mod 256) in
    891     let h = byte_of_int (prod / 256) in
    892     let status = { status with acc = l ; b = h } in
    893      set_flags status false None ov
    894  | DIV (`A,`B) ->
    895     let acc = int_of_byte status.acc in
    896     let b = int_of_byte status.b in
    897      if b = 0 then
    898       (* CSC: acc and b undefined! we leave them as they are... *)
    899       set_flags status false None true
    900      else
    901       let q = byte_of_int (acc / b) in
    902       let r = byte_of_int (acc mod b) in
    903       let status = { status with acc = q ; b = r } in
    904        set_flags status false None false
    905  | DA `A ->
    906      let (b1,b2,b3,b4),(b5,b6,b7,b8) = status.acc in
    907      let acc_int_val = int_of_byte ((b1,b2,b3,b4),(b5,b6,b7,b8)) in
    908      let (cy, ac, fo, rs1),(rs0, ov, ud, p) = status.psw in
    909      let lower_nibble_int_val = int_of_nibble (b5,b6,b7,b8) in
    910      let upper_nibble_int_val = int_of_nibble (b1,b2,b3,b4) in
    911        if lower_nibble_int_val > 9 or ac = true then
    912          let acc_int_val = acc_int_val + 6 in
    913            if lower_nibble_int_val > 15 then
    914              let upper_nibble_int_val = upper_nibble_int_val + 6 in
    915              let upper_nibble = nibble_of_int upper_nibble_int_val in
    916              let lower_nibble = nibble_of_int lower_nibble_int_val in
    917              let new_psw = (true, ac, fo, rs1),(rs0, ov, ud, p) in
    918                { status with acc = (upper_nibble, lower_nibble); psw = new_psw }
    919            else
    920              if upper_nibble_int_val > 9 then
    921                let upper_nibble_int_val = upper_nibble_int_val + 6 in
    922                  if upper_nibble_int_val > 15 then
    923                    let upper_nibble = nibble_of_int upper_nibble_int_val in
    924                    let lower_nibble = nibble_of_int lower_nibble_int_val in
    925                    let new_psw = (true, ac, fo, rs1),(rs0, ov, ud, p) in
    926                      { status with acc = (upper_nibble, lower_nibble); psw = new_psw }
    927                  else
    928                    let upper_nibble = nibble_of_int upper_nibble_int_val in
    929                    let lower_nibble = nibble_of_int lower_nibble_int_val in
    930                      { status with acc = (upper_nibble, lower_nibble) }
    931              else
    932                let upper_nibble = nibble_of_int upper_nibble_int_val in
    933                let lower_nibble = nibble_of_int lower_nibble_int_val in
    934                  { status with acc = (upper_nibble, lower_nibble) }
    935        else
    936          let upper_nibble = nibble_of_int upper_nibble_int_val in
    937          let lower_nibble = nibble_of_int lower_nibble_int_val in
    938            { status with acc = (upper_nibble, lower_nibble) }
    939919 (* logical operations *)
    940920 | ANL (`U1(`A, ag)) ->
Note: See TracChangeset for help on using the changeset viewer.