pub fn decode_semihostcmd(
    r0: u32,
    r1: u32,
    processor: &mut Processor,
) -> Result<SemihostingCommand, Fault> {
    let result = match r0 {
        SYS_OPEN => {
            let argument_block = r1;

            let mut string_ptr = processor.read32(argument_block)?;
            let mode = processor.read32(argument_block + 4)?;
            let mut filename_len = processor.read32(argument_block + 8)?;
            let mut string_bytes: Vec<u8> = Vec::new();

            while filename_len > 0 {
                string_bytes.push(processor.read8(string_ptr)?);
                string_ptr += 1;
                filename_len -= 1;
            }

            SemihostingCommand::SysOpen {
                name: String::from_utf8(string_bytes).unwrap(),
                mode,
            }
        }
        SYS_CLOSE => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            SemihostingCommand::SysClose { handle }
        }
        SYS_WRITE => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let mut memoryptr = processor.read32(params_ptr + 4)?;
            let mut len = processor.read32(params_ptr + 8)?;

            let mut data: Vec<u8> = Vec::new();

            // :tt console output
            while len > 0 {
                data.push(processor.read8(memoryptr)?);
                memoryptr += 1;
                len -= 1;
            }
            SemihostingCommand::SysWrite { handle, data }
        }
        SYS_READ => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let memoryptr = processor.read32(params_ptr + 4)?;
            let len = processor.read32(params_ptr + 8)?;

            SemihostingCommand::SysRead {
                handle,
                memoryptr,
                len,
            }
        }
        SYS_FLEN => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;

            SemihostingCommand::SysFlen { handle }
        }
        SYS_ISTTY => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;

            SemihostingCommand::SysIstty { handle }
        }
        SYS_SEEK => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let position = processor.read32(params_ptr + 4)?;

            SemihostingCommand::SysSeek { handle, position }
        }
        SYS_CLOCK => SemihostingCommand::SysClock,
        SYS_ERRNO => SemihostingCommand::SysErrno,
        SYS_EXIT_EXTENDED => {
            let params_ptr = r1;
            let reason = SysExceptionReason::from_u32(processor.read32(params_ptr)?);
            let subcode = processor.read32(params_ptr + 4)?;

            SemihostingCommand::SysExitExtended { reason, subcode }
        }
        SYS_EXIT => SemihostingCommand::SysException {
            reason: SysExceptionReason::from_u32(r1),
        },
        _ => {
            todo!("unknown semihosting command {}", r0);
        }
    };
    Ok(result)
}
///
/// Decode semihosting command based on register values
///
Decode semihosting command based on register values
Decode semihosting command based on register values
pub fn decode_semihostcmd(
    r0: u32,
    r1: u32,
    processor: &mut Processor,
) -> Result<SemihostingCommand, Fault> {
    let result = match r0 {
        SYS_OPEN => {
            let argument_block = r1;
            let mut string_ptr = processor.read32(argument_block)?;
            let mode = processor.read32(argument_block + 4)?;
            let mut filename_len = processor.read32(argument_block + 8)?;
            let mut string_bytes: Vec<u8> = Vec::new();
            while filename_len > 0 {
                string_bytes.push(processor.read8(string_ptr)?);
                string_ptr += 1;
                filename_len -= 1;
            }
            SemihostingCommand::SysOpen {
                name: String::from_utf8(string_bytes).unwrap(),
                mode,
            }
        }
        SYS_CLOSE => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            SemihostingCommand::SysClose { handle }
        }
        SYS_WRITE => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let mut memoryptr = processor.read32(params_ptr + 4)?;
            let mut len = processor.read32(params_ptr + 8)?;
            let mut data: Vec<u8> = Vec::new();
            // :tt console output
            while len > 0 {
                data.push(processor.read8(memoryptr)?);
                memoryptr += 1;
                len -= 1;
            }
            SemihostingCommand::SysWrite { handle, data }
        }
        SYS_READ => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let memoryptr = processor.read32(params_ptr + 4)?;
            let len = processor.read32(params_ptr + 8)?;
            SemihostingCommand::SysRead {
                handle,
                memoryptr,
                len,
            }
        }
        SYS_FLEN => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            SemihostingCommand::SysFlen { handle }
        }
        SYS_ISTTY => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            SemihostingCommand::SysIstty { handle }
        }
        SYS_SEEK => {
            let params_ptr = r1;
            let handle = processor.read32(params_ptr)?;
            let position = processor.read32(params_ptr + 4)?;
            SemihostingCommand::SysSeek { handle, position }
        }
        SYS_CLOCK => SemihostingCommand::SysClock,
        SYS_ERRNO => SemihostingCommand::SysErrno,
        SYS_EXIT_EXTENDED => {
            let params_ptr = r1;
            let reason = SysExceptionReason::from_u32(processor.read32(params_ptr)?);
            let subcode = processor.read32(params_ptr + 4)?;
            SemihostingCommand::SysExitExtended { reason, subcode }
        }
        SYS_EXIT => SemihostingCommand::SysException {
            reason: SysExceptionReason::from_u32(r1),
        },
        _ => {
            todo!("unknown semihosting command {}", r0);
        }
    };
    Ok(result)
}
pub fn decode_semihostcmd ( r0 : u32 , r1 : u32 , processor : & mut Processor , ) -> Result < SemihostingCommand , Fault > { let result = match r0 { SYS_OPEN => { let argument_block = r1 ; let mut string_ptr = processor . read32 ( argument_block ) ? ; let mode = processor . read32 ( argument_block + 4 ) ? ; let mut filename_len = processor . read32 ( argument_block + 8 ) ? ; let mut string_bytes : Vec < u8 > = Vec :: new ( ) ; while filename_len > 0 { string_bytes . push ( processor . read8 ( string_ptr ) ? ) ; string_ptr += 1 ; filename_len -= 1 ; } SemihostingCommand :: SysOpen { name : String :: from_utf8 ( string_bytes ) . unwrap ( ) , mode , } } SYS_CLOSE => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; SemihostingCommand :: SysClose { handle } } SYS_WRITE => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; let mut memoryptr = processor . read32 ( params_ptr + 4 ) ? ; let mut len = processor . read32 ( params_ptr + 8 ) ? ; let mut data : Vec < u8 > = Vec :: new ( ) ; // :tt console output while len > 0 { data . push ( processor . read8 ( memoryptr ) ? ) ; memoryptr += 1 ; len -= 1 ; } SemihostingCommand :: SysWrite { handle , data } } SYS_READ => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; let memoryptr = processor . read32 ( params_ptr + 4 ) ? ; let len = processor . read32 ( params_ptr + 8 ) ? ; SemihostingCommand :: SysRead { handle , memoryptr , len , } } SYS_FLEN => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; SemihostingCommand :: SysFlen { handle } } SYS_ISTTY => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; SemihostingCommand :: SysIstty { handle } } SYS_SEEK => { let params_ptr = r1 ; let handle = processor . read32 ( params_ptr ) ? ; let position = processor . read32 ( params_ptr + 4 ) ? ; SemihostingCommand :: SysSeek { handle , position } } SYS_CLOCK => SemihostingCommand :: SysClock , SYS_ERRNO => SemihostingCommand :: SysErrno , SYS_EXIT_EXTENDED => { let params_ptr = r1 ; let reason = SysExceptionReason :: from_u32 ( processor . read32 ( params_ptr ) ? ) ; let subcode = processor . read32 ( params_ptr + 4 ) ? ; SemihostingCommand :: SysExitExtended { reason , subcode } } SYS_EXIT => SemihostingCommand :: SysException { reason : SysExceptionReason :: from_u32 ( r1 ) , } , _ => { todo ! ( " " r0 ) ; } } ; Ok ( result ) }
Decode semihosting command based on register values
Decode semihosting command based on register values
r0
u32
r1
u32
processor
&mut Processor
r0
u32
r1
u32
processor
&mut Processor