home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FreeWare Collection 3
/
FreeSoftwareCollection3pd199x-jp.img
/
oh_fm
/
mandel
/
mandel.asm
< prev
next >
Wrap
Assembly Source File
|
1980-01-02
|
112KB
|
4,196 lines
;*******************************
; mandel : mandelbrot figure
; for FM-TOWNS
; (C)1990.3.20 by Fumi
; #1 1990.4.3 Ver0.1 for SOFT BANK
; #2 1990.4.10 Ver1.0 first edition
;*******************************
.386p
TRUE equ 1
FALSE equ 0
;
EGBSIZ equ 2000 ; EGB work area byte size
VRAMW equ 1024 ; VRAM byte width
VRAMDW equ 640 ; VRAM display width
VRAMDH equ 480 ; VRAM display hight
;
BGBW equ 10 ; background block width
BGBH equ 10 ; background block hight
BGBSIZ equ BGBW*BGBH ; background block size
BGBCN equ 64 ; background block column number
BGBLN equ 48 ; background block line number
;
SCRX equ 40 ; display screen x position
SCRY equ 60 ; display screen y position
SCRW equ 400 ; display screen width
SCRH equ 400 ; display screen hight
SCRADR equ SCRY*VRAMW+SCRX ; display screen VRAM address
;
TITX equ SCRX+(SCRW-TITW)/2 ; title box x position
TITY equ 20 ; title box y position
TITW equ 260 ; title box width
TITH equ 25 ; title box hight
TITADR equ TITY*VRAMW+TITX ; title box VRAM address
;
PARX equ 470 ; parameter box display x positon
PARY equ 60 ; parameter box display y position
PARW equ 140 ; paremeter box display width
PARH equ 75 ; parameter box display hight
PARADR equ PARY*VRAMW+PARX ; parameter box VRAM address
;
PTX equ 470 ; pallet table x position
PTY equ 145 ; pallet table y position
PTW equ PTBCN*PTBW+40 ; pallet table boxwidth
PTH equ PTBLN*PTBH+20 ; pallet table box hight
PTADR equ PTY*VRAMW+PTX ; pallet table start VRAM address
PTBW equ 4 ; pallet table block width
PTBH equ 10 ; pallet table block hight
PTBCN equ 25 ; pallet table block column number
PTBLN equ 10 ; pallet table block line number
PTBADR equ (PTY+17)*VRAMW+(PTX+35) ; pallet table block address
;
MENUX equ 470 ; menu display x position
MENUY equ 275 ; menu display y position
MENUW equ 140 ; menu display width
MENUH equ 185 ; menu display hight
MENUADR equ MENUY*VRAMW+MENUX ; menu start VRAM address
;
LPOSX equ PARX+PARW-10*8-3+(PARY+18)*VRAMW ; position x
LPOSY equ PARX+PARW-10*8-3+(PARY+36)*VRAMW ; position y
LRESO equ PARX+PARW-10*8-3+(PARY+54)*VRAMW ; resolution
LLIMIT equ PARX+PARW-5*8-12+(PARY+72)*VRAMW ; limit parameter
LDSTEP equ MENUX+(MENUW-9*8)/2+(MENUY+110)*VRAMW ; drawing step
LZPOSX equ MENUX+MENUW-10*8-10+(MENUY+48)*VRAMW ; zoom in position x
LZPOSY equ MENUX+MENUW-10*8-10+(MENUY+66)*VRAMW ; zoom in position y
LCL1 equ MENUX+70+(MENUY+46)*VRAMW ; old limit
LCL2 equ MENUX+70+(MENUY+66)*VRAMW ; new limit
LAUP equ MENUX+(MENUW-5*8)/2+(MENUY+110)*VRAMW ; auto up limit
LCSTEP1 equ MENUX+72+(MENUY+46)*VRAMW ; color step change unit
LCSTEP2 equ MENUX+72+(MENUY+66)*VRAMW ; color step
;
EXTALL equ "LDM." ; extension all
EXTCOL equ "CDM." ; extension col
;
USRCN equ 250 ; numbers of color
PALSBS equ 42 ; pallet set block size (not factor 1+USRCN)
PALSBN equ (1+USRCN)/PALSBS+1 ; number of pallet block
PALSBR equ (1+USRCN) mod PALSBS ; number of rest pallet (inhibit 0)
;
PADREP equ 10 ; pad repeat count (unit VSYNC)
INIREP equ -1 ; initial repeat counter code
;
P$FWD equ 1 ; TOWNS pad button
P$BACK equ 2
P$LEFT equ 3
P$RIGHT equ 4
P$RUN equ 5
P$SEL equ 6
P$TRIG1 equ 01b
P$TRIG2 equ 10b
;
C$NULL equ 0 ; system pallet code
C$BLOCK equ 251
C$LIGHT equ 252
C$DARK equ 253
C$PANEL equ 254
C$INT equ 255
;
DS$NONE equ 0 ; no first figure
DS$ON equ 1 ; on the way
DS$FULL equ 2 ; full display
;
MINFR equ 16 ; zoom up frame minimum size
IPOSX equ -2 shl 24 ; initial position x
IPOSY equ -2 shl 24 ; initial position y
IRESO equ (4 shl 24)/SCRW ; initial resolution
ILIMIT equ 250 ; initial limit
;
boxstr struc ; down box structure
boxadr dd ? ; box start VRAM address
boxw dw ? ; box pixcel width
boxh dw ? ; box pixcel hight
boxstr ends
menuitm struc ; menu items index structre
butptr dw ? ; buttons pointer
butnum dw ? ; number of button
strptr dw ? ; strings pointer
menuitm ends
butstr struc ; button data structure
butadr dd ? ; button start VRAM address
butw dw ? ; button pixcel width
buth dw ? ; button pixcel hight
butstr ends
locdat struc ; location data structure
locdatx dd ? ; position x
locdaty dd ? ; position y
locdatr dd ? ; resolution
locdatl dw ? ; limit
locdat ends
data segment use32 rw
;*******************************
; variables
;*******************************
buffer dd ? ; calculate data buffer pointer
bufsiz dd ? ; buffer byte size (400*400*8 bytes)
;
posx dd IPOSX ; display position x
posy dd IPOSY ; display position y
reso dd IRESO ; resolution
limit dw ILIMIT ; upper limit of repeat number
curstat dw DS$FULL ; current display state
step dw 4 ; display step for dsp3q
islin dw 0 ; initial screen calculated line
;
cura dd ? ; current real part
curb dd ? ; current imaginary part
pstep dd ? ; position step (reso*step) for dsp3q
bstep dd ? ; block line VRAM step for ds3q
hbnum dw ? ; horizon block number for ds3q
count1 dw ? ; public counter 1
count2 dw ? ; public counter 2
;
repcnt dw ? ; pad repaet counter
frame dw SCRX+SCRW*3/8,SCRY+SCRH*3/8,SCRW/4,SCRH/4 ; zoom up frame
;
numwid db 5 ; dispaly width of integer for putdec
palpkt label byte ; pallet data packet address
palnum db 1 ; pallet number
bpal db 0 ; blue pallet data
rpal db 0 ; red pallet data
gpal db 255 ; green pallet data
db ? ; dummy
colnum db 1 ; color number
spflg db FALSE ; saving pallet plag
currgb db 0 ; current B|R|G (B=0,R=1,G=2)
exts dd ? ; extension for open
;*******************************
; constants
;*******************************
syspal db 251,0,192,62 ; block
db 252,200,200,200 ; light shadow
db 253,10,10,10 ; dark shadow
db 254,120,120,120 ; panel
db 255,10,10,200 ; string
syspalN equ 5
;
bgblock db 0FCh,0FCh,0FCh,0FCh,0FCh,0FCh,0FCh,0FCh,0FCh,0FDh
db 0FCh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FDh
db 0FCh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FDh
db 0FCh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FBh,0FDh
db 0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh
db 0FCh,0FCh,0FCh,0FCh,0FDh,0FCh,0FCh,0FCh,0FCh,0FCh
db 0FBh,0FBh,0FBh,0FBh,0FDh,0FCh,0FBh,0FBh,0FBh,0FBh
db 0FBh,0FBh,0FBh,0FBh,0FDh,0FCh,0FBh,0FBh,0FBh,0FBh
db 0FBh,0FBh,0FBh,0FBh,0FDh,0FCh,0FBh,0FBh,0FBh,0FBh
db 0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh,0FDh
;
cmdtbl1 dd zoomin,zoomout,whole,chgcol,chglim ; menu1 dispatch
dd load,save,main10,main99
cmdtbl2 dd indcol,setcs,grad,cload,csave,crest ; change color dispatch
;
mdrawon menuitm <butd,butdN,str3> ; on drawing message items
mzoin menuitm <but1,but1N,str6> ; zoom in menu
mcgl menuitm <but2,but2N,str7> ; change limit menu
mautad menuitm <butA,butAN,str8> ; automatically limit addition menu
mautup menuitm <butU,butUN,strU> ; automatically limit up menu
mcgc menuitm <but3,but3N,str9> ; change color menu
mindc menuitm <but4,but4N,strA> ; change individual color menu
mced menuitm <but5,but5N,strB> ; color edit menu
mexp menuitm <but6,but6N,strC> ; extract pallet number from pixcel
msave menuitm <but7,but7N,strD> ; save menu
mload menuitm <but8,but8N,strE> ; load menu
msetcs menuitm <but9,but9N,strF> ; set color step menu
mgrad menuitm <butG,butGN,strG> ; gradation menu
;
titbox boxstr <TITADR,TITW,TITH> ; title box data
scrbox boxstr <SCRADR,SCRW,SCRH> ; screen box data
parbox boxstr <PARADR,PARW,PARH> ; parameter box data
palbox boxstr <PTADR,PTW,PTH> ; pallet box data
menubox boxstr <MENUADR,MENUW,MENUH> ; menu box data
;
str1 dw 1,str11 ; title string index
str2 dw 9,str21,str22,str23,str24 ; starting message
dw str25,str26,str27,str28,str29
str3 dw 3,str31,str32,str33 ; on drawing message index
str4 dw 11,str411,str412,str413,str414 ; parameter box and
dw str421,str422 ; pallet table scale strings
dw str431,str432,str433,str434,str435
str5 dw 6,str51,str52,str53,str54 ; scroll mode message
dw str55,str56
str6 dw 7,str61,str62,str63,str64 ; zoom in mode messag
dw str65,str66,str67
str7 dw 8,str71,str72,str73,str74 ; limit change
dw str75,str76,str77,str78
str8 dw 4,str81,str82,str83,str84 ; automatically limit addition
strU dw 4,strU1,strU2,strU3,strU4 ; automatically limit up
str9 dw 2,str91,str92 ; change color menu
strA dw 10,strA1,strA2,strA3 ; change individual color menu
dw strA4,strA5,strA6,strA7
dw strA8,strA9,strA10
strB dw 7,strB1,strB2,strB3 ; edit color code
dw strB4,strB5,strB6,strB7
strC dw 6,strC1,strC2,strC3 ; extract pallet number from pixcel
dw strC4,strC5,strC6
strD dw 4,strD1,strD2,strD3,strD4 ; save
strE dw 5,strE1,strE2,strE3,strE4,strE5 ; load
strF dw 9,strF1,strF2,strF3,strF4,strF5 ; set color step
dw strF6,strF7,strF8,strF9
strG dw 4,strG1,strG2,strG3,strG4 ; gradation menu
;
str11 dw TITX+(TITW-30*8)/2,TITY+19,30
db "マンデルブロ図形描画プログラム"
str20 dw SCRX+(SCRW-28*8)/2,SCRY+(SCRH-16)/2+16,28
db "RUNボタンを押してください"
str29 dw SCRX+(SCRW-10*8)/2,SCRY+30,10
db "Volume One"
str21 dw SCRX+(SCRW-19*8)/2,SCRY+58,19
db "MANDEL.EXP"
str22 dw SCRX+(SCRW-11*8)/2,SCRY+82,11
db "Version 1.0"
str23 dw SCRX+(SCRW-16*8)/2,SCRY+124,16
db "このプログラムは"
str24 dw SCRX+(SCRW-28*8)/2,SCRY+148,28
db "TOWNSパッドで操作します"
str25 dw SCRX+(SCRW-40*8)/2,SCRY+270,40
db "本プログラムの無断複製・譲渡を許可します"
str26 dw SCRX+(SCRW-38*8)/2,SCRY+294,38
db "但し著作権を放棄するものではありません"
str27 dw SCRX+(SCRW-26*8)/2,SCRY+346,26
db "Copyright (C) 1990 by Fumi"
str28 dw SCRX+(SCRW-35*8)/2,SCRY+370,35
db "Special Thanks to Oh!FM and FUJITSU"
str31 dw MENUX+(MENUW-6*8)/2,MENUY+20,6
db "描画中" ; on drawing title
str32 dw MENUX+(MENUW-8*8)/2,MENUY+80,8
db "描画間隔"
str411 dw PARX+3,PARY+18,6
db "左上X"
str412 dw PARX+3,PARY+36,6
db "左上Y"
str413 dw PARX+3,PARY+54,6
db "分解能"
str414 dw PARX+3,PARY+72,8
db "上限回数"
str421 dw PTX+25,PTY+15,2
db "+1"
str422 dw PTX+112,PTY+15,3
db "+25"
str431 dw PTX+10,PTY+30,1
db "0"
str432 dw PTX+7,PTY+50,2
db "50"
str433 dw PTX+3,PTY+70,3
db "100"
str434 dw PTX+3,PTY+90,3
db "150"
str435 dw PTX+3,PTY+110,3
db "200"
str51 dw MENUX+(MENUW-14*8)/2,MENUY+30,14
db "SELECTボタンで"
str52 dw MENUX+(MENUW-10*8)/2,MENUY+50,10
db "メニューへ"
str53 dw MENUX+(MENUW-12*8)/2,MENUY+80,12
db "移動ボタンで"
str54 dw MENUX+(MENUW-10*8)/2,MENUY+100,10
db "スクロール"
str55 dw MENUX+(MENUW-10*8)/2,MENUY+130,10
db "Aボタンで"
str56 dw MENUX+(MENUW-8*8)/2,MENUY+150,8
db "描画続行"
str61 dw MENUX+(MENUW-5*8)/2,MENUY+20,5
db "拡 大"
str62 dw MENUX+10,MENUY+48,4
db "枠X"
str63 dw MENUX+10,MENUY+66,4
db "枠Y"
str64 dw MENUX+(MENUW-10*8)/2,MENUY+94,10
db "RUN 枠拡大"
str65 dw MENUX+(MENUW-10*8)/2,MENUY+116,10
db "SEL 枠縮小"
str71 dw MENUX+(MENUW-8*8)/2,MENUY+20,8
db "上限回数" ; change limit menu title
str72 dw MENUX+20,MENUY+46,6
db "現在値"
str73 dw MENUX+20,MENUY+66,6
db "変更値"
strF4 label word
str74 dw MENUX+(MENUW-10*8)/2,MENUY+89,10
db "↑ ↓ 増減"
str77 dw MENUX+(MENUW-12*8)/2,MENUY+112,12
db "RUN 自動追加"
str78 dw MENUX+(MENUW-12*8)/2,MENUY+134,12
db "SEL 自動増加"
str81 dw MENUX+(MENUW-8*8)/2,MENUY+20,8
db "自動追加"
strU2 label word
str82 dw MENUX+(MENUW-8*8)/2,MENUY+80,8
db "上限回数"
strU1 dw MENUX+(MENUW-8*8)/2,MENUY+20,8
db "自動増加"
str91 dw MENUX+(MENUW-6*8)/2,MENUY+20,6
db "色設定" ; change color menu title
str92 dw MENUX+(MENUW-11*8)/2,MENUY+175,11
db "↑ ↓ A B" ; cahnge color menu button
strA1 dw MENUX+(MENUW-10*8)/2,MENUY+20,10
db "色番号選択" ; change individual color menu title
strA2 dw MENUX+10,MENUY+63,2
db "←"
strA3 dw MENUX+MENUW-26,MENUY+63,2
db "→"
strRGB label word ; for indc
strRGBL equ 8 ; for indc
strC2 label word
strB2 label word
strA4 dw MENUX+12,MENUY+92,2
db "B"
strC3 label word
strB3 label word
strA5 dw MENUX+12,MENUY+108,2
db "R"
strC4 label word
strB4 label word
strA6 dw MENUX+12,MENUY+124,2
db "G"
strA7 dw MENUX+18,MENUY+156,3
db "SEL"
strA8 dw MENUX+14,MENUY+178,4
db "抽出"
strU3 label word
str83 label word
strG3 label word
str66 label word
str75 label word
strF8 label word
strC5 label word
strA9 dw MENUX+MENUW/2+8,MENUY+156,7
db "A 決定"
strU4 label word
str84 label word
str33 label word
strG4 label word
str67 label word
str76 label word
strF9 label word
strB7 label word
strC6 label word
strA10 dw MENUX+MENUW/2+8,MENUY+178,7
db "B 中止"
strB1 dw MENUX+(MENUW-6*8)/2,MENUY+20,6
db "色編集" ; edit color menu title
strB5 dw MENUX+10,MENUY+146,10
db "SEL ← →"
strB6 dw MENUX+10,MENUY+178,7
db "A 決定"
strC1 dw MENUX+(MENUW-6*8)/2,MENUY+20,6
db "色抽出" ; extract pallet number menu title
strD1 dw MENUX+(MENUW-5*8)/2,MENUY+20,5
db "保 存" ; save menu title
strD2 dw MENUX+(MENUW-10*8)/2,MENUY+50,10
db "ファイル名"
strD3 dw MENUX+(MENUW-11*8)/2+8,MENUY+120,10
db "CR A 決定"
strD4 dw MENUX+(MENUW-11*8)/2,MENUY+146,11
db "ESC B 中止"
strE1 dw MENUX+(MENUW-8*8)/2,MENUY+20,8
db "読み込み" ; load menu title
strE2 dw MENUX+106,MENUY+67,2
db "↑"
strE3 dw MENUX+106,MENUY+89,2
db "↓"
strE4 dw MENUX+106,MENUY+138,2
db "A"
strE5 dw MENUX+106,MENUY+160,2
db "B"
strF1 dw MENUX+(MENUW-6*8)/2,MENUY+20,6
db "色間隔" ; set color step menu title
strF2 dw MENUX+20,MENUY+46,6
db "増単位"
strF3 dw MENUX+20,MENUY+66,6
db "色間隔"
strF5 dw MENUX+(MENUW-10*8)/2,MENUY+114,10
db "← → 単位"
strF6 dw MENUX+18,MENUY+156,3
db "RUN"
strF7 dw MENUX+14,MENUY+178,4
db "自動"
strG1 dw MENUX+(MENUW-14*8)/2,MENUY+20,14
db "グラデーション" ; gradation menu title
strG2 dw MENUX+66-24,MENUY+90,9
db "← SEL →"
;
but1N equ 5 ; zoom up command button data
but1 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 拡大
butstr <(MENUY+94-18)*VRAMW+MENUX+(MENUW-10*8)/2-2,28,20> ; RUN
butstr <(MENUY+116-18)*VRAMW+MENUX+(MENUW-10*8)/2-2,28,20> ; SEL
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
but2N equ 7 ; change limit command button
but2 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 上限回数
butstr <(MENUY+72)*VRAMW+MENUX+(MENUW-10*8)/2-2,20,20> ; ↑
butstr <(MENUY+72)*VRAMW+MENUX+(MENUW-10*8)/2+3*8-2,20,20> ; ↓
butstr <(MENUY+94)*VRAMW+MENUX+(MENUW-12*8)/2-2,28,20> ; RUN
butstr <(MENUY+116)*VRAMW+MENUX+(MENUW-12*8)/2-2,28,20> ; SEL
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
butdN equ 2 ; on drawing message button
butUN equ 3 ; automatically limit up
butAN equ 3 ; automatically limit addition
butd label byte
butU label byte
butA butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20>; 自動追加/自動増加/描画中
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
but3N equ 4 ; change color menu button
but3 butstr <(MENUY+175-17)*VRAMW+MENUX+(MENUW-11*8)/2-2,20,20> ; ↑
butstr <(MENUY+175-17)*VRAMW+MENUX+(MENUW-11*8)/2+3*8-2,20,20> ; ↓
butstr <(MENUY+175-17)*VRAMW+MENUX+(MENUW-11*8)/2+6*8-2,20,20> ; A
butstr <(MENUY+175-17)*VRAMW+MENUX+(MENUW-11*8)/2+9*8-2,20,20> ; B
but4N equ 8 ; change color command button
but4 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 色番号選択
butstr <(MENUY+45)*VRAMW+MENUX+(MENUW-78)/2,78,20> ; color box
butstr <(MENUY+45)*VRAMW+MENUX+10-2,20,20> ; ←
butstr <(MENUY+45)*VRAMW+MENUX+MENUW-26-2,20,20> ; →
butstr <(MENUY+74)*VRAMW+MENUX+(MENUW-70)/2,70,52> ; bar frame
butstr <(MENUY+138)*VRAMW+MENUX+18-2,28,20> ; SEL
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
but5N equ 8 ; edit color button
but5 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 色編集
butstr <(MENUY+45)*VRAMW+MENUX+(MENUW-78)/2,78,20> ; color box
butstr <(MENUY+74)*VRAMW+MENUX+(MENUW-70)/2,70,52> ; bar frame
butstr <(MENUY+146-18)*VRAMW+MENUX+10-2,28,20> ; SEL
butstr <(MENUY+146-18)*VRAMW+MENUX+10+5*8-2,20,20> ; ←
butstr <(MENUY+146-18)*VRAMW+MENUX+10+8*8-2,20,20> ; →
butstr <(MENUY+160)*VRAMW+MENUX+10-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
but6N equ 5 ; extract pallet number button
but6 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 色抽出
butstr <(MENUY+45)*VRAMW+MENUX+(MENUW-78)/2,78,20> ; color box
butstr <(MENUY+74)*VRAMW+MENUX+(MENUW-70)/2,70,52> ; bar frame
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
but7N equ 6 ; save menu button
but7 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 保 存
butstr <(MENUY+80-18)*VRAMW+MENUX+(MENUW-80)/2,80,20> ; for file name
butstr <(MENUY+120-18)*VRAMW+MENUX+(MENUW-11*8)/2+8-2,2*8+4,20>; CR
butstr <(MENUY+120-18)*VRAMW+MENUX+(MENUW-11*8)/2+4*8-2,2*8+4,20>; A
butstr <(MENUY+146-18)*VRAMW+MENUX+(MENUW-11*8)/2-2,3*8+4,20> ; ESC
butstr <(MENUY+146-18)*VRAMW+MENUX+(MENUW-11*8)/2+4*8-2,2*8+4,20>; B
but8N equ 6 ; load menu button
but8 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 読み込み
butstr <(MENUY+33)*VRAMW+MENUX+20,10*8,8*18+2>; file name
butstr <(MENUY+67-17)*VRAMW+MENUX+104,20,20> ; ↑
butstr <(MENUY+89-17)*VRAMW+MENUX+104,20,20> ; ↓
butstr <(MENUY+138-18)*VRAMW+MENUX+104,20,20> ; A
butstr <(MENUY+160-18)*VRAMW+MENUX+104,20,20> ; B
but9N equ 8 ; set color step menu button
but9 butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; 色間隔
butstr <(MENUY+72)*VRAMW+MENUX+(MENUW-10*8)/2-2,20,20> ; ↑
butstr <(MENUY+72)*VRAMW+MENUX+(MENUW-10*8)/2+3*8-2,20,20> ; ↓
butstr <(MENUY+96)*VRAMW+MENUX+(MENUW-10*8)/2-2,20,20> ; ←
butstr <(MENUY+96)*VRAMW+MENUX+(MENUW-10*8)/2+3*8-2,20,20> ; →
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
butstr <(MENUY+138)*VRAMW+MENUX+18-2,28,20> ; RUN
butGN equ 8 ; gradation menu button
butG butstr <(MENUY+3)*VRAMW+MENUX+3,MENUW-6,20> ; グラデーション"
butstr <(MENUY+60-17)*VRAMW+MENUX+40-2,80,20> ; 1 color
butstr <(MENUY+120-17)*VRAMW+MENUX+40-2,80,20> ; 250 color
butstr <(MENUY+90-17)*VRAMW+MENUX+66-24-2,20,20> ; ←
butstr <(MENUY+90-17)*VRAMW+MENUX+66-2,28,20> ; SEL
butstr <(MENUY+90-17)*VRAMW+MENUX+66+32-2,20,20> ; →
butstr <(MENUY+138)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; A
butstr <(MENUY+160)*VRAMW+MENUX+MENUW/2+8-2,20,20> ; B
;
simain dw 0,9 ; selector item in main menu
dw simain0,simain1,simain2,simain3,simain4
dw simain5,simain6,simain7,simain8
sicol dw 0,6 ; selector item in color menu
dw sicol0,sicol1,sicol2,sicol3,sicol4,sicol5
;
simain0 dw MENUX+(MENUW-5*8)/2,MENUY+19,5
db "拡 大"
simain1 dw MENUX+(MENUW-5*8)/2,MENUY+39,5
db "縮 小"
simain2 dw MENUX+(MENUW-6*8)/2,MENUY+59,6
db "全体図"
simain3 dw MENUX+(MENUW-6*8)/2,MENUY+79,6
db "色設定"
simain4 dw MENUX+(MENUW-8*8)/2,MENUY+99,8
db "上限回数"
simain5 dw MENUX+(MENUW-8*8)/2,MENUY+119,8
db "読み込み"
simain6 dw MENUX+(MENUW-5*8)/2,MENUY+139,5
db "保 存"
simain7 dw MENUX+(MENUW-8*8)/2,MENUY+159,8
db "描画続行"
simain9 dw MENUX+(MENUW-10*8)/2,MENUY+159,10
db "スクロール"
simain8 dw MENUX+(MENUW-14*8)/2,MENUY+179,14
db "プログラム終了"
;
sicol0 dw MENUX+(MENUW-8*8)/2,MENUY+44,8
db "個別設定"
sicol1 dw MENUX+(MENUW-6*8)/2,MENUY+64,6
db "色間隔"
sicol2 dw MENUX+(MENUW-14*8)/2,MENUY+84,14
db "グラデーション"
sicol3 dw MENUX+(MENUW-8*8)/2,MENUY+104,8
db "読み込み"
sicol4 dw MENUX+(MENUW-5*8)/2,MENUY+124,5
db "保 存"
sicol5 dw MENUX+(MENUW-5*8)/2,MENUY+144,5
db "復 元"
data ends
code segment use32 eo
assume cs:code,ds:data
entry: mov ax,0110h ; TOWNS BIOS
mov fs,ax
;-------------------------------
; Initialize CRTC & data
;-------------------------------
mov edi,offset egbwork ; initialize EGB
mov ecx,EGBSIZ
xor ah,ah
call pword ptr fs:[20h]
mov ax,0100h ; set virtual screen
mov dx,12
call pword ptr fs:[20h]
mov ax,0701h ; set background color
mov edx,C$DARK
call pword ptr fs:[20h]
;
mov esi,offset syspal ; pallet packet address
mov ecx,syspalN
init10: call setpal ; set pallet
add esi,4
loop init10
;
mov edi,offset palbuf ; pallet data buffer
mov dword ptr [edi],0 ; pallet number = 0
mov esi,offset palpkt ; set display pallet
mov eax,0FFFFFFh/100
mov ecx,USRCN
mov dword ptr bpal,0
init12: add dword ptr bpal,eax
call setpal
add edi,3
mov dx,word ptr bpal
mov [edi],dx
mov dl,gpal
mov [edi+2],dl
inc palnum
loop init12
;-------------------------------
; save parameter & set
; in : es = stack & data segment
;-------------------------------
push ds
mov ax,0004h ; PSP selector
mov ds,ax
mov esi,80h ; command line address
mov edi,offset pathbuf ; saving address
movzx ecx,byte ptr [esi] ; string length
movsb ; save string length
rep movsb ; save command line string
;
mov eax,ds:[0000005Ch] ; necessary size
mov edx,ds:[00000060h] ; program size
pop ds
add eax,11b ; round up to 4 times
and al,111100b
mov buffer,eax ; save calculate data buffer pointer
sub edx,eax
mov bufsiz,edx ; save buffer size
;
push ds
xor ax,ax ; read ANK font address
mov dx,0810h ; 8*16 dot
xor bl,bl ; ANK code = 0
call pword ptr fs:[0A0h] ; call font BIOS
mov ss:ankfnt,esi ; font offset
mov word ptr ss:ankfnt[4],ds ; font selector
pop ds
;-------------------------------
; starting screen
;-------------------------------
mov ax,0128h ; TOWNS VRAM (1 screen mode)
mov es,ax
;
mov esi,offset bgblock
xor edi,edi
mov count1,BGBH ; set block hight counter
init30: mov dx,BGBLN ; set block line counter
init32: mov bx,BGBCN ; set block column counter
init34: mov ecx,BGBW/2
rep movsw ; display 1 line of block
sub esi,BGBW ; rewind source line address
dec bx ; decrese block column counter
jnz init34
add edi,BGBH*VRAMW-BGBW*BGBCN ; next destination address
dec dx
jnz init32
add esi,BGBW
sub edi,BGBLN*BGBH*VRAMW-VRAMW
dec count1
jnz init30
;
mov esi,offset titbox ; title box clear
mov al,C$PANEL
call boxdwn
mov esi,offset scrbox ; screen box clear
mov al,C$PANEL
call boxdwn
;
mov edi,offset egbwork ; work address
mov ah,19h ; set font style
mov dx,100b ; shadow
call pword ptr fs:[20h]
mov bx,offset str1 ; title string index
mov al,C$BLOCK
call dspss
;
mov ah,19h ; set font style
xor dx,dx ; standard
call pword ptr fs:[20h]
mov bx,offset str2 ; starting message index
mov al,C$DARK ; string color
call dspss ; display strings
mov al,C$INT ; string color
call color
mov esi,offset str20 ; "press RUN button"
mov ah,60h
call pword ptr fs:[20h]
;-------------------------------
; calculate initial screen
;-------------------------------
mov ebp,offset idata ; save address
mov count1,SCRH/2 ; set screen hight counter
mov curb,IPOSY+IRESO*SCRH/2 ; set y start position
init40: call getpad ; get pad button state
cmp al,P$RUN ; check press RUN button
je init60 ; press to intterrupt
mov count2,SCRW ; set screen width counter
mov cura,IPOSX ; set x start position
init42: push ebp
call calc ; calculate repeat number
pop ebp
mov [ebp],al ; save to memory
inc ebp ; next memory address
add cura,IRESO ; next x position
dec count2
jnz init42
inc islin ; line calculated counter up
add curb,IRESO ; set next y position
dec count1
jne init40
;
init48: call getpad ; get pad button state
cmp al,P$RUN ; wait RUN button press
jne init48
;-------------------------------
; display rest initial screen
;-------------------------------
init60: mov esi,offset parbox ; parameter box clear
mov al,C$PANEL
call boxdwn
mov esi,offset palbox ; pallet box clear
mov al,C$PANEL
call boxdwn
;
mov edi,PTBADR-2*VRAMW-2 ; pallet table address
mov ax,PTBCN*PTBW+4 ; table width
mov dx,PTBLN*PTBH+3 ; table hight
call boxup ; look like box up
;
mov dx,PTBLN ; pallet block line number counter
xor al,al ; initialize pallet number
mov edi,PTBADR ; VRAM start address
init62: mov bx,PTBH-1 ; block lines counter
init64: mov ecx,PTBCN ; block column number
init66: inc al
mov ah,al
stosw
stosw
loop init66
add edi,VRAMW-PTBW*PTBCN
sub al,PTBCN
dec bx
jnz init64
add edi,VRAMW ; skip 1 line
add al,PTBCN
dec dx
jnz init62
;
mov bx,offset str4 ; strings index
mov al,C$DARK ; dark shadow color
call dspss
;-------------------------------
; display mandelbrot figure
;-------------------------------
call dspis ; display initial screen
main10: call dspmain ; display main mandelbrot figure
;-------------------------------
; scroll mode
;-------------------------------
main20: mov esi,offset menubox ; menu box clear
mov al,C$PANEL
call boxdwn
mov bx,offset str5 ; scroll mode message index
mov ax,6 ; on drawing message numbers
cmp curstat,DS$FULL ; check display state
jne main21
mov ax,4 ; message numbers on completion
main21: mov [bx],ax ; set message numbers
mov al,C$INT ; string color
call dspss ; display messages
;
xor ax,ax ; wait no press state
call waitp
main22: call getpad ; get pad state
test ah,P$TRIG1
jnz main10 ; continue display
cmp al,P$SEL
je main30 ; go to menu mode
cmp al,P$FWD
je main24 ; go to scroll down
cmp al,P$BACK
je main26 ; go to scroll up
cmp al,P$LEFT
je main28 ; go to scroll right
cmp al,P$RIGHT
jne main22 ; go to get new state
;
call srlft ; scroll left
jmp main22
main24: call srdwn ; scroll down
jmp main22
main26: call srup ; scroll up
jmp main22
main28: call srrgt ; scroll right
jmp main22
;-------------------------------
; menu mode
;-------------------------------
main30: mov esi,offset menubox
mov al,C$PANEL
call boxdwn ; menu box clear
mov bx,offset simain ; selector data address
mov ax,offset simain7
cmp curstat,DS$FULL
jne main32
mov ax,offset simain9
main32: mov [bx+18],ax
call select ; select item
jc main20 ; escape to scroll mode
shl ax,2 ; make offset
cwde
jmp cmdtbl1[eax] ; jump destination procedure
;-------------------------------
; procedures for exit
;-------------------------------
main99: mov ax,4C00h ; exit to DOS
int 21h
;*******************************
; srdwn : scroll down
;
; in : step = half scroll step
; (0 is 1 step)
; call: dspbl,putfp
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
srdwn proc
;-------------------------------
; calculate new position
;-------------------------------
movzx ebx,step ; current dispaling step
shl ebx,1 ; scroll step
jnz srdw10
inc ebx ; scroll step = 1
srdw10: mov eax,ebx
mul reso ; scroll amount
sub posy,eax ; new y position
cmp posy,-2 shl 24 ; check lower limit
jge srdw20 ; OK!
add posy,eax ; recover
ret
;-------------------------------
; display new y position
;-------------------------------
srdw20: push ebx
mov eax,posy ; new position y
neg eax
mov edi,LPOSY ; display position
call putfp
pop ebx
;-------------------------------
; move down current screen
; in : ebx = scroll step
;-------------------------------
mov edi,(SCRY+SCRH-1)*VRAMW+SCRX
mov esi,edi
imul eax,ebx,VRAMW
sub esi,eax ; source start address
mov dx,SCRH
sub dx,bx ; move line counter
srdw40: mov ecx,SCRW/4
rep movs dword ptr [edi],es:[esi]
sub esi,SCRW+VRAMW
sub edi,SCRW+VRAMW
dec dx
jnz srdw40
;-------------------------------
; display block line
; in : ebx = scroll step
;-------------------------------
mov edi,SCRADR
mov eax,posy ; start y position
mov curb,eax
call dspbl ; display block line
ret
srdwn endp
;*******************************
; srup : scroll up
;
; in : step = half scroll step
; (0 is 1 step)
; call: dspbl,putfp
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
srup proc
;-------------------------------
; calculate new position
;-------------------------------
movzx ebx,step ; current dispaling step
shl ebx,1 ; scroll step
jnz srup10
inc ebx ; scroll step = 1
srup10: mov eax,ebx
mul reso ; scroll amount
imul edx,reso,SCRH
add edx,posy
add edx,eax
cmp edx,2 shl 24 ; check uppper limit
jg srup90 ; over
add posy,eax ; new y position
;-------------------------------
; display new y position
;-------------------------------
push ebx
mov eax,posy ; new position y
neg eax
mov edi,LPOSY ; display position
call putfp
pop ebx
;-------------------------------
; move up current screen
; in : ebx = scroll step
;-------------------------------
mov edi,SCRADR
imul esi,ebx,VRAMW
add esi,edi ; source start address
mov dx,SCRH
sub dx,bx ; move line counter
srup20: mov ecx,SCRW/4
rep movs dword ptr [edi],es:[esi]
add esi,-SCRW+VRAMW
add edi,-SCRW+VRAMW
dec dx
jnz srup20
;-------------------------------
; display block line
; in : ebx = scroll step
; edi = block line address
;-------------------------------
mov eax,SCRH ; screen hight
sub eax,ebx ; screen position
mul reso ; offset y position
add eax,posy ; start y position
mov curb,eax
call dspbl ; display block line
srup90: ret
srup endp
;*******************************
; srrgt : scroll right
;
; in : step = half scroll step
; (0 is 1 step)
; call: putfp,dspbc
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
srrgt proc
;-------------------------------
; calculate new position
;-------------------------------
movzx ebx,step ; current dispaling step
shl ebx,1 ; scroll step
jnz srrt10
inc ebx ; scroll step = 1
srrt10: mov eax,ebx
mul reso ; scroll amount
sub posx,eax ; new x position
cmp posx,-2 shl 24 ; check lower limit
jge srrt20 ; OK!
add posx,eax ; recover
ret
;-------------------------------
; display new x position
;-------------------------------
srrt20: push ebx
mov eax,posx ; new position x
mov edi,LPOSX ; display position
call putfp
pop ebx
;-------------------------------
; move right current screen
; in : ebx = scroll step
;-------------------------------
std ; set direction flag
mov edi,SCRY*VRAMW+SCRX+SCRW-4
mov esi,edi
sub esi,ebx ; source start address
mov eax,SCRW ; screen width
sub eax,ebx ; move width
mov ebp,eax
add ebp,VRAMW-3 ; VRAM step
mov dx,SCRH ; move line counter
push ebx
mov ebx,eax
shr eax,2
and ebx,11b
srrt30: mov ecx,eax ; set column counter
rep movs dword ptr [edi],es:[esi]
add esi,3
add edi,3
mov ecx,ebx
rep movs byte ptr [edi],es:[esi]
add esi,ebp ; next line
add edi,ebp
dec dx
jnz srrt30
pop ebx
cld ; clear direction flag
;-------------------------------
; display block column
; in : ebx = scroll step
;-------------------------------
mov edi,SCRADR
mov eax,posx ; start x position
mov cura,eax
call dspbc ; display block column
ret
srrgt endp
;*******************************
; srlft : scroll left
;
; in : step = half scroll step
; (0 is 1 step)
; call: putfp,dspbc
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
srlft proc
;-------------------------------
; calculate new position
;-------------------------------
movzx ebx,step ; current dispaling step
shl ebx,1 ; scroll step
jnz srlt10
inc ebx ; scroll step = 1
srlt10: mov eax,ebx
mul reso ; scroll amount
imul edx,reso,SCRW
add edx,posx
add edx,eax
cmp edx,2 shl 24 ; check uppper limit
jg srlt90 ; over
add posx,eax ; new x position
;-------------------------------
; display new x position
;-------------------------------
push ebx
mov eax,posx ; new position x
mov edi,LPOSX ; display position
call putfp
pop ebx
;-------------------------------
; move left current screen
; in : ebx = scroll step
;-------------------------------
push ebx
mov edi,SCRADR
mov esi,edi
add esi,ebx ; source start address
mov eax,SCRW ; screen width
sub eax,ebx ; move width
mov ebp,VRAMW
sub ebp,eax ; VRAM step
mov dx,SCRH ; move line counter
mov ebx,eax
shr eax,2
and ebx,11b
srlt22: mov ecx,eax ; set column counter
rep movs dword ptr [edi],es:[esi]
mov ecx,ebx
rep movs byte ptr [edi],es:[esi]
add esi,ebp ; next line
add edi,ebp
dec dx
jnz srlt22
pop ebx
;-------------------------------
; display block column
; in : ebx = scroll step
;-------------------------------
mov edi,SCRADR+SCRW
sub edi,ebx ; block VRAM address
mov eax,SCRW
sub eax,ebx
mul reso
add eax,posx ; start x position
mov cura,eax
call dspbc ; display block column
srlt90: ret
srlft endp
;*******************************
; zoomin : zoom in command
;*******************************
zoomin proc
;------------------------------
; dispaly message
;------------------------------
mov esi,offset mzoin ; display menu items
call dspmenu
xor ax,ax ; wait no press state
call waitp
mov esi,offset frame ; frame data address
call dspzx ; display zoom in x position
call dspzy ; display zoom in y position
call revfr ; display frame
;-------------------------------
; command input
;-------------------------------
zoin20: call getpad
test ax,ax
jz zoin20
push ax
call waitv ; wait VSYNC trigger
call revfr ; clear frame
pop ax
test ah,P$TRIG1
jnz zoin80 ; decision
test ah,P$TRIG2
jnz main30 ; return to main menu
cmp al,P$RUN
je zoin40 ; magnify
cmp al,P$SEL
je zoin50 ; reduce
cmp al,P$FWD
je zoin32 ; move up
cmp al,P$BACK
je zoin36 ; move down
cmp al,P$LEFT
je zoin38 ; move left
;-------------------------------
; move frame
; in : esi = frame data address
;-------------------------------
add word ptr [esi],2 ; move right
call revrl ; revise right limit
zoin30: call revfr ; display frame
call dspzx ; display zoom in x position
jmp zoin20
;
zoin32: sub word ptr [esi+2],2 ; move up
cmp word ptr [esi+2],SCRY ; check upper limit
jge zoin34 ; OK!
mov word ptr [esi+2],SCRY ; adjust
zoin34: call revfr ; display frame
call dspzy ; display zoom in y position
jmp zoin20
;
zoin36: add word ptr [esi+2],2 ; move down
call revdl ; revise down limit
jmp zoin34
;
zoin38: sub word ptr [esi],2 ; move left
cmp word ptr [esi],SCRX ; check left limit
jge zoin30 ; OK!
mov word ptr [esi],SCRX ; adjust
jmp zoin30
;-------------------------------
; magnify frame size
; in : esi = frame data address
;-------------------------------
zoin40: add word ptr [esi+4],2 ; extend width
add word ptr [esi+6],2 ; extend hight
dec word ptr [esi] ; x position -1
dec word ptr [esi+2] ; y position -1
cmp word ptr [esi+4],SCRW ; check width (unite hight)
jbe zoin42 ; OK!
mov word ptr [esi+4],SCRW ; adjust width
mov word ptr [esi+6],SCRW ; adjust hight
;
zoin42: cmp word ptr [esi+2],SCRY ; check upper limit
jge zoin44 ; OK!
mov word ptr [esi+2],SCRY ; adjust y position
zoin44: call revdl ; revise down limit
cmp word ptr [esi],SCRX ; check left limit
jge zoin46 ; OK!
mov word ptr [esi],SCRX ; adjust x position
zoin46: call revrl ; revise right limit
zoin48: call revfr ; display frame
call dspzx ; display zoom in x position
call dspzy ; display zoom in y position
jmp zoin20
;-------------------------------
; reduce frame size
; in : esi = frame data address
;-------------------------------
zoin50: sub word ptr [esi+4],2 ; narrow width
sub word ptr [esi+6],2 ; narrow hight
inc word ptr [esi] ; x position +1
inc word ptr [esi+2] ; y position +1
cmp word ptr [esi+4],MINFR ; check frame size
jge zoin48 ; OK!
mov word ptr [esi+4],MINFR ; adjust frame size
mov word ptr [esi+6],MINFR
dec word ptr [esi] ; x position -1
dec word ptr [esi+2] ; y position -1
jmp zoin48
;-------------------------------
; change region
;-------------------------------
zoin80: movzx eax,word ptr [esi+4] ; frame width
mul reso
mov ecx,SCRW ; screen width
div ecx ; calculate new resolution
test eax,eax ; check effectiveness
jz main30 ; interrupt to menu mode
push eax ; save new resolution
;
mov ax,[esi] ; frame x position
sub ax,SCRX ; x pixcel position in screen
cwde
mul reso
add posx,eax ; new x position
;
mov ax,[esi+2] ; frame y position
sub ax,SCRY ; y pixcel position in screen
cwde
mul reso
add posy,eax ; new y position
;
pop eax ; load new resolution
mov reso,eax ; set new resolution
;
call dspfp ; display new frame parameter
mov curstat,DS$NONE ; display start
jmp main10 ; go to display
;1111111111111111111111111111111
; dspzx : display position x
; in zoom in frame
;
; in : esi = frame data address
; call: putfp
; use: all except for esi
;
dspzx proc
mov ax,[esi] ; frame x position
sub ax,SCRX ; x pixcel position in screen
cwde
mul reso
add eax,posx ; new x position
mov edi,LZPOSX
push esi
call putfp
pop esi
ret
dspzx endp
;1111111111111111111111111111111
; dspzy : display position y
; in zoom in frame
;
; in : esi = frame data address
; call: putfp
; use: all except for esi
;
dspzy proc
mov ax,[esi+2] ; frame y position
sub ax,SCRY ; y pixcel position in screen
cwde
mul reso
add eax,posy ; new y position
neg eax ; neagative for display
mov edi,LZPOSY
push esi
call putfp
pop esi
ret
dspzy endp
;1111111111111111111111111111111
; revdl : revise down limit
; in : esi = frame data address
;
revdl proc
mov ax,SCRY+SCRH ; down limit + 1
sub ax,[esi+2] ; effective hight
sub ax,[esi+6] ; check frame hight
jge revdl9 ; OK!
add [esi+2],ax ; adjust y position
revdl9: ret
revdl endp
;1111111111111111111111111111111
; revrl : revise right limit
; in : esi = frame data address
;
revrl proc
mov ax,SCRX+SCRW ; right limit + 1
sub ax,[esi] ; effective width
sub ax,[esi+4] ; check frame width
jge revrl9 ; OK!
add [esi],ax ; adjust x position
revrl9: ret
revrl endp
zoomin endp
;*******************************
; zoomout : zoom out command
;*******************************
zoomout proc
shl reso,1 ; change resolution
imul eax,reso,SCRW/4
sub posx,eax ; change x position
sub posy,eax ; change y position
cmp reso,(4 shl 24)/SCRW ; check resolution limit
jbe zout10 ; OK!
mov reso,(4 shl 24)/SCRW ; adjust resolution
;
zout10: mov esi,offset posx ; revise position x
call revpos
mov esi,offset posy ; revise position y
call revpos
;
call dspfp ; display new frame parameter
mov curstat,DS$NONE ; display start
jmp main10 ; go to display
;1111111111111111111111111111111
; revpos : revise position x|y
; in : esi = position data address
;
revpos proc
cmp dword ptr [esi],-2 shl 24 ; check lower limit
jge revp10 ; OK!
mov dword ptr [esi],-2 shl 24 ; adjust position
jmp short revp90
revp10: mov ecx,2 shl 24 ; upper limit
sub ecx,[esi] ; effective width
imul eax,reso,SCRW ; screen width
sub ecx,eax
jge revp90 ; OK!
add [esi],ecx ; adjust position
revp90: ret
revpos endp
zoomout endp
;*******************************
; whole : return to whole
;*******************************
whole proc
call dspis ; display initial screen
jmp main30 ; go to menu mode
whole endp
;*******************************
; chglim : change limit
;*******************************
chglim proc
mov ax,limit ; current limit
mov count1,ax ; initialize new limit
;-------------------------------
; display screen
;-------------------------------
mov esi,offset mcgl
call dspmenu ; display menu items
mov ax,limit ; display current limit
mov edi,LCL1
call putdec
;-------------------------------
; command input
;-------------------------------
xor ax,ax ; wait no press state
call waitp
;
cgl20: call waitv ; wait VSYNC trigger
mov ax,count1 ; display limit
mov edi,LCL2
call putdec
cgl22: call getpad ; get pad state
cmp al,P$FWD
je cgl40 ; limit up
cmp al,P$BACK
je cgl50 ; limit down
cmp al,P$RUN
je cgl70 ; automatically limit additon
cmp al,P$SEL
je cgl60 ; automatically limit up
test ah,P$TRIG2
jnz main30 ; cancel to return main menu
test ah,P$TRIG1
jz cgl22 ; invalid
;-------------------------------
; decision upper limit
;-------------------------------
mov ax,count1 ; new limit number
mov limit,ax ; set mew limit
mov edi,LLIMIT ; display new limit
call putdec
mov curstat,DS$NONE ; request redisplay
jmp main10 ; go to display
;-------------------------------
; limit up
;-------------------------------
cgl40: add count1,10 ; limit up
jnc cgl20
sub count1,10 ; recover
jmp cgl22
;-------------------------------
; limit down
;-------------------------------
cgl50: sub count1,10 ; limit down
ja cgl20
add count1,10 ; recover
jmp cgl22
;-------------------------------
; automatically limit up
;-------------------------------
cgl60: cmp bufsiz,SCRW*SCRW*8 ; check memorey
jb cgl68 ; can't execute
;
mov esi,offset mautup ; auto up menu index
call dspmenu ; display menu items
call calup ; calculate up method
jnc cgl68 ; calculate up end
test ah,P$TRIG1
jz cgl68 ; quit end
;
mov ax,hbnum ; next limit number
dec ax ; new limit number
mov limit,ax ; set new limit
mov edi,LLIMIT ; display new limit
call putdec
cgl68: jmp main20 ; go to scroll mode
;-------------------------------
; automatically additon
;-------------------------------
cgl70: call dspmain ; display main mandelbrot figure
jc cgl90 ; interrupted
;
mov esi,offset mautad ; auto additon menu index
call dspmenu
push limit ; save current limit
cgl76: shl limit,1 ; double limit
jc cgl78 ; limit over
mov ax,limit ; display limit
mov edi,LAUP
call putdec
call dspadd ; display additive
jnc cgl76 ; not intrrupted
;
test ah,P$TRIG1 ; press A button ?
jz cgl78 ; no then end without changing limit
mov ax,limit ; interrupted limit
shr ax,1 ; new limit
mov [esp],ax ; set new limit on stack
mov edi,LLIMIT ; display new limit
call putdec
cgl78: pop limit ; set limit
;
cgl90: jmp main20 ; go to scroll mode
chglim endp
;*******************************
; load : load data
;*******************************
load proc
;-------------------------------
; file select and open
;-------------------------------
mov exts,EXTALL ; set extension
load10: call open ; file open
jc main30 ; quit to menu mode
;-------------------------------
; read location data
; in : ax = file handle
;-------------------------------
mov bx,ax ; file handel
mov ecx,size locdat ; location data size
mov edx,offset work1 ; buffer pointer
mov ah,3Fh ; read file
int 21h
jnc load30 ; complete
;
load20: mov ah,3Eh ; file close
int 21h
jmp load10 ; repeat file open
;-------------------------------
; check location data & set
; in : edx = data address
;-------------------------------
load30: mov eax,[edx].locdatr ; resolution
test eax,eax
jz load20 ; too small
cmp eax,(4 shl 24)/SCRW ; check range
ja load20 ; too big
mov ecx,-2 shl 24 ; location low limit
mov esi,[edx].locdatx ; position x
cmp esi,ecx ; check x low limit
jl load20 ; too small
mov edi,[edx].locdaty ; position y
cmp edi,ecx ; check y low limit
jl load20 ; too small
push eax
imul eax,SCRW ; screen width/hight
neg ecx ; location hight limit
sub ecx,eax
pop eax
cmp esi,ecx ; check x high position
jg load20 ; too big
cmp edi,ecx ; check y high position
jg load20 ; too big
;
mov posx,esi ; set position x
mov posy,edi ; set position y
mov reso,eax ; set resolution
mov ax,[edx].locdatl ; limit
mov limit,ax ; set limit
;-------------------------------
; load color data
; in : bx = file handle
;-------------------------------
call savpal ; backup color data
mov edx,offset palbuf
mov ecx,(1+USRCN)*3 ; color data byte size
mov ah,3Fh ; read file
int 21h
;-------------------------------
; file close & ending
; in : bx = file handle
;-------------------------------
mov ah,3Eh ; file close
int 21h
;
call dspfp ; display frame parameter
mov ax,limit ; limit
mov edi,LLIMIT ; display limit
call putdec
call setdp ; set display pallet
;
mov curstat,DS$NONE ; request full display
jmp main10 ; go to display
load endp
;*******************************
; open : file open
; with file selector
;
; in : exts = extension
; buffer = file name buffer pointer
; out: cf = set for quit
; ax = file handel
; call: dspmenu,waitp,chgsc,getpad
; waitv,makpath
; use: all register
; work1,count1,count2,hbnum
;
SCRSTEP equ 3 ; scroll step
MAXFIN equ 8 ; maximum file item number
open proc
;-------------------------------
; intialize
;-------------------------------
mov esi,offset mload
call dspmenu ; display menu items
xor ax,ax
mov count1,ax ; file number of top item
mov count2,ax ; item number
mov hbnum,ax ; file number of current DTA
;
xor ax,ax ; item number
call dspfn ; display file name
jc open90 ; quit end
mov ax,1
open10: push ax
call dspfn ; display file name
pop ax
jc open18 ; no exist
inc ax
cmp ax,MAXFIN-1
jbe open10
;
open18: xor ax,ax ; wait no press state
call waitp
mov repcnt,INIREP ; clear pad input counter
;-------------------------------
; intesify current item
;-------------------------------
open20: movzx edi,count2
imul edi,18*VRAMW
add edi,(MENUY+35)*VRAMW+MENUX+28
mov bx,8*8+1 ; string witdh
mov ax,C$DARK+C$INT*256
call chgsc ; intensify string
;-------------------------------
; input pad
;-------------------------------
open40: call getpad
test ax,ax ; press key ?
jz open40 ; no press state
test ah,P$TRIG1 ; A button
jnz open80 ; go to open
test ah,P$TRIG2 ; B button
jnz open90 ; quit
cmp al,P$BACK
je open70 ; move down
cmp al,P$FWD
je open50 ; move up
;
mov repcnt,INIREP ; clear pad input counter
jmp open40
;-------------------------------
; cursor move up
; in : edi = string box address
;-------------------------------
open50: mov ax,count2 ; current item number
dec ax ; move up
jns open60 ; executable
mov ax,count1 ; current top file number
dec ax
js open40 ; can't scroll down
mov count1,ax ; new top file number
;
mov eax,C$PANEL+(C$PANEL shl 8)+(C$PANEL shl 16)+(C$PANEL shl 24)
mov bx,18/SCRSTEP
open52: mov esi,(MENUY+32+18*MAXFIN-SCRSTEP)*VRAMW+MENUX+28
mov edi,(MENUY+32+18*MAXFIN)*VRAMW+MENUX+28
mov dx,18*MAXFIN-2-SCRSTEP
call waitv ; wait VSYNC trigger
open54: mov ecx,8*8/4
rep movs dword ptr [edi],es:[esi]
sub esi,VRAMW+8*8
sub edi,VRAMW+8*8
dec dx
jnz open54
mov dx,SCRSTEP
open56: mov ecx,8*8/4
rep stosd
sub edi,VRAMW+8*8
dec dx
jnz open56
dec bx
jnz open52
;
xor ax,ax ; top item
call dspfn ; display file name
mov edi,(MENUY+35+18)*VRAMW+MENUX+28 ; next item address
jmp short open62
;-------------------------------
; check repeatable & set new item
; in : edi = string box address
; ax = new item number
;-------------------------------
open60: call repable ; repeatalbe ?
jc open40 ; invalid
mov count2,ax ; renew item number
open62: mov bx,8*8+1 ; string width
mov ax,C$INT+C$DARK*256
call chgsc ; weaken string
jmp open20 ; go to display cursor
;-------------------------------
; cursor move down
; in : edi = string box address
;-------------------------------
open70: mov ax,count2 ; current item number
add ax,count1 ; current file number
inc ax ; next file number
push edi
call getfp ; get file name string pointer
pop edi
jc open40 ; no exist
;
mov ax,count2 ; current item number
inc ax ; next item number
cmp ax,MAXFIN-1 ; check down limit
jbe open60 ; OK!
;
mov eax,C$PANEL+(C$PANEL shl 8)+(C$PANEL shl 16)+(C$PANEL shl 24)
mov bx,18/SCRSTEP
open72: mov esi,(MENUY+35+SCRSTEP)*VRAMW+MENUX+28
mov edi,(MENUY+35)*VRAMW+MENUX+28
mov dx,18*MAXFIN-2-SCRSTEP
call waitv ; wait VSYNC trigger
open74: mov ecx,8*8/4
rep movs dword ptr [edi],es:[esi]
add esi,VRAMW-8*8
add edi,VRAMW-8*8
dec dx
jnz open74
mov dx,SCRSTEP
open76: mov ecx,8*8/4
rep stosd
add edi,VRAMW-8*8
dec dx
jnz open76
dec bx
jnz open72
;
inc count1 ; new top file number
mov ax,MAXFIN-1 ; bottom item
call dspfn ; display file name
mov edi,(MENUY+35+18*(MAXFIN-2))*VRAMW+MENUX+28 ; weaken item
jmp open62
;-------------------------------
; file open
;-------------------------------
open80: mov ax,count1 ; top item file number
add ax,count2 ; destination file number
call getfp ; get file name string pointer
jc open90 ; don't exist
mov eax,exts ; extension string
call makpath ; make pathlist
mov edx,offset pathbuf+1
mov ax,3D00h ; read open
int 21h
ret
open90: stc ; quit end
ret
;*******************************
; getfp : get file name stinrg pointer
; with 6 byte header
;
; in : ax = file number
; hbnum = current readin number
; out: esi = file name pointer
; err: cf = set by no exist
;
getfp proc
push es
mov dx,0004h ; PSP selector
mov es,dx
mov esi,buffer ; saving buffer pointer
cmp ax,hbnum ; check read in
jb getfp7 ; red
mov bx,ax ; save destination file number
;-------------------------------
; read file names in buffer
; in : bx = destination file number
; esi = buffer pointer
;-------------------------------
mov ax,6+13
mul hbnum
cwde
add esi,eax ; saving start address
test ax,ax ; first read ?
jz getfp4 ; yes
;
getfp1: mov ah,4Fh ; search next file
int 21h
jc getfp9 ; don't find
;
getfp2: mov edi,80h+1Eh ; file name offset in DTA buffer
mov word ptr [esi+4],-5 ; clear file name length
mov ecx,esi
add ecx,6 ; skip header bytes
getfp3: mov al,es:[edi]
mov byte ptr [ecx],al
inc word ptr [esi+4] ; count up file name length
inc edi ; proceed addresses
inc ecx
test al,al ; check string end
jnz getfp3 ; go to read next charactor
inc hbnum ; renew readin number
cmp bx,hbnum ; check file number
jb getfp8 ; found
add esi,6+13 ; next file name saving address
jmp getfp1
;
getfp4: mov edx,offset pathbuf+1 ; search pathlist pointer
movzx ecx,byte ptr [edx-1] ; directory list length
mov byte ptr [edx+ecx],'*' ; set wild card
mov eax,exts ; extension string
mov [edx+ecx+1],eax ; set extension(ex. ".MDL")
mov byte ptr [edx+ecx+5],0 ; null terminate
xor cx,cx ; normal attribute
mov ah,4Eh ; search first file
int 21h
jc getfp9 ; don't find
jmp getfp2
;-------------------------------
; return file string pointer
; in : ax = file number
; esi = buffer pointer
;-------------------------------
getfp7: imul ax,6+13
cwde
add esi,eax
getfp8: clc
getfp9: pop es
ret
getfp endp
;*******************************
; dspfn : display file name
;
; in : ax = item number
; count1 = top file number
; fs = TOWNS BIOS selector
; err: cf = set by no exist
; call: getfp
;
dspfn proc
push ax
add ax,count1 ; distination file number
call getfp ; get file name pointer
pop ax
jc dspfn9 ; no exist
;
mov word ptr [esi],MENUX+28 ; set x position
imul ax,18
add ax,MENUY+50
mov [esi+2],ax ; set y position
mov ah,60h ; display string
mov edi,offset egbwork
call pword ptr fs:[20h]
clc
dspfn9: ret
dspfn endp
;*******************************
; makpath : make pathlist
;
; in : esi = file name string
; 4(2) byte length
; 6(n) file name
; eax = extension (.MDL/.MDC)
; pathbuf = directory list
; out: pathbuf = pathlist buffer
; 1(n) pathlist (ASCIZ)
; err: cf = set by invalid file name
; use: ecx,esi,edi
;
makpath proc
push es
mov cx,ds ; set es selector
mov es,cx
mov edi,offset pathbuf ; pathlist buffer pointer
movzx ecx,byte ptr [edi] ; directory list length
inc ecx ; add byte of length
add edi,ecx ; directory tail address
movzx ecx,word ptr [esi+4] ; file name byte length
cmp ecx,1 ; check length
jc makpa9 ; invalid
add esi,6 ; file name start address & clear carry
rep movsb ; copy file name
mov [edi],eax ; set extension (ex. ".MDL")
mov byte ptr [edi+4],0 ; null terminate
makpa9: pop es
ret
makpath endp
open endp
;*******************************
; save : save data
;*******************************
save proc
;-------------------------------
; input file name and create
;-------------------------------
save10: mov eax,EXTALL ; extension
call create ; file create
jc save90 ; quit
;-------------------------------
; write data
; in : ax = file handle
;-------------------------------
mov edx,offset posx ; data pointer
mov ecx,size locdat ; location data byte size
mov bx,ax ; file handle
mov ah,40h ; write
int 21h
jc save50
mov edx,offset palbuf
mov ecx,(1+USRCN)*3 ; color data byte size
mov ah,40h ; write
int 21h
;-------------------------------
; handle close
; in : bx = file handle
; cf = error flag
;-------------------------------
save50: pushf
mov ah,3Eh ; file close
int 21h
popf
jc save10 ; repeat input
save90: jmp main30 ; go to menu mode
save endp
;*******************************
; create : create file
;
; in : eax = extension
; pathbuf = directory path
; out: cf = set for quit
; ax = file handel
; call: dspmenu,getstr,makpath
; use: all reg & work1
;
LOCFI equ (MENUX+(MENUW-8*8)/2)+((MENUY+80) shl 16)
create proc
push eax ; save extension
;-------------------------------
; display screen
;-------------------------------
crte10: mov esi,offset msave
call dspmenu ; display menu items
;-------------------------------
; get file name
;-------------------------------
mov esi,offset work1
mov dword ptr [esi],LOCFI ; location of file input
mov cx,8 ; maximum length
call getstr ; get string from keybord
;-------------------------------
; make pathlist
; in : esi = string buffer base
;-------------------------------
mov eax,[esp] ; extension
call makpath ; make pathlist
jc crte99 ; quit
;-------------------------------
; file create
;-------------------------------
mov edx,offset pathbuf+1
mov ah,3Ch ; file create
xor cx,cx ; common attribute
int 21h
jc crte10 ; go to repeat
;
crte99: pop ecx ; abandon
ret
create endp
;*******************************
; chgcol : change color
;*******************************
chgcol proc
mov spflg,FALSE ; save pallet flag off
chgco1: mov esi,offset mcgc
call dspmenu ; display menu items
mov bx,offset sicol ; selector data address
call select ; select item
jc main30 ; escape to main menu mode
shl ax,2 ; make offset
cwde
jmp cmdtbl2[eax] ; jump destination procedure
chgcol endp
;*******************************
; indcol : change color individually
;*******************************
indcol proc
;-------------------------------
; initailize
;-------------------------------
mov numwid,3 ; set display width of integer
mov cura,SCRX+SCRW/2 ; cross cursor x position
mov curb,SCRY+SCRH/2 ; cross cursor y position
;
indc10: mov esi,offset mindc
call dspmenu ; display menu items
mov repcnt,INIREP ; intialize repeat counter
xor ax,ax ; wait no press state
call waitp
;-------------------------------
; display current color data
;-------------------------------
indc20: call dsppbs ; display panel & bars
;-------------------------------
; command input
;-------------------------------
indc40: call getpad ; get pad state
cmp al,P$LEFT
je indc50 ; pallet code down
cmp al,P$RIGHT
je indc60 ; pallet code up
mov repcnt,INIREP ; intialize repeat counter
cmp al,P$SEL
je extpix ; go to extract pallet number from poxcel
test ah,P$TRIG1
jnz coledit ; go to edit mode
test ah,P$TRIG2
jz indc40 ; invalid
;
indc90: mov numwid,5 ; restore width of integer
jmp chgco1 ; go to change color menu mode
;-------------------------------
; color number down
;-------------------------------
indc50: call repable ; repeatable ?
jc indc40 ; invalid
movzx ax,colnum ; current color number
sub ax,1 ; number down
jb indc40 ; invalid
mov colnum,al ; set new number
jmp indc20 ; to display
;-------------------------------
; color number up
;-------------------------------
indc60: call repable ; repeatable ?
jc indc40 ; invalid
movzx ax,colnum ; current color number
inc ax ; number up
cmp ax,USRCN ; check
ja indc40 ; invalid
mov colnum,al ; set new number
jmp indc20 ; go to dispaly
indcol endp
;*******************************
; dsppbs : display panel & bars
; copy bpal,rpal,gpal from colbuf
;
; in : colnum = color number
; palbuf = pallet buffer
; out: bpal,rpal,gpal
; call: getpal,dspcp,dspbar
; use: all
;
dsppbs proc
call getpal ; get pallet data
call dspcp ; display color panel
xor al,al ; blue
call dspbar ; display bar
mov al,1 ; red
call dspbar ; display bar
mov al,2 ; green
call dspbar ; display bar
ret
dsppbs endp
;*******************************
; getpal : get pallet data
; from palbuf to palpkt
;
; in : colnum = color number
; palbuf = pallet buffer
; out: bpal,rpal,gpal
; use: eax,esi
;
getpal proc
movzx esi,colnum
imul esi,3 ; pallet data offset
mov eax,dword ptr ss:palbuf[esi] ; level data + 1
mov dword ptr bpal,eax ; set level data
ret
getpal endp
;*******************************
; dspcp : display color panel
; with color code number
;
; in : colnum = color number
; call: putdec
;
LINDCC equ MENUX+(MENUW-24)/2+(MENUY+44)*VRAMW ; color code
dspcp proc
movzx ax,colnum ; dispaly current color number
mov edi,LINDCC
call putdec
;
mov edi,(MENUY+47)*VRAMW+MENUX+(MENUW-74)/2
mov bx,16 ; set hight counter
mov al,colnum ; color number
mov ah,al ; extend AL to AX
dscp10: mov ecx,74/2 ; set width counter
rep stosw
add edi,VRAMW-74
dec bx
jnz dscp10
ret
dspcp endp
;*******************************
; dspbar : display level bar
;
; in : al = RGB species
; B=0,R=1,G=2
; bpal,rpal,gpal
; call: putdec
;
LINDCB equ MENUX+(MENUW-70)/2+72+(MENUY+92)*VRAMW ; blue level number
dspbar proc
movzx esi,al ; RGB offset
add esi,offset bpal ; destination address
movzx edi,al
imul edi,16*VRAMW
add edi,LINDCB ; destination display VRAM address
movzx ax,byte ptr [esi] ; destination level
push edi
push ax
call putdec
pop dx ; destination level
pop edi
add edi,-14*VRAMW-72+3
;-------------------------------
; draw color level bar
; in : edi = bar address
; dl = color level
;-------------------------------
xor dh,dh
add dx,11b ; round
shr dx,2
mov dh,64 ; total width
sub dh,dl ; top blank width
mov bh,12 ; set hight counter
dsbar1: movzx ecx,dl
mov al,C$INT
rep stosb
movzx ecx,dh
mov al,C$PANEL
rep stosb
add edi,VRAMW-64 ; next line
dec bh
jnz dsbar1
ret
dspbar endp
;*******************************
; coledit : color edit
;*******************************
coledit proc
;-------------------------------
; initailize
;-------------------------------
mov esi,offset mced
call dspmenu ; display menu items
call dsppbs ; display color panel & bars
xor ax,ax ; wait no press state
call waitp
mov al,colnum
mov palnum,al
mov al,C$INT ; string color
call dspRGB ; display destination RGB string
cmp spflg,TRUE ; check save pallet flag
je ced10
call savpal ; save all pallets
mov spflg,TRUE
ced10: mov repcnt,INIREP ; intialize repeat counter
;-------------------------------
; command input
;-------------------------------
ced40: call getpad ; get pad state
cmp al,P$SEL
je ced60 ; RGB rotate
mov repcnt,INIREP ; intialize repeat counter
cmp al,P$RIGHT
je ced50 ; level up
cmp al,P$LEFT
je ced55 ; level down
test ah,P$TRIG2
jnz ced80 ; cancel
test ah,P$TRIG1
jz ced40 ; invalid
;
movzx edi,colnum
imul edi,3 ; destination color offset
mov ax,word ptr bpal ; new pallet levels
mov word ptr ss:palbuf[edi],ax ; save new color data
mov al,gpal
mov ss:palbuf[edi+2],al
jmp indc10 ; return to color select mode
;-------------------------------
; color level up
;-------------------------------
ced50: call repable ; repeatable ?
jc ced40 ; invalid
movzx esi,currgb ; current RGB
add esi,offset bpal ; destination RGB parameter address
inc byte ptr [esi] ; increment level
jnz ced52 ; OK!
mov byte ptr [esi],255 ; to maximum value
ced52: mov esi,offset palpkt
call setpal ; set pallet register
mov al,currgb ; current RGB
call dspbar ; display bar
jmp ced40
;-------------------------------
; color level down
;-------------------------------
ced55: call repable ; repeatable ?
jc ced40 ; invalid
movzx esi,currgb ; current RGB
add esi,offset bpal ; destination RGB parameter address
sub byte ptr [esi],1 ; decriment level
jnc ced52 ; OK!
inc byte ptr [esi] ; to minimum value = 0
jmp ced40
;-------------------------------
; distination RGB rotate
;-------------------------------
ced60: call repable ; repeatable ?
jc ced40 ; invalid
mov al,C$DARK ; intensity off
call dspRGB
inc currgb ; change current RGB species
cmp currgb,2
jbe ced62 ; change OK!
mov currgb,0 ; round
ced62: mov al,C$INT ; intensity on
call dspRGB
jmp ced40 ; to get next command
;-------------------------------
; cancel
;-------------------------------
ced80: call getpal ; set pallet data from palbuf to palpkt
call waitv ; wait VSYNC trigger
mov esi,offset palpkt
call setpal ; set pallet register
jmp indc10 ; return to color select mode
;*******************************
; dspRGB : display RGB string
;
; in : currgb = current RGB species
; al = string color code
; call: color
;
dspRGB proc
call color ; set string color
mov esi,offset strRGB
mov al,strRGBL ; string data length
mul currgb ; current RGB string offset
cwde
add esi,eax ; current RGB string address
mov ah,60h ; display string
call pword ptr fs:[20h]
ret
dspRGB endp
coledit endp
;*******************************
; savpal : save pallets
; backup pallets destroy
;
; in : palbuf = current pallets
; palbak = saving area
; use: ax,ecx,esi,edi
;
savpal proc
mov esi,offset palbuf
mov edi,offset palbak
mov ecx,USRCN+1
savpa1: lodsw
mov [edi],ax
lodsb
mov [edi+2],al
add edi,3
loop savpa1
ret
savpal endp
;*******************************
; extpix : extact pallet number
; from pixcel
;*******************************
extpix proc
;-------------------------------
; initialize
;-------------------------------
mov esi,offset mexp
call dspmenu ; display menu items
xor ax,ax ; wait no press state
call waitp
mov al,C$PANEL
xchg al,colnum ; initialize number except display color
mov palnum,al ; save color number
;-------------------------------
; read pixcel & display
;-------------------------------
expi10: imul esi,curb,VRAMW
add esi,cura
mov al,es:[esi] ; destination pixcel data
cmp al,colnum ; check same color
je expi48 ; same to skip draw
mov colnum,al ; save pallet number
call dspcros ; display cross cursor
call dsppbs ; display panel & bars
;-------------------------------
; command input
;-------------------------------
expi40: call getpad ; get pad state
test ax,ax
jz expi40 ; no press
call waitv ; wait VSYNC
call dspcros ; erase cross cursor
;
cmp al,P$LEFT
je expi50 ; left move
cmp al,P$RIGHT
je expi55 ; right move
cmp al,P$FWD
je expi60 ; up move
cmp al,P$BACK
je expi65 ; down move
test ah,P$TRIG1
jnz indc10 ; go to color number select mode
test ah,P$TRIG2
jnz expi70 ; quit end
;
expi48: call dspcros ; display cross cursor
jmp expi40 ; go to get pad state
;-------------------------------
; cross cursor left
;-------------------------------
expi50: mov eax,cura ; current x position
dec eax ; decrement
cmp eax,SCRX ; check limit
jae expi52 ; OK!
mov eax,SCRX ; correction
expi52: mov cura,eax ; save x position
jmp expi10 ; go to display
;-------------------------------
; cross cursor right
;-------------------------------
expi55: mov eax,cura ; current x position
inc eax ; increment
cmp eax,SCRX+SCRW ; check limit
jb expi52 ; OK!
mov eax,SCRX+SCRW-1 ; correction
jmp expi52 ; go to save
;-------------------------------
; cross cursor up
;-------------------------------
expi60: mov eax,curb ; current y position
dec eax ; decrement
cmp eax,SCRY ; check limit
jae expi62 ; OK!
mov eax,SCRY ; correction
expi62: mov curb,eax ; save y position
jmp expi10 ; go to dislay
;-------------------------------
; crosss cursor down
;-------------------------------
expi65: mov eax,curb ; current y position
inc eax ; increment
cmp eax,SCRY+SCRH ; check limit
jb expi62 ; OK!
mov eax,SCRY+SCRH-1 ; correction
jmp expi62 ; go to save
;-------------------------------
; quit end
;-------------------------------
expi70: mov al,palnum ; resotre color number
mov colnum,al
jmp indc10 ; return to color number select mode
;*******************************
; dspcros : dsplay cross cursor
;
; in : cura = current x position
; curb = current y position
; es = VRAM selector
; use: ecx,edi
;
dspcros proc
;-------------------------------
; horizon line
;-------------------------------
imul edi,curb,VRAMW
add edi,SCRX ; line start address
mov ecx,SCRW/4
dscrs1: not dword ptr es:[edi]
add edi,4
loop dscrs1
;-------------------------------
; vertical line
;-------------------------------
mov edi,SCRY*VRAMW
add edi,cura ; line start address
mov ecx,SCRH
dscrs2: not byte ptr es:[edi]
add edi,VRAMW
loop dscrs2
ret
dspcros endp
extpix endp
;*******************************
; setcs : set color step
;*******************************
setcs proc
;-------------------------------
; initialize
;-------------------------------
mov esi,offset msetcs
call dspmenu ; display menu items
mov count1,1 ; color step
mov count2,1 ; color step change unit
mov hbnum,0 ; auto change flag off
mov currgb,P$FWD ; auto command
mov ax,count2 ; display current change unit
mov edi,LCSTEP1
call putdec
xor ax,ax ; wait no press state
call waitp
;-------------------------------
; display screen
;-------------------------------
stcs10: mov ax,count1 ; display current step
mov edi,LCSTEP2
call putdec
;
mov esi,offset work1 ; pallet packet
mov dword ptr [esi],0 ; initialize pallet number & levels
mov bx,PALSBN ; set pallet block counter
movzx eax,count1 ; color step
mov ecx,PALSBR-1 ; set rest pallet number
stcs12: call waitv ; wait VSYNC
stcs14: inc byte ptr [esi] ; next pallet number
add [esi+1],eax ; set new level
call setpal ; set pallet code
loop stcs14
mov ecx,PALSBS ; set pallet block size
dec bx
jnz stcs12
;-------------------------------
; command input
;-------------------------------
stcs30: call getpad ; get pad state
stcs32: cmp al,P$FWD
je stcs50 ; step up
cmp al,P$BACK
je stcs55 ; step down
cmp al,P$LEFT
je stcs60 ; unit up
cmp al,P$RIGHT
je stcs65 ; unit down
cmp al,P$RUN
je stcs70 ; switch auto change
;
cmp hbnum,0 ; check auto change flag
je stcs34 ; off
mov al,currgb ; load auto command
jmp stcs32 ; go to dispatch
stcs34: test ah,P$TRIG2
jnz stcs80 ; cancel
test ah,P$TRIG1
jz stcs30 ; invalid
;-------------------------------
; decision end
;-------------------------------
cmp spflg,TRUE ; check save pallet flag
je stcs40
call savpal ; save all pallets
mov spflg,TRUE
;
stcs40: mov edi,offset palbuf ; pallet buffer
mov ecx,USRCN ; set pallet number counter
movzx eax,count1 ; color step
xor edx,edx ; initialize color level
stcs42: add edi,3 ; next pallet address
add edx,eax ; next color level
mov [edi],edx ; set color level + 1
loop stcs42
jmp chgcol ; return to color menu
;-------------------------------
; step up or down
; in : al = command code
;-------------------------------
stcs50: mov currgb,al ; set auto command
mov ax,count2 ; change unit
add count1,ax ; step up
jnz stcs10 ; go to change pallet
inc count1 ; skip zero step
jmp stcs10
;
stcs55: mov currgb,al ; set auto command
mov ax,count2 ; change unit
sub count1,ax ; step down
jnz stcs10 ; go to change pallet
dec count1 ; skip zero step
jmp stcs10
;-------------------------------
; unit up or down
;-------------------------------
stcs60: inc count2 ; cahnge unit up
jns stcs62
dec count2
stcs62: call waitv ; wait VSYNC trigger
mov ax,count2 ; display current change unit
mov edi,LCSTEP1
call putdec
jmp stcs30 ; go to pad input
;
stcs65: dec count2 ; change unit down
jnz stcs62
inc count2
jmp stcs62 ; go to display
;-------------------------------
; auto change switch
;-------------------------------
stcs70: not hbnum ; switch auto change flag
xor ax,ax ; wait no press state
call waitp
jmp stcs30 ; go to pad input
;-------------------------------
; quit end
;-------------------------------
stcs80: call setdp ; set display pallet by old data
jmp chgcol ; return to color menu
setcs endp
;*******************************
; grad : gradation
;*******************************
grad proc
;-------------------------------
; initialize
;-------------------------------
mov esi,offset mgrad
call dspmenu ; display menu items
mov count1,111b ; color number 1 = White
mov count2,000b ; color number 250 = Black
mov hbnum,0 ; select number = 250
mov edi,(MENUY+60-17+2)*VRAMW+MENUX+40
mov al,1 ; color number 1
call gradp ; draw gradation panel
mov edi,(MENUY+120-17+2)*VRAMW+MENUX+40
mov al,250 ; color number 250
call gradp ; draw gradation panel
call dspgcn ; display gradation color number
;-------------------------------
; change pallet
;-------------------------------
grad20: mov esi,offset work1 ; pallet packet
call makgd ; make gradation data
mov bx,PALSBN ; set pallet block counter
mov ecx,PALSBR-1 ; set rest pallet number execpt 0
grad26: call waitv ; wait VSYNC
grad28: call setpal ; set pallet code
inc byte ptr [esi] ; next pallet number
mov al,[esi+4]
add [esi+1],al ; new blue level
mov al,[esi+5]
add [esi+2],al ; new red level
mov al,[esi+6]
add [esi+3],al ; new green level
loop grad28
mov ecx,PALSBS ; set pallet full block size
dec bx
jnz grad26
;-------------------------------
; command input
;-------------------------------
grad30: xor ax,ax ; wait no press state
call waitp
grad32: call getpad ; get pad state
cmp al,P$RIGHT
je grad50 ; next color
cmp al,P$LEFT
je grad60 ; previous color
cmp al,P$SEL
je grad70 ; select 0 or 250
test ah,P$TRIG2
jnz grad80 ; cancel
test ah,P$TRIG1
jz grad32 ; invalid
;-------------------------------
; decision end
;-------------------------------
cmp spflg,TRUE ; check save pallet flag
je grad40
call savpal ; save all pallets
mov spflg,TRUE
;
grad40: mov esi,offset work1 ; pallet packet
call makgd ; make gradation data
mov edi,offset palbuf+3 ; user pallet buffer address
mov ecx,USRCN ; set pallet number counter
mov ax,[esi+1] ; blue,red start level
mov dl,[esi+3] ; green start level
grad42: mov [edi],ax ; set green,red level
mov [edi+2],dl ; set blue level
add edi,3 ; next pallet address
add al,[esi+4] ; new blue level
add ah,[esi+5] ; new red level
add dl,[esi+6] ; new green level
loop grad42
jmp chgcol ; return to color menu
;-------------------------------
; next color
;-------------------------------
grad50: cmp hbnum,0 ; check destination
je grad52
inc count1
jmp grad20
grad52: inc count2
jmp grad20
;-------------------------------
; previous color
;-------------------------------
grad60: cmp hbnum,0 ; check destination
je grad62 ; color 250
or count1,1000b
dec count1
jmp grad20
grad62: or count2,1000b
dec count2
jmp grad20
;-------------------------------
; select 0 or 250
;-------------------------------
grad70: not hbnum ; change destination color
call dspgcn ; display gradatino color number
jmp grad30 ; go to next command
;-------------------------------
; cancel end
;-------------------------------
grad80: call setdp ; set display pallet by old data
jmp chgcol ; return to color menu
;*******************************
; gradp : draw gradation panel
;
; in : edi = start address
; al = color code
;
gradp proc
mov bx,16 ; set hight counter
mov ah,al
gradp1: mov ecx,76/2 ; set width counter
rep stosw
add edi,VRAMW-76
dec bx
jnz gradp1
ret
gradp endp
;*******************************
; dspgcn : display gradation
; color number
; select item is intensified
;
; in : hbnum = color number flag
; 00 = 250
; FF = 1
; call: color
;
gcnstr1 dw MENUX+8+16,MENUY+60,1 ; lowest color number string
db "1"
gcnstr2 dw MENUX+8,MENUY+120,3 ; highest color number string
db "250"
;
dspgcn proc
mov ax,(C$DARK shl 8)+C$INT
cmp hbnum,0
je dpgcn1 ; highest number
xchg ah,al
dpgcn1: push ax
mov al,ah
call color ; set color
mov edi,offset egbwork ; EGB work address
mov esi,offset gcnstr1 ; lowest number
mov ah,60h ; display string
call pword ptr fs:[20h]
pop ax
call color ; set color
mov esi,offset gcnstr2 ; highest number
mov ah,60h ; display string
call pword ptr fs:[20h]
ret
dspgcn endp
;*******************************
; makgd : make gradation data
;
; in : esi = work buffer
; 0(1) pallet number
; 1(1) blue level
; 2(1) red level
; 3(1) green level
; 4(1) blue step
; 5(1) red step
; 6(1) green step
; count1 = color 0 level flag
; count2 = color 250 level flag
;
makgd proc
mov byte ptr [esi],1 ; initialize pallet number
mov dx,count1 ; color 1 level flag
mov bx,count2 ; color 250 level flag
mov ecx,3
makgd1: mov ax,255-USRCN ; AL = lowest level
shr dx,1
jnc makgd2
mov ax,(-1 shl 8)+USRCN ; AL = highest level
makgd2: mov [esi+ecx],al ; set initial level
shr bx,1
adc ah,0
mov [esi+ecx+3],ah ; set level step (-1|0|+1)
loop makgd1
ret
makgd endp
grad endp
;*******************************
; cload : load color data
;*******************************
cload proc
mov exts,EXTCOL ; set extension
call open ; file open
jc clod90 ; quit
mov bx,ax ; file handel
;
cmp spflg,TRUE ; check save pallet flag
je clod10
call savpal ; save all pallets
mov spflg,TRUE
;
clod10: mov edx,offset palbuf ; pallet buffer
mov ecx,(1+USRCN)*3 ; color data byte size
mov ah,3Fh ; read file
int 21h
mov ah,3Eh ; file close
int 21h
;
call setdp ; set display pallet
clod90: jmp chgcol ; return to color menu
cload endp
;*******************************
; csave : save color data
;*******************************
csave proc
csav10: mov eax,EXTCOL ; extension
call create ; file create
jc csav90 ; quit
;
mov edx,offset palbuf
mov ecx,(1+USRCN)*3 ; data byte size
mov bx,ax ; file handle
mov ah,40h ; write
int 21h
pushf
mov ah,3Eh ; file close
int 21h
popf
jc csav10 ; error then input repeat
csav90: jmp chgcol ; return to color menu
csave endp
;*******************************
; crest : restore color data
;*******************************
crest proc
mov esi,offset palbak ; backup pallets
mov edi,offset palbuf ; pallet buffer
mov ecx,1+USRCN ; number of pallets
crest1: lodsw
xchg [edi],ax
mov [esi-2],ax
lodsb
xchg [edi+2],al
mov [esi-1],al
add edi,3
loop crest1
;
mov spflg,FALSE ; clear save pallet flag
call setdp ; set display pallets
jmp chgcol ; return to color menu
crest endp
;*******************************
; boxdwn : box down
; look like down area
; by C$LIGHT,C$DARK
;
; in : esi = box data base
; 0 : base address
; 4 : width(4*n)
; 6 : hight
; al = fill color code
; use: bx,ecx,edx
;
boxdwn proc
push esi
push edi
mov ah,al ; extend AL to EAX
mov dx,ax
shl eax,16
mov ax,dx
mov edi,[esi].boxadr ; start VRAM address
mov bx,[esi].boxh ; set hight counter
movzx esi,[esi].boxw ; width
mov edx,esi
sub esi,VRAMW ; negative line distance
shr edx,2 ; double word counter
bxdw10: mov byte ptr es:[edi-1],C$DARK
mov ecx,edx ; set width counter
rep stosd
mov byte ptr es:[edi],C$LIGHT
sub edi,esi ; next line address
dec bx ; line count down
jnz bxdw10
pop edi
pop esi
ret
boxdwn endp
;*******************************
; revfr : reverse frame
;
; in : esi = box address
; 0 : x position
; 2 : y position
; 4 : width
; 6 : hight
; use: eax,ebx,ecx,edx
;
revfr proc
push edi
movzx eax,word ptr [esi+2] ; y position
imul eax,VRAMW
movzx edi,word ptr [esi]
add edi,eax ; base address
;
movzx ecx,word ptr [esi+4] ; width counter
mov edx,ecx ; save
revf10: not byte ptr es:[edi+ecx-1] ; reverse top line
loop revf10
;
add edi,VRAMW ; next line address
movzx ecx,word ptr [esi+6] ; hight
sub ecx,2 ; intermediate lines counter
revf20: not byte ptr es:[edi] ; reverse left pixcel
not byte ptr es:[edi+edx-1] ; reverse right pixcel
add edi,VRAMW ; next line address
loop revf20
;
mov ecx,edx ; width counter
revf30: not byte ptr es:[edi+ecx-1] ; reverse bottom line
loop revf30
pop edi
ret
revfr endp
;*******************************
; boxup : look like box up
; use C$LIGHT,C$DARK
;
; in : edi = box start address
; ax = box width
; dx = box hight
; use: none
;
boxup proc
push edi
push ax
push ebx
push ecx
push dx
movzx ebx,ax ; save box width
mov al,C$LIGHT
mov ecx,ebx ; width counter
rep stosb ; draw top line
sub edi,ebx
add edi,VRAMW ; next line address
;
sub dx,2
movzx ecx,dx ; middle line counter
bxup10: mov es:[edi],al
mov byte ptr es:[edi+ebx-1],C$DARK
add edi,VRAMW ; next line address
loop bxup10
;
mov al,C$DARK
mov ecx,ebx ; width counter
rep stosb ; draw bottom line
pop dx
pop ecx
pop ebx
pop ax
pop edi
ret
boxup endp
;*******************************
; chgsc : string color change
; except for right pixcel
;
; in : edi = box start address
; bx = box width
; al = destination color
; ah = source color
; es = VRAM selector
; use: ecx,edx,ebp
;
chgsc proc
push edi
movzx ebx,bx
mov ebp,VRAMW
sub ebp,ebx ; distance between lines
mov dx,16 ; string hight counter
cgbx10: mov ecx,ebx ; set width counter
cgbx12: repne scasb
jcxz cgbx14
mov es:[edi-1],ah ; change color
jmp cgbx12
cgbx14: add edi,ebp ; next line address
dec dx
jnz cgbx10
pop edi
ret
chgsc endp
;*******************************
; color : set foreground color
;
; in : al = color code
; use: ax,edx,edi
;
color proc
mov edi,offset egbwork ; EGB work address
movzx edx,al ; color code
mov ax,0700h ; set foreground color
call pword ptr fs:[20h]
ret
color endp
;*******************************
; dspss : display strings
;
; in : bx = string index address
; al = string color
; fs = TOWNS BIOS
; call: color
; use: ax,bx,ecx,edi
;
dspss proc
push esi
call color ; set color
mov edi,offset egbwork ; EGB work address
movzx ecx,word ptr [bx] ; number of string
dpss10: add bx,2
movsx esi,word ptr [bx]
mov ah,60h
call pword ptr fs:[20h]
loop dpss10
pop esi
ret
dspss endp
;*******************************
; dspfp : display frame parameter
; posx,posy,reso
;
; use: putfp
;
dspfp proc
mov eax,posx ; position x
mov edi,LPOSX
call putfp
mov eax,posy ; position y
neg eax
mov edi,LPOSY
call putfp
mov eax,reso ; resolution
mov edi,LRESO
call putfp
ret
dspfp endp
;*******************************
; dspmenu : display menu items
;
; in : esi = menu items index
; 0(2) buttons pointer
; 2(2) buttons number
; 4(2) strings pointer
; call: boxdwn,boxup,dspss
; use: all
;
dspmenu proc
mov edi,esi ; save index pointer
mov esi,offset menubox ; menu box pointer
mov al,C$PANEL ; with panel color
call boxdwn ; clear box
;
push edi ; save index pointer
mov si,[edi].butptr ; buttons pointer
movzx ecx,[edi].butnum ; buttons number
dsme10: mov edi,[si].butadr ; start address
mov ax,[si].butw ; box width
mov dx,[si].buth ; box hight
call boxup ; button up
add si,8 ; next box
loop dsme10
pop edi ; load index pointer
;
mov bx,[edi].strptr ; strings pointer
mov al,C$DARK ; dark shadow color
call dspss ; display strings
ret
dspmenu endp
;*******************************
; getpad : get pad button state
;
; out: ah = trigger
; al = move, run and select
; use: dx
;
getpad proc
xor ax,ax
mov dx,04D6h ; set pad output register
mov al,00010011b
out dx,al
mov dx,04D0h ; get pad 1 input
in al,dx
test al,01000000b ; check COM input
jz gtpd22 ; no exist
call gtpd30 ; analyze pad 1 state
test ax,ax ; press any key ?
jnz gtpd99 ; yes
;
gtpd22: mov dx,04D6h ; set pad output register
mov al,00101100b
out dx,al
mov dx,04D2h ; get pad 2 input
in al,dx
test al,01000000b ; check COM input
jz gtpd99 ; no exist
call gtpd30 ; analyze pad 2 state
gtpd99: ret
gtpd30: mov ah,al
not ah
and ah,00110000b ; mask off trigger bits
shr ah,4 ; make return data
and al,00001111b ; mask off other button state
cmp al,0111b ; check RIGHT state
je gtpd50 ; on
cmp al,1011b ; check LEFT state
je gtpd52 ; on
cmp al,1101b ; check BACK state
je gtpd54 ; on
cmp al,1110b ; check FWD state
je gtpd56 ; on
cmp al,0011b ; check RUN state
je gtpd58 ; on
cmp al,1100b ; check SELECT state
je gtpd60 ; on
;
xor al,al ; not press
ret
gtpd50: mov al,P$RIGHT
ret
gtpd52: mov al,P$LEFT
ret
gtpd54: mov al,P$BACK
ret
gtpd56: mov al,P$FWD
ret
gtpd58: mov al,P$RUN
ret
gtpd60: mov al,P$SEL
ret
getpad endp
;*******************************
; waitp : wait special pad state
;
; in : ax = pad state
; call: getpad
; use: ax,cx,dx
;
waitp proc
mov cx,ax ; dave destination state
waip10: call getpad ; get pad state
cmp cx,ax ; compare pad state
jne waip10 ; difference
ret
waitp endp
;*******************************
; waitv : wait VSYNC happen
;
; use: none
;
waitv proc
push dx
push ax
mov dx,0FDA0h ; SUB status register I/O address
waiv10: in al,dx
test al,1b ; VSYNC
jnz waiv10 ; wait VSYNC off
waiv20: in al,dx
test al,1b ; VSYNC
jz waiv20 ; wait VSYNC on
pop ax
pop dx
ret
waitv endp
;*******************************
; repable : check repeatble
;
; in : repcnt = repeat count
; out: cf = able is clear
; call: waitv
; use: none
;
repable proc
call waitv
inc repcnt
jz repab9 ; first input
cmp repcnt,PADREP
jb repabE ; invalid
repab9: mov repcnt,0 ; clear counter
clc ; repeatable
repabE: ret
repable endp
;*******************************
; select : select menu item
;
; in : bx = selector data address
; fs = TOWNS BIOS
; out: ax = selector number
; err: cf = set by escape
; call: boxup,dspss,waitp
; getpad,repable,color
; use: ax,ecx,dx,esi
;
select proc
mov repcnt,INIREP ; clear pad input counter
;-------------------------------
; initialize screen
;-------------------------------
push bx
movzx ecx,word ptr [bx+2] ; set item counter
add bx,4 ; first item pointer address
mov ax,MENUW-6 ; selector box width
mov dx,19 ; selector box hight
sel10: mov di,[bx] ; item pointer
movsx edi,word ptr [di+2] ; item y position
sub edi,16 ; box top y position
imul edi,VRAMW
add edi,MENUX+3 ; box base VRAM address
call boxup ; look like box up
add bx,2 ; next item pointer address
loop sel10
pop bx
;
push bx
add bx,2 ; strings index address
mov al,C$DARK ; dark shdow color
call dspss ; display strings
pop bx
;
xor ax,ax ; wait no press state
call waitp
;-------------------------------
; display current item
; in : bx = menu data address
;-------------------------------
sel20: mov si,[bx] ; current item number
test si,si ; check under limit
jns sel22 ; OK!
mov si,[bx+2] ; arround highest number
dec si
sel22: cmp si,[bx+2] ; check upper limit
jb sel24 ; OK!
xor si,si ; arround lowest number
sel24: mov [bx],si ; save adjust number
;
shl si,1
movsx esi,word ptr [bx+si+4] ; current string address
movsx edi,word ptr [esi+2] ; item y position
sub edi,15 ; box top panel y position
imul edi,VRAMW
add edi,MENUX+4 ; box top panel base VRAM address
push bx
mov bx,MENUW-8 ; box top panel width
mov ax,C$DARK+C$INT*256
call chgsc ; change box color
pop bx
;-------------------------------
; input pad
; in : bx = selector data address
;-------------------------------
sel30: call getpad ; get pad button state
cmp al,P$FWD
je sel40 ; cursor up
cmp al,P$BACK
je sel44 ; cursor down
mov repcnt,INIREP ; clear counter
test ah,P$TRIG2
jnz sel38 ; escape
test ah,P$TRIG1
jz sel30 ; invalid
;
mov ax,[bx] ; select item number
clc ; clear carry
ret
sel38: stc ; set carry
ret
;-------------------------------
; move cursor
; in : edi = current box top address
; bx = menu data address
;-------------------------------
sel40: call repable ; repeatalbe ?
jc sel30 ; invalid
dec word ptr [bx] ; to lower item
jmp short sel48
;
sel44: call repable ; repeatalbe ?
jc sel30 ; invalid
inc word ptr [bx] ; to upper item
;
sel48: push bx
mov bx,MENUW-8 ; box top panel width
mov ax,C$INT+C$DARK*256
call chgsc ; change string color
pop bx
jmp sel20
select endp
;*******************************
; dspmain : display main
; mandelbrot figure
;
; in : curstat = current display state
; step = display step
; out: curstat = new display state
; step = new step
; err: cf = set by interrupted
; call: dspmenu,putdec,getpad
; dsp8s,dsp3q
; use: all
;
dspmain proc
cmp curstat,DS$FULL ; if full figure display completion
je dsma99 ; then end with do nothing
mov esi,offset mdrawon ; display menu items
call dspmenu
cmp curstat,DS$ON ; dispaly on the way ?
je dsma10 ; continue
;
mov ax,8 ; display step number
mov edi,LDSTEP ; display position
call putdec
call dsp8s ; first display by 8 step
mov curstat,DS$ON ; first display completion
mov step,4 ; set display step
call getpad ; get pad state
test ah,P$TRIG2 ; press B button ?
jnz dsma90 ; interrupt
;
dsma10: mov ax,step ; display step
mov edi,LDSTEP ; display position
call putdec
call dsp3q ; display 3/4
jc dsma99 ; interrupted end
shr step,1 ; set next step
jnz dsma10
mov curstat,DS$FULL ; display completion
clc ; clear carry for completed
ret
dsma90: stc ; set carry for interrupted
dsma99: ret
dspmain endp
;*******************************
; dspis : display initial screen
; and initial parameter
;
; in : idata= initial data
; islin = calculated lines
; es = VRAM selector
; call: dspfp,putdec,calc
; use: eax,ecx,edx,esi,edi,ebx,ebp
; count1
;
dspis proc
;-------------------------------
; initialize parameter & display
;-------------------------------
mov posx,IPOSX ; initial position x
mov posy,IPOSY ; initial position y
mov reso,IRESO ; initial resolution
call dspfp ; display frame parameter
mov ax,ILIMIT ; initial limit
mov limit,ax ; set limit
mov edi,LLIMIT ; display limit
call putdec
mov curstat,DS$FULL ; display complete
mov step,0
;-------------------------------
; display calculated data
;-------------------------------
mov esi,offset idata ; calculated data address
mov ebp,(SCRY+SCRH/2-1)*VRAMW+SCRX ; upper line VRAM address
mov ebx,(SCRY+SCRH/2)*VRAMW+SCRX ; lower line VRAM address
mov dx,islin ; set line counter
test dx,dx
jz dsis40
dsis20: mov edi,ebp ; upper line VRAM address
mov ecx,SCRW/4 ; set screen width counter
rep movsd ; write upper line
sub esi,SCRW ; rewind data line address
mov edi,ebx ; lower line VRAM address
mov ecx,SCRW/4 ; set screen width counter
rep movsd ; write lower line
sub ebp,VRAMW ; new upper line start address
add ebx,VRAMW ; new lower line start address
dec dx
jne dsis20
;-------------------------------
; calculate & display rest lines
; in : ebp = upper line VRAM address
; ebx = lower line VRAM address
; esi = data saving address
;-------------------------------
dsis40: movzx eax,islin ; calculated lines
cmp ax,SCRH/2
jae dsis90 ; needless
;
add eax,SCRH/2 ; start y pixcel
imul eax,RESO ; start y offset position
add eax,IPOSY ; start y position
mov curb,eax ; set start y position
mov edi,ebp ; upper line VRAM address
dsis50: mov count2,SCRW ; set screen width counter
mov cura,IPOSX ; set position x
dsis52: push esi
push ebx
push edi
call calc ; calculate repeat number
pop edi ; upper pixcel VRAM address
pop ebx ; lower pixcel VRAM address
pop esi ; data saving address
stosb ; write upper pixcel
mov es:[ebx],al ; write lower pixcel
mov [esi],al ; save data
inc ebx ; next lower pixcel address
inc esi ; next saving address
add cura,IRESO ; next x position
dec count2 ; line end ?
jnz dsis52
sub edi,VRAMW+SCRW ; next upper line start address
add ebx,VRAMW-SCRW ; next lower line start address
add curb,IRESO ; next y positon
inc islin ; line count up
cmp islin,SCRH/2 ; check line end
jb dsis50
;
dsis90: ret
dspis endp
;*******************************
; dsp8s : display by 8 step
; don't permit interrupt
;
; call: calc
; use: eax,ebx,ecx,edx,esi,edi
;
dsp8s proc
mov edi,SCRADR
mov count1,SCRH/8 ; set screen hight counter
mov eax,posy ; set y position
mov curb,eax
ds8s10: mov count2,SCRW/8 ; set screen width counter
mov eax,posx ; set x position
mov cura,eax
ds8s12: push edi
call calc ; calculate repeat number
pop edi
ds8s20: sub ax,USRCN ; adjust color code
ja ds8s20
add ax,USRCN
mov ah,al
mov dx,ax
shl eax,16
mov ax,dx
mov ecx,8
ds8s30: mov es:[edi],eax ; write VRAM
mov es:[edi+4],eax ; write VRAM
add edi,VRAMW
loop ds8s30
sub edi,VRAMW*8-8 ; next block VRAM address
mov eax,reso ; resolution
shl eax,3 ; 8 step
add cura,eax ; new current real part
dec count2 ; line end ?
jnz ds8s12
add edi,VRAMW*8-SCRW ; new line start address
mov eax,reso ; resolution
shl eax,3 ; 8 step
add curb,eax ; new current imaginary part
dec count1 ; exist rest lines ?
jnz ds8s10
ret
dsp8s endp
;*******************************
; dsp3q : display 3/4
; check B button per lines
;
; in : step = display step(1,2,4,8)
; out: cf = set by interruption
; call: getpad,calc
; use: eax,ebx,ecx,edx,esi,edi
;
dsp3q proc
;-------------------------------
; initialize
;-------------------------------
mov esi,SCRADR ; VRAM start address
movzx ebx,step ; display step
imul eax,ebx,VRAMW ; block line step
sub eax,SCRW ; for rewind
mov bstep,eax ; save block line VRAM step
;
mov ax,SCRW ; display screen width
cwd ; extend DX:AX
div bx ; block number in horizon
mov hbnum,ax ; save horizon block number
mov ax,SCRH ; screen pixcel hight
cwd ; extend DX:AX
div bx ; block number of vertical
mov count1,ax ; set block hight counter
;
mov eax,posy ; set start y position
mov curb,eax
imul ebx,reso ; position step
mov pstep,ebx ; save position step
;-------------------------------
; start display a block line
;-------------------------------
ds3q10: call getpad ; get pad state
test ah,P$TRIG2 ; press B button ?
jnz ds3q95 ; interruption
;
mov eax,posx ; set block line x position
mov cura,eax
mov ax,hbnum ; horizon block number
mov count2,ax ; set block counter of 1 line
;-------------------------------
; calculate repeat number
;-------------------------------
ds3q20: bt count1,0
jc ds3q22 ; odd line block
bt count2,0
jc ds3q22 ; odd column block
;
movzx ebx,step ; display step
jmp short ds3q50 ; skip to next block
;
ds3q22: push esi
call calc ; calculate repeat number
pop esi
;-------------------------------
; genarate color code
; in : ax = repeat number
;-------------------------------
ds3q30: sub ax,USRCN ; adjust color code
ja ds3q30
add ax,USRCN ; AL is effective
;-------------------------------
; display 1 block
; in : al = color code
; esi = block VRAM address
;-------------------------------
mov edi,esi ; set block VRAM address
movzx ebx,step ; display step
mov dx,bx ; set block line counter
ds3q40: mov ecx,ebx ; set block width counter
rep stosb ; write VRAM by 1 block line
sub edi,ebx ; rewind VRAM address
add edi,VRAMW ; next block line VRAM address
dec dx
jnz ds3q40
;-------------------------------
; move on right block
; in : ebx = display step
; esi = block VRAM address
;-------------------------------
ds3q50: add esi,ebx ; next block VRAM address
mov eax,pstep ; position step
add cura,eax ; next x position
dec count2 ; check block end of 1 line
jnz ds3q20 ; go tn right block
;-------------------------------
; move on down block line
; in : ebx = display step
; eax = position step
;-------------------------------
add esi,bstep ; next block line VRAM base address
add curb,eax ; next y position
dec count1 ; check block line end
jnz ds3q10 ; go to next block line
;-------------------------------
; ending procedure
;-------------------------------
clc ; clear carry for completion end
ret
ds3q95: stc ; set carry for intteruption end
ret
dsp3q endp
;*******************************
; dspadd : display additive
; calculate only C$NULL pixcel
; check A,B button per pixcel
;
; out: cf = set by interruption
; ax = button state
; call: getpad,calc
; use: eax,ebx,ecx,edx,esi,edi,ebp
;
dspadd proc
mov edi,SCRADR
mov eax,posy ; set y position
mov curb,eax
mov count1,SCRH ; set screen hight counter
dsad10: mov eax,posx ; set x position
mov cura,eax
mov count2,SCRW ; set screen width counter
dsad20: cmp byte ptr es:[edi],0 ; check VRAM state
jne dsad28 ; skip to next pixcel
call getpad ; get pad state
test ah,ah ; press A or B button ?
jnz dsad95 ; interruption
push edi
call calc ; calculate repeat number
pop edi
dsad22: sub ax,USRCN ; adjust color code
ja dsad22
add ax,USRCN
mov es:[edi],al ; write VRAM
dsad28: inc edi ; next VRAM position
mov eax,reso ; resolution
add cura,eax ; next x position
dec count2
jnz dsad20
add edi,VRAMW-SCRW ; new line start address
mov eax,reso ; resolution
add curb,eax ; next y position
dec count1
jne dsad10
;
clc ; clear carry for completion end
ret
dsad95: stc ; set carry for intteruption end
ret
dspadd endp
;*******************************
; dspbl : dsplay block line
;
; in : edi = block start VRAM address
; ebx = display step
; curb = start y position
; reso = resolution
; call: dspbk
; use: eax,ecx,edx,esi,edi,ebx,ebp
; count1,count2,pstep,cura
;
dspbl proc
mov esi,edi ; VRAM address
mov count2,bx ; save display step
mov ax,SCRW ; display screen width
cwd ; extend DX:AX
div bx ; block number in horizon
mov count1,ax ; set block counter of 1 line
imul ebx,reso
mov pstep,ebx ; save position step
mov eax,posx ; set block line x position
mov cura,eax
;-------------------------------
; display block
; in : esi = block VRAM address
;-------------------------------
dsbl10: call dspbk ; display block
;-------------------------------
; move on right block
; in : ebx = display step
; esi = block VRAM address
;-------------------------------
add esi,ebx ; next block VRAM address
mov eax,pstep ; position step
add cura,eax ; next x position
dec count1 ; check block end of 1 line
jnz dsbl10 ; go to right block
ret
dspbl endp
;*******************************
; dspbc : dsplay block column
;
; in : edi = block start VRAM address
; ebx = display step
; cura = start x position
; reso = resolution
; call: dspbk
; use: eax,ecx,edx,esi,edi,ebx,ebp
; count1,count2,pstep,curb
;
dspbc proc
mov esi,edi ; VRAM address
mov count2,bx ; save display step
mov ax,SCRH ; display screen hight
cwd ; extend DX:AX
div bx ; block number in vertical
mov count1,ax ; set block counter of 1 column
mov eax,posy ; set block line y position
mov curb,eax
imul ebx,reso
mov pstep,ebx ; save position step
;-------------------------------
; display block
; in : esi = block VRAM address
;-------------------------------
dsbc10: call dspbk ; display block
;-------------------------------
; move on down block
; in : ebx = display step
; edi = next block VRAM address
;-------------------------------
mov esi,edi ; next block VRAM address
mov eax,pstep ; position step
add curb,eax ; next y position
dec count1 ; check block end of 1 column
jnz dsbc10 ; go to down block
ret
dspbc endp
;*******************************
; dspbk : dsplay block
;
; in : esi = block VRAM address
; count2 = display step
; out: ebx = display step
; esi = block VRAM address
; edi = down block VRAM address
; use: eax,ecx,edx,esi,edi,ebx,ebp
;
dspbk proc
;-------------------------------
; calculate repeat number
;-------------------------------
push esi
call calc ; calculate repeat number
pop esi
;-------------------------------
; genarate color code
; in : ax = repeat number
;-------------------------------
dsbk20: sub ax,USRCN ; adjust color code
ja dsbk20
add ax,USRCN ; AL is effective
;-------------------------------
; display block
; in : al = color code
; esi = block VRAM address
;-------------------------------
mov edi,esi ; set block VRAM address
movzx ebx,count2 ; display step
mov dx,bx ; set block line counter
dsbk50: mov ecx,ebx ; set block width counter
rep stosb ; write VRAM by 1 block line
sub edi,ebx ; rewind VRAM address
add edi,VRAMW ; next block line VRAM address
dec dx
jnz dsbk50
ret
dspbk endp
;*******************************
; calc : calculate repeat number
;
; in : cura = real part
; curb = imaginary part
; limit = upper limit of number
; out: ax = repeat number
; use: ecx,edx,esi,edi,ebx,ebp
;
calc proc
movzx ecx,limit ; upper limit of number
mov ebx,cura ; real part
mov ebp,curb ; imaginary part
mov esi,ebx ; current x
mov edi,ebp ; current y
;
calc10: mov eax,esi ; current x
imul eax ; x^2
shrd eax,edx,24 ; adjust fixed point
xchg eax,esi ; esi=x^2, eax=x
imul edi ; x*y
shrd eax,edx,23 ; adjust fixed point and 2 times
add eax,ebp ; new y = 2xy+b
xchg edi,eax ; save new y and load old y
imul eax ; y^2
shrd eax,edx,24 ; adjust fixed point
mov edx,esi ; x^2
add edx,eax ; x^2+y^2
jz calc80 ; mandelbrot set or round error
cmp edx,4 shl 24 ; if not |z|<2 then
jae calc90 ; goto end
sub esi,eax ; x^2-y^2
add esi,ebx ; new x
loop calc10
;
calc80: xor ax,ax ; over => 0
ret
calc90: mov ax,limit
sub ax,cx ; repeat number
ret
calc endp
;*******************************
; calup : calculate up method
; interrupt by A,B button
;
; in : es = VRAM selector
; posx = position x
; posy = position y
; reso = resolution
; out: cf = set by quit end
; ax = pad state
; hbnum = next limit number
; call: boxdwn,putdec,getpad
; use: all
;
calup proc
;-------------------------------
; initialize buffer & screen
;-------------------------------
mov edi,buffer ; calculate buffer address
mov ebx,posy ; base position y
mov edx,reso ; resolution
mov ebp,SCRH ; set screen hight counter
clup10: mov eax,posx ; set base position x
mov ecx,SCRW ; set screen width counter
clup12: mov [edi],eax ; save position x
mov [edi+4],ebx ; save position y
add edi,8 ; next address
add eax,edx ; next position x
loop clup12
add ebx,edx ; next position y
dec ebp
jnz clup10
;
mov esi,offset scrbox ; screen box pointer
mov al,C$NULL ; with NULL color
call boxdwn ; clear box
;-------------------------------
; preparation for 1 number start
;-------------------------------
mov hbnum,0 ; initiarize repeat number
clup20: mov ax,hbnum ; current number
mov edi,LAUP ; display position
push esi
call putdec
pop esi
;
mov esi,buffer ; calculate buffer address
mov edi,reso ; set resolution
mov ebp,posy ; start position y
mov count1,SCRW ; set higth counter
clup30: mov ebx,posx ; start position x
mov count2,SCRW ; set width counter
clup40: cmp dword ptr [esi],0 ; check completed
jne clup50
cmp dword ptr [esi+4],0
je clup70 ; skip
;-------------------------------
; calculate 1 limit step
; in : ebx = a
; ebp = b
; esi = x,y data pointer
;-------------------------------
clup50: mov eax,[esi] ; current x
imul eax ; x^2
shrd eax,edx,24 ; adjust fixed point
mov ecx,eax ; save x^2
;
mov eax,[esi+4] ; current y
imul dword ptr [esi] ; x*y
shrd eax,edx,23 ; adjust fixed point and 2 times
add eax,ebp ; 2x*y+b
;
xchg [esi+4],eax ; load eax=y and save new y=2x*y+b
imul eax ; y^2
shrd eax,edx,24 ; adjust fixed point
;
mov edx,ecx ; x^2
add edx,eax ; x^2+y^2
jz clup84 ; mandelbrot element
cmp edx,4 shl 24 ; if not |z|<2 then
jae clup80 ; goto dispaly pixcel
;
sub ecx,eax ; x^2-y^2
add ecx,ebx ; x^2-y^2+a
mov [esi],ecx ; save new x
;-------------------------------
; repeat end check
;-------------------------------
clup70: add esi,8 ; next (x,y) data pointer
add ebx,edi ; left pixcel position a
dec count2 ; width counter down
jnz clup40 ; go to left pixcel
add ebp,edi ; next line position b
dec count1 ; hight counter down
jnz clup30 ; go to next line
;
inc hbnum ; repeat number up
jz clup90 ; limit over
call getpad ; get pad state
test ah,ah ; press A or B button ?
jz clup20 ; no go to next repeat number
;-------------------------------
; ending
;-------------------------------
stc ; quit end
clup90: mov curstat,DS$FULL ; display completion
mov step,0
ret
;-------------------------------
; display pixcel
; in : edi = VRAM address
;-------------------------------
clup80: mov cx,hbnum ; repeat number
clup82: sub cx,USRCN ; adjust color code
ja clup82
add cx,USRCN
mov ax,SCRY+SCRH
sub ax,count1
cwde
imul eax,VRAMW
add eax,SCRX+SCRW
movzx edx,count2
sub eax,edx
mov es:[eax],cl ; write VRAM
clup84: mov dword ptr [esi],0 ; set complete flag
mov dword ptr [esi+4],0
jmp clup70
calup endp
;*******************************
; putdec : put decimal number
; within 5 column
;
; in : ax = binary
; edi = display VAM base address
; numwid = display width of number
; call: bn2dec,dspank
; use: ax,ecx,dx,ebx,esi,edi
; work1
;
putdec proc
mov ebx,offset work1+2
movzx ecx,numwid ; display width
mov [ebx-2],cx
call bn2dec
mov esi,offset work1 ; string data address
call dspank
ret
putdec endp
;*******************************
; putfp : put fixed point
; within 10 column
;
; in : eax = fixed point
; edi = base VRAM address
; call: bn4dec,dspank
; use: all
; work1
;
putfp proc
mov ebx,offset work1 ; destination address
call bn4dec ; convert to decimal
mov esi,offset work1 ; string data address
movzx ecx,word ptr [esi] ; effective lenght
mov al,20h ; SPAC
putfp1: mov [esi+ecx+2],al
inc ecx
cmp ecx,10
jb putfp1
mov word ptr [esi],10
call dspank ; display ANK strings
ret
putfp endp
;*******************************
; bn2dec : 2 binary to decimal
;
; in : ax = unsigned binary
; ecx = column width
; ebx = destination address
; use: ax,ecx,dx
;
bn2dec proc
push si
mov si,10
bn2de1: xor dx,dx
div si
add dl,'0'
mov [ebx+ecx-1],dl ; save digit
test ax,ax ; check end
loopnz bn2de1
;
bn2de4: jcxz bn2de9
mov byte ptr [ebx+ecx-1],20h ; sapce padding
dec ecx
jmp bn2de4
bn2de9: pop si
ret
bn2dec endp
;*******************************
; bn4dec : signed 4 byte fixed
; point binary to decimal
;
; in : eax = binary
; ebx = destination address
; cs = ds
; out: ebx = fixed decimal
; 0(2) byte length n+3
; 2(1) sign ('-' or ' ')
; 3(1) integer part
; 4(1) decimal point
; 5(n) decimal part
; use: eax,ecx,edx,ebx
;
bn4de0 dd 10000000
dd 1000000
dd 100000
dd 10000
dd 1000
dd 100
dd 10
dd 1
;
bn4dec proc
push esi
push ebx
add ebx,2 ; skip length area
mov byte ptr [ebx],' '
test eax,eax
jns bn4de1
mov byte ptr [ebx],'-'
neg eax
bn4de1: inc ebx
;
mov esi,offset bn4de0
mul dword ptr [esi] ; significant figure
shrd eax,edx,24
adc eax,0 ; round
;
xor edx,edx ; integer part
div dword ptr [esi]
add al,'0'
mov ah,'.'
mov [ebx],ax
add esi,4
add ebx,2
mov eax,edx
;
mov ecx,7
bn4de2: xor edx,edx ; extend dividend EDX:EAX
div dword ptr [esi]
add al,'0'
mov [ebx],al ; save quotient
add esi,4 ; next divisor address
inc ebx ; next save address
mov eax,edx ; set new dividend
test eax,eax
loopnz bn4de2
;
pop eax ; destination address
sub ebx,eax
sub bx,2
mov [eax],bx ; save length
pop esi
ret
bn4dec endp
;*******************************
; setdp : set display pallets
; 0 to USRCN
;
; in : palbuf = pallet data buffer
; call: waitv,setpal
; use: all & work1
;
setdp proc
mov edi,offset palbuf ; pallet data buffer
mov esi,offset work1 ; pallet packet
mov byte ptr [esi],0 ; initialize pallet number
mov bx,PALSBN ; set pallet block counter
mov ecx,PALSBR ; set rest pallet number
setdp1: call waitv ; wait VSYNC
setdp2: mov eax,[edi] ; level data + 1
mov [esi+1],eax ; set level data
call setpal ; set pallet code
add edi,3 ; next pallet address
inc byte ptr [esi] ; next pallet number
loop setdp2
mov ecx,PALSBS ; set pallet block size
dec bx
jnz setdp1
ret
setdp endp
;*******************************
; setpal : set pallet data
;
; in : (ds:esi) = data address
; use: dx
;
setpal proc
push esi
mov dx,0FD90h ; pallet code
outsb
mov dx,0FD92h ; blue pallet data
outsb
mov dx,0FD94h ; red pallet data
outsb
mov dx,0FD96h ; green pallet data
outsb
pop esi
ret
setpal endp
;*******************************
; dspank : display ank
; string color is C$DARK
; backgraund is C$PANEL
;
; in : esi = string address
; edi = base VRAM address
; 0(2) byte size (n)
; 2(n) byte string
; es = VRAM selector
; use: none
;
dspank proc
push fs
push ebp
push esi
push edi
push edx
push ecx
push ebx
push eax
;
lfs ebx,pword ptr ss:[ankfnt]
lodsw
movzx ecx,ax ; length counter
dpank1: lodsb ; ANK code
call dpankA ; character display
add edi,8 ; next character address
loop dpank1
;
pop eax
pop ebx
pop ecx
pop edx
pop edi
pop esi
pop ebp
pop fs
ret
;------------------------------
; in : al = ANK code
; fs:ebx = font ROM address
; es:edi = base VRAM address
; use: ax
;
dpankA proc
push edi
push ecx
xor ah,ah
shl ax,4
add ax,15
movzx ebp,ax ; destination base offset
mov dx,16 ; hight counter
dpakA1: mov ah,fs:[ebx+ebp]
mov ecx,8
dpakA2: mov al,C$DARK ; number color
shl ah,1
jc dpakA3
mov al,C$PANEL ; backgraund color fixed
dpakA3: stosb
loop dpakA2
dec ebp
sub edi,VRAMW+8
dec dx
jnz dpakA1
pop ecx
pop edi
ret
dpankA endp
dspank endp
;*******************************
; getstr : get string from keybord
; with echo
; only 0-9,A-Z
; control code BS,CR,ESC
;
; in : (ds:esi) = string address
; 0(2) position x
; 2(2) position y
; cx = maximum string length
; es = VRAM selector
; fs = TOWNS BIOS selector
; out: (ds:esi)
; 4(2) inputed string length
; call: waitp,getpad
; use: eax,ebx,ecx,edx
;
getstr proc
push edi
;-------------------------------
; initialize
;-------------------------------
mov ax,0600h ; clear keybord buffer
int 90h
xor ax,ax ; wait no press state
push cx
call waitp
pop cx
mov word ptr [esi+4],0 ; clear counter
;-------------------------------
; get key or button & analyze it
;-------------------------------
gtst10: mov ax,0901h ; read charactor without waiting
int 90h
test ah,ah ; go well ?
jnz gtst12 ; read error
cmp dh,0FFh ; exist input charactor ?
jne gtst14 ; go to analyze
;
gtst12: call getpad ; get pad state
test ah,P$TRIG1 ; A button
jnz gtst99 ; input end
test ah,P$TRIG2 ; B button
jnz gtst90 ; quit
jmp gtst10
;
gtst14: cmp dl,1BH ; ESC
je gtst90 ; quit
cmp dl,0Dh
je gtst99 ; input end
cmp dl,08h ; CTRL+H
je gtst40 ; back space
cmp dl,'0'
jb gtst10 ; invalid
cmp dl,'9'
jbe gtst22 ; number
cmp dl,'A'
jb gtst10 ; invalid
cmp dl,'Z'
jbe gtst22 ; capital
cmp dl,'a'
jb gtst10 ; invalid
cmp dl,'z'
ja gtst10 ; invalid
;-------------------------------
; save and display
; in : esi = string address
; cx = maximum length
;-------------------------------
gtst20: add dl,'A'-'a' ; capitalize
gtst22: movzx eax,word ptr [esi+4] ; current length
cmp ax,cx ; check max length
jae gtst10 ; invalid
inc ax ; renew length
mov [esi+4],ax
mov byte ptr [esi+eax+5],dl ; save charactor
mov edi,offset egbwork
mov ax,6001h ; display ASCII string
call pword ptr fs:[20h]
jmp gtst10
;-------------------------------
; back space
; in : esi = string address
;-------------------------------
gtst40: movzx eax,word ptr [esi+4]
test ax,ax
jz gtst10 ; invalid
dec ax
mov [esi+4],ax
;
push ecx
shl ax,3 ; string pixcel width
add ax,[esi] ; clear start x position
movzx edi,ax
movzx eax,word ptr [esi+2]
imul eax,VRAMW
add edi,eax ; clear start address
mov ecx,16
mov eax,C$PANEL+(C$PANEL shl 8)+(C$PANEL shl 16)+(C$PANEL shl 24)
gtst42: mov es:[edi],eax
mov es:[edi+4],eax
sub edi,VRAMW
loop gtst42
pop ecx
jmp gtst10
;-------------------------------
; input end
;-------------------------------
gtst90: mov word ptr [esi+4],0 ; cancel string
gtst99: pop edi
ret
getstr endp
code ends
stack segment stack use32 rw
pathbuf db 80h dup(?) ; for pathlist
idata db SCRW*SCRH/2 dup(?) ; for initial screen data
ankfnt dd ? ; ANK font offset
dw ? ; ANK font selector
palbuf db (USRCN+1)*3 dup(?) ; pallet data buffer
db ? ; dummy
palbak db (USRCN+1)*3 dup(?) ; pallet data backup buffer
db ? ; dummy
work1 db 80 dup(?) ; public work 1
egbwork db EGBSIZ dup(?) ; EGB work area
db 256*256 dup(?) ; stack for EGB
db 6*1024 dup (?) ; stack area
stack ends
end entry