commit 24cfdc0b6a5cd6d632b116bb943ecf3e5f1ea144 Author: Paulo Garcia Date: Sun Jan 24 15:00:52 2016 -0500 First version diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a3c7b95 --- /dev/null +++ b/Makefile @@ -0,0 +1,94 @@ +# +# Makefile +# Apple2BuildPipelineSample +# +# Part of a sample build pipeline for Apple II software development +# +# Created by Quinn Dunki on 8/15/14. +# One Girl, One Laptop Productions +# http://www.quinndunki.com +# http://www.quinndunki.com/blondihacks +# + +include make/head.mk + +# Customize this file to control what gets built, what machines to +# target, where in memory to put it, etc. + +# The name of your system or binary file to build goes here: +PGM=gr2 + +# Set the config you are building for. See these pages for details: +# http://cc65.github.io/cc65/doc/apple2.html#s4 +# http://cc65.github.io/cc65/doc/apple2enh.html#s4 +# +# Uncomment the one you want below (the first one is the default): +# MACHINE = apple2 +# MACHINE = apple2-dos33 +# MACHINE = apple2-system +# MACHINE = apple2-loader +# MACHINE = apple2-reboot +# MACHINE = apple2enh +# MACHINE = apple2enh-dos33 +# MACHINE = apple2enh-system +# MACHINE = apple2enh-loader +# MACHINE = apple2enh-reboot + +# Uncomment and set this to your starting address in Apple II memory +# if necessary: +# START_ADDR = 6000 + +# Set the default CPU to assemble for. You can change this in the +# body of a .s file using control commands like ".PC02". Uncomment +# the one you want below (the first one is the default): +# CPU = 6502 +# CPU = 65SC02 +# CPU = 65C02 +# CPU = 65816 +# Note: You can assemble for 65816 in 16-bit mode but the C compiler +# will only produce 8-bit code. + +# Any *.c files in your main project directory will automatically be +# built. But, if you have subdirectories with C files in them, you +# should add them to the list of C_SRCS to build. Do that by +# uncommenting the following line and changing "someSubDir" to match +# the subdirectory you have created. Add multiple lines like this +# for each subdirectory: +# C_SRCS += $(wildcard someSubDir/*.c) + +# Any *.s files in your main project directory will automatically be +# built. But, if you have subdirectories with assembly files in them, +# you should add them to the list of ASM_SRCS to build. Do that by +# uncommenting the following line and changing "someSubDir" to match +# the subdirectory you have created. Add multiple lines like this +# for each subdirectory: +# ASM_SRCS += $(wildcard someSubDir/*.s) + +# If you have a non-standard cc65 install, you may need to change +# some of these. Uncomment the following line and change it to the +# correct path to CC65_HOME if the default is not correct: +# export CC65_HOME := /usr/local/lib/cc65 +# +# If the path to the cc65 binaries is not correct, uncomment this +# line and change it: +CC65_BIN = /usr/local/bin + +# If you want to add arguments to the compile commandline, add them +# to this variable: +# CFLAGS += -Os + +# If you want to add arguments to the assembly commandline, add them +# to this variable: +# ASMFLAGS += -g + +# If you want to add arguments to the link commandline, add them to +# this variable: +# LDFLAGS += -v + +# If you have java installed in a non-standard location, you can set +# the path to it by uncommenting the following line: +# export JAVA=/usr/bin/java + + +# Do not change anything else below here... +include make/tail.mk diff --git a/a2graph.c b/a2graph.c new file mode 100644 index 0000000..891fc41 --- /dev/null +++ b/a2graph.c @@ -0,0 +1,235 @@ +// +// a2graph.c +// test +// +// Created by Paulo Garcia on 2015-11-26. +// Copyright © 2015 Paulo Garcia. All rights reserved. +// + +#include +#include +#include +#include +#include + +#include "a2graph.h" + +void gr_setmode(unsigned int CRTMODE) +{ + /* note: the following constants must be hex values + or cc65 complains that the constant is a long */ + switch(CRTMODE) + { + case MODE_TEXT_PAGE_1: + POKE(0xc051,0); /* text */ + POKE(0xc054,0); /* page 1 */ + break; + case MODE_TEXT_PAGE_2: + POKE(0xc051,0); /* text */ + POKE(0xc055,0); /* page 2 */ + break; + case MODE_LORES_TEXT_PAGE_1: + POKE(0xc056,0); /* lo res */ + POKE(0xc054,0); /* page 1 */ + POKE(0xc050,0); /* set graphics */ + break; + case MODE_LORES_FULL_PAGE_1: + POKE(0xc056,0); /* lo res */ + POKE(0xc054,0); /* page 1 */ + POKE(0xc050,0); /* set graphics */ + POKE(0xc052,0); /* full graphics */ + break; + case MODE_LORES_FULL_PAGE_2: + POKE(0xc056,0); /* lo res */ + POKE(0xc055,0); /* page 2 */ + POKE(0xc050,0); /* set graphics */ + POKE(0xc052,0); /* full graphics */ + break; + case MODE_HIRES_FULL_PAGE_2: + POKE(0xc057,0); /* hi res */ + POKE(0xc055,0); /* page 2 */ + POKE(0xc050,0); /* set graphics */ + POKE(0xc052,0); /* full graphics */ + break; + case MODE_HIRES_FULL_PAGE_1: + default: + POKE(0xc057,0); /* hi res */ + POKE(0xc054,0); /* page 1 */ + POKE(0xc050,0); /* set graphics */ + POKE(0xc052,0); /* full graphics */ + } +} + + + + +void gr_fill(int page, unsigned ch) +{ + int idx; + unsigned fillcolor = ch * 0x11; + + for (idx = 0; idx < 8; idx++) { + memset ((char *)textbase[idx]+page, fillcolor, 0x78); + } +} + +void gr_hlin(unsigned int x1, unsigned int x2, unsigned int y, colors_t color, int page) +{ + + int length; + int y1, pos; + unsigned char c2 = (unsigned char ) ((int)color & 15); + unsigned char *crt, c1; + + if (x2> 1; + x1 = x1 + page; + + if (y&1) { + /* odd rows in high nibble mask value to preserve low nibble */ + c1 = 0xf; + c2 = c2 << 0x4; + } else { + /* even rows in low nibble mask value to preserve high nibble */ + c1 = 0xf0; + } + + crt = malloc(length); + + // Copy video memory first + memcpy((void *)crt, (void *)(textbase[y1]+x1), length); + + // Apply color to all positions + + if (crt) { + for (pos=0;pos> 1; + int *pos = textbase; + + if (y&1) { + /* odd rows in high nibble */ + /* mask value to preserve low nibble */ + c1 = 0xf; + c2 = c2 << 0x4; + } else { + /* even rows in low nibble */ + /* mask value to preserve high nibble */ + c1 = 0xf0; + } + + crt = (unsigned char *)(*(pos+y1))+x; + *crt = (*crt & c1) | c2; +} + +int gr_khit() +{ + unsigned char *KP = (unsigned char*)0xC000; + unsigned char c; + + /* read the keyboard buffer */ + /* and return 0 if no character is waiting */ + + c = KP[0]; + if(c<128)return 0; + return (int)c; +} + +void gr_clearkey() +{ + + /* return the last key press */ + unsigned char *KEYPRESS = (unsigned char*)0xC000; + /* clear the last key press */ + unsigned char *KEYCLEAR = (unsigned char*)0xC010; + + /* clear stragglers from the keyboard buffer */ + while(KEYPRESS[0] > 127)KEYCLEAR[0]=0; +} + +void gr_sprite(unsigned int x, unsigned int y, unsigned int w, unsigned int h, int page, unsigned char* cl) +{ + int x1,y1; + unsigned char ci = 0; + unsigned char *cl1 = cl; + int plt =0; // 0 = with mask - 1 = full byte + + x = x + page; + + y1 = y; + + do { + plt=0; + if (!(y&1) && (y1<(y+h-1))) { + // even row + plt=1; //doulbe + } + + if (plt) { + y1++; + } else { + // plot single line + for (x1=x;x1<(x+w);x1++) { + gr_plot1(x1,y1,*(cl1+ci)); + ci++; + } + } + y1++; + } while (y1<(y+h)); + +} + diff --git a/a2graph.h b/a2graph.h new file mode 100644 index 0000000..5e9815d --- /dev/null +++ b/a2graph.h @@ -0,0 +1,87 @@ +// +// a2graph.h +// test +// +// Created by Paulo Garcia on 2015-11-26. +// Copyright © 2015 Paulo Garcia. All rights reserved. +// + +#ifndef a2graph_h +#define a2graph_h + +#define PAGE_1 0 +#define PAGE_2 1024 + +#define MODE_TEXT_PAGE_1 0x0 +#define MODE_TEXT_PAGE_2 0x1 +#define MODE_LORES_FULL_PAGE_1 0x2 +#define MODE_LORES_FULL_PAGE_2 0x3 +#define MODE_HIRES_FULL_PAGE_1 0x4 +#define MODE_HIRES_FULL_PAGE_2 0x5 +#define MODE_LORES_TEXT_PAGE_1 0x6 + +/* Colors */ + +typedef enum { + BLACK = 0, + MAGENTA, + DARK_BLUE, + PURPLE, + DARK_GREEN, + GREY, + MEDIUM_BLUE, + LIGHT_BLUE, + BROWN, + ORANGE, + GREY_2, + PINK, + GREEN, + YELLOW, + AQUA, + WHITE +} colors_t; + +/* base addresses for primary text page */ +/* also the base addresses for the 48 scanline pairs */ +/* for lores graphics mode 40 x 48 x 16 colors */ +int textbase[24]={ + 0x0400, + 0x0480, + 0x0500, + 0x0580, + 0x0600, + 0x0680, + 0x0700, + 0x0780, + 0x0428, + 0x04A8, + 0x0528, + 0x05A8, + 0x0628, + 0x06A8, + 0x0728, + 0x07A8, + 0x0450, + 0x04D0, + 0x0550, + 0x05D0, + 0x0650, + 0x06D0, + 0x0750, + 0x07D0 +}; + +/* Function Prototypes */ +extern void gr_setmode(unsigned int CRTMODE); +extern void gr_plot(int x,int y, colors_t color,int page); +extern void gr_hlin(unsigned int x1, unsigned int x2, unsigned int y, colors_t color, int page); +extern void gr_vlin(unsigned int y1, unsigned int y2, unsigned int x, colors_t color, int page); +extern void gr_fill(int page, unsigned ch); +extern int gr_khit(); +extern void gr_clearkey(); +extern void gr_sprite(unsigned int x, unsigned int y, unsigned int w, unsigned int h, int page, unsigned char *); + +/* private functions */ +void gr_plot1(int x, int y, unsigned char c2); + +#endif /* a2graph_h */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..f104259 --- /dev/null +++ b/main.c @@ -0,0 +1,83 @@ +/* + * main.c + * gr2 + * + * Created by Paulo Garcia on 2015-12-16. + * Copyright (c) 2015 Paulo Garcia. All rights reserved. + * + */ + + +#include +#include +#include +#include + +#include "a2graph.h" + +unsigned char sprite[36] = { BLACK, BLACK, BLACK, MAGENTA, MAGENTA, BLACK, + BLACK, BLACK, BLACK, MAGENTA, BLACK, BLACK, + BLACK, WHITE, BLACK, MAGENTA, BLACK, BLACK, + WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, + BLACK, BLACK, BLACK, MAGENTA, BLACK, BLACK, + BLACK, BLACK, BLACK, MAGENTA, MAGENTA, BLACK}; + +int my_test() +{ + int page=0; + int x,y; + //fill_screen(PAGE_1,0); + for (x=5;x<35;x++) { + for(y=10;y<36;y+=2) { + gr_plot(x, y, DARK_BLUE, page); + } + } + for (y=10;y<35;y++) { + for(x=5;x<36;x+=2) { + gr_plot(x, y, YELLOW, page); + } + } +} + +int main(void) +{ + int i,j; + + gr_clearkey(); + printf("Press any key to start..."); + while(gr_khit()==0); + + gr_setmode(MODE_LORES_TEXT_PAGE_1); + gr_fill(PAGE_1, BLACK); + + while(gr_khit()==0); + + my_test(); + j=0; + for(i=0;i<48;i++) { + gr_hlin(39,0,i,j,PAGE_1); + j++; + if (j==16) j=0; + } + + j=0; + for(i=0;i<40;i++) { + gr_vlin(47,0,i,j,PAGE_1); + j++; + if (j==16) j=0; + } + gr_clearkey(); + while(gr_khit()==0); + + for (i=33;i>0;i--) { + gr_sprite(i, 10, 6, 6, PAGE_1, sprite); + } + + gr_clearkey(); + while(gr_khit()==0); + for (i=0;i<16;i++) { + gr_fill(0, i); + } + + return 0; +}