Initial commit, can calculate a factorial recursively with C calling convetion
authorNick Downing <nick@ndcode.org>
Sun, 9 Jun 2019 23:28:05 +0000 (09:28 +1000)
committerNick Downing <nick@ndcode.org>
Sun, 9 Jun 2019 23:28:05 +0000 (09:28 +1000)
.gitignore [new file with mode: 0644]
asxxxx_build.sh [new file with mode: 0755]
n.sh [new file with mode: 0755]
sm.asm [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b1eeaf6
--- /dev/null
@@ -0,0 +1,8 @@
+*.com
+*.hlr
+*.ihx
+*.lst
+*.rel
+/asxs5p30.zip
+/asxxxx_build
+/bin
diff --git a/asxxxx_build.sh b/asxxxx_build.sh
new file mode 100755 (executable)
index 0000000..c398009
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# put asxs5p30.zip in current directory first
+# wget http://shop-pdp.net/_ftp/asxxxx/asxs5p30.zip
+
+rm -rf asxxxx_build
+mkdir asxxxx_build
+(cd asxxxx_build && unzip -L -a ../asxs5p30)
+(cd asxxxx_build/asxv5pxx/asxmak/linux/build && make asz80 aslink)
+mkdir --parents bin
+cp asxxxx_build/asxv5pxx/asxmak/linux/exe/as* bin
diff --git a/n.sh b/n.sh
new file mode 100755 (executable)
index 0000000..9cdca7f
--- /dev/null
+++ b/n.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+#pip3 install --user intelhex
+bin/asz80 -l -o sm.asm
+bin/aslink -i sm.ihx sm.rel
+python3 ~/.local/bin/hex2bin.py sm.ihx sm.com
+../z80pack/cpmsim/srctools/cpmw.sh a sm.com
diff --git a/sm.asm b/sm.asm
new file mode 100644 (file)
index 0000000..e6c5418
--- /dev/null
+++ b/sm.asm
@@ -0,0 +1,680 @@
+       .area   SM (abs,ovr)
+
+       .org    0x100
+
+       ld      hl,0x308
+       ld      de,8
+       ld      bc,0x38 ;0x10
+       ldir
+
+       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
+
+       .db     esc
+       rst     0x10 ; ex bc,hl
+       call    print_word
+       jp      print_crlf
+
+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
+
+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
+       jr      print_char
+
+print_space:
+       push    af
+       ld      a,0x20
+       call    print_char
+       pop     af
+       ret
+
+print_stack:
+       push    de
+       push    hl
+       ld      hl,6
+       add     hl,sp
+       call    print_word
+       call    print_space
+       rst     0x10 ; ex bc,hl
+       call    print_word
+       rst     0x10 ; ex bc,hl
+       call    print_space
+       ld      e,(hl)
+       inc     hl
+       ld      d,(hl)
+       inc     hl
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       call    print_space
+       ld      e,(hl)
+       inc     hl
+       ld      d,(hl)
+       inc     hl
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       call    print_space
+       ld      e,(hl)
+       inc     hl
+       ld      d,(hl)
+       ;inc    hl
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       pop     hl
+       pop     de
+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
+
+       .org    0x308
+
+; ld hl,(de)+
+       ex      de,hl
+       ld      e,(hl)
+       inc     hl
+       ld      d,(hl)
+       inc     hl
+       ex      de,hl
+       ret
+
+       .org    0x310
+
+; ex bc,hl
+       ld      a,l
+       ld      l,c
+       ld      c,a
+       ld      a,h
+       ld      h,b
+       ld      b,a
+       ret
+
+       .org    0x318
+
+; print bc
+       rst     0x10 ; ex bc,hl
+       call    print_word
+       rst     0x10 ; ex bc,hl
+       jp      print_space
+
+       .org    0x320
+
+; print de
+       ex      de,hl
+       call    print_word
+       ex      de,hl
+       jp      print_space
+       
+       .org    0x328
+
+; print hl
+       call    print_word
+       jp      print_space
+
+       .org    0x330
+
+; print stack
+       jp      print_stack
+
+       .org    0x338
+
+; print 'A'
+       push    af
+       ld      a,0x41
+       call    print_char
+       pop     af
+       ret
+
+; lower dispatcher, just before 0x100
+
+       .org    0x3ed
+
+sm:
+       pop     hl
+       .db     0x11 ; ld de,
+
+dispatch_l5m1: ; pc in bc
+       rst     0x10 ; ex bc,hl
+dispatch_l5: ; pc in hl
+       pop     bc
+dispatch_l6: ; tos in bc, pc in hl, d clobbered
+       ld      d,>esc
+dispatch_l7: ; tos in bc, pc in hl, d = >esc
+ rst 0x28 ; print hl
+       ld      e,(hl)
+       inc     hl
+       ex      de,hl
+ rst 0x28 ; print hl
+ rst 0x30 ; print stack
+       jp      (hl)
+
+dispatch_l1: ; tos in bc and hl, pc in de
+       push    bc
+dispatch_l2: ; tos in hl, pc in de
+       ld      c,l
+       ld      b,h
+dispatch_l3: ; tos in bc, pc in de, h clobbered
+       ld      h,>esc
+dispatch_l4: ; tos in bc, pc in de, h = >esc
+ rst 0x20 ; print de
+       ld      a,(de)
+       ld      l,a
+       inc     de
+ rst 0x28 ; print hl
+ rst 0x30 ; print stack
+       jp      (hl)
+
+; 0x100
+
+esc:
+       ex      de,hl
+       jp      (hl)
+
+call_i: ; same as imm_w, call
+       rst     8 ; ld hl,(de)+
+       push    bc
+       ld      c,e
+       ld      b,d
+       jr      dispatch_l6
+
+_call:
+       ex      de,hl
+       rst     0x10 ; ex bc,hl
+       jr      dispatch_l6
+
+jmp_i: ; same as imm_w, jmp
+       rst     8 ; ld hl,(de)+
+       jr      dispatch_l7
+
+jz_i: ; same as imm_w, jz
+       rst     8 ; ld hl,(de)+
+       rst     0x10 ; ex bc, hl
+       .db     0x3e ; ld a,
+jz:
+       pop     hl
+       ld      a,l
+       or      h
+       jr      nz,dispatch_mm1
+       jr      dispatch_l5m1
+
+jnz_i: ; same as imm_w, jnz
+       rst     8 ; ld hl,(de)+
+       rst     0x10 ; ex bc, hl
+       .db     0x3e ; ld a,
+jnz:
+       pop     hl
+       ld      a,l
+       or      h
+       jr      z,dispatch_mm1
+       jr      dispatch_l5m1
+
+;jmp_x: ; same as xchg_w, jmp
+;      pop     hl
+;      jr      dispatch_l6
+
+jmp: ; also means ret
+       ld      e,c
+       ld      d,b
+       jr      dispatch_m0
+
+xchg_w:
+       pop     hl
+       jr      dispatch_l1
+
+dup_w:
+       push    bc
+       jr      dispatch_l4
+
+imm_w:
+       rst     8 ; ld hl,(de)+
+       jr      dispatch_l1
+
+adj_isp: ; same as imm_w, adj_sp
+       rst     8 ; ld hl,(de)+
+       push    bc
+       .db     0x3e ; ld a,
+adj_sp: ; same as add_sp, st_sp
+       rst     0x10 ; ex bc,hl
+       add     hl,sp
+       .db     0x3e ; ld a,
+st_sp:
+       rst     0x10 ; ex bc,hl
+       ld      sp,hl
+       jr      dispatch_mm1
+
+add_isp: ; same as imm_w, add_sp
+       rst     8 ; ld hl,(de)+
+       push    bc
+       .db     0x3e ; ld a,
+add_sp:
+       rst     0x10 ; ex bc,hl
+       add     hl,sp
+       jr      dispatch_l2
+
+ld_iw: ; same as imm_w, ld_w
+       rst     8 ; ld hl,(de)+
+       push    bc
+       .db     0x3e ; ld a,
+ld_w:
+       rst     0x10 ; ex bc,hl
+       ld      c,(hl)
+       inc     hl
+       ld      b,(hl)
+       jr      dispatch_l3
+
+ld_isb: ; same as imm_w, ld_sb
+       rst     8 ; ld hl,(de)+
+       push    bc
+       .db     0x3e ; ld a,
+ld_sb:
+       rst     0x10 ; ex bc,hl
+       ld      c,(hl)
+       ld      a,c
+       rla
+       sbc     a,a
+       ld      b,a
+       jr      dispatch_l3
+
+ld_iub: ; same as imm_w, ld_ub
+       rst     8 ; ld hl,(de)+
+       push    bc
+       .db     0x3e ; ld a,
+ld_ub:
+       rst     0x10 ; ex bc,hl
+       ld      c,(hl)
+       ld      b,0
+       jr      dispatch_l3
+
+;st_ixw: ; same as imm_w, xchg_w, st_w
+;      rst     8 ; ld hl,(de)+
+;      ld      (hl),c
+;      inc     hl
+;      ld      (hl),b
+;      jr      dispatch_mm1
+
+st_iw: ; same as imm_w, st_w
+       rst     8 ; ld hl,(de)+
+       rst     0x10 ; ex bc,hl
+       .db     0x3e ; ld a,
+st_w:
+       pop     hl
+       ld      (hl),c
+       inc     hl
+       ld      (hl),b
+       jr      dispatch_mm1
+
+st_ixb: ; same as imm_w, xchg_w, st_b
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+st_b:
+       pop     hl
+       ld      (hl),c
+       jr      dispatch_mm1
+
+neg_w:
+       dec     bc
+not_w:
+       ld      a,c
+       cpl
+       ld      c,a
+       ld      a,b
+       cpl
+       ld      b,a
+       jr      dispatch_l4
+
+; middle dispatcher, near 0x180, smaller in size
+; used for store-type routines that empty stack and need it to be popped
+
+dispatch_mm1: ; pc in de
+       ld      h,>esc
+dispatch_m0: ; pc in de, h = >esc
+       pop     bc
+dispatch_m4:
+ rst 0x20 ; print de
+       ld      a,(de)
+       ld      l,a
+       inc     de
+ rst 0x28 ; print hl
+ rst 0x30 ; print stack
+       jp      (hl)
+
+add_iw: ; same as imm_w, add_w
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+add_w:
+       pop     hl
+       add     hl,bc
+       jr      dispatch_u2
+
+;sub_iw: ; same as imm_w, sub_w
+;      rst     8 ; ld hl,(de)+
+;      .db     0x3e ; ld a,
+sub_xw: ; same as xchg_w, sub_w
+       pop     hl
+       rst     0x10
+       .db     0x3e ; ld a,
+sub_w: ; same as neg_w, add_w
+       pop     hl
+       or      a
+       sbc     hl,bc
+       jr      dispatch_u2
+
+mul_iw:
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+mul_w:
+       pop     hl
+       push    de
+       call    mul_bc_hl
+       pop     de
+       jr      dispatch_u2
+
+eq_iw: ; same as imm_w, eq_w
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+eq_w:
+       pop     hl
+       sub     a
+       sbc     hl,bc
+       ld      c,a
+       ld      b,a
+       jr      nz,dispatch_u3
+       inc     c
+       jr      dispatch_u3
+
+lt_iuw: ; same as imm_w, lt_iuw
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+gt_uw: ; same as xchg_w, lt_uw
+       pop     hl
+       rst     0x10 ; ex bc,hl
+       .db     0x3e ; ld a,
+lt_uw:
+       pop     hl
+       sub     a
+       sbc     hl,bc
+       ld      b,a
+       adc     a,a
+       ld      c,a
+       jr      dispatch_u3
+
+lt_isw: ; same as imm_w, lt_isw
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+gt_sw: ; same as xchg_w, lt_sw
+       pop     hl
+       rst     0x10 ; ex bc,hl
+       .db     0x3e ; ld a,
+lt_sw:
+       pop     hl
+       sub     a
+       sbc     hl,bc
+       ld      b,a
+       jp      pe,lt_sw_overflow
+       add     hl,hl
+       adc     a,a
+       ld      c,a
+       jr      dispatch_u3
+lt_sw_overflow:
+       add     hl,hl
+       ccf
+       adc     a,a
+       ld      c,a
+       jr      dispatch_u3
+
+and_iw: ; same as imm_w, and_w
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+and_w:
+       pop     hl
+       ld      a,l
+       or      c
+       ld      c,a
+       ld      a,h
+       or      b
+       ld      b,a
+       jr      dispatch_u3
+
+or_iw: ; same as imm_w, and_w
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+or_w:
+       pop     hl
+       ld      a,l
+       or      c
+       ld      c,a
+       ld      a,h
+       or      b
+       ld      b,a
+       jr      dispatch_u3
+
+xor_iw: ; same as imm_w, and_w
+       rst     8 ; ld hl,(de)+
+       .db     0x3e ; ld a,
+xor_w:
+       pop     hl
+       ld      a,l
+       xor     c
+       ld      c,a
+       ld      a,h
+       xor     b
+       ld      b,a
+       jr      dispatch_u3
+
+sl_w:
+       pop     hl
+       call    sl_hl_c
+       jr      dispatch_u2
+
+sr_uw:
+       pop     hl
+       call    srl_hl_c
+       jr      dispatch_u2
+
+sr_sw:
+       pop     hl
+       call    sra_hl_c
+       jr      dispatch_u2
+
+; upper dispatcher, after 0x200
+
+dispatch_u1: ; tos in bc and hl, pc in de
+       push    bc
+dispatch_u2: ; tos in hl, pc in de
+       ld      c,l
+       ld      b,h
+dispatch_u3: ; tos in bc, pc in de, h clobbered
+       ld      h,>esc
+dispatch_u4: ; tos in bc, pc in de, h = >esc
+ rst 0x20 ; print de
+       ld      a,(de)
+       ld      l,a
+       inc     de
+ rst 0x28 ; print hl
+ rst 0x30 ; print stack
+       jp      (hl)
+
+; math package
+
+sl_hl_c:
+       ld      a,c
+sl_hl_a:
+       and     0xf
+       ret     z
+       ld      b,a
+1$:    add     hl,hl
+       djnz    1$
+       ret
+
+srl_hl_c:
+       ld      a,c
+srl_hl_a:
+       and     0xf
+       ret     z
+       ld      b,a
+       ld      a,l
+srl_hl_loop:
+       srl     h
+       rra
+       djnz    srl_hl_loop
+       ld      l,a
+       ret
+
+sra_hl_c:
+       ld      a,c
+sra_hl_a:
+       and     0xf
+       ret     z
+       ld      b,a
+       ld      a,l
+sra_hl_loop:
+       sra     h
+       rra
+       djnz    sra_hl_loop
+       ld      l,a
+       ret
+
+mul_bc_hl:
+       ex      de,hl
+mul_bc_de:
+       ld      hl,0
+       ld      a,b
+       ld      b,8
+1$:    add     hl,hl
+       rla
+       jr      nc,2$
+       add     hl,de
+2$:    djnz    1$
+       ld      a,c
+       ld      b,8
+3$:    add     hl,hl
+       rla
+       jr      nc,4$
+       add     hl,de
+4$:    djnz    3$
+       ret