home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
PARASOL
/
VIDEOSTO.ARK
/
SCREEN.LIB
< prev
next >
Wrap
Text File
|
1986-07-20
|
29KB
|
1,089 lines
print off;
{---------------------------------------------------}
{ data for screen-handler routines }
{---------------------------------------------------}
set `lin.chars = 80; {# chars per line}
set `s.lins = 24; {# lines per `screen}
set `max.fields = 180;{max # fields per `screen}
external word `bios.ptr address 1;
external record `dflt.dma address ^h80 length ^h80;
external label `entry address 5;
{---------------------------------------------}
{ special characters in screen record }
{---------------------------------------------}
set `i.end = ^h00;
set `i.crsr = ^h01;
set `i.alf = ^h02;
set `i.dt = ^h03;
set `i.dol = ^h04;
set `i.dec = ^h05;
set `i.prot = ^h06;
set `i.up = ^h07;
set `i.lo = ^h08;
set `i.nm = ^h09;
set `i.iv = ^h0a;
set `i.tot = ^h0b;
{---------------------------}
{ screen field data }
{---------------------------}
string screen.data ((`lin.chars * `s.lins) + 1)
byte pointer `c.d.bp value #screen.data;
{------------------------------}
{ screen image storage }
{------------------------------}
string `c.s.rec ((`lin.chars * `s.lins) + 1);
byte pointer `c.s.bp value #`c.s.rec;
{-----------------------------------------}
{ screen field descriptor storage }
{-----------------------------------------}
record `c.fld.parms;
byte `c.fld.type;
byte `c.fld.x.pos;
byte `c.fld.y.pos;
byte `c.fld.len;
endrec;
string `c.s.fields (`max.fields * 4);
byte pointer `c.fld.bp value #`c.s.fields;
{----------------------------
{ Internal Control-Codes
{----------------------------
set `t.end = ^h1b;
set `t.abort = ^h03;
set `t.tab = ^h09;
set `t.bktab = ^h0b;
set `t.fwd = ^h0c;
set `t.bksp = ^h08;
{-------------------------------------------}
{ the terminal-characteristics file }
{-------------------------------------------}
file `t.file,
disk, random, key terminal.type,
record `dflt.dma,
value "TERMINAL.DAT";
record `t.parms;
string `t.xlate 32;
string `t.clr 24;
string `t.crsr.lead 5;
byte `t.crsr.offset;
byte `t.crsr.y.1st;
string `t.fore 16;
string `t.back 16;
byte `t.exit.fore;
string 16; {ascii name of terminal}
byte `t.no.wrap; {flag no end-of-line wrap-around}
string `t.lead.ins 5; {~1b~, ~01~, etc.}
word `t.timeout; {lower for MP/M}
byte `t.ibm;
endrec;
byte pointer `t.bp;
{-------------------------}
{ the screen file }
{-------------------------}
record `s.file.rec;
string `ix.name 9;
word `ix.key;
string 110; {10 more of above}
word `nxt.ix;
field 3; {filler}
word `nxt.scr;
endrec;
string pointer `ix.ptr value #`ix.name;
string screen.file.name 15 value "SCREEN.DAT";
word `s.next.key;
file `s.file,
disk, random, key `s.key,
record `s.file.rec,
value screen.file.name;
{-------------------------------------------------}
{ the name of the screen currently in use }
{-------------------------------------------------}
string screen.name 9;
string `prev.screen.name 9;
word `c.s.key;
{-----------------------------------------}
{ the status-line / error-message }
{-----------------------------------------}
string status.line (`lin.chars + 1);
{-----------------------}
{ misc. storage }
{-----------------------}
word `s.sz;
word `num.bl;
word `prev.num.bl;
byte `c.x.pos;
byte `c.y.pos;
byte `c.char;
byte `c.fld.pos;
byte `field.in.process value "N";
byte `p.y.pos;
byte `init.done value "N";
byte `wk.byte;
byte get.data.skip.count value 0;
word get.data.cursor.loc value 0;
string `con.str 251;
{-----------------------------------------------}
{ console I/O bios calls }
{-----------------------------------------------}
procedure `con.out: goto `con.out;
procedure `con.in: goto `con.in;
procedure `con.stat: goto `con.stat;
{----------------
{ Initialize
{----------------
procedure `init:
begin
if `init.done = "N" then
mcall `entry using 32,^hff giving ,,,`init.done;
push terminal.type;
open `t.file shared error begin
mcall `entry using 32,0;
open `t.file error standard;
end;
pop terminal.type;
read `t.file error standard;
move `dflt.dma[string] to `t.parms[string] length ##`t.parms;
close `t.file error standard;
mcall `entry using 32,`init.done;
open `s.file shared error standard;
add 3 to `bios.ptr giving `con.stat[+1,word];
add 6 to `bios.ptr giving `con.in[+1,word];
add 9 to `bios.ptr giving `con.out[+1,word];
move "Y" to `init.done;
fi;
end;
{-----------------------------------------------}
{ clear-screen }
{ out: `c.x.pos and `c.y.pos both = 1 }
{-----------------------------------------------}
procedure clear.screen:
begin
display `t.clr,;
move 1 to `c.x.pos;
move 1 to `c.y.pos;
end;
{-----------------------------------------------}
{ set & reset hi-lighting }
{-----------------------------------------------}
procedure `hilite.fore: display `t.fore,;
procedure `hilite.back: display `t.back,;
procedure close.screen.file:
begin
if `init.done = "Y" then
close `s.file error standard;
fi;
end;
{-----------------------------------------------}
{ find screen }
{ in: screen.name }
{ out: screen.sz (=0 if not found) }
{ `c.s.rec }
{ `s.key = 0 if not found on disk }
{-----------------------------------------------}
procedure `find.screen:
begin
call `init;
move 0 to `s.sz;
move 0 to `s.key;
do
read `s.file error standard;
move #`s.file.rec to `ix.ptr;
while `ix.ptr < #`nxt.ix do
if @`ix.ptr = screen.name then
add 9 to `ix.ptr;
move @`ix.ptr[wp] to `s.key;
move #`c.s.rec to `ix.ptr;
do
read `s.file error standard;
move `nxt.scr to `s.key;
move 0 to `nxt.scr[byte];
move `s.file.rec[string] to @`ix.ptr;
add 126 to `ix.ptr;
od until `s.key = 0;
size `c.s.rec giving `s.sz;
add 1 to `s.sz;
exit;
fi;
add 11 to `ix.ptr;
od;
move `nxt.ix to `s.key;
od until `s.key = 0;
end;
{-----------------------------------}
{ set crsr address }
{-----------------------------------}
procedure `set.crsr:
begin
byte x.loc;
byte y.loc;
string ansi.str 4;
if `t.crsr.lead = "ANSI" then
convert `c.y.pos to ansi.str;
display "~1b~[",ansi.str,";",;
convert `c.x.pos to ansi.str;
display ansi.str,"f",;
else
display `t.crsr.lead,;
add `t.crsr.offset to `c.x.pos giving x.loc
add `t.crsr.offset to `c.y.pos giving y.loc;
if `t.crsr.y.1st = 'Y' then
mcall `con.out using y.loc;
mcall `con.out using x.loc;
else
mcall `con.out using x.loc;
mcall `con.out using y.loc;
fi;
fi;
move `c.y.pos to `p.y.pos;
end;
{-------------------------------------------}
{ bump current crsr pos }
{-------------------------------------------}
procedure `bump.ch.pos:
begin
add 1 to `c.x.pos;
if `c.x.pos > `lin.chars then
move 1 to `c.x.pos;
add 1 to `c.y.pos;
if `c.y.pos > `s.lins then
move 1 to `c.y.pos;
fi; fi;
end;
{-------------------------------------------}
{ display status-line }
{-------------------------------------------}
procedure status.line.display:
begin
call `init;
push `c.x.pos[word];
move 1 to `c.x.pos;
move `s.lins to `c.y.pos;
call `set.crsr;
call `hilite.fore;
append " " to status.line;
append `con.str to status.line;
move 0 to `con.str[byte];
justify status.line left length (`lin.chars - 1);
move screen.name to status.line[+(`lin.chars - 9),field,length 8];
display status.line,;
move 0 to status.line[byte];
call `hilite.back;
pop `c.x.pos[word];
call `set.crsr;
end;
procedure `make.up:
if `c.char >= 'a'
and `c.char <= 'z' then
subtract ^h20 from `c.char;
fi;
procedure `make.lo:
if `c.char >= 'A'
and `c.char <= 'Z' then
add ^h20 to `c.char;
fi;
{-----------------------------------------------}
{ display screen data }
{-----------------------------------------------}
procedure display.screen.data:
begin
move #screen.data to `c.d.bp;
move #`c.s.fields to `c.fld.bp;
while @`c.fld.bp <> `i.end do
move @`c.fld.bp[sp] to `c.fld.parms[string] length 4;
add 4 to `c.fld.bp;
move `c.fld.x.pos[word] to `c.x.pos[word];
call `set.crsr;
if `c.fld.type <> `i.prot then
call `hilite.fore;
fi;
move 0 to `num.bl; {-zero-suppress flag-}
while `c.fld.len <> 0 do
subtract 1 from `c.fld.len;
move @`c.d.bp to `c.char;
and `c.char with ^h7f;
if `c.char < ' ' then
move ' ' to `c.char;
fi;
switch on `c.fld.type:
`i.tot,
`i.dec,
`i.dol:
if `num.bl <> 0
or `c.char <> '0'
or `c.fld.len = 1 then
move ^hff to `num.bl;
else
move ' ' to `c.char;
fi;
`i.iv: move ' ' to `c.char;
endswitch;
mcall `con.out using `c.char;
add 1 to `c.d.bp;
call `bump.ch.pos;
od;
call `hilite.back;
od;
end;
{-----------------------------------------------}
{ display screen }
{ in: screen.name }
{ screen.data }
{ out: `c.s.fields }
{-----------------------------------------------}
procedure display.screen:
begin
if screen.name <> `prev.screen.name then
call `find.screen;
call clear.screen;
move 0 to `con.str[byte];
call `hilite.back;
if `s.sz = 0 then
move screen.name to status.line;
append " screen not found" to status.line;
move 0 to `con.str[byte];
call status.line.display;
goto end;
fi;
move #screen.data to `c.d.bp;
move #`c.s.fields to `c.fld.bp;
move #`c.s.rec to `c.s.bp;
do
switch on @`c.s.bp:
`i.end: exitdo; {end of screen}
`i.crsr: begin {screen pos}
add 1 to `c.s.bp;
move @`c.s.bp[wp] to `c.x.pos[word];
add 2 to `c.s.bp;
call `set.crsr;
end;
`i.alf,
`i.up,
`i.lo,
`i.nm,
`i.iv,
`i.dt,
`i.dol,
`i.dec,
`i.tot,
`i.prot: begin {start of field}
move @`c.s.bp to @`c.fld.bp;
move @`c.s.bp to `c.fld.type;
add 1 to `c.fld.bp;
move `c.x.pos[word] to @`c.fld.bp[wp];
add 2 to `c.fld.bp;
add 1 to `c.s.bp;
move @`c.s.bp to `c.fld.len;
move `c.fld.len to @`c.fld.bp; {width}
add 1 to `c.fld.bp;
add 1 to `c.s.bp;
while `c.fld.len <> 0 do
subtract 1 from `c.fld.len;
call `bump.ch.pos;
if @`c.s.bp = " " then
add 1 to `c.s.bp;
mcall `con.out using ' ';
fi;
od;
end;
else begin {display screen char}
if `c.y.pos <> `p.y.pos
and `t.no.wrap = 'Y' then
call `set.crsr;
fi;
move @`c.s.bp to `c.char;
mcall `con.out using `c.char;
call `bump.ch.pos;
add 1 to `c.s.bp;
end;
endswitch;
od;
move `i.end to @`c.fld.bp;
fi;
{--clear status.line--}
call `hilite.back;
move 1 to `c.x.pos;
move `s.lins to `c.y.pos;
call `set.crsr;
move 0 to `num.bl;
do
mcall `con.out using ' ';
add 1 to `num.bl;
od until `num.bl >= (`lin.chars - 9);
display screen.name,;
move screen.name to `prev.screen.name;
end;
{-----------------------------------------------
{ get screen data
{ in: screen.data
{ `c.s.fields - `c.fld.bp
{ out: screen.data
{-----------------------------------------------
procedure get.screen.data:
begin
byte pointer wk.bp1,
wk.bp2,
wk.bp3;
word wk.word;
byte data.entered.this.field value 'N';
byte skip.past.end value 'N';
byte field.overflow value 'N';
byte minus.flag value 'N';
string digits 11 value "0123456789";
string wk.month 3,
wk.day 3,
wk.year 5;
{-------------------------------------------------
{ Special fields for multi-byte key-sequences
{-------------------------------------------------
string ctl.str 9;
record ctl.codes;
{--------------------
{ IBM 3101 codes
{--------------------
string 3 value "~1b~A"; byte value `t.bktab; {up}
string 3 value "~1b~B"; byte value `t.tab; {down}
string 3 value "~1b~C"; byte value `t.fwd; {right}
string 3 value "~1b~D"; byte value `t.bksp; {left}
string 3 value "~1b~H"; byte value `t.end; {home}
string 3 value "~1b~I"; byte value `t.end; {clear EOL}
string 3 value "~1b~J"; byte value `t.end; {clear EOS}
string 3 value "~1b~K"; byte value `t.end; {erase input}
string 3 value "~1b~L"; byte value `t.end; {clear}
string 4 value "~FFFFFF~";
endrec;
procedure `blank.rest:
while `c.fld.pos < `c.fld.len
and data.entered.this.field = 'Y'
and field.overflow <> 'Y' do
move ' ' to @`c.d.bp;
mcall `con.out using ' ';
add 1 to `c.d.bp;
add 1 to `c.fld.pos;
od;
procedure skip.to.next.field:
begin
move 'N' to skip.past.end;
do
call `blank.rest;
if data.entered.this.field = 'Y' then
if field.overflow = 'Y' then
add 1 to `c.d.bp;
fi;
else
add `c.fld.len to `c.d.bp;
subtract `c.fld.pos from `c.d.bp;
fi;
move 'N' to field.overflow;
move 'N' to data.entered.this.field;
move 0 to `c.fld.pos;
add 4 to `c.fld.bp;
if @`c.fld.bp = `i.end then
move #`c.s.fields to `c.fld.bp;
move #screen.data to `c.d.bp;
move 'Y' to skip.past.end;
fi;
move @`c.fld.bp[sp] to `c.fld.parms[string] length 4;
move `c.fld.x.pos[word] to `c.x.pos[word];
od until `c.fld.type <> `i.prot;
end;
procedure test.numeric.char:
if `c.char < '0'
or `c.char > '9' then
move ^h00 to `c.char;
fi;
procedure test.alpha.char:
if `c.char < " "
or `c.char > "~~" then
move ^h00 to `c.char;
fi;
procedure left.just.field:
begin
while `con.str[byte] = '0'
or `con.str[byte] = ' ' do
move `con.str[+1] to `con.str;
od;
end;
procedure right.just.field:
begin
scan `con.str for " " giving address wk.bp1;
move 0 to @wk.bp1;
do
size `con.str giving wk.word;
if wk.word >= `c.fld.len then
exitdo;
fi;
move `con.str to `con.str[+1] length (##`con.str - 1) reverse;
move '0' to `con.str[byte];
od;
if minus.flag = 'Y' then
{--if no room for minus, force size error--}
if `con.str[byte] <> '0' then
move `con.str to `con.str[+1] length (##`con.str - 1)
reverse;
fi;
move '-' to `con.str[byte];
fi;
move 'N' to minus.flag;
end;
procedure move.6.date:
begin
move `con.str[word] to wk.month[word];
move `con.str[+2,word] to wk.day[word];
move `con.str[+4,word] to wk.year[word];
move 0 to wk.year[+2,byte];
end;
procedure screen.bottom:
begin
if `t.exit.fore = 'Y' then
call `hilite.fore;
else
call `hilite.back;
fi;
move `s.lins to `c.y.pos;
move 1 to `c.x.pos;
call `set.crsr;
end;
{-----main body of get.screen.data-----}
if screen.name <> `prev.screen.name then
call display.screen;
fi;
call display.screen.data;
move #`c.s.fields to `c.fld.bp;
move #screen.data to `c.d.bp;
if @`c.fld.bp = `i.end then
exit;
fi;
move @`c.fld.bp[sp] to `c.fld.parms[string] length 4;
while `c.fld.type = `i.prot do
call skip.to.next.field;
od until skip.past.end = 'Y';
if get.data.cursor.loc <> 0 then
while get.data.cursor.loc > `c.d.bp do
call skip.to.next.field;
od until skip.past.end = 'Y';
else
while get.data.skip.count <> 0 do
subtract 1 from get.data.skip.count;
call skip.to.next.field;
od until skip.past.end = 'Y';
fi;
move 0 to get.data.cursor.loc;
`get.dat.redisplay:
mcall `con.stat giving ,,,`c.char;
if `c.char <> 0 then
mcall `con.in giving ,,,`c.char;
goto `get.dat.redisplay;
fi;
move 'N' to field.overflow;
call `hilite.fore;
{-----loop by field-----}
do
{---skip initial protected field---}
while @`c.fld.bp = `i.prot do
add 3 to `c.fld.bp;
add @`c.fld.bp to `c.d.bp;
add 1 to `c.fld.bp;
od;
move @`c.fld.bp[sp] to `c.fld.parms[string]
length 4;
move `c.fld.x.pos[word] to `c.x.pos[word];
move 0 to `c.fld.pos;
move 'N' to field.overflow;
move 'N' to data.entered.this.field;
{-----loop by character within field-----}
do
call `set.crsr;
mcall `con.in giving ,,,`c.char;
{-------------------------------------------------
{ Special keystrokes for IBM-PC & compatibles
{-------------------------------------------------
if `c.char = 0
and `t.ibm = "Y" then
mcall `con.in giving ,,,`c.char;
switch on `c.char:
^h03: move `t.abort to `c.char; {break}
^h48: move `t.bktab to `c.char; {up}
^h4b: move `t.bksp to `c.char; {back}
^h4d: move `t.fwd to `c.char; {fwd}
^h50: move `t.tab to `c.char; {down}
^h52: move `t.fwd to `c.char; {ins}
^h53: move `t.bksp to `c.char; {del}
^h3b - ^h71: move `t.end to `c.char; {func}
else move 0 to `c.char;
endswitch;
goto `got.char;
fi;
{---check for lead-in char for multi-byte key-sequence---}
fill ctl.str with 0;
move `c.char to ctl.str[byte];
scan `t.lead.ins for ctl.str
true begin
move (#ctl.str + 1) to wk.bp2;
move `t.timeout to wk.word;
do
mcall `con.stat giving ,,,`c.char;
if `c.char <> 0 then
mcall `con.in giving ,,,`c.char;
{---------------------------------------------
{--multi-byte sequence can't contain another--}
{--lead-in character, discard previous. }
{-- (I.B.M 3101 running under MPM has trouble
{-- keeping up with arrow keys typed fast
{----------------------------------------------
{ move #`t.lead.ins to wk.bp1;
{ while @wk.bp1 <> 0 do
{ if @wk.bp1 = `c.char then
{ fill ctl.str with 0;
{ move `t.timeout to wk.word;
{ move #ctl.str to wk.bp2;
{ exitdo;
{ fi;
{ add 1 to wk.bp1;
{ od;
move `c.char to @wk.bp2;
add 1 to wk.bp2;
if wk.bp2 >= (#ctl.str + (##ctl.str - 1))
then exitdo;
fi;
fi;
subtract 1 from wk.word;
od until wk.word = 0;
move #ctl.codes to wk.bp1;
do
move #ctl.str to wk.bp2;
do
if @wk.bp2 OR @wk.bp1 then
else {--if end of both-}
add 1 to wk.bp1;
move @wk.bp1 to `c.char;
goto `got.char;
fi;
if @wk.bp2 <> @wk.bp1 then
while @wk.bp1 <> 0 do
add 1 to wk.bp1;
od;
add 2 to wk.bp1;
exitdo;
fi;
add 1 to wk.bp1;
add 1 to wk.bp2;
od;
od until @wk.bp1 = ^hff;
move ctl.str[byte] to `c.char; {-restore 1st char-}
end;
if `c.char < ' ' then
add #`t.xlate to `c.char giving `t.bp;
move @`t.bp to `c.char;
fi;
`got.char:
switch on `c.char:
{---end of data entry---}
`t.end: begin
call skip.to.next.field;
call screen.bottom;
goto `get.dat.validate;
end;
`t.abort: begin
move "Abort? (Y/N):" to status.line;
move 0 to `con.str[byte];
call status.line.display;
mcall `con.in giving ,,,`c.char;
if `c.char = "Y"
or `c.char = "y" then
call screen.bottom;
reboot;
fi;
end;
`t.tab: begin
call skip.to.next.field;
exitdo;
end;
{---back-tab---}
`t.bktab: begin
call `blank.rest;
move "N" to field.overflow;
subtract `c.fld.pos from `c.d.bp;
do
if `c.fld.bp > #`c.s.fields then
subtract 1 from `c.fld.bp;
subtract @`c.fld.bp from `c.d.bp;
subtract 3 from `c.fld.bp;
else
move #`c.s.fields to `c.fld.bp;
move #screen.data to `c.d.bp;
do
add 3 to `c.fld.bp;
add @`c.fld.bp to `c.d.bp;
add 1 to `c.fld.bp;
od until @`c.fld.bp = `i.end;
subtract 1 from `c.fld.bp;
subtract @`c.fld.bp from `c.d.bp;
subtract 3 from `c.fld.bp;
fi;
od until @`c.fld.bp <> `i.prot;
exitdo;
end;
{---forward space---}
`t.fwd: begin
add 1 to `c.fld.pos;
add 1 to `c.d.bp;
if `c.fld.pos >= `c.fld.len then
call skip.to.next.field;
exitdo;
fi;
call `bump.ch.pos;
end;
^h7f,
`t.bksp: begin
move 'N' to field.overflow;
if `c.fld.pos <> 0 then
subtract 1 from `c.d.bp;
subtract 1 from `c.fld.pos;
if `c.x.pos > 1 then
subtract 1 from `c.x.pos;
else
move `lin.chars to `c.x.pos;
if `c.y.pos > 1 then
subtract 1 from `c.y.pos;
else
move `s.lins to `c.y.pos;
fi; fi; fi;
end;
else begin {normal input char}
move 0 to wk.word[byte];
if `c.char = ' ' then
move ^hff to wk.word[byte];
fi;
if `c.char = '?'
and `c.fld.pos = 0 then
move ^hff to wk.word[byte];
fi;
if wk.word[byte] = 0 then
switch on `c.fld.type:
`i.dec: call test.numeric.char;
`i.tot: if `c.char <> '.'
and `c.char <> '-' then
call test.numeric.char;
fi;
`i.dol: if `c.char <> "." then
call test.numeric.char;
fi;
`i.dt: if `c.char <> "/"
and `c.char <> '-' then
call test.numeric.char;
fi;
`i.iv,
`i.up: call `make.up;
`i.lo: call `make.lo;
`i.nm: begin
move 0 to wk.word[byte];
if `c.fld.pos = 0 then
move ^hff to wk.word[byte];
else
subtract 1 from `c.d.bp;
switch on @`c.d.bp:
" ","/","`",".",",","-":
move ^hff to wk.word[byte];
endswitch;
add 1 to `c.d.bp;
fi;
if wk.word[byte] <> 0 then
call `make.up;
fi;
end;
endswitch;
call test.alpha.char;
fi;
if `c.char <> ^h00 then
move `c.char to @`c.d.bp;
if `c.fld.type = `i.iv then
move ' ' to `c.char;
fi;
mcall `con.out using `c.char;
move 'Y' to data.entered.this.field;
add 1 to `c.fld.pos;
if `c.fld.pos < `c.fld.len then
add 1 to `c.d.bp;
call `bump.ch.pos;
else
subtract 1 from `c.fld.pos;
mcall `con.out using ^h08;
move 'Y' to field.overflow;
fi; fi;
end;
endswitch;
od;
od;
{-----validate screen data-----}
`get.dat.validate:
move #`c.s.fields to `c.fld.bp;
move #screen.data to `c.d.bp;
do
if @`c.d.bp <> '?' then
move @`c.fld.bp[sp] to `c.fld.parms[string]
length 4;
if `c.fld.type <> `i.end then
move @`c.d.bp[sp] to `con.str
length `c.fld.len;
add #`con.str to `c.fld.len giving wk.bp3;
move 0 to @wk.bp3;
fi;
switch on `c.fld.type:
`i.end: exitdo;
`i.up,
`i.lo,
`i.iv,
`i.alf,
`i.nm,
`i.prot: null;
`i.dec: begin
scan `con.str for no " " true begin
call left.just.field;
call right.just.field;
move `con.str to @`c.d.bp[sp] length `c.fld.len;
end;
end;
`i.tot,
`i.dol: begin
{---if field is blank, leave it blank---}
scan `con.str for no " " true begin
call left.just.field;
{--remove leading blanks--}
scan `con.str for " " giving address wk.bp2;
move 0 to @wk.bp2;
{--remove any minus'es--}
move 'N' to minus.flag;
do
scan `con.str for '-' giving address wk.bp1
false exitdo;
move 'Y' to minus.flag;
add 1 to wk.bp1 giving wk.bp2;
move @wk.bp2[sp] to @wk.bp1[sp]; {remove '-'}
od;
scan `con.str for "." giving address wk.bp1
error begin
append ".00" to `con.str;;
goto `valid.dollar;
end;
size @wk.bp1[sp] giving wk.word;
switch on wk.word[byte]:
1: append "00" to @wk.bp1[sp];
2: append "0" to @wk.bp1[sp];
3: null;
else begin
move "too many decimal places" to status.line;
call status.line.display;
goto `get.dat.redisplay;
end;
endswitch;
`valid.dollar:
call right.just.field;
size `con.str giving wk.word;
if wk.word[byte] > `c.fld.len then
move "won't fit with cents added" to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
move `con.str to @`c.d.bp[sp]
length `c.fld.len;
end;
end;
`i.dt: begin
scan `con.str for no " "
error exitswitch;
if `c.fld.len = 6 then
scan `con.str for no digits
error begin
call move.6.date;
goto `valid.date;
end;
move "all six digits must be entered (MMDDYY)"
to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
move #`con.str to wk.bp1;
scan `con.str for any "/-" giving address wk.bp2
error begin
scan `con.str for no digits
giving wk.word;
if wk.word[byte] = 6 then
call move.6.date;
goto `valid.date;
else
move "must be 6 digits unless using slashes"
to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
end;
subtract wk.bp1 from wk.bp2 giving wk.word;
switch on wk.word[byte]:
1: begin
move "0" to wk.month[byte];
move @wk.bp1 to wk.month[+1,byte];
end;
2: move @wk.bp1[wp] to wk.month[word];
else move "00" to wk.month[word];
endswitch;
add 1 to wk.bp2 giving wk.bp1;
scan @wk.bp1[sp] for any "/-" giving address wk.bp2
error begin
move "two slashes required" to status.line;
call status.line.display;
goto `get.dat.redisplay;
end;
subtract wk.bp1 from wk.bp2 giving wk.word;
switch on wk.word[byte]:
1: begin
move "0" to wk.day[byte];
move @wk.bp1 to wk.day[+1,byte];
end;
2: move @wk.bp1[wp] to wk.day[word];
else move "00" to wk.day[word];
endswitch;
add 1 to wk.bp2 giving wk.bp1;
scan @wk.bp1[sp] for no digits giving wk.word;
switch on wk.word[byte]:
2: begin
move @wk.bp1[wp] to wk.year[word];
move 0 to wk.year[+2,byte];
end;
4: move @wk.bp1[sp] to wk.year length 4;
else move 0 to wk.year[byte];
endswitch;
`valid.date:
if wk.month < '01'
or wk.month > '12' then
move "invalid month" to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
size wk.year giving wk.word;
switch on wk.word[byte]:
2: begin
move wk.year[word] to wk.year[+2,word];
move "19" to wk.year[word];
end;
4: null;
else begin
move "year must be 2 or 4 digits" to status.line;
call status.line.display;
goto `get.dat.redisplay;
end;
endswitch;
if wk.day < '01'
or wk.day > '31' then
move "invalid day" to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
switch on wk.month[word]:
'04','06','09','11': begin
if wk.day > '30' then
move "month entered only has 30 days"
to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
end;
'02': begin
move 0 to status.line[byte];
convert dec wk.year[+2] to wk.word;
divide wk.word by 4 giving wk.bp2 remainder wk.word;
if wk.word[byte] <> 0 then
if wk.day > '28' then
move "(not " to status.line;
fi;
else
if wk.day > '29' then
move "(" to status.line;
fi;
fi;
if status.line[byte] <> 0 then
append "leap year) - wrong day for Feb."
to status.line;
call status.line.display;
goto `get.dat.redisplay;
fi;
end;
endswitch;
move `c.d.bp to wk.bp1;
move wk.month[word] to @wk.bp1[wp];
add 2 to wk.bp1;
switch on `c.fld.len:
6: begin
move wk.day[word] to @wk.bp1[wp];
add 2 to wk.bp1;
move wk.year[+2,word] to @wk.bp1[wp];
end;
8,10: begin
move "/" to @wk.bp1;
add 1 to wk.bp1;
move wk.day[word] to @wk.bp1[wp];
add 2 to wk.bp1;
move "/" to @wk.bp1;
add 1 to wk.bp1;
if `c.fld.len = 8 then
move wk.year[+2,word] to @wk.bp1[wp];
else
move wk.year to @wk.bp1[sp] length 4;
fi;
end;
endswitch;
end;
endswitch;
fi;
add 3 to `c.fld.bp;
add @`c.fld.bp to `c.d.bp;
add 1 to `c.fld.bp;
od;
move 0 to `con.str[byte];
end;
print on;