アクティブパターンでPDP11のディスアセンブラを作る


F#では[アクティブパターン](http://msdn.microsoft.com/ja-jp/library/vstudio/dd233248.aspx)を使う事でパターンマッチングのパターンを自分で作る事が出来ます。

ここでは、アクティブパターンを使って、PDP11のディスアセンブラを書くと奇麗に書けるので、その例を示します。全テストは出来てはいませんが参考にしてください。

```fsharp:
open System

module disasm =

    (* 4 6 6 bit active pattern *)
    let (|Word|_|) (i: int32) : Option<int32 * int32 * int32> =
        Some(i >>> 12, (i >>> 6) &&& 0O77, i &&& 0O77)

    (* 4 4 8 bit active pattern *)
    let (|Word2|_|) (i: int32) : Option<int32 * int32 * int32> =
        Some(i >>> 12, (i >>> 8) &&& 0O77, i &&& 0O377)

    let word(a: int32, b:int32, c:int32) : int32 =
        (a <<< 12) + (b <<< 6) + c

    let word2(a: int32, b:int32, c:int32) : int32 =
        (a <<< 12) + (b <<< 8) + c

    let disasm(word:int32):string = 
        match word with
        // 4     6     6 = 16 bit
        | Word(0, 0O00, 0O00) -> sprintf "HALT"
        | Word(0, 0O00, 0O01) -> sprintf "WAIT"
        | Word(0, 0O00, 0O02) -> sprintf "RTI"
        | Word(0, 0O00, 0O03) -> sprintf "BPT"
        | Word(0, 0O00, 0O04) -> sprintf "IOT"
        | Word(0, 0O00, 0O05) -> sprintf "RESET"
        | Word(0, 0O00, 0O06) -> sprintf "RTT"
        | Word(0, 0O00, 0O07) -> sprintf "(unused)"

        | Word(0, 0O01,   dd) -> sprintf "JMP %d" dd
        | Word(0, 0O02,    r) when (r < 0O10) -> sprintf "RTS r%d" r
        | Word(0, 0O02,    r) when (010 <= r && r <= 027) -> sprintf "(unused)"
        | Word(0, 0O02,    n) when (030 <= n && n <= 037) -> sprintf "SPL %d" (7 &&& n)
        | Word(0, 0O02, 0O40) -> sprintf "NOP"
        | Word(0, 0O02,    _) -> sprintf "cond codes"
        | Word(0, 0O03,   dd) -> sprintf "SWAB %d" dd

        | Word(0, 0O04,  xxx) -> sprintf "BR %d" xxx
        | Word(0, 0O10,  xxx) -> sprintf "BNE %d" xxx
        | Word(0, 0O14,  xxx) -> sprintf "BEQ %d" xxx
        | Word(0, 0O20,  xxx) -> sprintf "BGE %d" xxx
        | Word(0, 0O24,  xxx) -> sprintf "BLT %d" xxx
        | Word(0, 0O30,  xxx) -> sprintf "BGT %d" xxx
        | Word(0, 0O34,  xxx) -> sprintf "BLE %d" xxx
        | Word(0,    r,   dd) when ((070 &&& r) = 040) -> sprintf "JSR %d, %d" (r &&& 7) dd

        | Word(0, 0O50,   dd) -> sprintf "CLR %d" dd
        | Word(0, 0O51,   dd) -> sprintf "COM %d" dd
        | Word(0, 0O52,   dd) -> sprintf "INC %d" dd
        | Word(0, 0O53,   dd) -> sprintf "DEC %d" dd
        | Word(0, 0O54,   dd) -> sprintf "NEG %d" dd
        | Word(0, 0O55,   dd) -> sprintf "ADC %d" dd
        | Word(0, 0O56,   dd) -> sprintf "SBC %d" dd
        | Word(0, 0O57,   dd) -> sprintf "TST %d" dd

        | Word(0, 0O60,   dd) -> sprintf "ROR %d" dd
        | Word(0, 0O61,   dd) -> sprintf "ROL %d" dd
        | Word(0, 0O62,   dd) -> sprintf "ASR %d" dd
        | Word(0, 0O63,   dd) -> sprintf "ASL %d" dd
        | Word(0, 0O64,   nn) -> sprintf "MARK %d" nn
        | Word(0, 0O65,   ss) -> sprintf "MFPI %d" ss
        | Word(0, 0O66,   dd) -> sprintf "MTPI %d" dd
        | Word(0, 0O67,   dd) -> sprintf "SXT %d" dd
        | Word(0,   d1,   d2) -> sprintf "(unused)"

        | Word(1,   ss,   dd) -> sprintf "MOV %d, %d" ss dd
        | Word(2,   ss,   dd) -> sprintf "CMP %d, %d" ss dd
        | Word(3,   ss,   dd) -> sprintf "BIT %d, %d" ss dd
        | Word(4,   ss,   dd) -> sprintf "BIC %d, %d" ss dd
        | Word(5,   ss,   dd) -> sprintf "BIS %d, %d" ss dd
        | Word(6,   ss,   dd) -> sprintf "ADD %d, %d" ss dd

        | Word(7,    r,   ss) when ((r &&& 0O70) = 0O00) -> sprintf "MUL %d, %d" r ss
        | Word(7,    r,   ss) when ((r &&& 0O70) = 0O10) -> sprintf "DIV %d, %d" (r &&& 7) ss
        | Word(7,    r,   ss) when ((r &&& 0O70) = 0O20) -> sprintf "ASH %d, %d" (r &&& 7) ss
        | Word(7,    r,   ss) when ((r &&& 0O70) = 0O30) -> sprintf "ASHC %d, %d" (r &&& 7) ss
        | Word(7,    r,   dd) when ((r &&& 0O70) = 0O40) -> sprintf "XOR %d, %d" (r &&& 7) dd
        | Word(7, 0O50,    r) when ((r &&& 0O70) = 0O00) -> sprintf "FADD %d" (r &&& 7)
        | Word(7, 0O50,    r) when ((r &&& 0O70) = 0O10) -> sprintf "FSUB %d" (r &&& 7)
        | Word(7, 0O50,    r) when ((r &&& 0O70) = 0O20) -> sprintf "FMUL %d" (r &&& 7)
        | Word(7, 0O50,    r) when ((r &&& 0O70) = 0O30) -> sprintf "FDIV %d" (r &&& 7)
        | Word(7,    r,   nn) when ((r &&& 0O70) = 0O70) -> sprintf "SOB %d, %d" r nn
        | Word(7,   r1,   r2) -> sprintf "(unused)"

        | Word(8, 0O00,  xxx) -> sprintf "BPL %d" xxx
        | Word(8, 0O04,  xxx) -> sprintf "BMI %d" xxx
        | Word(8, 0O10,  xxx) -> sprintf "BHI %d" xxx
        | Word(8, 0O14,  xxx) -> sprintf "BLOS %d" xxx
        | Word(8, 0O20,  xxx) -> sprintf "BVC %d" xxx
        | Word(8, 0O24,  xxx) -> sprintf "BVS %d" xxx
        | Word(8, 0O30,  xxx) -> sprintf "BCC %d" xxx
        | Word(8, 0O34,  xxx) -> sprintf "BCS %d" xxx
        | Word(8,   v1,   v2) when(0O40 <= v1 && v1 <= 0O43) -> sprintf "EMT"
        | Word(8,   v1,   v2) when(0O44 <= v1 && v1 <= 0O47) -> sprintf "TRAP"

        | Word(8, 0O50,   dd) -> sprintf "CLRB %d" dd
        | Word(8, 0O51,   dd) -> sprintf "COMB %d" dd
        | Word(8, 0O52,   dd) -> sprintf "INCB %d" dd
        | Word(8, 0O53,   dd) -> sprintf "DECB %d" dd
        | Word(8, 0O54,   dd) -> sprintf "NEGB %d" dd
        | Word(8, 0O55,   dd) -> sprintf "ADCB %d" dd
        | Word(8, 0O56,   dd) -> sprintf "SBCB %d" dd
        | Word(8, 0O57,   dd) -> sprintf "TSTB %d" dd
        | Word(8, 0O60,   dd) -> sprintf "RORB %d" dd
        | Word(8, 0O61,   dd) -> sprintf "ROLB %d" dd
        | Word(8, 0O62,   dd) -> sprintf "ASRB %d" dd
        | Word(8, 0O63,   dd) -> sprintf "ASLB %d" dd
        | Word(8, 0O64,   dd) -> sprintf "(unused)"
        | Word(8, 0O65,   ss) -> sprintf "MFPD %d" ss
        | Word(8, 0O66,   dd) -> sprintf "MTPD %d" dd
        | Word(8,   d1,   d2) -> sprintf "(unused)"

        | Word(9,   ss,   dd) -> sprintf "MOVB %d, %d" ss dd
        | Word(10,  ss,   dd) -> sprintf "CMPB %d, %d" ss dd
        | Word(11,  ss,   dd) -> sprintf "BITB %d, %d" ss dd
        | Word(12,  ss,   dd) -> sprintf "BICB %d, %d" ss dd
        | Word(13,  ss,   dd) -> sprintf "BISB %d, %d" ss dd
        | Word(14,  ss,   dd) -> sprintf "SUB %d, %d" ss dd
        | Word(15,  d1,   d2) -> sprintf "floating point %d %d" d1 d2
        | _ -> sprintf "error %d" word

    let mutable count = 0
    let mutable ok = 0
    let mutable ng = 0

    let show(word:int32):string = 
        match word with
        | Word(a,b,c) -> sprintf "word(%d,%d,%d)" a b c
        | Word2(a,b,c) -> sprintf "word2(%d,%d,%d)" a b c
        | _ -> sprintf "error %d" word

    let test(o:int32, expected:string):unit =
        let v = disasm(o)
        if (v <> expected) then (
            Console.WriteLine("error " + show(o) + " expected is " + expected.ToString() + " but found '" + v.ToString() + "'.")
            ng <- ng + 1
        ) else
            ok <- ok + 1
    
        count <- count + 1
    
    let main =
        test(word(0,0,0), sprintf "HALT")
        test(word(0,0,1), sprintf "WAIT")
        test(word(0,0,2), sprintf "RTI")
        test(word(0,0,3), sprintf "BPT")
        test(word(0,0,4), sprintf "IOT")
        test(word(0,0,5), sprintf "RESET")
        test(word(0,0,6), sprintf "RTT")
        test(word(0,0,7), sprintf "(unused)")
        test(word(0,1,7), sprintf "JMP 7")
        test(word(0,2,1), sprintf "RTS r1")
        test(word(0,2,2), sprintf "RTS r2")
        test(word(0,2,3), sprintf "RTS r3")
        test(word(0,2,4), sprintf "RTS r4")
        test(word(0,2,8), sprintf "(unused)")
        test(word(0,2,0O10), sprintf "(unused)")
        test(word(0,2,0O27), sprintf "(unused)")
        test(word(0,2,0O30), sprintf "SPL 0")
        test(word(0,2,0O31), sprintf "SPL 1")
        test(word(0,2,0O37), sprintf "SPL 7")
        test(word(0,2,0O40), sprintf "NOP")
        test(word(0,2,0O41), sprintf "cond codes")
        test(word(0,2,0O77), sprintf "cond codes")
        test(word(0,3,0O00), sprintf "SWAB 0")
        test(word(0,3,0O77),sprintf "SWAB %d" 0O77)
        test(word(0,4,0O00), sprintf "BR 0")
        test(word(0,4,0O77),sprintf "BR %d" 0O77)
        test(word(0,0O10,0O00), sprintf "BNE 0")
        test(word(0,0O10,0O77), sprintf "BNE %d" 0O77)
        test(word(0,0O14,0O00), sprintf "BEQ 0")
        test(word(0,0O14,0O77), sprintf "BEQ %d" 0O77)
        test(word(0,0O20,0O00), sprintf "BGE 0")
        test(word(0,0O20,0O77), sprintf "BGE %d" 0O77)
        test(word(0,0O24,0O00), sprintf "BLT 0")
        test(word(0,0O24,0O77), sprintf "BLT %d" 0O77)
        test(word(0,0O30,0O00), sprintf "BGT 0")
        test(word(0,0O30,0O77), sprintf "BGT %d" 0O77)
        test(word(0,0O34,0O00), sprintf "BLE 0")
        test(word(0,0O34,0O77), sprintf "BLE %d" 0O77)
        test(word(0,0O40,0O00), sprintf "JSR 0, 0")
        test(word(0,0O47,0O77), sprintf "JSR 7, %d" 0O77)
        test(word(0,0O50,0O00), sprintf "CLR 0")
        test(word(0,0O50,0O77), sprintf "CLR %d" 0O77)
        test(word(0,0O51,0O00), sprintf "COM 0")
        test(word(0,0O51,0O77), sprintf "COM %d" 0O77)
        test(word(0,0O52,0O00), sprintf "INC 0")
        test(word(0,0O52,0O77), sprintf "INC %d" 0O77)
        test(word(0,0O53,0O00), sprintf "DEC 0")
        test(word(0,0O53,0O77), sprintf "DEC %d" 0O77)
        test(word(0,0O54,0O00), sprintf "NEG 0")
        test(word(0,0O54,0O77), sprintf "NEG %d" 0O77)
        test(word(0,0O55,0O00), sprintf "ADC 0")
        test(word(0,0O55,0O77), sprintf "ADC %d" 0O77)
        test(word(0,0O56,0O00), sprintf "SBC 0")
        test(word(0,0O56,0O77), sprintf "SBC %d" 0O77)
        test(word(0,0O57,0O00), sprintf "TST 0")
        test(word(0,0O57,0O77), sprintf "TST %d" 0O77)

        test(word(0,0O60,0O00), sprintf "ROR 0")
        test(word(0,0O60,0O77), sprintf "ROR %d" 0O77)
        test(word(0,0O61,0O00), sprintf "ROL 0")
        test(word(0,0O61,0O77), sprintf "ROL %d" 0O77)
        test(word(0,0O62,0O00), sprintf "ASR 0")
        test(word(0,0O62,0O77), sprintf "ASR %d" 0O77)
        test(word(0,0O63,0O00), sprintf "ASL 0")
        test(word(0,0O63,0O77), sprintf "ASL %d" 0O77)
        test(word(0,0O64,0O00), sprintf "MARK 0")
        test(word(0,0O64,0O77), sprintf "MARK %d" 0O77)
        test(word(0,0O65,0O00), sprintf "MFPI 0")
        test(word(0,0O65,0O77), sprintf "MFPI %d" 0O77)
        test(word(0,0O66,0O00), sprintf "MTPI 0")
        test(word(0,0O66,0O77), sprintf "MTPI %d" 0O77)
        test(word(0,0O67,0O00), sprintf "SXT 0")
        test(word(0,0O67,0O77), sprintf "SXT %d" 0O77)
        test(word(0,0O70,0O00), sprintf "(unused)")
        test(word(0,0O70,0O77), sprintf "(unused)")
        test(word(0,0O77,0O00), sprintf "(unused)")
        test(word(0,0O77,0O77), sprintf "(unused)")


        test(word(1,0O00,0O00), sprintf "MOV 0, 0")
        test(word(1,0O77,0O77), sprintf "MOV %d, %d" 0O77 0O77)
        test(word(2,0O00,0O00), sprintf "CMP 0, 0")
        test(word(2,0O77,0O77), sprintf "CMP %d, %d" 0O77 0O77)
        test(word(3,0O00,0O00), sprintf "BIT 0, 0")
        test(word(3,0O77,0O77), sprintf "BIT %d, %d" 0O77 0O77)
        test(word(4,0O00,0O00), sprintf "BIC 0, 0")
        test(word(4,0O77,0O77), sprintf "BIC %d, %d" 0O77 0O77)
        test(word(5,0O00,0O00), sprintf "BIS 0, 0")
        test(word(5,0O77,0O77), sprintf "BIS %d, %d" 0O77 0O77)
        test(word(6,0O00,0O00), sprintf "ADD 0, 0")
        test(word(6,0O77,0O77), sprintf "ADD %d, %d" 0O77 0O77)

        test(word(7,0O00,0O00), sprintf "MUL 0, 0")
        test(word(7,0O07,0O77), sprintf "MUL 7, %d" 0O77)
        test(word(7,0O10,0O00), sprintf "DIV 0, 0")
        test(word(7,0O17,0O77), sprintf "DIV 7, %d" 0O77)
        test(word(7,0O20,0O00), sprintf "ASH 0, 0")
        test(word(7,0O27,0O77), sprintf "ASH 7, %d" 0O77)
        test(word(7,0O30,0O00), sprintf "ASHC 0, 0")
        test(word(7,0O37,0O77), sprintf "ASHC 7, %d" 0O77)
        test(word(7,0O40,0O00), sprintf "XOR 0, 0")
        test(word(7,0O47,0O77), sprintf "XOR 7, %d" 0O77)


        test(word(7,0O50,0O00), sprintf "FADD 0")
        test(word(7,0O50,0O07), sprintf "FADD 7")
        test(word(7,0O50,0O10), sprintf "FSUB 0")
        test(word(7,0O50,0O17), sprintf "FSUB 7")
        test(word(7,0O50,0O20), sprintf "FMUL 0")
        test(word(7,0O50,0O27), sprintf "FMUL 7")
        test(word(7,0O50,0O30), sprintf "FDIV 0")
        test(word(7,0O50,0O37), sprintf "FDIV 7")
        
        test(word(7,0O50,0O40), sprintf "(unused)")
        test(word(7,0O50,0O77), sprintf "(unused)")
        test(word(7,0O67,0O00), sprintf "(unused)")
        test(word(7,0O67,0O77), sprintf "(unused)")
        
        test(word(0O10,0O00,0O00), sprintf "BPL 0")
        test(word(0O10,0O00,0O77), sprintf "BPL %d" 0O77)
        test(word(0O10,0O04,0O00), sprintf "BMI 0")
        test(word(0O10,0O04,0O77), sprintf "BMI %d" 0O77)
        test(word(0O10,0O10,0O00), sprintf "BHI 0")
        test(word(0O10,0O10,0O77), sprintf "BHI %d" 0O77)
        test(word(0O10,0O14,0O00), sprintf "BLOS 0")
        test(word(0O10,0O14,0O77), sprintf "BLOS %d" 0O77)
        test(word(0O10,0O20,0O00), sprintf "BVC 0")
        test(word(0O10,0O20,0O77), sprintf "BVC %d" 0O77)
        test(word(0O10,0O24,0O00), sprintf "BVS 0")
        test(word(0O10,0O24,0O77), sprintf "BVS %d" 0O77)
        test(word(0O10,0O30,0O00), sprintf "BCC 0")
        test(word(0O10,0O30,0O77), sprintf "BCC %d" 0O77)
        test(word(0O10,0O34,0O00), sprintf "BCS 0")
        test(word(0O10,0O34,0O77), sprintf "BCS %d" 0O77)

        test(word(0O10,0O40,0O00), sprintf "EMT")
        test(word(0O10,0O43,0O77), sprintf "EMT")
        test(word(0O10,0O44,0O00), sprintf "TRAP")
        test(word(0O10,0O47,0O77), sprintf "TRAP")
        
        test(word(0O10,0O50,0O00), sprintf "CLRB %d" 0)
        test(word(0O10,0O50,0O77), sprintf "CLRB %d" 0O77)
        test(word(0O10,0O51,0O00), sprintf "COMB %d" 0)
        test(word(0O10,0O51,0O77), sprintf "COMB %d" 0O77)
        test(word(0O10,0O52,0O00), sprintf "INCB %d" 0)
        test(word(0O10,0O52,0O77), sprintf "INCB %d" 0O77)
        test(word(0O10,0O53,0O00), sprintf "DECB %d" 0)
        test(word(0O10,0O53,0O77), sprintf "DECB %d" 0O77)
        test(word(0O10,0O54,0O00), sprintf "NEGB %d" 0)
        test(word(0O10,0O54,0O77), sprintf "NEGB %d" 0O77)
        test(word(0O10,0O55,0O00), sprintf "ADCB %d" 0)
        test(word(0O10,0O55,0O77), sprintf "ADCB %d" 0O77)
        test(word(0O10,0O56,0O00), sprintf "SBCB %d" 0)
        test(word(0O10,0O56,0O77), sprintf "SBCB %d" 0O77)
        test(word(0O10,0O57,0O00), sprintf "TSTB %d" 0)
        test(word(0O10,0O57,0O77), sprintf "TSTB %d" 0O77)

        test(word(0O10,0O60,0O00), sprintf "RORB %d" 0)
        test(word(0O10,0O60,0O77), sprintf "RORB %d" 0O77)
        test(word(0O10,0O61,0O00), sprintf "ROLB %d" 0)
        test(word(0O10,0O61,0O77), sprintf "ROLB %d" 0O77)
        test(word(0O10,0O62,0O00), sprintf "ASRB %d" 0)
        test(word(0O10,0O62,0O77), sprintf "ASRB %d" 0O77)
        test(word(0O10,0O63,0O00), sprintf "ASLB %d" 0)
        test(word(0O10,0O63,0O77), sprintf "ASLB %d" 0O77)
        test(word(0O10,0O64,0O00), sprintf "MTPS %d" 0)
        test(word(0O10,0O64,0O77), sprintf "MTPS %d" 0O77)
        test(word(0O10,0O64,0O00), sprintf "(unused)")
        test(word(0O10,0O64,0O77), sprintf "(unused)")
        test(word(0O10,0O65,0O00), sprintf "MFPD %d" 0)
        test(word(0O10,0O65,0O77), sprintf "MFPD %d" 0O77)
        test(word(0O10,0O66,0O00), sprintf "MTPD %d" 0)
        test(word(0O10,0O66,0O77), sprintf "MTPD %d" 0O77)
        test(word(0O10,0O67,0O00), sprintf "MFPS %d" 0)
        test(word(0O10,0O67,0O77), sprintf "MFPS %d" 0O77)
        test(word(0O10,0O67,0O00), sprintf "(unused)")
        test(word(0O10,0O67,0O77), sprintf "(unused)")
     
        test(word(0O11,0O00,0O00), sprintf "MOVB %d, %d" 0 0)
        test(word(0O11,0O77,0O77), sprintf "MOVB %d, %d" 0O77 0O77)
        test(word(0O12,0O00,0O00), sprintf "CMPB %d, %d" 0 0)
        test(word(0O12,0O77,0O77), sprintf "CMPB %d, %d" 0O77 0O77)
        test(word(0O13,0O00,0O00), sprintf "BITB %d, %d" 0 0)
        test(word(0O13,0O77,0O77), sprintf "BITB %d, %d" 0O77 0O77)
        test(word(0O14,0O00,0O00), sprintf "BICB %d, %d" 0 0)
        test(word(0O14,0O77,0O77), sprintf "BICB %d, %d" 0O77 0O77)
        test(word(0O15,0O00,0O00), sprintf "BISB %d, %d" 0 0)
        test(word(0O15,0O77,0O77), sprintf "BISB %d, %d" 0O77 0O77)
        test(word(0O16,0O00,0O00), sprintf "SUB %d, %d" 0 0)
        test(word(0O16,0O77,0O77), sprintf "SUB %d, %d" 0O77 0O77)

        test(word(0O17,0O00,0O00), sprintf "CFCC")
        test(word(0O17,0O00,0O01), sprintf "SETF")
        test(word(0O17,0O00,0O02), sprintf "SETI")
        test(word(0O17,0O00,0O11), sprintf "SETD")
        test(word(0O17,0O00,0O12), sprintf "SETL")
        test(word(0O17,0O01,0O00), sprintf "LDFPS %d" 0)
        test(word(0O17,0O01,0O77), sprintf "LDFPS %d" 0O77)
        test(word(0O17,0O02,0O00), sprintf "STFPS %d" 0)
        test(word(0O17,0O02,0O77), sprintf "STFPS %d" 0O77)
        test(word(0O17,0O03,0O00), sprintf "STST %d" 0)
        test(word(0O17,0O03,0O77), sprintf "STST %d" 0O77)
        test(word(0O17,0O04,0O00), sprintf "CLRF %d" 0)
        test(word(0O17,0O04,0O77), sprintf "CLRF %d" 0O77)
        test(word(0O17,0O05,0O00), sprintf "TSTF %d" 0)
        test(word(0O17,0O05,0O77), sprintf "TSTF %d" 0O77)
        test(word(0O17,0O06,0O00), sprintf "ABSF %d" 0)
        test(word(0O17,0O06,0O77), sprintf "ABSF %d" 0O77)
        test(word(0O17,0O07,0O00), sprintf "NEGF %d" 0)
        test(word(0O17,0O07,0O77), sprintf "NEGF %d" 0O77)
        test(word(0O17,0O10,0O00), sprintf "MULF %d, %d" 0 0O00)
        test(word(0O17,0O13,0O77), sprintf "MULF %d, %d" 3 0O77)
        test(word(0O17,0O14,0O00), sprintf "MODF %d, %d" 0 0O00)
        test(word(0O17,0O17,0O77), sprintf "MODF %d, %d" 3 0O77)

        test(word(0O17,0O20,0O00), sprintf "ADDF %d, %d" 0 0O00)
        test(word(0O17,0O23,0O77), sprintf "ADDF %d, %d" 3 0O77)
        test(word(0O17,0O24,0O00), sprintf "LDF %d, %d"  0 0O00)
        test(word(0O17,0O27,0O77), sprintf "LDF %d, %d"  3 0O77)

        test(word(0O17,0O30,0O00), sprintf "SUBF %d, %d" 0 0O00)
        test(word(0O17,0O33,0O77), sprintf "SUBF %d, %d" 3 0O77)
        test(word(0O17,0O34,0O00), sprintf "CMPF %d, %d" 0 0O00)
        test(word(0O17,0O37,0O77), sprintf "CMPF %d, %d" 3 0O77)

        test(word(0O17,0O40,0O00), sprintf "STF %d, %d" 0 0O00)
        test(word(0O17,0O43,0O77), sprintf "STF %d, %d" 3 0O77)
        test(word(0O17,0O44,0O00), sprintf "DIF %d, %d" 0 0O00)
        test(word(0O17,0O47,0O77), sprintf "DIF %d, %d" 3 0O77)

        test(word(0O17,0O50,0O00), sprintf "STEXP %d, %d" 0 0O00)
        test(word(0O17,0O53,0O77), sprintf "STEXP %d, %d" 3 0O77)
        test(word(0O17,0O54,0O00), sprintf "STCFI %d, %d" 0 0O00)
        test(word(0O17,0O57,0O77), sprintf "STCFI %d, %d" 3 0O77)

        test(word(0O17,0O60,0O00), sprintf "STCFD %d, %d" 0 0O00)
        test(word(0O17,0O63,0O77), sprintf "STCFD %d, %d" 3 0O77)
        test(word(0O17,0O64,0O00), sprintf "LDEXP %d, %d" 0 0O00)
        test(word(0O17,0O67,0O77), sprintf "LDEXP %d, %d" 3 0O77)

        test(word(0O17,0O70,0O00), sprintf "LDCIF %d, %d" 0 0O00)
        test(word(0O17,0O73,0O77), sprintf "LDCIF %d, %d" 3 0O77)
        test(word(0O17,0O74,0O00), sprintf "LDCDF %d, %d" 0 0O00)
        test(word(0O17,0O77,0O77), sprintf "LDCDF %d, %d" 3 0O77)

        test(word(0O17,0O00,0O00), sprintf "floating point %d, %d" 0 0O00)
        test(word(0O17,0O00,0O01), sprintf "floating point %d, %d" 0 0O01)
        test(word(0O17,0O00,0O02), sprintf "floating point %d, %d" 0 0O02)
        test(word(0O17,0O00,0O11), sprintf "floating point %d, %d" 0 0O11)
        test(word(0O17,0O00,0O12), sprintf "floating point %d, %d" 0 0O12)
        test(word(0O17,0O01,0O00), sprintf "floating point %d, %d" 1 0)
        test(word(0O17,0O01,0O77), sprintf "floating point %d, %d" 1 0O77)
        test(word(0O17,0O02,0O00), sprintf "floating point %d, %d" 2 0)
        test(word(0O17,0O02,0O77), sprintf "floating point %d, %d" 2 0O77)
        test(word(0O17,0O03,0O00), sprintf "floating point %d, %d" 3 0)
        test(word(0O17,0O03,0O77), sprintf "floating point %d, %d" 3 0O77)
        test(word(0O17,0O04,0O00), sprintf "floating point %d, %d" 4 0)
        test(word(0O17,0O04,0O77), sprintf "floating point %d, %d" 4 0O77)
        test(word(0O17,0O05,0O00), sprintf "floating point %d, %d" 5 0)
        test(word(0O17,0O05,0O77), sprintf "floating point %d, %d" 5 0O77)
        test(word(0O17,0O06,0O00), sprintf "floating point %d, %d" 6 0)
        test(word(0O17,0O06,0O77), sprintf "floating point %d, %d" 6 0O77)
        test(word(0O17,0O07,0O00), sprintf "floating point %d, %d" 7 0)
        test(word(0O17,0O07,0O77), sprintf "floating point %d, %d" 7 0O77)
        test(word(0O17,0O77,0O77), sprintf "floating point %d, %d" 0O77 0O77)

        Console.WriteLine(sprintf "test %d ok %d ng %d" count ok ng)

disasm.main
```