8088单板机C程序“Hellow World!”----Prj03

1.固件代码更新

2.C程序代码

#define ADR_273 0x0200
#define ADR_244 0x0400
#define  LED_PORT   0x800
#define  PC16550_THR   0x1f0
#define  PC16550_LSR   0x1f5
/
//基本的IO操作函数
/
char str[]="Hello World!  20250531  Very Ok!!!\r\n";
char cx='A';
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;
 }

//串口发送函数

void  uart_send(char x)
{
 int temp;
  while(1)
  {
   temp=inp(PC16550_LSR);
   if((temp&0x20)==0x20)
   {
    break;
    }
   }
  outp(PC16550_THR,x);
 }

void uart_str_send(char *p)
{
 //int i=0;
 //char str1[20]="Hello World!\r\n";
 //char *p;
 //p=str1;
 
 while(*p!='\0')
  {
    uart_send(*p);
    p++;
   }

/*
 for(i=0;i<14;i++)
   {
     uart_send(str1[i]);
    }
*/
 }
///


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;
     uart_str_send(str);
     uart_send(cx);
     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);
   }
 }


3.编译下载  测试

4.8088单板机固件代码

#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


     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

       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!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iCxhust

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值