// ================================
//	Moscovium
//		unsigned 32 bit shift divide routine
//		(c) 2022	1YEN Toru
// ================================
asm		"mcoc_irom.mem"
incl	"mcoc115.incl"
incl	"mcvm_mcr_long.incl"
# ================================
# user macro
macro	lsl32	rh,rl
// lsl32 $(rh):$(rl)
lsli	$(rl),1
csli	$(rh),1
endm

macro	lsl64	rhh,rhl,rlh,rll
// lsl64 $(rhh):$(rhl):$(rlh):$(rll)
lsli	$(rll),1
csli	$(rlh),1
csli	$(rhl),1
csli	$(rhh),1
endm
# ================================


// initialize
ldc		sp,ramtop+0x0100
ldwi	r6,simctrl
ldiu	r0,simc_noto
stw		[r6],r0
ldwi	r6,princtl
ldwi	r0,(asc_spc<<8)|prin_nld
stw		[r6],r0

// ================================
// divu32 load test
// ================================
ldwi	r7,lab_load_data
loop:
ldw		r0,[r7]							// DenH
addi	r7,2
ldw		r1,[r7]							// DenL
addi	r7,2
ldw		r2,[r7]							// DsoH
addi	r7,2
ldw		r3,[r7]							// DsoL
addi	r7,2
// check finish condition
mov		r4,r2
or		r4,r3
beq		tstpass
// show progress
ldwi	r6,prinhex
stw		[r6],r0
stw		[r6],r1
stw		[r6],r2
stw		[r6],r3
// divide routine test
jalwr6	divu32
// show result
ldwi	r6,prinhex
stw		[r6],r0
stw		[r6],r1
stw		[r6],r2
stw		[r6],r3
ldbiu	r5,asc_lf
ldwi	r6,princhr
stw		[r6],r5
// check result
ldw		r4,[r7]							// QuoH
addi	r7,2
ldw		r5,[r7]							// QuoL
addi	r7,2
cmp		r0,r4
bne		tstfail
cmp		r1,r5
bne		tstfail
ldw		r4,[r7]							// RemH
addi	r7,2
ldw		r5,[r7]							// RemL
addi	r7,2
cmp		r2,r4
bne		tstfail
cmp		r3,r5
bne		tstfail
// end of loop
bra		loop


// ================================
// unsigned 32/32=32...32 bits shift divide routine:
//		r0:r1...r2:r3=r0:r1/r2:r3 ; disturbed none
// ================================
divu32:
// initialize
pushwm	r4,r5,r6
ldbiu	r4,0
ldbiu	r5,0
ldbiu	r6,32
// loop
sdlu_loop:
lsl64	r4,r5,r0,r1
// quotient
bcc		sdlu_quo_else
// can not subtract, Quo=0 and add back
addl	r4,r5,r2,r3
bra		sdlu_quo_endif
sdlu_quo_else:
// can subtract, Quo=1 and subtract again
subl	r4,r5,r2,r3
ori		r1,1
sdlu_quo_endif:
// end of loop
subi	r6,1
bne		sdlu_loop
// remainder
lsl32	r0,r1
cmpi	r4,0
bpl		sdlu_rem_else
// can not subtract, Quo=0 and add back
addl	r4,r5,r2,r3
bra		sdlu_rem_endif
sdlu_rem_else:
// can subtract, Quo=1
ori		r1,1
sdlu_rem_endif:
// r4:r5 is Rem
movl	r2,r3,r4,r5
// end of subroutine
sdlu_return:
popwm	r6,r5,r4
rtnw


// ================================
tstpass:
ldwi	r0,simpass						// pass: LED=blue
bra		tstfnsh
tstfail:
ldwi	r0,simfail						// fail: LED=red
tstfnsh:
ldwi	r7,simfnsh
stw		[r7],r0
bra		pcnt-2
nop
// ================================


// ================================
// load test data & expected value
//		divu32 data: DenH,DenL, DsoH,DsoL, QuoH,QuoL, RemH,RemL
// ================================
load_data:
datw	0x06c9,0x61af,0x0002,0x104a,0x0000,0x0349,0x0001,0xde95
datw	0x214c,0xbf84,0x0001,0x1d40,0x0000,0x1de2,0x0000,0xad04
datw	0x09c1,0xb7c3,0x0001,0x74c6,0x0000,0x06b3,0x0000,0x6d51
datw	0x1102,0x330c,0x0001,0x2f88,0x0000,0x0e58,0x0000,0x6c4c
datw	0x0147,0xf129,0x0003,0x65ea,0x0000,0x0060,0x0001,0xb969
datw	0x0252,0x0ddd,0x0002,0x4ddd,0x0000,0x0101,0x0001,0xe300
datw	0x1e92,0xda19,0x0001,0x35c2,0x0000,0x1944,0x0000,0xa091
datw	0x1017,0xfb5e,0x0002,0x360b,0x0000,0x0747,0x0000,0xb151
datw	0x0b9e,0xa933,0x0000,0xb7e1,0x0000,0x102d,0x0000,0x46a6
datw	0x08bc,0xb48d,0x0000,0x90fa,0x0000,0x0f6d,0x0000,0x541b
datw	0x0b6e,0x92c5,0x0000,0xe390,0x0000,0x0cdc,0x0000,0x4305
datw	0x2e72,0xe9a4,0x0001,0x2e40,0x0000,0x2757,0x0000,0x71e4
datw	0x3254,0x18f3,0x0000,0xd7ae,0x0000,0x3bbc,0x0000,0x9b2b
datw	0x1bf8,0x5a58,0x0000,0xdd62,0x0000,0x2058,0x0000,0x00a8
datw	0x0ce0,0xbdf1,0x0002,0xecec,0x0000,0x0466,0x0002,0xa7e9
datw	0x2dbe,0x8d02,0x0000,0x402d,0x0000,0xb679,0x0000,0x39bd
datw	0x2d3d,0xc373,0x0000,0x6ce3,0x0000,0x6a5d,0x0000,0x36fc
datw	0x10c1,0xf341,0x0002,0x7974,0x0000,0x06c5,0x0001,0xc4fd
datw	0x2101,0x4e3e,0x0003,0xd980,0x0000,0x0892,0x0003,0x433e
datw	0x0031,0x8552,0x0001,0x5b08,0x0000,0x0024,0x0000,0xb832
datw	0x29a4,0x2042,0x0002,0x2048,0x0000,0x1395,0x0001,0xfe5a
datw	0x3f50,0xf2fe,0x0003,0x1f33,0x0000,0x1448,0x0000,0x30a6
datw	0x208b,0x4a58,0x0001,0x626d,0x0000,0x1781,0x0000,0xe66b
datw	0x3d65,0xb1d7,0x0002,0x3078,0x0000,0x1c0b,0x0000,0x7caf
datw	0x1f86,0x8a44,0x0001,0xfafa,0x0000,0x0feb,0x0000,0x80c6
datw	0x281c,0x9a7b,0x0000,0x6dbb,0x0000,0x5d94,0x0000,0x3b5f
datw	0x041d,0x3fd0,0x0001,0x2815,0x0000,0x038e,0x0000,0xc52a
datw	0x2520,0x4d5f,0x0003,0x3d30,0x0000,0x0b76,0x0001,0x093f
datw	0x12d9,0xf3e7,0x0000,0x4e45,0x0000,0x3da8,0x0000,0x259f
datw	0x3f44,0xda11,0x0001,0x2173,0x0000,0x37f5,0x0000,0x2202
datw	0x1e51,0xdf06,0x0000,0xb951,0x0000,0x29e2,0x0000,0x4c84
datw	0x3a7b,0xf1f4,0x0000,0x9619,0x0000,0x63bf,0x0000,0x4a4d
datw	0x05ed,0xd411,0x0001,0xbd74,0x0000,0x0368,0x0000,0x80f1
datw	0x1b17,0x77d1,0x0003,0x01de,0x0000,0x0902,0x0000,0xa615
datw	0x31e5,0x3171,0x0002,0x1762,0x0000,0x17db,0x0001,0x629b
datw	0x1670,0x93a4,0x0002,0xea85,0x0000,0x07b1,0x0002,0xcaaf
datw	0x286f,0xca85,0x0003,0x1a3b,0x0000,0x0d08,0x0001,0xf9ad
datw	0x1d2d,0xa61d,0x0000,0xd17b,0x0000,0x23a8,0x0000,0x5c65
datw	0x2856,0x7fe5,0x0000,0xb6a1,0x0000,0x388b,0x0000,0x1e7a
datw	0x1285,0x7115,0x0002,0xcf3a,0x0000,0x0697,0x0001,0xd9df
datw	0x30c4,0x5d2b,0x0000,0x6cc7,0x0000,0x72c5,0x0000,0x0a08
datw	0x2f52,0xdf11,0x0001,0xfe21,0x0000,0x17bf,0x0001,0x4d72
datw	0x09a8,0xc730,0x0001,0x0bdd,0x0000,0x093b,0x0000,0x4641
datw	0x2a86,0xbb8d,0x0001,0xc853,0x0000,0x17db,0x0000,0xe78c
datw	0x3111,0xf20e,0x0002,0x15e8,0x0000,0x1787,0x0000,0x8cb6
datw	0x24b5,0x6d74,0x0001,0x673d,0x0000,0x1a28,0x0001,0x19ec
datw	0x13ad,0xd13a,0x0001,0x5a60,0x0000,0x0e8b,0x0000,0x7f1a
datw	0x3e4a,0x9df2,0x0001,0x4d50,0x0000,0x2fd7,0x0000,0xffc2
datw	0x0e8c,0x557e,0x0003,0xb047,0x0000,0x03f1,0x0002,0x8da7
datw	0x2c18,0x8299,0x0002,0xdd4b,0x0000,0x0f64,0x0002,0xac4d
datw	0x1691,0x2c79,0x0003,0x47c4,0x0000,0x06e1,0x0000,0x8135
datw	0x17e8,0xabf8,0x0000,0x66c7,0x0000,0x3b8d,0x0000,0x335d
datw	0x1fd0,0xfa18,0x0002,0x1708,0x0000,0x0f39,0x0000,0x6150
datw	0x2f3b,0x837b,0x0001,0x8178,0x0000,0x1f5e,0x0000,0x716b
datw	0x1162,0xd2db,0x0001,0x56cf,0x0000,0x0cfb,0x0001,0x01e6
datw	0x011e,0xf026,0x0002,0x43bf,0x0000,0x007e,0x0001,0x9824
datw	0x306a,0x81ae,0x0003,0xc019,0x0000,0x0ce8,0x0003,0x3f06
datw	0x20b8,0x54d1,0x0000,0xa40d,0x0000,0x330f,0x0000,0x210e
datw	0x04eb,0x69de,0x0001,0xf6d5,0x0000,0x0281,0x0000,0x5e89
datw	0x17ff,0x4ce5,0x0000,0xb98b,0x0000,0x211c,0x0000,0x16b1
datw	0x10eb,0x7106,0x0003,0x92c9,0x0000,0x04bc,0x0000,0x816a
datw	0x30e9,0x23ab,0x0001,0x27af,0x0000,0x2a58,0x0000,0xc983
datw	0x3fa9,0x8e3a,0x0002,0x59a5,0x0000,0x1b16,0x0001,0x730c
datw	0x11be,0xb88e,0x0003,0xab8a,0x0000,0x04d5,0x0002,0xd6bc
#
# end of data
datw	0,0,0,0,0,0,0,0
