Browse files

Further improvements to new parser

  • Loading branch information...
1 parent 4f989c7 commit 5cce4eed4be9111a0cfed8d77154b52477e958d8 @jamie124 committed Apr 11, 2012
View
BIN dcpu_emulator.suo
Binary file not shown.
View
286 dcpu_emulator/assembler.cpp
@@ -312,41 +312,33 @@ argumentStruct_t Assembler::argumentFor(char* arg)
/*
char *replace(char *st, char *orig, char *repl) {
- char buffer[MAX_CHARS];
- char *ch;
- if (!(ch = strstr(st, orig)))
- return st;
- strncpy(buffer, st, ch-st);
- buffer[ch-st] = 0;
- sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
+char buffer[MAX_CHARS];
+char *ch;
+if (!(ch = strstr(st, orig)))
+return st;
+strncpy(buffer, st, ch-st);
+buffer[ch-st] = 0;
+sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
- buffer[strlen(st)] = '\0';
+buffer[strlen(st)] = '\0';
- return buffer;
+return buffer;
}
*/
std::string replace(std::string& str, const std::string& from, const std::string& to) {
std::string temp = str;
- size_t start_pos = str.find(from);
- if(start_pos == std::string::npos)
- return false;
- return temp.replace(start_pos, from.length(), to);
-
+ size_t start_pos = str.find(from);
+ if(start_pos == std::string::npos)
+ return false;
+ return temp.replace(start_pos, from.length(), to);
+
}
int Assembler::compile(std::string filename)
{
- std::string compiledFilename = replace(filename, "asm", "bin");
-
- /*
- FILE* sourceFile = fopen(filename, "r");
-
- if (!sourceFile) {
- std::cout << "ERROR: Could not open " << filename << std::endl;
- }
- */
+ std::string compiledFilename = replace(filename, "dasm16", "bin");
std::ifstream sourceFile(filename);
@@ -363,9 +355,9 @@ int Assembler::compile(std::string filename)
}
char lineBuffer[MAX_CHARS];
- //std::string line;
bool foundComment = false;
+ bool finished = false;
word_t address = 0;
@@ -374,24 +366,30 @@ int Assembler::compile(std::string filename)
assembledInstruction_t* instruction = NULL;
char command[MAX_CHARS], label[MAX_CHARS], arg1[MAX_CHARS], arg2[MAX_CHARS], data[MAX_CHARS];
- //char* label;
+
+ bool processNextLine = true;
while (1) {
// Reset variables
for (int i = 0; i < MAX_CHARS; i++) {
data[i] = '\0';
- label[i] = '\0';
+
+ if (processNextLine) {
+ label[i] = '\0';
+ }
+
command[i] = '\0';
arg1[i] = '\0';
arg2[i] = '\0';
}
- // Read line into buffer
- //fgets(lineBuffer, MAX_CHARS, sourceFile);
-
+ if (!processNextLine) {
+ processNextLine = true;
+ }
if (sourceFile.getline(lineBuffer, MAX_CHARS).eof()) {
- break;
+ //break;
+ finished = true;
}
//std::cout << lineBuffer << std::endl;
@@ -402,95 +400,36 @@ int Assembler::compile(std::string filename)
// Check if whole line is a blank
if (strlen(temp) == 0) {
- std::cout << "Blank line, skipping whole line" << std::endl;
+ //std::cout << "Blank line, skipping whole line" << std::endl;
} else {
// Non blank line, start processing
// Get label if applicable
if (temp[0] == ':') {
- //label = (char*) malloc(MAX_CHARS * sizeof(char));
-
- processLine(temp, data, label, command, arg1, arg2, true);
+ processLine(temp, data, label, processNextLine, command, arg1, arg2, true);
std::cout << "label: " << label << " " << std::endl;
} else {
- //label = NULL;
-
- processLine(temp, data, label, command, arg1, arg2, false);
- }
-
- std::cout << "command: " << command << " arg1: " << arg1 << " arg2: " << arg2 << " dat: " << data << std::endl;
-
- processCommand(command, data, address, label, head, tail, instruction);
-
- processArg1(command, arg1, address, label, instruction);
- processArg2(command, arg2, address, label, instruction);
-
- /*
- assembledInstruction_t* instruction = new assembledInstruction_t;
-
- // Read the command
- if (fscanf(sourceFile, "%s", command) == 1) {
-
- // Add new instruction
- //assembledInstruction_t* instruction = (assembledInstruction_t*) malloc(sizeof(assembledInstruction_t));
-
- processCommand(sourceFile, command, address, label, head, tail, instruction);
-
- }
-
- if (fscanf(sourceFile, " %s", arg1) == 1) {
-
- opcode_t opcode = processArg1(sourceFile, command, arg1, address, label, instruction);
-
- if (opcode == OP_NONBASIC) {
- // No second argument
- instruction->b = instruction->a;
-
- instruction->a.argument = (argument_t) nonbasicOpcodeFor(command);
- instruction->a.labelReference = NULL;
-
- std::cout << "Non-basic opcode: " << instruction->a.argument << std::endl;
- } else {
- // Second argument
-
- if (fscanf(sourceFile, "%s", arg2) != 1) {
- std::cout << " ERROR: Missing second argument for " << command << " (got " << arg2 << ")" << std::endl;
- return -1;
- }
-
- int i = 0;
- while (arg2[i] != '\0') {
- arg2[i] = tolower(arg2[i]);
- i++;
-
- // Check for badly placed comment
- if (arg2[i] == ';') {
- foundComment = true;
- arg2[i] = '\0';
- }
+ processLine(temp, data, label, processNextLine, command, arg1, arg2, false);
}
- instruction->b = argumentFor(arg2);
+ if (processNextLine) {
+ processCommand(command, data, address, label, head, tail, instruction);
+ if (strcmp(command, "dat") != 0) {
+ processArg1(command, arg1, address, label, instruction);
+ processArg2(command, arg2, address, label, instruction);
+ }
- if (Cpu::usesNextWord(instruction->b.argument)) {
- address++;
- }
+ std::cout << "Command: " << command << " Arg1: " << arg1 << " Arg2: " << arg2 << " Dat: " << data << std::endl;
}
- } else {
- std::cout << "No more valid codes" << std::endl;
-
- fclose(sourceFile);
- */
- // Assemble binary code
-
-
- //break;
+ }
+ if (finished) {
+ break;
}
}
@@ -592,8 +531,9 @@ char* Assembler::cleanString(char *rawLine)
}
while (rawLine[rawIndex] != ';' && rawLine[rawIndex] != '\0') {
- if (rawLine[rawIndex] >= 65 && rawLine[rawIndex] < 123) {
- skippingChars = false;
+ if (rawLine[rawIndex] >= 65 && rawLine[rawIndex] < 123
+ || rawLine[rawIndex] == ':') {
+ skippingChars = false;
}
if (!skippingChars){
@@ -617,7 +557,7 @@ char* Assembler::cleanString(char *rawLine)
}
// Split up
-int Assembler::processLine(char *currentLine, char *data, char *label, char *command, char *arg1, char *arg2, bool containsLabel)
+int Assembler::processLine(char *currentLine, char *data, char *label, bool &functionOnNextLine, char *command, char *arg1, char *arg2, bool containsLabel)
{
int lineIndex = 0; // Current position in line
int itemIndex = 0; // Current position in item being stored
@@ -626,15 +566,34 @@ int Assembler::processLine(char *currentLine, char *data, char *label, char *com
// Don't include ':' in label
lineIndex++;
- //label = new char[MAX_CHARS * sizeof(char)];
-
// Read in until either a space or end of line is found
- while (currentLine[lineIndex] != ' ' && currentLine[lineIndex] != '\t' && currentLine[lineIndex] != '\n') {
- label[itemIndex++] = currentLine[lineIndex++];
+ while (currentLine[lineIndex] != ' ' && currentLine[lineIndex] != '\t'
+ && currentLine[lineIndex] != '\n' && currentLine[lineIndex] != '\0') {
+
+ label[itemIndex++] = currentLine[lineIndex++];
}
label[itemIndex++] = '\0';
+ int tempLineIndex = lineIndex;
+
+ while (currentLine[tempLineIndex] == ' ' || currentLine[tempLineIndex] == '\t'
+ || currentLine[tempLineIndex] != '\0') {
+
+ if (currentLine[tempLineIndex] < 65 || currentLine[tempLineIndex] > 122){
+ // Function code start the line below label.
+ functionOnNextLine = false;
+ } else {
+ functionOnNextLine = true;
+ }
+
+ tempLineIndex++;
+ }
+
+ if (!functionOnNextLine) {
+ return 1;
+ }
+
// Consume whitespace between label and command if needed
lineIndex++;
@@ -650,7 +609,11 @@ int Assembler::processLine(char *currentLine, char *data, char *label, char *com
// Check if label is on the same line as first statement
if ((currentLine[lineIndex] >= 32 && currentLine[lineIndex] < 127) &&
(currentLine[lineIndex] != ' ' || currentLine[lineIndex] != '\t')) {
- // Will be a alpha character, either lower or upper case.
+ // Consume any spaces or tabs between label and command
+ while (currentLine[lineIndex] == ' ' || currentLine[lineIndex] == '\t') {
+ lineIndex++;
+ }
+
while (currentLine[lineIndex] != ' ') {
command[itemIndex++] = currentLine[lineIndex++];
}
@@ -670,60 +633,79 @@ int Assembler::processLine(char *currentLine, char *data, char *label, char *com
itemIndex = 0;
- lineIndex++;
+ int i = strcmp(command, "dat");
+ if (strcmp(command, "dat") == 0) {
+ while (currentLine[lineIndex] == ' ' || currentLine[lineIndex] == '\t') {
+ lineIndex++;
+ }
- // Find first arg
- if ((currentLine[lineIndex] >= 65 && currentLine[lineIndex] < 123) || currentLine[lineIndex] == '[') {
- while (currentLine[lineIndex] != ',') {
- if (currentLine[lineIndex] == '\0') {
- // ',' was not found
- std::cout << "\",\" not found." << std::endl;
+ while (currentLine[lineIndex] != '\0' && currentLine[lineIndex] != ';'
+ && currentLine[lineIndex] != '0' && currentLine[lineIndex] != '\n'){
+ data[itemIndex++] = currentLine[lineIndex++];
+ }
- return -1;
- }
- arg1[itemIndex++] = currentLine[lineIndex++];
+ data[itemIndex++] = '\0';
- }
- }
+ } else {
- arg1[itemIndex++] = '\0';
+ itemIndex = 0;
- itemIndex = 0;
+ lineIndex++;
- // Find second arg, optional
- // Find start of second arg
- bool hasArg2 = false;
+ // Find first arg
+ if ((currentLine[lineIndex] >= 65 && currentLine[lineIndex] < 123) || currentLine[lineIndex] == '[') {
+ while (currentLine[lineIndex] != ',' && currentLine[lineIndex] != ' ') {
+ if (currentLine[lineIndex] == '\0') {
+ // ',' was not found
+ std::cout << "\",\" not found." << std::endl;
- if (currentLine[lineIndex] == ',') {
- // Check next character for ',' indicating a second arg
- hasArg2 = true;
- } else {
- while (currentLine[lineIndex] == ' ' && currentLine[lineIndex] != '\0' ) {
- lineIndex++;
+ return -1;
+ }
+
+ arg1[itemIndex++] = currentLine[lineIndex++];
+
+ }
}
- if (currentLine[lineIndex] == ','){
+
+ arg1[itemIndex++] = '\0';
+
+ itemIndex = 0;
+
+ // Find second arg, optional
+ // Find start of second arg
+ bool hasArg2 = false;
+
+ if (currentLine[lineIndex] == ',') {
+ // Check next character for ',' indicating a second arg
hasArg2 = true;
+ } else {
+ while (currentLine[lineIndex] == ' ' && currentLine[lineIndex] != '\0' ) {
+ lineIndex++;
+ }
+ if (currentLine[lineIndex] == ','){
+ hasArg2 = true;
+ }
}
- }
- if (hasArg2){
- while (currentLine[lineIndex] <= 48 || currentLine[lineIndex] >= 123) {
- lineIndex++;
- }
+ if (hasArg2){
+ while (currentLine[lineIndex] < 48 || currentLine[lineIndex] >= 123) {
+ lineIndex++;
+ }
- while (currentLine[lineIndex] != '\0' && currentLine[lineIndex] != ' '
- && currentLine[lineIndex] != '\t' && currentLine[lineIndex] != '\n'){
+ while (currentLine[lineIndex] != '\0' && currentLine[lineIndex] != ' '
+ && currentLine[lineIndex] != '\t' && currentLine[lineIndex] != '\n'){
- arg2[itemIndex++] = currentLine[lineIndex++];
- }
+ arg2[itemIndex++] = currentLine[lineIndex++];
+ }
- arg2[itemIndex++] = '\0';
- } else {
- arg2[0] = '\0';
- }
+ arg2[itemIndex++] = '\0';
+ } else {
+ arg2[0] = '\0';
+ }
+ }
itemIndex = 0;
}
@@ -792,7 +774,7 @@ int Assembler::processCommand(char* command, char *data, word_t &address, char*
}
escaped = 0;
- } else if (nextChar == '"') {
+ } else if (nextChar == '"' || nextChar == '\0') {
break;
} else if (nextChar == '\\') {
escaped = 1;
@@ -872,12 +854,12 @@ void Assembler::processArg1(char* command, char* arg, word_t &address, char* lab
i++;
}
- std::cout << "Argument 1: " << arg << std::endl;
+ //std::cout << "Argument 1: " << arg << std::endl;
// Determine opcode
instruction->opcode = opcodeFor(command);
//std::cout << "Basic opcode: " << instruction->opcode << std::endl;
- printf("Basic opcode: %d\n", instruction->opcode);
+ //printf("Basic opcode: %d\n", instruction->opcode);
instruction->a = argumentFor(arg);
@@ -907,7 +889,7 @@ void Assembler::processArg2(char* command, char* arg, word_t &address, char* lab
instruction->a.argument = (argument_t) nonbasicOpcodeFor(command);
instruction->a.labelReference = NULL;
- std::cout << "Non-basic opcode: " << instruction->a.argument << std::endl;
+ //std::cout << "Non-basic opcode: " << instruction->a.argument << std::endl;
} else {
memcpy(tempArg, arg, len + 1);
@@ -923,7 +905,7 @@ void Assembler::processArg2(char* command, char* arg, word_t &address, char* lab
i++;
}
- std::cout << "Argument 2: " << arg << std::endl;
+ //std::cout << "Argument 2: " << arg << std::endl;
/*
// Determine opcode
View
2 dcpu_emulator/assembler.h
@@ -31,7 +31,7 @@ class Assembler
argumentStruct_t argumentFor(char* arg);
char* cleanString(char *rawLine);
- int processLine(char *currentLine, char *data, char *label, char *command, char *arg1, char *arg2, bool containsLabel);
+ int processLine(char *currentLine, char *data, char *label, bool &functionOnNextLine, char *command, char *arg1, char *arg2, bool containsLabel);
int processCommand(char* command, char* data, word_t &address, char* label, assembledInstruction_t *&head, assembledInstruction_t *&tail, assembledInstruction_t *&instruction);
void processArg1(char* command, char* arg, word_t &address, char* label, assembledInstruction_t *&instruction);
View
4 dcpu_emulator/dcpu_emulator.vcxproj
@@ -73,14 +73,16 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
+ <None Include="demo_asm\atlas.dasm16" />
<None Include="demo_asm\demo.dasm16" />
<None Include="demo_asm\demo2.dasm16" />
<None Include="demo_asm\hello.dasm16" />
<None Include="demo_asm\loop.dasm16" />
- <None Include="demo_asm\notch.dasm16" />
+ <None Include="demo_asm\basic.dasm16" />
<None Include="demo_asm\os_test.dasm16" />
<None Include="demo_asm\rain.dasm16" />
<None Include="demo_asm\simple.dasm16" />
+ <None Include="demo_asm\subroutine.dasm16" />
<None Include="demo_asm\terminal.dasm16" />
<None Include="ReadMe.txt" />
</ItemGroup>
View
12 dcpu_emulator/dcpu_emulator.vcxproj.filters
@@ -31,9 +31,6 @@
<None Include="demo_asm\loop.dasm16">
<Filter>demo_asm</Filter>
</None>
- <None Include="demo_asm\notch.dasm16">
- <Filter>demo_asm</Filter>
- </None>
<None Include="demo_asm\os_test.dasm16">
<Filter>demo_asm</Filter>
</None>
@@ -46,6 +43,15 @@
<None Include="demo_asm\terminal.dasm16">
<Filter>demo_asm</Filter>
</None>
+ <None Include="demo_asm\basic.dasm16">
+ <Filter>demo_asm</Filter>
+ </None>
+ <None Include="demo_asm\subroutine.dasm16">
+ <Filter>demo_asm</Filter>
+ </None>
+ <None Include="demo_asm\atlas.dasm16">
+ <Filter>demo_asm</Filter>
+ </None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
View
0 dcpu_emulator/demo_asm/atlas.bin
No changes.
View
483 dcpu_emulator/demo_asm/atlas.dasm16
@@ -0,0 +1,483 @@
+; clear screen (for emulator)
+JSR clear
+
+SET [0xE000], proc01_start
+SET [0xD000], proc02_start
+
+; low level routines
+; runs best in DCPU-16 Studio (http://badsector.github.com/dcpustud/)
+
+; Bootmessage
+SET A, text_start
+JSR text_out
+
+; Reserve kernel-memory
+SET A, 0
+:kernel_mem IFG A, kernel_end
+ SET PC, kernel_mem_end
+JSR mem_reserve
+ADD A, 1024
+SET PC, kernel_mem
+:kernel_mem_end SET A, 0x8000
+JSR mem_reserve
+
+; Reserve stack-memory
+SET A, 0xFFFF
+JSR mem_reserve
+
+; OS ready message
+SET A, text_start_ok
+JSR text_out
+
+SET A, text_cmd
+JSR text_out
+
+
+:wait_loop
+; SET PC, wait_loop
+
+
+:kernel_loop
+
+ ; The Kernel does nothing so far...
+
+ JSR proc_suspend
+ SET PC, kernel_loop
+
+SET PC, stop
+
+; adds 32 bit integers (working)
+; A: address of first int
+; B: address of second int
+:int32_add
+ SET PUSH, C ; Save C
+ ADD [A], [B] ; Add lower parts
+ SET C, O ; Save overflow
+ ADD A, 1
+ ADD B, 1
+ ADD [A], [B] ; Add upper parts
+ ADD [A], C ; Add overflow
+ SUB A, 1
+ SUB B, 1
+ SET C, POP ; Restore C
+ SET PC, POP ; Jump back
+
+; subtracts 32 bit integers (working)
+; A: address of first int
+; B: address of second int
+:int32_sub
+ SET PUSH, C ; Save C
+ SUB [A], [B]
+ SET C, O
+ ADD A, 1
+ ADD B, 1
+ ADD [A], C
+ SUB [A], [B]
+ SUB A, 1
+ SUB B, 1
+ SET C, POP
+ SET PC, POP
+
+; prints a text to stdout (working)
+; A: address of the text
+:text_out
+ SET PUSH, A
+ SET PUSH, B
+ SET PUSH, C
+ SET PUSH, I
+
+ SET B, [video_col]
+ SET I, [video_cur]
+
+:text_out_loop
+ SET C, [A]
+ IFE C, 0x0000
+ SET PC, text_out_end
+ IFE C, 0x00A0
+ SET PC, text_out_nl
+ IFG C, 0x00FF
+ AND C, 0x00FF
+ BOR C, B
+ SET [I], C
+ ADD A, 1
+ ADD I, 1
+ IFE I, 0x8200
+ SET PC, text_out_scroll
+ SET PC, text_out_loop
+
+:text_out_scroll
+ SET [video_cur], I
+ JSR scroll
+ SET I, [video_cur]
+ SET PC, text_out_loop
+
+:text_out_nl
+ SET [video_cur], I
+ JSR newline
+ SET I, [video_cur]
+ ADD A, 1
+ SET PC, text_out_loop
+
+:text_out_end
+ SET [video_cur], I
+ SET I, POP
+ SET C, POP
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; Linefeed (working)
+:newline
+ SET PUSH, A
+ SET PUSH, B
+
+ SET A, 0x0020
+ SET B, [video_cur]
+ ; SUB B, 0x8000
+ MOD B, A
+ SUB A, B
+ ADD [video_cur], A
+ IFE [video_cur], 0x8200
+ JSR scroll
+
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; Scrolls the screen one line (working)
+:scroll
+ SET PUSH, X
+ SET PUSH, Y
+
+ SET X, 0x8000
+ SET Y, 0x8020
+
+:scroll_loop1
+ SET [X], [Y]
+ ADD X, 1
+ ADD Y, 1
+ IFE Y, 0x8200
+ SET PC, scroll_loop2
+ SET PC, scroll_loop1
+
+:scroll_loop2
+ SET [X], [video_col]
+ ADD X, 1
+ IFE X, 0x8200
+ SET PC, scroll_end
+ SET PC, scroll_loop2
+
+:scroll_end
+ SUB [video_cur], 0x20
+ SET Y, POP
+ SET X, POP
+ SET PC, POP
+
+:clear
+ SET PUSH, A
+ SET PUSH, B
+
+ SET A, [video_mem]
+ SET B, [video_col]
+
+:clear_loop
+ SET [A], B
+ ADD A, 1
+ IFE A, 0x8200
+ SET PC, clear_end
+ SET PC, clear_loop
+
+:clear_end
+ SET [video_cur], [video_mem]
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; Finds free memory and reserves it
+; Return:
+; A: Start address of the newly allocated memory
+:mem_alloc
+ SET PUSH, B
+
+ SET A, mem_table
+:mem_alloc_loop
+ SET B, [A]
+ AND B, 0x00FF
+ IFE B, 0x0000
+ SET PC, mem_alloc_lower
+ SET B, [A]
+ AND B, 0xFF00
+ IFE B, 0x0000
+ SET PC, mem_alloc_upper
+ ADD A, 1
+ IFN A, mem_table_end
+ SET PC, mem_alloc_loop
+ SET A, 0x00
+
+:mem_alloc_end
+ SET B, POP
+ SET PC, POP
+
+:mem_alloc_lower
+ BOR [A], 0x0003
+ SUB A, mem_table
+ MUL A, 1024
+ SET PC, mem_alloc_end
+
+:mem_alloc_upper
+ BOR [A], 0x0300
+ SUB A, mem_table
+ MUL A, 1024
+ ADD A, 1024
+ SET PC, mem_alloc_end
+
+; Frees the memory previously reserved
+; A: Address of or in the memory to be freed
+:mem_free
+ SET PUSH, A
+ SET PUSH, B
+
+ SET B, A ; Make the Address the start address
+ MOD B, 1024
+ SUB A, B
+
+ DIV A, 1024
+ SET B, A
+ DIV A, 2
+ AND B, 1
+ ADD A, mem_table
+ IFN B, 0
+ SET PC, mem_free_upper
+ SET B, [A]
+ AND B, 0x00FF
+ IFN B, 0x0001
+ AND [A], 0xFF00
+ SET PC, mem_free_end
+
+:mem_free_upper
+ SET B, [A]
+ AND B, 0xFF00
+ IFN B, 0x0100
+ AND [A], 0x00FF
+
+:mem_free_end
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; mem_reserve
+; A: Address of or in the memory to reserve
+:mem_reserve
+ SET PUSH, A
+ SET PUSH, B
+
+ SET B, A ; Make the Address the start address
+ MOD B, 1024
+ SUB A, B
+
+ DIV A, 1024
+ SET B, A
+ DIV A, 2
+ AND B, 1
+ ADD A, mem_table
+ IFN B, 0
+ SET PC, mem_reserve_upper
+ AND [A], 0xFF00
+ BOR [A], 0x0001
+ SET PC, mem_reserve_end
+
+:mem_reserve_upper
+ AND [A], 0x00FF
+ BOR [A], 0x0100
+
+:mem_reserve_end
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; mem_clear
+; A: From Addr
+; B: Length
+:mem_clear
+ SET PUSH, A
+ SET PUSH, B
+
+ ADD B, A
+
+:mem_clear_loop
+ SET [A], 0
+ ADD A, 1
+ IFN A, B
+ SET PC, mem_clear_loop
+
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; A: source
+; B: dest
+; C: length
+:mem_copy
+ SET PUSH, A
+ SET PUSH, B
+ SET PUSH, C
+
+ ; Calulate the last address
+ ADD C, A
+
+:mem_copy_loop
+ SET [B], [A]
+ ADD A, 1
+ ADD B, 1
+ IFN A, C
+ SET PC, mem_copy_loop
+
+ SET C, POP
+ SET B, POP
+ SET A, POP
+ SET PC, POP
+
+; ##############################################################
+
+; proc_suspend
+:proc_suspend
+ SET [proc_buffer], [proc_current] ; Buffer the registers of the current process
+ SET [proc_buffer1], A
+ SET [proc_buffer2], B
+ SET [proc_buffer3], C
+ SET [proc_buffer4], X
+ SET [proc_buffer5], Y
+ SET [proc_buffer6], Z
+ SET [proc_buffer7], I
+ SET [proc_buffer8], J
+; SET [proc_buffer9], PC
+ SET [proc_buffer10], SP
+
+ ; Restore the Stackpointer so we can call subroutines
+ SET SP, [proc_table10]
+
+ ; Copy the buffered state to the table
+ SET A, proc_buffer
+
+ SET B, [proc_current]
+ MUL B, 12
+ ADD B, proc_buffer
+
+ SET C, 12
+
+ JSR mem_copy
+
+ ; Process saved, now restore the next proc
+ SET A, B
+ ADD A, 12
+:proc_suspend_loop
+ IFE A, proc_table_end
+ SET A, proc_table
+ SET X, [A]
+ IFN X, 0x0000
+ SET PC, proc_suspend_invoke
+ ADD A, 1
+ SET PC, proc_suspend_loop
+
+:proc_suspend_invoke
+ ; Copy the Processinformation to the buffer
+ SET B, proc_buffer
+ JSR mem_copy
+
+ SET [proc_current], [proc_buffer]
+ SET A, [proc_buffer1]
+ SET B, [proc_buffer2]
+ SET C, [proc_buffer3]
+ SET X, [proc_buffer4]
+ SET Y, [proc_buffer5]
+ SET Z, [proc_buffer6]
+ SET I, [proc_buffer7]
+ SET J, [proc_buffer8]
+ SET SP, [proc_buffer10]
+ SET PC, POP ; Jump into the Programm
+
+; ##############################################################
+
+; Halts the CPU
+:stop SET PC, stop
+
+:data
+:video_mem dat 0x8000
+:video_col dat 0x7000
+:video_cur dat 0x8000
+
+:text_start dat "AtlasOS v0.1 starting... ", 0x00
+:text_start_ok dat "OK", 0xA0, 0x00
+:text_cmd dat "$>;", 0xA0, 0x00
+
+:mem_table
+ dat 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+:mem_table_end
+
+:proc_current
+ dat 0x0001
+:proc_buffer
+ dat 0x0000
+:proc_buffer1
+ dat 0x0000
+:proc_buffer2
+ dat 0x0000
+:proc_buffer3
+ dat 0x0000
+:proc_buffer4
+ dat 0x0000
+:proc_buffer5
+ dat 0x0000
+:proc_buffer6
+ dat 0x0000
+:proc_buffer7
+ dat 0x0000
+:proc_buffer8
+ dat 0x0000
+:proc_buffer9
+ dat 0x0000
+:proc_buffer10
+ dat 0x0000
+:proc_buffer11
+ dat 0x0000
+:proc_table
+ dat 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+:proc_table10
+ dat 0xFFFF, 0xFFFF ; OS-Proc
+ dat 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0x0000 ; First proc
+ dat 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xD000, 0x0000 ; Second proc
+:proc_table_end
+
+:kernel_end
+
+
+; First Process
+:proc01
+
+:proc01_start
+ JSR mem_alloc
+ SET B, A
+ SET A, proc01_msg1
+ JSR text_out
+ JSR proc_suspend
+ SET A, B
+ JSR mem_free
+ SET A, proc01_msg2
+ JSR text_out
+ JSR proc_suspend
+ SET PC, proc01_start
+
+:proc01_msg1
+ dat "Memory allocated!", 0xA0, 0x00
+:proc01_msg2
+ dat "Memory freed!", 0xA0, 0x00
+
+:proc02
+:proc02_start
+ SET A, proc02_msg1
+ JSR text_out
+ JSR proc_suspend
+ SET PC, proc02_start
+
+:proc02_msg1
+ dat "Hello", 0xA0, 0x00
View
9 dcpu_emulator/demo_asm/basic.dasm16
@@ -0,0 +1,9 @@
+ ; Try some basic stuff
+ SET A, 0x30 ; 7c01 0030
+ SET [0x1000], 0x20 ; 7de1 1000 0020
+ SUB A, [0x1000] ; 7803 1000
+ IFN A, 0x10 ; c00d
+ SET PC, crash ; 7dc1 001a [*]
+
+ ; Hang forever. X should now be 0x40 if everything went right.
+ :crash SET PC, crash ; 7dc1 001a [*]
View
BIN dcpu_emulator/demo_asm/hello.bin
Binary file not shown.
View
9 dcpu_emulator/demo_asm/hello.dasm16
@@ -6,12 +6,15 @@ set a, 0xbeef ; Assign 0xbeef to register a
set PC, end ; .. and jump to end if they don't match
set i, 0 ; Init loop counter, for clarity
-:nextchar ife [data+i], 0 ; If the character is 0 ..
+:nextchar
+ ife [data+i], 0 ; If the character is 0 ..
set PC, end ; .. jump to the end
set [0x8000+i], [data+i] ; Video ram starts at 0x8000, copy char there
add i, 1 ; Increase loop counter
set PC, nextchar ; Loop
-:data dat "Hello world!\n"
+:data
+ dat "Hello world!\n", 0
-:end sub PC, 1 ; Freeze the CPU forever
+:end
+ sub PC, 1 ; Freeze the CPU forever
View
BIN dcpu_emulator/demo_asm/loop.bin
Binary file not shown.
View
23 dcpu_emulator/demo_asm/loop.dasm16
@@ -1,16 +1,7 @@
-set i, 1
-
-:loop IFG i, 0x77
-SET PC, next
-SET [0x000e], i
-SET a, I
-MOD a, 8
-ADD a, 1
-MUL a, 0x1001
-SET [0x0020], a
-ADD i, 1
-SET PC, loop
-
-:next SET [0x0018], 0x1234
-
-SUB PC, 1
+ ; Do a loopy thing
+ SET I, 10 ; a861
+ SET A, 0x2000 ; 7c01 2000
+ :loop SET [0x2000+I], [A] ; 2161 2000
+ SUB I, 0 ; 8463
+ IFN I, 0 ; 806d
+ SET PC, loop ; 7dc1 000d [*]
View
BIN dcpu_emulator/demo_asm/notch.bin
Binary file not shown.
View
50 dcpu_emulator/demo_asm/notch.dasm16
@@ -1,50 +0,0 @@
-;Notch's examples
-;Should compile fine, by default
-
-;Try some basic stuff
- SET A, 0x30 ; 7c01 0030
- SET [0x1000], 0x20 ; 7de1 1000 0020
- SUB A, [0x1000] ; 7803 1000
- IFN A, 0x10 ; c00d
- SET PC, crash ; 7dc1 001a [*]
-
-;Do a loopy thing
- SET I, 10 ; a861
- SET A, 0x2000 ; 7c01 2000
-:loop SET [0x2000+I], [A] ; 2161 2000
- SUB I, 1 ; 8463
- IFN I, 0 ; 806d
- SET PC, loop ; 7dc1 000d [*]
-
-;Call a subroutine
- SET X, 0x4 ; 9031
- JSR testsub ; 7c10 0018 [*]
- SET PC, crash ; 7dc1 001a [*]
-
-:testsub
- SHL X, 4 ; 9037
- SET PC, POP ; 61c1
-
-
-;Hang forever. X should now be 0x40 if everything went right.
-:crash SET PC, crash ; 7dc1 001a [*]
-
-; Assembler test for DCPU
-; by Markus Persson
-
- set a, 0xbeef ; Assign 0xbeef to register a
- set [0x1000], a ; Assign memory at 0x1000 to value of register a
- ifn a, [0x1000] ; Compare value of register a to memory at 0x1000 ..
- set PC, end ; .. and jump to end if they don't match
-
- set i, 0 ; Init loop counter, for clarity
-:nextchar
- ife [data+i], 0 ; If the character is 0 ..
- set PC, end ; .. jump to the end
- set [0x8000+i], [data+i] ; Video ram starts at 0x8000, copy char there
- add i, 1 ; Increase loop counter
- set PC, nextchar ; Loop
-
-:data dat "Hello world!", 0 ; Zero terminated string
-
-:end sub PC, 1 ; Freeze the CPU forever
View
0 dcpu_emulator/demo_asm/os_test.bin
No changes.
View
BIN dcpu_emulator/demo_asm/subroutine.bin
Binary file not shown.
View
9 dcpu_emulator/demo_asm/subroutine.dasm16
@@ -0,0 +1,9 @@
+ ; Call a subroutine
+ SET X, 0x4 ; 9031
+ JSR testsub ; 7c10 0018 [*]
+
+ :testsub SHL X, 4 ; 9037
+ SET PC, POP ; 61c1
+
+ ; Hang forever. X should now be 0x40 if everything went right.
+:crash SET PC, crash ; 7dc1 001a [*]
View
BIN dcpu_emulator/demo_asm/terminal.bin
Binary file not shown.
View
39 dcpu_emulator/demo_asm/terminal.dasm16
@@ -1,20 +1,16 @@
; Program to do printing
-:start
- set I, 0
+:start set I, 0
; Print all the string characters.
-:loop
- set A, [string+I]
+:loop set A, [string+I]
add I, 1
ife A, 0
set PC, end
jsr putc
set PC, loop
-:end
- set PC, start
+:end set PC, start
; Put the character specified by A
-:putc
- set PUSH, B ; Destination address of character
+:putc set PUSH, B ; Destination address of character
ife A, [newline]
set PC, putc_newline
@@ -33,47 +29,38 @@
set PC, putc_end ; Still room on the line
; We need to go to the next line
-:putc_newline
- add [putc_line], 1
+:putc_newline add [putc_line], 1
set [putc_col], 0
ifg 16, [putc_line]
set PC, putc_end ; Still room on the screen
; We need to scroll!
jsr scroll
set [putc_line], 16
-:putc_end
- set B, POP
+:putc_end set B, POP
set PC, POP ; return
; Scroll the terminal up one line
; Each line is 32 words
-:scroll
- set PUSH, I ; Index in video ram
+:scroll set PUSH, I ; Index in video ram
set PUSH, A ; Index of thing we're copying
set I, 0x8000
-:scroll_loop
- set A, I
+:scroll_loop set A, I
add A, 32 ; Corresponding character on next line
ifg A, 0x8400 ; End of video ram
set PC, scroll_end ; return
set [I], [A] ; Copy back 32 words
add I, 1
set PC, scroll_loop
-:scroll_end
- set A, POP
+:scroll_end set A, POP
set I, POP
set PC, POP ; return
; Globals
-:putc_line
-dat 0
-:putc_col
-dat 0
-:string
-dat "Hello,\nscrolling,\nmy old friend; I've come to talk with you again.\n", 0
-:newline
-dat "\n"
+:putc_line dat 0
+:putc_col dat 0
+:string dat "Hello,\nscrolling,\nmy old friend; I've come to talk with you again.\n", 0
+:newline dat "\n"
View
4 dcpu_emulator/main.cpp
@@ -15,13 +15,13 @@ int _tmain(int argc, _TCHAR* argv[])
Assembler* assembler = new Assembler();
- assembler->compile("demo_asm/loop.dasm16");
+ assembler->compile("demo_asm/os_test.dasm16");
delete assembler;
Cpu* cpu = new Cpu();
- cpu->run("loop.bin");
+ cpu->run("demo_asm/os_test.bin");
delete cpu;

0 comments on commit 5cce4ee

Please sign in to comment.