Do you have a SEGMENT X USE16 at the front of this code? If not, NASM will be generating the wrong opcodes.
Other than that, I don't see why the code would crash. Best to singlestep it in bochs, and see. The DIV looks like it should work.
Besides that, your math is wrong. You don't need the DIV in the first place. To convert BCD to decimal this way, you'd need to divide by 16, not 10. Which you can do with SHR and AND.
Clock troubles [Fixed]
-
- Member
- Posts: 118
- Joined: Mon May 05, 2008 5:51 pm
Bochs helped, it told me the system was throwing a fit because I was trying to write to address 0x00. So I changed the base write address to 0x1337 and now it works.
BTW:
How does that math work?... Why 16 instead of 10?
Final Code:
BTW:
How does that math work?... Why 16 instead of 10?
Final Code:
Code: Select all
cli
xor ax,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ds,ax
mov ss,ax
mov sp,0x7C00
sti
mov ah,01h
mov cx,2000h
int 10h
start:
mov dx,0
mov si,1337
mov di,1337
call gettime
call strtime
mov ecx,3
loop0:
call bcd2ascii
loop loop0
mov bh,0
call asciiout
call colonout
call asciiout
call colonout
call asciiout
call crout
jmp start
gettime:
mov ah,02h
int 1Ah
ret
strtime:
mov [si],ch
add si,8h
mov [si],cl
add si,8h
mov [si],dh
add si,8h
ret
bcd2ascii:
mov bh,10h
mov ax,[di]
mov dx,0
div bh
add al,30h
add ah,30h
mov [si],al
add si,8h
mov [si],ah
add si,8h
add di,8h
ret
asciiout:
mov al,[di]
mov ah,0Eh
int 10h
add di,8h
mov al,[di]
mov ah,0Eh
int 10h
add di,8h
ret
colonout:
mov al,3Ah
mov ah,0Eh
int 10h
ret
crout:
mov al,0Dh
mov ah,0Eh
int 10h
ret
TIMES 510-($-$$) DB 0x00
SIGNATURE DW 0xAA55
> BTW: How does that math work?... Why 16 instead of 10?
Well, it's because BCD is all based on hex digits, and hex is base 16.
The whole point of BCD is to code 2 decimal digits into separate nibbles of a byte, right?
So, let's take a date as an example. CMOS will return the Day of Month as 0x31, if today is the 31st.
If I want to convert that back to decimal, then the bottom digit is easy, right? Just AND off the bottom 4 bits. So how do I convert that top digit to a 30 (decimal)? Or, in your case, you are converting to ascii directly, so you want to convert it to a 3, and then add '0' to it. To convert a 0x30 (= decimal 48) into a 3, you need to shift it down 4 bits -- which means dividing by 16.
So, instead of doing a DIV 16 to get your values of AL and AH, you could do:
-- which would accomplish basically the same thing (except that al and ah would be reversed from your calculation, I think).
If the value was coded in binary, rather than bcd, then dividing by 10 is correct.
Well, it's because BCD is all based on hex digits, and hex is base 16.
The whole point of BCD is to code 2 decimal digits into separate nibbles of a byte, right?
So, let's take a date as an example. CMOS will return the Day of Month as 0x31, if today is the 31st.
If I want to convert that back to decimal, then the bottom digit is easy, right? Just AND off the bottom 4 bits. So how do I convert that top digit to a 30 (decimal)? Or, in your case, you are converting to ascii directly, so you want to convert it to a 3, and then add '0' to it. To convert a 0x30 (= decimal 48) into a 3, you need to shift it down 4 bits -- which means dividing by 16.
So, instead of doing a DIV 16 to get your values of AL and AH, you could do:
Code: Select all
mov bl, al
and al, 0xf
shr bl, 4
mov ah, bl
If the value was coded in binary, rather than bcd, then dividing by 10 is correct.
-
- Member
- Posts: 118
- Joined: Mon May 05, 2008 5:51 pm
Hymmm that cuts 11 cycles off my code.
My implementation of the idea (one less register):
Works here on the school computers grandly.
Now Im going to ask a REALLY noobish question that may be a tad off topic but might as well ask it here rather than bog up the forum elsewhere.
When it boots does it copy the whole boot sector to the 7C address? I was under the impression that it only copied a peice of it but when I remo ve the disk from the school computers it just keeps ticking. Furthermore while the disk is in it only reads for half a second and then the disk goes idle (by that time the clock has already begun ticking).
My implementation of the idea (one less register):
Code: Select all
mov ah,al
and ah,0Fh
shr al,4
Now Im going to ask a REALLY noobish question that may be a tad off topic but might as well ask it here rather than bog up the forum elsewhere.
When it boots does it copy the whole boot sector to the 7C address? I was under the impression that it only copied a peice of it but when I remo ve the disk from the school computers it just keeps ticking. Furthermore while the disk is in it only reads for half a second and then the disk goes idle (by that time the clock has already begun ticking).