home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sound
/
midi
/
mb.asm
< prev
next >
Wrap
Assembly Source File
|
1988-03-20
|
193KB
|
4,248 lines
TITLE Main Work Loop for Modular Sequencer
NAME MB
.SALL
;==============================================================
; MusicBox Modular Sequencer, Version 2
; main module
;--------------------------------------------------------------
; author: John Dunn
; date: 03/07/86
; update: 03/20/88
;--------------------------------------------------------------
; COPYRIGHT (C) 1986 John Dunn, All Rights Reserved
; Entered into the Public Domain, March 20, 1988
;
; Use and copying of this software and preparation of derivative works
; based upon this software are permitted. Any distribution of this
; software or derivative works must comply with all applicable United
; States export control laws.
;
; This software is made available AS IS, and the author makes no warranty
; about the software, its performance, or its conformity to any specification.
;
; Any person obtaining a copy of this software is requested to send their
; name and address address to:
;
; John Dunn, Senior Research Fellow
; Time Arts Inc.
; 3436 Mendocino Ave.
; Santa Rosa, CA 95401
;
;==============================================================
include order.asm
;--------------------------------------------------------------
include equates.asm
clkadr equ 146+(23*160) ; addr of page 0 clock
;==============================================================
include macros.asm
;==============================================================
; MACROS
;--------------------------------------------------------------
; convert character x,y to an address
; call with al = video y, bx = video x
; (x= 0-79, y= 0=24)
; returns with bx = offset, ax trashed
;
vxyadr macro
mov ah,160
mul ah
add bx,bx
add bx,ax
endm
;--------------------------------------------------------------
; display priority number
;
showp macro
and ah,1 ;; do ms byte
xor ah,1
add ah,0f8h
mov byte ptr es:158[bx],ah ;; set high byte
tohex ;; binary to hex
mov byte ptr es:160[bx],ah ;; set the priority
mov byte ptr es:162[bx],al ;; /
endm
;==============================================================
if not withc
STACK SEGMENT para stack 'STACK'
db 512 dup (?)
STACK ENDS
endif
;==============================================================
BUFFV SEGMENT
db 0
db 4094 dup (?) ; video "foo" buffer
db 0
BUFFV ENDS
;==============================================================
_DATA SEGMENT
ASSUME DS:DGROUP, CS:_TEXT
;--------------------------------------------------------------
extrn mute:word,mutef:byte,midisf:byte,midixsf:byte
extrn vartbl:near,modscr:near
extrn _chrtbl:near
extrn _exetbl:near
extrn @dummy:near
extrn _modsrc:near
extrn $menu:near ; page #'s and menu
extrn $dummy:near ; 25 line dummy for module text buffer
extrn _modtxt:near,?modtxt:near
extrn @zero:near
extrn mmreset:byte,mmstart:byte
extrn mmtick:word,mmcount:word,mclocks:word
extrn mvlsav:near,mvlnum:abs
extrn mprstf:byte
;--------------------------------------------------------------
extrn midip:byte
;--------------------------------------------------------------
public varsav,cmdflg,special,cmdloc,vpage,locsav,curadr,noop
public ticka,tickis,cmdcnt,valflg,usrflg,magflg,holdv,colr,doesc
public _tmpfn,_savfn,_lodfn,_bakfn,_mpab,_header,fastflg,modnum
public lodflg,clrchf,midiok,curonf,asensf
;--------------------------------------------------------------
_bases dw 0 ; base seg is saved here
clrchf db 0 ; clear channel flag, used by chanl
tickis db 0 ; timer value after modules
lodflg db 0 ; nz for 2 clocks after loading
fastflg db 0 ; nz = fast as possible loops
savtime dw 0 ; place to save time of day
timecnt db 8 ; time count for colon flash
midiss db 0 ; place to save last midi xtrn sync
waiting db 0 ; nz if waiting on timer
pdf db 0 ; pd values set by interrupt
pdx db 39 ; /
pdy db 12 ; /
curonf db 0 ; nz = don't restore screen char
curflg db 0 ; z to display normal cursor
curcol db 017h ; 0 = cursor not being displayed
curdata dw 0 ; data under the cursor
savcol db 0 ; /
colr db blue ; current number readout color
vpage dw 0B800H ; current video page seg
vpagen db 0 ; current video page number
vpagep db 0 ; previous video page number
curadr dw 1998 ; cursor address offset
execur dw 0 ; z = don't do it
modchar dw offset dgroup:$dummy; current module char list
cmdcol db 0 ; command color
cmdcnt db 0 ; command count
cmdptr dw offset dgroup:@dummy; command pointer
cmdloc dw 0 ; command location offset
cmdtag dw 0 ; command label offset
shosav dw 0 ; place to save it
shoflg db 0 ; nz = showing output-inputs
cmdflg db 0 ; nz = a command is pending
magflg db 0 ; 0=no-value, 1=channel #, 2=input value
errflg db 0 ; 1 = write, 2 = non-fatal read
errwrd dw 0 ; dos error word
byemsg dw 0 ; addr of exit msg, or 0
room db 0 ; disk room, in save files
tmpsav dw offset dgroup:vartbl; place to hold a variable ptr (move)
; or modsrc addr (reincarnate)
locsav dw 0 ; place to hold cmdloc, to remember hilights
modnum db 0 ; module number *2 of last new module
special dw noop ; place to hold exe addr of special routine
usrflg db 0 ; nz when special magenta input is happening
valflg db 0 ; nz when blue value input is happening
mickx dw 0 ; current mickey horiz count
lastx db 0 ; place to save last pdx for no-button cmds
lasty db 0 ; place to save last pdy for no-button cmds
holdv dw 0 ; place to hold last value offset
doesc dw noop ; do this when ESC is selected
cscale db 'C:C#D:D#E:F:F#G:G#A:A#B:'
diradr dw 0 ; temp storage for screen directory
dirptr dw 0 ; last directory file name pointer
_mpab db 8Fh ; file load flags
asensf db 1 ; active sensing send flag
;==============================================================
; the following are constants that may be changed either before
; assembley or with debug after MB.EXE is built. Actual number of
; bytes must remain the same, or previously saved files will be
; incompatable, causing upredictable results when loaded.
;
usesf db 1 ; 1 = use _scrfn file if found
midiok db 1 ; 0= off, 1= 1 MPU, 3= 2 MPU's
_numpg dw 3 ; number of video pages -1 (1/3/7)
; should be 3 for CGA, 7 for EGA/VGA
_scrfn db 'tutor.scr',0,0,0,0 ; screen file name
; if not found, uses screen image
; from MODSCR, last section of MBV.ASM
_tmpfn db '\undo.mb$',0,0,0,0 ; file name for set/undo
; 0 in 1st byte disables
_bakfn db 'previous.mb ',0 ; file name for backup
; 0 in 1st byte disables
_lodfn db 'temp.mb ',0,0,0,0,0; file name for dir loading
_dirfn db '*.mb ',0 ; directory file name
;==============================================================
_inbuf db 128 dup (?) ; kbd input buffer
_err_wp db 7,'Write Protect: Retry Ignore Quit$'
_err_dx db 7,'Disk Error: Retry Ignore Quit? $'
_errwx db 7,'Write Error: Retry Escape Quit? $'
_errwr db 7,'Write Error: Retry Ignore Quit? $'
_errver db 7,'Wrong Vers: M disabled. Escape? $'
_noundo db 7,'Error in writing to Undo File.$'
_opundo db 7,'Error in opening Undo File.$'
_errmod db 7,'Error in reading modules. $'
roomis db "Room= 20$"
;--------------------------------------------------------------
; header format (only first 128 bytes are actually used)
; byte 0 = revision
; byte 1 = version
; byte 2 = encoding (0 = no encoding in this version)
; byte 3 = 0
; byte 4-43 = copyright notice
; other bytes unused
;--------------------------------------------------------------
_header db version,release ; version/release word
db 0,0 ; encoding = 0 = none
db 'MusicBox Copyright (c) 1986, 1987 John Dunn'
db 100 dup (0) ; more stuff
_foo db 128 dup (?) ; scratch area
;--------------------------------------------------------------
; the following are saved/loaded
;
valsav equ $ ; start of values to save
_savfn db 'temp.mb ',0,0,0,0,0; file name for saving
ticka db 0CH ; timer tick (1456/mtempo)
varptr dw offset dgroup:vartbl; addr of next free variable space
varnow dw offset dgroup:vartbl; current variable table addr
varsav dw offset dgroup:vartbl; saved variable table addr
last dw 0 ; index of last module in exetbl
; also next module's priority
valend equ $ ; end of values to save
_DATA ENDS
;==============================================================
_TEXT SEGMENT
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: NOTHING
;--------------------------------------------------------------
public loops
loops dw 0 ; module loop count
;--------------------------------------------------------------
extrn _dummy:near
extrn ticks:word,timer:word,midixs:byte
extrn startm:near,stopm:near,startt:near,stopt:near
extrn sendm:near,alloff:near,tomidi:near
extrn allclr:near,allmidi:near
extrn secondf:byte,seconds:word
;==============================================================
; main body of program
;--------------------------------------------------------------
; initialization
;
public _doit
_doit:
if withc ; if compiled with C
push es ; save C regs
push bp ; /
push si ; /
push di ; /
else ; else if assembly
mov ax,seg dgroup ; set data seg
mov dx,ds ; save initial data seg
mov ds,ax ; /
mov _bases,dx ; /
endif
;
mov ah,25H ; set int vect
mov al,24H ; int 24h for MS crit error
push ds ; save data seg
mov dx,cs ; get code ds
mov ds,dx ; point to cerror
mov dx,offset cerror; vector to mine
int 21H ; set new int vect
pop ds ; restore data seg
;
mov cx,_numpg ; get number of pages
inc cx ; +1 for loop
if debug ; if debug mode, don't clr page 7
dec cx ; /
endif ; /
mov al,0 ; /
start0: push cx ; /
push ax ; /
call page ; /
call clx ; /
pop ax ; /
inc al ; /
pop cx ; /
loop start0 ; /
mov al,0 ; set page 0 active
call page ; /
call shoall ; show all modules
call modloc ; set module location addresses
;
call savmod ; save undo modules
;
call getfn ; get file name from cmd line
jnc start1 ; branch if no input filename
;
mov ah,3dh ; dos open file command
mov al,0 ; read only
mov dx,offset dgroup:_savfn; point to file name
int 21H ; open the file
jc start1 ; branch if open error
call lodmod0 ; else load modules
call showfn ; show the save filename
call getdir ; show directory enterys
call dopath ; show current path
call dompab ; show mpad status
call menus ; draw menus
mov vpagen,0 ; set up for swaps
mov al,1 ; show page 1
call page ; /
jmp short start2 ; /
;
start1: call showfn ; show the save filename
call getdir ; show directory enterys
call dopath ; show current path
call dompab ; show mpad status
call menus ; draw menus
mov vpagen,1 ; set up for swaps
mov al,0 ; show page 0
call page ; /
;
start2: call startt ; start system timer
call initpd ; initialize pointing device
test midiok,-1 ; was MIDI on?
jz start3 ; no, branch
call startm ; yes, turn it on
;
start3: mov curonf,1 ; no old cursor
call curon ; activate cursor
mov pdf,80h ; /
call fixhlt ; fix halt status
;==============================================================
; registers that must be preserved: DS, SI
;==============================================================
; main work loop
public work
work:
if debug ; if true compile this stuff
mov al,really ; if really, really do it
or al,al ; /
jz really1 ; /
;
mov bx,varnow ; ...display the variable list
sub bx,8 ; back up a little
;--------------------------------------------------------------
; use this stuff to show MIDI data stream
comment |
;
mov bx, offset dgroup:mobuf;; get next byte
add bx,mobiix ;; get midi in buffer index
sub bx,36 ; back up a little
mov ax,mobiix
mov show2,ax
sub ax,moboix
mov show3,ax
comment ends |
;--------------------------------------------------------------
; use this stuff to show mouse location & screen address
;
mov ax,curadr ; cursor screen address
mov show0,ax ; show it
mov al,pdx ; cursor x
mov ah,pdy ; cursor y
mov show1,ax ; show it
mov show2,sp
;--------------------------------------------------------------
call showw ; /
call show ; /
really1: ; /
endif ; /
;==============================================================
; display time if on page 0
;
mov es,vpage ; set up for video page
cmp vpagen,0 ; on page 0?
jnz work0 ; no, branch
mov ah,2ch ; dos get time function
int 21h ; call dos
;
test lodflg,-1 ; did a load happen
jnz workt ; yes, set new time
;
cmp cx,savtime ; has time changed?
jz worktz ; no, branch
;
workt: mov colr,cyan ; set color to cyan
test lodflg,-1 ; did a load happen
jnz workt2 ; yes, don't check hrs
cmp ch,byte ptr savtime+1 ; hrs changed?
jz workt1 ; no, branch
;
workt2: mov al,ch ; setup for ascii
mov bx,clkadr ; address of decimal readout
call todec ; show it in decimal
mov bx,clkadr ; zip ms zero
mov byte ptr es:[bx],0b3h ; /
;
workt1: mov al,cl ; setup for ascii
mov bx,clkadr+6 ; address of decimal readout
call todec ; show it in decimal
mov bx,clkadr+6 ; zip ms zero
mov byte ptr es:[bx],':' ; /
;
worktx: mov savtime,cx ; save time
mov colr,blue ; fix color
worktz: dec timecnt ; seconds changed?
jnz work0 ; no, exit
; mov timecnt,64 ; yes, set new count
mov bx,clkadr+7 ; flip colon color
xor byte ptr es:[bx],green ; /
;--------------------------------------------------------------
; test to see if a request to change pages has been asserted
;
work0: cmp pdf,82H ; change page if pdf=2
jnz work0a ; else, go on
and pdf,07fh ; clear pen-down flag
call curoff ; no cursor while changing pages
mov al,vpagep ; get previous page number
call page ; swap with current
mov curonf,1 ; don't restore screen data
call curon ; do turn on the cursor
work0x: jmp workx ; back to the work loop
;==============================================================
; test to see if a command request has been asserted
;
work0a: cmp pdf,81h ; do command if pdf = 1
jnz work02 ; else check for user input
and pdf,07fh ; clear pen-down flag
cmp pdx,2 ; in vertical menu area?
jbe workm0 ; yes, go do it
;
cmp vpagen,0 ; on page 0?
jnz work01 ; no, branch
cmp pdy,10h ; horiz menu?
jz workh ; yes, go do it
cmp pdy,15h ; below file area
ja work0x ; yes, not interested
cmp pdy,11h ; in file area?
ja workf ; yes, go process
work01: jmp work00 ; no, go process screen commands
workf: jmp workf0 ; branch to file area processing
workh: jmp workh0 ; branch to horiz menu processing
;==============================================================
; no putton push, if user input was requested (cmdflg =7 ), and
; if x,y position has changed, process user input
;
work02: mov ax,11 ; check for mouse movement
int 33H ; /
cmp mickx,cx ; has x changed?
jnz work02a ; yes, go do it
mov ah,pdy ; has y changed
cmp lasty,ah ; /
jz work02x ; no, then back to work loop
work02a:mov mickx,cx ; save x,y mickeys
mov al,pdx ; save last pdx,pdy
mov lastx,al ; yes, save pdx,pdy
mov ah,pdy ; /
mov lasty,ah ; /
cmp cmdflg,7 ; blue input?
jnz work02b ; no, branch
jmp work72 ; yes, process blue user input
work02b:cmp cmdflg,10 ; magenta input?
jnz work02c ; no, branch
jmp work92 ; yes, process magenta special input
work02c:
work02x:jmp workx ; no, back to the work loop
;==============================================================
; Process Menu command.
;
workm0: cmp pdy,7 ; page change command
ja workm1 ; no, go fish
call curoff ; yes, set page
mov al,pdy ; /
call page ; /
mov curonf,1 ; don't restore screen data
call curon ; cursor back on
jmp workx ; back to the work loop
;==============================================================
; menu commands other than page change
;
workm1: cmp pdy,8 ; ESC?
jnz workm4 ; no, branch
jmp workm1a ; yes, go do it
workm4: cmp pdy,10 ; SET?
jnz workm5 ; no, branch
jmp workm4a ; yes, go do it
workm5:
;
workm2: cmp cmdflg,0 ; something pending?
jnz workmz ; yes, split
;
cmp pdy,9 ; delete?
jnz workm3 ; no, branch
jmp workm2a ; yes, branch to delete
workm3: cmp pdy,11 ; HLT?
jnz workm7 ; no, branch
jmp workm3a ; yes, go do it
workm7: cmp pdy,12 ; OFF?
jnz workm8 ; no, branch
jmp workm7a ; yes, go do it
workm8: cmp pdy,17 ; mute/solo command
jb workmz ; no, exit
jmp workm8a ; yes, go do it
;
workmz: jmp workx ; none of the above, exit
;==============================================================
; Delete command given, turn on highlite, set cmdflg to 4
;
workm2a:mov bx,5a0h ; address of DEL
call turnon ; turn on
mov cmdflg,4 ; set command flag = 4
mov word ptr doesc,offset workm2d; set up for ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from delete
;
workm2d:mov bx,5a0h ; turn off hilight
jmp turnoff
;==============================================================
; process HLT command (on/off)
;
workm3a:mov bx,6E0H ; text offset
test mprstf,2 ; stopped already?
jz workm3b ; no, branch
call turnoff ; yes, turn off highlight
mov al,0fah ; send MIDI START command
call allmidi ; send to all midi ports
mov mmtick,1 ; reset to 1st note in measure
and mprstf,0FDH ; clear halt flag
jmp workx ; exit
workm3b:call turnon ; turn on highlight
or mprstf,2 ; set master halt the flag
mov al,0fch ; send MIDI STOP command
call allmidi ; /
jmp workx ; exit
;==============================================================
; SET command given, save current system to temp file
;
workm4a:
test _tmpfn,-1 ; want to do it?
jz workm4e ; no, branch
;
cmp cmdflg,0 ; was it clear?
jz workm4d ; yes, branch
jmp workx ; no, ignore
;
workm4d:mov bx,160*10 ; address of menu text
call turnon ; turn on highlight
call curoff ; zip cursor
call allclr ; clear all midi channels
;
call savmod ; save modules
;
mov pdf,80h ; reset mouse flag
call curon ; cursor back on
mov bx,160*10 ; address of menu text
call turnoff ; turn off highlight
mov clrchf,1 ; setup to clear chanl
workm4e:jmp workx ; exit
;==============================================================
; process OFF command (all notes off)
;
workm7a:
call alloff ; process all notes off
jmp workx ; exit
;==============================================================
; ESC command given.
; Turn cursor off, execute DOESC, then zip DOSEC.
; If cursor is a module image, turn it off.
; Clear cmdflg.
;
public _cancel,cancel
_cancel:
workm1a:call curoff ; cursor off
cancel: mov ax,doesc ; get the esc exe addr
call ax ; go do it
mov doesc,offset noop ; put it to sleep
call curon ; cursor back on
test curflg,1 ; dragging a module around?
jz workm1d ; no, branch
call setcur ; yes, set cursor
workm1d:mov cmdflg,0 ; clear command flag
jmp workx ; exit
;--------------------------------------------------------------
; mute/solo commands
;
workm8a:test mutef,1 ; action mute or solo?
jnz workm8e ; branch if mute
;
mov dx,-1 ; set up solo mask
mov cl,pdy ; point to the screen location
sub cl,17 ; cl = 0-7
add cl,cl ; *2 for 0-14
cmp pdx,2 ; do odd?
jz workm8b ; yes, branch
mov ax,1 ; set flag bit
shl ax,cl ; ax = bit flag for mute
xor dx,ax ; set the bit
cmp pdx,0 ; was this just even?
jz workm8c ; yes, branch
workm8b:inc cl ; +1 for 1-15
mov ax,1 ; set flag bit
shl ax,cl ; ax = bit flag for mute
xor dx,ax ; set the bit
;
workm8c:cmp dx,mute ; same as last time?
jnz workm8d ; no, branch
mov dx,0 ; yes, clear solo flags
workm8d:mov mute,dx ; set new solo
jmp workx ; back to the work loop
;--------------------------------------------------------------
workm8e:mov cl,pdy ; point to the screen location
sub cl,17 ; cl = 0-7
add cl,cl ; *2 for 0-14
cmp pdx,2 ; do odd?
jz workm8f ; yes, branch
mov ax,1 ; set flag bit
shl ax,cl ; ax = bit flag for mute
xor mute,ax ; flip the bit
cmp pdx,0 ; was this just even?
jz workm8g ; yes, branch
workm8f:inc cl ; +1 for 1-15
mov ax,1 ; set flag bit
shl ax,cl ; ax = bit flag for mute
xor mute,ax ; flip the bit
workm8g:jmp workx ; back to work loop
;==============================================================
; Process horiz page 0 menu
;
workh0: cmp pdx,8 ; QUIT @ workh0a
jnb workh01 ; /
jmp workh0a ; /
workh01:cmp pdx,0DH ; EXIT @ workh1a
jnb workh02 ; /
test room,-1 ; room to save?
jz workhx ; no, ignore the command
jmp workh1a ; /
workh02:cmp pdx,12H ; MPAD @ workh2a
jnb workh03 ; /
jmp workh2a ; /
workh03:cmp pdx,17H ; UNDO @ workh3a
jnb workh05 ; /
jmp workh3a ; /
workh05:cmp pdx,1CH ; REDO @ workh5a
jnb workh04 ; /
jmp workh5a ; else go do it
workh04:cmp pdx,21H ; SAVE @ workh4a
jnb workh06 ; /
test room,-1 ; room to save?
jz workhx ; no, ignore the command
jmp workh4a ; else go do it
workh06:cmp pdx,2bh ; NAME @ workh6a
jnb workh07 ; /
jmp workh6a ; /
workh07:jmp workh7a ; PATH @ workh7a
workhx: jmp workx ; back to the work loop
;--------------------------------------------------------------
; Turn on horiz menu command highlight.
; call with cursor on, bx = menu text offset
;
public horzon
horzon: push bx ; save text addr
call curoff ; zip cursor
pop bx ; get text addr
add bx,16*160 ; offset for line
mov dx,0b800h ; do page 0 only
mov es,dx ;
or byte ptr es:1[bx],8 ; make bright
or byte ptr es:3[bx],8 ; /
or byte ptr es:5[bx],8 ; /
or byte ptr es:7[bx],8 ; /
mov curonf,1 ; don't restore
jmp curon ; cursor normal
;--------------------------------------------------------------
; Turn off menu command highlight.
; call with cursor on, bx = menu text offset
;
public horzoff
horzoff:push bx ; save text addr
call curoff ; zip cursor
pop bx ; get text addr
add bx,16*160 ; offset for line
mov dx,0b800h ; do page 0 only
mov es,dx ;
and byte ptr es:1[bx],0f7h ; make dark
and byte ptr es:3[bx],0f7h ; /
and byte ptr es:5[bx],0f7h ; /
and byte ptr es:7[bx],0f7h ; /
mov curonf,1 ; don't restore
jmp curon ; keep it right
;--------------------------------------------------------------
; show mapb status
;
dompab: mov bx,1cH+(16*160) ; offset for line
mov dx,0b800h ; do page 0 only
mov es,dx ; /
mov al,_mpab ; get it
mov ah,1 ; set bit test flag
mov cl,4 ; 4 bits to do
dompab0:test al,ah ; look at the bit
jz dompab1 ; branch if off
mov byte ptr es:1[bx],cyan; else make bright
jmp short dompab2 ; branch
dompab1:mov byte ptr es:1[bx],grey; make dark
dompab2:inc bl ; bump pointers
inc bl ; /
shl ah,1 ; /
loop dompab0 ; loop
ret
;==============================================================
; QUIT command given, turn on highlite, set cmdflg to 6
;
workh0a:mov bx,8 ; address of QUIT
cmp cmdflg,6 ; already set?
jnz workh0b ; no, branch
mov dx,ds ; yes, fix es = ds
mov es,dx ; /
test _mpab,80H ; has there been a save?
jz workh0e ; no, branch
call delmod ; delete temp file
workh0e:jmp split ; exit
workh0b:cmp cmdflg,0 ; was it clear?
jz workh0d ; yes, branch
jmp workx ; no, ignore
workh0d:call horzon ; was clear, so turn on
call tmphlt ; set temp hlt
mov cmdflg,6 ; set command flag = 6
mov doesc,offset workh0c ; set up ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from QUIT
; also define "noop" as a dummy return
;
workh0c:mov bx,8 ; turn off highlight
call horzoff ; /
call clrhlt ; clear hlt
noop: ret ; "noop" is dummy return
;==============================================================
; EXIT command given, turn on highlite, set cmdflg to 18
;
workh1a:mov bx,12h ; address of EXIT
cmp cmdflg,16 ; already set?
jnz workh1b ; no, branch
mov cmdflg,0 ; clear the command
;
call horzoff ; yes, turn off highlight
mov bx,3ah ; zip save highlight
call horzoff ; /
call curoff ; zip cursor
;
call delmod ; delete temp file
;
mov dx,ds ; fix es = ds
mov es,dx ; /
;
test _bakfn,-1 ; doing backups?
jz workh1e ; no, branch
;
mov dx,offset dgroup:_savfn; file already exists?
mov cx,0 ; /
mov ah,4eh ; dos search for first
int 21h ; /
jc workh1e ; branch if not already existing
;
mov dx,offset dgroup:_bakfn; delete old bakfn
mov ah,41h ; dos delete function call
int 21h ; /
;
mov dx,offset dgroup:_savfn; rename savfn to bakfn
mov di,offset dgroup:_bakfn
mov ah,56h ; dos rename function call
int 21h ; /
;
workh1e:mov dx,offset dgroup:_savfn; point to file name
call savmods ; save modules
test errflg,-1 ; any errors?
jz workh1f ; no, branch
mov dx,offset dgroup:_errwx; yes, setup message
call errmsg ; do msg, get response
cmp al,'Q' ; want to ignore?
jz workh1f ; /
cmp al,'R' ; Retry
jz workh1e ; /
; ; else Escape
mov pdf,80h ; reset mouse flag
call curon ; cursor back on
call workh1c ; fix menu & HLT status
call getdir ; show directory
jmp workx ; exit
;
workh1f:jmp split ; exit
;
workh1b:cmp cmdflg,0 ; was it clear?
jz workh1d ; yes, branch
jmp workx ; no, ignore
;
workh1d:call horzon ; was clear, so turn on
mov bx,3ah ; set save highlight
call horzon ; /
call tmphlt ; set temp hlt
mov cmdflg,16 ; set command flag = 18
mov doesc,offset workh1c ; set up ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from EXIT
;
workh1c:mov bx,12h ; turn off highlight
call horzoff ; /
mov bx,3ah ; zip save highlight
call horzoff ; /
call clrhlt ; clear temp hlt
ret
;==============================================================
; set MPAB bit & display status
;
workh2a:mov ah,1 ; set bit flag
mov dh,pdx ; get cursor x-loc
mov dl,0EH ; first match position
mov cx,4 ; 4 to do
workh2b:cmp dl,dh ; match?
jz workh2c ; yes, branch out
shl ah,1 ; bump bit flag
inc dl ; bump x-loc
loop workh2b ; do them all
workh2c:xor _mpab,ah ; flip the mpab bit
call curoff ; zip cursor
call dompab ; show it
mov curonf,1 ; don't restore
call curon ; keep it right
jmp workx ; exit
;==============================================================
; UNDO command given, turn on highlite, set cmdflg to 16
;
workh3a:
test _tmpfn,-1 ; want to do it?
jz workh3e ; no, branch
;
mov bx,26h ; address of UNDO
cmp cmdflg,17 ; already set?
jnz workh3b ; no, branch
mov cmdflg,0 ; clear the command
;
call curoff ; zip cursor
xor _tmpfn+4,1 ; switch file name
call savmod ; save modules
xor _tmpfn+4,1 ; switch file name
call lodmod ; load modules
;
call delmod ; delete just loaded file
xor _tmpfn+4,1 ; switch file name
;
call showfn ; show the save filename
call getdir ; show directory enterys
call dopath ; show current path
call dompab ; show mpad status
call menus ; draw menus
;
mov pdf,80h ; reset mouse flag
mov curonf,1 ; don't restore
call curon ; cursor back on
mov bx,26h ; turn off highlight
call horzoff ; /
mov bx,160*10 ; address of menu text
call turnoff ; turn off highlight
call showfn ; show exit file name
call fixhlt ; clear temp HLT
mov lodflg,2 ; flag that a load happened
workh3e:jmp workx ; exit
;
workh3b:cmp cmdflg,0 ; was it clear?
jz workh3d ; yes, branch
jmp workx ; no, ignore
;
workh3d:mov bx,26h ; point menu text
call horzon ; turn on
call tmphlt ; set temp HLT
mov cmdflg,17 ; set command flag = 19
mov doesc,offset workh3c ; set up ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from UNDO
;
workh3c:mov bx,26h ; turn off highlight
call horzoff ; /
call clrhlt ; clear temp hlt
ret
;==============================================================
; SAVE command given, turn on highlite, set cmdflg to 19
;
workh4a:cmp cmdflg,19 ; already set?
jnz workh4b ; no, branch
mov cmdflg,0 ; clear the command
;
mov bx,3ah ; point to text
call horzoff ; turn off highlight
call curoff ; zip cursor
;
mov dx,ds ; fix es = ds
mov es,dx ; /
;
test _bakfn,-1 ; doing backups?
jz workh4e ; no, branch
;
mov dx,offset dgroup:_savfn; file already exists?
mov cx,0 ; /
mov ah,4eh ; dos search for first
int 21h ; /
jc workh4e ; branch if not already existing
;
mov dx,offset dgroup:_bakfn; delete old bakfn
mov ah,41h ; dos delete function call
int 21h ; /
;
mov dx,offset dgroup:_savfn; rename savfn to bakfn
mov di,offset dgroup:_bakfn
mov ah,56h ; dos rename function call
int 21h ; /
;
workh4e:mov dx,offset dgroup:_savfn; point to file name
call savmods ; save modules
test errflg,-1 ; any errors?
jz workh4f ; no, branch
mov dx,offset dgroup:_errwr; yes, setup message
call errmsg ; do msg, get response
cmp al,'I' ; want to ignore?
jz workh4f ; /
cmp al,'R' ; Retry
jz workh4e ; /
jmp split ; must be split
;
workh4f:
mov pdf,80h ; reset mouse flag
call curon ; cursor back on
call workh4c ; fix menu & HLT status
call getdir ; show directory
jmp workx ; exit
;
workh4b:cmp cmdflg,0 ; was it clear?
jz workh4d ; yes, branch
jmp workx ; no, ignore
;
workh4d:mov bx,3ah ; point menu text
call horzon ; turn on
call tmphlt ; set temp HLT
mov cmdflg,19 ; set command flag = 19
mov doesc,offset workh4c ; set up ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from SAVE
;
workh4c:mov bx,3ah ; turn off highlight
call horzoff ; /
call clrhlt ; fix hlt status
ret
;==============================================================
; REDO command given, turn on highlite, set cmdflg to 18
;
workh5a:
test _tmpfn,-1 ; want to do it?
jz workh5e ; no, branch
;
mov bx,30h ; address of UNDO
cmp cmdflg,18 ; already set?
jnz workh5b ; no, branch
mov cmdflg,0 ; clear the command
;
call curoff ; zip cursor
call lodmod ; load modules
;
call showfn ; show the save filename
call getdir ; show directory enterys
call dopath ; show current path
call dompab ; show mpad status
call menus ; draw menus
;
mov pdf,80h ; reset mouse flag
mov curonf,1 ; don't restore
call curon ; cursor back on
mov bx,26h ; turn off highlight
call horzoff ; /
mov bx,160*10 ; address of menu text
call turnoff ; turn off highlight
call showfn ; show exit file name
call fixhlt ; clear temp HLT
mov lodflg,2 ; flag that a load happened
workh5e:jmp workx ; exit
;
workh5b:cmp cmdflg,0 ; was it clear?
jz workh5d ; yes, branch
jmp workx ; no, ignore
;
workh5d:mov bx,30h ; point menu text
call horzon ; turn on
call tmphlt ; set temp HLT
mov cmdflg,18 ; set command flag = 19
mov doesc,offset workh5c ; set up ESC
jmp workx ; exit
;--------------------------------------------------------------
; escape from REDO
;
workh5c:mov bx,30h ; turn off highlight
call horzoff ; /
call clrhlt ; clear temp hlt
ret
;--------------------------------------------------------------
; NAME command, put new name in _savfn
;
workh6a:call curoff ; zip cursor
;
mov ah,2 ; bios set cursor position
mov bh,0 ; page 0
mov dx,1023H ; x,y of cursor
int 10H ; do bios int
;
mov _savfn,'.' ; clear the name area
call showfn ; /
mov _inbuf,9 ; 8 chars max
call getkey ; get them
;
mov cx,8 ; put them in savfn
mov bx,offset dgroup:_inbuf+2; /
mov di,offset dgroup:_savfn ; /
workh6b:mov al,[bx] ; get the char
cmp al,21h ; /
jb workh6d ; /
mov [di],al ; put char in savfn buffer
inc di ; bump fn pointer
inc bx ; bump cmd line pointer
loop workh6b ; loop to max of input chars
;
workh6d:mov byte ptr [di],'.' ; set up save extension
mov byte ptr 1[di],'M' ; /
mov byte ptr 2[di],'B' ; /
mov byte ptr 3[di],' ' ; /
mov byte ptr 4[di],0 ; /
call showfn ; show it
mov curadr,0a44h ; set cursor to 0th char
mov curonf,1 ; don't restore
call curon ; but turn it on
mov pdf,80h ; /
mov clrchf,1 ; setup to clear chanl
jmp workx ; exit
;--------------------------------------------------------------
; PATH command, set new directory path
;
workh7a:call curoff ; zip cursor
;
mov ax,0b800h ; set up video seg
mov es,ax ; /
mov bx,58H+(16*160) ; offset for line
mov ax,whi ; set color
mov cx,35 ; words in line
workh7b:mov es:[bx],ax ; set the word
inc bx ; bump
inc bx ; /
loop workh7b ; do the line
;
mov ah,2 ; bios set cursor position
mov bh,0 ; page 0
mov dx,102CH ; x,y of cursor
int 10H ; do bios int
;
mov _inbuf,36 ; 36 chars max
call getkey ; get them
mov al,_inbuf+1 ; get number of chars
mov ah,0 ; /
mov bx,offset dgroup:_inbuf+2;/
mov dx,bx ; save for path
add bx,ax ; point to end of string
mov byte ptr [bx],0 ; null terminate
;
mov ah,19h ; get current disk drive
int 21h ; dos call
mov _inbuf,al ; put it away
;
cmp byte ptr _inbuf+2,'\' ; directory or drive?
jz workh7c ; branch if directory
;
mov al,_inbuf+2 ; get the new drive
call touc ; make uppercase
sub al,'A' ; make A=0, B=1, etc.
mov dl,al ; set up for dos call
mov ah,0eh ; set default drive
int 21h ; dos call
;
cmp byte ptr _inbuf+4,'\' ; drive change only
jnz workh7d ; yes, don't change path
;
workh7c:mov ah,3bh ; set new path
mov dx,offset dgroup:_inbuf+2;/
int 21h ; dos call
jnc workh7d ; branch if ok
;
mov dl,_inbuf ; else get old drive
mov ah,0eh ; set default drive
int 21h ; dos call
;
workh7d:call dopath ; show it
call getdir ; show new directory
;
mov curadr,0a56h ; set cursor to 0th char
mov curonf,1 ; don't restore
call curon ; but turn it on
mov pdf,80h ; /
jmp workx ; exit
;==============================================================
; Process file area loads, set cmdflg = 20
;
workf0: call curoff ; zip cursor
mov bx,0b800H ; setup video seg
mov es,bx ; /
mov bx,curadr ; get cursor address
mov al,es:1[bx] ; get attribute byte
and al,lo ; strip highlight
cmp al,yellow ; got anything?
jz workf0a ; yes, branch
jmp workfq ; no, cancel the command
;
workf0a:cmp byte ptr es:[bx],' ' ; is it a letter
ja workf1 ; yes, go on
jmp workfq ; no, cancel
;
workf1: dec bx ; no, back up
dec bx ; /
cmp byte ptr es:[bx],' ' ; look for 1st non-letter
ja workf1 ; /
inc bx ; point to start
inc bx ; /
;
cmp cmdflg,20 ; ready to do it
jz workf1a ; yes, branch
cmp cmdflg,4 ; DEL
jz workf1b ; yes, branch
jmp workf8 ; no, exit
;
workf1a:test byte ptr es:1[bx],hi ; hi bit set
jnz workf1b ; yes, go on
jmp workfq ; no, cancel
;
workf1b:mov di,offset dgroup:_lodfn ; point to file text area
mov cx,8 ; 8 maximum to do
workf3: mov al,es:[bx] ; get first char
cmp al,' ' ; ignore spaces
jna workf2 ; /
mov [di],al ; put char in save file name buffer
inc bx ; bump screen pointer
inc bx ; /
inc di ; bump text pointer
loop workf3 ; loop to max
;
workf2: mov byte ptr [di],'.' ; set up extension
mov byte ptr 1[di],'M' ; /
mov byte ptr 2[di],'B' ; /
mov byte ptr 3[di],' ' ; /
mov byte ptr 4[di],0 ; /
;
cmp cmdflg,20 ; want to load?
jz workf2a ; yes, go do it
mov ah,41H ; else DEL file
mov dx,offset dgroup:_lodfn ; point to file name
int 21H ; zap it
mov cmdflg,0 ; clear the cmd
call getdir ; show directory enterys
mov pdf,80h ; reset mouse flag
mov curonf,1 ; don't restore
call curon ; but turn it on
mov bx,5a0h ; turn off DEL hilight
call turnoff ; /
jmp workx ; split
;
workf2a:
mov ah,3dh ; dos open file command
mov al,0 ; read only
mov dx,offset dgroup:_lodfn ; point to file name
int 21H ; open the file
jc workf6 ; exit if error
call lodmod0 ; load modules
;
workf6: call showfn ; show the save filename
call getdir ; show directory enterys
call dopath ; show current path
call dompab ; show mpad status
call menus ; draw menus
;
workfx: mov cmdflg,0 ; reset
mov pdf,80h ; fix mouse flag
workfz: mov curonf,1 ; don't restore
call curon ; but turn it on
call fixhlt ; fix hlt status
mov lodflg,2 ; flag that a load happened
jmp workx ; exit
;
workfq: mov pdf,80h ; /
jmp cancel ; so forget it
;--------------------------------------------------------------
; cmdflg was not alreay 20, setup new one
;
workf8: cmp cmdflg,0 ; was it clear?
jz workf9 ; yes, branch
jmp cancel ; no, cancel
;
workf9: mov dirptr,bx ; text location
call dirnon ; highlight
call tmphlt ; set temp HLT
mov cmdflg,20 ; set command flag = 20
mov doesc,offset workf10 ; set up ESC
mov curonf,1 ; don't restore
call curon ; but turn it on
jmp workx ; exit
;--------------------------------------------------------------
; escape from DIR load
;
workf10:call clrhlt ; fix hlt status
call dirnoff ; lowlight
ret
;--------------------------------------------------------------
; highlight a directory file name
; call with cursor OFF
;
dirnon: mov cx,8 ; 8 chars to do
mov bx,0b800h ; do page 0 only
mov es,bx ;
mov bx,dirptr ; get last picked name
dirnon1:
or byte ptr es:1[bx],hi ; make bright
inc bx ; bump pointer
inc bx ; /
loop dirnon1 ; do all 8
ret
;--------------------------------------------------------------
; loghlight a directory file name
; call with cursor ON
;
dirnoff:call curoff ; cursor on
mov cx,8 ; 8 chars to do
mov bx,0b800h ; do page 0 only
mov es,bx ;
mov bx,dirptr ; get last picked name
dirnoff1:
and byte ptr es:1[bx],lo ; make dark
inc bx ; bump pointer
inc bx ; /
loop dirnoff1 ; do all 8
mov curonf,1 ; don't restore
jmp curon ; keep it right
;==============================================================
; Process Screen command.
;
work0bx:jmp workx ; split
;
work00:
call curoff ; cursor off while reading screen
call cmdchk ; get new cmdloc, ptr, tag, cnt, & col
cmp vpagen,0 ; on page 0?
jz work0b ; yes, branch
cmp cmdflg,3 ; reincarnate?
jz work0b ; yes, branch
call varlst ; else find the variable list
or di,di ; is it good
jz work0b ; no, branch
mov varnow,di ; save it
work0b: call curon ; cursor back on
cmp cmdflg,3 ; move, copy, or reincarnate?
ja workp0 ; no, process other stuff
jmp work20a ; yes, branch
;--------------------------------------------------------------
; process pending commands > 3
; 4 = delete module
; 5 = priority swap
; 6 = bye
; 7 = user variable input
; 8 = flagged output to variable input
; 9 = special user input (magenta inputs )
;
workp0: cmp cmdflg,4 ; delete?
jnz workp1 ; /
jmp workpa ; yes, go do the delete
workp1: cmp cmdflg,5 ; priority?
jnz workp2 ; /
jmp work6 ; yes, go do the priority swap
workp2: cmp cmdflg,6 ; trying to QUIT
jnz workp3 ; /
jmp _cancel ; yes, kill it
workp3: cmp cmdflg,7 ; user input value?
jnz workp4 ; /
jmp _cancel ; yes, set it
workp4: cmp cmdflg,8 ; flagged output value?
jnz workp5 ; /
jmp work8 ; yes, go set the value
workp5: cmp cmdflg,9 ; special user input?
jnz workp6 ; /
jmp work9 ; yes, go process magenta stuff
workp6: cmp cmdflg,10 ; special user input?
jnz workp7 ; /
jmp work9 ; yes, go process magenta stuff
workp7: cmp cmdflg,16 ; EXIT?
jnz workp8 ; /
jmp _cancel ; yes, kill it
workp8: cmp cmdflg,17 ; UNDO?
jnz workp9 ; /
jmp _cancel ; yes, kill it
workp9: cmp cmdflg,18 ; REDO?
jnz workp10 ; /
jmp _cancel ; yes, kill it
workp10:cmp cmdflg,19 ; was SAVE set?
jnz workp11 ; /
jmp _cancel ; yes, kill it
workp11:cmp cmdflg,20 ; was directory load pending
jnz workp12 ; /
jmp _cancel ; yes, kill it
workp12:
workpq: mov cmdflg,0 ; no, clear the flag
jmp workx ; back to the work loop
;--------------------------------------------------------------
; no command pending above 3, check if cursor is a module,
; if it is branch to work2a to do the pending create or move.
; Otherwise, check color under cursor.
; If white branch to work2e to set up a pending move/create.
; If color is not white branch to work1 for further processing.
;
work20a:test curflg,1 ; already dragging something around?
jz work20c ; yes, go do something with it
jmp work2a ; /
work20c:cmp cmdcol,7 ; is this a module pickup?
jz work2e ; yes, go do it
jmp work1 ; no, go do something else
;==============================================================
; Module pickup requested: don't do anything except set the module
; to be the cursor (so it can be dragged around), and set cmdflg
; to indicate a pending module create or move. If currently on
; page 0, a new module will be created, if on any other page, the
; existing module will be moved. Nothing is done, however, until
; the next command request. Modules with "*" for the module number
; are not allowed to be picked up.
; Modules with "X" will be reincarnated.
;
work2e: cmp vpagen,0 ; is this page 0?
jnz work2d ; no, branch
mov bx,cmdloc ; get the module number
mov es,vpage ; /
cmp byte ptr es:2[bx],'*'; out of gas?
jnz work2e1 ; no, go on
jmp workx ; yes, exit
work2e1:cmp byte ptr es:2[bx],'X'; a deleted module?
jnz work2e2 ; no, go on
jmp workr ; yes, go reincarnate it.
work2e2:mov bx,cmdptr ; set up the cursor
mov ax,2[bx] ; ... to be the module
mov modchar,ax ; the module source text
call setmod ; ... is now the cursor
mov cmdflg,1 ; set the command flag
jmp workx ; back to the work loop
;==============================================================
; It's not on page 0, so setup a copy of the existing module
;
work2d: call curoff ; turn cursor off
mov ax,varnow ; get variable table address
mov tmpsav,ax ; save it
mov bx,cmdptr ; set up the cursor
mov ax,2[bx] ; ... to be the module
mov bx,ax ; point to module source text
mov di,offset dgroup:$dummy; gonna put it in the dummy
mov cx,[bx] ; get number of lines in module
mov [di],cx ; store in dummy buffer
add di,4 ; bump index
mov bx,cmdloc ; point to current screen text
mov es,vpage ; get current screen seg
work2d1:mov ax,es:-2[bx] ; get left word
mov [di],ax ; put in dummy
or byte ptr es:-1[bx],80h ; blink
inc di ; bump index
inc di ; /
mov ax,es:[bx] ; get center word
mov [di],ax ; put in dummy
or byte ptr es:1[bx],80h ; blink
inc di ; bump index
inc di ; /
mov ax,es:2[bx] ; get right word
mov [di],ax ; put in dummy
or byte ptr es:3[bx],80h ; blink
inc di ; bump index
inc di ; /
add bx,160 ; next line
loop work2d1 ; loop til done
mov modchar,offset dgroup:$dummy ; set dummy as cursor source
mov curonf,1 ; don't replace blinking label
call curon ; keep it even
call setmod ; dummy copy is now the cursor
mov cmdflg,2 ; set the command flag
mov doesc, offset work2dx; setup for ESC
jmp workx ; back to the work loop
;--------------------------------------------------------------
; escape from move
; fixes blinking module
;
work2dx:mov di,tmpsav ; find variable list
mov es,4[di] ; get screen seg
mov bx,6[di] ; get screen addr
mov di,[di] ; get number of lines
mov di,2[di] ; /
mov cx,[di] ; /
jmp unblink ; zip blinking
;==============================================================
; Set up to drag around a gost module (module # = "X")
;
workr: call curoff ; zip old cursor
mov bx,cmdptr ; set up new cursor...
mov tmpsav,bx ; (save MODSRC for later)
mov ax,2[bx] ; ... to be the module
mov bx,ax ; point to module source text
mov di,offset dgroup:$dummy; gonna put it in the dummy
mov cx,[bx] ; get number of lines in module
mov [di],cx ; store in dummy buffer
add di,4 ; bump index
add bx,4 ;
workr1: mov ax,[bx] ; get left word
mov [di],ax ; put in dummy
inc di ; bump index
inc di ; /
inc bx ; /
inc bx ; /
mov ax,[bx] ; get center word
mov [di],ax ; put in dummy
inc di ; bump index
inc di ; /
inc bx ; /
inc bx ; /
mov ax,[bx] ; get right word
cmp ah,white ; this a label?
jnz workr2 ; no, branch
mov al,'X' ; yes, change number to 'X'
workr2: mov [di],ax ; put in dummy
inc di ; bump index
inc di ; /
inc bx ; /
inc bx ; /
loop workr1 ; loop til done
mov modchar,offset dgroup:$dummy ; set dummy as cursor source
mov curonf,1 ; don't replace blinking label
call curon ; keep it even
call setmod ; dummy copy is now the cursor
mov cmdflg,3 ; set the command flag for reincarnate
jmp workx ; back to the work loop
;==============================================================
; case of not currently dragging something, color <> white
; possible commands (all not page 0):
; grey: priority swap
; cyan: flag output for value input from cmdflg = 7
; blue: value input from user
; green: value input from user
; magenta: user input
work1: cmp vpagen,0 ; in page 0
jz work1x ; yes, go back to the work loop
; ; no, ( process other commands)
cmp cmdcol,grey ; priority swap?
jnz work1b ; no, branch
jmp work60 ; yes, go do the priority swap
work1b: cmp cmdcol,blue ; value input from user?
jnz work1bb ; no, branch
jmp work70 ; yes, go do user input
work1bb:cmp cmdcol,green ; value input from user?
jnz work1c ; no, branch
jmp work70 ; yes, go do user input
work1c: cmp cmdcol,cyan ; output value flagged?
jnz work1d ; no, branch
jmp work80 ; yes, process output value flag
work1d: cmp cmdcol,magenta ; want special user input
jnz work1x ; no, branch
jmp work90 ; yes set up for special input
work1x: jmp workx ; and back to the work loop
;==============================================================
; Priority selected, set cmdflg = 5
;
work60: mov cmdflg,5 ; set the flag
call curoff ; turn cursor off
mov ax,varnow ; get variable table address
mov tmpsav,ax ; save it
mov bx,cmdtag ; highlight the command
mov es,vpage ; /
or byte ptr es:161[bx],7; /
or byte ptr es:163[bx],7; /
mov curonf,1 ; don't restore
call curon ; normal cursor
mov doesc,offset work61 ; set up for ESC
jmp workx ; back to the work loop
;--------------------------------------------------------------
; escape from priority swap
;
work61: mov di,tmpsav ; turn off highlight
mov es,4[di] ; get seg
mov bx,6[di] ; get addr
mov byte ptr es:161[bx],grey; zip hilight
mov byte ptr es:163[bx],grey; /
mov curonf,1 ; don't restore cursor
ret
;==============================================================
; Output flag selected, set cmdflg = 8
;
work80: mov cmdflg,8 ; set the flag
call curoff ; turn cursor off
mov ax,varnow ; get variable table address
mov tmpsav,ax ; save it
mov bx,cmdloc ; highlight the command
mov locsav,bx ; (save hilight addr)
mov es,vpage ; /
or byte ptr es:1[bx],hi; /
or byte ptr es:3[bx],hi; /
mov bx,cmdtag ; get icon tag
mov al,es:[bx] ; /
mov ah,es:2[bx] ; /
mov shosav,ax ; save it
mov curonf,1 ; don't restore
call curon ; normal cursor
mov doesc,offset work81 ; set up for ESC
jmp workx ; back to the work loop
;--------------------------------------------------------------
; escape from flag output command
;
work81: mov di,tmpsav ; turn off highlight
mov es,4[di] ; get seg
mov bx,locsav ; get addr
and byte ptr es:1[bx],lo; zip hilight
and byte ptr es:3[bx],lo; /
;--------------------------------------------------------------
; lowlight all inputs currently associated with output
; if shoflg = 1
;
test shoflg,1 ; wanna show inputs?
jz work81d ; no, branch
mov shoflg,0 ; yes, zip flag
mov ax,shosav ; get icon tag
push ds ; save data seg
mov cx,0b800H ; point to color screen
mov ds,cx ; /
mov cx,4000H ; 16K words to look at
mov bx,0 ; set up index
work81c:cmp al,[bx] ; got an icon match?
jz work81e ; yes, go look
;
work81b:inc bx ; no, bump address
inc bx ; /
loop work81c ; loop
pop ds ; restore data seg
mov pdf,80h ; reset mouse flag
work81d:mov curonf,1 ; don't restore cursor
ret ; exit
;
work81e:cmp ah,2[bx] ; got a module match
jnz work81b ; no, go loop
cmp byte ptr 1[bx],green OR hi; is it a green label?
jnz work81b ; no, go loop
and byte ptr 1[bx],lo; zip hilight
and byte ptr 3[bx],lo; /
jmp short work81b ; go to loop
;--------------------------------------------------------------
; process flagged output to become an input variable
;
work8: call curoff
cmp cmdcol,blue ; was an input variable selected?
jz work8y ; yes, do it
cmp cmdcol,green ; was an input variable selected?
jz work8y ; yes, go doit
cmp cmdcol,cyan OR hi; wanna show exitsting connections
jnz work8x ; no, exit
;--------------------------------------------------------------
; highlight all inputs currently associated with output
;
mov shoflg,1 ; set the show flag
call curoff ; turn cursor off
mov ax,shosav ; get module icon
push ds ; save data seg
mov cx,0b800H ; point to color screen
mov ds,cx ; /
mov cx,4000H ; 16K words to look at
mov bx,0 ; set up index
work80c:cmp al,[bx] ; got an icon match?
jz work80e ; yes, go look
;
work80b:inc bx ; no, bump address
inc bx ; /
loop work80c ; loop
;
pop ds ; restore data seg
mov curonf,1 ; don't restore
mov pdf,80h ; reset mouse flag
work8x: call curon ; normal cursor
jmp workx ; exit
;
work80e:cmp ah,2[bx] ; got a module match
jnz work80b ; no, go loop
cmp byte ptr 1[bx],green; is it a green label
jnz work80b ; no, go loop
or byte ptr 1[bx],hi;yes, set the highlight
or byte ptr 3[bx],hi; /
jmp short work80b ; go to loop
;--------------------------------------------------------------
; connect flagged output to input
;
work8y: mov cmdflg,0 ; yes, clear cmdflg
call work81 ; clear the highlight
mov bx,6[di] ; get the screen addr of source module
mov es,4[di] ; get screen seg of module
mov dl,es:[bx] ; dl = tag character
mov dh,es:2[bx] ; dh = module number tag
;
mov cx,di ; calculate the output address
add cx,8 ; cx = address of output value
;
mov es,vpage ; get current screen seg
mov bx,cmdloc ; get current variable pointer
mov es:[bx],dl ; set the label to input module
mov es:2[bx],dh ; /
mov al,green ; set the color to green
mov es:1[bx],al ; /
mov es:3[bx],al ; /
;
mov ax,0 ; find out which value it is
work80a:sub bx,160 ; /
add ax,2 ; /
cmp byte ptr es:1[bx],blue
jz work80a ; /
cmp byte ptr es:1[bx],green
jz work80a ; /
mov bx,ax ; bx = word offset to variables
mov di,varnow ; get current variable table
mov 10[bx+di],cx ; set address of new variable
;
call curon
jmp workx
;==============================================================
; User value input selected, set cmdflg = 7
;
work70: mov cmdflg,7 ; set the flag
call curoff ; turn cursor off
mov ax,varnow ; get variable table address
mov tmpsav,ax ; save it
mov bx,cmdloc ; highlight the command
mov locsav,bx ; (save hilight addr)
mov es,vpage ; /
or byte ptr es:1[bx],hi; /
or byte ptr es:3[bx],hi; /
mov ax,0 ; find out which value it is
work70a:sub bx,160 ; /
add ax,2 ; /
cmp byte ptr es:1[bx],blue;/
jz work70a ; /
cmp byte ptr es:1[bx],green
jz work70a ; /
mov holdv,ax ; save the offset
;
mov bx,holdv ; read current value
mov di,tmpsav ; get value table for module
mov bx,10[bx+di] ; bx = address of value
mov dl,[bx] ; dl = binary value
mov dh,0 ; make into a word
add dx,dx ; make into a word
add dx,offset dgroup:@zero; dx = address pointer into number table
mov bx,holdv ; get offset to the value
mov 10[bx+di],dx ; store the new value
mov bx,dx ; convert number addr to number
mov al,[bx] ; /
tohex ; convert it to ascii hex
mov es,4[di] ; get seg
mov bx,locsav ; get addr
mov es:[bx],ah ; display number
mov es:2[bx],al ; /
mov al,blue+hi ; set color to blue (may have been green)
mov es:1[bx],al ; /
mov es:3[bx],al ; /
;
mov curonf,1 ; don't restore
call curon ; normal cursor
mov doesc,offset work71; set up for ESC
mov al,curcol ; save cursor color
mov savcol,al ; /
mov ax,3 ; get current position
int 33h ; /
mov ax,7 ; don't move cursor
push dx ; /
mov dx,cx ; /
int 33h ; /
pop dx ; /
mov cx,dx ; /
mov ax,8 ; /
int 33h ; /
mov curcol,0 ; hide the cursor
mov valflg,1 ; flag value input is happening
jmp workx ; back to the work loop
;--------------------------------------------------------------
; escape from value input command
;
work71: mov di,tmpsav ; turn off highlight
mov es,4[di] ; get seg
mov bx,locsav ; get addr
and byte ptr es:1[bx],lo; zip hilight
and byte ptr es:3[bx],lo; /
mov al,savcol ; restore cursor color
mov curcol,al ; /
mov dx,199 ; maximum y
mov cx,0 ; minimum y
mov ax,8 ; set min, max allowable pdy values
int 33h ; /
mov ax,7 ; set min, max allowable pdx values
mov dx,639 ; maximum x
mov cx,0 ; minimum x
int 33h ; set it
mov es,vpage ; lowlight the menu readout
mov bx,960H ; addr of decimal readout
mov byte ptr es:1[bx],blue ; make dark
mov byte ptr es:3[bx],blue ; /
mov byte ptr es:5[bx],blue ; /
mov byte ptr es:7[bx],blue ; /
mov bx,0A00H ; addr of note readout
mov byte ptr es:1[bx],blue ; make dark
mov byte ptr es:3[bx],blue ; /
mov byte ptr es:5[bx],blue ; /
mov byte ptr es:7[bx],blue ; /
mov curonf,1 ; don't restore under cursor
mov valflg,0 ; finished with value input
ret
;--------------------------------------------------------------
; case of pdf = 0, cmdflg = 7, and change in pdx,pdy
; process value input from user
;
work72: call curoff ; cursor off
mov bx,holdv ; get offset to the value
mov di,tmpsav ; get value table for module
mov bx,10[bx+di] ; get adr of current value
mov dx,mickx ; get mickey count
add dx,[bx] ; add value to mickeys
jz work72b ; if = 0, go on
cmp dx,255 ; if = 255, go on
jz work72b ; /
test dh,128 ; if neg, make it 0
jz work72a ; /
mov dx,0 ; /
work72a:test dh,1 ; if > 255, make it 255
jz work72b ; /
mov dx,255 ; /
work72b:add dx,dx ; make into a word
mov di,tmpsav ; get value table for module
add dx,offset dgroup:@zero; dx = address pointer into number table
mov bx,holdv ; get offset to the value
mov 10[bx+di],dx ; store the new value
mov bx,dx ; convert number addr to number
mov al,[bx] ; /
push ax ; save for decimal conversion
tohex ; convert it to ascii hex
mov es,4[di] ; get seg
mov bx,locsav ; get addr
mov es:[bx],ah ; display number
mov es:2[bx],al ; /
mov al,blue+hi ; set color to blue (may have been green)
mov es:1[bx],al ; /
mov es:3[bx],al ; /
mov bx,960H ; address of decimal readout
mov colr,blue+hi ; set highlight blue
pop ax ; get the number again
call todec ; show it in decimal
mov bx,0A00h ; address of note readout
call tonote ; show it as CM scale
mov curonf,1 ; don't restore cursor
call curon ; turn it back on
work72x:jmp workx ; exit
;==============================================================
; Special User input selected, set cmdflg = 9
; magflg gets set here:
; no-value--> 0
; up/down --> 1
; channel --> 2
; value --> 3
;
work90: mov cmdflg,9 ; else set the flag for channel value
call curoff ; turn cursor off
mov di,varnow ; get variable table address
mov tmpsav,di ; save it
mov varsav,di ; save it
mov bx,[di] ; get exe addr of special routine
mov ax,40[bx] ; ax = exec addr of special
mov special,ax ; save it
mov bx,cmdloc ; highlight the command
mov locsav,bx ; (save hilight addr)
mov es,vpage ; /
mov magflg,0 ; set flag for no-value
cmp byte ptr es:[bx],'#'; is this a no-value cmd
jz work90b ; yes, set up for no-value
inc magflg ; no, set flag for up/down
cmp byte ptr es:[bx],1eh; branch if up/down
jz work90b ; /
or byte ptr es:1[bx],hi; highlight single for channel
inc magflg ; set magenta flag for channel
cmp byte ptr es:3[bx],white; is this a channel cmd
jz work90b ; yes, branch
inc magflg ; no, set up for value change
or byte ptr es:3[bx],hi; highlight double for value
work90b:mov ax,0 ; find out which value it is
work90a:sub bx,160 ; /
add ax,2 ; /
cmp byte ptr es:1[bx],magenta
jz work90a ; /
mov holdv,ax ; save the offset
mov curonf,1 ; don't restore
call curon ; normal cursor
cmp magflg,3 ; want value input?
jnz work90x ; no, exit
mov al,curcol ; save cursor color
mov savcol,al ; /
mov ax,3 ; get current position
int 33h ; /
mov ax,7 ; don't move cursor
push dx ; /
mov dx,cx ; /
int 33h ; /
pop dx ; /
mov cx,dx ; /
mov ax,8 ; /
int 33h ; /
mov curcol,0 ; hide the cursor
work90x:mov doesc,offset work91 ; set up for ESC
mov usrflg,1 ; flag user input is happening
mov ax,special ; get the special routine
call ax ; do it
jmp workx ; back to the work loop
;--------------------------------------------------------------
; escape from special user command
;
work91: mov usrflg,0 ; clear happening flag
cmp magflg,3 ; data input
jnz work91a ; no, branch
jmp work71 ; yes, same as blue
;
work91a:mov di,varsav ; turn off highlight
mov es,4[di] ; get seg
mov bx,locsav ; get addr
and byte ptr es:1[bx],lo; zip hilight
mov ax,offset noop ; reset special
mov special,ax ; /
mov curonf,1 ; don't restore cursor
ret ; return from call
;--------------------------------------------------------------
; process special user input routine
;
work9: mov cmdflg,0
mov usrflg,0
mov ax,special
jmp ax
;--------------------------------------------------------------
; special user input routines
; case of pdf = 0, cmdflg = 9, and change in pdx,pdy
; process value input from user
;
work92: cmp magflg,2 ; want channel?
jz work92a ; yes, branch
cmp magflg,3 ; want data?
jz work92e ; yes, branch
jmp workx ; no, exit
work92a:mov dl,pdx ; get x value
sub dl,8 ; offset by 8
jnb work92d ; branch if ok
mov dl,0 ; else set to 0
work92d:cmp dl,63 ; max is 63
jna work92b ; branch if ok
mov dl,63 ; else max out
work92b:shr dl,1 ; /4
shr dl,1 ; /
and dl,0fH ; only use low nybble
mov al,dl ; load with x value
mov di,varsav ; get value table for module
mov byte ptr 8[di],dl; save in the output location
tohex ; convert it to ascii hex
mov es,4[di] ; get seg
mov bx,locsav ; get addr
mov es:[bx],al ; display number
;
jmp workx ; exit
work92e:
call curoff ; cursor off
mov bx,holdv ; get offset to the value
mov di,varsav ; get value table for module
mov dl,10[bx+di] ; get current value
mov dh,0 ; /
add dx,mickx ; get mickey count
jz work92g ; if = 0, go on
cmp dx,255 ; if = 255, go on
jz work92g ; /
test dh,128 ; if neg, make it 0
jz work92f ; /
mov dx,0 ; /
work92f:test dh,1 ; if > 255, make it 255
jz work92g ; /
mov dx,255 ; /
work92g:mov di,varsav ; get value table for module
mov bx,holdv ; get offset to the value
mov 10[bx+di],dl ; store the new value
mov ax,dx ; get value to ax
push ax ; save for decimal conversion
tohex ; convert it to ascii hex
mov es,4[di] ; get seg
mov bx,locsav ; get addr
mov es:[bx],ah ; display number
mov es:2[bx],al ; /
mov colr,magenta+hi ; set hilighted magenta
pop ax ; get the number again
mov bx,960H ; address of decimal readout
call todec ; show it in decimal
mov bx,0A00h ; address of note readout
call tonote ; show it as CM scale
mov curonf,1 ; don't restore cursor
call curon ; turn it back on
jmp workx ; exit
;==============================================================
; have been dragging a module around, now want to do something with it
;
work2a: call setcur ; set normal cursor again
call curoff ; and then turn it off
work2b: cmp vpagen,0 ; now in page 0 ?
jnz work2b1 ; no, continue
jmp work3 ; yes, go get a new module
work2b1:cmp cmdflg,1 ; was last command "create module"?
jz work2c ; yes, go do it
cmp cmdflg,2 ; no, was it "copy module"?
jz work2b2 ; yes, go do it
jmp work5 ; no, go do "reincarnate module"
work2b2:jmp work4 ; go do "copy module"
;==============================================================
; Want to create a new module. Check that there is enough empty
; space on the screen, and if ok, draw the module.
;
work2c: mov es,vpage ; pick up video page segment
mov bx,curadr ; current cursor offset
mov di,modchar ; point to module char source
mov cx,[di] ; get the line count
mov ax,0 ; clear register
work2f: or al,es:1[bx] ; look to see that there is space
or al,es:-1[bx] ; /
or al,es:3[bx] ; /
add bx,160 ; /
loop work2f ; /
or al,al ; was there?
jz work2g ; yes, branch
call setmod ; no, continue dragging the module around
jmp workx ; back to work
;--------------------------------------------------------------
; There is enough space on the screen, show the module
;
work2g: mov cmdflg,0 ; clear the command flag
mov cx,[di] ; get module line count again
add di,4 ; point to 1st char
mov bx,curadr ; cursor address
dec bx ; shift for module
dec bx ; /
call shomod$ ; show the module
mov bx,curadr ; cursor address
mov ax,last ; get priority
showp ; show priority
;--------------------------------------------------------------
; set up exetbl enteries, variable space, and pointers thereto
;
mov bx,offset dgroup:_exetbl; calc addr of last module
mov ax,last ; /
add ax,ax ; /
add ax,ax ; /
add bx,ax ; /
mov di,cmdptr ; get address of modsrc table
mov ax,[di] ; get module exe addr
mov [bx],ax ; put it in exetbl
mov ax,varptr ; get end of variable table
mov 2[bx],ax ; put it in exetbl
mov ax,offset work ; get exe addr of work
mov 4[bx],ax ; put it at the end of the exetbl
mov ax,4[di] ; get variable allocation for module
mov dx,ax ; (dx=variable allocation)
add ax,ax ; *2 for word
add ax,14 ; plus static allocation
mov bx,varptr ; get current variable address
add ax,bx ; ax = next one, bx = this one
mov varptr,ax ; set varptr to new end of list
;--------------------------------------------------------------
; build the variable list
;
mov [bx],di ; first word is modsrc addr
mov ax,last ; get priority
mov 2[bx],ax ; second word is priority
push bx ; save variable list pointer for later
inc ax ; bump index
and ax,maxmods ; limit to 512 active modules
mov last,ax ; store it
mov ax,vpage ; current display seg addr
mov 4[bx],ax ; third word is vpage seg address
mov ax,curadr ; current head of module text
mov 6[bx],ax ; forth word is addr of module label
mov word ptr 8[bx],0; fifth word is module output
mov 10[bx],dx ; sixth word is variable alloc count
add bx,12 ; point to start of variables
mov cx,4[di] ; get number of variables allocated
or cx,cx ; got at least one?
jnz work2h ; yes, branch
inc cx ; always make at least one
work2h: mov word ptr [bx], offset dgroup:@zero; set variables to zero
inc bx ; point to next
inc bx ; /
loop work2h ; loop til done
mov bx,-2 ; find out the module number
work2i: add bx,2 ; /
cmp word ptr 6[bx+di],0; /
jnz work2i ; bx = module number *2
mov ax,bx ; get actual number
shr ax,1 ; /
mov modnum,al ; save it for the other guys
pop ax ; get variable list ptr from stack
mov 6[bx+di],ax ; put it in modsrc
mov di,2[di] ; get source text for the module
; mov bx,2[di] ; get page 0 address
mov bx,cmdtag ; get page 0 address
mov ax,0b800H ; page 0 segment
mov es,ax ; set up seg reg for page 0
mov al,byte ptr es:2[bx]; get the current module number
mov ah,al ; copy it
inc ah ; bump
cmp al,'$' ; system module?
jnz work2j ; no, branch
mov ah,'*' ; yes, show "in use"
work2j: cmp ah,':' ; did it go from 9->10?
jnz work2k ; no, branch
mov ah,'A' ; yes, funky hex conversion
work2k: cmp ah,'G' ; >16?
jnz work2l ; no, branch
mov ah,'*' ; yes, show "in use"
work2l: mov byte ptr es:2[bx],ah; set new module number
mov byte ptr 8[di],ah; set it in the source
;--------------------------------------------------------------
; finish up by turning on the regular cursor, going back to work
;
mov curonf,1 ; don't restore old cursor
call curon ; normal cursor
jmp workx ; back to the grind
;==============================================================
; command was "create", now another page 0 module is selected,
; zip pending command, kill module cursor
;
work3: cmp cmdflg,2 ; stray move?
jnz work3a ; no, branch
jmp cancel ; yes, cancel the command
work3a: mov cmdflg,0 ; zip pending command
mov curonf,1 ; don't restore old cursor
call curon ; drop module and exit
jmp workx ; ...back to the work loop
;==============================================================
; Want to move an existing module. Check that there is enough empty
; space on the screen, and if ok, draw the module.
;
work4: mov es,vpage ; pick up video page segment
mov bx,curadr ; current cursor offset
mov di,modchar ; point to module char source
mov cx,[di] ; get the line count
mov al,0 ; clear register
work4a: test byte ptr es:1[bx],80h ; look to see that there is space
jnz work4aa ; blinking counts as 0
or al,es:1[bx] ; /
work4aa:test byte ptr es:-1[bx],80h; /
jnz work4ab ; /
or ax,es:-1[bx] ; /
work4ab:test byte ptr es:3[bx],80h; /
jnz work4ac ; /
or ax,es:3[bx] ; /
work4ac:add bx,160 ; /
loop work4a ; /
or al,al ; the final test
jz work4b ; nothing there, branch to the move
call setmod ; else continue dragging the module around
jmp workx ; back to work
;--------------------------------------------------------------
; There is enough space, erase the old module,
; then display it in its new location.
; First find old module's location page.
;
work4b: mov di,tmpsav ; get varlist of source module
mov es,4[di] ; get seg of source module display
mov bx,6[di] ; get offset of tag
;--------------------------------------------------------------
; Now erase the old module.
;
mov di,[di] ; di = modsrc(old_varlist)
mov di,2[di] ; di = txtadr(modsrc(old_varlist))
mov cx,[di] ; cx = line count
call eramod$ ; erase the old module
;--------------------------------------------------------------
; Show the module in its new location
;
mov cmdflg,0 ; clear the command flag
mov di,modchar ; point to module char source
mov cx,[di] ; get module line count again
add di,4 ; point to 1st char
mov bx,curadr ; cursor address
dec bx ; shift for module
dec bx ; /
mov es,vpage ; get current screen seg addr
call shomod$ ; show the module
;--------------------------------------------------------------
; set new screen location in the variable list
;
mov di,tmpsav ; get varlist of source module
mov ax,vpage ; get current seg
mov 4[di],ax ; put it in the list
mov ax,curadr ; get cursor addr
mov 6[di],ax ; in the list
;--------------------------------------------------------------
; finish up by turning on the regular cursor, going back to work
;
work4x: mov curonf,1 ; don't restore old cursor
call curon ; normal cursor
jmp workx ; back to the grind
;==============================================================
; Have been dragging a gost around, now it's time to reincarnate.
; Check that there is enough empty space on the screen.
;
work5: mov es,vpage ; pick up video page segment
mov bx,curadr ; current cursor offset
mov di,modchar ; point to module char source
mov cx,[di] ; get the line count
mov ax,0 ; clear register
work5a: or al,es:1[bx] ; look to see that there is space
or al,es:-1[bx] ; /
or al,es:3[bx] ; /
add bx,160 ; /
loop work5a ; /
or al,al ; was there?
jz work5b ; yes, branch
call setmod ; no, continue dragging the module around
jmp workx ; back to work
;--------------------------------------------------------------
; There is enough space. Get a delete flag from MODSRC,
; Use it as a pointer to the variable list.
;
work5b: mov di,tmpsav ; get last modsrc
mov ax,38[di] ; get the bit flags
call frombit ; convert to a number
push ax ; save a copy for later
mov bx,ax ; convert to an address offset
add bx,bx ; /
mov bx,6[bx+di] ; bx = address of the variable table
call tobit ; mask out the reincarnated bit
xor ax,-1 ; /
and 38[di],ax ; /
jnz work5c ; branch if there are more delete flags
;--------------------------------------------------------------
; no more delete flags, fix 'X'
;
push bx ; save variable table pointer
mov bx,-2 ; find out the module number
work5d: add bx,2 ; /
cmp word ptr 6[bx+di],0; /
jnz work5d ; bx = module number *2
shr bx,1 ; /2
mov al,'*' ; load
cmp bl,16 ; last module?
jz work5e ; yes, branch using '*'
mov al,bl ; no, use the module number
tohex ; convert to ascii hex
work5e: mov bx,2[di] ; find text address
mov bx,2[bx] ; bx = page0 screen offset
mov dx,0b800h ; set page0 seg
mov es,dx ; /
cmp word ptr 36[di],-1; system module?
jnz work5e0 ; no, branch
mov al,'*' ; yes, use * instead of number
work5e0:mov es:4[bx],al ; set the module number
pop bx ; restore the variable table addr
;--------------------------------------------------------------
; restore the original module number and priority number
;
work5c: mov dx,2[bx] ; get priority number
pop ax ; get the module number
tohex ; convert to ascii hex
push bx ; save the variable table addr
mov bx,modchar ; point to $dummy
cmp word ptr 36[di],-1; system module?
jnz work5c0 ; no, branch
mov al,'$' ; yes, use $ instead of number
work5c0:mov 8[bx],al ; set the current module number
mov ax,dx ; get lsb of priority number
and ah,1 ; do ms byte
xor ah,1 ; /
add ah,0f8h ; /
mov 10[bx],ah ; /
tohex ; convert to ascii hex
mov 12[bx],ah ; set the priority number
mov 14[bx],al ; /
pop bx ; restore variable table addr
;--------------------------------------------------------------
; update the variable table
;
mov ax,vpage ; get current seg addr
mov 4[bx],ax ; put in seg slot of var table
mov ax,curadr ; current cursor offset
mov 6[bx],ax ; put in addr slot of var table
mov cx,10[bx] ; get number of variables allocated
or cx,cx ; don't do it if 0 variables
jz work5f ; /
push bx ; save variable pointer
work5g: mov word ptr 12[bx], offset dgroup:@zero; set variables to zero
inc bx ; point to next
inc bx ; /
loop work5g ; loop til done
pop bx ; restore variable pointer
work5f: mov word ptr 8[bx],0; set output to 0
;--------------------------------------------------------------
; reactivate by inserting the module exe addr in the exe table
;
mov di,[bx] ; get modsrc addr
mov di,[di] ; di = exe addr of module
mov bx,2[bx] ; get priority
add bx,bx ; *4
add bx,bx ; /
add bx,offset dgroup:_exetbl;bx = addr position in exetbl
mov [bx],di ; replace dummy with the real one
;--------------------------------------------------------------
; Show the module in its new location
;
mov cmdflg,0 ; clear the command flag
mov di,modchar ; point to module char source
mov cx,[di] ; get module line count again
add di,4 ; point to 1st char
mov bx,curadr ; cursor address
dec bx ; shift for module
dec bx ; /
mov es,vpage ; get current screen seg addr
call shomod$ ; show the module
;--------------------------------------------------------------
; finish up by turning on the regular cursor, going back to work
;
work5x: mov curonf,1 ; don't restore old cursor
call curon ; normal cursor
jmp workx ; back to the grind
;==============================================================
; Priority swap was pending, now do it.
;
work6: call curoff ; turn cursor off
mov bx,tmpsav ; get saved variable table
mov es,4[bx] ; get seg of last screen
mov bx,6[bx] ; get offset of last screen
mov byte ptr es:161[bx],grey; turn off hilight
mov byte ptr es:163[bx],grey; /
;
mov di,tmpsav ; old variable table
mov si,varnow ; new variable table
mov ax,2[di] ; get old priority #
mov dx,ax ; dx = old priority #
xchg ax,2[si] ; swap with new
mov 2[di],ax ; /
;
add ax,ax ; convert to exetbl addr
add ax,ax ; /
add ax,offset dgroup:_exetbl; ax = new exetbl addr
mov bx,ax ; bx = new exetbl addr
mov ax,[bx] ; ax = new exe addr
mov cx,2[bx] ; cx = new vartbl addr
add dx,dx ; convert old # to exetbl addr
add dx,dx ; /
add dx,offset dgroup:_exetbl; dx = old exetbl addr
mov bp,dx ; bp = old exetbl addr
xchg ax,ds:[bp] ; swap exe addrs
mov [bx],ax ; /
xchg cx,ds:2[bp] ; swap vartbl addrs
mov 2[bx],cx ; /
;
mov es,4[si] ; get screen seg of new
mov bx,6[si] ; get screen addr of new
mov ax,2[si] ; get priority #
showp ; show priority
mov es,4[di] ; get screen seg of old
mov bx,6[di] ; get screen addr of old
mov ax,2[di] ; get priority #
showp ; show priority
;
mov cmdflg,0 ; clear the command
mov curonf,1 ; don't restore
call curon ; normal cursor
jmp workx ; back to the work loop
;==============================================================
; Delete Module was pending, now it's time to do it.
;
workpa: cmp vpage,0 ; page 0 ?
jnz workpa0 ; no, branch
jmp workpz ; yes, exit
;
workpa0:test cmdcol,80H ; valid color
jnz workpz ; no, exit
;
mov bx,5a0h ; offset for DEL
call turnoff ; turn off highlight
call curoff ; turn off cursor
;
mov di,cmdptr ; find out which module #
mov bx,0 ; counter offset
mov ax,varnow ; get current variable list
workpb: cmp 6[di+bx],ax ; look for a match
jz workpc ; branch if found
add bx,2 ; else bump index
cmp bx,32 ; split if not found
jz workpx ; /
jmp short workpb ; loop
; ; bx = module # *2
workpc: mov al,bl ; al = module # *2
shr al,1 ; al = module #
call tobit ; ax = bit pattern
or 38[di],ax ; flag module as deleted
mov di,varnow ; get variable list
mov bx,2[di] ; get priority
add bx,bx ; *4
add bx,bx ; /
add bx,offset dgroup:_exetbl; point to position in exetable
mov word ptr [bx],offset _dummy ; insert dummy
; ; set up to erase the module from screen
mov es,4[di] ; get seg of module display
mov bx,6[di] ; get offset of tag
;
mov word ptr 4[di],0b000H; set illegal display seg
mov word ptr 6[di],-1; set illegal display offset
;
mov di,[di] ; di = modsrc(varlist)
mov di,2[di] ; di = txtadr(modsrc(varlist))
mov cx,[di] ; cx = line count
call eramod$ ; erase the old module
; ; mark source as erased
mov di,cmdptr ; get source text
mov di,2[di] ; di = txtadr(modsrc(cmdptr)))
mov bx,2[di] ; bx = screen address of source text
mov ax,0b800h ; set page0 seg
mov es,ax ; /
mov byte ptr es:4[bx],'X' ; mark source as deleted
; ; finish up and exit
workpx: mov curonf,1 ; don't restore under cursor
call curon ; cursor back on
mov cmdflg,0 ; clear command flag
workpz: jmp workx ; exit
;==============================================================
; End of WORK. If not HLT'd or module cursor, reset SI to the head
; of the module list, and run through the modules again.
;
public workx
workx:
test midixsf,1 ; external sync input?
jz workxa ; no, branch
mov al,midixs ; yes, get xtrn sync
cmp al,midiss ; same as before?
jz workxx ; yes, back to loop
mov midiss,al ; no, reset saved count
mov tickis,al ; set alpha display
jmp short workx2 ; go to work
;
workxa:
test asensf,-1 ; want active sensing?
jz workxas ; no, branch
test byte ptr ticks,7fh; time for active sensing?
jnz workxas ; branch if not needed yet
mov al,0feh ; send MIDI active sensing
call allmidi ; /
workxas:sendmb
;
test fastflg,-1 ; fast flag set
jnz workx4 ; yes, branch
test byte ptr cs:timer,255; timer zeroed out?
jz workx4 ; yes, branch
test waiting,-1 ; have been waiting?
jnz workxx ; yes, do housekeeping again
mov waiting,1 ; no, set flag
mov al,byte ptr cs:timer; get current timer value
mov tickis,al ; save it
workxx: sendmb ; send midi byte, if any
jmp work ; go do housekeeping
;
workx4: mov al,ticka ; get new timer value
mov byte ptr cs:timer,al; put it in the timer
test waiting,-1 ; was waiting?
jnz workx2 ; yes, branch
mov tickis,0 ; no, zip tick readout
workx2: mov waiting,0 ; not waiting now
;
workx0: cmp mmreset,0 ; want to reset measures?
jnz workx5 ; no, branch
mov mmcount,0 ; yes, reset measure count
mov mmreset,0 ; clear flag on sync
jmp short workx6 ; set new measure
;
workx5: mov mmstart,0 ; flag not end of measure
dec mmtick ; kick measure timer
jnz workx3 ; branch if really not eom
workx6: mov ax,mclocks ; else reload timer
mov mmtick,ax ; /
mov mmstart,1 ; flag start of measure
inc mmcount ; bump measure count
mov ax,mmcount ; else display measure count
mov bx,vpage ; current video page
mov es,bx ; /
mov bx,160*13 ; address of decimal readout
call toddec ; display
;
workx3: ;
test secondf,-1 ; new seconds count?
jz workx9 ; no, branch
mov secondf,0 ; yes, clear the flag
mov ax,seconds ; display seconds count
mov bx,vpage ; current video page
mov es,bx ; /
mov bx,160*14 ; address of decimal readout
call toddec ; display
;
workx9: test lodflg,-1 ; lodflg aready 0
jz workx9a ; yes, do nothing
dec lodflg ; else dec the flag
;
workx9a:test clrchf,2 ; channel cleared?
jz workx7 ; no, branch
mov clrchf,0 ; yes, clear flag
;
workx7: cmp pdx,3 ; in menu area
jnb workx7e ; no, branch
cmp pdy,17 ; in mute area
jb workx7e ; no, branch
workx7e:mov bx,vpage ; get video page
mov es,bx ; es = current video page
mov bx,160*17 ; point to menu area
inc bx ; point to highlight byte
mov dx,mute ; get mute flags
mov al,hi ; hi if not mute
mov ah,lo ; lo if mute
mov cx,8 ; 8 * 2 mute flags
workx7l:ror dx,1 ; pop even flag
jc workx7a ; branch if mute
or es:[bx],al ; set hi if not mute
jmp short workx7b ; branch
workx7a:and es:[bx],ah ; set lo if mute
workx7b:ror dx,1 ; pop odd flag
jc workx7c ; branch if mute
or es:4[bx],al ; set hi if not mute
jmp short workx7d ; branch
workx7c:and es:4[bx],ah ; set lo if mute
workx7d:add bx,160 ; next line
loop workx7l ; do 8 pairs
;
test midisf,1 ; midi sync flag on?
jz workx8a ; no, branch
mov al,0f8h ; yes, send one
mov midip,0 ; ... only to port 0
call tomidi ; /
;
workx8a:inc cs:loops ; inc loop counter
mov si,offset dgroup:_exetbl; point to start of table
mov di,2[si] ; set di pointing to variable list
jmp [si] ; go for it
;--------------------------------------------------------------
; cleanup & exit
public split
split: call curoff ; turn pd cursor off
split1: mov dx,seg dgroup ; set up ds
mov ds,dx ; /
mov al,0 ; set vpage0
call page ;
call cls ; clear screen
mov ah,2 ; set cursor to top of screen
mov dx,0 ; /
mov bh,dh ; /
int 10H ; /
mov ah,1 ; turn dos cursor on
mov ch,6 ; /
mov cl,7 ; /
int 10H ; /
call stopt ; stop system timer
call stopm ; stop mpu ints
;
mov dx,byemsg ; get exit message
or dx,dx ; anything there
jz split2 ; no, branch
mov ah,9 ; dos print string
int 21h ; dos call
split2: ;
if withc ; if compiled with C
pop di ; restore C regs
pop si ; /
pop bp ; /
pop es ; /
ret ; back to C
else ; if assembley
;
mov ax,4c00h ; then do assembly exit
int 21h ; split
endif
;==============================================================
; routines used by WORK
;--------------------------------------------------------------
; Return to di the varlist for the currently selected module.
; Assumes the current module tag address is in CMDTAG, and
; the current page address is in VPAGE. Error if DI = 0 on return.
;
varlst: mov bp,offset dgroup:_exetbl ; point to start of table
mov dx,vpage ; dx = current seg
mov cx,cmdtag ; cx = current module addr
varlst0:mov di,0 ; err if 0 returned
cmp word ptr ds:[bp],offset work; exit when list is exausted
jz varlstx ; /
mov di,ds:2[bp] ; get the variable list
cmp 4[di],dx ; right seg?
jnz varlst2 ; /
cmp 6[di],cx ; right address?
jz varlstx ; yes, exit
varlst2:add bp,4 ; bump to next module
jmp short varlst0 ; loop
varlstx:ret ; exit with di=varlist addr
;--------------------------------------------------------------
; look at color at the cursor (CURADR), if it is one of the
; command colors, set up CMDCOL, CMDCNT, CMDLOC, CMDTAG & CMDPTR,
; otherwise clear CMDCOL and exit with no further action.
; Normally, this routine will be called only if pdf = 1.
;
cmdchk proc near
mov es,vpage ; get screen segment
mov bx,curadr ; get cursor offset
mov dl,es:1[bx] ; get the color
cmp dl,white ; compare against command color list
jz cmdchk1 ; branch out if good
cmp dl,grey ; /
jz cmdchk1 ; /
cmp dl,cyan ; /
jz cmdchk1 ; /
cmp dl,cyan OR hi ; /
jz cmdchk1 ; /
cmp dl,blue ; /
jz cmdchk1 ; /
cmp dl,green ; /
jz cmdchk1 ; /
cmp dl,magenta ; /
jz cmdchk1 ; /
or dl,80H ; not on list, flag ng color
mov cmdcol,dl ; /
ret ; exit
cmdchk1:mov cmdcol,dl ; is good, set the color
cmp dl,es:-1[bx] ; look left
jnz cmdchk2 ; branch if not same color
dec bx ; else bump address left
dec bx ; /
cmdchk2:mov cmdloc,bx ; save the location
mov cmdcnt,0 ; default count is 0
cmp dl,blue ; check for blue or green
jz cmdchk3 ; /
cmp dl,green ; /
jz cmdchk3 ; /
cmp dl,magenta ; check for magenta
jnz cmdchk3 ; no, go on
cmp curadr,0f9ch ; test for lower left
jnb cmdchk4 ; /
cmp byte ptr es:5[bx],white ; left of top label?
jnz cmdchk4 ; no, branch
add bx,2 ; yes, bump to label
jmp short cmdchk4 ; branch around count
;
cmdchk3:mov dh,-1 ; blue or green needs count
cmdchk5:inc dh ; dh = count
sub bx,160 ; up one line
cmp byte ptr es:1[bx],blue; look for blue or green
jz cmdchk5 ; /
cmp byte ptr es:1[bx],green;/
jz cmdchk5 ; look until color not blue or green
cmp byte ptr es:1[bx],magenta
jz cmdchk5 ; look until color not magenta
mov cmdcnt,dh ; set the count
mov bx,cmdloc ; restore bx
cmdchk4:cmp byte ptr es:1[bx],white; look for white
jz cmdchk6 ; exit loop when found
sub bx,160 ; back one line
jmp short cmdchk4 ; /
cmdchk6:mov cmdtag,bx ; save the tag address
mov al,byte ptr es:[bx] ; get the character
mov ah,0 ; make it into an address
add ax,ax ; /
mov di,offset dgroup:_chrtbl; find the ptr for that char
add di,ax ; /
mov ax,[di] ; /
mov cmdptr,ax ; /
ret ; exit
cmdchk endp
;--------------------------------------------------------------
; use module text for cursor
;
setmod proc near
call curoff ; turn off regular cursor
mov di,modchar ; get line size
mov ax,[di] ; /
add ax,ax ; convert to pixel addr
add ax,ax ; /
add ax,ax ; /
mov dx,200 ; subtract from max
sub dx,ax ; dx = maximum pdy for this char
mov cx,0 ; 0 = minimum pdy
mov ax,8 ; set min, max allowable pdy values
int 33h ; /
mov ax,7 ; set min, max allowable pdx values
mov dx,631 ; maximum x
mov cx,8 ; minimum x
int 33h ; set it
;
mov execur,offset modcur; do show-modules
mov curflg,1 ; flag special cursor
call curon ; continue
ret
setmod endp
;--------------------------------------------------------------
; use module text for cursor
;
setcur proc near
call curoff ; stop pd interupts
mov dx,199 ; maximum y
mov cx,0 ; minimum y
mov ax,8 ; set min, max allowable pdy values
int 33h ; /
mov ax,7 ; set min, max allowable pdx values
mov dx,639 ; maximum x
mov cx,0 ; minimum x
int 33h ; set it
;
mov execur,0 ; no special cursors
mov curflg,0 ; /
call curon ; continue
ret
setcur endp
;--------------------------------------------------------------
; Turn on menu command highlight.
; call with cursor on, bx = menu text offset
;
public turnon
turnon: push bx ; save text addr
call curoff ; zip cursor
pop bx ; get text addr
mov dx,0b800h ; do all 8 pages
mov cx,8 ; /
turnon1:mov es,dx ; set the page seg
or byte ptr es:1[bx],8 ; make bright
or byte ptr es:3[bx],8 ; /
or byte ptr es:5[bx],8 ; /
inc dh ; next page
loop turnon1 ; loop til done
mov curonf,1 ; don't restore
jmp curon ; cursor normal
;--------------------------------------------------------------
; Turn off menu command highlight.
; call with cursor on, bx = menu text offset
;
public turnoff
turnoff:push bx ; save text addr
call curoff ; zip cursor
pop bx ; get text addr
mov dx,0b800h ; do all 8 pages
mov cx,8 ; /
turnoff1:mov es,dx ; set the page seg
and byte ptr es:1[bx],0f7h ; make dark
and byte ptr es:3[bx],0f7h ; /
and byte ptr es:5[bx],0f7h ; /
inc dh ; next page
loop turnoff1 ; loop til done
mov curonf,1 ; don't restore
jmp curon ; keep it right
;--------------------------------------------------------------
; convert binary in al to decimal in in screen location es:bx
; all registers preserved
;
public todec
todec: push dx ; save registers
mov dl,al ; /
push ax ; /
push bx ; /
push cx ; /
add bx,4 ; start at ls digit
mov cx,3 ; initialize counter
todec1: cmp dl,0 ; if 0, do shortcut
jnz todec0 ; /
mov al,30H ; ascii bias if 0
jmp short todec2 ; /
todec0: push cx ; save outer loop
mov al,dl ; ax = numerator
mov ah,0 ; /
mov cl,10 ; divisor of 10
div cl ; divide
mov dl,al ; get quotient
mov al,ah ; get remainder
add al,30h ; add ASCII bias
pop cx ; get loop counter
todec2: mov es:[bx],al ; put to the screen
dec bx ; bump count address
dec bx ; /
loop todec1 ; do 3 digits
mov al,valflg ; mouse input?
or al,usrflg ; /
jz todec3 ; no, branch
mov al,colr ; yes, set color
mov es:3[bx],al ; /
mov es:5[bx],al ; /
mov es:7[bx],al ; /
todec3: pop cx ; restore registers
pop bx ; /
pop ax ; /
pop dx ; /
ret ; exit
;--------------------------------------------------------------
; convert binary in ax to decimal in in screen location es:bx
; all registers preserved
;
public toddec
toddec: push dx ; save registers
mov dx,ax ; /
push ax ; /
push bx ; /
push cx ; /
add bx,4 ; start at ls digit
mov cx,3 ; initialize counter
toddec1:mov ax,dx ; ax = numerator
mov dx,0 ; clear upper half
cmp ax,0 ; if 0, do shortcut
jnz toddec0 ; /
mov al,30H ; ascii bias if 0
jmp short toddec2 ; /
toddec0:push cx ; save outer loop
mov cx,10 ; divisor of 10
div cx ; divide
xchg ax,dx ; get quotent
add al,30h ; add ASCII bias
pop cx ; get loop counter
toddec2:mov es:[bx],al ; put to the screen
mov byte ptr es:1[bx],grey
dec bx ; bump count address
dec bx ; /
loop toddec1 ; do 3 digits
pop cx ; restore registers
pop bx ; /
pop ax ; /
pop dx ; /
ret ; exit
;--------------------------------------------------------------
; convert binary in al to CM scale in screen location es:bx
; all registers preserved
;
public tonote
tonote: push di ; save registers
push ax ; /
push cx ; /
and al,127 ; 0-127 allowed
mov ah,0 ; ax = midi key value
mov cl,12 ; 12 notes per octave
div cl ; al = octave, ah = scale
mov cl,ah ; save remainder in cl
tohex ; convert octave to ascii
mov es:4[bx],al ; put to the screen
mov ch,0 ; get address of note char
add cx,cx ; /
add cx,offset dgroup:cscale
mov di,cx ; di = address of note char
mov ax,[di] ; get the chars
mov es:2[bx],al ; send to the screen
mov es:[bx],ah ; /
mov al,valflg ; mouse input?
or al,usrflg ; /
jz tonot0 ; no, branch
mov al,colr ; yes, set color
mov es:1[bx],al ; /
mov es:3[bx],al ; /
mov es:5[bx],al ; /
tonot0: pop cx ; restore registers
pop ax ; /
pop di ; /
ret ; exit
;--------------------------------------------------------------
; convert binary in al to hex in ax
; no regs but ax used
;
tohexx: rol al,1
rol al,1
rol al,1
rol al,1
mov ah,al
and al,0FH
daa
add al,0F0H
adc al,040H
;
xchg al,ah
rol al,1
rol al,1
rol al,1
rol al,1
and al,00FH
daa
add al,0F0H
adc al,040H
ret
;--------------------------------------------------------------
; convert hex in al to binary in al
; only al is used
;
fromhex:sub al,30H ; for 0-9
cmp al,9 ; if 0-9
jle fromhxx ; ... go
and al,5fh ; for lower case
sub al,7 ; adjust for A-F
fromhxx:ret
;--------------------------------------------------------------
; convert bit set in ax to nybble in al
; first bit seen is taken
;
frombit:mov cl,0
stc
frombi1:inc cl
rcr ax,1
jnc frombi1
dec cl
mov al,cl
and ax,15
ret
;--------------------------------------------------------------
; convert nybble in al to bit set in ax
;
tobit: mov cl,al ; for shift
mov ax,1
shl ax,cl
ret
;--------------------------------------------------------------
; convert al to upper case
;
touc: cmp al,'a' ; below lower case chars
jb toucx ; yes, branch
cmp al,'z' ; above lower case chars
ja toucx ; yes, branch
and al,5fh ; mask out bit 5
toucx: ret
;--------------------------------------------------------------
; Temp HLT set
; Set clrchf to send out channel module settings
; reset to 1st note in measure
;
tmphlt: or mprstf,4 ; turn tmp hlt on
ret
;--------------------------------------------------------------
; Temp HLT clear
; Set HLT highlight according to HLT flag
; Set clrchf to send out channel module settings
; reset to 1st note in measure
;
fixhlt:
mov bx,6E0H ; text offset
test mprstf,2 ; was previously halted?
jnz fixhlt1 ; yes, turn on highlight
call turnoff ; turn off highlight
jmp clrhlt ; finish up
fixhlt1:
call turnon ; turn on highlight
;
clrhlt: and mprstf,0FBH ; turn tmp hlt off
mov clrchf,1 ; set for chanl module
mov mmtick,1 ; reset to 1st note in measure
ret
;--------------------------------------------------------------
; find module text address on screen 0, and insert them into the
; module source table (_modtxt). Called once only, on startup.
;
modloc: mov ax,0b800H ; set page 0 seg
mov es,ax ; /
mov di,0 ; start at offset 0
modlo1: inc di ; point to next screen location
inc di ; /
cmp di,4090 ; do all of screen 0
jnz modlo2 ; branch if not done
ret ; else exit loop
;
modlo2: mov bx,es:[di] ; get it
cmp bh,white ; look for label color
jnz modlo1 ; not interested if not label color
cmp bl,'0' ; not interested if label number
jz modlo1 ; /
cmp bl,'$' ; not interested if system module
jz modlo1 ; /
;
mov bh,0 ; bx = label char (0-255)
add bx,bx ; bx = _chrtbl offset
add bx,offset dgroup:_chrtbl; add the _chrtbl base address
mov bx,[bx] ; bx = _modsrc address for the label
mov bx,2[bx] ; bx = _modtxt address for the label
mov ax,di ; ax = screen address of the label
dec ax ; drop back two for module address
dec ax ; ax = module address
mov 2[bx],ax ; insert module address into table
jmp short modlo1 ; loop
;==============================================================
; DOS & BIOS Utilities
;--------------------------------------------------------------
; print string
; call with DX = string addr, terminated with $
;
print$: push ds
mov ax,cs
mov ds,ax
mov ah,9
int 21H
pop ds
ret
;--------------------------------------------------------------
; clear current display screen
; cls0 can be called with bh=atrribute
;
cls: mov bh,7 ; normal blank
jmp short cls0 ; /
clx: mov bh,0 ; blank w 0's
cls0: mov al,0 ; blank entire page
mov ah,7 ; scroll down bios call
mov cx,0 ; start at 0,0
mov dx,184fH ; 24, 79
int 10H ; do bios thing
ret ; exit
;--------------------------------------------------------------
; set video page
; call with al = video page to be set
; cursor must be off!
;
page: and ax,_numpg ; 0-7 for EGA, 0-3 for CGA
push ax ; save it
mov al,vpagep ; get previous page
mov ah,160 ; convert to a screen address
mul ah ; /
mov bx,ax ; /
mov es,vpage ; get seg of current page
and byte ptr es:1[bx],0F7H; return to low yellow
and byte ptr es:3[bx],0F7H; /
mov al,vpagen ; get current page
mov vpagep,al ; remember it
pop ax ; get new page
mov vpagen,al ; store it
push ax ; save page number
mov ah,5 ; bios call to change vpage
int 10H ; /
pop ax ; get page back
mov bx,0b800H ; base page address
add bh,al ; set new base page seg
mov vpage,bx ; /
mov al,vpagep ; get previous page number
mov ah,160 ; convert to a screen address
mul ah ; /
mov bx,ax ; /
mov es,vpage ; get seg of current page
or byte ptr es:1[bx],8; highlight
or byte ptr es:3[bx],8; /
ret ; exit
;--------------------------------------------------------------
; copy menus in all pages
;
menus: mov dx,0b800H ; address of page0
mov di,offset dgroup:$menu ; point to the menu text
mov bp,[di] ; get number of lines
add di,4 ; point to start of text
mov cx,_numpg ; 8/4 pages to do
inc cx ; /
menus1: push cx ; save outer count
push di ; save orig index
mov cx,bp ; get count of lines
mov es,dx ; set target seg
mov bx,0 ; screen offset is 0
menus2: mov ax,[di] ; get character
mov es:[bx],ax ; put it to the screen
mov ax,2[di] ; get 2nd of three
mov es:2[bx],ax ; put it away
mov ax,4[di] ; get third
mov es:4[bx],ax ; put it away
add di,6 ; bump indexes
add bx,160 ; next line for video
loop menus2 ; do all text lines
mov al,dh ; get page #
and al,byte ptr _numpg; 0-7
mov ah,160 ; convert to line number
mul ah ; /
mov bx,ax ; now it's an address
or byte ptr es:5[bx],8; make it brite
pop di ; get orig index back
add dh,1 ; bump to next page
pop cx ; get page count
loop menus1 ; do all pages
ret ; exit
;--------------------------------------------------------------
; display modules names
;
shoall: test usesf,1 ; want to use screen file?
jz shoall0 ; no, then use internal data
;
mov ah,3dh ; dos open file command
mov al,0 ; read only
mov dx,offset dgroup:_scrfn; point to file name
int 21H ; open the file
jc shoall0 ; internal data if no file
;
push ax ; save file handle
mov bx,ax ; set up file handle
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,vpage ; set page seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4096 ; screen is 4K bytes
int 21h ; read the file
pop ds ; restore data seg
jc errexit ; bomb if error
;
pop bx ; get file handle
mov ah,3eh ; dos close file
int 21h ; close the file
ret ; exit
;
errexit:pop ax ; discard return address
jmp split1 ; exit
;
shoall0:cld ; direction forward
mov ax,0b800h ; set up for block copy
mov es,ax ; /
mov si,offset dgroup:modscr
mov di,0 ; /
mov cx,2048 ;/
rep movsw ; move from vartbl to screen
ret ; exit
;==============================================================
; save modules
;
savmod: test _tmpfn,-1 ; want to do it?
jnz savmodt ; yes, branch
ret ; no, just return
savmodt:mov dx,offset dgroup:_tmpfn; point to file name
call savmods ; save the stuff
test errflg,-1 ; was there an error
jz savmodu ; no, go on
mov ax,offset dgroup:_noundo; yes, give parting shot
mov byemsg,ax ; /
jmp split ; exit
savmodu:ret
;--------------------------------------------------------------
; save modules & sequencers
; call with dx pointing to filename
;
savmods:mov ah,3ch ; dos create file command
mov cx,0 ; regular file
int 21H ; create the file
call erropw ; check for disk error
;
push ax ; save file handle
mov bx,ax ; set up file handle
mov ah,40h ; dos write file command
mov dx,offset dgroup:_header; point to header
mov cx,128 ; 128 byte header
int 21h ; save it
mov cx,128 ; 128 byte header
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,seg bufsp ; set small seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4096 ; 16 seq's of 256 bytes each
int 21h ; save them
pop ds ; restore data seg
mov cx,4096 ; 16 seq's of 256 bytes each
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,seg buffs ; set large seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,8000H ; save half at a time
int 21h ; save first half
pop ds ; restore data seg
mov cx,8000H ; save half at a time
call errwrt ; check for disk error
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,seg buffs ; set large seq seg
mov ds,dx ; /
mov dx,8000h ; page offset for 2nd half
mov cx,8000H ; save half at a time
int 21h ; save second half
pop ds ; restore data seg
mov cx,8000H ; save half at a time
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,seg bufpa ; set large seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,8000h ; save half at a time
int 21h ; save first half
pop ds ; restore data seg
mov cx,8000h ; save half at a time
call errwrt ; check for disk error
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,seg bufpa ; set large seq seg
mov ds,dx ; /
mov dx,8000h ; page offset for 2nd half
mov cx,8000h ; save half at a time
int 21h ; save second half
pop ds ; restore data seg
mov cx,8000h ; save half at a time
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,0bc00h ; set page 4 seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4000H ; 4 screens of 4K bytes
int 21h ; save the video screens
pop ds ; restore data seg
mov cx,4000H ; 4 screens of 4K bytes
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
push ds ; save data seg
mov dx,0b800h ; set page 0 seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4000H ; 4 screens of 4K bytes
int 21h ; save the video screens
pop ds ; restore data seg
mov cx,4000H ; 4 screens of 4K bytes
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:valsav; point to values
mov cx,valend-valsav; cx = bytes to save
int 21h ; save the values
mov cx,valend-valsav; cx = bytes to save
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:mvlsav; point to values
mov cx,mvlnum ; cx = bytes to save
int 21h ; save the values
mov cx,mvlnum ; cx = bytes to save
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:_modsrc; point to module source table
mov cx,offset dgroup:_chrtbl; calc number of bytes
sub cx,dx ; cx = bytes in modsrc table
push cx
int 21h ; save the modsrc table
pop cx
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:_exetbl; module exec table
mov cx,2048 ; 512 modules @ 4 bytes each
int 21h ; save the table
mov cx,2048 ; 512 modules @ 4 bytes each
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:vartbl; variable table
mov cx,varsiz ; var table
int 21h ; save the table
mov cx,varsiz ; var table
call errwrt ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,40h ; dos write file command
mov dx,offset dgroup:_modtxt; module text
mov cx,offset dgroup:?modtxt; end of module text
sub cx,dx ; cx = bytes in module text
push cx
int 21h ; save the table
pop cx
call errwrt ; check for disk error
;
pop bx ; get file handle
mov ah,3eh ; dos close file
int 21h ; close the file
call errclw ; check for disk error
ret ; exit
;--------------------------------------------------------------
; load modules from _tmpfn
;
lodmod: test _tmpfn,-1 ; want to do it?
jz lodmodq ; no, just return
mov ah,3dh ; dos open file command
mov al,0 ; read only
mov dx,offset dgroup:_tmpfn; point to file name
int 21H ; open the file
call errundo ; check for undo error
mov dl,_mpab ; get current mpab status
push dx ; save on stack
or _mpab,15 ; force all
call lodmod0 ; do the rest
pop dx ; get mpab status
mov _mpab,dl ; restore
lodmodq:ret ; exit
;--------------------------------------------------------------
; load modules with filename already setup (as lodmod, above)
;
lodmod0:
push ax ; save file handle
mov bx,ax ; set up file handle
mov ah,3fh ; dos read file command
mov dx,offset dgroup:_header; point to header
mov cx,128 ; 128 byte header
int 21h ; load it
call erropr ; check for disk error
;
cmp _header,version; right version?
jnz lodmodz ; no, exit
cmp _header+1,release; right release
jz lodmod1 ; yes, go on
lodmodz:test _mpab,1 ; want to load MODS
jz lodmod1 ; no, then it's ok
and _mpab,0feh ; zip the MOD bit
call dompab ; show new mpab
mov dx,offset dgroup:_errver; else give message
call errmsg ; /
;
lodmod1:test _mpab,8 ; want to do this?
jz lodmod2 ; no, branch
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,seg bufsp ; set small seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4096 ; 16 seq's of 256 bytes each
push cx ; save number of read bytes
int 21h ; load them
pop cx ; get number of read bytes
pop ds ; restore data seg
call errqrd ; check for disk error
;
lodmod2:test _mpab,4 ; want to do this?
jz lodmod3 ; no, branch
pop bx ; yes, set file pointer
push bx ; handle
mov cx,0 ; ms word of pointer
mov dx,4096+128 ; ls word of pointer
mov al,0 ; offset from start of file
mov ah,42H ; Move File Pointer
int 21H ; dos call
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,seg buffs ; set large seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,8000H ; load half at a time
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errqrd ; check for disk error
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,seg buffs ; set large seq seg
mov ds,dx ; /
mov dx,8000h ; page offset for 2nd half
mov cx,8000H ; load half at a time
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errqrd ; check for disk error
;
lodmod3:test _mpab,2 ; want to do this?
jz lodmod4 ; no, branch
pop bx ; yes, set file pointer
push bx ; handle
mov cx,1 ; ms word of pointer
mov dx,4096+128 ; ls word of pointer
mov al,0 ; offset from start of file
mov ah,42H ; Move File Pointer
int 21H ; dos call
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,seg bufpa ; set large seq seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,8000h ; load half at a time
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errqrd ; check for disk error
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,seg bufpa ; set large seq seg
mov ds,dx ; /
mov dx,8000h ; page offset for 2nd half
mov cx,8000h ; load half at a time
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errqrd ; check for disk error
;
lodmod4:test _mpab,1 ; want to do this?
jnz lodmod5 ; yes, branch
jmp lodmodx ; no, just go to exit
lodmod5:pop bx ; yes, set file pointer
push bx ; handle
mov cx,2 ; ms word of pointer
mov dx,4096+128 ; ls word of pointer
mov al,0 ; offset from start of file
mov ah,42H ; Move File Pointer
int 21H ; dos call
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,0bc00h ; set page 4 seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4000H ; 4 screens of 4K bytes
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
push ds ; save data seg
mov dx,0b800h ; set page 0 seg
mov ds,dx ; /
mov dx,0 ; page offset is 0
mov cx,4000H ; 8 screens of 4K bytes
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
pop ds ; restore data seg
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:valsav; point to values
mov cx,valend-valsav; cx = bytes to load
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:mvlsav; point to values
mov cx,mvlnum ; cx = bytes to load
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:_modsrc; point to module source table
mov cx,offset dgroup:_chrtbl; calc number of bytes
sub cx,dx ; cx = bytes in modsrc table
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:_exetbl; module exec table
mov cx,2048 ; 512 modules @ 4 bytes each
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:vartbl; variable table
mov cx,varsiz ; var table
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
pop bx ; get handle
push bx ; save it again
mov ah,3fh ; dos read file command
mov dx,offset dgroup:_modtxt; module text
mov cx,offset dgroup:?modtxt; end of module text
sub cx,dx ; cx = bytes in module text
push cx ; save read bytes
int 21h ; load first half
pop cx ; restore read bytes
call errxrd ; check for disk error
;
lodmodx:
pop bx ; get file handle
mov ah,3eh ; dos close file
int 21h ; close the file
call errclr ; check for disk error
ret ; exit
;--------------------------------------------------------------
; delete temp file
;
delmod: test _tmpfn,-1 ; want to do it
jz delmodq ; no, just exit
mov dx,offset dgroup:_tmpfn; delete the load file
mov ah,41h ; dos delete function call
int 21h ; /
delmodq:ret
;==============================================================
; pointing device interface
;--------------------------------------------------------------
; The following pointing device interface assumes an interrupt
; driven microsoft-compatable mouse. When a the mouse position
; changes, or a button is pushed, the interrupt routine sets
; the new x, y and flag, but does no other processing.
; The cursor update and other action is performed by the work
; loop, thus allowing multiple page usage, and control over when
; cursor updating should occur.
;--------------------------------------------------------------
; initialize pointing device
;
initpd:
mov ax,0 ; test for mouse
mov es,ax ; /
mov bx,0cch ; es:bx = mouse inte vector
cmp es:[bx],ax ; int vector = 0?
jz pdng ; yes, exit
mov ax,es:2[bx] ; no, get the vector addr
mov bx,es:[bx] ; /
mov es,ax ; es:bx = vector addr
cmp byte ptr es:[bx],0cfh; pointing to return?
jnz pdok ; no, go to it
pdng:
mov dx,offset nopd$ ; no mouse, print message
call print$ ; /
jmp split1 ; exit program
pdok: mov ax,0 ; initialize
int 33H ; mouse driver inte
mov ah,1 ; turn dos cursor off
mov ch,32 ; /
mov cl,0 ; /
int 10H ; /
ret
nopd$ db 'No Pointing Device$',cr,lf
;--------------------------------------------------------------
; this routine is called only by interrupt, when
; the pd position or flag changes.
;
pdupd proc far ; called by interrupt
mov di,seg dgroup ; set local seg
mov ds,di ; /
; test al,1EH ; button change?
; jz pdupd1 ; no, branch
test al,14H ; button released
jz pdupd2 ; no, branch
or bl,80H ; set bit 7 hi
pdupd2: mov al,pdf ; or with prev bit 7
and al,80H ; /
or bl,al ; /
mov pdf,bl ; store flags
pdupd1: mov ax,dx ; convert pixel xy to char xy
mov bx,cx ; /
mov cl,3 ; /
shr ax,cl ; /
shr bx,cl ; /
mov pdx,bl ; save in pdx, pdy
mov pdy,al ; /
;
vxyadr ; convert vx,vy to offst in bx
mov ax,curadr ; get last cursor address
mov curadr,bx ; save the new one
mov es,vpage ; point to current video page
test curflg,1 ; wanna do the normal cursor
jnz pdupd3 ; no, branch
xchg bx,ax ; get addr of old cursor
mov dx,curdata ; get old cursor data
mov es:[bx],dx ; restore
xchg bx,ax ; get addr of new cursor
mov dx,es:[bx] ; get new data
mov curdata,dx ; save it
mov dh,curcol ; get cursor color
or dh,dh ; doing it?
jz pdupd3 ; no, branch
mov ch,pdf ; yes, get flag info
mov cl,5 ; show it
shl ch,cl ; /
or dh,ch ; /
pdupd4: mov es:[bx],dx ; display cursor
;
pdupd3: mov cx,execur ; get cursor exe address
or cx,cx ; only do if nz
jz pdupdx ; /
jmp cx ; /
pdupdx: ret ; exit
pdupd endp
;--------------------------------------------------------------
; show cursor
;
public curon
curon proc near
mov es,vpage ; point to current video page
test curflg,1 ; special cursor?
jz curon0 ; no, branch
;
mov di,modchar ; get char table
mov cx,[di] ; get number of lines
add di,4 ; point to 1st char
mov bx,curadr ; cursor address
dec bx ; shift for module
dec bx ; /
call shomod$ ; show the module
jmp short curon2 ; branch around regular stuff
;
curon0: mov bx,curadr ; get last cursor address
mov dx,curdata ; get cursor data
test curonf,1 ; want to restore?
jz curon1 ; no, branch
mov curonf,0 ; yes, clear flag
mov dx,es:[bx] ; use screen character
mov curdata,dx ; /
;
curon1: mov dh,curcol ; get cursor color
or dh,dh ; doing it?
jz curon2 ; no, branch
mov ch,pdf ; yes, get flag info
mov cl,5 ; show it
shl ch,cl ; /
or dh,ch ; /
mov es:[bx],dx ; display cursor
;
curon2: mov cx,1fh ; inte on any change
mov ax,12 ; "set call mask"
mov dx,cs ; seg of pd update routine
mov es,dx ; /
mov dx,offset pdupd ; address of pd update
int 33H ; set the mask
ret ; exit
curon endp
;--------------------------------------------------------------
; hide cursor
; turn off pd interrupts
; must be called upon program exit
;
public curoff
curoff proc near
mov es,vpage ; point to current video page
test curflg,1 ; special cursor?
jz curoff0 ; no, branch
;
mov di,modchar ; get char table
mov cx,[di] ; get number of lines
mov bx,curadr ; cursor address
dec bx ; shift for module
dec bx ; /
call fixmod$ ; restore the screen
;
mov bx,curadr ; save cursor
push ds ; save data seg
mov ax,seg buffv ; get back buffer seg
mov ds,ax ; /
mov ax,es:[bx] ; get current screen info
mov [bx],ax ; put it in back buffer
pop ds ; get data seg back
mov curdata,ax ; update cursor data
jmp short curoff1 ; jump around regular stuff
;
curoff0:mov bx,curadr ; get last cursor address
mov dx,curdata ; get cursor data
mov es:[bx],dx ; display cursor
;
curoff1:mov cx,0 ; mask intes
mov ax,12 ; "set call mask"
mov dx,cs ; seg of pd update routine
mov es,dx ; /
mov dx,offset pdupd ; address of pd update
int 33H ; set the mask
ret ; exit
curoff endp
;==============================================================
; video display routines
;--------------------------------------------------------------
; module cursor
; call with with ax= old curadr, bx:es=current curadr
; addr of character list is in modchar
;
modcur proc far
push bx ; save new curadr
mov bx,ax ; get old curadr
dec bx ; modules at vx-1
dec bx ; /
mov di,modchar ; point to module char source
mov cx,[di] ; get the line count
push cx ; save for later
add di,4 ; point to first char
push di ; save for later
call fixmod$ ; restore the old stuff
pop di ; it's later
pop cx ; get count
pop bx ; get new curadr
push bx ; save it again
dec bx ; modules at vx-1
dec bx ; /
call shomod$ ; show the modules
pop bx ; get new curadr
or byte ptr es:1[bx],18H ; cursor
ret ; exit
modcur endp
;--------------------------------------------------------------
; draw modules to screen
; call with: di=module character array
; cx=count of module char lines
; es:bx=video page:offset of 1st char
;
shomod$ proc near
push bp ; save bp
mov bp,ds ; bp = data seg
mov dx,seg buffv ; dx = back buffer seg
shomod1:mov ax,[di] ; get first char
xchg ax,es:[bx] ; put it on the screen
mov ds,dx ; set buffer seg
mov ds:[bx],ax ; save the old one
mov ds,bp ; restore data seg
inc di ; point to next
inc di ; /
mov ax,[di] ; get 2nd character
xchg ax,es:2[bx] ; put it on the screen
mov ds,dx ; set buffer seg
mov ds:2[bx],ax ; save the old one
mov ds,bp ; restore data seg
inc di ; point to next
inc di ; /
mov ax,[di] ; get 3rd char
xchg ax,es:4[bx] ; put it on the screen
mov ds,dx ; set buffer seg
mov ds:4[bx],ax ; save the old one
mov ds,bp ; restore data seg
inc di ; point to next
inc di ; /
add bx,160 ; next line
loop shomod1 ; do all of module
pop bp ; restore bp
ret
shomod$ endp
;--------------------------------------------------------------
; restore screen from modules previously drawn
; call with: di=module character array
; cx=count of module char lines
; es:bx=video page:offset of 1st char
;
fixmod$ proc near
push ds ; save data seg
mov ax,seg buffv ; set ds to back buffer
mov ds,ax ; /
fixmod1:mov ax,ds:[bx] ; get the old char
mov es:[bx],ax ; put it back on the screen
mov ax,ds:2[bx] ; get the old char
mov es:2[bx],ax ; put it back on the screen
mov ax,ds:4[bx] ; get the old char
mov es:4[bx],ax ; put it back on the screen
add bx,160 ; next line
loop fixmod1 ; do all of module
pop ds ; restore data seg
ret
fixmod$ endp
;--------------------------------------------------------------
; erase module from screen
; call with es:bx = module tag addr
; cx = count of char lines
;
eramod$ proc near
mov word ptr es:[bx],0 ; erase center char
mov word ptr es:2[bx],0 ; erase right char
mov word ptr es:-2[bx],0; erase left char
add bx,160 ; next line
loop eramod$ ; loop til done
ret ; exit
eramod$ endp
;--------------------------------------------------------------
; fix blink bit for a blinking module
; call with es:bx = module tag addr
; cx = count of char lines
;
unblink proc near
and byte ptr es:1[bx],07fh ; fix center char
and byte ptr es:3[bx],07fh ; fix right char
and byte ptr es:-1[bx],07fh; fix left char
add bx,160 ; next line
loop unblink ; loop til done
ret ; exit
unblink endp
;==============================================================
; get file name, if any, from command line
;
getfn proc near
mov es,_bases ; es = base seg
mov di,80h ; di = offset of cmd line
mov si,offset dgroup:_savfn ; si = save file name buffer
mov cl,es:[di] ; get the number of bytes
cmp cl,9 ; 8 bytes maximum
jbe getfn3 ; /
mov cl,9 ; /
getfn3: mov ch,0 ; /
or cl,cl ; exit if no name given
jnz getfna ; /
clc ; cy clr means no name
ret ; /
getfna: inc di ; point to start of text
getfn0: mov al,es:[di] ; get first char
cmp al,' ' ; ignore spaces
jz getfn1 ; /
cmp al,'.' ; stop on dot or 0
jz getfn2 ; /
cmp al,0 ; /
jz getfn2 ; /
mov [si],al ; put char in save file name buffer
inc si ; bump fn pointer
getfn1: inc di ; bump cmd line pointer
loop getfn0 ; loop to max of input chars
;
getfn2: mov byte ptr [si],'.' ; set up extension
mov byte ptr 1[si],'M' ; /
mov byte ptr 2[si],'B' ; /
mov byte ptr 3[si],' ' ; /
mov byte ptr 4[si],0 ; /
stc ; cy set means fn given
ret ; exit
getfn endp
;--------------------------------------------------------------
; show save file name on screen 0
showfn:
mov dx,0b800h ; es = page 0
mov es,dx ; /
mov di,0a46h ; di = char addr
mov si,offset dgroup:_savfn ; si = temp file name buffer
mov cx,8 ; 8 chars to do
mov dl,0 ; flag for end of name
showfn1:test dl,1 ; reached end of name?
jnz showfn2 ; yes, branch
mov al,[si] ; get the char
call touc ; convert to upper case
cmp al,'.' ; end of name
jnz showfn3 ; no, branch
mov dl,1 ; yes, set flag
showfn2:mov al,' ' ; set char to blank
showfn3:mov es:[di],al ; write the char
inc di ; bump pointers
inc di ; /
inc si ; /
loop showfn1 ; do 8 chars
ret
;==============================================================
; get a string from the keyboard to _inbuf
; call with first byte of _inbuf set to max chars
;
getkey:
mov ah,1 ; turn dos cursor on
mov ch,6 ; /
mov cl,7 ; /
int 10H ; /
;
mov dx,offset dgroup:_inbuf
mov ah,0ah ; dos read buffer line function
int 21h ; /
;
mov ah,1 ; turn dos cursor off
mov ch,32 ; /
mov cl,0 ; /
int 10H ; /
;
ret
;==============================================================
; read directory into the filename area
;
getdir: call clrdir ; clear the directory area
;
mov dx,offset dgroup:_dirfn; now read the name
mov cx,0 ; attribute "normal"
mov ah,4eh ; read first
int 21h ; dos call
jc getdirx ; exit if no match
call dodir0 ; else print it
;
mov cx,30 ; 30+first+room max
getdir1:push cx ; save count
mov ah,4fh ; read next
int 21h ; dos call
pop cx ; get count
jc getdirx ; exit if no match
push cx ; save count
call dodir ; else print it
pop cx ; get count
loop getdir1 ; do until done or limit
getdirx:
;
mov ah,36h ; get free disk space
mov dl,0 ; default drive
int 21h ; dos call
mul cx ; find out in bytes
mul bx ; result in dx:ax
mov ax,dx ; /65K
mov cl,2 ; /4 = 256K/file
shr ax,cl ; /
push ax ; save result
;
mov ax,0b800h ; set up video seg
mov es,ax ; /
mov ax,diradr ; current offset
add ax,0612h ; ah=x
mov bl,ah ; al=y, bl=x
mov bh,0 ; /
vxyadr ; bx = video page address
mov colr,grey
mov word ptr es:[bx],gry+'['; set up brackets
mov word ptr es:8[bx],gry+']'
add bx,2
;
pop ax ; get numb of files
mov room,al ; save the room number
mov ah,0 ; 50 MB is enough
call toddec ; print them
;
ret ; split
;--------------------------------------------------------------
; read from _inbuf into the filename area
; do 4 names, then bump to next column
; call dodir0 to initialize, then call dodir
;
dodir0: mov diradr,0 ; initialize address
dodir: mov ax,0b800h ; set up video seg
mov es,ax ; /
mov ax,diradr ; current offset
add ax,0612h ; ah=x
mov bl,ah ; al=y, bl=x
mov bh,0 ; /
vxyadr ; bx = video page address
mov di,9eh ; point to source
push ds ; save local data seg
mov ds,_bases ; get system data seg
mov cx,8 ; 8 max to do
dodir1: mov al,[di] ; get the char
cmp al,'.' ; extension ?
jz dodir2
mov es:[bx],al ; no, write the char
inc bx ; bump pointers
inc bx ; /
inc di ; /
loop dodir1 ; loop
;
dodir2: pop ds ; get local ds back
mov ax,diradr ; bump screen address
inc al ; bump y
test al,4 ; 3 max
jz dodir3 ; branch if < 4
mov al,0 ; else reset y
add ah,9 ; .. bump x
dodir3: mov diradr,ax ; put it away
ret
;--------------------------------------------------------------
; clear the directory filename area
;
clrdir: mov ax,0b800h ; set up video seg
mov es,ax ; /
mov di,0b4ch ; point to 1st char
mov dl,4 ; 4 lines
mov ax,yel ; set color
clrdir0:mov bx,0 ; /
mov cx,72 ; 72 words per line
clrdir1:mov es:[bx+di],ax ; set the word
inc bx ; bump
inc bx ; /
loop clrdir1 ; do the line
add di,160 ; next line
dec dl ; /
jnz clrdir0 ; /
ret
;==============================================================
; show the current path
;
dopath: mov ah,19h ; get current disk drive
int 21h ; dos call
add al,'A' ; make it a letter
mov _inbuf,al ; put it away
mov byte ptr _inbuf+1,':' ; send colon & slash
mov byte ptr _inbuf+2,'\' ; /
;
mov ah,47H ; get current directory
mov dl,0 ; 0 = default drive
mov si,offset dgroup:_inbuf+3; put it in inbuf
int 21h ; dos call
jc dopathx ; exit if error
;
mov ax,0b800h ; set up video seg
mov es,ax ; /
mov bx,58H+(16*160) ; offset for line
mov ax,yel ; set color
mov cx,35 ; words in line
dopath1:mov es:[bx],ax ; set the word
inc bx ; bump
inc bx ; /
loop dopath1 ; do the line
;
mov bx,58H+(16*160) ; offset for line
mov di,offset dgroup:_inbuf; dir text
dopath2:mov al,[di] ; get the char
or al,al ; end?
jz dopathx ; yes, exit
mov es:[bx],al ; no, output to screen
inc di ; bump pointers
inc bx ; /
inc bx ; /
jmp short dopath2 ; loop
dopathx:ret ; exit
;==============================================================
; critical error handeling (trapped DOS int 24H )
;
cerror:
push bx ; save cpu state
push cx ; /
push dx ; /
push di ; /
push si ; /
push bp ; /
push ds ; /
push es ; /
mov al,0 ; setup to ignore
test ah,80h ; disk error ?
jnz cerrorx ; no, exit
push di ; save error cond
;
mov dx,seg dgroup ; set up data seg
mov ds,dx ; /
;
mov dx,offset dgroup:_err_wp;write protect ermsg
pop ax ; check for write protect
or al,al ; write protect
jz cerror1 ; yes, branch
mov dx,offset dgroup:_err_dx; general ermsg
cerror1:call errmsg ; do the message
;
mov ah,al ; put result in ah
mov al,0 ; ...to Ignore
cmp ah,'I' ; wanna?
jz cerrorx ; yes, go do it
inc al ; ...to Retry
cmp ah,'R' ; /
jz cerrorx ; /
;
call curoff ; this is serious
call cls ; clear screen
mov ah,2 ; set cursor to top of screen
mov dx,0 ; /
mov bh,dh ; /
int 10H ; /
mov ah,1 ; turn dos cursor on
mov ch,6 ; /
mov cl,7 ; /
int 10H ; /
call stopt ; stop system timer
call stopm ; stop mpu ints
mov al,2 ; Quit
;
cerrorx:pop es ; restore cpu state
pop ds ; /
pop bp ; /
pop si ; /
pop di ; /
pop dx ; /
pop cx ; /
pop bx ; /
iret
;==============================================================
; Error message handler
; call with errormsg in dx
; returns with al = I, R, or Q
;
errmsg:
push dx ; save message addr
mov vpagen,1 ; set page 1 as swap
mov al,0 ; set page 0 active
call page ; /
;
mov ax,0b800h ; set up video seg
mov es,ax ; /
mov si,58H+(16*160) ; offset for line
mov di,offset dgroup:_foo; scratch buffer
mov bx,0 ; clear index
mov cx,35 ; words in line
errmsg0:
mov ax,es:[bx+si] ; get the char
mov [bx+di],ax ; save it
inc bx ; bump
inc bx ; /
loop errmsg0 ; do the line
;
mov ah,2 ; bios set cursor position
mov bh,0 ; page 0
mov dx,102CH ; x,y of cursor
int 10H ; do bios int
;
pop dx ; get the message
mov ah,9 ; print line
int 21H ; dos call
;
errmsg1:mov ah,8 ; get a key response
int 21h ; dos call
call touc ; convert to uppercase
cmp al,'I' ; check for "I", "R", or "Q"
jz errmsg2 ; ...and branch if ok
cmp al,'E' ; /
jz errmsg2 ; /
cmp al,'R' ; /
jz errmsg2 ; /
cmp al,'Q' ; /
jnz errmsg1 ; /
errmsg2:push ax ; save result
;
mov ax,0b800h ; set up video seg
mov es,ax ; /
mov si,58H+(16*160) ; offset for line
mov di,offset dgroup:_foo; scratch buffer
mov bx,0 ; clear index
mov cx,35 ; words in line
;
errmsg3:
mov ax,[bx+di] ; get the char
mov es:[bx+si],ax ; restore it
inc bx ; bump
inc bx ; /
loop errmsg3 ; do the line
;
mov ah,2 ; bios set cursor position
mov bh,0 ; page 0
mov dx,102CH ; x,y of cursor
int 10H ; do bios int
;
pop ax ; return kbd input
ret ; exit
;--------------------------------------------------------------
; errwrt: check for error while writing
; call with cx = proper file size
;
errwrt: jnc errwrt1 ; branch if no error
or errflg,1 ; set flag
mov errwrd,ax ; save message
ret
errwrt1:cmp ax,cx ; correct size
jz errwrtx ; yes, exit
or errflg,2 ; no, set flag
errwrtx:ret
;--------------------------------------------------------------
; check for error while opening write file
;
erropw: mov errflg,0 ; clear error flag
jnc erropwx ; exit if no error
or errflg,4 ; set flag
mov errwrd,ax ; save message
erropwx:ret
;--------------------------------------------------------------
; check for error while closing write file
;
errclw: jnc errclwx ; exit if no error
or errflg,8 ; set flag
mov errwrd,ax ; save message
errclwx:ret
;--------------------------------------------------------------
; check for error while opening read file
;
erropr: mov errflg,0 ; clear error flag
jnc erroprx ; exit if no error
or errflg,40H ; set flag
mov errwrd,ax ; save message
erroprx:ret
;--------------------------------------------------------------
; check for error while closing read file
;
errclr: jnc errclrx ; exit if no error
or errflg,80h ; set flag
mov errwrd,ax ; save message
errclrx:ret
;--------------------------------------------------------------
; errxrt: check for non fatal error while reading
; call with cx = proper file size
;
errqrd: jnc errqrd1 ; exit if no error
or errflg,10h ; set flag
mov errwrd,ax ; save message
ret
errqrd1:cmp ax,cx ; correct size
jz errqrdx ; yes, exit
or errflg,20h ; no, set flag
errqrdx:ret
;--------------------------------------------------------------
; errxrt: check for fatal error while reading
;
errxrd: jnc errxrd1 ; exit if no error
errxrd0:mov ax,offset dgroup:_errmod; yes, give parting shot
mov byemsg,ax ; /
jmp split ; exit
errxrd1:cmp ax,cx ; correct size
jnz errxrd0 ; no, split
ret
;--------------------------------------------------------------
; errundo: check for undo open error
;
errundo:
jnc errundx ; exit if no error
mov ax,offset dgroup:_opundo; yes, give parting shot
mov byemsg,ax ; /
jmp split ; exit
errundx:ret
;==============================================================
; debugging routines
if debug
;--------------------------------------------------------------
_DATA SEGMENT
public show0,show1,show2,show3,showq
show0 dw 0 ; debug show words
show1 dw 1 ;
show2 dw 2 ;
show3 dw -1 ;
showq dw 22 dup (0)
dw 0
_DATA ENDS
;--------------------------------------------------------------
; move 16 words, starting with ds:[bx] into show array
; all registers preserved
;
showw proc near
push es
push ds
push ax
push bx
push cx
push di
mov ax,seg dgroup
mov ds,ax
mov di,offset dgroup:showq
mov cx,44
showwl: mov al,[bx]
mov [di],al
inc bx
inc di
loop showwl
showw2:
pop di
pop cx
pop bx
pop ax
pop ds
pop es
showw endp
;--------------------------------------------------------------
; show 16 memory values starting with SHOW0
; all registers preserved
;
show proc near
cmp word ptr vpage,0b800h; don't show 0
jnz showa ; /
ret ; /
showa: cmp word ptr vpage,0bf00h; don't show 7
jnz showb ; /
ret ; /
showb: push ax ; preserve all registers
push bx ;
push cx ;
push dx ;
push di ;
push es ;
push ds ;
mov es,vpage ; seg of screen
mov ax,seg dgroup ; seg of SHO0
mov ds,ax ; /
mov di,offset dgroup:show0 ; address of show0
mov bx,152 ; addr of 76,0
mov cx,25 ; 25 words
mov dh,yellow ; color
showl: mov al,1[di] ; get hi byte
tohex ; convert it to hex
mov dl,ah ; get hi nybble
mov es:[bx],dx ; send hi nybble
mov dl,al ; get low nybble
mov es:2[bx],dx ; send low nybble
mov al,[di] ; get low byte
tohex ; convert it to hex
mov dl,ah ; get hi nybble
mov es:4[bx],dx ; send hi nybble
mov dl,al ; get low nybble
mov es:6[bx],dx ; send low nybble
add bx,160 ; move down
add di,2 ; bump index
loop showl ; do 24 bytes
pop ds ; restore registers
pop es
pop di
pop dx
pop cx
pop bx
pop ax
ret
show endp
endif ; end of debug routines
;==============================================================
_TEXT ENDS
;==============================================================
end _doit ; change to END if withc