; Registers: ; B: minutes ; C: hours ; E: seconds ; D: flags BLINK_ON_BIT EQU 0 BLINK_ALL_BIT EQU 1 PM_BIT EQU 2 MIN_BUTTON_BIT EQU 3 HOUR_BUTTON_BIT EQU 4 TIMER_0 EQU 08h TIMER_1 EQU 09h TIMER_2 EQU 0Ah TIMER_CNTRL EQU 0Bh DISPLAY EQU 00h BUTTONS EQU 04h DISP_ON EQU 0Dh DISP_OFF EQU 0Ch RESET_DISP EQU 0Ah INC_DISP EQU 08h DEC_DISP EQU 09h BLANK_ZERO EQU 0Eh SHOW_ZERO EQU 0Fh LAMP_TEST EQU 0Bh AM_COLON_ON EQU 04h AM_COLON_OFF EQU 01h PM_COLON_ON EQU 08h PM_COLON_OFF EQU 07h COLON_AM_PM EQU 00h MINUTE_LOW EQU 01h MINUTE_HIGH EQU 02h HOUR_LOW EQU 03h HOUR_HIGH EQU 04h SET_BUTTON EQU 0 MIN_BUTTON EQU 1 HOUR_BUTTON EQU 2 NUM_SECONDS EQU 60 ORG 0 DI JP INIT ; interrupt handler ORG 38h DI ; check for button press IN A, (BUTTONS) BIT SET_BUTTON, A JP Z, BUTTON_HANDLER RES MIN_BUTTON_BIT, D RES HOUR_BUTTON_BIT, D ; update time ; update minutes DEC E JP NZ, BLINK LD E, 2*NUM_SECONDS INC B LD A, B AND A, 0Fh CP 0Ah JP NZ, REFRESH_MIN LD A, B AND A, F0h ADD A, 10h LD B, A CP 60h JP NZ, REFRESH_MIN LD B, 00h ; update hours INC C LD A, C CP 0Ah JP Z, SET_TO_TEN CP 13h JP Z, SET_TO_ONE CP 12h JP Z, UPDATE_AM_PM JP REFRESH_HOUR SET_TO_TEN: LD C, 10h JP REFRESH_HOUR SET_TO_ONE: LD C, 01h JP REFRESH_HOUR ; reverse pm bit UPDATE_AM_PM: BIT PM_BIT, D JP NZ, SET_AM SET PM_BIT, D BIT BLINK_ALL_BIT, D JP Z, REFRESH_HOUR LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP NOP LD A, PM_COLON_ON OUT (DISPLAY), A NOP NOP NOP NOP JP REFRESH_HOUR SET_AM: RES PM_BIT, D BIT BLINK_ALL_BIT, D JP Z, REFRESH_HOUR LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP NOP LD A, AM_COLON_ON OUT (DISPLAY), A NOP NOP NOP NOP JP REFRESH_HOUR REFRESH_MIN: LD A, MINUTE_LOW OUT (DISPLAY), A NOP NOP NOP NOP LD A, B OUT (DISPLAY), A NOP NOP NOP NOP LD A, MINUTE_HIGH OUT (DISPLAY), A LD A, B SRA A SRL A SRL A SRL A NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP JP BLINK REFRESH_HOUR: LD A, HOUR_LOW OUT (DISPLAY), A NOP NOP NOP NOP LD A, C OUT (DISPLAY), A NOP NOP NOP NOP LD A, HOUR_HIGH OUT (DISPLAY), A LD A, C SRA A SRL A SRL A SRL A NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP JP REFRESH_MIN ; handle blinking BLINK: BIT BLINK_ALL_BIT, D JP NZ, BLINK_ALL BIT BLINK_ON_BIT, D JP NZ, BLINK_OFF BLINK_ON: SET BLINK_ON_BIT, D LD A, COLON_AM_PM OUT (DISPLAY), A LD A, AM_COLON_ON BIT PM_BIT, D JP Z, AM_ON LD A, PM_COLON_ON AM_ON: NOP NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP JP EOI BLINK_OFF: RES BLINK_ON_BIT, D LD A, COLON_AM_PM OUT (DISPLAY), A LD A, AM_COLON_OFF BIT PM_BIT, D JP Z, AM_OFF LD A, PM_COLON_OFF AM_OFF: NOP NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP JP EOI BLINK_ALL: BIT BLINK_ON_BIT, D JP NZ, BLINK_ALL_OFF SET BLINK_ON_BIT, D LD A, DISP_ON OUT (DISPLAY), A NOP NOP NOP NOP JP EOI BLINK_ALL_OFF: RES BLINK_ON_BIT, D LD A, DISP_OFF OUT (DISPLAY), A NOP NOP NOP NOP JP EOI ; end of interrupt EOI: EI HALT BUTTON_HANDLER: BIT BLINK_ON_BIT, D JP NZ, ALREADY_ON BIT BLINK_ALL_BIT, D JP NZ, ON_FROM_OFF LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP LD A, AM_COLON_ON BIT PM_BIT, D JP Z, ON_FROM_AM LD A, PM_COLON_ON ON_FROM_AM: OUT (DISPLAY), A NOP NOP NOP JP ALREADY_ON ON_FROM_OFF: SET BLINK_ALL_BIT, D LD A, DISP_ON OUT (DISPLAY), A NOP NOP NOP ALREADY_ON: RES BLINK_ALL_BIT, D SET BLINK_ON_BIT, D LD E, 2*NUM_SECONDS IN A, (BUTTONS) BIT MIN_BUTTON, A JP Z, SET_MIN BIT HOUR_BUTTON, A JP Z, SET_HOUR RES MIN_BUTTON_BIT, D RES HOUR_BUTTON_BIT, D JP EOI SET_MIN: RES HOUR_BUTTON_BIT, D INC B LD A, B AND A, 0Fh CP 0Ah JP NZ, MIN_OK LD A, B AND A, F0h ADD A, 10h LD B, A CP 60h JP NZ, MIN_OK LD B, 00h MIN_OK: LD A, MINUTE_LOW OUT (DISPLAY), A NOP NOP NOP NOP LD A, B OUT (DISPLAY), A NOP NOP NOP NOP LD A, MINUTE_HIGH OUT (DISPLAY), A LD A, B SRA A SRL A SRL A SRL A NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP LD H, 1Fh BIT MIN_BUTTON_BIT, D JP NZ, SET_MIN_LOOP1 LD H, 7Fh SET MIN_BUTTON_BIT, D SET_MIN_LOOP1: LD A, FFh SET_MIN_LOOP2: DEC A JP NZ, SET_MIN_LOOP2 IN A, (BUTTONS) BIT MIN_BUTTON, A JP Z, MIN_DOWN RES MIN_BUTTON_BIT, D JP EOI MIN_DOWN: DEC H JP NZ, SET_MIN_LOOP1 JP EOI SET_HOUR: INC C LD A, C CP 0Ah JP Z, HBTN_SET_TEN CP 12h JP Z, HBTN_SET_AM_PM CP 13h JP NZ, HOUR_OK LD C, 01h JP HOUR_OK HBTN_SET_TEN: LD C, 10h JP HOUR_OK HBTN_SET_AM_PM: BIT PM_BIT, D JP Z, HBTN_PM_ON RES PM_BIT, D LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP NOP LD A, AM_COLON_ON OUT (DISPLAY), A NOP NOP NOP NOP JP HOUR_OK HBTN_PM_ON: SET PM_BIT, D LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP NOP LD A, PM_COLON_ON OUT (DISPLAY), A NOP NOP NOP NOP HOUR_OK: LD A, HOUR_LOW OUT (DISPLAY), A NOP NOP NOP NOP LD A, C OUT (DISPLAY), A NOP NOP NOP NOP LD A, HOUR_HIGH OUT (DISPLAY), A LD A, C SRA A SRL A SRL A SRL A NOP NOP NOP OUT (DISPLAY), A NOP NOP NOP NOP LD H, 1Fh BIT HOUR_BUTTON_BIT, D JP NZ, SET_HOUR_LOOP1 LD H, 7Fh SET HOUR_BUTTON_BIT, D SET_HOUR_LOOP1: LD A, FFh SET_HOUR_LOOP2: DEC A JP NZ, SET_HOUR_LOOP2 IN A, (BUTTONS) BIT HOUR_BUTTON, A JP Z, HOUR_DOWN RES HOUR_BUTTON_BIT, D JP EOI HOUR_DOWN: DEC H JP NZ, SET_HOUR_LOOP1 JP EOI ; initialization INIT: LD B, 00h LD C, 12h LD D, 00h LD E, 2*NUM_SECONDS ;SET BLINK_ON_BIT, D SET BLINK_ALL_BIT, D ; program counter 0 for mode 2 LD A, 34h OUT (TIMER_CNTRL), A ; load count (divide by 8 = 0008h) LD A, 08h OUT (TIMER_0), A LD A, 00h OUT (TIMER_0), A ; program counter 1 for mode 2 LD A, 74h OUT (TIMER_CNTRL), A ; load count (divide by 62500 = F424h) LD A, 24h OUT (TIMER_1), A LD A, F4h OUT (TIMER_1), A ; program counter 2 for mode 5 LD A, BAh OUT (TIMER_CNTRL), A ; load count 96h = 1200 microsecond delay) LD A, 96h OUT (TIMER_2), A LD A, 00h OUT (TIMER_2), A ; initialize display LD A, RESET_DISP OUT (DISPLAY), A NOP NOP NOP LD A, DISP_OFF OUT (DISPLAY), A NOP NOP NOP LD A, BLANK_ZERO OUT (DISPLAY), A NOP NOP NOP ; turn on colon and turn off pm light LD A, COLON_AM_PM OUT (DISPLAY), A NOP NOP NOP LD A, AM_COLON_ON OUT (DISPLAY), A NOP NOP NOP ; display first digit LD A, MINUTE_LOW OUT (DISPLAY), A NOP NOP NOP LD A, 00h OUT (DISPLAY), A NOP NOP NOP ; display second digit LD A, MINUTE_HIGH OUT (DISPLAY), A NOP NOP NOP LD A, 00h OUT (DISPLAY), A NOP NOP NOP ; display third digit LD A, HOUR_LOW OUT (DISPLAY), A NOP NOP NOP LD A, 02h OUT (DISPLAY), A NOP NOP NOP ; display last digit LD A, HOUR_HIGH OUT (DISPLAY), A NOP NOP NOP LD A, 01h OUT (DISPLAY), A NOP NOP NOP ; enable interrupts and halt LD A, DISP_ON OUT (DISPLAY), A NOP NOP NOP IM 1 EI HALT END