mirror of https://github.com/nmlgc/ReC98.git
403 lines
6.5 KiB
NASM
403 lines
6.5 KiB
NASM
; master library - pattern - clip - PC98V
|
|
;
|
|
; Description:
|
|
; クリップ枠で切断するパターン表示
|
|
;
|
|
; Function/Procedures:
|
|
; void super_put_rect( int x, int y, int patnum ) ;
|
|
;
|
|
; Parameters:
|
|
; x,y 座標
|
|
; patnum パターン番号
|
|
;
|
|
; Returns:
|
|
; none
|
|
;
|
|
; Binding Target:
|
|
; Microsoft-C / Turbo-C / Turbo Pascal
|
|
;
|
|
; Running Target:
|
|
; PC-9801V
|
|
;
|
|
; Requiring Resources:
|
|
; CPU: V30
|
|
; GRCG
|
|
;
|
|
; Notes:
|
|
; まだ最適化してないぜ(遅いってことある)
|
|
;
|
|
; Assembly Language Note:
|
|
;
|
|
;
|
|
; Compiler/Assembler:
|
|
; TASM 3.0
|
|
; OPTASM 1.6
|
|
;
|
|
; Author:
|
|
; 恋塚昭彦
|
|
;
|
|
; Revision History:
|
|
; 93/ 6/17 Initial: superptr.asm/master.lib 0.19
|
|
; 93/ 7/13 [M0.20] bugfix: ・shiftありのときにソースデータの先頭番地-1の
|
|
; 場所を読んでいるが、ソースデータが0番地から
|
|
; 始まって、かつパターンが非常に小さい場合、
|
|
; 0ffffh番地がVRAM領域に達してハングアップ!
|
|
; ・xが負で、かつパターンの右側が見える場合
|
|
; おかしくなっていた。
|
|
; 呼べる条件ならば super_putを呼ぶようにした。
|
|
|
|
GC_MODEREG equ 7ch
|
|
GC_TILEREG equ 7eh
|
|
|
|
MRETURN macro
|
|
pop DI
|
|
pop SI
|
|
pop BP
|
|
ret 6
|
|
EVEN
|
|
endm
|
|
|
|
retfunc SUPERPTR_EXIT
|
|
MRETURN
|
|
endfunc
|
|
|
|
func SUPER_PUT_RECT ; super_put_rect() {
|
|
push BP
|
|
mov BP,SP
|
|
push SI
|
|
push DI
|
|
|
|
; 引数
|
|
@@x = (RETSIZE+3)*2
|
|
@@y = (RETSIZE+2)*2
|
|
@@patnum = (RETSIZE+1)*2
|
|
|
|
mov BX,[BP+@@patnum]
|
|
shl BX,1
|
|
mov AX,super_patdata[BX]
|
|
mov CS:SUPERPTR_PTNSEG_,AX
|
|
|
|
mov BX,super_patsize[BX]
|
|
xor AX,AX
|
|
xchg AL,BH ; BX = ylen
|
|
mov linebyte,AX
|
|
|
|
mov CX,AX
|
|
shl CX,3
|
|
add CX,[BP+@@x]
|
|
dec CX ; CX:rx = x + linebyte * 8 - 1
|
|
|
|
imul BX
|
|
mov CS:SUPERPTR_PLANESIZE_,AX
|
|
|
|
; 全体が枠内なら何もせず終了
|
|
cmp CX,ClipXR ; CX = rx
|
|
jg short @@SOME_OUT
|
|
mov DX,ClipXL ; DX = ClipXL
|
|
cmp [BP+@@x],DX
|
|
jl short @@SOME_OUT
|
|
mov DI,[BP+@@y] ; DI = y
|
|
cmp ClipYT,DI
|
|
jg short @@SOME_OUT
|
|
mov AX,BX
|
|
add AX,DI
|
|
cmp AX,ClipYB ; ylen + y : ClipYB
|
|
jge short @@SOME_OUT
|
|
|
|
; 完全に中だから、super_put()に任せてしまう(^^;
|
|
pop DI
|
|
pop SI
|
|
pop BP
|
|
jmp near ptr SUPER_PUT
|
|
EVEN
|
|
|
|
@@SOME_OUT:
|
|
; 全体が枠外なら何もせず終了
|
|
cmp CX,ClipXL ; CX = rx
|
|
jl short SUPERPTR_EXIT
|
|
mov DX,ClipXR ; DX = ClipXR
|
|
cmp [BP+@@x],DX
|
|
jg short SUPERPTR_EXIT
|
|
mov DI,[BP+@@y] ; DI = y
|
|
cmp ClipYB,DI
|
|
jl short SUPERPTR_EXIT
|
|
mov AX,BX
|
|
add AX,DI
|
|
cmp AX,ClipYT ; ylen + y : ClipYT
|
|
jle short SUPERPTR_EXIT
|
|
|
|
; 右クリップ
|
|
cmp CX,DX ; rx : ClipXR
|
|
jle short @@RIGHT_CLIPPED
|
|
mov CX,DX
|
|
@@RIGHT_CLIPPED:
|
|
|
|
mov AL,[BP+@@x]
|
|
and AL,7
|
|
mov CS:SUPERPTR_SHIFT_,AL
|
|
|
|
; 左クリップ
|
|
xor SI,SI ; SI = pattern offset
|
|
|
|
mov AX,ClipXL
|
|
cmp [BP+@@x],AX
|
|
jge short @@LEFT_CLIPPED
|
|
|
|
mov DX,AX
|
|
shr DX,3
|
|
add SI,DX ; SI += ClipXL / 8
|
|
mov DX,[BP+@@x]
|
|
sar DX,3
|
|
sub SI,DX ; SI -= x / 8
|
|
|
|
mov [BP+@@x],AX ; x = ClipXL
|
|
@@LEFT_CLIPPED:
|
|
|
|
; 上クリップ
|
|
sub DI,ClipYT ; DI:y -= ClipYT
|
|
jns short @@TOP_CLIPPED
|
|
add BX,DI ; ylen += DI
|
|
mov AX,linebyte
|
|
imul DI ; SI -= DI * linebyte
|
|
sub SI,AX
|
|
xor DI,DI ; DI:y = 0
|
|
@@TOP_CLIPPED:
|
|
|
|
; 下クリップ
|
|
lea AX,[BX+DI-1]
|
|
sub AX,ClipYH ; y+ylen : ClipYH
|
|
jle short @@BOTTOM_CLIPPED
|
|
sub BX,AX
|
|
@@BOTTOM_CLIPPED:
|
|
mov CS:SUPERPTR_YLEN_,BX
|
|
|
|
;
|
|
mov AX,[BP+@@x] ; AX = x / 8
|
|
shr AX,3
|
|
imul BX,DI,80
|
|
add BX,AX
|
|
mov CS:SUPERPTR_DRAW_ADR_,BX
|
|
|
|
mov BX,CX ; BX = rx
|
|
|
|
mov DX,80ffh
|
|
and CL,7
|
|
sar DH,CL ; DH = rmask
|
|
mov CL,[BP+@@x]
|
|
and CL,7
|
|
shr DL,CL ; DL = lmask
|
|
|
|
mov CX,AX
|
|
shr BX,3
|
|
sub BX,CX
|
|
jnz short @@NAGAI
|
|
and DL,DH ; lmask &= rmask
|
|
@@NAGAI:
|
|
mov CS:SUPERPTR_DRAWLEN_,BX
|
|
|
|
; DX = (DL=lmask, DH=rmask)
|
|
|
|
mov ES,ClipYT_seg
|
|
|
|
mov CL,12h
|
|
org $-1
|
|
SUPERPTR_SHIFT_ db ?
|
|
|
|
mov AL,11000000b ; GC_RMW or GC_BRGI
|
|
out GC_MODEREG,AL
|
|
mov AL,0
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
call superptr_draw
|
|
|
|
mov AL,11001110b ; GC_RMW or GC_B
|
|
out GC_MODEREG,AL
|
|
mov AL,0ffh
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
out GC_TILEREG,AL
|
|
call superptr_draw
|
|
mov AX,011001101b ; GC_RMW or GC_R
|
|
out GC_MODEREG,AL
|
|
call superptr_draw
|
|
mov AX,11001011b ; GC_RMW or GC_G
|
|
out GC_MODEREG,AL
|
|
call superptr_draw
|
|
mov AX,11000111b ; GC_RMW or GC_I
|
|
out GC_MODEREG,AL
|
|
call superptr_draw
|
|
|
|
mov AL,0
|
|
out GC_MODEREG,AL
|
|
|
|
MRETURN
|
|
endfunc ; }
|
|
|
|
|
|
|
|
; 描画実体 -------------------
|
|
|
|
; 8ドット境界以外 -----------
|
|
|
|
; CL = shift
|
|
; DL = lmask
|
|
; DH = rmask
|
|
; SI = pat
|
|
; DI = drawadr
|
|
; ES = clipyt_seg
|
|
superptr_draw_shift proc near
|
|
test SI,SI ; 1バイト前を読むので、0->0ffffhになると
|
|
; DSによってはVRAMに重なる!ので絶対避けるのだ
|
|
jz short @@draw_shift_low
|
|
EVEN
|
|
@@draw_shift_loop:
|
|
mov AH,[SI-1] ; 前のバイトを読む必要があるのは、
|
|
; 左クリップされていて、必要なのは元データの
|
|
; 2byte目以降で、右シフトされていて、
|
|
; 左端マスクがそのシフト量よりも左から描画を
|
|
; 許可しているとき。
|
|
@@draw_shift_low:
|
|
mov AL,[SI]
|
|
inc SI
|
|
mov BX,AX
|
|
|
|
shr BX,CL
|
|
and BL,DL
|
|
mov ES:[DI],BL
|
|
inc DI
|
|
|
|
mov CH,12h
|
|
org $-1
|
|
SUPERPTR_S_DRAWLEN_ db ?
|
|
dec CH
|
|
js short @@shift_1byte
|
|
je short @@shift_2byte
|
|
|
|
@@shift_xloop:
|
|
mov AH,AL
|
|
mov AL,[SI]
|
|
inc SI
|
|
mov BX,AX
|
|
shr BX,CL
|
|
mov ES:[DI],BL
|
|
inc DI
|
|
dec CH
|
|
jnz short @@shift_xloop
|
|
|
|
@@shift_2byte:
|
|
mov AH,AL
|
|
mov AL,[SI]
|
|
inc SI
|
|
shr AX,CL
|
|
and AL,DH
|
|
mov ES:[DI],AL
|
|
inc DI
|
|
|
|
@@shift_1byte:
|
|
add SI,1234h
|
|
org $-2
|
|
SUPERPTR_S_ADD_SI_ dw ?
|
|
|
|
add DI,1234h
|
|
org $-2
|
|
SUPERPTR_S_ADD_DI_ dw ?
|
|
|
|
dec BP
|
|
jnz @@draw_shift_loop
|
|
|
|
ret
|
|
superptr_draw_shift endp
|
|
|
|
|
|
; 8ドット境界 -----------
|
|
EVEN
|
|
superptr_draw_noshift proc near
|
|
mov AL,[SI]
|
|
inc SI
|
|
and AL,DL
|
|
mov ES:[DI],AL
|
|
inc DI
|
|
|
|
cmp BX,1
|
|
jl short @@noshift_1byte
|
|
|
|
lea CX,[BX-1]
|
|
shr CX,1
|
|
rep movsw
|
|
adc CX,CX
|
|
rep movsb
|
|
|
|
lodsb
|
|
and AL,DH
|
|
stosb
|
|
|
|
@@noshift_1byte:
|
|
mov AL,0
|
|
xchg AL,AH ; AX = linebyte - 1
|
|
|
|
add SI,AX
|
|
sub SI,BX
|
|
mov AH,AL
|
|
|
|
add DI,80-1
|
|
sub DI,BX
|
|
|
|
dec BP
|
|
jnz short superptr_draw_noshift
|
|
|
|
ret
|
|
superptr_draw_noshift endp
|
|
EVEN
|
|
|
|
|
|
|
|
; in:
|
|
; SI = pat (save)
|
|
; ES = clipyt_seg
|
|
;
|
|
superptr_draw proc near
|
|
push SI
|
|
push DS
|
|
|
|
JMOV AX,SUPERPTR_PTNSEG_
|
|
push AX
|
|
JMOV BP,SUPERPTR_YLEN_
|
|
|
|
JMOV DI,SUPERPTR_DRAW_ADR_
|
|
JMOV BX,SUPERPTR_DRAWLEN_
|
|
mov AX,linebyte
|
|
dec AX
|
|
cmp CL,0
|
|
jne short @@j_shift
|
|
@@j_noshift:
|
|
mov AH,AL
|
|
|
|
pop DS ; get ds
|
|
push offset @@j_end
|
|
jmp superptr_draw_noshift
|
|
|
|
@@j_shift:
|
|
mov CS:SUPERPTR_S_DRAWLEN_,BL
|
|
|
|
sub AX,BX
|
|
mov CS:SUPERPTR_S_ADD_SI_,AX
|
|
|
|
mov AX,80 - 1
|
|
sub AX,BX
|
|
mov CS:SUPERPTR_S_ADD_DI_,AX
|
|
|
|
pop DS ; get ds
|
|
call superptr_draw_shift
|
|
|
|
@@j_end:
|
|
pop DS
|
|
pop SI
|
|
add SI,1234h
|
|
org $-2
|
|
SUPERPTR_PLANESIZE_ dw ?
|
|
ret
|
|
superptr_draw endp
|