Gabriel,
You're off to a pretty good start! I assume you want to handle strings longer than 256 bytes since you're using a 16 bit byte counter in BC. In this case, the compare operation you do after the DCX B at the bottom of the loop won't work properly since it's only checking the LSB byte of the counter for zero.
Secondly, though this is changing your algorithm a bit, rather than shifting and adding D to create the mirror byte, you could simply shift the mirror byte the opposite direction as you shift the source byte. The RAL instruction, for example, will pull the value of the carry bit in as the new LS bit of the result.
Finally, I unrolled the first call to NXTBYTE, though this doesn't really affect much of anything.
I didn't update the code with the following comments, but it would be more efficient to save the source byte into a register after each shift rather than back into memory each time. The load and save to a register for each shift would save 4 cycles per bit or up to 32 cycles per byte. Unfortunately, you have no spare registers left unless you really only need to handle strings less than 256 bytes in length. Or, you could push/pop HL each time through the byte loop, but that would take 21 of the cycles you'd be saving, so it may no be worth it.
Mike
- Code: Select all
; ***************************************************************************
; * BIT-FLIPPER Flip bits (7<>0, 6<>1, 5<>2, 4<>3) in each byte in a string *
; ***************************************************************************
; This program starts at 0100h
; The string starts at 8000h
; The stack is wherever CP/M puts it
; H,L holds the address where the string starts
; B,C holds the length of the string
; D holds count of bits within a byte
; E stores the mirrored byte until we're ready to put it back into memory
org 0100h
LXI H,8000h ; put address of string-start into H,L pair
LXI B,0005h ; put string length (16 bits) into B,C pair
NXTBYTE MVI D,8 ; D=bit counter within a byte
NEXTBIT MOV A,M ; A=byte we're working on (pointed to by H,L)
RRC ; shift source byte right into carry
MOV M,A ; save the rotated byte back in memory
MOV A,E ; A=partially completed mirror byte
RAL ; shift new bit left into the mirror byte
MOV E,A ; save the temp result in E
DCR D ; decrement bit counter
JNZ NEXTBIT ; loop through all 8 bits
; The completely flipped byte is in A. Store back in memory at (HL),
; then increment HL, decrement byte count in BC until BC=0.
MOV M,A ; store mirrored byte in memory
INX H ; point to the next location in memory to work on
DCX B ; decrement 16-bit byte counter
MOV A,B ; A=msbyte of counter
ORA C ; A=msbyte + lsbyte of counter
JNZ NXTBYTE ; loop while BC not zero
RET ; return to CP/M
Mike