# HG changeset patch # User John Tsiombikas # Date 1509369863 -7200 # Node ID 3d9aaefb8ba6624cc830c0ac9ad15ff44cb83614 # Parent 5614fbb9c1debc87309b82a3f5839519aad4c202 interlace mode diff -r 5614fbb9c1de -r 3d9aaefb8ba6 src/amiga/gfx.c --- a/src/amiga/gfx.c Sun Oct 29 22:53:41 2017 +0200 +++ b/src/amiga/gfx.c Mon Oct 30 15:24:23 2017 +0200 @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include "gfx.h" #include "copper.h" #include "hwregs.h" @@ -10,16 +12,28 @@ static int scr_width, scr_height; static int fb_width, fb_height; static int num_bitplanes; +static unsigned int init_flags; +/* updated by vblank_intr to indicate the current field in interlaced mode */ +static unsigned short scr_field; +static uint32_t *coplist_bplptr[6]; + static uint16_t prev_intena, prev_intreq, prev_adkcon, prev_dmacon; static unsigned char *framebuf; static unsigned long fbsize; static int own_framebuf; +static unsigned int short_fields, long_fields; + +static struct Interrupt *vbint; + +static __amigainterrupt void vblank_intr(); + int gfx_init(int nbpl, unsigned int flags) { uint16_t bplcon0; + init_flags = flags; num_bitplanes = nbpl; scr_width = fb_width = (flags & GFX_HIRES) ? 640 : 320; scr_height = fb_height = (flags & GFX_ILACE) ? 512 : 256; @@ -37,6 +51,19 @@ return -1; } + /* setup vblank interrupt handler */ + if(!(vbint = malloc(sizeof *vbint))) { + gfx_shutdown(); + return -1; + } + vbint->is_Node.ln_Type = NT_INTERRUPT; + vbint->is_Node.ln_Pri = -60; + vbint->is_Node.ln_Name = "imgv_vblank_intr"; + vbint->is_Data = 0; + vbint->is_Code = vblank_intr; + + AddIntServer(INTR_VERTB, vbint); + if(!gfx_set_framebuffer(0, scr_width, scr_height)) { gfx_shutdown(); return -1; @@ -83,8 +110,18 @@ } framebuf = 0; + if(vbint) { + RemIntServer(INTR_VERTB, vbint); + free(vbint); + vbint = 0; + } + cleanup_copper(); Permit(); + + if(init_flags & GFX_ILACE) { + printf("fields shown - long: %u / short: %u\n", long_fields, short_fields); + } } int gfx_screen_width(void) @@ -112,7 +149,7 @@ framebuf = fb; own_framebuf = 0; } else { - if(!(framebuf = AllocMem(sz, MEMF_CHIP))) { + if(!(framebuf = AllocMem(sz, MEMF_CHIP | MEMF_CLEAR))) { logmsg("gfx_set_framebuffer failed to allocate %lu bytes of chip mem for framebuffer\n", sz); return 0; } @@ -127,6 +164,9 @@ logmsg("bitplane address: %lx\n", (unsigned long)bpladdr); bplmod = (fb_width - scr_width) / 8 + fb_width / 8 * (num_bitplanes - 1); + if(init_flags & GFX_ILACE) { + bplmod += fb_width / 8 * num_bitplanes; + } REG_BPL1MOD = bplmod; REG_BPL2MOD = bplmod; @@ -158,18 +198,23 @@ void gfx_begin_copperlist(void) { - static const uint16_t bplptr[] = { - REGN_BPL1PTH, REGN_BPL2PTH, REGN_BPL3PTH, REGN_BPL4PTH, REGN_BPL5PTH, REGN_BPL6PTH - }; int i; uint32_t bpladdr; + uint16_t reg_bplptr = REGN_BPL1PTH; bpladdr = (uint32_t)framebuf; + REG_INTENA = CLRBITS(INTEN_VERTB); + for(i=0; i> 16)); - add_copper(COPPER_MOVE(bplptr[i] + 2, bpladdr)); + add_copper(COPPER_VWAIT_OVERSCAN(10)); + coplist_bplptr[i] = copperlist_end; + add_copper(COPPER_MOVE(reg_bplptr, bpladdr >> 16)); + reg_bplptr += 2; + add_copper(COPPER_MOVE(reg_bplptr, bpladdr)); + reg_bplptr += 2; bpladdr += fb_width / 8; } + REG_INTENA = SETBITS(INTEN_VERTB); } static int mouse_bnstate(void) @@ -242,3 +287,33 @@ } add_copper(COPPER_END); } + +static __amigainterrupt void vblank_intr() +{ + if(init_flags & GFX_ILACE) { + int i; + uint32_t bpladdr; + uint16_t reg_bplptr = REGN_BPL1PTH; + bpladdr = (uint32_t)framebuf; + + /* 0: when long frame flag is set in VPOS */ + scr_field = REG_VPOSR & 0x8000; + if(scr_field) { + bpladdr += fb_width / 8 * num_bitplanes; + ++long_fields; + } else { + ++short_fields; + } + + if(coplist_bplptr[0]) { + for(i=0; i> 16); + reg_bplptr += 2; + coplist_bplptr[i][1] = COPPER_MOVE(reg_bplptr, bpladdr); + reg_bplptr += 2; + bpladdr += fb_width / 8; + } + } + } + /* TODO read mouse */ +} diff -r 5614fbb9c1de -r 3d9aaefb8ba6 src/amiga/hwregs.h --- a/src/amiga/hwregs.h Sun Oct 29 22:53:41 2017 +0200 +++ b/src/amiga/hwregs.h Mon Oct 30 15:24:23 2017 +0200 @@ -349,6 +349,24 @@ #define SETBITS(x) ((x) | 0x8000) #define CLRBITS(x) (x) +/* interrupt numbers */ +enum { + INTR_TBE, + INTR_DSKBLK, + INTR_SOFT, + INTR_PORTS, + INTR_COPPER, + INTR_VERTB, + INTR_BLITTER, + INTR_AUDIO0, + INTR_AUDIO1, + INTR_AUDIO2, + INTR_AUDIO3, + INTR_RBF, + INTR_DSKSYN, + INTR_EXTER +}; + /* interrupt enable flags */ enum { INTEN_TBE = 0x0001, diff -r 5614fbb9c1de -r 3d9aaefb8ba6 src/sdl/gfx.c --- a/src/sdl/gfx.c Sun Oct 29 22:53:41 2017 +0200 +++ b/src/sdl/gfx.c Mon Oct 30 15:24:23 2017 +0200 @@ -50,6 +50,8 @@ void *gfx_set_framebuffer(void *fb, int width, int height) { + fb_width = width; + fb_height = height; return 0; } @@ -131,13 +133,15 @@ void gfx_show_image(struct ham_image *img) { - int i, j, k; - uint32_t color, palette[16]; + int i, j, k, ncolors; + uint32_t color, palette[256]; uint32_t *dest; unsigned char *src; struct palchange *chg = img->chglist; - for(i=0; i<16; i++) { + ncolors = 1 << img->nbitplanes; + + for(i=0; ipalette[i]; int red = ARED(pcol); int green = AGREEN(pcol); @@ -152,6 +156,8 @@ dest = fbsurf->pixels; src = img->pixels; for(i=0; iheight; i++) { + if(i >= scr_height) break; + while(chg && chg->line <= i) { int idx = (chg->entry & 0xf000) >> 12; int red = ARED(chg->entry);