leotranslat.c 4.5 KB
/*
 *  F i l e N a m e : l e o t r a n s l a t .c
 *
 ****************************************************************************
 *                   (C) Copyright ALPS Electric Co., Ltd. 1995-1996
 ****************************************************************************
 *  Version:
 *
 *  ver       date
 *  ----   ---------
 *  1.02   '96-04-05   Change LEOVZONE_PZONEHD_TBL[] .
 *  1.01   '96-02-27   Rename file name translat.c to leotranslat.c
 *  1.00   '95-12-20   Initial Revision.
 ****************************************************************************
*/
#include <ultra64.h>
#include "leodefine.h"
#include "leodrive.h"
#include "leoappli.h"

/*************************************/
/*  PROTOTYPE                        */
/*************************************/
void leoTranslate(void);

/*************************************/
/* EXTERNAL DEFINED FUNCTIONS        */
/*************************************/
extern  u16  leoLba_to_vzone(u32 lba);

/*************************************/
/* EXTERNAL DEFINED RAMS             */
/*************************************/
extern u16 LEOVZONE_TBL[DISK_TYPES][VZONES_PER_DRV];
extern u16 LEOBYTE_TBL2[ZONES_PER_DRV];
extern u8  LEOVZONE_PZONEHD_TBL[DISK_TYPES][VZONES_PER_DRV];
extern OSMesg LEOcur_command;
extern union  leo_sys_form LEO_sys_data;
extern u8 LEOdisk_type;

/*************************************/
/*  MACRO                            */
/*************************************/
#define trans_cmd   ((LEOCmdTranslate *)LEOcur_command)

/* ==========================================================================
* Function : leoTranslate
* --------------------------------------------------------------------------
* Description : Execute translate command
* --------------------------------------------------------------------------
* IN    : LEOcur_command
* OUT   : *LEOcur_command
* ARG   : non
* RET   : non
* ==========================================================================
*/
void leoTranslate(void)
{
    u32 lba;
    u32 calc_bytes;
    u32 calc_blks;
    u32 byte_p_blk;
    u16 zone,vzone;
    u8  flag;

    if (trans_cmd->start_lba > MAX_L_LBA)
    {
        /* LBA out of range */
        trans_cmd->header.sense  = LEO_SENSE_LBA_OUT_OF_RANGE;
        trans_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
        return;
    }
    lba = trans_cmd->start_lba + SYSTEM_LBAS;

    calc_bytes = calc_blks = 0;
    flag = vzone = 1;

    if (trans_cmd->header.control & LEO_CONTROL_TBL)
    {
        /* translate byte to block */
        calc_bytes = trans_cmd->in_param;

        while (calc_bytes)
        {
            if (flag || (lba == LEOVZONE_TBL[LEOdisk_type][vzone]))
            {
                vzone      = leoLba_to_vzone(lba);
                zone       = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
                if (zone > (u8)7)
                    zone -= (u8)7;
                byte_p_blk = LEOBYTE_TBL2[zone];
            }

            if (calc_bytes < byte_p_blk)
                calc_bytes = 0;
            else
                calc_bytes -= byte_p_blk;

            calc_blks++;
            lba++;

            if ((calc_bytes) && (lba > (u32)MAX_P_LBA))
            {
                trans_cmd->header.sense  = LEO_SENSE_LBA_OUT_OF_RANGE;
                trans_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
                return;
            }
            flag = 0;
        }
        trans_cmd->out_param = calc_blks;
    }
    else
    {
        /* translate block to byte */
        calc_blks = trans_cmd->in_param;

        while (calc_blks)
        {
            if (flag || (lba == LEOVZONE_TBL[LEOdisk_type][vzone]))
            {
                vzone      = leoLba_to_vzone(lba);
                zone       = LEOVZONE_PZONEHD_TBL[LEOdisk_type][vzone];
                if (zone > (u8)7)
                    zone -= (u8)7;
                byte_p_blk = LEOBYTE_TBL2[zone];
            }

            calc_bytes += byte_p_blk;
            calc_blks--;
            lba++;

            if ((calc_blks) && (lba > (u32)MAX_P_LBA))
            {
                trans_cmd->header.sense  = LEO_SENSE_LBA_OUT_OF_RANGE;
                trans_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
                return;
            }
            flag = 0;
        }
        trans_cmd->out_param = calc_bytes;
    }
#ifdef _ERRCHK
    if (trans_cmd->header.sense = trans_cmd->header.reserve1 )
        trans_cmd->header.status = LEO_STATUS_CHECK_CONDITION;
    else
        trans_cmd->header.status = LEO_STATUS_GOOD;
#else
    trans_cmd->header.status = LEO_STATUS_GOOD;
#endif
}