Add externs to avoid multiple definitions, and then add missing definitions.
[rrq/maintain_lilo.git] / src / crt.S
1 ; crt.S
2 ;
3 ;  Copyright 2000-2005 John Coffman
4 ;  Copyright 2009-2011 Joachim Wiedorn
5 ;  All rights reserved.
6 ;
7 ;  Licensed under the terms contained in the file 'COPYING'
8 ;  in the source directory.
9 ;
10
11 XPITCH  =       MAX_IMAGE_NAME+6
12 MINROW  =       4
13 MAX2COL =       14
14 MAXTITLE  =     3
15 MAXCOMMENT  =   3
16
17
18 ; menu_setup:
19 ;   main setup menu for LILO boot selection process
20 ;
21 menu_setup:
22         pusha
23         call    mn_getcursor
24         push    dx              ; save cursor position
25         call    mn_init
26         mov     dx,cx
27
28         cmp     byte [abs_cx+1],#0
29         jne     findl0          ; skip clearing screen on second time thru
30 ; clear the screen
31         xor     cx,cx
32         mov     bh,[mn_at_mono]
33         mov     al,#0
34         call    mn_drawbox
35
36 findl0:
37         xor     si,si           ; number of names
38         xor     di,di           ; max. name length
39         mov     cx,#IMAGES      ; get max number to search
40         mov     bx,#DESCR0      ; get address to start at
41 findl1: call    strlen          ; get length in ax
42         or      ax,ax
43         jz      findl3
44 #ifdef LCF_VIRTUAL
45         test    word ptr (bx+id_flags),#FLAG_VMDEFAULT
46         jz      findl1c
47         call    vmtest
48         jnc     findl1c
49         mov     [vimage],si
50 findl1c:
51 #endif
52 #ifdef LCF_NOKEYBOARD
53         test    word ptr (bx+id_flags),#FLAG_NOKBDEFAULT
54         jz      findl1d
55         call    kbtest
56         jc      findl1d
57         mov     [vimage],si
58 findl1d:
59 #endif
60         cmp     ax,di
61         jb      findl2
62         xchg    ax,di
63 findl2: add     bx,#id_size
64         inc     si
65         loop    findl1
66
67 findl3: mov     [nimage],si
68         mov     [limage],di
69         mov     bx,#str_title   ;
70         call    strlen
71         mov     bl,[mn_max_row_col]
72         sub     bl,al
73         shr     bl,#1
74
75         push    bx
76
77         mov     ax,si
78         mov     bl,#2           ;set for 2 columns
79         cmp     al,#MAX2COL
80         jle     col1
81         inc     bl
82 col1:   mov     [ncol],bl
83         add     al,bl
84         dec     al
85         div     bl
86         cmp     al,#MINROW
87         jg      row1
88         mov     al,#MINROW
89 row1:   cbw
90         mov     [nrow],ax
91 ;;;     add     ax,#4+4+1
92         add     ax,#MAXTITLE+1 +MAXCOMMENT+1 +1
93         mov     dh,al           ; 
94         mov     al,#XPITCH              ; standard width
95         mul     bl
96         mov     dl,al
97         mov     cl,[mn_max_row_col]
98         sub     cl,dl
99         shr     cl,#1
100         mov     ch,#1
101         mov     al,#0x83
102         mov     bh,[mn_at_text]
103         call    mn_drawbox
104         mov     [area_cx],cx
105         mov     [area_dx],dx
106         push    dx
107         add     dx,cx           ; absolute location
108         sub     dx,#0x0306
109         mov     [timer_dx],dx   ; save location of timer
110         pop     dx
111         add     ch,#2           ; title height
112
113         mov     bp,sp
114         xchg    dx,(bp)
115
116         mov     dh,ch
117         mov     bx,#str_title
118         mov     al,[mn_at_title]
119         call    mn_wrstra
120
121         pop     dx
122
123         add     ch,#2
124         mov     al,#1
125         call    mn_hline
126
127         push    cx
128
129         inc     ch
130         add     ch,[nrow]
131         mov     al,#1
132         call    mn_hline
133         mov     dx,cx
134
135         push    dx
136
137         add     dx,#0x102
138         mov     al,[mn_at_text]
139         mov     bx,#str_com1
140         test    byte ptr par2_flag2,#FLAG2_UNATTENDED
141         jz      mn_attended
142         mov     bx,#str_com1u   ; unattended
143 mn_attended:
144         call    mn_wrstra
145         inc     dh
146         mov     bx,#str_com2
147         call    mn_wrstra
148         inc     dh
149         mov     bx,#str_com3
150         call    mn_wrstra
151         mov     dx,[timer_dx]
152         mov     bx,#str_timer
153         call    mn_wrstra
154
155         pop     dx
156         pop     cx
157
158         sub     dh,ch
159         mov     ah,[ncol]
160         mov     si,#DESCR0      ; get start pointer
161         mov     di,[nimage]
162         mov     [norigin],cx
163 vlines:
164         add     cl,#3
165         mov     al,#1
166         call    mn_vline
167
168         push    cx
169         push    dx
170
171         mov     dx,cx
172         add     dx,#0x102
173         mov     cx,[nrow]
174         cmp     cx,di
175         jb      vl1
176         mov     cx,di
177 vl1:    jcxz    vl3
178 vl2:    mov     bx,si
179         mov     al,[mn_at_text]
180         call    mn_wrstra
181
182         push    ax
183         push    dx
184         sub     dl,#4
185         mov     ah,al
186         test    word [id_flags](si),#FLAG_TOOBIG        ; test for unbootable
187         mov     al,#0x55                ; 'U' for possibly unbootable
188         jnz     vl20
189         mov     al,#0x46                ; 'F' for fallback
190         test    byte [id_flags](si),#FLAG_FALLBACK
191         jnz     vl20
192         mov     al,#0x4C                ; 'L' for lock
193         test    byte [id_flags](si),#FLAG_LOCK
194 #ifdef LCF_VIRTUAL
195         jnz     vl20
196         mov     al,#0x57                ; 'W' for vmWarn
197         test    word [id_flags](si),#FLAG_VMWARN
198 #endif
199         jz      vl21
200 vl20:   call    mn_wrcha
201 vl21:   
202         inc     dl
203         test    byte [id_flags](si),#FLAG_PASSWORD      ; test for password
204         jz      vl23
205         mov     al,#0x50                ; 'P' for password
206         test    byte [id_flags](si),#FLAG_RESTR
207         jz      vl22
208         mov     al,#0x52                ; 'R' for restricted options
209 vl22:   call    mn_wrcha
210 vl23:   pop     dx
211         pop     ax
212
213         inc     dh
214         dec     di
215         add     si,#id_size
216         loop    vl2
217 vl3:
218         pop     dx
219         pop     cx
220
221         add     cl,#XPITCH-3
222         dec     ah
223         jz      vdone
224         mov     al,#2
225         call    mn_vline
226         jmp     vlines
227 vdone:
228         mov     ax,[dimage]             ; usually zero
229 #if defined(LCF_VIRTUAL) || defined(LCF_NOKEYBOARD)
230         test    byte ptr [cmdline],#0xFF
231         jnz     vdone3
232         mov     ax,[vimage]
233 vdone3:
234 #endif
235         call    hilite
236
237         pop     dx                      ; get saved cursor position
238         cmp     byte [abs_cx+1],#0
239         jne     nohome
240
241         mov     dx,[area_cx]
242         add     dx,[area_dx]
243         xor     dl,dl
244         add     dh,#2
245         mov     [abs_cx],dx             ; set home cursor position
246 nohome: 
247         call    mn_setcursor
248
249         popa
250         ret
251 ; end of menu_setup subroutine
252
253 #if 0
254 ; find_image
255 ;       if there is something on the command line
256 ;       return the image number it selects
257 ;
258 ;       enter with:
259 ;               nothing
260 ;       exit with:
261 ;               If nothing selected:
262 ;                   Carry Clear
263 ;                   AX==0
264 ;               If an image is selected:
265 ;                   Carry SET
266 ;                   AX==#image
267 ;                   BX==pointer to descriptor
268 ;                   
269 ;
270 ;       side effect:
271 ;               The selected image is hi-lited if the menu is displayed
272 ;
273 find_image:
274         push    cx
275         push    si
276         push    di
277         
278         mov     cx,#IMAGES      ! test all names
279         mov     si,#DESCR0
280         push    si
281 fi_nextn:
282         mov     di,#cmdline
283 fi_nextc:
284         mov     al,(si)         ! get next character in descr
285                                 ! get the character
286 #ifdef LCF_IGNORECASE
287         call    upcase
288 #endif
289         mov     ah,al
290         mov     al,(di)         ! get next char in cmdline
291 #ifdef LCF_IGNORECASE
292         call    upcase
293 #endif
294         or      ah,ah           ! NUL in descriptor name
295         jz      fi_dscend
296         cmp     al,ah           ! character equal ?
297         jne     fi_skipn                ! no -> try next one
298         inc     si              ! test next character
299         inc     di
300         jmp     fi_nextc
301 fi_dscend:      
302         cmp     al,#32          ! space or NUL -> equal
303         je      fi_found
304         or      al,al
305         jz      fi_found
306
307 fi_skipn:
308         pop     si
309         add     si,#id_size     ! test next name
310         push    si
311         loop    fi_nextn
312
313         pop     si
314         xor     ax,ax           ; clears the carry
315 fi_exit:
316         pop     di
317         pop     si
318         pop     cx
319         ret
320         
321 fi_found:
322         pop     bx              ! BX is matched descriptor
323         mov     ax,bx
324         sub     ax,#DESCR0
325         mov     cl,#id_size
326         div     cl
327         cbw
328         mov     di,[dimage]
329         cmp     ax,di
330         je      fi_nochange
331         mov     [dimage],ax
332         cmp     byte [abs_cx+1],#0      ! see if menu is displayed
333         je      fi_nochange
334         xchg    ax,di
335         call    lowlite
336         xchg    ax,di
337         call    hilite
338 fi_nochange:
339         stc
340         jmp     fi_exit
341 #endif
342
343 ; menu_delline:
344 ;       delete the current command line
345 ;                               common code from original second.S
346 ;
347 ;       enter with:
348 ;               BX = command line pointer
349 ;
350 ;       exit with:
351 ;               BX = updated command line pointer
352 ;
353 ;
354 menu_delline:
355         cmp     bx,#cmdline     ! done ?
356         je      mdel9           ! yes -> done
357         push    bx              ! display BS,SPC,BS
358         mov     bx,#bs
359         call    say
360         pop     bx
361         dec     bx              ! move the pointer
362         jmp     menu_delline            ! next one
363 mdel9:  ret
364
365
366 ; menu_setcmd:
367 ;       set currently selected image to be the command line
368 ;
369 ;       enter with:
370 ;               AX = image# to select
371 ;               BX = cmdline pointer
372 ;
373 ;       exit with:
374 ;               BX = updated
375 ;
376 ;
377 menu_setcmd:
378         push    si
379
380         push    ax
381
382         call    menu_delline    ; delete the current line
383
384         pop     si              ; get image# back
385
386         imul    si,#id_size
387         add     si,#DESCR0
388 mset1:  lodsb
389         or      al,al
390         jz      mset6
391         mov     (bx),al
392         inc     bx
393         push    bx
394         call    display
395         pop     bx
396         jmp     mset1
397         
398 mset6:
399         pop     si      
400         ret
401
402
403 ; arrow
404 ;
405 ;   Code that handles the arrow keys:  left, up, down, right
406 ;
407 ;
408 arrow:  cbw                     ; signed delta vector in AL
409         mov     dx,[dimage]     ;
410         add     dx,ax           ; new position
411         or      dx,dx
412         jns     arr1
413 arr0:   xor     dx,dx           ; set to zero if neg.
414 arr1:   mov     ax,[nimage]
415         cmp     dx,ax           ; compare to max.
416         jb      arr2
417         mov     dx,ax
418         dec     dx
419 arr2:                   ; we know the one to hi-lite is in range
420         mov     ax,[dimage]
421         cmp     ax,dx
422         je      arr6
423
424         call    lowlite         ; un-hilite the old
425         xchg    ax,dx
426         call    hilite
427
428         call    menu_setcmd     ; set new command line
429 arr6:
430         jmp     arr_vector
431
432         
433 null:   mov     al,#1
434         cmp     ah,#0x50                ; down arrow
435         je      arrow
436
437         neg     al
438         cmp     ah,#0x48                ; up arrow
439         je      arrow
440
441         mov     dx,[nimage]
442         cmp     ah,#0x4f                ; end
443         je      arr1
444
445         cmp     ah,#0x47                ; home
446         je      arr0
447
448         mov     al,[nrow]
449         xchg    ax,dx
450         mov     ax,[dimage]
451         div     dl                      
452         xchg    ax,dx                   ; DL = cur col.
453
454         cmp     ah,#0x4d                ; right arrow
455         jne     arr8
456         inc     dx                      ; similar to  dec al
457         cmp     dl,[ncol]               ; cmp (CUR COL + 1) : (NCOL)
458         jb      arrow
459         jmp     arr9
460         
461 arr8:
462         cmp     ah,#0x49                ; pg up
463         jne     arr84
464         neg     dh                      ; remainder [0..(nrow-1)]
465         mov     al,dh
466 arrow1: jmp     arrow
467
468 arr84:
469         cmp     ah,#0x51                ; pg dn
470         jne     arr88
471         not     dh
472         add     al,dh
473         jmp     arrow
474
475 arr88:
476         neg     al
477         cmp     ah,#0x4b                ; left arrow
478         jne     arr9
479         or      dl,dl
480         jnz     arrow1
481
482 arr9:
483         cmp     ah,#0x53                ; DEL
484         jne     arr_vector
485         br      delch                   ; treat as 0177 (rubout)
486
487 arr_vector:
488         br      input           ; ignore the rest
489
490 ; menu_exit:
491 ;       erase the menu box to black
492 ;
493 menu_exit:
494         pusha
495         mov     cx,[area_cx]
496         mov     dx,[area_dx]
497         mov     al,#0x80
498         mov     bh,[mn_at_mono]
499         call    mn_drawbox
500         popa
501         ret
502
503 ; menu_form_feed:
504 ;       simulate a FF on the console
505 ;
506 menu_form_feed:
507         pusha
508 ;;      push    ds
509 ;;      push    cs
510 ;;      pop     ds
511         mov     cx,[abs_cx]     ! get home position
512         mov     dx,[mn_max_row_col]
513         xor     al,al
514         mov     bh,#0x07
515         call    mn_drawbox
516         mov     dx,cx
517         call    mn_setcursor
518 ;;      pop     ds
519         popa
520         ret
521
522 ; timer_display:
523 ;       check the timer 'cntdown' and display changes
524 ;
525 timer_display:
526         pusha
527
528         cmp     word [timer_dx],#0      ; see if not initialized
529         jz      timer99
530
531         mov     dx,#0x2d2d      ; get "--" means disabled
532         mov     [tim_min],dx
533         mov     [tim_sec],dx
534         mov     ax,[cntdown]    ; get timer countdown location
535         cmp     ax,[tim_tick]
536         je      timer99
537         mov     [tim_tick],ax   ; save last tick count  
538         inc     ax
539         jz      timer8
540
541         mul     c55             ; get time remaining in ms.
542         div     c1000           ; convert to seconds
543         xor     dx,dx
544         div     c60             ; minutes in AX, seconds in DX  
545         aam
546         add     ax,#0x3030
547         xchg    ah,al
548         mov     [tim_min],ax    ; put characters in buffer
549         xchg    ax,dx
550         aam
551         add     ax,#0x3030
552         xchg    ah,al
553         mov     [tim_sec],ax    ; put characters in buffer
554
555 timer8:
556         call    mn_getcursor
557         push    dx
558         mov     dx,[timer_dx]
559         mov     ah,[mn_at_text]
560         mov     si,#tim_min
561         mov     bx,#tim_old
562         mov     cx,#5
563 timer91:
564         lodsb
565         cmp     al,(bx)
566         je      timer92
567         call    mn_wrcha
568         mov     (bx),al
569 timer92:
570         inc     bx
571         inc     dl
572         loop    timer91
573         pop     dx
574         call    mn_setcursor
575 timer99:
576         popa
577         ret
578
579 tim_min: db     0,0
580         .ascii  ":"
581 tim_sec: db     0,0
582
583 tim_old: .ascii "*****"
584 tim_tick: dw    0               ; last timer tick value examined
585
586 c55:    .word   2197            ;was 55, now 54.925*40
587 c1000:  .word   40000           ;was 1000, now 40*1000
588 c60:    .word   60
589
590
591 ; hilite/lowlite
592 ;       enter with:
593 ;               AX = number [0..(nimage-1)] of entry to hilite
594 ;
595 hilite: push    bx
596         mov     [dimage],ax             ; remember the latest
597         mov     bh,[mn_at_hilite]
598         jmp     lowlite1
599
600 lowlite:  push  bx
601         mov     bh,[mn_at_text]
602 lowlite1:
603         push    cx
604         push    dx
605         push    ax
606
607         call    mn_getcursor
608         push    dx                      ;save current cursor position
609
610         mov     dx,[norigin]
611         add     dx,#0x104
612         mov     cx,[limage]
613         inc     cx
614         inc     cx
615
616         push    bx
617         mov     bx,[nrow]
618 ll1:    cmp     ax,bx
619         jb      ll2
620         add     dl,#XPITCH              ; index by column
621         sub     ax,bx
622         jmp     ll1
623 ll2:    add     dh,al
624         pop     bx              ; restore attribute in BH
625
626 ll3:    call    mn_rdcha        ; read char and attribute
627         mov     ah,bh
628         call    mn_wrcha        ; write back with new attribute
629         inc     dl
630         loop    ll3
631
632         pop     dx              ; restore cursor
633         call    mn_setcursor
634
635         pop     ax
636         pop     dx
637         pop     cx
638         pop     bx
639         ret
640
641
642 ; title_stuff
643 ;
644 ;
645 title_stuff:
646         cmp     dword (bx),#0x554e454d  ; "MENU"
647         jne     noschema
648         mov     edx,(bx+4)
649         mov     [mn_attrib],edx
650 noschema:
651         add     bx,#9           ; point at possible title
652         mov     al,(bx-1)       ; get length stored by installer
653         or      al,al
654         jz      notitle         ; no title if supplied length is 0
655         cbw
656         xchg    ax,cx           ; supplied length to CX
657         call    strlen
658         cmp     ax,cx
659         jne     notitle
660         cmp     ax,#str_title_len
661         jae     notitle
662         push    di
663         mov     di,#str_title   ;
664 titlemov:
665         mov     al,(bx)
666         inc     bx
667         seg ds
668           stosb
669         or      al,al
670         jnz     titlemov
671
672         pop     di
673 notitle:
674         ret
675
676
677 dimage: dw      0       ; default image
678 #if defined(LCF_VIRTUAL) || defined(LCF_NOKEYBOARD)
679 vimage: dw      0       ; vmdefault image
680 #endif
681 norigin: dw     0       ; row/col origin of names on screen
682 nimage: dw      0       ; number of images
683 limage: dw      0       ; longest length of image name
684 nrow:   dw      0       ; number of rows of selections
685 ncol:   dw      0       ; number of columns (default=2)
686 ;wcol:  db      0       ; width of each column (default=XPITCH=21)
687 area_cx:  dw    0       ; area of interaction
688 area_dx:  dw    0       ; area of interaction
689 abs_cx: dw      0       ; upper left of scrolling area
690 ;abs_dx:        dw      0       ; lower right of scrolling area
691 ;       mn_max_row_col is the same as the above (abs_dx)
692 timer_dx: dw    0       ; timer location
693
694
695 str_title:
696         .ascii  "GNU/Linux - "
697         .ascii  "LILO "
698 #ifdef LCF_VERSION
699         .ascii  SA(VERSION_MAJOR)
700         .ascii  " - "   
701 #endif
702         .ascii  "Boot Menu"
703         .byte   0
704         .org    str_title+MAX_MENU_TITLE+1
705
706 str_timer:
707         .ascii  "--:--"
708         db      0
709
710 str_title_len   = str_timer-str_title-1
711
712 str_com1:
713         .ascii  "Hit any key to cancel timeout"
714 ;               "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 00:00"
715         db      0
716 str_com1u:
717         .ascii  "Hit any key to restart timeout"
718         db      0
719
720 str_com2:
721         .ascii  "Use "
722         db      27              ; left-arrow
723         db      24,25           ; up-arrow, down-arrow
724         db      26              ; right-arrow
725         .ascii  " arrow keys to make selection"
726         db      0
727 str_com3:
728         .ascii  "Enter choice & options, hit CR to boot"
729         db      0
730
731 ; end of crt.S