102 call div_hl_de_signed
107 call div_hl_de_signed
127 ; ; push result pointer
131 ; ; call sm_factorial(argument)
137 ;; ; print it the easy way
208 ; rst 0 ; can't return into ccp as clobbered by stack growth
222 ; ; no, set up for *result =
236 ; ; push result pointer
240 ; ; call sm_factorial(argument - 1)
254 ; ; set *result = sm_factorial(argument - 1) * argument
260 ;1$: ; yes, set up for *result =
282 .ascii '0123456789abcdef'
472 ; lower dispatcher, just before 0x100
476 dispatch_l5: ; pc in de
479 dispatch_l6: ; tos in de, pc in hl
484 rst 0x30 ; print stack
491 dispatch_l1: ; tos in de and hl, pc in bc
493 dispatch_l2: ; tos in hl, pc in bc
495 dispatch_l3: ; tos in de, pc in bc, h clobbered
497 dispatch_l4: ; tos in de, pc in bc, h = >esc
501 rst 0x30 ; print stack
510 call_i: ; same as imm_w, call
522 jmp_i: ; same as imm_w, jmp
526 jz_i: ; same as imm_w, jz
537 jnz_i: ; same as imm_w, jnz
560 add_isp: ; same as imm_w, add_sp
569 ld_iw: ; same as imm_w, ld_w
580 ld_isb: ; same as imm_w, ld_sb
593 ld_iub: ; same as imm_w, ld_ub
614 add_iw: ; same as imm_w, add_w
622 ;sub_iw: ; same as imm_w, sub_w
623 ; rst 8 ; ld hl,(bc)+
625 sub_xw: ; same as xchg_w, sub_w
629 sub_w: ; same as neg_w, add_w
635 eq_iw: ; same as imm_w, eq_w
648 ; middle dispatch routines
650 jmp: ; also means ret
655 adj_isp: ; same as imm_w, adj_sp
659 adj_sp: ; same as add_sp, st_sp
668 ;st_ixw: ; same as imm_w, xchg_w, st_w
669 ; rst 8 ; ld hl,(bc)+
675 st_iw: ; same as imm_w, st_w
686 st_ixb: ; same as imm_w, xchg_w, st_d
694 ; middle dispatcher, near 0x180, smaller in size
695 ; used for store-type routines that empty stack and need it to be popped
697 dispatch_mm1: ; pc in bc
699 dispatch_m0: ; pc in bc, h = >esc
704 rst 0x30 ; print stack
708 lt_iuw: ; same as imm_w, lt_iuw
711 gt_uw: ; same as xchg_w, lt_uw
724 lt_isw: ; same as imm_w, lt_isw
727 gt_sw: ; same as xchg_w, lt_sw
748 and_iw: ; same as imm_w, and_w
761 or_iw: ; same as imm_w, and_w
774 xor_iw: ; same as imm_w, and_w
834 ; upper dispatcher, after 0x200
836 dispatch_um1: ; tos in hl and de, pc in bc
839 ;dispatch_u1: ; tos in de and hl, pc in bc
841 dispatch_u2: ; tos in hl, pc in bc
843 dispatch_u3: ; tos in de, pc in bc, h clobbered
845 dispatch_u4: ; tos in de, pc in bc, h = >esc
848 rst 0x30 ; print stack
920 jp p,4$ ; positive dividend
923 dec hl ; reduces remainder by 1 (we inc later)
927 jr c,2$ ; negative dividend, negative divisor
929 ; negative dividend, positive divisor
937 1$: inc hl ; get into range -divisor+1..0
943 2$: ; negative dividend, negative divisor
950 3$: inc hl ; get into range divisor+1..0
956 4$: ; positive dividend
960 jr nc,divu ; positive dividend, positive divisor
962 ; positive dividend, negative divisor
981 divu: ; positive dividend, positive divisor
993 ; non-restoring division routine
995 ; de = divisor, hl:a = dividend with hl = previous remainder, a = next byte
996 ; enter at div0 with positive remainder in hl, such that hl < de
997 ; enter at div1 with negative remainder in hl, such that hl >= -de
999 ; div0/1 return a = 8-bit quotient as an odd number interpreted as -ff..ff,
1000 ; by summing positive/negative place values, e.g. -80 +40 +20 -10 +8 -4 -2 +1
1002 ; if entered at div0, there is a -80 and so quotient is in range -ff..-1
1003 ; if entered at div1, there is a +80 and so quotient is in range 1..ff
1004 ; falls out of loop after div01 with positive remainder, div11 with negative,
1005 ; depending on this we should re-enter at div0 or div1, signalled by cf return
1007 ; the successive quotient bytes can be concatenated into a full quotient,
1008 ; but negative bytes require the next higher quotient byte to be decremented,
1009 ; we know in advance if this will happen because the implied sign of the
1010 ; quotient byte depends only on whether we entered at div0 or div1, hence,
1011 ; before the div11 return we'll decrement to compensate for next negative byte
1013 ; the decrement can also be seen as compensating for the extra add hl,de that
1014 ; may be needed to make negative remainder positive before return to caller,
1015 ; thus leaving quotient in a consistent state regardless of which exit taken,
1016 ; remainder needs the add hl,de if cf=1 returned (equiv. return byte is even)
1018 ; in the following code each sbc hl,de gets an inc a and each add hl,de gets
1019 ; a dec a, guaranteeing the integrity of the division, the initial scf/rla is
1020 ; needed to make the result 100 + -ff..ff or 1..1ff, so that the decrements
1021 ; cannot borrow into the upcoming dividend bits also held in a, and there must
1022 ; be another shift between the scf/rla and increment/decrement so that the scf
1023 ; is implicitly in the 100s place, making the code awkward though it's correct
1025 ; now optimized to only inc/dec a when doing zero-crossing, fix above analysis
1028 div0: ; bit 0, above
1035 div11: ; bit 1, below
1041 div02: ; bit 2, above
1047 div13: ; bit 3, below
1053 div04: ; bit 4, above
1059 div15: ; bit 5, below
1065 div06: ; bit 6, above
1071 div17: ; bit 7, below
1077 div08: ; done, above
1083 div1: ; bit 0, below
1089 div01: ; bit 1, above
1095 div12: ; bit 2, below
1101 div03: ; bit 3, above
1107 div14: ; bit 4, below
1113 div05: ; bit 5, above
1119 div16: ; bit 6, below
1125 div07: ; bit 7, above
1131 div18: ; done, below
1134 ;dec a ; compensation
1138 ; divn0/1 are the same as div0/1 but carry reversed after add/subtract divisor
1139 ; this is for negative divisors where we expect carry (means no zero crossing)
1141 ; when divisor negated, remainder also negated, so we expect to do subtraction
1142 ; when remainder negative and vice versa, need to clear carry after add hl,hl
1145 divn0: ; bit 0, above
1153 divn11: ; bit 1, below
1159 divn02: ; bit 2, above
1166 divn13: ; bit 3, below
1172 divn04: ; bit 4, above
1179 divn15: ; bit 5, below
1185 divn06: ; bit 6, above
1192 divn17: ; bit 7, below
1198 divn08: ; done, above
1204 divn1: ; bit 0, below
1210 divn01: ; bit 1, above
1217 divn12: ; bit 2, below
1223 divn03: ; bit 3, above
1230 divn14: ; bit 4, below
1236 divn05: ; bit 5, above
1243 divn16: ; bit 6, below
1249 divn07: ; bit 7, above
1256 divn18: ; done, below
1259 ;dec a ; compensation