Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
Software
Beiträge im Thema:
10
Erster Beitrag:
vor 1 Jahr, 10 Monaten
Letzter Beitrag:
vor 1 Jahr
Beteiligte Autoren:
Robin Tönniges, Dennis Kuschel

User Written Programs

Startbeitrag von Robin Tönniges am 10.01.2016 14:05

Hi MyCPU-User,

I think it would be nice if user who developed their own programs would upload their work so it may be useful for other people.

Antworten:

MAX542 Library

This is my lib for a MAX542 (16bit DAC).

I've tested it with the Adress 3000h but the Multi-IO outputs will also work.

sl30max542.asm

;[ASCII]

;******************************************
;*********** MAX542 Driver **************
;******************************************
;******* 2016 by Robin Tönniges *********
;******************************************

;Include
#include
#include

;Declare variables
MAX542 SET 3000h ;MAX542 adress

;Bits
CSn SET 01h ;D0
SCLK SET 02h ;D1
DOUT SET 04h ;D2

;Bit counter
BCNT DB 80h

;DAC Data, high and low Byte
DDATA DS 2

;Program start
codestart
#include ;include library source code

initfunc
JSR csHigh
CLA
RTS

termfunc
JMP csHigh

funcdispatch
STXA DDATA
STYA DDATA+1
DEC ;Accu = 1
JPZ setOutput ;Set output to 16bit value in X,Y-Register
DEC ;Accu = 2
JPZ setMin ;Set output to min value X,Y = 0000h
DEC ;Accu = 3
JPZ setMax ;Set output to max value X,Y = FFFFh
RTS


setOutput
;Load high byte
_lhb LDAA BCNT
ANDA DDATA+1
JSR tData
SHRA BCNT
JNZ _lhb

LDA #80h
STAA BCNT

;Load low byte
_llb LDAA BCNT
ANDA DDATA
JSR tData
SHRA BCNT
JNZ _llb

csHigh LDA #CSn
STAA MAX542
RTS

setMin
LDA #00h
STAA DDATA
STAA DDATA+1
JMP setOutput

setMax
LDA #FFh
STAA DDATA
STAA DDATA+1
JMP setOutput

tData
JNZ _tData0
CLA ;DOUT = low
STAA MAX542
LDA #SCLK
STAA MAX542
JMP _tData1
_tData0 LDA #DOUT ;DOUT = high
STAA MAX542
LDA #SCLK | DOUT
STAA MAX542
_tData1 CLA
STAA MAX542
RTS



Here is a simple program that uses the lib.

dac.asm

;[ASCII]

;Include
#include
#include
#include
#include

;Declare variables
paramPtr DW 0

DACLIB SET 30h

;Program start
codestart

main
;Get parameters from the console
skipPar LPA
JPZ _RTS
CMP #20h
JNZ skipPar

_skp0 SPTA paramPtr
LPA
JPZ _RTS
CMP #20h
JPZ _skp0

LPTA paramPtr
JSR (KERN_STRING2NUMBER)
SAY
SXY
PHR
;Load DAC Library
LDA #DACLIB
JSR (KERN_LIBSELECT)

PLR
LDA #1 ;Function 1 = setOutput to number in X,Y-Reg
JSR (KERN_LIBCALL)

CLA
_RTS RTS


von Robin Tönniges - am 10.01.2016 14:09

7-Segment Library

This lib ist for displaying an 8-bit number to a 2-digit 7-Segment display.

You can chose between an output in hex or dec.


sl50seg7.asm

;[ASCII]

;******************************************
;******* 2x7Seg-Display Driver **********
;******************************************
;******* 2016 by Robin Tönniges *********
;******************************************

;D0 = a
;D1 = b
;D2 = c
;D3 = d
;D4 = e
;D5 = f
;D6 = g
;D7 = dot

;Include
#include
#include

;Declare variables
DISPLAY EQU 3000h ;7Segement display adress (3000h - 3001h)

;Constants for diplay with common anode!
CONST_0 EQU C0h
CONST_1 EQU F9h
CONST_2 EQU A4h
CONST_3 EQU B0h
CONST_4 EQU 99h
CONST_5 EQU 92h
CONST_6 EQU 82h
CONST_7 EQU F8h
CONST_8 EQU 80h
CONST_9 EQU 90h
CONST_A EQU 88h
CONST_B EQU 83h
CONST_C EQU C6h
CONST_D EQU A1h
CONST_E EQU 86h
CONST_F EQU 8Eh

;Program start
codestart
#include ;include library source code

initfunc
JSR clearDisplay
CLA
RTS

termfunc
CLA
RTS

funcdispatch
DEC ;Accu = 1
JPZ dispHex
DEC ;Accu = 2
JPZ dispDec
DEC ;Accu = 3
JPZ clearDisplay
RTS

dispHex
SAX
;low nibble
PHA
AND #0Fh
JSR getSeg
STAA DISPLAY

;high nibble
PLA
SWP
AND #0Fh
JSR getSeg
STAA DISPLAY+1
RTS

dispDec
SAX
;Einer
PHA
MOD #10
AND #0Fh
JSR getSeg
STAA DISPLAY

;Zehner
PLA
DIV #10
AND #0Fh
JSR getSeg
STAA DISPLAY+1
RTS

clearDisplay
LDA #FFh
STAA DISPLAY
LDA #FFh
STAA DISPLAY+1
RTS

getSeg
CMP #00h
JNZ _01
LDA #CONST_0
JMP _RTS
_01 CMP #01h
JNZ _02
LDA #CONST_1
JMP _RTS
_02 CMP #02h
JNZ _03
LDA #CONST_2
JMP _RTS
_03 CMP #03h
JNZ _04
LDA #CONST_3
JMP _RTS
_04 CMP #04h
JNZ _05
LDA #CONST_4
JMP _RTS
_05 CMP #05h
JNZ _06
LDA #CONST_5
JMP _RTS
_06 CMP #06h
JNZ _07
LDA #CONST_6
JMP _RTS
_07 CMP #07h
JNZ _08
LDA #CONST_7
JMP _RTS
_08 CMP #08h
JNZ _09
LDA #CONST_8
JMP _RTS
_09 CMP #09h
JNZ _0A
LDA #CONST_9
JMP _RTS
_0A CMP #0Ah
JNZ _0B
LDA #CONST_A
JMP _RTS
_0B CMP #0Bh
JNZ _0C
LDA #CONST_B
JMP _RTS
_0C CMP #0Ch
JNZ _0D
LDA #CONST_C
JMP _RTS
_0D CMP #0Dh
JNZ _0E
LDA #CONST_D
JMP _RTS
_0E CMP #0Eh
JNZ _0F
LDA #CONST_E
JMP _RTS
_0F CMP #0Fh
JNZ _RTS
LDA #CONST_F

_RTS RTS



von Robin Tönniges - am 10.01.2016 14:24
Hi Robin,

thank you for your contribution. I hope that many users will follow your example and will also post there projects here.

I have found one problem in your source codes: That is the way you deal with zero-page addresses. Zero-page memory is expensive, so you should only use it if you really have to. Otherwise use your local program's storage.

If you have to use zero-page memory, please follow these guidelines:

In your program above you are using

ZP_paramPtr SET 00h

This declaration is wrong and will screw up the MyCPU's Operating System, because it will lead to overwritten bytes in the zero-page that are used by the OS. Please use only the address locations 10h - 2Fh, these are save for user application programs. Note that the program loader will re-assign these addresses, so if you have two libraries using 10h, one lib will get the 10h and the other lib will get the next free address, lets say 11h.
Also it is important that you reference every used zero-page-address one time before you use it. So, please write for example:


main
FLG ZP_paramPtr
FLG ZP_paramPtr+1
skipPar LPA
JPZ _RTS
CMP #20h
JNZ skipPar


This will help the program-loader to figure out which memory locations are used in your program.

von Dennis Kuschel - am 10.01.2016 14:52
Hi Dennis,

thank you for the hint!
I've changed it now.

The Adress range 00h-0Fh for the ZeroPages did I get from the sampleprog.asm in the RemoteFileServer-Directory.


;-------------------------------------;
; declare variables

;ZeropageVar EQU 00h ;(range 00h-0Fh)
;var1 DB 0 ;byte variable, initialize with 0
;var2 DW 0 ;word variable, initialize with 0
;array5 DS 5 ;array of 5 bytes

string DB "\rHello World!\r",0 ;string constant


von Robin Tönniges - am 10.01.2016 17:30
Hi Robin,

indeed you were right, but I was confused :-)

Ok, lets bring some more light to this topic:

1) The zero-page-addresses 0x00 - 0x0F are reserved for user application programs like yours.
These address range is shared with all other user applications and should only be used for temporary storage.

2) The zero-page-addresses 0x10 - 0x2F are reserved for TSR programs like libraries.
This memory region is managed by the program loader and every TSR gets its own memory cells like I have written before.

So you where right to use the memory locations 0x00 and 0x01 in your "application" program.

von Dennis Kuschel - am 11.01.2016 06:06
Hello again,

I've found a DCF77-Receiver in my catacombs so I developed a little circuit (To convert flanks in pulses) and wrote a library to decode the Signal.
The schematic is attached as *.png.

EDIT: I've forgotten to say that the output from the "Flank-Puls" circuit have to be attached to IRQ7.
You can change this by editing CON_INT from 7 to any free Hardware-Interrupt.

Update 16.03.16: Little try to clean up the code and further signal checking to detect errors.
Update 17.03.16: Minutes and hours were load to early so 20:40:50 was load as 20:41:50....fixed
Update 18.03.16: Translated all comments into english
Update 29.03.16: Added option to display "synchronized" status on Multi-I/O-LEDs (default enabled)
Update 29.03.16: Little update to test-app and more comments
Update 31.03.16: Little bit code optimizing and fixed a bug in partity checking
Update 13.10.16: Updated status display on Multi-I/O and fixed error that couses BRK after LIB_CALL
Update 20.02.17: Many many code optimizations (Memory and speed) and bug fixes (Big bug causes library function only every second year :()
Update 24.02.17: More bug fixes and I've changed the LED-SyncDisplay (B4 = Sync status; B3 = Date status; B2 = Hour status; B1 = Minute status)
Update 03.05.17: Added option to select using the SCC-Board (default disabled)
Update 09.05.17: Fixed bug in "SYNC_DISP"

sl60dcf77.asm

;[ASCII]
;******************************************
;*********** DCF77 Library **************
;******************************************
;****** by Robin Tönniges (2017) ********
;******************************************

#include
#include
#include
#include

;Comment this line out if you dont want synced status on Multi-I/O-LEDs
#DEFINE SYNC_DISP
;Comment this line in if you use the SCC-Rack-Extension
;#DEFINE SCC_BOARD

;-------------------------------------;
; declare variables

;Zeropointer
ZP_temp1 EQU 10h

;Parameter
HDW_INT EQU 7 ;IRQ7
HDW_SCC_BOARD EQU 3000h ;Address of SCC board
KERN_IOCHANGELED EQU 0306h ;Kernel routine for changing the Multi-I/O-LEDs
PARAM_LOWHIGH EQU 4 ;Edge time < PARAM_LOWHIGH = 0(Low), >= PARAM_LOWHIGH = 1(High)
PARAM_SYNCPAUSE EQU 40 ;Edge time < PARAM_SYNCPAUSE = New second/bit, >= PARAM_SYNCPAUSE = Syncpoint
PARAM_SECOND EQU 20 ;Edge time < PARAM_SECOND = New bit, >= PARAM_SECOND = New second

;Variables
FLG_dcfReceiver DB 1 ;This flag is set to 1 if input comes from the DCF77-Receiver
FLG_synced DB 1 ;Sync flag -> 0 if synchron with dcf77
VAR_edgeCnt DB 0 ;Edge counter
VAR_dataOK DB 0 ;Parity check -> Bit 1 = Minutes OK, Bit 2 = Hours OK, Bit 3 = Date OK

VAR_pSecond DB 0 ;Pseudo second to bridge desynchronization
VAR_second DB 0 ;DCF77-Second/Bit counter

;Time variables initialized with FFh to "lock" Get-functions until 2nd synchronization point reached
VAR_minutes DB FFh
VAR_hours DB FFh

VAR_day DB FFh
VAR_weekday DB FFh
VAR_month DB FFh
VAR_year DB FFh

VAR_dateParity DB 0

VAR_tmpMinutes DB 0
VAR_tmpHours DB 0
VAR_tmpDay DB 0
VAR_tmpWeekday DB 0
VAR_tmpMonth DB 0
VAR_tmpYear DB 0
VAR_ledsDataOK DB 0

VAR_timerhandle DB 0 ;Address of timer interrupt handle



;-------------------------------------;
; begin of assembly code

codestart
#include
;---------------------------------------------------------
;Library handling
;---------------------------------------------------------

;Library initialization
;---------------------------------------------------------
initfunc

;Initialize zeropage variables
FLG ZP_temp1 ;Time between two interrupts (Value * 1/30.517578Hz)s
FLG ZP_temp1+1 ;Temporary data

;Enable hardware interrupt (IRQ7)
LDA #HDW_INT
LPT #int_dcf77
JSR (KERN_IC_SETVECTOR)
JSR (KERN_IC_ENABLEINT)

;Enable timer interrupt
CLA
LPT #int_timer
JSR (KERN_MULTIPLEX)
STAA VAR_timerhandle ;Save adress of timerhandle

;If sync display enabled clear LEDs
#IFDEF SYNC_DISP
CLA
JSR (KERN_IOCHANGELED)
#ENDIF
CLA
RTS

;Termination function
;---------------------------------------------------------
termfunc
;Disable timer-interrupt
LDA #1
LDXA VAR_timerhandle
JSR (KERN_MULTIPLEX)
;Disable hardware-interrupt
LDA #HDW_INT
JSR (KERN_IC_DISABLEINT)
;Disable spinlock
CLC
JSR (KERN_SPINLOCK)
;Set LEDs to default
#IFDEF SYNC_DISP
LDA #0FFh
JSR (KERN_IOCHANGELED)
#ENDIF
RTS

;Functiondispatch
;---------------------------------------------------------
funcdispatch
DEC
JPZ func_getSeconds ;Function 01h
DEC
JPZ func_getMinutes ;Function 02h
DEC
JPZ func_getHours ;Function 03h
DEC
JPZ func_getDay ;Function 04h
DEC
JPZ func_getWeekday ;Function 05h
DEC
JPZ func_getMonth ;Function 06h
DEC
JPZ func_getYear ;Function 07h
DEC
JPZ func_getEntryPoint ;Function 08h
JMP _failRTS


;Function '01h' = Get seconds (OUTPUT = Accu), Carry = 0 if successfull
func_getSeconds
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_second
JMP _RTS

;Function '02h' = Get minutes (OUTPUT = Accu), Carry = 0 if successfull
func_getMinutes
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #01h
JPZ _failRTS
LDAA VAR_minutes
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '03h' = Get hours (OUTPUT = Accu), Carry = 0 if successfull
func_getHours
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #02h
JPZ _failRTS
LDAA VAR_hours
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '04h' = Get day (OUTPUT = Accu), Carry = 0 if successfull
func_getDay
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #04h
JPZ _failRTS
LDAA VAR_day
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '05h' = Get weekday (OUTPUT = Accu), Carry = 0 if successfull
;1 = monday, 2 = tuesday, 3 = wednesday, 4 = thursday, 5 = friday, 6 = saturday, 7 = sunday
func_getWeekday
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #04h
JPZ _failRTS
LDAA VAR_weekday
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '06h' = Get month (OUTPUT = Accu), Carry = 0 if successfull
func_getMonth
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #04h
JPZ _failRTS
LDAA VAR_month
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '07h' = Get year (OUTPUT = Accu), Carry = 0 if successfull
func_getYear
LDAA FLG_synced
JNZ _failRTS
LDAA VAR_dataOK
AND #04h
JPZ _failRTS
LDAA VAR_year
CMP #FFh
JPZ _failRTS
JMP _RTS

;Function '08h' = Get entrypoint of library
func_getEntryPoint
LPT #funcdispatch
JMP _RTS

;---------------------------------------------------------
;Interrupt routines
;---------------------------------------------------------

;Receiver interrupt
int_dcf77
LDA #1
STAA FLG_dcfReceiver ;Flank detected -> Set flag
INCA VAR_edgeCnt ;Count edges (For signal error detection)
RTS

;Timer interrupt
int_timer
;Measure time between two edges
LDA FLG_dcfReceiver
JNZ decode
INC ZP_temp1
RTS

;---------------------------------------------------------
;DCF77 decoding
;---------------------------------------------------------
decode
;From this point no interrupt should break the programm
SEC
JSR (KERN_SPINLOCK) ;"You shall not pass"

;Synchronize with signal -> Detect syncpoint/-gap
LDA ZP_temp1
CMP #PARAM_SYNCPAUSE
JNC _dec0
;Time >= PARAM_SYNCPAUSE -> Time longer than 1 second
;Syncpoint reached
STZ FLG_synced
STZ VAR_second
STZ VAR_edgeCnt
JMP _decEnd

;Time < PARAM_SYNCPAUSE -> New second or bit information
;Count seconds, Check signal for errors
_dec0 CMP #PARAM_SECOND
JNC newBit
;Time >= PARAM_SECOND -> Next second
INCA VAR_second
JMP _decEnd

;Time < PARAM_SECOND -> New bit
newBit
;Display synced status on I/O-Module LEDs
#IFDEF SYNC_DISP
JSR syncDisp
#ENDIF
;Display synced status on SCC-Board
#IFDEF SCC_BOARD
JSR sccBoard
#ENDIF
;First do signal checking -> Twice as many edges+1 as seconds?
LDAA VAR_edgeCnt
SEC
SBC #1
DIV #2
CMPA VAR_second
JPZ _nBit0 ;Check successfull -> Go forward to bit checking

;No longer synchronized
deSync
LDA #1
STAA FLG_synced
STZ VAR_dataOK
STZ VAR_ledsDataOK
JMP _decEnd

;Decode bit
_nBit0
LDAA VAR_second
JNZ _nBit3
JSR getBit
JNZ deSync ;If Bit 0 != 0 -> Not synchronized or incorrect signal

;Second/bit = 0 -> Take over data from last minute
LDAA VAR_dataOK
AND #01h
JPZ _nBit1
LDAA VAR_tmpMinutes ;Take over 'minutes'
STAA VAR_minutes
_nBit1 LDAA VAR_dataOK
AND #02h
JPZ _nBit2
LDAA VAR_tmpHours ;Take over 'hours'
STAA VAR_hours
_nBit2 LDAA VAR_dataOK
AND #04h
JPZ _decEnd
LDAA VAR_tmpWeekday ;Take over 'weekday'
STAA VAR_weekday
LDAA VAR_tmpDay ;Take over 'day'
STAA VAR_day
LDAA VAR_tmpMonth ;Take over 'month'
STAA VAR_month
LDAA VAR_tmpYear ;Take over 'year'
STAA VAR_year
JMP _decEnd

_nBit3 CMP #20
JNC _decEnd ;Below bit 20 is nothing important
JNZ _nBit4
JSR getBit; Second/bit = 20 -> Begin of time information always '1'
JPZ deSync ;If Bit 20 != 1 -> Not synchronized or incorrect signal
JMP _decEnd

;Bit >20 - Get/decode data
_nBit4 LDAA FLG_synced
JNZ _decEnd
;Only continue if synchronized
LDAA VAR_second
CMP #29
JNC getMinutes ;Go to minute decoding
;Second >= 29
CMP #36
JNC getHours ;Go to hour decoding
;Second >= 36
CMP #42
JNC getDay ;Go to day decoding
;Second >= 42
CMP #45
JNC getWDay ;Go to weekday decoding
;Second >= 45
CMP #50
JNC getMonth ;Go to month decoding
;Second >= 50
CMP #59
JNC getYear ;Go to year decoding
JNZ _decEnd
;Second = 59 -> Leap second!
JSR getBit ;Always '0'
JNZ deSync
JMP _decEnd

;Get/decode minutes
;---------------------------------------------------------
getMinutes
CMP #28
JPZ parityMinutes ;Last bit -> Check parity
CMP #21
JNZ _gMin0
MOV ZP_temp1+1,#0 ;First bit -> Clear data

;Get bit (minutes)
_gMin0 JSR getBit
ORA ZP_temp1+1
SHR
STA ZP_temp1+1
JMP _decEnd

;Last bit
;Check parity (minutes)
parityMinutes
JSR getBit ;Get "Carry-Bit" and save it to stack for later use
PHA
;Determine if bitcount of data is even or odd
LDA ZP_temp1+1
LDX #7
CLY
JSR bitCnt
JPC _pMin0
PLA ;Bit count = "odd"
JNZ _pMinOK

_pMinBAD LDA #06h ;Parity n.OK
ANDA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd

_pMin0 PLA ;Bit count = "even"
JNZ _pMinBAD

_pMinOK LDA ZP_temp1+1 ;Parity OK
JSR bcdToDec
STAA VAR_tmpMinutes
LDA #01h
ORAA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd


;Get/decode hours
;---------------------------------------------------------
getHours
CMP #35
JPZ parityHours ;Last bit -> Check parity
CMP #29
JNZ _gHrs0
MOV ZP_temp1+1,#0 ;First Bit -> Clear data

;Get bit (hours)
_gHrs0 JSR getBit
ORA ZP_temp1+1
SHR
STA ZP_temp1+1
JMP _decEnd

;Last bit
;Check parity (hours)
parityHours
SHR ZP_temp1+1 ;Shift data right by 1

JSR getBit ;Get "Carry-Bit" and save it to stack for later use
PHA
;Determine if bitcount of data is even or odd
LDA ZP_temp1+1
LDX #6
CLY
JSR bitCnt
JPC _pHrs0
PLA ;Bit count = "odd"
JNZ _pHrsOK

_pHrsBAD LDA #05h ;Parity n.OK
ANDA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd

_pHrs0 PLA ;Bit count = "even"
JNZ _pHrsBAD

_pHrsOK LDA ZP_temp1+1 ;Parity OK
JSR bcdToDec
STAA VAR_tmpHours
LDA #02h
ORAA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd


;Get/decode day
;---------------------------------------------------------
getDay
CMP #36
JNZ _gDay0
MOV ZP_temp1+1,#0 ;First Bit -> Clear data

;Get bit (day)
_gDay0 JSR getBit
ORA ZP_temp1+1
SHR
STA ZP_temp1+1
;Check for last bit
LDAA VAR_second
CMP #41
JNZ _decEnd


;Last bit
SHR ZP_temp1+1 ;Shift data right by 1

;Count high bits and add it to "VAR_dateParity"
LDA ZP_temp1+1
LDX #6
CLY
JSR bitCnt
STAA VAR_dateParity
;Save day value
LDA ZP_temp1+1
JSR bcdToDec
STAA VAR_tmpDay
JMP _decEnd


;Get/decode weekday
;---------------------------------------------------------
getWDay
CMP #42
JNZ _getWDay0
MOV ZP_temp1+1,#0 ;First Bit -> Clear data

;Get bit (weekday)
_getWDay0 JSR getBit
ORA ZP_temp1+1
SHR
STA ZP_temp1+1
;Check for last bit
LDAA VAR_second
CMP #44
JNZ _decEnd

;Last bit
;Shift data right by 4
LDA ZP_temp1+1
DIV #10h
STA ZP_temp1+1

;Count high bits and add it to "VAR_dateParity"
LDX #3
LDYA VAR_dateParity
JSR bitCnt
STAA VAR_dateParity
;Save weekday value
LDA ZP_temp1+1
JSR bcdToDec
STAA VAR_tmpWeekday
JMP _decEnd


;Get/decode month
;---------------------------------------------------------
getMonth
CMP #45
JNZ _gMon0
MOV ZP_temp1+1 ,#0 ;First Bit -> Clear data

;Get bit (month)
_gMon0 JSR getBit
ORA ZP_temp1+1
SHR
STA ZP_temp1+1
;Check for last bit
LDAA VAR_second
CMP #49
JNZ _decEnd

;Last bit
;Shift data right by 2
SHR ZP_temp1+1
SHR ZP_temp1+1

;Count high bits and add it to "VAR_dateParity"
LDA ZP_temp1+1
LDX #5
LDYA VAR_dateParity
JSR bitCnt
STAA VAR_dateParity
;Save month value
LDA ZP_temp1+1
JSR bcdToDec
STAA VAR_tmpMonth
JMP _decEnd

;Get/decode year
;---------------------------------------------------------
getYear
CMP #58
JPZ parityDate ;Last bit -> Check parity
CMP #50
JNZ _gYear0
MOV ZP_temp1+1 ,#0 ;First Bit -> Clear data

;Get bit (year)
_gYear0 SHR ZP_temp1+1
JSR getBit
ORA ZP_temp1+1
STA ZP_temp1+1
JMP _decEnd

;Last bit
;Check parity for whole date (Day, weekday, month, year)
parityDate
JSR getBit ;Get "Carry-Bit" and save it to stack for later use
PHA
;Count high bits and add it to "VAR_dateParity"
;Determine if bitcount of "VAR_dateParity" is even or odd
LDA ZP_temp1+1
LDX #8
LDYA VAR_dateParity
JSR bitCnt
JPC _pDat0
PLA ;Bit count = "odd"
JNZ _pDateOK

_pDateBAD LDA #03h ;Partity n.OK
ANDA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd

_pDat0 PLA ;Bit count = "even"
JNZ _pDateBAD

_pDateOK LDA ZP_temp1+1 ;Parity OK
JSR bcdToDec
STAA VAR_tmpYear ;Save year value
LDA #04h
ORAA VAR_dataOK
STAA VAR_dataOK
JMP _decEnd


;Ready for next bit
_decEnd
STZ FLG_dcfReceiver ;Reset dcf77 interrupt flag
MOV ZP_temp1, #0 ;Reset Edge time
CLC
JSR (KERN_SPINLOCK) ;Enable the interrupts again
RTS

;---------------------------------------------------------
;Display snyc/data status on Multi-I/O LEDs
;---------------------------------------------------------
#IFDEF SYNC_DISP
syncDisp
;Display synced status
LDAA FLG_synced
JPZ _syncD0
LDA #08h
EORA VAR_ledsDataOK
STAA VAR_ledsDataOK
JMP _syncD4
_syncD0 LDA #08h
ORAA VAR_ledsDataOK
STAA VAR_ledsDataOK

LDAA VAR_second
CMP #21
JNC _syncD4 ;Second No time information fetching
CMP #29
JNC _syncD1 ;Second >= 21 & Fetching minutes
CMP #36
JNC _syncD2 ;Second >= 29 & < 36 -> Fetching hours
CMP #59
JNC _syncD3 ;Second >= 36 & < 59 -> Fetching date
JMP _syncD4

;Fetching minutes
_syncD1 LDAA VAR_dataOK
AND #01h
JNZ _syncD4
LDA #01h
EORA VAR_ledsDataOK
STAA VAR_ledsDataOK
JMP _syncD4

;Fetching hours
_syncD2 LDAA VAR_dataOK
AND #02h
JNZ _syncD4
LDA #02h
EORA VAR_ledsDataOK
STAA VAR_ledsDataOK
JMP _syncD4

;Fetching date
_syncD3 LDAA VAR_dataOK
AND #04h
JNZ _syncD4
LDA #04h
EORA VAR_ledsDataOK
STAA VAR_ledsDataOK

_syncD4 LDAA VAR_dataOK
ORAA VAR_ledsDataOK
JSR (KERN_IOCHANGELED)
RTS

#ENDIF

;---------------------------------------------------------
;Display snyc/data status on SCC-Board
;---------------------------------------------------------
#IFDEF SCC_BOARD
sccBoard
;Receiver not synced (LED off)
LDAA FLG_synced
JPZ _sccB0
LDAA HDW_SCC_BOARD
AND #04h
JPZ _RTS
LDAA HDW_SCC_BOARD
EOR #04h
STAA HDW_SCC_BOARD
RTS

;Receiver synced but no data available (Toggle LED)
_sccB0 LDAA VAR_dataOK
CMP #07h
JPZ _sccB1
LDAA HDW_SCC_BOARD
EOR #04h
STAA HDW_SCC_BOARD
RTS

;Receiver synced and data available (LED on)
_sccB1 LDAA HDW_SCC_BOARD
ORA #04h
STAA HDW_SCC_BOARD
RTS
#ENDIF

;---------------------------------------------------------
;Helper functions
;---------------------------------------------------------

;Get bit information from Time (Output: A = High(80h), Low(00h))
getBit
LDA ZP_temp1
CMP #PARAM_LOWHIGH
JNC _gBit0
;Time >= PARAM_LOWHIGH -> Bit = 1
LDA #80h
SKA
_gBit0 CLA ;Time < PARAM_LOWHIGH -> Bit = 0
RTS


;Count high bits
;Input: A = Byte, X = Number of bits, Y = Counter offset
;Output: A = Counter value, Carry = 0 -> odd, Carry = 1 -> even
bitCnt
_bCnt0 SHR
JNC _bCnt1
INY
_bCnt1 DXJP _bCnt0
SAY
PHA
MOD #2
JPZ _bCnt2
CLC ;Counter value "odd"
SKA
_bCnt2 SEC ;Counter value "even"
PLA
RTS


;Convert BCD to decimal (Input: A = BCD value) (Output: A = decimal vlaue)
VAR_tmpConvert DB 0
bcdToDec
PHA
DIV #10h
MUL #0Ah
STA ZP_temp1+1
PLA
AND #0Fh
CLC
ADC ZP_temp1+1
RTS


_RTS
CLC
RTS

_failRTS
CLA
SEC
RTS



And a little test app...
Input Parameter:
nothing = System time and date will be synchronized
1 = Display seconds
2 = Display minutes
3 = Display hours
4 = Display day
5 = Display weekday (1 = monday, 7 = sunday)
6 = Display month
7 = Display year

To use this programm first you have to start the sl60dcf77 library so it fetches data in the background.

dcf77_test.asm

;[ASCII]
;******************************************
;**** DCF77 Library - Test program *******
;******************************************
;****** by Robin Tönniges (2016) ********
;******************************************

;***********************************************
;*Parameter:
;*Nothing = Set system clock with DCF77 - Data
;*Number 1-7 = Display data set 1-7 from the library
;*Number 8 = Display current time and date
;*
;*
;*
;***********************************************

;Include
#include
#include
#include
#include
#include

;Declare variables
DCF77LIB EQU 60h

ZP_paramPtr EQU 00h

STR_done DB "System clock successfully set!",0
STR_fault DB "Receiver not synchronized or data incomplete!",0

VAR_seconds DB 0
VAR_minutes DB 0
VAR_hours DB 0
VAR_day DB 0
VAR_month DB 0
VAR_year DB 0


;---------------------------------------------------------
;Main program
;---------------------------------------------------------
codestart

main
FLG ZP_paramPtr ;Initialize zeropointer

;Get parameter from console
skipPar LPA
JPZ setSysTime
CMP #20h
JNZ skipPar

_skp0 SPT ZP_paramPtr
LPA
JPZ setSysTime ;No parameter -> set system clock
CMP #20h
JPZ _skp0

LPT ZP_paramPtr
JSR (KERN_STRING2NUMBER)
CMP #8
JPZ printTime ;Parameter '8' -> print date/time
PHA

;Parameter 0-7 -> Print data from library
LDA #DCF77LIB
JSR (KERN_LIBSELECT)
PLA
JSR (KERN_LIBCALL)
JPC printFault
CLX
CLY
JSR (KERN_PRINTDEZ)
CLA
RTS

setSysTime
LDA #DCF77LIB
JSR (KERN_LIBSELECT)
LDA #1 ;Seconds
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_seconds
LDA #2 ;Minutes
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_minutes
LDA #3 ;Hours
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_hours
LDA #4 ;Day
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_day
LDA #6 ;Month
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_month
LDA #7 ;Year
JSR (KERN_LIBCALL)
JPC printFault
STAA VAR_year

;Set system clock
LDAA VAR_hours
LDXA VAR_minutes
LDYA VAR_seconds
SEC
JSR (KERN_GETSETTIME)

LDAA VAR_day
LDXA VAR_month
LDYA VAR_year
SEC
JSR (KERN_GETSETDATE)

LPT #STR_done
JSR (KERN_PRINTSTR)
CLA
RTS

printTime
LDA #DCF77LIB
JSR (KERN_LIBSELECT)
LDA #3 ;Hours
JSR (KERN_LIBCALL)
JPC printFault
JSR leadingZero
CLX
CLY
JSR (KERN_PRINTDEZ)
LDA #':'
JSR (KERN_PRINTCHAR)
LDA #2 ;Minutes
JSR (KERN_LIBCALL)
JPC printFault
JSR leadingZero
CLX
CLY
JSR (KERN_PRINTDEZ)
LDA #':'
JSR (KERN_PRINTCHAR)
LDA #1 ;Seconds
JSR (KERN_LIBCALL)
JPC printFault
JSR leadingZero
CLX
CLY
JSR (KERN_PRINTDEZ)
LDA #13
JSR (KERN_PRINTCHAR)
LDA #4 ;Day
JSR (KERN_LIBCALL)
JPC printFault
JSR leadingZero
CLX
CLY
JSR (KERN_PRINTDEZ)
LDA #'.'
JSR (KERN_PRINTCHAR)
LDA #6 ;Month
JSR (KERN_LIBCALL)
JPC printFault
JSR leadingZero
CLX
CLY
JSR (KERN_PRINTDEZ)
LDA #'.'
JSR (KERN_PRINTCHAR)
LDA #7 ;Year
JSR (KERN_LIBCALL)
JPC printFault
CLX
CLY
JSR (KERN_PRINTDEZ)
CLA
RTS


;---------------------------------------------------------
;Helper functions
;---------------------------------------------------------

;Print leading zero for date and time


von Robin Tönniges - am 06.03.2016 21:31
Hello folks,

I've decided to upload all my project to [github.com] so everyone can get every project (software and hardware) in its up-to-date-state even if its not finished like my all-time-project "RegMonV2".

Another nice thing is that every user who have an account on github can commit fixes, update or changes for which I would be infinitely grateful.

Thanks for reading ;)

von Robin Tönniges - am 19.03.2016 00:12
Hello again,

I've routed a little evaluation board for MyCPU which I use very often to play a little with self builded hardware extensions.

You can download the files on my [github.com] repository.

I know thats not really a software thing but I dont want to open a new thread :)


Have fun!

von Robin Tönniges - am 18.10.2016 16:59
Hi,

I've finished another project... a slave clock control (with build in hardware from the DCF77-Project)
[en.wikipedia.org]

This is my first board that can be easily put to the MyCPU Backplane-Bus. :rp:

The Board is designed for clocks that works with alternating DC.
You are able to use the 12V from the MyCPU-PowerUnit or you can use an external power source for the clock.

Code and hardware can (as always) be found on [github.com] under MyCPU_PRO_SCC


P.S.:
In the folder "Hardware/external module" is a basic version board that can be connected to the Multi-I/O-Unit.
This module only controls the clock and dont have the hardware for the DCF77-Receiver on it.


Hope you can use it!

von Robin Tönniges - am 29.10.2016 15:08
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.