リンクその4: 3D graphics プロジェクト(MZ80B編) ;3D graphics ver.2.21 for MZ-80B (C) 1991, 2008, 2017 org &12a0, &12a0 jp start jp hotstart ;******* test: call init ld hl,50 ld [p4_x1],hl ld hl,50 ld [p4_y1],hl ld hl,100 ld [p4_x2],hl ld hl,50 ld [p4_y2],hl ld hl,100 ld [p4_x3],hl ld hl,100 ld [p4_y3],hl ld hl,50 ld [p4_x4],hl ld hl,100 ld [p4_y4],hl test00: call clsc call clsv ld hl,p4_x1 ld de,p40_x1 ld bc,(2+2)*4 ldir call p4_line ld hl,[test_cursor] add hl,hl add hl,hl ld de,p4_x1 add hl,de ld [test_cursorptr],hl ld e,[hl] inc hl ld d,[hl] ld [dr_x1],de ld [dr_x2],de ld hl,0 ld [dr_y1],hl ld hl,199 ld [dr_y2],hl call line ld hl,[test_cursorptr] inc hl inc hl ld e,[hl] inc hl ld d,[hl] ld [dr_y1],de ld [dr_y2],de ld hl,0 ld [dr_x1],hl ld hl,319 ld [dr_x2],hl call line test10: call keywait cp 11 jp z,_monitor cp '1' jr z,test11 cp '3' jr z,test13 cp '2' jr z,test12 cp '4' jr z,test14 cp '6' jr z,test16 cp '8' jr z,test18 cp 13 jr nz,test10 ld a,1 ld [vvactive],a call p4_polygon jr test10 test11: ld a,[test_cursor] dec a test110: and 3 ld [test_cursor],a jp test00 test13: ld a,[test_cursor] inc a jr test110 test12: ld hl,[test_cursorptr] inc hl inc hl ld e,[hl] inc hl ld d,[hl] ex de,hl ld bc,5 add hl,bc ex de,hl ld [hl],d dec hl ld [hl],e jp test00 test18: ld hl,[test_cursorptr] inc hl inc hl ld e,[hl] inc hl ld d,[hl] ex de,hl ld bc,-5 add hl,bc ex de,hl ld [hl],d dec hl ld [hl],e jp test00 test14: ld hl,[test_cursorptr] ld e,[hl] inc hl ld d,[hl] ex de,hl ld bc,-5 add hl,bc ex de,hl ld [hl],d dec hl ld [hl],e jp test00 test16: ld hl,[test_cursorptr] ld e,[hl] inc hl ld d,[hl] ex de,hl ld bc,5 add hl,bc ex de,hl ld [hl],d dec hl ld [hl],e jp test00 test_cursor: dw 0 test_cursorptr: dw 0 ;******* cr_x1: dw 0 cr_y1: dw 0 cr_x2: dw 0 cr_y2: dw 0 cr_x3: dw 0 cr_y3: dw 0 cr_x4: dw 0 cr_y4: dw 0 cr_x5: dw 0 cr_y5: dw 0 cr_y1y2: dw 0 cr_y1y3: dw 0 cr_y3y4: dw 0 cr_u: dw 0 crre_u: db 0,0,0,0,0,0 cr_us: dw 0 cr_ut: dw 0 crre_s: db 0,0,0,0,0,0 crre_t: db 0,0,0,0,0,0 cr_flag: db 0 cross: ;(cr_x1,cr_y1)-(cr_x2,cr_y2)と(cr_x3,cr_y3)-(cr_x4,cr_y4)の交点を計算する ;cf=0ならば交点は(cr_x5,cr_y5)に入っている ;y1y2=y1-y2 ld hl,[cr_y1] ld de,[cr_y2] call isub ret c ld [cr_y1y2],hl ;y1y3=y1-y3 ld hl,[cr_y1] ld de,[cr_y3] call isub ret c ld [cr_y1y3],hl ;y3y4=y3-y4 ld hl,[cr_y3] ld de,[cr_y4] call isub ret c ld [cr_y3y4],hl ;u= (x3 - x4) * y1y2 ld hl,[cr_x3] ld de,[cr_x4] call isub ret c ex de,hl ld bc,[cr_y1y2] call imul ret c ld [cr_u],hl ; - (x1 - x2) * y3y4 ld hl,[cr_x1] ld de,[cr_x2] call isub ret c ex de,hl ld bc,[cr_y3y4] call imul ret c ex de,hl ld hl,[cr_u] call isub ret c ld [cr_u],hl ;if( u .ne. 0.0_8 ) then ld a,h or l scf ret z call itof16 ld hl,acc1 ld de,crre_u call mtom ;us= x4 * y1y3 ld de,[cr_x4] ld bc,[cr_y1y3] call imul ret c ld [cr_us],hl ; + x1 * y3y4 ld de,[cr_x1] ld bc,[cr_y3y4] call imul ret c ex de,hl ld hl,[cr_us] call iadd ret c ld [cr_us],hl ; + x3 * (y4 - y1) ld hl,[cr_y4] ld de,[cr_y1] call isub ret c ex de,hl ld bc,[cr_x3] call imul ret c ex de,hl ld hl,[cr_us] call iadd ret c ld [cr_us],hl ;ut= x3 * y1y2 ld de,[cr_x3] ld bc,[cr_y1y2] call imul ret c ld [cr_ut],hl ; + x1 * (y2 - y3) ld hl,[cr_y2] ld de,[cr_y3] call isub ret c ex de,hl ld bc,[cr_x1] call imul ret c ex de,hl ld hl,[cr_ut] call iadd ret c ld [cr_ut],hl ; - x2 * y1y3 ld de,[cr_x2] ld bc,[cr_y1y3] call imul ret c ex de,hl ld hl,[cr_ut] call isub ret c ld [cr_ut],hl ;s= us / -u ld hl,[cr_us] call itof16 ld hl,acc1 call chs call mtox ld hl,crre_u call mtox call div ld hl,crre_s call xtom ;t= ut / u ld hl,[cr_ut] call itof16 ld hl,acc1 call mtox ld hl,crre_u call mtox call div ld hl,crre_t call xtom ;if( s .ge. 0.0_8 ) then ;if( s .le. 1.0_8 ) then ;if( t .ge. 0.0_8 ) then ;if( t .le. 1.0_8 ) then ld hl,crre_s push hl call is0 pop hl jr z,cro00 ld a,[hl] add a,a ret c ld de,float1 call fcp ;1-s ret c cro00: ld hl,crre_t push hl call is0 pop hl jr z,cro10 ld a,[hl] add a,a ret c ld de,float1 call fcp ;1-t ret c cro10: ; x5=x1+(x2-x1)*s ld hl,[cr_x2] ld de,[cr_x1] call isub ret c call itof16 ld hl,acc1 call mtox ld hl,crre_s call mtox call mul ld hl,acc1 call xtom call ftoi16 ret c ld de,[cr_x1] call iadd ret c ld [cr_x5],hl ; y5=y1+(y2-y1)*s ld hl,[cr_y2] ld de,[cr_y1] call isub ret c call itof16 ld hl,acc1 call mtox ld hl,crre_s call mtox call mul ld hl,acc1 call xtom call ftoi16 ret c ld de,[cr_y1] call iadd ret c ld [cr_y5],hl ;end if ;end if ;end if ;end if ret ;cf=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 p30_x1: dw 0 p30_y1: dw 0 p30_x2: dw 0 p30_y2: dw 0 p30_x3: dw 0 p30_y3: dw 0 ;double s3(int x1,int y1,int x2,int y2,int x3,int y3) { ; return(fabs(0.5f*((x1-x2)*(y3-y1)+(x1-x3)*(y1-y2)))); ; } sum3: ;[p3_x1]〜の3角形の面積*2→hl, cf=status ;(x1-x2)*(y3-y1) ld hl,[p3_x1] ld de,[p3_x2] and a sbc hl,de push hl ld hl,[p3_y3] ld de,[p3_y1] and a sbc hl,de ex de,hl pop bc call imul ret c push hl ;(x1-x3)*(y1-y2) ld hl,[p3_x1] ld de,[p3_x3] and a sbc hl,de push hl ld hl,[p3_y1] ld de,[p3_y2] and a sbc hl,de ex de,hl pop bc call imul pop de ret c call iadd ret c bit 7,h 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 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 p3_minx:dw 0 p3_miny:dw 0 p3_maxx:dw 0 p3_maxy:dw 0 p3_sum3:dw 0 p3_polygon: ;[p3_x1]〜の3角形をポリゴンで表示する, cf=status call sum3 ret c ld [p3_sum3],hl ld hl,p3_x1 ld de,p3_minx push hl ldi ldi ldi ldi pop hl ldi ldi ldi ldi ;最大値、最小値を決める ld hl,[p3_minx] ld de,[p3_x2] and a sbc hl,de bit 7,h jr nz,p3p00 ld [p3_minx],de p3p00: ld hl,[p3_minx] ld de,[p3_x3] and a sbc hl,de bit 7,h jr nz,p3p01 ld [p3_minx],de p3p01: ld hl,[p3_maxx] ld de,[p3_x2] and a sbc hl,de bit 7,h jr z,p3p10 ld [p3_maxx],de p3p10: ld hl,[p3_maxx] ld de,[p3_x3] and a sbc hl,de bit 7,h jr z,p3p11 ld [p3_maxx],de p3p11: ld hl,[p3_miny] ld de,[p3_y2] and a sbc hl,de bit 7,h jr nz,p3p20 ld [p3_miny],de p3p20: ld hl,[p3_miny] ld de,[p3_y3] and a sbc hl,de bit 7,h jr nz,p3p21 ld [p3_miny],de p3p21: ld hl,[p3_maxy] ld de,[p3_y2] and a sbc hl,de bit 7,h jr z,p3p30 ld [p3_maxy],de p3p30: ld hl,[p3_maxy] ld de,[p3_y3] and a sbc hl,de bit 7,h jr z,p3p31 ld [p3_maxy],de p3p31: ;点や直線になるポリゴンは表示しない ld hl,[p3_maxx] ld de,[p3_minx] and a sbc hl,de ret z ;cf=0 ld hl,[p3_maxy] ld de,[p3_miny] and a sbc hl,de ret z ;cf=0 ld a,[vvactive] and a jr z,p3vv_polygon00 call p3vv_polygon ret nc p3vv_polygon00: ld hl,p3_x1 ld de,p30_x1 ld bc,(2+2)*3 ldir ;描画 ld hl,[p3_miny] p3p40: ld [p3_y1],hl ld de,200 and a sbc hl,de jr nc,p3p70 ;minx --> ld hl,[p3_minx] p3p50: ld [p3_x1],hl ld de,[p3_maxx] and a sbc hl,de jr z,p3p53 add hl,de ld de,320 and a sbc hl,de jr nc,p3p51 call inner123 ret c jr z,p3p52 p3p51: ld hl,[p3_x1] inc hl jr p3p50 p3p53: call inner123 ret c jr nz,p3p70 p3p52: ld hl,[p3_x1] ld [dr_x1],hl ;<-- maxx ld hl,[p3_maxx] p3p60: ld [p3_x1],hl ld de,[dr_x1] and a sbc hl,de jr z,p3p62 add hl,de ld de,320 and a sbc hl,de jr nc,p3p61 call inner123 ret c jr z,p3p62 p3p61: ld hl,[p3_x1] dec hl jr p3p60 p3p62: ld hl,[p3_x1] ld [dr_x2],hl ld hl,[p3_y1] ld [dr_y1],hl ld [dr_y2],hl call hline ;横1本を塗る p3p70: ld hl,[p3_y1] inc hl ld de,[p3_maxy] and a sbc hl,de ret z ;cf=0 add hl,de jr p3p40 inner123: ;[p3_x1],[p3_y1]の[p30_x1〜4],[p30_y1〜4]の内包判定, cf=status, zf=1ならば内側にある ;p30の面積は[p3_sum3]に入れておく ;p12 ld hl,[p30_x1] ld [p3_x2],hl ld hl,[p30_y1] ld [p3_y2],hl ld hl,[p30_x2] ld [p3_x3],hl ld hl,[p30_y2] ld [p3_y3],hl call sum3 ret c push hl ;p23 ld hl,[p30_x2] ld [p3_x2],hl ld hl,[p30_y2] ld [p3_y2],hl ld hl,[p30_x3] ld [p3_x3],hl ld hl,[p30_y3] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c push hl ;p31 ld hl,[p30_x3] ld [p3_x2],hl ld hl,[p30_y3] ld [p3_y2],hl ld hl,[p30_x1] ld [p3_x3],hl ld hl,[p30_y1] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c ld de,[p3_sum3] ;cf=0 sbc hl,de ;△123==△p12+p23+p31で内側にある ret p4_x1: dw 0 p4_y1: dw 0 p4_x2: dw 0 p4_y2: dw 0 p4_x3: dw 0 p4_y3: dw 0 p4_x4: dw 0 p4_y4: dw 0 p40_x1: dw 0 p40_y1: dw 0 p40_x2: dw 0 p40_y2: dw 0 p40_x3: dw 0 p40_y3: dw 0 p40_x4: dw 0 p40_y4: dw 0 ;double s4(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4) { ; return(fabs(0.5f*((x1-x2)*(y3-y1)+(x1-x3)*(y4-y2)+(x1-x4)*(y1-y3)))); ; } sum4: ;[p4_x1]〜の4角形の面積*2→hl, cf=status ;(x1-x2)*(y3-y1) ld hl,[p4_x1] ld de,[p4_x2] and a sbc hl,de push hl ld hl,[p4_y3] ld de,[p4_y1] and a sbc hl,de ex de,hl pop bc call imul ret c push hl ;(x1-x3)*(y4-y2) ld hl,[p4_x1] ld de,[p4_x3] and a sbc hl,de push hl ld hl,[p4_y4] ld de,[p4_y2] and a sbc hl,de ex de,hl pop bc call imul pop de ret c call iadd ret c push hl ;(x1-x4)*(y1-y3) ld hl,[p4_x1] ld de,[p4_x4] and a sbc hl,de push hl ld hl,[p4_y1] ld de,[p4_y3] and a sbc hl,de ex de,hl pop bc call imul pop de ret c call iadd ret c bit 7,h 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 p4_minx:dw 0 p4_miny:dw 0 p4_maxx:dw 0 p4_maxy:dw 0 p4_sum4: dw 0 p4_sum42: dw 0 p4_sum123: dw 0 p4_sum341: dw 0 vvactive: db 0 p4v_start: dw 0 ;vram上の左上のアドレス p4v_lenx: dw 0 ;x方向の長さ(1バイト単位)(1〜40) p4v_leny: dw 0 ;y方向の長さ(1〜200) p34_minx: dw 0 p4v_cls: ;仮想vramをクリアする。 (0,0)-(p4v_lenx-1,leny-1) ld hl,40 ld de,[p4v_lenx] and a sbc hl,de ex de,hl ld hl,vvr ld bc,[p4v_leny] p4vc00: ld a,[p4v_lenx] ld b,a p4vc01: ld [hl],0 inc hl djnz p4vc01 add hl,de dec c jr nz,p4vc00 ret p4v_tfr: ;仮想vram1→vram2転送する。 (0,0)-(p4v_lenx-1,leny-1) ld hl,vvr ld de,vvr2 ld a,[p4v_leny] ld b,a p4vt00: push bc push hl push de ld bc,[p4v_lenx] ldir pop hl ld c,40 ;b=0 add hl,bc ex de,hl pop hl add hl,bc pop bc djnz p4vt00 ret p4v_xor: ;仮想vram1=not(vram1 xor vram2), (0,0)-(p4v_lenx-1,leny-1) ld hl,vvr ld de,vvr2 ld a,[p4v_leny] ld c,a p4vx00: push bc push hl push de ld a,[p4v_lenx] ld b,a p4vx01: ld a,[de] ;vvr2 inc de xor [hl] ;vvr cpl ld [hl],a inc hl djnz p4vx01 pop hl ld c,40 ;b=0 add hl,bc ex de,hl pop hl add hl,bc pop bc dec c jr nz,p4vx00 ret p4v_or: ;[p4v_start〜]=[p4v_start〜] or [vvr〜], (0,0)-(p4v_lenx-1,leny-1) in a,[&e8] ;vramアクセス許可 set 7,a res 6,a out [&e8],a ld a,&02 out [&f4],a ld hl,[p4v_start] ld de,vvr ld a,[p4v_leny] ld c,a p4vo00: push bc push hl push de ld a,[p4v_lenx] ld b,a p4vo01: ld a,[de] ;vvr inc de or [hl] ;実際のvram ld [hl],a inc hl djnz p4vo01 pop hl ld c,40 ;b=0 add hl,bc ex de,hl pop hl add hl,bc pop bc dec c jr nz,p4vo00 in a,[&e8] ;vramアクセス禁止 res 7,a out [&e8],a ld a,&03 out [&f4],a ret p3vv_polygon: ;[p3_x1]〜の3角形をポリゴンで表示する, cf=status ;p3_polygonから呼ばれる ;p3_minx,y,maxx,yも設定済みとする ld hl,[p3_minx] ;320*200の枠から外れたものは除外する bit 7,h scf ret nz ld de,320 and a sbc hl,de ccf ret c ld hl,[p3_maxx] bit 7,h scf ret nz and a sbc hl,de ccf ret c ld hl,[p3_miny] bit 7,h scf ret nz ld de,200 and a sbc hl,de ccf ret c ld hl,[p3_maxy] bit 7,h scf ret nz and a sbc hl,de ccf ret c ld de,[p3_minx] ;下位3ビットを切り捨てる ld a,e and &ff-7 ld e,a ld [p34_minx],de ld hl,[p3_maxx] ;下位3ビットを切り捨てる ld a,l and &ff-7 ld l,a ;cf=0 sbc hl,de srl h ;最大320/2 rr l srl l ;最大160/2 srl l ;最大80/2 inc hl ld [p4v_lenx],hl ld hl,[p3_maxy] ld de,[p3_miny] and a sbc hl,de inc hl ld [p4v_leny],hl ld h,d ;miny*40 ld l,e 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 de,[p34_minx] srl d ;最大320/2 rr e srl e ;最大160/2 srl e ;最大80/2 add hl,de ;+minx/8 ld de,&e000 add hl,de ld [p4v_start],hl ;minx,minyのオフセットを引く ld de,[p34_minx] ld hl,[p3_x1] and a sbc hl,de ld [p30_x1],hl ld hl,[p3_x2] and a sbc hl,de ld [p30_x2],hl ld hl,[p3_x3] and a sbc hl,de ld [p30_x3],hl ld de,[p3_miny] ld hl,[p3_y1] and a sbc hl,de ld [p30_y1],hl ld hl,[p3_y2] and a sbc hl,de ld [p30_y2],hl ld hl,[p3_y3] and a sbc hl,de ld [p30_y3],hl ;仮想vramをクリアする call p4v_cls ;仮想vramに直線を描く ld hl,vvr ld [dr_code3+1],hl call p3_line ld hl,&e000 ld [dr_code3+1],hl jp p34vv_polygon p4vv_polygon: ;[p4_x1]〜の凸型4角形をポリゴンで表示する, cf=status ;p4_polygonから呼ばれるため、凸型のチェック済み ;p4_minx,y,maxx,yも設定済みとする ld hl,[p4_minx] ;320*200の枠から外れたものは除外する bit 7,h scf ret nz ld de,320 and a sbc hl,de ccf ret c ld hl,[p4_maxx] bit 7,h scf ret nz and a sbc hl,de ccf ret c ld hl,[p4_miny] bit 7,h scf ret nz ld de,200 and a sbc hl,de ccf ret c ld hl,[p4_maxy] bit 7,h scf ret nz and a sbc hl,de ccf ret c ld de,[p4_minx] ;下位3ビットを切り捨てる ld a,e and &ff-7 ld e,a ld [p34_minx],de ld hl,[p4_maxx] ;下位3ビットを切り捨てる ld a,l and &ff-7 ld l,a ;cf=0 sbc hl,de srl h ;最大320/2 rr l srl l ;最大160/2 srl l ;最大80/2 inc hl ld [p4v_lenx],hl ld hl,[p4_maxy] ld de,[p4_miny] and a sbc hl,de inc hl ld [p4v_leny],hl ld h,d ;miny*40 ld l,e 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 de,[p34_minx] srl d ;最大320/2 rr e srl e ;最大160/2 srl e ;最大80/2 add hl,de ;+minx/8 ld de,&e000 add hl,de ld [p4v_start],hl ;minx,minyのオフセットを引く ld de,[p34_minx] ld hl,[p4_x1] and a sbc hl,de ld [p40_x1],hl ld hl,[p4_x2] and a sbc hl,de ld [p40_x2],hl ld hl,[p4_x3] and a sbc hl,de ld [p40_x3],hl ld hl,[p4_x4] and a sbc hl,de ld [p40_x4],hl ld de,[p4_miny] ld hl,[p4_y1] and a sbc hl,de ld [p40_y1],hl ld hl,[p4_y2] and a sbc hl,de ld [p40_y2],hl ld hl,[p4_y3] and a sbc hl,de ld [p40_y3],hl ld hl,[p4_y4] and a sbc hl,de ld [p40_y4],hl ;仮想vramをクリアする call p4v_cls ;仮想vramに直線を描く ld hl,vvr ld [dr_code3+1],hl call p4_line ld hl,&e000 ld [dr_code3+1],hl p34vv_polygon: ;3角形、4角形共通 ;仮想vram1→vram2転送する。 (0,0)-(p4v_lenx-1,leny-1) call p4v_tfr ;仮想vram1の3角形または4角形の外側を塗りつぶす ld a,[p4v_leny] ld c,a ld hl,vvr p4vv00: push hl ld a,[p4v_lenx] ld b,a p4vv10: ld a,[hl] and a jr nz,p4vv11 ld [hl],&ff inc hl djnz p4vv10 jr p4vv21 p4vv11: bit 0,a jr nz,p4vv20 or 1 bit 1,a jr nz,p4vv20 or 2 bit 2,a jr nz,p4vv20 or 4 bit 3,a jr nz,p4vv20 or 8 bit 4,a jr nz,p4vv20 or 16 bit 5,a jr nz,p4vv20 or 32 bit 6,a jr nz,p4vv20 or 64 bit 7,a jr nz,p4vv20 or 128 p4vv20: ld [hl],a p4vv21: pop hl push hl ld de,[p4v_lenx] add hl,de ld b,e ;lenx p4vv30: dec hl ld a,[hl] and a jr nz,p4vv31 ld [hl],&ff djnz p4vv30 jr p4vv32 p4vv31: bit 7,a jr nz,p4vv40 or 128 bit 6,a jr nz,p4vv40 or 64 bit 5,a jr nz,p4vv40 or 32 bit 4,a jr nz,p4vv40 or 16 bit 3,a jr nz,p4vv40 or 8 bit 2,a jr nz,p4vv40 or 4 bit 1,a jr nz,p4vv40 or 2 bit 0,a jr nz,p4vv40 or 1 p4vv40: ld [hl],a p4vv32: pop hl ld de,40 add hl,de dec c jp nz,p4vv00 ;仮想vram1=not(vram1 xor vram2), (0,0)-(p4v_lenx-1,leny-1) call p4v_xor ;[p4v_start〜]=[p4v_start〜] or [vvr〜], (0,0)-(p4v_lenx-1,leny-1) call p4v_or and a ret ;cf=0 ;四角形1234について ; ;仮説1:その頂点1,2,3,4を使って面積を計算する。 ;△123+△234+△341+△412==2*□1234ならば、□1234は凸型である。 ;□1234が凸型であれば、□1234をそのまま描画する。 ; ;仮説2:□1234が凹型である場合、 ;△123+△341==□1234ならば、△123と△341に分けて描画する。 ;△123+△341!=□1234ならば、△234と△412に分けて描画する。 p4_polygon: ;[p4_x1]〜の4角形をポリゴンで表示する, cf=status xor a ld [cr_flag],a call sum4 ret c ld [p4_sum4],hl add hl,hl ret c ld [p4_sum42],hl ;123 ld hl,[p4_x1] ld [p3_x1],hl ld hl,[p4_y1] ld [p3_y1],hl ld hl,[p4_x2] ld [p3_x2],hl ld hl,[p4_y2] ld [p3_y2],hl ld hl,[p4_x3] ld [p3_x3],hl ld hl,[p4_y3] ld [p3_y3],hl call sum3 ret c ld [p4_sum123],hl ;234 push hl ld hl,[p4_x2] ld [p3_x1],hl ld hl,[p4_y2] ld [p3_y1],hl ld hl,[p4_x3] ld [p3_x2],hl ld hl,[p4_y3] ld [p3_y2],hl ld hl,[p4_x4] ld [p3_x3],hl ld hl,[p4_y4] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c ;341 push hl ld hl,[p4_x3] ld [p3_x1],hl ld hl,[p4_y3] ld [p3_y1],hl ld hl,[p4_x4] ld [p3_x2],hl ld hl,[p4_y4] ld [p3_y2],hl ld hl,[p4_x1] ld [p3_x3],hl ld hl,[p4_y1] ld [p3_y3],hl call sum3 ld [p4_sum341],hl pop de ret c add hl,de ret c ;412 push hl ld hl,[p4_x4] ld [p3_x1],hl ld hl,[p4_y4] ld [p3_y1],hl ld hl,[p4_x1] ld [p3_x2],hl ld hl,[p4_y1] ld [p3_y2],hl ld hl,[p4_x2] ld [p3_x3],hl ld hl,[p4_y2] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c ld de,[p4_sum42] ;cf=0 sbc hl,de jp z,p4p100 ;△123+△234+△341+△412==2*□1234ならば、□1234は凸型である。 ;凹型である場合 ;1-4と2-3が自己交差していないか ld hl,[p4_x1] ld [cr_x1],hl ld hl,[p4_y1] ld [cr_y1],hl ld hl,[p4_x4] ld [cr_x2],hl ld hl,[p4_y4] ld [cr_y2],hl ld hl,[p4_x2] ld [cr_x3],hl ld hl,[p4_y2] ld [cr_y3],hl ld hl,[p4_x3] ld [cr_x4],hl ld hl,[p4_y3] ld [cr_y4],hl call cross jp c,p4p300 ;自己交差1-4,2-3 ld a,1 ld [cr_flag],a ;1-2-5 ld hl,[p4_x1] ld [p3_x1],hl ld hl,[p4_y1] ld [p3_y1],hl ld hl,[p4_x2] ld [p3_x2],hl ld hl,[p4_y2] ld [p3_y2],hl ld hl,[cr_x5] ld [p3_x3],hl ld hl,[cr_y5] ld [p3_y3],hl call p3_polygon ret c ;4-3-5 ld hl,[p4_x4] ld [p3_x1],hl ld hl,[p4_y4] ld [p3_y1],hl ld hl,[p4_x3] ld [p3_x2],hl ld hl,[p4_y3] ld [p3_y2],hl ld hl,[cr_x5] ld [p3_x3],hl ld hl,[cr_y5] ld [p3_y3],hl jp p3_polygon p4p300: ;1-2と3-4が自己交差していないか ld hl,[p4_x1] ld [cr_x1],hl ld hl,[p4_y1] ld [cr_y1],hl ld hl,[p4_x2] ld [cr_x2],hl ld hl,[p4_y2] ld [cr_y2],hl ld hl,[p4_x3] ld [cr_x3],hl ld hl,[p4_y3] ld [cr_y3],hl ld hl,[p4_x4] ld [cr_x4],hl ld hl,[p4_y4] ld [cr_y4],hl call cross jp c,p4p310 ;自己交差1-2,3-4 ld a,2 ld [cr_flag],a ;1-4-5 ld hl,[p4_x1] ld [p3_x1],hl ld hl,[p4_y1] ld [p3_y1],hl ld hl,[p4_x4] ld [p3_x2],hl ld hl,[p4_y4] ld [p3_y2],hl ld hl,[cr_x5] ld [p3_x3],hl ld hl,[cr_y5] ld [p3_y3],hl call p3_polygon ret c ;2-3-5 ld hl,[p4_x2] ld [p3_x1],hl ld hl,[p4_y2] ld [p3_y1],hl ld hl,[p4_x3] ld [p3_x2],hl ld hl,[p4_y3] ld [p3_y2],hl ld hl,[cr_x5] ld [p3_x3],hl ld hl,[cr_y5] ld [p3_y3],hl jp p3_polygon p4p310: ld hl,[p4_sum123] ld de,[p4_sum341] add hl,de ret c ld de,[p4_sum4] ;cf=0 sbc hl,de jr nz,p4p200 ;△123+△341==□1234ならば、△123と△341に分けて描画する。 ;123 ld hl,[p4_x1] ld [p3_x1],hl ld hl,[p4_y1] ld [p3_y1],hl ld hl,[p4_x2] ld [p3_x2],hl ld hl,[p4_y2] ld [p3_y2],hl ld hl,[p4_x3] ld [p3_x3],hl ld hl,[p4_y3] ld [p3_y3],hl call p3_polygon ret c ;341 ld hl,[p4_x3] ld [p3_x1],hl ld hl,[p4_y3] ld [p3_y1],hl ld hl,[p4_x4] ld [p3_x2],hl ld hl,[p4_y4] ld [p3_y2],hl ld hl,[p4_x1] ld [p3_x3],hl ld hl,[p4_y1] ld [p3_y3],hl jp p3_polygon p4p200: ;△123+△341!=□1234ならば、△234と△412に分けて描画する。 ;234 ld hl,[p4_x2] ld [p3_x1],hl ld hl,[p4_y2] ld [p3_y1],hl ld hl,[p4_x3] ld [p3_x2],hl ld hl,[p4_y3] ld [p3_y2],hl ld hl,[p4_x4] ld [p3_x3],hl ld hl,[p4_y4] ld [p3_y3],hl call p3_polygon ret c ;412 ld hl,[p4_x4] ld [p3_x1],hl ld hl,[p4_y4] ld [p3_y1],hl ld hl,[p4_x1] ld [p3_x2],hl ld hl,[p4_y1] ld [p3_y2],hl ld hl,[p4_x2] ld [p3_x3],hl ld hl,[p4_y2] ld [p3_y3],hl jp p3_polygon p4p100: ;凸型である場合 ld hl,p4_x1 ld de,p4_minx push hl ldi ldi ldi ldi pop hl ldi ldi ldi ldi ;最大値、最小値を決める ld hl,[p4_minx] ld de,[p4_x2] and a sbc hl,de bit 7,h jr nz,p4p00 ld [p4_minx],de p4p00: ld hl,[p4_minx] ld de,[p4_x3] and a sbc hl,de bit 7,h jr nz,p4p01 ld [p4_minx],de p4p01: ld hl,[p4_minx] ld de,[p4_x4] and a sbc hl,de bit 7,h jr nz,p4p02 ld [p4_minx],de p4p02: ld hl,[p4_maxx] ld de,[p4_x2] and a sbc hl,de bit 7,h jr z,p4p10 ld [p4_maxx],de p4p10: ld hl,[p4_maxx] ld de,[p4_x3] and a sbc hl,de bit 7,h jr z,p4p11 ld [p4_maxx],de p4p11: ld hl,[p4_maxx] ld de,[p4_x4] and a sbc hl,de bit 7,h jr z,p4p12 ld [p4_maxx],de p4p12: ld hl,[p4_miny] ld de,[p4_y2] and a sbc hl,de bit 7,h jr nz,p4p20 ld [p4_miny],de p4p20: ld hl,[p4_miny] ld de,[p4_y3] and a sbc hl,de bit 7,h jr nz,p4p21 ld [p4_miny],de p4p21: ld hl,[p4_miny] ld de,[p4_y4] and a sbc hl,de bit 7,h jr nz,p4p22 ld [p4_miny],de p4p22: ld hl,[p4_maxy] ld de,[p4_y2] and a sbc hl,de bit 7,h jr z,p4p30 ld [p4_maxy],de p4p30: ld hl,[p4_maxy] ld de,[p4_y3] and a sbc hl,de bit 7,h jr z,p4p31 ld [p4_maxy],de p4p31: ld hl,[p4_maxy] ld de,[p4_y4] and a sbc hl,de bit 7,h jr z,p4p32 ld [p4_maxy],de p4p32: ;点や直線になるポリゴンは表示しない(後でポリゴンの境界にラインを引いて上書きするため) ld hl,[p4_maxx] ld de,[p4_minx] and a sbc hl,de ret z ;cf=0 ld hl,[p4_maxy] ld de,[p4_miny] and a sbc hl,de ret z ;cf=0 ld a,[vvactive] ;仮想vramが使えるときは、内包判定を使用しないアルゴリズムを試す and a jr z,p4vv_polygon00 call p4vv_polygon ret nc p4vv_polygon00: ;描画 ld hl,[p4_miny] p4p40: ld [p3_y1],hl ld de,200 and a sbc hl,de jr nc,p4p70 ;minx --> ld hl,[p4_minx] p4p50: ld [p3_x1],hl ld de,[p4_maxx] and a sbc hl,de jr z,p4p53 add hl,de ld de,320 and a sbc hl,de jr nc,p4p51 call inner1234 ret c jr z,p4p52 p4p51: ld hl,[p3_x1] inc hl jr p4p50 p4p53: call inner1234 ret c jr nz,p4p70 p4p52: ld hl,[p3_x1] ld [dr_x1],hl ;<-- maxx ld hl,[p4_maxx] p4p60: ld [p3_x1],hl ld de,[dr_x1] and a sbc hl,de jr z,p4p62 add hl,de ld de,320 and a sbc hl,de jr nc,p4p61 call inner1234 ret c jr z,p4p62 p4p61: ld hl,[p3_x1] dec hl jr p4p60 p4p62: ld hl,[p3_x1] ld [dr_x2],hl ld hl,[p3_y1] ld [dr_y1],hl ld [dr_y2],hl call hline ;横1本を塗る p4p70: ld hl,[p3_y1] inc hl ld de,[p4_maxy] and a sbc hl,de ret z ;cf=0 add hl,de jr p4p40 inner1234: ;[p3_x1],[p3_y1]の[p4_x1〜4],[p4_y1〜4]の内包判定, cf=status, zf=1ならば内側にある ;p4の面積は[p4_sum4]に入れておく ;p12 ld hl,[p4_x1] ld [p3_x2],hl ld hl,[p4_y1] ld [p3_y2],hl ld hl,[p4_x2] ld [p3_x3],hl ld hl,[p4_y2] ld [p3_y3],hl call sum3 ret c push hl ;p23 ld hl,[p4_x2] ld [p3_x2],hl ld hl,[p4_y2] ld [p3_y2],hl ld hl,[p4_x3] ld [p3_x3],hl ld hl,[p4_y3] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c push hl ;p34 ld hl,[p4_x3] ld [p3_x2],hl ld hl,[p4_y3] ld [p3_y2],hl ld hl,[p4_x4] ld [p3_x3],hl ld hl,[p4_y4] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c push hl ;p41 ld hl,[p4_x4] ld [p3_x2],hl ld hl,[p4_y4] ld [p3_y2],hl ld hl,[p4_x1] ld [p3_x3],hl ld hl,[p4_y1] ld [p3_y3],hl call sum3 pop de ret c add hl,de ret c ld de,[p4_sum4] ;cf=0 sbc hl,de ;□1234==△p12+p23+p34+p41で内側にある ret p3_line: ld hl,[p30_x1] ld [dr_x1],hl ld hl,[p30_y1] ld [dr_y1],hl ld hl,[p30_x2] ld [dr_x2],hl ld hl,[p30_y2] ld [dr_y2],hl call line ld hl,[p30_x2] ld [dr_x1],hl ld hl,[p30_y2] ld [dr_y1],hl ld hl,[p30_x3] ld [dr_x2],hl ld hl,[p30_y3] ld [dr_y2],hl call line ld hl,[p30_x3] ld [dr_x1],hl ld hl,[p30_y3] ld [dr_y1],hl ld hl,[p30_x1] ld [dr_x2],hl ld hl,[p30_y1] ld [dr_y2],hl call line ret p4_line: ld hl,[p40_x1] ld [dr_x1],hl ld hl,[p40_y1] ld [dr_y1],hl ld hl,[p40_x2] ld [dr_x2],hl ld hl,[p40_y2] ld [dr_y2],hl call line ld hl,[p40_x2] ld [dr_x1],hl ld hl,[p40_y2] ld [dr_y1],hl ld hl,[p40_x3] ld [dr_x2],hl ld hl,[p40_y3] ld [dr_y2],hl call line ld hl,[p40_x3] ld [dr_x1],hl ld hl,[p40_y3] ld [dr_y1],hl ld hl,[p40_x4] ld [dr_x2],hl ld hl,[p40_y4] ld [dr_y2],hl call line ld hl,[p40_x4] ld [dr_x1],hl ld hl,[p40_y4] ld [dr_y1],hl ld hl,[p40_x1] ld [dr_x2],hl ld hl,[p40_y1] ld [dr_y2],hl call line ret p4_bline2: ;a=1 or 2, ポリゴンが自己交差した場合の輪郭表示 cp 1 jp nz,p4_bline21 ;a=1 --> 1-2-5, 4-3-5 ;1-2-5 ld hl,[p4_x1] ld [dr_x1],hl ld hl,[p4_y1] ld [dr_y1],hl ld hl,[p4_x2] ld [dr_x2],hl ld hl,[p4_y2] ld [dr_y2],hl call bline ld hl,[p4_x2] ld [dr_x1],hl ld hl,[p4_y2] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ld hl,[p4_x1] ld [dr_x1],hl ld hl,[p4_y1] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ;4-3-5 ld hl,[p4_x4] ld [dr_x1],hl ld hl,[p4_y4] ld [dr_y1],hl ld hl,[p4_x3] ld [dr_x2],hl ld hl,[p4_y3] ld [dr_y2],hl call bline ld hl,[p4_x3] ld [dr_x1],hl ld hl,[p4_y3] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ld hl,[p4_x4] ld [dr_x1],hl ld hl,[p4_y4] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl jp bline p4_bline21: ;a=2 --> 1-4-5, 2-3-5 ;1-4-5 ld hl,[p4_x1] ld [dr_x1],hl ld hl,[p4_y1] ld [dr_y1],hl ld hl,[p4_x4] ld [dr_x2],hl ld hl,[p4_y4] ld [dr_y2],hl call bline ld hl,[p4_x4] ld [dr_x1],hl ld hl,[p4_y4] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ld hl,[p4_x1] ld [dr_x1],hl ld hl,[p4_y1] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ;2-3-5 ld hl,[p4_x2] ld [dr_x1],hl ld hl,[p4_y2] ld [dr_y1],hl ld hl,[p4_x3] ld [dr_x2],hl ld hl,[p4_y3] ld [dr_y2],hl call bline ld hl,[p4_x3] ld [dr_x1],hl ld hl,[p4_y3] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl call bline ld hl,[p4_x2] ld [dr_x1],hl ld hl,[p4_y2] ld [dr_y1],hl ld hl,[cr_x5] ld [dr_x2],hl ld hl,[cr_y5] ld [dr_y2],hl jp bline p4_bline: ld hl,[p4_x1] ld [dr_x1],hl ld hl,[p4_y1] ld [dr_y1],hl ld hl,[p4_x2] ld [dr_x2],hl ld hl,[p4_y2] ld [dr_y2],hl call bline ld hl,[p4_x2] ld [dr_x1],hl ld hl,[p4_y2] ld [dr_y1],hl ld hl,[p4_x3] ld [dr_x2],hl ld hl,[p4_y3] ld [dr_y2],hl call bline ld hl,[p4_x3] ld [dr_x1],hl ld hl,[p4_y3] ld [dr_y1],hl ld hl,[p4_x4] ld [dr_x2],hl ld hl,[p4_y4] ld [dr_y2],hl call bline ld hl,[p4_x4] ld [dr_x1],hl ld hl,[p4_y4] ld [dr_y1],hl ld hl,[p4_x1] ld [dr_x2],hl ld hl,[p4_y1] ld [dr_y2],hl call bline ret 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 hline: ;[dr_x1]-[dr_x2],[dr_y1] 横1本を塗る(ただしx1<=x2であること) ld hl,[dr_y1] ld de,200 and a sbc hl,de ret nc add hl,de 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 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 in a,[&e8] ;vramアクセス許可 set 7,a res 6,a out [&e8],a ld a,&02 out [&f4],a ex af,af' or [hl] ld [hl],a jr hline100 hline00: exx ld b,a exx ld a,b ;from ex af,af' exx in a,[&e8] ;vramアクセス許可 set 7,a res 6,a out [&e8],a ld a,&02 out [&f4],a ex af,af' or [hl] ;from ld [hl],a jr hline10 hline11: ld [hl],&ff hline10: inc hl djnz hline11 exx ld a,c ;to exx or [hl] ;to 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 vvr(仮想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 ldcalddb: ;c=a, d=b ld hl,floata ld de,floatc call mtom ld hl,floatb ld de,floatd jp mtom ldgaldhb: ;g=a, h=b ld hl,floata ld de,floatg call mtom ld hl,floatb ld de,floath jp mtom ldpaldqb: ;p=a, q=b ld hl,floata ld de,floatp call mtom ld hl,floatb ld de,floatq jp mtom ldagldbh: ;a=g, b=h ld hl,floatg ld de,floata call mtom ld hl,floath ld de,floatb jp mtom addagaddbh: ;a=a+g, b=b+h ld hl,floata push hl call mtox ld hl,floatg call mtox call ad jp c,err24 pop hl call xtom ld hl,floatb push hl call mtox ld hl,floath call mtox call ad jp c,err24 pop hl jp xtom ;5050 "CHCS"G=A:H=B:GOSUB "CEXP":P=A:Q=B:A=-G:B=-H:GOSUB "CEXP":A=(P+A)/2:B=(Q+B)/2:RETURN ncosh: call ldgaldhb call nexp call ldpaldqb call ldagldbh call nchs call nexp ld hl,floatp call mtox ld hl,floata push hl call mtox call ad jp c,err24 pop hl push hl call xtom pop hl call fatn30 ;[hl]/2 ld hl,floatq call mtox ld hl,floatb push hl call mtox call ad jp c,err24 pop hl push hl call xtom pop hl jp fatn30 ;[hl]/2 ;5060 "CHSN"G=A:H=B:GOSUB "CEXP":P=A:Q=B:A=-G:B=-H:GOSUB "CEXP":A=(P-A)/2:B=(Q-B)/2:RETURN nsinh: call ldgaldhb call nexp call ldpaldqb call ldagldbh call nchs call nexp ld hl,floatp call mtox ld hl,floata push hl call mtox call sb jp c,err25 pop hl push hl call xtom pop hl call fatn30 ;[hl]/2 ld hl,floatq call mtox ld hl,floatb push hl call mtox call sb jp c,err25 pop hl push hl call xtom pop hl jp fatn30 ;[hl]/2 mul2: ;[hl]=[hl]*2, cf=status inc hl ld a,[hl] and a ret z ;cf=0 inc a scf ret z ;cf=1 ld [hl],a and a ret ;cf=0 ;5070 "CHTN"A=-2*A:B=-2*B:GOSUB "CEXP": ntanh: ld hl,floata push hl call mul2 jp c,err2 pop hl call chs ld hl,floatb push hl call mul2 jp c,err2 pop hl call chs call nexp ;C=1+A:D=B:A=1-A:B=-B:GOTO "C/" ld hl,float1 call mtox ld hl,floata call mtox call ad jp c,err24 ld hl,floatc call xtom ld hl,floatb ld de,floatd call mtom ld hl,float1 call mtox ld hl,floata push hl call mtox call sb jp c,err25 pop hl call xtom ld hl,floatb call chs jp ndiv ;5080 "CAHC"G=A:H=B:C=A:D=B:CALL FMUL:A=A-1:GOSUB "CSQR":A=A+G:B=B+H:GOTO "CLN" narccosh: call ldgaldhb call ldcalddb call nmul ld hl,floata push hl call mtox ld hl,float1 call mtox call sb jp c,err25 pop hl call xtom call nsqr call addagaddbh jp nln ;5090 "CAHS"G=A:H=B:C=A:D=B:CALL FMUL:A=A+1:GOSUB "CSQR":A=A+G:B=B+H:GOTO "CLN" narcsinh: call ldgaldhb call ldcalddb call nmul ld hl,floata push hl call mtox ld hl,float1 call mtox call ad jp c,err24 pop hl call xtom call nsqr call addagaddbh jp nln ;5100 "CAHT"C=1-A:D=-B: narctanh: ld hl,float1 call mtox ld hl,floata call mtox call sb jp c,err25 ld hl,floatc call xtom ld hl,floatb ld de,floatd push de call mtom pop hl call chs ;A=1+A:CALL FDIV:GOSUB "CLN":A=A/2:B=B/2:RETURN ld hl,float1 call mtox ld hl,floata push hl call mtox call ad jp c,err24 pop hl call xtom call ndiv call nln ld hl,floata call fatn30 ;[hl]/2 ld hl,floatb jp fatn30 ;[hl]/2 err27: ld a,27 ;error on cos jp err ;5110 "CCOS"C=COS A*HCS B: ncos: ld hl,floata call mtox call cos jr c,err27 ld hl,floatb call mtox call cosh jr c,err27 call mul jr c,err27 ld hl,floatc call xtom ;B=-SIN A*HSN B:A=C:RETURN ld hl,floata call mtox call sin jr c,err27 ld hl,floatb call mtox call sinh jr c,err27 call mul jr c,err27 ld hl,floatb push hl call xtom pop hl call chs ld hl,floatc ld de,floata jp mtom err28: ld a,28 ;error on sin jp err ;5120 "CSIN"C=SIN A*HCS B nsin: ld hl,floata call mtox call sin jr c,err28 ld hl,floatb call mtox call cosh jr c,err28 call mul jr c,err28 ld hl,floatc call xtom ;:B=COS A*HSN B:A=C:RETURN ld hl,floata call mtox call cos jr c,err28 ld hl,floatb call mtox call sinh jr c,err28 call mul jr c,err28 ld hl,floatb call xtom ld hl,floatc ld de,floata jp mtom ;5130 "CTAN"G=A:H=B:GOSUB "CCOS":P=A:Q=B:A=G:B=H:GOSUB "CSIN":C=P:D=Q:GOTO "C/" ntan: call ldgaldhb call ncos call ldpaldqb call ldagldbh call nsin ld hl,floatp ld de,floatc call mtom ld hl,floatq ld de,floatd call mtom jp ndiv ;5140 "CATN"C=-A:D=1-B:B=1+B narctan: ld hl,floata ld de,floatc push de call mtom pop hl call chs ld hl,float1 call mtox ld hl,floatb call mtox call sb jp c,err25 ld hl,floatd call xtom ld hl,float1 call mtox ld hl,floatb call mtox call ad jp c,err24 ld hl,floatb call xtom ;:CALL FDIV:GOSUB "CLN":C=-B/2:B=A/2:A=C:RETURN call ndiv call nln ld hl,floatb ld de,floatc push de call mtom pop hl push hl call fatn30 ;[hl]/2 pop hl call chs ld hl,floata ld de,floatb push de call mtom pop hl call fatn30 ;[hl]/2 ld hl,floatc ld de,floata jp mtom ;5150 "CASN"G=-B:H=A:C=A:D=B:CALL FMUL:A=1-A:B=-B:GOSUB "CSQR" narcsin: ld hl,floatb ld de,floatg push de call mtom pop hl call chs ld hl,floata ld de,floath call mtom call ldcalddb call nmul call nchs ld hl,float1 call mtox ld hl,floata push hl call mtox call ad jp c,err24 pop hl call xtom call nsqr ;5151 A=A-G:B=B-H:GOSUB "CLN":C=-B:B=A:A=C:RETURN ld hl,floatg call chs ld hl,floath call chs call addagaddbh call nln ld hl,floatb ld de,floatc push de call mtom pop hl call chs ld hl,floata ld de,floatb call mtom ld hl,floatc ld de,floata jp mtom ;5160 "CACS"GOSUB "CASN":A=PI /2-A:B=-B:RETURN narccos: call narcsin call nchs ld hl,floatpidiv2 call mtox ld hl,floata push hl call mtox call ad jp c,err24 pop hl jp xtom ncomma: ld hl,floatc ld de,floata call mtom ld hl,floatd ld de,floatb jp mtom nimage: ld hl,floatb ld de,floata call mtom ; nreal: xor a ld [floatb+1],a ret err26: ld a,26 ;not left value jp err nequal: ld a,[charformula_leftvalue] and a jr z,err26 call ncomma dec a ld c,a ld b,0 add a,a ;*2 add a,c ;*3 add a,a ;*6 ld l,a ld h,b add hl,hl ;*12 ld de,complextmpatoz add hl,de ex de,hl ld hl,floata ld c,12 ldir ret float1div3: db &00,&7e,&ab,&aa,&aa,&aa ;1/3 npower: ;complex[a, b] ^= complex[c, d] ;5350 "C^"IF A=0THEN IF B=0THEN IF C>0THEN RETURN ld a,[floata+1] ld b,a ld a,[floatb+1] or b jr nz,npower10 ld a,[floatc+1] and a jr z,err23 ld a,[floatc+0] and a ret z npower10: ;5351 E=C:F=D:GOSUB "CLN":C=E:D=F:CALL FMUL:GOTO "CEXP" ld hl,floatc ld de,floate call mtom ld hl,floatd ld de,floatf call mtom call nln ld hl,floate ld de,floatc call mtom ld hl,floatf ld de,floatd call mtom call nmul jp nexp err23: ld a,23 ;error on power jp err nsqr: ld a,[floatb+1] and a jr nz,nsqr00 ld hl,floata inc hl ld a,[hl] and a ret z ;sqrt(0+0i) dec hl ld a,[hl] add a,a jr c,nsqr00 call mtox call sqr jr c,err23 ld hl,floata jp xtom nsqr00: ld hl,float1div2 jr npowerfloat ncur: ld hl,float1div3 ; npowerfloat: ;complex[a, b] ^= float[hl] push hl ld hl,floata call is0 jr nz,npower00 ld hl,floatb call is0 jr z,npower01 npower00: call nln ld hl,floata call mtox pop hl push hl call mtox call mul jr c,err23 ld hl,floata call xtom ld hl,floatb call mtox pop hl call mtox call mul jr c,err23 ld hl,floatb call xtom call nexp ret npower01: pop hl ret nln: ;5030 "CLN" ;5031 IF ABS A>=ABS B THEN ld hl,floata ld de,fnlna push de call mtom pop de push de xor a ld [de],a ld hl,floatb ld de,fnlnb push de call mtom pop de xor a ld [de],a pop hl call fcp ;ABS B - ABS A jr nc,nln00 ;5032 C=ABS A*SQR (1+(B/A)^2) ld hl,floatb call mtox ld hl,floata call mtox call div jp c,err22 ld hl,fnlnc push hl push hl call xtom pop hl push hl call mtox pop hl call mtox call mul jp c,err22 pop hl push hl call mv1 pop hl call mtox call ad jp c,err22 call sqr jp c,err22 ld hl,fnlna jr nln01 ;5033 ELSE nln00: ;5034 C=ABS B*SQR (1+(A/B)^2) ld hl,floata call mtox ld hl,floatb call mtox call div jp c,err22 ld hl,fnlnc push hl push hl call xtom pop hl push hl call mtox pop hl call mtox call mul jp c,err22 pop hl push hl call mv1 pop hl call mtox call ad jp c,err22 call sqr jp c,err22 ld hl,fnlnb ;5035 ENDIF nln01: call mtox call mul jp c,err22 ld hl,floatc call xtom ;5036 D=(SGN B+1)*10+SGN A+1 ld hl,floata push hl call is0 pop hl jr z,nln11 ld a,[hl] and a jr z,nln12 xor a ;A<0 jr nln13 nln11: ld a,1 ;A==0 jr nln13 nln12: ld a,2 ;A>0 nln13: ld b,a ld hl,floatb push hl call is0 pop hl jr z,nln21 ld a,[hl] and a jr z,nln22 xor a ;B<0 jr nln23 nln21: ld a,3 ;B==0 jr nln23 nln22: ld a,6 ;B>0 nln23: add a,b cp 3*1+0 jr z,nln5038 cp 3*1+1 jr z,nln5039 cp 3*1+2 jr z,nln5040 cp 3*2+0 jr z,nln5041 cp 3*2+1 jr z,nln5042 cp 3*2+2 jr z,nln5043 cp 3*0+0 jr z,nln5044 cp 3*0+1 jr z,nln5045 cp 3*0+2 jr z,nln5046 ;5037 SWITCH D nln5038: ;5038 CASE 10:B=PI ld hl,floatpi ld de,floatb call mtom jr nln5047 nln5039: ;5039 CASE 11:PRINT "LN 0" jr err22 nln5040: ;5040 CASE 12:B=0 ld hl,floatb call mv0 jr nln5047 nln5041: ;5041 CASE 20:B=PI +ATN (B/A) call nln30 ld hl,floatpi nln40: call mtox call ad jr c,err22 jr nln42 nln5042: ;5042 CASE 21:B=PI /2 ld hl,floatpidiv2 nln41: ld de,floatb call mtom jr nln5047 nln5046: ;5046 CASE 2:B=ATN (B/A) nln5043: ;5043 CASE 22:B=ATN (B/A) call nln30 nln42: ld hl,floatb call xtom jr nln5047 nln5044: ;5044 CASE 0:B=-PI +ATN (B/A) call nln30 ld hl,floatmpi jr nln40 nln5045: ;5045 CASE 1:B=-PI /2 ld hl,floatmpidiv2 jr nln41 ;5047 ENDSWITCH nln5047: ;5048 A=LN C:RETURN ld hl,floatc call mtox call ln jr c,err22 ld hl,floata call xtom ret nln30: ld hl,floatb ld de,acc1 call mtom ld hl,floata ld de,acc2 call mtom call farctan jr c,err22 ld hl,acc1 jp mtox err22: ld a,22 ;error on ln jp err nexp: ;5020 "CEXP"IF B=0THEN A=EXP A:RETURN ld hl,floatb call is0 jr nz,nexp00 ld hl,floata push hl call mtox call exp jr c,err21 pop hl call xtom ret nexp00: ;5021 F=EXP A:E=F*COS B:B=F*SIN B:A=E:RETURN ld hl,floata push hl call mtox call exp jr c,err21 ld hl,floatf push hl call xtom pop hl push hl call mtox pop hl call mtox ld hl,floatb push hl push hl call mtox call cos jr c,err21 call mul jr c,err21 ld hl,floate call xtom pop hl call mtox call sin jr c,err21 call mul jr c,err21 pop hl call xtom ld hl,floate pop de call mtom ret err21: ld a,21 ;error on exp jp err err2: ld a,2 ;error on mul jp err nmul: ;E=A*C-B*D ld hl,floata call mtox ld hl,floatc call mtox call mul jr c,err2 ld hl,floatb call mtox ld hl,floatd call mtox call mul jr c,err2 call sb jr c,err2 ;B=A*D+B*C:A=E ld hl,floata call mtox ld hl,floatd call mtox call mul jr c,err2 ld hl,floatb call mtox ld hl,floatc call mtox call mul jr c,err2 call ad ;b=(y1)+(y0) jr c,err2 ld hl,floatb call xtom ld hl,floata call xtom ret err3: ld a,3 ;error on div jp err ndiv: ;F=C*C+D*D ld hl,floatc call mtox ld hl,floatc call mtox call mul jr c,err3 ld hl,floatd call mtox ld hl,floatd call mtox call mul jr c,err3 call ad jr c,err3 ld hl,floatf call xtom ;E=(A*C+B*D)/F ld hl,floata call mtox ld hl,floatc call mtox call mul jr c,err3 ld hl,floatb call mtox ld hl,floatd call mtox call mul jr c,err3 call ad jr c,err3 ld hl,floatf call mtox call div jr c,err3 ;B=(B*C-A*D)/F:A=E ld hl,floatb call mtox ld hl,floatc call mtox call mul jr c,err3 ld hl,floata call mtox ld hl,floatd call mtox call mul jp c,err3 call sb jp c,err3 ld hl,floatf call mtox call div jp c,err3 ld hl,floatb call xtom ld hl,floata call xtom ret err24: ld a,24 ;error on add jp err nadd: ld hl,floata call mtox ld hl,floatc call mtox call ad jr c,err24 ld hl,floata call xtom ld hl,floatb call mtox ld hl,floatd call mtox call ad jr c,err24 ld hl,floatb jp xtom err25: ld a,25 ;error on sub jp err nsub: ld hl,floata call mtox ld hl,floatc call mtox call sb jr c,err25 ld hl,floata call xtom ld hl,floatb call mtox ld hl,floatd call mtox call sb jr c,err25 ld hl,floatb jp xtom mv0: ;[hl] = 0 inc hl 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 nchs: ld hl,floata call chs ld hl,floatb ; chs: ;[hl] = -[hl] ld a,[hl] 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 sinh: call popacc1 call fsinh jr mtox100 cosh: call popacc1 call fcosh jr mtox100 printcomplex: ;[ix~] = bcd complex [floata],[floatb] ld hl,floata ld de,acc1 call mtom ld a,[floata+1] ld b,a ld a,[floatb+1] ld c,a or b jp z,printbcdacc1 ;0+0i inc b dec b jr z,printcmp00 push bc call printbcdacc1 pop bc inc c dec c ret z printcmp00: ld hl,floatb ld de,acc1 call mtom call printbcdacc1 ld [ix],'i' inc ix ret getx: xor a ld [charformula_leftvalue],a call spcs call inputbcdacc1 jr c,getx00 call spcs ld hl,acc1 ld a,[ix] cp 'i' jr nz,getx01 inc ix xor a ld [floata+1],a ld de,floatb jp mtom getx01: xor a ld [floatb+1],a ld de,floata jp mtom getx00: ld a,[ix] call isoperator1 ld c,a ld b,0 ld hl,ptroperator1 add hl,bc add hl,bc ld e,[hl] inc hl ld d,[hl] ex de,hl jp [hl] getx10: call getalphalength dec b jr nz,getx20 ld a,[ix] sub 'a' cp 26 jp nc,err1 inc ix inc a ld [charformula_leftvalue],a dec a ld c,a add a,a ;*2 add a,c ;*3 add a,a ;*6 ld l,a ld h,0 add hl,hl ;*12 ld bc,complextmpatoz add hl,bc ld de,floata ld bc,12 ldir ret getx20: inc b call isstringoperator1 jp c,err1 push hl ;exp, ln などの処理アドレス call getalphalength push hl pop ix getx31: call getx xor a ld [charformula_leftvalue],a ;左辺値ではない ret ;関数処理へ getxnop: ;'+' ld hl,nnop jr getx30 getxnchs: ;'-' ld hl,nchs ; getx30: push hl inc ix jr getx31 getxparentheses: ;'(' call mtox16 inc ix call getformula call xtom16 call spcs ld a,[ix] cp ')' jp nz,err1 inc ix xor a ld [charformula_leftvalue],a ;左辺値ではない ret getalphalength: ;[ix~]アルファベット文字の長さを調べる --> b=長さ, hl=次のアドレス ld b,0 push ix pop hl geta00: ld a,[hl] cp 'a' ret c cp 'z'+1 ret nc inc hl inc b jr geta00 isstringoperator1: ;[ix~]=character, b=長さ --> 一致する文字列を探す ;hl=関数処理アドレス,cf=status ld hl,stringoperator1 isst00: ld a,[hl] and a scf ret z cp b jr nz,isst10 ex af,af' push bc push hl exx pop hl pop bc push ix pop de isst01: ld a,[de] inc hl cp [hl] jr nz,isst02 inc de djnz isst01 inc hl ld a,[hl] inc hl ld h,[hl] ld l,a and a ret ;cf=0 isst02: ex af,af' exx isst10: add a,1+2 ld e,a ld d,0 add hl,de jr isst00 isoperator1: ;a=character --> a=単項演算子コード ld hl,charoperator1 ld b,charoperator1e-charoperator1 isop100:cp [hl] jr z,isop110 inc hl djnz isop100 isop110: ld a,charoperator1e-charoperator1 sub b ret charoperator1: db '+', '-', '(' charoperator1e: ptroperator1: dw getxnop, getxnchs, getxparentheses, getx10 stringoperator1: db 3,'exp' dw nexp db 2,'ln' dw nln db 3,'sqr' dw nsqr db 4,'sqrt' dw nsqr db 3,'cur' dw ncur db 4,'cosh' dw ncosh db 4,'sinh' dw nsinh db 4,'tanh' dw ntanh db 7,'arccosh' dw narccosh db 7,'arcsinh' dw narcsinh db 7,'arctanh' dw narctanh db 3,'cos' dw ncos db 3,'sin' dw nsin db 3,'tan' dw ntan db 6,'arctan' dw narctan db 6,'arcsin' dw narcsin db 6,'arccos' dw narccos db 2,'re' dw nreal db 2,'im' dw nimage db 0 getformula: ;[ix~] = character --> [floata],[b] = complex number ld a,255 ld [charformula_entrylevel],a ; getformula00: ;bool getformula00(bool mustfindlabel, unsigned char entrylevel) ;{ ; long x; ; unsigned char q; ; ; if(getx(mustfindlabel)) {return(TRUE);}; call getx ; ;lbl00:; getf00: ; ; x=result; ld hl,floata ld de,floatformula_a call mtom ld hl,floatb ld de,floatformula_b call mtom ; ; spcs(); call spcs ; ; operator2[7]=*p; ; q=0; ; while(operator2[q]!=*p) {q++;}; ld a,[ix] call isoperator2 ; ; if(operator2priority[q]<entrylevel) ld c,a ld b,0 ld hl,charpriorityoperator2 add hl,bc ld a,[charformula_entrylevel] ld e,a ld a,[hl] cp e ret nc ; { ; p++; inc ix ;a=現在の priority level, bc=2項演算子番号 ld hl,ptroperator2 add hl,bc add hl,bc ld e,[hl] inc hl ld d,[hl] ld [ptrformula_execaddress],de call mtox16 ;a保存 ld [charformula_entrylevel],a ; if(getformula00(mustfindlabel, operator2priority[q])) {return(TRUE);}; call getformula00 ; if(execoperator2(x, q)) {return(TRUE);}; //result=(x op2 result) call xtom16 ld hl,floata ld de,floatc call mtom ld hl,floatb ld de,floatd call mtom ld hl,floatformula_a ld de,floata call mtom ld hl,floatformula_b ld de,floatb call mtom ld hl,getf01 push hl ld hl,[ptrformula_execaddress] jp [hl] ; goto lbl00; getf01: xor a ld [charformula_leftvalue],a ;左辺値ではない jr getf00 ; } ; else ; { ; return(FALSE); ; }; ;} ; ;bool getformula(bool mustfindlabel) ;{ ; labelnotfound=FALSE; ; ; return(getformula00(mustfindlabel, 255)); ;//エラーの時 TRUE を返す ;//エラー申告は関数最深部にて ;} charoperator2: db '+', '-', '*', '/', '^', '=', ',' charoperator2e: ptroperator2: dw nadd, nsub, nmul, ndiv, npower, nequal, ncomma charpriorityoperator2: db 3, 3, 2, 2, 1, 4, 5, 255 isoperator2: ;a=character --> a=2項演算子コード ld hl,charoperator2 ld b,charoperator2e-charoperator2 isop200:cp [hl] jr z,isop210 inc hl djnz isop200 isop210: ld a,charoperator2e-charoperator2 sub b ret spcs00: inc ix spcs: ld a,[ix] cp ' ' jr z,spcs00 ret mtox16: ;stack push = [formulawork~] ld hl,[ptrstackpointer] ld bc,16 and a sbc hl,bc ;cf=0 ld bc,floatstack sbc hl,bc jr c,err4 add hl,bc ld [ptrstackpointer],hl ld de,formulawork ex de,hl ; mtom16: ;[de~] = [hl~] ld bc,16 ldir ret xtom16: ;[formulawork~] = stack pop ld hl,[ptrstackpointer] ld bc,floatstacktop and a sbc hl,bc jr nc,err4 ;スタックが空である add hl,bc ld de,formulawork call mtom16 ld [ptrstackpointer],hl ret mtox: ;float stack push = float [hl] ex de,hl ld hl,[ptrstackpointer] ld bc,6 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,6 ldir ret mctomc: ;complex [de] = complex [hl] ld bc,12 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 err1: ld a,1 ;syntax error jr err err29: ld a,29 ;unknown error jr err err4: ld a,4 ;stack over flow ; err: ld b,a ld hl,errmsg jr errchk00 errchk01: ld a,[hl] and a jr z,err29 ;定義されていないエラー push bc ld bc,0 ld a,13 cpir pop bc errchk00: djnz errchk01 call message call crlf jp main errmsg: db 'syntax/value input error',13 ;1 db 'error on mul',13 ;2 db 'error on div',13 ;3 db 'stack over flow',13 ;4 db 'over flow',13 ;5 +++++++ db 'out of memory',13 ;6 +++++++ db 13 ;7 db 13 ;8 db 13 ;9 db 13 ;10 db 13 ;11 db 13 ;12 db 13 ;13 db 13 ;14 db 13 ;15 db 13 ;16 db 13 ;17 db 13 ;18 db 13 ;19 db 13 ;20 db 'error on exp',13 ;21 db 'error on ln',13 ;22 db 'error on power',13 ;23 db 'error on add',13 ;24 db 'error on sub',13 ;25 db 'not left value',13 ;26 db 'error on cos',13 ;27 db 'error on sin',13 ;28 db 'unknown error',13 ;29 db 0 floatsqrt2: db &00,&80,&33,&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 inc hl ld a,[hl] ;指数部 ld [charwork00],a ld [hl],128 ;1<=acc1<2とする ;6040 Y0=Y:Y=1+(Y-1)/2 ;SQR Yの概略の近似値を出しておく ld hl,acc1 ld de,acc3 ld bc,6 ldir ld hl,float1 ld de,acc2 ld c,6 ldir call fsub ret c ld hl,acc1 call fatn30 ld hl,float1 ld de,acc2 ld bc,6 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,6 ldir pop hl ld de,acc2 ld c,6 ldir ld hl,acc3 pop de ld c,6 ldir call fdiv jr c,fsqrerr ld hl,acc4 ld de,acc2 ld bc,6 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 128 sra a push af add a,128 ld [acc1+1],a pop af ret nc ld hl,floatsqrt2 ld de,acc2 ld bc,6 ldir jp fmul float1div2: db &00,&7f,&00,&00,&00,&80 ;1/2 farctan: ;acc1=arctan(acc1/acc2), cf=status ld hl,acc1+0 ld a,[hl] ld [hl],0 ld hl,acc2+0 ld b,[hl] ld [hl],0 xor b 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,6 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,6 ldir ld hl,acc1+0 ld a,[hl] xor 128 ld [hl],a call fadd ret c fatn02: ld a,[charwork00] ld hl,acc1+0 xor [hl] ld [hl],a and a ret ;cf=0 floatfatn0to1div2: db &00,&7b,&a4,&81,&94,&9d ;x^6 db &80,&7c,&27,&5b,&2c,&a3 ;x^5 db &00,&7c,&fc,&2a,&fd,&df ;x^4 db &80,&7d,&09,&43,&24,&92 ;x^3 db &00,&7d,&22,&69,&cb,&cc ;x^2 db &80,&7e,&6b,&a8,&aa,&aa ;x^1 db &00,&80,&00,&00,&00,&80 ;1 floatfatn1div2to1: db &80,&7c,&e9,&b8,&13,&8e ;x^5 db &00,&7c,&aa,&a2,&6a,&de ;x^4 db &80,&7d,&3f,&4f,&25,&92 ;x^3 db &00,&7d,&3d,&f0,&cb,&cc ;x^2 db &80,&7e,&ce,&a9,&aa,&aa ;x^1 db &00,&80,&00,&00,&00,&80 ;1 floatarctan1div2: db &00,&7e,&2b,&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,6 ldir pop hl ld de,acc2 ld c,6 ldir call fmul ret c ld hl,floatfatn0to1div2 ld b,7 call fpolynomial ret c ld hl,acc4 ld de,acc2 ld bc,6 ldir jp fmul fatn20: ;acc1 > 1/2 ;(acc1 - 1/2)/(1 + acc1/2) ld hl,acc1 push hl ld de,acc3 ld bc,6 ldir pop hl call fatn30 ld hl,float1 ld de,acc2 ld bc,6 ldir call fadd ret c ld hl,acc1 ld de,acc4 ld bc,6 ldir ld hl,acc3 ld de,acc1 ld bc,6 ldir ld hl,float1div2 ld de,acc2 ld c,6 ldir call fsub ret c ld hl,acc4 ld de,acc2 ld bc,6 ldir call fdiv ret c ld hl,acc1 push hl ld de,acc4 ld bc,6 ldir pop hl ld de,acc2 ld c,6 ldir call fmul ret c ld hl,floatfatn1div2to1 ld b,6 call fpolynomial ret c ld hl,acc4 ld de,acc2 ld bc,6 ldir call fmul ret c ld hl,floatarctan1div2 ld de,acc2 ld bc,6 ldir jp fadd fatn30: ;[hl]/2 inc hl ld a,[hl] and a ret z dec a ld [hl],a ret floatpidiv2: db &00,&80,&a3,&da,&0f,&c9 ;pi/2 floatmpidiv2: db &80,&80,&a3,&da,&0f,&c9 ;-pi/2 floatpi: db &00,&81,&a3,&da,&0f,&c9 ;pi floatmpi: db &80,&81,&a3,&da,&0f,&c9 ;-pi floatfsin: db &80,&66,&04,&5b,&36,&cd ;x^5 db &00,&6d,&2e,&8e,&b8,&b8 ;x^4 db &80,&73,&22,&f1,&0b,&d0 ;x^3 db &00,&79,&39,&86,&88,&88 ;x^2 db &80,&7d,&a5,&aa,&aa,&aa ;x^1 db &00,&80,&00,&00,&00,&80 ;1 floatfcos: db &00,&63,&15,&5a,&ce,&88 ;x^6 db &80,&6a,&83,&de,&c5,&93 ;x^5 db &00,&70,&85,&d9,&0b,&d0 ;x^4 db &80,&76,&d9,&5c,&0b,&b6 ;x^3 db &00,&7b,&9f,&aa,&aa,&aa ;x^2 db &80,&7f,&00,&00,&00,&80 ;x^1 db &00,&80,&00,&00,&00,&80 ;1 fcos: ;acc1=cos(acc1), cf=status ld hl,floatpidiv2 ld de,acc2 ld bc,6 ldir call fadd ret c ; fsin: ;acc1=sin(acc1), cf=status ld hl,acc1+0 ld a,[hl] ld [charwork00],a ld [hl],0 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,6 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,6 ldir pop hl ld de,acc2 ld c,6 ldir call fmul ret c ld hl,floatfsin ld b,6 call fpolynomial ret c ld hl,acc4 ld de,acc2 ld bc,6 ldir call fmul ret c jr fsin30 fsin20: ;acc1 > pi/2 ld hl,floatpidiv2 ld de,acc2 ld bc,6 ldir call fsub ret c ld hl,acc1 ld de,acc2 ld bc,6 ldir call fmul ret c ld hl,floatfcos ld b,7 call fpolynomial ret c ; fsin30: ld a,[charwork01] rrca and 128 ld b,a ld a,[charwork00] xor b ld [acc1+0],a and 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,6 ldir xor a ld [acc5+1],a ld [acc6+1],a ld a,[ix] cp '.' jp z,inba10 call isnumber ret c inba00: push af ld hl,acc5 ld de,acc1 ld bc,6 ldir ld hl,float10 ld de,acc2 ld c,6 ldir call fmul ld hl,acc1 ld de,acc2 ld bc,6 ldir pop bc jr c,inbaerr ld a,b call itof call fadd jr c,inbaerr ld hl,acc1 ld de,acc5 ld bc,6 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,6 ldir ld hl,acc6 ld de,acc2 ld c,6 ldir call fadd jr c,inbaerr ld hl,acc8 ld de,acc2 ld bc,6 ldir call fmul ret nc ; inbaerr:ld ix,[intwork00] scf ret inba10: ;[ix]='.' ld hl,float10 ld de,acc7 ld bc,6 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,6 ldir call fdiv jr c,inbaerr ld hl,acc6 ld de,acc2 ld bc,6 ldir call fadd jr c,inbaerr ld hl,acc1 ld de,acc6 ld bc,6 ldir ld hl,acc7 ld de,acc1 ld c,6 ldir ld hl,float10 ld de,acc2 ld c,6 ldir call fmul jr c,inbaerr ld hl,acc1 ld de,acc7 ld bc,6 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,6 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 &00,&83,&00,&00,&00,&a0 ;10 printbcdacc1: ;[ix~]=bcd acc1 ld hl,[acc1+0] ld a,h and a jr nz,prba00 ld [ix],'0' inc ix ret prba00: ld a,l ld [charwork00],a xor a ld [acc1+0],a ld hl,acc1 ld de,acc5 ld bc,6 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,6 ldir ld hl,acc5 ld de,acc1 ld c,6 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,6 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,6 ldir call fdiv inc [iy] jr prba10 prba12: ld iy,charwork01 call ftoi ld [iy],a inc iy ld b,8 prba20: push bc ld hl,acc1 ld de,acc2 ld bc,6 ldir call itof ld a,128 ld [acc1+0],a call fadd ld hl,acc1 ld de,acc2 ld bc,6 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+8 ld a,[hl] ld [hl],0 cp 5 jr c,prba31 ld b,8 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,8 and a jp m,prba33 cp 8 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,7 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,6 ldir pop hl ld de,ftmpy ;[ftmpy]=[de] ld c,6 ldir ld hl,ftmpy push hl call is0 pop hl jr z,cp00 ld a,[hl] and a 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 ld a,[hl] and a 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+1 ld hl,ftmpx+1 ld a,[de] cp [hl] ret nz ld de,ftmpy+5 ld hl,ftmpx+5 ld b,4 xgt0ygt000: ld a,[de] dec de cp [hl] dec hl ret nz djnz xgt0ygt000 ret floatflog2: db &00,&7e,&18,&2d,&73,&b4 ;x^5 db &00,&7e,&ff,&2c,&0b,&9e ;x^4 db &00,&7e,&45,&ad,&66,&d3 ;x^3 db &00,&7f,&e8,&3d,&ba,&93 ;x^2 db &00,&7f,&42,&51,&38,&f6 ;x^1 db &00,&81,&29,&3b,&aa,&b8 ;x^0 float2: db &00,&81,&00,&00,&00,&80 ;2 floatlog2divlog10: db &00,&7e,&85,&9a,&20,&9a ;log 2 / log 10 floatlog2: db &00,&7f,&f8,&17,&72,&b1 ;log 2 flog: ;acc1=x --> acc1=log(x), cf=status call flog2 ret c ld hl,floatlog2 ld de,acc2 ld bc,6 ldir jp fmul flog10: ;acc1=x --> acc1=log10(x), cf=status call flog2 ret c ld hl,floatlog2divlog10 ld de,acc2 ld bc,6 ldir jp fmul flog2: ;acc1=x --> acc1=log2(x), cf=status ld hl,[acc1+0] ld a,h and a scf ret z bit 7,l scf ret nz sub 128 push af ld a,128 ld [acc1+1],a ld hl,float1 ld de,acc2 ld bc,6 ldir call fsub jr c,flog2e ;acc4 = acc1/(2 + acc1) ld hl,acc1 ld de,acc3 ld bc,6 ldir ld hl,float2 ld de,acc2 ld c,6 ldir call fadd jr c,flog2e ld hl,acc1 ld de,acc2 ld bc,6 ldir ld hl,acc3 ld de,acc1 ld c,6 ldir call fdiv jr c,flog2e ld hl,acc1 push hl ld de,acc4 ld bc,6 ldir ;acc1=acc4^2 pop hl ld de,acc2 ld c,6 ldir call fmul jr c,flog2e ld hl,floatflog2 ld b,6 call fpolynomial jr c,flog2e ld hl,acc4 ld de,acc2 ld bc,6 ldir call fmul jr c,flog2e ld hl,acc1 ld de,acc2 ld bc,6 ldir pop af call itof jp fadd flog2e: pop bc scf ret fsinh: ;acc1=x --> acc1=sinh(x), cf=status ==(exp(x) - exp(-x))/2 call fexp jp c,err21 ld hl,acc1 ld de,acc3 call mtom ;acc3=exp(x) call frcp ;acc1=exp(-x) jp c,err3 ld hl,acc1 call chs fsinh00:ld hl,acc3 ld de,acc2 call mtom call fadd jp c,err24 ld hl,acc1 call fatn30 ;[hl]/2 and a ret ;cf=0 fcosh: ;acc1=x --> acc1=cosh(x), cf=status ==(exp(x) + exp(-x))/2 call fexp jp c,err21 ld hl,acc1 ld de,acc3 call mtom ;acc3=exp(x) call frcp ;acc1=exp(-x) jr nc,fsinh00 jp err3 floatfexp2: db &00,&70,&a1,&b5,&b8,&b5 ;x^7 db &00,&73,&33,&21,&f0,&95 ;x^6 db &00,&76,&a0,&08,&05,&b0 ;x^5 db &00,&79,&e5,&78,&82,&9d ;x^4 db &00,&7b,&38,&75,&59,&e3 ;x^3 db &00,&7d,&09,&e7,&fd,&f5 ;x^2 db &00,&7f,&0e,&18,&72,&b1 ;x^1 float1: db &00,&80,&00,&00,&00,&80 ;1 floatlog10divlog2: db &00,&81,&4b,&78,&9a,&d4 ;log 10 / log 2 float1divlog2: db &00,&80,&29,&3b,&aa,&b8 ;1 / log(2) fexp: ;acc1=x --> acc1=e^x, cf=status ld hl,float1divlog2 ld de,acc2 ld bc,6 ldir call fmul ret c jr fexp2 fexp10: ;acc1=x --> acc1=10^x, cf=status ld hl,floatlog10divlog2 ld de,acc2 ld bc,6 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) xor a ld [acc1+0],a call fexp200 ret c ld hl,acc1 ld de,acc2 ld bc,6 ldir ld hl,float1 ld de,acc1 ld c,6 ldir jp fdiv fexp210:xor a ld [acc1+1],a ret ;cf=0 fexp200:call ftoi ret c push af ld hl,acc1 ld de,acc2 ld bc,6 ldir call itof ld a,128 ld [acc1+0],a call fadd pop bc ret c push bc ld hl,floatfexp2 ld b,8 call fpolynomial pop bc ret c ld a,[acc1+1] and a ret z ;cf=0 add a,b ld [acc1+1],a ret ;cf=status fpolynomial: ;acc1=x, hl=ptr constant, b=count --> acc1=polynomial, cf=status exx ld hl,acc1 ld de,acc3 ld bc,6 ldir exx push bc ld de,acc2 ld bc,6 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,6 ldir exx push bc push hl call fmul pop hl pop bc ret c fpoly00: push bc ld de,acc2 ld bc,6 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 itof16: ;hl=int --> acc1=float ld a,h or l jr nz,itof1600 ld [acc1+1],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 bc,(128+16)*256+0 itof1620: dec b ld d,h ld e,l add hl,hl jr nc,itof1620 ld hl,acc1+1 ld [hl],b inc hl ld [hl],c ;+2 inc hl ld [hl],c ;+3 inc hl ld [hl],e ;+4 inc hl ld [hl],d ;+5 ret itof1611: ;8bit ld a,l ld bc,(128+8)*256+0 itof1610: dec b add a,a jr nc,itof1610 rra ld hl,acc1+1 ld [hl],b inc hl ld [hl],c ;+2 inc hl ld [hl],c ;+3 inc hl ld [hl],c ;+4 inc hl ld [hl],a ;+5 ret itof: ;a=int --> acc1=float and a jr nz,itof00 ld [acc1+1],a ret itof00: jp p,itof02 ex af,af' ld a,128 ld [acc1+0],a ex af,af' neg jr itof01 itof02: ex af,af' xor a ld [acc1+0],a ex af,af' itof01: ld bc,(128+8)*256+0 itof10: dec b add a,a jr nc,itof10 rra ld hl,acc1+1 ld [hl],b inc hl ld [hl],c ;+2 inc hl ld [hl],c ;+3 inc hl ld [hl],c ;+4 inc hl ld [hl],a ;+5 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 bc,[acc1+0] ld hl,0 ld a,b and a jr z,ftoi1620 sub 128 ccf ret nc ;hl=0, a!=0, cf=0 inc a ld de,[acc1+4] ld hl,0 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 de,[acc1+2] or d or e ret ;cf=0 ftoi1620: ;hl=0, a=0, cf=0 ld c,a ret ftoi: ;acc1 --> a=int abs acc1, c=sign, cf=status ld bc,[acc1+0] ld a,b and a ret z ;cf=0 sub 128 jr c,ftoi00 inc a ld b,a ld hl,[acc1+5] ld h,0 ftoi10: add hl,hl bit 7,h scf ret nz djnz ftoi10 ld a,h and a ret ;cf=0 ftoi00: xor a ret ;cf=0 fsub: ;acc1=acc1-acc2, cf=status ld a,[acc2+0] xor 128 ld [acc2+0],a ; 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,6 ldir and a ;cf=0 ret fadd00: ld bc,0 ld hl,[acc1+2] ld de,[acc2+2] exx ld hl,[acc1+4] ld de,[acc2+4] ld a,[acc2+1] ld b,a ld a,[acc1+1] sub b ld b,a jr nz,fadd10 ld a,h cp d jr nz,fadd10 ld a,l cp e jr nz,fadd10 exx ld a,h cp d jr nz,fadd11 ld a,l cp e fadd11: exx fadd10: jr nc,fadd20 ;abs acc2 > abs acc1 ld a,[acc2+1] ld [acc1+1],a ld a,[acc2+0] ld c,a ex af,af' ld a,[acc1+0] cp c ex af,af' ld [acc1+0],a ld a,b neg ld b,a ex de,hl exx ex de,hl exx jr fadd21 fadd20: ;abs acc1 >= abs acc2 ld a,[acc1+0] ld c,a ex af,af' ld a,[acc2+0] cp c ex af,af' fadd21: ld a,b and a jr z,fadd22 cp 40 jp nc,fadd30 cp 8 jr c,fadd23 sub 8 ld b,a exx ld c,e ld e,d exx ld a,e exx ld d,a exx ld e,d ld d,0 jr fadd21 fadd23: srl d rr e exx rr d rr e rr c exx djnz fadd23 fadd22: ld a,[acc1+1] ld b,a ex af,af' jr nz,fsub40 ;同符号 exx ld a,b add a,c ld b,a adc hl,de exx adc hl,de jr nc,fadd41 inc b scf ret z ;cf=1 rr h rr l exx rr h rr l rr b exx fadd41: ;丸め exx bit 7,b jr z,fadd42 inc l jr nz,fadd42 inc h jr nz,fadd42 exx inc l jr nz,fadd43 inc h jr nz,fadd43 ld h,&80 inc b scf ret z ;cf=1 jr fadd43 fadd42: exx fadd43: ld [acc1+0],bc ld [acc1+4],hl exx ld [acc1+2],hl and a ;cf=0 ret fsub40: ;異符号 exx ld a,b sub c ld b,a sbc hl,de exx sbc hl,de ld a,h or l exx or h or l or b exx jr nz,fsub41 fsub43: xor a ld [acc1+1],a ret ;cf=0 fsub41: ld a,h and a jr nz,fsub42 ld a,b sub 8 jr c,fsub43 jr z,fsub43 ld b,a ld h,l exx ld a,h exx ld l,a exx ld h,l ld l,b exx jr fsub41 fsub42: bit 7,h jr nz,fadd41 ;丸め exx sla b adc hl,hl exx adc hl,hl dec b jr nz,fsub42 jr fsub43 fadd30: ld a,c ld [acc1+0],a ld [acc1+4],hl exx ld [acc1+2],hl and a ;cf=0 ret 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+2] ld de,[acc2+2] ld bc,0 exx ld hl,[acc1+4] ld de,[acc2+4] ld bc,&0800 call fdiv00 jr nc,fdiv12 exx inc b add hl,hl exx adc hl,hl ;(cf=1) jr fdiv15 fdiv10: call fdiv00 jr c,fdiv14 fdiv12: scf fdiv15: rl c exx ;(cf=0) sbc hl,de exx sbc hl,de ; fdiv11: exx add hl,hl exx adc hl,hl jr nc,fdiv13 djnz fdiv15 ;cf=1 ld a,c ld [acc1+5],a ;next(sub32 OK) ld bc,&0800 jr fdiv22 fdiv14: and a ;cf=0 rl c jr fdiv11 fdiv13: djnz fdiv10 ld a,c ld [acc1+5],a ;next ld bc,&0800 fdiv20: call fdiv00 jr c,fdiv24 fdiv22: scf fdiv25: rl c exx ;(cf=0) sbc hl,de exx sbc hl,de ; fdiv21: exx add hl,hl exx adc hl,hl jr nc,fdiv23 djnz fdiv25 ;cf=1 ld a,c ld [acc1+4],a ;next(sub32 OK) ld bc,&0800 jr fdiv32 fdiv24: and a ;cf=0 rl c jr fdiv21 fdiv23: djnz fdiv20 ld a,c ld [acc1+4],a ;next ld bc,&0800 fdiv30: call fdiv00 jr c,fdiv34 fdiv32: scf fdiv35: rl c exx ;(cf=0) sbc hl,de exx sbc hl,de ; fdiv31: exx add hl,hl exx adc hl,hl jr nc,fdiv33 djnz fdiv35 ;cf=1 ld a,c ld [acc1+3],a ;next(sub32 OK) ld bc,&0800 jr fdiv42 fdiv34: and a ;cf=0 rl c jr fdiv31 fdiv33: djnz fdiv30 ld a,c ld [acc1+3],a ;next ld bc,&0800 fdiv40: call fdiv00 jr c,fdiv44 fdiv42: scf fdiv45: rl c exx ;(cf=0) sbc hl,de exx sbc hl,de ; fdiv41: exx add hl,hl exx adc hl,hl jr nc,fdiv43 djnz fdiv45 ;cf=1 ld a,c ld [acc1+2],a ;next(sub32 OK) jr fdiv52 fdiv44: and a ;cf=0 rl c jr fdiv41 fdiv43: djnz fdiv40 ld a,c ld [acc1+2],a ;next call fdiv00 jr c,fdiv51 fdiv52: ld hl,[acc1+4] exx ld hl,[acc1+2] inc l jr nz,fdiv53 inc h jr nz,fdiv53 exx inc l jr nz,fdiv54 inc h jr nz,fdiv54 ld h,&080 exx inc c exx ; fdiv54: exx fdiv53: ld [acc1+2],hl exx ld [acc1+4],hl fdiv51: ld a,[acc1+1] ld b,a ld a,[acc2+1] sub 128 jr nc,fdiv60 neg ld c,a ld a,b add a,c jr nc,fdiv61 ret ;cf=1 fdiv60: ld c,a ld a,b sub c jr z,fdiv70 jr c,fdiv70 ; fdiv61: exx sub b jr z,fdiv70 add a,c ret c ld [acc1+1],a ld a,[acc1+0] ld b,a ld a,[acc2+0] xor b ld [acc1+0],a ret ;cf=0 fdiv70: xor a ld [acc1+1],a ret ;cf=0 fdiv00: ;compare hl:hl' - de:de'--> cf=status ld a,h cp d ret nz ld a,l cp e ret nz exx ld a,h cp d jr nz,fdiv01 ld a,l cp e ; fdiv01: exx ret fmul: ;acc1=acc1*acc2, cf=status ld hl,acc1 call is0 ret z ;cf=0 ld hl,acc2 call is0 jp z,fmul00 ld a,[acc1+2] ld d,a exx ld bc,[acc1+3] ld a,[acc1+5] ld d,a xor a ex af,af' xor a ld h,a ld l,a exx ld e,a ld h,a ld l,a ld bc,[acc2+5] ld b,8 fmul10: sla c jr c,fmul11 exx jr fmul12 fmul11: add hl,de exx adc hl,bc adc a,d jr nc,fmul12 ex af,af' inc a ex af,af' fmul12: srl d rr b rr c exx rr d rr e djnz fmul10 ld bc,[acc2+4] inc c dec c jr nz,fmul201 push af ld e,d exx ld a,c exx ld d,a exx ld c,b ld b,d exx pop af jr fmul300 fmul201: ld b,8 fmul20: sla c jr c,fmul21 exx jr fmul22 fmul21: add hl,de exx adc hl,bc adc a,d jr nc,fmul22 ex af,af' inc a ex af,af' fmul22: srl b rr c exx rr d rr e djnz fmul20 fmul300: ld bc,[acc2+3] inc c dec c jr nz,fmul301 push af ld e,d exx ld a,c exx ld d,a exx ld c,b exx pop af jr fmul400 fmul301: ld b,8 fmul30: sla c jr c,fmul31 exx jr fmul32 fmul31: add hl,de exx adc hl,bc adc a,d jr nc,fmul32 ex af,af' inc a ex af,af' fmul32: srl c exx rr d rr e djnz fmul30 fmul400: ld bc,[acc2+2] inc c dec c jr z,fmul501 ld b,8 fmul40: sla c jr nc,fmul41 add hl,de exx adc hl,bc adc a,d jr nc,fmul42 ex af,af' inc a ex af,af' fmul42: exx fmul41: srl d rr e djnz fmul40 fmul501: exx ld c,a ld a,[acc1+1] ld b,a ex af,af' fmul50: and a jr z,fmul51 ;cf=0 rra rr c rr h rr l exx rr h rr l exx inc b jr nz,fmul50 fmul54: scf ret ;over flow fmul51: exx bit 7,l jr z,fmul52 inc h jr nz,fmul52 exx inc l jr nz,fmul53 inc h jr nz,fmul53 inc c jr nz,fmul53 ld c,&80 inc b jr z,fmul54 fmul53: exx fmul52: ld a,h ld [acc1+2],a exx ld [acc1+3],hl ld a,c ld [acc1+5],a ld a,[acc2+1] sub 128 jr nc,fmul60 neg ld c,a ld a,b sub c jr c,fmul00 jr z,fmul00 jr fmul61 fmul60: ld c,a ld a,b add a,c jr c,fmul54 fmul61: ld [acc1+1],a ld a,[acc1+0] ld b,a ld a,[acc2+0] xor b ld [acc1+0],a ret ;cf=0 fmul00: xor a ld [acc1+1],a ret ;cf=0 is0: ;hl==ptr acc --> zf=status, cf=0 inc hl ld a,[hl] and a ret title00: db '3D graphics ver.2.21 for MZ-80B',13 title01: db '(C) 1991, 2008, 2017 by someone',13 title10: db 'Key function:',13 title11: db ' 2,8,4,6,1,3: Roll',13 title111: db ' z,w,a,s,x,c: Roll 4x',13 title12: db ' m: Rendering mode',13 title13: db ' i: Input formula',13 title14: db ' r: Reset degree',13 title20: db 'Save data=',13 title30: db 'Input formula',13 title40: db 'Quit ?(y/n)',13 title50: db 'Sorting...',13 foinit_xyzst: db 'x=s,y=t,r=sqr(s*s+t*t),z=cos(r)*2/(r/3+0.4)',13 foinit_startend_s: db 'a=-8,b=8',13 foinit_startend_t: db 'a=-8,b=8',13 foinit_mesh_s: db 'm=10',13 foinit_mesh_t: db 'm=10',13 foinit_zoom: db 'z=150',13 fomsg_xyzst: db '> x=x(s,t), y=y(s,t), z=z(s,t)',13 fomsg_startend_s: db '> a=start s, b=end s',13 fomsg_startend_t: db '> a=start t, b=end t',13 fomsg_mesh_s: db '> m=mesh s',13 fomsg_mesh_t: db '> m=mesh t',13 fomsg_zoom: db '> z=zoom',13 start_s: db 0,0,0,0,0,0, 0,0,0,0,0,0 end_s: db 0,0,0,0,0,0, 0,0,0,0,0,0 start_t: db 0,0,0,0,0,0, 0,0,0,0,0,0 end_t: db 0,0,0,0,0,0, 0,0,0,0,0,0 mesh_s: dw 0 mesh_s1: dw 0 ;mesh s+1 mesh_t: dw 0 mesh_t1: dw 0 ;mesh t+1 ds: db 0,0,0,0,0,0, 0,0,0,0,0,0 ;(end_s - start_s)/mesh_s dt: db 0,0,0,0,0,0, 0,0,0,0,0,0 ;(end_t - start_t)/mesh_t ptrxyz1: dw xyz ptrxyz2: dw xyz ptrxyz3: dw xyz current_s: db 0,0,0,0,0,0, 0,0,0,0,0,0 current_t: db 0,0,0,0,0,0, 0,0,0,0,0,0 current_x: minx: db 0,0,0,0,0,0 maxx: db 0,0,0,0,0,0 ; current_y: miny: db 0,0,0,0,0,0 maxy: db 0,0,0,0,0,0 ; current_z: minz: db 0,0,0,0,0,0 maxz: db 0,0,0,0,0,0 screen: db 0,0,0,0,0,0 eyeoffset: db 0,0,0,0,0,0 zoom: db 0,0,0,0,0,0 z0: db 0,0,0,0,0,0 mmflag: db 0 rendermode: db 0 zoomfactor: dw 150 rollsin: db 0,0,0,0,0,0 ;sin(pi/rollfactor) rollsinm: db 0,0,0,0,0,0 ;-sin(pi/rollfactor) rollcos: db 0,0,0,0,0,0 ;cos(pi/rollfactor) rollfactor: dw 0 mesh_st: dw 0 rollsin1: db 0,0,0,0,0,0 ;sin(pi/rollfactor1) rollsinm1: db 0,0,0,0,0,0 ;-sin(pi/rollfactor1) rollcos1: db 0,0,0,0,0,0 ;cos(pi/rollfactor1) rollfactor1: dw 16 ;+++++++可変としてもよい rollsin4: db 0,0,0,0,0,0 ;sin(pi/rollfactor4) rollsinm4: db 0,0,0,0,0,0 ;-sin(pi/rollfactor4) rollcos4: db 0,0,0,0,0,0 ;cos(pi/rollfactor4) rollfactor4: dw 4 ;+++++++可変としてもよい setrollfactor: ld de,rollsin ld bc,6*3+2 push hl push de push bc ldir call setrollfactor00 pop bc pop hl pop de ldir ret setrollfactor00: ;[rollsin〜]=回転行列 ld hl,floatpi call mtox ld hl,[rollfactor] call itof16 err51: jp c,err5 ld hl,acc1 call mtox call div jr c,err51 ld hl,buffer+0 push hl call xtom pop hl push hl ld de,acc1 push de call mtom call fsin jr c,err51 pop hl push hl ld de,rollsin call mtom pop de ;acc1 pop hl ;buffer+0 push de call mtom call fcos jr c,err51 pop hl ;acc1 ld de,rollcos call mtom ld hl,rollsin ld de,rollsinm push de call mtom pop hl call chs ret initformula: ld hl,foinit_xyzst ld de,fo_xyzst call init10 ld hl,foinit_startend_s ld de,fo_startend_s call init10 ld hl,foinit_startend_t ld de,fo_startend_t call init10 ld hl,foinit_mesh_s ld de,fo_mesh_s call init10 ld hl,foinit_mesh_t ld de,fo_mesh_t call init10 ld hl,foinit_zoom ld de,fo_zoom call init10 ret init10: ld a,[hl] inc hl ld [de],a inc de cp 13 jr nz,init10 ret initvariable: ld hl,complextmpatoz+1 ld de,6 ld b,2*26 init00: ld [hl],0 add hl,de djnz init00 ret initstack: ld hl,floatstacktop ld [ptrstackpointer],hl ret init: call initstack call initvariable ret start: ld hl,title00 call message call crlf ld hl,title01 call message call crlf call initformula ; hotstart: ld hl,title10 call message call crlf ld hl,title11 call message call crlf ld hl,title111 call message call crlf ld hl,title12 call message call crlf ld hl,title13 call message call crlf ld hl,title14 call message call crlf ld [sp_work],sp main: ld sp,[sp_work] in a,[&e8] ;vramアクセス禁止 res 7,a out [&e8],a ld a,&01 ;vram表示もしない out [&f4],a call init call crlf ld hl,title30 call message call crlf ld hl,fomsg_xyzst ld de,fo_xyzst call inputformula ld hl,fomsg_startend_s ld de,fo_startend_s call inputformula ld hl,fomsg_startend_t ld de,fo_startend_t call inputformula ld hl,fomsg_mesh_s ld de,fo_mesh_s call inputformula ld hl,fomsg_mesh_t ld de,fo_mesh_t call inputformula ld hl,fomsg_zoom ld de,fo_zoom call inputformula main00: ld ix,fo_startend_s call main10 ld hl,complextmpatoz+0*12 ;複素変数a ld de,start_s call mctomc ld hl,complextmpatoz+1*12 ;複素変数b ld de,end_s call mctomc ld ix,fo_startend_t call main10 ld hl,complextmpatoz+0*12 ;複素変数a ld de,start_t call mctomc ld hl,complextmpatoz+1*12 ;複素変数b ld de,end_t call mctomc ld ix,fo_mesh_s call main10 ld hl,complextmpatoz+12*12+0 ;変数mの実数部 ld de,acc1 call mtom call ftoi16 jp c,err5 bit 7,h jp nz,err5 ld [mesh_s],hl inc hl bit 7,h jp nz,err5 ld [mesh_s1],hl ld ix,fo_mesh_t call main10 ld hl,complextmpatoz+12*12+0 ;変数mの実数部 ld de,acc1 call mtom call ftoi16 jp c,err5 bit 7,h jp nz,err5 ld [mesh_t],hl inc hl bit 7,h jp nz,err5 ld [mesh_t1],hl ;end_s - start_s ld hl,end_s ld de,floata call mctomc ld hl,start_s ld de,floatc call mctomc call nsub ;/mesh_s ld hl,[mesh_s] call itof16 ld hl,acc1 ld de,floatc call mtom xor a ld [floatd+1],a call ndiv ld hl,floata ld de,ds call mctomc ;end_t - start_t ld hl,end_t ld de,floata call mctomc ld hl,start_t ld de,floatc call mctomc call nsub ;/mesh_t ld hl,[mesh_t] call itof16 ld hl,acc1 ld de,floatc call mtom xor a ld [floatd+1],a call ndiv ld hl,floata ld de,dt call mctomc ld ix,fo_zoom call main10 ld hl,complextmpatoz+25*12+0 ;変数zの実数部 ld de,acc1 call mtom call ftoi16 jp c,err5 bit 7,h jp nz,err5 ld a,h or l jp z,err5 ld [zoomfactor],hl ;[rollsin1〜]=回転行列(1x) ld hl,rollsin1 call setrollfactor ;[rollsin4〜]=回転行列(4x) ld hl,rollsin4 call setrollfactor ;データ領域へのポインタを計算する ld hl,xyz ld [ptrxyz1],hl ld de,[mesh_s] push de inc de ld bc,[mesh_t] push bc inc bc ld a,b and a jp nz,err6 call imulp err60: jp c,err6 ex de,hl ld bc,22 ;*(6*3+2*2)=*22 call imulp jr c,err60 ld de,xyz add hl,de jr c,err60 ld [ptrxyz2],hl pop bc ;mesh_t pop de ;mesh_s call imulp ld [mesh_st],hl push hl ex de,hl ld bc,22 ;*(2*8+6)=*22 call imulp jr c,err60 ld de,[ptrxyz2] add hl,de jr c,err60 ld [ptrxyz3],hl ex de,hl pop hl ;mesh_s*mesh_t add hl,hl ;*2 jr c,err60 add hl,de jr c,err60 ;仮想vramが使えるか xor a ld [vvactive],a ld hl,vvr ld de,320*200/8 add hl,de jr c,calc ld bc,&d000 ;cf=0 sbc hl,bc jr nc,calc ld hl,vvr2 add hl,de jr c,calc ;cf=0 sbc hl,bc jr nc,calc inc a ld [vvactive],a ;vvactive!=0ならば、仮想vramが使える calc: ld sp,[sp_work] in a,[&e8] ;vramアクセス禁止 res 7,a out [&e8],a ld a,&01 ;vram表示もしない out [&f4],a xor a ld [rendermode],a ;データを計算する xor a ld [mmflag],a ld hl,start_t ld de,current_t call mctomc ld de,[ptrxyz1] ld bc,[mesh_t1] calc00: push bc ld h,b ld l,c call hex call crlf push de ld hl,start_s ld de,current_s call mctomc pop de ld bc,[mesh_s1] calc10: push bc push de call initstack call initvariable ld hl,current_s ld de,complextmpatoz+18*12 ;複素変数s call mctomc ld hl,current_t ld de,complextmpatoz+19*12 ;複素変数t call mctomc ld ix,fo_xyzst call main11 ;式を計算 pop de ld hl,complextmpatoz+23*12+0 ;変数xの実数部 call mtom ld hl,complextmpatoz+24*12+0 ;変数yの実数部 call mtom ld hl,complextmpatoz+25*12+0 ;変数zの実数部 call mtom inc de ;2*2の領域を飛ばす inc de inc de inc de push de ld a,[mmflag] and a jr nz,calc20 inc a ld [mmflag],a ld hl,complextmpatoz+23*12+0 ;変数xの実数部 ld de,minx push hl call mtom ;minx pop hl call mtom ;maxx ld hl,complextmpatoz+24*12+0 ;変数yの実数部 push hl call mtom ;miny pop hl call mtom ;maxy ld hl,complextmpatoz+25*12+0 ;変数zの実数部 push hl call mtom ;minz pop hl call mtom ;maxz jr calc30 calc20: ld hl,complextmpatoz+23*12+0 ;変数xの実数部 ld de,minx push hl push de call fcp ;minx-x pop de pop hl call nc,mtom ld hl,complextmpatoz+23*12+0 ;変数xの実数部 ld de,maxx push hl push de call fcp ;maxx-x pop de pop hl call c,mtom ld hl,complextmpatoz+24*12+0 ;変数yの実数部 ld de,miny push hl push de call fcp ;miny-y pop de pop hl call nc,mtom ld hl,complextmpatoz+24*12+0 ;変数yの実数部 ld de,maxy push hl push de call fcp ;maxy-y pop de pop hl call c,mtom ld hl,complextmpatoz+25*12+0 ;変数zの実数部 ld de,minz push hl push de call fcp ;minz-z pop de pop hl call nc,mtom ld hl,complextmpatoz+25*12+0 ;変数zの実数部 ld de,maxz push hl push de call fcp ;maxz-z pop de pop hl call c,mtom calc30: ld hl,current_s ld de,floata push hl push de call mctomc ld hl,ds ld de,floatc call mctomc call nadd pop hl ;floata pop de ;current_s call mctomc pop de pop bc dec bc ld a,b or c jp nz,calc10 push de ld hl,current_t ld de,floata push hl push de call mctomc ld hl,dt ld de,floatc call mctomc call nadd pop hl ;floata pop de ;current_t call mctomc pop de pop bc dec bc ld a,b or c jp nz,calc00 ld hl,minx call main20 ld hl,miny call main20 ld hl,minz call main20 ;minx, miny, minz = (min+max)/2 ld hl,minx call main30 ld hl,miny call main30 ld hl,minz call main30 ;(0,0,0)を中心にする ld hl,[ptrxyz1] calc100: ld de,[ptrxyz2] and a sbc hl,de jr nc,calc101 add hl,de ;x push hl ld de,acc1 call mtom ld hl,minx ld de,acc2 call mtom call fsub ld hl,acc1 pop de call mtom ex de,hl ;y push hl ld de,acc1 call mtom ld hl,miny ld de,acc2 call mtom call fsub ld hl,acc1 pop de call mtom ex de,hl ;z push hl ld de,acc1 call mtom ld hl,minz ld de,acc2 call mtom call fsub ld hl,acc1 pop de call mtom ld hl,2*2 ;読み飛ばす add hl,de jr calc100 calc101: call hex ;+++++++ ;screen=2*sqr(max(x^2+y^2+z^2)) xor a ld [mmflag],a ld hl,[ptrxyz1] calc110: ld de,[ptrxyz2] and a sbc hl,de jp nc,calc111 add hl,de ;x push hl ld de,acc1 call mtom pop hl ld de,acc2 call mtom push hl call fmul ld hl,acc1 ld de,buffer+0 call mtom pop hl ;y push hl ld de,acc1 call mtom pop hl ld de,acc2 call mtom push hl call fmul ld hl,acc1 ld de,buffer+6 call mtom pop hl ;z push hl ld de,acc1 call mtom pop hl ld de,acc2 call mtom push hl call fmul ld hl,acc1 ld de,buffer+12 call mtom ld hl,buffer+0 ld de,acc1 ld bc,12 ldir call fadd ld hl,buffer+12 ld de,acc2 call mtom call fadd ld a,[mmflag] and a jr nz,calc120 inc a ld [mmflag],a ld hl,acc1 ld de,screen call mtom jr calc121 calc120: ld hl,acc1 ld de,screen push hl push de call fcp ;screen-acc1 pop de pop hl call c,mtom calc121: pop hl ld de,2*2 ;読み飛ばす add hl,de jp calc110 calc111: call hex ;+++++++ call crlf ;+++++++ ld hl,screen push hl ld de,acc1 push de call mtom call fsqrt pop hl pop de call mtom ld hl,screen+1 ;screen*=2 inc [hl] ;eyeoffset=screen*1.6 ld a,16 call itof ld hl,acc1 push hl call mtox ld a,10 call itof pop hl call mtox call div ;16/10+++++++ ld hl,screen call mtox call mul ld hl,eyeoffset call xtom ;zoom=zoomfactor/screen ld hl,[zoomfactor] call itof16 ld hl,acc1 call mtox ld hl,screen call mtox call div ld hl,zoom call xtom ;screen=screen+eyeoffset ld hl,screen push hl call mtox ld hl,eyeoffset call mtox call ad pop hl call xtom call clsc loop: ;メインループ ld sp,[sp_work] ld hl,[ptrxyz1] loop100: ld de,[ptrxyz2] and a sbc hl,de jp nc,loop101 add hl,de ld de,current_x call mtom ld de,current_y call mtom ld de,current_z call mtom push hl ld hl,screen call mtox ld hl,current_z call mtox ld hl,eyeoffset call mtox call ad ;z+eyeoffset jp c,err5 call div ;screen/(z+eyeoffset) jp c,err5 ld hl,zoom call mtox call mul ;*zoom jp c,err5 ld hl,z0 call xtom ld hl,current_x call mtox ld hl,z0 call mtox call mul jp c,err5 ld hl,acc1 call xtom call ftoi16 jp c,err5 ld de,160 add hl,de ex de,hl pop hl ;disp x ld [hl],e inc hl ld [hl],d inc hl push hl ld hl,current_y call mtox ld hl,z0 call mtox call mul jp c,err5 ld hl,acc1 call xtom call ftoi16 jp c,err5 ld de,100 add hl,de ex de,hl pop hl ;disp y ld [hl],e inc hl ld [hl],d inc hl jp loop100 loop101: call clsv ld a,[rendermode] and a jp nz,loop200 ;mode=0(ライン) ld de,[mesh_s1] ld bc,6*3+2*2 call imulp ld [buffer+0],hl ld hl,[ptrxyz1] loop110: call keyint ;キー割込みがあるか ld [buffer+2],hl ld de,[ptrxyz2] and a sbc hl,de jp nc,loop111 add hl,de ld bc,[mesh_s] jr loop121 loop120: push bc ld de,6*3 add hl,de ;読み飛ばす ld de,dr_x1 ldi ;x ldi ldi ;y ldi push hl ld de,6*3 add hl,de ld de,dr_x2 ldi ;x ldi ldi ;y ldi call line pop hl pop bc dec bc loop121: ld a,b or c jr nz,loop120 ld hl,[buffer+2] ld de,[buffer+0] add hl,de jp loop110 loop111: ld hl,[ptrxyz1] ld de,[buffer+0] add hl,de ld [buffer+4],hl ld hl,[ptrxyz1] loop130: call keyint ;キー割込みがあるか ld [buffer+2],hl ld de,[buffer+4] and a sbc hl,de jp nc,loop131 add hl,de ld bc,[mesh_t] jr loop141 loop140: push bc ld de,6*3 add hl,de ;読み飛ばす ld de,dr_x1 ldi ;x ldi ldi ;y ldi ld de,-(6*3+2*2) add hl,de ;戻す ld de,[buffer+0] add hl,de ;次のアドレス push hl ld de,6*3 add hl,de ld de,dr_x2 ldi ;x ldi ldi ;y ldi call line pop hl pop bc dec bc loop141: ld a,b or c jr nz,loop140 ld hl,[buffer+2] ld de,6*3+2*2 add hl,de jp loop130 loop131: jp loop300 ;キー入力待ちへ loop200: ;mode=1(ソリッド) ld de,[mesh_s1] ld bc,6*3+2*2 call imulp ld [buffer+0],hl ld hl,[ptrxyz2] ld [buffer+2],hl ld hl,[ptrxyz1] ld bc,[mesh_t] jp loop211 loop210: push bc ld bc,[mesh_s] jp loop241 loop240: push bc ;4角形の座標をセットする ld de,[buffer+2] push hl ld bc,6*3 add hl,bc ldi ;x1 ldi ldi ;y1 ldi ld bc,6*3 add hl,bc ldi ;x2 ldi ldi ;y2 ldi ld bc,[buffer+0] ;縦方向 add hl,bc ld bc,-(2*2) add hl,bc ldi ;x3 ldi ldi ;y3 ldi ld bc,-((6*3+2*2)+(2*2)) add hl,bc ldi ;x4 ldi ldi ;y4 ldi pop hl ld [buffer+2],de ;視点からの距離(xyz/4 - eye)をセットする push hl ld de,current_x+0*6 ld bc,6*3 ldir ld bc,2*2 add hl,bc call loop220 ;current_xyz+=xyz, hl=hl+6*3 pop hl push hl ld bc,[buffer+0] ;縦方向 add hl,bc call loop220 ;current_xyz+=xyz, hl=hl+6*3 ld bc,2*2 add hl,bc call loop220 ;current_xyz+=xyz, hl=hl+6*3 ld hl,current_x+0*6 call loop230 ;x/4 dec hl push hl call mtox pop hl call mtox call mul ;(x/4)^2 ld hl,current_x+1*6 call loop230 ;y/4 dec hl push hl call mtox pop hl call mtox call mul ;(y/4)^2 ld hl,current_x+2*6 call loop230 ;z/4 dec hl push hl call mtox ld hl,eyeoffset call mtox call sb ;z/4-eyeoffset pop hl push hl call xtom pop hl push hl call mtox pop hl call mtox call mul ;(z/4-eyeoffset)^2 call ad ;+(y/4)^2 call ad ;+(x/4)^2 ld hl,[buffer+2] call xtom ld [buffer+2],de pop hl ld bc,6*3+2*2 add hl,bc pop bc dec bc loop241: ld a,b or c jp nz,loop240 ld bc,6*3+2*2 add hl,bc pop bc dec bc loop211: ld a,b or c jp nz,loop210 ld hl,[buffer+2] ;+++++++ ld de,[ptrxyz3] and a sbc hl,de call hex call crlf ld hl,[ptrxyz2] ld de,[ptrxyz3] ld bc,[mesh_st] jr loop251 loop250: ex de,hl ld [hl],e inc hl ld [hl],d inc hl ex de,hl push bc ld bc,2*8+6 add hl,bc pop bc dec bc loop251: ld a,b or c jr nz,loop250 ld hl,title50 ;+++++++ call message call crlf call qsort call c,sort call clsc ld hl,[ptrxyz3] ld bc,[mesh_st] jr loop261 loop260: push bc call keyint ;+++++++ ld e,[hl] inc hl ld d,[hl] inc hl push hl ex de,hl ld de,p4_x1+0 ld bc,2*8 ldir call p4_polygon ld a,[cr_flag] and a push af call z,p4_bline pop af call nz,p4_bline2 pop hl pop bc dec bc loop261: ld a,b or c jr nz,loop260 jp loop300 qsort: ;[[ptrxyz3]〜]をdistanceの遠い順にソートする。cf=status ld hl,[mesh_st] ld a,h or l ret z ;データ個数=0, cf=0 dec hl ld a,h or l ret z ;データ個数=1, cf=0 ld a,[vvactive] and a scf ret z ld [sort_wsp],sp ld sp,vvr+320*200/8*2-1 ;仮想vramが空いているのでスタックに使う ld [sort_last],hl ;[mesh_st]-1 ld hl,0 ld [sort_first],hl call qsort00 ld sp,[sort_wsp] ret qsort00: ;[sort_first]:first, [sort_last]:last ld hl,[sort_first] ld de,[sort_last] add hl,de rr h rr l add hl,hl ld de,[ptrxyz3] add hl,de ld e,[hl] inc hl ld d,[hl] ex de,hl ld de,2*8 add hl,de ld de,sort_w01 ;x=a[(first+last)/2] ld bc,6 ldir ;i=first ld ix,[sort_first] ;j=last ld iy,[sort_last] qsort10: ;while(a[i] < x) i++; push ix pop hl add hl,hl ld de,[ptrxyz3] add hl,de ld [sort_ptr00],hl ;i ld e,[hl] inc hl ld d,[hl] ex de,hl ld de,2*8 add hl,de ;a[i] ld de,sort_w01 ;x ex de,hl call fcp ;a[i]-x jr nc,qsort20 inc ix jr qsort10 qsort20: ;while(x < a[j]) j--; push iy pop hl add hl,hl ld de,[ptrxyz3] add hl,de ld [sort_ptr01],hl ;j ld e,[hl] inc hl ld d,[hl] ex de,hl ld de,2*8 add hl,de ;a[j] ld de,sort_w01 ;x call fcp ;x-a[j] jr nc,qsort21 dec iy jr qsort20 qsort21: ;if( i >= j ) break; push ix pop hl push iy pop de and a sbc hl,de ;i-j bit 7,h jr z,qsort30 ;xchg a[i],a[j] push ix push iy ld ix,[sort_ptr00] ld iy,[sort_ptr01] ld l,[ix+0] ld h,[ix+1] ld e,[iy+0] ld d,[iy+1] ld [ix+0],e ld [ix+1],d ld [iy+0],l ld [iy+1],h pop iy pop ix ;i++; j--; inc ix dec iy jp qsort10 qsort30: ;if(first < i-1) qsort(first, i-1) push ix pop de dec de ;i-1 ld hl,[sort_first] and a sbc hl,de ;first - (i-1) bit 7,h jr z,qsort31 ld hl,[sort_last] push hl ld [sort_last],de ;i-1 call qs_stackcheck call qsort00 pop hl ld [sort_last],hl qsort31: ;if(j+1 < last) qsort(j+1, last) push iy pop hl inc hl ;j+1 ld de,[sort_last] and a sbc hl,de ;(j+1) - last bit 7,h jr z,qsort32 add hl,de ;j+1 ex de,hl ld hl,[sort_first] push hl ld [sort_first],de ;j+1 call qs_stackcheck call qsort00 pop hl ld [sort_first],hl qsort32: and a ret ;cf=0 qs_stackcheck: ld hl,vvr+256 ;+++++++ and a sbc hl,sp ret c ld sp,[sort_wsp] ld hl,sort_msg00 ;+++++++ call message call crlf scf ret sort_msg00: db 'Quick sort failed, trying normal sort...',13 sort_ptr00: dw 0 sort_ptr01: dw 0 sort_first: dw 0 sort_last: dw 0 sort_wsp: dw 0 sort_w00: dw 0 sort_w01: db 0,0,0,0,0,0 sort: ld hl,[mesh_st] ld a,h or l ret z ;データ個数=0 dec hl ld a,h or l ret z ;データ個数=1 ld [sort_w00],hl ld bc,0 ld ix,[ptrxyz3] sort00: ld e,[ix+0] ld d,[ix+1] inc ix inc ix ld hl,2*8 add hl,de ld de,sort_w01 push bc ld bc,6 ldir ;distance(1) pop bc inc bc push bc push ix pop iy sort10: ld e,[iy+0] ld d,[iy+1] inc iy inc iy ld hl,2*8 add hl,de ;distance(2) ld de,sort_w01 ;distance(1) push bc ex de,hl call fcp ;[de]-[hl] pop bc jr nc,sort11 ;[ix-2〜] <--> [iy-2〜] ld l,[ix-2] ld h,[ix-1] ld e,[iy-2] ld d,[iy-1] ld [ix-2],e ld [ix-1],d ld [iy-2],l ld [iy-1],h ld hl,2*8 add hl,de ld de,sort_w01 push bc ld bc,6 ldir ;new distance(1) pop bc sort11: inc bc ld hl,[mesh_st] and a sbc hl,bc jr nz,sort10 pop bc ld hl,[sort_w00] and a sbc hl,bc jr nz,sort00 ret loop230: inc hl ld a,[hl] and a ret z dec [hl] ;/2 ret z dec [hl] ;/4 ret loop220: call mtox ;x push hl ld hl,current_x+0*6 ;x push hl call mtox call ad pop hl call xtom pop hl call mtox ;y push hl ld hl,current_x+1*6 ;y push hl call mtox call ad pop hl call xtom pop hl call mtox ;z push hl ld hl,current_x+2*6 ;z push hl call mtox call ad pop hl call xtom pop hl ret loop300: call keyint ;キー割込みがあるか jr loop300 keyint10: push de push bc ld de,rollsin ld bc,6*3 ldir pop bc pop de ret keyint: ;キー割込みがあるか push hl call _getkey pop hl and a ret z cp 11 jp z,keyint00 cp 'I' jp z,main cp 'R' jp z,calc cp 'M' jr z,mode push hl ld hl,rollsin1 call keyint10 pop hl cp '2' jp z,rollyz0 cp '8' jp z,rollyz1 cp '4' jp z,rollzx0 cp '6' jp z,rollzx1 cp '1' jp z,rollxy0 cp '3' jp z,rollxy1 push hl ld hl,rollsin4 call keyint10 pop hl cp 'Z' jr z,rollyz0 cp 'W' jr z,rollyz1 cp 'A' jp z,rollzx0 cp 'S' jp z,rollzx1 cp 'X' jp z,rollxy0 cp 'C' jp z,rollxy1 ret mode: ld a,[rendermode] xor 1 ld [rendermode],a jp loop rollyz0:xor a jr rollyz rollyz1:ld a,1 rollyz: ld [mmflag],a ; ld hl,[ptrxyz1] rollyz00: ld de,[ptrxyz2] and a sbc hl,de jp nc,loop add hl,de ld de,6 add hl,de push hl call mtox ;y ld hl,rollcos call mtox call mul ;cos*y jp c,err5 pop hl ld de,6 add hl,de push hl call mtox ;z ld hl,rollsinm ld a,[mmflag] and a jr z,rollyz10 ld hl,rollsin rollyz10: call mtox call mul ;-+sin*z jp c,err5 call ad ;cos*y-+sin*z jp c,err5 ld hl,buffer+0 call xtom pop hl ld de,-6 add hl,de push hl call mtox ;y ld hl,rollsin ld a,[mmflag] and a jr z,rollyz11 ld hl,rollsinm rollyz11: call mtox call mul ;+-sin*y jp c,err5 pop hl ld de,6 add hl,de push hl call mtox ;z ld hl,rollcos call mtox call mul ;cos*z jp c,err5 call ad ;+-sin*y+cos*z jp c,err5 ld hl,buffer+6 call xtom pop hl ld de,-6 add hl,de ex de,hl ;de=y ld hl,buffer+0 call mtom ;y ld hl,buffer+6 call mtom ;z ld hl,2*2 add hl,de jp rollyz00 rollzx0:xor a jr rollzx rollzx1:ld a,1 rollzx: ld [mmflag],a ; ld hl,[ptrxyz1] rollzx00: ld de,[ptrxyz2] and a sbc hl,de jp nc,loop add hl,de push hl ld de,6+6 add hl,de call mtox ;z ld hl,rollcos call mtox call mul ;cos*z jp c,err5 pop hl push hl call mtox ;x ld hl,rollsinm ld a,[mmflag] and a jr z,rollzx10 ld hl,rollsin rollzx10: call mtox call mul ;-+sin*x jp c,err5 call ad ;cos*z-+sin*x jp c,err5 ld hl,buffer+0 call xtom pop hl push hl ld de,6+6 add hl,de call mtox ;z ld hl,rollsin ld a,[mmflag] and a jr z,rollzx11 ld hl,rollsinm rollzx11: call mtox call mul ;+-sin*z jp c,err5 pop hl push hl call mtox ;x ld hl,rollcos call mtox call mul ;cos*x jp c,err5 call ad ;+-sin*z+cos*x jp c,err5 ld hl,buffer+6 call xtom pop hl ex de,hl ;de=x ld hl,buffer+6 call mtom ;x ld hl,6 add hl,de ex de,hl ;de=z ld hl,buffer+0 call mtom ;z ld hl,2*2 add hl,de jp rollzx00 rollxy0:xor a jr rollxy rollxy1:ld a,1 rollxy: ld [mmflag],a ; ld hl,[ptrxyz1] rollxy00: ld de,[ptrxyz2] and a sbc hl,de jp nc,loop add hl,de push hl call mtox ;x ld hl,rollcos call mtox call mul ;cos*x jp c,err5 pop hl ld de,6 add hl,de push hl call mtox ;y ld hl,rollsinm ld a,[mmflag] and a jr z,rollxy10 ld hl,rollsin rollxy10: call mtox call mul ;-+sin*y jp c,err5 call ad ;cos*x-+sin*y jp c,err5 ld hl,buffer+0 call xtom pop hl ld de,-6 add hl,de push hl call mtox ;x ld hl,rollsin ld a,[mmflag] and a jr z,rollxy11 ld hl,rollsinm rollxy11: call mtox call mul ;+-sin*x jp c,err5 pop hl ld de,6 add hl,de push hl call mtox ;y ld hl,rollcos call mtox call mul ;cos*y jp c,err5 call ad ;+-sin*x+cos*y jp c,err5 ld hl,buffer+6 call xtom pop hl ld de,-6 add hl,de ex de,hl ;de=x ld hl,buffer+0 call mtom ;x ld hl,buffer+6 call mtom ;y ld hl,6+2*2 add hl,de jp rollxy00 keyint00: in a,[&e8] ;vramアクセス禁止 res 7,a out [&e8],a ld a,&01 ;vram表示もしない out [&f4],a push hl call crlf ld hl,title40 call message call crlf pop hl keyint01: call keywait cp 'Y' jp z,mainend cp 'N' jr nz,keyint01 push hl call clsc pop hl ld a,&03 ;vram表示する out [&f4],a ret keywait: push hl call _getkey pop hl and a jr z,keywait ret err5: ld a,5 ;over flow jp err err6: ld a,6 ;out of memory jp err main30: push hl ld de,acc1 ld bc,12 ldir call fadd jr c,err5 ld a,[acc1+1] and a jr z,main31 dec a ld [acc1+1],a main31: ld hl,acc1 pop de jp mtom main10: ;ix=数式の文字列へのポインタ → 式を評価する。結果は変数領域[complextmpatoz〜] call initstack call initvariable main11: call getformula call spcs ld a,[ix] cp 13 jp nz,err1 ret main20: ld de,acc1 push de call mtom push hl ld ix,buffer call printbcdacc1 ld [ix],' ' inc ix pop hl pop de call mtom call printbcdacc1 ld [ix],13 ld hl,buffer call message jp crlf mainend: ;終了 in a,[&e8] ;vramアクセス禁止 res 7,a out [&e8],a ld a,&01 ;vram表示もしない out [&f4],a call crlf ld hl,title20 call message ld hl,savedata call hex ld a,'-' call _pcha ld hl,savedataend call hex call crlf jp monitor inputformula: ;数式の入力 push de call message call crlf pop hl push hl call message ld a,'?' call _pcha call crlf call input jr nc,inf00 call crlf ld hl,title40 call message call crlf inf10: call keywait cp 'Y' jr z,mainend cp 'N' jr nz,inf10 ld a,13 ld [_ptrinputdata],a inf00: ld hl,_ptrinputdata ld a,[hl] cp 13 pop de ret z ;空入力の時は式を変更しない call init10 ret dumpacc:ld b,6 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+6*0 acc2= datastart00+6*1 acc3= datastart00+6*2 acc4= datastart00+6*3 acc5= datastart00+6*4 acc6= datastart00+6*5 acc7= datastart00+6*6 acc8= datastart00+6*7 ftmpx= datastart00+6*8 ftmpy= datastart00+6*9 fnlna= datastart00+6*10 fnlnb= datastart00+6*11 fnlnc= datastart00+6*12 datastart10=datastart00+6*13 ;int 作業用 intwork00=datastart10+2*0 sp_work=datastart10+2*1 ;spレジスタ保存 datastart20=datastart10+2*2 ;char 作業用 charwork00=datastart20+1*0 charwork01=datastart20+1*1 charwork02=datastart20+1*10 datastart30=datastart20+1*11 ;complex tmp a〜z 式評価用一時変数 complextmpatoz=datastart30 datastart40=datastart30+12*26 ;float a〜z 作業用 floata= datastart40+6*0 floatb= datastart40+6*1 floatc= datastart40+6*2 floatd= datastart40+6*3 floate= datastart40+6*4 floatf= datastart40+6*5 floatg= datastart40+6*6 floath= datastart40+6*7 floati= datastart40+6*8 floatj= datastart40+6*9 floatk= datastart40+6*10 floatl= datastart40+6*11 floatm= datastart40+6*12 floatn= datastart40+6*13 floato= datastart40+6*14 floatp= datastart40+6*15 floatq= datastart40+6*16 floatr= datastart40+6*17 floats= datastart40+6*18 floatt= datastart40+6*19 floatu= datastart40+6*20 floatv= datastart40+6*21 floatw= datastart40+6*22 floatx= datastart40+6*23 floaty= datastart40+6*24 floatz= datastart40+6*25 datastart50=datastart40+6*26 ;計算用スタック ptrstackpointer=datastart50 floatstack=datastart50+2*1 floatstacktop=floatstack+256 datastart60=datastart50+2+256 ;式計算作業用 formulawork=datastart60 floatformula_a=datastart60 floatformula_b=datastart60+6 charformula_entrylevel=datastart60+12 ptrformula_execaddress=datastart60+13 charformula_leftvalue=datastart60+15 datastart70=datastart60+16 buffer=datastart70 ;文字表示用バッファー savedata=datastart70+80 ;セーブデータ領域 fo_xyzst= savedata+80*0 fo_startend_s= savedata+80*1 fo_startend_t= savedata+80*2 fo_mesh_s= savedata+80*3 fo_mesh_t= savedata+80*4 fo_zoom= savedata+80*5 savedataend=savedata+80*6 vvr=savedataend ;仮想vram(320*200) vvr2=vvr+320*200/8 ;仮想vram2(320*200) xyz=vvr2+320*200/8 ;1) 実数座標(x,y,z)および整数座標(x,y)が(mesh_s1)*(mesh_t1)個 ;2) 4角形ポリゴン整数座標(x1,y1,x2,y2,x3,y3,x4,y4) ; および視点からの実数距離(d) ; がmesh_s*mesh_t個 ;3) 2)へのポインタ配列がmesh_s*mesh_t個 |