Jam Digital (assembler)

*** NeoClock1.asm
*** KX8 Digital Clock
*** Purpose: Introduction 2 Assembly
*** Device: 68HC908KX8
*** Assembler: CASM @ WIN IDE pemicro
* Description: On Main Loop: Count Time, Display Time.
* On Interrupt: Timer using ICG (Internal Clock Generator).

*** MACRO DEFINITIONS ***********************************************************
* Combine 2 parameter (bit & byte) to single parameter (bitname)
* Based on Macro by Raymond Weisling.
*********************************************************************************
$MACRO bitset bitname
bset %1-(%1\8)*8,%1\8
$MACROEND
$MACRO bitclr bitname
bclr %1-(%1\8)*8,%1\8
$MACROEND
$MACRO braset bitname,bradest
brset %1-(%1\8)*8,%1\8,%2
$MACROEND
$MACRO braclr bitname,bradest
brclr %1-(%1\8)*8,%1\8,%2
$MACROEND

*** Start Of Equates ************************************************************
* INPUT/OUTPUT PORTS
PORTA equ $00 ; Port A x-x-x-PA4-PA0 x = unused (R/W).
SW2 equ PORTA*8+0 ; Switch to change Time display.
PORTB equ $01 ; Port B PB7..PB0 (R/W).
DDRA equ $04 ; Port A Data Direction Reg DDRA4-0 (R/W).
DDRB equ $05 ; Port B Data Direction Reg DDRB7-0 (R/W).
PTAPUE equ $0D ; Port A In Pullup Enable PTAPUE4-0 (R/W).
* TIME BASE (TBM)
TBCR equ $1C ; Timebase Control Register.
TACK equ TBCR*8+3 ; Timebase ACKnowledge (W).
* EXTERNAL INTERRUPT (IRQ)
ISCR equ $1D ; IRQ Status and Control Register.
IRQF1 equ ISCR*8+3 ; IRQ1 Flag (R).
ACK1 equ ISCR*8+2 ; IRQ1 Interrupt Request Acknowledge (W).
IMASK1 equ ISCR*8+1 ; IRQ1 Interrupt Mask (R/W).
MODE1 equ ISCR*8+0 ; IRQ1 Edge/Level Select (R/W).
* CONFIGURATION REGISTER (CONFIG)
CONFIG2 equ $1E ; Configuration Register 2 (R/W).
CONFIG1 equ $1F ; Configuration Register 1 (R/W).
* TIMER
TSC equ $20 ; Timer Status and Control Register.
TOF equ TSC*8+7 ; Timer Overflow Flag (R).
TSTOP equ TSC*8+5 ; Timer STOP bit, stops the timer counter.
*** End Of Equates ************************************************************

$BASE 10T ; Change default base to decimal

RAM equ $0040 ; Beginning of RAM.
* RAM ($0040 – $00FF) 192 Bytes
org RAM
Jam10 ds 1 ; Jam Puluhan
Jam1 ds 1 ; Jam Satuan
Menit10 ds 1 ; Menit Puluhan
Menit1 ds 1 ; Menit Satuan
Detik10 ds 1 ; Detik Puluhan
Detik1 ds 1 ; Detik Satuan
Tick ds 1 ; Second Prescaler
Dig2Disp ds 1 ; Digit Seq to display (0 -3 format)
Dig2Fire ds 1 ; Digit to fire (bit format 1110x – 0111x)
Flags ds 1 ; Flag Register.
DoSec equ Flags*8+0 ; Time to play time 🙂

FLASHROM equ $E000 ; Beginning of Flash ROM
* FLASH-ROM ($E000 – $FDFF) 7680 Bytes
org FLASHROM
Reset
Init rsp ; Reset Stack Pointer to default address.
mov #1,CONFIG1 ; cop disable (belum perlu untuk dipakai)
mov #0,CONFIG2 ; untuk memastikan semua pada settingnya
Init_I/O clr PORTA ; PortA all zero
mov #0,PORTB ; PortB all zero
Init_DDR mov #$1E,DDRA ; PTA0 = Input, PTA1-4 = Output
mov #$FF,DDRB ; All Output
Init_PullUp mov #$01,PTAPUE ; PTA0 Pull-Up Resistor activated
Init_RAM ldhx #$00FF-$003F ; prepair index counter to clear RAM
Init_loop clr $3F,x ; clear one by one
dbnzx Init_loop ; until all erased
Init_Timer mov #$70,TSC ; Timer Setup. Reset cnt, no prescale.
bitclr TSTOP ; Clear Timer Stop Bit to start count.
Init_Clock mov #1,Jam10 ; Start Jam dengan
mov #2,Jam1 ; 12 : 00
mov #25,Tick ; untuk detik pertama

cli ; clear interrupt mask (now interrupt enable)

*** MAIN LOOP ******************************************************************
MAIN braclr DoSec,MAIN6 ; if Second task time,
bitclr DoSec ; .. clear flag first
jsr SecondJob ; .. Increment Time Register
MAIN6 jsr DisplayJob ; else, Display Time
bra MAIN ; make a loop

*** Second Task ****************************************************************
*** SecondJob bekerja setiap second untuk menaikkan angka detik.
*** Bila Detik mencapai 60, jadikan 0 dan naikkan menit.
*** Bila Menit mencapai 60, jadikan 0 dan naikkan jam.
*** Bila Jam mencapai 24, jadikan 0.
SecondJob inc Detik1 ; tambah detik satuan
lda Detik1 ; check detik satuan
cmp #10 ; if belum 10
bne Sec99 ; .. keluar (Sec99), else
clr Detik1 ; jadikan detik satuan = 0
inc Detik10 ; tambah detik puluhan
lda Detik10 ; check detik puluhan
cmp #6 ; if belum 6
bne Sec99 ; .. keluar (Sec99), else
clr Detik10 ; jadikan detik puluhan = 0
inc Menit1 ; tambah menit satuan
lda Menit1 ; check menit satuan
cmp #10 ; if belum 10
bne Sec99 ; .. keluar (Sec99), else
clr Menit1 ; jadikan menit satuan = 0
inc Menit10 ; tambah menit puluhan
lda Menit10 ; check menit puluhan
cmp #6 ; if belum 6
bne Sec99 ; .. keluar (Sec99)
clr Menit10 ; jadikan menit puluhan
inc Jam1 ; tambah jam satuan
lda Jam1 ; check jam satuan
cmp #10 ; if belum 10
bne Sec50 ; .. check = 24 ? (Sec50), else
clr Jam1 ; jadikan jam satuan = 0
inc Jam10 ; tambah jam puluhan
bra Sec99 ; keluar (Sec99)

* jika jam sudah 24 maka di reset menjadi 0
Sec50 lda Jam1 ; check jam satuan
cmp #4 ; if bukan 4
bne Sec99 ; .. keluar (Sec99), else
lda Jam10 ; selanjutnya check jam puluhan
cmp #2 ; if bukan 2
bne Sec99 ; .. keluar (Sec99), else
clr Jam1 ; jadikan jam satuan = 0
clr Jam10 ; jadikan jam puluhan = 0

Sec99 rts ; Quit

*** Display Task ***************************************************************
*** DisplayJob bekerja setiap loop untuk menampilkan Detik, Menit, Jam.
*** Setiap loop menampilkan 1 digit dan bertahan sampai beberapa waktu sebelum
*** tampilan digit selanjutnya dilaksanakan.
DisplayJob inc Dig2Disp ; inc giliran Digit yang akan diproses
lda Dig2Disp ; check giliran
cmp #4 ; if = 4
bne Disp30 ; .. 4 is invalid, so
clr Dig2Disp ; .. clear giliran

Disp30 ldx Dig2Disp ; use Dig2Disp as pointer to
lda DigTable,x ; get Digit # to display (in bit pattern)
sta Dig2Fire ; save it temporarily

lda #%00011110 ; 1 @ PTA0-4
sta PortA ; kill all digit first to avoid ghost.

ldx Dig2Disp ; use Dig2Disp as pointer to get

DispMode braset SW2,Disp70 ; but if Sw2 On or Jumper 3 On,
incx ; .. Move pointer Jam10-Menit1 -> Menit10-Detik1
incx ; .. by increment Pointer 2 byte.

Disp70 ldx Jam10,x ; value to display, use as pointer to
lda SegTable,x ; get Segment pattern
sta PortB ; send to PortB

lda Dig2Fire ; get Digit in charge
sta PortA ; turn it on
rts ; Quit
***************
DigTable fcb $1C ; Digit # 1 = Jam10 or Menit10
fcb $1A ; Digit # 2 = Jam1 or Menit1
fcb $16 ; Digit # 3 = Menit10 or Detik10
fcb $0E ; Digit # 4 = Menit1 or Detik1

* Segment information for Decimal Value. Segment-> gfa bedc 1 = Off, 0 = On except PB7.
SegTable fcb $40 ; 0 0100 0000
fcb $76 ; 1 0111 0110
fcb $21 ; 2 0010 0001
fcb $24 ; 3 0010 0100
fcb $16 ; 4 0001 0110
fcb $0C ; 5 0000 1100
fcb $08 ; 6 0000 1000
fcb $66 ; 7 0110 0110
fcb $00 ; 8 0000 0000
fcb $04 ; 9 0000 0100

*** TIMOverFloISR Task ********************************************************
* Aktif apabila counter yang membagi Internal Clock menghasilkan Overflow
* Cara mudah menghasilkan periodic event
TIMovISR lda TSC ; Clr int by read TSC reg & clear
bitclr TOF ; Timer Overflow Flag (TOF).

dec Tick ; Use Tick Register as counter
bne TimExit ; to devide TimerOverFlow event
lda #25 ; by 25
sta Tick ; to create about (not accurate)
bitset DoSec ; 1 Second Event
TimExit
DummyISR rti ; Quit

*** Interrupt Vector Table ****************************************************
org $FFF2
TimerInt dw TIMovISR ; $FFF2-FFF3 TIM Overflow Vector

org $FFF6
Security dw DummyISR ; $FFF6-FFF7 TIM Channel 0
dw DummyISR ; $FFF8-FFF9 CMIREQ Vector
dw DummyISR ; $FFFA-FFFB IRQ 1 Vector
dw DummyISR ; $FFFC-FFFD SWI Vector

org $FFFE
dw Reset ; $FFFE-FFFF RESET Vector
END.
************************************************************************************

S113E0009C6E011F6E001E3F006E00016E1E046EAA
S113E010FF056E010D4500C06F3F5BFC6E70201B59
S113E020206E01406E02416E19469A01490511495C
S113E030CDE038CDE07F20F33C45B645A10A263E2D
S113E0403F453C44B644A10626343F443C43B643D2
S113E050A10A262A3F433C42B642A10626203F425B
S113E0603C41B641A10A26063F413C402010B6413E
S113E070A104260AB640A10226043F413F40813C48
S113E08047B647A10426023F47BE47D6E0A7B74894
S113E090A61EB700BE470000025C5CEE40D6E0ABB3
S113E0A0B701B648B700811C1A160E407621241613
S113E0B00C08660004B6201F203A462606A619B7A7
S107E0C04610498039
S105FFF2E0B574
S10BFFF6E0C3E0C3E0C3E0C373
S105FFFEE0001D
S9030000FC

File S19 untuk dibandingkan dengan file S19 hasil assembling.

==================================gambar=================================
7-segment-info

dc-buzzer
kx8-digital-clock