;--------------------------------------------------------------------------- ; L351.ASM ; ; This program uses the 80C188 internal timer to generate a periodic ; interrupt. The interrupt toggles the state of LED-5 of KEY_PC 80-times ; before it is turned off. ; ; ASM code for the SBC188 boards. ; C.P. Diduch, March 1999. ;--------------------------------------------------------------------------- KEY_PC EQU 13CH ; Port Addresses for the 8255A. KEY_CON EQU 13EH ; ; EOI EQU 0FF22H ; 80C188 EOI register. IT_TYPE EQU 18 ; 80C188 Interrupt TYPE no. for TIMER1. TCUCON EQU 0FF32H ; 80C188 Interrupt control reg. for TIMERS. ; T1CNT EQU 0FF58H ; 80C188 TIMER1 count register. T2CNT EQU 0FF60H ; 80C188 TIMER2 count register. T1CON EQU 0FF5EH ; 80C188 TIMER1 control register. T2CON EQU 0FF66H ; 80C188 TIMER2 control register. T1CMPA EQU 0FF5AH ; 80C188 TIMER1 maximum count register. T2CMPA EQU 0FF62H ; 80C188 TIMER2 maximum count register. ; TRUE EQU 1 ; ; ;--------------------------------------------------------------------------- _DATA segment word public 'DATA' assume cs:_TEXT, ds:_DATA ; Program variables and stack ; DW 10 DUP(?) ; Reserve stack area TOS LABEL WORD ; Top of stack label N DW ? ; int N; ; _DATA ends ; ;--------------------------------------------------------------------------- _TEXT segment para public 'CODE' assume cs:_TEXT, ds:_DATA ; Program code ; ENTRY: cli ; Turn interrupts off. mov ax, _DATA ; Initialize segment registers mov ds, ax ; and so variables & stack are in mov ss, ax ; in segment _DATA, program code is mov sp, offset TOS ; in segment _TEXT. ; mov N, 0 ; N = 0; ; mov dx, KEY_CON ; outportb(KEY_CON, 0x92); mov al, 92H ; Initialize port KEY_PC as out dx, al ; a simple O/P port. call INT_VECT_INIT ; Initialize interrupt vector table. sti ; Unmask interrupts. call TIMER_80188_INIT ; Initialize 80188 timer. call INT_CON_INIT ; Initialize 80C188 interrupt controllers. ; HERE: mov ax, 5000 ; call DELAY ; while(TRUE) { jmp HERE ; delay(5000); ; } and ax, 7FH ; Gracefully return to push ax ; the debug/monitor. xor bx, bx ; mov es, bx ; pushf ; push bx ; push bx ; jmp dword ptr es:[000CH] ; ;--------------------------------------------------------------------------- TIMER_80188_INT_HANDLER proc far push ax ; Save status push dx ; ; mov dx, KEY_PC ; Toggle LED 5 of port KEY_PC. in al, dx ; xor al, 20H ; out dx, al ; ; add N, 1 ; N++; cmp N, 80 ; if (N > 80) { jc T0 ; ; mov dx, TCUCON ; mov ax, 0009H ; outport(TCUCON, 0x0009) out dx, ax ; Turn 80188 TIMER1 interrupt off. ; } T0: mov dx, EOI ; outport(EOI, 8) mov ax, 0008H ; Specific EOI for TIMER1 out dx, ax ; Reqired TYPE = 08D for all TIMERS. ; pop dx ; Restore status. pop ax ; iret ; Return from interrupt handler. TIMER_80188_INT_HANDLER endp ;--------------------------------------------------------------------------- INT_VECT_INIT proc near ; Initialize Interrupt Vector Table. push ds push bx push ax mov ax, 0 mov ds, ax mov bx, IT_TYPE*4 mov word ptr [bx], offset TIMER_80188_INT_HANDLER mov word ptr [bx+2], seg TIMER_80188_INT_HANDLER pop ax pop bx pop ds ret INT_VECT_INIT endp ;--------------------------------------------------------------------------- TIMER_80188_INIT proc near ; { ; Initialize the 80C188XL internal TIMER-COUNTER and INTERRUPT CONTROLLER ; for a 2.0 Hz. periodic interrupt. Refer to Chapter 8 and 9 in the ; 80C188XL/80C186XL Microprocessor Unsers Manual. mov dx, T2CNT ; Clear TIMER2 count register. mov ax, 0 ; out dx, ax ; ; mov dx, T1CNT ; Clear TIMER2 count register. mov ax, 0 ; out dx, ax ; ; mov dx, T2CMPA ; Set TIMER2 COUNT value to time-out mov ax, 20000 ; periodically at 4 MHz/20000 = 200 Hz. out dx, ax ; ; mov dx, T1CMPA ; TIMER1 is programmed to generate mov ax, 50 ; a periodic interrupt at 200 Hz/100 out dx, ax ; = 4 Hz. ; mov dx, T1CON ; TIMER1 control word for enabling mov ax, 0E009H ; interrupt generation and pre-scaling out dx, ax ; by TIMER2. ; mov dx, T2CON ; TIMER2 control word for continuous mov ax, 0C001H ; counting. out dx, ax ; ; ret ; ; } TIMER_80188_INIT endp ;--------------------------------------------------------------------------- INT_CON_INIT proc near ; Initialize 80C188 interrupt controller. ; mov dx, TCUCON ; Set up interrupt controller and mov ax, 0001H ; unmask internal timer interrupts out dx, ax ; with priority 001. ret INT_CON_INIT endp ;--------------------------------------------------------------------------- DELAY proc near ; Software delay. ; cmp ax, 0 ; Subtract 1 from ax until 0. jz D3 ; D0: mov bx, 375; D1: cmp bx, 0 jz D2 sub bx, 1; jmp D1 D2: sub ax, 1 jnz D0 D3: ret DELAY endp _TEXT ends ; end ENTRY ; ENTRY is the label of the first ; instruction of the program.