.title adaida ; ; Adaida converts ASCII date into internal date. ; call adaida( byte(10), date ) ; returns date in 2nd word., if date is bad, returns 0 ; .dsabl gbl .globl leap .globl day, month, year, date, tbnday, months .psect user$i adaida:: tst (r5)+ mov (r5)+,r1 ; pointer to ascii date tstb @r1 ; null date ?? beq 40$ ; error call getnum ; get the day bcs 40$ ; unexpected eol beq 40$ ; can't be day 0..... cmpb -1(r1),#'- ; correct delimiter? bne 40$ ; nope... mov r0,day ; save day, check when got month swab r0 ; swap and shift so day number asr r0 ; is in bits <09:05> asr r0 asr r0 bicb #40,@r1 ; month(1) ucase bisb #40,1(r1) ; month(2) lcase bisb #40,2(r1) ; month(3) lcase mov r0,date ; save partial rt format date jsr pc,getmon ; get the month bcs 40$ ; unexpected eol cmpb -1(r1),#'- ; correct delimiter? bne 40$ mov r0,month ; save month swab r0 ;swap and shift month into asl r0 ; bits <13:10> asl r0 add r0,date ;continue forming rt format date jsr pc,getnum ;get the year tstb @r1 ;expected eol? bne 40$ cmp r0,#99. ;is it valid? bgt 40$ sub #72.,r0 ;maybe, adjust for rt-type date blt 40$ mov month,r2 dec r2 asl r2 ; *2 mov tbnday(r2),r2 ; max days for this month cmp month,#2 ; feb ?? bne 20$ ; nope, so days as in table mov r0,r4 ; copy year call leap ; leap year ?? bcc 20$ ; br, not a leap year inc r2 ; leap year and feb, so add 1 20$: cmp day,r2 ; is day valid ?? bgt 40$ ; bad day for the month add date,r0 ;year is okay in bits <04:00> 30$: mov r0,@(r5)+ ; return valid date return ; so complete rt format date 40$: clr r0 ; return date 0 br 30$ ; ; getmon returns month number to caller ; enter r1 = > string ; returns r0 = month number ; getmon: mov #months,r0 ; r0 => month names 10$: mov r1,-(sp) ; save current position 20$: mov @sp,r1 ; restore old position mov #4,r2 ; count of characters to match 30$: tstb @r0 ; end of month name string? beq 60$ ; yes...error tstb @r1 ; end of input string? beq 60$ ; yes...error cmpb (r1)+,(r0)+ ; this character matches? bne 20$ ; nope... sob r2,30$ ; match 4 characters tst (sp)+ ; pop off current position sub #months,r0 ; adjust month name offset asr r0 ; / 4 asr r0 tst (pc)+ ; good return 50$: sec ; error return return 60$: tst (sp)+ ; pop off old r1 info br 50$ ; and take error return ; ; getnum returns number ; r1 => string ; r0 = number ; getnum: clr -(sp) ; clear total 5$: tstb @r1 ; end of string? beq 20$ ; yes, error movb (r1)+,r0 ; get a character cmpb r0,#'0 ; is it a valid digit? blo 10$ ; nope... cmpb r0,#'9 ; maybe, check upper limit bhi 10$ ; nope... sub #'0,r0 ; yes, convert to octal asl @sp ; multiply current total by 10. mov @sp,-(sp) asl @sp asl @sp add (sp)+,@sp add r0,@sp ; add this digit br 5$ ; and go get another one 10$: tst (pc)+ ; clear carry 20$: sec mov (sp)+,r0 ; return number in r0 return .end