;++++++++++++++++++++++++++++++++++++
; AKI80 serbo control test
; Ver 0.01 2025/06/06 by skyriver
;++++++++++++++++++++++++++++++++++++
.LIST
0023 SETTIM EQU 00100011B ; CTC mode enable int,timer,pre:256
0080 INTBIT EQU 10000000B ; enabke interrupt
0004 TIMBIT EQU 00000100B ; set timer value next
0000' ASEG
ORG 0100H
0100 18 25 START: JR Init ; initialize CTC & PIO
0102 18 5D EXIT: JR StopInt ; stop interrupt
0104 80 00 Serbo0: DB 80H,00H ; PIOA0 serbo pulse width and adjust
0106 80 00 Serbo1: DB 80H,00H ; PIOB0
0108 80 00 Serbo2: DB 80H,00H ; PIOA1
010A 80 00 Serbo3: DB 80H,00H ; PIOB1
010C 80 00 Serbo4: DB 80H,00H ; PIOA2
010E 80 00 Serbo5: DB 80H,00H ; PIOB2
0110 80 00 Serbo6: DB 80H,00H ; PIOA3
0112 80 00 Serbo7: DB 80H,00H ; PIOB3
0114 80 00 Serbo8: DB 80H,00H ; PIOA4
0116 80 00 Serbo9: DB 80H,00H ; PIOB4
0118 80 00 SerboA: DB 80H,00H ; PIOA5
011A 80 00 SerboB: DB 80H,00H ; PIOB5
011C 80 00 SerboC: DB 80H,00H ; PIOA6
011E 80 00 SerboD: DB 80H,00H ; PIOB6
0120 80 00 SerboE: DB 80H,00H ; PIOA7
0122 80 00 SerboF: DB 80H,00H ; PIOB7
0124 0104 SerbPt: DW Serbo0
0126 01 PerBit: DB 1 ; period bit value
; initialize CTC, PIO and work area
0127 F3 Init: DI
0128 ED 5E IM 2
012A 3E 01 LD A,high IntVec
012C ED 47 LD I,A
012E CD 0141 CALL IniCtc
0131 CD 014E CALL IniPio
0134 21 0104 LD HL,Serbo0
0137 22 0124 LD (SerbPt),HL
013A 3E 01 LD A,1
013C 32 0126 LD (PerBit),A
013F FB EI
0140 C9 RET
; initialize CTC
0141 3E C8 IniCtc: LD A,low IntVec
0143 D3 10 OUT (CTCCH0),A ; set vector addr
0145 3E A7 LD A,SETTIM OR INTBIT OR TIMBIT
0147 D3 10 OUT (CTCCH0),A
0149 3E 78 LD A,120 ; 12.288*1000000/256/120=400[Hz] = 2.5ms
014B D3 10 OUT (CTCCH0),A
014D C9 RET
; initialize PIO
014E 21 015E IniPio: LD HL,PINIDAT
0151 E5 PUSH HL
0152 01 031D LD BC,PINILEN * 256 + PIOACMD
0155 ED B3 OTIR
0157 E1 POP HL
0158 01 031F LD BC,PINILEN * 256 + PIOBCMD
015B ED B3 OTIR
015D C9 RET
015E PINIDAT:
015E CF DB 11001111B ; mode3(bit mode)
015F 00 DB 00000000B ; all bits are output
0160 07 DB 00000111B ; no interrupt
0003 PINILEN EQU $ - PINIDAT
; stop CTC int
0161 StopInt:
0161 3E 03 LD A,00000011B ; reset channel
0163 D3 10 OUT (CTCCH0),A
0165 F3 DI
0166 C9 RET
; timer interrupt
; pulse width 1.5 +/ 0.8[ms]
; 2.5ms : 120 96 ; (255*(1/2-1/8)+24)/120*2.5 = 2.49[ms]
; 1.5ms : 72 48
; 0.5ms : 24 0
0018 LOWOFST EQU 24 ; lowest value offset
0167 IntCtc0:
0167 F5 PUSH AF
0168 C5 PUSH BC
0169 E5 PUSH HL
016A 3E A7 LD A,SETTIM OR INTBIT OR TIMBIT
016C D3 11 OUT (CTCCH1),A
016E D3 12 OUT (CTCCH2),A
0170 2A 0124 LD HL,(SerbPt)
0173 7E LD A,(HL)
0174 CB 3F SRL A
0176 47 LD B,A
0177 E6 FC AND 0FCH
0179 0F RRCA
017A 0F RRCA
017B 90 SUB B
017C ED 44 NEG
017E C6 18 ADD A,LOWOFST ; add serbo senter value
0180 23 INC HL
0181 86 ADD A,(HL) ; add adjust
0182 23 INC HL
0183 D3 11 OUT (CTCCH1),A
0185 7E LD A,(HL)
0186 CB 3F SRL A
0188 47 LD B,A
0189 E6 FC AND 0FCH
018B 0F RRCA
018C 0F RRCA
018D 90 SUB B
018E ED 44 NEG
0190 C6 18 ADD A,LOWOFST ; add serbo senter value
0192 23 INC HL
0193 86 ADD A,(HL) ; add adjust
0194 23 INC HL
0195 D3 12 OUT (CTCCH2),A
0197 3A 0126 LD A,(PerBit) ; get bit pattern
019A D3 1C OUT (PIOADAT),A
019C D3 1E OUT (PIOBDAT),A
019E 07 RLCA
019F 30 03 JR NC,IntC010
01A1 21 0104 LD HL,Serbo0
01A4 IntC010:
01A4 22 0124 LD (SerbPt),HL
01A7 32 0126 LD (PerBit),A
01AA E1 POP HL
01AB C1 POP BC
01AC F1 POP AF
01AD FB IntNul: EI
01AE ED 4D RETI
; CTC ch1 interrupt
; (serbo pulse off
01B0 IntCtc1:
01B0 F5 PUSH AF
01B1 3E 23 LD A,SETTIM ; disable int, not set timer value
01B3 D3 11 OUT (CTCCH1),A
01B5 AF XOR A
01B6 D3 1C OUT (PIOADAT),A ; set serbo pulse off
01B8 F1 POP AF
01B9 FB EI
01BA ED 4D RETI
01BC IntCtc2:
01BC F5 PUSH AF
01BD 3E 23 LD A,SETTIM ; disable int, not set timer value
01BF D3 12 OUT (CTCCH2),A
01C1 AF XOR A
01C2 D3 1E OUT (PIOBDAT),A ; set serbo pulse off
01C4 F1 POP AF
01C5 FB EI
01C6 ED 4D RETI
ORG ($+0007H) AND 0FFF8H
01C8 IntVec:
01C8 0167 DW IntCtc0
01CA 01B0 DW IntCtc1
01CC 01BC DW IntCtc2
01CE 01AD DW IntNul
END