1
Create a new grid using your grids extent as input and with a spacing of half your grid. My start grid spacing is 200 m, so I create a new one with 100 m to get four squares in each.
2
Join attributes by location to join the id (56, 57, 58, 59 in your screenshot) of the large grid to the small grid. Your small grid should be Join to features in layer, and predicate should be are within:

My id column in the large grid is named id so I specify it in Fields to add
3
Execute SQL with row_number and char functions:
select *, concat(id_2, '_', char( row_number() over (partition by id_2 order by id_2, st_x(st_centroid(geometry)), -st_y(st_centroid(geometry))) + 64)) as newid
from input1
My joined id column is named id_2 after the Join attributes by location. So change id_2 to the name of your id column in the query above (if it is not id_2).
The query will number each id ordered by id, x centroid coordinate and negative y centroid coordinate and add 64 to produce the numbers 65, 66, 67, 68 and they are converted to A, B, C, D with char function.
4
The output layer will be temporary, save it to disk with Convert format
