.mcall .MODULE .MODULE MATEST,comment=,release=V09,version=06 ;**************************************************************; ; ; ; Copyright (c) 1989 Bob Schor ; ; Eye and Ear Institute ; ; 203 Lothrop St. ; ; Pittsburgh, PA 15213 ; ; ; ; All rights reserved. May not be copied without this notice. ; ; ; ;**************************************************************; ;Test routine for Matrox QC-640 board, exercising MX: handler ;Code adapted from MATEST.PAS, version 8.5 ;b schor May 29, 1989 ;modifications -- ; may, 1989 Psects $CODE and $DATA added ; jun, 1989 Numerous bug fixes ;define our .psects before calling SUMAC to force ours low .psect $code ro,i,lcl,rel,con .psect $data rw,d,lcl,rel,con .psect mxdata rw,d,lcl,rel,con ;uses SUMAC for structured macro code .library /lib:sumac/ ;use external macro definition file .mcall SUMAC SUMAC ;initialization macro .dsabl gbl ;if undefined symbol, force error HEAD sysmac, .mcall .PRINT ;to announce identification .mcall .EXIT ;return to RT-11 on errors .mcall .ENTER, .WRITW, .CLOSE ;to send to MX: .mcall .LOOKUP, .READW ;to receive from MX: .mcall .GTLIN, .TTYOUT ;to communicate with user .mcall .TWAIT ;to wait for Matrox HEAD ioconst, mxout = 1 ;i/o channel for output mxin = 2 ;i/o channel for input cr = 15 ;carriage return lf = 12 ;line feed space = 40 ;space lefta = '< ;left angle bracket righta = '> ;right angle bracket HEAD mtxconst, width = ^d 640 ;points across height = ^d 480 ;points up and down cellx = ^d640 / ^d16 ;basic cell width, screen width/16 celly = ^d480 / ^d16 ;basic cell height, screen height/16 HEAD SENDMX, .macro SENDMX string, return, ?stbgn, ?stend .enabl lsb .save .psect mxdata stbgn: .if nb return .ascii |string| .iff .ascii |string| .endc stend: .restore PUSH r5 ;preserve r5 mov #stbgn, r5 ;get string fwa WHILE r5, lo, #stend ;move entire string movb (r5)+, @mxoptr ;put character in buffer INVOKE bmpmxo ;bump pointer, writing if needed ENDWHILE POP r5 .dsabl lsb .endm SENDMX HEAD NUMMX, .macro NUMMX value, octal PUSH ;save registers PUSH value ;put number on stack .if b octal mov #^d10, radix INVOKE code10 ;encode in decimal .iff mov #10, radix INVOKE encode ;encode in octal .endc POP .endm NUMMX HEAD DELAY, .macro DELAY second, tick PUSH r3 ;save register .if nb second mov #second, r3 ;get seconds of delay mul #^d60, r3 ;convert to ticks, assuming 60 Hz .iff clr r3 .endc .if nb tick add #tick, r3 ;add ticks .endc mov r3, ticks+2 ;save ticks clr ticks PUSH r0 ;save register around emt .TWAIT #emtarg, #ticks POP ;restore registers .endm DELAY .sbttl ------------- .sbttl code area .sbttl ------------- .psect $code LABEL matest, NOTE .PRINT #modnam ;identify module NOTE NOTE NOTE INVOKE initio ;initialize i/o INVOKE resetm ;reset matrox INVOKE shoflg ;show Matrox flags INVOKE slftst ;do self-test INVOKE hello ;do character test INVOKE imagio ;read back image INVOKE chkbd1 ;first checkerboard test INVOKE chkbd2 ;second checkerboard test INVOKE chkbd3 ;third checkerboard test INVOKE echot ;respond to terminal INVOKE close ;close i/o channels .EXIT ;and exit PROCED initio, .ENTER #emtarg, #mxout, #outdb, #0 ;open channel to send to MX IF cs NOTE .EXIT ENDIF .LOOKUP #emtarg, #mxin, #indb IF cs NOTE .EXIT ENDIF clr mxblk ;start from block 0 mov #mxobuf, mxoptr ;initialize output pointer ENDPROC PROCED resetm, NOTE NOTE NOTE SENDMX , cr ;should return just a space INVOKE flush ;force out to Matrox INVOKE rdinfo ;read any information returned ENDPROC PROCED shoflg, NOTE NOTE NOTE FOR r1, #1, #^d43 ;for each flag, IF r1, ne, #5 ;skip unused or non-working flags AND r1, ne, #^d40 AND r1, ne, #^d43 PNOTE IF r1, le, #^d9 PNOTE < > ENDIF TYP.10 r1 PNOTE < -- > SENDMX NUMMX r1 ;send decimal SENDMX <>, cr ;should return a string INVOKE flush ;force out to Matrox INVOKE readcr ;read any information returned DELAY 0, 30 ;delay 0.5 seconds between flags ENDIF ENDFOR ENDPROC PROCED slftst, NOTE NOTE NOTE SENDMX , cr ;should return a string INVOKE flush ;force out to Matrox INVOKE readcr ;read any information returned DELAY 5 ;wait 5 seconds ENDPROC PROCED hello, NOTE NOTE NOTE SENDMX , cr SENDMX , cr SENDMX , cr SENDMX , cr SENDMX , cr SENDMX , cr FOR r1, #0, #377 SENDMX NUMMX r1 SENDMX <>, cr SENDMX < Text "Hello">, cr SENDMX , cr mov r1, r2 ;see if = 15 mod 16 bic #^c17, r2 ;keep low 4 bits IF r2, eq, #17 SENDMX , cr ENDIF ENDFOR INVOKE flush ;force out to Matrox DELAY 5 ENDPROC PROCED imagio, NOTE NOTE NOTE SENDMX , cr ;should return an image INVOKE readcr ;return the image ENDPROC PROCED chkbd1, NOTE NOTE NOTE SENDMX , cr SENDMX , cr SENDMX , cr SENDMX , cr SENDMX , cr FOR r1, #0, #377 SENDMX NUMMX r1 SENDMX <>, cr SENDMX NUMMX #cellx SENDMX < > NUMMX #celly SENDMX <>, cr SENDMX NUMMX #celly SENDMX <>, cr mov r1, r2 ;see if = 15 mod 16 bic #^c17, r2 ;keep low 4 bits IF r2, eq, #17 SENDMX NUMMX #cellx SENDMX < > NUMMX #-height SENDMX <>, cr ENDIF ENDFOR SENDMX , cr INVOKE flush ;force out to Matrox DELAY 5 ENDPROC PROCED chkbd2, NOTE NOTE NOTE FOR r1, #0, #5 PNOTE TYP.10 r1 NOTE SENDMX NUMMX r1 SENDMX <>, cr INVOKE flush ;force out to Matrox DELAY 5 ENDFOR ENDPROC PROCED chkbd3, ;r2 = redness, r3 = greenness, r4 = blueness NOTE NOTE NOTE clr r2 ;initialize RGB clr r3 clr r4 REPEAT FOR r1, #0, #377 SENDMX NUMMX r1 SENDMX < > NUMMX r2 SENDMX < > NUMMX r3 SENDMX < > NUMMX r4 SENDMX <>, cr add #20, r2 ;bump redness bic #^c377, r2 ;keep single byte IF eq ;when we wrap around, add #20, r3 ;bump greenness bic #^c377, r3 IF eq ;when we wrap around, add #20, r4 ;bump blueness bic #^c377, r4 ENDIF ENDIF ENDFOR UNTIL r2, eq ;loop until all colors cycle AND r3, eq AND r4, eq INVOKE flush ;force out to Matrox ENDPROC PROCED echot, NOTE NOTE NOTE NOTE NOTE NOTE NOTE .GTLIN #comand INVOKE cmdlen ;get command length WHILE (sp), ne ;while non-zero, INVOKE sndcmd ;send command to matrox INVOKE flush ;force out to Matrox INVOKE rdinfo ;echo any returned information .GTLIN #comand ;get next command INVOKE cmdlen ENDWHILE POP ;discard 0 length ENDPROC PROCED close, INVOKE flush ;make sure output finished .CLOSE #mxout .CLOSE #mxin ENDPROC .sbttl -------------------- .sbttl Utility routines .sbttl -------------------- PROCED rdinfo, ;sets "sawcr" if return seen INVOKE flush ;make sure command sent to Matrox DELAY 0, 3 ;wait a few ticks for the Matrox PUSH ;preserve registers clr sawcr ;initialize CR flag to false clr col ;start at column 0 REPEAT clr r1 ;clear character count .READW #emtarg, #mxin, #mxibuf, #ibufsz ;get some data IF cs NOTE ENDIF INVOKE echo ;echo to user, count UNTIL r1, eq ;repeat until no more POP ENDPROC PROCED echo, ;count non-null characters in r1 PUSH ;preserve registers mov #mxibuf, r2 ;point to buffer FOR r3, #1, #2*ibufsz ;for each byte, IFB (r2), ne ;if not null, inc r1 ;count it IFB (r2), eq, #cr ;if we see a CR, inc sawcr ;note it ENDIF IFB (r2), gt, #space ;if printable, .TTYOUT (r2)+ ;output it inc col ;bump column for format ELSE PUSHB (r2)+ ;put it on the stack bic #^c377, (sp) ;make single byte add #3, col ;increment counter IF (sp), ge, #10 ;check for inc col ;double-digits ENDIF .TTYOUT #lefta ;output left angle bracket TYP.8 (sp)+ ;output octal value .TTYOUT #righta ;output right angel bracket ENDIF IF col, ge, #^d72 ;constrain carriage NOTE ;put out cr/lf clr col ;and reset count ENDIF ELSE inc r2 ;merely bump pointer ENDIF ENDFOR POP ;restore registers ENDPROC PROCED readcr, REPEAT INVOKE rdinfo ;read from Matrox UNTIL sawcr, ne ;until we see CR NOTE ;echo cr/lf ENDPROC PROCED cmdlen, ;data returned on stack PUSH (sp) ;move return address PUSH r0 ;save register mov #comand, r0 ;initialize pointer WHILEB (r0), ne ;look for asciz inc r0 ;bump to next ENDWHILE sub #comand, r0 ;r0 now has length of string mov r0, 4(sp) ;return length (stack = r0, pc, value) POP r0 ;restore register ENDPROC PROCED sndcmd, ;length of command, in bytes, on stack PUSH r0 ;save register mov #comand, r0 ;point to command WHILE 4(sp), gt movb (r0)+, @mxoptr ;send out a byte INVOKE bmpmxo ;and bump pointer dec 4(sp) ;count down each byte ENDWHILE SENDMX <>, cr POP r0 ;restore register POP (sp) ;discard argument ENDPROC PROCED encode, ;Enter with value on the stack, radix set. r2 and r3 are free. clr r2 mov 2(sp), r3 ;get value POP (sp) ;clean up stack div radix, r2 ;isolate least-significant digit IF ne ;if more-to-do, PUSH r3 ;save least-significant PUSH r2 ;pass quotient as next argument INVOKE encode ;call recursively POP r3 ;and restore least-significant ENDIF add #'0, r3 ;make numeric movb r3, @mxoptr ;save in output buffer INVOKE bmpmxo ;bump pointer ENDPROC PROCED code10, ;Enter with value on the stack, radix set. r2 and r3 are free. ;Other than taking care of sign bit, simply calls encode. mov 2(sp), r3 ;get value POP (sp) ;discard one argument IF r3, ge ;if argument positive, PUSH r3 ;simply encode INVOKE encode ELSE movb #'-, @mxoptr ;output sign INVOKE bmpmxo neg r3 ;encode absolute value PUSH r3 INVOKE encode ENDIF ENDPROC PROCED bmpmxo, inc mxoptr ;bump pointer IF mxoptr, eq, #> ;buffer full? PUSH r0 ;save register .WRITW #emtarg, #mxout, #mxobuf, #obufsz, mxblk IF cs NOTE ENDIF POP r0 inc mxblk ;increment "block" number mov #mxobuf, mxoptr ;reset output pointer ENDIF ENDPROC PROCED flush, WHILE mxoptr, ne, #mxobuf ;while not at start of buffer, clrb @mxoptr ;clear a byte INVOKE bmpmxo ;and bump pointer ENDWHILE ;will flush buffer ENDPROC .sbttl ------------- .sbttl data area .sbttl ------------- .psect $data radix: .word 10 ; Radix for numerical conversions sawcr: .word 0 ; Flag, if we see CR from Matrox col: .word 0 ; Column, for formatting echo outdb: .rad50 /MX MATESTDAT/ ; File name used to send to MX: indb: .rad50 /MX MATESTTXT/ ; File name used to read from MX: emtarg: .blkw 10. ; Space for EMT arguments ibufsz = 100 ; Size of Matrox input buffer mxibuf: .blkw ibufsz ; Space for getting input from Matrox obufsz = 400 ; Size of Matrox output buffer mxobuf: .blkw obufsz ; Space for sending output to Matrox mxoptr: .word mxobuf ; Output pointer mxblk: .word 0 ; MX output "block" number ticks: .word 0 ; Ticks for delay .word 3 comand: .blkb 81. ; Space for .GTLIN .even LABEL modnam, .NLCSI ;generates .asciz module string .even ENDEND .end matest