2

I realized that in protected mode, one could use memory mapped I/O to print letters by modifying the memory location 0xb8000 and so forth... Can we do this in 16 bit real mode? (Using segmentation to access the location and then modifying it)

This is my assembly code...

[bits 16]
mov ax,0xb800
mov ds,ax    #This is the segment register that should hopefully give me 0xb8000
mov byte[ds:0x0000],'X'
mov byte[ds:0x0001],0x0f

times 510-($ -$$) db 0
dw 0xaa55

This is not working btw..

[edit] Turns out I needed jmp $ at the end to prevent any random code execution and the code works as expected

Suraaj K S
  • 600
  • 3
  • 21
  • This is just curiosity – Suraaj K S Nov 23 '19 at 07:12
  • Yes, something like this should work in a bootloader. (BTW, it's not exactly MMIO; you're writing to device memory, not to IO registers where each read or write has a side-effect). Did you try to follow a working example that writes to VGA memory? There should be others in the VGA and bootloader tags; use SO's search. Also, "not working" how? What happens when you single-step it in the BOCHS debugger? IDK if it matters that you didn't include a `hlt` / `jmp` loop after your code, so it continues executing `00 00` bytes as `add [mem], al` (with some addressing mode, IDK 16-bit modrm) – Peter Cordes Nov 23 '19 at 07:20
  • 2
    You might want to put a `jmp $` infinite loop after that bit of code, I don't know off the top of my head the operation for `00`, `aa` and `55` but there's a better than even chance it will just run off the end of your boot sector and execute arbitrary code - that's unlikely to end well. – paxdiablo Nov 23 '19 at 07:24
  • And, yes, that's actually the way it was done for speed back in the day, portability concerns only came later. From a cursory glance, and relying on potentially damaged memory rather than research :-), what you have should work okay. Just keep in mind that address was for CGA, I believe MDA and EGA used totally different addresses. Since you have a VGA tag on your question, you may need to do some initialisation first, VGA has registers that decided the mode and where it was in the address space. – paxdiablo Nov 23 '19 at 07:37
  • 1
    And you may also want to think about looking over at our retro computing sister site, https://retrocomputing.stackexchange.com/. They're probably *much* more knowledgable on the subject. – paxdiablo Nov 23 '19 at 07:39
  • Post your answer as an answer, not an edit to the question. Someone else spent time writing an answer because they missed your little not at the bottom of the question. – Peter Cordes Nov 27 '19 at 13:17

2 Answers2

1

It should work, with two possible cause of failure:

  • if you're not yet in text mode, the B800 segment isn't used to render text on screen. (quite likely with modern BIOS)
  • if you have a monochrome screen, your graphic card may decide to use B000 instead of B800. (very unlikely with modern BIOS).
PypeBros
  • 2,607
  • 24
  • 37
1

Turns out I just needed the jmp $ at the end to prevent any random code execution.. The code works as expected

Suraaj K S
  • 600
  • 3
  • 21