Hello there!
I stumbled upon Programming:Unlocking ASIC. Neat stuff there in the optimized routines! ![]()
And here are my 2 bits on the matter.
As mentioned in the linked old-forum thread, it is the caller’s responsibility
to handle the interrupts, so all DI/EI be gone! -2 bytes
As a reminder, the complete RMR2 unlock sequence to be written to I/O port #BCxx is:
NZB, #00,#FF,#77...#8A, STATE (#CD), EOK
NZB: Any value but zero.
STATE: #CD will unlock (anything else will lock).
EOK: It must be sent to snap the ASIC out of it’s unlocking sequence and get the CRTC register selection I/O back. It can be any value.
The classic optimized routine does not leverage some properties of the unlock sequence. Such as:
- We put the sequence data right after the routine ends, with a
RET, i.e. a&C9opcode, not zero, hmm… smell like anNZBto me! : -1 byte - Why storing the
EOKvalue in the sequence data? We do not care what value it is, we will send whatever we find: -1 byte
This gives a slightly tighter version:
; Send a 17 bytes sequence to I/O port #BCxx to unlock RMR2
; register access. KISS approach using a table of raw values.
;
; Size: 28 bytes
; Time: 178 µs
;
; Output:
; BC=&BC00
; Trashes HL and Flags
rmr2_unlock:
ld bc,&BC00+17
ld hl,_rmr2_data_key
_rmr2_send_key inc b
outi
dec c
jr nz,_rmr2_send_key
_rmr2_data_key ret ; This opcode is also used as SYNC/NZB value (#C9)
db 0, &FF,&77,&B3,&51,&A8,&D4,&62,&39,&9C,&46,&2B,&15,&8A
_rmr2_data_lock db 205 ; 205 to Unlock, anything else to lock
; The routine will over-read one byte at this location
; to retrieve an EOK value, necessary for proper unlocking.
And now at 28 bytes long, this KISS-friendly routine makes the optimized ones look like… Oh well, that’s not important. (we still love you!)
But the LFSR re-implementation routine by @Urusergi caused my nose to tingle. There are soooo many ways and bit-trickeries to implement these tiny LFSR thing, there might be some shorter variations out there…
…a few days, cries and nose bleeds later: well, not that many it seems!
Only found one:
; Software re-implementation of the LFSR logic described in
; the Amstrad Patent (GB2243701A). It generates a 15 bytes
; sequence as verified by the ASIC to unlock RMR2 access.
;
; Designed by Urusergi
; Modified by Grim (shaving a single byte, pfew!)
;
; Size: 27 bytes
; Time: 389 µs
;
; Output:
; BC=&BCFF
; Trashes HL and AF
rmr2_unlock:
ld bc,&BCFF
out (c),c ; SYNC/NZB
out (c),0 ; SYNC/NUL
ld a,c
_rmr2_send_key
out (c),a
ld h,a
add hl,hl
rra
add hl,hl
ld l,a
xor h
and &F7
xor l
add a,h
and &88
xor l
cp c
jr nz,_rmr2_send_key
ret
I tried to ditch the (cute) cp c exit test and use some flag instead after the last xor l, but failed so far. The cp c lives on! ![]()