@@com_done:
mov ax, di ; Get serial interface count
or [ds:11h], al ; equipment flag
mov cx, 100 ; Check for game port 100 times
mov dx, 201h
@@check_game:
in al, dx ; Anything there?
cmp al, 0FFh
jne @@found_game ; Yep, game port is present
dec cx ; Otherwise keep polling
jcxz @@game_done ; Countdown is zero; no game port
jmp @@check_game
@@found_game:
or [byte ds:11h], 00010000b ; Set flag in equipment word
@@game_done:
call fpu_check ; check for FPU
mov dx, 0C000h ; ROM segment start
mov bx, [ds:72h] ; Save warm boot flag
push bx ; (Some ROM inits may trash it)
push ds
ifdef TURBO_BOOT ; if defined enable turbo speed at bootup
in al, 61h ; Read equipment flags
xor al, 00001100b ; toggle speed
out 61h, al ; Write new flags back
endif
@@find_rom:
mov ds, dx ; Load ROM segment
xor bx, bx ; ID offset
mov ax, [bx] ; Read the ROM ID
cmp ax, 0AA55h
jnz @@next_rom ; not valid ROM
mov ax, 40h
mov es, ax
mov ah, 0
mov al, [bx+2] ; Get ROM size (bytes * 512)
mov cl, 5
shl ax, cl ; Now ROM size in segments
add dx, ax ; add base segment
mov cl, 4
shl ax, cl ; ROM address in bytes
mov cx, ax ; checksum requires cx
call checksum_entry ; Find ROM checksum
jnz @@bad_rom ; bad ROM
push dx
mov [word es:67h], 3 ; Offset for ROM being setup
mov [es:69h], ds ; Segment for ROM being setup
call [dword es:67h] ; call ROM initialization
pop dx
jmp short @@continue_rom
@@bad_rom:
or [byte es:15h], error_rom ; ROM present, bad checksum
@@next_rom:
add dx, 80h ; Segment for next ROM
@@continue_rom:
cmp dx, 0F600h ; End of ROM space?
jl @@find_rom ; no, continue
pop ds
pop bx
mov [ds:72h], bx ; Restore warm boot flag
in al, 21h ; Read 8259 interrupt mask
and al, 10111100b ; enable IRQ (0, 1, 6) ints
out 21h, al ; (tod_clock, key, floppy_disk)
mov ax, 40h ; Test for EGA/VGA
mov es, ax
mov ah, 12h
mov bx, 0FF10h
int 10h ; Video Get EGA Info
cmp bh, 0FFh ; If EGA or later present BH != FFh
je @@not_ega
and [byte es:10h], 11001111b ; Set video flag in equipment list to EGA/VGA
@@not_ega:
push es
call video_mem_test ; Do video memory test
pop es
mov ah, 1
mov ch, 0F0h
int 10h ; Set cursor type
call clear_screen ; clear display
push cs
pop ds
test [byte es:10h], 1 ; Floppy disk present?
jz @@skip_config ; no
cmp [word es:72h], 1234h ; Bios setup before?
jne @@config ; no
@@skip_config:
jmp @@reset ; Else skip memory check
@@config:
mov si, offset str_banner
call color_print
mov si, offset str_banner_2
call print
test [byte es:15h], 11111111b ; Any errors so far?
jz @@no_errors ; no, skip
mov ax, 0300h
print_error:
call locate
mov si, offset str_error
call print ; Print string
mov al, [es:15h] ; get error number
call number ; print hex value
call print ; print prompt
mov bl, 2 ; long beep
call beep
call get_key ; Wait for keypress
push ax ; save answer
call out_char ; echo answer
pop ax ; get answer
cmp al, 'Y' ; Was it "Y"?
jz @@no_errors ; ok, continue
cmp al, 'y' ; Was it "y"?
jz @@no_errors ; ok, continue
jmpf 0F000h, cold_boot ; Else cold reset
@@no_errors:
mov ax, 0300h ; Where to move cursor
call locate ; Position cursor
call display_cpu ; Display CPU type
mov si, offset str_mono ; Assume mono video
mov ax, 0407h
call locate
mov al, [es:49h] ; Get CRT mode
cmp al, 7 ; Is it mono?
jz @@display_video ; Yes
mov al, [es:10h] ; Check equipment word
and al, 00110000b ; Is it EGA/VGA?
jnz @@is_cga ; No, we have CGA
mov si, offset str_ega_vga ; Otherwise we have EGA/VGA
jmp short @@display_video
@@is_cga:
mov si, offset str_cga
@@display_video:
call print ; Print video adapter present
mov bx, 0507h
mov al, [es:11h] ; Get equipment byte
push ax
mov cl, 6
ror al, cl
and al, 3 ; Number of LPT ports
jz @@display_com_ports ; Skip if none
mov bp, 8
mov si, offset str_parallel
call formatted_ascii_output ; Formatted ASCII output
@@display_com_ports:
pop ax
push ax
mov si, offset str_serial
ror al, 1 ; Check for COM ports
and al, 3
jz @@display_game_port ; Skip if none
xor bp, bp
call formatted_ascii_output ; Formatted ASCII output
@@display_game_port:
pop ax ; Equipment byte restore
mov si, offset str_game
test al, 00010000b ; Check for game port
jz @@display_timer ; Skip if none
mov ax, bx
call locate ; Position cursor
call print ; and print string
inc bh ; scroll line
@@display_timer:
call timer_check ; Check for timer device
jb @@finish_device_list ; Skip if none
mov ax, bx
call locate ; Position cursor
inc bh
mov si, offset str_timer
call print
@@finish_device_list:
dec bh
mov bl, 7
call fix_last_line_char
inc bh
inc bh
xor bl, bl
mov ax, bx ; Where to position cursor
call locate ; position cursor
mov si, offset str_ram_test ; Memory size string
call print ; print string
push es
mov bp, [es:13h] ; Memory size (1 K blocks)
dec bp
dec bp
mov si, 2
mov dx, si
mov ax, 80h
mov es, ax
add bl, 0Dh
push bx
@@mem_count:
pop ax ; Cursory check of memory
push ax
mov cx, es
cmp bp, 1 ; Always show final memory size
je @@last_time
test cx, 0000000111111111b ; Only print memoy size every 8K
jz @@show_mem_size
xor ch, ch ; If ch is cleared memory size isn't printed
@@show_mem_size:
dec dx
@@last_time:
call locate ; Position cursor
call print_mem_kb ; Print size in K
inc dx
call mem_test ; Memory check es:0 - es:0400
jb @@bad_ram ; bad RAM found (How ???)
dec bp
jnz @@mem_count
pop bx
pop es
call boot_basic ; Boot BASIC if space pressed
@@reset:
mov bl, 1 ; Do a warm boot
call beep ; short beep
call clear_screen ; clear display
mov ax, 40h
mov es, ax
mov [word es:72h], 1234h ; Show cold start done
mov ah, 1
mov cx, 0B0Ch ; Set underline cursor mono
cmp [byte es:49h], 7 ; Get CRT mode
jz @@is_mono ; monochrome
mov cx, 607h ; Set underline cursor color
@@is_mono:
int 10h ; Set the correct cursor shape
int 19h ; Boot the machine