Category : Files from Magazines
Archive   : N7V11.ZIP
Filename : SCANTD.ASM
Output of file : SCANTD.ASM contained in archive : N7V11.ZIP
title SCANTD.ASM --- time & date input conversion
page 55,132
;
;
; SCANTD.ASM --- Convert ASCII times and dates
; to binary in MS-DOS format.
;
; Copyright (c) 1988 Ziff Communications Co.
; PC Magazine * Ray Duncan
;
; This module contains two public routines:
;
;
; SCANTIME convert ASCII time to binary
;
; Call with: DS:SI = address of string
;
; Returns: Carry = Set if bad time
; or
; Carry = Clear if good time
; CH = hour
; CL = minute
; DH = second
; DL = hundredths
; DS:SI = address+1 of terminator
; other registers preserved
;
;
; SCANDATE convert ASCII date to binary
;
; Call with: DS:SI = address of string
;
; Returns: Carry = Set if bad date
; or
; Carry = Clear if good date
; CX = year (1980+)
; DH = month (1-12)
; DL = day (1-31)
; DS:SI = address+1 of terminator
; other registers preserved
;
DGROUP group _DATA
_DATA segment word public 'DATA'
n1 dw 0 ; first converted field
n2 dw 0 ; second converted field
n3 dw 0 ; third converted field
dlmtab db '/-.' ; valid date delimiters
dlmtab_len equ $-dlmtab ; length of table
tlmtab db ':.' ; valid time delimiters
tlmtab_len equ $-tlmtab ; length of table
; date format table
dftab dw mdy ; code 0 = mon/day/year
dw dmy ; code 1 = day/mon/year
dw ymd ; code 2 = year/mon/day
dfptr dw 0 ; becomes address of
; mdy, dmy, or ymd
mdy dw n2 ; day
dw n1 ; month
dw n3 ; year
dmy dw n1 ; day
dw n2 ; month
dw n3 ; year
ymd dw n3 ; day
dw n2 ; month
dw n1 ; year
daytab dw 31,28,31 ; days in month
dw 30,31,30
dw 31,31,30
dw 31,30,31
cbuff db 34 dup (0) ; current country info
_DATA ends
_TEXT segment word public 'CODE'
assume cs:_TEXT,ds:DGROUP
extrn atoi:near ; we need ATOI routine
public scantime ; make these routines
public scandate ; available to Linker
scantime proc near ; convert ASCII time to binary
push ax ; save registers
push bx
push di
push es
call getctry ; get internationalization
; info if first call
call chknum ; convert first field
jc scant9 ; jump, bad number
mov n1,ax ; save result
mov al,[si-1] ; check time delimiter
call chktlm
jc scant9 ; jump if no good
call chknum ; convert second field
jc scant9 ; jump, bad number
mov n2,ax ; save result
mov n3,0 ; force seconds = 0
mov al,[si-1] ; another field present?
call chktlm ; if no delimiter,
jc scant1 ; assume seconds absent
call chknum ; convert third field
jc scant9 ; jump, bad number
mov n3,ax ; save value
scant1: ; validate entry
cmp word ptr n1,0 ; hours must be 0-23
jc scant9 ; jump, bad hour
cmp word ptr n1,24
cmc
jc scant9 ; jump, bad hour
cmp word ptr n2,0 ; minutes must be 0-59
jc scant9 ; jump, bad minute
cmp word ptr n2,60
cmc
jc scant9 ; jump, bad minute
cmp word ptr n3,0 ; seconds must be 0-59
jc scant9 ; jump, bad second
cmp word ptr n3,60
cmc
jc scant9 ; jump, bad second
; load the results...
mov ch,byte ptr n1 ; hours
mov cl,byte ptr n2 ; minutes
mov dh,byte ptr n3 ; seconds
mov dl,0 ; hundredths always = 0
scant9: ; common exit point
pop es ; restore registers
pop di
pop bx
pop ax
ret ; return to caller
scantime endp
scandate proc near ; convert ASCII date to binary
push ax ; save registers
push bx
push di
push es
call getctry ; get internationalization
; info if first call
call chknum ; convert first field
jc scand9 ; jump, bad number
mov n1,ax ; save result
mov al,[si-1] ; get delimiter
call chkdlm ; and check it
jc scand9 ; exit, bad delimiter
call chknum ; convert second field
jc scand9 ; jump, bad number
mov n2,ax ; save result
mov al,[si-1] ; get delimiter
call chkdlm ; and check it
jc scand9 ; exit, bad delimiter
call chknum ; convert third field
jc scand9 ; jump, bad number
mov n3,ax ; and save result
; validate entry and
; load results...
mov bx,dfptr ; point to year
mov bx,[bx+4] ; year must be 80-99
cmp word ptr [bx],80
jc scand9 ; jump, bad year
cmp word ptr [bx],100
cmc
jc scand9 ; jump, bad year
mov cx,[bx] ; load year and correct
add cx,1900 ; to range 1980-1999
; adjust days/month table
mov daytab+2,28 ; assume not leap year
test word ptr [bx],3 ; is it a leap year?
jnz scand1 ; jump, not multiple of 4
mov daytab+2,29 ; fix table for leap year
scand1: mov bx,dfptr ; point to month
mov bx,[bx+2]
cmp word ptr [bx],1 ; month must be 1-12
jc scand9 ; jump, bad month
cmp word ptr [bx],13
cmc
jc scand9 ; jump, bad month
mov dh,byte ptr [bx]; load month result
mov di,[bx] ; also prepare to index
dec di ; into days/month table
shl di,1
mov bx,dfptr ; point to day
mov bx,[bx]
cmp word ptr [bx],1 ; day must be >= 1
jc scand9 ; jump, bad day
mov ax,[di+daytab] ; get max day for this
; month from table
cmp ax,[bx]
jc scand9 ; jump, bad day
mov dl,byte ptr [bx]; load day result
scand9: ; common exit point
pop es ; restore registers
pop di
pop bx
pop ax
ret ; return to caller
scandate endp
chkdlm proc near ; check date delimiter
; call with:
; AL = character to check
; returns:
; Carry = Clear if OK
; Carry = Set if not OK
push ds ; make delimiter table
pop es ; addressable
mov di,offset DGROUP:dlmtab
mov cx,dlmtab_len
repne scasb ; compare to table
je chkd9 ; jump if match found
; (Carry is cleared)
stc ; else force Carry = set
chkd9: ret ; back to caller
chkdlm endp
chktlm proc near ; check time delimiter
; call with:
; AL = character to check
; returns:
; Carry = Clear if OK
; Carry = Set if not OK
push ds ; make delimiter table
pop es ; addressable
mov di,offset DGROUP:tlmtab
mov cx,tlmtab_len
repne scasb ; compare to table
je chkt9 ; jump if match found
; (Carry is cleared)
stc ; else force Carry = set
chkt9: ret ; back to caller
chktlm endp
chknum proc near ; check for valid numeric
; field and convert it
; call with:
; DS:DI = ASCII field
; returns:
; Carry = clear if OK
; AX = value of field
; or
; Carry = set if not OK
; check if >= '0'
cmp byte ptr [si],'0'
jb chkn1 ; jump, bad digit
; check if <= '9'
cmp byte ptr [si],'9'+1
cmc ; invert Carry flag
jc chkn1 ; jump, bad digit
call atoi ; convert field and
clc ; clear carry flag
chkn1: ret ; back to caller
chknum endp
getctry proc near ; get country information
test dfptr,-1 ; did we already get info?
jnz getc2 ; if we did, just exit
mov ax,3000h ; Fxn. 30h = get DOS vers.
int 21h ; transfer to MS-DOS
or al,al ; is it version 1.x?
jz getc1 ; yes, jump
mov ax,3800h ; get current country info
mov dx,offset DGROUP:cbuff
int 21h ; transfer to MS-DOS
getc1: ; get date code (default=0)
mov bx,word ptr cbuff
shl bx,1 ; extract pointer to
mov ax,[bx+dftab] ; date format table
mov dfptr,ax
getc2: ret ; back to caller
getctry endp
_TEXT ends
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/