Added stuff. Fixed bug.
Data Pointer value now properly displayed in debug mode. Added conditional calls to match conditional branches.
This commit is contained in:
@@ -0,0 +1,128 @@
|
|||||||
|
; print.asm
|
||||||
|
|
||||||
|
; Some simple SplitBit subroutines for printing.
|
||||||
|
; Anachronaut
|
||||||
|
; 10/27/2024
|
||||||
|
|
||||||
|
#Program
|
||||||
|
BRI start ; Branch immediately to the start of the program.
|
||||||
|
|
||||||
|
lineFeed:
|
||||||
|
INIA 0x0A ; Load the character for linefeed into A.
|
||||||
|
OUTA 0x00 ; Output it.
|
||||||
|
RET ; Return to the caller.
|
||||||
|
|
||||||
|
; Expects A to contain the number of spaces to print.
|
||||||
|
blankSpace:
|
||||||
|
INIB 0x20 ; Set B to the ASCII value for space.
|
||||||
|
OUTB 0x00 ; Print it.
|
||||||
|
BRA printDone ; If A is zero, we're done.
|
||||||
|
DECA ; Decrement A.
|
||||||
|
BRI blankSpace ; Branch back to the loop again.
|
||||||
|
|
||||||
|
printString: ; Expects Data Pointer to be set to the beginning of the string to be printed.
|
||||||
|
LDA ; Move the first character of the string into A.
|
||||||
|
BRA printDone ; If A is NULL, the string is finished, so return.
|
||||||
|
OUTA 0x00 ; Output the character.
|
||||||
|
INCD ; Increment Data Pointer to the next character.
|
||||||
|
BRI printString ; Branch to the beginning of the loop.
|
||||||
|
printDone:
|
||||||
|
RET ; Return to the caller.
|
||||||
|
|
||||||
|
; Expects A to contain the value to be printed in decimal form.
|
||||||
|
printByteDecimal:
|
||||||
|
; Clear the buffer we're going to write into.
|
||||||
|
SETD DecimalValue ; Set the Data Pointer to the buffer.
|
||||||
|
RSTB ; Set B to 0.
|
||||||
|
STB ; Store it in the buffer.
|
||||||
|
INCD ; Increment to the tens place.
|
||||||
|
STB ; Store 0 in it.
|
||||||
|
INCD ; Increment to the hundred's place.
|
||||||
|
STB ; Store 0 in it.
|
||||||
|
INIB 0d10 ; Load 10 into B.
|
||||||
|
PSHA ; Save the value onto the stack.
|
||||||
|
printDecimalLoopStart:
|
||||||
|
POPA ; Pop the value to A from the stack.
|
||||||
|
CCF ; Clear the Carry Flag.
|
||||||
|
SUB ; Subtract 10 from the value in A.
|
||||||
|
BRC getOnes ; If 10 is bigger than A, We're done looping and A contains the ones.
|
||||||
|
BRA getOnes ; If the value 0, we're also done.
|
||||||
|
; Otherwise, increment the tens place.
|
||||||
|
SETD DecimalValue ; Set the Data Pointer to the buffer.
|
||||||
|
INCD ; Increment to the tens place.
|
||||||
|
PSHQ ; Save the new value onto the stack.
|
||||||
|
LDA ; Load the number of tens into A.
|
||||||
|
INCA ; Increment it.
|
||||||
|
; Now check to see if there are ten tens and we need to carry to the hundreds.
|
||||||
|
CCF ; Clear the Carry Flag.
|
||||||
|
SUB ; Subtract 10 from A.
|
||||||
|
BRQ incrementHundreds ; If Q is 0, set the tens to 0 and increment the hundreds place.
|
||||||
|
STA ; Otherwise, store the value back to the tens place.
|
||||||
|
BRI printDecimalLoopStart ; and loop again.
|
||||||
|
incrementHundreds:
|
||||||
|
STQ ; Store 0 in the tens place.
|
||||||
|
INCD ; Increment the Data Pointer to the hundreds place.
|
||||||
|
LDA ; Load it into A.
|
||||||
|
INCA ; Increment it.
|
||||||
|
STA ; Store it back again.
|
||||||
|
BRI printDecimalLoopStart ; and Loop again.
|
||||||
|
getOnes:
|
||||||
|
SETD DecimalValue ; Set the Data Pointer to the ones place.
|
||||||
|
STA ; Store A in it.
|
||||||
|
; At this point we're done. We just need to print the digits with the printDecimalDigit subroutine.
|
||||||
|
INCD INCD ; Increment the Data Pointer twice to the hundreds place.
|
||||||
|
decimalCheckLoop:
|
||||||
|
LDA ; Load the value into A.
|
||||||
|
BRA checkTens ; If the hundreds are 0, skip printing their digit.
|
||||||
|
CALL printDecimalDigit ; Otherwise, print it.
|
||||||
|
DECD
|
||||||
|
LDA
|
||||||
|
CALL printDecimalDigit ; And the tens place, too.
|
||||||
|
BRI printOnes ; And finally, the ones.
|
||||||
|
checkTens:
|
||||||
|
DECD ; Decrement to the tens place.
|
||||||
|
LDA ; Load it into A.
|
||||||
|
BRA printOnes ; If the tens are zero, skip printing their digit, too.
|
||||||
|
CALL printDecimalDigit ; Otherwise, print it.
|
||||||
|
printOnes:
|
||||||
|
DECD ; Decrement to the ones place.
|
||||||
|
LDA
|
||||||
|
CALL printDecimalDigit ; Print it no matter what.
|
||||||
|
RET ; We're done, return to the caller.
|
||||||
|
|
||||||
|
; Expects A to contain the byte you want to print as a hexadecimal value.
|
||||||
|
printByteHex:
|
||||||
|
INIB 0x00 ; Set B to 0.
|
||||||
|
SHR SHR SHR SHR ; Shift Right four times to move the high nybble into the lower half of A.
|
||||||
|
CALL printHexDigit ; Print the nybble.
|
||||||
|
INIA 0x00 ; Set A to 0.
|
||||||
|
SHL SHL SHL SHL ; Shift left four times to move the low nybble back into the lower half of A.
|
||||||
|
CALL printHexDigit ; Print the nybble.
|
||||||
|
RET ; Return to the caller.
|
||||||
|
|
||||||
|
; Expects A to contain the nybble you want to print.
|
||||||
|
printHexDigit:
|
||||||
|
INIB 0d10 ; Set B to 10.
|
||||||
|
SUB ; Subtract it.
|
||||||
|
BRC printDecimalDigit ; If the Carry Flag is set, the digit is less than 9. Print it.
|
||||||
|
; Since it's greater than 9, add the ASCII offset for capital letters.
|
||||||
|
INIB 0x37 ; Set B to the offset.
|
||||||
|
ADD ; Add it to A.
|
||||||
|
OUTQ 0x00 ; Print the result.
|
||||||
|
RET ; Return to the caller.
|
||||||
|
|
||||||
|
; Expects A to contain a single BCD digit to print.
|
||||||
|
printDecimalDigit:
|
||||||
|
INIB 0x30 ; Load ASCII offset for numbers into B.
|
||||||
|
CCF ; Clear the Carry Flag.
|
||||||
|
ADD ; Add it to A.
|
||||||
|
OUTQ 0x00 ; Send it to the output.
|
||||||
|
RET ; Return from subroutine.
|
||||||
|
|
||||||
|
#Data
|
||||||
|
|
||||||
|
; This is where printDecimal stores its result.
|
||||||
|
DecimalValue:
|
||||||
|
0x00 ; The ones place.
|
||||||
|
0x00 ; The tens place.
|
||||||
|
0x00 ; The hundreds place.
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
; 10/27/2024
|
; 10/27/2024
|
||||||
|
|
||||||
; Include the subroutine file.
|
; Include the subroutine file.
|
||||||
#Include print.asm
|
#Include Libraries/print.asm
|
||||||
|
|
||||||
#Program
|
#Program
|
||||||
|
|
||||||
@@ -14,12 +14,12 @@ start:
|
|||||||
CALL printString ; Call the string printing subroutine.
|
CALL printString ; Call the string printing subroutine.
|
||||||
CALL lineFeed ; Call the line feed subroutine to end the line.
|
CALL lineFeed ; Call the line feed subroutine to end the line.
|
||||||
SETD MyDecimal ; Set the Data Pointer to the value to print as a decimal.
|
SETD MyDecimal ; Set the Data Pointer to the value to print as a decimal.
|
||||||
CALL printDecimal ; Call the decimal printing subroutine.
|
LDA ; Load it into A.
|
||||||
|
CALL printByteDecimal ; Call the decimal printing subroutine.
|
||||||
SETD MyMessage ; Set the Data Pointer to another string.
|
SETD MyMessage ; Set the Data Pointer to another string.
|
||||||
CALL printString ; Call the string printing subroutine again.
|
CALL printString ; Call the string printing subroutine again.
|
||||||
CALL lineFeed ; Call the line feed subroutine to end the line.
|
CALL lineFeed ; Call the line feed subroutine to end the line.
|
||||||
HALT ; Stop the program.
|
HALT ; Stop the program.
|
||||||
|
|
||||||
#Data
|
#Data
|
||||||
|
|
||||||
MyString:
|
MyString:
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
; Tests for the printDecimal subroutine.
|
||||||
|
|
||||||
|
#Program
|
||||||
|
|
||||||
|
printByteDecimalTest:
|
||||||
|
INIB 0xFF ; Load 255 into B.
|
||||||
|
printDecimalTestloop:
|
||||||
|
SUB
|
||||||
|
CCF ; Clear the Carry Flag.
|
||||||
|
CALL printByteDecimal ; Print the value.
|
||||||
|
INCA ; Increment it.
|
||||||
|
PSHA
|
||||||
|
INIA 0x00
|
||||||
|
CALL blankSpace
|
||||||
|
POPA
|
||||||
|
BRQ printDecimalTestend ; If Q is zero, we're done.
|
||||||
|
BRI printDecimalTestloop ; Branch back to the start of the loop.
|
||||||
|
printDecimalTestend:
|
||||||
|
CALL lineFeed
|
||||||
|
RET
|
||||||
|
|
||||||
|
#Data
|
||||||
|
|
||||||
|
Space:
|
||||||
|
" "
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#Program
|
||||||
|
|
||||||
|
printDigitTest:
|
||||||
|
INIB 0d10
|
||||||
|
printDigitTestLoop:
|
||||||
|
CALL printDecimalDigit
|
||||||
|
INCA
|
||||||
|
SUB
|
||||||
|
CCF
|
||||||
|
BRQ printDigitTestend
|
||||||
|
CALL lineFeed
|
||||||
|
BRI printDigitTestLoop
|
||||||
|
printDigitTestend:
|
||||||
|
CALL lineFeed
|
||||||
|
RET
|
||||||
|
|
||||||
|
#Data
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
; Test for the hexadecimal printing routines.
|
||||||
|
|
||||||
|
#Program
|
||||||
|
printByteHexTest:
|
||||||
|
INIB 0xFF
|
||||||
|
CALL printByteHex
|
||||||
|
printHexTestLoop:
|
||||||
|
PSHA
|
||||||
|
INIA 0x00
|
||||||
|
CALL blankSpace
|
||||||
|
POPA
|
||||||
|
INCA
|
||||||
|
SUB
|
||||||
|
CCF
|
||||||
|
CALL printByteHex
|
||||||
|
BRQ printHexTestend
|
||||||
|
BRI printHexTestLoop
|
||||||
|
printHexTestend:
|
||||||
|
CALL lineFeed
|
||||||
|
RET
|
||||||
|
|
||||||
|
#Data
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
; Tests for the printing subroutines provided by print.asm
|
||||||
|
|
||||||
|
#Include ../Libraries/print.asm
|
||||||
|
#Include printDigitTest.asm
|
||||||
|
#Include printDecimalTest.asm
|
||||||
|
#Include printHexTest.asm
|
||||||
|
|
||||||
|
#Program
|
||||||
|
|
||||||
|
clearRegisters:
|
||||||
|
INIA 0x00;
|
||||||
|
INIB 0x00;
|
||||||
|
ADD
|
||||||
|
RET
|
||||||
|
|
||||||
|
start:
|
||||||
|
SETD String0
|
||||||
|
CALL printString
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String1
|
||||||
|
CALL printString
|
||||||
|
CALL lineFeed
|
||||||
|
CALL clearRegisters
|
||||||
|
CALL printDigitTest
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String2
|
||||||
|
CALL printString
|
||||||
|
CALL lineFeed
|
||||||
|
CALL clearRegisters
|
||||||
|
CALL printByteDecimalTest
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String3
|
||||||
|
CALL printString
|
||||||
|
CALL lineFeed
|
||||||
|
CALL clearRegisters
|
||||||
|
CALL printByteHexTest
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String4
|
||||||
|
CALL printString
|
||||||
|
CALL lineFeed
|
||||||
|
HALT
|
||||||
|
|
||||||
|
#Data
|
||||||
|
|
||||||
|
String0:
|
||||||
|
"Test suite for SplitBit's print.asm library."
|
||||||
|
|
||||||
|
String1:
|
||||||
|
"Testing printDigit..."
|
||||||
|
|
||||||
|
String2:
|
||||||
|
"Testing printByteDecimal..."
|
||||||
|
|
||||||
|
String3:
|
||||||
|
"Testing printByteHex..."
|
||||||
|
|
||||||
|
String4:
|
||||||
|
"Testing complete!"
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
; A simple test for the new SHL and SHR instructions.
|
||||||
|
|
||||||
|
#Include print.asm
|
||||||
|
|
||||||
|
#Program
|
||||||
|
|
||||||
|
start:
|
||||||
|
SETD String0
|
||||||
|
CALL printString
|
||||||
|
loop0:
|
||||||
|
SETD TestValue0
|
||||||
|
CALL printDecimal
|
||||||
|
LDA
|
||||||
|
SHL
|
||||||
|
STA
|
||||||
|
SETD Space
|
||||||
|
CALL printString
|
||||||
|
BRA doB
|
||||||
|
BRI loop0
|
||||||
|
doB:
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String1
|
||||||
|
CALL printString
|
||||||
|
SETD TestValue0
|
||||||
|
STB
|
||||||
|
loop1:
|
||||||
|
SETD TestValue0
|
||||||
|
CALL printDecimal
|
||||||
|
LDB
|
||||||
|
SHL
|
||||||
|
STB
|
||||||
|
SETD Space
|
||||||
|
CALL printString
|
||||||
|
BRB doRight
|
||||||
|
BRA loop1
|
||||||
|
doRight:
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String0
|
||||||
|
CALL printString
|
||||||
|
loop2:
|
||||||
|
SETD TestValue1
|
||||||
|
CALL printDecimal
|
||||||
|
LDA
|
||||||
|
SHR
|
||||||
|
STA
|
||||||
|
SETD Space
|
||||||
|
CALL printString
|
||||||
|
BRA doRightB
|
||||||
|
BRI loop2
|
||||||
|
doRightB:
|
||||||
|
CALL lineFeed
|
||||||
|
SETD String1
|
||||||
|
CALL printString
|
||||||
|
SETD TestValue1
|
||||||
|
STB
|
||||||
|
loop3:
|
||||||
|
SETD TestValue1
|
||||||
|
CALL printDecimal
|
||||||
|
LDB
|
||||||
|
SHR
|
||||||
|
STB
|
||||||
|
SETD Space
|
||||||
|
CALL printString
|
||||||
|
BRB end
|
||||||
|
BRA loop3
|
||||||
|
end:
|
||||||
|
CALL lineFeed
|
||||||
|
HALT
|
||||||
|
|
||||||
|
#Data
|
||||||
|
TestValue0:
|
||||||
|
0d01
|
||||||
|
|
||||||
|
TestValue1:
|
||||||
|
0d128
|
||||||
|
|
||||||
|
String0:
|
||||||
|
"A values: "
|
||||||
|
|
||||||
|
String1:
|
||||||
|
"B values: "
|
||||||
|
|
||||||
|
Space:
|
||||||
|
" "
|
||||||
@@ -29,9 +29,13 @@ Instruction instruction_set[] = {
|
|||||||
{0x11, "BRQ"},
|
{0x11, "BRQ"},
|
||||||
{0x12, "BRA"},
|
{0x12, "BRA"},
|
||||||
{0x13, "BRB"},
|
{0x13, "BRB"},
|
||||||
{0x14, "CALL"},
|
{0x14, "BRC"},
|
||||||
{0x15, "RET"},
|
{0x17, "CALL"},
|
||||||
{0x16, "BRC"},
|
{0x18, "CALLA"},
|
||||||
|
{0x19, "CALLB"},
|
||||||
|
{0x1A, "CALLQ"},
|
||||||
|
{0x1B, "CALLCF"},
|
||||||
|
{0x1F, "RET"},
|
||||||
// Register Operations:
|
// Register Operations:
|
||||||
{0x20, "RSTA"},
|
{0x20, "RSTA"},
|
||||||
{0x21, "RSTB"},
|
{0x21, "RSTB"},
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ void populateOutputBuffers(intermediateElement *intermediateArray, int arraySize
|
|||||||
Program[(*programCount)++] = intermediateArray[i].byteValue;
|
Program[(*programCount)++] = intermediateArray[i].byteValue;
|
||||||
|
|
||||||
// Check if it's a branch instruction.
|
// Check if it's a branch instruction.
|
||||||
if (((intermediateArray[i].byteValue & 0xF0) == 0x10) && (intermediateArray[i].byteValue != 0x15)){
|
if (((intermediateArray[i].byteValue & 0xF0) == 0x10) && (intermediateArray[i].byteValue != 0x1F)){
|
||||||
if (intermediateArray[i + 1].type != LABEL) {
|
if (intermediateArray[i + 1].type != LABEL) {
|
||||||
fprintf(stderr, RED "Error: Branch without label.\n" RESET);
|
fprintf(stderr, RED "Error: Branch without label.\n" RESET);
|
||||||
printf("File: %s at line %d.\n", intermediateArray[i].fileName, intermediateArray[i].lineNumber);
|
printf("File: %s at line %d.\n", intermediateArray[i].fileName, intermediateArray[i].lineNumber);
|
||||||
|
|||||||
+59
-32
@@ -31,6 +31,31 @@ void genericBranch(CPURegisters *cpu){
|
|||||||
cpu->ProgramCounter = DestinationAddress-1;
|
cpu->ProgramCounter = DestinationAddress-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void genericCall(CPURegisters *cpu){
|
||||||
|
// Order, low byte, high byte
|
||||||
|
cpu->Data[cpu->StackPointer] = cpu->ProgramCounter & 0xFF;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
cpu->Data[cpu->StackPointer] = (cpu->ProgramCounter >> 8) & 0xFF;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
// Push the Data Pointer to the Stack.
|
||||||
|
// Order, low byte, high byte
|
||||||
|
cpu->Data[cpu->StackPointer] = cpu->DataPointer & 0xFF;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
cpu->Data[cpu->StackPointer] = (cpu->DataPointer >> 8) & 0xFF;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
// Push Q to the Stack.
|
||||||
|
cpu->Data[cpu->StackPointer] = cpu->Q;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
// Push B to the Stack.
|
||||||
|
cpu->Data[cpu->StackPointer] = cpu->B;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
// Push A to the Stack.
|
||||||
|
cpu->Data[cpu->StackPointer] = cpu->A;
|
||||||
|
cpu->StackPointer--;
|
||||||
|
// Perform a Generic Branch to the Address.
|
||||||
|
genericBranch(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
||||||
switch(Instruction) {
|
switch(Instruction) {
|
||||||
// 0x - Arithmetic and Logic Operations.
|
// 0x - Arithmetic and Logic Operations.
|
||||||
@@ -131,31 +156,41 @@ uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x14:
|
case 0x14:
|
||||||
// CALL - Push the Program Counter to the Stack, and perform an immediate branch.
|
// BRC - Do an immediate branch if the Carry Flag is set.
|
||||||
// Order, low byte, high byte
|
if (cpu->Status & 0x01) {
|
||||||
cpu->Data[cpu->StackPointer] = cpu->ProgramCounter & 0xFF;
|
genericBranch(cpu);
|
||||||
cpu->StackPointer--;
|
} else {
|
||||||
cpu->Data[cpu->StackPointer] = (cpu->ProgramCounter >> 8) & 0xFF;
|
cpu->ProgramCounter+=2;
|
||||||
cpu->StackPointer--;
|
}
|
||||||
// Push the Data Pointer to the Stack.
|
|
||||||
// Order, low byte, high byte
|
|
||||||
cpu->Data[cpu->StackPointer] = cpu->DataPointer & 0xFF;
|
|
||||||
cpu->StackPointer--;
|
|
||||||
cpu->Data[cpu->StackPointer] = (cpu->DataPointer >> 8) & 0xFF;
|
|
||||||
cpu->StackPointer--;
|
|
||||||
// Push Q to the Stack.
|
|
||||||
cpu->Data[cpu->StackPointer] = cpu->Q;
|
|
||||||
cpu->StackPointer--;
|
|
||||||
// Push B to the Stack.
|
|
||||||
cpu->Data[cpu->StackPointer] = cpu->B;
|
|
||||||
cpu->StackPointer--;
|
|
||||||
// Push A to the Stack.
|
|
||||||
cpu->Data[cpu->StackPointer] = cpu->A;
|
|
||||||
cpu->StackPointer--;
|
|
||||||
// Perform a Generic Branch to the Address.
|
|
||||||
genericBranch(cpu);
|
|
||||||
break;
|
break;
|
||||||
case 0x15:
|
case 0x17:
|
||||||
|
// CALL - Push the Program Counter to the Stack, and perform an immediate branch.
|
||||||
|
genericCall(cpu);
|
||||||
|
break;
|
||||||
|
case 0x18:
|
||||||
|
// CALLA
|
||||||
|
if (cpu->A == 0) {
|
||||||
|
genericCall(cpu);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x19:
|
||||||
|
// CALLB
|
||||||
|
if (cpu->B == 0) {
|
||||||
|
genericCall(cpu);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1A:
|
||||||
|
// CALLQ
|
||||||
|
if (cpu->Q == 0) {
|
||||||
|
genericCall(cpu);
|
||||||
|
}
|
||||||
|
case 0x1B:
|
||||||
|
// CALLCF
|
||||||
|
if (cpu->Status & 0x01) {
|
||||||
|
genericCall(cpu);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
// RET - Return from subroutine, restore the registers and set the Program Counter to the Return Address.
|
// RET - Return from subroutine, restore the registers and set the Program Counter to the Return Address.
|
||||||
// Pop A from the Stack.
|
// Pop A from the Stack.
|
||||||
cpu->StackPointer++;
|
cpu->StackPointer++;
|
||||||
@@ -179,14 +214,6 @@ uint8_t executeOperation(uint8_t Instruction, CPURegisters *cpu) {
|
|||||||
// Add 2 to the Program Counter to skip over the address when it returns.
|
// Add 2 to the Program Counter to skip over the address when it returns.
|
||||||
cpu->ProgramCounter += 2;
|
cpu->ProgramCounter += 2;
|
||||||
break;
|
break;
|
||||||
case 0x16:
|
|
||||||
// BRC - Do an immediate branch is the Carry Flag is set.
|
|
||||||
if (cpu->Status & 0x01) {
|
|
||||||
genericBranch(cpu);
|
|
||||||
} else {
|
|
||||||
cpu->ProgramCounter+=2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//
|
//
|
||||||
// 2x - Register Operations:
|
// 2x - Register Operations:
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ void printRegisters(CPURegisters *cpu, uint8_t *Program, uint8_t *Data) {
|
|||||||
printf("A: 0x%02X\tB: 0x%02X\tQ: 0x%02X\tStatus: 0b%08b\n", cpu->A, cpu->B, cpu->Q, cpu->Status);
|
printf("A: 0x%02X\tB: 0x%02X\tQ: 0x%02X\tStatus: 0b%08b\n", cpu->A, cpu->B, cpu->Q, cpu->Status);
|
||||||
printf("Program Counter: 0x%04X Current Instruction: 0x%02X (%s)\n", cpu->ProgramCounter, Program[cpu->ProgramCounter],getMnemonic(Program[cpu->ProgramCounter]));
|
printf("Program Counter: 0x%04X Current Instruction: 0x%02X (%s)\n", cpu->ProgramCounter, Program[cpu->ProgramCounter],getMnemonic(Program[cpu->ProgramCounter]));
|
||||||
printf(" Data Pointer: 0x%04X Current Data Value: 0x%02X\n", cpu->DataPointer, Data[cpu->DataPointer]);
|
printf(" Data Pointer: 0x%04X Current Data Value: 0x%02X\n", cpu->DataPointer, Data[cpu->DataPointer]);
|
||||||
printf(" Stack Pointer: 0x%04X Current Value: (0x%02X) (0x%02X)\n", Data[cpu->StackPointer], Data[cpu->StackPointer+1], Data[cpu->StackPointer+2]);
|
printf(" Stack Pointer: 0x%04X Current Value: (0x%02X) (0x%02X)\n", cpu->StackPointer, Data[cpu->StackPointer+1], Data[cpu->StackPointer+2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,9 +38,14 @@ Hex Code | Mnemonic | Description
|
|||||||
11 | BRQ | Branch on Q. If Q is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
11 | BRQ | Branch on Q. If Q is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
||||||
12 | BRA | Branch on A. If A is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
12 | BRA | Branch on A. If A is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
||||||
13 | BRB | Branch on B. If B is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
13 | BRB | Branch on B. If B is zero, loads the immediate next two bytes of Program Memory into the Program Counter.
|
||||||
14 | CALL | Stores all the registers to the Stack, A, B, Q, the Data Pointer, and the Program Counter, then performs an immediate branch.
|
14 | BRC | Branch if Carry is set.
|
||||||
15 | RET | Restores all registers from the Stack, then immediately branches to the Return Address by setting the Program Counter to the next instruction after the last CALL.
|
17 | CALL | Call subroutine. Stores all the registers to the Stack, A, B, Q, the Data Pointer, and the Program Counter, then performs an immediate branch.
|
||||||
16 | BRC | Branch if Carry is set.
|
18 | CALLA | Conditional Call on A. Calls subroutine if A is zero.
|
||||||
|
19 | CALLB | Conditional Call on B. Calls subroutine if B is zero.
|
||||||
|
1A | CALLQ | Conditional Call on Q. Calls subroutine if Q is zero.
|
||||||
|
1B | CALLCF | Conditional Call on Carry. Calls subroutine if the Carry Flag is set.
|
||||||
|
1F | RET | Restores all registers from the Stack, then immediately branches to the Return Address by setting the Program Counter to the next instruction after the last CALL.
|
||||||
|
|
||||||
|
|
||||||
### Register Operations: 11 Instructions
|
### Register Operations: 11 Instructions
|
||||||
| Hex Code | Mnemonic | Description |
|
| Hex Code | Mnemonic | Description |
|
||||||
|
|||||||
Reference in New Issue
Block a user