;-*-MIDAS-*- subttl BYELIB -- cute messages ; 8/30/88 Maeda -- added conditional assembly for other lins files comment|  File: BYELIB Node: Top The BYELIB library is used to get messages from the COMMON;LINS > file. For instance the BYE program uses this. This library is pretty easy to use, but you have to give it a lot of registers and channels. You have to give it registers labeled A-F, a register called CNT, and a stack pointer in P. Only registers A and B need be consecutive. You also have to give it three idle channels: LINCH, IDXCH, ODXCH. Some day I may reduce the register and channel demands if I have nothing better to do. To use, just PUSHJ P, GETMSG. It will bash only registers A and B, and will remember to close the file channels. It will return a byte pointer to an ASCIZ string in A, its length in B. This library never skip-returns. Normally all errors will .LOSE. If you want to handle errors yourself, you must set $$DETH nonzero and define a routine called DEATH. Then .CALL errors will JSR DEATH. The variable CALOSS (only defined when $$DETH is nonzero) will then have the error code. Bugs to Gumby PS: Don't forget: Soft soap often has a high percentage of lye in it. -- Salada tea.  | ;end info documentation .begin BYELIB .auxil .tyo6 .ifnm1 .tyo 40 .tyo6 .ifnm2 printx / included in this assembly. / ifndef $$deth, $$deth==0 ;jsr to DEATH call=: ret=: save=:push p, rest=:pop p, ascbyt==440700 ;ascii bye pointer ifn $$deth,[ .scalar caloss define syscall name,args .call [setz ? sixbit /name/ ? args ? setzb caloss] termin define calerr jsr death termin ] ;handle errors? ife $$deth,[ define syscall name,args .call [setz ? sixbit /name/ ? args((setz))] termin define calerr .lose %lsfil termin ] ;errors just .lose ;;; We do this ugly thing so that the filenames go in user's literal space, ;;; rather than wherever this file happens to be loaded. ifndef $$yow, $$yow==:0 ; ... ifndef $$foo, $$foo==:0 ifn $$yow, $$bye==:0 ifndef $$bye, $$bye==:1 disk: sixbit /DSK/ idxtmp: sixbit /_TEMP_/ byesnm: sixbit /COMMON/ ifn $$bye,[ byefil: sixbit /LINS/ sixbit />/ idxfil: sixbit /INDEX/ sixbit /.BYE./ ] ; ifn $$bye ifn $$yow,[ byefil: sixbit /YOW/ sixbit />/ idxfil: sixbit /INDEX/ sixbit /.YOW./ ] ; ifn $$yow insiz==100. ;input buffer size outsiz==100. ;output buffer size isiz==600 ;max size of message subttl GETMSG -- get the quip from the file .scalar inlins(isiz+1) ;;; there's no need for the hair here -- it should open idxch in unit mode ;;; (.uii) and linch in block ascii mode (.bai) getmsg: save c save d save e save f save cnt call fileo ;open index and lins files syscal sstatu,[repeat 4,%clout,,b ;discard %clout,,a] ;uptime in seconds jfcl .pdtime b, ;be vaguely random rot b,3 xor a,b movms a idiv a,nwds ;B becomes message number .access idxch,b ;look in table for its character position hrroi a,b .iot idxch,a hlrz d,b ;length to d hrrzs b ;clear length from access idivi b,5 ;turn into number or 36-bit words into file .access linch,b move a,[-isiz,,inlins] .iot linch,a move a,[ascbyt,,inlins] sojl c,done ;did message fall on a word boundary? getms2: ibp a ;nope, so adjest byte pointer forward sojge c,getms2 ;(how can this work?) done: move b,d ;move length to b .close linch, ;nettoyer .close idxch, rest cnt rest f rest e rest d rest c ret subttl FILEO -- open lins and idx files. .scalar nwds fileo: syscal open,[%clbit,,.bii ? %climm,,linch disk ? byefil ? byefil+1 ? byesnm] calerr syscal open,[%clbit,,.bii ? %climm,,idxch disk ? idxfil ? idxfil+1 ? byesnm] jrst newidx ;no index file at all!!! syscal rfdate,[%climm,,linch ? %clout,,a] calerr syscal rfdate,[%climm,,idxch ? %clout,,b] calerr came a,b ;index created at same time? jrst newidx ;nope, make a new one. syscal fillen,[%climm,,idxch ? %clout,,nwds] calerr ret subttl NEWIDX -- make a new index file. ;;; Every time a new lines file is written, a new index file must be ;;; produced. The file has one entry for each message, containing ;;; character-length,,location-of-first-character .scalar inbuf (insiz) .scalar outbuf (outsiz) newidx: .close idxch, syscal open,[%clbit,,.bio ? %climm,,odxch disk ? idxfil ? idxtmp ? byesnm] calerr syscal rfdate,[%climm,,linch ? %clout,,a] calerr syscal sfdate,[%climm,,odxch ? %clin,,a] calerr setz cnt, ;access count in characters movei c,<5*insiz>+1 ;c is # in this buffer movei f,<5*insiz>+1 ;f is # chars used this buffer move e,[-outsiz,,outbuf] setz a, ;used to accumulate length of message outlup: call getchr ;returns char in b, uses bptr in d jrst outend ;no more characters jumpe b,outptr ;if ^@, then output count for previous message cain b,177 jrst outptq ;if , interpret next char specially aoja a,outlup ;keep counting length of current message outend: .close linch, ;here at eof hrrzs e ;clean up output buffer subi e,outbuf movns e hrls e hrri e,outbuf .iot odxch,e syscal renmwo,[%climm,,odxch ? idxfil ? idxfil+1] calerr .close odxch, jrst fileo ;tail-recurse trying once again to open... outptq: call getchr ;just read , so need next character jrst outptr ;nothing there, so ignore it tlnn a,-1 jrst outpt2 ;ignore if after first message subi b,"0 ;turn into a number outpt2: sojl b,outpt3 ;done? movsm a,(e) ;stuff out pointer aobjn e,outpt2 ;buffer full? move e,[-outsiz,,outbuf] ;yes, print it out .iot odxch,e move e,[-outsiz,,outbuf] jrst outpt2 ;and see if need to stuff again outpt3: call getchr jrst outend ;all out of characters jumpe b,outbck ;if followed by , flush that, too add d,[70000,,0] tlne d,400000 add d,[347777,,-1] ;replace the character in the buffer soj f, soja cnt,outbck ;and re-enter main loop outptr: tlnn a,-1 ;doesn't skip if on first message (doc) jrst outbck movei b,1 ;default jrst outpt2 outbck: hrlzi a,(cnt) ;cnt is maintained by getchr jrst outlup ;;; gets character from file being indexed. getchr: camge f,c jrst getch1 caige c,<5*insiz> ret ;no more characters move c,[-insiz,,inbuf] .iot linch,c hrrzs c subi c,inbuf jumpe c,cpopj ;didn't read any new ones imuli c,5 setz f, move d,[ascbyt,,inbuf] getch1: ildb b,d aoj f, aoj cnt, ;aos char address in file aos (p) cpopj: ret .end byelib