I.nfraR.ed Posted November 20, 2019 Posted November 20, 2019 (edited) 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 November 20, 2019 by I.nfraR.ed Quote
Tzk Posted November 20, 2019 Posted November 20, 2019 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. Quote
I.nfraR.ed Posted November 20, 2019 Posted November 20, 2019 (edited) 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 November 20, 2019 by I.nfraR.ed Quote
Tzk Posted November 20, 2019 Posted November 20, 2019 (edited) 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 November 20, 2019 by Tzk Quote
I.nfraR.ed Posted November 20, 2019 Posted November 20, 2019 (edited) 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? 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 November 20, 2019 by I.nfraR.ed Quote
Tzk Posted November 20, 2019 Posted November 20, 2019 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. Quote
I.nfraR.ed Posted November 20, 2019 Posted November 20, 2019 (edited) 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 November 20, 2019 by I.nfraR.ed 1 Quote
I.nfraR.ed Posted November 21, 2019 Posted November 21, 2019 (edited) 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 November 22, 2019 by I.nfraR.ed 1 Quote
Tzk Posted November 21, 2019 Posted November 21, 2019 (edited) 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 November 21, 2019 by Tzk Quote
I.nfraR.ed Posted November 21, 2019 Posted November 21, 2019 (edited) 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 November 21, 2019 by I.nfraR.ed Quote
Tzk Posted November 21, 2019 Posted November 21, 2019 (edited) 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 November 21, 2019 by Tzk Quote
I.nfraR.ed Posted November 21, 2019 Posted November 21, 2019 (edited) @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 November 22, 2019 by I.nfraR.ed Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by Tzk Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 (edited) 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 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 November 22, 2019 by I.nfraR.ed Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by Tzk Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by I.nfraR.ed Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 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. Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by I.nfraR.ed 1 Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by Tzk Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 (edited) 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 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 November 22, 2019 by I.nfraR.ed Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 (edited) Works in QEMU, will test on the mobo in the evening 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 Edited November 22, 2019 by I.nfraR.ed 1 1 Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 (edited) 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 November 22, 2019 by Tzk 1 1 Quote
TerraRaptor Posted November 22, 2019 Author Posted November 22, 2019 23 minutes ago, Tzk said: What's left to do is to port this over to A7N8X-E Dlx ? will truly appreciate it as I'm not able to follow you both the last pages:) Great cooperation friends! 1 Quote
I.nfraR.ed Posted November 22, 2019 Posted November 22, 2019 The message is nice, but nothing shows on the real machine Will get the tREF done, fix tRC range and that will be for now. Then port it to AN7, should be able to just copy and paste most of the things. Quote
Tzk Posted November 22, 2019 Posted November 22, 2019 I just tried to mess with the sector, landingzone etc display items... Looks like they aren't getting greyed out anymore when i change the function ID to FFFF. Interesting... ? Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.