page 64 title 'Simple terminal emulator - TERMINAL part' maclib term ; -->> File : TERMINAL.ASM ; ============ ; Copyright (c) Werner Cirsovius ; Hohe Weide 44 ; D-2000 Hamburg 20 ; Federal Republic of Germany ; Tel.: 040/4223247 ; Version 1.0, January 1988 ; ===== Externals ===== ; From LIB BASELIB extrn userf,strbi0,escchr,break,conind,condir,uppcon extrn conino,comp3,crlf,getlin,conchd,upinoc,open extrn physid,drvnam,close,create,setbuf,opnapp,delete extrn dskput,dskwrt,puteof,prnout,wrbuf,wrbfp,filsiz extrn indexa,rdbfp,geteof ; From LIB HILIB extrn clrscr,@leng,@assig,getams,del1ms ; From module XMODEM extrn send,receiv ; To module XMODEM public errcnt,sndrem,block,xmitch,rcvok,getbd,prbaud public errstk,errdo,rcvchr,inrdy ; From module TIMER extrn @cnlen,concti,clkon,clock ; To module SCREEN public header,comstr ; From module SCREEN extrn scrn1,scrn2,vidini,savwn1,savwn2,cursof,curson ; From very last module as DSEG extrn @top ; ===== Start the code ===== jmp syschk ; dseg ; flscr window 0,0,row-1,col ; Set full window if not debug db esc,'H' ; .. set cursor to top endif;NOT debug db 0 ; resscr window 0,0,row-1,col ; Set full window if not debug db esc,'H' ; Set cursor to top db esc,'E' ; .. clear screen endif;NOT debug db 0 ; oldwin window 1,0,row-2,col ; Set less status line db 0 cseg ; ===== Start of SIO support ===== cliost: ; Clear the SIO status register ; mvi a,siores out ioctrl ; Simple reset ret ; outrdy: ; Check SIO ready for data ; ENTRY : None ; EXIT : Return carry set if port ready for data ; call cliost ; Reset SIO in ioctrl ; Get state ani rcvrdy ; Test bit rz ; Not set stc ret ; xmitch: ; Transmit SIO character ; ENTRY : Accu holds character ; EXIT : None ; mov b,a @xmwt: call outrdy ; Wait for ready jnc @xmwt mov a,b out iodata ; Output ret ; inrdy ; Check SIO input state ; ENTRY : None ; EXIT : Carry set on character from port ; call cliost in ioctrl ; Get status ani rxcav ; Get bit rz stc ret ; recvch: ; Receive SIO character if any ; ENTRY : None ; EXIT : Carry set if ready and Accu holds character ; call inrdy ; Test any on tele line cc rcvchr ; Get it if there ret ; rcvchr: ; Receive SIO character ; ENTRY : None ; EXIT : Accu holds character from port ; in iodata ; Get it ret ; inisio: ; Initialize the SIO chip ; call userf ; Get SIO parameters dw sapara shld siobit ; Save set up mvi h,bit8 ; Eight bits mvi l,bit8 call sioset ; Set it mvi a,rtson ; Set RTS call sioset mvi a,dtron ; Set DTR sioset: call userf dw sainit ret ; clrsio: ; Reset the SIO chip ; call userf ; Get SIO parameters dw sapara lhld siobit ; Get set up call sioset ; Set old bits mvi a,rtsoff; Reset RTS call sioset mvi a,dtroff; Reset DTR jmp sioset ; dseg siobit ds 2 cseg ; ===== Start of BAUD rate support ===== setbd: ; Set BAUD rate ; ENTRY : Accu holds coded speed ; EXIT : None ; mov h,a ; Set it mov l,a call userf dw sabaud ret ; getbd: ; Get current BAUD rate ; ENTRY : None ; EXIT : Accu holds coded speed ; call userf ; Get it dw sapara mov a,b ret ; ===== The commands to be executed ===== setrat: ; The 'B' command : set the BAUD rate ; lxi d,gtbdms call strbi0 call readln ; Read line rc ; .. empty mvi c,BAUDln mvi b,1 lxi h,BAUDtb ldax d ; Check output cpi '?' jnz @valit lxi d,BDav call strbi0 @BDlop: mvi e,' ' mvi b,6 call conchd xchg push d call strbi0 ; Tell rates pop d lxi h,BAUDit dad d dcr c ; .. test end jz @BDrdy mov a,c ani 11b cz crlf jmp @BDlop @BDrdy: call crlf jmp setrat @valit: push d push h dcx d ; Point to length ldax d xchg inx h mov e,a mvi d,0 dad d ; Point to end mvi a,BAUDit-1 sub e jz BAUDpo BAUDbl: mvi m,' ' ; .. fill with blanks inx h dcr a jnz BAUDbl mvi m,0 ; .. clear end BAUDpo: pop h pop d @valil: push b push d push h mvi c,BAUDit call comp3 ; Compare pop h pop d jz @BDfin ; .. found lxi b,BAUDit dad b pop b inr b dcr c ; Test more jnz @valil jmp setrat @BDfin: pop b mov a,b call setbd ; Set the rate now ret ; dseg if german gtbdms db 'Welche Baud Rate (? f}r vorhandene Raten) ',0 BDav db 'Vorhandene Raten:',cr,lf,0 else gtbdms db 'Select Baud rate (? for rates available) ',0 BDav db 'Rates available:',cr,lf,0 endif;german cseg ; priset: ; The 'P' command : set protocol ; lxi d,prstat lda pmod call toggle ; Tell state and set it sta pmod ret ; dseg if german prstat db 'Drucker Status : ',0 else prstat db 'Current print state : ',0 endif;german cseg ; upset: ; The 'U' command : set UPPER case ; lxi d,upstat lda umod call toggle ; Tell state and set it sta umod ret ; dseg if german upstat db 'Gro~buchstaben : ',0 else upstat db 'UPPER case : ',0 endif;german cseg ; sndfil: ; The 'S' command : send a file ; call filnam ; Get name of file to send dcr a ; .. empty exists rz dcr a jz sndgo ; Ok, here let's go lxi d,finfil call strbi0 ; .. tell to reenter jmp sndfil sndgo: lxi d,fcb call filsiz ; Get records in file shld sndrem mov a,h ora l jnz rdany lxi d,filrng jmp capers ; Tell file has no records rdany: lxi d,sndmod call strbi0 ; Ask for mode call upinoc cpi 'X' ; Test XMODEM jz xmode cpi 'A' ; Test ASCII jnz sndgo ; ; The ASCII send routine ; lxi d,sndmd1 call strbi0 ; Ask for delay between characters call upinoc sui yes sta @dlmod mvi a,3 sta hedlev call comsta ; Show status mvi a,reclng sta rdbfp ; Init pointer call cursof ; No cursor asclop: call geteof ; Get character jc ascend ; .. check end push psw ; Else save call xmitch ; Send it lda @dlmod ; Test delay requested ora a jnz @nodel lxi h,500 dellop: push h call del1ms ; Delay a bit pop h dcx h mov a,l ora h jnz dellop @nodel: pop psw cpi cr ; Test new line mvi a,'=' cz condir ; Indicate it call break ; Test user break jnc asclop call conind ; Get character cpi can ; Check cancel jnz asclop lxi d,asccan jmp capers ; Tell cancel ascend: mvi a,eof call xmitch ; Close ASCII load lxi d,ascdon jmp capers ; Tell ready ; ; The XMODEM send routine ; xmode: mvi a,1 lxi h,dwnret call inixdm ; Init cancell address call send ; Send file tlser: lxi h,tabsnd call indexa ; .. Accu returns error code jmp capers dwnret: mvi a,3 jmp tlser ; dseg if german finfil db 'Datei nicht vorhanden - nochmal',cr,lf,0 sndmod db 'MODEM oder SCII Datei}bertragung ',0 sndmd1 db 'Verz|gerung der Zeichen ',0 ascdon db cr,lf,'ASCII ]bertragung fertig',cr,lf,0 filrng db 'Datei ist leer',cr,lf,0 asccan db cr,lf,'ASCII ]bertragung abgebrochen',cr,lf,0 else finfil db 'Cannot find file - reenter',cr,lf,0 sndmod db '[X]MODEM or [A]SCII file transfer ',0 sndmd1 db 'Delay of characters [Y/N]',0 ascdon db cr,lf,'ASCII transfer complete',cr,lf,0 filrng db 'File is empty',cr,lf,0 asccan db cr,lf,'ASCII transfer cancelled',cr,lf,0 endif;german tabsnd dw cmpxdm,eofxdm,errxdm,canxdm sndrem ds 2 @dlmod ds 1 cseg ; rcvfil: ; The 'R' command : receive a file ; call filnam ; Get name of file to receive dcr a ; .. empty exists rz dcr a jnz upgo ; Ok, here it is upwait: lxi d,upexi call strbi0 ; .. tell Delete or Quit call upinoc cpi 'Q' jz rcvfil cpi Cdel jnz upwait call delfcb ; .. delete file upgo: lxi d,fcb call create ; .. create new one lxi d,cancre jc errstr ; .. oops, cannot do so mvi a,2 lxi h,upret call inixdm ; Init xfer call receiv ; .. receive lxi d,cmpxdm lda rcvok ; Check all well done cpi true jz errstr lxi d,errxdm tlrer: call errstr ; Tell error rcerw: lxi d,partsv call strbi0 ; .. tell Delete or Save call upinoc cpi Csav rz ; Save what we got cpi Cdel jnz rcerw delfcb: lxi d,fcb call delete ; .. delete file ret upret: lxi d,canxdm jmp tlrer ; dseg if german upexi db 'Datei vorhanden |schen oder uit ',0 partsv db 'Teildatei |schen oder etten ',0 cancre db 'Datei kann nicht eingerichtet werden',cr,lf,0 cmpxdm db 'XMODEM ]bertragung fertig',cr,lf,0 errxdm db 'XMODEM ]bertragung fehlerhaft',cr,lf,0 canxdm db 'XMODEM ]bertragung abgebrochen',cr,lf,0 eofxdm db 'XMODEM ]bertragung ohne EOF',cr,lf,0 else upexi db 'File exists [D]elete or [Q]uit ',0 partsv db 'Partial file [D]elete or [S]ave ',0 cancre db 'Cannot create file',cr,lf,0 cmpxdm db 'XMODEM transfer completed',cr,lf,0 errxdm db 'XMODEM transfer failed',cr,lf,0 canxdm db 'XMODEM transfer cancelled',cr,lf,0 eofxdm db 'XMODEM transfer EOF not acknowledged',cr,lf,0 endif;german rcvok ds 1 cseg ; captur: ; The 'C' command : Capture data ; lxi d,dma call setbuf ; Set DMA lxi d,capsta call strbi0 ; Tell capture status lda rmod cpi true ; Test active jz alcapt ; .. already active lxi d,cappas call strbi0 lxi h,capbuf lxi d,wrbuf lxi b,5 ldir ; Init write parameter capfil: call filnam dcr a ; Test file requested rz lxi d,capfcb lxi h,fcb lxi b,36 ldir ; Unpack file name dcr a ; Check file her jz tstapp appcr: lxi d,capfcb call create ; Create the file jc caperr ; .. cannot do so stapac: mvi a,true sta rmod ; Set capture active ret tstapp: lxi d,capfcb call close @tsapp: lxi d,appcap call strbi0 ; Ask for quit, append or delete call upinoc lxi d,capfcb cpi 'A' jz appnd ; .. Append cpi 'Q' jz capfil ; .. Quit cpi Cdel jnz @tsapp call delete ; .. Delete jmp appcr ; .. and create appnd: call opnapp ; Get append buffer pointer sta wrbfp jmp stapac alcapt: lxi d,capact call strbi0 ; Tell active call upinoc cpi yes rnz ; .. no clcap: mvi a,false sta rmod ; .. set passive call puteof ; .. write last buffer lxi d,capfcb cnc close ; .. close it rnc call delete ; .. error, delete file lxi d,clerr jmp capers caperr: lxi d,cancap capers: call errstr ret ; dseg capbuf dw dma ; The capture parameter block db 0 dw capfcb rmod ds 1 capfcb ds 36 if german capsta db 'Protokolldatei z.Z ',0 cappas db 'abgeschaltet',cr,lf,0 capact db 'eingeschalet - Datei schlie~en ',0 appcap db 'Datei bereits vorhanden uit, |schen ' db 'oder nh{ngen ',0 clerr db 'Protokolldatei kann nicht geschlossen weden',0 cancap db 'Protokolldatei kann nicht angelegt werden',0 capwer db cr,lf,'** Schreibfehler in Protokolldatei **' db cr,lf,0 else capsta db 'Capture state currently ',0 cappas db 'passive',cr,lf,0 capact db 'active - Should file be closed [Y/N] ',0 appcap db 'File already exists [Q]uit, [D]elete ' db 'or [A]ppend ',0 clerr db 'Capture file close error',0 cancap db 'Capture file create error',0 capwer db cr,lf,'** Capture file write error **',cr,lf,0 endif;german cseg ; ===== Start of subroutines ===== ; inixdm: ; Init lotta things for XMODEM transfer ; ENTRY : Reg pair HL holds return address ; Accu holds level of status ; EXIT : None ; sta hedlev ; Set level shld errdo ; .. save ERROR PC lxi h,2 dad sp shld errstk ; .. and ERROR STACK call comsta ; Tell status call cursof ; No cursor lxi d,dma call setbuf ; Set DMA lxi h,0 shld block ; .. init BLOCK mvi a,0 sta errcnt ; .. and ERROR count mvi a,true sta rcvok ; .. and success lxi d,stxmdm call strbi0 ; Tell start and rule ret ; dseg if german stxmdm db 'XMODEM ]bertragung gestarted - Eingabe Ctrl-X' db ' bricht ]bertragung ab',cr,lf,0 else stxmdm db 'XMODEM transfer started - Type Ctrl-X to ' db 'cancel transfer',cr,lf,0 endif;german errdo ds 2 errstk ds 2 block ds 2 errcnt ds 1 cseg ; uppchr: ; Convert character to UPPER case if mode set ; ENTRY : Accu holds character ; EXIT : Accu holds UPPER character if mode set ; push b mov b,a lda umod cpi true ; Check request mov a,b pop b cz uppcon ; .. convert ret ; dseg umod db false cseg ; prtchr: ; Print character on console and printer if mode set ; ENTRY : Accu holds character ; EXIT : None ; push b mov b,a call condir ; .. to console lda pmod cpi true ; Check request mov a,b cz prnout ; .. print mov a,b pop b ret ; dseg pmod db false cseg ; capit: ; Put character to capture file ; ENTRY : Accu holds character ; EXIT : None ; push b mov b,a lda rmod ; Test capture cpi true jnz nocapt mov a,b call dskput ; Write to disk jnc nocapt lxi d,capwer call strbi0 ; .. oops error lxi d,capfcb call delete ; Delete file mvi a,false sta rmod ; .. set passive nocapt: mov a,b pop b ret ; toggle: ; Output state and ask for toggle ; ENTRY : Reg pair DE holds string ; Accu holds TRUE or FALSE ; EXIT : Accu holds new value ; push b mov b,a call strbi0 ; Tell state mov a,b call bolset lxi d,@togms call strbi0 ; Ask for toggle call upinoc cpi yes mov a,b ; Get old pop b rnz ; .. not toggle cma ; .. toggle ret ; bolset: ; Tell boolean state ; ENTRY : Accu holds boolean value ; EXIT : None ; lxi d,@on cpi true ; .. check current jz strbi0 lxi d,@off jmp strbi0 ; dseg if german @on db 'EIN',0 @off db 'AUS',0 @togms db ', umschalten ',0 else @on db 'ON ',0 @off db 'OFF',0 @togms db ', toggle it [Y/N] ',0 endif;german cseg ; readln: ; Read line from keyboard without Ctrl-C activity ; ENTRY : None ; EXIT : Register pair DE points to filled line ; Carry flag set on empty line ; mvi c,setcon lxi d,1000b call bdos ;Set console mode no break lxi d,rdbuff call getlin ; Fill the line push psw call crlf lxi d,0 mvi c,setcon call bdos ;Reset old state pop psw lxi d,rdbuff+2 ret ; dseg rdbuff db buflng ; The input buffer ds buflng+1 cseg ; filnam: ; Input a file name ; ENTRY : None ; EXIT : Reg pair DE points to standard FCB ; Accu holds return code: ; 1 - Zero file name ; 2 - File on disk ; 3 - File not on disk ; lxi d,@flnam call strbi0 call readln ; Get name push psw call crlf pop psw mvi a,1 rc ; .. empty xchg lxi d,fcb call @assig ; Assign it jc filnam ; .. syntax error lxi h,fcb+1 lxi b,11 mvi a,'?' cpir ; Check illegal wildcards jz filnam call physid ; .. and disk inserted jnc filok lxi d,drver call strbi0 lxi d,fcb call drvnam call crlf jmp filnam filok: call open ; Find file mvi a,2 aci 0 ret ; dseg if german @flnam db 'Name der Datei : ',0 drver db 'Keine Diskette im Laufwerk ',0 else @flnam db 'Input name of file : ',0 drver db 'No disk inserted in drive ',0 endif;german cseg ; invers: ; Set invers screen ; if debug ret else mvi a,'p' jmp escchr endif;debug ; normal: ; Set normal screen ; if debug ret else mvi a,'q' jmp escchr endif;debug ; prcomm: ; Print available commands ; ENTRY : Reg pair DE points to control string ; EXIT : None ; ; Control characters interpreted: ; ; SOH : Start of new line ; STX : Start of text item ; ETX : End of tex item ; EOT : End of text ; FF : Special end indicator ; CR : End of line ; ; All other characters will be sent to screen ; ldax d ; Check control inx d cpi soh jnz prco1 mov a,c ora a jz prcomm ; ..suppress at start mvi b,5 prcbln: call @prcom ; Give blanks rescnt: mvi c,0 ; Clear counter jmp prcomm prco1: cpi stx ; Test start of text jnz prco2 mvi a,16 sub c mov b,a call @prcom ; Fill blanks call invers ; Indicate capital letter ldax d inx d call condir call normal mvi c,1 pr1lop: ldax d inx d cpi etx ; Print till end found jz prcomm call condir inr c jmp pr1lop prco2: cpi cr ; Test end of line jnz prco3 call crlf ; Close it jmp rescnt prco3: cpi ff ; Test special jnz prco4 mvi b,53 jmp prcbln ; Give blanks prco4: cpi eot ; Test total end rz call condir inr c jmp prcomm @prcom: push d mvi e,' ' ; Dont't overwrite pointer call conchd pop d ret ; comsta: ; Give some info of system while in command mode ; call status ; Get status lxi d,savwn1 call strbi0 ; Clear command field lxi d,savwn2 call strbi0 ; Set smaller one ret ; header: ; Give some info of system ; call status ; Get status lxi d,oldwin call strbi0 ; Set old window ret ; status: ; Tell current state of system ; lxi d,flscr ; Set full screen call strbi0 call invers lxi h,hdtab ; Get pointer to status line hdlop: mov e,m ; .. get text inx h mov d,m inx h mov a,e ; Check end ora d jz endhed call strbi0 ; Print it mov e,m ; .. get PC inx h mov d,m inx h push h xchg call callhl ; .. call through HL pop h jmp hdlop ; .. loop on endhed: lxi h,hdlvtb lda hedlev call indexa ; Set level call strbi0 ; .. tell it call normal ret ; prbaud: ; Tell current BAUD rate ; call getbd ; Get BAUD rate dcr a add a ; *2 mov b,a add a ; *4 add b ; *6 mov c,a mvi b,0 lxi h,BAUDtb dad b ; Get pointer xchg call strbi0 ret ; boolP: ; Tell state of printer ; lda pmod jmp bolset ; boolU: ; Tell state of upper case ; lda umod jmp bolset ; boolC: ; Tell state of capture ; lda rmod jmp bolset ; dseg BAUDtb db '50 ',0 BAUDit equ $-BAUDtb db '75 ',0,'110 ',0,'134.5',0 db '150 ',0,'300 ',0,'600 ',0,'1200 ',0 db '1800 ',0,'2400 ',0,'3600 ',0,'4800 ',0 db '7200 ',0,'9600 ',0,'19200',0 BAUDln equ ($-BAUDtb) / BAUDit ; if german headC db 'Protokoll.: ',0 headP db ' ',delim,' Drucker : ',0 headU db ' ',delim,' Gro~buchst.: ',0 headB db ' ',delim,' Baud Rate : ',0 headL0 db ' ',delim,' EXIT f}r Befehle.',0 headL1 db ' ',delim,' XMODEM Sendung .',0 headL2 db ' ',delim,' XMODEM Empfang .',0 headL3 db ' ',delim,' ASCII Sendung .',0 else headC db 'Capture : ',0 headP db ' ',delim,' Printer : ',0 headU db ' ',delim,' Upper case : ',0 headB db ' ',delim,' Baud rate : ',0 headL0 db ' ',delim,' EXIT for command.',0 headL1 db ' ',delim,' XMODEM send file .',0 headL2 db ' ',delim,' XMODEM receive file',0 headL3 db ' ',delim,' ASCII send file .',0 endif;german ; hdtab dw headC,boolC dw headP,boolP dw headU,boolU dw headB,prbaud dw 0 hdlvtb dw headL0,headL1,headL2,headL3 hedlev ds 1 cseg ; switch: ; Search key in table and execute routine ; ENTRY : Accu holds key ; Reg pair HL points to table, ; last element is -1 ; mov b,m ; Get the key inx h cmp b ; Compare jz @swfnd inr b ; Test end of table jz @swfnd inx h ; Skip entry inx h jmp switch @swfnd: mov e,m ; Get address inx h mov d,m xchg callhl: pchl ; Execute ; comand: ; Execute command ; call scrn1 ; Set screen mode lxi d,comms call prcomm ; Tell available commands call conino ; Get next character call uppcon push psw call crlf pop psw lxi h,comtab call switch ; Execute illcom: call scrn2 ; Restore all ret byebye: lda rmod ; Test capture cpi true cz clcap ; .. close file if open lxi d,resscr call strbi0 ; .. set full screen mvi e,' ' mvi b,(col-@trln) / 2 call conchd ; Set to middle call invers lxi d,terex call strbi0 ; Tell exit call normal mvi e,' ' lhld @cnlen mvi a,col sub l ora a rar mov b,a call conchd ; Set to middle call invers call concti ; Tell time used call normal call crlf call clrsio ; Clear SIO jmp warm ; dseg comtab db 'B' dw setrat db 'S' dw sndfil db Crecv dw rcvfil db Ccapt dw captur db Cprnt dw priset db Ccase dw upset db 'Q' dw byebye db -1 dw illcom if german comms db 'Eingabe Befehl:',cr db soh,stx,'Baud Rate',etx db stx,'Drucker',etx db stx,'Gro~buchstaben',etx,cr db soh,stx,'Senden Datei',etx db stx,'Empfangen Datei',etx db stx,'Protokoll Datei',etx,cr db ff,stx,'Quit',etx,cr db '->',eot terex db '*** TERMINAL Programm - ',cprig db ' WEC 1988 - beendet ***' @trln equ $-terex db cr,lf,0 else comms db 'Enter command:',cr db soh,stx,'Baud rate set',etx db stx,'Printer',etx db stx,'Upcase',etx,cr db soh,stx,'Send file',etx db stx,'Receive file',etx db stx,'Capture data',etx,cr db ff,stx,'Quit',etx,cr db '->',eot terex db '*** TERMINAL Program - ',cprig db ' WEC 1988 - stopped ***' @trln equ $-terex db cr,lf,0 endif;german cseg ; errstr: ; The ERROR handler ; ENTRY : Reg pair DE points to message ; mvi a,0 sta hedlev mvi a,bell call condir ; .. ring the bell call crlf call invers ; Set invers call strbi0 ; .. give message lxi d,quit call strbi0 call normal call wtquit ; Get quit call curson ; Turn on the cursor ret ; dseg if german quit db ' - Eingabe beliebige Taste',0 else quit db ' - Press any key to quit',0 endif;german cseg ; wtquit: ; Wait for quit, fill background buffer meanwhile ; call break ; Test character here jc upinoc ; Get it, if so call getsio ; Get from line if any here jmp wtquit ; getsio: ; Get character from tele line and save it ; call recvch ; Get character rnc ; None here push h push b lxi h,0 dad sp ; Get stack mov b,h lhld bkbpnt mov m,a ; Save it mov a,h cmp b ; Test still room jz skget inx h ; .. doen't bump if no room skget: mvi m,0 shld bkbpnt pop b pop h ret ; outbkb: ; Output the background buffer ; lxi d,@top ldax d ; Test any character her ora a rz ; No, exit call strbi0 ; If so,show it inibkb: lxi h,@top shld bkbpnt ; Clear buffer mvi m,0 ret ; dseg bkbpnt ds 2 cseg ; ===== The MAIN part ===== syschk: lhld bdos+1 sphl call getams ; Get validation lxi d,illver jc comstr call userf ; Get XBIOS info dw cdinfo mov a,c ; State in reg C cpi 0ffh ; Should be fitted state lxi d,serial jz main comstr: call strbi0 ; Tell error lxi d,@abort call strbi0 ; .. and BREAK jmp warm ; .. exit ; dseg if german illver db 'Diese BBS Version ben|tigt CP/M 3.x ' db 'und den JOYCE',cr,lf,0 serial db 'Der JOYCE ben|tigt die serielle Schnitstelle' db ' f}r BBS',cr,lf,0 @abort db cr,lf,'ABBRUCH: Fehler beseitigen und neu ' db 'starten',cr,lf,0 else illver db 'This BBS version requires CP/M 3.x and the ' db 'PCW8256/8512 as machine',cr,lf,0 serial db 'The PCW8xxx requires the serial interface for' db ' running BBS',cr,lf,0 @abort db cr,lf,'ABORT: Fix bugs and retry',cr,lf,0 endif;german ; cseg main: call vidini ; Init video saver lxi d,clkon call clock ; Freeze start of program call inisio ; .. init the SIO mvi a,0 sta hedlev ; Set header level call header ; Give header info if not debug call clrscr ; .. clear rest of screen endif;NOT debug mvi a,false sta rmod ; .. no capture call inibkb ; Clear background buffer @main: call break ; Test keyboard available jnc @sio ; No, get from the line call conind ; .. get it call uppchr ; .. as UPPER case ani msb ; Only seven bit cpi esc ; Test command mode jnz @send call comand ; Execute command call outbkb ; Output what we found @sio: call inrdy ; Check character on line jnc @main ; .. no call rcvchr ; Get it ani msb ; .. without MSB cpi ' ' ; Check range jnc putcon lxi h,ctrtab lxi b,ctrlen cpir ; .. test legal control jnz @main ; .. no, exit ; dseg ctrtab db bs,tab,lf,ff,cr,bell ctrlen equ $-ctrtab cseg putcon: call prtchr ; .. to console and printer call capit ; .. and file jmp @main @send: mov b,a call xmitch ; Transmit it mov a,b cpi cr ; Check new line jnz @main mvi a,lf call capit jmp @main end