古いCPUの話題が多いです

 リンクその5:影のある積み木プロジェクト(MZ-80B編)


;Cube with shadow for MZ-80B ver 1.31 (C) 1985, 1990, 1991, 2008, 2017
; by someone

org &12a0, &12a0

maxcubes=500 ;立方体の最大個数 +++++++

jp coldstart
jp hotstart

coldstart:
call coldinit
hotstart:
call hotinit
call title
ld [ml_spwork],sp
mainloop:
call clsc
call clsv

ld hl,mlm_busy00
ld de,&d000
call ml_indicatebusy

call nc_inverse

ld a,[ncb_mode]
and a
call z,ml_wire

ld a,[ncb_mode]
dec a
call p,ml_solid

ld hl,mlm_busy01
ld de,&d000
call ml_indicatebusy

call keywait
ml10:
cp 11
jp z,mlkeybrk

cp '2'
jr z,mlkey2
cp '4'
jr z,mlkey4
cp '6'
jr z,mlkey6
cp '8'
jr z,mlkey8
cp '1'
jr z,mlkey1
cp '3'
jr z,mlkey3

cp 'W'
jr z,mlkeyw
cp 'Z'
jr z,mlkeyz
cp 'A'
jr z,mlkeya
cp 'S'
jr z,mlkeys
cp ' '
jr z,mlkeyspc
cp 9
jr z,mlkeytab

cp '0'
jr z,mlkey0

cp 'E'
jr z,mlkeye

cp 'M'
jp z,mlkeym

cp 'R'
jp z,mlkeyr

jp mainloop

mlkey8: xor a
ld hl,1+2*256
jr mlroll

mlkey2: ld a,&ff
ld hl,1+2*256
jr mlroll

mlkey6: ld a,&ff
ld hl,2+0*256
jr mlroll

mlkey4: xor a
ld hl,2+0*256
jr mlroll

mlkey1: ld a,&ff
ld hl,0+1*256
jr mlroll

mlkey3: xor a
ld hl,0+1*256
jr mlroll

mlroll: ld [ncb_s],a
ld [ncb_indx],hl
call nc_rolling
jp mainloop

mlkeyw: ld hl,&0001
jr mlforward

mlkeyz: ld hl,&ff01
jr mlforward

mlkeya: ld hl,&ff00
jr mlforward

mlkeys: ld hl,&0000
jr mlforward

mlkeyspc:
ld hl,&0002
jr mlforward

mlkeytab:
ld hl,&ff02
jr mlforward

mlforward:
ld a,h
ld [ncb_s],a
ld a,l
ld [ncb_i],a
call mlmove
jp mainloop

mlkey0: call ml_insdel
call ml_setrelation
jp mainloop

mlkeye: ld hl,mlm_00
call ml_inquire
cp 'Y'
jp nz,mainloop
call nc_reseteye
jp nc,mainloop
ld hl,mlm_01
call ml_inquire
cp 'Y'
call z,nc_initx0
jp mainloop

mlkeym: ld a,[ncb_mode]
inc a
cp 2+1
jr nz,mlkeym00
xor a
mlkeym00:
ld [ncb_mode],a
jp mainloop

ml_inquire: ;hl=メッセージ文字列 --> a=キー入力待ち
ld a,&00 ;vramを表示しない
out [&f4],a

call crlf
call message
call crlf

call keywait

push af
ld a,&02 ;vramを表示する
out [&f4],a
pop af

ret

mlm_00: db 'Fixing eye direction ?(Y/N)',13
mlm_01: db 'Fixing is failed. Reset eye direction ?(Y/N)',13
mlm_10: db 'Save data=',13
mlm_20: db 'Setting current eye direction --> ray direction ?(Y/N)',13
mlm_title: db 'Cube with shadow for MZ-80B ver 1.31',13
db '(C) 1985, 1990, 1991, 2008, 2017',13
db ' by someone',13
db 13
db 'Key function:',13
db ' 2,4,6,8,1,3: Roll eye direction',13
db ' W,Z,A,S,Space,Tab: Move',13
db ' 0: Insert or delete cube',13
db ' E: Fix eye direction',13
db ' M: Change display mode',13
db ' R: Set ray direction',13
db ' BREAK: Quit',13
db 13
db 'Press any key to start',13
db 0
mlm_busy00: db 'busy',13
mlm_busy01: db ' ',13

mlkeyr:
ld hl,mlm_20
call ml_inquire
cp 'Y'
call z,setraydirection
jp mainloop

setraydirection:
;視線方向=(x0[0][2], x0[1][2], x0[2][2])
;[ncf_ray_0,1,2]に視線方向を設定する
ld hl,ncf_x0_02
ld de,ncf_ray_0
call mtom

ld hl,ncf_x0_12
ld de,ncf_ray_1
call mtom

ld hl,ncf_x0_22
ld de,ncf_ray_2
call mtom

ret

ml_indicatebusy: ;busyインディケーター表示
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ml_indi00:
ld a,[hl]
cp 13
jr z,ml_indi01
ld [de],a
inc hl
inc de
jr ml_indi00
ml_indi01:
in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

ret

title:
ld hl,mlm_title
title00:
ld a,[hl]
and a
jr z,title10
call message
call crlf
inc hl
jr title00
title10:
call keywait
cp 11
ret nz
;
mlkeybrk:
ld a,&00 ;vramを表示しない
out [&f4],a

call crlf
ld hl,mlm_10
call message
ld hl,savedata_start
call hex
ld a,'-'
call _pcha
ld hl,savedata_end
call hex
call crlf
jp _monitor

mlmove:
ld hl,nci_eye
ld de,nci_e0
ld bc,2*3
ldir

call nc_forwarding
call nc_forwarding

ld hl,nci_e0
ld de,nci_eye
ld bc,2*3
ldir

ld hl,nci_eye_0
res 0,[hl]
ld hl,nci_eye_1
res 0,[hl]
ld hl,nci_eye_2
res 0,[hl]

ret

ml_insdel:
ld a,&00
ld [ncb_s],a
ld a,&02
ld [ncb_i],a
ld hl,nci_eye
ld de,nci_e0
ld bc,2*3
ldir
call nc_forwarding
call nc_forwarding
;
ml_insdel00: ;[nci_e0,e1,e2]の座標を追加、または削除する
ld bc,[nci_number]
ld ix,nci_cubes
jr ml_id00
ml_id01:
ld hl,[nci_e0]
ld e,[ix+0]
ld d,[ix+1]
and a
sbc hl,de
jr nz,ml_id02

ld hl,[nci_e1]
ld e,[ix+2]
ld d,[ix+3]
and a
sbc hl,de
jr nz,ml_id02

ld hl,[nci_e2]
ld e,[ix+4]
ld d,[ix+5]
and a
sbc hl,de
jr z,ml_id20 ;座標が見つかった
ml_id02:
ld de,2*3
add ix,de
dec bc
ml_id00:
ld a,b
or c
jr nz,ml_id01
;座標が見つからなかった

ld hl,[nci_number]
ld de,maxcubes
and a
sbc hl,de
ret z ;これ以上記憶できない

ld hl,nci_e0
push ix
pop de
ld bc,2*3
ldir

ld hl,[nci_number]
inc hl
jr ml_id10

ml_id21:
exx
push ix
pop hl
ld bc,2*3
add hl,bc
push ix
pop de
ldir
exx
ld de,2*3
add ix,de
ml_id20:
dec bc
ld a,b
or c
jr nz,ml_id21

ld hl,[nci_number]
dec hl
ml_id10:
ld [nci_number],hl

ret

ml_setrelation: ;各面について、隣と接する面であるか事前に調べる
ld hl,[nci_number]

ld a,h
or l
ret z

ld b,h
ld c,l
add hl,hl ;*2
add hl,bc ;*3
add hl,hl ;*6
ld b,h
ld c,l
ld hl,ncb_relation
ld de,ncb_relation+1
ld [hl],0
dec bc
ldir

ld hl,nci_cubes
ld iy,ncb_relation
ld bc,[nci_number]
ml_chkr00:
push bc
ld de,nci_current
ld bc,2*3
ldir
pop bc
dec bc
ld a,b
or c
jp z,ml_chkr01

ld [nci_work10],hl
ld [nci_work11],bc

ld a,[iy+0] ;z+
and a
jr nz,ml_chkr31
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+4]
inc hl
inc hl
ld [nci_target+4],hl
call ml_chkr10
sbc a,a
ld [iy+0],a
jr z,ml_chkr31
ld de,-nci_cubes+ncb_relation+1 ;相手はz-
add hl,de
ld [hl],&ff
ml_chkr31:
ld a,[iy+1] ;z-
and a
jr nz,ml_chkr32
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+4]
dec hl
dec hl
ld [nci_target+4],hl
call ml_chkr10
sbc a,a
ld [iy+1],a
jr z,ml_chkr32
ld de,-nci_cubes+ncb_relation+0 ;相手はz+
add hl,de
ld [hl],&ff
ml_chkr32:
ld a,[iy+2] ;y+
and a
jr nz,ml_chkr33
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+2]
inc hl
inc hl
ld [nci_target+2],hl
call ml_chkr10
sbc a,a
ld [iy+2],a
jr z,ml_chkr33
ld de,-nci_cubes+ncb_relation+3 ;相手はy-
add hl,de
ld [hl],&ff
ml_chkr33:
ld a,[iy+3] ;y-
and a
jr nz,ml_chkr34
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+2]
dec hl
dec hl
ld [nci_target+2],hl
call ml_chkr10
sbc a,a
ld [iy+3],a
jr z,ml_chkr34
ld de,-nci_cubes+ncb_relation+2 ;相手はy+
add hl,de
ld [hl],&ff
ml_chkr34:
ld a,[iy+4] ;x+
and a
jr nz,ml_chkr35
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+0]
inc hl
inc hl
ld [nci_target+0],hl
call ml_chkr10
sbc a,a
ld [iy+4],a
jr z,ml_chkr35
ld de,-nci_cubes+ncb_relation+5 ;相手はx-
add hl,de
ld [hl],&ff
ml_chkr35:
ld a,[iy+5] ;x-
and a
jr nz,ml_chkr36
ld hl,nci_current
ld de,nci_target
ld bc,2*3
ldir
ld hl,[nci_target+0]
dec hl
dec hl
ld [nci_target+0],hl
call ml_chkr10
sbc a,a
ld [iy+5],a
jr z,ml_chkr36
ld de,-nci_cubes+ncb_relation+4 ;相手はx+
add hl,de
ld [hl],&ff
ml_chkr36:

ld hl,[nci_work10]
ld bc,[nci_work11]
ml_chkr01:
ld de,6
add iy,de

ld a,b
or c
jp nz,ml_chkr00

ret

ml_chkr10: ;[nci_target〜]と一致する座標を探す
;cf=0のとき、見つからなかった
;cf=1のとき、見つかった
ld bc,[nci_work11]
ld hl,[nci_work10]
ml_chkr20:
push bc
push hl

ld b,2*3
ld de,nci_target
ml_chkr21:
ld a,[de]
cp [hl]
jr nz,ml_chkr22
inc de
inc hl
djnz ml_chkr21

;targetと座標が一致する立方体が見つかったときは、cf=1,hl=nci_cubesへのポインタ
pop hl
pop bc
scf
ret ;cf=1
ml_chkr22:
pop hl
pop bc
ld de,2*3
add hl,de
dec bc
ld a,b
or c
jr nz,ml_chkr20

and a
ret ;cf=0

ml_offset0: dw -1,-1,+1, -1,+1,+1, +1,+1,+1, +1,-1,+1
ml_offset1: dw -1,-1,-1, -1,+1,-1, +1,+1,-1, +1,-1,-1
ml_offset2: dw -1,+1,-1, -1,+1,+1, +1,+1,+1, +1,+1,-1
ml_offset3: dw -1,-1,-1, -1,-1,+1, +1,-1,+1, +1,-1,-1
ml_offset4: dw +1,-1,-1, +1,-1,+1, +1,+1,+1, +1,+1,-1
ml_offset5: dw -1,-1,-1, -1,-1,+1, -1,+1,+1, -1,+1,-1
ml_xyz: dw 0,0,0, 0,0,0, 0,0,0, 0,0,0
ml_xyz2: dw 0,0,0, 0,0,0, 0,0,0, 0,0,0
ml_xy0: db 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
ml_xy1: db 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
ml_spwork: dw 0
ml_center0: dw 0,0,+1
ml_center1: dw 0,0,-1
ml_center2: dw 0,+1,0
ml_center3: dw 0,-1,0
ml_center4: dw +1,0,0
ml_center5: dw -1,0,0

ncf_ezdivzoom: db 0,0,0,0
ncf_px: db 0,0,0,0
ncf_py: db 0,0,0,0
ncf_pz: db 0,0,0,0
nci_ptrstart: dw 0
nci_distance: dw 0
nci_current: dw 0,0,0
nci_currentcenter: dw 0,0,0
ncb_currentsurface: db 0
nci_currentphase: dw 0
nci_target: dw 0,0,0
ncb_currentsurface2: db 0
nci_currentphase2: dw 0
ncb_exclude: db 0,0,0,0,0,0

float4: db &42,&00,&00,&80 ;4

sh80: ;hl=ml_center0〜5
; --> cf=0ならばその面番号は影の原因となる、cf=1ならばスキップする
ld de,ml_xyz
ld bc,2*3
ldir

ld hl,ncf_ray
ld de,ncf_work10
ld bc,4*3
ldir

ld hl,ncf_work10+4*0
push hl
call mtox
ld hl,float4
call mtox
call div
pop hl
call xtom
ld hl,ncf_work10+4*1
push hl
call mtox
ld hl,float4
call mtox
call div
pop hl
call xtom
ld hl,ncf_work10+4*2
push hl
call mtox
ld hl,float4
call mtox
call div
pop hl
call xtom

;[center0〜5]の座標に光源ベクトル[ncf_ray_0,1,2]/4を加え、その座標を[ncf_work00〜]に入れる
ld hl,[ml_xyz+2*0]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_work10+4*0
call mtox
call sb
ld hl,ncf_work00+4*0
call xtom
ld hl,[ml_xyz+2*1]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_work10+4*1
call mtox
call sb
ld hl,ncf_work00+4*1
call xtom
ld hl,[ml_xyz+2*2]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_work10+4*2
call mtox
call sb
ld hl,ncf_work00+4*2
call xtom

;[ncf_work00〜]の座標がx=-1〜+1,y=-1〜+1,z=-1〜+1ならばcf=1
ld de,ncf_work00+4*0
ld hl,floatm1
call fcp
ccf
ret nc
ld de,float1
ld hl,ncf_work00+4*0
call fcp
ccf
ret nc

ld de,ncf_work00+4*1
ld hl,floatm1
call fcp
ccf
ret nc
ld de,float1
ld hl,ncf_work00+4*1
call fcp
ccf
ret nc

ld de,ncf_work00+4*2
ld hl,floatm1
call fcp
ccf
ret nc
ld de,float1
ld hl,ncf_work00+4*2
call fcp
ccf
ret

ml_solid: ;すべての立方体をソリッドで表示する
ld a,[ncb_mode]
cp 2
jr nz,sh90

;影モード
ld hl,ml_center0 ;z+
call sh80
sbc a,a
ld [ncb_exclude+0],a

ld hl,ml_center1 ;z-
call sh80
sbc a,a
ld [ncb_exclude+1],a

ld hl,ml_center2 ;y+
call sh80
sbc a,a
ld [ncb_exclude+2],a

ld hl,ml_center3 ;y-
call sh80
sbc a,a
ld [ncb_exclude+3],a

ld hl,ml_center4 ;x+
call sh80
sbc a,a
ld [ncb_exclude+4],a

ld hl,ml_center5 ;x-
call sh80
sbc a,a
ld [ncb_exclude+5],a
sh90:
ld hl,[nci_number]
ld a,h
or l
ret z

ld b,h
ld c,l
add hl,hl ;*2
add hl,bc ;*3
add hl,hl ;*6
ld de,nci_cubes
add hl,de
ld [nci_ptrstart],hl ;ポインタの配列
ld de,0 ;ポインタは 0,2,4,6 ...のようになっている
ml_s00:
ld [hl],e
inc hl
ld [hl],d
inc hl
inc de
inc de
dec bc
ld a,b
or c
jr nz,ml_s00

ld [nci_distance],hl ;視点[ncf_px,py,pz]からの距離(4バイト実数)の配列

ld hl,ncf_ez
call mtox
ld hl,ncf_zoom
call mtox
call div
ld hl,ncf_ezdivzoom
call xtom

;視線方向=(x0[0][2], x0[1][2], x0[2][2])
ld bc,0+2*256
call nc_leax0cb
call mtox
ld hl,ncf_ezdivzoom
call mtox
call mul
ld hl,[nci_eye_0]
call itof16
ld hl,acc1
call mtox
call ad
ld hl,ncf_px
call xtom

ld bc,1+2*256
call nc_leax0cb
call mtox
ld hl,ncf_ezdivzoom
call mtox
call mul
ld hl,[nci_eye_1]
call itof16
ld hl,acc1
call mtox
call ad
ld hl,ncf_py
call xtom

ld bc,2+2*256
call nc_leax0cb
call mtox
ld hl,ncf_ezdivzoom
call mtox
call mul
ld hl,[nci_eye_2]
call itof16
ld hl,acc1
call mtox
call ad
ld hl,ncf_pz
call xtom

;視点[ncf_px,py,pz]からの距離を設定する
ld hl,nci_cubes
ld de,[nci_distance]
ld bc,[nci_number]
ml_s10:
push bc
push de

ld de,nci_current
ld bc,2*3
ldir
push hl

ld hl,[nci_current+0]
call itof16
ld hl,ncf_px
ld de,acc2
call mtom
call fsub ;x-px
ld hl,acc1
push hl
call mtox
pop hl
call mtox
call mul ;(x-px)*(x-px)

ld hl,[nci_current+2]
call itof16
ld hl,ncf_py
ld de,acc2
call mtom
call fsub ;y-py
ld hl,acc1
push hl
call mtox
pop hl
call mtox
call mul ;(y-py)*(y-py)

ld hl,[nci_current+4]
call itof16
ld hl,ncf_pz
ld de,acc2
call mtom
call fsub ;z-pz
ld hl,acc1
push hl
call mtox
pop hl
call mtox
call mul ;(z-pz)*(z-pz)

call ad
call ad

call sqr ;sqr( (x-px)^2+(y-py)^2+(z-pz)^2 )

pop hl
pop de

push de
push hl
ex de,hl
call xtom
pop hl
pop de
inc de
inc de
inc de
inc de

pop bc
dec bc
ld a,b
or c
jp nz,ml_s10

call ml_sort

ld hl,[nci_ptrstart]
ld bc,[nci_number]
ml_s20:
push bc
ld e,[hl]
inc hl
ld d,[hl]
inc hl
push hl

ex de,hl
ld [nci_currentptr],hl
ld d,h
ld e,l
add hl,hl ;*4
add hl,de ;*6
push hl
ld de,nci_cubes
add hl,de
ld de,nci_current
ld bc,2*3
ldir
pop hl
ld de,ncb_relation
add hl,de
ld de,ncb_currentrelation
ld bc,6
ldir

ld a,[ncb_currentrelation+0] ;z+
and a
jr nz,ml_s21
ld a,2
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+4]
inc hl
ld [nci_currentcenter+4],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s21

ld hl,ml_offset0
call ml_draw
ml_s21:
ld a,[ncb_currentrelation+1] ;z-
and a
jr nz,ml_s22
ld a,2
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+4]
dec hl
ld [nci_currentcenter+4],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s22

ld hl,ml_offset1
call ml_draw
ml_s22:
ld a,[ncb_currentrelation+2] ;y+
and a
jr nz,ml_s23
ld a,1
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+2]
inc hl
ld [nci_currentcenter+2],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s23

ld hl,ml_offset2
call ml_draw
ml_s23:
ld a,[ncb_currentrelation+3] ;y-
and a
jr nz,ml_s24
ld a,1
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+2]
dec hl
ld [nci_currentcenter+2],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s24

ld hl,ml_offset3
call ml_draw
ml_s24:
ld a,[ncb_currentrelation+4] ;x+
and a
jr nz,ml_s25
xor a
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+0]
inc hl
ld [nci_currentcenter+0],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s25

ld hl,ml_offset4
call ml_draw
ml_s25:
ld a,[ncb_currentrelation+5] ;x-
and a
jr nz,ml_s26
xor a
ld [ncb_currentsurface],a
ld hl,nci_current
ld de,nci_currentcenter
ld bc,2*3
ldir
ld hl,[nci_currentcenter+0]
dec hl
ld [nci_currentcenter+0],hl
ld [nci_currentphase],hl

call ml_checkinner
jp c,ml_s26

ld hl,ml_offset5
call ml_draw
ml_s26:
pop hl
pop bc
dec bc
ld a,b
or c
jp nz,ml_s20

ret

ncb_currentrelation: db 0,0,0,0,0,0
ncb_currentrelation2: db 0,0,0,0,0,0
nci_work10: dw 0
nci_work11: dw 0
nci_work20: dw 0
nci_work21: dw 0
nci_work3s: dw 0
nci_work3e: dw 0
nci_work3l: dw 0
nci_work3dy: dw 0

ml_draw: ;[nci_current]に[hl+0,2,4〜]で示される4つのオフセットを足して、表示座標を計算
;表示を行う
call keycheck ;+++++++

ld de,ml_xyz+0
ld [nci_work20],de
ld iy,ml_xy0
ld b,4
ml_dr00:
push bc
push hl

push hl
pop ix

ld hl,[nci_current+2*0] ;x
ld e,[ix+0]
ld d,[ix+1]
add hl,de
ld [nci_xx],hl
ex de,hl
ld hl,[nci_work20]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work20],hl

ld hl,[nci_current+2*1] ;y
ld e,[ix+2]
ld d,[ix+3]
add hl,de
ld [nci_yy],hl
ex de,hl
ld hl,[nci_work20]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work20],hl

ld hl,[nci_current+2*2] ;z
ld e,[ix+4]
ld d,[ix+5]
add hl,de
ld [nci_zz],hl
ex de,hl
ld hl,[nci_work20]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work20],hl

push iy
call nc_setdot
pop iy
jr nc,ml_dr01

pop af
pop af
ret
ml_dr01:
ld hl,[nci_dx]
ld [iy+0],l
ld [iy+1],h
ld hl,[nci_dy]
ld [iy+2],l
ld [iy+3],h
ld de,4
add iy,de

pop hl
ld de,2*3
add hl,de
pop bc
dec b
jp nz,ml_dr00

ld a,[ncb_mode]
cp 2
jp z,shadow ;影モード

ld a,[ncb_currentsurface]
ld [gradation],a
call setgradbase
sh11:
call sethlinenormal

;0-1-2
ld hl,[ml_xy0+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy0+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy0+4*1+0]
ld [p3_x2],hl
ld hl,[ml_xy0+4*1+2]
ld [p3_y2],hl
ld hl,[ml_xy0+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy0+4*2+2]
ld [p3_y3],hl
call p3_polygon

;0-3-2
ld hl,[ml_xy0+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy0+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy0+4*3+0]
ld [p3_x2],hl
ld hl,[ml_xy0+4*3+2]
ld [p3_y2],hl
ld hl,[ml_xy0+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy0+4*2+2]
ld [p3_y3],hl
call p3_polygon

ret

sethlinenormal: ;ポリゴンを通常のvramに表示する準備
ld hl,&e000 ;vram address
ld [hline_code3+1],hl
ld hl,0
ld [dr_miny],hl
ld hl,200
ld [dr_maxy],hl
ld hl,hlineskip00
ld [hline_code40+1],hl
ld hl,hlineskip10
ld [hline_code41+1],hl
ret

sethlinespecialvram: ;ポリゴンを仮想vramに表示する準備
ld hl,vvram ;仮想vram
ld [hline_code3+1],hl

ld hl,hlineskip01
ld [hline_code40+1],hl
ld hl,hlineskip11
ld [hline_code41+1],hl
ret

shadow: ;影モード
ld a,[ncb_currentsurface]
ld hl,[nci_currentphase]
call getabcd

;aa*px+bb*py+cc*pz+ddの符号を取る
ld hl,ncf_aa
call mtox
ld hl,ncf_px
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,ncf_py
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,ncf_pz
call mtox
call mul
ld hl,ncf_dd
call mtox
call ad
call ad
call ad
ld hl,acc1
call xtom
call sh00 ;符号を取る

and a
ret z ;視点が表示しようとする面上にあるときは、何もしない

ld [ncb_work00],a ;表示する面に対する視点の符号

;表示する面の中心座標に光源ベクトル[ncf_ray_0,1,2]を加え、その座標を[ncf_work00〜]に入れる
ld hl,[nci_currentcenter+2*0]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_0
call mtox
call ad
ld hl,ncf_work00+4*0
call xtom
ld hl,[nci_currentcenter+2*1]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_1
call mtox
call ad
ld hl,ncf_work00+4*1
call xtom
ld hl,[nci_currentcenter+2*2]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_2
call mtox
call ad
ld hl,ncf_work00+4*2
call xtom

;aa*workx+bb*worky+cc*workz+ddの符号を取る
ld hl,ncf_aa
call mtox
ld hl,ncf_work00+4*0
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,ncf_work00+4*1
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,ncf_work00+4*2
call mtox
call mul
ld hl,ncf_dd
call mtox
call ad
call ad
call ad
ld hl,acc1
call xtom
call sh00 ;符号を取る

and a ;光源ベクトルを足しても表示面上にあるときは、全面を影とする
jp z,sh10

ld [ncb_work01],a ;表示する面に対する光源ベクトルを加算した座標の符号

ld b,a
ld a,[ncb_work00] ;表示する面に対する視点の符号
cp b
jp z,sh10 ;光源ベクトルを足したものと視点が同符号の時は、全面を影とする

;ここからは、全面が影ではない処理

xor a ;仮想vramを&ffで塗る
ld [gradation],a
call setgradbase

call sethlinespecialvram

;ポリゴンのy座標の最大値を求める
ld hl,[ml_xy0+4*0+2]
ld de,[ml_xy0+4*1+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy00
ex de,hl
mlmaxy00:
ld de,[ml_xy0+4*2+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy01
ex de,hl
mlmaxy01:
ld de,[ml_xy0+4*3+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy02
ex de,hl
mlmaxy02:
inc hl
ld a,h
and a
ret m ;最大値が負のときは、何もしない
ld de,200
push hl
and a
sbc hl,de
pop hl
jr c,mlmaxy11
ex de,hl ;hl=200
mlmaxy11:
ld [dr_maxy],hl

;ポリゴンのy座標の最小値を求める
ld hl,[ml_xy0+4*0+2]
ld de,[ml_xy0+4*1+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy00
ex de,hl
mlminy00:
ld de,[ml_xy0+4*2+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy01
ex de,hl
mlminy01:
ld de,[ml_xy0+4*3+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy02
ex de,hl
mlminy02:
ld a,h
and a
jp p,mlminy10
;負数のとき
ld hl,0
jr mlminy11
mlminy10: ;正数のとき
ld de,200
and a
sbc hl,de
ret nc ;最小値が200以上のときは、何もしない
add hl,de
mlminy11:
ld [dr_miny],hl

;[dr_miny]〜[dr_maxy]-1までの領域が描画の対象となる

ld hl,[dr_maxy]
ld de,[dr_miny]
and a
sbc hl,de
ld [nci_work3dy],hl

ld hl,[dr_miny]
ld d,h
ld e,l
add hl,hl ;*2
add hl,hl ;*4
add hl,de ;*5
add hl,hl ;*10
add hl,hl ;*20
add hl,hl ;*40
ld [nci_work3s],hl

push hl

ld hl,[dr_maxy]
ld d,h
ld e,l
add hl,hl ;*2
add hl,hl ;*4
add hl,de ;*5
add hl,hl ;*10
add hl,hl ;*20
add hl,hl ;*40
ld [nci_work3e],hl

pop de

and a
sbc hl,de
ld [nci_work3l],hl

;vvramの該当領域をクリアする
ld hl,[nci_work3s]
ld de,vvram
add hl,de
ld d,h
ld e,l
inc de
ld bc,[nci_work3l]
dec bc
ld [hl],0
ldir

;vvram2の該当領域をクリアする
ld hl,[nci_work3s]
ld de,vvram2
add hl,de
ld d,h
ld e,l
inc de
ld bc,[nci_work3l]
dec bc
ld [hl],0
ldir

;0-1-2
ld hl,[ml_xy0+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy0+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy0+4*1+0]
ld [p3_x2],hl
ld hl,[ml_xy0+4*1+2]
ld [p3_y2],hl
ld hl,[ml_xy0+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy0+4*2+2]
ld [p3_y3],hl
call p3_polygon

;0-3-2
ld hl,[ml_xy0+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy0+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy0+4*3+0]
ld [p3_x2],hl
ld hl,[ml_xy0+4*3+2]
ld [p3_y2],hl
ld hl,[ml_xy0+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy0+4*2+2]
ld [p3_y3],hl
call p3_polygon

;個々の影をvvram2に塗る

xor a ;仮想vram2を&ffで塗る
ld [gradation],a
call setgradbase

ld hl,vvram2 ;仮想vram2
ld [hline_code3+1],hl

ld hl,0
ld bc,[nci_number]
sh40:
push bc
push hl

call keycheck ;+++++++

ld de,[nci_currentptr]
and a
sbc hl,de
jp z,sh41 ;自分自身の影は表示しない
add hl,de

ld d,h
ld e,l
add hl,hl ;*4
add hl,de ;*6
push hl
ld de,nci_cubes
add hl,de
ld de,nci_current2
ld bc,2*3
ldir
pop hl
ld de,ncb_relation
add hl,de
ld de,ncb_currentrelation2
ld bc,6
ldir

;current2は影の原因となりうる立方体の中心座標
;aa*current2x+bb*current2y+cc*current2z+ddの符号を取る
ld hl,ncf_aa
call mtox
ld hl,[nci_current2+2*0]
call itof16
ld hl,acc1
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,[nci_current2+2*1]
call itof16
ld hl,acc1
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,[nci_current2+2*2]
call itof16
ld hl,acc1
call mtox
call mul
ld hl,ncf_dd
call mtox
call ad
call ad
call ad
ld hl,acc1
call xtom
call sh00 ;符号を取る

ld b,a

ld a,[ncb_work00] ;表示する面に対する視点の符号
cp b
jp nz,sh41 ;視点と対象立方体が表示面の反対側にあるので、なにもしない

;z+
ld a,[ncb_exclude+0]
and a
jr nz,sh71
ld a,[ncb_currentrelation2+0] ;隣と接している面は、影の原因としない
and a
jr nz,sh71
ld a,2
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+4]
inc hl
ld [nci_currentcenter2+4],hl
ld [nci_currentphase2],hl
ld hl,ml_offset0
call sh50_draw
sh71:
;z-
ld a,[ncb_exclude+1]
and a
jr nz,sh72
ld a,[ncb_currentrelation2+1]
and a
jr nz,sh72
ld a,2
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+4]
dec hl
ld [nci_currentcenter2+4],hl
ld [nci_currentphase2],hl
ld hl,ml_offset1
call sh50_draw
sh72:
;y+
ld a,[ncb_exclude+2]
and a
jr nz,sh73
ld a,[ncb_currentrelation2+2]
and a
jr nz,sh73
ld a,1
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+2]
inc hl
ld [nci_currentcenter2+2],hl
ld [nci_currentphase2],hl
ld hl,ml_offset2
call sh50_draw
sh73:
;y-
ld a,[ncb_exclude+3]
and a
jr nz,sh74
ld a,[ncb_currentrelation2+3]
and a
jr nz,sh74
ld a,1
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+2]
dec hl
ld [nci_currentcenter2+2],hl
ld [nci_currentphase2],hl
ld hl,ml_offset3
call sh50_draw
sh74:
;x+
ld a,[ncb_exclude+4]
and a
jr nz,sh75
ld a,[ncb_currentrelation2+4]
and a
jr nz,sh75
xor a
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+0]
inc hl
ld [nci_currentcenter2+0],hl
ld [nci_currentphase2],hl
ld hl,ml_offset4
call sh50_draw
sh75:
;x-
ld a,[ncb_exclude+5]
and a
jr nz,sh76
ld a,[ncb_currentrelation2+5]
and a
jr nz,sh76
xor a
ld [ncb_currentsurface2],a
ld hl,nci_current2
ld de,nci_currentcenter2
ld bc,2*3
ldir
ld hl,[nci_currentcenter2+0]
dec hl
ld [nci_currentcenter2+0],hl
ld [nci_currentphase2],hl
ld hl,ml_offset5
call sh50_draw
sh76:

sh41:
pop hl
pop bc

inc hl
inc hl
dec bc
ld a,b
or c
jp nz,sh40

in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ld a,&02
out [&f4],a

;穴をあけ、影でないグラデーション番号を塗る
ld a,[ncb_currentsurface] ;影でないグラデーション番号
ld [gradation],a
call setgradbase

ld ix,[gradation_base]
ld a,[dr_miny]
and 7
ld [sh20_code+2],a

ld hl,vvram
ld bc,[nci_work3s]
add hl,bc
ex de,hl
ld hl,&e000
add hl,bc
exx
ld a,[nci_work3dy]
ld b,a
sh20:
exx

ld b,320/8
sh21:
ld a,[de]
cpl
and [hl]
ld c,a
ld a,[de]
sh20_code:
and [ix+0]
or c
ld [hl],a
inc hl
inc de
djnz sh21

exx

ld a,[sh20_code+2]
inc a
and 7
ld [sh20_code+2],a

djnz sh20

;穴をあけ、影のグラデーション番号を塗る
ld a,[ncb_currentsurface]
add a,3 ;影のグラデーション番号
ld [gradation],a
call setgradbase

ld ix,[gradation_base]
ld a,[dr_miny]
and 7
ld [sh30_code+2],a

ld hl,vvram
ld bc,[nci_work3s]
add hl,bc
ex de,hl
ld hl,&e000
add hl,bc
push bc
exx
pop bc
ld hl,vvram2
add hl,bc
ld a,[nci_work3dy]
ld b,a
sh30:
exx

ld b,320/8
sh31:
ld a,[de]
exx
and [hl]
inc hl
exx
ld c,a
cpl
and [hl]
ld [hl],a
ld a,c
sh30_code:
and [ix+0]
or [hl]
ld [hl],a
inc hl
inc de
djnz sh31

exx

ld a,[sh30_code+2]
inc a
and 7
ld [sh30_code+2],a

djnz sh30

in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

ret

sh00: ;ncf_epsilonを考慮したacc1の符号がaに入る
ld hl,acc1
call sgn
and a
ret z

push af ;1か-1

res 7,[hl] ;abs
ld de,ncf_epsilon
call fcp ;eps-abs acc1
jr c,sh01

;ゼロとみなす
pop af
xor a
ret

sh01: ;絶対値が大きい
pop af
ret

sh10: ;全面を影とする
ld a,[ncb_currentsurface]
add a,3
ld [gradation],a
call setgradbase
jp sh11

sh50_draw:
;[nci_current2]に[hl+0,2,4〜]で示される4つのオフセットを足して、表示座標を計算
;影を表示する
;影が表示される面の座標はint [ml_xyz〜]に4点入っているので、接している点があるか調べる

;hl=offset0〜5
xor a
ld [ncb_work20],a
ld de,ml_xyz2
ld [nci_work21],de
ld iy,ml_xy2
ld b,4
sh500:
push bc
push hl

push hl
pop ix

ld hl,[nci_current2+2*0] ;x
ld e,[ix+0]
ld d,[ix+1]
add hl,de
ld [nci_xx2],hl
ex de,hl
ld hl,[nci_work21]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work21],hl

ld hl,[nci_current2+2*1] ;y
ld e,[ix+2]
ld d,[ix+3]
add hl,de
ld [nci_yy2],hl
ex de,hl
ld hl,[nci_work21]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work21],hl

ld hl,[nci_current2+2*2] ;z
ld e,[ix+4]
ld d,[ix+5]
add hl,de
ld [nci_zz2],hl
ex de,hl
ld hl,[nci_work21]
ld [hl],e
inc hl
ld [hl],d
inc hl
ld [nci_work21],hl

;[nci_xx2,yy2,zz2]と接している点を数える
ld hl,ml_xyz+0
ld c,4
sh510:
push hl

ld de,nci_xx2
ld b,2*3
sh511:
ld a,[de]
inc de
cp [hl]
inc hl
jr nz,sh512
djnz sh511
;座標が一致した
ld hl,ncb_work20
inc [hl]
sh512:
pop hl
ld de,2*3
add hl,de
dec c
jr nz,sh510

push iy
call nc_setshadowdot
pop iy
jr nc,sh501

pop af
pop af
ret
sh501:
ld hl,[nci_dx]
ld [iy+0],l
ld [iy+1],h
ld hl,[nci_dy]
ld [iy+2],l
ld [iy+3],h
ld de,4
add iy,de

pop hl
ld de,2*3
add hl,de
pop bc
dec b
jp nz,sh500

ld a,[ncb_work20]
cp 2
jp nz,sh520
;影の原因となる面と、影を表示される面が2点で接している場合
;[px,py,pz]に対する符号を調べる
ld a,[ncb_currentsurface2]
ld hl,[nci_currentphase2]
call getabcd

;aa*px+bb*py+cc*pz+ddの符号を取る
ld hl,ncf_aa
call mtox
ld hl,ncf_px
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,ncf_py
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,ncf_pz
call mtox
call mul
ld hl,ncf_dd
call mtox
call ad
call ad
call ad
ld hl,acc1
call xtom
call sh00 ;符号を取る
ld [ncb_work10],a

;影の原因となる面の座標に光源ベクトル[ncf_ray_0,1,2]を加え、その座標を[ncf_work00〜]に入れる
ld hl,[ml_xyz2+2*0]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_0
call mtox
call ad
ld hl,ncf_work00+4*0
call xtom
ld hl,[ml_xyz2+2*1]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_1
call mtox
call ad
ld hl,ncf_work00+4*1
call xtom
ld hl,[ml_xyz2+2*2]
call itof16
ld hl,acc1
call mtox
ld hl,ncf_ray_2
call mtox
call ad
ld hl,ncf_work00+4*2
call xtom

;aa*workx+bb*worky+cc*workz+ddの符号を取る
ld hl,ncf_aa
call mtox
ld hl,ncf_work00+4*0
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,ncf_work00+4*1
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,ncf_work00+4*2
call mtox
call mul
ld hl,ncf_dd
call mtox
call ad
call ad
call ad
ld hl,acc1
call xtom
call sh00 ;符号を取る
ld [ncb_work11],a

ld b,a
ld a,[ncb_work10]
cp b

push af
;aa,bb,cc,ddを元に戻す
ld a,[ncb_currentsurface]
ld hl,[nci_currentphase]
call getabcd
pop af

ret nz ;異符号なら、何もしない
sh520:
;ポリゴンのy座標の最大値を求める
ld hl,[ml_xy2+4*0+2]
ld de,[ml_xy2+4*1+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy200
ex de,hl
mlmaxy200:
ld de,[ml_xy2+4*2+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy201
ex de,hl
mlmaxy201:
ld de,[ml_xy2+4*3+2]
push hl
and a
sbc hl,de
pop hl
jp p,mlmaxy202
ex de,hl
mlmaxy202:
inc hl
ld a,h
and a
ret m ;最大値が負のときは、何もしない
ld de,200
push hl
and a
sbc hl,de
pop hl
jr c,mlmaxy211
ex de,hl ;hl=200
mlmaxy211:
ld [dr_maxy2],hl

;ポリゴンのy座標の最小値を求める
ld hl,[ml_xy2+4*0+2]
ld de,[ml_xy2+4*1+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy200
ex de,hl
mlminy200:
ld de,[ml_xy2+4*2+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy201
ex de,hl
mlminy201:
ld de,[ml_xy2+4*3+2]
push hl
and a
sbc hl,de
pop hl
jp m,mlminy202
ex de,hl
mlminy202:
ld a,h
and a
jp p,mlminy210
;負数のとき
ld hl,0
jr mlminy211
mlminy210: ;正数のとき
ld de,200
and a
sbc hl,de
ret nc ;最小値が200以上のときは、何もしない
add hl,de
mlminy211:
ld [dr_miny2],hl

;[dr_miny2]〜[dr_maxy2]-1までの領域が描画の対象となる

;[dr_miny2]〜[dr_maxy2]-1が[dr_miny]〜[dr_maxy]-1の範囲外の時は、何もしない
ld hl,[dr_maxy]
ld de,[dr_miny2]
and a
sbc hl,de
ret m
ld hl,[dr_maxy2]
ld de,[dr_miny]
and a
sbc hl,de
ret m

;0-1-2
ld hl,[ml_xy2+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy2+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy2+4*1+0]
ld [p3_x2],hl
ld hl,[ml_xy2+4*1+2]
ld [p3_y2],hl
ld hl,[ml_xy2+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy2+4*2+2]
ld [p3_y3],hl
call p3_polygon

;0-3-2
ld hl,[ml_xy2+4*0+0]
ld [p3_x1],hl
ld hl,[ml_xy2+4*0+2]
ld [p3_y1],hl
ld hl,[ml_xy2+4*3+0]
ld [p3_x2],hl
ld hl,[ml_xy2+4*3+2]
ld [p3_y2],hl
ld hl,[ml_xy2+4*2+0]
ld [p3_x3],hl
ld hl,[ml_xy2+4*2+2]
ld [p3_y3],hl
call p3_polygon

ret

nc_setshadowdot: ;[nci_xx2,yy2,zz2]から[ncf_aa,bb,cc,dd]へ[ncf_ray_0,1,2]を使って投影する
;結果は[nci_dx,dy]に入る、cf=status
;次の方程式をtについて解く
;x == x0 + (x1 - x0)*t
;y == y0 + (y1 - y0)*t
;z == z0 + (z1 - z0)*t
;a*x + b*y + c*z + d == 0

;結果は
;u = -a*ray_0-b*ray_1-c*ray_2
ld hl,ncf_aa
call mtox
ld hl,ncf_ray_0
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,ncf_ray_1
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,ncf_ray_2
call mtox
call mul
call ad
call ad
ld hl,acc1
push hl
call xtom
pop hl
ld de,ncf_u
push de
call mtom
pop hl
call chs
call sh00 ;符号を取る
and a
scf
ret z

;t = (d + a*x0 + b*y0 + c*z0) / u
ld hl,ncf_dd
call mtox
ld hl,ncf_aa
call mtox
ld hl,[nci_xx2]
call itof16
ld hl,acc1
push hl
ld de,ncf_work10+4*0
call mtom
pop hl
call mtox
call mul
ld hl,ncf_bb
call mtox
ld hl,[nci_yy2]
call itof16
ld hl,acc1
push hl
ld de,ncf_work10+4*1
call mtom
pop hl
call mtox
call mul
ld hl,ncf_cc
call mtox
ld hl,[nci_zz2]
call itof16
ld hl,acc1
push hl
ld de,ncf_work10+4*2
call mtom
pop hl
call mtox
call mul
call ad
call ad
call ad
ld hl,ncf_u
call mtox
call div
ld hl,ncf_t
call xtom

;x=x0+ray_0*t
ld hl,ncf_ray_0
call mtox
ld hl,ncf_t
call mtox
call mul
ld hl,ncf_work10+4*0
call mtox
call ad
ld hl,ncf_xx
call xtom
;y=y0+ray_1*t
ld hl,ncf_ray_1
call mtox
ld hl,ncf_t
call mtox
call mul
ld hl,ncf_work10+4*1
call mtox
call ad
ld hl,ncf_yy
call xtom
;z=z0+ray_2*t
ld hl,ncf_ray_2
call mtox
ld hl,ncf_t
call mtox
call mul
ld hl,ncf_work10+4*2
call mtox
call ad
ld hl,ncf_zz
call xtom

; v[0]=(ncf_xx-eye[0])*400;ncf_zoom
ld hl,ncf_xx
call mtox
ld hl,[nci_eye_0]
call itof16
ld hl,acc1
call mtox
call sb
ld hl,ncf_zoom
call mtox
call mul
ld hl,ncf_v_0
call xtom
; v[1]=(ncf_yy-eye[1])*400;ncf_zoom
ld hl,ncf_yy
call mtox
ld hl,[nci_eye_1]
call itof16
ld hl,acc1
call mtox
call sb
ld hl,ncf_zoom
call mtox
call mul
ld hl,ncf_v_1
call xtom
; v[2]=(ncf_zz-eye[2])*400;ncf_zoom
ld hl,ncf_zz
call mtox
ld hl,[nci_eye_2]
call itof16
ld hl,acc1
call mtox
call sb
ld hl,ncf_zoom
call mtox
call mul
ld hl,ncf_v_2
call xtom

jp setshdot00

ncf_work10: db 0,0,0,0, 0,0,0,0, 0,0,0,0
ncf_xx: db 0,0,0,0
ncf_yy: db 0,0,0,0
ncf_zz: db 0,0,0,0
nci_xx2: dw 0
nci_yy2: dw 0
nci_zz2: dw 0
ml_xy2: db 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
ncf_vectorlen2: db 0,0,0,0
ncf_vector2: db 0,0,0,0, 0,0,0,0, 0,0,0,0
ncf_currentcenter2: db 0,0,0,0, 0,0,0,0, 0,0,0,0
nci_current2: dw 0,0,0
nci_currentcenter2: dw 0,0,0
nci_currentptr: dw 0
ncb_work00: db 0
ncb_work01: db 0
ncb_work10: db 0
ncb_work11: db 0
ncb_work20: db 0
ncf_work00: db 0,0,0,0, 0,0,0,0, 0,0,0,0

ncf_vectorlen: db 0,0,0,0
ncf_vector: db 0,0,0,0, 0,0,0,0, 0,0,0,0
ncf_currentcenter: db 0,0,0,0, 0,0,0,0, 0,0,0,0

ml_checkinner: ;[nci_currentcenter]-->[ncf_px,py,pz]のベクトルを正規化する
;ベクトルを1/4倍する
;[nci_currentcenter]を実数にして[ncf_currentcenter]とする
;[ncf_currentcenter]+vが[nci_current](立方体の中央)+-1の範囲内であればcf=1
;範囲外であればcf=0で、この場合は[nci_currentcenter]を中心とする4角形を表示する
ld hl,[nci_currentcenter+2*0]
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*0
call mtom
ld hl,[nci_currentcenter+2*1]
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*1
call mtom
ld hl,[nci_currentcenter+2*2]
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*2
call mtom

ld hl,ncf_px
call mtox
ld hl,ncf_currentcenter+4*0
call mtox
call sb
ld hl,ncf_vector+4*0
call xtom

ld hl,ncf_py
call mtox
ld hl,ncf_currentcenter+4*1
call mtox
call sb
ld hl,ncf_vector+4*1
call xtom

ld hl,ncf_pz
call mtox
ld hl,ncf_currentcenter+4*2
call mtox
call sb
ld hl,ncf_vector+4*2
call xtom

ld hl,ncf_vector+4*0
push hl
call mtox
pop hl
call mtox
call mul ;x*x

ld hl,ncf_vector+4*1
push hl
call mtox
pop hl
call mtox
call mul ;y*y

ld hl,ncf_vector+4*2
push hl
call mtox
pop hl
call mtox
call mul ;z*z

call ad
call ad

call sqr ;sqr(x*x+y*y+z*z)

ld hl,ncf_vectorlen
push hl
call xtom
pop hl
call mul2 ;*2
call mul2 ;*2

;ベクトルを正規化して、4で割る
ld hl,ncf_vector+4*0
push hl
call mtox
ld hl,ncf_vectorlen
call mtox
call div
pop hl
call xtom

ld hl,ncf_vector+4*1
push hl
call mtox
ld hl,ncf_vectorlen
call mtox
call div
pop hl
call xtom

ld hl,ncf_vector+4*2
push hl
call mtox
ld hl,ncf_vectorlen
call mtox
call div
pop hl
call xtom

;ncf_currentcenterにvを足す
ld hl,ncf_currentcenter+4*0
push hl
call mtox
ld hl,ncf_vector+4*0
call mtox
call ad
pop hl
call xtom

ld hl,ncf_currentcenter+4*1
push hl
call mtox
ld hl,ncf_vector+4*1
call mtox
call ad
pop hl
call xtom

ld hl,ncf_currentcenter+4*2
push hl
call mtox
ld hl,ncf_vector+4*2
call mtox
call ad
pop hl
call xtom

;[ncf_currentcenter]が[nci_current]の+-1の範囲内か調べる
ld hl,[nci_current+2*0] ;x-1
dec hl
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*0
call fcp ;center-(x-1)<0ならば、表示できる
ccf
ret nc
ld hl,[nci_current+2*0] ;x+1
inc hl
call itof16
ld de,acc1
ld hl,ncf_currentcenter+4*0
call fcp ;(x+1)-center<0ならば、表示できる
ccf
ret nc

ld hl,[nci_current+2*1] ;y-1
dec hl
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*1
call fcp ;center-(y-1)<0ならば、表示できる
ccf
ret nc
ld hl,[nci_current+2*1] ;y+1
inc hl
call itof16
ld de,acc1
ld hl,ncf_currentcenter+4*1
call fcp ;(y+1)-center<0ならば、表示できる
ccf
ret nc

ld hl,[nci_current+2*2] ;z-1
dec hl
call itof16
ld hl,acc1
ld de,ncf_currentcenter+4*2
call fcp ;center-(z-1)<0ならば、表示できる
ccf
ret nc
ld hl,[nci_current+2*2] ;z+1
inc hl
call itof16
ld de,acc1
ld hl,ncf_currentcenter+4*2
call fcp ;(z+1)-center<0ならば、表示できる
ccf
ret ;すべての検査で立方体の内側にある場合は表示しない

nci_c0: dw 0
nci_c1: dw 0
nci_nm1: dw 0
nci_nm2: dw 0
nci_pwork00: dw 0
nci_pwork01: dw 0
nci_pwork10: dw 0
nci_pwork11: dw 0

ml_sort: ;距離[[nci_distance]〜]により、[[nci_ptrstart]〜]のポインタをソートする
ld hl,[nci_number]
dec hl
ld a,h
or l
ret z

ld [nci_nm1],hl
dec hl
ld [nci_nm2],hl

ld hl,0
ml_so00:
ld [nci_c0],hl
ml_so10:
inc hl
ld [nci_c1],hl

ld hl,[nci_c0]
add hl,hl
ld de,[nci_ptrstart]
add hl,de
ld [nci_pwork00],hl
ld e,[hl]
inc hl
ld d,[hl]
ex de,hl
ld [nci_pwork01],hl
add hl,hl ;*4
ld de,[nci_distance]
add hl,de

push hl

ld hl,[nci_c1]
add hl,hl
ld de,[nci_ptrstart]
add hl,de
ld [nci_pwork10],hl
ld e,[hl]
inc hl
ld d,[hl]
ex de,hl
ld [nci_pwork11],hl
add hl,hl ;*4
ld de,[nci_distance]
add hl,de

pop de

call fcp
jr nc,ml_so20

ld hl,[nci_pwork00]
ld de,[nci_pwork11]
ld [hl],e
inc hl
ld [hl],d

ld hl,[nci_pwork10]
ld de,[nci_pwork01]
ld [hl],e
inc hl
ld [hl],d
ml_so20:
ld hl,[nci_c1]
ld de,[nci_nm1]
and a
sbc hl,de
jr z,ml_so11
add hl,de
jp ml_so10
ml_so11:
ld hl,[nci_c0]
ld de,[nci_nm2]
and a
sbc hl,de
ret z
add hl,de
inc hl
jp ml_so00

ml_wire: ;すべての立方体をワイヤーフレームで表示する
ld bc,[nci_number]
ld ix,nci_cubes
jp ml_wi20
ml_wi21:
call keycheck ;+++++++

push bc

ld iy,ml_offset0
ld hl,ml_xy0
push ix
call ml_wi00
pop ix
ld iy,ml_offset1
ld hl,ml_xy1
push ix
call ml_wi00

ld hl,ml_xy0+5*0
ld de,ml_xy0+5*1
call ml_wi30
ld hl,ml_xy0+5*1
ld de,ml_xy0+5*2
call ml_wi30
ld hl,ml_xy0+5*2
ld de,ml_xy0+5*3
call ml_wi30
ld hl,ml_xy0+5*3
ld de,ml_xy0+5*0
call ml_wi30

ld hl,ml_xy1+5*0
ld de,ml_xy1+5*1
call ml_wi30
ld hl,ml_xy1+5*1
ld de,ml_xy1+5*2
call ml_wi30
ld hl,ml_xy1+5*2
ld de,ml_xy1+5*3
call ml_wi30
ld hl,ml_xy1+5*3
ld de,ml_xy1+5*0
call ml_wi30

ld hl,ml_xy0+5*0
ld de,ml_xy1+5*0
call ml_wi30
ld hl,ml_xy0+5*1
ld de,ml_xy1+5*1
call ml_wi30
ld hl,ml_xy0+5*2
ld de,ml_xy1+5*2
call ml_wi30
ld hl,ml_xy0+5*3
ld de,ml_xy1+5*3
call ml_wi30

pop ix

pop bc
ld de,2*3
add ix,de
dec bc
ml_wi20:
ld a,b
or c
jp nz,ml_wi21

ret

ml_wi30: ;hl,de=ml_xy0〜1 --> line [hl]-[de]
bit 7,[hl]
ret nz
ld a,[de]
and a
ret nz
inc hl
inc de
push de
ld de,dr_x1
ld bc,2*2
ldir
pop hl
ld de,dr_x2
ld bc,2*2
ldir
jp line

ml_wi00: ;1:ix=nci_cubesへのポインタ、iy=ml_offset0〜1、hl=ml_xy0〜1
; --> [ml_xyz〜]に座標を設定
push hl

ld hl,ml_xyz
ld c,4
ml_wi02:
ld b,3
ml_wi01:
exx
ld l,[ix+0]
ld h,[ix+1]
inc ix
inc ix
ld e,[iy+0]
ld d,[iy+1]
inc iy
inc iy
add hl,de
push hl
exx
pop de
ld [hl],e
inc hl
ld [hl],d
inc hl
djnz ml_wi01

ld de,-(2*3)
add ix,de

dec c
jr nz,ml_wi02

pop de ;ml_xy0 or xy1

;2:[ml_xyz〜]を変換し、[ml_xy0〜1]に設定する
ld hl,ml_xyz
ld b,4
ml_wi10:
push bc

push de
ld de,nci_xx
ld bc,2*3
ldir
pop de

push hl

push de
call nc_setdot
pop de

sbc a,a
ld [de],a

ld hl,nci_dx
inc de
ld bc,2*2
ldir

pop hl
pop bc
djnz ml_wi10

ret

keycheck:
call _getkey
and a
ret z
ld sp,[ml_spwork]
jp ml10

;#define ez (-1000)
ncf_ez: db &c7,&00,&00,&fa ;-1000/4 = -250 +++++++

;#define cz (-400/sqrt((double)2)+10)
ncf_cz: db &c5,&bc,&d7,&f2 ;-400/4/sqr2+10 = -60.71

;#define rollcount 6 +++++++
;#define st (sin(atan((double)1)/45*90/rollcount))
;#define ct (cos(atan((double)1)/45*90/rollcount))
ncf_mst: db &be,&ee,&83,&84 ;-0.258819045
ncf_st: db &3e,&ee,&83,&84 ;0.258819045
ncf_ct: db &3f,&ea,&46,&f7 ;0.965925826

;int eye[3]={0,0,0}; //現在位置
;セーブデータ nci_eye
nc_initeye:
ld hl,0
ld [nci_eye_0],hl
ld [nci_eye_1],hl
ld [nci_eye_2],hl
ret

;
;double x0[3][3]={1,0,0, 0,1,0, 0,0,1};
;//視線方向=(x0[0][2], x0[1][2], x0[2][2])
;セーブデータ ncf_x0
nc_initx0:
ld hl,ncf_x0
ld de,ncf_x0+1
ld bc,4*9-1
ld [hl],0
ldir
ld hl,float1
ld de,ncf_x0_00
push hl
call mtom
pop hl
ld de,ncf_x0_11
push hl
call mtom
pop hl
ld de,ncf_x0_22
call mtom
ret

;
;double x[3][3];
ncf_x:
ncf_x_00: db 0,0,0,0
ncf_x_01: db 0,0,0,0
ncf_x_02: db 0,0,0,0
ncf_x_10: db 0,0,0,0
ncf_x_11: db 0,0,0,0
ncf_x_12: db 0,0,0,0
ncf_x_20: db 0,0,0,0
ncf_x_21: db 0,0,0,0
ncf_x_22: db 0,0,0,0

;double v[3];
ncf_v:
ncf_v_0: db 0,0,0,0
ncf_v_1: db 0,0,0,0
ncf_v_2: db 0,0,0,0

;int i[3];
ncb_i:
ncb_i_0: db 0
ncb_i_1: db 0
ncb_i_2: db 0

ncf_zoom: db &46,&00,&00,&c8 ;100 +++++++
ncf_offsetx: db &47,&00,&00,&a0 ;160
ncf_offsety: db &46,&00,&00,&c8 ;100

nci_xx: dw 0
nci_yy: dw 0
nci_zz: dw 0
nci_dx: dw 0
nci_dy: dw 0
ncf_rx: db 0,0,0,0
ncf_ry: db 0,0,0,0
ncf_rz: db 0,0,0,0
ncf_z0: db 0,0,0,0
;
nc_leai: ;hl=ptr i[a], a=[hl]
ld hl,ncb_i
dec a
jp m,nc_lea000
inc hl
dec a
jp m,nc_lea000
inc hl
nc_lea000:
ld a,[hl]
ret

nc_leavi: ;hl=ptr v[i[a]]
call nc_leai

dec a
jp m,nc_lea00
dec a
jp m,nc_lea01
ld hl,ncf_v_2
ret
nc_lea00:
ld hl,ncf_v_0
ret
nc_lea01:
ld hl,ncf_v_1
ret

nc_leaxib: ;hl=ptr x[i[a]][b]
dec b
jp m,nc_leaxi0
dec b
jp m,nc_leaxi1
;
nc_leaxi2: ;hl=ptr x[i[a]][2]
call nc_leaxi
ld bc,4*2
add hl,bc
ret

nc_leaxi1: ;hl=ptr x[i[a]][1]
call nc_leaxi
inc hl
inc hl
inc hl
inc hl
ret

nc_leaxi0: ;hl=ptr x[i[a]][0]
nc_leaxi: ;hl=ptr x[i[a]][0]
call nc_leai

dec a
jp m,nc_lea10
dec a
jp m,nc_lea11
ld hl,ncf_x_20
ret
nc_lea10:
ld hl,ncf_x_00
ret
nc_lea11:
ld hl,ncf_x_10
ret

;座標変換する
nc_setdot: ;(nci_xx,yy,zz) --> (nci_dx,dy)変換する, cf=status
;void setdot(double xx, double yy, double zz, int po)
;{
; double rx, ry, rz, z0;
; int dx, dy;
;
; flag0=0; flag1=0; flag2=0;
;
; v[0]=(xx-eye[0])*400;ncf_zoom
ld hl,[nci_xx]
ld de,[nci_eye_0]
and a
sbc hl,de
call itof16
ld hl,ncf_zoom
ld de,acc2
call mtom
call fmul
ret c
ld hl,acc1
ld de,ncf_v_0
call mtom
; v[1]=(yy-eye[1])*400;ncf_zoom
ld hl,[nci_yy]
ld de,[nci_eye_1]
and a
sbc hl,de
call itof16
ld hl,ncf_zoom
ld de,acc2
call mtom
call fmul
ret c
ld hl,acc1
ld de,ncf_v_1
call mtom
; v[2]=(zz-eye[2])*400;ncf_zoom
ld hl,[nci_zz]
ld de,[nci_eye_2]
and a
sbc hl,de
call itof16
ld hl,ncf_zoom
ld de,acc2
call mtom
call fmul
ret c
ld hl,acc1
ld de,ncf_v_2
call mtom

setshdot00:

; v[i[1]]=v[i[1]]-v[i[0]]*x[i[1]][0];
xor a
call nc_leavi
ld de,acc1
call mtom ;v[i[0]]
ld a,1
call nc_leaxi0
ld de,acc2
call mtom ;x[i[1]][0]
call fmul
ret c
ld hl,acc1
call chs
ld a,1
call nc_leavi
push hl
ld de,acc2
call mtom ;v[i[1]]
call fadd
pop de ;ptr v[i[1]]
ret c
ld hl,acc1
call mtom

; v[i[2]]=v[i[2]]-v[i[0]]*x[i[2]][0]-v[i[1]]*x[i[2]][1];
ld a,2
call nc_leavi
call mtox ;v[i[2]]
xor a
call nc_leavi
call mtox ;v[i[0]]
ld a,2
call nc_leaxi0
call mtox ;x[i[2]][0]
call mul
ret c
call sb
ret c
ld a,1
call nc_leavi
call mtox ;x[i[1]]
ld a,2
call nc_leaxi1
call mtox ;x[i[2]][1]
call mul
ret c
call sb
ret c
ld a,2
call nc_leavi
call xtom

; rz=v[i[2]]/x[i[2]][2];
ld a,2
call nc_leavi
call mtox
ld a,2
call nc_leaxi2
call mtox
call div
ret c
ld hl,ncf_rz
call xtom

; if(rz<=ez) {flag0=1; return;};
; if(rz<=cz) {flag1=1;};
ld de,ncf_cz
ld hl,ncf_rz
call fcp ;cz-rz
ccf
ret c

; ry=(v[i[1]]-rz*x[i[1]][2])/x[i[1]][1];
ld a,1
call nc_leavi
call mtox
ld hl,ncf_rz
call mtox
ld a,1
call nc_leaxi2
call mtox
call mul
ret c
call sb
ret c
ld a,1
call nc_leaxi1
call mtox
call div
ret c
ld hl,ncf_ry
call xtom

; rx=(v[i[0]]-rz*x[i[0]][2]-ry*x[i[0]][1])/x[i[0]][0];
xor a
call nc_leavi
call mtox
ld hl,ncf_rz
call mtox
xor a
call nc_leaxi2
call mtox
call mul
ret c
call sb
ret c
ld hl,ncf_ry
call mtox
xor a
call nc_leaxi1
call mtox
call mul
ret c
call sb
ret c
xor a
call nc_leaxi0
call mtox
call div
ret c
ld hl,ncf_rx
call xtom

; z0=ez/(ez-rz);
ld hl,ncf_ez
call mtox
ld hl,ncf_ez
call mtox
ld hl,ncf_rz
call mtox
call sb
ret c
call div
ret c
ld hl,ncf_z0
call xtom

; dx=(int)(240+rx*z0);
ld hl,ncf_offsetx
call mtox
ld hl,ncf_rx
call mtox
ld hl,ncf_z0
call mtox
call mul
ret c
call ad
ret c
ld hl,acc1
call xtom
call ftoi16
ret c
ld [nci_dx],hl

; dy=(int)(240-ry*z0);
ld hl,ncf_offsety
call mtox
ld hl,ncf_ry
call mtox
ld hl,ncf_z0
call mtox
call mul
ret c
call sb
ret c
ld hl,acc1
call xtom
call ftoi16
ret c
ld [nci_dy],hl

; if((dx<0)|(dx>479)|(dy<0)|(dy>479)) {flag2=1;};
; p[pe0*4+po].x=dx; p[pe0*4+po].y=dy;

and a
ret ;cf=0
;}

ncb_j: db 0
ncb_k: db 0
ncb_l: db 0
ncf_t: db 0,0,0,0
ncf_u: db 0,0,0,0

nc_leaxicb: ;hl=ptr x[i[c]][b]
push bc
ld a,c
call nc_leaxib
pop bc
ret

nc_inverse:
;x0[3][3] --> 座標変換用に変形する --> x[3][3], i[3]
;単にx0[3][3]の逆行列を求めればよいのだが、ここでは座標変換をより高速にする
; int j,k,l,tmp;
; double t,u;
;
; for(j=0; j<3; j++)
; {
; for(k=0; k<3; k++)
; {x[j][k]=x0[j][k];};
; };
ld hl,ncf_x0
ld de,ncf_x
ld bc,4*9
ldir

; i[0]=0; i[1]=1; i[2]=2;
ld hl,ncb_i+0
xor a
ld [hl],a
inc a
inc hl
ld [hl],a
inc a
inc hl
ld [hl],a

; for(j=0; j<3; j++)
; {
xor a
nc_inv00:
ld [ncb_j],a

; u=0;
xor a
ld [ncf_u+0],a

; for(k=j; k<3; k++)
; {
ld a,[ncb_j]
nc_inv10:
ld [ncb_k],a
; t=doubleabs(x[i[k]][j]);
ld c,a
ld a,[ncb_j]
ld b,a
call nc_leaxicb
ld de,ncf_t
push de
call mtom
pop hl
res 7,[hl]
; if(t>u) {u=t; l=k;};
ld de,ncf_u
push de
push hl
call fcp ;u-t
pop hl
pop de
jr nc,nc_inv11
call mtom
ld a,[ncb_k]
ld [ncb_l],a
nc_inv11:
; };
ld a,[ncb_k]
inc a
cp 3
jr c,nc_inv10

; tmp=i[j]; i[j]=i[l]; i[l]=tmp;
ld a,[ncb_j]
call nc_leai
ld b,a
ex de,hl
ld a,[ncb_l]
call nc_leai
ld [hl],b
ld [de],a

; if(j!=2)
; {
ld a,[ncb_j]
cp 2
jp z,nc_inv20

; t=x[i[j]][j];
ld b,a
ld c,a
call nc_leaxicb
ld de,ncf_t
call mtom

; for(k=j+1; k<3; k++)
; {
ld a,[ncb_j]
inc a
nc_inv30:
ld [ncb_k],a

; u=x[i[k]][j]/t;
ld c,a
ld a,[ncb_j]
ld b,a
call nc_leaxicb
call mtox
ld hl,ncf_t
call mtox
call div
ld hl,ncf_u
call xtom

; for(l=j+1; l<3; l++)
; {
ld a,[ncb_j]
inc a
nc_inv40:
ld [ncb_l],a
; x[i[k]][l]=x[i[k]][l]-x[i[j]][l]*u;
ld b,a
ld a,[ncb_k]
ld c,a
call nc_leaxicb
push hl
call mtox
ld a,[ncb_j]
ld c,a
ld a,[ncb_l]
ld b,a
call nc_leaxicb
call mtox
ld hl,ncf_u
call mtox
call mul
call sb
pop hl
call xtom

; };
ld a,[ncb_l]
inc a
cp 3
jr c,nc_inv40

; x[i[k]][j]=u;
ld a,[ncb_k]
ld c,a
ld a,[ncb_j]
ld b,a
call nc_leaxicb
ex de,hl
ld hl,ncf_u
call mtom

; };
ld a,[ncb_k]
inc a
cp 3
jr c,nc_inv30

; };
nc_inv20:

; };
ld a,[ncb_j]
inc a
cp 3
jp c,nc_inv00

ret

ncb_indx: db 0
ncb_indy: db 0
ncb_s: db 0
ncf_r: db 0,0,0,0
nci_work00: dw 0

nc_leax0cb: ;hl=ptr x0[c][b]
push bc
ld a,c
call nc_leax0b
pop bc
ret

nc_leax0b: ;hl=ptr x0[a][b]
dec b
jp m,nc_leax00
dec b
jp m,nc_leax01
;
nc_leax02: ;hl=ptr x0[a][2]
call nc_leax0
ld bc,4*2
add hl,bc
ret

nc_leax01: ;hl=ptr x0[a][1]
call nc_leax0
inc hl
inc hl
inc hl
inc hl
ret

nc_leax00: ;hl=ptr x0[a][0]
nc_leax0: ;hl=ptr x0[a][0]
dec a
jp m,nc_lea010
dec a
jp m,nc_lea011
ld hl,ncf_x0_20
ret
nc_lea010:
ld hl,ncf_x0_00
ret
nc_lea011:
ld hl,ncf_x0_10
ret

nc_rol10:
ld a,[ncb_s]
ld hl,ncf_mst
and a
ret m
ld hl,ncf_st
ret

ncf_epsilon: db &32,&17,&b7,&d1 ;1e-04 +++++++

nc_rolling: ;視線を回転させる [ncb_indx], [ncb_indy]方向に、符号[ncb_s](bit7)
;void rolling(int ix, int iy, int s)
;{
; int j, k;
; double r;
;
; for(j=0; j<3; j++)
; {
xor a
nc_rol00:
ld [ncb_j],a

; r=ct*x0[j][ix]-s*st*x0[j][iy];
ld hl,ncf_ct
call mtox
ld a,[ncb_j]
ld c,a
ld a,[ncb_indx]
ld b,a
call nc_leax0cb
push hl
call mtox
call mul
call nc_rol10 ;s*st
call mtox
ld a,[ncb_j]
ld c,a
ld a,[ncb_indy]
ld b,a
call nc_leax0cb
call mtox
call mul
call sb
ld hl,ncf_r
call xtom

; x0[j][iy]=s*st*x0[j][ix]+ct*x0[j][iy];
ld hl,ncf_ct
call mtox
ld a,[ncb_j]
ld c,a
ld a,[ncb_indy]
ld b,a
call nc_leax0cb
push hl
call mtox
call mul
call nc_rol10 ;s*st
call mtox
ld a,[ncb_j]
ld c,a
ld a,[ncb_indx]
ld b,a
call nc_leax0cb
call mtox
call mul
call ad
pop hl
call xtom

; x0[j][ix]=r;
pop de
ld hl,ncf_r
call mtom

; };
ld a,[ncb_j]
inc a
cp 3
jr c,nc_rol00

;
; for(j=0; j<3; j++)
; {
xor a
nc_rol20:
ld [ncb_j],a

; for(k=0; k<3; k++)
; {
xor a
nc_rol21:
ld [ncb_k],a

; if( (doubleabs(1-doubleabs(x0[j][k]))>0.00001)
; & (doubleabs(x0[j][k])>0.00001) ) {goto donot;};
call nc_rol30
jr nc,nc_rol22

ld hl,[nci_work00]
ld de,acc1
push de
call mtom
pop hl
res 7,[hl]
ld de,ncf_epsilon
call fcp ;eps-acc1
ret c
nc_rol22:

; };
ld a,[ncb_k]
inc a
cp 3
jr c,nc_rol21

; };
ld a,[ncb_j]
inc a
cp 3
jr c,nc_rol20

; for(j=0; j<3; j++)
; {
xor a
nc_rol40:
ld [ncb_j],a

; for(k=0; k<3; k++)
; {
xor a
nc_rol41:
ld [ncb_k],a

; if( doubleabs(1-doubleabs(x0[j][k]))<=0.00001 )
; {
call nc_rol30
jr c,nc_rol42
; if(x0[j][k]>0) {r=1;} else {r=-1;};
ld hl,float1
ld de,ncf_r
call mtom
ld hl,[nci_work00]
bit 7,[hl]
jr z,nc_rol44

ld hl,ncf_r
call chs
nc_rol44:
; }
jr nc_rol43
; else
; {
nc_rol42:
; r=0;
xor a
ld [ncf_r+0],a

; };
nc_rol43:

; x0[j][k]=r;
ld de,[nci_work00]
ld hl,ncf_r
call mtom

; };
ld a,[ncb_k]
inc a
cp 3
jr c,nc_rol41

; };
ld a,[ncb_j]
inc a
cp 3
jr c,nc_rol40

;donot:;
ret
;}

nc_rol30:
ld a,[ncb_j]
ld c,a
ld a,[ncb_k]
ld b,a
call nc_leax0cb
ld [nci_work00],hl
ld de,acc1
push de
call mtom
pop hl
res 7,[hl]
ld hl,float1
ld de,acc2
call mtom
call fsub
ld hl,acc1
res 7,[hl]
ld de,ncf_epsilon
call fcp ;eps-acc1
ret

nci_e0: dw 0
nci_e1: dw 0
nci_e2: dw 0
nci_e00: dw 0
nci_e01: dw 0
nci_e02: dw 0

ncf_x1: db 0,0,0,0
ncf_y1: db 0,0,0,0
ncf_z1: db 0,0,0,0

nc_forwarding: ;[nci_e0,e1,e2]を視線方向に+1する。
;どの視線を使うかは[ncb_i](0 or 1 or 2), 進行方向の符号は[ncb_s](0 or 255)
;void forwarding(int i, int s)
;{
; double x1=(double)eye[0];
; double y1=(double)eye[1];
; double z1=(double)eye[2];
ld hl,[nci_e0]
call itof16
ld hl,acc1
ld de,ncf_x1
call mtom
ld hl,[nci_e1]
call itof16
ld hl,acc1
ld de,ncf_y1
call mtom
ld hl,[nci_e2]
call itof16
ld hl,acc1
ld de,ncf_z1
call mtom

; // x0[0][i], x0[1][i], x0[2][i]
; while( ((int)(.5+x1)==eye[0]) & ((int)(.5+y1)==eye[1]) & ((int)(.5+z1)==eye[2]) )
; {
nc_for00:
ld hl,ncf_x1
call mtox
ld hl,float1div2
call mtox
call ad
ld hl,acc1
call xtom
call ftoi16
ret c
ld [nci_e00],hl

ld hl,ncf_y1
call mtox
ld hl,float1div2
call mtox
call ad
ld hl,acc1
call xtom
call ftoi16
ret c
ld [nci_e01],hl

ld hl,ncf_z1
call mtox
ld hl,float1div2
call mtox
call ad
ld hl,acc1
call xtom
call ftoi16
ret c
ld [nci_e02],hl

ld hl,[nci_e00]
ld de,[nci_e0]
and a
sbc hl,de
jr nz,nc_for10
ld hl,[nci_e01]
ld de,[nci_e1]
and a
sbc hl,de
jr nz,nc_for10
ld hl,[nci_e02]
ld de,[nci_e2]
and a
sbc hl,de
jr nz,nc_for10

; x1+=s*x0[0][i]; y1+=s*x0[1][i]; z1+=s*x0[2][i]; (ptr x0[c][b]: call nc_leax0cb)
ld hl,ad
ld a,[ncb_s]
and a
jr z,nc_for20
ld hl,sb
nc_for20:
ld [ncc_for00+1],hl
ld [ncc_for01+1],hl
ld [ncc_for02+1],hl

ld hl,ncf_x1
push hl
call mtox
ld c,0
ld a,[ncb_i]
ld b,a
call nc_leax0cb
call mtox
ncc_for00:
call ad
pop hl
call xtom

ld hl,ncf_y1
push hl
call mtox
ld c,1
ld a,[ncb_i]
ld b,a
call nc_leax0cb
call mtox
ncc_for01:
call ad
pop hl
call xtom

ld hl,ncf_z1
push hl
call mtox
ld c,2
ld a,[ncb_i]
ld b,a
call nc_leax0cb
call mtox
ncc_for02:
call ad
pop hl
call xtom

jp nc_for00

; };
nc_for10:

; eye[0]=(int)(.5+x1); eye[1]=(int)(.5+y1); eye[2]=(int)(.5+z1);
ld hl,nci_e00
ld de,nci_e0
ld bc,2*3
ldir

ret
;}

sgn: ;a=sgn [hl]
ld a,[hl]
and a
ret z
ld a,&ff
ret m
ld a,1
ret

ncf_s: db 0,0,0,0
ncf_a: db 0,0,0,0
ncf_s1: db 0,0,0,0
ncf_a1: db 0,0,0,0
ncb_k1: db 0

nc_leaxcb: ;hl=ptr x[c][b]
push bc
ld a,c
call nc_leaxb
pop bc
ret

nc_leaxb: ;hl=ptr x[a][b]
dec b
jp m,nc_leax0a
dec b
jp m,nc_leax1
;
nc_leax2: ;hl=ptr x[a][2]
call nc_leax
ld bc,4*2
add hl,bc
ret

nc_leax1: ;hl=ptr x[a][1]
call nc_leax
inc hl
inc hl
inc hl
inc hl
ret

nc_leax0a: ;hl=ptr x[a][0]
nc_leax: ;hl=ptr x[a][0]
dec a
jp m,nc_lea20
dec a
jp m,nc_lea21
ld hl,ncf_x_20
ret
nc_lea20:
ld hl,ncf_x_00
ret
nc_lea21:
ld hl,ncf_x_10
ret

nc_reseteye: ;視線ncf_x0を吸着する --> cf=0ならncf_x0=吸着したベクトル, cf=1ならncf_x0は不変
;subroutine reseteye()
; use common_variables
; implicit none
;
; real(8) s, a, s1, a1
; integer(2) j, k, k1
; real(8), external :: sgn
;
; matrix=0
ld hl,ncf_x
ld de,ncf_x+1
ld bc,4*9-1
ld [hl],0
ldir

; do j=0, 2
xor a
nc_re00:
ld [ncb_j],a
; k1=0
xor a
ld [ncb_k1],a
; s1=matrix0(0,j)
ld c,0
ld a,[ncb_j]
ld b,a
call nc_leax0cb
ld de,ncf_s1
call mtom
; a1=dabs(s1)
ld hl,ncf_s1
ld de,ncf_a1
push de
call mtom
pop hl
res 7,[hl]
; s1=sgn(s1)
ld hl,ncf_s1
call sgn
ld [hl],a
; do k=1, 2
ld a,1
nc_re10:
ld [ncb_k],a
; s=matrix0(k,j)
ld a,[ncb_k]
ld c,a
ld a,[ncb_j]
ld b,a
call nc_leax0cb
ld de,ncf_s
call mtom
; a=dabs(s)
ld hl,ncf_s
ld de,ncf_a
push de
call mtom
pop hl
res 7,[hl]
; s=sgn(s)
ld hl,ncf_s
call sgn
ld [hl],a
; if( a .gt. a1) then
ld hl,ncf_a
ld de,ncf_a1
call fcp ;a1-a
jr nc,nc_re20 ;a1>=a
; k1=k
ld a,[ncb_k]
ld [ncb_k1],a
; a1=a
ld hl,ncf_a
ld de,ncf_a1
call mtom
; s1=s
ld a,[ncf_s+0]
ld [ncf_s1+0],a
; end if
nc_re20:
; end do
ld a,[ncb_k]
inc a
cp 3
jr c,nc_re10

; matrix(k1,j)=s1
ld a,[ncb_k1]
ld c,a
ld a,[ncb_j]
ld b,a
call nc_leaxcb
push hl
ld a,[ncf_s1+0]
ld l,a
add a,a
sbc a,a
ld h,a
call itof16
ld hl,acc1
pop de
call mtom

; end do
ld a,[ncb_j]
inc a
cp 3
jp c,nc_re00

; if( (dabs(matrix(0,0))+dabs(matrix(0,1))+dabs(matrix(0,2)) .eq. 1.0_8)
ld bc,0+256*0
call nc_leaxcb
ld de,acc1
push de
call mtom
pop hl
res 7,[hl]
ld bc,0+256*1
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld bc,0+256*2
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld hl,acc1
ld de,float1
call fcp
scf
ret nz

; .and. (dabs(matrix(1,0))+dabs(matrix(1,1))+dabs(matrix(1,2)) .eq. 1.0_8)
ld bc,1+256*0
call nc_leaxcb
ld de,acc1
push de
call mtom
pop hl
res 7,[hl]
ld bc,1+256*1
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld bc,1+256*2
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld hl,acc1
ld de,float1
call fcp
scf
ret nz

; .and. (dabs(matrix(2,0))+dabs(matrix(2,1))+dabs(matrix(2,2)) .eq. 1.0_8) ) then
ld bc,2+256*0
call nc_leaxcb
ld de,acc1
push de
call mtom
pop hl
res 7,[hl]
ld bc,2+256*1
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld bc,2+256*2
call nc_leaxcb
ld de,acc2
push de
call mtom
pop hl
res 7,[hl]
call fadd
ld hl,acc1
ld de,float1
call fcp
scf
ret nz

; matrix0=matrix
ld hl,ncf_x
ld de,ncf_x0
ld bc,4*9
ldir

; else
; result=messageboxqq('吸着できません。方向(0,0,1)に初期化しますか?'C, MB$OKCANCEL)
; if (result .eq. MB$IDOK) call reseteye001()
; end if
;
;end subroutine reseteye
and a
ret ;cf=0

ncf_aa: db 0,0,0,0
ncf_bb: db 0,0,0,0
ncf_cc: db 0,0,0,0
ncf_dd: db 0,0,0,0

getabcd: ;平面の方程式aax+bby+ccz+dd==0を求める
;ただし取り扱う平面はx+dd==0,y+dd==0,z+dd==0の3種類だけ
;a=0のときaa=1,bb=0,cc=0,dd=-hl(x==hl)
;a=1のときaa=0,bb=1,cc=0,dd=-hl(y==hl)
;a=2のときaa=0,bb=0,cc=1,dd=-hl(z==hl)
;aa,bb,cc,ddは実数でncf_aa,ncf_bb,ncf_cc,ncf_ddに入る
ex af,af'
xor a
ld [ncf_aa+0],a
ld [ncf_bb+0],a
ld [ncf_cc+0],a
ex af,af'
push hl
ld hl,float1
and a
jr z,getabcd00
dec a
jr z,getabcd01
;z==hl
ld de,ncf_cc
jr getabcd10
getabcd01:
;y==hl
ld de,ncf_bb
jr getabcd10
getabcd00:
;x==hl
ld de,ncf_aa
getabcd10:
call mtom
pop hl
call itof16
ld hl,acc1
call chs
ld de,ncf_dd
call mtom
ret
;int getabcd(double *pi, double *po)
; {
; double a[3][6];
; double tmp, m, b;
; int j, k, l, kp;
;
; a[0][0]=*(pi+0); //x0
; a[0][1]=*(pi+3); //x1
; a[0][2]=*(pi+6); //x2
; a[1][0]=*(pi+1); //y0
; a[1][1]=*(pi+4); //y1
; a[1][2]=*(pi+7); //y2
; a[2][0]=*(pi+2); //z0
; a[2][1]=*(pi+5); //z1
; a[2][2]=*(pi+8); //z2
;
; for(j=0; j<=2; j++) {
; for(k=0; k<=2; k++) {
; if(j == k) {
; a[j][3+k]=-1.0f;
; } else {
; a[j][3+k]=0.0f;
; };
; };
; };
;
; for(j=0; j<=2; j++) {
; for(k=0; k<=1; k++) {
; a[j][k]=a[j][k]-a[j][2];
; };
; };
;
; for(j=0; j<=1; j++) {
; m=fabs(a[j][j]);
; kp=j;
; for(k=j+1; k<=2; k++) {
; if( fabs(a[k][j]) > m ) {
; m=fabs(a[k][j]);
; kp=k;
; };
; };
; if(fabs(m) < 1.0E-07) {return(1);};
; if(kp != j) {
; for(k=j; k<=5; k++) {
; tmp=a[j][k];
; a[j][k]=a[kp][k];
; a[kp][k]=tmp;
; };
; };
;
; for(k=j+1; k<=2; k++) {
; b=a[k][j]/a[j][j];
; for(l=j+1; l<=5; l++) {
; a[k][l]=a[k][l]-b*a[j][l];
; };
; };
; };
;
; *(po+0)=a[2][3];
; *(po+1)=a[2][4];
; *(po+2)=a[2][5];
; *(po+3)=a[2][2];
; return(0);
; }

imul: ;整数hl=整数de*整数bc, cf=status(16bitx8bitに収まらないときはエラー)
xor a
bit 7,d
jr z,imul00
inc a
ex af,af'
ld a,d
cpl
ld d,a
ld a,e
cpl
ld e,a
inc de
ex af,af'
imul00:
bit 7,b
jr z,imul01
inc a
ex af,af'
ld a,b
cpl
ld b,a
ld a,c
cpl
ld c,a
inc bc
ex af,af'
imul01:
ex af,af'
imul10:
ld a,b
and a
jr z,imul11
inc a
jr z,imul11
push bc
push de
pop bc
pop de
ld a,b
and a
jr z,imul11
inc a
scf
ret nz
imul11:
call imulp
ret c
bit 7,h ;正数x正数=負数ならばエラー
scf
ret nz
ex af,af'
and 1
ret z ;cf=0
ld a,h
cpl
ld h,a
ld a,l
cpl
ld l,a
inc hl
and a
ret ;cf=0

imulp: ;正数hl=正数de*正数c, cf=status
ld hl,0
srl c ;1回目
jr nz,imulp00
ret nc ;0
ex de,hl
and a
ret ;cf=0
imulp00:
jr nc,imulp01
ld h,d
ld l,e
imulp01:
ex de,hl ;1回目
add hl,hl
ex de,hl
jr nc,imulp10
ld a,c
and a
ret z ;cf=0
scf
ret
imulp10:
ld a,d
or e
ret z ;0

srl c ;2,3,4,5,6,7,8回目
jr nz,imulp20
;cf=1
add hl,de
ret
imulp20:
jr nc,imulp21
add hl,de
imulp21:
ex de,hl ;2,3,4,5,6,7回目
add hl,hl
ex de,hl
jr nc,imulp10
ret

p3_x1: dw 0
p3_y1: dw 0
p3_x2: dw 0
p3_y2: dw 0
p3_x3: dw 0
p3_y3: dw 0

trix0: dw 0
triy0: dw 0
trix1: dw 0
triy1: dw 0
trix2: dw 0
triy2: dw 0

dxybig: db 0,0,0,0
dxysmall: db 0,0,0,0
xbig: db 0,0,0,0
xsmall: db 0,0,0,0
dybig: dw 0
dysmall: dw 0
p3d_d: db 0,0,0,0
dxybig2: db 0,0,0,0
dxysmall2: db 0,0,0,0

p3_polygon: ;ポリゴン(p3_x1,y1)-(p3_x2,y2)-(p3_x3,y3)を塗る
;座標は-8192〜8191であること
;[gradation_base]:グラデーション描画データへのポインタ

ld hl,p3_x1
ld de,trix0
ld bc,(2+2)*3
ldir

;!整数座標( trix(0), triy(0) ) - ( trix(1), triy(1) ) - ( trix(2), triy(2) )
;!の3角形を色 co で vram に表示する
;subroutine drawtriangle(co)
; use common_variables
; implicit none
;
; integer(4) co
; integer(2) tmp
; real(4) dxybig, dxysmall
; real(4) xbig, xsmall
; integer(2) left, right
; integer(2) j
; integer(2) dybig, dysmall
; real(4) d
;
; !y座標が小さい順に並べる
; if(triy(0) .gt. triy(1)) then
ld hl,[triy1]
ld de,[triy0]
and a
sbc hl,de
jp p,p3p000
; tmp=triy(0)
; triy(0)=triy(1)
; triy(1)=tmp
; tmp=trix(0)
; trix(0)=trix(1)
; trix(1)=tmp
push de ;triy0
ld hl,[triy1]
ld [triy0],hl
pop hl
ld [triy1],hl
ld hl,[trix0]
push hl
ld hl,[trix1]
ld [trix0],hl
pop hl
ld [trix1],hl
; end if
p3p000:
; if(triy(0) .gt. triy(2)) then
ld hl,[triy2]
ld de,[triy0]
and a
sbc hl,de
jp p,p3p001
; tmp=triy(0)
; triy(0)=triy(2)
; triy(2)=tmp
; tmp=trix(0)
; trix(0)=trix(2)
; trix(2)=tmp
push de ;triy0
ld hl,[triy2]
ld [triy0],hl
pop hl
ld [triy2],hl
ld hl,[trix0]
push hl
ld hl,[trix2]
ld [trix0],hl
pop hl
ld [trix2],hl
; end if
p3p001:
; if(triy(1) .gt. triy(2)) then
ld hl,[triy2]
ld de,[triy1]
and a
sbc hl,de
jp p,p3p002
; tmp=triy(2)
; triy(2)=triy(1)
; triy(1)=tmp
; tmp=trix(2)
; trix(2)=trix(1)
; trix(1)=tmp
; end if
push de ;triy1
ld hl,[triy2]
ld [triy1],hl
pop hl
ld [triy2],hl
ld hl,[trix1]
push hl
ld hl,[trix2]
ld [trix1],hl
pop hl
ld [trix2],hl
p3p002:
;
; dybig=triy(2)-triy(0)
ld hl,[triy2]
ld de,[triy0]
and a
sbc hl,de
ld [dybig],hl
; dxybig=(trix(2)-trix(0))/(dybig*2.0_4)
add hl,hl ;dybig*2
call itof16
ld hl,acc1
ld de,acc2
call mtom
ld hl,[trix2]
ld de,[trix0]
and a
sbc hl,de
call itof16
call fdiv
ld hl,acc1
ld de,dxybig
call mtom
;
; !上半分
; dysmall=triy(1)-triy(0)
ld hl,[triy1]
ld de,[triy0]
and a
sbc hl,de
ld [dysmall],hl
; dxysmall=(trix(1)-trix(0))/(dysmall*2.0_4)
add hl,hl ;dysmall*2
call itof16
ld hl,acc1
ld de,acc2
call mtom
ld hl,[trix1]
ld de,[trix0]
and a
sbc hl,de
call itof16
call fdiv
ld hl,acc1
ld de,dxysmall
call mtom
; select case (dysmall)
ld hl,[dysmall]
ld a,h
or l
jr nz,p3p100
;
; case(0) !横一線
; left=imin0( trix(0), trix(1) )
; right=imax0( trix(0), trix(1) )
ld hl,[trix0]
ld de,[trix1]
and a
push hl
sbc hl,de
pop hl
jp m,p3p010 ;trix0<trix1
;trix0>=trix1
ex de,hl
p3p010:
ld [dr_x1],hl
ld [dr_x2],de
; vram2(left:right, triy(0))= co !塗る
; vram3(left:right, triy(0))= 0 !塗る
ld hl,[triy0]
ld [dr_y1],hl
call hline

jp p3p300
;
p3p100:
; case default !一般
; xbig=trix(0)+dxybig
ld hl,[trix0]
call itof16
ld hl,dxybig
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,xbig
call mtom
; xsmall=trix(0)+dxysmall
ld hl,[trix0]
call itof16
ld hl,dxysmall
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,xsmall
call mtom
; !最初の横一線
; left=int2( 0.5_4+ amin1( trix(0)+0.0_4, xbig, xsmall ) )
; right=int2( 0.5_4+ amax1( trix(0)+0.0_4, xbig, xsmall ) )
ld hl,[trix0]
call itof16
ld hl,acc1
ld de,fwork00
call mtom
ld hl,xbig
ld de,fwork01
call mtom
ld hl,xsmall
ld de,fwork02
call mtom
ld b,3
call p3p_compare
; vram2(left:right, triy(0))= co !塗る
; vram3(left:right, triy(0))= 0 !塗る
ld hl,[triy0]
ld [dr_y1],hl
call p3p_hlineminmax
; !中の線
; if(dysmall .ge. 2) then
ld hl,[dysmall]
ld de,2
and a
sbc hl,de
jp c,p3p200
; do j=triy(0)+1, triy(1)-1
ld hl,dxybig
ld de,dxybig2
push de
call mtom
pop hl
call mul2
ld hl,dxysmall
ld de,dxysmall2
push de
call mtom
pop hl
call mul2

ld hl,[triy1]
ld de,[triy0]
inc de
and a
sbc hl,de
ld b,h
ld c,l
ex de,hl
p3p210:
push bc
ld [dr_y1],hl
; left=int2( 0.5_4+ amin1( xbig, xsmall, xbig+dxybig*2, xsmall+dxysmall*2 ) )
; right=int2( 0.5_4+ amax1( xbig, xsmall, xbig+dxybig*2, xsmall+dxysmall*2 ) )
ld hl,xbig
ld de,fwork00
call mtom
ld hl,xsmall
ld de,fwork01
call mtom
ld hl,xbig
ld de,acc1
call mtom
ld hl,dxybig2
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,fwork02
call mtom
ld hl,xsmall
ld de,acc1
call mtom
ld hl,dxysmall2
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,fwork03
call mtom
ld b,4
call p3p_compare
; vram2(left:right, j)= co !塗る
; vram3(left:right, j)= 0 !塗る
call p3p_hlineminmax
; xbig=xbig+dxybig*2
ld hl,fwork02
ld de,xbig
call mtom
; xsmall=xsmall+dxysmall*2
ld hl,fwork03
ld de,xsmall
call mtom
; end do
ld hl,[dr_y1]
inc hl
pop bc
dec bc
ld a,b
or c
jr nz,p3p210
; end if
p3p200:
; !最後の横一線
; if(dybig .eq. dysmall) then
ld hl,[dybig]
ld de,[dysmall]
and a
sbc hl,de
ld hl,dxybig
jr z,p3p220
; d=dxybig
; else
; d=dxybig*2
ld hl,dxybig2
; end if
p3p220:
ld de,p3d_d
call mtom
; left=int2( 0.5_4+ amin1( xbig, xsmall, xbig+d, xsmall+dxysmall ) )
; right=int2( 0.5_4+ amax1( xbig, xsmall, xbig+d, xsmall+dxysmall ) )
ld hl,xbig
ld de,fwork00
call mtom
ld hl,xsmall
ld de,fwork01
call mtom
ld hl,xbig
ld de,acc1
call mtom
ld hl,p3d_d
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,fwork02
call mtom
ld hl,xsmall
ld de,acc1
call mtom
ld hl,dxysmall
ld de,acc2
call mtom
call fadd
ld hl,acc1
ld de,fwork03
call mtom
ld b,4
call p3p_compare
; vram2(left:right, triy(1))= co !塗る
; vram3(left:right, triy(1))= 0 !塗る
ld hl,[triy1]
ld [dr_y1],hl
call p3p_hlineminmax
;
; end select
p3p300:
;
; !下半分
; dysmall=triy(2)-triy(1)
ld hl,[triy2]
ld de,[triy1]
and a
sbc hl,de
ld [dysmall],hl
; dxysmall=(trix(2)-trix(1))/(dysmall*2.0_4)
add hl,hl ;dysmall*2
call itof16
ld hl,acc1
ld de,acc2
call mtom
ld hl,[trix2]
ld de,[trix1]
and a
sbc hl,de
call itof16
call fdiv
ld hl,acc1
ld de,dxysmall
call mtom
; select case (dysmall)
ld hl,[dysmall]
ld a,h
or l
jr nz,p3p400
;
; case(0) !横一線
; left=imin0( trix(1), trix(2) )
; right=imax0( trix(1), trix(2) )
ld hl,[trix1]
ld de,[trix2]
and a
push hl
sbc hl,de
pop hl
jp m,p3p310 ;trix1<trix2
;trix1>=trix2
ex de,hl
p3p310:
ld [dr_x1],hl
ld [dr_x2],de
; vram2(left:right, triy(1))= co !塗る
; vram3(left:right, triy(1))= 0 !塗る
ld hl,[triy1]
ld [dr_y1],hl
call hline

jp p3p600
;
; case default !一般
p3p400:
; xbig=trix(2)-dxybig
ld hl,[trix2]
call itof16
ld hl,dxybig
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,xbig
call mtom
; xsmall=trix(2)-dxysmall
ld hl,[trix2]
call itof16
ld hl,dxysmall
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,xsmall
call mtom
; !最初の横一線
; left=int2( 0.5_4+ amin1( trix(2)+0.0_4, xbig, xsmall ) )
; right=int2( 0.5_4+ amax1( trix(2)+0.0_4, xbig, xsmall ) )
ld hl,[trix2]
call itof16
ld hl,acc1
ld de,fwork00
call mtom
ld hl,xbig
ld de,fwork01
call mtom
ld hl,xsmall
ld de,fwork02
call mtom
ld b,3
call p3p_compare
; vram2(left:right, triy(2))= co !塗る
; vram3(left:right, triy(2))= 0 !塗る
ld hl,[triy2]
ld [dr_y1],hl
call p3p_hlineminmax
; !中の線
; if(dysmall .ge. 2) then
ld hl,[dysmall]
ld de,2
and a
sbc hl,de
jp c,p3p500
; do j=triy(2)-1, triy(1)+1, -1
ld hl,dxybig
ld de,dxybig2
push de
call mtom
pop hl
call mul2
ld hl,dxysmall
ld de,dxysmall2
push de
call mtom
pop hl
call mul2

ld hl,[triy2]
ld de,[triy1]
inc de
and a
sbc hl,de
ld b,h
ld c,l
add hl,de
p3p510:
push bc
dec hl
ld [dr_y1],hl
; left=int2( 0.5_4+ amin1( xbig, xsmall, xbig-dxybig*2, xsmall-dxysmall*2 ) )
; right=int2( 0.5_4+ amax1( xbig, xsmall, xbig-dxybig*2, xsmall-dxysmall*2 ) )
ld hl,xbig
ld de,fwork00
call mtom
ld hl,xsmall
ld de,fwork01
call mtom
ld hl,xbig
ld de,acc1
call mtom
ld hl,dxybig2
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,fwork02
call mtom
ld hl,xsmall
ld de,acc1
call mtom
ld hl,dxysmall2
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,fwork03
call mtom
ld b,4
call p3p_compare
; vram2(left:right, j)= co !塗る
; vram3(left:right, j)= 0 !塗る
call p3p_hlineminmax
; xbig=xbig-dxybig*2
ld hl,fwork02
ld de,xbig
call mtom
; xsmall=xsmall-dxysmall*2
ld hl,fwork03
ld de,xsmall
call mtom
; end do
ld hl,[dr_y1]
pop bc
dec bc
ld a,b
or c
jr nz,p3p510
; end if
p3p500:
; !最後の横一線
; if(dybig .eq. dysmall) then
ld hl,[dybig]
ld de,[dysmall]
and a
sbc hl,de
ld hl,dxybig
jr z,p3p520
; d=dxybig
; else
; d=dxybig*2
ld hl,dxybig2
; end if
p3p520:
ld de,p3d_d
call mtom
; left=int2( 0.5_4+ amin1( xbig, xsmall, xbig-d, xsmall-dxysmall ) )
; right=int2( 0.5_4+ amax1( xbig, xsmall, xbig-d, xsmall-dxysmall ) )
ld hl,xbig
ld de,fwork00
call mtom
ld hl,xsmall
ld de,fwork01
call mtom
ld hl,xbig
ld de,acc1
call mtom
ld hl,p3d_d
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,fwork02
call mtom
ld hl,xsmall
ld de,acc1
call mtom
ld hl,dxysmall
ld de,acc2
call mtom
call fsub
ld hl,acc1
ld de,fwork03
call mtom
ld b,4
call p3p_compare
; vram2(left:right, triy(1))= co !塗る
; vram3(left:right, triy(1))= 0 !塗る
ld hl,[triy1]
ld [dr_y1],hl
call p3p_hlineminmax
;
; end select
p3p600:
;
;end subroutine drawtriangle
ret

p3p_compare: ;[fwork00]〜[fwork03]を比較する
;b=実数の個数
;[fwork10]=最小値、[fwork11]=最大値
push bc
ld hl,fwork00
push hl
ld de,fwork10
call mtom
pop hl
ld de,fwork11
call mtom
pop bc
dec b
ret z
ld hl,fwork01
p3pc00:
push bc

push hl
ld de,fwork10
push de
call fcp ;暫定最小値-[fwork]
pop de
jr c,p3pc10
pop hl ;fwork
push hl
call mtom
p3pc10:
pop hl
push hl
ld de,fwork11
push de
call fcp ;暫定最大値-[fwork]
pop de
jr nc,p3pc11
pop hl ;fwork
push hl
call mtom
p3pc11:
pop hl
ld de,4
add hl,de

pop bc
djnz p3pc00

ret

p3p_hlineminmax: ;hline(0.5+[fwork10],[dr_y1])-(0.5+[fwork11],[dr_y1])
ld hl,fwork10
ld de,acc1
call mtom
ld hl,float1div2
ld de,acc2
call mtom
call fadd
ret c
call ftoi16
ret c
ld [dr_x1],hl ;min
ld de,320
and a
sbc hl,de
ret p ;min>=320

ld hl,fwork11
ld de,acc1
call mtom
ld hl,float1div2
ld de,acc2
call mtom
call fadd
ret c
call ftoi16
ret c
ld [dr_x2],hl ;max
bit 7,h
ret nz ;max<0

ld hl,[dr_x1] ;min
bit 7,h
jr z,p3ph00
;min<0
ld hl,0
ld [dr_x1],hl
p3ph00:
ld hl,[dr_x2] ;max
ld de,320
and a
sbc hl,de
jr c,p3ph10
;max>=320
ld hl,319
ld [dr_x2],hl
p3ph10:
jp hline

gradation: db 0

gradation_table:
db &ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff
db &ff-&11,&ff-&00,&ff-&44,&ff-&00,&ff-&11,&ff-&00,&ff-&44,&ff-&00
db &ff-&11,&ff-&44,&ff-&88,&ff-&22,&ff-&11,&ff-&44,&ff-&88,&ff-&22
db &55,&aa,&55,&aa,&55,&aa,&55,&aa
db &11,&44,&88,&22,&11,&44,&88,&22
db &11,&00,&44,&00,&11,&00,&44,&00
db &00,&00,&00,&00,&00,&00,&00,&00

gradation_base: dw gradation_table

setgradbase:
ld hl,gradation_table
ld a,[gradation]
add a,a ;*2
add a,a ;*4
add a,a ;*8
ld e,a
ld d,0
add hl,de
ld [gradation_base],hl
ret

isub: ;hl=hl-de(符号付き), cf=status
ld a,d
cpl
ld d,a
ld a,e
cpl
ld e,a
inc de
;
iadd: ;hl=hl+de(符号付き), cf=status
ld a,h
xor d
jp m,iadd00
;同符号
ld a,h
add hl,de
xor h
ret p ;cf=0
scf
ret
iadd00: ;異符号
add hl,de
and a
ret ;cf=0

hline_from: db 1+2+4+8+16+32+64+128
db 2+4+8+16+32+64+128
db 4+8+16+32+64+128
db 8+16+32+64+128
db 16+32+64+128
db 32+64+128
db 64+128
db 128

hline_to: db 1
db 1+2
db 1+2+4
db 1+2+4+8
db 1+2+4+8+16
db 1+2+4+8+16+32
db 1+2+4+8+16+32+64
db 1+2+4+8+16+32+64+128

dr_miny: dw 0
dr_maxy: dw 200
dr_miny2: dw 0
dr_maxy2: dw 0

hline: ;[dr_x1]-[dr_x2],[dr_y1] 横1本を塗る(ただしx1<=x2であること)
;y座標の範囲は[dr_miny]〜[dr_maxy]-1
;x方向は8bit単位で処理するため、0〜320-1とする
ld hl,[dr_y1]
ld de,[dr_miny] ;0
push hl
and a
sbc hl,de
bit 7,h
pop hl
ret nz

ld de,[dr_maxy] ;200
and a
sbc hl,de
ret nc
add hl,de

ld ix,[gradation_base]
ld a,l
and 7
ld [hline_code0+2],a
ld [hline_code1+2],a
ld [hline_code2+2],a

ld d,h
ld e,l
add hl,hl ;*2
add hl,hl ;*4
add hl,de ;*5
add hl,hl ;*10
add hl,hl ;*20
add hl,hl ;*40
hline_code3:
ld de,&e000 ;vram address
add hl,de

exx

ld hl,[dr_x2]
ld de,320
and a
sbc hl,de
ret nc
add hl,de

ld a,l ;to
and 7
ld c,a

srl h ;最大320/2
rr l
srl l ;最大160/2
srl l ;最大80/2

push hl
ld hl,[dr_x1]
ld de,320
and a
sbc hl,de
pop hl
ret nc
ld de,[dr_x1]

ld a,e ;from
and 7
ld b,a

srl d
rr e
srl e
srl e

ld a,l
sub e ;count

ex af,af'

push de

exx
pop de
add hl,de ;vram address (from)
exx

ld hl,hline_from
ld e,b ;from
add hl,de
ld b,[hl]

ld hl,hline_to
ld e,c ;to
add hl,de
ld c,[hl]

ex af,af'
jr nz,hline00
;同じアドレス上にfrom, toがある
ld a,b
and c
ex af,af'
exx

hline_code40:
jp hlineskip00
hlineskip00:
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ld a,&02
out [&f4],a
hlineskip01:

ex af,af'
ld e,a
cpl
and [hl]
ld d,a
hline_code0:
ld a,[ix+0] ;グラデーション
and e
or d
ld [hl],a
jr hline100
hline00:
exx
ld b,a
exx
ld a,b ;from
ex af,af'
exx

hline_code41:
jp hlineskip10
hlineskip10:
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ld a,&02
out [&f4],a
hlineskip11:

ex af,af'
ld e,a ;from
cpl
and [hl]
ld d,a
hline_code1:
ld a,[ix+0]
push af
and e
or d
ld [hl],a
pop af
jr hline10
hline11:
ld [hl],a
hline10:
inc hl
djnz hline11
exx
ld a,c ;to
exx
ld e,a
cpl
and [hl]
ld d,a
hline_code2:
ld a,[ix+0]
and e
or d
ld [hl],a
;
hline100:
in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

ret

clsc: ;キャラクタvramをクリアする
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a

ld hl,&d000 ;vramクリア
ld de,&d000+1
ld bc,80*25-1
ld [hl],0
ldir

in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

ret

clsv: ;vramをクリアする
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ld a,&02
out [&f4],a

ld hl,&e000 ;vramクリア
ld de,&e000+1
ld bc,320*200/8-1
ld [hl],0
ldir

in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

ret

dr_x1: dw 0
dr_y1: dw 0
dr_x2: dw 0
dr_y2: dw 0
dr_dx: dw 0
dr_dy: dw 0
dr_s: dw 0
dr_spw: dw 0

pset: ;pset or preset(x1,y1): line/bline専用、他から呼び出さない
ld hl,[dr_y1]
ld bc,200
and a
sbc hl,bc
jr nc,pset10
ld hl,[dr_x1]
ld bc,320
and a
sbc hl,bc
jr c,pset00
pset10:
;(x1,y1)が範囲外
exx
bit 1,c
exx
ret z ;範囲外なので引き続きフェーズ=0を続ける
;フェーズ=1(範囲内)から範囲外へ移動したので終了する
ld sp,[dr_spw]
ret
pset00:
;(x1,y1)が範囲内
exx

bit 1,c
jr z,pset20 ;フェーズ0→1に移行する

;フェーズ1を続ける
ld a,b ;コード
dr_code11: ;&c6(set) or &86(res)
add a,&c6
ld [dr_code2+1],a
jr pset30

pset20: ;フェーズ=0→1に移行する最初のドット
set 1,c
exx
ld hl,[dr_y1]
ld b,h
ld c,l
add hl,hl ;*2
add hl,hl ;*4
add hl,bc ;*5
add hl,hl ;*10
add hl,hl ;*20
add hl,hl ;*40
dr_code3: ;&e000(実際のvram) or 仮想vram
ld bc,&e000 ;vram address
add hl,bc
ex de,hl

ld hl,[dr_x1]
ld a,l
and 7
add a,a
add a,a
add a,a
exx
ld b,a ;コード
exx
dr_code10: ;&c6(set) or &86(res)
add a,&c6
ld [dr_code2+1],a
srl h
rr l
srl h
rr l
srl h
rr l
add hl,de
push hl
exx
pop hl
pset30:
in a,[&e8] ;vramアクセス許可
set 7,a
res 6,a
out [&e8],a
ld a,&02
out [&f4],a

dr_code2: ;&c6+8*bit(set) or &86+8*bit(res)
set 0,[hl]

in a,[&e8] ;vramアクセス禁止
res 7,a
out [&e8],a
ld a,&03
out [&f4],a

exx

ret

line: ;line (dr_x1,dr_y1)-(dr_x2,dr_y2)
ld a,&c6 ;set
jr drawline

bline: ;bline (dr_x1,dr_y1)-(dr_x2,dr_y2)
ld a,&86 ;res
;
drawline:
ld [dr_spw],sp
ld [dr_code10+1],a
ld [dr_code11+1],a

ld c,0 ;フェーズ(bit1)=0
ld de,40
exx

;1000 *DRAWLINE
;1010 DX=ABS (X2-X1):DY=ABS (Y2-Y1)
ld hl,[dr_x1]
ld de,[dr_x2]
and a
sbc hl,de
bit 7,h
jr z,dr00
ex de,hl
xor a
ld h,a
ld l,a
sbc hl,de
dr00: ld [dr_dx],hl
ld hl,[dr_y1]
ld de,[dr_y2]
and a
sbc hl,de
bit 7,h
jr z,dr01
ex de,hl
xor a
ld h,a
ld l,a
sbc hl,de
dr01: ld [dr_dy],hl

;1020 10) IF DX>DY THEN
ld hl,[dr_dy] ;0>dy-dx
ld de,[dr_dx]
and a
sbc hl,de
bit 7,h
jr nz,dr10
jp dr1000
dr10:
;1030 20) IF X1>X2 THEN
ld hl,[dr_x2] ;0>x2-x1
ld de,[dr_x1]
and a
sbc hl,de
bit 7,h
jr nz,dr20
jp dr2000
dr20:
;1031 30) IF Y1>Y2 THEN ST=1 ELSE ST=-1
ld hl,[dr_y2] ;0>y2-y1
ld de,[dr_y1]
and a
sbc hl,de
bit 7,h
exx
jr z,dr3010
set 0,c ;c(bit0)=1のときst=1
jr dr3000
dr3010: res 0,c ;c(bit0)=0のときst=-1
dr3000: exx

;1032 S=X1:X1=X2:X2=S:Y1=Y2
ld hl,[dr_x1]
ld de,[dr_x2]
ld [dr_x1],de
ld [dr_x2],hl
ld hl,[dr_y2]
ld [dr_y1],hl

jp dr2010
;1040 20) ELSE
dr2000:
;1041 31) IF Y1<Y2 THEN ST=1 ELSE ST=-1
ld hl,[dr_y1] ;y1-y2<0
ld de,[dr_y2]
and a
sbc hl,de
bit 7,h
exx
jr z,dr3110
set 0,c ;c(bit0)=1のときst=1
jr dr3100
dr3110: res 0,c ;c(bit0)=0のときst=-1
dr3100: exx

;1050 20) ENDIF
dr2010:
;1060 X=X1:Y=Y1:GOSUB *DOT
call pset
;1070 S=INT (DX/2)
ld hl,[dr_dx]
srl h
rr l
ld [dr_s],hl
;1080 X1=X1+1
ld hl,[dr_x1]
inc hl
ld [dr_x1],hl

exx
ld a,b
add a,8
and 7*8
ld b,a
jr nz,drix01
inc hl
drix01: exx

;1090 32) WHILE X1<=X2
dr3200:
ld hl,[dr_x2] ;0<=x2-x1
ld de,[dr_x1]
and a
sbc hl,de
bit 7,h
jr nz,dr3210
;1091 S=S-DY
ld hl,[dr_s]
ld de,[dr_dy]
and a
sbc hl,de
ld [dr_s],hl
;1092 40) IF S<0 THEN S=S+DX:Y1=Y1+ST
bit 7,h
jr z,dr4000
ld de,[dr_dx]
add hl,de
ld [dr_s],hl
ld hl,[dr_y1]
exx
bit 0,c ;c(bit0)=1のときst=1
exx
jr nz,dr4010

dec hl
ld [dr_y1],hl

exx
and a
sbc hl,de
exx

jr dr4000
dr4010:
inc hl
ld [dr_y1],hl

exx
add hl,de
exx
dr4000:
;1093 X=X1:Y=Y1:GOSUB *DOT
call pset
;1094 X1=X1+1
ld hl,[dr_x1]
inc hl
ld [dr_x1],hl

exx
ld a,b
add a,8
and 7*8
ld b,a
jr nz,drix02
inc hl
drix02: exx

;1095 32) WEND
jr dr3200
dr3210:
jp dr1010
;1100 10) ELSE
dr1000:
;1110 20a) IF Y1>Y2 THEN
ld hl,[dr_y2] ;0>y2-y1
ld de,[dr_y1]
and a
sbc hl,de
bit 7,h
jr nz,dr20a
jp dr2000a
dr20a:
;1111 30a) IF X1>X2 THEN ST=1 ELSE ST=-1
ld hl,[dr_x2] ;0>x2-x1
ld de,[dr_x1]
and a
sbc hl,de
bit 7,h
exx
jr z,dr3010a
set 0,c ;c(bit0)=1のときst=1
jr dr3000a
dr3010a:res 0,c ;c(bit0)=0のときst=-1
dr3000a:exx

;1112 S=Y1:Y1=Y2:Y2=S:X1=X2
ld hl,[dr_y1]
ld de,[dr_y2]
ld [dr_y1],de
ld [dr_y2],hl
ld hl,[dr_x2]
ld [dr_x1],hl

jp dr2010a
;1120 20a) ELSE
dr2000a:
;1121 31a) IF X1<X2 THEN ST=1 ELSE ST=-1
ld hl,[dr_x1] ;x1-x2<0
ld de,[dr_x2]
and a
sbc hl,de
bit 7,h
exx
jr z,dr3110a
set 0,c ;c(bit0)=1のときst=1
jr dr3100a
dr3110a:res 0,c ;c(bit0)=0のときst=-1
dr3100a:exx

;1130 20a) ENDIF
dr2010a:
;1140 X=X1:Y=Y1:GOSUB *DOT
call pset
;1150 S=INT (DY/2)
ld hl,[dr_dy]
srl h
rr l
ld [dr_s],hl
;1160 Y1=Y1+1
ld hl,[dr_y1]
inc hl
ld [dr_y1],hl

exx
add hl,de
exx

;1170 32a) WHILE Y1<=Y2
dr3200a:
ld hl,[dr_y2] ;0<=y2-y1
ld de,[dr_y1]
and a
sbc hl,de
bit 7,h
jr nz,dr3210a
;1171 S=S-DX
ld hl,[dr_s]
ld de,[dr_dx]
and a
sbc hl,de
ld [dr_s],hl
;1172 40a) IF S<0 THEN S=S+DY:X1=X1+ST
bit 7,h
jr z,dr4000a
ld de,[dr_dy]
add hl,de
ld [dr_s],hl
ld hl,[dr_x1]
exx
bit 0,c ;c(bit0)=1のときst=1
exx
jr nz,dr4010a
dec hl
ld [dr_x1],hl

exx
ld a,b
sub 8
and 7*8
ld b,a
cp 7*8
jr nz,drdx01
dec hl
drdx01: exx

jr dr4000a
dr4010a:inc hl
ld [dr_x1],hl

exx
ld a,b
add a,8
and 7*8
ld b,a
jr nz,drix03
inc hl
drix03: exx

dr4000a:
;1173 X=X1:Y=Y1:GOSUB *DOT
call pset
;1174 Y1=Y1+1
ld hl,[dr_y1]
inc hl
ld [dr_y1],hl

exx
add hl,de
exx

;1175 32a) WEND
jr dr3200a
dr3210a:
;1180 10) ENDIF
dr1010:
;1190 RETURN
ret

itof16: ;hl=int --> acc1=float
ld a,h
or l
jr nz,itof1600

ld [acc1+0],a
ret
itof1600:
ld a,h
and 128
ld [acc1+0],a
jr z,itof1602
;cf=0
ex de,hl
ld hl,0
sbc hl,de
itof1602:
ld a,h
and a
jr z,itof1611
;16bit
ld b,64+16
itof1620:
dec b
ld d,h
ld e,l
add hl,hl
jr nc,itof1620
ld hl,acc1+0
ld a,[hl]
or b
ld [hl],a
inc hl
ld [hl],0 ;+1
inc hl
ld [hl],e ;+2
inc hl
ld [hl],d ;+3
ret

itof1611: ;8bit
ld a,l
ld b,64+8
itof1610:
dec b
add a,a
jr nc,itof1610
rra
ld c,a
ld hl,acc1+0
ld a,[hl]
or b
ld [hl],a
inc hl
ld [hl],0 ;+1
inc hl
ld [hl],0 ;+2
inc hl
ld [hl],c ;+3
ret

ftoi16: ;acc1 --> hl=int acc1, cf=status
;範囲は-8191〜8191、範囲外はcf=1
;1) acc1の整数部を取る
;2) ただしacc1が負で小数部が0でない場合は-1する
;int(2)=2, int(1.9)=1, int(1)=1, int(0.9)=0, int(0)=0
;int(-2)=-2, int(-1.9)=-2, int(-1.1)=-2, int(-1)=-1, int(-0.9)=-1, int(-0.1)=-1
call ftoi1600
ret c
ld b,a
bit 7,c
ret z ;cf=0, 正数
;負数
ex de,hl
xor a
ld h,a
ld l,a
sbc hl,de
ld a,b
and a
ret z ;cf=0, 小数部が0の負数
dec hl
ret ;cf=0, 小数部が0でない負数

ftoi1600: ;acc1 --> hl=int abs acc1, c=sign, a=0なら小数部は0, cf=status
ld a,[acc1+0]
ld c,a
ld hl,0
and a
ret z ;hl=0, a=0, cf=0
and 127
sub 64
ccf
ret nc ;hl=0, a!=0, cf=0
inc a
ld de,[acc1+2]
cp 8
jr c,ftoi1611
ld l,d
ld d,e
ld e,0
sub 8
jr z,ftoi1612
ftoi1611:
ld b,a
ftoi1610:
ex de,hl
add hl,hl
ex de,hl
adc hl,hl
bit 5,h
scf
ret nz
djnz ftoi1610
ftoi1612:
ld a,d
or e
ld d,a
ld a,[acc1+1]
or d
ret ;cf=0

keywait:
push hl
call _getkey
pop hl
and a
jr z,keywait
ret

mul2: ;[hl]=[hl]*2, cf=status
ld a,[hl]
and a
ret z ;cf=0
and 127
inc a
scf
ret m ;cf=1
bit 7,[hl] ;符号
jr z,mul21
or 128
mul21:
ld [hl],a
and a
ret ;cf=0

float1div3: db &3e,&ab,&aa,&aa ;1/3

mv0: ;[hl] = 0
ld [hl],0
ret

mv1: ;[hl] = 1
push de
push bc
ex de,hl
ld hl,float1
mv100: call mtom
ex de,hl
pop bc
pop de
ret

mv0p5: ;[hl] = 0.5
push de
push bc
ex de,hl
ld hl,float1div2
jr mv100

chs: ;[hl] = -[hl]
ld a,[hl]
and a
ret z
xor 128
ld [hl],a
nnop: ret

mul: ;y*x -> x
call popacc12
call fmul
mtox100:push af
ld hl,acc1
call mtox
pop af
ret

div: ;y/x -> x
call popacc12
call fdiv
jr mtox100

ad: ;y+x -> x
call popacc12
call fadd
jr mtox100

sb: ;y-x -> x
call popacc12
call fsub
jr mtox100

sqr: ;sqr(x) -> x
call popacc1
call fsqrt
jr mtox100

exp: call popacc1
call fexp
jr mtox100

ln: call popacc1
call flog
jr mtox100

sin: call popacc1
call fsin
jr mtox100

cos: call popacc1
call fcos
jr mtox100

errmsg4: db 'stack over flow',13
err4: ;stack over flow
ld hl,errmsg4
call message
call crlf
jp _monitor

mtox: ;float stack push = float [hl]
ex de,hl
ld hl,[ptrstackpointer]
ld bc,4
and a
sbc hl,bc
;cf=0
ld bc,floatstack
sbc hl,bc
jr c,err4
add hl,bc
ld [ptrstackpointer],hl
ex de,hl
;
mtom: ;float [de] = float [hl]
ld bc,4
ldir
ret

popacc12:
ld hl,acc2
call xtom
;
popacc1:ld hl,acc1
;
xtom: ;float [hl] = float stack pop
ex de,hl
ld hl,[ptrstackpointer]
ld bc,floatstacktop
and a
sbc hl,bc
jr nc,err4 ;スタックが空である
add hl,bc
call mtom
ld [ptrstackpointer],hl
ret

floatsqrt2: db &40,&f3,&04,&b5 ;sqrt(2)

fsqrt: ;acc1=sqrt(acc1), cf=status
ld hl,acc1
push hl
call is0
pop hl
ret z ;cf=0
bit 7,[hl]
scf
ret nz ;acc1<0

ld a,[hl]
and 127 ;指数部
ld [charwork00],a
ld [hl],64 ;1<=acc1<2とする

;6040 Y0=Y:Y=1+(Y-1)/2 ;SQR Yの概略の近似値を出しておく
ld hl,acc1
ld de,acc3
ld bc,4
ldir

ld hl,float1
ld de,acc2
ld c,4
ldir
call fsub
ret c

ld hl,acc1
call fatn30

ld hl,float1
ld de,acc2
ld bc,4
ldir
call fadd
ret c

;6050 K=1
ld b,8

fsqr00: push bc

;6051 Y1=Y:Y=(Y0/Y+Y)/2:IF Y1<>Y THEN K=K+1:GOTO 6051;平方根を求めるループ
ld hl,acc1
push hl
push hl
ld de,acc4
ld bc,4
ldir
pop hl
ld de,acc2
ld c,4
ldir
ld hl,acc3
pop de
ld c,4
ldir
call fdiv
jr c,fsqrerr

ld hl,acc4
ld de,acc2
ld bc,4
ldir
call fadd
jr c,fsqrerr

ld hl,acc1
call fatn30

ld hl,acc4
ld de,acc1
call fcp

pop bc

jr z,fsqr10

djnz fsqr00

;++++
ld a,'R'
call pcha
call space

jr fsqr10

fsqrerr:pop bc
scf
ret

fsqr10: ld a,[charwork00]
sub 64
sra a
push af
add a,64
ld [acc1+0],a
pop af
ret nc

ld hl,floatsqrt2
ld de,acc2
ld bc,4
ldir

jp fmul

float1div2: db &3f,&00,&00,&80 ;1/2

farctan: ;acc1=arctan(acc1/acc2), cf=status
ld hl,acc1+0
ld a,[hl]
res 7,[hl]
ld hl,acc2+0
ld b,[hl]
res 7,[hl]
xor b
and 128
ld [charwork00],a

ld de,acc2
ld hl,acc1
call fcp
jr c,fatn00

call fdiv
ret c

call fatn10
ret c
jr fatn02
fatn00:
ld hl,acc1
ld de,acc2
ld b,4
fatn01: ld c,[hl]
ld a,[de]
ex de,hl
ld [hl],c
ld [de],a
ex de,hl
inc hl
inc de
djnz fatn01

call fdiv
ret c

call fatn10
ret c

ld hl,floatpidiv2
ld de,acc2
ld bc,4
ldir
ld hl,acc1+0
ld a,[hl]
xor 128
ld [hl],a
call fadd
ret c
fatn02:
ld hl,acc1+0
ld a,[hl]
and a
ret z ;cf=0
ld a,[charwork00]
xor [hl]
ld [hl],a
and a
ret ;cf=0

floatfatn0to1div2:
db &3c,&52,&b9,&8e ;x^4, 0.06968940951183931151
db &bd,&7e,&28,&8a ;x^3, -0.13492008363515708439
db &3d,&f2,&26,&cc ;x^2, 0.19936732026918082527
db &be,&92,&a8,&aa ;x^1, -0.3333173498572714481
db &40,&00,&00,&80 ;1

floatfatn1div2to1:
db &bc,&2a,&f2,&f7 ;x^3, -0.12106735776398421038
db &3d,&9b,&5e,&cb ;x^2, 0.19860307570476346448
db &be,&44,&a7,&aa ;x^1, -0.33330738096447419754
db &40,&00,&00,&80 ;1

floatarctan1div2:
db &3e,&38,&63,&ed ;arctan(1/2)

fatn10: ;acc1=arctan(acc1)ただし0<=acc1<=1,cf=status
ld de,float1div2
ld hl,acc1
call fcp
jr c,fatn20

;acc1 <= 1/2
ld hl,acc1
push hl
ld de,acc4
ld bc,4
ldir
pop hl
ld de,acc2
ld c,4
ldir
call fmul
ret c

ld hl,floatfatn0to1div2
ld b,5
call fpolynomial
ret c

ld hl,acc4
ld de,acc2
ld bc,4
ldir
jp fmul

fatn20: ;acc1 > 1/2
;(acc1 - 1/2)/(1 + acc1/2)
ld hl,acc1
push hl
ld de,acc3
ld bc,4
ldir
pop hl
call fatn30
ld hl,float1
ld de,acc2
ld bc,4
ldir
call fadd
ret c
ld hl,acc1
ld de,acc4
ld bc,4
ldir

ld hl,acc3
ld de,acc1
ld bc,4
ldir
ld hl,float1div2
ld de,acc2
ld c,4
ldir
call fsub
ret c

ld hl,acc4
ld de,acc2
ld bc,4
ldir
call fdiv
ret c

ld hl,acc1
push hl
ld de,acc4
ld bc,4
ldir
pop hl
ld de,acc2
ld c,4
ldir
call fmul
ret c

ld hl,floatfatn1div2to1
ld b,4
call fpolynomial
ret c

ld hl,acc4
ld de,acc2
ld bc,4
ldir
call fmul
ret c

ld hl,floatarctan1div2
ld de,acc2
ld bc,4
ldir

jp fadd

fatn30: ;[hl]/2
ld a,[hl]
and a
ret z
and 127
dec a
jr z,fatn301
bit 7,[hl]
jr z,fatn301
or 128
fatn301:
ld [hl],a
ret

floatpidiv2: db &40,&db,&0f,&c9 ;pi/2
floatmpidiv2: db &c0,&db,&0f,&c9 ;-pi/2

floatpi: db &41,&db,&0f,&c9 ;pi
floatmpi: db &c1,&db,&0f,&c9 ;-pi

floatfsin:
db &2d,&be,&d5,&ae ;x^4, 2.605243392949960341*10^-6
db &b3,&e5,&b7,&cf ;x^3, -0.00019809564243621044612
db &39,&6d,&87,&88 ;x^2, 0.008333068958302137484
db &bd,&a6,&aa,&aa ;x^1, -0.16666659804159301236
db &40,&00,&00,&80 ;1

floatfcos:
db &30,&34,&3b,&c2 ;x^4, 0.00002315417032094177922
db &b6,&1d,&97,&b5 ;x^3, -0.001385423933941702925
db &3b,&a4,&a7,&aa ;x^2, 0.04166378010744274476
db &be,&e7,&ff,&ff ;x^1, -0.4999992512092836161
db &40,&00,&00,&80 ;1

fcos: ;acc1=cos(acc1), cf=status
ld hl,floatpidiv2
ld de,acc2
ld bc,4
ldir
call fadd
ret c
;
fsin: ;acc1=sin(acc1), cf=status
ld hl,acc1+0
ld a,[hl]
and 128
ld [charwork00],a
res 7,[hl]

ld b,16
fsin00: push bc

ld de,floatpi
ld hl,acc1
call fcp
jr nc,fsin10

ld hl,floatpi
ld de,acc2
ld bc,4
ldir
call fsub

pop bc
ret c
djnz fsin00
scf
ret

fsin10: pop af
ld [charwork01],a

ld de,floatpidiv2
ld hl,acc1
call fcp
jr c,fsin20

;acc1 <= pi/2

ld hl,acc1
push hl
ld de,acc4
ld bc,4
ldir
pop hl
ld de,acc2
ld c,4
ldir
call fmul
ret c

ld hl,floatfsin
ld b,5
call fpolynomial
ret c

ld hl,acc4
ld de,acc2
ld bc,4
ldir
call fmul
ret c

jr fsin30

fsin20: ;acc1 > pi/2
ld hl,floatpidiv2
ld de,acc2
ld bc,4
ldir
call fsub
ret c

ld hl,acc1
ld de,acc2
ld bc,4
ldir
call fmul
ret c

ld hl,floatfcos
ld b,5
call fpolynomial
ret c
;
fsin30: ld a,[charwork01]
rrca
and 128
ld b,a
ld a,[charwork00]
xor b
ld b,a
ld hl,acc1+0
ld a,[hl]
and a
ret z ;cf=0
or b
ld [hl],a
ret ;cf=0

inputbcdacc1: ;[ix~]=character --> acc1=number, cf=status
;cf=0のとき、正常終了、ix=next address
;cf=1のとき、エラー終了、ix=保存
;[acc5]=小数点以上の合計
;[acc6]=小数点以下の合計
;[acc7]=10, 100, 1000, 10000, ...
;[acc8]=10のべき乗

ld [intwork00],ix

ld hl,float1
ld de,acc8
ld bc,4
ldir

xor a
ld [acc5+0],a
ld [acc6+0],a

ld a,[ix]
cp '.'
jp z,inba10

call isnumber
ret c

inba00: push af
ld hl,acc5
ld de,acc1
ld bc,4
ldir
ld hl,float10
ld de,acc2
ld c,4
ldir
call fmul
ld hl,acc1
ld de,acc2
ld bc,4
ldir
pop bc
jr c,inbaerr
ld a,b
call itof
call fadd
jr c,inbaerr
ld hl,acc1
ld de,acc5
ld bc,4
ldir

inc ix
ld a,[ix]
cp '.'
jr z,inba10
cp 'e'
jp z,inba20

call isnumber
jr nc,inba00
;
inbaend:ld hl,acc5
ld de,acc1
ld bc,4
ldir
ld hl,acc6
ld de,acc2
ld c,4
ldir
call fadd
jr c,inbaerr
ld hl,acc8
ld de,acc2
ld bc,4
ldir
call fmul
ret nc
;
inbaerr:ld ix,[intwork00]
scf
ret

inba10: ;[ix]='.'
ld hl,float10
ld de,acc7
ld bc,4
ldir

inba11: inc ix
ld a,[ix]
cp 'e'
jr z,inba20

call isnumber
jr c,inbaend

call itof
ld hl,acc7
ld de,acc2
ld bc,4
ldir
call fdiv
jr c,inbaerr
ld hl,acc6
ld de,acc2
ld bc,4
ldir
call fadd
jr c,inbaerr

ld hl,acc1
ld de,acc6
ld bc,4
ldir

ld hl,acc7
ld de,acc1
ld c,4
ldir

ld hl,float10
ld de,acc2
ld c,4
ldir

call fmul
jr c,inbaerr

ld hl,acc1
ld de,acc7
ld bc,4
ldir

jr inba11

inba20: ;[ix]='e'
inc ix
ld a,[ix]
cp '+'
jr z,inba21
cp '-'
jr z,inba21
call isnumber
jp c,inbaerr
ld a,'+'
dec ix
inba21: inc ix
ex af,af'
call inba30
jp c,inbaerr
ex af,af'
cp '+'
jr z,inba22
ld a,b
neg
ld b,a
inba22: ld a,b
call itof
call fexp10
jp c,inbaerr
ld hl,acc1
ld de,acc8
ld bc,4
ldir
jp inbaend

inba30: ld b,0
ld a,[ix]
call isnumber
ret c
inba31: ld c,a
ld a,b
add a,a
ret c
add a,a
ret c
add a,b
ret c
add a,a
ret c
add a,c
ret c
cp 100
ccf
ret c
ld b,a
inc ix
ld a,[ix]
call isnumber
jr nc,inba31
and a
ret ;cf=0

isnumber: ;a=character --> 数字のとき cf=0, a=数、数字でないとき cf=1
sub '0'
ret c
cp 10
ccf
ret

float10:db &43,&00,&00,&a0 ;10

printbcdacc1: ;[ix~]=bcd acc1
ld a,[acc1+0]
and a
jr nz,prba00

ld [ix],'0'
inc ix
ret
prba00:
and 128
ld [charwork00],a
ld hl,acc1+0
res 7,[hl]

ld hl,acc1
ld de,acc5
ld bc,4
ldir

ld iy,charwork02

call flog10
call ftoi
bit 7,c
jr z,prba13
neg
prba13:
ld [iy],a
call itof
call fexp10

ld hl,acc1
ld de,acc2
ld bc,4
ldir
ld hl,acc5
ld de,acc1
ld c,4
ldir
call fdiv
prba10:
ld de,acc1
ld hl,float1
call fcp
jr nc,prba11
;acc1<1
ld hl,float10
ld de,acc2
ld bc,4
ldir
call fmul
dec [iy]
jr prba10
prba11:
ld de,acc1
ld hl,float10
call fcp
jr c,prba12
;acc1>=10
ld hl,float10
ld de,acc2
ld bc,4
ldir
call fdiv
inc [iy]
jr prba10
prba12:
ld iy,charwork01

call ftoi
ld [iy],a
inc iy

ld b,6
prba20:
push bc

ld hl,acc1
ld de,acc2
ld bc,4
ldir
call itof
ld hl,acc1+0
ld a,[hl]
and a
jr z,prba201
or 128
prba201:
ld [hl],a
call fadd
ld hl,acc1
ld de,acc2
ld bc,4
ldir
ld a,10
call itof
call fmul
call ftoi
ld [iy],a
inc iy

pop bc
djnz prba20

ld hl,charwork00
ld a,[hl]
and a
ld a,'+'
jr z,prba30
ld a,'-'
prba30: ld [ix],a
inc ix

ld hl,charwork01+6
ld a,[hl]
ld [hl],0
cp 5
jr c,prba31
ld b,6
prba32:
ld [hl],0
dec hl
inc [hl]
ld a,[hl]
cp 10
jr c,prba31
djnz prba32

ld [hl],1
ld hl,charwork02
inc [hl]
prba31:
ld hl,charwork01
ld a,[charwork02]
ld c,a
ld b,6
and a
jp m,prba33
cp 6
jr nc,prba40

;xxxx.yyyy
inc c
prba60:
ld a,[hl]
inc hl
add a,'0'
ld [ix],a
inc ix
dec b
dec c
jr nz,prba60

inc b
dec b
ret z

call prba70
ret z

ld [ix],'.'
inc ix
prba61:
ld a,[hl]
inc hl
add a,'0'
ld [ix],a
inc ix
call prba70
ret z
djnz prba61
ret

prba33: cp -3
jr c,prba40
;
prba50: ;0.000xxxx
ld [ix],'0'
inc ix
ld [ix],'.'
inc ix
jr prba51
prba52:
ld [ix],'0'
inc ix
prba51: inc c
jr nz,prba52
jr prba61

prba40: ;x.yyyyyezz
ld a,[hl]
inc hl
add a,'0'
ld [ix],a
inc ix

ld b,5

call prba70
jr z,prba42

ld [ix],'.'
inc ix
prba41:
ld a,[hl]
inc hl
add a,'0'
ld [ix],a
inc ix
call prba70
jr z,prba42
djnz prba41
prba42:
ld [ix],'e'
inc ix
ld a,[charwork02]
ld b,a
jp printbcdb

prba70: push bc
push hl
prba71: ld a,[hl]
inc hl
and a
jr nz,prba72
djnz prba71
prba72: pop hl
pop bc
ret

fcp: ;[de] - [hl] --> zf,cf=status
push de
ld de,ftmpx ;[ftmpx]=[hl]
ld bc,4
ldir
pop hl
ld de,ftmpy ;[ftmpy]=[de]
ld c,4
ldir

ld hl,ftmpy
push hl
call is0
pop hl
jr z,cp00
bit 7,[hl]
jr z,cp01
ld b,0 ;[y]<0
jr cp02
cp00: ld b,1 ;[y]==0
jr cp02
cp01: ld b,2 ;[y]>0
cp02:
ld hl,ftmpx
push hl
call is0
pop hl
jr z,cp10
bit 7,[hl]
jr z,cp11
ld a,0 ;[x]<0
jr cp12
cp10: ld a,3 ;[x]==0
jr cp12
cp11: ld a,6 ;[x]>0
cp12:
add a,b
jr z,xlt0ylt0
dec a
jr z,xlt0yeq0
dec a
jr z,xlt0ygt0
dec a
jr z,xeq0ylt0
dec a
jr z,xeq0yeq0
dec a
jr z,xeq0ygt0
dec a
jr z,xgt0ylt0
dec a
jr z,xgt0yeq0
dec a
jr z,xgt0ygt0

xlt0ylt0: ;(-) - (-)
call xgt0ygt0
ret z
jr c,cp21
scf
ret
cp21: ld a,1
and a
ret ;zf=0, cf=0

xlt0yeq0: ;(0) - (-)
xlt0ygt0: ;(+) - (-)
xeq0ygt0: ;(+) - (0)
ld a,1
sub 0
ret

xeq0ylt0: ;(-) - (0)
xgt0ylt0: ;(-) - (+)
xgt0yeq0: ;(0) - (+)
ld a,0
sub 1
ret

xeq0yeq0: ;(0) - (0)
sub a
ret

xgt0ygt0: ;(+) - (+)
ld de,ftmpy+0
ld hl,ftmpx+0
ld a,[hl]
and 127
ld b,a
ld a,[de]
and 127
cp b
ret nz
ld de,ftmpy+3
ld hl,ftmpx+3
ld b,3
xgt0ygt000:
ld a,[de]
dec de
cp [hl]
dec hl
ret nz
djnz xgt0ygt000
ret

floatflog2:
db &3e,&72,&f9,&fc ;x^3, 0.4940906034086626992
db &3f,&ec,&41,&92 ;x^2, 0.5713183765901300653
db &3f,&b4,&3f,&f6 ;x^1, 0.9619095603848335652
db &41,&3b,&aa,&b8 ;x^0, 2.8853900817779268147

float2: db &41,&00,&00,&80 ;2

floatlog2divlog10:
db &3e,&9b,&20,&9a ;log 2 / log 10

floatlog2:
db &3f,&18,&72,&b1 ;log 2

flog: ;acc1=x --> acc1=log(x), cf=status
call flog2
ret c
ld hl,floatlog2
ld de,acc2
ld bc,4
ldir
jp fmul

flog10: ;acc1=x --> acc1=log10(x), cf=status
call flog2
ret c
ld hl,floatlog2divlog10
ld de,acc2
ld bc,4
ldir
jp fmul

flog2: ;acc1=x --> acc1=log2(x), cf=status
ld a,[acc1+0]
and a
scf
ret z
ret m

and 127
sub 64
push af

ld a,64
ld [acc1+0],a
ld hl,float1
ld de,acc2
ld bc,4
ldir
call fsub
jr c,flog2e

;acc4 = acc1/(2 + acc1)
ld hl,acc1
ld de,acc3
ld bc,4
ldir
ld hl,float2
ld de,acc2
ld c,4
ldir
call fadd
jr c,flog2e
ld hl,acc1
ld de,acc2
ld bc,4
ldir
ld hl,acc3
ld de,acc1
ld c,4
ldir
call fdiv
jr c,flog2e
ld hl,acc1
push hl
ld de,acc4
ld bc,4
ldir
;acc1=acc4^2
pop hl
ld de,acc2
ld c,4
ldir
call fmul
jr c,flog2e

ld hl,floatflog2
ld b,4
call fpolynomial
jr c,flog2e

ld hl,acc4
ld de,acc2
ld bc,4
ldir
call fmul
jr c,flog2e

ld hl,acc1
ld de,acc2
ld bc,4
ldir

pop af

call itof

jp fadd

flog2e: pop bc
scf
ret

floatfexp2:
db &36,&ba,&9f,&f8 ;x^5, 0.0018968500441373925430
db &39,&96,&99,&92 ;x^4, 0.008947750309703873759
db &3b,&86,&c8,&e4 ;x^3, 0.05585529641316513080
db &3d,&21,&e9,&f5 ;x^2, 0.2401471231302491269
db &3f,&79,&72,&b1 ;x^1, 0.6931529801027444760
float1: db &40,&00,&00,&80 ;1

floatm1: db &c0,&00,&00,&80 ;-1

floatlog10divlog2:
db &41,&78,&9a,&d4 ;log 10 / log 2

float1divlog2:
db &40,&3b,&aa,&b8 ;1 / log(2)

fexp: ;acc1=x --> acc1=e^x, cf=status
ld hl,float1divlog2
ld de,acc2
ld bc,4
ldir
call fmul
ret c
jr fexp2

fexp10: ;acc1=x --> acc1=10^x, cf=status
ld hl,floatlog10divlog2
ld de,acc2
ld bc,4
ldir
call fmul
ret c
;
fexp2: ;acc1=x --> acc1=2^x, cf=status
ld a,[acc1+0]
add a,a
jr nc,fexp200

call ftoi
jr c,fexp210 ;2^LT(-127)
bit 7,c
jr z,fexp202 ;2^GE(0)
cp 64
jr nc,fexp210 ;2^LT(-63)
fexp202:
ld hl,acc1+0
res 7,[hl]
call fexp200
ret c
ld hl,acc1
ld de,acc2
ld bc,4
ldir
ld hl,float1
ld de,acc1
ld c,4
ldir
jp fdiv

fexp210:xor a
ld [acc1+0],a
ret ;cf=0

fexp200:call ftoi
ret c
push af
ld hl,acc1
ld de,acc2
ld bc,4
ldir
call itof
ld hl,acc1+0
ld a,[hl]
and a
jr z,fexp201
set 7,[hl]
fexp201:
call fadd
pop bc
ret c
push bc
ld hl,floatfexp2
ld b,6
call fpolynomial
pop bc
ret c
ld a,[acc1+0]
and a
ret z ;cf=0
add a,b
ld [acc1+0],a
and a
ret p ;cf=0
scf
ret ;cf=1

fpolynomial: ;acc1=x, hl=ptr constant, b=count --> acc1=polynomial, cf=status
exx
ld hl,acc1
ld de,acc3
ld bc,4
ldir
exx
push bc
ld de,acc2
ld bc,4
ldir
push hl
call fmul
pop hl
pop bc
ret c

djnz fpoly00

ret ;cf=0

fpoly01:
exx
ld hl,acc3
ld de,acc2
ld bc,4
ldir
exx
push bc
push hl
call fmul
pop hl
pop bc
ret c
fpoly00:
push bc
ld de,acc2
ld bc,4
ldir
push hl
call fadd
pop hl
pop bc
ret c

djnz fpoly01

ret ;cf=0

printbcdb: ;[ix~] = bcd b
inc b
dec b
jr nz,pbcdb00

ld [ix],'0'
inc ix
ret
pbcdb00:
bit 7,b
ld a,'+'
jr z,pbcdb10
ld a,b
neg
ld b,a
ld a,'-'
pbcdb10:
ld [ix],a
inc ix

ld c,0
ld a,b

ld b,100
call pbcdb20
ld b,10
call pbcdb20
add a,'0'
ld [ix],a
inc ix
ret

pbcdb20:ld d,-1
pbcdb21:
inc d
sub b
jr nc,pbcdb21

add a,b

ex af,af'
ld a,d
and a
jr z,pbcdb22

add a,'0'
ld [ix],a
inc ix
ld c,1
jr pbcdb23
pbcdb22:
inc c
dec c
jr z,pbcdb23

ld [ix],'0'
inc ix

pbcdb23:ex af,af'
ret

itof: ;a=int --> acc1=float
and a
jr nz,itof00

ld [acc1+0],a
ret
itof00:
jp p,itof02

ex af,af'
ld a,128
ex af,af'
neg
jr itof01
itof02:
ex af,af'
xor a
ex af,af'
itof01:
ld bc,(64+8)*256+0
itof10: dec b
add a,a
jr nc,itof10
rra
ld hl,acc1+0
ex af,af'
or b
ld [hl],a ;+0
ex af,af'
inc hl
ld [hl],c ;+1
inc hl
ld [hl],c ;+2
inc hl
ld [hl],a ;+3
ret

ftoi: ;acc1 --> a=int abs acc1, c=sign, cf=status
ld a,[acc1+0]
ld c,a
and a
jr z,ftoi00
and 127
sub 64
jr c,ftoi00
inc a
ld b,a
ld hl,[acc1+3]
ld h,0
ftoi10:
add hl,hl
bit 7,h
scf
ret nz
djnz ftoi10
ld a,c
and 128
ld c,a
ld a,h
ret ;cf=0

ftoi00: xor a
ld c,a
ret ;cf=0

fadd_table: dw fsft00,fsft01,fsft02,fsft03,fsft04,fsft05,fsft06,fsft07
dw fsft08,fsft09,fsft10,fsft11,fsft12,fsft13,fsft14,fsft15
dw fsft16,fsft17,fsft18,fsft19,fsft20,fsft21,fsft22,fsft23
dw fsft24

fsub: ;acc1=acc1-acc2, cf=status
ld hl,acc2
call chs
;
fadd: ;acc1=acc1+acc2, cf=status
ld hl,acc2
call is0
ret z ;cf=0
ld hl,acc1
call is0
jr nz,fadd00

ld hl,acc2
ld de,acc1
ld bc,4
ldir
and a ;cf=0
ret
fadd00:
ld a,[acc2+3]
ld c,a
ld de,[acc2+1]
ld a,[acc1+3]
ld b,a
ld hl,[acc1+1]

exx
ld a,[acc2+0]
ld d,a ;符号
and 127
ld e,a ;指数
ld a,[acc1+0]
ld h,a ;符号
and 127
ld l,a ;指数

cp e
jr nz,fadd10

exx
ld a,b
cp c
jr nz,fadd11
ld a,h
cp d
jr nz,fadd11
ld a,l
cp e
fadd11:
exx
fadd10:
jr nc,fadd20

;abs acc2 > abs acc1

ex af,af'
ld a,h
xor d ;同符号か異符号かを保持
ex af,af'

ld a,e
sub l
ld b,a ;シフトカウンタ
ld l,e ;答えの指数
ld a,d
and 128
ld h,a ;答えの符号

exx
ld a,b
ld b,c
ld c,a
ex de,hl
exx
jr fadd21
fadd20:
;abs acc1 >= abs acc2

ex af,af'
ld a,h
xor d ;同符号か異符号かを保持
ex af,af'

ld a,l
sub e
ld b,a ;シフトカウンタ
;l=答えの指数
ld a,h
and 128
ld h,a ;答えの符号
fadd21:
ld a,b
cp 25
jp nc,fadd30

;シフト数0〜24
ld [fadd_work00],hl
ld hl,fadd_table
add a,a
add a,l
ld l,a
ld a,h
adc a,0
ld h,a
ld a,[hl]
inc hl
ld h,[hl]
ld l,a
push hl
ld hl,[fadd_work00]
xor a ;bit7=丸め
exx
ret

fsft24:
ld a,c
ld e,0
ld d,0
ld c,0
jp fsft00
fsft23:
ld a,d ;16回シフト
ld e,c
ld d,0
ld c,0
add a,a ;1回逆シフト
rl e
rl d
ld a,e ;8回シフト
ld e,d
ld d,c
jp fsft00
fsft22:
ld a,d ;16回シフト
ld e,c
ld d,0
ld c,0
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
ld a,e ;8回シフト
ld e,d
ld d,c
jp fsft00
fsft21:
ld a,d ;16回シフト
ld e,c
ld d,0
ld c,0
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
ld a,e ;8回シフト
ld e,d
ld d,c
jp fsft00
fsft20:
ld a,d ;16回シフト
ld e,c
ld d,0
ld c,0
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
add a,a ;1回逆シフト
rl e
rl d
ld a,e ;8回シフト
ld e,d
ld d,c
jp fsft00
fsft19:
ld a,d
ld e,c
ld d,0
ld c,0
jp fsft03
fsft18:
ld a,d
ld e,c
ld d,0
ld c,0
jp fsft02
fsft17:
ld a,d
ld e,c
ld d,0
ld c,0
jp fsft01
fsft16:
ld a,d
ld e,c
ld d,0
ld c,0
jp fsft00
fsft15:
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
add a,a ;1回逆シフト
rl e
rl d
rl c
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
jp fsft00
fsft14:
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
add a,a ;1回逆シフト
rl e
rl d
rl c
add a,a ;1回逆シフト
rl e
rl d
rl c
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
jp fsft00
fsft13:
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
add a,a ;1回逆シフト
rl e
rl d
rl c
add a,a ;1回逆シフト
rl e
rl d
rl c
add a,a ;1回逆シフト
rl e
rl d
rl c
ld a,e ;8回シフト
ld e,d
ld d,c
ld c,0
jp fsft00
fsft12:
ld a,e
ld e,d
ld d,c
ld c,0
jp fsft04
fsft11:
ld a,e
ld e,d
ld d,c
ld c,0
jp fsft03
fsft10:
ld a,e
ld e,d
ld d,c
ld c,0
jp fsft02
fsft09:
ld a,e
ld e,d
ld d,c
ld c,0
jp fsft01
fsft08:
ld a,e
ld e,d
ld d,c
ld c,0
jp fsft00
fsft05:
sla e
rl d
rl c
rla
fsft06:
sla e
rl d
rl c
rla
fsft07:
sla e
rl d
rl c
rla
ex af,af'
ld a,e ;丸めビット
ld e,d
ld d,c
ex af,af'
ld c,a ;最上位
ex af,af'
;a=丸めビット、f=同符号か異符号か
jp m,fsub000310
jp fadd000310
fsft04:
srl c
rr d
rr e
rra
fsft03:
srl c
rr d
rr e
rra
fsft02:
srl c
rr d
rr e
rra
fsft01:
srl c
rr d
rr e
rra
fsft00:
ex af,af'
jp m,fsub0003

ex af,af'
fadd000310:
add a,a
adc hl,de
ld a,b
adc a,c
jr nc,fadd_end

exx
inc l ;指数
ret m ;cf=1
exx
rra
rr h
rr l
;
fadd_end:
ld [acc1+3],a
ld [acc1+1],hl
exx
ld a,h ;符号
or l ;指数
ld [acc1+0],a
ret ;cf=0

fsub0003:
ex af,af'
fsub000310:
neg
sbc hl,de
ld e,a
ld a,b
sbc a,c
ld b,a

or h
or l
jr nz,fsub41
;
fadd_z: xor a
ld [acc1+0],a
ret ;cf=0

fsub41: ld a,b
and a
jr nz,fsub42

exx
ld a,l ;指数
sub 8
jr c,fadd_z
jr z,fadd_z
ld l,a

exx
ld b,h
ld h,l
ld l,e
ld e,0

jr fsub41

fsub43:
and a
fsub42:
jp m,fsub44

sla e
adc hl,hl
rla

exx
dec l
exx
jr nz,fsub43
jr fadd_z

fsub44: ;丸め
bit 7,e
jr z,fadd_end
inc l
jr nz,fadd_end
inc h
jr nz,fadd_end
inc a
jr nz,fadd_end
ld a,&80
exx
inc l
scf
ret m ;cf=1
exx
jr fadd_end

fadd30: ld a,h
or l
ld [acc1+0],a
exx
ld [acc1+1],hl
ld a,b
ld [acc1+3],a
ret ;cf=0

frcp: ;acc1=1/acc1, cf=status
ld hl,acc1
ld de,acc2
call mtom
ld hl,float1
ld de,acc1
call mtom
;
fdiv: ;acc1=acc1/acc2, cf=status
ld hl,acc2
call is0
scf
ret z
ld hl,acc1
call is0
ret z ;cf=0

ld hl,[acc1+1]
ld a,[acc1+3]
ld de,[acc2+1]
ld bc,[acc2+3]
ld b,0

exx
ld b,24
fdiv00:
exx

bit 7,b
jr nz,fdiv03

cp c
jr c,fdiv001

and a
sbc hl,de
sbc a,c
jr nc,fdiv01

add hl,de
adc a,c
fdiv001:
exx
add hl,hl
rl c
exx
jr fdiv02
fdiv03:
and a
sbc hl,de
sbc a,c
fdiv01:
exx
scf
adc hl,hl
rl c
exx
fdiv02:
add hl,hl
adc a,a
rr b

exx
djnz fdiv00

;丸めビット
ld b,2
fdiv10:
exx

bit 7,b
jr nz,fdiv13

and a
sbc hl,de
sbc a,c
jr nc,fdiv11

add hl,de
adc a,c
exx
and a
rl e
exx
jr fdiv12
fdiv13:
and a
sbc hl,de
sbc a,c
fdiv11:
exx
scf
rl e
exx
fdiv12:
add hl,hl
adc a,a
rr b

exx
djnz fdiv10

rrc e
rrc e

ex af,af'
xor a

bit 7,c
jr nz,fdiv20

dec a
sla e
adc hl,hl
rl c
fdiv20:
;丸め
bit 7,e
jr z,fdiv21
inc l
jr nz,fdiv21
inc h
jr nz,fdiv21
inc c
jr nz,fdiv21
ld c,&80
inc a
fdiv21:
ex af,af'

exx

ld a,[acc1+0]
ld b,a
and 127
ld d,a
ld a,[acc2+0]
ld c,a
and 127
ld e,a

ld a,d
sub e
jr c,fdiv30

;答え>=1
add a,64
scf
ret m ;over flow

ld d,a
ex af,af'
add a,d
scf
ret m ;over flow
jr fdiv31
fdiv30:
;答え<1
add a,64
jp m,fdiv40

ld d,a
ex af,af'
add a,d
jp m,fdiv40
jr z,fdiv40
fdiv31:
ld d,a
ld a,b
xor c
and 128
or d
ld [acc1+0],a
exx
ld [acc1+1],hl
ld a,c
ld [acc1+3],a
ret ;cf=0

fdiv40: ;0とする
xor a
ld [acc1+0],a
ret ;cf=0

fmul: ;acc1=acc1*acc2, cf=status
push ix
push iy
call fmulixiy
pop iy
pop ix
ret

fmulixiy: ;acc1=acc1*acc2, cf=status (ix,iy使用)
ld hl,acc1
call is0
ret z ;cf=0
ld hl,acc2
call is0
jp z,fmul00

ld ix,0
ld iy,0

ld a,[acc2+2]
ld h,a
ld a,[acc2+3]
ld c,a
ld a,[acc1+1] ;iy:ix+=a*(c:h)(上位2byte)
and a
call nz,fmul10

ld hl,[acc2+1]
ld a,[acc2+3]
ld c,a
ld a,[acc1+2] ;iy:ix+=a*(c:hl)(上位3byte)
and a
call nz,fmul20

ld de,[acc2+1]
ld a,[acc2+3]
ld c,a
ld a,[acc1+3] ;iy:ix+=a*(c:de)(上位4byte)
and a
call nz,fmul30

push ix
pop de
push iy
pop hl

ld a,[acc1+0]
ld b,a
ld a,[acc2+0]
ld c,a
xor b
and 128
ex af,af'
ld a,b
and 127
ld b,a
ld a,c
and 127
add a,b
sub 63
jr c,fmul00 ;0とする
jr z,fmul00
scf
ret m ;over flow
ld b,a

fmul60: ;丸め
bit 7,h
jr nz,fmul61
ex de,hl
add hl,hl
ex de,hl
adc hl,hl
dec b
jr nz,fmul60
;
fmul00: xor a ;0とする
ld [acc1+0],a
ret ;cf=0

fmul61: bit 7,e
jr z,fmul70
inc d
jr nz,fmul70
inc l
jr nz,fmul70
inc h
jr nz,fmul70
ld h,&80
inc b
scf
ret m
fmul70:
ld a,d
ld [acc1+1],a
ld [acc1+2],hl
ex af,af'
or b
ld [acc1+0],a
ret ;cf=0

fmul10: ;iy:ix+=a*(c:h)(上位2byte)
;cf=0
ld b,0
rra ;1
jr nc,fmul101
add ix,bc
jr nc,fmul101
inc iy
fmul101:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;2
jr nc,fmul102
add ix,bc
jr nc,fmul102
inc iy
fmul102:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;3
jr nc,fmul103
add ix,bc
jr nc,fmul103
inc iy
fmul103:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;4
jr nc,fmul104
add ix,bc
jr nc,fmul104
inc iy
fmul104:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;5
jr nc,fmul105
add ix,bc
jr nc,fmul105
inc iy
fmul105:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;6
jr nc,fmul106
add ix,bc
jr nc,fmul106
inc iy
fmul106:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;7
jr nc,fmul107
add ix,bc
jr nc,fmul107
inc iy
fmul107:
and a
ret z
sla h
rl c
rl b

;cf=0
rra ;8
ret nc
add ix,bc
ret nc
inc iy
ret

fmul20: ;iy:ix+=a*(c:hl)(上位3byte)
;cf=0
ld b,0
rra ;1
jr nc,fmul201
ld e,h
ld d,c
add ix,de
jr nc,fmul201
inc iy
fmul201:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;2
jr nc,fmul202
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul202a
inc de
fmul202a:
add iy,de
fmul202:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;3
jr nc,fmul203
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul203a
inc de
fmul203a:
add iy,de
fmul203:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;4
jr nc,fmul204
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul204a
inc de
fmul204a:
add iy,de
fmul204:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;5
jr nc,fmul205
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul205a
inc de
fmul205a:
add iy,de
fmul205:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;6
jr nc,fmul206
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul206a
inc de
fmul206a:
add iy,de
fmul206:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;7
jr nc,fmul207
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul207a
inc de
fmul207a:
add iy,de
fmul207:
and a
ret z
add hl,hl
rl c
rl b

;cf=0
rra ;8
ret nc
ld e,h
ld d,c
add ix,de
ld e,b
ld d,0
jr nc,fmul208a
inc de
fmul208a:
add iy,de

ret

fmul30: ;iy:ix+=a*(c:de)(上位4byte)
;cf=0
ld b,0
rra ;1
jr nc,fmul301
add ix,de
jr nc,fmul301a
inc iy
fmul301a:
add iy,bc
fmul301:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;2
jr nc,fmul302
add ix,de
jr nc,fmul302a
inc iy
fmul302a:
add iy,bc
fmul302:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;3
jr nc,fmul303
add ix,de
jr nc,fmul303a
inc iy
fmul303a:
add iy,bc
fmul303:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;4
jr nc,fmul304
add ix,de
jr nc,fmul304a
inc iy
fmul304a:
add iy,bc
fmul304:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;5
jr nc,fmul305
add ix,de
jr nc,fmul305a
inc iy
fmul305a:
add iy,bc
fmul305:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;6
jr nc,fmul306
add ix,de
jr nc,fmul306a
inc iy
fmul306a:
add iy,bc
fmul306:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;7
jr nc,fmul307
add ix,de
jr nc,fmul307a
inc iy
fmul307a:
add iy,bc
fmul307:
and a
ret z
sla e
rl d
rl c
rl b

;cf=0
rra ;8
ret nc
add ix,de
jr nc,fmul308a
inc iy
fmul308a:
add iy,bc

ret

is0: ;hl==ptr acc --> zf=status, cf=0
ld a,[hl]
and a
ret

hotinit:
ld hl,floatstacktop
ld [ptrstackpointer],hl

xor a
ld [gradation],a
call setgradbase

call ml_setrelation

ret

coldinit:
call nc_initeye

call nc_initx0

call setraydirection

ld hl,0
ld [nci_number],hl

xor a
ld [ncb_mode],a

ret

dumpacc:ld b,4
dumpacc00:
ld a,[hl]
inc hl
call hex8
call space
djnz dumpacc00
ret

;****** bios for mz-80b

_monitor= &00b1
_pcha= &08c6
_hex4= &05f3
_input= &06a4
_maxinputstroke=&06a2
_ptrinputdata= &1093
_getkey= &0832

;_input de=入力バッファアドレス
; [_maxinputstroke]: 最大入力文字数(最大79まで設定可)
; [_ptrinputdata+0]=&0b :breakキーが押された
; [_ptrinputdata~]=入力データ(13で終わる)

input: ;cf=0:enterキーが押された
;cf=1:breakキーが押された
;[_ptrinputdata~]=入力データ(大文字を小文字に変換、13で終わる)
ld a,79
ld [_maxinputstroke],a
ld de,_ptrinputdata
call _input ;de保存
ex de,hl
ld a,[hl]
cp &0b
scf
ret z ;cf=1

input00:ld a,[hl]
cp 13
ret z ;cf=0
cp 'A'
jr c,input01
cp 'Z'+1
jr nc,input01
add a,&20
ld [hl],a
input01:inc hl
jr input00

monitor:jp _monitor

crlf: ld a,13
;
pcha: jp _pcha

space: ld a,' '
jr pcha

hex: push hl
push hl
ld a,h
call hex8
pop hl
ld a,l
call hex8
pop hl
ret

hex8: push af
rra
rra
rra
rra
and &0f
call _hex4
call _pcha
pop af
and &0f
call _hex4
jr pcha

message: ;hl:pointer, end mark=&0d
ld a,[hl]
cp &0d
ret z
call _pcha
inc hl
jr message

;******プログラム終了
endaddress:

datastart00=endaddress ;float 作業用

acc1= datastart00+4*0
acc2= datastart00+4*1
acc3= datastart00+4*2
acc4= datastart00+4*3
acc5= datastart00+4*4
acc6= datastart00+4*5
acc7= datastart00+4*6
acc8= datastart00+4*7
ftmpx= datastart00+4*8
ftmpy= datastart00+4*9
fwork00=datastart00+4*10 ;比較する変数
fwork01=datastart00+4*11
fwork02=datastart00+4*12
fwork03=datastart00+4*13
fwork10=datastart00+4*14 ;最小値
fwork11=datastart00+4*15 ;最大値

datastart10=datastart00+4*16 ;int 作業用

intwork00=datastart10+2*0
fadd_work00=datastart10+2*1

datastart20=datastart10+2*2 ;char 作業用

charwork00=datastart20+1*0
charwork01=datastart20+1*1
charwork02=datastart20+1*10

datastart30=datastart20+1*11

datastart40=datastart30

datastart50=datastart40 ;計算用スタック

ptrstackpointer=datastart50
floatstack=datastart50+2*1
floatstacktop=floatstack+256

datastart60=datastart50+2+256

vvram=datastart60 ;仮想vram(320/8*200)
vvram2=vvram+320/8*200 ;仮想vram2(320/8*200)

savedata_start=vvram2+320/8*200 ;セーブデータ

;int eye[3]={0,0,0}; //現在位置
nci_eye=savedata_start
nci_eye_0=nci_eye+2*0
nci_eye_1=nci_eye+2*1
nci_eye_2=nci_eye+2*2

ncf_ray=nci_eye+2*3 ;平行光線
ncf_ray_0=ncf_ray+4*0
ncf_ray_1=ncf_ray+4*1
ncf_ray_2=ncf_ray+4*2

;double x0[3][3]={1,0,0, 0,1,0, 0,0,1};
;//視線方向=(x0[0][2], x0[1][2], x0[2][2])
ncf_x0=ncf_ray+4*3
ncf_x0_00=ncf_x0+4*0
ncf_x0_01=ncf_x0+4*1
ncf_x0_02=ncf_x0+4*2
ncf_x0_10=ncf_x0+4*3
ncf_x0_11=ncf_x0+4*4
ncf_x0_12=ncf_x0+4*5
ncf_x0_20=ncf_x0+4*6
ncf_x0_21=ncf_x0+4*7
ncf_x0_22=ncf_x0+4*8

ncb_mode=ncf_x0+4*9 ;表示モード(0=ワイヤーフレーム、1=ソリッド、2=シャドー)
nci_number=ncb_mode+1 ;立方体の個数
nci_cubes=nci_number+2 ;座標データ int x,y,z

savedata_end=nci_cubes+2*3*maxcubes

datastart70=savedata_end
;[nci_ptrstart] 2*maxcubes
;[nci_distance] 4*maxcubes
ncb_relation=savedata_end +2*maxcubes +4*maxcubes
;モード1および2のとき、隣と接する面であるか事前に調べる
;(z+,z-,y+,y-,x+,x-の6バイト)

buffer=ncb_relation +6*maxcubes
;文字表示用バッファー