R.O.B. Firmware
;R.O.B. firmware disassembly, nocash 2019
;——————
;dumping info:
;http://www.seanriddle.com/sm590/
;http://www.seanriddle.com/sm590/sm590dump.txt
;——————
;Component list
;base, with mainboard “(C)1985 Nintendo, RFC-03-CPU”
; IC1 16pin “RFC-CPU10, Nintendo JAPAN, 8644 A” (CPU SM590)
; IC2 8pin “IR2C25, SHARP 8638 A” motor driver
; IC3 8pin “IR2C25, SHARP 8638 A” motor driver
; IC4 8pin “IR2C25, SHARP 8638 A” motor driver
; x 2pin “CSB455” 455kHz resonator
; SW 5pin Power switch (on/off)
; Batteries 4x AA
;head, with daughterboard “RFC-03-AMxxx?”
; IC? 9pin “IR3T07 JAPAN, SHARP 8637 B”
; x xpin “43PI” light sensor ;unknown if there is lens, too?
; x 2pin LED (on separate tiny PCB)
;motors
; There are three motors, each can run forward/back or stop,
; each motor has a gear with a series of 5 big/small wheels
; (to reduce the fast spinning motors to slower rotations).
; The left/right motor is in the base, the up/down and
; open/close motors are in the shoulders.
; The up/down and left/right motors are bundled with switches
; (for sensing the six up/down and five left/right notches).
; The open/close motor has no such feedback mechanism.
;——————
;PORT usage
;—
PORT[0].0 in light_sensor
PORT[0].1 in notch switch (for sensing five left/right step positions)
PORT[0].2 in notch switch (for sensing six up/down step positions)
PORT[0].3 out LED
PORT[1].0 out move down
PORT[1].1 out move up
PORT[1].2 out arm close
PORT[1].3 out arm open
PORT[2].0 out rotate right
PORT[2].1 out rotate left
PORT[2].2 - -
PORT[2].3 - - ;(no external pin; 18pin/20pin package only)
PORT[3].0 out debug ;(no external pin; 18pin/20pin package only)
PORT[3].1 out debug ;(no external pin; 20pin package only)
PORT[3].2 - - ;(no external pin; 20pin package only)
PORT[3].3 clock? -
;——————
;RAM usage
;—
[00h] command_buffer_msb (first 4bit)
[01h] command_buffer_mid (middle 4bit)
[02h] command_buffer_lsb (last 4bit)
[03h] ;\delay count’s
[04h] ;/
[05h] - ;unused
[06h] - ;unused
[07h] - ;unused
[08h] - ;unused
[09h] - ;unused
[0Ah] another_step (0=no, 1=down, 2=up)
[0Bh] some offhold … for LED
[0Ch] - ;unused
[0Dh] led_flag (bit0) ;and another somewhat unused flag in bit1
[0Eh] ;\offhold for led-blink test command
[0Fh] ;/
[10h] - ;unused
[11h] - ;unused
[12h] - ;unused
[13h] - ;unused
[14h] - ;unused
[15h] - ;unused
[16h] - ;unused
[17h] - ;unused
[18h] - ;unused
[19h] - ;unused
[1Ah] - ;unused
[1Bh] - ;unused
[1Ch] lopcount_for_calibration_steps
[1Dh] lopcount for move/grab
[1Eh] ;\lopcount
[1Fh] ;/
;——————
reset_entrypoint:
0000 (000) 48 clr c ;uh, what for?
;- - - - - ——–
standy_entrypoint:
0001 (040) 74 mov h,00 ;
0002 (060) 20 mov l,00 ;
0003 (070) 7D 00 call 0100 ;zerofill_up_to_16_nibbles; clear 32 ram nibbles
0005 (07C) 75 mov h,01 ;
0006 (07E) 7D 00 call 0100 ;zerofill_up_to_16_nibbles;/
;- - - - - ——–
softreset_entrypoint:
0008 (05F) 22 mov l,02 ;
0009 (06F) 30 mov a,00 ;
@@clear_port_lop: ; clear port 2,1,0
000A (077) 46 out [l],a ;PORT[2,1,0]=0 ;
000B (07B) 53 decsk l ;
000C (07D) F7 jmp 000A ;@@clear_port_lop ;/
;- - -
000D (03E) 75 mov h,01 ;
000E (01F) 2C mov l,0C ;
000F (04F) 3C mov a,0C ;aka -4 (num steps) ;
@@rightmost_lop: ; rotate 4x to rightmost
0010 (067) 4A mov [hl],a ;[1Ch] ; (and up/open)
0011 (073) 3A mov a,0A ;\up ; (until hitting four
0012 (079) 21 mov l,01 ; open ; horizontal notches)
0013 (03C) 46 out [l],a ;PORT[1]=2+8 ;/ ;
0014 (05E) 7D 51 call 012E ;move_right ; this is doing 4 steps
0016 (057) F5 jmp 0018 ;@@notyet_rightmost ; (albeit tiny steps if
0017 (06B) C3 jmp 001D ;@@rightmost_timeout ; it was already at
;— ; rightmost position)
@@notyet_rightmost: ;
0018 (075) 75 mov h,01 ;
0019 (03A) 2C mov l,0C ;
001A (01D) 40 mov a,[hl] ;[1Ch] ;
001B (00E) 01 addsk a,01 ;
001C (007) E7 jmp 0010 ;@@rightmost_lop ;
@@rightmost_timeout: ;/
;- - -
001D (043) 75 mov h,01 ;
001E (061) 2C mov l,0C ;
001F (030) 3E mov a,0E ;aka -2 (num steps) ;
@@center_lop: ; rotate 2x to center
0020 (058) 4A mov [hl],a ;[1Ch] ; (and up/open)
0021 (06C) 3A mov a,0A ;\up ; (until hitting two
0022 (076) 21 mov l,01 ; open ; horizontal notches)
0023 (03B) 46 out [l],a ;PORT[1]=2+8 ;/ ;
0024 (05D) 7D 28 call 012F ;move_left ; uhm, this is doing
0026 (017) E5 jmp 0028 ;@@notstill_rightmost ; only 2 steps (enough
0027 (04B) A3 jmp 002D ;@@center_timeout ; to rotate to center)
;— ; (but probably not
@@notstill_rightmost: ; enough to reach top;
0028 (065) 75 mov h,01 ; unless up/down was
0029 (032) 2C mov l,0C ; already near top)
002A (019) 40 mov a,[hl] ;[1Ch] ;
002B (00C) 01 addsk a,01 ;
002C (046) D8 jmp 0020 ;@@center_lop ;
@@center_timeout: ;/
;- - -
002D (023) 20 mov l,00 ;
002E (051) 55 in a,[l] ;PORT[0] ;
002F (028) 66 testsk a.2 ;bit2:PORT[0] ;
0030 (054) 8D jmp 0034 ;@@notyet_topmost ; up 1x more
0031 (06A) 7D 1C call 015F ;initial_move_up ;
0033 (01A) 00 nop ;
@@notyet_topmost: ;/
0034 (00D) 74 mov h,00 ;
0035 (006) 2D mov l,0D ;
0036 (003) 60 testsk [hl].0 ;[0Dh] ;LED.flag ; LED
0037 (041) E8 jmp 003A ;@@do_not_enable_led ;
0038 (020) 7D 2D call 0166 ;set_port_0_to_8 ;
@@do_not_enable_led: ;/
;- - - - - - ——
want_fresh_command: ;MAINLOOP for NEW command
003A (068) 74 mov h,00 ;
003B (074) 22 mov l,02 ; clear command buffer
@@clear_cmdbuf_lop: ; [02h,01h,00h]=F:F:F
003C (07A) 3F mov a,0F ;
003D (03D) 43 xchgsk a,[hl-] ;[02h,01h,00h]=Fh ;
003E (01E) FA jmp 003C ;@@clear_cmdbuf_lop ;/
;- - - - - - ——
want_next_cmd_bit: ;MAINLOOP for NEXT command BIT
003F (00F) 24 mov l,04
0040 (047) 30 mov a,00 ;inner.lopcount
0041 (063) 43 xchgsk a,[hl-] ;[04h], L=3, and do NOT skip
0042 (071) 33 mov a,03 ;outer.lopcount
@@scan_light_outer_lop: ;
@@scan_light_inner_lop: ;
0043 (038) 4A mov [hl],a ;[03h] or [04h] ;
0044 (05C) 23 mov l,03 ;\DEBUG info ;
0045 (06E) 32 mov a,02 ; 20pin chip ;
0046 (037) 46 out [l],a ;PORT[3]=2 ;/only ;
0047 (05B) 7D EC call 01A1 ;skip_if_dark ; –> and TEST LIGHT
0049 (036) A5 jmp 0054 ;@@got_light ;
004A (01B) 24 mov l,04 ;
004B (04D) 40 mov a,[hl] ;[04h] ;inner.lopcount ;
004C (026) 0F addsk a,0F ;
004D (013) A4 jmp 004F ;@@scan_light_inner_done ;
004E (049) B8 jmp 0043 ;@@scan_light_inner_lop ;
;— ;
@@scan_light_inner_done: ;
004F (024) 43 xchgsk a,[hl-] ;[04h], L=3 ;
0050 (052) 40 mov a,[hl] ;[03h] ;outer.lopcount ;
0051 (029) 0F addsk a,0F ;
0052 (014) A2 jmp 006A ;@@got_no_light ;
0053 (04A) B8 jmp 0043 ;@@scan_light_outer_lop ;
;— ;
@@got_light: ;/
@@wait_till_end_of_light: ;
0054 (025) 7D EC call 01A1 ;skip_if_dark ; wait until dark again
0056 (009) A5 jmp 0054 ;@@wait_till_end_of_light ;/
0057 (004) 24 mov l,04 ;
0058 (042) 3B mov a,0B ;
0059 (021) 43 xchgsk a,[hl-] ;[04h], L=3 ;
005A (010) 33 mov a,03 ; post-light delay
@@afterlight_outer_delay: ;
@@afterlight_inner_delay: ;
005B (048) 4A mov [hl],a ;[03h] or [04h] ;
005C (064) 7D EC call 01A1 ;skip_if_dark ;\delay ;
005E (039) 00 nop ;/dummy ;
005F (01C) 24 mov l,04 ;
0060 (04E) 40 mov a,[hl] ;[04h] ;
0061 (027) 0F addsk a,0F ;
0062 (053) B4 jmp 0064 ;@@afterlight_inner_done ;
0063 (069) C8 jmp 005B ;@@afterlight_inner_delay ;
;— ;
@@afterlight_inner_done: ;
0064 (034) 23 mov l,03 ;
0065 (05A) 40 mov a,[hl] ;[03h] ;
0066 (02D) 0F addsk a,0F ;
0067 (016) C5 jmp 0069 ;@@afterlight_outer_done ;
0068 (00B) C8 jmp 005B ;@@afterlight_outer_delay ;
;— ;
@@afterlight_outer_done: ;/
0069 (045) 49 set c ;<– set LIGHT flag
@@got_no_light: ;in: cy=light
006A (022) 74 mov h,00
006B (011) 23 mov l,03 ;
006C (008) 54 testsk c ; output DEBUG info
006D (044) 30 mov a,00 ; (18pin/20pin chip only)
006E (062) 31 mov a,01 ; (none such in 16pin retail)
006F (031) 46 out [l],a ;PORT[3]=0/1 ;/
0070 (018) 22 mov l,02
@@shift_cmdbuf_lop: ;
0071 (04C) 40 mov a,[hl] ;[02h,01h,00h] ; left-shift RAM[02h,01h,00h]
0072 (066) 72 adc a,[hl] ;[02h,01h,00h] ; with carry-in = LIGHT
0073 (033) 43 xchgsk a,[hl-] ;[02h,01h,00h] ;
0074 (059) CC jmp 0071 ;@@shift_cmdbuf_lop ;/
0075 (02C) 79 A7 jmp 01E1 ;process_cmd_if_any ;——>
;——————
0077 (02B) 00 nop ;
0078 (055) 00 nop ;
0079 (02A) 00 nop ;
007A (015) 00 nop ; unused (8 bytes)
007B (00A) 00 nop ;
007C (005) 00 nop ;
007D (002) 00 nop ;
007E (001) 00 nop ;/
;——————
007F (07F) 80 jmp 0000
;——————
;unused, unless this is wakeup vector for standby?
0080 (080) 78 40 jmp 0001 ;standy_entrypoint
;——————
;unused, unless this is another exception vector?
0082 (0E0) 78 5F jmp 0008 ;softreset_entrypoint
;——————
not_0010_1011_1110_cont: ;in: HL=01h
0084 (0F8) 3F mov a,0F ;0010_1111_1110 ;
0085 (0FC) 45 cmpsk a,[hl] ;[01h] ;
0086 (0FE) 87 jmp 009C ;@@not_0010_1111_1110 ;/
0087 (0BF) DA jmp 00E5 ;@@to_want_next_cmd_bit ;–> CMD_0010_1111_1110 –> N/A
;——————
not_0010_xxxx_1110_cont: ;in: HL=02h
0088 (0DF) 3A mov a,0A ;0010_xxxx_1010
0089 (0EF) 45 cmpsk a,[hl] ;[02h]
008A (0F7) A2 jmp 00EA ;@@not_0010_xxxx_1010
008B (0FB) 21 mov l,01
;mov a,0A ;0010_1010_1010
008C (0FD) 45 cmpsk a,[hl] ;[01h]
008D (0BE) CF jmp 008F ;@@not_0010_1010_1010
008E (09F) DA jmp 00E5 ;@@to_want_next_cmd_bit ;–> CMD_0010_1010_1010 –> N/A
@@not_0010_1010_1010:
008F (0CF) 3E mov a,0E ;0010_1110_1010 ;
0090 (0E7) 45 cmpsk a,[hl] ;[01h] ; check
0091 (0F3) 3B mov a,0B ;0010_1011_1010 ; if 0Eh
0092 (0F9) 45 cmpsk a,[hl] ;[01h] ; or 0Bh
0093 (0BC) 8E jmp 009B ;@@not_0010_1110_1010_nor_0010_1011_1010 ;/
0094 (0DE) 1E cmpsk a,0E ;this is either 0Eh or 0Bh ;
0095 (0AF) 32 mov a,02 ;CMD_0010_1011_1010 –> turn left ; move
0096 (0D7) 31 mov a,01 ;CMD_0010_1110_1010 –> turn right ; left
0097 (0EB) 7D 54 call 0130 ;move_left_or_right ; right
0099 (0BA) 00 nop ;/
009A (09D) D1 jmp 00AE ;set_led_and_want_fresh_command
;—
@@not_0010_1110_1010_nor_0010_1011_1010:
009B (08E) 3F mov a,0F ;0010_1111_1010
@@not_0010_1111_1110:
009C (087) 3A mov a,0A ;0010_1010_1110
009D (0C3) 45 cmpsk a,[hl] ;[01h]
009E (0E1) 83 jmp 00B6 ;@@not_0010_1111_1010_nor_0010_1010_1110
;- -
;CMD_0010_1111_1010 –> up small step
;CMD_0010_1010_1110 –> down small step
009F (0B0) 1F cmpsk a,0F ;\direction
;- - - - - - - —- ;
move_down: ; ;
@@move_down_lop: ; ;
00A0 (0D8) 31 mov a,01 ; ;
move_up: ; ;
@@move_up_lop: ; ;
00A1 (0EC) 32 mov a,02 ;/ ;
00A2 (0F6) 7D 27 call 0161 ;move_up_or_down ;
00A4 (0DD) 00 nop ;
00A5 (0AE) 74 mov h,00 ;
00A6 (097) 2A mov l,0A ;
00A7 (0CB) 30 mov a,00 ;
00A8 (0E5) 41 xchg a,[hl] ;[0Ah] ; <– test if another_step
00A9 (0B2) 0F addsk a,0F ;
00AA (099) D1 jmp 00AE ;set_led_and_want_fresh_command ;–> no, done
00AB (08C) 0F addsk a,0F ; <– direction of another_step
00AC (0C6) D8 jmp 00A0 ;@@move_down_lop ;
00AD (0A3) EC jmp 00A1 ;@@move_up_lop ;/
;—
set_led_and_want_fresh_command:
00AE (0D1) 74 mov h,00
00AF (0A8) 2D mov l,0D
00B0 (0D4) 6C set [hl].0 ;[0Dh] ;LED.flag
00B1 (0EA) 6D set [hl].1 ;[0Dh]
;- - -
set_led_temporarily_and_want_fresh_command:
00B2 (0B5) 7D 2D call 0166 ;set_port_0_to_8
00B4 (08D) 78 68 jmp 003A ;want_fresh_command
;—
@@not_0010_1111_1010_nor_0010_1010_1110:
00B6 (083) 2D mov l,0D
00B7 (0C1) 6D set [hl].1 ;[0Dh] ??????????
00B8 (0A0) DA jmp 00E5 ;@@to_want_next_cmd_bit
;—
not_0_0010_xxxx_xxxx_cont:
00B9 (0D0) 20 mov l,00
00BA (0E8) 35 mov a,05 ;0101_xxxx_xxxx
00BB (0F4) 45 cmpsk a,[hl] ;[00h]
00BC (0FA) 3A mov a,0A ;1010_xxxx_xxxx
00BD (0BD) 45 cmpsk a,[hl] ;[00h]
00BE (09E) C2 jmp 00D8 ;@@not_0101_xxxx_xxxx_nor_1010_xxxx_xxxx
00BF (08F) 52 incsk l ;L=1 (and no skip)
00C0 (0C7) 45 cmpsk a,[hl] ;[01h] ;1010_1010_xxxx or 0101_0101_xxxx
00C1 (0E3) C2 jmp 00D8 ;@@not_0101_0101_xxxx_nor_1010_1010_xxxx
00C2 (0F1) 52 incsk l ;L=2 (and no skip)
00C3 (0B8) 45 cmpsk a,[hl] ;[02h] ;1010_1010_1010 or 0101_0101_0101
00C4 (0DC) C2 jmp 00D8 ;@@not_0101_0101_0101_nor_1010_1010_1010
;- - -
;CMD_0101_0101_0101 ;\aka bits toggle on/off repeatedly
;CMD_1010_1010_1010 ;/
00C5 (0EE) 2E mov l,0E ;
00C6 (0B7) 48 clr c ;
00C7 (0DB) 3F mov a,0F ;
00C8 (0ED) 72 adc a,[hl] ;[0Eh] ;
00C9 (0B6) 42 xchgsk a,[hl+] ;[0Eh], L=0Fh, and do not skip… ;
00CA (09B) 31 mov a,01 ;uhm, why this? that will ADC 1+cy ? ;
00CB (0CD) 72 adc a,[hl] ;[0Fh] ;
00CC (0A6) 4A mov [hl],a ;[0Fh] ;
00CD (093) 54 testsk c ;
00CE (0C9) DA jmp 00E5 ;@@to_want_next_cmd_bit ;/
00CF (0A4) 7D 11 call 016B ;set_0Bh_to_zero ;[0Bh]=0
00D1 (0A9) 2D mov l,0D
00D2 (094) 68 clr [hl].0 ;[0Dh] ;LED.flag
00D3 (0CA) 20 mov l,00
00D4 (0A5) 55 in a,[l] ;PORT[0]
00D5 (092) 08 addsk a,08 ;bit3 to cy (LED)
00D6 (089) B5 jmp 00B2 ;set_led_temporarily_and_want_fresh_command
00D7 (084) D3 jmp 00E2 ;@@clr_led_temporarily_and_want_next_cmd_bit
;—
@@not_0101_0101_0101_nor_1010_1010_1010:
00D8 (0C2) 2B mov l,0B
00D9 (0A1) 40 mov a,[hl] ;[0Bh] ;offhold ?
00DA (090) 01 addsk a,01
00DB (0C8) B4 jmp 00E4 ;@@apply_increased_led_offhold_and_want_next_cmd_bit ;in: L=0Bh, and A=[0Bh]+1
00DC (0E4) 4A mov [hl],a ;[0Bh]
00DD (0F2) 2D mov l,0D
00DE (0B9) 6D set [hl].1 ;[0Dh]
00DF (09C) 60 testsk [hl].0 ;[0Dh] ;LED.flag
00E0 (0CE) D3 jmp 00E2 ;@@clr_led_temporarily_and_want_next_cmd_bit
00E1 (0A7) 96 jmp 00E7 ;@@set_led_temporarily_and_want_next_cmd_bit
;—
@@clr_led_temporarily_and_want_next_cmd_bit:
00E2 (0D3) 7D 16 call 0167 ;set_port_0_to_0 ;out: L=0, A=0
;- - -
@@apply_increased_led_offhold_and_want_next_cmd_bit:
00E4 (0B4) 4A mov [hl],a ;[00h]=0 … OR … [0Bh]=increased ;uhm?
@@to_want_next_cmd_bit:
00E5 (0DA) 78 0F jmp 003F ;want_next_cmd_bit
;—
@@set_led_temporarily_and_want_next_cmd_bit:
00E7 (096) 7D 2D call 0166 ;set_port_0_to_8
00E9 (0C5) DA jmp 00E5 ;@@to_want_next_cmd_bit
;—
@@not_0010_xxxx_1010:
00EA (0A2) 3B mov a,0B ;0010_xxxx_1011
00EB (091) 45 cmpsk a,[hl] ;[02h]
00EC (088) DA jmp 00E5 ;@@to_want_next_cmd_bit ;@@not_0010_xxxx_1011
00ED (0C4) 21 mov l,01
00EE (0E2) 63 testsk [hl].3 ;[01h] ;0010_1xxx_1011 ;
00EF (0B1) DA jmp 00E5 ;@@to_want_next_cmd_bit ;@@not_0010_1xxx_1011 ; verify fixed bits
00F0 (098) 61 testsk [hl].1 ;[01h] ;0010_1x1x_1011 ;
00F1 (0CC) DA jmp 00E5 ;@@to_want_next_cmd_bit ;@@not_0010_1x1x_1011 ;/
00F2 (0E6) 79 B6 jmp 01C9 ;is_0010_1x1x_1011 ;–>
;——————
00F4 (0D9) 00 nop ;
00F5 (0AC) 00 nop ;
00F6 (0D6) 00 nop ;
00F7 (0AB) 00 nop ;
00F8 (0D5) 00 nop ; unused (11 bytes)
00F9 (0AA) 00 nop ;
00FA (095) 00 nop ;
00FB (08A) 00 nop ;
00FC (085) 00 nop ;
00FD (082) 00 nop ;
00FE (081) 00 nop ;/
;——————
00FF (0FF) 80 jmp 0080
;——————
zerofill_up_to_16_nibbles: ;in: HL=dest, out: L=0
@@lop: ;fill [xxh..0Fh] or [xxh..1Fh]
0100 (100) 30 mov a,00
0101 (140) 42 xchgsk a,[hl+] ;[xxh]
0102 (160) 80 jmp 0100 ;@@lop
0103 (170) 4C ret
;——————
cmd_open_arms:
0104 (178) 38 mov a,08 ;open
;- - - - - ——–
cmd_close_arms:
0105 (17C) 34 mov a,04 ;close
0106 (17E) 21 mov l,01 ;\apply motor direction
0107 (13F) 46 out [l],a ;PORT[1]=4/8 ;/
0108 (15F) 75 mov h,01 ;
0109 (16F) 2D mov l,0D ;
010A (177) 3D mov a,0D ;
@@arm_delay_lop: ;
010B (17B) 4A mov [hl],a ;[1Dh] ; delay
010C (17D) 7D 3A call 0119 ;do_long_delay ;
010E (11F) 75 mov h,01 ;
010F (14F) 2D mov l,0D ;
0110 (167) 40 mov a,[hl] ;[1Dh] ;
0111 (173) 01 addsk a,01 ;
0112 (179) FB jmp 010B ;@@arm_delay_lop ;/
;- - - - - ——–
stop_all_motors:
0113 (13C) 30 mov a,00 ;
0114 (15E) 21 mov l,01 ;
0115 (12F) 46 out [l],a ;PORT[1]=0 ; stop ALL motors
0116 (157) 22 mov l,02 ;
0117 (16B) 46 out [l],a ;PORT[2]=0 ;/
0118 (175) 4C ret
;——————
do_long_delay:
0119 (13A) 7D 16 call 0167 ;set_port_0_to_0 ;-
011B (10E) 75 mov h,01 ;\init ONE nibble of TWO-nibble-delay count
011C (107) 2F mov l,0F ;[1Fh] ; uhm, but don’t init [1Eh] here?
011D (143) 7D 00 call 0100 ;zerofill_up_to_16_nibbles;/
@@lop1: ;100h cycles ;
011F (130) 24 mov l,04 ;0Ch cycles ;\ ;
@@lop2: ; ;
0120 (158) 30 mov a,00 ;\ ; ;
@@lop3: ;10h cycles ; ; ;
0121 (16C) 01 addsk a,01 ; ; ;
0122 (176) EC jmp 0121 ;@@lop3 ;/ ; ; long delay
0123 (13B) 52 incsk l ; ; (loop 100h0Ch10h)
0124 (15D) D8 jmp 0120 ;@@lop2 ;/ ;
0125 (12E) 2E mov l,0E ;\ ;
@@carry_to_msb_lop: ; ;
0126 (117) 40 mov a,[hl] ;[1Eh,1Fh] ; ;
0127 (14B) 01 addsk a,01 ; ;
0128 (165) C6 jmp 012C ;@@no_carry ; ;
0129 (132) 42 xchgsk a,[hl+] ;[1Eh,1Fh] ; ;
012A (119) 97 jmp 0126 ;@@carry_to_msb_lop ;/ ;
012B (10C) 4C ret ;–> done ;
;— ;
@@no_carry: ;
012C (146) 4A mov [hl],a ;[1Eh,1Fh] ;
012D (123) B0 jmp 011F ;@@lop1 ;/
;——————
move_right:
012E (151) 31 mov a,01 ;direction (right)
;- - - - - - ——
move_left:
012F (128) 32 mov a,02 ;direction (left)
;- - - - - - ——
move_left_or_right:
0130 (154) 49 set c ;input bit (for left/right)
0131 (16A) 22 mov l,02 ;output port (for left/right)
;- - - - - - ——
move_up_or_down_or_left_or_right: ;in: A,L,Cy
0132 (135) 46 out [l],a ;PORT[1/2]=1/2 ;-run in desired direction
0133 (11A) 7D 3A call 0119 ;do_long_delay ;-delay <—- this helps to
0135 (106) 75 mov h,01 ;\ get AWAY from
0136 (103) 2D mov l,0D ; the CURRENT notch
0137 (141) 34 mov a,04 ;lopcount;
@@test_notch_lop: ; now run until NEXT notch…
0138 (120) 4A mov [hl],a ;[1Dh] ;lopcount;
0139 (150) 7D 80 call 0180 ;test_notch_switch; –> test notch switch
013B (174) CD jmp 014B ;@@reached_notch ;
013C (17A) 75 mov h,01 ;
013D (13D) 2D mov l,0D ;
013E (11E) 40 mov a,[hl] ;[1Dh] ;lopcount;
013F (10F) 01 addsk a,01 ;
0140 (147) A0 jmp 0138 ;@@test_notch_lop ;/
;- - -
;oops, timeout (this may happen if the mechanics are blocked,
;or perhaps if batteries are too low to move the motor)…
0141 (163) 30 mov a,00 ;
0142 (171) 21 mov l,01 ;
0143 (138) 46 out [l],a ;PORT[1]=0 ; stop (timeout)
0144 (15C) 22 mov l,02 ;
0145 (16E) 46 out [l],a ;PORT[2]=0 ;/
0146 (137) 74 mov h,00 ;
0147 (15B) 2A mov l,0A ; prevent another_step
0148 (16D) 68 clr [hl].0 ;[0Ah] ; upon timeout
0149 (136) 69 clr [hl].1 ;[0Ah] ;/
014A (11B) 4D retsk ;-return and skip upon timeout
;—
@@reached_notch:
014B (14D) 54 testsk c ;
014C (126) B4 jmp 0164 ;@@motor_port_1 ; set L=1/2
014D (113) 22 mov l,02 ;port_2 ;
@@this_motor_port: ;/
014E (149) 55 in a,[l] ;PORT[1/2] ;
014F (124) 64 testsk a.0 ; output REVERSE (to move back
0150 (152) 31 mov a,01 ; to center of notch?)
0151 (129) 32 mov a,02 ;
0152 (114) 46 out [l],a ;PORT[1/2]=1/2 ;/
0153 (14A) 20 mov l,00 ;outer lopcount ;
0154 (125) 30 mov a,00 ;inner lopcount ;
@@reverse_delay1: ;10h times ;
@@reverse_delay2: ;10h times ;
0155 (112) 00 nop ; delay (10h*10h)
0156 (109) 00 nop ;
0157 (104) 00 nop ;
0158 (142) 00 nop ;
0159 (121) 00 nop ;
015A (110) 01 addsk a,01 ;
015B (148) 92 jmp 0155 ;@@reverse_delay2 ;
015C (164) 52 incsk l ;
015D (172) 92 jmp 0155 ;@@reverse_delay1 ;/
015E (139) BC jmp 0113 ;stop_all_motors ;-clear PORT 1/2 and RET
;——————
initial_move_up:
015F (11C) 32 mov a,02 ;up
0160 (14E) 31 mov a,01 ;down <– blah/unused
;- - - - - ——–
move_up_or_down: ;in; A=1/2
0161 (127) 48 clr c ;input bit (for up/down)
0162 (153) 21 mov l,01 ;output port (for up/down)
0163 (169) B5 jmp 0132 ;move_up_or_down_or_left_or_right
;——————
@@motor_port_1:
;(weirdly, this two opcodes are part of the function at 0132)
0164 (134) 21 mov l,01
0165 (15A) C9 jmp 014E ;@@this_motor_port
;——————
set_port_0_to_8:
0166 (12D) 38 mov a,08
;- - - - - ——–
set_port_0_to_0:
0167 (116) 30 mov a,00
0168 (10B) 20 mov l,00
0169 (145) 46 out [l],a ;PORT[0]=0/8 ;LED
016A (122) 4C ret
;——————
set_0Bh_to_zero: ;[0Bh]=0 ;in: H=0
016B (111) 2B mov l,0B
016C (108) 30 mov a,00
016D (144) 4A mov [hl],a ;[0Bh]=0
016E (162) 4C ret
;——————
016F (131) 00 nop ;
0170 (118) 00 nop ;
0171 (14C) 00 nop ;
0172 (166) 00 nop ;
0173 (133) 00 nop ;
0174 (159) 00 nop ;
0175 (12C) 00 nop ; unused (16 bytes)
0176 (156) 00 nop ;
0177 (12B) 00 nop ;
0178 (155) 00 nop ;
0179 (12A) 00 nop ;
017A (115) 00 nop ;
017B (10A) 00 nop ;
017C (105) 00 nop ;
017D (102) 00 nop ;
017E (101) 00 nop ;/
;——————
;hmmm, why is this different as than at 007F/00FF/01FF, and,
;does the rom-dump-self-test even allow to read xx7F/xxFF ?
017F (17F) FF jmp 017F
;——————
test_notch_switch: ;in: Cy=motor (0=up/down, 1=left/right)
0180 (180) 75 mov h,01
0181 (1C0) 2E mov l,0E
0182 (1E0) 30 mov a,00
0183 (1F0) 42 xchgsk a,[hl+] ;[1Eh]=0, L=Fh, which will not skip…
0184 (1F8) 30 mov a,00
@@outmost_test_lop:
0185 (1FC) 4A mov [hl],a ;[1Fh,1Eh]
0186 (1FE) 30 mov a,00 ;number of switch-hits
@@test_retry_again:
0187 (1BF) 5C mov x,a ;number of switch-hits
0188 (1DF) 20 mov l,00 ;
0189 (1EF) 55 in a,[l] ;PORT[0] ;
018A (1F7) 54 testsk c ; test port, bit1/bit2
018B (1FB) E1 jmp 019E ;@@test_bit2 ;cy=0 –> ; –> test bit2 (up/dn)
018C (1FD) 65 testsk a.1 ;bit1:PORT[0] ;cy=1 –> ; –> test bit1 (lt/rt)
018D (1BE) 9D jmp 019A ;@@test_hit ;
@@cont_next: ;/
;- - - - -
@@outer_delay: ;
018E (19F) 3D mov a,0D ;\3x ; 16x
@@inner_delay: ; inner ; outer
018F (1CF) 01 addsk a,01 ; delay ; delay
0190 (1E7) CF jmp 018F ;@@inner_delay ;/ ;
0191 (1F3) 52 incsk l ;
0192 (1F9) 9F jmp 018E ;@@outer_delay ;/
0193 (1BC) 2E mov l,0E ;
@@carry_to_msb_lop: ;
0194 (1DE) 40 mov a,[hl] ;[1Fh,1Eh] ; raise 2x4bit
0195 (1AF) 01 addsk a,01 ; lopcount
0196 (1D7) FC jmp 0185 ;@@outmost_test_lop ;
0197 (1EB) 42 xchgsk a,[hl+] ;[1Fh,1Eh] ;
0198 (1F5) DE jmp 0194 ;@@carry_to_msb_lop ;/
0199 (1BA) 4D retsk ;RET with SKIP
;—
@@test_hit:
019A (19D) 5D xchg x,a ;number of switch-hits
019B (18E) 01 addsk a,01 ;increase
019C (187) BF jmp 0187 ;@@test_retry_again ;not yet 16 switch-hits
019D (1C3) 4C ret ;RET without SKIP ;okay got 16 switch-hits
;—
@@test_bit2:
019E (1E1) 66 testsk a.2 ;bit2:PORT[0]
019F (1B0) 9D jmp 019A ;@@test_hit
01A0 (1D8) 9F jmp 018E ;@@cont_next
;——————
skip_if_dark: ;out: Cy,Skip,FixedExecutionTiming
01A1 (1EC) 20 mov l,00
01A2 (1F6) 55 in a,[l] ;PORT[0] ;
01A3 (1BB) 64 testsk a.0 ;
01A4 (1DD) 97 jmp 01A6 ;@@has_light_1 ;
01A5 (1AE) BD jmp 01BD ;@@got_dark_1 ;
;— ;
@@has_light_1: ;/
01A6 (197) 55 in a,[l] ;PORT[0] ;
01A7 (1CB) 64 testsk a.0 ;
01A8 (1E5) 99 jmp 01AA ;@@has_light_2 ;
01A9 (1B2) 9E jmp 01BE ;@@got_dark_2 ;
;— ;
@@has_light_2: ;/
01AA (199) 55 in a,[l] ;PORT[0] ;
01AB (18C) 64 testsk a.0 ;
01AC (1C6) D1 jmp 01AE ;@@has_light_3 ;
01AD (1A3) 8F jmp 01BF ;@@got_dark_3 ;
;— ;
@@has_light_3: ;/
01AE (1D1) 55 in a,[l] ;PORT[0] ;
01AF (1A8) 64 testsk a.0 ;
01B0 (1D4) B5 jmp 01B2 ;@@has_light_4 ;
01B1 (1EA) C7 jmp 01C0 ;@@got_dark_4 ;
;— ;
@@has_light_4: ;/
01B2 (1B5) 55 in a,[l] ;PORT[0] ;
01B3 (19A) 64 testsk a.0 ;
01B4 (18D) 83 jmp 01B6 ;@@has_light_5 ;
01B5 (186) E3 jmp 01C1 ;@@got_dark_5 ;
;— ;
@@has_light_5: ;/
01B6 (183) 55 in a,[l] ;PORT[0] ;
01B7 (1C1) 64 testsk a.0 ;
01B8 (1A0) E8 jmp 01BA ;@@has_light_6 ;
01B9 (1D0) F1 jmp 01C2 ;@@got_dark_6 ;
;— ;
@@has_light_6: ;/
01BA (1E8) 00 nop ;delay
01BB (1F4) 49 set c ;CY=1 (light) (continous light on seen 6 times)
01BC (1FA) 4C ret ;ret without skip
;— — —
@@got_dark_1:
01BD (1BD) 3A mov a,0A ;delay count -6
@@got_dark_2:
01BE (19E) 3B mov a,0B ;delay count -5
@@got_dark_3:
01BF (18F) 3C mov a,0C ;delay count -4
@@got_dark_4:
01C0 (1C7) 3D mov a,0D ;delay count -3
@@got_dark_5:
01C1 (1E3) 3E mov a,0E ;delay count -2
@@got_dark_6:
01C2 (1F1) 3F mov a,0F ;delay count -1
@@got_dark_delay: ;\delay (to maintain
01C3 (1B8) 01 addsk a,01 ; fixed execution time)
01C4 (1DC) B8 jmp 01C3 ;@@got_dark_delay ;/
01C5 (1EE) 48 clr c ;CY=0 (dark)
01C6 (1B7) 4D retsk ;SKIP
;——————
01C7 (1DB) 00 nop ;\unused (2 bytes)
01C8 (1ED) 00 nop ;/
;——————
is_0010_1x1x_1011:
01C9 (1B6) 60 testsk [hl].0 ;[01h] ;0010_1x11_1011
01CA (19B) 92 jmp 01D5 ;@@not_0010_1x11_1011
01CB (1CD) 62 testsk [hl].2 ;[01h] ;0010_1111_1011
01CC (1A6) A9 jmp 01D1 ;@@not_0010_1111_1011
;CMD_0010_1111_1011 –> down large step
01CD (193) 2A mov l,0A
01CE (1C9) 6C set [hl].0 ;[0Ah] ;nonzero=request another_step (value=1=down)
01CF (1A4) 78 D8 jmp 00A0 ;move_down
;—
@@not_0010_1111_1011: ;aka is 0010_1011_1011
;CMD_0010_1011_1011 –> up large step
01D1 (1A9) 2A mov l,0A
01D2 (194) 6D set [hl].1 ;[0Ah] ;nonzero=request another_step (value=2=up)
01D3 (1CA) 78 EC jmp 00A1 ;move_up
;—
@@not_0010_1x11_1011: ;aka is 0010_1x10_1011
01D5 (192) 62 testsk [hl].2 ;[01h] ;0010_1110_1011
01D6 (189) C8 jmp 01DB ;@@not_0010_1110_1011
;CMD_0010_1110_1011 –> turn LED on permanently
01D7 (184) 2D mov l,0D
01D8 (1C2) 6C set [hl].0 ;[0Dh] ;LED.flag
01D9 (1A1) 78 0F jmp 003F ;want_next_cmd_bit
;—
@@not_0010_1110_1011: ;aka is 0010_1010_1011
;CMD_0010_1010_1011 –> reset
01DB (1C8) 2D mov l,0D
01DC (1E4) 6C set [hl].0 ;[0Dh] ;LED.flag
01DD (1F2) 78 5F jmp 0008 ;softreset_entrypoint
;——————
01DF (19C) 00 nop ;\unused (2 bytes)
01E0 (1CE) 00 nop ;/
;——————
process_cmd_if_any:
01E1 (1A7) 20 mov l,00
01E2 (1D3) 54 testsk c ;\test 13th bit
01E3 (1E9) DA jmp 01E5 ;@@is__0_xxxx_xxxx_xxxx ; (aka carry-out from
01E4 (1B4) 82 jmp 01FD ;@@not_0_xxxx_xxxx_xxxx ; 3x4bit cmd buffer)
@@is__0_xxxx_xxxx_xxxx: ;/
01E5 (1DA) 32 mov a,02 ;0010_xxxx_xxxx ;
01E6 (1AD) 45 cmpsk a,[hl] ;[00h] ; check start bits
01E7 (196) 82 jmp 01FD ;@@not_0010_xxxx_xxxx ;/
01E8 (18B) 22 mov l,02 ;-now end bits
01E9 (1C5) 3E mov a,0E ;0010_xxxx_1110 ;
01EA (1A2) 45 cmpsk a,[hl] ;[02h] ;
01EB (191) 8A jmp 01FB ;@@not_0010_xxxx_1110 ;/
01EC (188) 21 mov l,01 ;-now middle bits
;mov a,0E ;0010_1110_1110 ;
01ED (1C4) 45 cmpsk a,[hl] ;[01h] ;
01EE (1E2) E6 jmp 01F2 ;@@not_0010_1110_1110 ;/
01EF (1B1) 7D 78 call 0104 ;cmd_open_arms ;–> CMD_0010_1110_1110 –> open arms
01F1 (1CC) AB jmp 01F7 ;@@to_set_led_and_want_fresh_command
;—
@@not_0010_1110_1110: ;in: HL=01h
01F2 (1E6) 3B mov a,0B ;0010_1011_1110 ;
01F3 (1B3) 45 cmpsk a,[hl] ;[01h] ;
01F4 (1D9) AA jmp 01F9 ;@@not_0010_1011_1110 ;/
01F5 (1AC) 7D 7C call 0105 ;cmd_close_arms ;–> CMD_0010_1011_1110 –> close arms
@@to_set_led_and_want_fresh_command:
01F7 (1AB) 78 D1 jmp 00AE ;set_led_and_want_fresh_command
;—
@@not_0010_1011_1110: ;in: HL=01h
01F9 (1AA) 78 F8 jmp 0084 ;not_0010_1011_1110_cont
;—
@@not_0010_xxxx_1110: ;in: HL=02h
01FB (18A) 78 DF jmp 0088 ;not_0010_xxxx_1110_cont
;—
@@not_0_xxxx_xxxx_xxxx:
@@not_0010_xxxx_xxxx:
01FD (182) 78 D0 jmp 00B9 ;not_0_0010_xxxx_xxxx_cont
;——————
01FF (1FF) 80 jmp 0180
;——————