; CPUINFO - the values of the rows as text, and the numbers to text. ; ==================================================================== ; The values: eax = the argument of the row, edi -> the text; out: edi at ; its terminating zero. They change all the registers. ; eax -> dword from CPUID, "-" without CPUID: its signature is never 0 val_id: cmp [signature], 0 je fmt_none ; eax -> dword val_uint: mov eax, [eax] jmp fmt_uint ; eax -> dword, 0: unknown val_count: mov eax, [eax] test eax, eax jz fmt_none jmp fmt_uint ; eax -> dword; with its unit, 0: unknown val_mhz: mov ebp, sz_mhz jmp val_unit val_deg: mov ebp, sz_deg jmp val_unit val_bytes: mov ebp, sz_bytes ; ebp -> the unit val_unit: mov eax, [eax] test eax, eax jz fmt_none call fmt_uint mov esi, ebp jmp fmt_str ; eax -> dword: 8 hex digits, 0: unknown val_hex8: mov eax, [eax] test eax, eax jz fmt_none mov ecx, 16 mov ebx, 8 jmp fmt_digits ; eax -> tenths of MHz: "99.8 MHz", 0: unknown val_mhz10: mov eax, [eax] test eax, eax jz fmt_none call fmt_tenths mov esi, sz_mhz jmp fmt_str ; eax -> the multiplier in tenths: "x4.5", 0: unknown val_mult: mov eax, [eax] test eax, eax jz fmt_none mov byte [edi], "x" inc edi jmp fmt_tenths ; eax -> CACHE: "6 x 32 KB", the count if more than one and the cores ; are known val_cache: mov ebp, eax cmp [ebp + CACHE.size], 0 je fmt_none cmp [cores], 0 je .size mov ecx, [ebp + CACHE.shared] jecxz .size mov eax, [threads] movi edx, 0 div ecx cmp eax, 1 jbe .size call fmt_uint mov esi, sz_times call fmt_str .size: mov eax, [ebp + CACHE.size] jmp fmt_size ; the last leaves: "20h, 8..28h", "-" without CPUID val_levels: cmp [signature], 0 je fmt_none mov eax, [max_leaf] call fmt_hex cmp [max_ext], EXT_LEAVES jb .done mov esi, sz_ext_leaves call fmt_str mov eax, [max_ext] sub eax, EXT_LEAVES jmp fmt_hex .done: ret ; ==================================================================== ; Numbers to text: write to edi and leave it at the terminating zero. ; "-": unknown fmt_none: mov word [edi], "-" ; and the zero after it inc edi ret ; eax = number; in hex, then "h"; changes eax, ebx, ecx, edx, esi fmt_hex: mov ecx, 16 movi ebx, 0 call fmt_digits mov word [edi], "h" ; and the zero after it inc edi ret ; eax = number; changes eax, ebx, ecx, edx, esi fmt_uint: mov ecx, 10 movi ebx, 0 ; eax = number, ecx = base, ebx = the fewest digits: the digits from the ; lowest into digits from its end, then to edi; changes eax, ebx, edx, esi fmt_digits: mov esi, digits_end mov byte [esi], 0 .divide: movi edx, 0 div ecx add dl, "0" cmp dl, "9" jbe .digit add dl, "A" - "9" - 1 .digit: dec esi mov [esi], dl dec ebx test eax, eax jnz .divide test ebx, ebx jg .divide jmp fmt_str ; eax = tenths; printed as "4.5"; changes eax, ebx, ecx, edx, esi fmt_tenths: movi edx, 0 mov ecx, 10 div ecx push edx ; the tenths, the digit after the point call fmt_uint mov byte [edi], "." inc edi pop eax jmp fmt_uint ; eax = KB; printed as "48 KB", "1.2 MB", "32 MB"; changes eax, ebx, ecx, ; edx, esi, ebp fmt_size: ; the largest unit it fills, its number in sz_units in ebp, the ; rest of the smaller one in edx movi ebp, 0 movi edx, 0 .scale: cmp eax, 1024 jb .print mov edx, eax and edx, 1023 shr eax, 10 inc ebp jmp .scale ; with a decimal if it has one .print: imul edx, 10 shr edx, 10 test edx, edx jz .whole imul eax, 10 add eax, edx call fmt_tenths jmp .unit .whole: call fmt_uint .unit: mov esi, sz_units mov eax, ebp call str_nth ; esi -> string; changes eax, esi fmt_str: lodsb stosb test al, al jnz fmt_str dec edi ret ; esi -> strings one after another, eax = the number of one from 0: esi ; -> it; changes eax, ecx str_nth: dec eax js .done call str_skip jmp str_nth .done: ret ; esi -> a string; out: esi past its terminating zero, ecx = its length str_skip: movi ecx, -1 .char: inc ecx inc esi cmp byte [esi - 1], 0 jne .char ret uglobal digits rb 32 ; fmt_digits: up to 32 of them digits_end rb 1 endg