| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600 |
- ;*** TURBO PASCAL version 3.01 A source code
- ;***
- ;*** commented by Pascal Dornier
- ;*** all rights reserved
- ;"***
- cseg $100 ;"COM file...
- ;
- ;I/O port equates
- ;
- timerfrq = $0042 ;timer: frequency
- timercmd = $0043 ;timer: command
- timerflg = $0061 ;"PPI: sound enable
- ;
- ;interrupt numbers
- ;
- bioscrt = $0010 ;BIOS: CRT driver
- bioskbd = $0016 ;BIOS: KBD driver
- msdos = $0021 ;"MS-DOS entry
- ;
- ;variable definitions
- ;
- attnrm = $0000 ;attribute NormVideo
- attlow = $0001 ;attribute LowVideo
- att2 = $0002 ;attribute #2 (used by editor)
- att3 = $0003 ;attribute #3
- txwinx1 = $0004 ;upper left edge current window
- txwiny1 = $0005
- scrmod = $0006 ;video mode
- coltxt = $0007 ;color or text ?
- attcur = $0008 ;current attribute
- grmod = $0009 ;graphics mode
- grwinx1 = $000A ;graphics window: upper left edge
- grwinx2 = $000C
- grwiny1 = $000E ; bottom right edge
- grwiny2 = $0010
- delaycnt = $0012 ;number of loop's for 1 ms
- collin = $0014 ;line color
- lnxdir = $0016 ;X direction
- lnydir = $0018 ;Y direction
- lnxpos = $001A ;X position
- lnypos = $001C ;Y position
- lndda = $001E ;DDA register
- grback = $0020 ;"graphics: background color
- ;heap pointer
- hpstrt = $0022 ;beginning of heap
- hpstrt1 = $0024
- hpdstpt = $0026 ;^ destination pointer
- hpdstpt1 = $0028
- hpesize = $002A ;size of entry to delete
- hpesize1 = $002C
- hplast = $002E ;^ previous entry
- hplast1 = $0030
- hpmerg = $0032 ;length of entry to be merged
- hpmerg1 = $0034 ;"with next entry
- coninbuf = $0036 ;CON input buffer
- pnbuf0 = $00B5
- pnbuf = $00B6 ;buffer for filename etc.
- pnbuf1 = $00B7
- pnbuf2 = $00B8
- pnbuf3 = $00B9
- pndiratt = $00CB ;for Dir: file attribute
- pndirnm = $00D4 ;name of file
- pndirpad = $00E4 ;^ end for formatting
- pnbufend = $0135 ;"end of buffer
- ;I/O vectors
- vkbdstat = $0136 ;KBD stat (ConStPtr)
- vkbdget = $0138 ;KBD get (ConInPtr)
- vconput = $013A ;CON put (ConOutPtr)
- vprnput = $013C ;PRN put (LstOutPtr)
- vauxput = $013E ;AUX put (AuxOutPtr)
- vauxget = $0140 ;AUX get (AuxInPtr)
- vusrput = $0142 ;USR put (UsrOutPtr)
- vusrget = $0144 ;"USR get (UsrInPtr)
- ;file entries for std files
- filcon = $0146 ;CON, TRM
- filkbd = $014A ;KBD
- fillst = $014E ;LST
- filaux = $0152 ;AUX
- filusr = $0156 ;USR
- stdin = $015A ;MS-DOS input file
- stdinfl = $015C ;flag
- stdinof = $015E ;^ buffer
- stdinsz = $0160 ;buffer size
- stdout = $0166 ;MS-DOS output file
- stdoutfl = $0168 ;flag
- stdoutof = $016A ;^ buffer
- stdoutsz = $016C ;"buffer size
- modeflg = $0172 ;option flag - see initmem
- spval = $0174 ;SP on initialisation
- turbocs = $0176 ;CS for return to Turbo
- turbods = $0178 ;DS for return to Turbo
- filtabpt = $017A ;^ into list of open files
- filemax = $017C ;max number of open files
- verror = $017E ;ErrorPtr
- errnum = $0180 ;error number
- conbufln = $0181 ;BufLen (for ReadLn)
- conbufpt = $0182 ;^ into input buffer
- conbfend = $0184 ;end of input buffer
- errpos = $0186 ;return address ->
- errpos2 = $0188 ;position of error
- hptop = $018A ;HeapPtr: ^ end of heap
- hptop1 = $018C
- svintv = $018E ;buffer for vector:
- svintv1 = $0190 ;DIV/0 interrupt
- lastkey = $0192 ;code of last key pressed
- cbreak = $0194 ;CBreak
- ovrpnbuf = $0196 ;"buffer for overlay filename
- fmtfield = $01E6 ;formatting: field size
- fmttype = $01E7 ;type of conversion
- fmtsdst = $01E8 ;^ dest string (STR)
- fmtsdst1 = $01EA
- fmtvdst = $01EC ;^ dest var (VAL)
- fmtvdst1 = $01EE
- fmtpdst = $01F0 ;^ error var (VAL)
- fmtpdst1 = $01F2
- recvbuf = $01F4 ;"real buffer: number to convert
- errio = $01FA ;flag: return because of error
- rndseed = $01FC ;random seed: last random number
- rndseed1 = $01FE
- strdstln = $0200 ;string operations: max. length of result
- strpos = $0202 ;Pos
- strnum = $0204 ;Num
- strtrgt = $0206 ;^ dest string
- strtrgt1 = $0208
- strobj = $020A ;^ object string
- strobj1 = $020C ;"
- remul11 = $020E ;real arithmetics
- remul11a = $020F ;first number * /
- remul12 = $0210
- remul13 = $0212
- remul21b = $0213
- remul21 = $0214 ;second number * /
- remul21a = $0215
- remul22 = $0216
- remul23 = $0218
- retrc1 = $021A ;number for Sqrt, ArcTan, polynomials
- retrc2 = $021C
- retrc3 = $021E
- resign = $0220 ;sign for + -
- resave = $0221
- remant = $0222 ;mantissa + -
- remant1 = $0223 ;"
- cvdecexp = $0224 ;real -> ASCII: decimal exponent
- cvexpcnt = $0225 ;ASCII -> real: counter for exponent
- cvoutbuf = $0226 ;output buffer for result
- currfil = $0232 ;^ current file var
- currfil1 = $0234
- filfunc = $0238 ;function code file operation
- filerr = $0239 ;error code, if failure
- prnum = $023A ;real: number to print
- filetab = $0240 ;"table of open files (file handles)
- ;kernel variables
- freemem = $0260 ;free memory (paragraphs)
- stackseg = $0262 ;stack segment on start
- stackpt = $0264 ;stack pointer
- destseg = $0266 ;segment of compiled program
- codesize = $0268 ;code size (paragraphs)
- datasize = $026A ;data size (paragraphs)
- minstksz = $026C ;min size stack + heap
- mincssz = $026E ;min size CS
- mindssz = $0270 ;min size DS
- minhpsz = $0272 ;min size free heap
- maxhpsz = $0274 ;max size free heap
- txbeg = $0276 ;^ beginning of text
- txend = $0278 ;^ end of text
- txmemend = $027A ;^ end of text memory
- txerrpos = $027C ;^ error in text
- vfilbig = $027E ;vector: file too big
- vnewfil = $0280 ;vector: file not found
- txcomp = $0282 ;0 = text not translated
- cpmode = $0283 ;(0 memory, 1 find error, 2 COM, 3 CHN)
- cperr = $0284 ;compiler's error number
- txchg = $0285 ;0 = text not changed
- defdrv = $0286 ;number of default drive
- scrpn = $0287 ;buffer for filename processing
- scrpnend = $02C6 ;end of buffer
- workpn = $02C7 ;filename work file
- mainpn = $0307 ;filename main file
- mainflg = $0347 ;0 = work file used
- msgflg = $0348 ;0 = error messages not read
- codedest = $0349 ;(1 = memory, 2 = COM, 3 = CHN)
- parmlin = $034A ;buffer: input line for program
- knumbuf = $0386 ;number output buffer
- curatt = $038E ;"number current video attribute
- ;editor variables
- srend = $0390 ;^ block end for search
- srbeg = $0392 ;^ block beg for search
- bkbeg = $0394 ;^ block beg
- bkend = $0396 ;^ block end
- lnupper = $0398 ;^ line above
- disbeg = $039A ;^ beginning of text displayed
- oldpos = $039C ;old position
- eolpos = $039E ;^ end of line
- srpos = $03A0 ;current search pos
- srcnt = $03A2 ;search counter
- horscr = $03A4 ;horizontal scrolling
- attflg = $03A5 ;(1 = block beg, 2 = block end in curr line)
- phrow = $03A6 ;cursor position
- phcol = $03A7
- statobs = $03A8 ;0 = invalid status line
- edcol = $03A9 ;column
- attchg = $03AA ;FF = attribute changes in curr line
- sropt = $03AB ;options for search
- ; 1=entire words, 2=replace without query
- ; 4=upper = lower, 8=global
- ;10=backwards 20=L (?)
- srmode = $03AC ;0=search, FF=search and replace
- editflg = $03AD ;? never referenced !
- bkhide = $03AE ;FF = invisible block
- scrfl1 = $03AF ;FF = short redisplay
- statera = $03B0 ;# chars to delete in status line
- oldlen = $03B1 ;old length curr line
- dislin = $03B2 ;redisplay from line ...
- overflg = $03B3 ;0 = overwrite, FF = insert
- indntflg = $03B4 ;0 = normal, FF = indent
- disflg = $03B6 ;FF = don't display
- scrfl2 = $03B7 ;redisplay: 0 = small displacement
- bkbegl = $03BA ;^ block beg in curr line
- bkendl = $03BC ;^ block end in curr line
- edpos = $03BE ;^ current line
- lnpos = $03C0 ;pos in line buffer
- posfifo = $03C2 ;old position for ^QP
- pfifosrc = $03C5
- qppos = $03C6
- qppos1 = $03C8
- pfifodst = $03C9 ;(for block transfer)
- cmdbuf = $03CA ;buffer for command entry
- cmdbuf1 = $03CB
- srword = $03CE ;max length of search word
- srword1 = $03CF ;length
- srword2 = $03D0 ;string
- srrepl = $03EF ;replace word
- srrepl1 = $03F0
- srrepl2 = $03F1
- stopt = $0410 ;options for search / replace
- sropt1 = $0411
- fnbuf = $041D ;buffer for filename entry
- fnbuf2 = $041F
- fnbufend = $0460
- nbkbeg = $0461 ;block transfer destination
- nbk = $0463 ;block
- sepptr = $0465 ;^ word separator table
- explen = $0467 ;expected length
- curpast = $0469 ;1 = cursor past end of line
- line0 = $046B
- line = $046C ;buffer: current line
- lineend0 = $04E9
- lineend1 = $04EA
- lineend = $04EB
- dmabuf = $04EE ;buffer for redisplay
- scrseg = $0590 ;segment of video memory
- scrrow = $0592 ;video row
- scrbad = $0593 ;"FF = snowy screen
- ;compiler variables
- spsav = $0594 ;SP at start
- symtop = $0596 ;current end of symbol table
- symtop2 = $0598 ;end of symbol table
- ptcbeg = $059A ;^ beg symbol table, patch list
- tyfence = $059C ;limit for undefined pointer types
- fence = $059E ;limit for search on new definition
- pc = $05A0 ;PC of emitted code
- dc = $05A2 ;data offset of emitted code
- varspc = $05A4 ;space used on stack
- cdptr = $05A6 ;^ into code buffer
- cdbufpt = $05A8 ;PC of beg code buffer
- cdbegpt = $05AA ;^ code buffer
- cdfoff = $05AC ;buffer's offset in file
- cdprcoff = $05AD ;offset for overlay
- cdfoff1 = $05AE
- lincnt = $05B0 ;line counter
- cdinval = $05B2 ;<> 0: invalid code
- recnum = $05B3 ;number of current record
- reccnt = $05B4 ;record counter
- scalcnt = $05B5 ;enumeration type counter
- srcend = $05B6 ;<> 0: end of source reached
- lexnest = $05B7 ;lexical nesting
- flgpshax = $05B8 ;<> 0: save AX on stack
- flgpshes = $05B9 ;<> 0: save ES on stack
- flgpshdi = $05BA ;<> 0: save DI on stack
- usrint = $05BB ;<> 0: user interrupt used
- ovrcnt = $05BC ;overlay counter
- inclflg = $05BD ;FF = include file used
- cmaxfil = $05BF ;max number of open files
- cinpsize = $05C1 ;size of std input buffer
- coutsize = $05C3 ;size of std output buffer
- direct = $05C5 ;compiler directives:
- ; 1 = I/O check
- ; 2 = range check
- ; 4 = I/O mode (CON or TRM)
- ; 8 = value for CBreak
- ;10 = user interrupt
- ;20 = stack check
- ;40 = type check
- ;80 = device check
- destpn = $05C7 ;object filename
- destpne = $0603
- dstfile = $0607 ;object file handle
- ptctop = $0609 ;current end of patch list
- ptcend = $060B ;limit for patch list
- srcptr = $060D ;^ into text
- srclnbeg = $060F ;^ beg of source line
- chptr = $0611 ;^ into line buffer
- ;variable entry 1:
- indflg = $0615 ;<> 0: indexed var
- indptflg = $0616 ;<> 0: indirect via pointer
- varseg = $0617 ;segment (FF=DS, FE=CS, FD=ES, else:
- ;lexical nesting
- varofs = $0618 ;variable offset
- vartp = $061A ;type
- varctp = $061C ;element type
- varnest = $061D ;<>0: record #, FF: undef pointer
- lower = $061E ;lower bound or ^ index type
- upper = $0620 ;upper bound or ^ element type
- varsize = $0622 ;variable size
- parm1end = $0624
- parm2 = $0625 ;variable entry 2
- var2ctp = $062C ;type
- lower2 = $062E ;lower bound
- upper2 = $0630 ;upper bound
- var2size = $0632 ;size
- maxsize = $0634 ;max size for variant records
- uncrlink = $0636 ;link for uncrunch list
- flgvar = $0638 ;F = VAR parameter
- vrecflg = $0639 ;number of record variant
- procfnc = $063A ;procedure or function
- ovrproc = $063B ;<>0: overlay procedure
- absflg = $0647 ;FF = Absolute variable
- var3ofs = $0648 ;offset
- var3seg = $064A ;segment
- ovrlen = $064C ;max length of overlay procedures in a file
- creal1 = $064E ;buffer for real constant
- creal2 = $0650
- creal3 = $0652
- cresign = $0653
- stklev = $0654 ;stack use (WITH, FOR, display)
- casectp = $0655 ;CASE element type
- direcsv = $0656 ;directives at beg of statement
- brnchop = $0658 ;branch op on comparision
- rdlnflg = $0659 ;flag: Read / ReadLn
- forptr = $065A ;pointer for FOR: TO / DOWNTO
- withnest = $065C ;WITH nesting
- inlinflg = $065D ;inline flag
- withtab = $065E ;WITH table: record number, segment
- withtab1 = $0660 ;offset, FFFF = indexed
- functp = $069E ;^ result type
- comptp = $06A0 ;^ type for comparison
- oldpc = $06A2 ;PC before translation of this atom
- negflg = $06A4 ;negation flag
- exres = $06A6 ;integer constant
- cxbuf = $06A8 ;buffer for CX
- direcin = $06AA ;directives before include
- semiflg = $06AC ;flag for missing ; error
- wordflg = $06AD ;type of word read
- typept = $06AE ;^ type
- sympos = $06B0 ;^ into symbol table
- wrdend = $06B2 ;end of word read
- retbuf = $06B4 ;buffer for return address
- inclpn = $06B6 ;include filename
- incfile = $06F6 ;include file handle
- bufpt = $06F8 ;include pointer
- bufend = $06FA ;end of include buffer
- srclnbg = $06FC ;beg of line in buffer
- frelpos = $06FE ;relative position in file
- ptcbuf1 = $0700 ;buffer for patch
- wordbuf = $0702 ;buffer for word, filename, string...
- wrdbuf1 = $0703
- inclbuf = $0782 ;include buffer
- txstrt = $0802 ;"beg of text space / error messages
- JMP start ;"jump to main code
- B $90,$90,$CD,$AB
- B "Copyright (C) 1985 BORLAND Inc"
- B $02,$04,$00
- W ecmd1 ;ptrs for TINST.COM
- B $00
- W errpath
- B $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
- B $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
- B $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
- displstr B $14,"Default display mod"
- B $65
- txwinx2 B $50 ;lower edge of text window
- txwiny2 B $19
- B $01,$FF,$FF
- attmono B $0F,$07,$07,$70 ;monochrome attributes
- attbwgr B $0F,$07,$07,$70 ;mono graphic atts
- attcolgr B $0E,$07,$07,$4F ;"color graphic atts
- putstr CS: ;put attribute string
- MOV.B AH,[BX] ;length
- OR.B AH,AH
- STC
- JZ puts2 ;nothing to put
- putstrl INC BX ;next char
- CS:
- MOV.B AL,[BX] ;get it
- PUSH AX ;save cnt
- CALL conput ;put CRT
- POP AX
- DEC.B AH ;another one ?
- JNZ putstrl ;:yes
- CLC
- puts2 RET ;"
- meascnt W $0000
- measdone B $00
- vtimer W $0000 ;"space for timer int vector
- vtimer1 W $0000
- msspeed MOV delaycnt,#$006E ;measure CPU speed
- CS: ;measurement value
- MOV.B measdone,#$00 ;flag:not done
- MOV SI,#timvec ;ptr to timer INT
- ES:
- MOV AX,[SI]
- CS:
- MOV vtimer,AX ;save it
- ES:
- MOV AX,[SI]$02
- CS:
- MOV vtimer1,AX
- CLI
- ES:
- MOV [SI],#msint1
- ES:
- MOV [SI]$02,CS
- STI ;INT ok again
- JMP.b mssploop ;"measurement loop
- msint1 PUSH DS ;first INT entry
- PUSH AX
- XOR AX,AX
- MOV DS,AX
- MOV timvec,#msint2 ;set second vector
- CS:
- MOV meascnt,AX ;clear counter
- POP AX
- POP DS
- CS:
- JMPF [vtimer] ;"do timer routine
- msint2 CS: ;second INT entry
- MOV.B measdone,#$FF ;set flag:done
- CS:
- JMPF [vtimer] ;"do timer routine
- mssploop CALL delay1ms ;wait one step
- CS:
- INC meascnt ;count those steps
- CS:
- CMP.B measdone,#$FF ;done ?
- JNZ mssploop ;no, continue counting
- CS:
- MOV AX,vtimer1 ;restore timer INT vec
- CLI
- ES:
- MOV [SI]$02,AX
- CS:
- MOV AX,vtimer
- ES:
- MOV [SI],AX
- STI ;INT ok again
- CS:
- MOV AX,meascnt ;number of steps done
- ADD AX,AX ;*2
- MOV delaycnt,AX ;-> result
- RET ;"
- delaybx MOV AX,BX ;Delay(BX)
- xdelay MOV CX,AX ;DELAY(AX)
- JCXZ delay2 ;:no delay
- delay1 CALL delay1ms ;delay 1ms
- LOOP delay1
- delay2 RET ;"
- delay1ms PUSH CX ;Delay 1 ms
- MOV CX,delaycnt ;get count for 1ms
- delay3 LOOP delay3 ;do it
- POP CX ;restore cnt
- RET ;"
- xclrscr PUSH BP ;CLRSCR
- MOV AH,#$0F ;get screen stat
- INT bioscrt
- POP BP
- CMP.B AL,scrmod ;= current screen mode ?
- JZ clrscr1 ;:ok
- MOV AL,scrmod ;no: do set it
- JMP xtxtmode ;'
- clrscr1 PUSH BP
- MOV AX,#$0600 ;scroll window up, 0 lines
- MOV.B BH,attcur
- MOV CX,txwinx1 ;upper left edge
- CS:
- MOV DX,txwinx2 ;lower right edge
- DEC.B DH
- DEC.B DL
- INT bioscrt ;clear window
- MOV AH,#$02 ;set cursor position
- MOV DX,txwinx1 ;upper left edge
- XOR.B BH,BH
- INT bioscrt ;do it
- POP BP
- RET ;"
- xdelline PUSH BX ;DelLine
- PUSH CX
- PUSH DX
- PUSH BP
- CALL getcpos ;get cursor pos
- MOV AH,#$06 ;scroll window up
- doscroll MOV AL,#$01 ;one line
- MOV.B BH,attcur
- MOV.B CH,DH
- MOV.B CL,txwinx1 ;upper left edge
- CS:
- MOV DX,txwinx2 ;lower right of window
- DEC.B DH
- DEC.B DL
- CMP.B CH,DH ;same ?
- JNZ dellin1 ;:no
- XOR.B AL,AL ;no lines
- dellin1 INT bioscrt ;do it
- POP BP
- POP DX
- POP CX
- POP BX
- RET ;"
- xinsline PUSH BX ;InsLine
- insline2 PUSH CX
- PUSH DX
- PUSH BP
- CALL getcpos ;get cursor pos
- MOV AH,#$07 ;scroll window down
- JMP doscroll ;"as above
- xlowvid PUSH AX ;LowVideo
- MOV AL,attlow ;set low attribute
- MOV attcur,AL
- POP AX
- RET ;"
- xnormvid PUSH AX ;NormVideo, HighVideo
- MOV AL,attnrm ;set normal attribute
- MOV attcur,AL
- POP AX
- RET ;"
- getcpos MOV AH,#$03 ;get cursor position
- XOR.B BH,BH ;page 0
- INT bioscrt ;do it
- RET ;"
- xclreol PUSH BX ;ClrEol
- PUSH CX
- PUSH DX
- PUSH BP
- CALL getcpos ;get cursor pos
- MOV AX,#$0600 ;clear window
- MOV.B BH,attcur
- MOV CX,DX ;pos -> upper left
- CS:
- MOV.B DL,txwinx2 ;X-position
- DEC.B DL ;Y-pos from current pos
- INT bioscrt ;do it
- POP BP
- POP DX
- POP CX
- POP BX
- RET ;"
- xcrtinit CALL xnosound ;CrtInit
- CS: ;Screen mode
- MOV AL,scrmodch ;defined with TINST
- CMP AL,#$FF
- JNZ xtxtmode ;do change it
- PUSH BP
- MOV AH,#$0F ;get current screen mode
- INT bioscrt
- POP BP
- xtxtmode MOV.B txwinx1,#$00 ;TextMode
- MOV.B txwiny1,#$00 ;set window
- MOV.B grmod,#$FF ;no graphics mode
- CMP AL,#$07 ;monochrome ?
- MOV BH,#$50
- MOV BL,#$00
- MOV SI,#attmono ;ptr to screen attributes
- JZ txtmd3 ;:yes, mono
- MOV SI,#attcolgr
- CMP AL,#$02 ;BW80 ?
- JZ txtmd2 ;:yes
- CMP AL,#$04
- JB txtmd1 ;:C80, C40, BW40
- MOV AL,#$03
- txtmd1 MOV BL,#$FF
- CMP AL,#$03 ;C80 ?
- JZ txtmd3 ;:yes
- MOV BH,#$28
- CMP AL,#$01 ;C40 ?
- JZ txtmd3 ;:yes
- XOR.B AL,AL ;monochrome
- MOV BL,#$00
- txtmd2 MOV SI,#attbwgr
- txtmd3 MOV scrmod,AL ;set screen mode
- MOV.B coltxt,BL ;color or mono
- CS:
- MOV.B txwinx2,BH ;set screen size
- CS:
- MOV AX,[SI] ;get screen attributes
- MOV attnrm,AX
- CS:
- MOV AX,[SI]$02
- MOV att2,AX
- PUSH BP
- MOV AH,#$0F ;get screen status
- INT bioscrt
- CMP.B AL,scrmod ;correct mode ?
- JZ txtmd4 ;:yes
- MOV AL,scrmod
- XOR.B AH,AH ;set screen mode
- INT bioscrt
- txtmd4 POP BP
- JMP xnormvid ;"
- xcrtexit RET ;"CrtExit
- setcpos PUSH AX ;Set cursor position
- PUSH BX ;DL=row
- PUSH CX ;DH=col
- PUSH DX ;pos relative to curr window
- PUSH SI
- PUSH DI
- PUSH BP
- PUSHF
- XCHG.B DL,DH
- ADD DX,txwinx1 ;add window pos
- CS:
- CMP.B DH,txwiny2 ;over edge of screen ?
- JNB setcbad ;:yes
- CS:
- CMP.B DL,txwinx2
- JNB setcbad ;:yes
- MOV AH,#$02 ;set cursor
- XOR.B BH,BH ;page 0
- INT bioscrt
- setcbad POPF
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- RET ;"
- xupcase JMP upcase ;"UpCase
- xwherex CALL getcpos ;WhereX
- MOV.B AL,DL ;get cursor pos
- SUB.B AL,txwinx1 ;col-window col
- INC.B AL ;+1
- XOR.B AH,AH
- RET ;"
- xwherey CALL getcpos ;WhereY
- MOV.B AL,DH ;get cursor pos
- SUB.B AL,txwiny1 ;row-window row
- INC.B AL ;+1
- XOR.B AH,AH
- RET ;"
- xwindow POP BX ;Window
- CMP AL,#$19 ;Row 2 - limit to 25
- JA window1 ;:too much
- CS:
- MOV txwiny2,AL ;set it
- window1 POP AX ;Col 2
- CMP AL,#$50 ;limit to 80
- JA window2 ;:too much
- CS:
- MOV txwinx2,AL ;set it
- window2 POP AX ;Row 1
- CS:
- CMP.B AL,txwiny2 ;> row 2 ?
- JNB window3 ;: no good
- DEC.B AL
- MOV txwiny1,AL ;set it
- window3 POP AX ;Col 1
- CS:
- CMP.B AL,txwinx2 ;> col 2
- JNB window4 ;:no good
- DEC.B AL
- MOV txwinx1,AL ;set it
- window4 JMP BX ;"return
- xtxtcol AND AL,#$1F ;TextColor
- TEST AL,#$10 ;Blink ?
- JZ txtcol1 ;:no
- AND AL,#$0F
- OR AL,#$80 ;set blink flag
- txtcol1 AND.B attcur,#$70
- OR.B attcur,AL ;set new attribute
- RET ;"
- xtxtbg AND AL,#$07 ;TextBackground
- MOV CL,#$04
- SHL.B AL,CL
- AND.B attcur,#$8F
- OR.B attcur,AL ;set attribute
- RET ;"
- setgmod PUSH BP ;Set graphic mode
- MOV grwinx2,AX ;X-size
- MOV grwinx1,#$0000 ;clear window
- MOV grwiny1,#$0000
- MOV grwiny2,#$00C7 ;Y-size = 199
- MOV AL,grmod
- XOR.B AH,AH
- INT bioscrt ;set graph mode
- XOR BX,BX
- MOV.B grback,BL ;clear background
- MOV AH,#$0B ;set palette -> backgrnd
- INT bioscrt
- INC.B BH ;set foregrnd
- MOV AH,#$0B
- INT bioscrt ;set palette
- POP BP
- RET ;"
- xgrcolmd MOV.B grmod,#$04 ;GraphColorMode
- setgmod2 MOV AX,#$013F ;X-size = 319
- JMP setgmod ;'set it
- xgrmode MOV.B grmod,#$05 ;GraphMode
- JMP setgmod2 ;"set it
- xhires MOV.B grmod,#$06 ;Hires
- MOV AX,#$027F ;X-size = 639
- CALL setgmod ;set it
- MOV AX,#$000F ;set background
- JMP.b xhirscol ;"
- xgrbg AND AL,#$0F ;GraphBackground
- MOV.B AH,grback ;get old color
- AND.B AH,#$10
- OR.B AL,AH
- MOV grback,AL ;store it
- setbg PUSH BP ;set graph background
- XOR.B BH,BH
- MOV.B BL,grback
- MOV AH,#$0B ;set palette
- INT bioscrt ;do it
- POP BP
- RET ;"
- xpalette PUSH BP ;set palette AL
- MOV.B BL,grback ;get current color
- AND.B BL,#$EF ;clear palette
- MOV AH,#$02
- CMP.B grmod,#$04 ;color graphics ?
- JZ setpal1 ;yes
- MOV AH,#$01
- setpal1 CMP.B AL,AH
- JB setpal2
- SUB.B AL,AH ;upper bit: part of backgnd
- OR.B BL,#$10
- setpal2 MOV.B grback,BL ;set it
- MOV BH,#$01 ;set palette
- MOV.B BL,AL ;palette number
- MOV AH,#$0B
- INT bioscrt ;do it
- POP BP
- JMP setbg ;"set backgnd color
- xhirscol PUSH BP ;HiresColor
- MOV BX,AX ;as background
- MOV AH,#$0B ;set palette
- INT bioscrt ;do it
- POP BP
- RET ;"
- xgrwindw POP BX ;GraphWindow
- MOV CX,#$027F ;max. X = 639
- CMP.B grmod,#$06 ;Hires ?
- JZ gwind1 ;:yes
- MOV CX,#$013F ;max. X = 319
- gwind1 CMP AX,#$00C7 ;Y2 > 199
- JA gwind2 ;:no good
- MOV grwiny2,AX ;set Y2
- gwind2 POP AX ;X2
- CMP AX,CX ;> max X ?
- JA gwind3 ;:no good
- MOV grwinx2,AX ;set X2
- gwind3 POP AX ;Y1
- CMP AX,grwiny2 ;>= Y2 ?
- JNB gwind4 ;:no good
- MOV grwiny1,AX ;set Y1
- gwind4 POP AX ;X1
- CMP AX,grwinx2 ;>= X2 ?
- JNB gwind5 ;:no good
- MOV grwinx1,AX ;set X1
- gwind5 JMP BX ;"return
- xplot POP BX ;Plot
- POP DX ;Y-pos
- POP CX ;X-pos
- PUSH BX ;restore return addr
- MOV AH,#$0C ;set point, AL is color
- doplot OR CX,CX ;test X-pos (do clipping)
- JS noplot ;negative: clip it
- ADD CX,grwinx1 ;add window offset
- CMP CX,grwinx2 ;outside window ?
- JA noplot ;yes: clip it
- OR DX,DX ;test Y-pos
- JS noplot ;negative: clip it
- ADD DX,grwiny1 ;add window offset
- CMP DX,grwiny2 ;outside window ?
- JA noplot ;yes: clip it
- PUSH BP
- INT bioscrt ;do plot
- POP BP
- noplot RET ;"
- xdraw MOV AH,#$0C ;Line. AL is color
- MOV collin,AX ;set color, command:plot
- POP DI ;return addr
- POP AX ;Y2
- POP DX ;X2
- POP BX ;Y1
- MOV lnypos,BX ;store it
- CALL getdelta ;calculate direction
- MOV lnydir,CX ;store it
- CALL iabs ;ABS(AX)
- XCHG AX,DX ;DX:=Y-distance YD
- POP BX ;X1
- PUSH DI ;restore ret addr
- MOV lnxpos,BX ;store X1
- CALL getdelta ;calculate direction
- MOV lnxdir,CX ;store it
- CALL iabs ;ABS(AX)
- MOV BX,AX ;BX:=X-distance XD
- CMP BX,DX ;XD <= YD ?
- JLE lnyline ;yes:Y-oriented line
- MOV AX,DX ;X-oriented line
- ADD AX,AX
- SUB AX,BX
- MOV lndda,AX ;DDA:=YD+YD-XD
- MOV CX,BX ;XD -> count
- INC CX
- lnxloop CALL lnplot ;plot point with clipping
- MOV AX,lndda ;test DDA
- OR AX,AX
- JLE lnxnostp ;:no step
- ADD AX,DX ;DDA:=DDA+YD+YD-XD-XD
- ADD AX,DX
- SUB AX,BX
- SUB AX,BX
- MOV lndda,AX
- MOV AX,lnydir ;Ypos:=Ypos+Ydir
- ADD lnypos,AX
- JMP.b lnxcont ;'
- lnxnostp ADD AX,DX ;DDA:=DDA+YD+YD;
- ADD AX,DX
- MOV lndda,AX
- lnxcont MOV AX,lnxdir ;Xpos:=Xpos+Xdir
- ADD lnxpos,AX
- LOOP lnxloop ;another step
- RET ;'
- lnyline MOV AX,BX ;Y-oriented line
- ADD AX,AX
- SUB AX,DX
- MOV lndda,AX ;DDA:=XD+XD-YD
- MOV CX,DX ;YD -> count
- INC CX
- lnyloop CALL lnplot ;plot point with clipping
- MOV AX,lndda ;test DDA
- OR AX,AX
- JLE lnynostp ;:no step
- ADD AX,BX ;DDA:=DDA+XD+XD-YD-YD
- ADD AX,BX
- SUB AX,DX
- SUB AX,DX
- MOV lndda,AX
- MOV AX,lnxdir ;Xpos:=Xpos+Xdir
- ADD lnxpos,AX
- JMP.b lnycont ;'
- lnynostp ADD AX,BX ;DDA:=DDA+XD+XD
- ADD AX,BX
- MOV lndda,AX
- lnycont MOV AX,lnydir ;Ypos:=Ypos+Ydir
- ADD lnypos,AX
- LOOP lnyloop ;:another one
- RET ;"
- getdelta XOR CX,CX ;calculate direction -> CX
- SUB AX,BX ;compare them
- JZ deltazer ;equal: CX=0
- JS deltaneg ;:negative
- INC CX ;positive: CX=1
- RET ;'
- deltaneg DEC CX ;negative: CX=-1
- deltazer RET ;"
- lnplot PUSH CX ;Set line point with clipping
- PUSH DX ;save count, YD
- MOV AX,collin ;color, command
- MOV CX,lnxpos ;Xpos
- MOV DX,lnypos ;Ypos
- CALL doplot ;plot that point
- POP DX
- POP CX
- RET ;"
- xsound MOV BX,AX ;Sound
- MOV AX,#$34DD ;for frequency calculation
- MOV DX,#$0012
- CMP DX,BX ;frequency < 12 Hz ?
- JNB sounddis ;:might damage speaker
- DIV BX ;calculate timer value
- MOV BX,AX
- IN AL,timerflg ;sound on ?
- TEST AL,#$03
- JNZ soundon ;:yes
- OR AL,#$03 ;switch it on
- OUT timerflg,AL
- MOV AL,#$B6 ;set frequency
- OUT timercmd,AL
- soundon MOV.B AL,BL ;set freq lo
- OUT timerfrq,AL
- MOV.B AL,BH ;set freq hi
- OUT timerfrq,AL
- sounddis RET ;"
- xnosound IN AL,timerflg ;NoSound
- AND AL,#$FC ;switch it off
- OUT timerflg,AL
- RET ;"
- xgetmem XCHG AX,CX ;GetMem, AX=length requested
- POP BX ;ret addr
- POP DI ;dest ptr
- JMP.b new1 ;"like New
- hpconv PUSH AX ;change representation:
- PUSH CX ;AX=ofs 0..15, BX=seg
- MOV CL,#$04
- SHR AX,CL
- ADD BX,AX ;seg:=seg+ofs DIV 16
- POP CX
- POP AX
- AND AX,#$000F ;ofs:=ofs MOD 16
- RET ;"
- hpcmp CMP BX,DX ;Compare BX:AX with DX:CX
- JNZ hpcmp1
- CMP AX,CX
- hpcmp1 RET ;"
- hpadd ADD AX,CX ;BX:AX + DX:CX -> BX:AX
- ADD BX,DX
- JMP hpconv ;"change representation
- hplen ES: ;Get length of entry
- MOV AX,[DI]$04
- ES:
- MOV BX,[DI]$06
- PUSH AX
- OR AX,BX ;test if end of heap = 0
- POP AX
- RET ;"
- xnew POP BX ;New
- new1 POP ES ;dest ptr
- PUSH BX ;restore ret
- MOV hpdstpt,DI ;save addr dest ptr
- MOV hpdstpt1,ES
- MOV AX,CX ;number of bytes wanted
- ADD AX,#$0007 ;+7
- MOV BX,#$1000 ;carry ?
- JB new2 ;:yes
- XOR BX,BX ;no carry
- new2 AND AL,#$F8 ;space allocated is n*8
- CALL hpconv ;convert to seg,ofs
- MOV CX,AX ;needed size
- MOV DX,BX
- MOV hplast,#$0022 ;last entry
- MOV hplast1,DS
- LES DI,hpstrt ;get start of heap
- newseek CALL hplen ;get len of entry
- JZ newend ;:end of heap
- CALL hpcmp ;sufficient size ?
- JNB newfnd ;:large enough
- MOV hplast,DI ;remember last entry
- MOV hplast1,ES
- ES: ;get next entry
- LES DI,[DI]
- JMP newseek ;'continue searching
- newfnd CALL newdest ;store ES:DI to dest ptr
- JZ newfits ;equal - nothing to crunch
- SUB AX,CX ;calculate superfluous mem
- SBB BX,DX
- AND AX,#$000F
- JMP.b newrem ;'mark the remainder as free
- newfits ES: ;get next entry
- LES DI,[DI]
- JMP.b newlink ;'set link to it
- newend CALL newdest
- MOV AX,DI
- MOV BX,ES
- CALL hpadd ;sum up sizes
- MOV hptop,AX ;new heap top
- MOV hptop1,BX
- PUSH CX ;save size of entry
- PUSH DX
- MOV CX,AX ;test if heap overflow
- MOV DX,BX
- MOV AX,SP ;heap top - stack top
- MOV BX,SS
- SUB BX,#$0E
- CALL hpconv ;convert sp
- XOR AX,AX
- CALL hpcmp ;compare them
- POP DX
- POP CX
- JA newmemok ;:ok
- JMP chkstk1 ;'Error FF - memory overflow
- newmemok XOR AX,AX ;mark next entry
- XOR BX,BX ;as end of heap
- newrem PUSH BX ;save length
- PUSH AX
- ES: ;save ptr to next entry
- PUSH [DI]$02
- ES:
- PUSH [DI]
- MOV AX,DI ;try to put together with
- MOV BX,ES ;next entry
- CALL hpadd ;calc end of this entry
- MOV DI,AX ;new top
- MOV ES,BX
- ES: ;now produce that entry
- POP [DI] ;link
- ES:
- POP [DI]$02
- ES:
- POP [DI]$04 ;length
- ES:
- POP [DI]$06
- newlink PUSH ES ;save ES
- PUSH ES
- LES SI,hplast ;store ES:DI in last
- ES: ;entry as link to next entry
- MOV [SI],DI
- ES:
- POP [SI]$02
- POP ES ;restore ES
- RET ;"
- newdest PUSH ES ;store ES:DI in dest ptr
- PUSH ES
- LES SI,hpdstpt
- ES:
- MOV [SI],DI
- ES:
- POP [SI]$02
- POP ES
- RET ;"
- xfreemem XCHG AX,CX ;FreeMem
- POP BX ;ret addr
- POP DI ;get ptr
- JMP.b disp1 ;'like Dispose
- xdispose POP BX ;Dispose
- disp1 POP ES ;get dest ptr
- PUSH BX ;restore ret
- MOV AX,CX ;number of bytes
- ES:
- MOV CX,[DI] ;get value of ptr
- ES:
- MOV DX,[DI]$02
- ADD AX,#$0007 ;size+7
- MOV BX,#$1000 ;carry ?
- JB disp2 ;:yes
- XOR BX,BX ;no carry
- disp2 AND AL,#$F8
- CALL hpconv
- MOV hpesize,AX ;save size of
- MOV hpesize1,BX ;entry to erase
- LES DI,hpstrt ;start at the beginning
- MOV AX,DI
- MOV BX,ES
- CALL hpcmp ;= entry to erase ?
- JNB dispdel ;:no free space before
- dispseek ES: ;get link
- MOV AX,[DI]
- ES:
- MOV BX,[DI]$02
- CALL hpcmp ;compare with our entry
- JNB dispfnd
- MOV DI,AX ;go to next entry
- MOV ES,BX
- JMP dispseek ;'continue
- dispfnd PUSH ES ;ES:DI last entry
- MOV SI,CX ;DX:CX searched one
- MOV ES,DX ;AX:BX current entry
- PUSH hpesize1
- PUSH hpesize
- ES: ;store link in disposed entry
- MOV [SI],AX
- ES:
- MOV [SI]$02,BX
- ES: ;store length
- POP [SI]$04
- ES:
- POP [SI]$06
- POP ES ;restore ES
- ES:
- MOV [DI],CX ;store addr in last entry
- ES:
- MOV [DI]$02,DX
- ES:
- MOV AX,[DI]$04 ;get length of this entry
- ES:
- MOV BX,[DI]$06
- CALL dispmerg ;try to put them together
- JZ dispdone ;:end of heap
- ES: ;get addr of next one
- LES DI,[DI]
- dispdone ES: ;get length of this entry
- MOV AX,[DI]$04
- ES:
- MOV BX,[DI]$06
- ES: ;get link of this entry
- MOV CX,[DI]
- ES:
- MOV DX,[DI]$02
- JMP.b dispmerg ;'try to put them together
- dispdel MOV hpstrt,CX ;link to next entry
- MOV hpstrt1,DX
- MOV DI,CX ;ptr to this entry
- MOV ES,DX
- ES: ;store link to next one
- MOV [DI],AX
- ES:
- MOV [DI]$02,BX
- MOV CX,AX ;link for collect
- MOV DX,BX
- MOV AX,hpesize ;store its len
- MOV BX,hpesize1
- ES:
- MOV [DI]$04,AX
- ES:
- MOV [DI]$06,BX
- ;try to merge contiguous entries - thus reducing
- ;fragmentation of the heap.
- dispmerg MOV hpmerg,AX ;length of this entry
- MOV hpmerg1,BX
- ADD AX,DI ;+ its address
- MOV BX,ES
- ADD BX,hpmerg1
- CALL hpconv ;convert
- CALL hpcmp ;= next entry ?
- JNZ disprt ;no:cannot put them together
- MOV AX,hptop ;= heap top ?
- MOV BX,hptop1
- CALL hpcmp
- JZ disptop ;yes:set new, lower heap top
- PUSH ES ;save ES
- MOV SI,CX ;addr of next entry
- MOV ES,DX
- ES: ;get link to next entry
- MOV AX,[SI]
- ES:
- MOV BX,[SI]$02
- ES: ;get length
- MOV CX,[SI]$04
- ES:
- MOV DX,[SI]$06
- POP ES ;restore ES
- ES: ;store link
- MOV [DI],AX
- ES:
- MOV [DI]$02,BX
- MOV AX,hpmerg ;get length
- MOV BX,hpmerg1
- CALL hpadd ;add them
- ES: ;store new length
- MOV [DI]$04,AX
- ES:
- MOV [DI]$06,BX
- XOR AX,AX
- RET ;'
- disptop MOV hptop,DI ;set new heap top
- MOV hptop1,ES
- PUSH DI ;clear 8 bytes
- XOR AX,AX ;= marker for end of heap
- CLD
- MOV CX,#$0004
- REPZ
- STOS
- POP DI ;restore
- XOR AX,AX
- disprt RET ;"
- xmemavl XOR CX,CX ;MemAvail
- XOR DX,DX ;clear sum
- XOR SI,SI
- LES DI,hpstrt ;get heap start
- memav1 CALL hplen ;get length
- JZ memav2 ;:end of heap
- CALL hpaddcmp ;sum it up, test size
- ES: ;get next entry
- LES DI,[DI]
- JMP memav1 ;'continue
- memav2 MOV AX,SP ;last entry: free space
- MOV BX,SS ;between stack and heap
- SUB BX,#$10 ;leave some space
- CALL hpconv ;convert
- XOR AX,AX ;clear offset
- SUB BX,hptop1 ;subtract heap top
- JB memav3 ;:nothing left
- CALL hpaddcmp ;sum it up
- memav3 MOV AX,DX ;space left (paragraphs)
- RET ;"
- hpaddcmp CMP SI,BX ;is it the largest one ?
- JNB hpac2 ;:no
- MOV SI,BX ;yes, remember its size
- hpac2 CALL hpadd ;sum it up
- MOV CX,AX ;remember sum
- MOV DX,BX
- RET ;"
- xmaxavl CALL xmemavl ;MaxAvail: do MemAvail
- MOV AX,SI ;get largest size
- RET ;"
- xmark POP BX ;Mark
- POP ES ;get ptr
- MOV AX,hptop ;Heap top -> ptr
- ES:
- MOV [DI],AX
- MOV DX,hptop1
- ES:
- MOV [DI]$02,DX
- JMP BX ;"return
- xrelease POP BX ;Release
- POP ES ;ptr addr
- ES: ;get pointer
- LES DI,[DI]
- MOV hptop,DI ;-> heap top
- MOV hpstrt,DI ;-> heap start
- MOV hptop1,ES
- MOV hpstrt1,ES
- XOR AX,AX ;clear 8 bytes in entry
- LES DI,hpstrt ;= marker for end of heap
- MOV CX,#$0004
- CLD
- REPZ
- STOS
- JMP BX ;"return
- kbdstat CMP.B lastkey,#$00 ;Get key stat
- MOV AL,#$FF ;something there ?
- JNZ kbdst2 ;:true
- MOV AH,#$01 ;test kbd stat
- INT bioskbd
- MOV AL,#$00 ;false
- JZ kbdst2 ;:nothing available
- DEC.B AL ;true
- kbdst2 AND AX,#$0001
- RET $0001 ;"
- kbdget MOV AL,lastkey ;Get KBD char
- MOV.B lastkey,#$00 ;clear last key code
- OR.B AL,AL
- JNZ kbdg3 ;:was full - take it
- XOR.B AH,AH ;get key
- INT bioskbd
- OR.B AL,AL ;test it
- JNZ kbdg2 ;:normal char
- MOV.B lastkey,AH ;store scan code
- MOV AL,#$1B ;return ESC
- OR.B AH,AH
- JNZ kbdg3
- MOV AL,#$03 ;Break !
- kbdg2 CMP.B cbreak,#$01 ;Break allowed ?
- JNZ kbdg3 ;:no
- CMP AL,#$03 ;Break ?
- JNZ kbdg3 ;:no
- JMP brkmsg ;'
- kbdg3 XOR.B AH,AH ;clear hi byte
- RET $0001 ;"
- crtput POP AX ;Print char to screen
- POP DX ;char to be printed
- PUSH AX ;restore ret
- PUSH DX ;save regs
- PUSH BP
- PUSH DX
- CALL getcpos ;get cursor pos
- POP AX ;char to be printed
- CMP AL,#$0D ;Carriage Return ?
- JNZ crtlf ;:no
- MOV.B DL,txwinx1 ;go to left margin
- JMP.b crtsetps ;'set new pos
- crtlf CMP AL,#$0A ;Line Feed ?
- JNZ crtbs ;:no
- INC.B DH ;add 1 to line
- CS:
- CMP.B DH,txwiny2 ;>= bottom ?
- JB crtsetps ;:no, set pos
- JMP.b crtscrol ;'scroll up
- crtbs CMP AL,#$08 ;Backspace ?
- JNZ crtbell ;:no
- CMP.B DL,txwinx1 ;at the left ?
- JZ crtsetps ;yes, no change
- DEC.B DL ;go back
- JMP.b crtsetps ;'set cursor pos
- crtbell CMP AL,#$07 ;Bell ?
- JNZ crtchar ;:no
- MOV AH,#$0E ;write char
- XOR.B BH,BH
- INT bioscrt
- JMP.b crttest ;'no pos change
- crtchar PUSH DX ;remember position - put char
- MOV AH,#$09 ;write char
- XOR.B BH,BH ;screen page 0
- MOV CX,#$0001 ;1 char
- MOV.B BL,attcur ;current attribute
- INT bioscrt ;do it
- POP DX ;restore pos
- INC.B DL ;go right one char
- CS:
- CMP.B DL,txwinx2 ;= right margin ?
- JB crtsetps ;:no, set new pos
- MOV.B DL,txwinx1 ;go to the left
- INC.B DH ;next line
- CS:
- CMP.B DH,txwiny2 ;= bottom ?
- JB crtsetps ;no: set pos
- crtscrol DEC.B DH ;scroll up
- PUSH DX ;save pos
- MOV AX,#$0601 ;scroll up one line
- MOV.B BH,attcur ;att for empty line
- MOV CX,txwinx1 ;position upper left
- CS:
- MOV DX,txwinx2 ;position lower right
- DEC.B DH
- DEC.B DL
- INT bioscrt ;do it
- POP DX
- crtsetps MOV AH,#$02 ;set cursor pos
- XOR.B BH,BH ;screen 0
- INT bioscrt ;do it
- crttest POP BP
- CMP.B cbreak,#$01 ;test for break ?
- JNZ crtnobrk ;:no
- DEC SP
- CALL kbdstat ;get key stat
- JZ crtnobrk ;:nothing
- DEC SP
- CALL kbdget ;get key
- CMP AL,#$13 ;^S ?
- JNZ crtnobrk ;:no
- DEC SP
- CALL kbdget ;get key
- crtnobrk POP AX ;restore char
- RET ;"
- lstput POP AX ;put to LST
- POP DX ;get char
- PUSH AX ;restore ret
- MOV AH,#$05 ;operation
- JMP.b dos ;'do MS-DOS
- NOP ;Courtesy of LINK
- auxput POP AX ;put to AUX
- POP DX ;get char
- PUSH AX ;restore ret
- MOV AH,#$04 ;operation
- JMP.b dos ;'do MS-DOS
- NOP
- auxget MOV AH,#$03 ;Get from AUX
- CALL dos ;do MS-DOS
- XOR.B AH,AH ;clear hi byte
- RET $0001 ;'
- dos CMP.B AH,#$3D ;do MS-DOS-operation
- JZ openfil ;:Open file
- CMP.B AH,#$3C
- JZ openfil ;:Create file
- CMP.B AH,#$3E
- JZ closfil ;:Close file
- CMP.B AH,#$80
- JZ closeall ;:Close all files
- dodos PUSH BP ;save this
- INT msdos
- POP BP ;restore it
- RET ;'
- openfil PUSH SI ;put file into table of
- PUSH CX ;open files, open/create it
- MOV SI,filtabpt ;start of file table
- MOV CX,filemax
- openlp CMP [SI],#$00 ;empty ?
- JZ opendoit ;:yes
- INC SI
- INC SI
- LOOP openlp ;another one
- POP CX ;restore regs
- POP SI
- MOV AX,#$0004 ;Error: file not open
- STC
- RET ;'
- opendoit POP CX ;get offset to filename
- PUSH DS ;save DS
- PUSH ES ;ES -> DS
- POP DS
- CALL dodos ;open file
- POP DS ;restore DS
- JB openerr ;:error
- MOV [SI],AX ;file handle -> file list
- openerr POP SI ;restore
- RET ;"
- closfil PUSH CX ;Close file
- PUSH SI
- MOV SI,filtabpt ;start of file table
- MOV CX,filemax
- closlp CMP [SI],BX ;is it this file ?
- JNZ clsother ;:no
- MOV [SI],#$0000 ;clear its entry
- clsother INC SI ;next one
- INC SI
- LOOP closlp ;:not yet done
- POP SI ;restore regs
- POP CX
- JMP dodos ;'do it
- closeall MOV SI,filtabpt ;Close all files
- MOV CX,filemax
- clall1 MOV BX,[SI] ;test all file handles
- OR BX,BX
- JZ clall2 ;:not open
- MOV AH,#$3E ;close file
- CALL dodos ;do it
- MOV [SI],#$0000 ;store a 0: closed
- clall2 INC SI ;next one
- INC SI
- LOOP clall1 ;:continue
- RET ;"
- initio XOR AX,AX ;Init files, I/O
- initiofl MOV modeflg,AX ;clear flag
- MOV DI,#filetab ;set pt to file tab
- MOV filtabpt,DI
- MOV filemax,CX ;CX=max number of open files
- XOR AX,AX ;clear file list
- PUSH DS ;DS -> ES
- POP ES
- CLD
- REPZ
- STOS
- MOV ES,AX ;segment 0:
- ES:
- MOV verrhnd,#errhndl ;set vector:
- ES: ;error handler
- MOV verrhnd1,CS
- CALL msspeed ;measure CPU speed
- reinit1 MOV.B cbreak,#$00 ;no test for break
- reinit2 MOV SI,#inittab ;transfer vectors into table
- MOV DI,#vkbdstat
- PUSH DS ;DS -> ES
- POP ES
- PUSH CS ;CS -> DS
- POP DS
- MOV CX,#$001E ;count
- CLD
- REPZ ;move it
- MOVS
- PUSH ES ;restore DS
- POP DS
- XOR AX,AX ;clear vars
- MOV lastkey,AX ;no key stored
- MOV errnum,AL ;no error
- MOV conbufpt,AX ;no con buf
- MOV conbfend,AX
- MOV.B conbufln,#$7E
- MOV.B coninbuf,#$0D ;mark end of buffer
- RET ;"
- inittab W kbdstat,kbdget,crtput,lstput,auxput,auxget,crtput,kbdget
- W $FFFF,$00C1,$FFFF,$0082,$FFFF,$0043,$FFFF,$00C4,$FFFF
- W $00C5,$FFFF,$00C1,$0000,$0000,$0000,$0000,$FFFF,$00C1
- W $0000,$0000,$0000,$0000 ;"
- errhndl IRET ;"Error handler
- conput PUSH BX ;put to CON
- PUSH CX ;save registers
- PUSH DX
- PUSH DI
- PUSH SI
- XOR.B AH,AH
- PUSH AX ;char to put
- CALL [vconput] ;put it
- conret POP SI ;restore regs
- POP DI
- POP DX
- POP CX
- POP BX
- RET ;"
- keyget PUSH BX ;Get from KBD
- PUSH CX ;save regs
- PUSH DX
- PUSH DI
- PUSH SI
- DEC SP
- CALL [vkbdget] ;do it
- JMP conret ;"restore
- prints PUSH BP ;Print inline string
- MOV BP,SP
- XCHG BX,[BP]$02 ;return addr -> BX
- prsl CS:
- MOV.B AL,[BX] ;get char
- INC BX ;go to next one
- OR.B AL,AL ;test it
- JZ prsend ;0:end
- CALL conput ;put to CRT
- JMP prsl ;'continue
- prsend XCHG BX,[BP]$02 ;restore ret to pos after text
- POP BP
- RET ;"
- xwriteln CALL prints ;Writeln CRT
- B $0D,$0A,$00 ;print string: CR,LF
- RET ;"
- upcase CMP AL,#$61 ;UpCase. < a ?
- JB upcas1 ;:not lower case
- CMP AL,#$7A ;> z ?
- JA upcas1 ;yes:not lower case
- SUB AL,#$20 ;change to upper
- upcas1 RET ;"
- whexword PUSH AX ;Write Hex number: save it
- MOV.B AL,AH ;do hi byte
- CALL whexbyte ;do it
- POP AX ;restore lo byte
- whexbyte PUSH AX ;write hex byte: save low nibble
- ROR.B AL,1 ;get hi nibble
- ROR.B AL,1
- ROR.B AL,1
- ROR.B AL,1
- CALL whexnib ;do digit
- POP AX ;get lo nibble
- whexnib AND AL,#$0F ;mask it
- ADD AL,#$90 ;convert to hex - tricky
- DAA
- ADC AL,#$40
- DAA
- JMP conput ;"now print it
- limstind OR.B AH,AH ;limit string index
- JZ limst1 ;:ok
- STC ;hi <> 0: error
- MOV AX,#$0000 ;clear it
- JS limst1 ;negative:0
- DEC.B AL ;+:255
- limst1 RET ;"
- ;Init Memory - with inline parms:
- ;+ 0:mode flag
- ; 1=direct mode; 2=no device checking;
- ; 4=test for break; 8=set breakpoint interrupt
- ;+ 2:CS for returning to Turbo
- ;+ 4:DS for returning to Turbo
- ;+ 6:CS size
- ;+ 8:DS size
- ;+ A:heap, stack size
- ;+ C:max. heap, stack size
- ;+ E:max. number of open files
- ;+10:size of std input buffer
- ;+12:size of std output buffer
- initmem CALL readvers ;Init memory - with inline parms
- POP SI ;ret addr
- MOV AX,CS ;calculate segments
- CS:
- ADD AX,[SI]$06 ;+CS size
- CS:
- ADD AX,[SI]$08 ;+DS size
- CS:
- ADD AX,[SI]$0A ;+heap, stack size
- CS:
- CMP AX,availmem ;> available memory ?
- JBE memin1 ;:no
- JMP memerr ;'Not enough memory
- memin1 MOV BX,CS ;CS + CS size -> DS
- CS:
- ADD BX,[SI]$06
- MOV DS,BX
- CS: ;DS + DS size -> beg of free mem
- ADD BX,[SI]$08
- CS:
- MOV DX,availmem
- SUB DX,BX ;how much is left ?
- CS:
- CMP DX,[SI]$0C ;> max size ?
- JB memin2 ;:no
- CS:
- MOV DX,[SI]$0C ;limit to max size
- memin2 MOV DI,DX ;DI: heap size
- MOV AX,#$FFFE ;value for full stack
- SUB DX,#$1000 ;64 K free ?
- JNB memin3 ;:yes
- MOV AX,DX ;calculate stack size -> AX
- ADD AX,#$1000
- MOV CL,#$04
- SHL AX,CL
- XOR DX,DX ;at beg of heap segment
- memin3 ADD DX,BX ;+ heap segment
- MOV SS,DX ;-> SS
- MOV SP,AX ;set SP
- MOV spval,AX ;remember SP
- XOR AX,AX ;clear heap:
- MOV hptop,AX ;ptrs to beg of free memory
- MOV hptop1,BX
- MOV hpstrt,AX
- MOV hpstrt1,BX
- PUSH DI ;save heap size
- LES DI,hpstrt ;init heap:
- MOV CX,#$0004 ;mark heap top
- CLD
- REPZ
- STOS
- POP DI ;restore heap size
- CS: ;return excess memory ?
- TEST [SI],#$0001
- JNZ memin4 ;direct mode:no
- MOV AX,CS ;CS -> ES
- MOV ES,AX
- ADD BX,DI ;Heap pos + Heap size
- SUB BX,AX ;-> top of used memory
- MOV AH,#$4A ;change memory blocks
- CALL dos ;do MS-DOS
- memin4 CS: ;set variables
- MOV AX,[SI]$02 ;CS for return
- MOV turbocs,AX
- CS:
- MOV AX,[SI]$04 ;DS for return
- MOV turbods,AX
- CS:
- MOV AX,[SI] ;main flag
- CS:
- MOV CX,[SI]$0E ;max file count
- PUSH CX
- PUSH SI
- CALL initiofl ;init files, I/O
- POP SI
- POP CX
- MOV DI,#filetab ;get end addr
- ADD DI,CX ;of file tab
- ADD DI,CX
- MOV stdinof,DI ;buffer addr std input
- CS:
- MOV AX,[SI]$10 ;set std in buffer
- MOV stdinsz,AX
- ADD DI,AX
|