OpenCores
URL https://opencores.org/ocsvn/light8080/light8080/trunk

Subversion Repositories light8080

[/] [light8080/] [trunk/] [sw/] [demos/] [hello/] [hello.asm] - Rev 74

Compare with Previous | Blame | View Log

;*******************************************************************************
; tb1.asm -- light8080 core basic demo: 'Hello World!"
;*******************************************************************************
; Should be used with SoC vhdl\soc\l80soc.vhdl
; Assembler format compatible with TASM for DOS and Linux.
;*******************************************************************************
; This program will print a Hello message to a 9600/8/N/1 serial port, then 
; will loop forever copying the input port P1 to the output port P2. 
; This demo is meant to be used as a starting point for those wanting to play 
; with the l80soc core -- which in turn is little more than an usage example
; for the light8080 cpu core.
; See the readme file for instructions for setting up a project with this 
; program on Digilentic's DE-1 development board.
;*******************************************************************************

; DS pseudo-directive; reserve space in bytes, without initializing it
#define ds(n)    \.org $+n

MASK_RX_IRQ:  .equ 20h
MASK_TX_IRQ:  .equ 10h
MASK_RX_RDY:  .equ 02h
MASK_TX_RDY:  .equ 01h

UART_DATA:    .equ 80h
UART_STATUS:  .equ 81h
UART_BAUDL:   .equ 82h
UART_BAUDH:   .equ 83h
IRQ_ENABLE:   .equ 88h

P1IN:         .equ 84h
P2OUT:        .equ 86h


;*******************************************************************************

          .org  0H              ; Reset entry point
          jmp   start           ; Skip the rst address area
                        
        ;***** Interrupt vectors in area 0008h-0038h *****************
        
          .org  0h+(1*8)        ; interrupt vector 1
          ret
          .org  0h+(2*8)        ; interrupt vector 2
          ret
          .org  0h+(3*8)        ; interrupt vector 3
          ret
          .org  0h+(4*8)        ; interrupt vector 4
          ret
          .org  0h+(5*8)        ; interrupt vector 5
          ret
          .org  0h+(6*8)        ; interrupt vector 6
          ret
          
          .org  0h+(7*8)        ; interrupt vector 7
int38h:   jmp   irq_uart        ; UART interrupt 
       
          ;***** program entry point *******************************************
                
start:    .org  60H
          lxi   sp,stack

          ; Initialize UART RX and TX buffers
          lxi   h,void_buffer
          shld  ptr_tx
          lxi   h,rx_buffer
          shld  ptr_rx
          ; Set up UART baud rate to 9600 bauds @ 50MHz:
          ; (50E6 / 9600) = 5208d = 1458h
          mvi   a,14h           
          out   UART_BAUDH
          mvi   a,58h
          out   UART_BAUDL
          
          ; Clear P2 port
          mvi   a,00h
          out   P2OUT
          
          ; Set up interrupts
          mvi   a,08h           ; Enable UART irq...
          out   IRQ_ENABLE
          ei                    ; ...and enable interrupts in the CPU
        
          ; print hello message to console
          lxi   h,msg_hello
          call  print_string

forever:          
          in    P1IN
          mov   c,a
          rlc   
          rlc
          add   c
          out   P2OUT
          jmp   forever

          di
          hlt
done:     jmp   done 

msg_hello: .text "\n\r\nHello World!$\000"          
          
;irq_uart: UART interrupt processing 
irq_uart:
          push  h
          push  psw
          
          ; Deal with RX interrupt (if any) first and then the TX interrupt.
          in    UART_STATUS     ; Is there new data in the RX register?
          ani   MASK_RX_IRQ
          jz    irq_uart_rx_done ; If there isn't, process TX interrupt.
          
          ; Process UART RX interrupt
irq_uart_rx:     
          mvi   a,MASK_RX_IRQ   ; Clear IRQ flag.
          out   UART_STATUS     
          in    UART_DATA       ; Get RX byte...
          out   P2OUT           ; ...display it in the output port...
          lhld  ptr_rx          ; ...and store it in the rx buffer.
          mov   m,a
          inx   h
          shld  ptr_rx          ; Update the rx buffer pointer.
          ; Note there's no check for RX buffer overrun! 

irq_uart_rx_done:
          ; Ok, RX is done. Now deal with TX irq, if any
          in    UART_STATUS     ; Is the TX buffer re new data in the RX register?
          ani   MASK_TX_IRQ
          jz    irq_uart_end    ; If there isn't, we're done.
          
          ; process UART TX interrupt
irq_uart_tx:
          mvi   a,MASK_TX_IRQ   ; Clear IRQ flag.
          out   UART_STATUS
          lhld  ptr_tx          ; Get next byte from the TX buffer 
          mov   a,m
          cpi   '$'             ; Did we reach the end of the buffer?
          jz    irq_uart_tx_done ; If we did, we're done here...
          inx   h               ; ...otherwise increment the TX pointer...
          shld  ptr_tx
          out   UART_DATA       ; ...and transmit the data byte.
          
irq_uart_tx_done:
        
irq_uart_end:
          pop   psw             ; Done, quit.
          pop   h
          ei
          ret                
          ; Note there's no check for RX buffer overrun! we shouldn't need it 
          ; in this program, anyway.
     
   
;print_string: print $-terminated string at HL
; Returns as soon as the transmission has started; transmission proceeds in 
; 'background' through the UART interrupt service routine.
print_string:
          ; We don't check if there's a transmission going on, we just start
          ; transmitting. Not suitable for real use!
          mov   a,m             ; Get first character from string...
          inx   h               ; ...and move updated string pointer to TX  
          shld  ptr_tx          ; buffer pointer.
          cpi   '$'             ; Kickstart transmission by sending 1st byte...
          jz    print_string_end; ...unless its the end of string marker.
          out   UART_DATA       ; 
print_string_end:
          ret

          
          ; data space, placed immediately after object code in memory
void_buffer:  .text "$"
ptr_tx:       ds(2)
ptr_rx:       ds(2)
rx_buffer:    ds(32)
              ds(64)
stack:        ds(2)
          .end
        

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.