-
Notifications
You must be signed in to change notification settings - Fork 0
/
tod.a86
439 lines (403 loc) · 13 KB
/
tod.a86
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
;
; Licensed under the MIT license. See LICENSE file in the project root for details.
;
title 'CP/M-86 TOD replacement'
code cseg
mov cx,ds
mov es,cx
mov cx,0Ch
int 0E0h
sub al,22H
ja wrg_os
call arg_avail
or ax,ax
jz just_show
call parse_date
or ax,ax
jnz wrg_fmt
call check_date
or ax,ax
jnz wrg_fmt
call cpm_set_time
cmp ax,0
jnz wrg_fmt
just_show:
call clear_keys
just_show_time:
call cpm_show_time
mov cl, byte ptr disp_loop
or cl, 0
jz loop_just_show
call quit
loop_just_show:
call wait_key
or ax, 0
jnz loop_show_done
lea si, msg_back
call print_str
jmp just_show_time
loop_show_done:
call clear_keys
call quit
wrg_os:
lea si, msg_wrg_os
call print_str
call quit
wrg_fmt:
lea si, msg_wrg_fmt
call print_str
call quit
arg_avail:
push cx
push si
mov si, 80h
mov cl, byte ptr [si]
or cl,cl
jz arg_noarg
tail_loop:
inc si
mov al, ds:[si]
cmp al,' '
je tail_loop
cmp al,0Dh
je arg_noarg
cmp al,00h
je arg_noarg
arg_args:
cmp al, 'P'
je arg_loop
mov ax,1
jmp arg_end
arg_loop:
mov al, 0
mov byte ptr disp_loop, al
arg_noarg:
mov ax,0
jmp arg_end
arg_end:
pop si
pop cx
ret
parse_date:
push es
push bx
push dx
push di
mov cx,ds
mov es,cx
mov di, 80h ; date
lea si, tmz_date
pd_spc:
inc di
mov al, [di]
cmp al, ' '
je pd_spc
mov cx, 2
pd_year:
mov al, [di] ; year
call isdigit
or ah, ah
jnz pd_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pd_year
mov al, [di]
cmp al, '/'
jne pd_err
inc si
inc di
mov cx, 2
pd_month:
mov al, [di] ; month
call isdigit
or ah, ah
jnz pd_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pd_month
mov al, [di]
cmp al, '/'
jne pd_err
inc si
inc di
mov cx, 2
pd_day:
mov al, [di] ; day
call isdigit
or ah, ah
jnz pd_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pd_day
inc si
jnz pt_spc
pd_err:
jmp pt_err
pt_section:
inc di
pt_spc:
mov al, [di]
cmp al, ' '
je pt_section
mov cx, 2
pt_hour:
mov al, [di] ; hour
call isdigit
or ah, ah
jnz pt_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pt_hour
mov al, [di]
cmp al, ':'
jne pt_err
inc si
inc di
mov cx, 2
pt_min:
mov al, [di] ; minute
call isdigit
or ah, ah
jnz pt_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pt_min
mov al, [di]
cmp al, ':'
jne pt_err
inc si
inc di
mov cx, 2
pt_sec:
mov al, [di] ; second
call isdigit
or ah, ah
jnz pt_err
mov [si], al
inc si
inc di
dec cx
or cx,cx
jnz pt_sec
mov ax,0
jmp pt_end
pt_err:
mov ax,1
jmp pt_end
pt_end:
pop di
pop dx
pop bx
pop es
ret
check_date:
push bx
push cx
push dx
mov al, byte ptr tmz_date+6 ;check leap year
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_date+7
sub bl, '0'
add ax, bx
or ax, ax
jz no_leap
and ax, 3
jnz no_leap
mov bx, offset month_siz+2
mov ax, 29
mov [bx], ax
no_leap:
mov al, byte ptr tmz_date ;check month
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_date+1
sub bl, '0'
add ax, bx
mov dx, ax
cmp ax, 12
ja ckd_err
cmp ax, 1
jb ckd_err
mov al, byte ptr tmz_date+3 ;check day
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_date+4
sub bl, '0'
add ax, bx
mov bx, offset month_siz
add bx,dx
mov cl, [bx]
xor ch, ch
cmp ax, cx
ja ckd_err
cmp ax, 1
jb ckd_err
jmp ck_time
ckd_err:
jmp ckt_err
ck_time:
mov al, byte ptr tmz_time ;check hour
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_time+1
sub bl, '0'
add ax, bx
cmp ax, 23
ja ckt_err
mov al, byte ptr tmz_time+3 ;check minutes
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_time+4
sub bl, '0'
add ax, bx
cmp ax, 59
ja ckt_err
mov al, byte ptr tmz_time+6 ;check seconds
sub al, '0'
xor ah,ah
mov bl,10
imul bl
xor bh, bh
mov bl, byte ptr tmz_time+7
sub bl, '0'
add ax, bx
cmp ax, 59
ja ckt_err
mov ax,0
jmp ckt_end
ckt_err:
mov ax,1
jmp ckt_end
ckt_end:
pop dx
pop cx
pop bx
ret
cpm_set_time:
push es
push ds
push si
push di
push bx
push cx
push dx
cli
mov cl, 31h ;Call Get Sysdata Addrs interrupt.
int 0E0h ;CP/M interrupt. ES:BX -> Sysdata.
add bx, 20h ;ES:BX now -> 17 bytes of time/date data.
mov di, bx
mov byte ptr tmz_sep,','
lea si, tmz_date
mov cx, 17
cst_cpy: mov bl, ds:[si] ;copy source to destination
mov es:[di], bl
inc si ;increment source and destination
inc di
dec cx ;decrement count
jnz cst_cpy ;if not zero goto next bit
sti
mov ax, 0
pop dx
pop cx
pop bx
pop di
pop si
pop ds
pop es
ret
cpm_show_time:
push es
push ds
push si
push di
push ax
push bx
push cx
push dx
cli
mov cl, 31h ;Call Get Sysdata Addrs interrupt.
int 0E0h ;CP/M interrupt. ES:BX -> Sysdata.
add bx, 20h ;ES:BX now -> 17 bytes of time/date data.
mov di, bx
lea si, tmz_date
mov cx, 17
csh_cpy: mov bl, es:[di] ;copy source to destination
mov ds:[si], bl
inc si ;increment source and destination
inc di
dec cx ;decrement count
jnz csh_cpy ;if not zero goto next bit
sti
lea si, tmz_date
mov byte ptr tmz_sep,9
call print_str
pop dx
pop cx
pop bx
pop ax
pop di
pop si
pop ds
pop es
ret
isdigit:
cmp al, '0'
jb id_err
cmp al, '9'
ja id_err
mov ah, 0
jmp id_end
id_err:
mov ah, 1
id_end:
ret
include tinylib.a86
include baselib.a86
data dseg
month_siz db 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
msg_wrg_os db 'Requires CP/M-86 1.1',13,10,0
msg_wrg_fmt db 'Invalid Date & Time Format',13,10
db 'Please retry using:',13,10
db 'X>TOD MM/DD/YY HH:MM:SS',13,10
db 'where YY is in range 00-99 for 2000 to 2099',13,10,0
msg_nl db 13,10,0
msg_back db 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
disp_loop db 1
tmz_date db '01/01/01'
tmz_sep db 9
tmz_time db '01:01:01'
db 0
tm_buffer rs 256
db 0
end