You can regard 어(요) as the default ending suffix.
Rule 1) It changes to 아(요) if the last vowel in the stem is an ㅏ, ㅑ, ㅗ, ㅘ
Rule 2) It changes to 여(요) if the verb is ~하다.
* It doesn't change after 었(past),겠(future)
Likely, 었 is the default past tense suffix.
Rule 3) It changes to 았 if the last vowel in the stem is an ㅏ, ㅑ, ㅗ, ㅘ
Rule 4) It changes to 였 if the verb is ~하다.
* It doesn't change after 었(past),겠(future)
자요 << 자(다) + (어요->아요)(Rule 1)
잤어요 << 자(다) + (었->았)(Rule 3) + 어요 -> (자았어요 => 잤어요)(repeated vowel contraction : mandatory)
봤어요 << 보(다) + (었->았)(Rule 3) + 어요 -> (보았어요 -> 봤어요)(duplicated vowel contraction : optional)
Othere examples,
먹었어요 << 자(다) + 었 + 어요 -> 먹었어요
잡았어요 << 잡(다) + (었->았)(Rule 3) + 어요
잡았겠어요 << 잡(다) + (었->았)(Rule 3) + 겠 + 어요
잡았었어요 << 잡(다) + (었->았)(Rule 3) + 었 + 어요