Binary digits: Difference between revisions

Content added Content deleted
(Added 6502 assembly example)
Line 89:
50 110010
9000 10001100101000
</pre>
 
=={{header|6502 Assembly}}==
{{works with|http://vice-emu.sourceforge.net/ VICE}}
This example has been written for the C64 and uses some BASIC routines to read the parameter after the SYS command and to print the result.
Compile with the [http://turbo.style64.org/ Turbo Macro Pro cross assembler]:
<pre>
tmpx -i dec2bin.s -o dec2bin.prg
</pre>
Use the [http://vice-emu.sourceforge.net/vice_13.html c1541 utility] to create a disk image that can be loaded using VICE x64.
Run with:
<pre>
SYS828,x
</pre>
where x is an integer ranging from 0 to 65535 (16 bit int). Floating point numbers are truncated and converted accordingly.
The example can easily be modified to run on the VIC-20, just change the labels as follows:
<pre>
chkcom = $cefd
frmnum = $cd8a
getadr = $d7f7
strout = $cb1e
</pre>
<lang 6502asm>
; C64 - Binary digits
; http://rosettacode.org/wiki/Binary_digits
 
; *** labels ***
 
declow = $fb
dechigh = $fc
binstrptr = $fd ; $fe is used for the high byte of the address
chkcom = $aefd
frmnum = $ad8a
getadr = $b7f7
strout = $ab1e
 
; *** main ***
 
*=$033c ; sys828 tbuffer ($033c-$03fb)
 
jsr chkcom ; check for and skip comma
jsr frmnum ; evaluate numeric expression
jsr getadr ; convert floating point number to two-byte int
jsr dec2bin ; convert two-byte int to binary string
lda #<binstr ; load the address of the binary string - low
ldy #>binstr ; high byte
jsr skiplz ; skip leading zeros, return an address in a/y
; that points to the first "1"
jsr strout ; print the result
rts
 
; *** subroutines ****
 
; Converts a 16 bit integer to a binary string.
; Input: y - low byte of the integer
; a - high byte of the integer
; Output: a 16 byte string stored at 'binstr'
dec2bin sty declow ; store the two-byte integer
sta dechigh
lda #<binstr ; store the binary string address on the zero page
sta binstrptr
lda #>binstr
sta binstrptr+1
ldx #$01 ; start conversion with the high byte
wordloop ldy #$00 ; bit counter
byteloop asl declow,x ; shift left, bit 7 is shifted into carry
bcs one ; carry set? jump
lda #"0" ; a="0"
bne writebit
one lda #"1" ; a="1"
writebit sta (binstrptr),y ; write the digit to the string
iny ; y++
cpy #$08 ; y==8 all bits converted?
bne byteloop ; no -> convert next bit
clc ; clear carry
lda #$08 ; a=8
adc binstrptr ; add 8 to the string address pointer
sta binstrptr
bcc nooverflow ; address low byte did overflow?
inc binstrptr+1 ; yes -> increase the high byte
nooverflow dex ; x--
bpl wordloop ; x<0? no -> convert the low byte
rts ; yes -> conversion finished, return
 
; Skip leading zeros.
; Input: a - low byte of the byte string address
; y - high byte -"-
; Output: a - low byte of string start address without leading zeros
; y - high byte -"-
skiplz sta binstrptr ; store the binary string address on the zero page
sty binstrptr+1
ldy #$00 ; byte counter
skiploop lda (binstrptr),y ; load a byte from the string
iny ; y++
cpy #$11 ; y==17
beq endreached ; yes -> end of string reached without a "1"
cmp #"1" ; a=="1"
bne skiploop ; no -> take the next byte
beq add2ptr ; yes -> jump
endreached dey ; move the pointer to the last 0
add2ptr clc
dey
tya ; a=y
adc binstrptr ; move the pointer to the first "1" in the string
bcc loadhigh ; overflow?
inc binstrptr+1 ; yes -> increase high byte
loadhigh ldy binstrptr+1
rts
 
; *** data ***
 
binstr .repeat 16, $00 ; reserve 16 bytes for the binary digits
.byte $0d, $00 ; newline + null terminator
</lang>
Output:
<pre>
SYS828,5
101
 
SYS828,50
110010
 
SYS828,9000
10001100101000
 
SYS828,4.7
100
</pre>