Subversion Repositories aysalia

Rev

Rev 25 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1.  
  2. ; Aysalia DOS Launcher
  3. ; Launches aydos1.gam and aydos2.gam
  4. ; Revision 2018-12-07
  5. ; (C) 2018 Daniel Marschall, ViaThinkSoft
  6.  
  7. .model small
  8. .stack 100h
  9.  
  10. ; -------------------------------------------------------
  11.  
  12. .data
  13.  
  14.     exename1  db "AYDOS1.GAM", 0
  15.     exename2  db "AYDOS2.GAM", 0
  16.     cmdargs   db 0, '', 0Dh
  17.  
  18.     dummy_fcb db 36 dup(0)
  19.  
  20.     paramblk  dw 0          ; use environment of parent
  21.               dw cmdargs    ; command line arguments
  22.               dw 0          ; cmdargs_seg
  23.               dw dummy_fcb  ; fcb1
  24.               dw 0          ; fcb1_seg
  25.               dw dummy_fcb  ; fcb2
  26.               dw 0          ; fcb2_seg
  27.  
  28.     menu1     db 13, 10, \
  29.                  13, 10, \
  30.                  13, 10, \
  31.                  13, 10, \
  32.                  '                            Aysalia DOS', 13, 10, \
  33.                  13, 10, \
  34.                  13, 10, \
  35.                  '              Welches Spiel soll gestartet werden?', 13, 10, \
  36.                  13, 10, \
  37.                  '              Dr', 81h, 'cke eine der folgenden Tasten:', 13, 10, \
  38.                  13, 10, \
  39.                  '              1  Aysalia DOS I', 13, 10, \
  40.                  '              2  Aysalia DOS II', 13, 10, \
  41.                  13, 10, \
  42.                  '              9  Beenden', 13, 10, \
  43.                  13, 10, \
  44.                  13, 10, \
  45.                  13, 10, 0
  46.    
  47.     error1    db 13, 10, \
  48.                  'Fehler: Spiel kann nicht gestartet werden. Fehlt eine Datei?', 13, 10, \
  49.                  13, 10, 0
  50.  
  51.     gameover1 db 13, 10, \
  52.                  'Spiel zu Ende!', 13, 10, \
  53.                  13, 10, 0
  54.  
  55. ; -------------------------------------------------------
  56.  
  57. .code
  58.  
  59. clear_vga PROC
  60.     mov     ax, 0A000h
  61.     mov     es, ax
  62.     xor     di, di
  63.     mov     ax, 0
  64.     mov     cx, 64000
  65.     rep     stosb
  66.     ret
  67. clear_vga ENDP
  68.  
  69. set_screen12 PROC
  70.     mov     ah, 0         ; set screen mode
  71.     mov     al, 12h       ; graphic mode, 640x480 pixel, 16 colors (VGA)
  72.     int     10h
  73.     ret
  74. set_screen12 ENDP
  75.  
  76. setup_paramblk PROC
  77.     mov     ax, cs
  78.     mov     [paramblk +  4], ax   ; cmdargs_seg
  79.     mov     [paramblk +  8], ax   ; fcb1_seg
  80.     mov     [paramblk + 12], ax   ; fcb2_seg
  81.     ret
  82. setup_paramblk ENDP
  83.  
  84. set_numlock_on PROC
  85.     push es
  86.  
  87.     ; In Windows 98+, we cannot access the BIOS Data Area,
  88.     ; so we use this technique to check if we are inside Windows.
  89.     ; This code was taken from http://www.fysnet.net/chkwin.htm
  90.     xor     ax,ax         ; point es:di to 0000:0000h
  91.     mov     es,ax         ;  
  92.     mov     di,ax         ;
  93.     mov     ax,1602h      ; Get API entry point
  94.     int     2Fh           ;   call to multiplex interrupt
  95.     mov     ax,es         ;
  96.     or      ax,ax         ; if es:di doesn't point to 0000:0000h
  97.     jnz     short is_win  ;   then Windows is running a DOS box
  98.     or      di,di         ; else
  99.     jnz     short is_win  ;   we are in True DOS
  100.  
  101.     ; Now the actual code that sets numlock on
  102.     push    ds
  103.     mov     ax, 40h
  104.     mov     ds, ax        ; Go to BIOS Data Area ( http://stanislavs.org/helppc/bios_data_area.html )
  105.     mov     bx, 17h       ; Load Keyboard flag byte 0
  106.     mov     al, [bx]      ; Read
  107.     or      al, 20h       ; Set bit 5 (numlock) to 1
  108.     mov     [bx], al      ; Write
  109.     pop     ds
  110.    
  111. is_win:
  112.     pop es
  113.     ret
  114. set_numlock_on ENDP
  115.  
  116. flush_keyb_buf PROC
  117.     mov     ah, 0Ch       ; Flush input buffer and input
  118.     mov     al, 0
  119.     int     21h
  120.     ret
  121. flush_keyb_buf ENDP
  122.  
  123. exit_to_dos PROC
  124.     mov     ah, 4Ch
  125.     mov     al, 00h
  126.     int     21h
  127.     ret
  128. exit_to_dos ENDP
  129.  
  130. sleep_5 PROC
  131.     mov     ah, 00h
  132.     int     1Ah
  133.     cmp     dx, 7FFFh
  134.     jg      sleep_5_upperhalf
  135. sleep_5_lowerhalf:
  136.     mov     bx, dx
  137.     add     bx, 91        ; 18.2 = 1 sec (therefore 91 = 5 sec)
  138. sleep_5_lowerhalf_again:
  139.     int     1Ah
  140.     cmp     dx, bx
  141.     jl      sleep_5_lowerhalf_again
  142.     ret
  143. sleep_5_upperhalf:
  144.     mov     bx, dx
  145.     sub     bx, 7FFFh
  146.     add     bx, 91        ; 18.2 = 1 sec (therefore 91 = 5 sec)
  147. sleep_5_upperhalf_again:
  148.     int     1Ah
  149.     sub     dx, 7FFFh
  150.     cmp     dx, bx
  151.     jl      sleep_5_upperhalf_again
  152.     ret
  153. sleep_5 ENDP
  154.  
  155. print_color_string PROC
  156.     ; This function requires:
  157.     ; dx = Pointer to zero terminated string
  158.     ; cl = Color
  159.     mov     ah, 0Eh
  160. print_color_string_again:
  161.     mov     bx, dx
  162.     mov     al, [bx]
  163.     test    al, al        ; is the character zero? then we are done
  164.     jz      print_color_string_end
  165.     mov     bl, cl
  166.     int     10h
  167.     add     dx, 1         ; go to next character
  168.     jmp     print_color_string_again
  169. print_color_string_end:
  170.     ret
  171. print_color_string ENDP
  172.  
  173. set_bg_color PROC
  174.     ; This function requires:
  175.     ; bl = Color
  176.     mov     ah, 0Bh
  177.     mov     bh, 00h
  178.     int     10h
  179.     ret
  180. set_bg_color ENDP
  181.  
  182. print_menu_screen PROC
  183.     ; Clear screen
  184.     call    clear_vga
  185.  
  186.     ; Set background color
  187.     mov     bl, 8         ; dark green background
  188.     call    set_bg_color
  189.    
  190.     ; Set text color
  191.     mov     cl, 0Fh       ; white font
  192.     lea     dx, menu1
  193.     call    print_color_string
  194.    
  195.     ret
  196. print_menu_screen ENDP
  197.  
  198. print_error_screen PROC
  199.     ; Clear screen
  200.     call    clear_vga
  201.  
  202.     ; Set background color
  203.     mov     bl, 4         ; dark red background
  204.     call    set_bg_color
  205.    
  206.     ; Set text color
  207.     mov     cl, 0Fh       ; white font
  208.     lea     dx, error1
  209.     call    print_color_string
  210.    
  211.     ret
  212. print_error_screen ENDP
  213.  
  214. print_gameover_message PROC
  215.     ; Keep cursor position
  216.  
  217.     ; Set background color
  218.     mov     bl, 4         ; dark red background
  219.     call    set_bg_color
  220.    
  221.     ; Set text color
  222.     mov     cl, 0Fh       ; white font
  223.     lea     dx, gameover1
  224.     call    print_color_string
  225.    
  226.     ret
  227. print_gameover_message ENDP
  228.  
  229. ; -------------------------------------------------------
  230.  
  231. start:
  232.     ; Setup data segment
  233.     mov     ax, @data     ; moving base address of data to ax
  234.     mov     ds, ax        ; moving contents of ax into ds
  235.                           ; data section now gets initialized                                        
  236.  
  237.     ; Preserve the original screen mode
  238.     mov     ah, 0Fh       ; Query screen mode
  239.     int     10h
  240.     push    ax            ; actually, we are only interested in register al (screen mode), not in ah (column count)
  241.    
  242.     ; Change numlock to ON
  243.     ; DOSBox has a bug where the NumLock is not correctly set to the setting of the host system,
  244.     ; so you have to press the NumLock key twice so that DOSBox recognizes the status.
  245.     ; see: https://sourceforge.net/p/dosbox/bugs/71/
  246.     ;      https://superuser.com/questions/255102/is-there-a-way-to-use-the-numeric-keypad-in-dosbox/1146986
  247.     ; Since the game uses number keys very often, we set NumLock to ON
  248.     call    set_numlock_on
  249.  
  250.     ; Reduce size of own application to give the called applications more space
  251.     ; see https://stackoverflow.com/a/10067627
  252.     mov     ah, 4Ah
  253.     mov     bx, 100       ; 100 paragraphs a 16 bytes = 1600 bytes
  254.     int     21h
  255.  
  256. menu:
  257.     ; Video Mode VGA 12
  258.     call    set_screen12
  259.  
  260.     ; Flush keyboard buffer    
  261.     call    flush_keyb_buf
  262.  
  263.     ; Print menu screen
  264.     call    print_menu_screen
  265.    
  266. retry:
  267.     ; Query keyboard input
  268.     mov     ah, 07h       ; Direct character input, without echo
  269.     int     21h
  270.     cmp     al, '1'
  271.     je      prog1
  272.     cmp     al, '2'
  273.     je      prog2
  274.     cmp     al, '9'
  275.     je      exit
  276.  
  277.     ; Invalid input
  278.     jmp     retry
  279.  
  280. prog1:
  281.     ; Clear screen
  282.     call    clear_vga
  283.  
  284.     ; Setup parameter block for the EXEC command
  285.     call    setup_paramblk
  286.  
  287.     ; Start game 1
  288.     mov     ax, @data     ; ds:dx = ASCIZ program name (must include extension)
  289.     mov     ds, ax
  290.     lea     dx, exename1
  291.     mov     ax, @data     ; es:bx = Parameter block
  292.     mov     es, ax
  293.     mov     bx, paramblk
  294.     mov     ah, 4Bh       ; execute
  295.     mov     al, 00h       ; load and execute
  296.     int     21h           ; DOS API
  297.    
  298.     ; Is everything OK? Or is the GAM file missing?
  299.     jc      error
  300.  
  301.     ; Notify the player that the game has finished
  302.     jmp     gameover
  303.  
  304. prog2:
  305.     ; Clear screen
  306.     call    clear_vga
  307.    
  308.     ; Setup parameter block for the EXEC command
  309.     call    setup_paramblk
  310.  
  311.     ; Start game 2
  312.     mov     ax, @data     ; ds:dx = ASCIZ program name (must include extension)
  313.     mov     ds, ax
  314.     lea     dx, exename2
  315.     mov     ax, @data     ; es:bx = Parameter block
  316.     mov     es, ax
  317.     mov     bx, paramblk
  318.     mov     ah, 4Bh       ; execute
  319.     mov     al, 00h       ; load and execute
  320.     int     21h           ; DOS API
  321.    
  322.     ; Is everything OK? Or is the GAM file missing?
  323.     jc      error
  324.  
  325.     ; Notify the player that the game has finished
  326.     jmp     gameover
  327.    
  328. error:
  329.     ; Video Mode VGA 12
  330.     call    set_screen12
  331.  
  332.     ; Print error
  333.     call    print_error_screen
  334.    
  335.     ; Give the player time to read the error message (approx 5 seconds)
  336.     call    sleep_5
  337.  
  338.     ; Go back to the menu
  339.     jmp     menu
  340.    
  341. gameover:
  342.     ; Print gameover message
  343.     call    print_gameover_message
  344.  
  345.     ; Give the player time to read the game over message (approx 5 seconds)
  346.     call    sleep_5
  347.  
  348.     ; Go back to the menu
  349.     jmp     menu
  350.    
  351. exit:
  352.     ; Reset video mode to DOS default
  353.     pop     ax            ; the video mode we have preserved at program start
  354.     mov     ah, 0         ; set screen mode
  355.     int     10h
  356.  
  357.     ; Return to DOS
  358.     call    exit_to_dos
  359.  
  360. ; -------------------------------------------------------
  361.  
  362. end start