Jump to content
HWBOT Community Forums

A7N8X-E Deluxe as an alternative for socket 462


TerraRaptor

Recommended Posts

Yes, that would savee me some time, although I will have to adapt the item in the system.bin (position in the group, label position, etc.) I've already copied the labels in _EN_CODE.BIN from DFI Ultra-D bios, but my plan is to start from scratch - basically get a clean bios and copy/paste just the option labels I need, then fix the offsets.

 

PS: Wish we had the newer layout with separate _ITEM.BIN :(

Edited by I.nfraR.ed
Link to comment
Share on other sites

That's what i did too.

I started with the stock 1007 Asus bios, moved items with modbin, relabeled them, edited en_code.bin, swapped romsips and BPL. I just opted to create a new item label group to have everything in a single place. So there are some unused labels now in some label groups which the bios originally used before i made my changes.

Link to comment
Share on other sites

Some more info about _item.bin. Not sure if the extra status bits are applicable in our case. I would try some of the other possible statuses to see the effect.

Info taken from ROM.by site: http://wiki.rom.by/index.php?title=Award_Inside

Quote

ItemAward


struct ItemAward
{
dw	Status;			+00
dw	Name;			+02
dw	ChipReg;		         +04
dw	ChipReg_mask;		+06
db	CMOS;			+08
dw	CMOS_mask;		+09
dw	index_ValueNameTable;	+0A
dw	ItemMin;		         +0C
dw	ItemMax;		         +0E
db	xPosition;		+11
db	yPosition;		+12
dw	BIOS_default;		+13
dw	SETUP_default;		+15
dw	Help;			+17
};				=19h (25 bytes)

Status

Status bits:


"NOMODBIN"       0x0000;
"CT_RVS"         0x0001;
"CT_RIS"         0x0002;
"SHOWONLY"       0x0004;
"ITEMDISABLE"    0x0008;
"GAP_ITEM"       0x0010;
"PMITEM"         0x0020;
"NODEFAULT"      0x0040;
"USERONLY"       0x0080;
"KEYIN"          0x0100;
"SHOWNUM"        0x0200;
"SHOWHEX"        0x0400;
"DIGIT3"         0x0800; // 0x1800);
"DIGIT4"         0x1000; // 0x1800);
"DIGIT5"         0x1800; // 0x1800);
"EARLYPROG"      0x2000;
"AUTOPROG"       0x4000;
"APPEND"         0x8000;

 

Edited by I.nfraR.ed
Link to comment
Share on other sites

So if i got you right, then this should work to set Trc, correct? I use 00h as "auto" and then every value is passed cirectly from al to ebx which is my data register.

So this is bacially a switchless and compact solution for Trc and Trfc.

;====================================================================
                    ; set trc      
mov al, 76h         ; read index - 76h
out 072h, al        ; send register offset
in al, 073h         ; fetch data
and al, 1Fh         ; mask al to discard first 3 bits
cmp al, 00h
je trc_end          ; jump to next setting if auto selected (equal 0000.0000)
;    
mov eax,080000190h  ; move address for 32bit register offset
mov ebx,al          ; move data we want to set
mov dx,0CF8h        ; pci register address port
out dx,eax          ; set port we want to read
mov dx,0CFCh        ; pci register data port
in eax,dx           ; read register values
and eax,0FFFFFF00h  ; mask for data to remove pre-set value, usually the inverse of the data we set
or eax,ebx          ; add custom value to old register data
out dx,eax          ; write new custom register value   

trc_end:            ; jump target
;====================================================================

Trc is B0D0F1 offset 90h while Trfc is 91h. So i inset a left shift by 2 bits on Trfc right after the data is set, correct?

;Trc (90h):

mov eax,080000190h  ; move address for 32bit register offset
mov ebx,al          ; move data we want to set
; no left shift here
mov dx,0CF8h        ; pci register address port
;====================================================================
;Trfc 91h:

mov eax,080000190h  ; move address for 32bit register offset
mov ebx,al          ; move data we want to set
shl ebx,2           ; leftshift by 2 bits (011h -> 01100h)
mov dx,0CF8h        ; pci register address port

 

Edited by Tzk
Link to comment
Share on other sites

I will go through the actual code later and tell you if it is 100% correct, since I read ASM slow and takes me time to comprehend, but you should be careful with eax, al, ebx, edx, etc, since you can overwrite.

eax is a 32bit register, then the subset ax is 16 bit register (low 16 bits), which also consists of ah and al (high and low). Changing eg al overwrites the lowest 8 bits in eax. The optimal code should probably keep aex, copy needed parts into other registers(ebx, edx, dx, etc.), reset needed values with masks, then OR with modified value and copy back to al, ah, full ax, etc. Depends on the data.

I'm still at work, so my "free" time is limited and it had been very busy lately :(.

PS: If I do it in C/C++ first it might help me write more efficient ASM. Perhaps use gcc to convert C code to ASM?

register1.jpg

Edit: If you read offset 90 to 93, your offset 90h is basically al, while 91h is ah. You can then e.g. manipulate them separately using helper dx for example, apply mask, OR the data and copy changed dx to corresponding subset. And finally push the whole eax if not both trc and trfc CMOS registers are 00h. Otheriwse just skip.

This way you can just read and write the whole word (PCI register) once for adjacent offsets, in this case 93h, 92h, 91h, 90h.

Edited by I.nfraR.ed
Link to comment
Share on other sites

The Code above is almost the same AS the macro from the ASM code i uploaded a few days ago. No major changes.

I was aware that al and ah are inside ax and inside eax. I wasn't aware that i can store data in ax and use eax afterwards while keeping the data. Makes it a bit easier to handle instead of numerous bitshifts.

I haven't finished the option rom yet, will upload the completed code when IT works.

Link to comment
Share on other sites

I was thinking something like this*, but I don't think it is optimal if I want to reuse same macros for all settings.

It also might be a nonsense and not work, it's jut my understanding.

Most of these read/write blocks can be macros, but I don't know how efficient is this code compared to simple switches.

Edit: I can probably use dx instead of al in those cmos read operations, so I know dx is always used as a variable for data. EAX will hold my original data, EBX will be zeroed and the needed bits will be positioned correctly, depending on data I want to set, sometimes using BX, BH and BL directly, sometimes bitshifting some of them or using some helper variable (edc for example) for the bitshift and then use OR to set the bits on EBX if those bits are in the higher 16bit segment. Something like that...

 

*Sample code:

;
; Let's assume we want to set tRFC and tRC.
; tRC is 90h, tRFC is 91h, so I will arrange them at the same order they need to be set, just for convenience
; each CMOS register is 8bit
; #76h
; | 000 | 00000 |
; |     |  tRFC |
; #75h
; | 0000 | 0000 |
; |      |  tRC |
mov ebx, 0          ; reset ebx
; read tRC
mov al, 75h         ; set CMOS index, basically var x = 75h
out 70h, al         ; send register offset, 70/71 is CMOS, 72/73 is higher/extended CMOS, for our needs we can use both, since we're dealing with lower CMOS registers and one is an alias to the other.
in al, 71h          ; fetch cmos data to al
mov bl, al
and bl, 0Fh         ; mask the data and zero the high 4 bits, which we probably use for other setting
; read tRFC
mov al, 76h         ; set CMOS index, basically var x = 75h
out 70h, al         ; send register offset
in al, 71h          ; fetch data to al
mov bh, al
and bh, 1Fh         ; mask lower 5 bits
; we now have bx holding both of our values, something like 00011111 00001111
;
cmp bx, 0h          ; check both 0
je codeend          ; or some other segment
; else we know at least one of them is not 0
; get register data
mov eax, 80000190h  ; move address for 32bit register offset, note no leading zero necessary. It's only needed infront of hex values with letter, so the compiler knows it is not a symbol
mov dx, 0CF8h       ; pci register address port
out dx, eax         ; set port we want to read
mov dx, 0CFCh       ; pci register data port
in eax, dx          ; read register values
; register data is now in eax and cmos values in bx
;
cmp bl, 0h          ; check if tRC is 0
je set_trfc         ; trfc is not 0 then
; else zero tRC in eax
and eax, 0FFFFFFF0h
jmp set_trfc

set_trfc:
cmp bh, 0h          ; check if tRFC is 0
je write_data       ; tRFC is 0, then tRC is not
; else zero tRFC bits in 91h
and eax, 0FFFFE0FFh
jmp write_data

write_data:
; write data
or eax, ebx
out dx, eax         ; write new custom register value
jmp codeend
;

 

Edited by I.nfraR.ed
  • Thanks 1
Link to comment
Share on other sites

I think this is better and cleaner code. Decided to set each one separately, much easier.

Also fasm supports C-style hex numbers, so I will use that. This code is untested and might have some errors, but that's the idea I will use.

define PCI_ADDR_PORT    0xCF8
define PCI_DATA_PORT    0xCFC
define CMOS_ADDR_PORT   0x70
define CMOS_DATA_PORT   0x71

macro configurePort pci
{
  mov eax, pci
  mov dx, PCI_ADDR_PORT
  out dx, eax
}

macro readPciReg pci
{
  configurePort pci
  mov dx, PCI_DATA_PORT
  in eax, dx
}

macro writePciReg pci, data, mask
{
  readPciReg pci
  and eax, mask
  or eax, data
  out dx, eax
}

macro readCmosReg reg, mask
{
  mov al, reg                     ; set CMOS index
  out CMOS_ADDR_PORT, al          ; send register offset
  in al, CMOS_DATA_PORT           ; read CMOS data 
  and al, mask                    ; mask the data and zero unneeded bits
}

jmp set_trc

set_trc:
  ; read tRC from CMOS
  readCmosReg 0x75, 0x0F
  cmp al, 0
  je set_trfc
  ; else
  mov ebx, 0
  mov bl, al
  writePciReg 0x80000190, ebx, 0xFFFFFFF0
  jmp set_trfc

set_trfc:
  ; read tRFC from CMOS
  readCmosReg 0x76, 0x1F
  cmp al, 0
  je codeend                                  ; replace with next segment
  ; else
  mov ebx, 0
  mov bh, al
  writePciReg 0x80000190, ebx, 0xFFFFE0FF
  jmp codeend

codeend:

 

Edited by I.nfraR.ed
  • Thanks 1
Link to comment
Share on other sites

Your code looks great!

I just got DS, SR, Trc and Trfc working, all of them without case switching. Next is Tref, however my guess is that this isn't doable without switch table as we can't map the input from cmos cirectly to hex values. This are Tref values i'll implement:

;   00: Auto (keep value, skip custom code)
;   01: 0402 -> 0204h =  516 cycles
;   02: 8802 -> 0288h =  648 cycles
;   03: 0803 -> 0308h =  776 cycles
;   04: 0D03 -> 030Dh =  780 cycles
;   05: 8C03 -> 038Ch =  908 cycles
;   06: 0804 -> 0408h = 1032 cycles
;   07: 9004 -> 0490h = 1168 cycles
;   08: 1005 -> 0510h = 1296 cycles
;   09: 0006 -> 0600h = 1536 cycles
;   0A: 1006 -> 0610h = 1552 cycles
;   0B: 1806 -> 0618h = 1560 cycles
;   0C: 1807 -> 0718h = 1816 cycles
;   0D: 0008 -> 0800h = 2048 cycles
;   0E: 1008 -> 0810h = 2064 cycles
;   0F: 2009 -> 0920h = 2336 cycles
;   10: 000A -> 0A00h = 2560 cycles
;   11: 200A -> 0A20h = 2592 cycles
;   12: 000C -> 0C00h = 3072 cycles
;   13: 300C -> 0C30h = 3120 cycles
;   14: 300E -> 0E30h = 3632 cycles
;   15: 640E -> 0E64h = 3684 cycles
;   16: 2010 -> 1020h = 4128 cycles
;   17: 6410 -> 1064h = 4196 cycles
;   18: 4012 -> 1240h = 4672 cycles
;   19: 6412 -> 1264h = 4708 cycles    

And here's my isa option rom (without Tref) i currently use:

ISA-option-ROM-A7N8X-v5.ASM

Edited by Tzk
Link to comment
Share on other sites

The DFI options are ordered strangely in the bios. Here are them sorted.

I will just use a long switch, but haven't decided if I want to list them all or limit the options like you did.

The good thing is we can zero both registers and set the value directly, since they are in the order we want them -> 61h 60h.

Your  option #4 is wrong, should be 0x030C. Not that it matters at all.

04: 0D03 -> 030Dh =  780 cycles
0016 Cycles	0x0010
0032 Cycles	0x0020
0064 Cycles	0x0040
0128 Cycles	0x0080
0388 Cycles	0x0184
0516 Cycles	0x0204
0648 Cycles	0x0288
0776 Cycles	0x0308
0780 Cycles	0x030C
0908 Cycles	0x038C
1032 Cycles	0x0408
1168 Cycles	0x0490
1296 Cycles	0x0510
1536 Cycles	0x0600
1552 Cycles	0x0610
1560 Cycles	0x0618
1816 Cycles	0x0718
2048 Cycles	0x0800
2064 Cycles	0x0810
2336 Cycles	0x0920
2560 Cycles	0x0A00
2592 Cycles	0x0A20
3072 Cycles	0x0C00
3120 Cycles	0x0C30
3632 Cycles	0x0E30
3684 Cycles	0x0E64
4128 Cycles	0x1020
4196 Cycles	0x1064
4672 Cycles	0x1240
4708 Cycles	0x1264

 

Edited by I.nfraR.ed
Link to comment
Share on other sites

Good spot. Fixed number 4.

Yes, DFI somehow thought it's a great idea to group the refresh rates by refresh cycle time. That's why they got 1.95us, 3.9us, 7.8us and 15.6us groups and each of these got 4 options: 100/133/166/200Mhz. Interestingly 100MHz 15.6us hasn't got the same count of cycles as 7.8us 200MHz which is weird. That's the same for other values, too...

Edited by Tzk
Link to comment
Share on other sites

@Tzk tRC is 4bit, so from 0 to 15, tRFC is 5bit - 0 to 31. 0 = Auto for both. Currently you have tRC settings up to 31.

Edit: Ofcourse I had an error! Had CMOS_ADDR_PORT and CMOS_DATA_PORT switched in readCmosReg macro, which was leading to incorrect CMOS data and it was always setting both tRC and tRFC to 9. It also corrupted my windows installation, because that test memory couldn't handle it at DDR-400. I have corrected the code snippet above.

But now everything works great! I have all the settings in the bios, just need to write the code for the rest - trfc, drive strength and slew rate.

Instead of

mov ebx, 0

I now use

and ebx, 0x0

to reset it. Not sure which one is better though, the result should be the same, I think.

I will probably be ready with the whole thing tomorrow and will post the full code.

Edited by I.nfraR.ed
Link to comment
Share on other sites

I just doublechecked a DFI LPB bios with modbin. DFI allows Trc = 31T and Trfc = 31T. Same for NF2 Tweaker. I've been testing these at 100Mhz because at this low clocks you can do Trc 7 and Trfc 8 easily and without data corruption.

I've had errors in fasmw when using mov ebx,al. That's why i switched to using either registers of same size (mov bl,al) or use movzx eax,al. The last one fills all other bits of the eax register with zeros and thus cleans any leftover data on that register. I also ended up building a huge switch table for Tref. Will test now and upload when it works.

Here's my code for DS and SR. I had to read cmos twice on each of these for this because ebx and al are used inside the writeregister macro and thus i have to re-read them to set the second set of registers. Maybe you got a better idea for this.

;read drive strength
readcmos 75h, 0F0h  ; read cmos and write to al
cmp al, 00h
je drivestrength_end ; jump to next setting if auto selected (equal 0000.0000)

shr al, 4           ; al now: 01h
movzx ebx,al        ; ebx now: 000000001h
shl ebx, 4          ; ebx now: 000000010h
add bl,al           ; ebx now: 000000011h
shl ebx,8           ; ebx now: 000001100h

writeregister 08000047Ch, 0FFFF00FFh ; offset 7D
writeregister 080000480h, 0FFFF00FFh ; offset 81

readcmos 75h, 0F0h  ; read cmos and write to al

shr al, 4           ; al now: 01h
movzx ebx,al        ; ebx now: 000000001h
shl ebx, 4          ; ebx now: 000000010h
add bl,al           ; ebx now: 000000011h
shl ebx,12          ; ebx now: 000001100h
add bl,al           ; ebx now: 000011001h
shl ebx, 4          ; ebx now: 000110010h
add bl,al           ; ebx now: 000110011h
shl ebx,8           ; ebx now: 011001100h

writeregister 080000464h, 000FF00FFh ; offset 65 and 67
writeregister 080000470h, 000FF00FFh ; offset 71 and 73

drivestrength_end:  ; jump target
;====================================================================
                    ; read Slew rate
readcmos 75h, 0Fh   ; read cmos and write to al
cmp al, 00h
je slewrate_end     ; jump to next setting if auto selected (equal 0000.0000)

movzx ebx,al        ; ebx now: 000000001h
shl ebx, 4          ; ebx now: 000000010h
add bl,al           ; ebx now: 000000011h

writeregister 08000047Ch, 0FFFFFF00h ;offset 7C

readcmos 75h, 0Fh   ; read cmos and write to al

movzx ebx,al        ; ebx now: 000000001h
shl ebx, 4          ; ebx now: 000000010h
add bl,al           ; ebx now: 000000011h
shl ebx,12          ; ebx now: 000011000h
add bl,al           ; ebx now: 000011001h
shl ebx, 4          ; ebx now: 000110010h
add bl,al           ; ebx now: 000110011h

writeregister 080000464h, 0FF00FF00h ;offset 64 and 66

slewrate_end:       ; jump target
;====================================================================  

 

 

And these are the macros i use for readcmos and writeregister, as posted several times on this thread:

;====================================================================
macro writeregister pcireg, cmask
{
mov eax,pcireg      ; move address for 32bit register offset
mov dx,0CF8h        ; pci register address port
out dx,eax          ; set port we want to read
mov dx,0CFCh        ; pci register data port
in eax,dx           ; read register values
and eax,cmask       ; mask for data to remove pre-set value, usually the inverse of the data we set
or eax,ebx          ; add custom value to old register data
out dx,eax          ; write new custom register value
}
;====================================================================
macro readcmos cmosreg, mask
{
mov al, cmosreg     ; set cmos register
out 072h, al        ; send register offset
in al, 073h         ; fetch data
and al, mask        ; mask al to discard last 4 bits as these are used for slew rate
}
;==================================================================== 
Edited by Tzk
Link to comment
Share on other sites

Yes, I copy al to bl or bh, depending on the situation. mov bl, al will replace the whole bl with what is inside al. Don't know which method for clearing (zero-ing) ebx is best and most efficient one. Currently using xor ebx, ebx :D

Quote

The XOR operation sets the resultant bit to 1, if and only if the bits from the operands are different. If the bits from the operands are same (both 0 or both 1), the resultant bit is cleared to 0

Here's my code for drive strength and slew rate with some comments.

set_slew_rate:
  ; read slew rate from CMOS
  readCmosReg 0x78, 0xF0
  ; for example cmos data is 7 -> al is 0111 0000
  ; need to set 0,0,4 reg 64, 66, 7C
  cmp al, 0
  je set_drive_strength
  ; else
  xor ebx, ebx
  mov bl, al  ; bl is 0111 0000
  shr bl, 4   ; bl is 0000 0111
  or bl, al   ; bl is 0111 0111
  mov al, bl  ; save bl
  shl ebx, 16 ; shift bl to higher 16bit segment
  mov bl, al  ; ebx is 0000 0000 0111 0111 0000 0000 0111 0111
  writePciReg 0x80000464, ebx, 0xFF00FF00 ; 66, 64
  writePciReg 0x8000047C, ebx, 0xFFFFFF00 ; 7C

set_drive_strength:
  ; read drive strength from CMOS
  readCmosReg 0x78, 0x0F
  ; for example cmos data is 7 -> al is 0000 0111
  ; need to set 0,0,4 reg 65, 67, 71, 73, 7D, 81
  cmp al, 0
  je codeend
  ; else
  xor ebx, ebx
  mov bl, al  ; bl is 0000 0111
  shl bl, 4   ; bl is 0111 0000
  or bl, al   ; bl is 0111 0111
  mov al, bl  ; save bl
  shl ebx, 24 ; shift bl to highest 8bit segment for reg 67
  mov bh, al  ; ebx is 0111 0111 0000 0000 0111 0111 0000 0000
  writePciReg 0x80000464, ebx, 0x00FF00FF ; 67, 65
  writePciReg 0x80000470, ebx, 0x00FF00FF ; 73, 71
  writePciReg 0x8000047C, ebx, 0xFFFF00FF ; 7D
  writePciReg 0x80000480, ebx, 0xFFFF00FF ; 81

 

I could eventually even combine adjacent SR and DS, but that means more "if" statements.

Attached is my current code - everything except tREF. for drive strength I could have copied al to bh instead and use smaller bitshift on the ebx, but I'm not sure if it matters. Currently, I save both DS and SR in one CMOS register, that's why I need to left shift for the one and right shift for the other in order to "double" the value. If I save them in separate CMOS registers (both in the lower 4 bits), then I could use a common macro for the "doubling". I will also probably switch the CMOS mask for them, so they are in the same order as in the mask for writePciReg (like you have them in the correct order).

As for tRC, I' will have to correct that in my bios, option rom and in the PCR file. Thanks! I've somehow overlooked it, since memset has up to 15 only. It doesn't read tRP correctly anyway (IIRC reads one of tRCD-R or tRCD-W).

NF7_OPTION.ASM

Edited by I.nfraR.ed
Link to comment
Share on other sites

Looks good. However i do not get how you're setting two registers and a single register with the same data (ebx). Shouldn't this also set undesired registers, eg. 7F and 7D instead of only 7D? Or are you masking the old value and the new data in ebx before applying it?

Edited by Tzk
Link to comment
Share on other sites

Yes, I mask ebx before setting it, but it's in the code at home. Sorry about that. Same for slew rate.

  writePciReg 0x80000464, ebx, 0x00FF00FF ; 67, 65
  writePciReg 0x80000470, ebx, 0x00FF00FF ; 73, 71
  and ebx, 0x00FFFFFF ; <-- here
  writePciReg 0x8000047C, ebx, 0xFFFF00FF ; 7D
  writePciReg 0x80000480, ebx, 0xFFFF00FF ; 81

 

Edited by I.nfraR.ed
Link to comment
Share on other sites

Regarding the XOR:

xor ebx,ebx   ; clears ebx with zeros
mov bl,al     ; moves al -> bl

movzx ebx, al ; move with zero extend
              ; moves al -> bl AND sets all other bits of ebx to zero

So you can basically use movzx instead of xor+mov.

Using a mask inbetween is smart. I'll do that in the exact same way as it saves a bit of code.

Link to comment
Share on other sites

And I will use the movzx :)

I also experimented with printing text from the ROM to the screen and it worked, but I did something wrong with the return, since it was stuck at it and didn't continue.

One more day and we will have everything working, then I will try again. 

 

PS:

Quote
2
This is exactly correct. On modern Core i7 processors, MOVZX reg, mem has identical latency to MOV reg, mem. – icecreamsword Apr 19 '17 at 17:45
  • 1
    That's true on modern Intel processors, but not true historically. However, all the way back to the Pentium Pro, you had the significant penalty of partial register stalls, which meant that MOVZX was still a net performance win. The exception was that you could write the code to clear the entire register first (XOR reg, reg), and then load only a lower 16-bit or 8-bit alias. This didn't break the dependency on the PPro (which didn't really do dependency-breaking), but it did on later processors, and was often slightly faster than MOVZX, given that instruction's historically high latency. 

so maybe

xor ebx, ebx
mov bl, al

is actually a little bit faster, although I'm not sure if the compiler optimizes it further. Maybe check compiled binary in both cases.

Edited by I.nfraR.ed
  • Thanks 1
Link to comment
Share on other sites

So you want to basically the values which were set? Interesting idea. I also had another idea for Memtest: What if we include Memtest in the ISA option rom and start it from there? You could basically bypass or start it like we do with our "auto" settings.

And finally, here's my (ugly, but working) Tref code:

tref.ASM

So all in all the bios works as expected and i'll upload it somewhere. Next, i'll see if i got some other items in bios left to (re)use. Maybe we can add the alphatimings.

Edited by Tzk
Link to comment
Share on other sites

At least it is perfectly readable. I don't know how to optimize that, so will probably use your code, since I was going to write the same long "switch".

For any other setting I want to use the direct value, yes. For DS and SR we need "doubling" the bits, so the direct value e.g. A turns into AA.

Don't know if there's a more efficient/shorter way of doing it compared to the bitshifts I'm currently using. I would do it the same way on C++ or javascript.

That's where my knowledge for bitwise operations ends :D

All in all, I think we got the code on the "next" level, compared to the patch ROM of tictac for example. We now have fully functional bios items, while his code only sets things unconditionally.

The memtest idea could work. Control if it runs with an option in bios (you can use EPA logo, for example).

Edited by I.nfraR.ed
Link to comment
Share on other sites

Works in QEMU, will test on the mobo in the evening

image.thumb.png.1e726ec1edd0e4b0f8255e96fae7938c.png

 

code end

codeend:
  popa
  popfd
  ; return far to system bios routine
  retf

print_string:                               ; Routine: output string in SI to screen
  mov ah, 0eh                               ; BIOS tty Print
  xor bx, bx                                ; Set display page to 0 (BL)
  jmp .getch
.repeat:
  int 10h                                   ; print character
.getch:
  mov al, [cs:si]
  inc si
  test al, al                               ; Have we reached end of string?
  jnz .repeat                               ; if not process next character
.end:
  ret

  ; String ends with 0x0d (Carriage return) and 0x0a (linefeed) to
  ; advance cursor to the beginning of next line
  text_string db 'ABIT NF7 v2 OC OPTION ROM v1.00', 0dh, 0ah, 0

  ; use 00h as the padding bytes until we reach the ROM size
  ; The last byte (512th) will be the patch_byte for the checksum
  ; patch_byte is calculated and automagically inserted below
  times (ROM_SIZE_IN_BYTE-$) db 0
  PREV_CHKSUM = 0
  repeat $
  load CHKSUM byte from %-1
  CHKSUM = (PREV_CHKSUM + CHKSUM) mod 0x100
  PREV_CHKSUM = CHKSUM
  end repeat
  ; store the patch_byte
  store byte (0x100 - CHKSUM) at ($-1)

call of the print routine

MAIN:
  ; save all registers for later restore
  pushfd
  pusha
  mov si, text_string                         ; Put string position into SI
  call print_string

Got the print code from stackoverflow: https://stackoverflow.com/questions/49001298/option-rom-code-failing-to-print-intended-string-using-qemu-emulation

Perhaps we can simplify the code by using call instead of near jumps. Basically define all SET functions at the end of the ROM, read CMOS for each setting and if not 0 (Auto) call set_timing.

 

Edit: no NIC ROM to reduce clutter

qemu-system-x86_64 -net none -option-rom NF7_OPTION.BIN

 

Now with color :D

image.png.61f1237d2236e7731b713283f929aca4.png

Edited by I.nfraR.ed
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I guess i'm done with modding (for now). Everything works, custom items are added. Here's the files for A7N8X Dlx v2.0:

A7N8X-DLX-v20-1007-EVO-v1.zip

Also uploaded to bierbude: http://bierbude.spdns.org:2302/USER UPLOADS/Tzk/Asus/A7N8X Deluxe v2.0/

What's left to do is to port this over to A7N8X-E Dlx and to try to add more settings. Also the custom message upon boot looks very nice... :)

Edited by Tzk
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...