; Orange programmer module v2.5
; (c) 1999-2011 CnCLab
; CHIP=93CS56,128x16,93S66.HPL
; CHIP=93CS66,256x16,93S66.HPL

; TESTED on SGS ST93CS56, Microchip 93S56

; При чтении Protect регистра
; результат сдвигается (ProtectFlag)!
; ProtectFlag отображается инверсно (птичка - активен)
; Версия с автоматическим восстановлением Protect

SOCKET=2 ;"MW"

PINO=CLK,0
PINO=DI,1
PINO=CS,2
PINO=PE,3    ;6
PINO=PRE,4   ;7
PINI=DO,1

CDELAY=3 ; one set delay

R10=Protect,H
R11=ProtFlag,c1

[_SEND]
LOOP=(10,0){DI=R0[I],CLK=P}

[_WAITWR]
LOOP=(0,5000){
DO?1{BREAK}
P=10
}


[!#SETUP]
$WDELAY=20000

[INIT]
CS=0
PE=0	;write disable
PRE=0
CLK=0

[READ]
CS=0
CLK=0
CS=1
DI=1,CLK=P    ; start bit
DI=1,CLK=P    ; \ read instruction
DI=0,CLK=P    ; /
LOOP=(7,0){DI=ADR[I],CLK=P}    ; out adr
DI=1,P=1
DO?1{PRINT=A("Chip not respond at %04lX, continue?",ADR),RA?0{EXIT}}
LOOP=(15,0){CLK=P,DATA[I]=DO}  ; read data word
CS=0

[_RDPROT]
PE=0
PRE=1   ;!!!
CS=0,CLK=0,CS=1
DI=1,CLK=P    ; start bit
DI=1,CLK=P    ; \ PrRead instruction
DI=0,CLK=0,CLK=0    ; /
LOOP=(7,0) {DI=0,CLK=P}    ; don't care bits
DI=1
R10=0
LOOP=(8,0){CLK=P,R10[I]=DO}  ; read protect reg
R11=0
CLK=P,R11[0]=DO
R11=^1 ;invert flag
CS=0
PRE=0   ;!!!


[_WRPROT]
CS=0
CLK=0

PRE=0,PE=1
CS=1
R0=10011000000b                ; out EWEN
_SEND
CS=0

PRE=1,PE=1
CS=1
R0=10011000000b                ; out PREN
_SEND
CS=0

CS=1
DI=1,CLK=P    ; start bit
DI=0,CLK=P    ; \ write instruction
DI=1,CLK=P    ; /
LOOP=(7,0){DI=R10[I],CLK=P}    ; out reg data
CS=0,DI=1,CS=1      ; check status
P=40000
_WAITWR
CS=0
PRE=0

[_CLRPROT]
CS=0
CLK=0

PRE=0,PE=1

CS=1
R0=10011000000b                ; out EWEN
_SEND
CS=0

PRE=1,PE=1

CS=1
R0=10011000000b
_SEND    ; out PREN
CS=0

CS=1
R0=11111111111b
_SEND    ; out PRCLEAR
CS=0

CS=0,DI=1,CS=1      ; check status
P=40000
;DO?1
CS=0


[WRITEINIT]
_RDPROT
_CLRPROT
PE=1
PRE=0
CS=0
CLK=0
CS=1
R0=10011000000b
_SEND    ; out EWEN
CS=0
P=30000

[WRITE]
CS=1
R0=10011000000b
_SEND    ; out EWEN
CS=0
P=10

CS=1
DI=1,CLK=P    ; start bit
DI=0,CLK=P    ; \ write instruction
DI=1,CLK=P    ; /
LOOP=(7,0){DI=ADR[I],CLK=P}    ; out adr
LOOP=(15,0){DI=DATA[I],CLK=P}  ; write data word
CS=0,DI=1,CS=1      ; check status
P=$WDELAY
_WAITWR
CS=0
P=10


[WRITEEND]
R8=R10
_RDPROT
R8?R10{RETURN}
R10=R8
PRINT=S("Restore protect...")
_WRPROT
PE=0


[ReadProtect]
_RDPROT
P=10000
GET=("Protect",R10,R11)


[WriteProtect]
GET=("Write Protect",R10)
RA?0{EXIT}
_WRPROT


[ClearProtect]
CS=0
CLK=0

PRE=0,PE=1

CS=1
R0=10011000000b
_SEND    ; out EWEN
CS=0

PRE=1,PE=1

CS=1
R0=10011000000b
_SEND    ; out PREN
CS=0

CS=1
R0=11111111111b
_SEND    ; out PRCLEAR
CS=0

CS=0,DI=1,CS=1      ; check status
P=40000
;DO?1
CS=0