-[bits 16]
-[org 0x7c00]
-
-; Initialize registers
-xor ax, ax
-mov ds, ax
-mov es, ax
-mov bx, 0x8000
-
-call boot
-
-; Print al register
-print_al:
- mov ah, 0x0e ; TTY output
- mov bh, 0x00 ; Page 0
- mov bl, 0x07 ; Color: Light grey on black background
- int 0x10
-
- ret
-
-; Call print_al on all characters in si
-; si must be null terminated
-print_bytes_si:
- mov cl, 0 ; Start with iteration 0 - equivalent of int i = 0
-print_bytes_si_loop:
- lodsb ; Load next characet of si into al
- call print_al
-
- inc cl
-
- cmp cl, ch
- jb print_bytes_si_loop
-
- ret
-
-; APM is not supported
-apm_error:
- mov ch, 9 ; Our string is 9 characters long
- mov si, apm_err
- call print_bytes_si
-
- jmp $ ; Infinite loop
-
-; Check APM support
-apm_chk:
- mov ah, 0x53 ; This is an APM command
- mov al, 0x00 ; APM: Installation Check
- mov bx, 0x0000 ; Device ID (0 is APM BIOS)
- int 0x15 ; Call
-
- jc apm_error ; Carry flag is set if there was an error
-
- cmp ah, 1 ; APM major version must be at least one
- jb apm_error
-
- cmp al, 1 ; APM minor version must be at least one
- jb apm_error
-
- ret
-
-
-; Disconnect from any APM interface
-apm_disco:
- mov ah, 0x53 ; This is an APM command
- mov al, 0x04 ; APM: Disconnect
- mov bx, 0x0000 ; Device ID (0 is APM BIOS)
- int 0x15 ; Call
-
- jc .apm_disco_error ; Carry flag is set if there was an error
- jmp .apm_disco_success
-
-; Disconnecting any APM interface failed
-.apm_disco_error:
- cmp ah, 0x03 ; Error code for no interface connected
- jne apm_error
-
-; No interface are connected now
-.apm_disco_success:
- ret
-
-; Connect to an APM interface
-apm_connect:
- mov ah, 0x53 ; This is an APM command
- mov bx, 0x0000 ; Device ID (0 is APM BIOS)
- int 0x15 ; Call
-
- jc apm_error ; Carry flag is set if there was an error
- ret
-
-; Set the APM Driver Version to 1.1
-apm_drv_init:
- mov ah, 0x53 ; This is an APM command
- mov al, 0x0e ; APM: Set Driver Supported Version
- mov bx, 0x0000 ; Device ID (0 is APM BIOS)
- mov ch, 1 ; APM Driver Major Version Number
- mov cl, 1 ; APM Driver Minor Version Number
- int 0x15 ; Call
-
- jc apm_error ; Carry flag is set if there was an error
- ret
-
-; Enable APM Power Management
-apm_mgmt_on:
- mov ah, 0x53 ; This is an APM command
- mov al, 0x08 ; APM: Change power management state
- mov bx, 0x0001 ; on all devices
- mov cx, 0x0001 ; to on
- int 0x15 ; Call
-
- jc apm_error ; Carry flag is set if there was an error
- ret
-
-; Power down the system
-apm_power_off:
- mov ah, 0x53 ; This is an APM command
- mov al, 0x07 ; APM: Set power state
- mov bx, 0x0001 ; on all devices
- mov cx, 0x0003 ; to off
- int 0x15 ; Call
-
- jc apm_error ; Carry flag is set if there was an error
- ret
-
-; Main
-boot:
- call apm_chk ; Is APM supported?
- call apm_disco ; Disconnect from any APM interface
-
- mov al, 0x01 ; Interface to connect to: Real Mode
- call apm_connect ; Connect to APM interface
-
- call apm_drv_init ; Set the APM Driver Version to 1.1
- call apm_mgmt_on ; Enable Power Management
-
- ; Clear the screen
- mov ah, 0x06
- mov al, 0x00
- mov bh, 0x07
- mov ch, 0x00
- mov cl, 0x00
- mov dh, 0xff
- mov dl, 0xff
- int 0x10
-
- ; Move cursor to 0, 0 on page 0
- mov ah, 0x02
- mov bh, 0 ; Page
- mov dh, 0 ; Row
- mov dl, 0 ; Column
- int 0x10
-
- mov ch, 5 ; Our string is 5 characters long
- mov si, hello
- call print_bytes_si
-
- mov ch, 29 ; Our string is 29 characters long
- mov si, paktc ; paktc: Press any key to continue
- call print_bytes_si
-
- mov ah, 0x00 ; Keyboard: Read key press
- int 0x16 ; Call
-
- call apm_power_off
- jmp $ ; Infinite loop
-
-hello db 'foo', 13, 10 ; \r\n
-apm_err db 'APM Error'
-paktc db 'Press any key to continue... '
-
-times (446 - ($ - $$)) db 0x00