; SPDX-License-Identifier: NOASSERTION ; ; radmode - front end for the radmode driver: a button per desktop size, and a ; line saying what came of it. ; ; The size goes to the driver on its command line and the driver does all of it, ; hardware first and the kernel after, through SetScreen. ; ; There are only two sizes worth a button. The driver leaves the vertical half ; of the scaler alone, so the height is fixed at the panel's, and it has no ; control over the scaler's destination rectangle either - on DCE4 that belongs ; to the ATOM EnableScaler table - so any width below the panel's is simply ; stretched across the whole panel instead of being centred with black sides. ; That makes the panel's own size the one correct mode, and the size the ; firmware used the one useful thing to go back to. ; ; Function 14 reads the size back afterwards, so the line below the buttons says ; whether the kernel really moved. Why it did not is on the debug board, where ; the driver reports. ; ; Given a "width height" command line it does that one size and exits without a ; window, which is the form for AUTORUN.DAT: ; ; /SYS/RADMODE "1366 768" -1 use32 org 0x0 db 'MENUET01' dd 0x01 dd START dd I_END dd MEM_END dd STACKTOP dd params dd 0x0 include '../../macros.inc' DRIVER equ '/sys/drivers/radmode.sys' struct PRESET width dd ? height dd ? label dd ? ends WIN_X = 100 WIN_Y = 100 WIN_W = 300 CLIENT_H = 76 BTN_W = 130 BTN_H = 26 BTN_X0 = 10 BTN_Y0 = 12 BTN_DX = 140 BTN_DY = 34 BTN_ID0 = 10 LABEL_LEN = 17 STATUS_X = 10 STATUS_Y = 52 COLOUR_BODY = 0xDDDDDD COLOUR_BUTTON = 0x6688CC COLOUR_LABEL = 0xFFFFFF COLOUR_TEXT = 0x000000 START: ; a command line means one shot and no window at all mov esi, params call parse_dec test eax, eax jz .gui mov [req_w], eax call parse_dec test eax, eax jz .gui mov [req_h], eax call load_driver mcall -1 .gui: mcall 48, 4 mov [skin_h], eax mcall 40, 0x7 ; redraw, key, button call draw_window .events: mcall 10 dec eax jz .redraw dec eax jz .key mcall 17 shr eax, 8 cmp eax, 1 jz .exit sub eax, BTN_ID0 cmp eax, PRESET_COUNT jb .apply jmp .events .redraw: call draw_window jmp .events .key: mcall 2 jmp .events .exit: mcall -1 ; eax - the preset to switch to .apply: imul eax, sizeof.PRESET mov ecx, [presets + eax + PRESET.width] mov [req_w], ecx mov ecx, [presets + eax + PRESET.height] mov [req_h], ecx call load_driver ; the driver reports to the board; here all that matters is whether the kernel ; ended up where it was asked to mcall 14 mov ecx, eax shr ecx, 16 inc ecx mov [got_w], ecx movzx ecx, ax inc ecx mov [got_h], ecx mov edi, status mov eax, [req_w] call str_dec mov esi, txt_x call str_cat mov eax, [req_h] call str_dec mov eax, [got_w] cmp eax, [req_w] jnz .failed mov eax, [got_h] cmp eax, [req_h] jnz .failed mov esi, txt_done call str_cat call draw_status jmp .events .failed: mov esi, txt_failed call str_cat mov eax, [got_w] call str_dec mov esi, txt_x call str_cat mov eax, [got_h] call str_dec call draw_status jmp .events ; req_w and req_h go to the driver on its command line load_driver: mov edi, cmdline mov eax, [req_w] call str_dec mov esi, txt_space call str_cat mov eax, [req_h] call str_dec mcall 68, 21, driver_path, cmdline ret draw_window: mcall 12, 1 mov ecx, [skin_h] add ecx, CLIENT_H + 5 or ecx, (WIN_Y shl 16) mcall 0, (WIN_X shl 16) + WIN_W, , 0x34000000 + COLOUR_BODY, 0, title mov dword [idx], 0 .button: mov eax, [idx] cmp eax, PRESET_COUNT jae .done mov ecx, eax and ecx, 1 imul ecx, BTN_DX add ecx, BTN_X0 mov [btn_x], ecx shr eax, 1 imul eax, BTN_DY add eax, BTN_Y0 mov [btn_y], eax mov ebx, [btn_x] shl ebx, 16 or ebx, BTN_W mov ecx, [btn_y] shl ecx, 16 or ecx, BTN_H mov edx, [idx] add edx, BTN_ID0 mcall 8, , , , COLOUR_BUTTON ; the labels are padded to one width, so one offset centres them all mov ebx, [btn_x] add ebx, (BTN_W - LABEL_LEN*6) / 2 shl ebx, 16 mov eax, [btn_y] add eax, (BTN_H - 9) / 2 or ebx, eax mov eax, [idx] imul eax, sizeof.PRESET mov edx, [presets + eax + PRESET.label] mcall 4, , 0x80000000 + COLOUR_LABEL inc dword [idx] jmp .button .done: call draw_status mcall 12, 2 ret ; the line is rewritten in place, so clear what was under it first draw_status: mcall 13, (STATUS_X shl 16) + WIN_W - 2*STATUS_X, \ ((STATUS_Y - 2) shl 16) + 13, COLOUR_BODY mcall 4, (STATUS_X shl 16) + STATUS_Y, 0x80000000 + COLOUR_TEXT, status ret ; esi - the text, left past the number; eax - the value, zero if there is none parse_dec: xor eax, eax .spaces: cmp byte [esi], ' ' jnz .digits inc esi jmp .spaces .digits: movzx ecx, byte [esi] sub ecx, '0' cmp ecx, 9 ja .done lea eax, [eax*4 + eax] lea eax, [eax*2 + ecx] inc esi jmp .digits .done: ret ; esi - the source, edi - the destination, left on the terminator str_cat: lodsb mov [edi], al inc edi test al, al jnz str_cat dec edi ret ; eax - the number, edi - the destination, left on the terminator str_dec: push ebx mov ebx, 10 xor ecx, ecx .split: xor edx, edx div ebx push edx inc ecx test eax, eax jnz .split .emit: pop eax add al, '0' mov [edi], al inc edi loop .emit mov byte [edi], 0 pop ebx ret align 4 presets: dd 1366, 768, lbl_native dd 1024, 768, lbl_firmware PRESET_COUNT = 2 lbl_native db ' 1366x768 native ', 0 lbl_firmware db '1024x768 firmware', 0 title db 'radmode', 0 driver_path db DRIVER, 0 txt_x db 'x', 0 txt_space db ' ', 0 txt_done db ': done', 0 txt_failed db ' failed, the screen is still ', 0 status db 'native size, or back to the firmware', 0 times 64 db 0 I_END: align 4 skin_h rd 1 idx rd 1 btn_x rd 1 btn_y rd 1 req_w rd 1 req_h rd 1 got_w rd 1 got_h rd 1 cmdline rb 32 params rb 256 rb 512 STACKTOP: MEM_END: