diff --git a/include/apple2.h b/include/apple2.h index ed387f7..cd7199e 100644 --- a/include/apple2.h +++ b/include/apple2.h @@ -22,6 +22,25 @@ enum color_modes { COLOR_FULL, }; +enum lores_colors { + LORES_BLACK, + LORES_MAGENTA, + LORES_DARKBLUE, + LORES_PURPLE, + LORES_DARKGREEN, + LORES_GRAY1, + LORES_MEDBLUE, + LORES_LIGHTBLUE, + LORES_BROWN, + LORES_ORANGE, + LORES_GRAY2, + LORES_PINK, + LORES_LIGHTGREEN, + LORES_YELLOW, + LORES_AQUAMARINE, + LORES_WHITE, +}; + typedef struct { /* * The apple 2 hardware used an MOS-6502 processor. @@ -77,5 +96,6 @@ extern int apple2_boot(apple2 *); extern void apple2_run_loop(apple2 *); extern void apple2_set_color(apple2 *, int); extern void apple2_set_video(apple2 *, int); +extern bool apple2_is_double_video(apple2 *); #endif diff --git a/src/apple2.c b/src/apple2.c index 412f09f..2c07f71 100644 --- a/src/apple2.c +++ b/src/apple2.c @@ -205,3 +205,12 @@ apple2_set_video(apple2 *mach, int mode) vm_screen_set_logical_coords(mach->screen, width, height); } + +bool +apple2_is_double_video(apple2 *mach) +{ + return + mach->video_mode == VIDEO_DOUBLE_HIRES || + mach->video_mode == VIDEO_DOUBLE_LORES || + mach->video_mode == VIDEO_80COL_TEXT; +} diff --git a/src/apple2.draw.c b/src/apple2.draw.c index c729ad5..b27dd72 100644 --- a/src/apple2.draw.c +++ b/src/apple2.draw.c @@ -4,11 +4,69 @@ #include "apple2.h" +static int lores_colors[][3] = { + { 0x00, 0x00, 0x00 }, // black + { 0xff, 0x28, 0x97 }, // magenta + { 0x60, 0x4d, 0xbc }, // dark blue + { 0xff, 0x44, 0xfd }, // purple + { 0x00, 0xa3, 0x60 }, // dark green + { 0x9c, 0x9c, 0x9c }, // gray + { 0x14, 0xcf, 0xfd }, // medium blue + { 0xd0, 0xc3, 0xff }, // light blue + { 0x60, 0x72, 0x03 }, // brown + { 0xff, 0x6a, 0x3c }, // orange + { 0x9c, 0x9c, 0x9c }, // gray + { 0xff, 0xa0, 0xd0 }, // pink + { 0x14, 0xf5, 0x3c }, // light green + { 0xd0, 0xdd, 0x81 }, // yellow + { 0x72, 0xff, 0xd0 }, // aquamarine + { 0xff, 0xff, 0xff }, // white +}; + void apple2_draw_pixel(apple2 *mach, vm_16bit addr) { } +/* + * In single lo-res mode, pixels are 40x40 on the screen. But since our + * single mode has 280 pixels that _we_ show, this means that a pixel in + * single lo-res is really 7 columns wide. (Confusing yet?) Each "row" in + * text page 1 is just a row of visible dots, and 4 rows are equivalent + * to one "pixel" in lo-res mode. + * + * Without text, you get 40x48 pixels. + */ +void +apple2_draw_pixel_lores(apple2 *mach, vm_16bit addr) +{ + vm_8bit color = vm_segment_get(mach->memory, addr); + vm_8bit top, bottom; + SDL_Rect loc; + int *colors; + + // The top color is the low order nibble, so we can blank out the + // high order nibble by AND-ing a mask of 0x0f (which is b00001111, + // 15 decimal). The bottom color, ergo, is the high order nibble; + // for that, we simply shift the color 4 positions to the right. + top = color & 0x0F; + bottom = color >> 4; + + // The next thing we need to consider is where we draw the pixel + loc.x = (addr & 0xff) * mach->sysfont->width; + loc.y = (addr >> 8) * mach->sysfont->height; + loc.w = mach->sysfont->width; + loc.h = mach->sysfont->height / 2; + + colors = lores_colors[top]; + vm_screen_set_color(mach->screen, colors[0], colors[1], colors[2], 255); + vm_screen_draw_rect(mach->screen, loc.x, loc.y, loc.w, loc.h); + + colors = lores_colors[bottom]; + vm_screen_set_color(mach->screen, colors[0], colors[1], colors[2], 255); + vm_screen_draw_rect(mach->screen, loc.x, loc.y + loc.h, loc.w, loc.h); +} + void apple2_draw_text(apple2 *mach, vm_16bit addr) { @@ -25,6 +83,13 @@ apple2_draw_text(apple2 *mach, vm_16bit addr) return; } + // If we're updating a page 2 address and we're not in some kind of + // double resolution mode, then we shouldn't actually render the + // thing. + if (addr > 0x07FF && !apple2_is_double_video(mach)) { + return; + } + // In a given page for 40-column mode, you get 960 grid parts that // you may use. In 80-column mode, it's more like 1920 grid parts // (40x24 = 960, 80x24 = 1920). The way we look at this is the diff --git a/tests/apple2.c b/tests/apple2.c index 083aa59..a4a5bbe 100644 --- a/tests/apple2.c +++ b/tests/apple2.c @@ -8,7 +8,7 @@ static apple2 *mach; void setup() { - mach = apple2_create(); + mach = apple2_create(700, 480); } void diff --git a/tests/vm_screen.c b/tests/vm_screen.c index 682e624..237d3d8 100644 --- a/tests/vm_screen.c +++ b/tests/vm_screen.c @@ -4,23 +4,18 @@ Test(vm_screen, create) { vm_screen *screen; - int x = 320; - int y = 240; - int scale = 2; - screen = vm_screen_create(x, y, scale); + screen = vm_screen_create(); cr_assert_neq(screen, NULL); - cr_assert_eq(screen->xcoords, x); - cr_assert_eq(screen->ycoords, y); - cr_assert_eq(screen->scale, scale); - cr_assert_eq(screen->window, NULL); cr_assert_eq(screen->render, NULL); cr_assert_eq(screen->rect.x, 0); cr_assert_eq(screen->rect.y, 0); cr_assert_eq(screen->rect.w, 0); cr_assert_eq(screen->rect.h, 0); + cr_assert_eq(screen->xcoords, 0); + cr_assert_eq(screen->ycoords, 0); vm_screen_free(screen); }