151 lines
7.1 KiB
NASM
151 lines
7.1 KiB
NASM
; 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.
|
|
|
|
blankSpace:
|
|
INIB 0x20 ; Set B to the ASCII value for space.
|
|
OUTB 0x00 ; Print it.
|
|
RET
|
|
|
|
; Expects A to contain the number of spaces to print.
|
|
blankSpaces:
|
|
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.
|
|
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
|
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|