I have a bootsector that displays a bunch of messages.
I want to create spaces in the bootsector so the messages arn't so long.
How would I create one or more spaces between messages in assembly?
Help!
Re:Help!
If by that you mean, you want to break the messages up between more than one line, then the answer is that it depends on how you've been displaying them.
If you've been using INT 0x10, function 0x0E (teletype mode), then all you have to do is print a carriage return (0x0D), and then a linefeed (0x0A), before the beginning of each new line (or more likely, after the end of each old one). This will return to the start of the line, advance the screen by one line.
If you are using INT 0x10, with either function 0x09 (write one character and attribute pair at current cursor) or 0x0A (write one character at current cursor) followed by INT 0x10, function 0x02 (set cursor), you can simply increment the value of DH (row) and clear the value of DL (column) when setting the cursor.
If you are writing to the text buffer directly, then you have to calculate the beginning of the next line; if you have been keeping track of the rows and columns separately and calculating the cursor position from them, then it works the same as the previous case; otherwise, you have to calculate from your current position where the next line begins, and set the cursor appropriately.
HTH. CCW.
If you've been using INT 0x10, function 0x0E (teletype mode), then all you have to do is print a carriage return (0x0D), and then a linefeed (0x0A), before the beginning of each new line (or more likely, after the end of each old one). This will return to the start of the line, advance the screen by one line.
If you are using INT 0x10, with either function 0x09 (write one character and attribute pair at current cursor) or 0x0A (write one character at current cursor) followed by INT 0x10, function 0x02 (set cursor), you can simply increment the value of DH (row) and clear the value of DL (column) when setting the cursor.
If you are writing to the text buffer directly, then you have to calculate the beginning of the next line; if you have been keeping track of the rows and columns separately and calculating the cursor position from them, then it works the same as the previous case; otherwise, you have to calculate from your current position where the next line begins, and set the cursor appropriately.
HTH. CCW.
Re:Help!
Er, which one? ;D I haven't any on hand for the later two cases, but I do have my original test boot loader, which used teletype mode (INT 0x10, func. 0x0E). The relevant sections are:
The macro write is used to simplify the calls to printstr, by automatically putting the string pointer into SI before calling the function. The carriage return (CR) and line feed (LF) characters are embedded in the strings that are meant to end the current line of text, and each of the strings is delimited with a null (EOL).
Note that this is not the most efficient way of doing things, necessarily. For example, rather than hard coding the newlines into the message strings, it probably would have been better to have a second function newline and a matching macro writeln, as here:
You can probably imagine other variations on this same idea, that offer different tradeoffs of time and space. Also, the example uses c-strings (ASCII text delimited with by 0x00) for the data. While these are familiar to any C programmers, and reasonably easy to use, they do not in this code take advantage of the CPU's built-in string instructions. In both of these case, it is as much a matter of programming style as anything else; YMMV.
If you need an example of using the INT 0x10, func. 0x09, or of writing direct to the video buffer, let me know and I'll work something out. Also, others here may have some relevant code samples as well. CCW.
Code: Select all
VBIOS equ 0x10 ; BIOS interrupt vector for video services
ttype equ 0x0E ; insert character in AL as if screen were teletype
EOL equ 0x00 ;end of string marker
CR equ 0x0D
LF equ 0x0A
;;; .... other code goes here
%macro write 1
mov si, %1
call printstr
%endmacro
;;; .... other code goes here
;; printstr - prints the string point to by SI
printstr:
push ax
mov ah, ttype ; set function to 'teletype mode'
.loop:
mov al, [si] ; update byte to print
cmp al, EOL ; test that it isn't EOL
jz .endstr
int VBIOS ; put character in AL at next cursor position
inc si
jmp short .loop
.endstr:
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; data
testnumber db 'Test #145', CR, LF, EOL
reset db 'Resetting disk drive.', CR, LF, EOL
loading db 'Loading stage two... ', EOL
;;; ... etc.
Note that this is not the most efficient way of doing things, necessarily. For example, rather than hard coding the newlines into the message strings, it probably would have been better to have a second function newline and a matching macro writeln, as here:
Code: Select all
%macro writeln %1
write %1
call newline
%endmacro
newline:
push ax
mov ah, ttype ; set function to 'teletype mode'
mov al, CR ; load a carriage return
int VBIOS ; and print it
mov al, LF ; load a line feed
int VBIOS ; and print it
ret
If you need an example of using the INT 0x10, func. 0x09, or of writing direct to the video buffer, let me know and I'll work something out. Also, others here may have some relevant code samples as well. CCW.