First version
This commit is contained in:
commit
24cfdc0b6a
|
@ -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
|
|
@ -0,0 +1,235 @@
|
||||||
|
//
|
||||||
|
// a2graph.c
|
||||||
|
// test
|
||||||
|
//
|
||||||
|
// Created by Paulo Garcia on 2015-11-26.
|
||||||
|
// Copyright © 2015 Paulo Garcia. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <peekpoke.h>
|
||||||
|
|
||||||
|
#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<x1) {
|
||||||
|
//swap
|
||||||
|
pos=x2;
|
||||||
|
x2=x1;
|
||||||
|
x1=pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = x2-x1;
|
||||||
|
|
||||||
|
y1 = y >> 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<length;pos++) {
|
||||||
|
*(crt+pos) = (*(crt+pos) & c1) | c2;
|
||||||
|
}
|
||||||
|
// Copy it back to video position
|
||||||
|
memcpy((void *)(textbase[y1]+x1), (void *)crt, length);
|
||||||
|
free(crt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gr_vlin(unsigned int y1, unsigned int y2, unsigned int x, colors_t color, int page)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
unsigned char c2;
|
||||||
|
|
||||||
|
if (y2<y1) {
|
||||||
|
//swap
|
||||||
|
pos=y2;
|
||||||
|
y2=y1;
|
||||||
|
y1=pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = x + page;
|
||||||
|
c2 = (unsigned char ) ((int)color & 15);
|
||||||
|
|
||||||
|
for (pos=y1;pos<=y2;pos++) {
|
||||||
|
gr_plot1(x,pos,c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void gr_plot(int x,int y,colors_t color,int page)
|
||||||
|
{
|
||||||
|
unsigned char c2;
|
||||||
|
|
||||||
|
x = x + page;
|
||||||
|
c2 = (unsigned char ) ((int)color & 15);
|
||||||
|
|
||||||
|
gr_plot1(x,y,c2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Internal plot - don't call directly
|
||||||
|
x already account for page, and color is calculated too
|
||||||
|
*/
|
||||||
|
void gr_plot1(int x, int y, unsigned char c2)
|
||||||
|
{
|
||||||
|
unsigned char *crt, c1;
|
||||||
|
int y1 = y >> 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
* gr2
|
||||||
|
*
|
||||||
|
* Created by Paulo Garcia on 2015-12-16.
|
||||||
|
* Copyright (c) 2015 Paulo Garcia. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <peekpoke.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
Loading…
Reference in New Issue