Subversion Repositories aysalia

Rev

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

Rev Author Line No. Line
9 daniel-mar 1
 
2
; Aysalia DOS Launcher
3
; Launches aydos1.gam and aydos2.gam
22 daniel-mar 4
; Revision 2018-12-07
9 daniel-mar 5
; (C) 2018 Daniel Marschall, ViaThinkSoft
6
 
7
.model small
27 daniel-mar 8
.stack 100h
11 daniel-mar 9
 
10
; -------------------------------------------------------
11
 
9 daniel-mar 12
.data
13
 
22 daniel-mar 14
    exename1  db "AYDOS1.GAM", 0
15
    exename2  db "AYDOS2.GAM", 0
16
    cmdargs   db 0, '', 0Dh
9 daniel-mar 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
 
22 daniel-mar 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
17 daniel-mar 46
 
22 daniel-mar 47
    error1    db 13, 10, \
48
                 'Fehler: Spiel kann nicht gestartet werden. Fehlt eine Datei?', 13, 10, \
49
                 13, 10, 0
9 daniel-mar 50
 
22 daniel-mar 51
    gameover1 db 13, 10, \
52
                 'Spiel zu Ende!', 13, 10, \
53
                 13, 10, 0
9 daniel-mar 54
 
11 daniel-mar 55
; -------------------------------------------------------
56
 
9 daniel-mar 57
.code
58
 
59
clear_vga PROC
22 daniel-mar 60
    mov     ax, 0A000h
9 daniel-mar 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
 
11 daniel-mar 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
 
9 daniel-mar 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
 
11 daniel-mar 84
set_numlock_on PROC
27 daniel-mar 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
11 daniel-mar 102
    push    ds
103
    mov     ax, 40h
22 daniel-mar 104
    mov     ds, ax        ; Go to BIOS Data Area ( http://stanislavs.org/helppc/bios_data_area.html )
11 daniel-mar 105
    mov     bx, 17h       ; Load Keyboard flag byte 0
22 daniel-mar 106
    mov     al, [bx]      ; Read
107
    or      al, 20h       ; Set bit 5 (numlock) to 1
108
    mov     [bx], al      ; Write
11 daniel-mar 109
    pop     ds
27 daniel-mar 110
 
111
is_win:
112
    pop es
11 daniel-mar 113
    ret
114
set_numlock_on ENDP
9 daniel-mar 115
 
11 daniel-mar 116
flush_keyb_buf PROC
117
    mov     ah, 0Ch       ; Flush input buffer and input 
118
    mov     al, 0
9 daniel-mar 119
    int     21h
11 daniel-mar 120
    ret
121
flush_keyb_buf ENDP
9 daniel-mar 122
 
11 daniel-mar 123
exit_to_dos PROC
22 daniel-mar 124
    mov     ah, 4Ch
11 daniel-mar 125
    mov     al, 00h
126
    int     21h
127
    ret
128
exit_to_dos ENDP
9 daniel-mar 129
 
11 daniel-mar 130
sleep_5 PROC
21 daniel-mar 131
    mov     ah, 00h
17 daniel-mar 132
    int     1Ah
21 daniel-mar 133
    cmp     dx, 7FFFh
22 daniel-mar 134
    jg      sleep_5_upperhalf
135
sleep_5_lowerhalf:
21 daniel-mar 136
    mov     bx, dx
22 daniel-mar 137
    add     bx, 91        ; 18.2 = 1 sec (therefore 91 = 5 sec)
138
sleep_5_lowerhalf_again:
21 daniel-mar 139
    int     1Ah
17 daniel-mar 140
    cmp     dx, bx
22 daniel-mar 141
    jl      sleep_5_lowerhalf_again
11 daniel-mar 142
    ret
22 daniel-mar 143
sleep_5_upperhalf:
21 daniel-mar 144
    mov     bx, dx
145
    sub     bx, 7FFFh
22 daniel-mar 146
    add     bx, 91        ; 18.2 = 1 sec (therefore 91 = 5 sec)
147
sleep_5_upperhalf_again:
21 daniel-mar 148
    int     1Ah
149
    sub     dx, 7FFFh
150
    cmp     dx, bx
22 daniel-mar 151
    jl      sleep_5_upperhalf_again
21 daniel-mar 152
    ret
11 daniel-mar 153
sleep_5 ENDP
9 daniel-mar 154
 
22 daniel-mar 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
25 daniel-mar 162
    mov     al, [bx]
27 daniel-mar 163
    test    al, al        ; is the character zero? then we are done
164
    jz      print_color_string_end
22 daniel-mar 165
    mov     bl, cl
166
    int     10h
25 daniel-mar 167
    add     dx, 1         ; go to next character
22 daniel-mar 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
21 daniel-mar 176
    mov     ah, 0Bh
177
    mov     bh, 00h
178
    int     10h
22 daniel-mar 179
    ret
180
set_bg_color ENDP
21 daniel-mar 181
 
22 daniel-mar 182
print_menu_screen PROC
23 daniel-mar 183
    ; Clear screen
184
    call    clear_vga
22 daniel-mar 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
9 daniel-mar 192
    lea     dx, menu1
22 daniel-mar 193
    call    print_color_string
194
 
11 daniel-mar 195
    ret
196
print_menu_screen ENDP
197
 
17 daniel-mar 198
print_error_screen PROC
23 daniel-mar 199
    ; Clear screen
200
    call    clear_vga
21 daniel-mar 201
 
22 daniel-mar 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
17 daniel-mar 208
    lea     dx, error1
22 daniel-mar 209
    call    print_color_string
210
 
17 daniel-mar 211
    ret
212
print_error_screen ENDP
213
 
23 daniel-mar 214
print_gameover_message PROC
22 daniel-mar 215
    ; Keep cursor position
21 daniel-mar 216
 
22 daniel-mar 217
    ; Set background color
27 daniel-mar 218
    mov     bl, 4         ; dark red background
22 daniel-mar 219
    call    set_bg_color
220
 
221
    ; Set text color
27 daniel-mar 222
    mov     cl, 0Fh       ; white font
11 daniel-mar 223
    lea     dx, gameover1
22 daniel-mar 224
    call    print_color_string
225
 
11 daniel-mar 226
    ret
23 daniel-mar 227
print_gameover_message ENDP
11 daniel-mar 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)
9 daniel-mar 241
 
11 daniel-mar 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
14 daniel-mar 253
    mov     bx, 100       ; 100 paragraphs a 16 bytes = 1600 bytes
11 daniel-mar 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
 
9 daniel-mar 266
retry:
267
    ; Query keyboard input
11 daniel-mar 268
    mov     ah, 07h       ; Direct character input, without echo
9 daniel-mar 269
    int     21h
270
    cmp     al, '1'
271
    je      prog1
272
    cmp     al, '2'
273
    je      prog2
274
    cmp     al, '9'
11 daniel-mar 275
    je      exit
9 daniel-mar 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
27 daniel-mar 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
9 daniel-mar 293
    mov     bx, paramblk
27 daniel-mar 294
    mov     ah, 4Bh       ; execute
295
    mov     al, 00h       ; load and execute
296
    int     21h           ; DOS API
9 daniel-mar 297
 
17 daniel-mar 298
    ; Is everything OK? Or is the GAM file missing?
299
    jc      error
300
 
11 daniel-mar 301
    ; Notify the player that the game has finished
9 daniel-mar 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
27 daniel-mar 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
9 daniel-mar 317
    mov     bx, paramblk
27 daniel-mar 318
    mov     ah, 4Bh       ; execute
319
    mov     al, 00h       ; load and execute
320
    int     21h           ; DOS API
17 daniel-mar 321
 
322
    ; Is everything OK? Or is the GAM file missing?
323
    jc      error
9 daniel-mar 324
 
11 daniel-mar 325
    ; Notify the player that the game has finished
9 daniel-mar 326
    jmp     gameover
11 daniel-mar 327
 
17 daniel-mar 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
 
9 daniel-mar 341
gameover:
23 daniel-mar 342
    ; Print gameover message
343
    call    print_gameover_message
9 daniel-mar 344
 
11 daniel-mar 345
    ; Give the player time to read the game over message (approx 5 seconds)
346
    call    sleep_5
9 daniel-mar 347
 
11 daniel-mar 348
    ; Go back to the menu
9 daniel-mar 349
    jmp     menu
350
 
11 daniel-mar 351
exit:
9 daniel-mar 352
    ; Reset video mode to DOS default
11 daniel-mar 353
    pop     ax            ; the video mode we have preserved at program start
354
    mov     ah, 0         ; set screen mode
9 daniel-mar 355
    int     10h
356
 
357
    ; Return to DOS
11 daniel-mar 358
    call    exit_to_dos
9 daniel-mar 359
 
11 daniel-mar 360
; -------------------------------------------------------
361
 
9 daniel-mar 362
end start