1.目的
将8088单板机的Bootlaoder移植到8086单板机上
2.两者的区别
主要是两者串口PC16550的片内寄存器编址不同。
具体参见博文8086最小系统串口发送测试-CSDN博客
3.8088单板机的Bootloader
#make_bin# ; BIN is plain binary format similar to .com format, but not limited to 1 segment; ; All values between # are directives, these values are saved into a separate .binf file. ; Before loading .bin file emulator reads .binf file with the same file name. ; All directives are optional, if you don't need them, delete them. ; set loading address, .bin file will be loaded to this address: #LOAD_SEGMENT=0500h# #LOAD_OFFSET=0000h# ; set entry point: #CS=0500h# ; same as loading segment #IP=0000h# ; same as loading offset ; set segment registers #DS=0500h# ; same as loading segment #ES=0500h# ; same as loading segment ; set stack #SS=0500h# ; same as loading segment #SP=FFFEh# ; set to top of loading segment ; set general registers (optional) #AX=0000h# #BX=0000h# #CX=0000h# #DX=0000h# #SI=0000h# #DI=0000h# #BP=0000h# ; add your code here ;--------------------------------------------------------------------------- ;2017.2.2 增加字符串输出“OK...” ;2017.1.18 增加8255控制的数码管显示部分 ;2017.1.17 修改led显示 加速初始化 ;2016.10.9 接收到4个55H 跳转 ;2016.10.7 修改程序下载后的触发方式,改成中断触发方式 ;2016.10.6 增加串口接收指令集,下载到ram 0000:2000处,然后跳转到此处进行执行 ;2016.10.2 将指令写到ram 0000:2000,然后串口跳转到0000:2000处进行执行 ;2016.10.2 验证汇编EQU伪指令,PC16550 RECIEVE 1 BYTE ;2016.10.1 在中断中增加利用串口发送1个字节 0X99 的功能 ;2016.10.1 成功对pc16550进行初始化,并且能够向PC端发送0X55 0XAA,非常高兴 ;2016.9.30 增加PC16550驱动部分代码 ;--------------------------------------------------------------------------- ;ASM Example ;assume that the EPROM is mapped starting at FF000h ;and is 4Kbytes wide.(2732 type of device) ; ;assume that there is SRAM at 00000-OOOFFh (256 bytes) ; ; ;------------------------------------------------------* ; Packaging Program * ;This program is designed for bottle packaging in a * ;factory. The bottles pass across a sensor and for * ;each bottle the sensor sends a signal to one of the * ;input ports of the microprocessor (8Ox88). The * ;microprocessor checks to see if number of bottles has * ;reached 16. If so, the program sends another signal * ;to the packaging machine. * ;------------------------------------------------------* ;.Model small ;64K Max. size ;.Model large ;------------------------------------------------------- ;Declare some useful constants. ;inport equ 3F8h ;Input port address ;outport equ 2F8h ;Output port address ;MaxBot equ 10h ;set maximum number ;of bottles to 16 ;------------------------------------------------------- ; DO NOT use a data segment. All fixed data that you ; want in ROM can be put in the code segment using the ; same compiler directives you used in the data segment ;------------------------------------------------------- ; .CODE ;ORG 0100h ;put permanent data here. ;start,of fixed data(rather arbitrary, ;only must not be at the high end of ;EPROM). The ORG statement MUST FOLLOW ;the segment declaration. ;tblstrt: db 0FFh ;Just defining some useless data. ;db 0EEh ;db 0DDh ;tblend: db 0A5h ;End of useless data ;--------------------------------------------------------- ;This is where the code "really" starts! ;LCR EQU 8003H LSR EQU 1f5H DATA_BRDL EQU 1F0H PORT_8253_CTRL EQU 303H ; 控制寄存器端口 PORT_8253_0 EQU 300H ; 计数器0 PORT_8253_1 EQU 301H ; 计数器1 PORT_8253_2 EQU 302H ; 计数器2 ORG 0000h ;keep data and code areas separate start: nop ;------------------------------- ;init ;------------------------------- mov ax,0 mov ds,ax mov ss,ax mov ax,6fffh mov sp,ax ;----------------------------- ;init si as 2000h ;----------------------------- mov ax,2000h mov bx,ax ;---------------------------------------- ;LIGHT LED ;--------------------------------------- ;MOV AL,0FH CALL NMI_INIT mov al,0f0h mov byte ptr ds:[80h],al mov al,00h mov byte ptr ds:[81h],al mov al,00h mov byte ptr ds:[1000h],al mov byte ptr ds:[1001h],0 CALL CMD_WR CALL COM_INIT ;----------------------------------------------------- ;main loop ;----------------------------------------------------- mov ax,2000h mov bx,ax MOV DX,DATA_BRDL ;IN AL,DX ;OUT DX,AL mov ax,bx ; out dx,ah out dx,al mov al,ah out dx,al CALL OK_STR ;----------------------------------------------- MOV AX,0F000H MOV ES,AX ;MOV DI,STR1 LEA DI,STR1 CALL STR_OUT ;----------------------------------------------- ; CALL OK_STR MOV CX,200 LOOP $ ;--------------------------------------------------- MOV CX,3 S100: MOV DX,800H MOV AL,0FFH OUT DX,AL CALL DELAY CALL DELAY MOV AL,0 OUT DX,AL CALL DELAY CALL DELAY CALL OK_STR LOOP S100 MOV DX,800H MOV AL,0FFH OUT DX,AL ; CALL OK_STR call init8255 call disp_8255 ; CALL OK_STR ;----------------------------------------------- MOV AX,0F000H MOV ES,AX ;MOV DI,STR1 ;LEA DI,STR2 ;CALL STR_OUT NOP NOP LEA DI,STR1 CALL STR_OUT ;----------------------------------------------- ; CALL OK_STR main: nop call rcv_inc mov al,byte ptr ds:[1000h] cmp al,55h jnz next_p ;---------------------------------------- ;初始化程序跳转前的段地址准备 ;0000:2000 EQU 01f0:0100h mov ax,01f0h mov ds,ax mov ss,ax mov ax,5fffh mov sp,ax ;----------------------------------------- ; mov byte ptr ds:[100h],00H ; mov byte ptr ds:[101h],20H ; mov byte ptr ds:[102h],00H ; mov byte ptr ds:[103h],00H mov byte ptr ds:[3100h],00H mov byte ptr ds:[3101h],01H ;ip=0100h mov byte ptr ds:[3102h],0f0H mov byte ptr ds:[3103h],01H ;cs=01f0 JMP DWORD PTR DS:[3100H] next_p:nop jmp main ;------------------------------------------------------ ;main loop end ;------------------------------------------------------ START01: NOP ;mov al,55h ;mov byte ptr ds:[80h],al mov al,byte ptr ds:[80h] ;OUT 10H,AL mov dx,0ffh out dx,al CALL DELAY CALL DELAY ;CALL DELAY ;CALL DELAY ;----------------------------------------- ;OFF LED ;----------------------------------------- ;MOV AL,00H ;mov al,0aah ;mov byte ptr ds:[80h],al mov al,byte ptr ds:[81h] ;OUT 10H,AL mov dx,0ffh out dx,al CALL RCV NOP NOP CALL COM_TEST CALL DELAY CALL DELAY CALL DELAY CALL DELAY jmp START01 ;START again ;--------------------------------------------------- ;将指令写到RAM 0000:2000处 ;b0 f0 e6 10 eb fa ; loopx:mov al,0f0h ; out 10h,al ; jmp loopx ;---------------------------------------------------- CMD_WR PROC NEAR mov byte ptr ds:[2000h],0B0H mov byte ptr ds:[2001h],0F0H mov byte ptr ds:[2002h],0E6H mov byte ptr ds:[2003h],10H mov byte ptr ds:[2004h],0EBH mov byte ptr ds:[2005h],0FAH RET CMD_WR ENDP ;--------------------------------------------------- ;16650 init ;--------------------------------------------------- COM_INIT PROC NEAR ;LINE MOV AL,8AH MOV DX,1F3H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;LSB MOV AL,120 MOV DX,1F0H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;MSB MOV AL,0 MOV DX,1F1H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;LINE ;MOV AL,0AH MOV AL,03H MOV DX,1F3H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;FIFO MOV AL,07H MOV DX,1F2H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY MOV DX,800H MOV AL,0AAH OUT DX,AL RET COM_INIT ENDP ;--------------------------------------------------- ;16650 SEND 1 BYTE ;--------------------------------------------------- COM_TEST PROC NEAR MOV AL,55H MOV DX,1F0H OUT DX,AL CALL DELAY MOV AL,0AAH MOV DX,1F0H OUT DX,AL RET COM_TEST ENDP ;--------------------------------------------------- ;PC16550 RECIEVE 1 BYTE ;--------------------------------------------------- RCV PROC NEAR PUSH AX MOV DX,LSR IN AL,DX TEST AL,01H JZ RCV_EXIT MOV DX,DATA_BRDL IN AL,DX OUT DX,AL ;JMP WORD PTR DS:[2000H] ;MOV AX,2000H ;MOV DS:[100H],AX ;MOV WORD PTR DS:[102H],0 mov byte ptr ds:[100h],00H mov byte ptr ds:[101h],20H mov byte ptr ds:[102h],00H mov byte ptr ds:[103h],00H JMP DWORD PTR DS:[100H] NOP RCV_EXIT: NOP POP AX RET RCV ENDP ;-------------------------------------------------------- ;pc16550 接收指令集,并写到指定的ram位置 ;-------------------------------------------------------- rcv_inc proc near PUSH AX MOV DX,LSR IN AL,DX TEST AL,01H JZ RCVinc_EXIT MOV DX,DATA_BRDL IN AL,DX OUT DX,AL ;mov ax,si ;out dx,ah ;out dx,al ;mov al,ah ;out dx,al mov byte ptr ds:[bx],al add bx,1 ;***************************************************** ; ;***************************************************** cmp al,55h jnz set_0 add byte ptr ds:[1001h],1 cmp byte ptr ds:[1001h],4 jnz skip mov byte ptr ds:[1000h],55h ;mov byte ptr ds:[1001h],0 jmp skip set_0: mov byte ptr ds:[1001h],0 skip: nop ;***************************************************** cmp al,0ffh jnz RCVinc_EXIT jz RCVinc_EXIT ;JMP WORD PTR DS:[2000H] ;MOV AX,2000H ;MOV DS:[100H],AX ;MOV WORD PTR DS:[102H],0 mov byte ptr ds:[100h],00H mov byte ptr ds:[101h],20H mov byte ptr ds:[102h],00H mov byte ptr ds:[103h],00H ;JMP DWORD PTR DS:[100H] mov ax,5 mov cx,ax mov ax,2000h mov si,ax ;mov s: mov al,byte ptr ds:[si]; MOV DX,DATA_BRDL OUT DX,AL add si,1 ;loop s ;cmp si,2100h ;mov cx,500 ;s1: loop s1 ;mov ax,1f5h mov dx,1f5h s2: in al,dx test al,20h jz s2 mov ax,si cmp ax,2fffh jnz s MOV DX,DATA_BRDL OUT DX,AL mov al,ah out dx,al ;JMP DWORD PTR DS:[100H] NOP RCVinc_EXIT: NOP POP AX RET ;ret rcv_inc endp ;--------------------------------------------------- ;DELAY PROC ;--------------------------------------------------- DELAY PROC NEAR ;push PUSH CX PUSH BX NOP NOP mov bx,10 del1: mov cx,5882 del2: loop del2 dec bx jnz del1 ;pop cx ;pop bx POP BX POP CX RET DELAY ENDP ;---------------------------------------------- ;nop delay ;---------------------------------------------- delay_100 proc near PUSH AX mov al,0FFh ;INC AL mov byte ptr ds:[80h],al NOP NOP NOP POP AX ret delay_100 endp ;--------------------------------------------------- ;DELAY01 PROC ;--------------------------------------------------- DELAY01: ;push NOP NOP mov bx,10 del10: mov cx,5882 del20: loop del20 dec bx jnz del10 ;pop cx ;pop bx RET ;--------------------------------------------------------- ;NMI_INIT PROC ;--------------------------------------------------------- NMI_INIT: PUSH ES XOR AX,AX MOV ES,AX MOV AL,02H XOR AH,AH SHL AX,1 SHL AX,1 MOV SI,AX MOV AX,OFFSET NMI_ISR MOV ES:[SI],AX INC SI INC SI MOV BX,CS MOV ES:[SI],BX POP ES RET ;-------------------------------------------------------- ;NMI_ISR ;-------------------------------------------------------- NMI_ISR: NOP NOP ;------------------------------------------------------------------------------ ; 关闭计数器0 MOV AL, 30H;00110000B ; 控制字: 计数器0, 模式0, 只写低字节, 二进制 MOV DX, PORT_8253_CTRL ;OUT PORT_8253_CTRL, AL OUT DX,AL MOV AL, 0 ; 计数初值低字节 = 0 MOV DX,PORT_8253_0 OUT DX, AL ;------------------------------------------------------------------------------- mov al,byte ptr ds:[80h] ;mov al,0FFh INC AL mov byte ptr ds:[80h],al ;MOV AL,0FFH ;OUT 10H,AL ;CALL DELAY01 NOP call delay_100 ;CALL DELAY ;CALL DELAY ;CALL DELAY ;------------------------------- ;DELAY ;------------------------------- ;------------------------------- ;uart send 0x99 function ;------------------------------- mov al,55h mov byte ptr ds:[1000h],al MOV AL,0a5H MOV DX,1F0H OUT DX,AL NOP NOP IRET ;----------------------------- ;8255 init ;----------------------------- init8255 proc near mov dx,203h ;mov al,80h mov al,89h;port a,b as output port c as input out dx,al ret init8255 endp ;------------------------------ ;8255 for disp ;------------------------------ disp_8255 proc near mov al,11000000b ;'1' mov dx,200h out dx,al ;8255 port b mov al,00h mov dx,201h out dx,al ret disp_8255 endp ;--------------------------------------- ;OK STR OUT ;--------------------------------------- OK_STR PROC NEAR MOV DX,DATA_BRDL MOV AL,'O' OUT DX,AL MOV AL,'K' OUT DX,AL MOV AL,'.' OUT DX,AL MOV AL,'.' OUT DX,AL MOV AL,'.' OUT DX,AL RET OK_STR ENDP ;----------------------------------------------------------- ;增加Boot启动输出“www.i8088.com”信息 ;2019.11.3 ;----------------------------------------------------------- STR_OUT PROC NEAR NOP STR_LOOP: MOV DX,DATA_BRDL MOV AL,BYTE PTR ES:[DI] CMP AL,'$' JZ STR_EXIT ;MOV AL,'X' OUT DX,AL ;MOV AL,'X' ;OUT DX,AL MOV CX,200 LOOP $ INC DI JMP STR_LOOP STR_EXIT: NOP RET STR_OUT ENDP STR1 DB 'www.i8088.cn',13,10,'$' STR2 DB 'just for fun!',13,10,'$' ;BLANK DB 0FFF0H-THIS ;db 3000-($-start) dup(0) ; Fill the rest of the sector with zero's db 25520-$ dup(0) ; Fill the rest of the sector with zero's db 45520-$ dup(0) ; Fill the rest of the sector with zero's ;db 55520-$ dup(0) ; Fill the rest of the sector with zero's db 20000 dup(0) ; JMP far START DB 0EAH DB 00H DB 00H DB 00H DB 0F0H ;SATRT DB 0EAH 00H 00H 00H 0F0H ;********************************************************************** ;********************************************************************** ;EPROM goes from XX000-XXFFFh. But, because of memory mapping, ;the XX is actually Ffh address. The jump must bea ;near jump (2 byte, ;relative address) so that the jump is relocatable. Otherwise ;a 4byte absolute address is put in. ; ;org 0FF0h ;restart address ; .CODE ;org 0eff0h ;27c512 64k rom,烧写时需手动移到fff0处 ;jmp far ptr start; ;again: mov al,01h ;again1: out 10h,al ;jmp 0f000:0100 end HLT ; halt!4.移植后的8086单板机BootLoader
#make_bin# ; BIN is plain binary format similar to .com format, but not limited to 1 segment; ; All values between # are directives, these values are saved into a separate .binf file. ; Before loading .bin file emulator reads .binf file with the same file name. ; All directives are optional, if you don't need them, delete them. ; set loading address, .bin file will be loaded to this address: #LOAD_SEGMENT=0500h# #LOAD_OFFSET=0000h# ; set entry point: #CS=0500h# ; same as loading segment #IP=0000h# ; same as loading offset ; set segment registers #DS=0500h# ; same as loading segment #ES=0500h# ; same as loading segment ; set stack #SS=0500h# ; same as loading segment #SP=FFFEh# ; set to top of loading segment ; set general registers (optional) #AX=0000h# #BX=0000h# #CX=0000h# #DX=0000h# #SI=0000h# #DI=0000h# #BP=0000h# ; add your code here ;--------------------------------------------------------------------------- ;2017.2.2 增加字符串输出“OK...” ;2017.1.18 增加8255控制的数码管显示部分 ;2017.1.17 修改led显示 加速初始化 ;2016.10.9 接收到4个55H 跳转 ;2016.10.7 修改程序下载后的触发方式,改成中断触发方式 ;2016.10.6 增加串口接收指令集,下载到ram 0000:2000处,然后跳转到此处进行执行 ;2016.10.2 将指令写到ram 0000:2000,然后串口跳转到0000:2000处进行执行 ;2016.10.2 验证汇编EQU伪指令,PC16550 RECIEVE 1 BYTE ;2016.10.1 在中断中增加利用串口发送1个字节 0X99 的功能 ;2016.10.1 成功对pc16550进行初始化,并且能够向PC端发送0X55 0XAA,非常高兴 ;2016.9.30 增加PC16550驱动部分代码 ;--------------------------------------------------------------------------- ;ASM Example ;assume that the EPROM is mapped starting at FF000h ;and is 4Kbytes wide.(2732 type of device) ; ;assume that there is SRAM at 00000-OOOFFh (256 bytes) ; ; ;------------------------------------------------------* ; Packaging Program * ;This program is designed for bottle packaging in a * ;factory. The bottles pass across a sensor and for * ;each bottle the sensor sends a signal to one of the * ;input ports of the microprocessor (8Ox88). The * ;microprocessor checks to see if number of bottles has * ;reached 16. If so, the program sends another signal * ;to the packaging machine. * ;------------------------------------------------------* ;.Model small ;64K Max. size ;.Model large ;------------------------------------------------------- ;Declare some useful constants. ;inport equ 3F8h ;Input port address ;outport equ 2F8h ;Output port address ;MaxBot equ 10h ;set maximum number ;of bottles to 16 ;------------------------------------------------------- ; DO NOT use a data segment. All fixed data that you ; want in ROM can be put in the code segment using the ; same compiler directives you used in the data segment ;------------------------------------------------------- ; .CODE ;ORG 0100h ;put permanent data here. ;start,of fixed data(rather arbitrary, ;only must not be at the high end of ;EPROM). The ORG statement MUST FOLLOW ;the segment declaration. ;tblstrt: db 0FFh ;Just defining some useless data. ;db 0EEh ;db 0DDh ;tblend: db 0A5h ;End of useless data ;--------------------------------------------------------- ;This is where the code "really" starts! ;LCR EQU 8003H ;LSR EQU 1f5H ;DATA_BRDL EQU 1F0H LSR EQU 10AH DATA_BRDL EQU 100H PORT_8253_CTRL EQU 303H ; 控制寄存器端口 PORT_8253_0 EQU 300H ; 计数器0 PORT_8253_1 EQU 301H ; 计数器1 PORT_8253_2 EQU 302H ; 计数器2 ORG 0000h ;keep data and code areas separate start: nop ;------------------------------- ;init ;------------------------------- mov ax,0 mov ds,ax mov ss,ax mov ax,6fffh mov sp,ax ;----------------------------- ;init si as 2000h ;----------------------------- mov ax,2000h mov bx,ax ;---------------------------------------- ;LIGHT LED ;--------------------------------------- ;MOV AL,0FH CALL NMI_INIT mov al,0f0h mov byte ptr ds:[80h],al mov al,00h mov byte ptr ds:[81h],al mov al,00h mov byte ptr ds:[1000h],al mov byte ptr ds:[1001h],0 CALL CMD_WR CALL COM_INIT ;----------------------------------------------------- ;main loop ;----------------------------------------------------- mov ax,2000h mov bx,ax MOV DX,DATA_BRDL ;IN AL,DX ;OUT DX,AL mov ax,bx ; out dx,ah out dx,al mov al,ah out dx,al CALL OK_STR ;----------------------------------------------- MOV AX,0F000H MOV ES,AX ;MOV DI,STR1 LEA DI,STR1 CALL STR_OUT ;----------------------------------------------- ; CALL OK_STR MOV CX,200 LOOP $ ;--------------------------------------------------- MOV CX,3 S100: MOV DX,800H MOV AL,0FFH OUT DX,AL CALL DELAY CALL DELAY MOV AL,0 OUT DX,AL CALL DELAY CALL DELAY CALL OK_STR LOOP S100 MOV DX,800H MOV AL,0FFH OUT DX,AL ; CALL OK_STR call init8255 call disp_8255 ; CALL OK_STR ;----------------------------------------------- MOV AX,0F000H MOV ES,AX ;MOV DI,STR1 ;LEA DI,STR2 ;CALL STR_OUT NOP NOP LEA DI,STR1 CALL STR_OUT ;----------------------------------------------- ; CALL OK_STR main: nop call rcv_inc mov al,byte ptr ds:[1000h] cmp al,55h jnz next_p ;---------------------------------------- ;初始化程序跳转前的段地址准备 ;0000:2000 EQU 01f0:0100h mov ax,01f0h mov ds,ax mov ss,ax mov ax,5fffh mov sp,ax ;----------------------------------------- ; mov byte ptr ds:[100h],00H ; mov byte ptr ds:[101h],20H ; mov byte ptr ds:[102h],00H ; mov byte ptr ds:[103h],00H mov byte ptr ds:[3100h],00H mov byte ptr ds:[3101h],01H ;ip=0100h mov byte ptr ds:[3102h],0f0H mov byte ptr ds:[3103h],01H ;cs=01f0 JMP DWORD PTR DS:[3100H] next_p:nop jmp main ;------------------------------------------------------ ;main loop end ;------------------------------------------------------ START01: NOP ;mov al,55h ;mov byte ptr ds:[80h],al mov al,byte ptr ds:[80h] ;OUT 10H,AL mov dx,0ffh out dx,al CALL DELAY CALL DELAY ;CALL DELAY ;CALL DELAY ;----------------------------------------- ;OFF LED ;----------------------------------------- ;MOV AL,00H ;mov al,0aah ;mov byte ptr ds:[80h],al mov al,byte ptr ds:[81h] ;OUT 10H,AL mov dx,0ffh out dx,al CALL RCV NOP NOP CALL COM_TEST CALL DELAY CALL DELAY CALL DELAY CALL DELAY jmp START01 ;START again ;--------------------------------------------------- ;将指令写到RAM 0000:2000处 ;b0 f0 e6 10 eb fa ; loopx:mov al,0f0h ; out 10h,al ; jmp loopx ;---------------------------------------------------- CMD_WR PROC NEAR mov byte ptr ds:[2000h],0B0H mov byte ptr ds:[2001h],0F0H mov byte ptr ds:[2002h],0E6H mov byte ptr ds:[2003h],10H mov byte ptr ds:[2004h],0EBH mov byte ptr ds:[2005h],0FAH RET CMD_WR ENDP ;--------------------------------------------------- ;16650 init ;--------------------------------------------------- COM_INIT PROC NEAR ;LINE MOV AL,8AH ;MOV DX,1F3H MOV DX,106H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;LSB MOV AL,120 ;MOV DX,1F0H MOV DX,100H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;MSB MOV AL,0 ;MOV DX,1F1H MOV DX,1F2H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;LINE ;MOV AL,0AH MOV AL,03H ;MOV DX,1F3H MOV DX,106H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY ;FIFO MOV AL,07H ;MOV DX,1F2H MOV DX,104H OUT DX,AL CALL DELAY ;CALL DELAY ;CALL DELAY ;CALL DELAY MOV DX,800H MOV AL,0AAH OUT DX,AL RET COM_INIT ENDP ;--------------------------------------------------- ;16650 SEND 1 BYTE ;--------------------------------------------------- COM_TEST PROC NEAR MOV AL,55H ; MOV DX,1F0H MOV DX,100H OUT DX,AL CALL DELAY MOV AL,0AAH ;MOV DX,1F0H MOV DX,100H OUT DX,AL RET COM_TEST ENDP ;--------------------------------------------------- ;PC16550 RECIEVE 1 BYTE ;--------------------------------------------------- RCV PROC NEAR PUSH AX MOV DX,LSR IN AL,DX TEST AL,01H JZ RCV_EXIT MOV DX,DATA_BRDL IN AL,DX OUT DX,AL ;JMP WORD PTR DS:[2000H] ;MOV AX,2000H ;MOV DS:[100H],AX ;MOV WORD PTR DS:[102H],0 mov byte ptr ds:[100h],00H mov byte ptr ds:[101h],20H mov byte ptr ds:[102h],00H mov byte ptr ds:[103h],00H JMP DWORD PTR DS:[100H] NOP RCV_EXIT: NOP POP AX RET RCV ENDP ;-------------------------------------------------------- ;pc16550 接收指令集,并写到指定的ram位置 ;-------------------------------------------------------- rcv_inc proc near PUSH AX MOV DX,LSR IN AL,DX TEST AL,01H JZ RCVinc_EXIT MOV DX,DATA_BRDL IN AL,DX OUT DX,AL ;mov ax,si ;out dx,ah ;out dx,al ;mov al,ah ;out dx,al mov byte ptr ds:[bx],al add bx,1 ;***************************************************** ; ;***************************************************** cmp al,55h jnz set_0 add byte ptr ds:[1001h],1 cmp byte ptr ds:[1001h],4 jnz skip mov byte ptr ds:[1000h],55h ;mov byte ptr ds:[1001h],0 jmp skip set_0: mov byte ptr ds:[1001h],0 skip: nop ;***************************************************** cmp al,0ffh jnz RCVinc_EXIT jz RCVinc_EXIT ;JMP WORD PTR DS:[2000H] ;MOV AX,2000H ;MOV DS:[100H],AX ;MOV WORD PTR DS:[102H],0 mov byte ptr ds:[100h],00H mov byte ptr ds:[101h],20H mov byte ptr ds:[102h],00H mov byte ptr ds:[103h],00H ;JMP DWORD PTR DS:[100H] mov ax,5 mov cx,ax mov ax,2000h mov si,ax ;mov s: mov al,byte ptr ds:[si]; MOV DX,DATA_BRDL OUT DX,AL add si,1 ;loop s ;cmp si,2100h ;mov cx,500 ;s1: loop s1 ;mov ax,1f5h ;mov dx,1f5h MOV DX,10AH s2: in al,dx test al,20h jz s2 mov ax,si cmp ax,2fffh jnz s MOV DX,DATA_BRDL OUT DX,AL mov al,ah out dx,al ;JMP DWORD PTR DS:[100H] NOP RCVinc_EXIT: NOP POP AX RET ;ret rcv_inc endp ;--------------------------------------------------- ;DELAY PROC ;--------------------------------------------------- DELAY PROC NEAR ;push PUSH CX PUSH BX NOP NOP mov bx,10 del1: mov cx,5882 del2: loop del2 dec bx jnz del1 ;pop cx ;pop bx POP BX POP CX RET DELAY ENDP ;---------------------------------------------- ;nop delay ;---------------------------------------------- delay_100 proc near PUSH AX mov al,0FFh ;INC AL mov byte ptr ds:[80h],al NOP NOP NOP POP AX ret delay_100 endp ;--------------------------------------------------- ;DELAY01 PROC ;--------------------------------------------------- DELAY01: ;push NOP NOP mov bx,10 del10: mov cx,5882 del20: loop del20 dec bx jnz del10 ;pop cx ;pop bx RET ;--------------------------------------------------------- ;NMI_INIT PROC ;--------------------------------------------------------- NMI_INIT: PUSH ES XOR AX,AX MOV ES,AX MOV AL,02H XOR AH,AH SHL AX,1 SHL AX,1 MOV SI,AX MOV AX,OFFSET NMI_ISR MOV ES:[SI],AX INC SI INC SI MOV BX,CS MOV ES:[SI],BX POP ES RET ;-------------------------------------------------------- ;NMI_ISR ;-------------------------------------------------------- NMI_ISR: NOP NOP ;------------------------------------------------------------------------------ ; 关闭计数器0 MOV AL, 30H;00110000B ; 控制字: 计数器0, 模式0, 只写低字节, 二进制 MOV DX, PORT_8253_CTRL ;OUT PORT_8253_CTRL, AL OUT DX,AL MOV AL, 0 ; 计数初值低字节 = 0 MOV DX,PORT_8253_0 OUT DX, AL ;------------------------------------------------------------------------------- mov al,byte ptr ds:[80h] ;mov al,0FFh INC AL mov byte ptr ds:[80h],al ;MOV AL,0FFH ;OUT 10H,AL ;CALL DELAY01 NOP call delay_100 ;CALL DELAY ;CALL DELAY ;CALL DELAY ;------------------------------- ;DELAY ;------------------------------- ;------------------------------- ;uart send 0x99 function ;------------------------------- mov al,55h mov byte ptr ds:[1000h],al MOV AL,0a5H MOV DX,1F0H OUT DX,AL NOP NOP IRET ;----------------------------- ;8255 init ;----------------------------- init8255 proc near mov dx,203h ;mov al,80h mov al,89h;port a,b as output port c as input out dx,al ret init8255 endp ;------------------------------ ;8255 for disp ;------------------------------ disp_8255 proc near mov al,11000000b ;'1' mov dx,200h out dx,al ;8255 port b mov al,00h mov dx,201h out dx,al ret disp_8255 endp ;--------------------------------------- ;OK STR OUT ;--------------------------------------- OK_STR PROC NEAR MOV DX,DATA_BRDL MOV AL,'O' OUT DX,AL MOV AL,'K' OUT DX,AL MOV AL,'.' OUT DX,AL MOV AL,'.' OUT DX,AL MOV AL,'.' OUT DX,AL RET OK_STR ENDP ;----------------------------------------------------------- ;增加Boot启动输出“www.i8088.com”信息 ;2019.11.3 ;----------------------------------------------------------- STR_OUT PROC NEAR NOP STR_LOOP: MOV DX,DATA_BRDL MOV AL,BYTE PTR ES:[DI] CMP AL,'$' JZ STR_EXIT ;MOV AL,'X' OUT DX,AL ;MOV AL,'X' ;OUT DX,AL MOV CX,200 LOOP $ INC DI JMP STR_LOOP STR_EXIT: NOP RET STR_OUT ENDP STR1 DB 'www.i8088.cn',13,10,'$' STR2 DB 'just for fun!',13,10,'$' ;BLANK DB 0FFF0H-THIS ;db 3000-($-start) dup(0) ; Fill the rest of the sector with zero's db 25520-$ dup(0) ; Fill the rest of the sector with zero's db 45520-$ dup(0) ; Fill the rest of the sector with zero's ;db 55520-$ dup(0) ; Fill the rest of the sector with zero's db 20000 dup(0) ; JMP far START DB 0EAH DB 00H DB 00H DB 00H DB 0F0H ;SATRT DB 0EAH 00H 00H 00H 0F0H ;********************************************************************** ;********************************************************************** ;EPROM goes from XX000-XXFFFh. But, because of memory mapping, ;the XX is actually Ffh address. The jump must bea ;near jump (2 byte, ;relative address) so that the jump is relocatable. Otherwise ;a 4byte absolute address is put in. ; ;org 0FF0h ;restart address ; .CODE ;org 0eff0h ;27c512 64k rom,烧写时需手动移到fff0处 ;jmp far ptr start; ;again: mov al,01h ;again1: out 10h,al ;jmp 0f000:0100 end HLT ; halt!5.下载测试例程
#define ADR_273 0x0200 #define ADR_244 0x0400 #define LED_PORT 0x800 void outp(unsigned int addr, char data) // 输出一字节到I/O端口 { __asm { mov dx, addr mov al, data out dx, al } } char inp(unsigned int addr) // 从I/O端口输入一字节 { char result; __asm { mov dx, addr in al, dx mov result, al } return result; } char end_flag[5]={0x55,0x55,0x55,0x55,0x55}; void main(void) /*检测按键状态并由LED发光二极管显示, 若按键闭合对应LED发光二极管点亮, 若按键断开对应LED发光二极管灭.*/ { int i=0; while (1) { //char button_state; //button_state=inp(ADR_244); //int i=0; for(i=0;i<5000;i++); for(i=0;i<5000;i++); outp(LED_PORT, 0xff); for(i=0;i<5000;i++); for(i=0;i<5000;i++); outp(LED_PORT, 0x00); } }