Changeset ac4e192 in buchla-emu


Ignore:
Timestamp:
08/19/2017 08:26:00 PM (7 years ago)
Author:
Thomas Lopatic <thomas@…>
Branches:
master
Children:
f285858
Parents:
82714ab
Message:

Started VSDD emulation.

Location:
emu
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • emu/cpu.c

    r82714ab rac4e192  
    7474static hw_t hw_map[] = {
    7575        { 0x180000, 0x200000, 0, fpu_init, fpu_quit, fpu_exec, fpu_read, fpu_write },
    76         { 0x200000, 0x280002, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
     76        { 0x200000, 0x280002, 1, vid_init, vid_quit, vid_exec, vid_read, vid_write },
    7777        { 0x3a0001, 0x3a4001, 4, tim_init, tim_quit, tim_exec, tim_read, tim_write },
    7878        { 0x3a4001, 0x3a8001, 0, lcd_init, lcd_quit, lcd_exec, lcd_read, lcd_write },
  • emu/vid.c

    r82714ab rac4e192  
    2424int32_t vid_verbose = 0;
    2525
     26#define SCR_W 512
     27#define SCR_H 350
     28#define VBL_H 50
     29
     30#define REG_VCR0 0
     31#define REG_VCR1 1
     32#define REG_RWBA 2
     33#define REG_DSBA 5
     34#define REG_ODTBA 7
     35#define REG_ATBA 8
     36#define REG_ATBAC 11
     37
     38#define VCR0_UCF 0x0001
     39#define VCR0_DEN 0x0008
     40
     41#define DSBA_BS1 0x0080
     42#define DSBA_BS0 0x0100
     43
     44#define REG_OFF 0x200
     45#define PAL_OFF 0x40000
     46
     47#define OD0_BLA 0x0010
     48
     49#define WIN_SZ_W 0x10000
     50#define MEM_SZ_W 0x20000
     51
     52#define N_BANKS 2
     53
     54static int32_t reg_off = REG_OFF;
     55
     56static uint16_t mem[MEM_SZ_W];
     57static int32_t bank = 0;
     58
     59static int32_t pal[16];
     60static int32_t i_pal = 0;
     61
    2662void vid_init(void)
    2763{
     
    3773{
    3874        ver3("vid exec");
     75
     76        static int32_t skip = 99999;
     77        static int32_t line = 99999;
     78
     79        if (++skip < 10) {
     80                ver3("vid skip %d", skip);
     81                return false;
     82        }
     83
     84        skip = 0;
     85        int32_t vcr0 = mem[REG_VCR0];
     86
     87        if ((vcr0 & VCR0_DEN) == 0) {
     88                ver3("vid dis");
     89                return false;
     90        }
     91
     92        if (++line < SCR_H + VBL_H) {
     93                ver3("vid line %d", line);
     94
     95                if (line < SCR_H) {
     96                        ++mem[REG_ATBAC];
     97                }
     98
     99                return line == SCR_H;
     100        }
     101
     102        // We get here every 4,000 invocations -> 25 fps.
     103
     104        ver2("vid frame");
     105        line = 0;
     106
     107        int32_t dsba = mem[REG_DSBA];
     108        bank = ((dsba & DSBA_BS0) != 0 ? 1 : 0) + ((dsba & DSBA_BS1) != 0 ? 2 : 0);
     109
     110        int32_t rwba = mem[REG_RWBA];
     111        reg_off = (rwba & 0xfff0) << 1;
     112
     113        int32_t atba = mem[REG_ATBA];
     114        mem[REG_ATBAC] = (uint16_t)atba;
     115
     116        int32_t odtba = mem[REG_ODTBA] & 0xffc0;
     117        int32_t y_beg[16], y_end[16];
     118
     119        for (int32_t i = 0; i < 16; ++i) {
     120                y_beg[i] = -1;
     121                y_end[i] = -1;
     122
     123                uint16_t *od = mem + odtba + 4 * i;
     124
     125                if ((od[0] & OD0_BLA) != 0) {
     126                        ver3("obj %d blanked", i);
     127                        continue;
     128                }
     129
     130                int32_t w = (od[1] & 0xfc00) >> 6;
     131
     132                if (w == 0) {
     133                        ver3("obj %d empty", i);
     134                        continue;
     135                }
     136
     137                int32_t mask = 1 << i;
     138
     139                for (int32_t k = 0; k < SCR_H; ++k) {
     140                        if ((mem[atba + k] & mask) == 0) {
     141                                if (y_beg[i] < 0) {
     142                                        y_beg[i] = k;
     143                                }
     144                                else if (y_end[i] < 0) {
     145                                        y_end[i] = k;
     146                                }
     147                        }
     148                }
     149
     150                if (y_beg[i] < 0) {
     151                        ver3("obj %d unused", i);
     152                        continue;
     153                }
     154
     155                int32_t x = od[1] & 0x03ff;
     156                ver2("obj %d %d:%d %d+%d", i, y_beg[i], y_end[i], x, w);
     157        }
     158
     159        int32_t vcr1 = mem[REG_VCR1];
     160        int32_t fon_h = (vcr1 & 0xf000) >> 12;
     161
    39162        return false;
    40163}
     
    42165uint32_t vid_read(uint32_t off, int32_t sz)
    43166{
    44         ver2("vid rd 0x%05x:%d", off, sz * 8);
    45         return 0;
     167        ver2("vid rd %d 0x%05x:%d", bank, off, sz * 8);
     168
     169        int32_t off16 = (int32_t)(off / 2);
     170
     171        if (sz != 2 || bank >= N_BANKS || off % 2 != 0 || off16 >= WIN_SZ_W) {
     172                fail("invalid vid rd %d %u:%d", bank, off, sz * 8);
     173        }
     174
     175        if (off16 >= reg_off && off16 < reg_off + 16) {
     176                return mem[off16 - reg_off];
     177        }
     178
     179        return mem[bank * WIN_SZ_W + off16];
    46180}
    47181
    48182void vid_write(uint32_t off, int32_t sz, uint32_t val)
    49183{
    50         ver2("vid wr 0x%05x:%d 0x%0*x", off, sz * 8, sz * 2, val);
    51 }
     184        ver2("vid wr %d 0x%05x:%d 0x%0*x", bank, off, sz * 8, sz * 2, val);
     185
     186        int32_t off16 = (int32_t)(off / 2);
     187
     188        if (sz != 2 || bank >= N_BANKS || off % 2 != 0 || (off16 >= WIN_SZ_W && off16 != PAL_OFF)) {
     189                fail("invalid vid wr %d %u:%d", bank, off, sz * 8);
     190        }
     191
     192        if (off16 == PAL_OFF) {
     193                pal[i_pal] = (int32_t)val;
     194                i_pal = (i_pal + 1) % 16;
     195                return;
     196        }
     197
     198        if (off16 >= reg_off && off16 < reg_off + 16) {
     199                mem[off16 - reg_off] = (uint16_t)val;
     200                return;
     201        }
     202
     203        mem[bank * WIN_SZ_W + off16] = (uint16_t)val;
     204}
Note: See TracChangeset for help on using the changeset viewer.