home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / OSBORNE / CLOCK.LBR / CLOCK.AZM / CLOCK.ASM
Assembly Source File  |  2000-06-30  |  8KB  |  206 lines

  1. ; CLOCK.ASM - December 20, 1987 - Walt Wheeler, Yankee Osborne Users (CT) 
  2. ;
  3. ; This program uses the remnants of the software clock built into the earliest
  4. ; versions of the Osborne 1 BIOS.  Most of that code was removed in vers. 1.1 or
  5. ; 1.2.  However,  OCC left a routine (in ROM) thru vers. 1.44, which increments
  6. ; a two byte counter beginning at 0efccH (which is within the BIOS scratch area
  7. ; in high RAM).  The ROM routine bumps the counter each 1/60th of a second --
  8. ; i.e. each time VERTICAL_RETRACE generates an interrupt -- with some relatively
  9. ; minor exceptions, such as disk accesses.   The exceptions limit the accuracy 
  10. ; of this clock, but I have found that in my typical use (and with the machine
  11. ; "on" 24 hours a day, this clock tends to run only a few seconds/day slow. 
  12. ; That's good enough for my purposes, including use on our RCPM.
  13. ;
  14. ; This program owes its existance to the work of others.  Many of the routines
  15. ; here are adapted (or simply "lifted") from public domain contributions by
  16. ; such CP/M gurus as Ward Christensen, Irv Hoff (W6FFC), Sigi Kluger, George
  17. ; Peace, Keith Petersen (W8SDZ), and Kelley Smith.   Jim Enright's artical
  18. ; on the OCC timer routine, reprinted from TOGGLE in FOGHORN (VI, 12, p.50) 
  19. ; renewed a latent interest in the OCC clock and provided the starting point 
  20. ; for this effort by locating the tick_counter, TICNTR.  (You'll find additional
  21. ; information beyond the scope of these comments in his text.)  Next, a belated 
  22. ; disassembley and review of Michael Rubenstein's OCLOCK.COM (written early in 
  23. ; OCC's life, for use in profiling 'C' programs) led me to the interrupt_jump_
  24. ; vector, INTJVC.  INTJVC seems to be the only point at which one can reliably
  25. ; intercept ROM calls under all (most?) circumstances.  Other vectors into the 
  26. ; ROM -- including those testing CON_STATUS -- go "unused" at times for reasons
  27. ; that I can't explain (yet?).  OCLOCK.COM also provides a neat algorithm for
  28. ; relocating and protecting its working code just beneath the CCP, for those 
  29. ; who chose not to implement ZCPR3.X.  Finally, Barry Siegfried (K2MF) of NYC
  30. ; worked out most of the "hard parts" in the disassembley, and in this code.
  31. ; Without his considerable investment of time and genius, on this and prelim-
  32. ; inary efforts, CLOCK.ASM would not exist.   
  33. ;  
  34. ; As presented here, this code has these KNOWN DEPENDENCIES:  OCC1, 1.4x ROM, 
  35. ; my particular implementation of ZCPR3 and NON-USE of RST2, whose vector 
  36. ; occupies the basepage addresses at which this program keeps date and time in 
  37. ; BCD (binary coded decimal). 
  38. ;
  39. ; HOWEVER, NONE OF THESE DEPENDENCIES IS ABSOLUTE.  This should be readily 
  40. ; modifiable for any Z80-based machine which utilizes a clocked_interrupt for
  41. ; routines like SCAN_KEYBOARD. Addresses -- including the locations used here
  42. ; for the relocated "working" code and for data -- can be changed to suit
  43. ; your system.   As it stands, it IS COMPATIBLE with DATTIM.COM, a
  44. ; proprietary program bundled with SuperCalc as distributed with the O1.
  45. ; PHILOSOPHICAL DIGRESSIONS:  First:  Z80-based computing still has a lot of 
  46. ; untapped potential, available at very low cost.  Second, good public domain
  47. ; code (of which this is NOT held out as an example, except as it derives from
  48. ; some VERY good code and the work of others) is widely available for inspir-
  49. ; ation, emulation, and modification to suit our current and future wishes.
  50. ; LASM, a public domain improvement on ASM, will assemble this code.
  51. ;
  52. DATE    EQU    011H    ; Addresses nominally reserved ...
  53. TIME    EQU    013H    ;   ...for RST 2 but generally unused for that
  54.             ;   purpose, and used for this one by DATTIM.COM.
  55. DEST    EQU    0D980H  ; IMPLEMENTATION DEPENDANT: this just happens to ...
  56.             ;   ...be handily available in WCW's system.   
  57. TICNTR    EQU    0EFCCH  ; ABSOLUTE, non-relocatable address under... 
  58. INTJVC    EQU    0EFF8H    ;   ...1.4x OCC ROM BIOS 
  59. ;
  60.     ORG    100H
  61. ;
  62.     LHLD    INTJVC    ; get int jump vector addr in HL
  63.     MOV    A,H    ; get int jump vector addr (high byte)
  64.     CPI    40H    ; Does INTVJC point into ROM ( < 4000H )?
  65.     JRNC    ZERO    ; no, already installed
  66. ;
  67.     SHLD    NINT    ; yes, store orig int jump vector addr...
  68.             ; ...at new int jump vector
  69. ;
  70. MOVUP:    LXI    D,DEST    ; dest addr in DE
  71.     PUSH    D    ; save dest addr
  72.     LXI    H,BNDRY    ; source addr in HL
  73.     LXI    B,LEN    ; program length in BC
  74.     LDIR        ; move ticker code
  75.     POP    D    ; store new int jump vector...
  76.     SDED    INTJVC    ; ...at orig int jump vector addr
  77. ;
  78. ZERO:    LXI    H,0    ; Zero the tick counter when this is initially run
  79.     SHLD    TICNTR    ;  to avoid TICNTR > 0E10H (i.e., past 1 minute)
  80.     RET        ; quit -- done with this .COM file
  81. ;
  82. ;Code for relocation, which actually tracks the clock, follows...
  83. ;
  84. BNDRY    EQU    $    ; for explanation of this notation, see such
  85.             ; code as early versions of BYE.ASM
  86. ;
  87.     DI        ; disable interrupts
  88.     OUT    1    ; switch in RAM bank
  89. ;
  90. ;---------------------------------------------------------------------
  91. ;
  92. ;NEXT 2 STACK INSTRUCTIONS PERHAPS NOT NECESSARY
  93. ;
  94.     SSPD    STK    ; save ROM stack pointer...
  95.     LXI    SP,STK    ; ...at top of temp stack
  96. ;
  97. ;---------------------------------------------------------------------
  98. ;
  99.     PUSH    PSW    ; save regs
  100.     PUSH    H
  101.     LHLD    TICNTR    ; get the tick count
  102.     MOV    A,H    ; look at high byte
  103.     CPI    0EH    ; are we near 0E10H ticks which is 1 minute?
  104.     JRC    EXIT    ; no, exit if <A> less than 0EH
  105. ;
  106.     MOV    A,L    ; yes, look at low byte
  107.     CPI    10H    ; and have we reached or exceeded 1 minute?
  108.     JRC    EXIT    ; no, exit if <A> less than 10H
  109. ;
  110.     LXI    H,0    ; but if we have reached 1 minute...
  111.     SHLD    TICNTR    ; ...ZERO the TICK COUNTER
  112.     LHLD    TIME    ; now, get the old TIME (hrs & mins)
  113.     MOV    A,H    ; move MINS to <A>
  114.     INR    A    ; bump it up
  115.     MOV    H,A    ; store it back to <H> - it may be OK
  116.     ANI    0FH    ; look at LEAST SIG BCD digit
  117.     CPI    0AH    ; has it reached 10 decimal?
  118.     JRNZ    ZTICK    ; if not, store the new time
  119. ;
  120.     MOV    A,H    ; else, get the bad BCD MINS back from <L>
  121.     ANI    0F0H    ; mask off the low nibble - i.e. ZERO it
  122.     ADI    10H    ; bump the high nibble (TENS) up one 
  123.     MOV    H,A    ; store it back to <H> - it may be OK
  124.     CPI    60H    ; and see if we're up to an hour
  125.     JRNZ    ZTICK    ; if not, store the new time
  126. ;
  127.     XRA    A    ; zero <A> - eg. 1:60 AM will become 2:00 AM
  128.     MOV    H,A    ; and put the new MINS value back in <H>
  129.     MOV    A,L    ; now get the HOURS byte
  130.     INR    A    ; bump it
  131.     MOV    L,A    ; store it back to <L> - it may be OK
  132.     CPI    24H    ; and see if we're up to a new date
  133.     JRZ    ZDATE    ; if so, bump the date and zero the time
  134. ;
  135.     ANI    0FH    ; else, look at LEAST SIG BCD digit
  136.     CPI    0AH    ; has it reached 10 decimal?
  137.     JRNZ    ZTICK    ; if not, store the new time
  138. ;
  139.     MOV    A,L    ; else, get the bad BCD HOURS back from <L>
  140.     ANI    0F0H    ; mask off the low nibble - i.e. ZERO it
  141.     ADI    10H    ; bump the high nibble (TENS) up one
  142.     MOV    L,A    ; correct # of TENS, 0 units to <L>
  143.     JR    ZTICK    ; and store the time
  144. ;
  145. ZDATE:    LDA    DATE    ; get the DATE byte in <A>
  146.     INR    A    ; bump it
  147.     STA    DATE    ; store it to back
  148.     ANI    0fH    ; mask to LEAST SIG BCD digit
  149.     CPI    0AH    ; is it a legal decimal digit
  150.     JRNZ    DATEX    ; if ok, get out
  151.     LDA    DATE    ; but if not, get both BCD digits back
  152.     ANI    0f0H    ; mask off LEAST SIG BCD digit, i.e. 0 it
  153.     ADI    010H    ; and bump the MORE SIG BCD digit  
  154.     STA    DATE    ; and store it... 
  155.             ; DAY 32?  too bad --  LET THE USER RESET each month
  156.             ; ---->  could be tested & fixed, but requires more
  157.             ; code like that above AND adds necessity for
  158.             ; table of month_lengths, coding for leap years, etc. 
  159. ;
  160. DATEX:    LXI    H,0    ; and ZERO the <HL> register
  161. ;
  162. ZTICK:    SHLD    TIME    ; store the time from <HL>
  163. ;
  164. EXIT:    POP    H    ; restore regs
  165.     POP    PSW
  166. ;
  167. ;---------------------------------------------------------------------
  168. ;
  169. ;NEXT STACK INSTRUCTION PERHAPS NOT NECESSARY
  170. ;
  171.     LSPD    STK    ; restore ROM stack pointer
  172. ;
  173. ;---------------------------------------------------------------------
  174. ;
  175.     OUT    0    ; switch ROM bank back in
  176. ;
  177. NINT    EQU    $+1    ; addr for the following new int...
  178.             ; ...jump vector filled in at runtime
  179. ;
  180.     JMP    0    ; jump to orig int jump vector addr
  181. ;    
  182. ;---------------------------------------------------------------------
  183. ;
  184. ;TEMPORARY STACK DEFINITION PERHAPS NOT NECESSARY
  185. ;
  186.     DW    0    ; 10 deep temporary stack
  187.     DW    0
  188.     DW    0
  189.     DW    0
  190.     DW    0
  191.     DW    0
  192.     DW    0
  193.     DW    0
  194.     DW    0
  195.     DW    0
  196. ;
  197. STK    EQU    $-BNDRY+DEST
  198. ;
  199. ;---------------------------------------------------------------------
  200. ;
  201. LEN    EQU    $-BNDRY
  202. ;
  203.     END
  204.