summaryrefslogtreecommitdiffstats
path: root/main.h
blob: 809a09baff3c280f30b8e962634f040bb5704f12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef MAIN_H
#define MAIN_H

#include <limits.h>
#include <stdbool.h>
#include "lookup.h"

bool render = false;

uint8_t V[16];//all the registers

#define WIDTH 64
#define HEIGHT 32

#define BITMASK(b) (1 << ((b) % CHAR_BIT))
#define BITSLOT(b) ((b) / CHAR_BIT)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))

//bittest that works with pointers
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

char *program; //program is defined here so it can be accessed in main.h
char *I; //left wild to be set later

int *pixels = NULL;//used SQL pixel setting

int returnPos[12];//the position to return to when the end of a subroute is reached (e.g. 0x00EE is reached). There's meant to be a 48 byte stack, but as on the COSMAC VIP there was 12, we do that.


//value of lower four bits of 8 bit string
int lowerFour(char s[])
{
return s[0] & 0x0F;
}

//value of upper four bits of 8 bit string
int upperFour(char s[])
{
return (s[0] & 0xF0) >> 4;
}

//Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N
//pixels. Each row of 8 pixels is read as bit-coded starting from memory location I;
//I value doesn’t change after the execution of this instruction.
//As described above, VF is set to 1 if any screen pixels are flipped from set to unset
//when the sprite is drawn, and to 0 if that doesn’t happen
int draw(uint8_t VX, uint8_t VY, int N)
{
render = true;
int bitPosition;//the bits read from I need to be bittested from bit 7 to 0. x can't be used since it goes from 0 to 7.

V[0xF] = 0;//0 by default, since if we don't unset pixels, then VF equals 0
bitPosition = 8;
for (int x=0; x<8; ++x)
	{
	--bitPosition;
	if (bitPosition == -1){printf("No\n"); exit(1);}
	for (int y=0; y<N; ++y)
		{
		//only draw if place to draw is within bounds
		if ((VX+x < WIDTH) && (VY+y < HEIGHT))//position of x is correct
			{
			if(CHECK_BIT(*(I+y),bitPosition))//draw white xor if bit in I+y is set, do not draw anything if pixel is black though
				{
				if (pixels[display[VY+y][VX+x]] == 0xFFFFFFFF){V[0xF] = 1;}//set VF to 1 if pixel to draw is already set
				pixels[display[VY+y][VX+x]] ^= 0xFFFFFFFF;//draw with XOR
				}
			}
		else
			{
			//use modulus make out of range writes start again at 0
			if(CHECK_BIT(*(I+y),bitPosition))//draw white xor if bit in I+y is set, do not draw anything if pixel is black though
				{
				if (pixels[display[(VY+y)%HEIGHT][(VX+x)%WIDTH]] == 0xFFFFFFFF){V[0xF] = 1;}
				pixels[display[(VY+y)%HEIGHT][(VX+x)%WIDTH]] ^= 0xFFFFFFFF;
				}
			}
		}

	}
}

void display_clear()
{
render = true;
for (int x = 0; x<WIDTH; ++x)
	{
	for (int y = 0; y<HEIGHT; ++y)
		{
		pixels[display[y][x]] = 0x00000000;
		}
	}
}


#endif