|
Post by admin on Mar 7, 2022 19:57:26 GMT
Found a solution/hack:
1. Add new function to asmguts.h:
void InstrXBWW(u_long op, u_char b1, u_short w1, u_short w2) { InstrClear(); InstrAddX(op); InstrAddB(b1); InstrAddW(w1); InstrAddW(w2); }
2. In asmguts.h change return value of the EvalBranch function from:
return val & 0xFF;
to
return val & 0xFFFF;
3. In asm68hc16.c under the o_BRCLR case:
case o_BRCLR: // $xxxx,X,#$mm = parm+$00 // $xxxx,Y,#$mm = parm+$10 // $xxxx,Z,#$mm = parm+$20 // $xxxx,#$mm = parm+$30 // $xx,X,#$mm = (~parm & 0x01)*$40 + $8B // $xx,Y,#$mm = (~parm & 0x01)*$40 + $9B // $xx,Z,#$mm = (~parm & 0x01)*$40 + $AB
val = Eval(); known = evalKnown; reg = GetIndex(); Comma(); Expect("#"); val2 = EvalByte(); if (typ == o_BRCLR) { Comma(); if (known && 0 <= val && val <= 255) { val3 = EvalBranch(4); if (reg<0) reg=3; InstrXBBB((~parm & 0x01)*0x40 + 0x8B + reg*16,val2,val,val3); } else { val3 = EvalBranch(6); if (reg<0) reg=3; //InstrXBWB((parm&0xFF)+reg*16,val2,val,val3); InstrXBWW((parm&0xFF)+reg*16,val2,val,val3); } } else if (reg < 0) { InstrXBW(parm+0x30,val2,val); } else { if (known && typ == o_BCLR && 0 <= val && val <= 255) InstrXBB(parm+0x1700+reg*16,val2,val); else InstrXBW(parm+ reg*16,val2,val); } break;
comment out the InstrXBWB call and change it to the new InstrXBWW call.
|
|
Piton
Junior Member
Posts: 94
|
Post by Piton on Mar 7, 2022 20:00:19 GMT
Add new func asmx.c and asmcx.h change val3 = EvalBranch(5); to val3 = EvalWBranch(6); void InstrXBWW(u_long op, u_char b1, u_short w1, u_short w2) { InstrClear(); InstrAddX(op); InstrAddB(b1); InstrAddW(w1); InstrAddW(w2); }
|
|
|
Post by admin on Mar 8, 2022 9:54:52 GMT
There were quite a few bugs in the source code. I patched/hacked it up and called it v1.8.3. Source package: asmx-1.8.3.zipThe makerom app has an unresolved issue where it writes a stray byte to the binary file for no apparent reason, sometimes it does, sometimes it does not, the worst kind of bug. So I couldn't care less and used hex2bin instead. As of now with v1.8.3 the compiled stock SBEC3 bootloader source file (not published yet) is a byte-by-byte match with the original binary.
|
|
Piton
Junior Member
Posts: 94
|
Post by Piton on Mar 8, 2022 11:54:34 GMT
Fine. A lot can be done together. My suggestions.
case o_JMP: InstrX3(0x7A+(parm & 0x80),val); change InstrX3(0x7A+(parm & 0x80),val & 0xFFFFF); ........ case o_BRCLR:
val3 = EvalBranch(6); //+-127 branch change val3 = EvalWBranch(6); //+-32768 branch
|
|
|
Post by admin on Mar 8, 2022 12:10:23 GMT
Thank you Konstantin, it's always a pleasure when you chime in with your elegant fixes!
The EvalWBranch(6); fixed one of the hack that made me add the value 4 to val3.
Download link is updated in the previous post.
|
|
Piton
Junior Member
Posts: 94
|
Post by Piton on Mar 8, 2022 12:28:43 GMT
Do not worry. A lot of mistakes.
|
|
|
Post by dino2gnt on Mar 8, 2022 15:16:38 GMT
|
|
|
Post by dino2gnt on Mar 9, 2022 22:02:20 GMT
I can't seem to get block-erase to work reliably. I am running the delete in a loop with a timer such that if the status register reports not ready, or if the erase fails (Vpp error, etc) it will loop, retrying the erase block command until the timer runs out or the command executes with no errors in the status register. This is to give me time to reach over and press the button that cuts SCI RX over from serial to +20V. Implementing the write loop like this works great. I can write data to pre-erased blocks like a champ in blocks of up to 255 bytes and it happily spins away retrying the write until I hit the button and create conditions allowing it to succeed. On erase, it will loop with status 0xA8 (10101000 / Ready - Block Erase Error - Vpp range error) until I apply +20V, whereupon those bits unset (AND with 0x78 equals zero) and the loop exits successfully. When I check the status register after the fact, it still contains 0xA8 and the block is not erased
I could use another set of eyes.
CMD_20: ldab #$21 ; echo 21 for 20 acknowledge jsr TXBYTE ldab #$4 tbxk ldx #$0000 jsr RXBYTE ; which flash bank to erase 0x00 - 0x04 jsr TXBYTE ; echo bank CMPB #$00 beq ERLOOP ; X already 0x40000 CMPB #$01 beq BANK1 CMPB #$02 beq BANK2 CMPB #$03 beq BANK3 CMPB #$04 beq BANK4
TX_RTN: jsr TXBYTE ; B will contain error or success ;jsr CLRSTAT ; put us back in read-array lbra START ; if no match, bail out ; XK:IX = 0x40000 ;BANK0: bra ERLOOP ; jump erase flash
BANK1: ldx #$4000 ; XK:IX = 0x44000 bra ERLOOP ; jump erase flash
BANK2: ldx #$6000 ; XK:IX = 0x46000 bra ERLOOP ; jump erase flash
BANK3: ldx #$8000 ; XK:IX = 0x48000 bra ERLOOP ; jump erase flash
BANK4: ldab #$6 ; 0x60000 because tbxk ; IX is already 0x0000
ERLOOP: jsr INITGPT ; init GPT jsr TIMEOUT ; set timeout ldd #$3F ; set retries std ADRWORD ; store retries TMRLOOP: brclr $7922,Z,#$10,TMRGOOD jsr TIMEOUT ; Reset timeout until retries=0 decw ADRWORD ; 256 divider with 15 retries should be over 10 clock seconds? beq ER_TMOUT jsr RD_STAT ; debug jsr TXBYTE ; debug TMRGOOD: jsr CLRSTAT jsr RD_STAT ; Fetch status andd #$80 ; check ready bit beq TMRLOOP ; bit 8 = 0, busy / not ready jsr ERASE ; if WSM is ready, send erase commands jsr RD_STAT ; Fetch status andd #$78 ; Erase suspended / Vpp range error &tc bne TMRLOOP ; Erase failed, retry ;ldab #$22 ; no errors, we're good? jsr RD_STAT ; debug lBRA TX_RTN ER_TMOUT: ldab #$80 ; 80 time out / fail | change these back to bra later lBRA TX_RTN RD_STAT: ldd #$70 ; CMD Read Status Register std 0,X ldd 0,X ; Read Status register rts ; Status register in D CLRSTAT: ldd #$50 std 0,X ; Clear CSM status register rts ERASE: jsr CLRSTAT ldd #$0020 ; CMD erase std 0,X ; Bank address ldd #$00D0 ; CMD erase confirm std 0,X rts ; Set timeout TIMEOUT: ldd $790A,Z ; Timer Counter Register (TCNT) addd #$0F424 ; some constant std $7916,Z ; Timer Output Compare Register 2 (TOC2) ldab $7922,Z ; Timer Flag Register 1 (TFLG1) bclr $7922,Z,#$10 rts ; Init GPT INITGPT: clr $791E,Z ; Timer Control Register 1 (TCTL1) ldab #6 ; 256 divider stab $7921,Z ; Timer Mask Register 2 (TMSK2) rts
A side note: I can't even get some blocks to delete consistently writing the commands directly to the CSM via the BDM interface on this ECU. It's really strange.
|
|
|
Post by admin on Mar 9, 2022 22:26:45 GMT
ERASE: jsr CLRSTAT
In 03_LdErase status is only cleared once during initialization. Calling it right before erasing seems suspicious to me.
|
|
|
Post by dino2gnt on Mar 10, 2022 16:35:09 GMT
Part of the problem is that X isn't being set properly. I may discard all the "bank select" case and make the command take an address instead, which would also make it consistent with how the other commands function. This would make knowing what addresses correspond to which bank the user's (or front end's) responsibility, but if it's documented that's probably good enough.
|
|
|
Post by dino2gnt on Mar 11, 2022 3:59:09 GMT
Yeah, some more careful handling of the values that become XK and IX cleared this up. Delete now works consistently. That gives it read, write, and erase capabilities. it's functional enough to be used for reflashing Source and binary in my github.
|
|
|
Post by admin on Mar 11, 2022 6:35:10 GMT
Legend.
|
|
Piton
Junior Member
Posts: 94
|
Post by Piton on Mar 17, 2022 18:44:03 GMT
Hello Dino. Looked at your current code.
LOADY: ldab #0
tbyk ; YK:IY = 0x00396
ldy #$396 ; NOTE this is the memory location for the start of SETUP and will change
rts ; if the assembly changes. We overwrite our init code as RAM buffer. I couldn't figure
; how to do this with a label :( change to
LOADY: ldab #0
tbyk ; YK:IY = 0x00396
ldy #SETUP
rts
This code wrong
MRLOOP: brclr $7922,Z,#$10,TMRGOOD
jsr TIMEOUT ; Reset timeout until retries=0
jsr CLRSTAT
decw CNTBYTE ; 256 divider with 15 retries should be over 10 clock seconds?
beq ER_TMOUT
TMRGOOD: jsr ERASE ; if WSM is ready, send erase commands
jsr RD_STAT ; Fetch status
andd #$80 ; check ready bit
beq TMRLOOP ; bit 8 = 0, busy / not ready
jsr RD_STAT ; Fetch status
andd #$78 ; Erase suspended / Vpp range error &tc
bne TMRLOOP ; Erase failed, retry
ldab #$22 ; no errors, we're good?
bra TX_RTN The erase command is given only once, while your command is repeated in a cycle.
|
|
|
Post by dino2gnt on Mar 17, 2022 18:49:35 GMT
Ah ha! #SETUP assembled to 37 BD 03 96
It was giving me 17 FD XX XX before, which was not functional.
Thanks!
The erase command is given only once, while your command is repeated in a cycle. This is intentional. It will send the command until it succeeds (per the CSM status register), or the timer expires. It can only succeed when Vpp is high.
|
|
Piton
Junior Member
Posts: 94
|
Post by Piton on Mar 17, 2022 19:04:04 GMT
Not right. The CSM cannot immediately set the ready bit, according to the specification, the erase command takes several seconds. You first need to wait for the ready bit, then proceed at your discretion. Writing a command always resets the ready bit. My code ;Address within the block being erased ;XK:IX Addres
ERASE: jsr CLRSTAT ldd #$20 ; CMD erase
std 0,X ; Bank address
ldd #$D0 ; CMD erase confirm
std 0,X jsr CHECK_READY ;return status rB .......check status
|
|