-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathPS2GUI.ASM
More file actions
6254 lines (6081 loc) · 189 KB
/
Copy pathPS2GUI.ASM
File metadata and controls
6254 lines (6081 loc) · 189 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; ============================================================================
; PS2GUI.COM - Graphical (VGA) system manager for the IBM PalmTop PC110
; A GUI fork of PS2TUI reproducing the IBM *Easy-Setup* as a real ICON GRID
; (VGA mode 12h): the main menu is a grid of 10 tiles, one per PS2TUI category;
; opening a tile shows a new icon-grid page for that category's items; settings
; open a short value picker. The selected tile is inverted (dark-red), just like
; Easy-Setup. Structure is identical to PS2TUI; there is no text-mode menu.
; (The only text step is the confirm/run of the real PS2.EXE / ULTRACHG tool and
; the diagnostic reports, which return to the grid after.)
;
; Version 1.6.17 (c) Ahmad Byagowi -- Keyboard test: Print Screen now lights up. The
; PC110's PrtSc key emits plain scancode 0x54 (make 54 / break D4), not the standard
; extended E0 37 - remapped PrS to 0x54 ext 0.
; Version 1.6.16 -- Duck cursor: removed the dithered-streak/shadow
; white specks (mis-classified transparent gaps -> stray white under belly/beak) by
; dropping isolated white pixels; and stopped clipping the wing-down frame's forward-
; folded wing (the previous leak-clean box had cut it). Dramatic wing-up/down flap
; kept; both frames clean, wings intact, silhouette verified.
; Version 1.6.15 -- Duck cursor flap made clearly visible: the two
; frames are now the DRAMATIC wing-down (folded, compact) vs wing-up (raised wing)
; real BIOS poses (v1.6.14 used two near-identical wing-up poses -> looked static).
; Cleared the flood-fill leak that had left white under the wing-down frame. Flap
; toggle verified alternating in QEMU.
; Version 1.6.14 -- Duck cursor cleanup + mouse ISR hardening:
; * frame 0 is now the REAL parked/resting pose (captured over the clean cyan
; Easy-Setup screen) instead of an awkward mid-flap phase whose flood-fill had
; trapped a white pocket behind the motion streak ("white space under cursor").
; * IRQ12 handler now consumes port 0x60 ONLY for a genuine aux byte (0x64 bit0
; OBF + bit5 aux) - a spurious IRQ or stray keyboard byte no longer misframes a
; packet (candidate for the intermittent startup-after-move crash).
; Version 1.6.13 -- Duck cursor from the real BIOS sprite (both flap frames), 32x32.
; Version 1.6.12 -- Duck cursor flap (procedural wing-up); superseded by 1.6.13.
; Version 1.6.11 -- Fn key removed from the keyboard test (it emits
; no scancode - resolved in the keyboard MCU, not
; host-visible per KBC+EC probing). Startup-crash fix:
; clamp the cursor fully on-screen (old bound let it
; draw off-screen -> VGA-BIOS fault on a misframed
; first packet) + drain OBF/reset framing before IRQ12.
; Version 1.6.10 -- Keyboard test: the Brk/Pause key now lights up
; whether it sends the E1 Pause sequence OR the
; E0 46 Break sequence (both map to the Brk key).
; Version 1.6.9 -- mouse_init: disable reporting (F5) + drain before
; configuring, so a finger on the trackpad during
; startup can't interleave packet bytes with the
; command ACKs and leave it half-configured (the
; intermittent "crash/quit on first move" at start).
; Version 1.6.8 -- Keyboard test: Brk now maps to the extended Break
; scancode E0 46 (was hijacked by the ScrollLock
; alias, which is now limited to the plain 0x46).
; Version 1.6.7 -- Keyboard test: pressed keys now LATCH (stay lit
; after release) so you can see which keys you've
; tested; ESC still exits (on release).
; Version 1.6.6 -- Keyboard test: show the last 3 raw scancode bytes
; at the bottom (to identify unknown keys), and map
; ScrollLock (0x46) onto the NumLock/ScrLk key so it
; lights. (Brk/Pause code TBD from the readout.)
; Version 1.6.5 -- Keyboard test: Enter and Backspace shortened so
; every key's right edge lines up flush; keyboard
; stays centred on screen (make_kbd.py computes KB_X).
; Version 1.6.3 -- Keyboard test: exact PC110 bottom-right too - the
; arrows tuck in (bottom row: ...Ctrl Left Down
; Right; Shift row: ...Ro Up RShift with Up above
; Down), and the right edge stacks Backspace over
; Enter over right-Shift.
; Version 1.6.2 -- Keyboard test: exact PC110 top area - a top row
; (Esc / PrtSc NumLk Pause / Ins Home PgUp) sitting
; ABOVE the function row (F1-F12 / Del End PgDn):
; Esc over F1, PrtSc/NumLk/Pause over F9/F10/F11,
; Ins/Home/PgUp over Del/End/PgDn. Pause (E1) seq
; swallowed so it doesn't false-trigger Ctrl/NumLk.
; Version 1.6.1 -- Keyboard test layout reworked to match the real
; PC110: grouped F-keys, a separated nav block
; (Ins/Home/PgUp over Del/End/PgDn), an inverted-T
; arrow cluster, tall Enter, taller keys.
; Version 1.6.0 -- Keyboard test is now a recreated PC110 keyboard
; (from the real JP layout): it hooks INT 9 and
; lights up each key (red) as it is pressed, incl.
; 0xE0-extended keys. Press ESC to exit. Layout
; generated by tools/make_kbd.py -> KBD.INC.
; Version 1.5.9 -- Signature pad: press C in the test to run a
; 4-corner calibration (touch each pad corner);
; it fits a linear raw->screen map (handles a
; flipped axis) so strokes land accurately. ESC
; cancels; uncalibrated falls back to the raw map.
; Version 1.5.8 -- All self-contained test/report pages now render
; on the graphical Easy-Setup page (mauve + dark
; text) like the signature test, not the blue text
; screen. cls_body_full/puts_hint honour [body_gfx];
; the R_CALL wrapper sets mode 12h + dark text. The
; Video test stays text-mode (it shows text
; attributes + the CP437 set); external PS2.EXE
; confirm/run screens stay text-mode too.
; Version 1.5.7 -- Hardware guard: at startup verify this is a
; genuine PC110 (APM vendor "SLO" identify via
; INT 15h 5380/7F); QEMU is allowed (fw_cfg
; "QEMU"). On anything else, show a text warning
; that PS2GUI is PC110-only and may DAMAGE other
; hardware -- ESC quits, F10 runs at own risk.
; Version 1.5.6 -- Duck cursor now FLAPS its wings as it moves
; (two frames: wings up/glide + wings down),
; like the real Easy-Setup cursor. (A direct
; VGA-planar cursor blitter was tried to kill the
; flicker but faulted on the real F65535/EMM386;
; reverted to the BIOS pixel path, which is safe.)
; Version 1.5.5 -- New "Signature pad test" (System Test): drives
; the PC110 resistive inking digitizer directly.
; Data is IRQ-driven (the pad reports only via its
; interrupt, not by polling): hook the inking IRQ
; (base+IRQ from INT 15h 5380/8300, as INKDRV does),
; enable (out base+2,0x38), collect 3-byte packets
; [flags,rawX,rawY] in an ISR, and draw your strokes
; in a VGA signing box. Restores IRQ/PIC/pad on exit.
; Also: flush the keyboard buffer and seed the mouse
; button baseline at startup, so a stale key/button
; left by a prior run can't insta-quit the relaunch.
; Version 1.5.4 -- first (polled) signature-pad test; superseded by the IRQ-driven 1.5.5.
; Version 1.5.3 -- Pointing-device test now reads the trackpad
; directly off the 8042 aux channel (polled),
; so it works with no INT 33h driver installed
; (was: "No pointing-device driver loaded").
; Version 1.5.2 -- fix: after a test/diagnostic you couldn't get back - a stuck
; trackpad byte in the 8042 OBF blocked the keyboard; disable
; aux + flush during text screens so 'press any key' works
; Build (host): nasm -f bin PS2GUI.ASM -o PS2GUI.COM
; Target: MS-DOS / PC DOS 7 (real mode), VGA mode 12h. Assemble as a .COM.
; ============================================================================
%define PS2TUI_VER "1.0" ; shown in the text-menu title bar
HL_COLOR equ 2 ; Easy-Setup selection-box colour (dark red)
cpu 586 ; allow CPUID (the PC110 486SX supports it); 16-bit real mode
bits 16
org 0x100
; ---- colour attributes (classic cyan window / yellow border theme) ---------
A_TITLE equ 0x3F ; title text: bright white on cyan
A_FOOT equ 0x3E ; footer key-hints: yellow on cyan
A_FRAME equ 0x3E ; panel frame: yellow on cyan (double-line border)
A_ITEM equ 0x30 ; menu label: black on cyan
A_DESC equ 0x31 ; description text: blue on cyan (secondary)
A_SEL equ 0x70 ; selection bar: black on light-grey
A_KEY equ 0x3F ; breadcrumb / accent: bright white on cyan
A_BODY equ 0x30 ; (legacy) black on cyan
A_HEAD equ 0x3E ; (legacy) yellow on cyan
A_BOX equ 0x1F ; popup dialogs: white on blue (pop against cyan)
A_WARN equ 0x4F ; white on red
A_DESK equ 0x30 ; window/desktop fill: black on cyan (space = cyan)
; ---- row types -------------------------------------------------------------
R_ITEM equ 1 ; setting with an option list
R_ACT equ 2 ; action (no options, just run "PS2 <cmd>")
R_INFO equ 3 ; runs "PS2 _@REVision"
R_CALL equ 4 ; calls the internal routine at the record's "cmd" field
R_UITEM equ 5 ; like R_ITEM but runs C:\ULTRACHG.COM <option> (no cmd word)
; ---- layout : a framed window floating on a grey desktop, with a drop shadow -
UI_L equ 2 ; window left column (border)
UI_R equ 77 ; window right column (border)
UI_TOP equ 1 ; window top row (border)
UI_BOT equ 17 ; window bottom row (border)
TITLE_ROW equ 2 ; title text row (inside window, below top border)
BC_ROW equ 3 ; breadcrumb row
ITEM_TOP equ 5 ; first item screen row
FOOT_ROW equ 16 ; footer key-hints row (inside window, above bottom border)
ITEM_COL equ 7 ; item label column
DESC_COL equ 31 ; description column (main menu)
A_SHADOW equ 0x08 ; drop-shadow cells: dark on black
A_DESKTOP equ 0x70 ; desktop backdrop: black on light-grey (space = grey)
; CP437 double-line box glyphs
BX_TL equ 0xC9
BX_TR equ 0xBB
BX_BL equ 0xC8
BX_BR equ 0xBC
BX_H equ 0xCD
BX_V equ 0xBA
GLY_ARROW equ 0x10 ; ► selection marker
; ============================================================================
; Program entry — the graphical IBM Easy-Setup launcher (VGA mode 12h)
; ============================================================================
; layout / palette-index constants for the graphical menu
C_MAUVE equ 0
C_WHITE equ 1
C_RED equ 2
C_NAVY equ 3
C_BLACK equ 4
ITEMROW0 equ 4 ; first list row (text rows are 8x16, 80x30)
; ============================================================================
; Program entry — graphical menu (VGA mode 12h, Easy-Setup style).
; Main menu = PS2TUI's 10 categories; sub-menus and pickers are graphical.
; ============================================================================
start:
mov ax, cs
mov ds, ax
mov es, ax
mov bx, 0x1000
mov ah, 0x4A
int 0x21
; --- refuse to run on non-PC110 hardware (QEMU allowed, for testing) ---
call is_pc110 ; CF clear = genuine PC110
jnc .hwok
call is_qemu ; CF clear = QEMU
jnc .hwok
call hw_warn ; CF set = user chose to quit
jnc .hwok
mov ax, 0x4C01 ; abort, exit code 1
int 0x21
.hwok:
mov ax, 0x0012 ; VGA 640x480x16
int 0x10
call set_palette
push es ; cache the ROM 8x16 font pointer for gtext
mov ax, 0x1130
mov bh, 6
int 0x10 ; -> ES:BP = 8x16 font
mov [font_seg], es
mov [font_off], bp
pop es
call mouse_init
mov word [gcat], 0
.kflush: ; drop any stale keystroke (e.g. the ESC that
mov ah, 1 ; quit a previous run) so we don't insta-quit
int 0x16
jz .kdone
xor ah, ah
int 0x16
jmp .kflush
.kdone:
call g_draw_main
.mloop:
mov ax, [gcat]
mov [gsel_old], ax ; remember selection for incremental redraw
call wait_event
cmp byte [ev], 1
je .mclick
mov ax, [ev_key]
cmp al, 0x1B
je .mquit
cmp al, 0x0D
je .mopen
cmp al, 0
jne .mloop
cmp ah, 0x48
je .mup
cmp ah, 0x50
je .mdown
cmp ah, 0x4B
je .mleft
cmp ah, 0x4D
je .mright
jmp .mloop
.mup:
mov ax, [gcat]
cmp ax, GCOLS
jb .mred
sub ax, GCOLS
mov [gcat], ax
jmp .mred
.mdown:
mov ax, [gcat]
add ax, GCOLS
cmp ax, NCATS
jae .mred
mov [gcat], ax
jmp .mred
.mleft:
cmp word [gcat], 0
je .mred
dec word [gcat]
jmp .mred
.mright:
mov ax, [gcat]
inc ax
cmp ax, NCATS
jae .mred
mov [gcat], ax
.mred:
call cursor_hide ; repaint only the two affected tiles
mov ax, [gsel_old]
mov [tile_i], ax
mov byte [tile_sel], 0
call main_tile
mov ax, [gcat]
mov [tile_i], ax
mov byte [tile_sel], 1
call main_tile
jmp .mloop
.mclick:
call hit_tile
jc .mloop
cmp ax, NCATS
jae .mloop
mov [gcat], ax ; click a category tile -> open it
.mopen:
mov word [gitem], 0
call g_sub_loop
call g_draw_main
jmp .mloop
.mquit:
call mouse_shutdown ; release IRQ12 / restore 8042 (direct mode)
mov ax, 0x0003
int 0x10
mov ax, 0x4C00
int 0x21
; ============================================================================
; Hardware guard: PS2GUI drives PC110-specific hardware directly, so it must
; only run on a genuine PC110 (QEMU is allowed so it can be developed/tested).
; ============================================================================
; is_pc110 : CF clear if the IBM PC110 APM vendor BIOS answers with its "SLO"
; identify signature (same check PS2.EXE / ULTRACHG use). CF set otherwise.
is_pc110:
push ax
push bx
push cx
mov ax, 0x5380 ; AH=53h APM, AL=80h IBM vendor extension
mov bh, 0x7F ; function 7F = identify
int 0x15
cmp bh, 0x53 ; 'S'
jne .no
cmp bl, 0x4C ; 'L'
jne .no
cmp cl, 0x4F ; 'O'
jne .no
clc
jmp .done
.no: stc
.done: pop cx
pop bx
pop ax
ret
; is_qemu : CF clear if the QEMU fw_cfg port (0x510/0x511) returns "QEMU".
is_qemu:
push ax
push dx
mov dx, 0x510 ; fw_cfg selector
xor ax, ax ; entry 0 = signature
out dx, ax
mov dx, 0x511 ; fw_cfg data
in al, dx
cmp al, 'Q'
jne .no
in al, dx
cmp al, 'E'
jne .no
in al, dx
cmp al, 'M'
jne .no
in al, dx
cmp al, 'U'
jne .no
clc
jmp .done
.no: stc
.done: pop dx
pop ax
ret
; hw_warn : this is not a PC110 (or QEMU). Show the warning in text mode and
; wait: ESC quits (CF set); F10 runs anyway (CF clear).
hw_warn:
mov ax, 0x0003 ; 80x25 text mode (clears screen)
int 0x10
mov ah, 0x09
mov dx, warn_msg
int 0x21
.wk: xor ah, ah
int 0x16
cmp al, 0x1B ; ESC -> quit (recommended)
je .quit
cmp ah, 0x44 ; F10 -> run anyway
je .run
jmp .wk
.run: clc
ret
.quit: stc
ret
; ---- sub-menu (items of category [gcat]) ----
g_sub_loop:
call g_draw_sub
.sloop:
mov ax, [gitem]
mov [gsel_old], ax ; remember selection for incremental redraw
call wait_event
cmp byte [ev], 1
je .sclick
mov ax, [ev_key]
cmp al, 0x1B
je .sback
cmp al, 0x0D
je .sopen
cmp al, 0
jne .sloop
cmp ah, 0x48
je .sup
cmp ah, 0x50
je .sdown
cmp ah, 0x4B
je .sleft
cmp ah, 0x4D
je .sright
jmp .sloop
.sclick:
call hit_tile
jc .sloop
mov bx, ax
mov al, [cat_count]
xor ah, ah
cmp bx, ax
jae .sloop
mov [gitem], bx ; click an item tile -> activate it
call g_activate
call g_draw_sub
jmp .sloop
.sup:
mov ax, [gitem]
cmp ax, GCOLS
jb .sred
sub ax, GCOLS
mov [gitem], ax
jmp .sred
.sdown:
mov ax, [gitem]
add ax, GCOLS
mov bl, [cat_count]
xor bh, bh
cmp ax, bx
jae .sred
mov [gitem], ax
jmp .sred
.sleft:
cmp word [gitem], 0
je .sred
dec word [gitem]
jmp .sred
.sright:
mov ax, [gitem]
inc ax
mov bl, [cat_count]
xor bh, bh
cmp ax, bx
jae .sred
mov [gitem], ax
.sred:
call cursor_hide ; repaint only the two affected tiles
mov ax, [gsel_old]
mov [tile_i], ax
mov byte [tile_sel], 0
call sub_tile
mov ax, [gitem]
mov [tile_i], ax
mov byte [tile_sel], 1
call sub_tile
jmp .sloop
.sopen:
call g_activate
call g_draw_sub
jmp .sloop
.sback:
ret
; ---- activate the selected item (dispatch by row type) ----
g_activate:
mov al, [cat_start]
xor ah, ah
add ax, [gitem]
mov [sel], ax
mov bx, ax
call row_ptr
mov al, [si+6]
cmp al, R_ITEM
je .item
cmp al, R_UITEM
je .uitem
cmp al, R_ACT
je .act
cmp al, R_INFO
je .info
mov ax, [si+2] ; R_CALL -> self-contained test/report
push ax
call to_text ; mouse off + mask IRQ12 (8042/keyboard safety)
mov ax, 0x0012 ; run it on a GRAPHICAL mauve page (Easy-Setup look)
int 0x10
call set_palette
mov byte [body_gfx], 1
mov word [tty_col], 0x0004 ; dark text
pop ax
call ax
mov byte [body_gfx], 0
mov word [tty_col], 0x0007
call to_gfx
ret
.info:
call to_text
call run_revision
call to_gfx
ret
.act:
mov si, [si+2]
call build_cmd_noopt
call to_text
call confirm_run
call to_gfx
ret
.item:
mov ax, [si+2]
mov [cur_cmd], ax
mov ax, [si+4]
mov [opt_base], ax
call g_picker
jc .done
call opt_ptr
mov [cur_opt], si
mov si, [cur_cmd]
call build_cmd_opt
call to_text
call confirm_run
call to_gfx
.done:
ret
.uitem:
mov word [exec_prog], ultra_prog
mov word [show_pfx], pfx_ultra
mov byte [ultra_mode], 1
mov ax, [si+4]
mov [opt_base], ax
call g_picker
jc .ureset
call opt_ptr
mov [cur_opt], si
call build_cmd_ultraopt
call to_text
call confirm_run
call to_gfx
.ureset:
mov word [exec_prog], progname
mov word [show_pfx], pfx_ps2
mov byte [ultra_mode], 0
ret
; ---- graphical value picker (options of [opt_base]); CF=0 chosen / CF=1 cancel ----
g_picker:
mov word [opt_sel], 0
call g_draw_pick
.ploop:
mov ax, [opt_sel]
mov [gsel_old], ax ; remember selection for incremental redraw
call wait_event
cmp byte [ev], 1
je .pclick
mov ax, [ev_key]
cmp al, 0x1B
je .pcancel
cmp al, 0x0D
je .pok
cmp al, 0
jne .ploop
cmp ah, 0x48
je .pup
cmp ah, 0x50
je .pdown
jmp .ploop
.pclick:
call hit_opt
jc .ploop
mov [opt_sel], ax ; click a value -> choose it
clc
ret
.pup:
cmp word [opt_sel], 0
je .pred
dec word [opt_sel]
jmp .pred
.pdown:
call opt_count
mov ax, [opt_sel]
inc ax
cmp ax, cx
jae .pred
mov [opt_sel], ax
.pred:
call cursor_hide ; repaint only the two affected option rows
mov ax, [gsel_old]
mov [tile_i], ax
mov byte [tile_sel], 0
call pick_row
mov ax, [opt_sel]
mov [tile_i], ax
mov byte [tile_sel], 1
call pick_row
jmp .ploop
.pok:
clc
ret
.pcancel:
stc
ret
; pick_row : repaint one picker option row [tile_i] with [tile_sel]
pick_row:
mov ax, [tile_i]
mov [pk_i], ax
mov bx, PK_ROW
mul bx
add ax, [pk_y]
add ax, PK_TITLE + 4
mov [pk_oy], ax
mov word [fr_x], PK_X + 8
mov ax, [pk_oy]
dec ax
mov [fr_y], ax
mov word [fr_w], PK_W - 16
mov word [fr_h], PK_ROW
mov al, C_WHITE
cmp byte [tile_sel], 0
je .bg
mov al, C_RED
.bg: mov [fr_col], al
call g_fillrect
mov byte [g_col], C_NAVY
cmp byte [tile_sel], 0
je .t
mov byte [g_col], C_WHITE
.t: call ptr_to_opt
push si
call gt_strlen
pop si
shl cx, 2
mov ax, PK_X + PK_W/2
sub ax, cx
mov [gt_x], ax
mov ax, [pk_oy]
add ax, 2
mov [gt_y], ax
call gtext
ret
; ---- graphical draw helpers ----
g_fill_mauve:
push es
mov dx, 0x3C4
mov al, 2
out dx, al
inc dx
mov al, 0x0F
out dx, al
mov ax, 0xA000
mov es, ax
xor di, di
mov cx, 19200
xor ax, ax
rep stosw
pop es
ret
; g_fill_page : white screen (like Easy-Setup's border) with the mauve panel
; inset at (32,32)-(607,400); everything else is drawn on the panel.
g_fill_page:
mov byte [cur_valid], 0 ; whole screen repainted -> cursor bg is stale
mov word [fr_x], 0
mov word [fr_y], 0
mov word [fr_w], 640
mov word [fr_h], 480
mov byte [fr_col], C_WHITE
call g_fillrect
mov word [fr_x], 32
mov word [fr_y], 32
mov word [fr_w], 576
mov word [fr_h], 369
mov byte [fr_col], C_MAUVE
call g_fillrect
ret
; g_bg : prepare the background for a menu/dialog draw. The white border, mauve
; panel, title and copyright are the same on every screen, so on a normal screen
; change we DON'T repaint them (that full white fill is what flashes) - we only
; clear the content region and refresh the breadcrumb. A full page is drawn only
; the first time and after a video-mode reset ([need_full]=1, set by to_gfx).
g_bg:
cmp byte [need_full], 0
je .content
call g_fill_page
call g_chrome
mov byte [need_full], 0
ret
.content:
mov byte [cur_valid], 0 ; content repainted -> cursor bg is stale
mov word [fr_x], 40 ; clear only the content area to mauve
mov word [fr_y], 108
mov word [fr_w], 560
mov word [fr_h], 286
mov byte [fr_col], C_MAUVE
call g_fillrect
mov word [fr_x], 240 ; clear the breadcrumb slot (keeps the title)
mov word [fr_y], 72
mov word [fr_w], 360
mov word [fr_h], 20
mov byte [fr_col], C_MAUVE
call g_fillrect
cmp word [bc_str], 0
je .d
mov byte [g_col], C_BLACK
mov dh, 5
mov dl, 32
mov si, [bc_str]
call g_puts
.d: ret
; g_puts : DH=row DL=col SI=asciiz, colour in [g_col]; stops at NUL or '='
g_puts:
push ax
push bx
push dx
mov ah, 2
xor bh, bh
int 0x10
.n: lodsb
test al, al
jz .d
cmp al, '='
je .d
mov ah, 0x0E
mov bl, [g_col]
xor bh, bh
int 0x10
jmp .n
.d: pop dx
pop bx
pop ax
ret
; g_box_draw : red/mauve 2-px outline around text row [box_row], colour [ringcol]
g_box_draw:
mov al, [box_row]
mov cl, 4
shl al, cl
xor ah, ah
mov dx, ax
mov [ry0], dx ; top of cell (row*16)
mov dx, ax
add dx, 15
mov [ry1], dx ; bottom of cell (row*16+15)
mov word [rx0], 40 ; picker selection box, kept inside the panel
mov word [rx1], 575
mov dx, [ry0]
call hline
mov dx, [ry0]
inc dx
call hline
mov dx, [ry1]
call hline
mov dx, [ry1]
dec dx
call hline
mov cx, [rx0]
call vline
mov cx, [rx0]
inc cx
call vline
mov cx, [rx1]
call vline
mov cx, [rx1]
dec cx
call vline
ret
; ---- main menu : 10 category tiles in an Easy-Setup icon grid ----
g_draw_main:
mov word [bc_str], t_main
call g_bg ; full page (first time) or content-only repaint
mov word [ri], 0
.n: mov ax, [ri]
cmp ax, NCATS
jae .done
mov bx, [ri]
shl bx, 1
mov si, [cat_tile+bx] ; category icon
mov ax, [ri]
mov [tile_i], ax
mov byte [tile_sel], 0
cmp ax, [gcat]
jne .ns
mov byte [tile_sel], 1
.ns: call g_tile ; SI = icon
mov bx, [ri]
call cat_ptr
mov si, [si] ; category label
call g_tile_label
inc word [ri]
jmp .n
.done:
ret
; ---- sub-menu : the category's items as an icon grid ----
g_draw_sub:
mov bx, [gcat]
call cat_ptr
mov ax, [si]
mov [bc_str], ax ; breadcrumb = category name
mov al, [si+4]
mov [cat_start], al
mov al, [si+5]
mov [cat_count], al
call g_bg ; full page (first time) or content-only repaint
mov word [ri], 0
.n: mov al, [cat_count]
xor ah, ah
mov bx, [ri]
cmp bx, ax
jae .done
mov al, [cat_start]
xor ah, ah
add ax, [ri]
mov [gidx], ax ; global row index (rows[] order)
mov bx, ax
call row_ptr
mov ax, [si]
mov [lbl_tmp], ax
mov bx, [gidx] ; per-item icon = row_icon[gidx]
shl bx, 1
mov si, [row_icon+bx]
mov ax, [ri]
mov [tile_i], ax
mov byte [tile_sel], 0
cmp ax, [gitem]
jne .ns
mov byte [tile_sel], 1
.ns: call g_tile
mov si, [lbl_tmp]
call g_tile_label
inc word [ri]
jmp .n
.done:
ret
; g_draw_pick : a centred Easy-Setup-style dialog window (drop shadow, white body,
; red title bar, red selection bar with white text) listing the option values.
PK_X equ 200
PK_W equ 240
PK_TITLE equ 26 ; title-bar height
PK_ROW equ 20 ; option row height
g_draw_pick:
call g_bg ; keeps the border/title; clears the content area
call opt_count ; CX = number of options
mov [pkd_n], cx
mov ax, cx ; H = PK_TITLE + n*PK_ROW + 10
mov bx, PK_ROW
mul bx
add ax, PK_TITLE + 10
mov [pk_h], ax
mov bx, 216 ; centre vertically in the panel
shr ax, 1
sub bx, ax
mov [pk_y], bx
; drop shadow (navy, offset 8)
mov word [fr_x], PK_X + 8
mov ax, [pk_y]
add ax, 8
mov [fr_y], ax
mov word [fr_w], PK_W
mov ax, [pk_h]
mov [fr_h], ax
mov byte [fr_col], C_NAVY
call g_fillrect
; body (white)
mov word [fr_x], PK_X
mov ax, [pk_y]
mov [fr_y], ax
mov word [fr_w], PK_W
mov ax, [pk_h]
mov [fr_h], ax
mov byte [fr_col], C_WHITE
call g_fillrect
; title bar (red)
mov word [fr_x], PK_X
mov ax, [pk_y]
mov [fr_y], ax
mov word [fr_w], PK_W
mov word [fr_h], PK_TITLE
mov byte [fr_col], C_RED
call g_fillrect
; title text (white, centred in the bar)
mov si, pk_title
call gt_strlen
shl cx, 2
mov ax, PK_X + PK_W/2
sub ax, cx
mov [gt_x], ax
mov ax, [pk_y]
add ax, 5
mov [gt_y], ax
mov byte [g_col], C_WHITE
mov si, pk_title
call gtext
; option rows
mov word [pk_i], 0
.n: mov ax, [pk_i]
cmp ax, [pkd_n]
jae .done
mov bx, PK_ROW ; opt_y = pk_y + PK_TITLE + 4 + i*PK_ROW
mul bx
add ax, [pk_y]
add ax, PK_TITLE + 4
mov [pk_oy], ax
mov ax, [pk_i] ; selected?
cmp ax, [opt_sel]
jne .navy
mov word [fr_x], PK_X + 8 ; red selection bar
mov ax, [pk_oy]
dec ax
mov [fr_y], ax
mov word [fr_w], PK_W - 16
mov word [fr_h], PK_ROW
mov byte [fr_col], C_RED
call g_fillrect
mov byte [g_col], C_WHITE
jmp .txt
.navy: mov byte [g_col], C_NAVY
.txt: call ptr_to_opt ; SI = option #pk_i
push si
call gt_strlen
pop si
shl cx, 2
mov ax, PK_X + PK_W/2 ; centre the value
sub ax, cx
mov [gt_x], ax
mov ax, [pk_oy]
add ax, 2
mov [gt_y], ax
call gtext
inc word [pk_i]
jmp .n
.done: ret
to_text:
push ax
cmp byte [mouse_mode], 2 ; suspend the direct mouse during text actions
jne .t
cli
in al, 0xA1 ; mask IRQ12
or al, 0x10
out 0xA1, al
mov al, 0xA7 ; DISABLE aux device: stop the trackpad clocking
call k_cmd ; (a stuck mouse byte in OBF would block the
call k_flush ; keyboard, so drain it) -> "press any key" works
sti
.t: mov ax, 0x0003
int 0x10
pop ax
ret
to_gfx:
push ax
mov ax, 0x0012
int 0x10
call set_palette
cmp byte [mouse_mode], 2 ; resume the direct mouse
jne .g
cli
mov al, 0xA8 ; re-enable aux device
call k_cmd
call k_flush ; drop bytes queued during the text action
mov byte [mpkt_idx], 0 ; resync packet framing
in al, 0xA1 ; unmask IRQ12
and al, 0xEF
out 0xA1, al
sti
.g: pop ax
mov byte [need_full], 1 ; mode reset cleared the screen -> full repaint next
ret
; ============================================================================
; Mouse (INT 33h) + a custom Easy-Setup arrow cursor drawn by hand so it is
; visible (white body, black outline) on any tile colour.
; ============================================================================
; mouse_init : if an INT 33h driver is present use it (mode 1); otherwise talk to
; the PS/2 trackpad (U75 uPD17137A) directly through the 8042 aux channel (mode 2).
mouse_init:
push es
xor ax, ax
mov es, ax
mov bx, [es:0x33*4] ; INT 33h vector
mov dx, [es:0x33*4+2]
pop es
mov ax, bx
or ax, dx
jz .direct ; no driver -> talk to the trackpad ourselves
xor ax, ax
int 0x33 ; reset; AX=FFFF if installed
cmp ax, 0xFFFF
jne .direct
mov ax, 7 ; x range (leave 16px for the cursor)
xor cx, cx
mov dx, 609
int 0x33
mov ax, 8 ; y range
xor cx, cx
mov dx, 449
int 0x33
mov ax, 4 ; start near the centre