Help!

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
beyondsociety

Help!

Post by beyondsociety »

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?
Schol-R-LEA

Re:Help!

Post by Schol-R-LEA »

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.
beyondsociety

Re:Help!

Post by beyondsociety »

It would help if you could give me some example on how to do this in assembly.
Schol-R-LEA

Re:Help!

Post by Schol-R-LEA »

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:

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.
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:

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
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.
beyondsociety

Re:Help!

Post by beyondsociety »

How does int 9h or as you put it 0x09 work. Why would you want to write to the video buffer and how would you do it. If you could also give me a general example in assembly, it would help.

thanks!
Post Reply