Another bit of 68xx code - Page 1
Forum section: electronics / general

author: metertech58761
author_rank: Frequent Contributor
timestamp: December 09, 2022, 06:19:07 am
content: I recently posted a bit of HC11 assembly code for converting unpacked BCD to binary, and I thank those that took time to look at it and for the replacement code that someone offered.I figure the code that does the opposite is probably just as inefficient, so here we go.; Convert binary data to BCD valuesbin2BCD LDX f2BCDLDAB f2bytesLDAA #$00func02_1 STAA $00,XDEXDECBBNE func02_1INXSTX f2BCDLDAA #$80STAA f2bitposfunc02_2 LDX f2binaryLDAA $00,XPSHADEXSTX f2binaryfunc02_3 PULAPSHAANDA f2bitposBEQ func02_5LDX f2BCDLDAB f2bytesLDAA $00,XADDA #$01func02_4 DAASTAA $00,XDECBBEQ func02_5INXLDAA $00,XADCA #$00BRA func02_4func02_5 LDAA f2bitsCMPA #$01BEQ func02_7LDX f2BCDLDAB f2bytesLDAA $00,XADDA $00,Xfunc02_6 DAASTAA $00,XDECBBEQ func02_7INXLDAA $00,XADCA $00,XBRA func02_6func02_7 DEC f2bitsBEQ func02_8LSR f2bitposBNE func02_3PULALDAA #$80STAA f2bitposBRA func02_2func02_8 PULARTSAs I mentioned in the other thread, this routine has a few prerequisites before being called:f2binary - 16-bit address of the source binary dataf2BCD - 16-bit address of the packed BCD output (these are stored in the same sequence as the readout as mentioned in the other thread; 7/6, 5/4, 3/2, 1/0)f2bytes - I assume this is a byte counter (only 2 values are used: 2 or 4)f2bits - I assume this is a bit counter (only 2 values are used: 8 or 24 - corresponding to above values)

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 06, 2023, 07:59:12 pm
content: I'm now actively working to figure out this bit of code... my interest is trying to figure out why it pushes and pulls values on and off the stack versus using an actual variable in RAM.It seems 6811IDE doesn't work well with PSHA / PULA, and I'm having fits trying to get THR6811 to accept ORG - no matter how I try and format the address, it gets rejected every time.

author: brucehoult
author_rank: Super Contributor
timestamp: January 07, 2023, 11:13:06 pm
content: Quote from: metertech58761 on January 06, 2023, 07:59:12 pmIt's only one thing -- the current byte from f2binary.Push and pull are normally used for code compactness, at the expense of speed, because they are only 1 byte, vs 2 bytes each for store to direct page and load from direct page. But that is negated when you do "PULA;PSHA" when it could have been just a load, and have to add not one but two gratuitous "PULA" in func02_7 / func02_8 to clean up. You're ending up with 5 bytes of code in total when it could have been just 4 with storing the result of "LDAA $00,X" to DP and then loading it at the start of func02_3 and that's it.I suspect the code was hacked on a lot after it was initially "designed".The whole 68xx "LDX ptr;LDAA $00,X;DEX;STX ptr" dance kind of pisses me off every time I see it. Sooo much easier and faster on 6502 to just do "LDA (ptr),Y;DEY", especially when you know the buffers are no more than 256 bytes, as here ("f2bytes" fits into B). When the size can be greater than 256 on 6502 then you need a little bit of fiddling in an outer loop which more or less equalises the code size. but there's still a fast inner loop.Or 6809, of course, where you have X, Y, and if you need it U.

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 09, 2023, 09:33:03 pm
content: So I could just add a dedicated variable (or even use one of the existing 'scratchpad' variables) and just do away with PSHA / PULA?The code I started with could easily be described as "And it still works?! Really?!" Some sections only needed minor cleanup but two major sections still had to be torn to bits and reassembled in a more logical order (and the result is ALSO a few dozen bytes shorter!)The bit about the index registers on the 68xx vs. the 6502 IS a pain indeed! It's almost like they flipped the index and base around.

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 10, 2023, 01:46:00 am
content: I already wrote the bin->dec for youhttps://www.eevblog.com/forum/programming/cleaning-up-a-bit-of-6800-assembly-code/msg4569265/#msg4569265I don't have the hardware to test it using the DAA instruction so it was emulated. Not exactly what you asked for as I didn't have the requirements. I'll look later at your code and resolve any differences.

author: brucehoult
author_rank: Super Contributor
timestamp: January 10, 2023, 01:49:52 am
content: Quote from: metertech58761 on January 09, 2023, 09:33:03 pmSure looks like it.But the whole code is pretty whack. Why do binary/BCD conversion 1 bit at a time (with a loop) instead of 4 bits at a time?

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 10, 2023, 04:11:56 am
content: Quote from: metertech58761 on January 09, 2023, 09:33:03 pmYou don't even need to do that. The way it is written, you can get the value into A withCode:LDX f2binary ; address of binary to convertLDAA $01,Xbecause X was decremented. I would prefer to decrement X at the end of the loop so it is LDAA $00,X but that's cosmetic.It appears the code is generic, convert X bits of binary to Y bytes of BCD. You say X is either 8 or 24 and Y is either 2 or 4, makes sense.It also does not destroy the binary (which my code does).Working on it.

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 10, 2023, 06:42:55 am
content: Quote from: brucehoult on January 10, 2023, 01:49:52 amDo you have an algorithm that does that?I now have a somewhat bastard child of my code and the OP code. It runs in the HVRSoftware emulator, make sure to put a break at Line 52 or it will just keep going. An oddity, the emulator did not return a Z flag on line 45 when the mask bit got shifted out. I thought it should. So I used BCC instead of BNE (the mask bit gets shifted into C). And I had to emulate DAA.I couldn't figure out which way the input and output bytes were ordered or addressed, so I made both big endian. That makes it easy to see the result in the emulator 7654321Code:bra mainbinVal.byte $74,$CB,$B1 ; big endianf2binary .rmb 2xyz .rmb 8decVal .rmb 8f2BCD .rmb 2f2bytes .byte 4f2bits .byte 24f2bitpos .rmb 1mainLDX#binValSTXf2binaryLDX#decValSTXf2BCDbin2BCD LDX f2BCD ; address of output ? couldn't figure what this DEX, INX adjustment of f2BCD was doingLDAB f2bytes ; number of bytes to outputLDAA #$00func021 STAA $00,X ; clear output to zeroDEXDECBBNE func021INXSTX f2BCDfunc022 LDAA #$80 ; mask forSTAA f2bitpos ; bit position in binary bytefunc023 LDX f2binary ; address of byte in binary to convertLDAA $00,XLDX f2BCD ; set up for loopLDAB f2bytesANDA f2bitpos ; a bit of A = 1?ADDA #$FF ; will set carry if A has any bit setfunc024 LDAA $00,X ; double the BCD and add in any carryADCA $00,Xbsr EmDAA ; and decimal adjust itSTAA $00,XDEX ; *** or INX if little endianDECB ; adjusted all output bytesBNE func024 ; no, next bytefunc025 DEC f2bits ; more binary bits to process?BEQ func028 ; noLSR f2bitpos ; yes, adjust the maskBCC func023 ; mask still has a bitLDX f2binary ; no bits, move to the next binary byteINX ; *** or DEX if little endianSTX f2binaryBRA func022 ; and repeatfunc028 RTS; emulate the DAA instructionEmDAA pshbtabtpaanda #$20 ; isolate half carrybcs EmCybne EmCnHy ; C clear H set; C clear H cleartbaanda #$0Fcmpa #$0Abcs xxxEmCnHy addb #$06bcs Em60xxx cmpb #$A0bcs EmXCnEm60 addb #$60EmXCy tbapulbsecrtsEmXCn tbapulbclcrts; C setEmCy bne EmCyHy ; C set H settbaanda #$0Fcmpa #$0Abcs Em60EmCyHy addb #$06bra Em60.end

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 10, 2023, 08:30:33 am
content: I'll check out the code, thanks again.Also, yes, both the source (f2bin) and destination (f2BCD) ranges are big endian.It also appears f2bits is the actual number of bits to be converted and f2bytes is the number of bytes to be converted plus one, and that matches the unpacking process for one of the instances after this routine is called.Oh, and for laughs, I'm attaching a reconstruction of the as-dumped code and the results of my ongoing cleanup.

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 10, 2023, 11:29:56 am
content: Quote from: metertech58761 on January 10, 2023, 08:30:33 amI am confused by the destination address passed to Bin2BCD in the variable f2BCD. It looks like it is the address of the last byte, and the destination gets cleared by stepping backward to the first byte. Then when doing the binary to decimal conversion it steps from first to last. Say the destination number is 01234567 it looks to me like it ends up in the bytes as 67|45|23|01 which is not big endian. This seems to be confirmed by dispBCD routine which will unpack it as 0|1|2|3|4|5|6|7 - little endianQuoteSo you had a dump of the memory, disassembled it, and now trying to make sense of it? Arrrrrgh!!I think it needs a LOT more annotation before doing a cleanup. What the ** are all those tests doing? I'd put a page of notes at the beginning to give some idea of what is going on.How's your headache? bedtime here, I'm off.

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 10, 2023, 01:32:31 pm
content: It may help to know the physical display on the unit is arranged 98 76543210.Digits 9 and 8 are represented by the variable testOne, hence the backwards representation of the test number.If you think this is hard to make sense of, the firmware for the LMT-2 is even worse - like trying cram 5K of code into 4K.Edit: I've attached notes that may help make more sense of the code.

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 17, 2023, 11:02:24 am
content: I downloaded the files and looked at them. Too much to take in without spending a lot of time (which, if I was being paid big bucks, maybe. Otherwise there's plenty of other things I can be doing). Specific questions are OK. Did the bin->dec code do the job?

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 18, 2023, 03:17:25 am
content: I have it saved, but I need to take a step back to make sure I understand how the data is being set up and handled. Perhaps we can trim the overhead requirements.Also, right now, the code goes from binary -> packed BCD -> unpacked BCD. I'm wondering if that intermediate step is truly necessary.

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 18, 2023, 05:50:29 am
content: Quote from: metertech58761 on January 18, 2023, 03:17:25 amIt is not necessary but it is advantageous. To convert from binary to decimal the process is to start with a decimal number of zero. then look at the binary number highest bit to lowest bit. Each decimal digit is multiplied by two (adding it to itself does the same thing) and the bit from the binary is added in. It is necessary to check each decimal digit after the add to see if it is > 9 and if it is subtract 10 and carry 1 to the next higher digit. So in your case it would be necessary to look at and possibly adjust every decimal digit for every bit moved in. The DAA instruction helps, but you still end up having to check and adjust every digit for every bit processed.By using packed decimal, it halves the number of bytes used to store decimal digits, and the DAA instruction does all the heavy lifting of adjusting for carries so it is not necessary to check each digit after each double. The computation time is a lot less and more than makes up for the extra step of unpacking. And if the packed to unpacked was a loop (I don't think your is at the moment) then a bit of code space is saved (although more code than binary->unpacked decimal. So it is a trade off between code and speed.

author: DiTBho
author_rank: Super Contributor
timestamp: January 18, 2023, 07:25:09 am
content: I bought a keyboard and found an HC11 chip as controllerthis resumed my interests for HC11 hacking and programmingSo, I am porting BUFFALO/HC11 from Motorola-AS/11 to GNU-AS/11.I can say ... BUFFALO is full of good assembly examplestake a deep look, it's very informative and entertaining

author: MIS42N
author_rank: Frequent Contributor
timestamp: January 18, 2023, 09:21:01 am
content: Quote from: DiTBho on January 18, 2023, 07:25:09 amMore info? I looked up buffalo hc11 and it described a monitor program. But no good assembly examples. I'm not looking in the right places.I prefer cross assembly - a good example is MPLAB X, has an emulator. I build some sort of UART capability into the program so when it is in the target, it can be debugged further if needed.

author: DiTBho
author_rank: Super Contributor
timestamp: January 18, 2023, 10:25:42 am
content: Quote from: MIS42N on January 18, 2023, 09:21:01 amyeah, BUFFALO is a monitor. It has several subroutines which are good examples of hc11 assembly programming.There are even BCD subroutines extensions that you can re-use as kind of "BIOS" for your uploaded programs.Quote from: MIS42N on January 18, 2023, 09:21:01 amHC11 is early 90's technology, rather abandonware. There is still some copy of PCBUG11 around, written in Delphi. It's Windows-only, but it comes with a "talker" (chip specific, 256byte, 512byte, greater), designed to consume only 200byte of ram, it allows iterative development and debugging via uart at 9600bps.Nice idea!I've implemented something similar on GNU/Linux (same "talker", different host-debugger), but if you have enough ROM space, you can also use BUFFALO for that, even writing a gdb-buffalo--bridge so you don't need to write a gdb11-stub.I think it's better, because ... well, a gdb-stub is ... basically ... the same as the mentioned "talker", just much more powerfulgcc has been pretty ignoring hc11 for several releases, *there was* a simulator with a very old gdb package.

author: metertech58761
author_rank: Frequent Contributor
timestamp: January 18, 2023, 11:53:29 am
content: So, 5 of the calls to the binary to BCD routine take the same parameters, so it's like we could almost just build those parameters into the routine: f2bits (24), f2bytes (4 - but we are actually converting 3 bytes, the existing code counting down to 1), and f2BCD (position 6/7, the code once again stopping one digit shy). The only thing that changes is which three bytes we are converting to decimal.The other two calls handle one digit apiece... given the firmware ID goes no higher than 95 (0x5F), and the revision is likely a low value number, a simple DAA should suffice for those values, correct?