Unroll the multiply, reinstate the state machine test code
authorNick Downing <nick@ndcode.org>
Thu, 13 Jun 2019 16:24:33 +0000 (02:24 +1000)
committerNick Downing <nick@ndcode.org>
Thu, 13 Jun 2019 16:24:33 +0000 (02:24 +1000)
sm.asm

diff --git a/sm.asm b/sm.asm
index 6297e60..43a2063 100644 (file)
--- a/sm.asm
+++ b/sm.asm
        call    div_hl_de_signed
        call    print_div
 
-       rst     0
-
-print_div:
-       ex      de,hl
-       call    print_word
-       ex      de,hl
-       call    print_space
-       call    print_word
-       jp      print_crlf
-
-;      pop     de
-;      call    sm
-;
-;      ; push argument
-;      .db     <imm_w
-;      .dw     5
-;
-;      ; push result pointer
-;      .db     <add_isp
-;      .dw     0
-;
-;      ; call sm_factorial(argument)
-;      .db     <call_i
-;      .dw     sm_factorial
-;      .db     <adj_isp
-;      .dw     2
-;
-;;     ; print it the easy way
-;;     .db     <esc
-;;     ex      de,hl
-;;     call    print_word
-;;     call    print_crlf
-;;     ex      de,hl
-;;     call    sm
-;
-;      ; print 10000s
-;      .db     <div_iuw
-;      .dw     10000
-;      .db     <add_iw
-;      .dw     '0
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      ; print 1000s
-;      .db     <div_iuw
-;      .dw     1000
-;      .db     <add_iw
-;      .dw     '0
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      ; print 100s
-;      .db     <div_iuw
-;      .dw     100
-;      .db     <add_iw
-;      .dw     '0
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      ; print 10s
-;      .db     <div_iuw
-;      .dw     10
-;      .db     <add_iw
-;      .dw     '0
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      ; print 1s
-;      .db     <add_iw
-;      .dw     '0
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      .db     <imm_w
-;      .dw     0xd
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      .db     <imm_w
-;      .dw     0xa
-;      .db     <call_i
-;      .dw     sm_print_char
-;      .db     <adj_isp
-;      .dw     2
-;
-;      .db     <esc
-;      rst     0 ; can't return into ccp as clobbered by stack growth
-;
-;sm_factorial:
-;      ; get argument
-;      .db     <add_isp
-;      .dw     4
-;      .db     <ld_w
-;
-;      ; is argument < 2?
-;      .db     <lt_isw
-;      .dw     2
-;      .db     <jnz_i
-;      .dw     1$
-;
-;      ; no, set up for *result =
-;      .db     <add_isp
-;      .dw     2
-;      .db     <ld_w
-;
-;      ; get argument
-;      .db     <add_isp
-;      .dw     6
-;      .db     <ld_w
-;
-;      ; subtract 1
-;      .db     <add_iw
-;      .dw     -1
-;
-;      ; push result pointer
-;      .db     <add_isp
-;      .dw     0
-;
-;      ; call sm_factorial(argument - 1)
-;      .db     <call_i
-;      .dw     sm_factorial
-;      .db     <adj_isp
-;      .dw     2
-;
-;      ; get argument
-;      .db     <add_isp
-;      .dw     8
-;      .db     <ld_w
-;
-;      ; multiply
-;      .db     <mul_w
-;
-;      ; set *result = sm_factorial(argument - 1) * argument
-;      .db     <st_w
-;
-;      ; return 
-;      .db     <jmp
-;
-;1$:   ; yes, set up for *result =
-;      .db     <add_isp
-;      .dw     2
-;      .db     <ld_w
-;
-;      ; set *result = 1
-;      .db     <st_iw
-;      .dw     1
-;
-;      ; return 
-;      .db     <jmp
-;
-;sm_print_char:
-;      .db     <esc
-;      ld      hl,0
-;      add     hl,sp
-;      ld      a,(hl)
-;      call    print_char
-;      call    sm
-;      .db     <jmp
-
-digits:
-       .ascii  '0123456789abcdef'
+       pop     de
+       call    sm
 
-print_word:
-       push    af
-       ld      a,h
-       call    print_byte
-       ld      a,l
-       call    print_byte
-       pop     af
-       ret
+       ; push argument
+       .db     <imm_w
+       .dw     5
 
-print_byte:
-       push    af
-       push    af
-       rrca
-       rrca
-       rrca
-       rrca
-       call    print_digit
-       pop     af
-       call    print_digit
-       pop     af
-       ret
+       ; push result pointer
+       .db     <add_isp
+       .dw     0
 
-print_digit:
-       push    de
-       push    hl
-       and     0xf
-       ld      e,a
-       ld      d,0
-       ld      hl,digits
-       add     hl,de
-       ld      a,(hl)
-       pop     hl
-       pop     de
-       jp      print_char
+       ; call sm_factorial(argument)
+       .db     <call_i
+       .dw     sm_factorial
+       .db     <adj_isp
+       .dw     2
 
-print_space:
-       push    af
-       ld      a,0x20
-       call    print_char
-       pop     af
-       ret
+;      ; print it the easy way
+;      .db     <esc
+;      ex      de,hl
+;      call    print_word
+;      call    print_crlf
+;      ex      de,hl
+;      call    sm
 
-print_trace:
-       push    af
-       push    bc
-       push    de
-       push    hl
-       ld      a,'p
-       call    print_char
-       ld      a,'c
-       call    print_char
-       ld      a,'=
-       call    print_char
-       rst     0x10 ; ex bc,hl
-       call    print_word
-       rst     0x10 ; ex bc,hl
-       call    print_space
-       ld      a,'o
-       call    print_char
-       ld      a,'p
-       call    print_char
-       ld      a,'=
-       call    print_char
-       call    print_word
-       call    print_space
-       ld      a,'s
-       call    print_char
-       ld      a,'p
-       call    print_char
-       ld      a,'=
-       call    print_char
-       ld      hl,10
+       ; print 10000s
+       .db     <div_iuw
+       .dw     10000
+       .db     <add_iw
+       .dw     '0
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       ; print 1000s
+       .db     <div_iuw
+       .dw     1000
+       .db     <add_iw
+       .dw     '0
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       ; print 100s
+       .db     <div_iuw
+       .dw     100
+       .db     <add_iw
+       .dw     '0
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       ; print 10s
+       .db     <div_iuw
+       .dw     10
+       .db     <add_iw
+       .dw     '0
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       ; print 1s
+       .db     <add_iw
+       .dw     '0
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       .db     <imm_w
+       .dw     0xd
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       .db     <imm_w
+       .dw     0xa
+       .db     <call_i
+       .dw     sm_print_char
+       .db     <adj_isp
+       .dw     2
+
+       .db     <esc
+       rst     0 ; can't return into ccp as clobbered by stack growth
+
+sm_factorial:
+       ; get argument
+       .db     <add_isp
+       .dw     4
+       .db     <ld_w
+
+       ; is argument < 2?
+       .db     <lt_isw
+       .dw     2
+       .db     <jnz_i
+       .dw     1$
+
+       ; no, set up for *result =
+       .db     <add_isp
+       .dw     2
+       .db     <ld_w
+
+       ; get argument
+       .db     <add_isp
+       .dw     6
+       .db     <ld_w
+
+       ; subtract 1
+       .db     <add_iw
+       .dw     -1
+
+       ; push result pointer
+       .db     <add_isp
+       .dw     0
+
+       ; call sm_factorial(argument - 1)
+       .db     <call_i
+       .dw     sm_factorial
+       .db     <adj_isp
+       .dw     2
+
+       ; get argument
+       .db     <add_isp
+       .dw     8
+       .db     <ld_w
+
+       ; multiply
+       .db     <mul_w
+
+       ; set *result = sm_factorial(argument - 1) * argument
+       .db     <st_w
+
+       ; return 
+       .db     <jmp
+
+1$:    ; yes, set up for *result =
+       .db     <add_isp
+       .dw     2
+       .db     <ld_w
+
+       ; set *result = 1
+       .db     <st_iw
+       .dw     1
+
+       ; return 
+       .db     <jmp
+
+sm_print_char:
+       .db     <esc
+       ld      hl,0
        add     hl,sp
-       call    print_word
-       call    print_space
-       ld      a,'t
-       call    print_char
-       ld      a,'o
-       call    print_char
-       ld      a,'s
-       call    print_char
-       ld      a,'=
-       call    print_char
-       ex      de,hl
-       call    print_word
-       ex      de,hl
-       call    print_space
-       ld      a,'s
-       call    print_char
-       ld      a,'t
-       call    print_char
-       ld      a,'k
-       call    print_char
-       ld      b,4
-       ld      a,'=
-1$:    call    print_char
-       ld      e,(hl)
-       inc     hl
-       ld      d,(hl)
-       inc     hl
-       ex      de,hl
-       call    print_word
-       ex      de,hl
-       ld      a,' 
-       djnz    1$
-       pop     hl
-       pop     de
-       pop     bc
-       pop     af
-print_crlf:
-       push    af
-       ld      a,0xd
-       call    print_char
-       ld      a,0xa
+       ld      a,(hl)
        call    print_char
-       pop     af
-       ret
-
-print_char:
-       push    bc
-       push    de
-       push    hl
-       ld      e,a
-       ld      c,2
-       call    5
-       pop     hl
-       pop     de
-       pop     bc
-       ret
+       call    sm
+       .db     <jmp
 
        .org    0x308
 
@@ -895,20 +752,54 @@ mul_hl_de:
        ld      a,h
        ld      c,l
        ld      hl,0
-       ld      b,8
-1$:    add     hl,hl
+       call    mul
+       ;ld     b,a             ; for 32-bit result
+       ld      a,c
+       call    mul
+       ;ld     c,a             ; for 32-bit result
+       pop     bc
+       ret
+
+mul:   ; bit 0
+       add     hl,hl
+       rla
+       jr      nc,1$
+       add     hl,de
+1$:    ; bit 1
+       add     hl,hl
        rla
        jr      nc,2$
        add     hl,de
-2$:    djnz    1$
-       ld      a,c
-       ld      b,8
-3$:    add     hl,hl
+2$:    ; bit 2
+       add     hl,hl
+       rla
+       jr      nc,3$
+       add     hl,de
+3$:    ; bit 3
+       add     hl,hl
        rla
        jr      nc,4$
        add     hl,de
-4$:    djnz    3$
-       pop     bc
+4$:    ; bit 4
+       add     hl,hl
+       rla
+       jr      nc,5$
+       add     hl,de
+5$:    ; bit 5
+       add     hl,hl
+       rla
+       jr      nc,6$
+       add     hl,de
+6$:    ; bit 6
+       add     hl,hl
+       rla
+       jr      nc,7$
+       add     hl,de
+7$:    ; bit 7
+       add     hl,hl
+       rla
+       ret     nc
+       add     hl,de
        ret
 
 div_hl_de_signed:
@@ -1259,3 +1150,146 @@ divn18: ; done, below
        ;dec    a                       ; compensation
        scf
        ret
+
+; debugging
+
+digits:
+       .ascii  '0123456789abcdef'
+
+print_word:
+       push    af
+       ld      a,h
+       call    print_byte
+       ld      a,l
+       call    print_byte
+       pop     af
+       ret
+
+print_byte:
+       push    af
+       push    af
+       rrca
+       rrca
+       rrca
+       rrca
+       call    print_digit
+       pop     af
+       call    print_digit
+       pop     af
+       ret
+
+print_digit:
+       push    de
+       push    hl
+       and     0xf
+       ld      e,a
+       ld      d,0
+       ld      hl,digits
+       add     hl,de
+       ld      a,(hl)
+       pop     hl
+       pop     de
+       jp      print_char
+
+print_space:
+       push    af
+       ld      a,0x20
+       call    print_char
+       pop     af
+       ret
+
+print_trace:
+       push    af
+       push    bc
+       push    de
+       push    hl
+       ld      a,'p
+       call    print_char
+       ld      a,'c
+       call    print_char
+       ld      a,'=
+       call    print_char
+       rst     0x10 ; ex bc,hl
+       call    print_word
+       rst     0x10 ; ex bc,hl
+       call    print_space
+       ld      a,'o
+       call    print_char
+       ld      a,'p
+       call    print_char
+       ld      a,'=
+       call    print_char
+       call    print_word
+       call    print_space
+       ld      a,'s
+       call    print_char
+       ld      a,'p
+       call    print_char
+       ld      a,'=
+       call    print_char
+       ld      hl,10
+       add     hl,sp
+       call    print_word
+       call    print_space
+       ld      a,'t
+       call    print_char
+       ld      a,'o
+       call    print_char
+       ld      a,'s
+       call    print_char
+       ld      a,'=
+       call    print_char
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       call    print_space
+       ld      a,'s
+       call    print_char
+       ld      a,'t
+       call    print_char
+       ld      a,'k
+       call    print_char
+       ld      b,4
+       ld      a,'=
+1$:    call    print_char
+       ld      e,(hl)
+       inc     hl
+       ld      d,(hl)
+       inc     hl
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       ld      a,' 
+       djnz    1$
+       pop     hl
+       pop     de
+       pop     bc
+       pop     af
+print_crlf:
+       push    af
+       ld      a,0xd
+       call    print_char
+       ld      a,0xa
+       call    print_char
+       pop     af
+       ret
+
+print_char:
+       push    bc
+       push    de
+       push    hl
+       ld      e,a
+       ld      c,2
+       call    5
+       pop     hl
+       pop     de
+       pop     bc
+       ret
+
+print_div:
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       call    print_space
+       call    print_word
+       jp      print_crlf