time.asm 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. ;
  2. ; CP/M Time-of-day Program
  3. ;
  4. ; v1.08 12/22/82 WGW Changed name of program to TIME.COM
  5. ; v1.07 11/12/82 WGW Correct values for get/settime
  6. ; v1.06 11/10/82 WGW Changed help message to fit on EC8800
  7. ; v1.05 9/20/82 WGW Get number of days via gettime
  8. ; v1.04 7/01/82 WGW Correct noon time (12 PM)
  9. ; v1.03 6/07/82 WGW Correct get character routine
  10. ; v1.02 5/27/82 WGW Check validity of time, regular/military time
  11. ; v1.01 5/21/82 WGW Set time of day
  12. ; v1.00 5/20/82 WGW Read time of day (original version)
  13. ;
  14. version equ 1
  15. revision equ 8
  16. month equ 12
  17. day equ 22
  18. year equ 82
  19. cpm equ 0
  20. bdos equ 5
  21. fcb1 equ 5ch ; location of first fcb parsed by ccp
  22. fcb2 equ 6ch ; location of second fcb
  23. filename equ 1 ; offset into fcb
  24. fileextension equ filename+8 ; offset into fcb
  25. parameter1a equ fcb1+filename
  26. parameter1b equ fcb1+fileextension
  27. parameter2a equ fcb2+filename
  28. parameter2b equ fcb2+fileextension
  29. tpa equ 100h
  30. beep equ 7
  31. cr equ 13
  32. lf equ 10
  33. endmsg equ '$'
  34. regulartime equ 0
  35. militarytime equ 0ffh
  36. uppercase equ 5fh
  37. displaychar equ ' ' ; character indicating display tod
  38. repeatchar equ 'P' ; character indicating repeat mode
  39. militarychar equ 'M' ; character indicating military tod
  40. maxhours equ 24h ; 24 hours
  41. morning equ maxhours/2
  42. noon equ 12h
  43. midnight equ 0
  44. maxminutes equ 60h ; 60 minutes
  45. readconsole equ 1 ; bdos function calls
  46. getconsole equ 6
  47. printstring equ 9
  48. consolestatus equ 11
  49. settime equ 104
  50. readtime equ 105
  51. readclock equ 155
  52. org tpa
  53. jmp start
  54. signon: db cr,lf
  55. db 'Time-of-day Program WGW V'
  56. db (version/10)+'0'
  57. db (version mod 10)+'0'
  58. db '.'
  59. db (revision/10)+'0'
  60. db (revision mod 10)+'0'
  61. db ' '
  62. db (month/10)+'0'
  63. db (month mod 10)+'0'
  64. db '/'
  65. db (day/10)+'0'
  66. db (day mod 10)+'0'
  67. db '/'
  68. db (year/10)+'0'
  69. db (year mod 10)+'0'
  70. db endmsg
  71. displaytype:
  72. db regulartime ; default display type
  73. ;
  74. ; --- Main part of program -----------
  75. ;
  76. start: lxi sp,stack ; use internal stack
  77. call main ; perform main program
  78. lxi d,crlfmsg
  79. call print1
  80. jmp cpm ; exit
  81. main: lda parameter1a ; a := first char of first parameter
  82. call isdigit ; see if a digit is entered
  83. jz settod ; see if the time is to be set
  84. cpi militarychar ; check for military time
  85. jnz checkdisplaytype
  86. mvi a,militarytime ; set display type to military time
  87. sta displaytype
  88. lda parameter2a ; a := first char of second parameter
  89. checkdisplaytype:
  90. cpi displaychar ; check for print one time display
  91. jz printtime
  92. cpi repeatchar ; check for repeat time display
  93. jz repeatprinttime
  94. lxi d,signon ; otherwise print signon
  95. call print
  96. lxi d,helpmsg ; and print format message
  97. print: call print1 ; print string
  98. printcrlf:
  99. lxi d,crlfmsg ; begin a new line
  100. print1: mvi c,printstring
  101. jmp bdos
  102. helpmsg:
  103. db 'The following display the time-of-day:',cr,lf
  104. db cr,lf
  105. db 'TIME Prints normal time',cr,lf
  106. db 'TIME M Prints military time',cr,lf
  107. db cr,lf
  108. db 'The following display the time-of-day',cr,lf
  109. db ' until a key is pressed:',cr,lf
  110. db cr,lf
  111. db 'TIME P Prints normal time',cr,lf
  112. db 'TIME M P Prints military time',cr,lf
  113. db cr,lf
  114. db 'The following set the time-of-day:',cr,lf
  115. db cr,lf
  116. db 'TIME hh.mm Set military time',cr,lf
  117. db 'TIME hh.mm AM Set normal time (morning)',cr,lf
  118. db 'TIME hh.mm PM Set normal time (evening)',cr,lf
  119. db ' when a key is pressed.',cr,lf
  120. db endmsg
  121. printtime: ; print time-of-day
  122. lxi d,timeismsg ; print 'time is'
  123. call print1
  124. lxi d,tod ; read the tod clock
  125. mvi c,readclock
  126. call bdos
  127. call converttime
  128. lxi d,timemsg ; print the time
  129. call print1
  130. call ismilitary ; see if military time display
  131. cnz printampm
  132. lxi d,crmsg ; print trailing cr
  133. jmp print1
  134. printampm:
  135. call getampm ; get right letter
  136. mov a,l ; a := am/pm character
  137. sta ampm ; update message
  138. lxi d,ampmmsg ; print am/pm message
  139. jmp print1
  140. getampm:
  141. mvi l,'P' ; l := possible result
  142. lda todhours ; a := hours
  143. cpi morning ; see if it is the morning
  144. rnc ; exit if in the evening
  145. mvi l,'A'
  146. ret
  147. converttime:
  148. lda todhours ; convert to ascii and display
  149. call converthourscheck ; check the hours
  150. call makeascii
  151. shld msghours
  152. lda todminutes
  153. call makeascii
  154. shld msgminutes
  155. lda todseconds
  156. call makeascii
  157. shld msgseconds
  158. ret
  159. converthourscheck:
  160. mov b,a ; b := hours (BCD)
  161. call ismilitary ; see if it is military time
  162. mov a,b ; a := hours (BCD)
  163. rz ; exit if military time
  164. ora a ; check for midnight
  165. mvi a,12h ; return 12 if midnight
  166. rz ; exit if midnight
  167. mov a,b ; a := hours (BCD)
  168. cpi morning+1 ; check if evening
  169. rc ; exit if in morning
  170. adi 88h ; subtract 12 hours
  171. daa ; make BCD
  172. ret
  173. ismilitary:
  174. lda displaytype ; a := displaytype
  175. cpi militarytime ; return zero if military time
  176. ret
  177. repeatprinttime: ; print tod until character entered
  178. call printtime
  179. mvi c,consolestatus ; get console status
  180. call bdos
  181. ora a
  182. jz repeatprinttime ; loop until done if no character typed
  183. getchr: mvi c,consolestatus ; get console status
  184. call bdos
  185. ora a
  186. jz getchr ; wait until character entered
  187. mvi e,0ffh ; e := get character
  188. mvi c,getconsole ; get the character
  189. jmp bdos ; and exit
  190. settod: ; set time-of-day
  191. lxi d,tod ; get time-of-day to set days
  192. mvi c,readtime
  193. call bdos
  194. lhld parameter1a ; get hours
  195. xchg ; de := parameter
  196. call makebcdblank ; convert to bcd, possible leading ' '
  197. cpi 0ffh ; check for entry errors
  198. jz seterror
  199. call checkhours ; check for range error
  200. jnc seterror ; jump if greater or equal to limit
  201. sta todhours
  202. lhld parameter1b ; get minutes
  203. xchg ; de := parameter
  204. call makebcd ; convert to bcd
  205. cpi 0ffh ; check for entry errors
  206. jz seterror
  207. cpi maxminutes ; check for range error
  208. jnc seterror ; jump if greater or equal to limit
  209. sta todminutes
  210. lxi d,startmsg ; print waiting to set time message
  211. call print1
  212. call getchr ; get a character
  213. call printcrlf
  214. lxi d,tod ; set time-of-day
  215. mvi c,settime
  216. call bdos
  217. jmp printtime ; print the time just set
  218. checkhours:
  219. mov b,a ; b := hours (BCD)
  220. lda parameter2a ; a := first char of second parameter
  221. cpi 'P' ; see if it is PM
  222. jz checkhourspm
  223. cpi 'A' ; see if it is AM
  224. jz checkhoursam
  225. cpi ' ' ; see if it is military time (default)
  226. jz checkhoursmilitary
  227. ora a ; no carry indicates an error
  228. ret
  229. checkhoursmilitary:
  230. mov a,b ; a := hours (BCD)
  231. cpi maxhours ; check max hours
  232. ret
  233. checkhourspm:
  234. mov a,b ; a := hours (BCD)
  235. ora a ; see if it is zero
  236. rz ; return with no carry if zero
  237. adi morning ; convert to PM hours
  238. daa ; make BCD
  239. cpi maxhours ; check max hours
  240. rnz ; return in not midnight
  241. mvi a,noon ; return a := 12h if noon
  242. stc ; set carry to indicate it is ok
  243. ret
  244. checkhoursam:
  245. mov a,b ; a := hours (BCD)
  246. ora a ; see if it is zero
  247. rz ; return with no carry if zero
  248. cpi morning ; check max hours
  249. rnc ; exit if ok (1 to 11 am)
  250. cpi 12h ; see if it is 12 am
  251. rnc ; exit if not 12 am (error)
  252. sub a ; a := 0 (12 midnight)
  253. stc ; set carry to indicate it is ok
  254. ret
  255. startmsg:
  256. db cr,lf
  257. db 'Enter any key to set time of day',endmsg
  258. seterrormsg:
  259. db 'Invalid time-of-day format',endmsg
  260. seterror:
  261. lxi d,seterrormsg ; print error message
  262. call error
  263. lxi d,helpmemsg ; print how-to-get-help message
  264. jmp print
  265. helpmemsg:
  266. db cr,lf
  267. db 'Enter the following to get more information:',cr,lf
  268. db cr,lf
  269. db 'TIME ?',endmsg
  270. error: push d ; save error message index
  271. lxi d,errorprefix ; print error prefix
  272. call print1
  273. pop d
  274. call print1 ; print error message
  275. lxi d,errorsuffix ; print error suffix
  276. jmp print
  277. errorprefix:
  278. db cr,lf
  279. db '*** ',endmsg
  280. errorsuffix:
  281. db ' ***',beep,endmsg
  282. isdigit: ; returns zero if A is an ascii digit
  283. mov c,a ; c := character
  284. push b ; save it
  285. call isdigit1 ; check digit
  286. pop b ; restore character, return zero flag
  287. mov a,c
  288. ret
  289. isdigit1:
  290. cpi '0' ; is is less than a '0'
  291. jc returnff
  292. cpi '9'+1
  293. jnc returnff ; is it greater than a '9'
  294. return0:
  295. sub a ; a := 0, zero = true
  296. ret
  297. returnff:
  298. mvi a,0ffh ; a := 0ffh, zero = false
  299. ora a
  300. ret
  301. makebcdblank: ; a := bcd value of de (ls, ms), ls can = ' '
  302. mov a,d ; a := ls ascii digit
  303. cpi ' ' ; see if it is a blank
  304. jnz makebcd ; convert if already a digit
  305. mov d,e ; shift right one digit
  306. mvi e,'0' ; set in a leading zero
  307. makebcd: ; a := bcd value of de (ls, ms)
  308. mov a,e ; a := ms ascii digit
  309. call isdigit ; see if it is a digit
  310. rnz ; exit if it is not
  311. mov a,e ; restore ms ascii digit
  312. ral ; shift into upper nibble
  313. ral
  314. ral
  315. ral
  316. ani 0f0h ; a (ms nibble) := bcd part of ms ascii digit
  317. mov e,a ; save it
  318. mov a,d ; a := ls ascii digit
  319. call isdigit ; see if this is a digit too
  320. rnz
  321. mov a,d ; restore ls ascii digit
  322. ani 0fh ; a (ls nibble) := bcd part of ls ascii digit
  323. ora e ; a := result
  324. ret
  325. makeascii:
  326. push psw
  327. call makedigit
  328. mov h,a ; h := ls digit (remember, msb stored last)
  329. pop psw
  330. rrc
  331. rrc
  332. rrc
  333. rrc ; a (ls nibble) := ms nibble
  334. call makedigit
  335. mov l,a ; hl := two ascii digits
  336. ret
  337. makedigit:
  338. ani 0fh ; a := ls nibble
  339. adi '0' ; convert to a digit
  340. ret
  341. tod: dw 0
  342. todhours: db 0
  343. todminutes: db 0
  344. todseconds: db 0
  345. timeismsg: db 'The time is ',endmsg
  346. timemsg: ; displays time
  347. msghours: db '00.'
  348. msgminutes: db '00.'
  349. msgseconds: db '00',endmsg
  350. ampmmsg: db ' '
  351. ampm: db ' M',endmsg
  352. crmsg: db cr,endmsg
  353. crlfmsg: db cr,lf,endmsg
  354. ds 256 ; internal stack
  355. stack:
  356. end
  357.