Coprolite.com
Google
 
Web Coprolite.com
SignalQ Sites:
L1G3R Information Systems - NetAdminTools - SpotBridge
RoboCoop - AreWeDown - SysAdminTools - NAW
Xfig - Gold Loaf - GeekPapa - FixGMC - FixRambler
Categories:
GNU/Linux | Homebrew designs | Perl | Microcontrollers | Graphics | Z-80 | FreeDOS | Electronics | Odyssey 2 | 8048 | Other/Msc.

Last 30 Days | Last 60 Days | Last 90 Days | All Articles/Links
Categories:
·GNU/Linux
·Homebrew Designs
·Perl
·Microcontrollers
·Graphics
·Z-80
·FreeDOS
·Other/Msc.
·Electronics
·8048
·All Categories
·Other SignalQ Websites


8048 Homebrew Simulation - Part 1 - Introduction
Topic:8048   Date: 2006-03-21
Printer Friendly: Print   Mobile View: mobile

There are five articles in this series:

Part 1 - 8048 Homebrew Simulation - Introduction
Part 2 - 8048 Homebrew Simulation - Java Source
Part 3 - 8048 Homebrew Simulation - Operation
Part 4 - 8048 Homebrew Simulation - Sample Machine Code
Part 5 - 8048 Homebrew Simulation - Simulation

I've always been a big fan of good old-fashioned red LED 7 segment displays, and I have added them to the digits for my virtual homebrew computer. Here is a picture of the homebrew computer running:



If you want to see this in action go straight to the simulation. Just toggle the run switch to watch it execute the program. I thought those of you doing web work might enjoy a taste of Java. Here is how the seven segment animation looks:



This run's well with Sun's VM. Get it at java.com. I've run this on GNU/Linux/Mozilla, Mac OS X/Firefox, Windows XP/IE6, NT/IE6, and Windows 2000/IE6 just fine, but you might have to get the new virtual machine from Sun.

Here is the Java code:

import java.applet.*;
import java.awt.*;
import java.lang.Integer;
public class dig extends Applet implements Animation {
private int dig;
int i;
byte locstate[][]={{1,3,3,1,3,3,0}
,{0,3,3,0,2,2,0},{1,3,2,1,3,2,1},{1,3,3,1,2,2,1}
,{0,3,3,0,2,3,1},{1,2,3,1,2,3,1},{1,2,3,1,3,3,1}
,{1,3,3,0,2,2,0},{1,3,3,1,3,3,1},{1,3,3,0,2,3,1}
,{1,3,3,0,3,3,1},{0,2,3,1,3,3,1},{1,2,2,1,3,3,0}
,{0,3,3,1,3,2,1},{1,2,2,1,3,3,1},{1,2,2,0,3,3,1}};
byte xoff[]={11,43,43,11,0,0,11};
byte yoff[]={0,8,42,68,42,8,34};
Dimension size;
Image buffer;
Graphics bufferGraphics;
AnimationTimer timer = new AnimationTimer(this, 500);
public void init(){
setBackground (Color.black);
size=this.size();
buffer=this.createImage(size.width, size.height);
bufferGraphics = buffer.getGraphics();
}
public void start() {
timer.start_animation();
dig=0;
}
public void paint(Graphics g) {
if (buffer != null)
g.drawImage(buffer, 0,0,this);
}
public void update(Graphics g){
if (buffer != null){
Image horoff = getImage(getCodeBase(), "horoff.jpg");
Image virtoff = getImage(getCodeBase(), "virtoff.jpg");
Image virton = getImage(getCodeBase(), "virton.jpg");
Image horon = getImage(getCodeBase(), "horon.jpg");
Image led = getImage(getCodeBase(), "led2.jpg");
Font  font = new Font("Helvetica", Font.BOLD, 10);
bufferGraphics.setFont(font);
for (i=0;i<=6;i++){
if(locstate[dig][i]==0)
bufferGraphics.drawImage (horoff, xoff[i],yoff[i], this);
else if (locstate[dig][i]==1)
bufferGraphics.drawImage (horon, xoff[i],yoff[i], this);
else if (locstate[dig][i]==2)
bufferGraphics.drawImage (virtoff, xoff[i],yoff[i], this);
else if (locstate[dig][i]==3)
bufferGraphics.drawImage (virton, xoff[i],yoff[i], this);
g.drawImage(buffer,0,0,this);
}
}
}
public void animate (){
dig++;
if(dig==16)
dig=0;
repaint();
}
public void stop() { timer.start_animation(); }
}
interface Animation { public void animate(); }
class AnimationTimer extends Thread {
Animation animation;
int delay;
public AnimationTimer(Animation animation, int delay) {
this.animation = animation;
this.delay = delay;
}
public void start_animation() {
if (isAlive()) super.resume();
else start();
}
public void pause_animation() { suspend(); }
public void run () {
for(;;) {
animation.animate();
try { Thread.sleep(delay); } catch (InterruptedException e) { ; }
}
}
}

I wrote most of the animation stuff over a weekend back in 1997, but recently added the digits. It was the first (and only) Java program I wrote. I was able to get a working virtual homebrew computer up by Monday. Ahhhhh... the joys of caffeine (C8H10N4O2). My meatworld homebrew computer was broken again, and I figured it would be more fun to go virtual. Of course, I needed a domain for this new virtual CPU. :) [I did eventually fix the meatworld version and finished the schematics.] I used Java 1.1 Unleashed to figure out how to code the Java. There are a lot of used copies around. True, my code is deprecated, now, but it works with the latest Sun JRE.

The coolest part, I think, is actually the graphics. A 7-segment display should show when off, as well as when on. Also, the light is diffused, and slightly uneven due to there being multiple LEDs under the plastic bar that diffuses the light. The 7-segment part I actually added to the site yesterday, but the single LEDs here were created back in 1997. I wanted the machine to operate much like the real thing. The code...

The tricky part about the code is how I set up the arrays. There are only four images that make up the display. Locstate is the state of a number. It will return what kind of segments for each location and whether they are on or off. There are 16 numbers (hex: 0-F). For each number, there are 7 segments. Each segment is one of the following:

0 = horizontal segment off
1 = horizontal segment on
2 = vertical segment off
3 = vertical segment on

So, locstate[0] is the code for the hex digit 0. I start at the top of the digit, and then rotate around. The top is 0. The middle is 6. The upper left is 5. This means that 1,3,3,1,3,3,0 translates to all segments on but the middle segment. The xoff and yoff are translations from the origin for each segment.

There are five articles in this series:

Part 1 - 8048 Homebrew Simulation - Introduction
Part 2 - 8048 Homebrew Simulation - Java Source
Part 3 - 8048 Homebrew Simulation - Operation
Part 4 - 8048 Homebrew Simulation - Sample Machine Code
Part 5 - 8048 Homebrew Simulation - Simulation


8048 Homebrew Simulation - Part 2 - Java Source
Topic:8048   Date: 2006-03-21
Printer Friendly: Print   Mobile View: mobile

There are five articles in this series:

Part 1 - 8048 Homebrew Simulation - Introduction
Part 2 - 8048 Homebrew Simulation - Java Source
Part 3 - 8048 Homebrew Simulation - Operation
Part 4 - 8048 Homebrew Simulation - Sample Machine Code
Part 5 - 8048 Homebrew Simulation - Simulation

Here is the Java source code:

import java.applet.*;
import java.awt.*;
import java.lang.Integer;
public class virthomebrew extends Applet implements Animation {
private int lastx, lasty, toggle , rega, pc, i;
boolean ledloc[]= new boolean [96];
boolean swloc[]= new boolean [27];
byte locstate[][]={{1,3,3,1,3,3,0}
,{0,3,3,0,2,2,0},{1,3,2,1,3,2,1},{1,3,3,1,2,2,1}
,{0,3,3,0,2,3,1},{1,2,3,1,2,3,1},{1,2,3,1,3,3,1}
,{1,3,3,0,2,2,0},{1,3,3,1,3,3,1},{1,3,3,0,2,3,1}
,{1,3,3,0,3,3,1},{0,2,3,1,3,3,1},{1,2,2,1,3,3,0}
,{0,3,3,1,3,2,1},{1,2,2,1,3,3,1},{1,2,2,0,3,3,1}};
byte xoff[]={11,43,43,11,0,0,11};
byte yoff[]={0,8,42,68,42,8,34};
Dimension size;
Image buffer;
Graphics bufferGraphics;
int mem[] = new int [65536];
String swtxt []={"A15","A14","A13","A12","A11","A10"," A9"," A8"," A7",
" A6"," A5"," A4"," A3"," A2"," A1"," A0"," D7"," D6",
" D5"," D4"," D3"," D2"," D1"," D0", " RD"," WR","RUN"};
AnimationTimer timer = new AnimationTimer(this, 1000);
public void init(){
setBackground (Color.black);
size=this.size();
buffer=this.createImage(size.width, size.height);
bufferGraphics = buffer.getGraphics();
}
public void start() {
for (int i=0;i<=95;i++){
ledloc[i]=false;
}
for (int i=0;i<=26;i++){
swloc[i]=false;
}
swloc[25]=true;
for (int i=0;i<=65535;i++){
mem[i]=255;
}
pc=0;
mem[0]=0x23;
mem[1]=0x00;
mem[2]=0xa8;
mem[3]=0x17;
mem[4]=0xa9;
mem[5]=0x17;
mem[6]=0xaa;
mem[7]=0x17;
mem[8]=0xab;
mem[9]=0x17;
mem[10]=0xac;
mem[11]=0x17;
mem[12]=0xad;
mem[13]=0x17;
mem[14]=0xae;
mem[15]=0x17;
mem[16]=0xaf;
mem[17]=0x17;
mem[18]=0x04;
mem[19]=0x02;
mem[20]=0x00;
mem[21]=0x00;
mem[22]=0x00;
mem[23]=0x00;
mem[24]=0x00;
mem[25]=0x00;
mem[26]=0x00;
mem[27]=0x00;
timer.start_animation();
}
public void paint(Graphics g) {
if (buffer != null)
g.drawImage(buffer, 0,0,this);
}
public void update(Graphics g){
if (buffer != null){
Image led = getImage(getCodeBase(), "led2.jpg");
Image horoff = getImage(getCodeBase(), "horoff.jpg");
Image virtoff = getImage(getCodeBase(), "virtoff.jpg");
Image virton = getImage(getCodeBase(), "virton.jpg");
Image horon = getImage(getCodeBase(), "horon.jpg");
Image ledoff = getImage(getCodeBase(), "led2off.jpg");
Image swoff = getImage(getCodeBase(), "switchoff.jpg");
Image swon = getImage(getCodeBase(), "switchon.jpg");
Font  font = new Font("Helvetica", Font.BOLD, 10);
bufferGraphics.setFont(font);
bufferGraphics.setColor(Color.gray);
bufferGraphics.drawString("Register 0",35,35);
bufferGraphics.drawString("Register 1",195,35);
bufferGraphics.drawString("Register 2",35,75);
bufferGraphics.drawString("Register 3",195,75);
bufferGraphics.drawString("Register 4",35,115);
bufferGraphics.drawString("Register 5",195,115);
bufferGraphics.drawString("Register 6",35,155);
bufferGraphics.drawString("Register 7",195, 155);
bufferGraphics.drawString("Switch Address",35,295);
bufferGraphics.drawString("Memory Data",35,335);
bufferGraphics.drawString("Switch Data",35,375);
bufferGraphics.drawString("Program Counter",508,130);
if (pc <16){
for (i=0;i<=6;i++){
if(locstate[0][i]==0)
bufferGraphics.drawImage (horoff, 489+xoff[i],30+yoff[i], this);
else if (locstate[0][i]==1)
bufferGraphics.drawImage (horon, 489+xoff[i],30+yoff[i], this);
else if (locstate[0][i]==2)
bufferGraphics.drawImage (virtoff, 489+xoff[i],30+yoff[i], this);
else if (locstate[0][i]==3)
bufferGraphics.drawImage (virton, 489+xoff[i],30+yoff[i], this);
}
for (i=0;i<=6;i++){
if(locstate[pc][i]==0)
bufferGraphics.drawImage (horoff, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc][i]==1)
bufferGraphics.drawImage (horon, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc][i]==2)
bufferGraphics.drawImage (virtoff, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc][i]==3)
bufferGraphics.drawImage (virton, 560+xoff[i],30+yoff[i], this);
}
}
else {
for (i=0;i<=6;i++){
if(locstate[1][i]==0)
bufferGraphics.drawImage (horoff, 489+xoff[i],30+yoff[i], this);
else if (locstate[1][i]==1)
bufferGraphics.drawImage (horon, 489+xoff[i],30+yoff[i], this);
else if (locstate[1][i]==2)
bufferGraphics.drawImage (virtoff, 489+xoff[i],30+yoff[i], this);
else if (locstate[1][i]==3)
bufferGraphics.drawImage (virton, 489+xoff[i],30+yoff[i], this);
}
for (i=0;i<=6;i++){
if(locstate[pc-16][i]==0)
bufferGraphics.drawImage (horoff, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc-16][i]==1)
bufferGraphics.drawImage (horon, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc-16][i]==2)
bufferGraphics.drawImage (virtoff, 560+xoff[i],30+yoff[i], this);
else if (locstate[pc-16][i]==3)
bufferGraphics.drawImage (virton, 560+xoff[i],30+yoff[i], this);
}
}
for (int i=0;i<=23;i++){
bufferGraphics.drawString(swtxt[i],swlbl(i+1),425);
}
for (int i=16;i<=18;i++){
bufferGraphics.drawString(swtxt[i+8],swlbl(i+1), 315);
}
for (int i=0; i<=3;i++){
for (int j=0;j<=15;j++){
if(ledloc[j+ i*16])
bufferGraphics.drawImage (led, 10+20*(j+1), 40*(i+1), this);
else
bufferGraphics.drawImage (ledoff, 10+20*(j+1), 40*(i+1), this);
}
}
for (int i=0;i<=15;i++){
if(ledloc[i+64])
bufferGraphics.drawImage (led, 10+20*(i+1), 300, this);
else
bufferGraphics.drawImage (ledoff, 10+20*(i+1), 300, this);
}
for (int i=0; i<=1;i++){
for (int j=0;j<=7;j++){
if(ledloc[j+ i*8 + 80])
bufferGraphics.drawImage (led, 10+20*(j+1), 40*(i+1)+300, this);
else
bufferGraphics.drawImage (ledoff, 10+20*(j+1), 40*(i+1)+300, this);
}
}
for (int i=1; i<=24;i++){
if(swloc[i-1])
bufferGraphics.drawImage (swon, 5+24*i, 425, this);
else
bufferGraphics.drawImage (swoff, 5+24*i, 425, this);
}
for (int i=17; i<=19;i++){
if(swloc[i+7])
bufferGraphics.drawImage (swon, 5+24*i, 325, this);
else
bufferGraphics.drawImage (swoff, 5+24*i, 325, this);
}
g.drawImage(buffer,0,0,this);
}
}
public boolean mouseDown(Event e, int x, int y) {
lastx = x;
lasty = y;
for(int i=1; i<=27; i++){
if (ontop(i))
toggle(i);
}
if (!swloc[26]){
if (!swloc[24]){
dectobin(mem[addval()], 80);
}
else if(swloc[24] & !swloc[25]){
mem[addval()]=datval();
}
}
repaint ();
return true;
}
public boolean ontop (int x){
if (x<=24) {
if (lastx >= 5+x24 & lastx <= 25 +x24 & lasty >= 425 & lasty <= 465)
return true;
else
return false;
}
else {
if (lastx >= 5+(x-8)*24 & lastx <= 25 +(x-8)*24 & lasty >= 325 & lasty <= 365)
return true;
else
return false;
}
}
public void toggle (int x){
if (swloc[x-1]){
swloc[x-1] = false;
}
else
swloc[x-1] = true;
if (x <= 16){
ledloc[63+x]=swloc[x-1];
}
if (x > 16 && x < 25){
ledloc[71 + x]=swloc[x-1];
}
}
public int swlbl (int x){
if (x<=24)
return 10+x*24;
else
return 10+(x-8)*24;
}
public void dectobin (int x, int y){
for (int i=7;i>=0;i--){
if (x >= twotox(i)){
ledloc[y+7-i]=true;
x=x-twotox(i);
}
else
ledloc[y+7-i]=false;
}
}
public int twotox (int x){
int y=1;
for(int i=1;i<=x & x>0 & x < 1024;i++){
y=2*y;
}
return y;
}
public int addval (){
int y=0;
for (int i=0;i<=15;i++){
if (swloc[i])
y=y+twotox(15-i);
}
return y;
}
public int datval (){
int y=0;
for (int i=0;i<=7;i++){
if (swloc[i+16])
y=y+twotox(7-i);
}
return y;
}
public void animate (){
int j;
if (swloc[26]){
if (mem[pc]==0x23){
rega=mem[pc+1];
pc=pc+2;
}
else if (mem[pc]==0xa8){
dectobin(rega,port(0));
pc=pc+1;
}
else if (mem[pc]==0xa9){
dectobin(rega,port(1));
pc=pc+1;
}
else if (mem[pc]==0xaa){
dectobin(rega,port(2));
pc=pc+1;
}
else if (mem[pc]==0xab){
dectobin(rega,port(3));
pc=pc+1;
}
else if (mem[pc]==0xac){
dectobin(rega,port(4));
pc=pc+1;
}
else if (mem[pc]==0xad){
dectobin(rega,port(5));
pc=pc+1;
}
else if (mem[pc]==0xae){
dectobin(rega,port(6));
pc=pc+1;
}
else if (mem[pc]==0xaf){
dectobin(rega,port(7));
pc=pc+1;
}
else if (mem[pc]==0x17){
rega++;
if (rega==256)
rega=0;
pc++;
}
else if (mem[pc]==0x00){
pc++;
}
else if (mem[pc]==0x04){
j=mem[pc+1];
pc=j;
}
repaint();
}
}
public int port (int x) {
if(x==0){
return 0;
}
else if(x==1){
return 8;
}
else if(x==2){
return 16;
}
else if(x==3){
return 24;
}
else if(x==4){
return 32;
}
else if(x==5){
return 40;
}
else if(x==6){
return 48;
}
else if(x==7){
return 56;
}
else
return 56;
}
public void stop() { timer.start_animation(); }
}
interface Animation { public void animate(); }
class AnimationTimer extends Thread {
Animation animation;
int delay;
public AnimationTimer(Animation animation, int delay) {
this.animation = animation;
this.delay = delay;
}
public void start_animation() {
if (isAlive()) super.resume();
else start();
}
public void pause_animation() { suspend(); }
public void run () {
for(;;) {
animation.animate();
try { Thread.sleep(delay); } catch (InterruptedException e) { ; }
}
}
}

For an explanation of this code, see this article.

There are five articles in this series:

Part 1 - 8048 Homebrew Simulation - Introduction
Part 2 - 8048 Homebrew Simulation - Java Source
Part 3 - 8048 Homebrew Simulation - Operation
Part 4 - 8048 Homebrew Simulation - Sample Machine Code
Part 5 - 8048 Homebrew Simulation - Simulation


8048 Homebrew Simulation - Part 3 - Operation
Topic:8048   Date: 2006-03-21
Printer Friendly: Print   Mobile View: mobile

There are five articles in this series:

Part 1 - 8048 Homebrew Simulation - Introduction
Part 2 - 8048 Homebrew Simulation - Java Source
Part 3 - 8048 Homebrew Simulation - Operation
Part 4 - 8048 Homebrew Simulation - Sample Machine Code
Part 5 - 8048 Homebrew Simulation - Simulation

After the app loads, toggle RUN to watch the initial program. This app let's you program and verify a 64k memory. To read: RUN and RD off, WR on. Just toggle the address switches to change the address. The LEDs on the lower middle bank of eight will show the data at the address pointed to by the switches. To write: RUN off, RD on, and WR off. Off is down. On is up. You have limited commands, but you can actually load and run a program. For instance, if you reload the app, and reprogram location 1 by flipping A0 up, and set it to a higher number, and then click run, the machine will increment each register and display it starting with the new value instead of 0x00



Recent Entries:
8048 Homebrew Simulation - Part 1 - Introduction2006-03-21
8048 Homebrew Simulation - Part 2 - Java Source2006-03-21
8048 Homebrew Simulation - Part 3 - Operation2006-03-21


Please read our Terms of Use and our Privacy Policy
Microsoft, Windows, Windows XP, Windows 2000, and NT are either trademarks or registered trademarks of Microsoft Corporation. Coprolite.com is not affiliated with Microsoft Corporation. Linux is a registered trademark of Linus Torvalds. All logos and trademarks in this site are property of their respective owner. Copyright 1997-2013 Coprolite.com