Created Program.java to hold and manipulate program data. Created Parser.java to contain all methods needed for parsing. Created test.asm as a test 6502 asm file. Changed Processor.java to import test.asm as a program, print the number of instructions, and print the contents of the file.
This commit is contained in:
parent
e976bd809c
commit
9145a37be8
27
Parser.java
Normal file
27
Parser.java
Normal file
@ -0,0 +1,27 @@
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Parser.java
|
||||
* Static class that handles all regex and parsing.
|
||||
*
|
||||
* @author Christopher Erickson
|
||||
*/
|
||||
public class Parser {
|
||||
|
||||
/**
|
||||
* Returns true if line is an instruction. False otherwise.
|
||||
*
|
||||
* @param line The line to be parsed.
|
||||
* @return True if line contains an instruction.
|
||||
*/
|
||||
public static boolean isInstruction( String line ) {
|
||||
// Setup instruction regex Instruction Operand Comment
|
||||
// This is not perfect and needs to accomodate symbols
|
||||
Pattern instruction = Pattern.compile( "^\\s*\\w{3}\\s+\\w*\\s*(;.*)?$" );
|
||||
Matcher regex = instruction.matcher( line );
|
||||
if ( regex.matches() )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
*
|
||||
* @author Christopher Erickson and Christopher Pable
|
||||
*/
|
||||
import java.util.regex.*;
|
||||
|
||||
public class Processor {
|
||||
/* Registers */ // 0 1 2 3 4 5 6 7
|
||||
@ -14,6 +13,8 @@ public class Processor {
|
||||
private Register Y; // Index register
|
||||
private Register SP; // Stack pointer ( Usage of page $01 implied )
|
||||
private PC PC; // Program counter
|
||||
/* Program */
|
||||
private Program theProgram;
|
||||
|
||||
// Default Constructor
|
||||
public Processor() {
|
||||
@ -45,10 +46,11 @@ public class Processor {
|
||||
SP.setVal("$ff");
|
||||
PC.setVal("%0000000000000000");
|
||||
|
||||
// Parse & execute!
|
||||
// Not yet implemented
|
||||
executeInstructionAt( PC );
|
||||
|
||||
// Read in our program
|
||||
theProgram = new Program( "test.asm" );
|
||||
|
||||
// Print it out
|
||||
System.out.println( theProgram );
|
||||
}
|
||||
|
||||
// Prints out the value of each register, used for testing
|
||||
@ -61,28 +63,15 @@ public class Processor {
|
||||
System.out.println("PC:\t" + PC.getValHex());
|
||||
}
|
||||
|
||||
/*
|
||||
* Here's the important stuff.
|
||||
*
|
||||
* Of course the stuff below (the parsing) is merely an example of what
|
||||
* I'll be doing. You'll handle things like the ADC method. Notice that
|
||||
* you will ALWAYS receive three bytes. If I parse a memory address, I will
|
||||
* use that Word to get the byte in memory it refers to, and then send you
|
||||
* that, so you will never receive a Word. Only Bytes.
|
||||
*
|
||||
*/
|
||||
|
||||
// THE FOLLOWING IS MERELY AN EXAMPLE
|
||||
|
||||
// Parsing stuff that I would do
|
||||
private String inst = " adc #$45 ";
|
||||
public void executeInstructionAt( Word prgAddr ) {
|
||||
public void execInst( Word prgAddr ) {
|
||||
// Setup instruction regex Instruction Immediate Comment
|
||||
Pattern instruction = Pattern.compile( "^\\s*(\\w{3})\\s+#(\\$[0-9abcdef]{1,2})\\s*(;\\w*)?.*$" );
|
||||
//Pattern instruction = Pattern.compile( "^\\s*(\\w{3})\\s+#(\\$[0-9abcdef]{1,2})\\s*(;\\w*)?.*$" );
|
||||
// Grabbed matched items
|
||||
Matcher matched = instruction.matcher( inst );
|
||||
//Matcher matched = instruction.matcher( inst );
|
||||
// Call the opcode!
|
||||
ADC( A, A, new Byte( matched.group(2) ) );
|
||||
//ADC( A, A, new Byte( matched.group(2) ) );
|
||||
}
|
||||
|
||||
// OPCODE HELPERS
|
||||
|
110
Program.java
Normal file
110
Program.java
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Program.java
|
||||
* Handles all file reading, writing, and accessing
|
||||
*
|
||||
* @author Christopher Erickson
|
||||
*/
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Vector;
|
||||
|
||||
public class Program {
|
||||
/* Class Variables */
|
||||
Vector<String> theProgram; // Stores the program.
|
||||
Vector<Integer> instTable; // Keeps track of where instructions are located in theProgram.
|
||||
|
||||
/**
|
||||
* Creates an instance of Program.
|
||||
* Reads in fileName as a vector and indexes instructions.
|
||||
*
|
||||
* @param fileName Location of the file to be read.
|
||||
*/
|
||||
public Program( String fileName ) {
|
||||
// Read the file in as a vector
|
||||
theProgram = asmFileToVector( fileName );
|
||||
// Parse the instructions and index them
|
||||
instTable = parseInstructions();
|
||||
System.out.println( "Number of instructions: " + instTable.size() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vector from a 6502 asm file.
|
||||
* Based on code from:
|
||||
* http://www.java2s.com/Code/Java/File-Input-Output/Filereadandwrite.htm
|
||||
*
|
||||
* @param asmFile The full location of the input file.
|
||||
* @return Vector containing all the lines of the file.
|
||||
*/
|
||||
public Vector<String> asmFileToVector( String asmFile ) {
|
||||
// Okay, maybe there's room for just a little Spaceballs humor :)
|
||||
Vector<String> victor = new Vector<String>();
|
||||
String curLine;
|
||||
try {
|
||||
File asm = new File( asmFile );
|
||||
BufferedReader buffReader = new BufferedReader(
|
||||
new InputStreamReader(
|
||||
new FileInputStream( asm )));
|
||||
|
||||
while ( ( curLine = buffReader.readLine() ) != null ) {
|
||||
victor.addElement( curLine );
|
||||
}
|
||||
|
||||
buffReader.close();
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
System.out.println( "File not found!" );
|
||||
}
|
||||
catch (IOException ex) {
|
||||
System.out.println( "I/O Error!" );
|
||||
}
|
||||
// Return the vector
|
||||
return victor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vector from a 6502 asm string.
|
||||
*
|
||||
* @param asmString The newline-delimited string containing asm.
|
||||
* @return Vector containing all the lines of the file.
|
||||
*/
|
||||
public Vector<String> asmToVector( String asm ) {
|
||||
Vector<String> victor = new Vector<String>();
|
||||
String[] asmString = asm.split( "\\n" );
|
||||
for ( int i = 0; i < asmString.length; i++ ) {
|
||||
victor.addElement( asmString[i] );
|
||||
}
|
||||
return victor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ArrayList indicative of the location of instructions in theProgram.
|
||||
*
|
||||
* @return ArrayList containing the indicies of instructions.
|
||||
*/
|
||||
public Vector<Integer> parseInstructions() {
|
||||
Vector<Integer> retArray = new Vector<Integer>();
|
||||
for ( int i = 0; i < theProgram.size(); i++ ) {
|
||||
if ( Parser.isInstruction( theProgram.get( i ) ) )
|
||||
retArray.add( i );
|
||||
}
|
||||
return retArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program as a newline-delimited string.
|
||||
*
|
||||
* @return theProgram as a String.
|
||||
*/
|
||||
public String toString() {
|
||||
String retString = "";
|
||||
for ( int i = 0; i < theProgram.size(); i++ ) {
|
||||
retString += theProgram.get( i ) + "\n";
|
||||
}
|
||||
return retString;
|
||||
}
|
||||
|
||||
}
|
260
test.asm
Normal file
260
test.asm
Normal file
@ -0,0 +1,260 @@
|
||||
; Sprite.asm
|
||||
; A sprite example with drawing routine.
|
||||
;
|
||||
; This could be applied to any sprite with
|
||||
; a little modification.
|
||||
;
|
||||
; Keys: WASD - Move mario is that direction
|
||||
; Q - Quit
|
||||
;
|
||||
; by NeoScriptor
|
||||
|
||||
start:
|
||||
; Let's draw Mario, and even move him!
|
||||
|
||||
; sprite = mario
|
||||
lda #<mario
|
||||
sta sprlow
|
||||
lda #>mario
|
||||
sta sprhigh
|
||||
|
||||
; Setup coordinates
|
||||
lda #8
|
||||
sta xpos
|
||||
lda #8
|
||||
sta ypos
|
||||
|
||||
; Width & height of sprite
|
||||
lda #16 ; width
|
||||
sta width
|
||||
lda #16 ; height
|
||||
sta height
|
||||
|
||||
mainloop:
|
||||
; Draw the sprite!
|
||||
jsr drawSprite
|
||||
|
||||
; Get the pressed key
|
||||
jsr getKey
|
||||
lda key
|
||||
cmp #0
|
||||
beq mainloop
|
||||
cmp #119
|
||||
beq wkey
|
||||
cmp #97
|
||||
beq akey
|
||||
cmp #115
|
||||
beq skey
|
||||
cmp #100
|
||||
beq dkey
|
||||
cmp #113
|
||||
beq qkey
|
||||
jmp mainloop
|
||||
wkey:
|
||||
; The w key was pressed
|
||||
; Move the sprite up
|
||||
lda ypos
|
||||
cmp #1
|
||||
bmi mainloop
|
||||
; Clear the bottom of the sprite
|
||||
clc
|
||||
adc height
|
||||
tay
|
||||
dey
|
||||
sty clsrow
|
||||
jsr clearLine
|
||||
dec ypos
|
||||
jmp mainloop
|
||||
akey:
|
||||
; The a key was pressed
|
||||
; Move the sprite left
|
||||
lda xpos
|
||||
cmp #0
|
||||
bmi mainloop
|
||||
dec xpos
|
||||
jmp mainloop
|
||||
skey:
|
||||
; The s key was pressed
|
||||
; Move the sprite down
|
||||
lda ypos
|
||||
cmp #16
|
||||
bpl mainloop
|
||||
; Clear the top of the sprite
|
||||
tay
|
||||
sty clsrow
|
||||
jsr clearLine
|
||||
inc ypos
|
||||
jmp mainloop
|
||||
dkey:
|
||||
; The d key was pressed
|
||||
; Move the sprite right
|
||||
lda xpos
|
||||
cmp #18
|
||||
bpl mainloop
|
||||
inc xpos
|
||||
jmp mainloop
|
||||
qkey:
|
||||
; The q key was pressed
|
||||
; End
|
||||
rts
|
||||
|
||||
; drawSprite - Draws a sprite
|
||||
; Note: Can only handle widths that are
|
||||
; multiples of two. i.e. 2, 4, 8, 16, etc
|
||||
drawSprite:
|
||||
; Initialize row & col
|
||||
lda #0
|
||||
sta row
|
||||
lda #0
|
||||
sta col
|
||||
|
||||
; Load the sprite
|
||||
lda sprlow
|
||||
sta $40
|
||||
lda sprhigh
|
||||
sta $41
|
||||
|
||||
drawloop:
|
||||
; Calculate where to grab data from using
|
||||
; row & col (width*row)+col
|
||||
ldy row
|
||||
lda #1
|
||||
; Do as many left shifts as it takes to mult
|
||||
; by the sprite width
|
||||
rowshift:
|
||||
tax
|
||||
tya
|
||||
asl
|
||||
tay
|
||||
txa
|
||||
asl
|
||||
cmp width
|
||||
bne rowshift
|
||||
; Done multiplying, result in y
|
||||
; Add col
|
||||
clc
|
||||
tya
|
||||
adc col
|
||||
tay
|
||||
|
||||
lda ($40), y ; Grab this pixel from sprite
|
||||
sta pixel
|
||||
|
||||
; Now we have to calculate where to put it!
|
||||
; ylookup(row + ypos) + (col + xpos)
|
||||
; Add row & ypos
|
||||
lda row
|
||||
clc
|
||||
adc ypos
|
||||
; Get appropriate value from table
|
||||
asl
|
||||
tax
|
||||
lda ylookup, x
|
||||
sta $50
|
||||
inx
|
||||
lda ylookup, x
|
||||
sta $51
|
||||
; Add col & xpos
|
||||
lda $50
|
||||
clc
|
||||
adc col
|
||||
adc xpos
|
||||
sta $50
|
||||
lda pixel
|
||||
ldy #0
|
||||
sta ($50), y ; Put it on the screen
|
||||
|
||||
; Increase the col
|
||||
inc col
|
||||
; If col != width, continue looping
|
||||
lda col
|
||||
cmp width
|
||||
bne drawloop
|
||||
; Otherwise, col = 0, row++
|
||||
lda #0
|
||||
sta col
|
||||
lda row
|
||||
clc
|
||||
adc #1
|
||||
sta row
|
||||
; If row == height, return
|
||||
lda row
|
||||
cmp height
|
||||
bne drawloop
|
||||
rts ; return
|
||||
|
||||
; drawSprite variables
|
||||
sprlow: dcb 0
|
||||
sprhigh: dcb 0
|
||||
width: dcb 0
|
||||
height: dcb 0
|
||||
row: dcb 0
|
||||
col: dcb 0
|
||||
pixel: dcb 0
|
||||
xpos: dcb 0
|
||||
ypos: dcb 0
|
||||
|
||||
; clearLine - Clears the line clsrow
|
||||
clearLine:
|
||||
lda clsrow
|
||||
; Get appropriate value from table
|
||||
asl
|
||||
tax
|
||||
lda ylookup, x
|
||||
sta $c0
|
||||
inx
|
||||
lda ylookup, x
|
||||
sta $c1
|
||||
lda #0
|
||||
ldy #0
|
||||
sta ($c0), y
|
||||
ldy #31
|
||||
clsLoop:
|
||||
sta ($c0), y
|
||||
dey
|
||||
bne clsLoop
|
||||
rts
|
||||
|
||||
; clearLine variables
|
||||
clsrow: dcb 0
|
||||
|
||||
; getKey - Stores the value of the pressed key
|
||||
getKey:
|
||||
lda $ff
|
||||
sta key
|
||||
lda #0
|
||||
sta $ff
|
||||
rts
|
||||
|
||||
; getKey variables
|
||||
key: dcb 0
|
||||
|
||||
; Table of mem corresponding to each row
|
||||
ylookup:
|
||||
dcb $00,$02,$20,$02,$40,$02,$60,$02
|
||||
dcb $80,$02,$a0,$02,$c0,$02,$e0,$02
|
||||
dcb $00,$03,$20,$03,$40,$03,$60,$03
|
||||
dcb $80,$03,$a0,$03,$c0,$03,$e0,$03
|
||||
dcb $00,$04,$20,$04,$40,$04,$60,$04
|
||||
dcb $80,$04,$a0,$04,$c0,$04,$e0,$04
|
||||
dcb $00,$05,$20,$05,$40,$05,$60,$05
|
||||
dcb $80,$05,$a0,$05,$c0,$05,$e0,$05
|
||||
|
||||
; Sprites
|
||||
mario: ; 16 x 16
|
||||
dcb 0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0
|
||||
dcb 0,0,0,2,2,2,2,2,2,2,2,2,2,0,0,0
|
||||
dcb 0,0,0,9,9,9,9,8,8,9,8,0,0,0,0,0
|
||||
dcb 0,0,9,9,8,9,8,8,8,9,8,8,8,0,0,0
|
||||
dcb 0,0,9,9,8,9,9,8,8,8,9,8,8,8,0,0
|
||||
dcb 0,0,9,9,9,8,8,8,8,9,9,9,9,0,0,0
|
||||
dcb 0,0,0,0,8,8,8,8,8,8,8,8,0,0,0,0
|
||||
dcb 0,0,0,9,9,9,2,9,9,9,0,0,0,0,0,0
|
||||
dcb 0,0,9,9,9,9,2,9,9,2,9,9,9,0,0,0
|
||||
dcb 0,9,9,9,9,9,2,2,2,2,9,9,9,9,0,0
|
||||
dcb 0,8,8,8,9,2,8,2,2,8,2,9,8,8,0,0
|
||||
dcb 0,8,8,8,8,2,2,2,2,2,2,8,8,8,0,0
|
||||
dcb 0,8,8,8,2,2,2,2,2,2,2,2,8,8,0,0
|
||||
dcb 0,0,0,2,2,2,2,0,2,2,2,2,0,0,0,0
|
||||
dcb 0,0,9,9,9,9,0,0,0,9,9,9,9,0,0,0
|
||||
dcb 0,9,9,9,9,9,0,0,0,9,9,9,9,9,0,0
|
Loading…
x
Reference in New Issue
Block a user