📄 bios.asm
字号:
MOV SI,offset STUF_8
CALL PRINT
NO_TIM: POP AX
MOV SI,offset STUF_6
ROR AL,1 ; Check for COM port
AND AL,3
JZ NO_COM ; ...skip if no com
XOR BP,BP
CALL FAO ; Formatted ascii output
NO_COM: MOV AX,121Ch ; Where to position cursor
CALL LOCATE ; ...position cursor
MOV SI,offset STUF_7 ; 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
CUTE: MOV AX,122Bh ; Cursory check of memory
CALL LOCATE ; ...position cursor
CALL K_BYTE ; ...print size in K
CALL MEMTST ; Memory check ES:0 - ES:0400
JB BADRAM ; ...bad RAM found (How ???)
DEC BP
JNZ CUTE
POP ES
RESET: MOV BL,2 ; Do a warm boot
CALL BEEP ; ...short beep
CALL BLANK ; ...clear display
MOV Word ptr ES:72h,1234h ; Show cold start done
MOV AH,1
MOV CX,607h ; Set underline cursor
INT 10h
MOV SI,offset BANNER ; Load banner address
CALL PRINT ; ...and print string
INT 19h ; Boot the machine
BADRAM: POP ES
OR Byte ptr ES:15h,ER_RAM ; Show "Bad Ram" error
JMP CONFIG
STUF db ' Generic Turbo XT Bios 1987',0
STUF_1 db CR,LF,0,'System error #',0,', Continue?',0
STUF_2 db ' ',0,'Interface card list',0,'Monochrome',0
STUF_3 db 'Color/Graphics',0
STUF_4 db 'Printer #',0
STUF_5 db 'Game controller',0
STUF_6 db 'Async. commu. #',0
STUF_7 db 'RAM Testing .. 000 KB',0
STUF_8 db 'Timer',0
ENTRY 0E600h ; Not necessary to IPL here..
IPL: STI ; Called to reboot computer
XOR AX,AX
MOV DS,AX
MOV Word ptr DS:78h,offset INT_1E ; Get disk parameter table
MOV DS:7Ah,CS ; ...save segment
MOV AX,4 ; Try up to four times
RETRY: PUSH AX ; Save retry count
MOV AH,0 ; ...reset
INT 13h ; ...floppy
JB FAILED
MOV AL,1 ; One sector
MOV AH,2 ; ...read
XOR DX,DX ; ...from drive 0, head 0
MOV ES,DX ; ...segment 0
MOV BX,7C00h ; ...offset 7C00
MOV CL,1 ; ...sector 1
MOV CH,0 ; ...track 0
INT 13h ; ...floppy
JB FAILED
JMPF 0000h,7C00h ; Call the boot block
;
FAILED: POP AX ; Get retries
DEC AL ; ...one less
JNZ RETRY
NODISK: OR AH,AH ; Disk present?
JNZ DERROR ; ...yes
CALL BLANK ; Clear display
PUSH CS
POP DS
MOV SI,offset DSKMSG ; Load disk message
CALL PRINT ; ...and print string
CALL GETCH ; ...wait for keypress
CALL BLANK ; ...clear display
MOV AX,0FF04h ; Reset retry count
JMP RETRY ; ...and retry
DERROR: XOR AX,AX ; Error from NEC 765
MOV DS,AX
LES AX,Dword ptr DS:60h ; ROM basic vector ES:AX
MOV BX,ES ; ...get ROM basic segment
CMP AX,0
MOV AX,0
JNZ NODISK ; No ROM basic found
CMP BX,0F600h
JNZ NODISK ; Invalid ROM basic segment
INT 18h ; ...else call ROM basic
DSKMSG db 'Insert diskette in DRIVE A.',CR,LF
db ' Press any key.',0
ENTRY 0E6F2h ; IBM entry point for INT 19h
INT_19: JMP IPL ; Warm boot
ENTRY 0E729h ; IBM entry point for INT 14h
BAUD dw 0417h ; 110 baud clock divisor
dw 0300h ; 150 baud clock divisor
dw 0180h ; 300 baud clock divisor
dw 00C0h ; 600 baud clock divisor
dw 0060h ; 1200 baud clock divisor
dw 0030h ; 2400 baud clock divisor
dw 0018h ; 4800 baud clock divisor
dw 000Ch ; 9600 baud clock divisor
INT_14: STI ; Serial com. RS232 services
PUSH DS ; ...thru IC 8250 uart (ugh)
PUSH DX ; ...DX = COM device (0 - 3)
PUSH SI
PUSH DI
PUSH CX
PUSH BX
MOV BX,40h
MOV DS,BX
MOV DI,DX ;
MOV BX,DX ; RS232 serial COM index (0-3)
SHL BX,1 ; ...index by bytes
MOV DX,[BX] ; Convert index to port number
OR DX,DX ; ...by indexing 40:0
JZ COM_ND ; ...no such COM device, exit
OR AH,AH ; Init on AH=0
JZ COMINI
DEC AH
JZ COMSND ; Send on AH=1
DEC AH
JZ COMGET ; Rcvd on AH=2
DEC AH
JZ COMSTS ; Stat on AH=3
COM_ND: POP BX ; End of COM service
POP CX
POP DI
POP SI
POP DX
POP DS
IRET
COMINI: PUSH AX ; Init COM port. AL has data
; = (Word Length in Bits - 5)
; +(1 iff two stop bits) * 4
; +(1 iff parity enable) * 8
; +(1 iff parity even ) * 16
; +(BAUD: select 0-7 ) * 32
MOV BL,AL
ADD DX,3 ; Line Control Register (LCR)
MOV AL,80h ; ...index RS232_BASE + 3
OUT DX,AL ; Tell LCR to set (latch) baud
MOV CL,4
ROL BL,CL ; Baud rate selects by words
AND BX,00001110b ; ...mask off extraneous
MOV AX,Word ptr CS:[BX+BAUD] ; Clock divisor in AX
SUB DX,3 ; Load in lo order baud rate
OUT DX,AL ; ...index RS232_BASE + 0
INC DX ; Load in hi order baud rate
MOV AL,AH
OUT DX,AL ; ...index RS232_BASE + 1
POP AX
INC DX ; Find Line Control Register
INC DX ; ...index RS232_BASE + 3
AND AL,00011111b ; Mask out the baud rate
OUT DX,AL ; ...set (censored) init stat
MOV AL,0
DEC DX ; Interrupt Enable Reg. (IER)
DEC DX ; ...index RS232_BASE + 1
OUT DX,AL ; Interrupt is disabled
DEC DX
JMP short COMSTS ; Return current status
COMSND: PUSH AX ; Send AL thru COM port
MOV AL,3
MOV BH,00110000b ;(Data Set Ready,Clear To Send)
MOV BL,00100000b ; ..(Data Terminal Ready) wait
CALL WAITFR ; Wait for transmitter to idle
JNZ HUNG ; ...time-out error
SUB DX,5 ; ...(xmit) index RS232_BASE
POP CX ; Restore char to CL register
MOV AL,CL ; ...get copy to load in uart
OUT DX,AL ; ...transmit char to IC 8250
JMP COM_ND ; ...AH register has status
HUNG: POP CX ; Transmit error, restore char
MOV AL,CL ; ...in AL for compatibility
; ...fall thru to gen. error
HUNGG: OR AH,80h ; Set error (=sign) bit in AH
JMP COM_ND ; ...common exit
COMGET: MOV AL,1 ; Get char. from COM port
MOV BH,00100000b ; Wait on DSR (Data Set Ready)
MOV BL,00000001b ; Wait on DTR (Data Term.Ready)
CALL WAITFR ; ...wait for character
JNZ HUNGG ; ...time-out error
AND AH,00011110b ; Mask AH for error bits
SUB DX,5 ; ...(rcvr) index RS232_BASE
IN AL,DX ; Read the character
JMP COM_ND ; ...AH register has status
COMSTS: ADD DX,5 ; Calculate line control stat
IN AL,DX ; ...index RS232_BASE + 5
MOV AH,AL ; ...save high order status
INC DX ; Calculate modem stat. reg.
IN AL,DX ; ...index RS232_BASE + 6
JMP COM_ND ; ...save low order status
;AX=(DEL Clear_To_Send) * 1
; (DEL Data_Set_ready)* 2
; (Trailing_Ring_Det.)* 4
; (DEL Carrier_Detect)* 8
; ( Clear_To_Send )* 16
; ( Data_Set_Ready)* 32
; ( Ring_Indicator)* 64
; ( Carrier_Detect)* 128
; **************
; ( Char received)* 256
; ( Char smothered)* 512
; ( Parity error )* 1024
; ( Framing error )* 2048
; ( Break detected)* 4096
; ( Able to xmit )* 8192
; ( Transmit idle )*16384
; ( Time out error)*32768
POLL: MOV BL,byte ptr [DI+7Ch] ; Wait on BH in status or error
POLL_1: SUB CX,CX ; Outer delay loop
POLL_2: IN AL,DX ; ... inner loop
MOV AH,AL
AND AL,BH ; And status with user BH mask
CMP AL,BH
JZ POLLXT ; ... jump if mask set
LOOP POLL_2 ; Else try again
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -