Get longs working, add a second 10-digit printout that can print up to 12!
authorNick Downing <nick@ndcode.org>
Thu, 20 Jun 2019 08:39:22 +0000 (18:39 +1000)
committerNick Downing <nick@ndcode.org>
Thu, 20 Jun 2019 08:39:22 +0000 (18:39 +1000)
sm3.asm

diff --git a/sm3.asm b/sm3.asm
index f6ff0ac..df94a6e 100644 (file)
--- a/sm3.asm
+++ b/sm3.asm
@@ -234,9 +234,10 @@ page1_stkst_w:
 
 page1_st_w:
        pop     hl
-       ld      (hl),e
-       inc     hl
-       ld      (hl),d
+;      ld      (hl),e
+;      inc     hl
+;      ld      (hl),d
+ call xxxmath_st_w
        jr      page1_dispatch0
 
 page1_imm_cmprev_sw:
@@ -646,39 +647,40 @@ page2_imm_mul_ul:
 
 page2_mul_l:
        rst     0x30
+       ex      de,hl
        call    math_mul_l
        jr      mul_l_done
 
-page1_imm_divrev_sl:
-       rst     0x30
-       .db     0x3e ; ld a,
-page1_div_sl:
+page2_imm_divrev_sl:
        rst     0x38
+       .db     0x3e ; ld a,
+page2_div_sl:
+       rst     0x30
        call    math_div_sl0
        jr      div_l_done
 
-page1_imm_div_sl:
-       rst     0x30
-       .db     0x3e ; ld a,
-page1_divrev_sl:
+page2_imm_div_sl:
        rst     0x38
+       .db     0x3e ; ld a,
+page2_divrev_sl:
+       rst     0x30
        ex      de,hl
        call    math_div_sl
        jr      div_l_done
 
-page1_imm_divrev_ul:
-       rst     0x30
-       .db     0x3e ; ld a,
-page1_div_ul:
+page2_imm_divrev_ul:
        rst     0x38
+       .db     0x3e ; ld a,
+page2_div_ul:
+       rst     0x30
        call    math_div_ul0
        jr      div_l_done
 
-page1_imm_div_ul:
-       rst     0x30
-       .db     0x3e ; ld a,
-page1_divrev_ul:
+page2_imm_div_ul:
        rst     0x38
+       .db     0x3e ; ld a,
+page2_divrev_ul:
+       rst     0x30
        ex      de,hl
        call    math_div_ul
 div_l_done:
@@ -791,6 +793,17 @@ math_stkst_w: ; de to sp(imm_w)
        ld      h,a
        add     hl,sp
 ; use inline code for math_st_w
+xxxmath_st_w:
+.if 0
+ call print_word
+ ld a,':
+ call print_char
+ ex de,hl
+ call print_word
+ ex de,hl
+ ld a,' 
+ call print_char
+.endif
        ld      (hl),e
        inc     hl
        ld      (hl),d
@@ -805,6 +818,23 @@ math_stkst_l: ; de:hl' to sp(imm_w)
        ld      h,a
        add     hl,sp
 math_st_l: ; de:hl' to (hl)
+.if 0
+ call print_word
+ ld a,':
+ call print_char
+ ex de,hl
+ call print_word
+ ex de,hl
+ push hl
+ exx
+ push hl
+ exx
+ pop hl
+ call print_word
+ pop hl
+ ld a,' 
+ call print_char
+.endif
        exx
        ld      a,l
        exx
@@ -2460,7 +2490,7 @@ div_l_n18: ; done, below
 
 ; debugging
 
-print_trace: ; print af, bc, de, hl, sp, (sp)
+print_trace: ; print af, bc, de:hl', hl:de', sp, (sp+2):(sp)
        push    hl
        push    af
        pop     hl
@@ -2476,10 +2506,26 @@ print_trace: ; print af, bc, de, hl, sp, (sp)
        ld      l,e
        ld      h,d
        call    print_word
+       ld      a,':
+       call    print_char
+       exx
+       push    hl
+       exx
+       pop     hl
+       call    print_word
        ld      a,' 
        call    print_char
+       pop     af
        pop     hl
        push    hl
+       push    af
+       call    print_word
+       ld      a,':
+       call    print_char
+       exx
+       push    de
+       exx
+       pop     hl
        call    print_word
        ld      a,' 
        call    print_char
@@ -2488,6 +2534,17 @@ print_trace: ; print af, bc, de, hl, sp, (sp)
        call    print_word
        ld      a,' 
        call    print_char
+       ld      hl,6
+       add     hl,sp
+       ld      a,(hl)
+       inc     hl
+       ld      h,(hl)
+       ld      l,a
+       call    print_word
+       ld      a,':
+       call    print_char
+       ld      hl,4
+       add     hl,sp
        ld      a,(hl)
        inc     hl
        ld      h,(hl)
@@ -2557,11 +2614,11 @@ digits:
 sm_main:
        ; create stack frame
        .db     <page0_stkadj
-       .dw     -2
+       .dw     -4
 
        ; push argument
        .db     <page0_imm_w
-       .dw     5
+       .dw     7
 
        ; push result pointer
        .db     <page1_page0
@@ -2574,13 +2631,43 @@ sm_main:
        .dw     sm_factorial
        .dw     4
 
-       ; print 10000s
+       ; let i = 0
+       .db     <page0_imm_w
+       .dw     0
+       .db     <page1_stkst_w
+       .dw     2+2
+
+digit_loop:
+       ; while i < 5
+       .db     <page0_stkld_w
+       .dw     2+2
+       .db     <page1_imm_cmp_sw
+       .dw     5
+       .db     <page0_jge
+       .dw     digit_loope
+
+       ; get current value
        .db     <page0_stkld_w
        .dw     0+2
-       .db     <page1_imm_div_sw
-       .dw     10000
+
+       ; get place value
+       .db     <page1_page0
+       .db     <page0_stkld_w
+       .dw     4+2
+       .db     <page1_imm_sl_w
+       .dw     1
+       .db     <page1_imm_add_w
+       .dw     place_values
+       .db     <page1_ld_w
+
+       ; divide by place value
+       .db     <page1_div_sw
+
+       ; replace current value with remainder
        .db     <page1_stkst_w
        .dw     2+2
+
+       ; print quotient plus '0
        .db     <page0_page1
        .db     <page1_imm_add_w
        .dw     '0
@@ -2589,61 +2676,112 @@ sm_main:
        .dw     sm_print_char
        .dw     2
 
-       ; print 1000s
+       ; ++i
        .db     <page0_stkld_w
-       .dw     0+2
-       .db     <page1_imm_div_sw
-       .dw     1000
-       .db     <page1_stkst_w
        .dw     2+2
-       .db     <page0_page1
        .db     <page1_imm_add_w
-       .dw     '0
+       .dw     1
+       .db     <page1_stkst_w
+       .dw     2+2
+
+       ; loop
+       .db     <page0_imm_jmp
+       .dw     digit_loop
+
+digit_loope:
+       ; print cr
+       .db     <page0_imm_w
+       .dw     0xd
        .db     <page1_page0
        .db     <page0_imm_call
        .dw     sm_print_char
        .dw     2
 
-       ; print 100s
-       .db     <page0_stkld_w
-       .dw     0+2
-       .db     <page1_imm_div_sw
-       .dw     100
-       .db     <page1_stkst_w
-       .dw     2+2
-       .db     <page0_page1
-       .db     <page1_imm_add_w
-       .dw     '0
+       ; print lf
+       .db     <page0_imm_w
+       .dw     0xa
        .db     <page1_page0
        .db     <page0_imm_call
        .dw     sm_print_char
        .dw     2
 
-       ; print 10s
+       ; enlarge stack frame
+       .db     <page0_stkadj
+       .dw     -2
+
+       ; push argument
+       .db     <page0_imm_l
+       .dw     12,0
+
+       ; push result pointer
+       .db     <page2_page0
+       .db     <page0_stkptr
+       .dw     4
+
+       ; call sm_factorial(argument)
+       .db     <page1_page0
+       .db     <page0_imm_call
+       .dw     sm_factorial2
+       .dw     6
+
+       ; let i = 0
+       .db     <page0_imm_w
+       .dw     0
+       .db     <page1_stkst_w
+       .dw     4+2
+
+digit_loop2:
+       ; while i < 10
        .db     <page0_stkld_w
-       .dw     0+2
-       .db     <page1_imm_div_sw
+       .dw     4+2
+       .db     <page1_imm_cmp_sw
        .dw     10
-       .db     <page1_stkst_w
-       .dw     2+2
+       .db     <page0_jge
+       .dw     digit_loope2
+
+       ; get current value
+       .db     <page0_stkld_l
+       .dw     0+2
+
+       ; get place value
+       .db     <page2_page0
+       .db     <page0_stkld_w
+       .dw     8+2
+       .db     <page1_imm_sl_w
+       .dw     2
+       .db     <page1_imm_add_w
+       .dw     place_values2
+       .db     <page1_ld_l
+
+       ; divide by place value
+       .db     <page2_div_sl
+
+       ; replace current value with remainder
+       .db     <page2_stkst_l
+       .dw     4+2
+
+       ; print quotient plus '0
        .db     <page0_page1
        .db     <page1_imm_add_w
        .dw     '0
        .db     <page1_page0
        .db     <page0_imm_call
        .dw     sm_print_char
-       .dw     2
+       .dw     4 ; cheating -- kill hi word of long too
 
-       ; print 1s
+       ; ++i
        .db     <page0_stkld_w
-       .dw     0+2
+       .dw     4+2
        .db     <page1_imm_add_w
-       .dw     '0
-       .db     <page1_page0
-       .db     <page0_imm_call
-       .dw     sm_print_char
-       .dw     2
+       .dw     1
+       .db     <page1_stkst_w
+       .dw     4+2
+
+       ; loop
+       .db     <page0_imm_jmp
+       .dw     digit_loop2
 
+digit_loope2:
        ; print cr
        .db     <page0_imm_w
        .dw     0xd
@@ -2662,13 +2800,26 @@ sm_main:
 
        ; destroy stack frame
        .db     <page0_stkadj
-       .dw     2
+       .dw     6
 
        ; return
        .db     <page0_ret
 
+place_values:
+       .dw     10000,1000,100,10,1
+place_values2:
+       .dw     0xca00,0x3b9a ; 1000000000
+       .dw     0xe100,0x5f5 ; 100000000
+       .dw     0x9680,0x98 ; 10000000
+       .dw     0x4240,0xf ; 1000000
+       .dw     0x86a0,1 ; 100000
+       .dw     10000,0
+       .dw     1000,0
+       .dw     100,0
+       .dw     10,0
+       .dw     1,0
+
 sm_factorial:
- .db <page0_trace
        ; get argument
        .db     <page0_stkld_w
        .dw     4+2
@@ -2714,7 +2865,6 @@ sm_factorial:
        .db     <page1_st_w
 
        ; return
- .db <page0_trace
        .db     <page0_ret
 
 1$:
@@ -2729,7 +2879,69 @@ sm_factorial:
        .db     <page1_st_w
 
        ; return
- .db <page0_trace
+       .db     <page0_ret
+
+sm_factorial2:
+       ; get argument
+       .db     <page0_stkld_l
+       .dw     4+2
+
+       ; is argument < 2?
+       .db     <page2_imm_cmp_sl
+       .dw     2
+       .dw     0
+       .db     <page0_jlt
+       .dw     1$
+
+       ; no, set up for *result =
+       .db     <page0_stkld_w
+       .dw     2+2
+
+       ; get argument
+       .db     <page1_page0
+       .db     <page0_stkld_l
+       .dw     6+2
+
+       ; subtract 1
+       .db     <page2_imm_add_l
+       .dw     -1,-1
+
+       ; push result pointer
+       .db     <page2_page0
+       .db     <page0_stkptr
+       .dw     0
+
+       ; call sm_factorial(argument - 1)
+       .db     <page1_page0
+       .db     <page0_imm_call
+       .dw     sm_factorial2
+       .dw     2
+
+       ; get argument
+       .db     <page0_stkld_l
+       .dw     10+2
+
+       ; multiply
+       .db     <page2_mul_l
+
+       ; set *result = sm_factorial(argument - 1) * argument
+       .db     <page2_st_l
+
+       ; return
+       .db     <page0_ret
+
+1$:
+       ; yes, set up for *result =
+       .db     <page0_stkld_w
+       .dw     2+2
+
+       ; set *result = 1
+       .db     <page1_page0
+       .db     <page0_imm_l
+       .dw     1,0
+       .db     <page2_st_l
+
+       ; return
        .db     <page0_ret
 
 sm_print_char: