マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

EFlags #10

今回はEFlagsクラスを定義する。EFlagsに関してはhttp://www.intel.com/jp/download/index.htmの『IA-32 インテル® アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル、上巻: 基本アーキテクチャー』に載っている。ここに載っている全てを定義するわけではないが、よく使われる四則演算で変更され条件分岐で使われるフラグと、string命令で使われる方向を表すフラグや、割り込みの許可・禁止を設定するフラグを定義しておく。

class EFlags
    attr_accessor :flags
    
    def initialize()
        @flags = 0
    end
    
    def set_carry(carry)
        carry_flag = 0x01;
        
        if carry then
            @flags |= carry_flag;
        else
            @flags &= ~carry_flag;
        end
    end
    
    def carry?()
        return (@flags & 0x01) == 0x01;
    end
    
    def set_parity!(parity)
        parity_flag = 0x01 << 0x02;
        
        if parity then
            @flags |= parity_flag;
        else
            @flags &= ~parity_flag;
        end
    end
    
    def parity?()
        parity = (@flags >> 0x02) & 0x01;
        return parity == 0x01;
    end
    
    def set_adjust!(adjust)
        adjust_flag = 0x01 << 0x04;
        
        if adjust then
            @flags |= adjust_flag;
        else
            @flags &= ~adjust_flag;
        end
    end
    
    def adjust?()
        adjust = (@flags >> 0x04) & 0x01;
        return adjust == 0x01;
    end
    
    def set_zero!(zero)
        zero_flag = 0x01 << 0x06;
        
        if zero then
            @flags |= zero_flag;
        else
            @flags &= ~zero_flag;
        end
    end
    
    def zero?()
        zero = (@flags >> 0x06) & 0x01;
        return zero == 0x01;
    end
    
    def set_sign!(sign)
        sign_flag = 0x01 << 0x07;
        
        if sign then
            @flags |= sign_flag;
        else
            @flags &= ~sign_flag;
        end
    end
    
    def sign?()
        sign = (@flags >> 0x07) & 0x01;
        return sign == 0x01;
    end
    
    def set_interrupt!(interrupt)
        interrupt_flag = 0x01 << 0x09;
        
        if interrupt then
            @flags |= interrupt_flag;
        else
            @flags &= ~interrupt_flag;
        end
    end
    
    def interrupt?()
        interrupt = (@flags >> 0x09) & 0x01;
        return interrupt == 0x01;
    end
    
    def set_direction!(direction)
        direction_flag = 0x01 << 0x0A;
        
        if direction then
            @flags |= direction_flag;
        else
            @flags &= ~direction_flag;
        end
    end
    
    def direction?()
        direction = (@flags >> 0x0A) & 0x01;
        return direction == 0x01;
    end
    
    def set_overflow!(overflow)
        overflow_flag = 0x01 << 0x0B;
        
        if overflow then
            @flags |= overflow_flag;
        else
            @flags &= ~overflow_flag;
        end
    end
    
    def overflow?()
        overflow = (@flags >> 0x0B) & 0x01;
        return overflow == 0x01;
    end
end