# HG changeset patch # User boisy # Date 1091381876 0 # Node ID 1f8962dfa31b9f081f20bf1e7c084eb42c52f46a # Parent 2ab141610086b8e4af7a1f71f3cc1b12a688f596 This clock2 has Rodney H's changes of 8/1 plus Robert's SmartWatch changes. Submitted to me by Robert Gault on 8/1 diff -r 2ab141610086 -r 1f8962dfa31b level1/modules/clock2.asm --- a/level1/modules/clock2.asm Sun Aug 01 15:19:35 2004 +0000 +++ b/level1/modules/clock2.asm Sun Aug 01 17:37:56 2004 +0000 @@ -1,939 +1,1131 @@ -******************************************************************** -* Clock2 - Real-Time Clock Subroutines -* -* $Id$ -* -* Edt/Rev YYYY/MM/DD Modified by -* Comment -* ------------------------------------------------------------------ -* 1 2003/08/18 Boisy G. Pitre -* Stripped from clock.asm in order to modularize clocks. -* -* 2004/7/13 Robert Gault -* Added Vavasour/Collyer emulator & MESS (Disto) versions and relocated -* 'GetTime equ' statement so it is not within a chip heading. - - nam Clock2 - ttl Real-Time Clock Subroutines - - ifp1 - use defsfile - endc - -* -* Setup for specific RTC chip -* - IFNE RTCJVEmu -RTC.Base equ $FFC0 - ENDC - - IFNE RTCMESSEmu -RTC.Base equ $FF50 - ENDC - - IFNE RTCDriveWire -RTC.Base equ $0000 - ENDC - - IFNE RTCElim -RTC.Sped equ $20 32.768 KHz, rate=0 -RTC.Strt equ $06 binary, 24 Hour, DST disabled -RTC.Stop equ $86 bit 7 set stops clock to allow setting time -RTC.Base equ $FF72 I don't know base for this chip. - ENDC - - IFNE RTCDsto2+RTCDsto4 -RTC.Base equ $FF50 Base address of clock - ENDC - - IFNE RTCBB+RTCCloud9 - IFNE RTCBB -RTC.Base equ $FF5C In SCS* Decode - ELSE -RTC.Base equ $FF7C Fully decoded RTC - ENDC -RTC.Zero equ -4 Send zero bit by writing this offset -RTC.One equ -3 Send one bit by writing this offset -RTC.Read equ 0 Read data from this offset - ENDC - - IFNE RTCSmart -RTC.Base equ $4004 We map the clock into this addr -RTC.Zero equ -4 Send zero bit by writing this offset -RTC.One equ -3 Send one bit by writing this offset -RTC.Read equ 0 Read data from this offset - ENDC - - IFNE RTCHarrs -RTC.Base equ $FF60 Base address for clock - ENDC - - IFNE RTCSoft -RTC.Base equ 0 Have to have one defined. - ENDC - -*------------------------------------------------------------ -* -* Start of module -* - mod len,name,Sbrtn+Objct,ReEnt+0,JmpTable,RTC.Base - -name fcs "Clock2" - fcb 1 - - IFNE MPIFlag -SlotSlct fcb MPI.Slot-1 Slot constant for MPI select code - ENDC - -* Jump table for RTC -* -* Entry points: -* - Init -* - SetTime -* - GetTime -JmpTable - lbra Init - bra GetTime - nop - lbra SetTime - -* -* GetTime Subroutine -* -* This subroutine is called by the main clock module. -* - -GetTime equ * - -* -* Vavasour / Collyer Emulator (ignores MPI slot) -* - IFNE RTCJVEmu - ldx #RTC.Base - clr ,-s - lda ,x get century - cmpa #19 - bls cnt - lda #100 - sta ,s -cnt lda 4,x - IFNE Level-1 - sta xx70 then its 19xx - bhi not20 - adda #100 - sta -1,y -not20 bsr getval month - bsr getval day - lda #7 AM/PM mask - stb 1,x - anda ,x - bitb #4 - pshs cc - anda #3 - bsr getval1 - puls cc - beq AM - lda #12 convert to 24hr time as it is PM - adda -1,y - sta -1,y -AM bsr getval minute -* and now fall through into get second -getval lda #$0f - stb 1,x - anda ,x -getval1 decb - pshs b - ldb #10 - mul - stb ,y - puls b - stb 1,x - decb - lda ,x - anda #$0f - adda ,y - sta ,y+ - rts - ENDC - -* -* Eliminator time update (lacks MPI slot select ability) -* - IFNE RTCElim - ldx M$Mem,pcr get RTC base address from fake memory requirement - ldb #$0A UIP status register address - stb ,x generate address strobe - lda 1,x get UIP status - bpl NoUIP Update In Progress, go shift next RTC read - lda #TkPerSec/2 set up next RTC read attempt in 1/2 second - sta $FFD9 2 MHz (Really should check $A0 first) - puls cc,b - - IFNE MPIFlag - stb >MPI.Slct Restore saved "currently" selected MPak slot - ENDC - - clrb - rts - -RTCPre orcc #IntMasks - - IFNE MPIFlag - ldb >MPI.Slct Save currently selected MPak slot on stack - stb 3,s - andb #$F0 - orb >SlotSlct,pcr Get slot to select - stb >MPI.Slct Select MPak slot for clock - ENDC - - ldy #D.Time - ldx M$Mem,pcr - clr 1,x - ldb #12 - clr >$FFD8 1 MHz - rts - -GetVal stb 2,x - decb - lda ,x read tens digit from clock - anda #$0f -GetVal1 pshs b save b - ldb #10 - mul multiply by 10 to get value - stb ,y save 10s value - puls b set up clock for ones digit - stb 2,x - decb - lda ,x read ones digit from clock - anda #$0f - adda ,y add ones + tens - sta ,y+ store clock value into time packet - rts - - ENDC - -* -* Disto 4-in-1 RTC time update -* - IFNE RTCDsto4 - IFNE MPIFlag - pshs cc Save old interrupt status and mask IRQs - orcc #IntMasks - ldb >MPI.Slct Save currently selected MPak slot on stack - pshs b - andb #$F0 - orb >SlotSlct,pcr Select MPak slot for clock - stb >MPI.Slct - ENDC - - ldx M$Mem,pcr - ldy #D.Time Start with seconds - - ldb #11 - bsr GetVal Get Year - bsr GetVal Get Month - bsr GetVal Get Day - lda #3 Mask tens digit of hour to remove AM/PM bit - bsr GetVal1 Get Hour - bsr GetVal Get Minute - bsr GetVal Get Second - - IFNE MPIFlag - puls b Restore saved "currently" selected MPak slot - stb >MPI.Slct - puls cc,pc Restore previous IRQ status - ELSE - rts No MPI, don't need to mess with slot, CC - ENDC - -GetVal lda #$0f Mask to apply to tens digit -GetVal1 stb 1,x - decb - anda ,x read ones digit from clock - pshs b save b - ldb #10 - mul multiply by 10 to get value - stb ,y Add to ones digit - puls b - stb 1,x - decb - lda ,x read tens digit from clock and mask it - anda #$0f - adda ,y - sta ,y+ - rts - - ENDC - - -* -* Update time from DriveWire -* - IFNE RTCDriveWire - - lbra DoDW - - use bbwrite.asm - -DoDW pshs y,x,cc - lda #'# Time packet - orcc #IntMasks Disable interrupts - lbsr SerWrite - bsr SerRead Read year byte - bcs UpdLeave - sta MPI.Slct Select slot - pshs b - andb #$F0 - orb SlotSlct,pcr - stb >MPI.Slct - ENDC - - lbsr SendMsg Initialize clock - ldx #D.Sec - ldb #8 Tfr 8 bytes - -tfrloop jsr ,y Tfr 1 byte - - bitb #$03 - beq skipstuf Skip over day-of-week, etc. - leax -1,x -skipstuf decb - bne tfrloop - - IFNE MPIFlag - puls b - stb >MPI.Slct restore MPAK slot - ENDC - - puls u,y,cc,pc - -ClkMsg fcb $C5,$3A,$A3,$5C,$C5,$3A,$A3,$5C -* Enable clock with message $C53AA35CC53AA35C -SendMsg lda RTC.Read,u Send Initialization message to clock - leax MPI.Slct Get MPI slot - ldb <$90 Get GIME shadow of $FF90 - pshs b,a - anda #$F0 - ora >SlotSlct,pcr Get new slot to select - anda #$03 *** TEST *** - sta >MPI.Slct And select it - andb #$FC - stb >$FF90 ROM mapping = 16k internal, 16k external - ldb >$FFA2 Read GIME for $4000-$5fff - pshs b - lda #$3E - sta >$FFA2 Put block $3E at $4000-$5fff - clr >$FFDE Map RAM/ROM, to map in external ROM - lbsr SendMsg Initialize clock - ldx #D.Sec Start with seconds - lda #$08 - sta ,-s Set up loop counter = 8 -L021E ldb #$08 -L0220 lda >RTC.Read+RTC.Base Read one bit - lsra - ror ,x Put bit into time - decb End of bit loop - bne L0220 - lda ,s Check loop counter - cmpa #$08 - beq L023D Fill "seconds" twice (ignore 1st value) - cmpa #$04 - bne L0239 - ldb ,x Save 4th value read at $34 (day of week?) - stb $0A,x - bra L023D And overwrite "day" with day -L0239 leax -$01,x Go to next time to read - bsr BCD2Dec Convert 1,x from BCD to decimal -L023D dec ,s - bne L021E End of loop for reading time - leas $01,s Done with loop counter - clr >$FFDF Map all RAM - puls b - stb >$FFA2 Put back original memory block - puls b,a - sta >MPI.Slct - stb >$FF90 Restore original ROM mapping - puls cc,pc Re-enable interrupts - -* Convert BCD to a normal number - -BCD2Dec lda $01,x - clrb -B2DLoop cmpa #$10 - bcs B2DDone - suba #$10 - addb #$0A - bra B2DLoop -B2DDone pshs a - addb ,s+ - stb $01,x - rts - -ClkMsg fcb $C5,$3A,$A3,$5C,$C5,$3A,$A3,$5C - -* Send above "string" to smartwatch, one bit at a time - -SendMsg leax RTC.Read+RTC.Base Tell clock we're going to start??? - lda #$08 - sta ,-s Store counter = 8 -L006B ldb #$08 Start of outer loop, 8 bytes to send - lda ,x+ Get byte to send -L006F lsra Start of inner loop, 8 bits to send - bcs L0077 - tst >RTC.Zero+RTC.Base Send a "zero" bit - bra L007A -L0077 tst >RTC.One+RTC.Base Send a "one" bit -L007A decb - bne L006F End of inner loop - dec ,s End of outer loop - bne L006B - puls pc,a - - ENDC - -* -* Update time from Harris RTC -* - IFNE RTCHarrs - pshs cc - orcc #IntMasks Disable interrupts - - ldu M$Mem,pcr Get base address - ldy #D.Time Pointer to time in system map - - lda #%00001100 Init command register (Normal,Int. Disabled, - sta $11,u Run,24-hour mode, 32kHz) - - lda ,u Read base address to set-up clock regs for read - lda 6,u Get year - sta ,y+ - lda 4,u Get month - sta ,y+ - lda 5,u Get day - sta ,y+ - lda 1,u Get hour - sta ,y+ - lda 2,u Get minute - sta ,y+ - lda 3,u Get second - sta ,y+ - - puls cc,pc Re-enable interrupts - ENDC -* -* -* Software time update -* -* - - IFNE RTCSoft - lda MPI.Slct Save currently selected MPak slot - pshs b - andb #$F0 - orb >SlotSlct,pcr Get slot to select - stb >MPI.Slct Select MPak slot for clock - ENDC - - ldy #D.Time+6 - ldx M$Mem,pcr - clrb - bsr SetVal Set Second - bsr SetVal Set Minute - bsr SetVal Set Hour - bsr SetVal Set Day - bsr SetVal Set Month - bsr SetVal Set Year - - IFNE MPIFlag - puls b Restore old MPAK slot - stb >MPI.Slct - ENDC - - puls cc - clrb No error - rts - -SetVal clr ,-s Create variable for tens digit - lda ,-y Get current value -DvLoop suba #10 Get Tens digit on stack, ones digit in A - bcs DvDone - inc ,s - bra DvLoop -DvDone adda #10 - stb 1,x Set Clock address - incb - sta ,x Store ones digit - stb 1,x - incb - puls a - sta ,x Store tens digit - rts - ENDC - -* -* Set B&B RTC from Time variables -* - IFNE RTCBB+RTCCloud9 - pshs u,y,cc - leay SendBCD,pcr Send bytes of clock - lbra TfrTime - ENDC - -* -* Set Harris 1770 RTC from Time variables -* - IFNE RTCHarrs - pshs cc - orcc #IntMasks Disable interrupts - - ldu M$Mem,pcr Get base address - ldy #D.Time Pointer to time in system map - - lda #%00000100 Init command register (Normal,Int. Disabled, - sta $11,u STOP clock,24-hour mode, 32kHz) - - lda ,y+ Get year - sta 6,u - lda ,y+ Get month - sta 4,u - lda ,y+ Get day - sta 5,u - lda ,y+ Get hour - sta 1,u - lda ,y+ Get minute - sta 2,u - lda ,y Get second - sta 3,u - - lda #%00001100 Init command register (Normal,Int. Disabled, - sta $11,u START clock,24-hour mode, 32kHz) - - puls cc,pc Re-enable interrupts - ENDC - - -* -* RTC-specific initializations here -* -Init equ * - IFNE RTCDsto4 -* Disto 4-N-1 RTC specific initialization - ldx M$Mem,pcr - ldd #$010F Set mode for RTC chip - stb 1,x - sta ,x - ldd #$0504 - sta ,x - stb ,x - ENDC - - IFNE RTCElim - IFGT Level-1 -* Eliminator will install specific system calls - leay NewSvc,pcr insert syscalls - os9 F$SSvc - ENDC - ENDC - - rts - - emod -len equ * - end +******************************************************************** +* Clock2 - Real-Time Clock Subroutines +* +* $Id$ +* +* Edt/Rev YYYY/MM/DD Modified by +* Comment +* ------------------------------------------------------------------ +* 1 2003/08/18 Boisy G. Pitre +* Stripped from clock.asm in order to modularize clocks. +* +* 2004/7/13 Robert Gault +* Added Vavasour/Collyer emulator & MESS (Disto) versions and relocated +* 'GetTime equ' statement so it is not within a chip heading. +* +* 2004/7/28 Robert Gault +* Complete rewrite of SmartWatch segment which would never have worked. +* See previous versions for old code if desired. Routine now will search +* through all MPI slots to find clock and accept either AM/PM or military +* time. User notified if clock not found or data memory not available. +* +* Initialization routine contains code that bypasses OS-9 system calls to +* acquire needed low RAM that can?t become ROM. This type of code is not +* recommended in most cases but nothing else was usable. +* +* 2004/7/31 Rodney Hamilton +* Improved RTCJVEmu code, conditionalized RTC type comments. + + nam Clock2 + ttl Real-Time Clock Subroutines + + ifp1 + use defsfile + endc + +* +* Setup for specific RTC chip +* + IFNE RTCJVEmu +RTC.Base equ $FFC0 + ENDC + + IFNE RTCMESSEmu +RTC.Base equ $FF50 + ENDC + + IFNE RTCDriveWire +RTC.Base equ $0000 + ENDC + + IFNE RTCElim +RTC.Sped equ $20 32.768 KHz, rate=0 +RTC.Strt equ $06 binary, 24 Hour, DST disabled +RTC.Stop equ $86 bit 7 set stops clock to allow setting time +RTC.Base equ $FF72 I don't know base for this chip. + ENDC + + IFNE RTCDsto2+RTCDsto4 +RTC.Base equ $FF50 Base address of clock + ENDC + + IFNE RTCBB+RTCCloud9 + IFNE RTCBB +RTC.Base equ $FF5C In SCS* Decode + ELSE +RTC.Base equ $FF7C Fully decoded RTC + ENDC +RTC.Zero equ -4 Send zero bit by writing this offset +RTC.One equ -3 Send one bit by writing this offset +RTC.Read equ 0 Read data from this offset + ENDC + + IFNE RTCSmart +RTC.Base equ $C000 clock mapped to $C000-$DFFF; $FFA6 MMU slot +RTC.Zero equ 0 Send zero bit +RTC.One equ 1 Send ones bit +RTC.Read equ 4 +D.RTCSlt equ 0 on SmartWatch ?data? page +D.RTCFlg equ 1 on SW page +D.Temp equ 2 on SW page, holds "clock" data +D.Start equ 3 on SW page, code starts here + ENDC + + IFNE RTCHarrs +RTC.Base equ $FF60 Base address for clock + ENDC + + IFNE RTCSoft +RTC.Base equ 0 Have to have one defined. + ENDC + +*------------------------------------------------------------ +* +* Start of module +* + mod len,name,Sbrtn+Objct,ReEnt+0,JmpTable,RTC.Base + +name fcs "Clock2" + fcb 1 + + IFNE MPIFlag +SlotSlct fcb MPI.Slot-1 Slot constant for MPI select code + ENDC + +* Jump table for RTC +* +* Entry points: +* - Init +* - SetTime +* - GetTime +JmpTable + lbra Init + bra GetTime + nop + lbra SetTime + +* +* GetTime Subroutine +* +* This subroutine is called by the main clock module. +* + +GetTime equ * + + IFNE RTCJVEmu +* +* Vavasour / Collyer Emulator (ignores MPI slot) +* + ldx #RTC.Base + ldd ,x get year (CCYY) + suba #20 + bmi yr1 19xx, OK as is +yr0 addb #100 20xx adjustment + deca also check for + bpl yr0 21xx (optional) +yr1 stb xx70 then its 19xx + bhi not20 + adda #100 + sta -1,y +not20 bsr getval month + bsr getval day + lda #7 AM/PM mask + stb 1,x + anda ,x + bitb #4 + pshs cc + anda #3 + bsr getval1 + puls cc + beq AM + lda #12 convert to 24hr time as it is PM + adda -1,y + sta -1,y +AM bsr getval minute +* and now fall through into get second +getval lda #$0f + stb 1,x + anda ,x +getval1 decb + pshs b + ldb #10 + mul + stb ,y + puls b + stb 1,x + decb + lda ,x + anda #$0f + adda ,y + sta ,y+ +* rts fall thru to Setime/Init rts + ENDC + + IFNE RTCElim +* +* Eliminator time update (lacks MPI slot select ability) +* + ldx M$Mem,pcr get RTC base address from fake memory requirement + ldb #$0A UIP status register address + stb ,x generate address strobe + lda 1,x get UIP status + bpl NoUIP Update In Progress, go shift next RTC read + lda #TkPerSec/2 set up next RTC read attempt in 1/2 second + sta $FFD9 2 MHz (Really should check $A0 first) + puls cc,b + + IFNE MPIFlag + stb >MPI.Slct Restore saved "currently" selected MPak slot + ENDC + + clrb + rts + +RTCPre orcc #IntMasks + + IFNE MPIFlag + ldb >MPI.Slct Save currently selected MPak slot on stack + stb 3,s + andb #$F0 + orb >SlotSlct,pcr Get slot to select + stb >MPI.Slct Select MPak slot for clock + ENDC + + ldy #D.Time + ldx M$Mem,pcr + clr 1,x + ldb #12 + clr >$FFD8 1 MHz + rts + +GetVal stb 2,x + decb + lda ,x read tens digit from clock + anda #$0f +GetVal1 pshs b save b + ldb #10 + mul multiply by 10 to get value + stb ,y save 10s value + puls b set up clock for ones digit + stb 2,x + decb + lda ,x read ones digit from clock + anda #$0f + adda ,y add ones + tens + sta ,y+ store clock value into time packet + rts + + ENDC + + IFNE RTCDsto4 +* +* Disto 4-in-1 RTC time update +* + IFNE MPIFlag + pshs cc Save old interrupt status and mask IRQs + orcc #IntMasks + ldb >MPI.Slct Save currently selected MPak slot on stack + pshs b + andb #$F0 + orb >SlotSlct,pcr Select MPak slot for clock + stb >MPI.Slct + ENDC + + ldx M$Mem,pcr + ldy #D.Time Start with seconds + + ldb #11 + bsr GetVal Get Year + bsr GetVal Get Month + bsr GetVal Get Day + lda #3 Mask tens digit of hour to remove AM/PM bit + bsr GetVal1 Get Hour + bsr GetVal Get Minute + bsr GetVal Get Second + + IFNE MPIFlag + puls b Restore saved "currently" selected MPak slot + stb >MPI.Slct + puls cc,pc Restore previous IRQ status + ELSE + rts No MPI, don't need to mess with slot, CC + ENDC + +GetVal lda #$0f Mask to apply to tens digit +GetVal1 stb 1,x + decb + anda ,x read ones digit from clock + pshs b save b + ldb #10 + mul multiply by 10 to get value + stb ,y Add to ones digit + puls b + stb 1,x + decb + lda ,x read tens digit from clock and mask it + anda #$0f + adda ,y + sta ,y+ + rts + + ENDC + + IFNE RTCDriveWire +* +* Update time from DriveWire +* + lbra DoDW + + use bbwrite.asm + +DoDW pshs y,x,cc + lda #'# Time packet + orcc #IntMasks Disable interrupts + lbsr SerWrite + bsr SerRead Read year byte + bcs UpdLeave + sta MPI.Slct Select slot + pshs b + andb #$F0 + orb SlotSlct,pcr + stb >MPI.Slct + ENDC + + lbsr SendMsg Initialize clock + ldx #D.Sec + ldb #8 Tfr 8 bytes + +tfrloop jsr ,y Tfr 1 byte + + bitb #$03 + beq skipstuf Skip over day-of-week, etc. + leax -1,x +skipstuf decb + bne tfrloop + + IFNE MPIFlag + puls b + stb >MPI.Slct restore MPAK slot + ENDC + + puls u,y,cc,pc + +ClkMsg fcb $C5,$3A,$A3,$5C,$C5,$3A,$A3,$5C +* Enable clock with message $C53AA35CC53AA35C +SendMsg lda RTC.Read,u Send Initialization message to clock + leax MPI.Slct Save currently selected MPak slot + pshs b + andb #$F0 + orb >SlotSlct,pcr Get slot to select + stb >MPI.Slct Select MPak slot for clock + ENDC + + ldy #D.Time+6 + ldx M$Mem,pcr + clrb + bsr SetVal Set Second + bsr SetVal Set Minute + bsr SetVal Set Hour + bsr SetVal Set Day + bsr SetVal Set Month + bsr SetVal Set Year + + IFNE MPIFlag + puls b Restore old MPAK slot + stb >MPI.Slct + ENDC + + puls cc + clrb No error + rts + +SetVal clr ,-s Create variable for tens digit + lda ,-y Get current value +DvLoop suba #10 Get Tens digit on stack, ones digit in A + bcs DvDone + inc ,s + bra DvLoop +DvDone adda #10 + stb 1,x Set Clock address + incb + sta ,x Store ones digit + stb 1,x + incb + puls a + sta ,x Store tens digit + rts + ENDC + + IFNE RTCBB+RTCCloud9 +* +* Set B&B RTC from Time variables +* + pshs u,y,cc + leay SendBCD,pcr Send bytes of clock + lbra TfrTime + ENDC + + IFNE RTCHarrs +* +* Set Harris 1770 RTC from Time variables +* + pshs cc + orcc #IntMasks Disable interrupts + + ldu M$Mem,pcr Get base address + ldy #D.Time Pointer to time in system map + + lda #%00000100 Init command register (Normal,Int. Disabled, + sta $11,u STOP clock,24-hour mode, 32kHz) + + lda ,y+ Get year + sta 6,u + lda ,y+ Get month + sta 4,u + lda ,y+ Get day + sta 5,u + lda ,y+ Get hour + sta 1,u + lda ,y+ Get minute + sta 2,u + lda ,y Get second + sta 3,u + + lda #%00001100 Init command register (Normal,Int. Disabled, + sta $11,u START clock,24-hour mode, 32kHz) + + puls cc,pc Re-enable interrupts + ENDC + + +* +* RTC-specific initializations here +* +Init equ * + IFNE RTCDsto4 +* Disto 4-N-1 RTC specific initialization + ldx M$Mem,pcr + ldd #$010F Set mode for RTC chip + stb 1,x + sta ,x + ldd #$0504 + sta ,x + stb ,x + ENDC + + IFNE RTCElim + IFGT Level-1 +* Eliminator will install specific system calls + leay NewSvc,pcr insert syscalls + os9 F$SSvc + ENDC + ENDC + + IFNE RTCSmart + clr