Is there a way to manually change BIOS POST codes on motherboard LCD? - bios

I was wondering if anyone knew if it was possible to change the BIOS POST Code that is displayed on the motherboard LCD. I want to develop a program that can manipulate the LCD screen on the motherboard to display any set of desired characters. I haven't been able to find anyone who has done something similar. Does anyone have any ideas on if this is possible? Thank You!

POST codes are usually displayed on LED devices on the motherboard, not LCD. Historically, POST codes can be output via IO port 0x80 on IBM/Intel compatible systems. Been a while since I have done x86 assembly, but would be something like this:
mov al, 41h ;41h, the value to output
out 80h, al ;send the value to IO port 80h
This will make "41" display on the POST code LEDs. If you have 4 LEDs (a four digit value), then use AX instead of AL or use port 81h and a second write.
mov ax, 5150h ;5150h, the value to output
out 80h, al ;send the value to IO port 80h
Note: as I recall in/out instructions are protected instructions and will generate an exeception when the CPU is in protected mode (e.g. from the Windows command line)

Related

Modbus register adress space not linear?

I'm currently developing a modbus server to control a device.
The device manual says about holding registers:
Adress 6000: ValueA, 2 Byte
Adress 6001: ValueB, 1 Byte; ValueC, 4 Byte; ValueD, 4 Byte
Adress 6005: ValueE, 2 Byte
The only supported read function is FC 03 / Read Multiple Holding Registers
To my knowledge, one can see the register as a memory block of numbered 16Bit values, and could read it in one go by reading 6 registers / 12 Byte beginning at 6000.
I think the 1Byte-value isn't an issue, the register simply contains a value not exceeding 255.
But expanding the table above gives:
Adress 6000: ValueA, 2 Byte
Adress 6001: ValueB, 1 Byte
Adress 6002-6003: ValueC, 4 Byte
Adress 6004-6005: ValueD, 4 Byte
Adress 6005: ValueE, 2 Byte
so, there is an overlap last line at 6005.
My device manual is full of such occurences, and meanwhile, I'm thinking that modbus registers ain't such a simple, linear memory as I thought.
Does anybody know if modbus registers are linear, or not?
I stumbled across a similar situation and asked about it in a more specialized forum. The "to long, didn`t read" was, that the address space is linear most of the time, but not always.
Check out the following example:
Excuse the German parts, but what you can see here, is that register address 0x2021 holds data made up of eight words or eight 16-bit blocks. Following your above logic you would expect the second word to be stored in the register 0x2022, but I checked on my local device and they are not the same. So, in summary, there are some devices out there which decide, that they give one register more memory than it's ought to have. So, register 0x2021 really holds 8 words on his own and does not use register 0x2022 to hold memory.
you might have a similar case.

Memory usage in assembler 8086

I made a program in assembler 8086 for my class and everything is working just fine.
But beside making working program we have to make it use as low memory as possible. Could you give me some tips in that aspect? What should I write and what should I avoid?
The program is supposed to first print letter A on the screen and then in avery new line two more of letters of next letter in the alphabet, stop at Z and after pressing any key end program. For stopping until key is pressed i'm using:
mov ah,00h
int 16h
Is it good way to do it?
Most of what you want can be done in zero memory (counting only data, not the code itself). In general:
use registers rather than variables in memory
do not use push/pop
do not use subroutines
But to interact with the OS, you need to make BIOS calls and/or OS system calls; these require some memory (typically a small amount of stack space). In your case, you have to:
output characters to screen
wait for keypress
exit back to the OS
However, if you are serious about doing this in minimal memory, then there are a few hacks you can use.
Output characters to screen
On a PC, in traditional text mode, you can write characters straight to video RAM (address B800:0000 and further). This requires zero memory.
Wait for keypress
The cheapest way is to wait for a change of the BIOS keyboard buffer head (a change of the 16-bit content at address 041A hex). This requires zero memory.
See also: http://support.microsoft.com/kb/60140
Exit back to the OS
Try a simple ret; it is not recommended but it might just work in some versions of MS-DOS. An even uglier escape is to jump to F000:FFF0, which will reboot the machine. That's guaranteed to work in zero memory.
Use these instructions:
INC (Register*) instead of ADD (Register*), 1
DEC (Register*) instead of SUB (Register*), 1
XOR (Register)(same register) instead of MOV (Register), 0 (Doesn't work with variables)
SHR (Register*), 1 instead of DIV (Register*), 2
SHR (Register*), 2 instead of DIV (Register*), 4
..
SHL (Register*), 1 instead of MUL (Register*), 2
..
*Register or variable
These optimizations makes the program faster AND the size larger

What happens when memory "wraps" on an IA-32 supporting machine?

I'm creating a 64-bit model of IA-32 and am representing memory as a 0-based array of 2**64 bytes (the language I'm modeling this in uses ** as the exponentiation operator). This means that valid indices into the array are from 0 to 2**64-1. Now, to model the possible modes of accessing that memory, one can treat one element as an 8-bit number, two elements as a (little-endian) 16-bit number, etc.
My question is, what should my model do if they ask for a 16-bit (or 32-bit, etc.) number from location 2**64-1? Right now, what the model does is say that the returned value is Memory(2**64-1) + (8 * Memory(0)). I'm not updating any flags (which feels wrong). Is wrapping like this the correct behavior? Should I be setting any flags when the wrapping happens?
I have a copy of Intel-64-ia-32-ISA.pdf which I'm using as a reference, but it's 1,479 pages, and I'm having a hard time finding the answer to this particular question.
The answer is in Volume 3A, section 5.3: "Limit checking."
For ia-32:
When the effective limit is FFFFFFFFH (4 GBytes), these accesses [which extend beyond the end of the segment] may or may not cause the indicated exceptions. Behavior is implementation-specific and may vary from one execution to another.
For ia-64:
In 64-bit mode, the processor does not perform rumtime limit checking on code or data segments. Howver, the processor does check descriptor-table limits.
I tested it (did anyone expect that?) for 64bit numbers with this code:
mov dword [0], 0xDEADBEEF
mov dword [-4], 0x01020304
mov rdi, [-4]
call writelonghex
In a custom OS, with pages mapped as appropriate, running in VirtualBox. writelonghex just writes rdi to the screen as a 16-digit hexadecimal number. The result:
So yes, it does just wrap. Nothing funny happens.
No flags should be affected (though the manual doesn't say that no flags should be set for address wrapping, it does say that mov reg, [mem] doesn't affect them ever, and that includes this case), and no interrupt/trap/whatever happens (unless of course one or both pages touched are not present).

How to draw a pixel on the screen in protected mode in x86 assembly?

I am creating a little bootloader+kernel and till now I managed to read disk, load second sector, load GDT, open A20 and enable pmode.
I jumped to the 32-bits function that show me a character on the screen, using the video memory for textual content (0x000B0000 - 0x000B7777)
pusha
mov edi, 0xB8000
mov bl, '.'
mov dl, bl
mov dh, 63
mov word [edi], dx
popa
Now, I would like to go a little further and draw a single pixel on the screen. As I read on some website, if I want to use the graphics mode of the VGA, I have to write my pixel at location 0x000A0000. Is that right?
Now, what is the format of a single pixel? For a single character you need ASCII code and attribute, but what do you need to define a pixel (if it works the same way as the textual mode)?
Unfortunately, it's a little more than a little further.
The rules for writing to video memory depend on the graphics mode. Among traditional video modes, VGA mode 320x200 (8bpp) is the only one where video memory behaves like a normal kind of memory: you write a byte corresponding to a pixel you want to the video buffer starting from 0xA000:0000 (or 0xA0000 linear), and that's all.
For other VGA (pre-SVGA) modes, the rules are more complicated: when you write a byte to video memory, you address a group of pixels, and some VGA registers which I have long since forgotten specify which planes of those pixels are updated and how the old value of them is used. It's not just memory any more.
There are SVGA modes (starting with 800x600x8bpp); you can switch to them in a hardware-independent way using VESA Video Bios Extensions. In those modes, video memory behaves like memory again, with 1,2,3 or 4 bytes per pixel and no VGA-like 8-pixel groups which you touch with one byte access. The problem is that the real-mode video buffer is not large enough any more to address the whole screen.
VESA VBE 1.2 addressed this problem by providing functions to modify the memory window base: in any particular moment, the segment at linear 0xA0000 is addressing 64Kb region of video memory, but you can control which 64Kb of the whole framebuffer are available at this address (minimal unit of base address adjustment, a.k.a window granularity, depends on the hardware, but you can rely on the ability to map N*64Kb offset at 0xA0000). The downside is that it requires VBE BIOS call each time when you start working with different 64Kb chunk.
VESA VBE 2.0 added flat framebuffer, available at some high address in protected mode (also in unreal mode). Thus VBE BIOS call is required for entering video mode, but not for drawing pixels.
VESA VBE 3.0, which might not be portable enough yet, provides a way to call VBE functions in protected mode. (I didn't have a chance to try it, it was not there during my "OS in assembly" age).
Anyway, you have to switch to graphics mode first. There are several variants of doing that:
The easiest thing to do is to use a BIOS call before you enter protected mode. With VBE 2.0, you won't need video memory window adjustment calls.
Another way is creating a V8086-mode environment which is good enough for BIOS. The hardest part is forwarding interrupts to real-mode interrupt handlers. It's not easy, but when it's done, you'll be able to switch video modes in PM and use some other BIOS functions (for disk I/O, for example).
Yet another way is to use VESA VBE 3.0 protected mode interface. No idea on how easy or complicated it might be.
And a real Jedi way is digging out the information on your specific video card, switching modes by setting its registers. Been there, done that for some Cirrus card in the past -- getting big plain framebuffer in PM was not too complicated. It's unportable, but maybe it's just what you need if the aim is understanding the internals of your machine.
It depends on the graphics mode in use, and there are a lot a differences. BIOS VGA video mode 13h (320x200 at 8 bits/pixel) is probably the easiest to get started with (and it's the only BIOS VGA video mode with 256 colors, however you can create your own modes by writing directly to the ports of the video card): in BIOS video mode 13h the video memory mapped to screen begins at 0x0A0000 and it runs continuosly 1 byte for each pixel, and only 1 bit plane, so each coordinate's memory address is 0x0A000 + 320*y + x:
To change to BIOS video mode 13h (320 x 200 at 8 bits/pixel) while in real mode:
mov ax,0x13
int 0x10
To draw a pixel in the upper left corner (in video mode 13h) while in protected mode:
mov edi,0x0A0000
mov al,0x0F ; the color of the pixel
mov [edi],al
org 100h
bits 16
cpu 386
section.text:
START:
mov ax,12h
int 10h
mov al,02h
mov ah,0ch
pixel.asm
c:\>nasm pixel.asm -f bin -o pixel.com
int 10h

Connecting 8051 to an External Ram-EEPROM

When I connect 8051 to an external memory, should I change the RD and WR signals in software or is this made by processor itself when I use the MOVX command?
For example I will read from some location at memory,
;CLR RD
MOV DPTR,#SOMELOCATION
MOVX A,#DPTR
is CLR read command required here or processor just clears that itself by looking if the code is
MOVX A,#DPTR ;or
MOVX #DPTR,A
If the processor has RD and WR lines, then yes, the processor will pulse the write line with timing as described in the data sheet as it executes the "movx #dptr,A" instruction. In addition, ALE would have been pulsed to latch the low byte of the address for the memory.
If for some reason it was necessary to operate the chip write using a clear bit instruction as you state above, you are doing it in the wrong place. You would need to set up address and data THEN pulse write low, then return it high, before any other change in address and data.

Resources