[haiku-commits] r42538 - in haiku/trunk/src/add-ons/accelerants/radeon_hd: . atombios

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 2 Aug 2011 08:07:50 +0200 (CEST)

Author: kallisti5
Date: 2011-08-02 08:07:49 +0200 (Tue, 02 Aug 2011)
New Revision: 42538
Changeset: https://dev.haiku-os.org/changeset/42538

Added:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp
Removed:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.c
Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile
   haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-bits.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.h
Log:
* Initial work on bios_init for setting up AtomBIOS parser
* Refactor AtomBIOS parser to use non-linux-kernel calls
  (normally I would keep it as-is and do wrappers, but the
  AtomBIOS parser has been rewritten from scratch twice
  by its creator  in the last 5 years.. so eh.
* Refactor AtomBIOS parser to be more haiku-like stylewise


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile       2011-08-02 
05:00:22 UTC (rev 42537)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/Jamfile       2011-08-02 
06:07:49 UTC (rev 42538)
@@ -9,7 +9,7 @@
 UsePrivateHeaders [ FDirName graphics common ] ;
 
 Addon radeon_hd.accelerant :
-       #atombios/atom.c
+       atombios/atom.cpp
        accelerant.cpp
        engine.cpp
        hooks.cpp

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp        
2011-08-02 05:00:22 UTC (rev 42537)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.cpp        
2011-08-02 06:07:49 UTC (rev 42538)
@@ -218,6 +218,9 @@
        init_lock(&info.accelerant_lock, "radeon hd accelerant");
        init_lock(&info.engine_lock, "radeon hd engine");
 
+       // Init AtomBIOS
+       bios_init();
+
        status = detect_displays();
        //if (status != B_OK)
        //      return status;

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-bits.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-bits.h  
2011-08-02 05:00:22 UTC (rev 42537)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-bits.h  
2011-08-02 06:07:49 UTC (rev 42538)
@@ -25,21 +25,21 @@
 #ifndef ATOM_BITS_H
 #define ATOM_BITS_H
 
-static inline uint8_t get_u8(void *bios, int ptr)
+static inline uint8 get_u8(void *bios, int ptr)
 {
     return ((unsigned char *)bios)[ptr];
 }
 #define U8(ptr) get_u8(ctx->ctx->bios,(ptr))
 #define CU8(ptr) get_u8(ctx->bios,(ptr))
-static inline uint16_t get_u16(void *bios, int ptr)
+static inline uint16 get_u16(void *bios, int ptr)
 {
-    return get_u8(bios,ptr)|(((uint16_t)get_u8(bios,ptr+1))<<8);
+    return get_u8(bios,ptr)|(((uint16)get_u8(bios,ptr+1))<<8);
 }
 #define U16(ptr) get_u16(ctx->ctx->bios,(ptr))
 #define CU16(ptr) get_u16(ctx->bios,(ptr))
-static inline uint32_t get_u32(void *bios, int ptr)
+static inline uint32 get_u32(void *bios, int ptr)
 {
-    return get_u16(bios,ptr)|(((uint32_t)get_u16(bios,ptr+2))<<16);
+    return get_u16(bios,ptr)|(((uint32)get_u16(bios,ptr+2))<<16);
 }
 #define U32(ptr) get_u32(ctx->ctx->bios,(ptr))
 #define CU32(ptr) get_u32(ctx->bios,(ptr))

Copied: haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp (from 
rev 42535, haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.c)
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp             
                (rev 0)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp     
2011-08-02 06:07:49 UTC (rev 42538)
@@ -0,0 +1,1121 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.  
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Stanislaw Skowronek
+ */
+
+/* Reworked for the Haiku Operating System Radeon HD driver
+ * Author:
+ *     Alexander von Gluck, kallisti5@xxxxxxxxxxx
+ */
+
+
+#include <Debug.h>
+
+#include "atom.h"
+#include "atom-names.h"
+#include "atom-bits.h"
+
+
+#undef TRACE
+
+#define TRACE_ATOM
+#ifdef TRACE_ATOM
+#   define TRACE(x...) _sPrintf("radeon_hd: " x)
+#else
+#   define TRACE(x...) ;
+#endif
+
+
+#define ATOM_COND_ABOVE                0
+#define ATOM_COND_ABOVEOREQUAL 1
+#define ATOM_COND_ALWAYS       2
+#define ATOM_COND_BELOW                3
+#define ATOM_COND_BELOWOREQUAL 4
+#define ATOM_COND_EQUAL                5
+#define ATOM_COND_NOTEQUAL     6
+
+#define ATOM_PORT_ATI  0
+#define ATOM_PORT_PCI  1
+#define ATOM_PORT_SYSIO        2
+
+#define ATOM_UNIT_MICROSEC     0
+#define ATOM_UNIT_MILLISEC     1
+
+#define PLL_INDEX      2
+#define PLL_DATA       3
+
+typedef struct {
+       atom_context *ctx;
+
+       uint32 *ps, *ws;
+       int ps_shift;
+       uint16 start;
+} atom_exec_context;
+
+int atom_debug = 0;
+void atom_execute_table(atom_context *ctx, int index, uint32 *params);
+
+static uint32 atom_arg_mask[8] = {0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000,
+       0xFF, 0xFF00, 0xFF0000, 0xFF000000};
+static int atom_arg_shift[8] = {0, 0, 8, 16, 0, 8, 16, 24};
+static int atom_dst_to_src[8][4] = {
+       // translate destination alignment field to the source alignment 
encoding
+       { 0, 0, 0, 0 },
+       { 1, 2, 3, 0 },
+       { 1, 2, 3, 0 },
+       { 1, 2, 3, 0 },
+       { 4, 5, 6, 7 },
+       { 4, 5, 6, 7 },
+       { 4, 5, 6, 7 },
+       { 4, 5, 6, 7 },
+};
+static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 };
+
+static int debug_depth = 0;
+
+static uint32
+atom_iio_execute(atom_context *ctx, int base, uint32 index, uint32 data)
+{
+       uint32 temp = 0xCDCDCDCD;
+       while (1)
+       switch(CU8(base)) {
+       case ATOM_IIO_NOP:
+               base++;
+               break;
+       case ATOM_IIO_READ:
+               temp = ctx->card->reg_read(CU16(base + 1));
+               base+=3;
+               break;
+       case ATOM_IIO_WRITE:
+               ctx->card->reg_write(CU16(base + 1), temp);
+               base+=3;
+               break;
+       case ATOM_IIO_CLEAR:
+               temp &= ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 
2));
+               base+=3;
+               break;
+       case ATOM_IIO_SET:
+               temp |= (0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 2);
+               base+=3;
+               break;
+       case ATOM_IIO_MOVE_INDEX:
+               temp &= ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 
2));
+               temp |= ((index >> CU8(base + 2))
+                       & (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + 
3);
+               base+=4;
+               break;
+       case ATOM_IIO_MOVE_DATA:
+               temp &= ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 
2));
+               temp |= ((data >> CU8(base + 2))
+                       & (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + 
3);
+               base+=4;
+               break;
+       case ATOM_IIO_MOVE_ATTR:
+               temp &= ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + 
2));
+               temp |= ((ctx->io_attr >> CU8(base + 2))
+                       & (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + 
3);
+               base+=4;
+               break;
+       case ATOM_IIO_END:
+               return temp;
+       default:
+               TRACE("Unknown IIO opcode.\n");
+               return 0;
+       }
+}
+
+
+static uint32
+atom_get_src_int(atom_exec_context *ctx, uint8 attr, int *ptr,
+       uint32 *saved, int print)
+{
+       uint32 idx, val = 0xCDCDCDCD, align, arg;
+       atom_context *gctx = ctx->ctx;
+       arg = attr & 7;
+       align = (attr >> 3) & 7;
+       switch(arg) {
+       case ATOM_ARG_REG:
+       idx = U16(*ptr);
+       (*ptr)+=2;
+       idx += gctx->reg_block;
+       switch(gctx->io_mode) {
+       case ATOM_IO_MM:
+               val = gctx->card->reg_read(idx);
+               break;
+       case ATOM_IO_PCI:
+               TRACE("PCI registers are not implemented.\n");
+               return 0;
+       case ATOM_IO_SYSIO:
+               TRACE("SYSIO registers are not implemented.\n");
+               return 0;
+       default:
+               if (!(gctx->io_mode&0x80)) {
+               TRACE("Bad IO mode.\n");
+               return 0;
+               }
+               if (!gctx->iio[gctx->io_mode&0x7F]) {
+               TRACE("Undefined indirect IO read method %d.\n", 
gctx->io_mode&0x7F);
+               return 0;
+               }
+               val = atom_iio_execute(gctx, gctx->iio[gctx->io_mode&0x7F], 
idx, 0);
+       }
+       break;
+       case ATOM_ARG_PS:
+       idx = U8(*ptr);
+       (*ptr)++;
+       val = ctx->ps[idx];
+       break;
+       case ATOM_ARG_WS:
+       idx = U8(*ptr);
+       (*ptr)++;
+       switch(idx) {
+       case ATOM_WS_QUOTIENT:
+               val = gctx->divmul[0];
+               break;
+       case ATOM_WS_REMAINDER:
+               val = gctx->divmul[1];
+               break;
+       case ATOM_WS_DATAPTR:
+               val = gctx->data_block;
+               break;
+       case ATOM_WS_SHIFT:
+               val = gctx->shift;
+               break;
+       case ATOM_WS_OR_MASK:
+               val = 1<<gctx->shift;
+               break;
+       case ATOM_WS_AND_MASK:
+               val = ~(1<<gctx->shift);
+               break;
+       case ATOM_WS_FB_WINDOW:
+               val = gctx->fb_base;
+               break;
+       case ATOM_WS_ATTRIBUTES:
+               val = gctx->io_attr;
+               break;
+       default:
+               val = ctx->ws[idx];
+       }
+       break;
+       case ATOM_ARG_ID:
+       idx = U16(*ptr);
+       (*ptr)+=2;
+       val = U32(idx + gctx->data_block);
+       break;
+       case ATOM_ARG_FB:
+       idx = U8(*ptr);
+       (*ptr)++;
+       TRACE("FB access is not implemented.\n");
+       return 0;
+       case ATOM_ARG_IMM:
+       switch(align) {
+       case ATOM_SRC_DWORD:
+               val = U32(*ptr);
+               (*ptr)+=4;
+               return val;
+       case ATOM_SRC_WORD0:
+       case ATOM_SRC_WORD8:
+       case ATOM_SRC_WORD16:
+               val = U16(*ptr);
+               (*ptr)+=2;
+               return val;
+       case ATOM_SRC_BYTE0:
+       case ATOM_SRC_BYTE8:
+       case ATOM_SRC_BYTE16:
+       case ATOM_SRC_BYTE24:
+               val = U8(*ptr);
+               (*ptr)++;
+               return val;
+       }
+       return 0;
+       case ATOM_ARG_PLL:
+       idx = U8(*ptr);
+       (*ptr)++;
+       gctx->card->reg_write(PLL_INDEX, idx);
+       val = gctx->card->reg_read(PLL_DATA);
+       break;
+       case ATOM_ARG_MC:
+       idx = U8(*ptr);
+       (*ptr)++;
+       TRACE("MC registers are not implemented.\n");
+       return 0;
+       }
+       if (saved)
+       *saved = val;
+       val &= atom_arg_mask[align];
+       val >>= atom_arg_shift[align];
+       return val;
+}
+
+
+static void
+atom_skip_src_int(atom_exec_context *ctx, uint8 attr, int *ptr)
+{
+       uint32 align = (attr >> 3) & 7, arg = attr & 7;
+       switch(arg) {
+               case ATOM_ARG_REG:
+               case ATOM_ARG_ID:
+                       (*ptr)+=2;
+                       break;
+               case ATOM_ARG_PLL:
+               case ATOM_ARG_MC:
+               case ATOM_ARG_PS:
+               case ATOM_ARG_WS:
+               case ATOM_ARG_FB:
+                       (*ptr)++;
+                       break;
+               case ATOM_ARG_IMM:
+               switch(align) {
+                       case ATOM_SRC_DWORD:
+                               (*ptr)+=4;
+                               return;
+                       case ATOM_SRC_WORD0:
+                       case ATOM_SRC_WORD8:
+                       case ATOM_SRC_WORD16:
+                               (*ptr)+=2;
+                               return;
+                       case ATOM_SRC_BYTE0:
+                       case ATOM_SRC_BYTE8:
+                       case ATOM_SRC_BYTE16:
+                       case ATOM_SRC_BYTE24:
+                               (*ptr)++;
+                               return;
+               }
+               return;
+       }
+}
+
+
+static uint32
+atom_get_src(atom_exec_context *ctx, uint8 attr, int *ptr)
+{
+       return atom_get_src_int(ctx, attr, ptr, NULL, 1);
+}
+
+
+static uint32
+atom_get_dst(atom_exec_context *ctx, int arg, uint8 attr,
+       int *ptr, uint32 *saved, int print)
+{
+       return atom_get_src_int(ctx,
+               arg|atom_dst_to_src[(attr>>3)&7][(attr>>6)&3]<<3, ptr, saved, 
print);
+}
+
+
+static void
+atom_skip_dst(atom_exec_context *ctx, int arg, uint8 attr, int *ptr)
+{
+       atom_skip_src_int(ctx,
+               arg|atom_dst_to_src[(attr>>3)&7][(attr>>6)&3]<<3, ptr);
+}
+
+
+static void
+atom_put_dst(atom_exec_context *ctx, int arg, uint8 attr,
+       int *ptr, uint32 val, uint32 saved)
+{
+       uint32 align = atom_dst_to_src[(attr>>3)&7][(attr>>6)&3],
+               old_val = val, idx;
+       atom_context *gctx = ctx->ctx;
+       old_val &= atom_arg_mask[align] >> atom_arg_shift[align];
+       val <<= atom_arg_shift[align];
+       val &= atom_arg_mask[align];
+       saved &= ~atom_arg_mask[align];
+       val |= saved;
+       switch(arg) {
+       case ATOM_ARG_REG:
+       idx = U16(*ptr);
+       (*ptr)+=2;
+       idx += gctx->reg_block;
+       switch(gctx->io_mode) {
+       case ATOM_IO_MM:
+               if (idx == 0)
+               gctx->card->reg_write(idx, val<<2);
+               else
+               gctx->card->reg_write(idx, val);
+               break;
+       case ATOM_IO_PCI:
+               TRACE("PCI registers are not implemented.\n");
+               return;
+       case ATOM_IO_SYSIO:
+               TRACE("SYSIO registers are not implemented.\n");
+               return;
+       default:
+               if (!(gctx->io_mode&0x80)) {
+               TRACE("Bad IO mode.\n");
+               return;
+               }
+               if (!gctx->iio[gctx->io_mode&0xFF]) {
+                       return;
+               }
+               atom_iio_execute(gctx, gctx->iio[gctx->io_mode&0xFF], idx, val);
+       }
+       break;
+       case ATOM_ARG_PS:
+       idx = U8(*ptr);
+       (*ptr)++;
+       ctx->ps[idx] = val;
+       break;
+       case ATOM_ARG_WS:
+       idx = U8(*ptr);
+       (*ptr)++;
+       switch(idx) {
+       case ATOM_WS_QUOTIENT:
+               gctx->divmul[0] = val;
+               break;
+       case ATOM_WS_REMAINDER:
+               gctx->divmul[1] = val;
+               break;
+       case ATOM_WS_DATAPTR:
+               gctx->data_block = val;
+               break;
+       case ATOM_WS_SHIFT:
+               gctx->shift = val;
+               break;
+       case ATOM_WS_OR_MASK:
+       case ATOM_WS_AND_MASK:
+               break;
+       case ATOM_WS_FB_WINDOW:
+               gctx->fb_base = val;
+               break;
+       case ATOM_WS_ATTRIBUTES:
+               gctx->io_attr = val;
+               break;
+       default:
+               ctx->ws[idx] = val;
+       }
+       break;
+       case ATOM_ARG_FB:
+       idx = U8(*ptr);
+       (*ptr)++;
+       TRACE("FB access is not implemented.\n");
+       return;
+       case ATOM_ARG_PLL:
+       idx = U8(*ptr);
+       (*ptr)++;
+       gctx->card->reg_write(PLL_INDEX, idx);
+       gctx->card->reg_write(PLL_DATA, val);
+       break;
+       case ATOM_ARG_MC:
+       idx = U8(*ptr);
+       (*ptr)++;
+       TRACE("MC registers are not implemented.\n");
+       return;
+       }
+}
+
+
+static void
+atom_op_add(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       dst += src;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_and(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       dst &= src;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("ATOM BIOS beeped!\n");
+}
+
+
+static void
+atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
+{
+       int idx = U8((*ptr)++);
+       TRACE("   table: %d\n", idx);
+       if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
+       atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+}
+
+
+static void
+atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 saved;
+       int dptr = *ptr;
+       attr &= 0x38;
+       attr |= atom_def_dst[attr>>3]<<6;
+       atom_get_dst(ctx, arg, attr, ptr, &saved, 0);
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, 0, saved);
+}
+
+
+static void
+atom_op_compare(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src;
+       TRACE("   src1: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
+       TRACE("   src2: ");
+       src = atom_get_src(ctx, attr, ptr);
+       ctx->ctx->cs_equal = (dst == src);
+       ctx->ctx->cs_above = (dst > src);
+       TRACE("   result: %s %s\n", ctx->ctx->cs_equal ? "EQ" : "NE",
+               ctx->ctx->cs_above ? "GT" : "LE");
+}
+
+
+static void
+atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 count = U8((*ptr)++);
+       TRACE("   count: %d\n", count);
+       if (arg == ATOM_UNIT_MICROSEC) {
+               // Microseconds
+               usleep(count);
+       } else {
+               // TODO : check
+               // Milliseconds
+               usleep(count);
+       }
+}
+
+
+static void
+atom_op_div(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src;
+       TRACE("   src1: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
+       TRACE("   src2: ");
+       src = atom_get_src(ctx, attr, ptr);
+       if (src != 0) {
+               ctx->ctx->divmul[0] = dst / src;
+               ctx->ctx->divmul[1] = dst%src;
+       } else {
+               ctx->ctx->divmul[0] = 0;
+               ctx->ctx->divmul[1] = 0;
+       }
+}
+
+
+static void
+atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)
+{
+       /* functionally, a nop */
+}
+
+
+static void
+atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
+{
+       int execute = 0, target = U16(*ptr);
+       (*ptr)+=2;
+       switch(arg) {
+       case ATOM_COND_ABOVE:
+       execute = ctx->ctx->cs_above;
+       break;
+       case ATOM_COND_ABOVEOREQUAL:
+       execute = ctx->ctx->cs_above || ctx->ctx->cs_equal;
+       break;
+       case ATOM_COND_ALWAYS:
+       execute = 1;
+       break;
+       case ATOM_COND_BELOW:
+       execute = !(ctx->ctx->cs_above || ctx->ctx->cs_equal);
+       break;
+       case ATOM_COND_BELOWOREQUAL:
+       execute = !ctx->ctx->cs_above;
+       break;
+       case ATOM_COND_EQUAL:
+       execute = ctx->ctx->cs_equal;
+       break;
+       case ATOM_COND_NOTEQUAL:
+       execute = !ctx->ctx->cs_equal;
+       break;
+       }
+       if (arg != ATOM_COND_ALWAYS)
+       TRACE("   taken: %s\n", execute?"yes":"no");
+       TRACE("   target: 0x%04X\n", target);
+       if (execute)
+       *ptr = ctx->start + target;
+}
+
+
+static void
+atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src1, src2, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src1: ");
+       src1 = atom_get_src(ctx, attr, ptr);
+       TRACE("   src2: ");
+       src2 = atom_get_src(ctx, attr, ptr);
+       dst &= src1;
+       dst |= src2;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_move(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 src, saved;
+       int dptr = *ptr;
+       if (((attr>>3)&7) != ATOM_SRC_DWORD)
+       atom_get_dst(ctx, arg, attr, ptr, &saved, 0);
+       else {
+       atom_skip_dst(ctx, arg, attr, ptr);
+       saved = 0xCDCDCDCD;
+       }
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, src, saved);
+}
+
+
+static void
+atom_op_mul(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src;
+       TRACE("   src1: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
+       TRACE("   src2: ");
+       src = atom_get_src(ctx, attr, ptr);
+       ctx->ctx->divmul[0] = dst * src;
+}
+
+
+static void
+atom_op_nop(atom_exec_context *ctx, int *ptr, int arg)
+{
+       /* nothing */
+}
+
+
+static void
+atom_op_or(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       dst |= src;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_postcard(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("unimplemented!\n");
+}
+
+
+static void atom_op_repeat(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("unimplemented!\n");
+}
+
+
+static void
+atom_op_restorereg(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("unimplemented!\n");
+}
+
+
+static void
+atom_op_savereg(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("unimplemented!\n");
+}
+
+
+static void
+atom_op_setdatablock(atom_exec_context *ctx, int *ptr, int arg)
+{
+       int idx = U8(*ptr);
+       (*ptr)++;
+       TRACE("   block: %d\n", idx);
+       if (!idx)
+       ctx->ctx->data_block = 0;
+       else if (idx==255)
+       ctx->ctx->data_block = ctx->start;
+       else
+       ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2 * idx);
+}
+
+
+static void
+atom_op_setfbbase(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       TRACE("   fb_base: ");
+       ctx->ctx->fb_base = atom_get_src(ctx, attr, ptr);
+}
+
+
+static void
+atom_op_setport(atom_exec_context *ctx, int *ptr, int arg)
+{
+       int port;
+       switch(arg) {
+       case ATOM_PORT_ATI:
+       port = U16(*ptr);
+       TRACE("   port: %d\n", port);
+       if (!port)
+               ctx->ctx->io_mode = ATOM_IO_MM;
+       else
+               ctx->ctx->io_mode = ATOM_IO_IIO|port;
+       (*ptr)+=2;
+       break;
+       case ATOM_PORT_PCI:
+       ctx->ctx->io_mode = ATOM_IO_PCI;
+       (*ptr)++;
+       break;
+       case ATOM_PORT_SYSIO:
+       ctx->ctx->io_mode = ATOM_IO_SYSIO;
+       (*ptr)++;
+       break;
+       }
+}
+
+
+static void
+atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg)
+{
+       ctx->ctx->reg_block = U16(*ptr);
+       (*ptr)+=2;
+}
+
+
+static void
+atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++), shift;
+       uint32 saved, dst;
+       int dptr = *ptr;
+       attr &= 0x38;
+       attr |= atom_def_dst[attr>>3]<<6;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       shift = U8((*ptr)++);
+       TRACE("   shift: %d\n", shift);
+       dst <<= shift;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++), shift;
+       uint32 saved, dst;
+       int dptr = *ptr;
+       attr &= 0x38;
+       attr |= atom_def_dst[attr>>3]<<6;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       shift = U8((*ptr)++);
+       TRACE("   shift: %d\n", shift);
+       dst >>= shift;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_sub(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       dst -= src;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_switch(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 src, val, target;
+       TRACE("   switch: ");
+       src = atom_get_src(ctx, attr, ptr);
+       while (U16(*ptr) != ATOM_CASE_END)
+       if (U8(*ptr) == ATOM_CASE_MAGIC) {
+               (*ptr)++;
+               TRACE("   case: ");
+               val = atom_get_src(ctx, (attr&0x38)|ATOM_ARG_IMM, ptr);
+               target = U16(*ptr);
+               if (val == src) {
+                       *ptr = ctx->start + target;
+                       return;
+               }
+               (*ptr) += 2;
+       } else {
+               TRACE("Bad case.\n");
+               return;
+       }
+       (*ptr) += 2;
+}
+
+
+static void
+atom_op_test(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src;
+       TRACE("   src1: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1);
+       TRACE("   src2: ");
+       src = atom_get_src(ctx, attr, ptr);
+       ctx->ctx->cs_equal = ((dst & src) == 0);
+       TRACE("   result: %s\n", ctx->ctx->cs_equal?"EQ":"NE");
+}
+
+
+static void
+atom_op_xor(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++);
+       uint32 dst, src, saved;
+       int dptr = *ptr;
+       TRACE("   dst: ");
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       TRACE("   src: ");
+       src = atom_get_src(ctx, attr, ptr);
+       dst ^= src;
+       TRACE("   dst: ");
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void
+atom_op_debug(atom_exec_context *ctx, int *ptr, int arg)
+{
+       TRACE("unimplemented!\n");
+}
+
+
+static struct {
+       void (*func)(atom_exec_context *, int *, int);
+       int arg;
+} opcode_table[ATOM_OP_CNT] = {
+       { NULL, 0 },
+       { atom_op_move, ATOM_ARG_REG },
+       { atom_op_move, ATOM_ARG_PS },
+       { atom_op_move, ATOM_ARG_WS },
+       { atom_op_move, ATOM_ARG_FB },
+       { atom_op_move, ATOM_ARG_PLL },
+       { atom_op_move, ATOM_ARG_MC },
+       { atom_op_and, ATOM_ARG_REG },
+       { atom_op_and, ATOM_ARG_PS },
+       { atom_op_and, ATOM_ARG_WS },
+       { atom_op_and, ATOM_ARG_FB },
+       { atom_op_and, ATOM_ARG_PLL },
+       { atom_op_and, ATOM_ARG_MC },
+       { atom_op_or, ATOM_ARG_REG },
+       { atom_op_or, ATOM_ARG_PS },
+       { atom_op_or, ATOM_ARG_WS },
+       { atom_op_or, ATOM_ARG_FB },
+       { atom_op_or, ATOM_ARG_PLL },
+       { atom_op_or, ATOM_ARG_MC },
+       { atom_op_shl, ATOM_ARG_REG },
+       { atom_op_shl, ATOM_ARG_PS },
+       { atom_op_shl, ATOM_ARG_WS },
+       { atom_op_shl, ATOM_ARG_FB },
+       { atom_op_shl, ATOM_ARG_PLL },
+       { atom_op_shl, ATOM_ARG_MC },
+       { atom_op_shr, ATOM_ARG_REG },
+       { atom_op_shr, ATOM_ARG_PS },
+       { atom_op_shr, ATOM_ARG_WS },
+       { atom_op_shr, ATOM_ARG_FB },
+       { atom_op_shr, ATOM_ARG_PLL },
+       { atom_op_shr, ATOM_ARG_MC },
+       { atom_op_mul, ATOM_ARG_REG },
+       { atom_op_mul, ATOM_ARG_PS },
+       { atom_op_mul, ATOM_ARG_WS },
+       { atom_op_mul, ATOM_ARG_FB },
+       { atom_op_mul, ATOM_ARG_PLL },
+       { atom_op_mul, ATOM_ARG_MC },
+       { atom_op_div, ATOM_ARG_REG },
+       { atom_op_div, ATOM_ARG_PS },
+       { atom_op_div, ATOM_ARG_WS },
+       { atom_op_div, ATOM_ARG_FB },
+       { atom_op_div, ATOM_ARG_PLL },
+       { atom_op_div, ATOM_ARG_MC },
+       { atom_op_add, ATOM_ARG_REG },
+       { atom_op_add, ATOM_ARG_PS },
+       { atom_op_add, ATOM_ARG_WS },
+       { atom_op_add, ATOM_ARG_FB },
+       { atom_op_add, ATOM_ARG_PLL },
+       { atom_op_add, ATOM_ARG_MC },
+       { atom_op_sub, ATOM_ARG_REG },
+       { atom_op_sub, ATOM_ARG_PS },
+       { atom_op_sub, ATOM_ARG_WS },
+       { atom_op_sub, ATOM_ARG_FB },
+       { atom_op_sub, ATOM_ARG_PLL },
+       { atom_op_sub, ATOM_ARG_MC },
+       { atom_op_setport, ATOM_PORT_ATI },
+       { atom_op_setport, ATOM_PORT_PCI },
+       { atom_op_setport, ATOM_PORT_SYSIO },
+       { atom_op_setregblock, 0 },
+       { atom_op_setfbbase, 0 },
+       { atom_op_compare, ATOM_ARG_REG },
+       { atom_op_compare, ATOM_ARG_PS },
+       { atom_op_compare, ATOM_ARG_WS },
+       { atom_op_compare, ATOM_ARG_FB },
+       { atom_op_compare, ATOM_ARG_PLL },
+       { atom_op_compare, ATOM_ARG_MC },
+       { atom_op_switch, 0 },
+       { atom_op_jump, ATOM_COND_ALWAYS },
+       { atom_op_jump, ATOM_COND_EQUAL },
+       { atom_op_jump, ATOM_COND_BELOW },
+       { atom_op_jump, ATOM_COND_ABOVE },
+       { atom_op_jump, ATOM_COND_BELOWOREQUAL },
+       { atom_op_jump, ATOM_COND_ABOVEOREQUAL },

[... truncated: 354 lines follow ...]

Other related posts:

  • » [haiku-commits] r42538 - in haiku/trunk/src/add-ons/accelerants/radeon_hd: . atombios - kallisti5