ϾSTEST DOC/hSTEST ZEX and constants cr equ 0dh lf equ 0ah ; External Definitions of Routines to be Used ext fname ; Convert file name into FCB format ext print ; Print string ext bbline ; Input Line Editor ext fo0$open ; Open File for Output ext fo0$close ; Close File ext f0$put ; Write Byte to File ; ; This part of the program prompts the user for input and inputs a line ; call print db 'STEST001 - Byte-Oriented File Output Demonstration' db cr,lf,'Name of File to Create? ',0 xor a ; A=0 so BBLINE does not capitalize line call bbline ; input file name from user or a ; check char count for zero ret z ; return to OS if no line input ; ; The file name specified by the user is converted into the FCB format ; and stored into an FCB ; ; First char of filename is pointed to by HL, as returned by BBLINE ; ld de,fcb ; load fcb call fname ; ; Now we open the file for byte-oriented output; since FNAME does not ; affect DE, DE still points to the FCB ; call fo0$open ; open file for output jp z,loop ; ok to proceed ; ; File could not be opened -- print error message and abort ; call print db cr,lf,'Cannot Open File -- Abort',0 ret ; ; This loop prompts the user for a line and stores it in the file. ; If the user types an empty line (just ), we exit and close the ; output file. ; loop: call print db cr,lf,'Input Line (=Done)? ',0 xor a ; A=0 so BBLINE does not capitalize line call bbline ; get line from user or a ; check char count jp z,done ; done if no chars ; ; This loop writes the string pted to by HL (from BBLINE) to disk. ; oloop: ld a,(hl) ; get char or a ; done if zero jp z,odone call f0$put ; write to disk jp nz,derr ; check for disk error inc hl ; pt to next char to output jp oloop ; ; This routine terminates the string just written to disk with a ; pair, and the creation of the file is continued. ; odone: ld a,cr ; new line call f0$put ld a,lf call f0$put jp loop ; ; The user has typed an empty line (just ), so we close the file ; and exit. ; done: call fo0$close ; close file ret ; ; Error message and abort if error occurs while writing to disk. ; derr: call print db cr,lf,'Disk Output Error',0 ret ; ; FCB used by program ; fcb: ds 36 end ; ; PROGRAM: STEST006 ; AUTHOR: Richard Conn ; PURPOSE: This program dumps the disk file specified by the user ; in hexadecimal and ASCII ; NOTE: This test demonstrates the use of the SYSLIB Byte-Oriented ; File Input routines ; ; External CP/M or ZCPR3 Buffers fcb equ 5ch ; External References for SYSLIB routines used ext fi1$open ; Open File for Byte-Oriented Input ext fi1$close ; Close File ext f1$get ; Get Byte from File ext cout ; Character Output ext pa2hc ; Print A as 2 Hex Chars ext phldc ; Print HL as up to 5 decimal digits ext print ; String Print ext crlf ; New Line ; ; Start of Routine -- Print Banner ; call print db 'STEST006 - Sample DUMP Program to Illustrate SYSLIB ' db 'Byte-Oriented File Input' db 0 call crlf ; new line ; ; Set Offset Counter ; ld hl,0 ; Init to zero ld (counter),hl ; ; Open File for Input ; ld de,fcb ; pt to FCB filled in by OS call fi1$open ; try to open it jp z,loop ; continue if OK call print ; file must not have been found db 'File Not Found',0 ret ; return to Operating System ; ; Main Loop ; loop: ld b,0 ; set byte count in case no more chars call f1$get ; get first character jp nz,readdn ; done if past EOF push af ; save character ld hl,(counter) ; get counter value call phldc ; print as decimal number ld de,8 ; add 8 to counter for next print add hl,de ld (counter),hl ; save count away call print db ': ',0 ld b,0 ; set byte count to zero ld hl,buffer ; point to first byte of buffer pop af ; get first character jr readlp1 readlp: call f1$get ; get next byte jp nz,readdn ; done if past EOF readlp1: ld (hl),a ; store byte into buffer inc hl ; point to next byte in buffer inc b ; increment byte count ld a,b ; check for done cp 8 ; read in 8 bytes? jp nz,readlp call bufprint ; print contents of buffer call crlf ; new line jp loop ; continue until End of File ; ; Done with Read -- Print current Buffer and Exit ; B = Number of bytes to print ; readdn: call bufprint ; print buffer call crlf ; new line call fi1$close ; close file ret ; ; Buffer print routine; print the contents of the buffer for B bytes ; bufprint: ld hl,buffer ; point to first byte of buffer push bc ; save character count bufploop: ld a,b ; check count first (in case of zero) or a ; done? jp z,ascprint ; print as ASCII chars if done dec b ; count down ld a,(hl) ; get byte from buffer inc hl ; point to next byte in buffer call pa2hc ; print byte as 2 Hex chars ld a,' ' ; print a space call cout jp bufploop ; ; Now print buffer as ASCII characters ; ascprint: ld hl,buffer ; point to first character pop bc ; get character count ld a,b ; check for empty buffer or a ret z call print ; print a separator db '! ',0 ascploop: ld a,b ; check for empty buffer or a ; done if zero ret z ; return to caller if so dec b ; count down ld a,(hl) ; get byte to output and 7fh ; mask out most significant bit ld c,a ; save character in C cp ' ' ; test for printable character jp nc,ascp ; print character if printable ld c,'.' ; print dot if not printable char ascp: ld a,c ; get char to print call cout ; print it inc hl ; point to next character jp ascploop ; continue until count is exhausted counter: ds 2 ; Offset Counter buffer: ds 8 ; 8-byte buffer for input bytes end ; PROGRAM: STEST008 ; NAME('S0FTEST') ; TITLE S0FTEST - SYSLIB FILEIO Timing Routine ; ; Program: S0FTEST ; Version: 1.0 ; Author: Al Dunsmuir ; Date: 4 May 85 ; ; ; S0FTEST reads a file via the FILEIO character I/O routines. It was ; written to determine the relative efficiency of the SYSLIB 3.1 ; optimized I/O routines vs the original SYSLIB 3.0 versions. ; ; On a 4 Mhz Z80 system, using a CompuPro Disk 1 DMA controller, ; 8" disks and 1024 byte sectors, the timings were as follows ; for a 388K file (3098 records): ; Program SYSLIB time (m:ss) Ratio ; S0FTEST 3.0 3:59 1.00 ; S0FTEST 3.1 1:52 0.47 ; VERS EQU 10 ; Version Number ; Constants TBUFF EQU 80H ZERO EQU 00H BELL EQU 07H BS EQU 08H TAB EQU 09H LF EQU 0AH FF EQU 0CH CR EQU 0DH EOF EQU 1AH ; Syslib external routines EXT PRINT EXT CLINE,SKSP EXT FNAME EXT FI0$OPEN,F0$GET,FI0$CLOSE EXT INITFCB BEGIN: LD (SP$SAVE),SP ;Save current stack. LD SP,STACK ;Set new stack. CALL PRINT ;Print sign-on message. db 'STEST008',cr,lf DEFB 'S0FTEST, Version ' DEFB VERS/10+'0','.',[VERS MOD 10]+'0' DEFB CR,LF,0 LD HL,TBUFF ;Pt to command line. CALL CLINE ;Save command line as a string. CALL SKSP ;Skip leading spaces. LD A,(HL) ;Get first char. CP '/' ;Help? JP Z,HELP OR A JP Z,HELP CALL PRINT ;Keep the folks up to date. DB 'Processing begins.',CR,LF,0 LD DE,I$FCB ;Point to input file ID. CALL FNAME ;Get first file name and data. JP Z,FNMERR ;Br if bad file spec. INC DE ;Get input file name. LD A,(DE) CP ' ' ;Must be specified. JP Z,CMDERR LD HL,I$FCB ;Check if ambiguous input file name, type. CALL CKAMBG JP Z,AMBERR LD DE,I$FCB ;Point to input file control block. CALL INITFCB ;Initialize. CALL FI0$OPEN ;Open file. JP NZ,NTFERR ;no input file. LOOP: CALL F0$GET ;Get next character. JR Z,LOOP ;Loop until EOF INPUT_EOF: ;All bytes have been processed. CALL FI0$CLOSE ;Close file. CALL PRINT ;Let everyone know the good news. DB 'Processing complete.',CR,LF,0 RETURN: LD SP,(SP$SAVE) ;Restore original stack. RET ;Return to CCP. ; Check file name and type for ambiguous file spec (?). ; ; Input: HL -> File name. ; Output: Z set if ambiguous ; reset if not ambigous. ; CKAMBG: LD B,11 ;Length of file name and type. CKAMB1: INC HL ;Next char. LD A,(HL) ;Get character. CP '?' ;Ambiguous? RET Z ;Return if error. DJNZ CKAMB1 ;Loop. INC B ;Return non-zero. RET HELP: CALL PRINT ;Print help message. DB CR,LF DB 'STEST008' DB CR,LF DB 'S0FTEST Syntax:',CR,LF DB ' S0FTEST infile',CR,LF DB 'where:',CR,LF DB ' infile is the input file spec',CR,LF DB CR,LF DB 'File spec may be in the form [DU:]fname.ftype.',CR,LF DB 'Ambiguous file spec is NOT allowed.',CR,LF DB CR,LF,0 JP RETURN ;Exit AMBERR: CALL PRINT ;Print error message. DB 'Ambiguous file spec not allowed.',CR,LF,0 JP RETURN ;Exit CLIERR: CALL PRINT ;Print error message. DB 'Can''t close input file.',CR,LF,0 JP RETURN ;Exit CMDERR: CALL PRINT ;Print error message. DB 'Command syntax error.',CR,LF,0 JP RETURN ;Exit DIRERR: CALL PRINT ;Print error message. DB 'No directory space.',CR,LF,0 JP RETURN ;Exit FNMERR: CALL PRINT ;Print error message. DB 'Invalid file name.',CR,LF,0 JP RETURN ;Exit NTFERR: CALL PRINT ;Print error message. DB 'Input file not found.',CR,LF,0 JP RETURN ;Exit ; Input file Control Block. ; I$FCB: DS 1 ;Drive - zeroed by FXIO DB ' ' ;File name. DB ' ' ;File type. DS 24 ;Remainder of FCB set by FXIO. ; User Stack and Initial Stack Pointer. ; SP$SAVE: DW ZERO ;Initial stack pointer stored here. DS 48 ;24 level stack. STACK: END ; PROGRAM: STEST009 ; NAME('SXFTEST') ; TITLE SXFTEST - SYSLIB FXIO Timing Routine ; ; Program: SXFTEST ; Version: 1.0 ; Author: Al Dunsmuir ; Date: 4 May 85 ; ; ; SXFTEST reads a file via the FXIO character I/O routines. It was ; written to determine the relative efficiency of the SYSLIB 3.1 ; optimized I/O routines vs the original SYSLIB 3.0 versions. ; ; On a 4 Mhz Z80 system, using a CompuPro Disk 1 DMA controller, ; 8" disks and 1024 byte sectors, the timings were as follows ; for a 388K file (3098 records): ; ; Program BUFFSIZE SYSLIB time (m:ss) Ratio ; SXFTEST 001 (128) 3.0 2:09 1.00 ; SXFTEST 3.1 1:55 0.89 ; ; SXFTEST 008 (1 k) 3.0 1:58 1.00 ; SXFTEST 3.1 1:51 0.94 ; ; SXFTEST 016 (2 k) 3.0 2:22 1.00 ; SXFTEST 3.1 1:23 0.58 ; ; SXFTEST 032 (4 k) 3.0 2:10 1.00 ; SXFTEST 3.1 1:23 0.64 ; ; SXFTEST 064 (8 k) 3.0 2:02 1.00 ; SXFTEST 3.1 1:23 0.68 ; ; SXFTEST 128 (16 k) 3.0 2:01 1.00 ; SXFTEST 3.1 1:23 0.69 ; ; SXFTEST 256 (32 k) 3.0 2:59 1.00 ; SXFTEST 3.1 1:42 0.57 ; ; BUFSIZE EQU 16 ;Input buffer size (# of 128 byte records) VERS EQU 10 ; Version Number ; Constants TBUFF EQU 80H ZERO EQU 00H BELL EQU 07H BS EQU 08H TAB EQU 09H LF EQU 0AH FF EQU 0CH CR EQU 0DH EOF EQU 1AH ; Syslib external routines EXT PRINT EXT CLINE,SKSP EXT IALLOC,ALLOC EXT FNAME EXT FXI$OPEN,FX$GET,FXI$CLOSE BEGIN: LD (SP$SAVE),SP ;Save current stack. LD SP,STACK ;Set new stack. CALL PRINT ;Print sign-on message. DB 'STEST009',CR,LF DB 'SXFTEST, Version ' DB VERS/10+'0','.',[VERS MOD 10]+'0' DB CR,LF,0 LD HL,TBUFF ;Pt to command line. CALL CLINE ;Save command line as a string. CALL SKSP ;Skip leading spaces. LD A,(HL) ;Get first char. CP '/' ;Help? JP Z,HELP OR A JP Z,HELP CALL PRINT ;Keep the folks up to date. DB 'Processing begins.',CR,LF,0 PUSH HL ;Save pointer to command line string. XOR A ;Initialize dynamic buffer. CALL IALLOC LD DE,BUFSIZE*128 ;Get size of input buffer. CALL ALLOC ;Get input buffer. JP Z,MEMERR ;Abort if memory not available. LD (BUFF$I),HL ;Save pointer to buffer. POP HL ;Restore pointer to command line. LD DE,I$FCB ;Point to input FCB. CALL FNAME ;Get input file name and data. JP Z,FNMERR ;Br if bad file spec. LD HL,I$FCB ;Check if ambiguous input file name, type. CALL CKAMBG JP Z,AMBERR LD DE,IOCTLI ;Point to input file parm block. CALL FXI$OPEN ;Open file. JP Z,NTFERR ;OOPS - no input file. LOOP: CALL FX$GET ;Get next character. JR NZ,LOOP ;Loop until if end of file. INPUT$EOF: ;All bytes have been processed. CALL FXI$CLOSE ;Close file. JP Z,CLIERR ;can't close input file. CALL PRINT ;Let everyone know the good news. DB 'Processing complete.',CR,LF,0 RETURN: LD SP,(SP$SAVE) ;Restore original stack. RET ;Return to CCP. ; Check file name and type for ambiguous file spec (?). ; ; Input: HL -> File name. ; Output: Z set if ambiguous ; reset if not ambigous. ; CKAMBG: LD B,11 ;Length of file name and type. CKAMB1: INC HL ;Next char. LD A,(HL) ;Get character. CP '?' ;Ambiguous? RET Z ;Return if error. DJNZ CKAMB1 ;Loop. INC B ;Return non-zero. RET HELP: CALL PRINT ;Print help message. DB CR,LF,'STEST009' DB CR,LF DB 'SXFTEST Syntax:',CR,LF DB ' SXFTEST infile',CR,LF DB 'where:',CR,LF DB ' infile is the input file spec',CR,LF DB CR,LF DB 'File spec may be in the form [DU:]fname.ftype.',CR,LF DB 'Ambiguous file spec is NOT allowed.',CR,LF DB CR,LF,0 JP RETURN ;Exit AMBERR: CALL PRINT ;Print error message. DB 'Ambiguous file spec not allowed.',CR,LF,0 JP RETURN ;Exit CLIERR: CALL PRINT ;Print error message. DB 'Can''t close input file.',CR,LF,0 JP RETURN ;Exit CMDERR: CALL PRINT ;Print error message. DB 'Command syntax error.',CR,LF,0 JP RETURN ;Exit DIRERR: CALL PRINT ;Print error message. DB 'No directory space.',CR,LF,0 JP RETURN ;Exit FNMERR: CALL PRINT ;Print error message. DB 'Invalid file name.',CR,LF,0 JP RETURN ;Exit MEMERR: CALL PRINT ;Print error message. DB 'Memory allocation failed.',CR,LF,0 JP RETURN ;Exit NTFERR: CALL PRINT ;Print error message. DB 'Input file not found.',CR,LF,0 JP RETURN ;Exit ; Input file I/O Control Block. ; IOCTLI: DB BUFSIZE ;# of 128 byte pages in input buffer. DS 5 ;Used by FXIO BUFF$I: DW 0 ;Input buffer address set after allocation. I$FCB: DS 1 ;Drive - zeroed by FXIO DB ' ' ;File name. DB ' ' ;File type. DS 24 ;Remainder of FCB set by FXIO. ; User Stack and Initial Stack Pointer. ; SP$SAVE: DW ZERO ;Initial stack pointer stored here. DS 48 ;24 level stack. STACK: END ; ; PROGRAM: STEST002 ; AUTHOR: Richard Conn ; PURPOSE: To demonstrate the SYSLIB routines for directory manipulation. ; NOTE: This program loads the disk directory and selects and prints files ; which are non-system in the user area given by the user; it ; may be used to test and compare DIRF and DIRFS ; ; ; Externals ; ext bbline ; Input Line Editor ext eval10 ; String to Binary Conversion ext dirf ; Fast Directory Load/Select/Alphabetize/Pack ext dirfs ; DIRF with File Sizing ext print ; Print String ext cin ; Char in ext caps ; Capitalize ext cout ; Char out ext crlf ; New Line ext retud ; Return User and Disk ext codend ; End of Code/Beginning of Buffer ; ; CP/M Equates ; fcb equ 5ch ; address of FCB loaded by CP/M cr equ 0dh lf equ 0ah ; ; I would normally look at the FCB to see if any file was specified and ; make it wild (all ?'s) if so, but I won't do this so we can get right ; to the problem at hand. Hence, if the user simply types SYSTEST2 as ; his command, the FCB will be all spaces and no file will match it. ; ld hl,fcb+1 ; clear FCB to ? chars ld b,11 ; 11 bytes ld a,'?' ; wild card fill: ld (hl),a ; copy into FCB inc hl dec b jp nz,fill ; ; Main Loop ; test: call print db cr,lf,'STEST002 - Demo of Directory Routines in SYSLIB' db cr,lf,'Use DIRF (Y), DIRFS (N), or Quit (Q)? ',0 call cin ; get and save response call caps call cout cp 'Q' ret z ld (routine),a call print db cr,lf,'User Number? ',0 call bbline ; get line from user call crlf ; new line call eval10 ; get user number in A ld c,a ; save user number call codend ; get buffer address in HL ld de,fcb ; pt to fcb in DE ld a,c ; user number in A or 10000000b ; Mask in MSB so only Non-System files selected ld c,a ; result in C ld a,(routine) ; get routine selection cp 'Y' ; use DIRF? ld a,c ; restore flag jp nz,usefs call dirf ; load dir/select files/alphabetize/pack jp usef usefs: call dirfs usef: ; ; We now have a set of fixed-length records in memory, the first one being ; pointed to by HL. The number of records is in BC, and the length of each ; record is 16 bytes. These are the first 16 bytes of the FCBs of all files ; which matched the files we were looking for. ; ; I will now print out these file names horizontally across the screen. ; ld d,0 ; set 4 count (new line every 4 entries) ld a,b ; any file names? or c ; zero if so jp nz,loop ; continue if any names call print db cr,lf,'No Files Match Ambiguous File Name',0 jp test ; return to OS ; ; This is the main loop to print the matching file names. ; loop: push de ; save 4-count in D call prfile ; print file name (HL, BC not affected) ld de,16 ; point to next file name by adding 16 to HL add hl,de pop de ; get 4-count in D inc d ; add 1 to 4-count ld a,d ; check to see if it is a 4 multiple and 3 ; zero if so call z,crlf ; ... and new line dec bc ; count down ld a,b or c jp nz,loop jp test ; return to Operating System when done ; ; Print file name whose FCB is pointed to by HL. Do not affect HL or BC. ; prfile: push bc ; save regs push hl inc hl ; pt to first char of file name ld b,8 ; print 8 bytes call prch ; my routine to do this (not in SYSLIB) ld a,'.' ; print dot call cout ld b,3 ; print 3 bytes call prch call print db ' ! ',0 ; print name separator pop hl ; restore regs pop bc ret ; ; Print B chars pointed to by HL ; prch: ld a,(hl) ; get char inc hl ; pt to next call cout ; print char dec b ; count down jp nz,prch ret ; ; Buffer ; routine: ds 1 ; routine select flag end ; ; PROGRAM: STEST011 ; AUTHOR: RICHARD CONN ; COMMENTS: This is a test program for SYSLIB which exercises the ; SFYIO routines, especially FY$GET and FY$UNGET ; ; The algorithm employed in this test routine illustrates the ; power and flexibility of the FY$GET/FY$UNGET combination. Very clean ; code can be generated, since this provides one-character lookahead. ; The algorithm is as follows: ; ; 1. Get next char from file ; 2. Case ; EOF : Exit and print counts ; ; : Increment comment count (semicolons) ; , : Increment comma count ; Tab : Increment tab count ; LF : Increment new line count ; ALNUM : (Alphanumeric) Increment word count ; Flush characters which follow that are ; alphanumeric ; Put terminating non-alphanumeric back for ; next get char (1) ; 3. Goto 1 ; ext fyi$open,fyi$close,fy$get,fy$unget ext print,phldc,moveb,isalnum,ccout ext codend cr equ 0dh lf equ 0ah fcb equ 5ch bel equ 7 ctrlz equ 'Z'-'@' call print db 'STEST011 - Testing SYSLIB SFYIO Routines',cr,lf,0 ld a,(fcb+1) ; check for file name cp '/' ; help? jp z,help cp ' ' ; help if space jp nz,start ; ; Help message ; help: call print db 'Syntax: STEST011 filename.typ',cr,lf db ' STEST011 counts the number of words, lines, and',cr,lf db 'various punctuation characters in the file.',cr,lf db ' File must be in current directory.',cr,lf db ' The file STEST011.DAT is a convenient test file.' db 0 ret ; ; Start routine ; start: ld hl,0 ; HL = 0 ld (nlcount),hl ; set new line count ld (wcount),hl ; set word count ld (ccount),hl ; set comment count (;) ld (tcount),hl ; set tab count ld (pcount),hl ; set period count (.) ld hl,fcb+1 ; set fcb ld de,tfcb+1 ld b,11 call moveb call codend ; scratch area ld (wbadr),hl ; set address of working buffer ld a,16 ; 16 records ld (wbsize),a ; set size of working buffer ld de,iocb ; pt to I/O Control Block call fyi$open ; open it jp nz,start0 call print db 'File not found',0 ret ; ; Test for UNGET error ; start0: ld a,'A' call fy$unget jp z,ugerr ;should have no error return ld a,'B' call fy$unget jp nz,ugerr ;we expect an error return here call fy$get ;get first char cp 'A' ;should be the A jp z,start1 ugerr: call print db cr,lf,'UNGET Error',bel,cr,lf,0 ; ; Process file ; DE = IOCB ; start1: call get ; get next char jp z,done and 7fh ; mask out msb cp lf ; new line? jp z,nlc ; increment new line count cp ';' ; comment? jp z,cc ; increment comment count cp 9 ; tab? jp z,tc ; increment tab count cp ',' ; comma? jp z,pc ; increment period count call isalnum ; alphanumeric? jp z,wc ; increment word count jp start1 ; continue nlc: ld hl,(nlcount) ; increment new line count inc hl ld (nlcount),hl jp start1 cc: ld hl,(ccount) ; increment comment count inc hl ld (ccount),hl jp start1 tc: ld hl,(tcount) ; increment tab count inc hl ld (tcount),hl jp start1 pc: ld hl,(pcount) ; increment period count inc hl ld (pcount),hl jp start1 ; ; Word count routine - this is where the UNGET is used ; for a clean design ; DE = IOCB ; wc: ld hl,(wcount) ; increment word count inc hl ld (wcount),hl wc1: call get ; get chars until word end jp z,done ; EOF? call isalnum ; alphanumeric? jp z,wc1 cp ''' ; single quote? jp z,wc1 call fy$unget ; put last char back jp start1 ; resume ; ; Get next char and send it to the screen ; get: call fy$get ; get char ret z ; EOF - done push af ; save flags and 7fh ; mask MSB cp ctrlz ; don't set ^Z call nz,ccout ; echo char pop af ; get flags ret ; ; Done - close file and print results ; done: call fyi$close ; close file call print db cr,lf,' >>>> Counts <<<<' db cr,lf,' Lines ',0 ld hl,(nlcount) call phldc call print db cr,lf,' Words ',0 ld hl,(wcount) call phldc call print db cr,lf,' Semicolons ',0 ld hl,(ccount) call phldc call print db cr,lf,' Commas ',0 ld hl,(pcount) call phldc call print db cr,lf,' Tabs ',0 ld hl,(tcount) call phldc ret ; ; Data area ; nlcount: ds 2 ; new line count wcount: ds 2 ; word count ccount: ds 2 ; comment count (;) tcount: ds 2 ; tab count pcount: ds 2 ; period count ; IOCB: WBSIZE: DS 1 ; working buffer size DS 7 ; filled in by SFYIO WBADR: DS 2 ; working buffer address TFCB: DB 0 ; current disk DS 35 ; space for FCB end ; ; PROGRAM: STEST003 ; AUTHOR: Richard Conn ; PURPOSE: This program demonstrates the EVAL routines and the Math ; routines within SYSLIB ; ; ; Externals ; EXT ADDHD ; HL = HL + DE EXT SUBHD ; HL = HL - DE EXT NEGH ; HL = NEGATE OF HL EXT MULHD ; HL = HL * DE EXT DIVHD ; HL = HL / DE EXT ANDHD ; HL = HL AND DE EXT ORHD ; HL = HL OR DE EXT XORHD ; HL = HL XOR DE EXT SHFTRH ; HL = HL shifted right one bit position EXT SHFTLH ; HL = HL shifted left one bit position EXT ROTRH ; HL = HL rotated right one bit position EXT ROTLH ; HL = HL rotated left one bit position EXT PRINT ; Print String EXT BBLINE ; Input Line Editor EXT EVAL ; Number Evaluator EXT PHLDC ; Print HL as up to 5 decimal chars EXT PHL4HC ; Print HL as 4 Hex chars ; ; ASCII Char defns ; cr equ 0dh lf equ 0ah ; ; Print Banner ; call print db 'STEST003 -- Math Routines and Evaluation Demo',0 ; ; This is the main loop and a prompt to the user. ; loop: call print db cr,lf,'Input Two Numbers, Separated by a Comma ( to Stop)' db ' -- ',0 call bbline ; get user input or a ; no input if A=0 ret z ; return to Operating System call eval ; evaluate the first number (pted to by HL) ex de,hl ; place number in HL ld (num1),hl ; save it away as 1st number ex de,hl ; restore pointer to comma after number in HL inc hl ; skip comma call eval ; evaluate the 2nd number (returned in DE) ; ; Through the rest of this loop, DE contains the 2nd number. Note that none ; of the routines affect it. ; call print db cr,lf,'First Number is ',0 ld hl,(num1) ; get and print first number call phldc ; print in decimal call print db ' in Decimal or ',0 call phl4hc ; print in hex call print db ' in Hex',cr,lf,0 call print db 'The Second Number is ',0 ex de,hl ; get 2nd number into HL call phldc ; print in decimal call print db ' in Decimal or ',0 call phl4hc ; print in hex call print db ' in Hex',cr,lf,0 ex de,hl ; save 2nd number in DE for rest of loop call print db cr,lf,'Sum = ',0 ld hl,(num1) ; get first number again call addhd ; HL = HL + DE call phldc ; print sum call print db ' Difference = ',0 ld hl,(num1) ; get first number (since destroyed by ADDHD) call subhd call phldc ; print difference call print db ' Product = ',0 ld hl,(num1) call mulhd call phldc ; print product call print db ' Quotient = ',0 ld hl,(num1) call divhd call phldc ; print quotient call print db cr,lf,' Negative of First Argument = ',0 ld hl,(num1) call negh call phldc ; print negative call print db cr,lf,'AND = ',0 ld hl,(num1) ; get first number call andhd call phl4hc call print db ' OR = ',0 ld hl,(num1) call orhd call phl4hc call print db ' XOR = ',0 ld hl,(num1) call xorhd call phl4hc call print db cr,lf,'First Argument: SHIFT L = ',0 ld hl,(num1) call shftlh call phl4hc call print db ' SHIFT R = ',0 ld hl,(num1) call shftrh call phl4hc call print db ' ROT L = ',0 ld hl,(num1) call rotlh call phl4hc call print db ' ROT R = ',0 ld hl,(num1) call rotrh call phl4hc jp loop num1: ds 2 ; first number db 0 end ; ; PROGRAM: STEST013 ; AUTHOR: RICHARD CONN ; PURPOSE: TO TEST THE F$APPL FUNCTION OF SYSLIB. STEST012 IS EXECUTED ; WITH COMMANDS LIKE: ; STEST013 FILE ; THE USER WILL BE PROMPTED FOR TEXT TO INPUT, AND THIS TEST WILL BE ; APPENDED AFTER THE LAST PIECE OF TEXT IN THE FILE. ; ; ; Externals ; ext initfcb ext print,bbline ext f$exist,f$make,f$write,f$close,eval10 ext f$appl ; ; Equates ; fcb equ 5ch fcb2 equ 6ch tbuff equ 80h cr equ 0dh lf equ 0ah ctrlz equ 'Z'-'@' ; ; Test program ; call print db 'STEST013 - Text Append file test for SYSLIB',0 ld a,(fcb+1) ; check for help cp '/' jp z,help cp ' ' jp nz,go ; ; Print help message ; help: call print db cr,lf,'Syntax: STEST013 file cn' db cr,lf,' "file" is the name of a file to append to' db cr,lf,' The user is prompted for text to input' db 0 ret ; ; Start ; go: ld de,fcb ; pt to fcb call initfcb ; init for possible MAKE call f$exist ; does file exist? jp nz,start call f$make ; create file if not ld a,ctrlz ; mark file as empty ld (tbuff),a call f$write ; write 1 record call f$close ; close it start: call f$appl ; open file for append on last record jp z,start1 cp 3 ; empty file? jp z,start1 call print db cr,lf,'File Append Error',0 ret start1: ld hl,tbuff ; find continuation point start2: ld a,(hl) ; get char inc hl ; pt to next cp ctrlz ; done? jp nz,start2 dec hl ; pt to ctrlz loop: ld (hl),ctrlz ; store ctrlz as if done push hl ; save ptr call print db cr,lf,'Input Line (CR to End)> ',0 xor a ; no caps call bbline ; get line from user pop de ; ptr to buffer in DE ld a,(hl) ; get first char or a ; none? jp z,done ex de,hl ; HL pts to dest, DE to source loop1: ld a,(de) ; get next char or a ; done? jp z,loop2 call putch ; put char to disk jp loop1 loop2: ld a,cr ; put CRLF call putch ld a,lf call putch jp loop ; ; Put char in A to disk ; putch: ld (hl),a ; store it inc hl ; pt to next inc de ld a,h ; record full? or a ; 0=no ret z push de ; save ptr to source ld de,fcb ; write record call f$write pop de ; get ptr to source ld hl,tbuff ; pt to tbuff as dest ret ; continue ; ; Fill last record with ^Z ; DE pts to next char in record ; done: ld a,ctrlz ; write ^Z ld (de),a inc de ; pt to next ld a,d ; done? or a ; 0=no jp z,done ld de,fcb ; write last record call f$write call f$close ; close file ret end ; ; PROGRAM: STEST004 ; AUTHOR: Richard Conn ; PURPOSE: To allow the user to input a list of text elements and ; then sort that list in alphabetical order ; NOTE: This program demonstrates the use of SYSLIB and its Sort ; ; ; External Routines ; ext ssbinit ; Initialize Sort Specification Block (SSB) ext sort ; SORT Routine ext crlf ; New Line ext cin ; Char In ext caps ; Capitalize char ext print ; Print string ext bbline ; Input Line Editor ext cout ; Print Char ext codend ; End of code/beginning of scratch buffer ; ; Equates ; cr equ 0dh lf equ 0ah ; ; Start of Program ; jp go done: ret ; placed here for testing purposes ; ; First we have to use the routine CODEND to determine where the first ; free byte in the scratch data area which follows the program is. ; go: call print db 'STEST004 -- Sort Demonstration',cr,lf,0 go1: call codend ; get address of end of code ld (start),hl ; save address of first byte of first record ex de,hl ; ... in DE ; ; I will use BC to contain a count of the number of records entered ; and DE to point to the next location in memory to store the next record. ; ld bc,0 ; set record count ; ; Prompt user for input and get a line of text from him. ; loop: call print db cr,lf,'Entry (=Done)? ',0 xor a ; do not capitalize input line call bbline ; get line from user or a ; A=char count=0 if done (just typed) jp z,sort1 ; do sort if done inc bc ; incr record count push bc ; save record count ld b,40 ; copy user input into next rec (pted to by DE) ; ; This loop copies the user's string, which was input by BBLINE and pointed ; to by HL, into the next record position, which is pointed to by DE. ; lp1: ld a,(hl) ; get byte or a ; done if zero jp z,lp2 ld (de),a ; put byte inc hl ; pt to next inc de dec b ; count down jp lp1 ; ; This loop fills the rest of the record with spaces. This is not ; a very good program in the sense that it does not do any error checking ; to see if the user typed more than 40 chars, but it is OK for this demo. ; lp2: ld a,' ' ; store ld (de),a ; put byte inc de ; pt to next dec b ; count down jp nz,lp2 ; ; Now we get our record count back and continue the program. ; pop bc ; get rec count jp loop ; continue until done ; ; The user has typed an empty line, and the number of records is in BC. ; sort1: ; ; Set up record count field of SSB ; ld h,b ; save record count ld l,c ld (recnt),hl ; save record count field of SSB ; ; Test for no records and abort if so ; ld a,h ; any records? or l jp nz,sort2 call print db cr,lf,'No Records -- Aborting Sort',0 ret ; Return to OS ; ; Set up record size field of SSB ; sort2: ld hl,40 ; 40 bytes/record ld (recsiz),hl ; save record size field of SSB ; ; Set up compare routine address field of SSB ; ld hl,comp ; address of compare routine ld (cmpadr),hl ; save compare address in proper field of SSB ; ; I shall now use SSBINIT to set up the ORDER buffer and check to see that ; it does not overflow the TPA. SSBINIT will also set FIRSTP to the byte ; after the order buffer, but I will discard this and reset FIRSTP to point ; to the first byte of my first record. ; ex de,hl ; HL pts to next available entry ld de,ssb ; Pt to SSB call ssbinit ; initialize the SSB FIRSTP and ORDER buffers ld hl,(start) ; set start address field of SSB since ORDER ld (firstp),hl ; buffer is located AFTER the FIRSTP buffer ; ; Set the flag to tell SORT to use pointers to do the sort. ; ld a,0ffh ; non-zero ld (sflag),a ; set flag in SSB ; ; The Sort Specification Block (SSB) is now properly loaded, so let's sort! ; call print db cr,lf,'Starting Sort --',cr,lf,0 ld de,ssb ; pt to ssb call sort ; sort it ; ; Buffer is now sorted -- print out results ; call print db cr,lf,'Buffer After Sort --',cr,lf,0 call prbuf ; ; Prompt the user to continue ; call print db cr,lf,'Do you wish to run this test again (Y/N)? ',0 call cin call caps call cout call crlf ; new line cp 'N' jp nz,go ; rerun if not No jp done ; ; Print the contents of the buffer containing all loaded records ; prbuf: ld hl,(recnt) ; get record count ex de,hl ; ... in DE ld hl,(firstp) ; pt to address of first record prloop: call crlf ; new line ld b,40 ; print 40 chars prl1: ld a,(hl) ; get char inc hl ; pt to next call cout ; print char dec b ; count down chars jp nz,prl1 dec de ; count recs ld a,d or e jp nz,prloop ret ; ; Compare Routine for SORT ; This is a simple byte-for-byte comparison routine, which exists as ; soon as two bytes which are not equal are encountered. ; ; This routine returns with the Zero Flag Set (Z) if the two records ; pointed to by HL and DE are equal (each byte the same). It returns ; with the Carry Flag Set (C) if the record pointed to by DE is less ; than the record pointed to by HL in ASCII sorting sequence. ; comp: push hl ; save regs push de push bc ld b,40 ; 40 bytes max cmpl: ld a,(de) ; get byte cp (hl) ; compare jp z,cmpok ; continue or fall thru with proper flags set cmpd: pop bc ; restore regs -- flag set pop de pop hl ret cmpok: inc hl ; pt to next inc de dec b ; count down jp nz,cmpl ; continue jp cmpd ; done ; ; Buffers ; start: ds 2 ; address of 1st record ssb: ; this is the Sort Specification Block firstp: ds 2 ; Pointer to the first byte of first record recnt: ds 2 ; Number of records recsiz: ds 2 ; Size of record cmpadr: ds 2 ; Address of comparison routine order: ds 2 ; Address of pointer table (if used) sflag: ds 2 ; Flag telling SORT to use pointers (0=no) end ; ; PROGRAM: STEST005 ; AUTHOR: Richard Conn ; PURPOSE: This program obtains a seed value and then generates ; 10 random numbers ; ; ; Externals ; ext cin ; char in ext cout ; char out ext print ; print string ext rndinit ; init random number generator by keypress ext rnd ; return random number ext rndseed ; init random number generator by user seed ext crlf ; new line ext padc ; print A as up to 3 decimal digits ext caps ; capitalize char ext bbline ; get line from user ext eval ; evaulate string ; ; Constants ; cr equ 0dh lf equ 0ah call print db 'STEST005 - Random Number Demo',0 ; ; Start of main loop, which generates 10 random numbers each time it is ; executed. ; start: ; ; Prompt user to see if he wants to select his own seed ; call print db cr,lf,'Do you want to pick your own seed (Y/N)? ',0 call cin ; get single-char response from user call caps call cout cp 'N' jp z,rseed ; ; Input a seed value from the user. ; call print db cr,lf,'What is your seed value? ',0 xor a ; no caps call bbline ; get string call eval ; evaluate string and return value in A call rndseed ; set seed from 8-bit value in A call print ; print seed stored db cr,lf,'Your seed is: ',0 call padc jp rseed1 ; ; Prompt user and wait for keypress to set seed. ; rseed: call print db cr,lf,'Wait a little and then press a key to set the seed - ',0 call rndinit ; ; Generate 10 random numbers ; rseed1: call print db cr,lf,'10 Random Numbers follow --',cr,lf,0 ld b,10 ; 10 numbers loop: call rnd ; get number call padc ; print it as decimal ld a,' ' ; print call cout dec b ; count down jp nz,loop ; ; Prompt user to continue ; call print db cr,lf,'Do you want to run this test again (Y/N)? ',0 call cin ; get response call caps call cout cp 'N' jp nz,start ret ; return to OS if done end ; ; Program: STEST007 ; Author: Richard Conn ; Date: 16 Jan 84 ; Version: 1.0 ; Previous Versions: None ; ; ; The purpose of STEST007 is to exercise and test the SFXIO routines. ; STEST007 creates a file, allows the user to type lines into it, and ; then closes it. It then reopens it and prints it back to the user. ; ; ; Constants ; cr equ 0dh lf equ 0ah ctrlz equ 'Z'-'@' ; ; Library Routines Used ; ext fx$get,fx$put,fxi$close,fxi$open,fxo$close,fxo$open ext fname,bbline ext version ext pafdc ; print A as floating decimal chars ext phlfdc ; print HL as floating decimal chars ext safdc ext shlfdc ext print ext cin,cout,caps,crlf ext csout,sprint,sctlfl,sout ext codend ext fillb ; ; Beginning of Program -- Print banner ; call print db 'STEST007 using SYSLIB Version ',0 call version ld a,h call pafdc ; print major version number ld a,'.' call cout ld a,l call pafdc ; print minor version number call print db cr,lf,' -- Testing SFXIO and SCTLFL Output',cr,lf,0 ; ; Get name of file ; mainloop: call print db 'Name of File (RETURN to Exit)? ',0 ld a,0ffh ; capitalize line call bbline ; get response from user or a ; any chars? ret z call crlf ld de,iocfcb ; pt to fcb of file call fname ; extract file name call codend ; get first byte of free space to use for ex de,hl ; ... buffer in DE ld hl,ioctl ; set user-provided I/O Control Values ld (hl),16 ; 16 128-byte blocks (2K) ld bc,6 ; skip 6 bytes add hl,bc ld (hl),e ; store I/O Buffer address inc hl ld (hl),d ld de,ioctl ; pt to I/O Control Block call fxo$open ; open file for output jp nz,ml0 ; no error call print db 'Error -- Cannot Create File',0 ret ; ; Set for printer and console or just console output ; ml0: ld a,1 ; set just console ld (sctlfl),a ; set SYSLIB flag call print db 'Do you want output to go to the printer as well (Y/N)? ',0 call cin ; get response call caps ; capitalize call cout ; echo call crlf ; new line cp 'Y' ; yes? jp nz,ml1 ld a,81h ; set printer and console ld (sctlfl),a ; ; Prompt for input ; ml1: call print db 'Input Lines (End with just RETURN) --',cr,lf,0 ld hl,0 ; set line counter ld (lcount),hl ; ; Get lines from User ; ml2: ld hl,(lcount) ; increment and print line number inc hl ld (lcount),hl call phlfdc ; print with floating decimal call print db '. ',0 xor a ; no caps call bbline ; get input from user or a ; any input? jp z,ml4 call crlf ; ; Copy Line into Output File ; ld de,ioctl ; DE pts to I/O Control Block ml3: ld a,(hl) ; get byte or a ; done? jp z,ml3a call fx$put ; put byte (I/O Control Block pted to by DE) jp z,werr inc hl ; pt to next jp ml3 ml3a: ld a,cr ; put to file call fx$put jp z,werr ld a,lf call fx$put jp z,werr jp ml2 ; ; Error in writing to file ; werr: call print db cr,lf,'Error -- FX$PUT can''t write to file',0 ret ; ; Close Output File ; ml4: ld de,ioctl ; pt to I/O Control Block call fxo$close ; close file jp nz,ml4a call print db cr,lf,'Error -- FXO$CLOSE can''t close output file',0 ret ; ; Open file and print to user ; ml4a: ld hl,0 ld (lcount),hl ; set line count call sprint ; print to console and/or printer db cr,lf,'---------------------',cr,lf,0 call sprint db 'STEST007 using SYSLIB ',0 call version ld a,h call safdc ld a,'.' call sout ld a,l call safdc call sprint db cr,lf,0 ld de,ioctl ; open file call fxi$open jp nz,ml5 call print db cr,lf,'Error -- FXI$OPEN can''t open input file',0 ret ; ; Read from file until end ; ml5: call sprint db 'File output --',cr,lf,0 ml5a: ld hl,(lcount) ; increment and print line count inc hl ld (lcount),hl call shlfdc ; print as floating call sprint db '. ',0 ml5b: call fx$get ; get next byte jp z,ml6 ; past EOF? cp ctrlz ; check for CTRLZ also jp z,ml6 ; at EOF call csout ; send char to console/printer with tab exp cp lf ; new line? jp z,ml5a jp ml5b ; ; Done with read ; ml6: call fxi$close ; close file jp nz,ml7 call print db cr,lf,'Error -- FXI$CLOSE can''t close input file',0 ret ml7: call sprint db cr,lf,cr,lf,'--> End of Output <--',cr,lf,cr,lf,0 jp mainloop ; ; Buffers ; lcount: ds 2 ; line count ; ; I/O Control Block ; ioctl: ds 8 ; 8 bytes for basic overhead iocfcb: ds 36 ; 36 bytes for FCB end ; ; PROGRAM: STEST010 ; AUTHOR: RICHARD CONN ; PURPOSE: This program tests the FSIZE routine. It creates a directory ; display (using DIRFS) and displays the name of each file with its size ; via the FSIZE routine. ; ext dirfs,fsize ext codend,retud ext print,phldc ext pfn1,crlf ; ; Begin ; call print db 'STEST010 - Testing FSIZE',0dh,0ah,0 call retud ; get disk/user in BC call codend ; determine end of code and pt to fcb ld de,fcb1 ld a,c ; get user in A or 80h ; set non-sys in current user call dirfs ; get files loop: push hl ex de,hl inc de call pfn1 pop hl call print db ' - ',0 push hl call fsize ex de,hl call phldc pop hl ld de,16 add hl,de call crlf dec bc ld a,b or c jp nz,loop ret fcb1: db 0 db '???????????' end ; ; PROGRAM: STEST012 ; AUTHOR: RICHARD CONN ; PURPOSE: TO TEST THE F$APPEND FUNCTION OF SYSLIB. STEST012 IS EXECUTED ; WITH COMMANDS LIKE: ; STEST012 FILE CN ; WHERE N RECORDS CONTAINING THE CHARACTER C WILL BE APPENDED TO THE ; INDICATED FILE OR THE INDICATED FILE WILL BE CREATED WITH N RECORDS ; CONTAINING THE CHARACTER C. EXAMPLE: ; STEST012 T.TXT A4 -- CREATES/APPENDS T.TXT WITH 4 RECORDS OF 'A' ; STEST012 T.TXT -- IF NO T.TXT, EMPTY T.TXT CREATED ; ; ; Externals ; ext initfcb ext print ext f$exist,f$make,f$write,f$close,eval10 ext f$append ; ; Equates ; fcb equ 5ch fcb2 equ 6ch tbuff equ 80h cr equ 0dh lf equ 0ah ; ; Test program ; call print db 'STEST012 - Append file test for SYSLIB',0 ld a,(fcb+1) ; check for help cp '/' jp z,help cp ' ' jp nz,go ; ; Print help message ; help: call print db cr,lf,'Syntax: STEST012 file cn' db cr,lf,' "file" is the name of a file to append to' db cr,lf,' "n" records containing the char "c" are appended' db cr,lf,'to the file, and the file is created if it does not' db cr,lf,'exist' db cr,lf db cr,lf,'Example:' db cr,lf,' STEST012 T.TXT A4 -- puts 4 records of "A" to T.TXT' db 0 ret ; ; Start ; go: push de ld hl,fcb2+1 ; pt to char to write ld a,(hl) ld (char),a ; set char inc hl ; pt to number call eval10 ; get number in DE ld (loopcnt),a ; number of times to loop pop de ld de,fcb ; pt to fcb call initfcb ; init for possible MAKE call f$exist ; does file exist? jp nz,start call f$make ; create file if not start: call f$append ; open file for append after last record jp z,start1 cp 3 ; empty file? jp z,start1 call print db cr,lf,'File Append Error',0 ret start1: ld a,(loopcnt) ; number of records to write or a ; no records? jp z,loop2 ld b,a ; ... in B loop: ld hl,tbuff ; fill TBUFF ld c,128 loop1: ld a,(char) ; get char ld (hl),a inc hl dec c ; fill TBUFF with count jp nz,loop1 call f$write ; write to file dec b ; count down jp nz,loop loop2: call f$close ; close file ret ; ; Data ; char: ds 1 ; char to write loopcnt: ds 1 ; number of records to write end ; ; PROGRAM: STEST014 ; AUTHOR: RICHARD CONN ; PURPOSE: Test the conditional branching routines in SYSLIB. These ; routines are the Case statement processors, the Computed goto routines, ; and the Arithmetic IF routines ; cr equ 0dh lf equ 0ah ext print,bbline,eval,capine,crlf,phldc,cout,padc ext acase1,acase2,acase3,agoto1,agoto2,aif1,aif2,bgoto1,bgoto2 ext hcase1,hcase2,hcase3,hgoto1,hgoto2,hif1,hif2,dgoto1,dgoto2 jp test1 ; ; Get value in HL ; Return with A=0 if no input ; getval: ld a,0ffh ; capitalize call bbline ; get line call crlf ; new line ld a,(hl) ; any input? or a ret z push de call eval ; convert to binary ex de,hl ; value in HL pop de or 0ffh ; set NZ ret ; ; Test 1 ; test1: call print db 'Test 1: ACASE1, ACASE2, and ACASE3',0 test1c: call print db cr,lf,' Enter value for case1 (1, 2, A, B, a, b) > ',0 call capine ; letters are capitalized ; call acase1 db 5 ; 5 case1 entries dw error1 ; error routine db cr ; abort dw test2 db '1' ; number 1 dw number1 db '2' ; number 2 dw number1 db 'A' ; letter A or a dw letter1 db 'B' ; letter B or b dw letter1 ; error1: call print db ' <-- Invalid Selection',0 jp test1d number1: call print db ' <-- Number ',0 call cout jp test1d letter1: call print db ' <-- Letter ',0 call cout test1d: ld de,test1tab ; pt to case table call acase2 error2: call print db ' Invld',0 jp test1e number2: call print db ' Num ',0 call cout jp test1e letter2: call print db ' Let ',0 call cout jp test1e test1tab: db 4 ; 4 case2 entries dw error2 ; error routine db '1' ; number 1 dw number2 db '2' ; number 2 dw number2 db 'A' ; letter A or a dw letter2 db 'B' ; letter B or b dw letter2 test1e: ld de,test11tab ; pt to case table call acase3 jp test1c ; resume flow error3: call print db ' Invld',0 ret number3: call print db ' Num ',0 call cout ret letter3: call print db ' Let ',0 call cout ret test11tab: db 4 ; 4 case2 entries dw error3 ; error routine db '1' ; number 1 dw number3 db '2' ; number 2 dw number3 db 'A' ; letter A or a dw letter3 db 'B' ; letter B or b dw letter3 ; ; Test 2 ; test2: call crlf call print db 'Test 2: HCASE1, HCASE2, and HCASE3',0 test2c: call print db cr,lf,' Enter value for case1 (25, 35, 1001, 9000) > ',0 call getval jp z,test3 ; no input ; call hcase1 dw 4 ; 4 entries dw t2err1 ; goto T2ERR if no match dw 25 dw t2print1 dw 35 dw t2print1 dw 1001 dw t2print1 dw 9000 dw t2print1 ; t2print1: call print db ' <-- Value = ',0 call phldc jp test2d t2err1: call print db ' <-- Error Value',0 test2d: ld de,test2tab ; case table call hcase2 t2print2: call print db ' Val=',0 call phldc jp test2e t2err2: call print db ' Error',0 jp test2e test2tab: dw 4 ; 4 entries dw t2err2 ; goto T2ERR if no match dw 25 dw t2print2 dw 35 dw t2print2 dw 1001 dw t2print2 dw 9000 dw t2print2 test2e: ld de,test21tab ; case table call hcase3 jp test2c ; resume flow t2print3: call print db ' Val=',0 call phldc ret t2err3: call print db ' Error',0 ret test21tab: dw 4 ; 4 entries dw t2err3 ; goto T2ERR if no match dw 25 dw t2print3 dw 35 dw t2print3 dw 1001 dw t2print3 dw 9000 dw t2print3 ; ; Test 3 ; test3: call print db 'Test 3: AGOTO1 and AGOTO2',0 test3c: call print db cr,lf,' Enter Value (Max = 2) > ',0 call capine cp cr jp z,test4 sub '0' ; convert to binary cp 3 jp nc,test3err ; range error routine call agoto1 dw val310 dw val311 dw val312 val310: call print db ' Value is 0',0 jp test3d val311: call print db ' Value is 1',0 jp test3d val312: call print db ' Value is 2',0 test3d: call agoto2 jp val320 jp val321 call print db ' 2',0 jp test3c val320: call print db ' 0',0 jp test3c val321: call print db ' 1',0 jp test3c test3err: call print db ' Range Error',0 jp test3c ; ; Test 4 ; test4: call crlf call print db 'Test 4: BGOTO1 and BGOTO2',0 test4c: call print db cr,lf,' Enter Value (Max = 2) > ',0 call capine cp cr jp z,test5 sub '0' ; convert to binary ld b,2 ; max value call bgoto1 dw val410 dw val411 dw val412 dw val413 ; this will be executed if range error val410: call print db ' Value is 0',0 jp test4d val411: call print db ' Value is 1',0 jp test4d val412: call print db ' Value is 2',0 jp test4d val413: call print db ' Range Error',0 test4d: call bgoto2 jp val420 jp val421 jp val422 test4err: call print db ' Range Error',0 jp test4c val422: call print db ' 2',0 jp test4c val420: call print db ' 0',0 jp test4c val421: call print db ' 1',0 jp test4c ; ; Test 5 ; test5: call crlf call print db 'Test 5: HGOTO1 and HGOTO2',0 test5c: call print db cr,lf,' Enter Value (Max = 2) > ',0 call getval jp z,test6 ld a,h ; range? or a jp nz,test5err ld a,l ; range? cp 3 jp nc,test5err call hgoto1 dw val510 dw val511 dw val512 val510: call print db ' Value is 0',0 jp test5d val511: call print db ' Value is 1',0 jp test5d val512: call print db ' Value is 2',0 test5d: call hgoto2 jp val520 jp val521 call print db ' 2',0 jp test5c val520: call print db ' 0',0 jp test5c val521: call print db ' 1',0 jp test5c test5err: call print db ' Range Error',0 jp test5c ; ; Test 6 ; test6: call print db 'Test 6: DGOTO1 and DGOTO2',0 test6c: call print db cr,lf,' Enter Value (Max = 2) > ',0 call getval jp z,test7 ld de,2 ; max value call dgoto1 dw val610 dw val611 dw val612 dw val613 ; error address val610: call print db ' Value is 0',0 jp test6d val611: call print db ' Value is 1',0 jp test6d val612: call print db ' Value is 2',0 jp test6d val613: call print db ' Range Error',0 test6d: call dgoto2 jp val620 jp val621 jp val622 test6err: call print db ' Range Error',0 jp test6c val622: call print db ' 2',0 jp test6c val620: call print db ' 0',0 jp test6c val621: call print db ' 1',0 jp test6c ; ; Test 7 ; test7: call print db 'Test 7: AIF1 and AIF2' db cr,lf,' Enter KEY value (base to test against) > ',0 call getval jp z,test8 ld b,l ; value in B jp test7c1 test7c: call crlf test7c1: call print db ' Enter value to test > ',0 call getval jp z,test7 ld a,l ; value in A push af ; save value call padc ; print value call aif1 ; do IF dw less7 dw eq7 dw more7 less7: call print db ' is less than ',0 ld a,b call padc jp test7d eq7: call print db ' is equal to ',0 ld a,b call padc jp test7d more7: call print db ' is greater than ',0 ld a,b call padc test7d: pop af ; get value in A call aif2 ; do IF jp less7a jp eq7a call print db ' > ',0 ld a,b call padc jp test7c less7a: call print db ' < ',0 ld a,b call padc jp test7c eq7a: call print db ' = ',0 ld a,b call padc jp test7c ; ; Test 8 ; test8: call print db 'Test 8: HIF1 and HIF2' db cr,lf,' Enter KEY value (base to test against) > ',0 call getval jp z,test9 ex de,hl ; value in DE jp test8c1 test8c: call crlf test8c1: call print db ' Enter value to test > ',0 call getval jp z,test8 push hl ; save value call phldc ; print value call hif1 ; do IF dw less8 dw eq8 dw more8 less8: call print db ' is less than ',0 ex de,hl call phldc jp test8d eq8: call print db ' is equal to ',0 ex de,hl call phldc jp test8d more8: call print db ' is greater than ',0 ex de,hl call phldc test8d: ex de,hl ; key in DE pop hl ; get value in HL call hif2 ; do IF jp less8a jp eq8a call print db ' > ',0 ex de,hl call phldc ex de,hl jp test8c less8a: call print db ' < ',0 ex de,hl call phldc ex de,hl jp test8c eq8a: call print db ' = ',0 ex de,hl call phldc ex de,hl jp test8c ; ; Test 9 - Exit ; test9: ret end ; ; PROGRAM: STEST015 ; AUTHOR: RICHARD CONN ; PURPOSE: ; This program illustrates the problem with the SFXIO and SFYIO routines ; in SYSLIB 3.2. It also serves to illustrate that the problem has been ; corrected in SYSLIB 3.3. ; -- Richard Conn ; false equ 0 true equ not false size equ 1024 ; buffer size to test against blksize equ size/128 ; buffer size in blocks sfyio equ false ; TRUE if testing SFYIO, FALSE if SFXIO cr equ 0dh lf equ 0ah ext f$make,f$close,f$write,f$delete,initfcb ; if sfyio ext fyi$open,fyi$close,fy$get else ext fxi$open,fxi$close,fx$get endif ; ext print,capine call print db 'This program creates the file DUMMY.BIN' db cr,lf,'Do you want to continue (Y/N)? ',0 call capine cp 'Y' ret nz call print db cr,lf,'Creating DUMMY.BIN at exactly 1K size',0 ld de,fcb call initfcb ; init FCB, delete file if it exists, call f$delete ; and create new call f$make ld b,blksize ; number of 128-byte blocks loop1: call f$write dec b ; count down jp nz,loop1 call f$close ; close file call print db cr,lf,'DUMMY.BIN created' db cr,lf,'Now reading 1K from DUMMY.BIN via SF' ; if sfyio db 'Y' else db 'X' endif ; db 'IO',0 ld de,iocb ; if sfyio call fyi$open else call fxi$open endif ; ld bc,size ; number of bytes to read loop2: ; if sfyio call fy$get else call fx$get endif ; jp z,premature$eof dec bc ; count down ld a,b or c jp nz,loop2 call print db cr,lf,'1K from DUMMY.BIN read in' db cr,lf,'The next read of a byte SHOULD return with EOF' db cr,lf,' If it does not, the error has been reproduced' db cr,lf,' If it does, the error has been corrected',0 ; if sfyio call fy$get else call fx$get endif ; jp z,no$error call print db cr,lf,'**** EOF NOT RETURNED - Error Exists ****',0 ; if sfyio call fyi$close else call fxi$close endif ; ret no$error: call print db cr,lf,'**** EOF RETURNED - No Error ****',0 ; if sfyio call fyi$close else call fxi$close endif ; ret premature$eof: call print db cr,lf,'Premature EOF - Some other error exists',0 ; if sfyio call fyi$close else call fxi$close endif ; ret ; ; Data buffers ; iocb: db blksize ds 5 ; if sfyio ds 2 ; 2 extra bytes endif ; dw 4000h ; safe area - this program can't be 16K in size fcb: db 0 db 'DUMMY ' db 'BIN' ds 24 end ; ; PROGRAM: STEST016 ; AUTHOR: RICHARD CONN ; PURPOSE: To test the ARGV routine in SYSLIB ; limit equ 6 ; max number of tokens to parse for cr equ 0dh lf equ 0ah ext bbline,print,argv,crlf,padc,pstr loop: call print db 'Enter String (RETURN to quit): ',0 ld a,0 ; don't cap call bbline call crlf ld a,(hl) ; any input? or a ret z call print db 'Strings without Markers',cr,lf,0 ld de,argv$table ; pt to table ld a,0 ; no markers push hl ; save string ptr call argv call display ; display tokens pop hl ; get string ptr call print db 'Strings with Markers',cr,lf,0 ld de,argv$table ; pt to table ld a,0ffh ; enable markers call argv call display ; display tokens jp loop ; ; Display tokens after an ARGV call ; display: jp z,loop1 call print db ' Token Overflow',cr,lf,0 loop1: call print db 'Tokens --',cr,lf,0 ld hl,argv$table+1 ; pt to count ld b,(hl) ; in B inc hl ; pt to first string loop2: ld a,b ; test for completion or a jp z,loop3 dec b ; count down call prtoken ; print token and advance ptr jp loop2 loop3: ld a,(token$count) ; get count call padc ; print call print db ' Tokens in String',cr,lf,0 ret prtoken: call print db ' > ',0 ld e,(hl) ; get low address inc hl ld d,(hl) ; get high address inc hl ; pt to next ex de,hl call pstr ; print string call crlf ; new line ex de,hl ; HL pts to next ptr ret ; ; Buffers ; argv$table: db limit ; allow LIMIT tokens token$count: ds 1 ; return count ds 2*limit ; token pointers end