Пример #1
0
static int perform_mode_change(raster_t *raster)
{
    if (!video_disabled_mode
        && raster->canvas && raster->canvas->palette != NULL) {
        if (video_canvas_set_palette(raster->canvas, raster->canvas->palette) < 0) {
            return -1;
        }
    }
    raster_force_repaint(raster);

    video_viewport_resize(raster->canvas, 1);

    return 0;
}
Пример #2
0
static int perform_mode_change(raster_t *raster)
{
    if (!video_disabled_mode
        && raster->canvas && raster->canvas->palette != NULL) {
        if (video_canvas_set_palette(raster->canvas,
            raster->canvas->palette) < 0)
            return -1;
    }
    raster_force_repaint(raster);

    /* FIXME: `video_viewport_resize()' already calls
       `video_canvas_resize()'. */
    video_canvas_resize(raster->canvas,
                        raster->canvas->draw_buffer->canvas_width,
                        raster->canvas->draw_buffer->canvas_height);
    video_viewport_resize(raster->canvas);

    return 0;
}
Пример #3
0
int vic_snapshot_read_module(snapshot_t *s)
{
    WORD i;
    snapshot_module_t *m;
    BYTE major_version, minor_version;
    WORD w;
    BYTE b;

    sound_close();

    m = snapshot_module_open(s, snap_module_name,
                             &major_version, &minor_version);
    if (m == NULL) {
        return -1;
    }

    if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) {
        log_error(vic.log, "Snapshot module version (%d.%d) newer than %d.%d.",
                  major_version, minor_version,
                  SNAP_MAJOR, SNAP_MINOR);
        goto fail;
    }

    if (SMR_B(m, &b) < 0) {
        goto fail;
    }
    if (b != VIC_RASTER_CYCLE(maincpu_clk)) {
        log_error(vic.log, "Cycle value (%d) incorrect; should be %d.",
                  (int)b, VIC_RASTER_CYCLE(maincpu_clk));
        goto fail;
    }
    vic.raster_cycle = (unsigned int)b;

    if (SMR_W(m, &w) < 0) {
        goto fail;
    }
    if (w != VIC_RASTER_Y(maincpu_clk)) {
          log_error(vic.log, "Raster line value (%d) incorrect; should be %d.",
                    (int)w, VIC_RASTER_Y(maincpu_clk));
        goto fail;
    }

    if (SMR_W(m, &w) < 0) {
        goto fail;
    }
    vic.area = (vic_area_state_t)w;

    if (SMR_W(m, &w) < 0) {
        goto fail;
    }
    vic.fetch_state = (vic_fetch_state_t)w;

    if (0
        || (SMR_DW_UINT(m, &vic.raster_line) < 0)
        || (SMR_DW_UINT(m, &vic.text_cols) < 0)
        || (SMR_DW_UINT(m, &vic.text_lines) < 0)
        || (SMR_DW_UINT(m, &vic.pending_text_cols) < 0)
        || (SMR_DW_UINT(m, &vic.line_was_blank) < 0)
        || (SMR_DW_UINT(m, &vic.memptr) < 0)
        || (SMR_DW_UINT(m, &vic.memptr_inc) < 0)
        || (SMR_DW_UINT(m, &vic.row_counter) < 0)
        || (SMR_DW_UINT(m, &vic.buf_offset) < 0)
        || SMR_B_INT(m, &vic.light_pen.state) < 0
        || SMR_B_INT(m, &vic.light_pen.triggered) < 0
        || SMR_DW_INT(m, &vic.light_pen.x) < 0
        || SMR_DW_INT(m, &vic.light_pen.y) < 0
        || SMR_DW_INT(m, &vic.light_pen.x_extra_bits) < 0
        || SMR_DW(m, &vic.light_pen.trigger_cycle) < 0
        || (SMR_B(m, &vic.vbuf) < 0)) {
        goto fail;
    }

    /* Color RAM.  */
    if (SMR_BA(m, mem_ram + 0x9400, 0x400) < 0) {
        goto fail;
    }

    for (i = 0; i < 0x10; i++) {
        if (SMR_B(m, &b) < 0) {
            goto fail;
        }

        /* XXX: This assumes that there are no side effects.  */
        vic_store(i, b);
    }

    raster_force_repaint(&vic.raster);
    return snapshot_module_close(m);

fail:
    if (m != NULL)
        snapshot_module_close(m);
    return -1;
}
Пример #4
0
int ted_snapshot_read_module(snapshot_t *s)
{
    BYTE major_version, minor_version;
    int i;
    snapshot_module_t *m;

    m = snapshot_module_open(s, snap_module_name,
                             &major_version, &minor_version);
    if (m == NULL) {
        return -1;
    }

    if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) {
        log_error(ted.log,
                  "Snapshot module version (%d.%d) newer than %d.%d.",
                  major_version, minor_version,
                  SNAP_MAJOR, SNAP_MINOR);
        goto fail;
    }

    /* FIXME: initialize changes?  */

    if (0
        || SMR_DW(m, &ted.last_emulate_line_clk) < 0
        /* AllowBadLines */
        || SMR_B_INT(m, &ted.allow_bad_lines) < 0
        /* BadLine */
        || SMR_B_INT(m, &ted.bad_line) < 0
        /* Blank */
        || SMR_B_INT(m, &ted.raster.blank_enabled) < 0
        /* ColorBuf */
        || SMR_BA(m, ted.cbuf, 40) < 0
        /* IdleState */
        || SMR_B_INT(m, &ted.idle_state) < 0
        /* MatrixBuf */
        || SMR_BA(m, ted.vbuf, 40) < 0
        ) {
        goto fail;
    }

    /* Read the current raster line and the current raster cycle.  As they
       are a function of `clk', this is just a sanity check.  */
    {
        WORD RasterLine;
        BYTE RasterCycle;

        if (SMR_B(m, &RasterCycle) < 0 || SMR_W(m, &RasterLine) < 0) {
            goto fail;
        }

        DBG(("TED read snapshot at clock: %d cycle: %d (%d) tedline: %d (%d) rasterline: %d\n",
             maincpu_clk, TED_RASTER_CYCLE(maincpu_clk), RasterCycle, TED_RASTER_Y(maincpu_clk),
             RasterLine, ted.raster.current_line));

        if (RasterCycle != (BYTE)TED_RASTER_CYCLE(maincpu_clk)) {
            log_error(ted.log,
                      "Not matching raster cycle (%d) in snapshot; should be %d.",
                      RasterCycle, TED_RASTER_CYCLE(maincpu_clk));
            goto fail;
        }

        if (RasterLine != (WORD)TED_RASTER_Y(maincpu_clk)) {
            log_error(ted.log,
                      "Not matching raster line (%d) in snapshot; should be %d.",
                      RasterLine, TED_RASTER_Y(maincpu_clk));
            goto fail;
        }
    }

    for (i = 0; i < 0x40; i++) {
        if (SMR_B(m, &ted.regs[i]) < 0 /* Registers */) {
            goto fail;
        }
    }

    if (0
        || SMR_DW_INT(m, (int*)&ted.ted_raster_counter) < 0
        /* Vc */
        || SMR_W_INT(m, &ted.mem_counter) < 0
        /* VcInc */
        || SMR_B_INT(m, &ted.mem_counter_inc) < 0
        /* VcBase */
        || SMR_W_INT(m, &ted.memptr) < 0
        /* VideoInt */
        || SMR_B_INT(m, &ted.irq_status) < 0) {
        goto fail;
    }

    /* FIXME: Recalculate alarms and derived values.  */

    ted_irq_set_raster_line(ted.regs[0x0b] | ((ted.regs[0x0a] & 1) << 8));

    ted_update_memory_ptrs(TED_RASTER_CYCLE(maincpu_clk));

    ted.raster.xsmooth = ted.regs[0x07] & 0x7;
    ted.raster.ysmooth = ted.regs[0x06] & 0x7;
    ted.raster.current_line = TED_RASTER_Y(maincpu_clk); /* FIXME? */

    /* Update colors.  */
    ted.raster.border_color = ted.regs[0x19];
    ted.raster.background_color = ted.regs[0x15];
    ted.ext_background_color[0] = ted.regs[0x16];
    ted.ext_background_color[1] = ted.regs[0x17];
    ted.ext_background_color[2] = ted.regs[0x18];

    ted.raster.blank = !(ted.regs[0x06] & 0x10);

    if (TED_IS_ILLEGAL_MODE (ted.raster.video_mode)) {
        ted.raster.idle_background_color = 0;
        ted.force_black_overscan_background_color = 1;
    } else {
        ted.raster.idle_background_color = ted.raster.background_color;
        ted.force_black_overscan_background_color = 0;
    }

    if (ted.regs[0x06] & 0x8) {
        ted.raster.display_ystart = ted.row_25_start_line;
        ted.raster.display_ystop = ted.row_25_stop_line;
    } else {
        ted.raster.display_ystart = ted.row_24_start_line;
        ted.raster.display_ystop = ted.row_24_stop_line;
    }

    if (ted.regs[0x07] & 0x8) {
        ted.raster.display_xstart = TED_40COL_START_PIXEL;
        ted.raster.display_xstop = TED_40COL_STOP_PIXEL;
    } else {
        ted.raster.display_xstart = TED_38COL_START_PIXEL;
        ted.raster.display_xstop = TED_38COL_STOP_PIXEL;
    }

    /* `ted.raster.draw_idle_state', `ted.raster.open_right_border' and
       `ted.raster.open_left_border' should be needed, but they would only
       affect the current ted.raster line, and would not cause any
       difference in timing.  So who cares.  */

    /* FIXME: `ted.ycounter_reset_checked'?  */
    /* FIXME: `ted.force_display_state'?  */

    ted.memory_fetch_done = 0; /* FIXME? */

    ted_update_video_mode(TED_RASTER_CYCLE(maincpu_clk));

    ted.draw_clk = maincpu_clk + (ted.draw_cycle - TED_RASTER_CYCLE(maincpu_clk));
    ted.last_emulate_line_clk = ted.draw_clk - ted.cycles_per_line;
    alarm_set(ted.raster_draw_alarm, ted.draw_clk);

    {
        DWORD dw;

        if (SMR_DW(m, &dw) < 0) {  /* FetchEventTick */
            goto fail;
        }

        ted.fetch_clk = maincpu_clk + dw;

        alarm_set(ted.raster_fetch_alarm, ted.fetch_clk);
    }

    if (ted.irq_status & 0x80) {
        interrupt_restore_irq(maincpu_int_status, ted.int_num, 1);
    }

    raster_force_repaint(&ted.raster);
    DBG(("TED: snapshot loaded.\n"));
    return 0;

fail:
    if (m != NULL) {
        snapshot_module_close(m);
    }
    log_error(ted.log, "could not load TED snapshot.");
    return -1;
}
int vicii_snapshot_read_module(snapshot_t *s)
{
    BYTE major_version, minor_version;
    int i;
    snapshot_module_t *m;
    BYTE color_ram[0x400];

    m = snapshot_module_open(s, snap_module_name,
                             &major_version, &minor_version);
    if (m == NULL) {
        return -1;
    }

    if (major_version > SNAP_MAJOR || minor_version > SNAP_MINOR) {
        log_error(vicii.log,
                  "Snapshot module version (%d.%d) newer than %d.%d.",
                  major_version, minor_version,
                  SNAP_MAJOR, SNAP_MINOR);
        goto fail;
    }

    /* FIXME: initialize changes?  */

    if (0
        /* AllowBadLines */
        || SMR_B_INT(m, &vicii.allow_bad_lines) < 0
        /* BadLine */
        || SMR_B_INT(m, &vicii.bad_line) < 0
        /* Blank */
        || SMR_B_INT(m, &vicii.raster.blank_enabled) < 0
        /* ColorBuf */
        || SMR_BA(m, vicii.cbuf, 40) < 0
        /* ColorRam */
        || SMR_BA(m, color_ram, 1024) < 0
        /* IdleState */
        || SMR_B_INT(m, &vicii.idle_state) < 0
        /* LPTrigger */
        || SMR_B_INT(m, &vicii.light_pen.triggered) < 0
        /* LPX */
        || SMR_B_INT(m, &vicii.light_pen.x) < 0
        /* LPY */
        || SMR_B_INT(m, &vicii.light_pen.y) < 0
        /* MatrixBuf */
        || SMR_BA(m, vicii.vbuf, 40) < 0
        /* NewSpriteDmaMask */
        || SMR_B(m, &vicii.raster.sprite_status->new_dma_msk) < 0) {
        goto fail;
    }

    mem_color_ram_from_snapshot(color_ram);

    {
        DWORD RamBase;

        if (SMR_DW(m, &RamBase) < 0) {
            goto fail;
        }
        vicii.ram_base_phi1 = mem_ram + RamBase;
    }

    /* Read the current raster line and the current raster cycle.  As they
       are a function of `clk', this is just a sanity check.  */
    {
        WORD RasterLine;
        BYTE RasterCycle;

        if (SMR_B(m, &RasterCycle) < 0
            || SMR_W(m, &RasterLine) < 0) {
            goto fail;
        }

        if (RasterCycle != (BYTE)VICII_RASTER_CYCLE(maincpu_clk)) {
            log_error(vicii.log,
                      "Not matching raster cycle (%d) in snapshot; should be %d.",
                      RasterCycle, VICII_RASTER_CYCLE(maincpu_clk));
            goto fail;
        }

        if (RasterLine != (WORD)VICII_RASTER_Y(maincpu_clk)) {
            log_error(vicii.log,
                      "VIC-II: Not matching raster line (%d) in snapshot; should be %d.",
                      RasterLine, VICII_RASTER_Y(maincpu_clk));
            goto fail;
        }
    }

    for (i = 0; i < 0x40; i++) {
        if (SMR_B(m, &vicii.regs[i]) < 0 /* Registers */) {
            goto fail;
        }
    }

    if (0
        /* SbCollMask */
        || SMR_B(m, &vicii.sprite_background_collisions) < 0
        /* SpriteDmaMask */
        || SMR_B(m, &vicii.raster.sprite_status->dma_msk) < 0
        /* SsCollMask */
        || SMR_B(m, &vicii.sprite_sprite_collisions) < 0
        /* VBank */
        || SMR_W_INT(m, &vicii.vbank_phi1) < 0
        /* Vc */
        || SMR_W_INT(m, &vicii.mem_counter) < 0
        /* VcInc */
        || SMR_B_INT(m, &vicii.mem_counter_inc) < 0
        /* VcBase */
        || SMR_W_INT(m, &vicii.memptr) < 0
        /* VideoInt */
        || SMR_B_INT(m, &vicii.irq_status) < 0) {
        goto fail;
    }

    for (i = 0; i < 8; i++) {
        if (0
            /* SpriteXMemPtr */
            || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].memptr) < 0
            /* SpriteXMemPtrInc */
            || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].memptr_inc) < 0
            /* SpriteXExpFlipFlop */
            || SMR_B_INT(m, &vicii.raster.sprite_status->sprites[i].exp_flag) < 0
            ) {
            goto fail;
        }
    }

    /* FIXME: Recalculate alarms and derived values.  */
#if 1
    {
        /*
            We cannot use vicii_irq_set_raster_line as this would delay
            an alarm on line 0 for one frame
        */
        unsigned int line = vicii.regs[0x12] | ((vicii.regs[0x11] & 0x80) << 1);

        if (line < (unsigned int)vicii.screen_height) {
            vicii.raster_irq_clk = (VICII_LINE_START_CLK(maincpu_clk)
                                    + VICII_RASTER_IRQ_DELAY - INTERRUPT_DELAY
                                    + (vicii.cycles_per_line * line));

            /* Raster interrupts on line 0 are delayed by 1 cycle.  */
            if (line == 0) {
                vicii.raster_irq_clk++;
            }

            alarm_set(vicii.raster_irq_alarm, vicii.raster_irq_clk);
        } else {
            vicii.raster_irq_clk = CLOCK_MAX;
            alarm_unset(vicii.raster_irq_alarm);
        }
        vicii.raster_irq_line = line;
    }

#else
    vicii_irq_set_raster_line(vicii.regs[0x12]
                              | ((vicii.regs[0x11] & 0x80) << 1));
#endif

    /* compatibility with older versions */
    vicii.ram_base_phi2 = vicii.ram_base_phi1;
    vicii.vbank_phi2 = vicii.vbank_phi1;

    vicii_update_memory_ptrs(VICII_RASTER_CYCLE(maincpu_clk));

    /* Update sprite parameters.  We had better do this manually, or the
       VIC-II emulation could be quite upset.  */
    {
        BYTE msk;

        for (i = 0, msk = 0x1; i < 8; i++, msk <<= 1) {
            raster_sprite_t *sprite;
            int tmp;

            sprite = vicii.raster.sprite_status->sprites + i;

            /* X/Y coordinates.  */
            tmp = vicii.regs[i * 2] + ((vicii.regs[0x10] & msk) ? 0x100 : 0);

            /* (-0xffff makes sure it's updated NOW.) */
            vicii_sprites_set_x_position(i, tmp, -0xffff);

            sprite->y = (int)vicii.regs[i * 2 + 1];
            sprite->x_expanded = (int)(vicii.regs[0x1d] & msk);
            sprite->y_expanded = (int)(vicii.regs[0x17] & msk);
            sprite->multicolor = (int)(vicii.regs[0x1c] & msk);
            sprite->in_background = (int)(vicii.regs[0x1b] & msk);
            sprite->color = (int) vicii.regs[0x27 + i] & 0xf;
            sprite->dma_flag = (int)(vicii.raster.sprite_status->new_dma_msk & msk);
        }
    }

    vicii.sprite_fetch_msk = vicii.raster.sprite_status->new_dma_msk;
    vicii.sprite_fetch_clk = VICII_LINE_START_CLK(maincpu_clk)
                             + vicii.sprite_fetch_cycle
                             - vicii.cycles_per_line;

    /* calculate the sprite_fetch_idx */
    {
        const vicii_sprites_fetch_t *sf;

        sf = vicii_sprites_fetch_table[vicii.sprite_fetch_msk];
        i = 0;
        while (sf[i].cycle >= 0 && sf[i].cycle + vicii.sprite_fetch_cycle <= vicii.cycles_per_line) {
            i++;
        }
        vicii.sprite_fetch_idx = i;
    }

    vicii.raster.xsmooth = vicii.regs[0x16] & 0x7;
    vicii.raster.sprite_xsmooth = vicii.regs[0x16] & 0x7;
    vicii.raster.ysmooth = vicii.regs[0x11] & 0x7;
    vicii.raster.current_line = VICII_RASTER_Y(maincpu_clk); /* FIXME? */

    vicii.raster.sprite_status->visible_msk = vicii.regs[0x15];

    /* Update colors.  */
    vicii.raster.border_color = vicii.regs[0x20] & 0xf;
    vicii.raster.background_color = vicii.regs[0x21] & 0xf;
    vicii.ext_background_color[0] = vicii.regs[0x22] & 0xf;
    vicii.ext_background_color[1] = vicii.regs[0x23] & 0xf;
    vicii.ext_background_color[2] = vicii.regs[0x24] & 0xf;
    vicii.raster.sprite_status->mc_sprite_color_1 = vicii.regs[0x25] & 0xf;
    vicii.raster.sprite_status->mc_sprite_color_2 = vicii.regs[0x26] & 0xf;

    vicii.raster.blank = !(vicii.regs[0x11] & 0x10);

    if (VICII_IS_ILLEGAL_MODE(vicii.raster.video_mode)) {
        vicii.raster.idle_background_color = 0;
        vicii.force_black_overscan_background_color = 1;
    } else {
        vicii.raster.idle_background_color
            = vicii.raster.background_color;
        vicii.force_black_overscan_background_color = 0;
    }

    if (vicii.regs[0x11] & 0x8) {
        vicii.raster.display_ystart = vicii.row_25_start_line;
        vicii.raster.display_ystop = vicii.row_25_stop_line;
    } else {
        vicii.raster.display_ystart = vicii.row_24_start_line;
        vicii.raster.display_ystop = vicii.row_24_stop_line;
    }

    if (vicii.regs[0x16] & 0x8) {
        vicii.raster.display_xstart = VICII_40COL_START_PIXEL;
        vicii.raster.display_xstop = VICII_40COL_STOP_PIXEL;
    } else {
        vicii.raster.display_xstart = VICII_38COL_START_PIXEL;
        vicii.raster.display_xstop = VICII_38COL_STOP_PIXEL;
    }

    /* `vicii.raster.draw_idle_state', `vicii.raster.open_right_border' and
       `vicii.raster.open_left_border' should be needed, but they would only
       affect the current vicii.raster line, and would not cause any
       difference in timing.  So who cares.  */

    /* FIXME: `vicii.ycounter_reset_checked'?  */
    /* FIXME: `vicii.force_display_state'?  */

    vicii.memory_fetch_done = 0; /* FIXME? */

    vicii_update_video_mode(VICII_RASTER_CYCLE(maincpu_clk));

    vicii.draw_clk = maincpu_clk + (vicii.draw_cycle - VICII_RASTER_CYCLE(maincpu_clk));
    vicii.last_emulate_line_clk = vicii.draw_clk - vicii.cycles_per_line;
    alarm_set(vicii.raster_draw_alarm, vicii.draw_clk);

    {
        DWORD dw;
        BYTE b;

        if (0
            || SMR_DW(m, &dw) < 0  /* FetchEventTick */
            || SMR_B(m, &b) < 0    /* FetchEventType */
            ) {
            goto fail;
        }

        vicii.fetch_clk = maincpu_clk + dw;
        vicii.fetch_idx = b;

        alarm_set(vicii.raster_fetch_alarm, vicii.fetch_clk);
    }

    if (vicii.irq_status & 0x80) {
        interrupt_restore_irq(maincpu_int_status, vicii.int_num, 1);
    }

    /* added in version 1.1 of snapshot format */
    if (minor_version > 0) {
        DWORD RamBase;

        if (0
            || SMR_DW(m, &RamBase) < 0
            || SMR_W_INT(m, &vicii.vbank_phi2) < 0 /* VBank */
            ) {
            goto fail;
        }
        vicii.ram_base_phi2 = mem_ram + RamBase;

        vicii_update_memory_ptrs(VICII_RASTER_CYCLE(maincpu_clk));
    }

    raster_force_repaint(&vicii.raster);
    snapshot_module_close(m);
    return 0;

fail:
    if (m != NULL) {
        snapshot_module_close(m);
    }
    return -1;
}
Пример #6
0
/* Redraw the current raster line. */
static void vdc_raster_draw_alarm_handler(CLOCK offset, void *data)
{
    int in_visible_area, in_idle_state;

    in_visible_area = (vdc.raster.current_line
                      >= vdc.first_displayed_line
                      && vdc.raster.current_line
                      <= vdc.last_displayed_line);
    in_idle_state = (vdc.raster.current_line < vdc.border_height)
                    || (vdc.raster.current_line >
                    (vdc.border_height + vdc.screen_ypix));

    if (vdc.raster.current_line == vdc.first_displayed_line * 2 + 1) {
        vdc.screen_adr = ((vdc.regs[12] << 8) | vdc.regs[13])
                         & vdc.vdc_address_mask;
        vdc.attribute_adr = ((vdc.regs[20] << 8) | vdc.regs[21])
                            & vdc.vdc_address_mask;
    }

    if (vdc.raster.current_line == 0) {
        vdc.mem_counter = 0;
        vdc.bitmap_counter = 0;
        vdc.raster.ycounter = 0;
		vdc.frame_counter++;
		if (vdc.regs[24] & 0x20) vdc.attribute_blink = vdc.frame_counter & 16;
		else vdc.attribute_blink = vdc.frame_counter & 8;

        if (vdc.update_geometry) {
            vdc_update_geometry();
            vdc.force_resize = 1;
            vdc.force_repaint = 1;
            /* Screen height has changed, so do not invalidate cache with
               the new value.  It will be recreated by resize anyway.  */
            vdc.force_cache_flush = 0;
        } else {
            if (vdc.force_cache_flush) {
                vdc_invalidate_cache(&vdc.raster, vdc.screen_height);
                vdc.force_cache_flush = 0;
            }
        }

        if (vdc.force_resize) {
            if (vdc.initialized) {
                vdc_set_geometry();
                raster_mode_change();
            }
            vdc.force_resize = 0;
        }

        if (vdc.force_repaint) {
            vdc.force_repaint = 0;
            raster_force_repaint(&vdc.raster);
        }
    }

    raster_line_emulate(&vdc.raster);

#ifdef __MSDOS__
    if (vdc.raster.canvas->viewport->update_canvas)
        canvas_set_border_color(vdc.raster.canvas,
                                vdc.raster.border_color);
#endif

    if (in_visible_area && !in_idle_state) {
        vdc_increment_memory_pointer();
        vdc_set_video_mode();
    }

    vdc_set_next_alarm(offset);
}