Skip to content

Commit

Permalink
[#314] zx-spectrum48k: border + background color
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed Feb 1, 2023
1 parent e467a4a commit 7501d00
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*
* <p>
* OUT:
* Bit 7 6 5 4 3 2 1 0
* 7 6 5 4 3 2 1 0
* +-------------------------------+
* | | | | E | M | Border |
* +-------------------------------+
Expand All @@ -49,7 +49,7 @@
* top to bottom.
* Each attribute byte colours an 8x8 character on the screen and is encoded as follows:
* <p>
* Bit 7 6 5 4 3 2 1 0
* 7 6 5 4 3 2 1 0
* +-------------------------------+
* | F | B | P2| P1| P0| I2| I1| I0|
* +-------------------------------+
Expand All @@ -75,8 +75,7 @@ public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener {
private final Context8080 cpu;

private int borderColor;
private boolean microphone;
private boolean ear;
private boolean microphoneAndEar;

private static int[] computeLineStartOffsets() {
final int[] result = new int[SCREEN_HEIGHT];
Expand Down Expand Up @@ -114,8 +113,7 @@ public void readScreen() {

public void reset() {
borderColor = 7;
microphone = false;
ear = true;
microphoneAndEar = false;
Arrays.fill(keymap, (byte) 0xBF);
}

Expand All @@ -128,7 +126,7 @@ public byte read(int portAddress) {
// A zero in one of the five lowest bits means that the corresponding key is pressed.
// If more than one address line is made low, the result is the logical AND of all single inputs

byte result = (byte)0xBF;
byte result = (byte) 0xBF;
if ((portAddress & 0xFEFE) == 0xFEFE) {
// SHIFT, Z, X, C, V
result &= keymap[0];
Expand All @@ -154,7 +152,7 @@ public byte read(int portAddress) {
// SPACE, SYM SHFT, M, N, B
result &= keymap[7];
}
if (!ear) {
if (!microphoneAndEar) {
result |= 0x40;
}
return result;
Expand All @@ -165,8 +163,7 @@ public void write(int portAddress, byte data) {
this.borderColor = data & 7;
if (((data & 0x10) == 0x10) || ((data & 0x8) == 0)) {
// the EAR and MIC sockets are connected only by resistors, so activating one activates the other
microphone = true;
ear = true;
microphoneAndEar = true;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,17 @@ public class DisplayCanvas extends Canvas implements AutoCloseable {
// a 3.5MHz/69888=50.08 Hz interrupt
private static final int REPAINT_CPU_TSTATES = 69888;

private static final int BORDER_WIDHT = 48; // pixels
private static final int BORDER_WIDTH = 48; // pixels
private static final int BORDER_HEIGHT = 56; // pixels
private static final int X_GAP = 48; // pixels
private static final int Y_GAP = 48; // pixels

private static final Color FOREGROUND = new Color(255, 255, 255);
private static final Color BACKGROUND = new Color(0xAA, 0xAA, 0xAA);

private static final Color[] COLOR_MAP = new Color[] {
new Color(0,0 ,0), // black
new Color(0,0, 0xEE), // blue
private static final Color[] COLOR_MAP = new Color[]{
new Color(0, 0, 0), // black
new Color(0, 0, 0xEE), // blue
new Color(0xEE, 0, 0), // red
new Color(0xEE, 0, 0xEE), // magenta
new Color(0, 0xEE, 0), // green
Expand All @@ -54,9 +55,9 @@ public class DisplayCanvas extends Canvas implements AutoCloseable {
new Color(0xEE, 0xEE, 0xEE) // white
};

private static final Color[] BRIGHT_COLOR_MAP = new Color[] {
new Color(0,0 ,0), // black
new Color(0,0, 0xFF), // blue
private static final Color[] BRIGHT_COLOR_MAP = new Color[]{
new Color(0, 0, 0), // black
new Color(0, 0, 0xFF), // blue
new Color(0xFF, 0, 0), // red
new Color(0xFF, 0, 0xFF), // magenta
new Color(0, 0xFF, 0), // green
Expand Down Expand Up @@ -154,28 +155,33 @@ protected void paint() {
byte[][] videoMemory = ula.videoMemory;
byte[][] attrMemory = ula.attributeMemory;

// border


graphics.setBackground(COLOR_MAP[ula.getBorderColor()]);
graphics.setColor(COLOR_MAP[ula.getBorderColor()]);
graphics.fillRect(
X_GAP, Y_GAP,
2*(BORDER_WIDTH + SCREEN_WIDTH*8 + BORDER_WIDTH),
2*(SCREEN_HEIGHT + 2*BORDER_HEIGHT)
);
int screenX = 0;
for (int y = 0; y < SCREEN_HEIGHT; y++) {
for (int x = 0; x < SCREEN_WIDTH; x++) {
byte row = videoMemory[x][y];
int attr = attrMemory[x][y/8];
int attr = attrMemory[x][y / 8];
Color[] colorMap = ((attr & 0x40) == 0x40) ? BRIGHT_COLOR_MAP : COLOR_MAP;
graphics.setBackground(colorMap[(attr >>> 3) & 7]);
graphics.setColor(colorMap[attr & 7]);

for (int i = 0; i < 8; i++) {
boolean bit = ((row << i) & 0x80) == 0x80;
if (bit) {
graphics.drawLine(
2*(X_GAP + BORDER_WIDHT) + 2*screenX + 2*i, 2*Y_GAP + 2*y,
2*(X_GAP + BORDER_WIDHT) + 2*screenX + 2*i + 1, 2*Y_GAP + 2*y);
graphics.drawLine(
2*(X_GAP + BORDER_WIDHT) + 2*screenX + 2*i, 2*Y_GAP + 2*y + 1,
2*(X_GAP + BORDER_WIDHT) + 2*screenX + 2*i + 1, 2*Y_GAP + 2*y + 1);
graphics.setColor(colorMap[attr & 7]);
} else {
graphics.setColor(colorMap[(attr >>> 3) & 7]);
}
graphics.drawLine(
X_GAP + 2 * (BORDER_WIDTH + screenX + i), Y_GAP + 2 * (BORDER_HEIGHT + y),
X_GAP + 2 * (BORDER_WIDTH + screenX + i) + 1, Y_GAP + 2 * (BORDER_HEIGHT + y));
graphics.drawLine(
X_GAP + 2 * (BORDER_WIDTH + screenX + i), Y_GAP + 2 * (BORDER_HEIGHT + y) + 1,
X_GAP + 2 * (BORDER_WIDTH + screenX + i) + 1, Y_GAP + 2 * (BORDER_HEIGHT + y) + 1);
}
screenX += 8;
}
Expand Down

0 comments on commit 7501d00

Please sign in to comment.