習作。 マークダウンにF#ってないのな。
module hoge // プログラムカウンター=r7 let r = [| 0; 0; 0; 0; 0; 0; 0; 0 |] let main file = let aout = System.IO.File.ReadAllBytes file let read16 (a:byte[]) b = (int a.[b]) ||| ((int a.[b+1]) <<< 8) let write16 (a:byte[]) b c = a.[b] <- byte c a.[b + 1] <- byte (c >>> 8) let tsize = read16 aout 2 let dsize = read16 aout 4 let mem = aout.[16 .. 16 + tsize + dsize - 1] let fetch() = let ret = read16 mem r.[7] r.[7] <- r.[7] + 2 ret let mutable running = true // dd書き込み w order let mov27 w = let t = ((w >>> 3) &&& 7) let rn = w &&& 7 if rn = 7 then match t with | 6 -> let w1 = fetch() let w2 = fetch() write16 mem (r.[7] + w2) w1 | _ -> printfn "??" else match t with | 0 -> let w1 = fetch() r.[rn] <- w1 | 1 -> let w1 = fetch() write16 mem r.[rn] w1 | 6 -> let w1 = fetch() let w2 = fetch() write16 mem (r.[rn] + w2) w1 | _ -> printfn "??" // dd書き込み w order v fetch let mov w = let t1 = ((w >>> 9) &&& 7) let rn1 = ((w >>> 6) &&& 7) let t2 = ((w >>> 3) &&& 7) let rn2 = w &&& 7 match t1 with | 0 -> match t2 with | 1 -> write16 mem r.[rn2] r.[rn1] | 2 -> let v = fetch() write16 mem (r.[rn2] + v) r.[rn1] | 6 -> let v = fetch() write16 mem (r.[rn2] + v) r.[rn1] | _ -> printfn "??" | 2 -> if rn1 = 7 then mov27 w else match t2 with | 6 -> let v = fetch() r.[rn2] <- read16 mem v | _ -> printfn "??" | _ -> printfn "??" // dd書き込み w order let movb27 w = let t = ((w >>> 3) &&& 7) let rn = w &&& 7 if rn = 7 then match t with | 6 -> let w1 = fetch() let w2 = fetch() mem.[r.[1] + w2] <- byte w1 | _ -> printfn "??" else match t with | 1 -> let w1 = fetch() mem.[r.[rn]] <- byte w1 | 6 -> let w1 = fetch() let w2 = fetch() mem.[r.[rn] + w2] <- byte w1 | _ -> printfn "??" // dd書き込み w order v fetch let movb w = let t1 = ((w >>> 9) &&& 7) let rn1 = ((w >>> 6) &&& 7) let t2 = ((w >>> 3) &&& 7) let rn2 = w &&& 7 match t1 with | 0 -> match t2 with | 1 -> mem.[r.[rn2]] <- byte r.[rn1] | 6 -> mem.[r.[rn2] + fetch()] <- byte r.[rn1] | _ -> printfn "??" | 2 -> if rn1 = 7 then movb27 w else printfn "??" | _ -> printfn "??" let swab w = let t = ((w >>> 3) &&& 7) let rn = w &&& 7 match t with | 0 -> r.[rn] <- ((r.[rn] &&& 0xff) <<< 8) ||| ((r.[rn] &&& 0xff00) >>> 8) | _ -> printfn "??" let sub27 w = let t = ((w >>> 3) &&& 7) let rn = w &&& 7 if rn = 7 then match t with | 6 -> let w1 = fetch() let w2 = fetch() let addr = r.[7] + w2 write16 mem addr ((read16 mem addr) - (w1)) | _ -> printfn "??" else match t with | _ -> printfn "??" // dd書き込み w order v fetch let sub w = let t1 = ((w >>> 9) &&& 7) let rn1 = ((w >>> 6) &&& 7) let t2 = ((w >>> 3) &&& 7) let rn2 = w &&& 7 match t1 with | 2 -> if rn1 = 7 then sub27 w else printfn "??" | _ -> printfn "??" while running && r.[7] < tsize do match fetch() with // mutableを付けない変数は中身が変わらないので、ビットシフト演算しても中身は変わらない | w when (w >>> 12 = 0o01) -> mov w | w when (w >>> 12 = 0o11) -> movb w | w when (w >>> 12 = 0o16) -> sub w | w when (w >>> 12 = 0o00) -> swab w // sys 1 ; exit | 0o104401 -> // exit r.[0] running <- false // sys 4 ; write | 0o104404 -> let arg1 = fetch() let arg2 = fetch() let bytes = mem.[arg1 .. arg1 + arg2 - 1] printf "%s" (System.Text.Encoding.ASCII.GetString bytes) | w -> printfn "%04x: %04x ???" r.[7] w running <- false