VOGONS


First post, by 32768

User metadata
Rank Newbie
Rank
Newbie

I'm beginning to learn how to make BIOS extensions for PC, while I had some minor success

CEYPbAv.jpg

All that was made writing each individual character, something like:
mov ah,0Eh
mov al,'2'
mov bh,vpage
int 10h

mov ah,0Eh
mov al,'1'
mov bh,vpage
int 10h
...

But is not really the way to go, on even simple messages will fillup EEPROM like nothing, so I tried making like a pointer

msg db 'Assembled by xxxxx xxxxxxxx - 2018'
mov dx,0
mov si,offset msg << I think here is the problem
loop:
mov ah,0Eh
mov al,[si] << I think here is the problem
mov bh,0
int 10h
inc si
inc dx
cmp dx,33
jbe loop ;jump if low or equal

The result is all blank, even tho same code made for DOS is working prerfectly

Q58Th2C.jpg

to me seems that ES/DS/SI? is not initialized properly when I'm in BIOS extension, normaly I made a noob debugging program to see ES and DS what values hold during my program
...
msg db 'Assembled by xxxxx xxxxxxxx - 2018'
...
mov ah,0Fh ;get video mode
int 10h
mov vpage,bh

push ds
push si

mov dx,ES ; to see where ES is
mov cx,DS ; to see where DS is
mov si, offset [msg]

mov ah,0Eh ;dh first 8 bit from ES
mov al,dh
mov bh,vpage
int 10h
mov ah,0Eh ;dl last 8 bit from ES
mov al,dl
mov bh,vpage
int 10h

mov ah,0Eh
mov al,219 ; a "space"
mov bh,vpage
int 10h

mov ah,0Eh ; ch first 8 bit from DS
mov al,ch
mov bh,vpage
int 10h
mov ah,0Eh ; cl last 8 bit from DS
mov al,cl
mov bh,vpage
int 10h

mov ah,0Eh
mov al,219
mov bh,vpage
int 10h

mov ah,0Eh ;[SI]
mov al,[si]
mov bh,vpage
int 10h

mov ah,0Eh
mov al,219 ; a "space"
mov bh,vpage
int 10h

Result is thihs:
v8Vbjjo.jpg
my bios extension is set via jumpers at D000
apparently ES is at D000, DS at 0040, and SI at 0
I think I tried every possible combination of

mov ah,0Eh
mov al,ES:DS / ES:[DS] / DS:SI / DS:[SI] / ES:[DS+SI]
mov bh,0
int 10h
All I get same behavior like in the second picture, no matter of combination I put in AL register. Basicaly I wonder what I dont see, even is in front of my eyes?
inb4: Also please dont tell about INT 21h, 09h.... is not about that

Reply 1 of 16, by MERCURY127

User metadata
Rank Member
Rank
Member

Write string (EGA+, meaning PC AT minimum)
AH=13h
AL = Write mode, BH = Page Number, BL = Color, CX = String length, DH = Row, DL = Column, ES:BP = Offset of string

Reply 4 of 16, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie
Predator99 wrote:
Quick Review: You dont know the content of DS when Executing. Insert.. Push cs Pop DS ..at the beginning […]
Show full quote

Quick Review: You dont know the content of DS when Executing.
Insert..
Push cs
Pop DS
..at the beginning

are you gauranteed any valid stack either?

I'd do (unless your ss:sp is setup by bios to be safe)

;; set stack to known position
xor ax,ax
mov ss,ax
mov sp,0x1000

push cs
push cs
pop ds
pop es

your

mov vpage,bh

where is DS, your in rom, where have you got your variables pointed to? when bios boots, screen resets, so you know your displaypage is always going to be 0!

--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--

Reply 6 of 16, by Predator99

User metadata
Rank Oldbie
Rank
Oldbie
BloodyCactus wrote:
are you gauranteed any valid stack either? […]
Show full quote
Predator99 wrote:
Quick Review: You dont know the content of DS when Executing. Insert.. Push cs Pop DS ..at the beginning […]
Show full quote

Quick Review: You dont know the content of DS when Executing.
Insert..
Push cs
Pop DS
..at the beginning

are you gauranteed any valid stack either?

I'd do (unless your ss:sp is setup by bios to be safe)

;; set stack to known position
xor ax,ax
mov ss,ax
mov sp,0x1000

push cs
push cs
pop ds
pop es

Yes, that a good idea. Was using my mobile yesterday I didnt want to make it too complicated 😉 But usally, SS/SP should already have a valid value as the stack was also used by the prevoius ROM.
You can set SS to 1000 as DOS is not loaded yet.

For debugging under DOS, its also a good idea to to change the initial CS:IP (xxxx:0100?) to something else (e.g. xxxx:0500) and also to set the DS/ES/SS to random values as you cannot rely on anything when its executed in the BIOS.

Reply 7 of 16, by stamasd

User metadata
Rank Oldbie
Rank
Oldbie
awgamer wrote:

Why are you censoring parts of a bios boot screen?

It's probably his real name, the part he covered is not part of the boot screen but a message that the executable displays.

I/O, I/O,
It's off to disk I go,
With a bit and a byte
And a read and a write,
I/O, I/O

Reply 8 of 16, by 32768

User metadata
Rank Newbie
Rank
Newbie

sorry but I still don't get it (its always one)... real simple example

P8086
MODEL TINY
ORG 0 ;for BIOS must be 0
DATASE
msg db 'Assembled'
CODESEG
STARTUPCODE:
db 55h,0AAh,1 ;BIOS
mov si, offset[msg] <<<
mov ah,0Eh
mov al,???<<<
mov bh,0
int 10h
RETF
END

what I still don't know for sure, if even this is right: mov si, offset[msg] and what exactly I sould put in AL register. Lets start with that.

Reply 9 of 16, by stamasd

User metadata
Rank Oldbie
Rank
Oldbie

Well for int10 AH=0xE you need to have in AL the character you want to output.
http://stanislavs.org/helppc/int_10-e.html

I/O, I/O,
It's off to disk I go,
With a bit and a byte
And a read and a write,
I/O, I/O

Reply 10 of 16, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie

I haven't tried doing x86 ROMs before so I would have a couple of questions. Where is the entry point and where is the data section (which contains the string) located in the ROM image?
To write a string to the screen using a BIOS function that outputs one character, maybe you could use a loop like this. (Add a 0 byte to the end of the string to make it null-terminated)

; routine for writing null-terminated string
; one character at a time
mov si, offset[msg]
looppoint:
lodsb
jz stringdone
mov ah,0Eh
mov bh,0
;push si ;does si need to be preserved when calling BIOS??
int 10h
;pop si
jmp looppoint
stringdone:

Reply 11 of 16, by K1n9_Duk3

User metadata
Rank Member
Rank
Member

Why don't you just put the message in the code segment?

jmp begin

msg db xxx

begin:
mov ax, cs
mov ds, ax
...

The code at the "begin" label demonstrates how to move CS into DS without using the stack, but you will need a proper stack to use interrupts anyway, so you might as well use "push cs" + "pop ds" after the stack was set up correctly.

Reply 12 of 16, by 32768

User metadata
Rank Newbie
Rank
Newbie

So far, until my last post I got nothing
the best I did was this

ZNZ6Ewv.jpg

with code:

P8086          ;select the processor
MODEL TINY ;always must be TINY model
org 0h
DATASEG
msg db 'Hello'
db 0FFh,0FFh,0FFh,0FFh ;for modul of 4096
db 0FFh,0FFh,0FFh,0FFh ;for modul of 4096
db 0FFh,101 ;for modul of 4096
CODESEG
STARTUPCODE
db 55h,0AAh,1

xor si,si
mov dx,0
loop1:
mov ah,0Eh
mov al,es:[SI]
mov bh,0
int 10h
inc SI
inc dx
cmp dx,140
jbe loop1

mov ah,0Eh
mov al,219 ;a visual marker to see when loop is done
mov bh,0
int 10h

mov ah,0Eh ; \n
mov al,10
mov bh,0
int 10h
mov ah,0Eh
mov al,13
mov bh,0
int 10h

RETF
END

but... everytime I try to link a pointer to msg it give me blank characters, no matter if is:
mov SI, offset msg
mov si,[msg]
lea bx,msg/mov si,bx or other variants found on internet, when I try to display it with
mov ah,0Eh
mov al,[si] or mov al,[msg][si] or even mov es:[si]
mov bh,0
int 10h
it give me blanks every time

All this make me wonder, mabye I'm chasing the wrong rabbit:
my rom BIOS extension acts like a harddisk??? and then when executes the program, actually the msg is in RAM memory? And all along this time I tryed to link my pointer so desperately to D000, but was in fact something equivalent like trying to link my pointer to what ever specific cylinder or sector on the harddisk? Mabye this is somewhat right

BloodyCactus wrote:
I'd do (unless your ss:sp is setup by bios to be safe) […]
Show full quote

I'd do (unless your ss:sp is setup by bios to be safe)

;; set stack to known position
xor ax,ax
mov ss,ax
mov sp,0x1000

push cs
push cs
pop ds
pop es

where is DS, your in rom, where have you got your variables pointed to?

K1n9_Duk3 wrote:

Why don't you just put the message in the code segment?
The code at the "begin" label demonstrates how to move CS into DS without using the stack, but you will need a proper stack to use interrupts anyway, so you might as well use "push cs" + "pop ds" after the stack was set up correctly.

What I'm asking afterall, is how this code in rom image behave? like a file on a harddisk? or like an already executed program loaded in to memory (I doubt that because I can modify some variabiles, for example vpage db 0 from my previous posts, the EEPROM cant be burned everytime I change a variabile)

Also about this stack cs/ss/cp, every time I touch them the computer freeze(but I suspect is my fault).

In case you wondering what is in the first pic, is the code from above compiled
82UCbX9.jpg

Reply 13 of 16, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie
32768 wrote:

All this make me wonder, mabye I'm chasing the wrong rabbit:

I see you using ES overrides, but have you actually set ES to your code segment manually? I dont see your coding doing

mov ax,cs
mov es,ax

to actually use it.

32768 wrote:

my rom BIOS extension acts like a harddisk??? and then when executes the program, actually the msg is in RAM memory?

.....

What I'm asking afterall, is how this code in rom image behave? like a file on a harddisk? or like an already executed program loaded in to memory (I doubt that because I can modify some variabiles, for example vpage db 0 from my previous posts, the EEPROM cant be burned everytime I change a variabile)

it behaves as its in a fixed location. You should also try and make it internally relocatable / relative.

db 0xE8,0,0
pop bx
sub bx,4

then you can index from that

lea si,[bx + msg]

I suspect your vpage variable 'works' in the sense its always 0, so it only _seems_ to work but its in ROM so it can never change, but since the computer boots up in page 0, you never need anything else.

also your header should have an index to the start of your code routine and make sure your CRC adds to zero.

why are you printing 140 characters when your message is 5? just zero terminate your message and detect zero byte.

--/\-[ Stu : Bloody Cactus :: http://kråketær.com :: http://mega-tokyo.com ]-/\--

Reply 14 of 16, by 32768

User metadata
Rank Newbie
Rank
Newbie
BloodyCactus wrote:
32768 wrote:
I see you using ES overrides, but have you actually set ES to your code segment manually? I dont see your coding doing mov ax,cs […]
Show full quote

I see you using ES overrides, but have you actually set ES to your code segment manually? I dont see your coding doing
mov ax,cs
mov es,ax
...
why are you printing 140 characters when your message is 5? just zero terminate your message and detect zero byte.

got home, made the modification...same behaviour
also tried:
mov ax,cs
mov ds,ax
just to be sure, still nothing
as soon I insert this mov si,offset msg all I get is blank characters

That 140 is because my style of debugging, I call it something close in english to crap shooting, before all I got was blank characters, I was probing blindly to see where I'm at

Reply 15 of 16, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie

You have org 0 before the data segment but for the option ROM to execute the bytes $55 $AA must be at 0, so it is still unclear where that data segment is really located. Why not move the string to the end of the code segment instead?

P8086          ;select the processor
MODEL TINY ;always must be TINY model
org 0h
CODESEG
STARTUPCODE
db 55h,0AAh,1

mov ax,cs
mov ds,ax
mov es,ax

mov si,offset msg
mov dx,0
loop1:
mov ah,0Eh
mov al,es:[SI]
mov bh,0
int 10h
inc SI
inc dx
cmp dx,140
jbe loop1

mov ah,0Eh
mov al,219 ;a visual marker to see when loop is done
mov bh,0
int 10h

mov ah,0Eh ; \n
mov al,10
mov bh,0
int 10h
mov ah,0Eh
mov al,13
mov bh,0
int 10h

RETF

msg:
db 'Hello'

END

yet another retro game on itch: https://90soft90.itch.io/super-wild-war-22

Reply 16 of 16, by 32768

User metadata
Rank Newbie
Rank
Newbie
bakemono wrote:
You have org 0 before the data segment but for the option ROM to execute the bytes $55 $AA must be at 0, so it is still unclear […]
Show full quote

You have org 0 before the data segment but for the option ROM to execute the bytes $55 $AA must be at 0, so it is still unclear where that data segment is really located. Why not move the string to the end of the code segment instead?

P8086          ;select the processor
MODEL TINY ;always must be TINY model
org 0h
CODESEG
STARTUPCODE
db 55h,0AAh,1
...
RETF
msg:
db 'Hello'
END

This code should have worked, many others said so and yet.... it didn't. But I found the bug eventually, was because of this: STARTUPCODE. Everything was wrong with this, until I had the ideea to remove that STARTUPCODE and lo behold my Hello apeared for the first time in almost two months. This STARTUPCODE was a reminent left in my code from an *.com example found in Turbo Pascal. Granted it worked under DOS, I dont think the ppl who made that example think that will become part of a BIOS extension after 20 years
Now evertyhing work, no matter if msg is placed in CODESEG or at the end of the code. Even the AH=13h, AL = Write mode, BH = Page Number, BL = Color, CX = String length, DH = Row, DL = Column, ES:BP = Offset of string worked.

All is fine under the sun
59xf5z5.jpg