home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------
- ; PROGRAM PLOT
- ;-----------------------------------------------------------------------
- ;
- ;THIS PROGRAM READS A SEQUENTIAL PLOT COMMAND FILE, MAKES A MEMORY IMAGE
- ;OF THE PLOT, AND PRINTS THE PLOT ON THE PRINTER
- ;
- ; COPYRIGHT (C) 1984 BY THOMAS E. SPEER. ALL RIGHTS RESERVED
- ; 887 BRIDDLEWOOD LN.
- ; DAYTON, OHIO 45430
- ; THIS PROGRAM IS RELEASED TO THE PUBLIC DOMAIN FOR
- ; NON-COMMERCIAL USE ONLY.
- ;
- ;
- ;REVISION HISTORY
- ;
- ; VERSION 3.3 31 JUL 84 T. SPEER
- ; FIXED BUG IN OKI VERSION OF PRESET ROUTINE. EXTRANEOUS EXIT
- ; GRAPHICS COMMAND WAS BEING SENT.
- ;
- ; VERSION 3.3 7 JUL 84 T. SPEER
- ; ADDED TEXT COMAND. ADDED QUIT TO PROPERLY CLOSE OUTPUT FILE.
- ; MODIFIED GBUFOUT TO SKIP TOTALLY BLANK LINES.
- ;
- ; VERSION 3.2B 27 JUN 84 T. SPEER
- ; CROSS HATCHED COLOR PATTERNS FINE TUNED. ADDED BLINKING
- ; STATUS MESSAGE. SPECIAL PATTERNS CORRECTED. ALL SUBROUTINES
- ; PLACED IN ALPHABETICAL ORDER.
- ;
- ; VERSION 3.2A 18 JUN 84 T. SPEER
- ; COLOR PATTERNS CHANGED. 15 SPECIAL PATTERNS ADDED FROM
- ; 49 TO 63. THESE MAKE IT EASIER TO MATCH PATTERNS FROM
- ; OTHER SYSTEMS. THE DEFAULT PATTERNS SUPPLIED ARE THE SAME
- ; AS USED FOR NMOS AND CMOS VLSI CIF PLOTS.
- ;
- ; VERSION 3.2 28 MAR 84 T. SPEER
- ; CITOH MODIFICATIONS DEBUGGED. IDS MODS REMOVED (SAME AS OKI)
- ; BASE2 MODS REMOVED (UNTESTED- NOT SUITABLE FOR RELEASE)
- ;
- ; VERSION 3.2 3 FEB 84 T. SPEER
- ; THIS VERSION ADDS THE PATTERNED ERASE, THE UPLOAD (COLOR
- ; CODES), AND EXTEND COMMANDS.
- ;
- ; VERSION 3.1 10 DEC 83 T. SPEER
- ; ADDED PATTERN FILLS AND LINES USING A CROSS-HATCHED METHOD AND
- ; AN ORDERED DITHER MATRIX METHOD.
- ;
- ; VERSION 3.0 5 NOV 83 T. SPEER
- ; THIS VERSION READS ALL X AND Y COORDINATES AS
- ; 2 BYTE FIXED POINT NUMBERS (16 BIT SIGNED VALUES BETWEEN 0 AND 1)
- ;
- ; COORDINATES MUST BE BETWEEN 0.0 AND 1.0 TO LIE ON PLOT. THIS
- ; MAKES THE PLOT DEVICE INDEPENDENT. THE FIXED POINT VALUES ARE EASILY
- ; CREATED BY THE HIGH LEVEL PROGRAM BY MULTIPLYING THE COORDINATES BY
- ; 32767 AND TRUNCATING TO AN INTEGER.
- ;
- ; VERSION 2.0 T. SPEER
- ; THIS VERSION USED 32 BIT FLOATING POINT INTEGERS WITH A FORTRAN
- ; ROUTINE PATCHED IN TO DO THE CONVERSION TO INTEGER RASTER COORD.
- ;
- ; VERSION 1.0 T. SPEER
- ; THIS VERSION USED 16 BIT INTEGER COORDINATES THAT WERE TIED TO
- ; THE EPSON MX-80 RESOLUTION. NO CONVERSION WAS REQUIRED.
- ;
- ;-----------------------------------------------------------------------
- ;
- ORG 100H ;BEGINNING OF TPA
- MVI C,09H ;SELECT PRINT FUNCTION
- LXI D,BANNER ;PRINT BANNER MESSAGE
- CALL FDOS
- ;
- JMP ENTRY ;JUMP AROUND VARIABLE STORAGE AREA
- BANNER: DB ' PLOT Version 3.3 31/7/84',0DH,0AH
- DB ' (c) by T. E. Speer',0DH,0AH,0AH,'$'
- DB ' All Rights Reserved',0DH,0AH,0DH,0AH,'$'
- ;
- ;
- ;
- ;========================= PRINTER FLAGS ==================================
- ;SET THE ONE THAT MATCHES YOUR PRINTER TO TRUE, AND SET THE OTHERS TO FALSE.
- ;
- TRUE EQU 0FFFFH
- FALSE EQU NOT TRUE
- EPSON EQU TRUE ;FLAG FOR EPSON MX-80 WITH GRAPHTRAX
- CITOH EQU FALSE ;FLAG FOR CITOH, PROWRITER, ETC
- OKI EQU FALSE ;FLAG FOR OKIDATA
- ;IDS SET OKI FLAG TO TRUE- IDS PRINTERS ACT SAME AS OKI
- ;GEMINI 10 SET EPSON FLAG TO TRUE- GEMINI 10 ACTS SAME AS EPSON
- ;NEC SET CITOH FLAG TO TRUE- NEC ACTS SAME AS CITOH
- ;APPLE DOT MATRIX - ACTS SAME AS CITOH, BUT SOME <ESC> SEQUENCES DIFFER.
- ; SET CITOH FLAG TO TRUE AND CHECK <ESC> SEQUENCES AT ESCK,
- ; AND IN LN772 AND PRESET SUBROUTINES.
- ;
- ;====================== PRINTER PARAMETERS ===============================
- ; THIS SECTION SETS THE SPECIFIC CONSTANTS FOR YOUR PRINTER.
- ;
- ;***** NOTE ***** THE MAXIMUM VALUE FOR MAXX THAT CAN BE USED IS 1530.
- ; THE MAXIMUM VALUE FOR MAXY THAT CAN BE USED IS 1785. THESE LIMITS
- ; ARE REQUIRED TO AVOID ARITHMETIC OVERFLOWS.
- ; THE SIZE OF THE MAP ( (MAXX+1)*(MAXY+1)/7 ) MUST FIT BETWEEN THE END OF
- ; THE PROGRAM AND THE END OF THE TPA.
- ;
- ; PRINTERS SEEM TO HAVE TWO BASIC METHODS OF GOING INTO GRAPHICS
- ; MODE. THE EPSON AND CITOH PRINTERS USE AN <ESC> SEQUENCE
- ; FOLLOWED BY A SPECIFIED NUMBER OF GRAPHICS BYTES. THE OKIDATA AND IDS
- ; PRINTERS USE AN <ETX> TO TOGGLE INTO GRAPHICS MODE, AND THEN REMAIN
- ; IN GRAPHICS UNTIL AN <ETX><SO> IS RECEIVED.
- ; THE BASIC PHILOSOPHY ADOPTED HERE IS TO APPEND THE <ESC>
- ; SEQUENCE AND THE NUMBER OF BYTES (IF REQUIRED) TO THE HEAD OF THE
- ; GRAPHICS OUTPUT BUFFER FOR THOSE PRINTERS IN THE FIRST GROUP. PRINTERS
- ; IN THE SECOND GROUP ARE HANDLED BY PUTTING THE <ETX> COMMANDS IN THE
- ; GBUFOUT ROUTINE. ALL PRINTERS ARE KEPT IN NORMAL TEXT MODE, EXCEPT
- ; WHEN ACTUALLY PRINTING GRAPHICS.
- ;
- IF EPSON
- MAXX EQU 479 ;SET MAXIMUM WIDTH TO EPSON LOW RES MODE
- MAXY EQU 573 ;SET MAXIMUM HEIGHT TO MAKE SQUARE PLOT
- MAPSIZE EQU 39360D ;TOTAL SIZE OF MAP
- CWIDTH EQU 6 ;RASTER WIDTH OF A PRINTED CHARACTER
- NO8BIT EQU FALSE ;SET TO FALSE IF YOUR INTERFACE CAN
- MSBTOP EQU TRUE ;MOST SIG. BIT IS TOP OF STROKE
- ; SET UP GRAPHIC OUTPUT BUFFER AREA
- ESCK DB 1BH,'K' ;DEFINE ESC "K" CHARACTER SEQUENCE
- NGRAPH DW 0000H ;INITIALIZE GRAPHIC COUNTER
- GBUFF DS MAXX+1 ;SET ASIDE AREA FOR GRAPHIC O/P BUFFER
- ENDIF ;(EPSON)
- ;
- IF CITOH
- MAXX EQU 636 ;SET MAXIMUM WIDTH FOR 80 DOTS/INCH MODE
- MAXY EQU 573 ;SET MAXIMUM HEIGHT TO MAKE SQUARE PLOT
- MAPSIZE EQU 52234D ;TOTAL SIZE OF MAP
- CWIDTH EQU 8 ;RASTER WIDTH OF A PRINTED CHARACTER
- NO8BIT EQU FALSE ;SET TO FALSE EVEN IF 7 BIT INTERFACE
- MSBTOP EQU FALSE ;LEAST SIG. BIT IS TOP DOT OF STROKE
- ; SET UP GRAPHIC OUTPUT BUFFER AREA
- ESCK: DB 1BH,'S',0,0,0,0 ;GRAPHIC MODE SELECT CODE
- GBUFF: DS MAXX+1 ;SET ASIDE AREA FOR GRAPHIC O/P BUFFER
- NGRAPH DW 0000H ;INITIALIZE GRAPHIC COUNTER
- ENDIF ;(CITOH)
- ;
- IF OKI
- MAXX EQU 575 ;SET MAXIMUM WIDTH FOR 72 DOTS/INCH
- MAXY EQU 573 ;SET MAXIMUM HEIGHT TO MAKE SQUARE PLOT
- MAPSIZE EQU 47232D ;TOTAL SIZE OF MAP
- CWIDTH EQU 6 ;RASTER WIDTH OF CHARACTER
- NO8BIT EQU FALSE ;SHOULD BE FALSE EVEN IF 7 BIT INTERFACE
- MSBTOP EQU FALSE ;LEAST SIG. BIT IS TOP DOT OF STROKE
- ; SET UP GRAPHIC OUTPUT BUFFER AREA
- GBUFF: DS MAXX+1
- NGRAPH DW 0000H
- ENDIF ;(OKI)
- ;
- ;
- ;========================= DATA STORAGE SECTION ============================
- ;
- COLOR DB 0
- XPOS DW 0
- YPOS DW 0
- X DW 0
- Y DW 0
- YFILL DW 0
- NCHAR DW 0
- ACHAR DB 40H
- POINTER DB 128D ;POINTER IN FILE BUFFER
- POINTR2 DB 00H ;POINTER IN OUTPUT FILE BUFFER
- OLDSTK DW 0000H
- STACK DS 80H ;SET ASIDE 128 LEVEL STACK
- XDOT DW 0000H ;POSITION OF DOT TO BE PLOTTED
- YDOT DW 0000H ;POSITION OF DOT TO BE PLOTTED
- XYADDR DW ORIGIN ;ADDRESS OF X,Y LOCATION
- XYBIT DB 00H ;BIT IN BYTE @ XYADDR FOR X,Y
- DIVDND DW 0000H ;2 BYTE DIVIDEND IN DIVIDE
- DIVSOR DB 00H ;1 BYTE DIVISOR IN DIVIDE
- QOTENT DB 00H ;1 BYTE QUOTIENT FROM DIVIDE
- RMANDR DB 00H ;1 BYTE REMAINDER FROM DIVIDE
- BLANK EQU ' '
- NOSPEC DB 'No File Specified',0DH,0AH,'$' ;ERROR MESSAGES
- NOFILE DB 'File Not Found',0DH,0AH,'$'
- EOFMSG DB 'End of File',0DH,0AH,'$'
- NODIR DB 'No Directory Space Available',0DH,0AH,'$'
- NOROOM DB 'Disk is Full',0DH,0AH,'$'
- UNKNCH DB 'Undefined Command Character Encountered',0DH,0AH,'$'
- STAT1 DB ' Working ... ',0DH,'$'
- STAT2 DB ' ... Working ',0DH,'$'
- STAT3 DB ' Printing Picture ',07H,0DH,'$'
- STATNO DB 00H
- DELTAX DW 0000H ;LOCAL VARIABLES FOR INCPLT
- DELTAY DW 0000H ;LOCAL VARIABLES FOR INCPLT
- EPSLNX DW 0000H ;LOCAL VARIABLES FOR INCPLT
- EPSLNY DW 0000H ;LOCAL VARIABLES FOR INCPLT
- SX DW 0000H ;LOCAL VARIABLES FOR INCPLT
- SY DW 0000H ;LOCAL VARIABLES FOR INCPLT
- DELTA3 DW 0000H ;LOCAL VARIABLES FOR INCPLT
- NI DW 0000H ;LOCAL VARIABLES FOR INCPLT
- ;
- CMASK DB 0FFH ;COLOR MASK
- PATRN DS 8 ;CELL STORAGE FOR CLRMAP (ERASE)
- PLAIDS DB 00H,01H,71H,13H,05H,0FH,35H,11H ; CROSS HATCHED PATTERNS
- ;
- CIFPAT DB 00H, 03H, 48H, 03H, 00H, 30H, 84H, 30H ;ND
- DB 00H,0CCH, 00H,0CCH, 00H, 00H, 00H, 00H ;NI S
- DB 08H, 04H, 02H, 01H, 80H, 40H, 20H, 10H ;NT P
- DB 11H, 30H, 71H, 30H, 11H, 03H, 17H, 03H ;NC E
- DB 22H, 00H, 88H, 00H, 22H, 00H, 88H, 00H ;NM C
- DB 0C0H, 81H, 03H, 06H, 03H, 81H,0C0H, 60H ;NB P I
- DB 1CH, 3EH, 36H, 3EH, 1CH, 00H, 00H, 00H ;NG A A
- DB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 01H ;CW T L
- DB 04H, 11H, 04H, 00H, 40H, 11H, 40H, 00H ;CD T
- DB 02H, 04H, 08H, 10H, 20H, 40H, 80H, 01H ;CP E
- DB 00H, 00H, 10H, 38H, 10H, 00H, 00H, 00H ;CS R
- DB 66H, 99H, 99H, 66H, 66H, 99H, 99H, 66H ;CC N
- DB 00H, 00H, 80H, 10H, 00H, 00H, 10H, 80H ;CM S
- DB 81H,0C3H, 66H, 66H,0C3H, 81H, 00H, 00H ;CG
- DB 0FH, 0EH, 0CH, 08H, 00H, 00H, 00H, 00H ;CE
- ;
- DITHARR DB 63, 95, 71, 103, 65, 97, 73, 105 ; ORDERED
- DB 111, 79, 119, 87, 113, 81, 121, 89 ;
- DB 75, 107, 67, 99, 77, 109, 69, 101 ; DITHER
- DB 123, 91, 115, 83, 125, 93, 117, 85 ;
- DB 66, 98, 74, 106, 64, 96, 72, 104 ; MATRIX
- DB 114, 82, 122, 90, 112, 80, 120, 88 ;
- DB 78, 110, 70, 102, 76, 108, 68, 100 ;
- DB 126, 94, 118, 86, 124, 92, 116, 84 ;
- ;
- ;
- ;
- ;
- BOOT EQU 0000H ;CP/M SYSTEM ENTRY POINT
- FCB EQU BOOT+005CH ;LOCATION OF FILE CONTROL BLOCK
- DMA EQU BOOT+0080H ;FILE BUFFER ADDRESS
- FDOS EQU BOOT+0005H ;ENTRY POINT FOR CPM FUNCTIONS
- FCB2 DS 33D ;OUTPUT FILE CONTROL BLOCK
- DMA2 DS 128D ;OUTPUT FILE BUFFER
- OPDISK DB 00H ;OUTPUT TO DISK FLAG
- ;
- ;-----------------------------------------------------------------------
- ;
- ENTRY LXI SP,STACK+80H ;SET NEW 128 LEVEL STACK
- LDA FCB+9 ;GET FIRST CHARACTER OF FILE TYPE
- CPI BLANK ;IS TYPE BLANK?
- JNZ NAME ;NO- TYPE HAS BEEN SPECIFIED
- MVI A,'V' ;MAKE DEFAULT TYPE "VEC"
- STA FCB+9 ;STORE DEFAULT IN FILE TYPE AREA
- MVI A,'E'
- STA FCB+10 ;STORE DEFAULT IN FILE TYPE AREA
- MVI A,'C'
- STA FCB+11 ;DONE- DEFAULT IS SET
- NAME LDA FCB+1 ;GET FIRST CHAR FROM FCB
- CPI BLANK ;IS NAME BLANK?
- JNZ OPENOP ;JUMP IF A FILE NAME EXISTS
- MVI C,09H ;SELECT PRINT STRING FUNCTION
- LXI D,NOSPEC ;PASS ERROR MESSAGE
- CALL FDOS ;PRINT IT
- JMP BOOT ;RETURN TO CPM SYSTEM LEVEL
- OPENOP LDA FCB+17D ;GET 1ST CHAR OF O/P FILE
- CPI BLANK ;IS NAME BLANK?
- JZ OPENFIL ;BLANK= NORMAL PRINT OUTPUT
- MVI A,01H ;SET O/P FILE FLAG=1 (DISK O/P)
- STA OPDISK ;STORE FLAG
- ;
- ; MOVE O/P FILE NAME TO NEW FCB
- ;
- MVI C,16D ;HALF OF FCB#1 IS O/P INFO
- LXI D,006CH ;START OF O/P FILE NAME
- LXI H,FCB2 ;SET DESTINATION ADDRESS
- MOVFCB LDAX D ;GET NAME CHARACTER
- MOV M,A ;STORE NAME CHARACTER
- INX D ;INCREMENT OLD NAME ADDRESS
- INX H ;INCREMENT NEW NAME ADDRESS
- DCR C ;DECREMENT COUNTER
- JNZ MOVFCB ;LOOP BACK IF NOT DONE
- ;
- MVI A,0 ;CLEAR ACCUMULATOR
- STA FCB2+32D ;ZERO CR FIELD IN O/P FCB
- ;
- LDA FCB2+9 ;GET 1ST CHAR IN O/P FILE TYPE
- CPI BLANK ;IS FILE TYPE BLANK?
- JNZ DELETE ;NOT BLANK- GO TO DELELTE OLD
- MVI A,'P' ;MAKE DEFAULT 'PLT'
- STA FCB2+9 ;STORE DEFAULT 'P'
- MVI A,'L'
- STA FCB2+10 ;STORE DEFAULT 'L'
- MVI A,'T'
- STA FCB2+11 ;STORE DEFAULT 'T'
- ;
- DELETE LXI D,FCB2 ;PASS O/P FILE FCB
- MVI C,19D ;SELECT DELETE FUNCTION
- CALL FDOS ;DELETE OLD FILE
- ;
- ; MAKE NEW O/P FILE
- ;
- MVI C,26D ;SELECT SET DMA FUNCTION
- LXI D,DMA2 ;PASS O/P FILE BUFFER ADDRESS
- CALL FDOS ;SET DMA ADDRESS
- ;
- MVI C,22D ;SELECT MAKE FILE FUNCTION
- LXI D,FCB2 ;PASS FCB FOR O/P
- CALL FDOS ;MAKE NEW FILE
- CPI 0FFH ;IS DIRECTORY FULL?
- JNZ OPENFIL ;NO- GO ON WITH PROGRAM
- ;
- MVI C,09H ;SELECT PRINT FUNCTION
- LXI D,NODIR ;PASS NO DIRECTORY SPACE MSG
- CALL FDOS ;PRINT ERROR MESSAGE
- JMP BOOT ;FATAL ERROR- QUIT
- ;
- ;OPEN DISK FILE OF PLOT COMMANDS
- ;
- OPENFIL MVI C,26D ;SELECT SET DMA FUNCTION
- LXI D,DMA ;PASS I/P BUFFER LOCATION
- CALL FDOS ;SET DMA TO I/P BUFFER
- ;
- MVI C,0FH ;SELECT OPEN FILE FUNCION
- MVI A,00H ;CLEAR ACCUMULATOR
- STA FCB+12 ;CLEAR EXTENT COUNTER
- STA FCB+14 ;CLEAR S2 PARAMETER IN FCB
- LXI D,FCB ;PASS FCB
- CALL FDOS ;OPEN FILE
- CPI 0FFH ;WAS FILE FOUND?
- JNZ REWIND ;IF FILE EXITS, REWIND IT
- MVI C,09H ;SELECT PRINT FUNCTION
- LXI D,NOFILE ;PASS MESSAGE
- CALL FDOS ;PRINT IT
- JMP BOOT ;RETURN TO CPM COMMAND LEVEL
- ;
- REWIND MVI A,00H ;CLEAR ACCUMULATOR
- STA FCB+32D ;REWIND BY SETTING RECORD#=0
- ;
- PARSE CALL BYTE ;GET COMMAND CHARACTER
- CPI 60H ;IS IT LOWER CASE?
- JC PARSE0 ;NO, SO SKIP SHIFTING IT
- XRI 00100000B ;SHIFT CHARACTER TO UPPER CASE
- ;
- PARSE0 CPI 'P' ;IS IT A "P"?
- PUSH PSW ;SAVE COMMAND CHARACTER
- CZ POINT ;P COMMANDS PLOT POINT
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CALL STAT ;DISPLAY STATUS MESSAGE
- ;
- ;
- CPI 'C'
- PUSH PSW
- CZ COLOUR ;C COMMANDS SET COLOR
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'D' ;IS IT A "D"?
- PUSH PSW ;SAVE COMMAND CHARACTER
- CZ PLOTSEG ;D COMMANDS PLOT SEGMENT
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'E'
- PUSH PSW
- CZ CLRMAP ;E COMMANDS CLEAR MEMORY MAP TO COLOR
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'F'
- PUSH PSW
- CZ FILL ;F COMMANDS FILL AREA TO COLOR
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHARACTER
- ;
- CPI 'I'
- PUSH PSW
- CZ INCPLT ;I COMMANDS PLOT INCREMENTAL SEGMENT
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'M' ;M COMMANDS MOVE TO COORD W/O PLOTTING
- PUSH PSW
- CZ MOVE
- POP PSW
- JZ PARSE
- ;
- CPI 'N'
- JZ PARSE ;N COMMANDS A NO OPERATION LOOP
- ;
- CPI 'O'
- PUSH PSW
- CZ MAPOUT ;O COMMANDS PRINTING OF PLOT
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'Q'
- PUSH PSW
- CZ QUIT ;Q COMMANDS TERMINATION OF PROGRAM
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'S'
- PUSH PSW
- CZ STRING ;S COMMANDS CHARACTER STRING PLOTTING
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'T'
- PUSH PSW
- CZ TEXT ;T COMMANDS RAW TEXT OUTPUT
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'U'
- PUSH PSW
- CZ UPLOAD ;U COMMANDS UPLOAD OF COLOR PATERNS
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 'X'
- PUSH PSW
- CZ XTEND ;PROVISION FOR NON-STANDARD COMMANDS
- POP PSW
- JZ PARSE ;LOOP BACK FOR NEW CHAR
- ;
- CPI 0DH ;IGNORE CARRIAGE RETURNS
- JZ PARSE
- ;
- CPI 0AH
- JZ PARSE ;IGNORE LINE FEEDS
- ;
- ; COMMAND CHARACTER DOES NOT MATCH ANY DEFINED COMMAND
- ;
- MVI C,09H ;SELECT PRINT STRING FUNCTION
- LXI D,UNKNCH ;PASS UNDEFINED CHARACTER MESSAGE
- CALL FDOS ;PRINT IT
- JMP PARSE ;LOOP UP TO TOP TO GET NEW CHARACTER
- ;
- ;-----------------------------------------------------------------------
- ; DEFINE SUBROUTINES
- ;-----------------------------------------------------------------------
- ;
- ; CONVERT BINARY INTEGER TO DECIMAL ASCII NUMBER
- ;
- ; INPUTS:
- ; N (BINARY NUMBER) IN [DE]
- ; ADDRESS TO STORE LOW DIGIT IN [HL]
- ; OUTPUTS:
- ; ASCII NUMBER STORED IN MEMORY, HIGH BYTE FIRST.
- ; NOTE: THE ADDRESS IS DECREMENTED FOR EACH CHAR.
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES PRESERVED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- IF CITOH
- BINDEC: PUSH H ;SAVE REGISTERS
- PUSH D
- PUSH B
- PUSH PSW
- ;
- MVI A,10D ;GET A TEN
- STA DIVSOR ;DIVISIONS WILL BE BY BASE 10
- ;
- BDECLP: PUSH H ;SAVE ADDRESS FOR FUTURE USE
- MOV A,D
- STA DIVDND ;FIRST DIVIDE HIGH BYTE
- MVI A,00H
- STA DIVDND+1 ;16 BIT DIVIDEND NOW = 8 BIT N HIGH BYTE
- CALL DIVIDE ;DIVIDE BY 10
- LDA QOTENT
- MOV D,A ;RESULT IS HIGH BYTE OF NEW N
- LXI H,RMANDR
- MOV H,M ;DIVIDE REMAINDER WITH LOW BYTE OF N
- MOV L,E ;ADD LOW BYTE OF N TO REMAINDER
- SHLD DIVDND
- CALL DIVIDE ;DIVIDE LOW BYTES BY 10
- POP H ;RETRIEVE ADDRESS TO RECEIVE CHARACTER
- LDA RMANDR ;REMAINDER IS DIGIT
- ADI 30H ;CONVERT DIGIT TO ASCII
- MOV M,A ;STORE CHARACTER
- DCX H ;MOVE POINTER LEFT
- LDA QOTENT ;GET RESULT OF DIVISION
- MOV E,A ;RESULT IS LOW BYTE OF NEW N
- ORA D ;IS NEW END = 0?
- JNZ BDECLP ;LOOP BACK UP IF > 0
- ;
- POP PSW
- POP B
- POP D
- POP H ;REGISTERS RESTORED
- RET
- ENDIF ;(CITOH)
- ;----------------------------------------------------------------------
- ;
- ; BMULT PERFORMS A 1-BYTE BY 2-BYTE MULTIPLY
- ;
- ; THIS ROUTINE IS FROM ELECTRONICS MAGAZINE, FEB 24, 1982.
- ; BY JERRY L. GOODRICH, PENN. STATE U.
- ;
- ; INPUTS:
- ; 8-BIT NUMBER IN [A]
- ; 16-BIT NUMBER IN [BC]
- ; OUTPUTS:
- ; PRODUCT IN [A],[HL] (HIGH BYTE IN [A])
- ; REGISTER STATUS:
- ; SEE INPUTS AND OUTPUTS
- ; ERROR CONDITIONS:
- ; NONE
- ;
- BMULT LXI H,0 ;ZERO PARTIAL PRODUCT
- LXI D,7 ;D=0,E=BIT COUNTER
- ADD A ;GET FIRST MULTIPLIER BIT
- LOOP1: JNC ZERO ;ZERO SKIP
- DAD B ;ONE-ADD MULTIPLICAND
- ADC D ;ADD CARRY TO THIRD BYTE OF PRODUCT
- ZERO: DAD H ;SHIFT PRODUCT LEFT
- ADC A
- DCR E ;DECREMENT BIT COUNTER
- JNZ LOOP1 ;LOOP UNTIL DONE
- RNC ;DONE IF NO CARRY
- DAD B ;OTHERWISE DO LAST ADD
- ADC D
- RET ;AND RETURN
- ;-----------------------------------------------------------------------
- ; BYTE GETS NEXT BYTE IN BUFFER
- ; NEXT RECORD IS READ IF NEED BE
- ; INPUTS:
- ; 128 CHARACTER BUFFER @ DMA
- ; CHARACTER POINTER @ POINTER WHICH IS SET @ LAST POSITION
- ; OUTPUTS:
- ; NEW BYTE IN ACCUMULATOR
- ; REGISTER STATUS:
- ; [BC],[DE],[HL] REGISTERS PRESERVED
- ; ERROR CONDITIONS:
- ; NONE- IF POINTER EXCEEDS 128, NEW RECORD IS READ
- ;
- BYTE PUSH B ;SAVE REGISTERS
- PUSH D
- PUSH H
- ;
- LDA POINTER ;GET POINTER VALUE
- CPI 128D ;IS POINTER=128?
- CZ READ ;GET RECORD IF LAST ONE WAS #128
- LDA POINTER ;GET NEW POINTER VALUE
- INR A ;INCREMENT POINTER VALUE
- STA POINTER ;STORE NEW POINTER VALUE
- MOV C,A ;SAVE POINTER VALUE IN C
- MVI B,0 ;MAKE BC=C
- LXI H,DMA-1 ;LOAD HL WITH BYTE BEFORE DMA
- DAD B ;CALCULATE ADDR OF DESIRED BYTE
- MOV A,M ;GET BYTE
- ;
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- RET ;DONE-- BYTE IS IN ACCUM.
- ;-----------------------------------------------------------------------
- ;
- ; PRINTED CHARACTER OUTPUT
- ;
- ; INPUTS:
- ; CHARACTER IN REGISTER [A]
- ;
- ; OUTPUTS:
- ; GRAPHIC BUFFER IS FLUSHED
- ; CHARACTER IS PUT OUT TO PRINTER
- ; ADDRESS IN [HL] IS INCREMENTED BY (CWIDTH - 1)
- ; DOT COUNTER INCREMENTED BY (CWIDTH - 1)
- ; THE ABOVE ARE TO ACCOUNT FOR THE SIZE OF A CHARACTER
- ; AS OPPOSED TO A SINGLE DOT
- ; REGISTER STATUS:
- ; [A,PSW],[BC] PRESERVED
- ; [DE] DECREMENTED BY (CWIDTH -1)
- ; [HL] INCREMENTED BY (CWIDTH -1)
- ; ERROR CONDITIONS:
- ; NONE
- ;
- CHAROUT: PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- XRI 10000000B ;CLEAR HIGH BIT OF CHARACTER
- CALL GBUFOUT ;FLUSH GRAPHIC BUFFER
- MVI C,05H ;SELECT LIST OUTPUT
- MOV E,A ;PASS CHARACTER
- CALL PDOS ;SEND CHARACTER TO PRINTER
- ;
- POP H ;RECALL REGISTERS
- POP D
- MVI A,CWIDTH-1
- CHARO1: INX H ;INCREMENT ADDRESS
- DCX D ;DECREMENT DOT COUNTER
- SUI 1 ;DECREMENT LOOP COUNTER
- JNZ CHARO1
- ;
- POP B
- POP PSW
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; CLEAR MEMORY SUBROUTINE
- ;
- ; INPUTS:
- ; BITMAP OF SIZE MAPSIZE LOCATED AT ORIGIN
- ; MAP COLOR STORED IN COLOR
- ; (POS = PATTERNED, 0 = WHITE, - = COMPLEMENTARY)
- ; OUTPUTS:
- ; ENTIRE MAP AREA SET TO DESIRED COLOR OR PATTERN
- ; REGISTERS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- CLRMAP: LDA COLOR ;GET COLOR
- ORA A ;SET FLAGE ACCORDING TO COLOR
- JNZ CLRNZ ;IS COLOR NON-WHITE?
- LXI D,MAPSIZE ;PUT MAPSIZE IN [DE] AS COUNTER
- LXI H,ORIGIN ;PUT START OF MAP IN [HL]
- MVI C,00H ;C CONTAINS IMAGE OF WHITE BYTE
- CLRLP1: MOV M,C ;TOP OF LOOP, STORE BYTE
- INX H ;INCREMENT ADDRESS IN MAP
- DCX D ;DECREMENT LOOP COUNTER
- MOV A,D ;MOVE HIGH BYTE OF COUNT. TO [A]
- ORA E ;CHECK FOR 0 COUNTER
- JNZ CLRLP1 ;LOOP UNTIL DONE
- RET ;FINISHED WITH WHITE ERASE
- ;
- CLRNZ: PUSH PSW ;SAVE FLAG VALUES
- ; NOW FORM 8 BYTE COLOR PATTERN
- LXI H,PATRN+7 ;POINT TO LAST IN PATTERN SEQUENCE
- MVI C,07H ;INITIALIZE X COUNTER
- CLRLP2: MVI D,80H ;SET UP Y BIT SELECT
- MVI E,07H ;INITIALIZE Y COUNTER
- MVI B,00H ;INITIALIZE PATTERN
- CLRLP3: CALL CLRMSK ;FORM COLOR MASK BASED ON X,Y
- LDA CMASK ;GET MASK
- ANA D ;SELECT ONE BIT
- ORA B ;ADD BIT TO PATTERN
- MOV B,A ;SAVE NEW PATTERN
- MOV A,D ;MODIFY BIT SELECT MASK
- RRC ;MOVE SELECT BIT DOWN ONE NOTCH
- MOV D,A ;SAVE NEW BIT SELECT
- DCR E ;DECREMENT Y COUNTER
- JP CLRLP3 ;JUMP BACK IF NOT NEGATIVE (NEED 0 PASS)
- POP PSW ;RETRIEVE COLOR CODE FLAG SETTINGS
- PUSH PSW ;RE-SAVE FLAGS SETTINGS
- JP CLRL31 ;POSITIVE FLAG MEANS PATTERN IS OK
- MOV A,B ;GET PATTERN
- CMA ;COMPLEMENT PATTERN FOR NEGATIVE COLORS
- MOV B,A ;STORE PATTERN BYTE
- CLRL31: MOV M,B ;SAVE PATTERN FOR THIS X LOCATION
- DCX H ;MOVE MEMORY POINTER OVER
- DCR C ;DECREMENT X COORDINATE/COUNTER
- JP CLRLP2 ;ONLY DONE WHEN NEGATIVE (NEED 0 PASS)
- ;
- ; SET UP FOR CLEARING MEMORY
- ; ROTATE ARRAY OF PATTENRX DOWN TO MATCH
- ;
- LXI B,(MAXY+1) MOD 8+1;COUNTER FOR ROTATIONS DUE TO MISMATCH
- CLRLP4: CALL ROTPAT ;ROTATE PATTERN ARRAY 1 POSITION
- DCR C ;DECREMENT COUNTER
- JNZ CLRLP4 ;LOOP BACK IF NOT DONE
- ;
- LXI H,ORIGIN ;SET MAP POINTER TO START OF MAP
- LXI B,(MAXY+1)/7 ;INITIALIZE LINE COUNTER
- CLRLP5: LXI D,(MAXX+1)/8 ;INITALIZE DOT COUNTER
- CLRL51: LDA PATRN ;GET FIRST BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+1 ;GET SECOND BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+2
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+3
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+4
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+5
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+6
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- LDA PATRN+7
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT X COUNTER
- MOV A,E
- ORA D ;IS COUNTER ZERO?
- JNZ CLRL51 ;LOOP BACK UNTIL DONE
- ;
- LXI D,(MAXX+1)MOD 8 ;SET COUNTER FOR REST OF LINE
- MOV A,D ;CHECK TO SEE IF LINESIZE ID MULT OF 8
- ORA E ;WAS MOD 8 =0?
- JZ CLRLP6 ;JUMP TO BOTTOM OF LOOP IF FINISHED
- LDA PATRN ;APPLY PATTERN TO REMANING 1-7 BYTES
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+1 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+2 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+3 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+4 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+5 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- DCX D ;DECREMENT LINE LENGTH COUNTER
- MOV A,E
- ORA D ;IS COUNTER = 0?
- JZ CLRLP6 ;IF FINISHED, SKIP TO BOTTOM OF OUTER LP
- LDA PATRN+6 ;CONTINUE WITH NEXT PATTERN BYTE
- ANI 7FH ;CLEAR HI BIT
- MOV M,A ;STORE PATTERN IN MEMORY MAP
- INX H ;MOVE MEMORY POINTER
- ;
- CLRLP6: CALL ROTPAT ;ROTATE PATTERN DOWN TO MATCH CELLS
- DCX B ;BOTTOM OF OUTER LOOP. DEC LINE COUNTER
- MOV A,C
- ORA B ;IS COUNTER = 0?
- JNZ CLRLP5 ;LOOP BACK UP FOR ANOTHER IF REQ'D
- ;
- POP PSW ;CLEAN UP STACK
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; COLOR MASK
- ;
- ; THIS SUBROUTINE FORMS THE COLOR MASK USED IN PLOTTING POINTS
- ;
- ; METHOD:
- ; THE PLOT IS DIVIDED UP INTO 8 X 8 RASTER CELLS.
- ; FOR COLOR VALUES BETWEEN 1 AND 63, THE CELL IS COMPOSED
- ; OF AN X PATTERN AND A Y PATTERN WHICH ARE XOR'ED WITH
- ; EACH OTHER TO FORM A "PLAID" PATTERN
- ; FOR COLOR VALUES 64 AND ABOVE, ORDERED DITHERING IS USED
- ; ORDERED DITHERING IS A TECHNIQUE IN WHICH THE DOTS IN
- ; THE CELL ARE ADDED IN IN A PRE-ARRANGED POSITION BASED
- ; UPON THE "INTENSITIY" OF THE CELL. THE INTERSECTION OF
- ; THE POINT AND THE PATTERN (STORED IN THE ARRAY "DITHARR"
- ; DETERMINES WHETHER OR NOT THE POINT IS PLOTTED
- ;
- ; FOR BOTH METHODS, A COLOR MASK IS CREATED, WHICH IS
- ; ALL 1'S IF THE POINT IN THE PATTERN PLANE IS ON, OR
- ; ALL 0'S IF THE POINT IN THE PATTERN PLANE IS OFF.
- ; INPUTS:
- ; X COORDINATE IN BC
- ; Y COORDINATE IN DE
- ; OUTPUTS:
- ; COLOR MASK STORED IN CMASK
- ; REGISTER STATUS:
- ; ALL REGISTERS PRESERVED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- CLRMSK PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- MOV A,C ;FORM X CELL COORDINATE
- ANI 00000111B
- MOV B,A
- ;
- MOV A,E ;FORM Y CELL COORDINATE
- ANI 00000111B
- MOV C,A
- ;
- LDA COLOR ;GET COLOR CODE
- ORA A ;SET FLAGS BASED ON BASIC CODE
- JZ WHTMSK ;ZERO COLOR => WHITE MASK
- JP POSCLR ;COLOR CODE IS POSITIVE
- CMA ;COMPLEMENT COLOR
- ADI 01H ;COLOR CODE IS NOW POSITIVE
- POSCLR CPI 64D ;IS COLOR CODE < 64
- JNC DITHER ;CODE >=64 --> DITHERED
- CPI 49D ;IS COLOR CODE < 49
- JNC SPECIAL ;CODE FROM 49 TO 63 --> CIFPAT'S ELSE PLAID
- ;
- PUSH PSW ;SAVE COLOR CODE
- ANI 07H ;SELECT LOWER 3 BITS OF COLOR CODE
- LXI H,PLAIDS ;GET BASE ADDRESS OF BASIC PATTERN
- ADD L ;ADD X CODE TO BASE ADDR TO FIND PATTERN
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY TO HIGH BYTE OF ADDRESS
- MOV H,A
- MOV A,M ;GET X PATTERN FOR CELL
- INR B ;INCREMENT X COORDINATE TO BE COUNTER
- XCELLP RAR ;ROTATE PATTERN BIT INTO CARRY
- DCR B ;DECREMENT COUNTER
- JNZ XCELLP ;LOOP BACK IF NOT DONE
- MVI A,0FFH ;CARRY --> PATTERN BIT SAYS PLOT POINT
- JC SAVXMSK
- MVI A,00H
- SAVXMSK MOV B,A ;REPLACE X CELL COORD WITH X COLOR MASK
- ;
- POP PSW ;RETRIEVE COLOR CODE
- ANI 38H ;SELECT 2ND 3 BITS FOR Y CODE
- RRC ;ROTATE BITS TO LOW ORDER POSITION
- RRC
- RRC
- LXI H,PLAIDS ;GET BASE ADDRESS OF BASIC PATTERN
- ADD L ;ADD X CODE TO BASE ADDR TO FIND PATTERN
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY TO HIGH BYTE OF ADDRESS
- MOV H,A
- MOV A,M ;GET Y PATTERN FOR CELL
- INR C ;INCREMENT Y COORDINATE TO BE COUNTER
- YCELLP RAR ;ROTATE PATTERN BIT INTO CARRY
- DCR C ;DECREMENT COUNTER
- JNZ YCELLP ;LOOP BACK IF NOT DONE
- MVI A,0FFH ;DOT WILL BE PLOTTED IF CARRY SET
- JC SAVYMSK
- MVI A,00H
- SAVYMSK XRA B ;FINAL COLOR MASK-- X PATRN XOR Y PATRN
- STA CMASK ;SAVE COLOR MASK
- ;
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET ;FINISHED -END OF PLAID BRANCH
- ;
- DITHER PUSH PSW ;SAVE COLOR CODE FOR FUTURE USE
- MOV A,C ;MULTIPLY Y CELL COORDINATE BY 8
- RLC
- RLC
- RLC
- ADD B ;OFFSET INTO DITHER TABLE = Y*8 + X
- LXI H,DITHARR ;GET BASE ADDRESS OF TABLE
- ADD L ;ADD OFFSET TO BASE ADDRESS
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY TO HIGH BYTE
- MOV H,A
- MOV A,M ;GET DITHER TABLE VALUE
- POP D ;RETRIEVE COLOR CODE (FORMERLY IN [A])
- CMP D ;IS DITHER VALUE > COLOR CODE?
- MVI A,0FFH ;CARRY--> PLOT POINT
- JC SAVMSK
- MVI A,00H ;CARRY NOT SET--> DON'T PLOT POINT
- SAVMSK STA CMASK ;STORE MASK FOR FUTURE USE
- ;
- POP H
- POP D
- POP B
- POP PSW ;REGISTERS RESTORED, STACK CLEANED UP
- RET
- ;
- ;
- SPECIAL:SUI 49D ;CODE IS NOW RELATIVE TO 49
- RLC ;CODE * 8
- RLC
- RLC
- ADD B ;ADD X COORD TO FORM OFFSET INTO ARRAY
- LXI H,CIFPAT ;GET FWA OF PATTERN ARRAY
- ADD L ;ADD OFFSET TO FWA
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY TO HI BYTE
- MOV H,A ;ADDITION COMPLETE
- MOV A,M ;GET PATTERN BYTE FOR THIS X COORD.
- INR C ;INCREMENT Y COORD TO FORM COUNTER
- SPCLP: RAR ;ROTATE PATTERN BIT INTO CARRY
- DCR C ;DECREMENT COUNTER
- JNZ SPCLP ;LOOP BACK UNTIL DONE
- MVI A,0FFH ;DOT WILL BE PLOTTED IF CARRY SET
- JC SAVMSK
- MVI A,00H ;CARRY NOT SET- DON'T PLOT POINT
- JMP SAVMSK
- ;
- ;
- WHTMSK MVI A,0FFH ;FOR WHITE, ALWAYS MODIFY DOT
- JMP SAVMSK ;SAVE MASK AND RETURN
- ;
- ;-----------------------------------------------------------------------
- ;
- ; DEFINE COLOR SUBROUTINE
- ;
- ; INPUTS:
- ; BUFFER @ DMA
- ; OUTPUTS:
- ; COLOR VALUE SAVED FOR FUTURE REFERENCE
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDTIONS:
- ; NONE
- ;
- COLOUR: CALL BYTE ;GET COLOR VALUE
- STA COLOR ;SAVE IT
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE COMPUTES THE NEXT POINT IN A LINE SEGMENT
- ; MUST BE USED WITH SEGINIT TO INITIALIZE ALL VARIABLES FIRST.
- ;
- ; INPUTS:
- ; NI COUNTER USED BY CALLING SUB. TO KNOW WHEN DONE.
- ; XPOS,YPOS PRESENT POSITION
- ; DX,DY SIZE OF LINE SEGMENT ALONG X,Y AXIS
- ; EPSLNX,EPSLNY,SX,SY,DELTA3 LOCAL VARIABLES
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED.
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE
- ;
- COMPSEG LHLD NI ;GET COUNTER VALUE
- INX H ;NI<DX- CONTINUE (FIRST INCR. NI)
- SHLD NI ;STORE NEW NI VALUE
- LHLD XPOS ;GET XPOS & PUT IN (BC)
- MOV B,H ;HI BYTE TO (B)
- MOV C,L ;LOW BYTE TO (C)
- LHLD YPOS ;FETCH YPOS
- XCHG ;PUT YPOS IN (DE)
- LHLD EPSLNX ;FETCH EPSILON X
- DAD B ;ADD EPSILON X TO X POSITION
- SHLD XPOS ;STORE NEW VALUE
- LHLD EPSLNY ;FETCH EPSILON Y
- DAD D ;ADD EPSILON Y TO Y POSITION
- SHLD YPOS ;STORE NEW VALUE OF Y POSITION
- LHLD DELTAY ;FETCH DELTA Y
- XCHG ;PUT DELTAY IN (DE)
- LHLD DELTA3 ;FETCH DELTA 3
- DAD D ;ADD DELTA Y TO DELTA 3
- SHLD DELTA3 ;STORE NEW VALUE OF DELTA3
- XCHG ;PUT NEW VALUE OF DELTA 3 IN (DE)
- LHLD DELTAX ;FETCH DELTA X
- MOV A,H ;CONTINUE IF DELTA X < DELTA 3
- CMP D ;OTHERWISE PLOT POINT AND LOOP
- JC CONT2 ;HI BYTES FIRST- DELTA3 DEFINITELY >
- JNZ DOPT ;DX > D3- PLOT POINT
- MOV A,L ;HIGH BYTES =: LOOK @ LOW BYTES
- CMP E ;NOW LOW BYTES
- JNC DOPT ;D3<=DX: PLOT POINT
- CONT2 MOV A,E ;COMPUTE D3=D3-DX
- SUB L ;SUBTRACT LOW BYTE FIRST
- MOV L,A ;PUT LOW BYTE IN POSITION FOR STORE
- MOV A,D ;NOW HIGH BYTE OF D3
- SBB H ;SUBTRACT HIGH BYTE
- MOV H,A ;PUT HI BYTE IN POSITION FOR STORE
- SHLD DELTA3 ;STORE RESULT
- LHLD SX ;COMPUTE XPOS=XPOS+SX
- XCHG ;PUT SX IN (DE)
- LHLD XPOS ;FETCH X POSITION
- DAD D ;ADD SX TO XPOS
- SHLD XPOS ;STORE RESULT
- LHLD SY ;COMPUTE YPOS=YPOS+SY
- XCHG ;PUT SY IN (DE)
- LHLD YPOS ;FETCH Y POSITION
- DAD D ;ADD SY
- SHLD YPOS ;STORE NEW Y POSITION
- DOPT RET ;RETURN SO CALLING SUB CAN USE POSITION.
- ;
- ;-----------------------------------------------------------------------
- ; CARRIAGE RETURN ROUTINE
- ;
- ; INPUTS:
- ; NONE
- ;
- ; OUTPUTS:
- ; PRINTER CARRIAGE IS RETURNED AND PAPER ADVANCED
- ;
- ; REGISTER STATUS:
- ; ALL VALUES PRESERVED
- ;
- ; ERROR CONDITIONS:
- ; NONE
- ;
- CRLF PUSH PSW ;SAVE ALL REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,0DH ;PASS CARRIAGE RETURN CHARACTER
- CALL PDOS
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,0AH ;PASS LINE FEED CHARACTER
- CALL PDOS ;SEND IT OUT
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE FORMS THE MASK FOR THE PLOTTING OF A POINT
- ; DIGIT= YCOORD MOD 7
- ; INPUTS:
- ; XCOORD IN BC
- ; YCOORD IN DE
- ; XYADDR IN HL
- ; OUTPUTS:
- ; CONTENTS OF XYADDR IN B
- ; MASK (1 BIT ON) IN C
- ; YCOORD IN DE
- ; XYADDR IN HL
- ; REGISTER STATUS:
- ; SEE OUTPUTS
- ; ERROR CONDITIONS:
- ; OVERFLOW IN DIVIDE CALLS WOOPS
- ;
- DIGIT PUSH H ;SAVE XYADDRESS
- PUSH D ;SAVE YCOORD
- CALL CLRMSK ;PREPARE COLOR MASK FOR FUTURE USE
- XCHG ;PUT YCOORD IN HL
- SHLD DIVDND ;CALCULATE YCOORD MOD 7
- MVI A,07H
- STA DIVSOR
- CALL DIVIDE ;MOD IS DIVIDE W/O QUOTIENT
- LDA RMANDR ;GET RESULT
- ORA A ;SET FLAGS
- CM WOOPS ;RMANDR= -1 ON OVERFLOW
- MOV B,A ;MOVE # OF DIGIT TO B
- MVI A,00H
- INR B ;INCREMENT B TO INIT FOR 1ST DEC
- IF MSBTOP
- STC ;CLEAR ACCUM, PUT 1 IN CARRY
- ROTMASK RAL ;MOVE MASK BIT 1 LEFT
- ENDIF ;(MSBTOP)
- ;
- IF NOT MSBTOP
- MVI A,10000000B ;SET HIGH BIT AND ROTATE IT RIGHT
- ROTMASK RRC ;MOVE MASK BIT 1 RIGHT
- ENDIF ;(NOT MSBTOP)
- ;
- DCR B ;DECREMENT # OF DIGIT
- JNZ ROTMASK ;LOOP BACK
- MOV C,A ;STORE MASK TEMPORARILY
- LDA CMASK ;GET COLOR MASK
- ANA C ;AND BIT MASK WITH COLOR MASK- BOTH RQD
- MOV C,A ;PUT MASK IN C
- POP D ;BRING BACK YCOORD
- POP H ;BRING BACK (XYADDR)
- MOV B,M ;GET BYTE @ (XYADDR)
- RET
- ;
- ;-----------------------------------------------------------------------
- ; DIVISION SUBROUTINE
- ; INPUTS:
- ; DIVDND TWO BYTE POSITIVE NUMBER
- ; DIVSOR ONE BYTE POSITIVE NUMBER
- ; OUTPUTS:
- ; QOTENT ONE BYTE POSITIVE QUOTIENT
- ; RMANDR ONE BYTE POSITIVE REMAINDER OR FLAG
- ; REGISTER STATUS:
- ; BC,DE,HL,PSW REGISTERS RETURNED TO ORIGINAL VALUES
- ; ERROR CONDITIONS:
- ; RMANDR=-1 IF OVERFLOW OCCURS
- ;
- DIVIDE PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- LHLD DIVDND ;FETCH DIVIDEND
- XCHG ;PUT DIVIDEND INTO THE DE PAIR
- LDA DIVSOR ;FETCH DIVSOR
- MOV C,A ;SAVE IN REGISTER C
- MVI B,8 ;LOOP COUNTER IN REGISTER B
- DIVLOOP MOV A,E ;SHIFT LOW ORDER BYTE TO LEFT
- ANA A ;CLEAR CARRY
- RAL ;SHIFT
- MOV E,A ;REPLACE VALUE
- MOV A,D ;FETCH HIGH ORDER BYTE
- RAL ;ROTATE BRINGING IN HIGH BIT
- SUB C ;SUBTRACT DIVISOR
- JP SETBIT ;IF RESULT WAS POSITIVE, JUMP
- ADD C ;OTHERWISE ADD BACK DIVISOR
- MOV D,A ;REPLACE HIGH ORDER BYTE
- JMP NEXT ;GO TO INCREMENT PHASE
- SETBIT MOV D,A ;REPLACE HIGH ORDER BYTE
- MOV A,E ;FETCH LOW ORDER BYTE
- ORI 1 ;SET LOW ORDER BIT
- MOV E,A ;REPLACE LOW ORDER BYTE
- NEXT DCR B ;DECREMENT LOOP COUNTER
- JNZ DIVLOOP ;REPEAT UNTIL DONE
- MOV A,E ;QUOTIENT
- ANA A ;TEST SIGN OF RESULT
- JP OK ;IF POSITIVE RESULT IS ACCURATE
- MVI A,0FFH ;SET OVERFLOW VALUE
- STA RMANDR
- JMP DONE
- OK STA QOTENT ;SAVE QUOTIENT
- MOV A,D ;REMAINDER
- STA RMANDR ;SAVE REMAINDER
- DONE POP H
- POP D
- POP B
- POP PSW
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE PLOTS THE VERTICAL LINE USED TO FILL IN AREAS
- ;
- ; INPUTS:
- ; XPOS,YPOS CURRENT POSITION ON SEGMENT
- ; YFILL HORIZONTAL LEVEL TO FILL TO
- ; OUTPUTS:
- ; VERTICAL LINE FROM (XPOS,YPOS) TO (XPOS,YFILL)
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE.
- ; NOTE: ALL COORDINATE VALUES ASSUMED TO BE POSITIVE
- ;
- FILINE CALL STAT ;UPDATE STATUS MESSAGE
- LHLD XPOS ;GET STARTING COORDINATES OF LINE
- SHLD XDOT ;XPOS WILL BE X COORD OF ALL DOTS
- LHLD YPOS ;GET Y COORDINATE
- PUSH H ;SAVE Y POSITION- PLOTDOT WILL RESET IT
- XCHG ;PUT Y COORDINATE IN [DE]
- LHLD YFILL ;GET Y FILL VALUE
- ;
- MOV A,D ;COMPARE Y COORDINATES FOR TOP AND BOT.
- CMP H ;COMPARE HIGH BYTES
- JC YFXCH ;CARRY INDICATES THAT YFILL IS > YPOS
- JNZ CONTFIL ;YFILL DEFINITELY LESS THAN YPOS
- MOV A,E ;HIGH BYTES EQUAL- COMPARE LOW BYTES
- CMP L ;IS YFILL ABOVE OR BELOW YPOS?
- JNC CONTFIL ;YFILL IS NOT ABOVE YPOS- CONTINUE
- YFXCH XCHG ;SWITCH YPOS AND YFILL- LARGER VAL IN DE
- CONTFIL SHLD YDOT ;PASS Y COORDINATE TO PLOTDOT
- PUSH D ;SAVE REGISTERS
- PUSH H
- CALL PLOTDOT ;PLOT POINT
- POP H ;RETRIEVE REGISTERS
- POP D
- INX H ;INCREMENT Y POSITION
- ;
- MOV A,D ;CHECK TO SEE IF LINE IS DONE
- CMP H ;COMPARE HIGH BYTES
- JC DONEFIL ;CARRY INDICATES THAT NEW Y IS ABOVE END
- JNZ CONTFIL ;NEW COORDINATE DEFINITELY BELOW END
- MOV A,E ;HIGH BYTES EQUAL- COMPARE LOW BYTES
- CMP L ;IS IT THERE YET?
- JC DONEFIL ;CARRY INDICATES THAT NEW Y IS ABOVE END
- JMP CONTFIL ;LOOP BACK AND DO NEXT POINT
- DONEFIL POP H ;RETRIEVE LINE Y POSITION
- SHLD YPOS ;RESTORE VALUE
- RET ;ALL FINISHED!
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE WILL FILL AN AREA BETWEEN A LINE SEGMENT AND
- ; A HORIZONTAL LINE
- ;
- ; INPUTS:
- ; BUFFER CONTAINING COORDINATE PAIRS AND Y COORDINATE OF
- ; FILL LEVEL. ALL FIVE ARE REAL VALUES
- ; OUTPUTS:
- ; XPOS,YPOS UPDATED TO END OF LINE SEGMENT
- ; AREA BETWEEN SEGMENT AND YFILL IS FILLED WITH CURRENT
- ; COLOR VALUE
- ; REGISTER STATUS:
- ; ALL REGISTERS DESTROYED
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE
- ;
- FILL CALL READXY ;GET STARTING COORDINATES
- LHLD X
- SHLD XPOS ;UPDATE X POSITION TO START OF SEGMENT
- LHLD Y
- SHLD YPOS ;UPDATE Y POSITION TO START OF SEGMENT
- CALL READXY ;GET END COORDINATES
- CALL BYTE ;GET FIRST BYTE OF FIXED PT. Y FILL
- PUSH PSW ;STORE FIRST BYTE
- CALL BYTE ;GET SECOND BYTE
- MOV B,A ;PUT HIGH BYTE IN [B]
- POP PSW ;GET LOW BYTE
- MOV C,A ;[BC] NOW CONTAINS FIXED POINT Y COORD.
- LXI D,MAXY*2 ;PASS MAXIMUM RASTER ADDRESS
- CALL MULT ;MULTIPLY Y COORD BY NO. OF Y RASTERS
- XCHG ;PUT HIGH BYTES IN [HL]
- SHLD YFILL ;SAVE INTEGER VALUE OF Y FILL LEVEL
- ;
- CALL SEGINIT ;INITIALIZE VARIABLES FOR SEG. INTERP.
- CALL FILINE ;FILL AREA BETWEEN FIRST PT. & YFILL
- STRTFIL CALL COMPSEG ;COMPUTE NEXT POINT IN SEGMENT
- LHLD DELTAX ;TOP OF LOOP- END WHEN NI>DX
- XCHG ;DELTAX IS NOW IN (DE)
- LHLD NI ;GET COUNTER
- MOV A,D ;COMPARE COUNTER W/DX HI BYTE FIRST
- CMP H ;COMPARE HI BYTES
- RC ;CARRY INDICATES NI HI BYTE>DX HI BYTE
- JNZ CHKFIL ;CONTINUE IF NI DEFINITELY < DX
- MOV A,E ;HIGH BYTES EQUAL- LOOK @ LOW BYTE
- CMP L ;NOW LOW BYTE
- RC ;NI LOW BYTE>DX LOW BYTE- DONE W/SEGMENT
- CHKFIL LHLD XDOT ;COMPARE XDOT AND XPOS
- XCHG
- LHLD XPOS ;XPOS=XDOT=> THIS WILL DUPLICATE FILL
- MOV A,D
- CMP H ;ARE HIGH BYTES THE SAME?
- JNZ LOOPFIL ;GO ON IF HIGH BYTES ARE NOT EQUAL
- MOV A,E ;HIGH BYTES EQUAL- LOOK AT LOW BYTES
- CMP L ;ARE THE TWO EXACTLY THE SAME?
- JZ STRTFIL ;YES- SKIP THIS POSITION
- LOOPFIL CALL FILINE ;FILL AREA BETWEEN SEGMENT & YFILL
- JMP STRTFIL ;LOOP BACK TO TOP
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE WILL SEND A STRING OF CHARACTERS TO THE PRINTER
- ;
- ; INPUTS:
- ; NUMBER-1 OF CHARACTERS TO SEND IN [DE]
- ; ADDRESS-1 OF FIRST CHARACTER IN [HL]
- ; OUTPUTS:
- ; 0 THROUGH [DE] CHARACTERS SENT TO PRINTER
- ; REGISTER STATUS:
- ; ALL REGISTERS DESTROYED
- ; ERROR CONDITIONS:
- ; NONE DETECTED BY THIS ROUTINE
- ;
- GBOLOOP NOP
- IF OKI
- PUSH D
- PUSH H
- MVI C,05H ;SEND ETX TO START INTO GRAPHIC MODE
- MVI E,03H
- CALL PDOS
- POP H
- POP D
- ENDIF ;(OKI)
- ;
- KIRKLOP DCX D ;DECREMENT COUNTER
- INX H ;INCREMENT ADDRESS
- PUSH D ;SAVE COUNTER
- PUSH H
- MOV E,M ;GET CHARACTER
- ;
- IF OKI ;IF GRAPHIC BYTE IS <ETX>, A SECOND
- ;<ETX> IS REQUIRED FOR THE OKI PRINTER
- MOV A,E
- CPI 03H ;IS BYTE <ETX>?
- JNZ GBOLP1
- PUSH D ;SAVE BYTE
- MVI C,05H ;SELECT CP/M LIST FUNCTION
- CALL PDOS
- MVI E,03H ;REPLACE <ETX> CHARACTER SENT
- POP D ;SAVE BYTE
- ENDIF ;(OKI)
- ;
- GBOLP1 MVI C,05 ;SELECT CP/M LIST OUTPUT FUNCTION
- CALL PDOS ;SEND CHARACTER OUT
- POP H ;RETRIEVE ADDRESS
- POP D ;RETRIEVE COUNTER
- MOV A,E ;IS COUNTER =0?
- ORA D ;TEST COUNTER
- JNZ KIRKLOP ;NOT DONE: LOOP BACK
- IF OKI ;SEND ETX-SO TO CANCEL GRAPHICS MODE
- PUSH D ;SAVE COUNTER
- PUSH H ;SAVE ADDRESS
- MVI C,05H
- MVI E,03H
- CALL PDOS
- MVI C,05H
- MVI E,02H
- CALL PDOS
- POP H ;RETRIEVE ADDRESS
- POP D ;RETRIEVE COUNTER
- ENDIF ;(OKI)
- ;
- RET
- ;
- ;-----------------------------------------------------------------------
- ; THIS ROUTINE SAVES A BYTE FROM BIT MAP IN GRAPHIC BUFFER
- ;
- ; INPUTS:
- ; BYTE IN (B)
- ; 2 BYTE COUNTER @ NGRAPH
- ;
- ; OUTPUTS:
- ; NGRAPH INCREMENTED
- ; BYTE STORED IN BUFFER @ GBUFF
- ; BUFFER FLUSHED IF FULL
- ;
- ; REGISTER STATUS:
- ; ALL REGISTERS PRESERVED
- ;
- ; ERROR CONDITIONS:
- ; NONE
- ;
- GBUFIN PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- LHLD NGRAPH ;GET NO. OF BYTES IN BUFFER
- INX H ;INCREMENT NGRAPH
- SHLD NGRAPH ;STORE NEW VALUE
- XCHG ;PUT NGRAPH IN [DE]
- ;
- LXI H,GBUFF-1 ;GET BUFFER BASE ADDRESS
- DAD D ;ADD COUNTER TO BASE ADDRESS
- MOV M,B ;STORE BYTE
- ;
- ;
- XCHG ;PUT NGRAPH IN [HL]
- LXI D,0-(MAXX+1) ;PUT -MAX NO. OF BYTES IN [DE]
- DAD D ;[HL]=NGRAPH-(MAX NO. OF BYTES)
- MOV A,H ;IF [HL]=0 THEN BUFFER IS FULL
- ORA L ;SET FLAGS
- CZ GBUFOUT
- ;BUFFER IS FULL- FLUSH IT TO PRINTER
- ;
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE FLUSHES THE GRAPHIC BUFFER
- ;
- ; INPUTS:
- ; GRAPHIC BUFFER @ GBUFF
- ; NUMBER OF VALID BYTES IN BUFFER @ NGRAPH
- ; "ESC K" SEQUENCE STORED AHEAD OF NGRAPH
- ;
- ; OUTPUTS:
- ; PRINTER IS PLACED IN DOT GRAPHIC MODE
- ; GRAPHIC STRING TRANSMITTED BYTE BY BYTE TO PRINTER
- ;
- ; REGISTER STATUS:
- ; ALL REGISTERS PRESERVED
- ;
- ; ERROR CONDITIONS:
- ; NONE
- ;
- GBUFOUT PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- GBOTOP LHLD NGRAPH ;FETCH BUFFER COUNTER
- XCHG ;PUT BUFFER COUNTER IN [DE]
- MOV A,E ;LOOK AT LOW BYTE
- ORA D ;IS COUNTER=0?
- JZ GBUFRET ;IF BUFFER IS EMPTY, DON'T O/P ANYTHING
- ;
- ; SKIP TOTALLY BLANK LINES
- ;
- LXI B,MAXX+1 ;GET LENGTH OF BUFFER
- MOV A,B ;COMPARE HIGH BYTES FIRST
- CMP D
- JNZ GBO2 ;NO MATCH INDICATES SOMETHING ON THIS LINE
- MOV A,C ;COMPARE LOW BYTES NEXT
- CMP E
- JNZ GBO2 ;NO MATCH INDICATES SOMETHING ON THIS LINE
- ;
- LXI H,GBUFF ;SET POINTER TO START OF BUFFER
- GBO1 MOV A,M ;GET BYTE FROM BUFFER
- ORA A ;IS IT A BLANK STROKE?
- JNZ GBO2 ;GO TO OUTPUT SECTION IF NOT BLANK
- INX H ;POINT TO NEW BYTE
- DCX B ;DECREMENT COUNTER
- MOV A,B ;CHECK FOR ZERO
- ORA C
- JNZ GBO1 ;REPEAT UNTIL LAST BYTE HAS BEEN CHECKED
- ;
- JMP GBUFRET ;RETURN W/O PLOTTING SINCE ALL WERE BLANK
- ;
- GBO2 NOP ;HEAD OF OUTPUT SECTION
- ;
- IF NO8BIT
- MOV A,E ;LOOK AT LOW BYTE OF COUNTER
- ORA A ;SET FLAGS- IS HIGH BIT SET?
- JP GBO7 ;LOW BYTE HAS 7 BITS-O/P WHOLE THING.
- ;
- ; THE PARALLEL INTERFACE WILL ONLY TRANSMIT 7 BITS. THE LOW BYTE
- ; OF THE BUFFER COUNTER HAS ITS HIGH BIT SET, THEREFORE, THE
- ; BUFFER MUST BE OUTPUT IN SMALLER CHUNKS
- ;
- PUSH D ;SAVE NGRAPH ON STACK
- ENDIF ;(NO8BIT)
- IF EPSON AND NO8BIT
- LXI D,126+4 ;COUNTER=>126 BYTES + 4 FOR ESCK,NGRAPH
- LXI H,126D ;SET NGRAPH TO 126
- SHLD NGRAPH ;PUT NEW NO. IN PRINTER SEQUENCE
- LXI H,ESCK-1 ;START WITH ESCAPE SEQUENCE
- ENDIF ;(EPSON AND NO8BIT)
- ;
- IF CITOH AND NO8BIT
- LXI D,126+6 ;COUNTER=>126 BYTES + 6 FOR ESC S N3210
- LXI H,ESCK+3 ;ADDRESS OF N1 BYTE
- LXI B,126D ;SET NO. OF BYTES
- MOV M,B ;STORE HIGH BYTE IN N1
- INX H ;ADDRESS OF N0
- MOV M,C ;STORE LOW BYTE IN N0
- LXI H,ESCK-1 ;START WITH ESCAPE SEQUENCE
- ENDIF ;(CITOH AND NO8BIT)
- ;
- IF NO8BIT
- CALL GBOLOOP ;SEND OUT FIRST 126 CHARACTERS
- ;
- ; MOVE CHARACTERS IN BUFFER UP TO REPLACE THOSE SENT OUT
- ;
- POP H ;RETRIEVE OLD VALUE OF NGRAPH
- LXI D,0FF82H ;[DE]=-126D
- DAD D ;[HL]NOW=NGRAPH-126
- SHLD NGRAPH ;STORE NEW VALUE
- XCHG ;PUT NGRAPH IN [DE] TO ACT AS COUNTER
- LXI H,GBUFF-1 ;GET BASE ADDRESS OF BUFFER
- PUSH H ;SAVE POINTER FOR SAVING DATA
- LXI B,007EH ;PUT 126D IN [BC]
- DAD B ;[HL] NOW POINTS TO NEW BYTES
- ;
- GBOMOV INX H ;INCRMENT NEW DATA POINTER
- MOV A,M ;GET BYTE FROM BUFFER
- XTHL ;EXCHANGE POINTERS
- INX H ;INCREMENT SAVE DATA POINTER
- MOV M,A ;MOVE BYTE UP IN BUFFER
- XTHL ;EXCHANGE POINTERS BACK AGAIN
- DCX D ;DECREMENT COUNTER
- MOV A,E ;CHECK TO SEE IF LOOP IS DONE
- ORA D ;IS [DE]=0?
- JNZ GBOMOV ;LOOP BACK UP IF NOT DONE
- POP H ;RETRIEVE POINTER TO CLEAN UP STACK
- ;
- ; NGRAPH HAS NOW BEEN UPDATED AND DATA IN BUFFER HAS BEEN MOVED
- ; TO REPLACE THAT WHICH HAS BEEN SENT OUT. NOW READY TO TRY ALL
- ; OVER AGAIN WITH NEW SEGMENT OF DATA IN BUFFER.
- ;
- JMP GBOTOP
- ENDIF ;(NO8BIT)
- ;
- IF EPSON
- GBO7 INX D
- INX D
- INX D
- INX D
- LXI H,ESCK-1 ;START WITH ESCAPE SEQUENCE
- ENDIF ;(EPSON)
- ;
- IF CITOH
- GBO7 LXI H,ESCK+2 ;ADDRESS OF N3 BYTE FOR GRAPHICS SELECT
- MVI A,30H ;INITIALIZE NUMBER OF BYES TO "0000"
- MOV M,A ;"0"
- INX H
- MOV M,A ;"00"
- INX H
- MOV M,A ;"000"
- INX H
- MOV M,A ;"0000"
- ;
- CALL BINDEC ;CONVERT N TO ASCII DECIMAL AND STORE
- ;
- INX D ;INCREMENT COUNTER FOR ESC S N3-N0
- INX D
- INX D
- INX D
- INX D
- INX D
- LXI H,ESCK-1 ;START WITH ESCAPE SEQUENCE
- ENDIF ;(CITOH)
- ;
- IF OKI
- GBO7 LXI H,GBUFF-1
- ENDIF ;(OKI)
- ;
- CALL GBOLOOP ;SEND OUT STRING OF GRAPHIC CHARACTERS
- ;
- GBUFRET MVI A,00H ;CLEAR ACCUMULATOR
- STA NGRAPH ;SET NGRAPH=0
- STA NGRAPH+1
- POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE PLOTS AN INCREMENTAL LINE SEGMENT FROM THE
- ; PRESENT POSITION
- ; INPUTS:
- ; FILE BUFFER @ DMA
- ; PRESENT POSITION @ XPOS,YPOS
- ; OUTPUTS:
- ; XPOS, YPOS UPDATED TO X,Y
- ; VISIBLE PORTION OF LINE SEGMENT DRAWN
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE
- ;
- INCPLT CALL READXY ;GET END POINT VALUES
- CALL SEGINIT ;INITIALIZE SEGMENT INTERPOLATION SUB.
- ;
- STRTPLT LHLD DELTAX ;TOP OF LOOP- END WHEN NI>DX
- XCHG ;DELTAX IS NOW IN (DE)
- LHLD NI ;GET COUNTER
- MOV A,D ;COMPARE COUNTER W/DX HI BYTE FIRST
- CMP H ;COMPARE HI BYTES
- RC ;CARRY INDICATES NI HI BYTE>DX HI BYTE
- JNZ CONTPLT ;CONTINUE IF NI DEFINITELY < DX
- MOV A,E ;HIGH BYTES EQUAL- LOOK @ LOW BYTE
- CMP L ;NOW LOW BYTE
- RC ;NI LOW BYTE>DX LOW BYTE- DONE W/SEGMENT
- CONTPLT CALL COMPSEG ;COMPUTE XPOS AND YPOS AT NEXT POINT
- LHLD XPOS ;FETCH X POSITION
- SHLD XDOT ;PASS IN XDOT
- LHLD YPOS ;FETCH Y POSITION
- SHLD YDOT ;PASS IN YDOT
- CALL PLOTDOT ;PLOT IT (FINALLY)
- JMP STRTPLT ;BOUNCE UP TO THE TOP OF THE LOOP
- ;
- ;-----------------------------------------------------------------------
- ; LINE SPACING SUBROUTINE
- ;
- ; INPUTS:
- ; NONE
- ; OUTPUTS:
- ; FORM FEED SENT
- ; ESC A 7 SENT TO SET THE PRINTER TO 7/72" LINE SPACING
- ; REGISTER STATUS:
- ; ALL VALUES CHANGED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- IF EPSON
- LN772 MVI C,05H ;SELECT LIST OUTPUT
- ; MVI E,0CH ;PASS FORMFEED
- ; CALL PDOS ;SEND IT OUT
- ;
- ; MVI C,05H ;SELECT LIST OUTPUT
- MVI E,1BH ;PASS ESC CHARACTER
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,'A' ;PASS "A"
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,07H ;PASS 7 FOR 7/72"
- CALL PDOS
- ;
- RET
- ENDIF ;(EPSON)
- ;
- IF CITOH
- LN772 MVI C,05H ;SELECT LIST OUTPUT
- ; MVI E,0CH ;PASS FORMFEED
- ; CALL PDOS ;SEND IT OUT
- ;
- ; MVI C,05H ;SELECT LIST OUTPUT
- MVI E,1BH ;PASS ESC CHARACTER
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,'>' ;ESC > SETS UNIDIRECTIONAL PRINTING
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,1BH ;PASS ESC CHARACTER
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,'T' ;PASS "T"
- CALL PDOS ;SEND IT OUT
- ;
- MVI C,05H
- MVI E,'1'
- CALL PDOS ;SEND OUT 1 AS HIGH BYTE
- ;
- MVI C,05H ;SELECT LIST OUTPUT
- MVI E,'4' ;PASS 14 FOR 14/144"
- CALL PDOS
- ;
- RET
- ENDIF ;(CITOH)
- ;
- IF OKI
- LN772 MVI C,05H
- MVI E,18H ;CLEAR PRINTER
- CALL PDOS
- MVI C,05H
- MVI E,1CH ;SET 12 CPI
- CALL PDOS
- MVI C,05H
- MVI E,1BH ;ESC % "9" 14 TO SET LINE SPACING
- CALL PDOS
- MVI C,05H
- MVI E,25H
- CALL PDOS
- MVI C,05H
- MVI E,39H
- CALL PDOS
- MVI C,05H
- MVI E,14D ;14/144 "/LINE
- CALL PDOS
- RET
- ENDIF ;(OKI)
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE CALCULATES THE ADDRESS FOR AN XY COORDINATE PAIR
- ; XYADDR= ORIGIN + XCOORD + (MAXY-YCOORD)/7 * (MAXX+1)
- ; INPUTS:
- ; XCOORDINATE IN REGISTERS BC
- ; YCOORDINATE IN REGISTERS DE
- ; MAXIMUM Y RASTER COUNT IN HL
- ; OUTPUTS:
- ; XCOORDINATE IN REGISTERS BC
- ; YCOORDINATE IN REGISTERS DE
- ; ADDRESS OF X,Y COORDINATES IN HL
- ; ADDRESS STORED @ XYADDR
- ; REGISTER STATUS:
- ; PSW VALUES CHANGED
- ; ERROR CONDITIONS:
- ; OVERFLOW OF ARITHMETIC CALLS WOOPS
- ;
- LOCDOT PUSH D ;STORE Y COORD ON STACK
- PUSH B ;STORE X COORD ON STACK
- MOV A,L
- SUB E ;SUBTRACT YCOORD FROM MAXY
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A ;[HL] NOW CONTAINS (MAXY - Y)
- SHLD DIVDND ;PASS (MAXY - Y) TO DIVISION ROUTINE
- MVI A,07H ;PASS 7 TO DIVISION ROUTINE
- STA DIVSOR
- CALL DIVIDE ;(MAXY - Y)/7
- LDA RMANDR ;RMANDR IS NEGATIVE IF OVERFLOW
- ORA A ;SET FLAGS
- CM WOOPS ;OVERFLOW IN DIVISION
- LDA QOTENT ;GET RESULT OF DIVISION
- LXI B,MAXX+1 ;[BC] NOW CONTAINS THE MAX. NO. OF X'S
- CALL BMULT ;[HL] HAS LOW ORDER BYTES, [A] THE HIGH
- ; [HL] NOW CONTAINS (MAX-YCOORD)/7*(MAX+1)
- POP B ;PUT XCOORD IN [BC]
- DAD B ;ADD TO X PREVIOUS TERM
- LXI D,ORIGIN ;LAST TERM
- DAD D ;FINAL SUM IS IN [HL]
- SHLD XYADDR ;STORE RESULT
- POP D ;RETRIEVE Y COORDINATE
- RET
- ;
- ;-----------------------------------------------------------------------
- ; OUTPUT ROUTINE
- ;
- ; INPUTS:
- ; MEMORY MAP STARTING @ ORIGIN
- ;
- ; OUTPUTS:
- ; MAP IS DUMPED TO PRINTER 1 BYTE AT A TIME
- ; MIXED GRAPHICS AND TEXT ARE OUTPUT
- ;
- ; REGISTER STATUS:
- ; ALL VALUES DESTROYED
- ;
- ; ERROR CONDITIONS:
- ; NONE. PRINTER WILL HANG IF IT DOESN'T GET PROPER INPUT
- ;
- MAPOUT MVI A,00H ;RESET STATUS COUNTER
- STA STATNO
- MVI C,09H ;PRINT PRINTING STATUS MESSAGE
- LXI D,STAT3
- CALL FDOS
- ;
- CALL LN772 ;SET PRINTER TO 7/72" LINE SPACING
- LXI H,ORIGIN ;INITIAIZE START ADDRESS
- MVI A,00H ;CLEAR ACCUMULATOR
- STA NGRAPH ;INITIALIZE GRAPHICS COUNTER
- STA NGRAPH+1
- MVI C,(MAXY+1)/7 ;INITIALIZE LINE COUNTER
- LINLOOP LXI D,MAXX+1 ;INITIALIZE DOT COUNTER
- ;
- BYTLOOP MOV B,M ;GET BYTE
- MOV A,B ;PUT BYTE IN (A)
- ORA A ;SET FLAGS - IS IT A GRAPHIC BYTE?
- CM CHAROUT ;NO- HI BIT SET THEREFORE CHARACTER
- CP GBUFIN ;YES- SAVE IT IN GRAPHIC BUFFER
- ;
- INX H ;INCREMENT ADDRESS TO NEXT X LOCATION
- DCX D ;DECREMENT DOT COUNTER
- MOV A,D
- ORA E ;IS DOT COUNTER = 0?
- JNZ BYTLOOP ;NO- SO LOOP TO TOP AGAIN
- ;
- CALL GBUFOUT ;AT END OF LINE- FLUSH BUFFER
- CALL CRLF ;SEND A LINE FEED TO PRINTER
- DCR C ;DECREMENT LINE COUNTER
- MOV A,C ;GET READY TO TEST LINE COUNTER
- ORA A ;SET FLAGS ON LINE COUNTER
- JNZ LINLOOP ;NOT DONE- REPEAT OUTER LOOP
- ;
- CALL PRESET ;RESET PRINTER TO NORMAL MODE
- ;
- RET ;LAST LINE FINISHED
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE MOVES THE PRESENT POSITION TO NEW COORDINATES
- ; WITHOUT DOING ANYTHING ELSE
- ;
- ; INPUTS:
- ; COORDINATE PAIR IN BUFFER
- ; OUTPUTS:
- ; XPOS AND YPOS UPDATED TO NEW COORDINATES
- ; REGISTER STATUS:
- ; ALL VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE
- ;
- MOVE CALL READXY ;GET COORDINATE PAIR
- LHLD X ;GET X COORDINATE
- SHLD XPOS ;UPDATE X AXIS POSITION
- LHLD Y ;GET Y COORDINATE
- SHLD YPOS ;UPDATE Y AXIS POSITION
- RET ;POSITION NOW UPDATED.
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE MULTIPLIES TWO 16 BIT INTEGERS
- ;
- ; THIS ROUTINE FROM ELECTRONICS MAGAZINE, FEB. 24, 1982.
- ; WRITTEN BY JERRY L. GOODRICH, PENN. STATE U.
- ;
- ;
- ; INPUTS:
- ; MULTIPLICAND IN [BC]
- ; MULTIPLIER IN [DE]
- ; OUTPUTS:
- ; 32 BIT PRODUCT IN [DE],[HL] (MOST SIG. BITS IN [DE])
- ; REGISTER STATUS:
- ; SEE INPUTS AND OUTPUTS
- ; ERROR CONDITIONS:
- ; NONE
- ;
- MULT MOV A,E ;LOAD LOWEST ORDER BYTE OF MULTIPLIER
- PUSH D ;SAVE HIGHEST ORDER BYTE OF MULTIPLIER
- CALL BMULT ;DO 1-BYTE MULTIPLY
- XTHL ;SAVE LOWEST ORDER BYTES PRODUCT, GET MULTIPLIER
- PUSH PSW ;STORE HIGHEST ORDER BYTE OF FIRST PROD.
- MOV A,H ;LOAD HIGHEST ORDER BYTE OF MULTIPLIER
- CALL BMULT ;DO SECOND 1-BYTE MULTIPLY
- MOV D,A ;POSITION HIGHEST-ORDER BYTE OF PRODUCT
- POP PSW ;GET HIGHEST ORDER BYTE OF FIRST PRODUCT
- ADD H ;UPDATE THIRD BYTE OF PRODUCT
- MOV E,A ;AND PUT IT IN E
- JNC NC1 ;DONT'T INCREMENT D IF NO CARRY
- INR D ;INCREMENT D IF CARRY
- NC1: MOV H,L ;RELOCATE LOWEST ORDER BYTES OF 2ND PROD
- MVI L,0
- POP B ;GET LOWEST ORDER 2 BYTES OF FIRST PROD.
- DAD B ;GET FINAL PRODUCT LOWEST ORDER 2 BYTES
- RNC ;DONE IF NO CARRY
- INX D ;OTHERWISE UPDATE HIGHEST ORDER 2 BYTES
- RET
- ;
- ;-----------------------------------------------------------------------
- ; PRINT OR DISK O/P SUBROUTINE
- ;
- ; INPUTS:
- ; 05H IN (C)
- ; CHARACTER IN (E)
- ; BUFFER POINTER SET TO LAST CHARACTER (POINTR2)
- ; O/P FLAG IN OPDISK
- ; OUTPUTS:
- ; CHARACTER PRINTED IF O/P FLAG SET
- ; CHARACTER WRITTEN TO DISK IF FLAG IS SET
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE IN THIS ROUTINE.
- ;
- PDOS LDA OPDISK ;GET DISK O/P FLAG
- CPI 00H ;IS FLAG SET?
- PUSH PSW ;SAVE FLAG
- CZ FDOS ;PRINT CHARACTER IF IT IS
- POP PSW ;RETRIEVE FLAGS
- RZ ;RETURN IF CHARACTER WAS PRINTED
- ;
- LDA POINTR2 ;GET BUFFER POINTER
- INR A ;INCREMENT POINTER FOR NEW CHAR.
- STA POINTR2 ;SAVE NEW VALUE
- MOV C,A ;SAVE POINTER VALUE IN (C)
- MVI B,0 ;CLEAR HIGH BYTE OF (BC)
- LXI H,DMA2-1 ;GET LAST ADDR. BEFORE DMA2
- DAD B ;CALCULATE ADDRESS OF BYTE
- MOV M,E ;PUT CHARACTER IN BUFFER
- CPI 128D ;IS BUFFER FULL?
- CZ WRITE ;WRITE IT OUT IF IT IS.
- RET ;DONE
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE PLOTS A POINT @ XDOT,YDOT
- ; METHOD:
- ; FIND BYTE CONTAINING XDOT,YDOT
- ; FORM MASK EG: IF XDOT,YDOT IS IN #4 BIT,
- ; MASK = 00010000
- ; DIGIT= 76543210
- ; MODIFY BYTE ACCORDING TO COLOR & STORE IT BACK
- ; INPUTS:
- ; 2 BYTE X LOCATION STORED @ XDOT
- ; 2 BYTE Y LOCATION STORED @ YDOT
- ; OUTPUTS:
- ; XPOS, YPOS RESET TO VALUES GIVEN IN XDOT, YDOT
- ; APPROPRIATE DOT TURNED ON OR OFF IN MEMORY MAP
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; IF XDOT OR YDOT ARE OUTSIDE OF WINDOW, NO POINT PLOTTED
- ; XPOS AND YPOS WILL STILL POINT OUTSIDE WINDOW
- ;
- PLOTDOT LHLD XDOT ;GET X POSITION
- SHLD XPOS ;UPDATE CURRENT POSITION
- MOV B,H ;MOVING XDOT TO BC
- MOV C,L ;XDOT NOW IN BC
- LHLD YDOT ;GET Y POSITION
- SHLD YPOS ;UPDATE CURRENT POSITION
- MOV D,H ;MOVING YDOT TO DE
- MOV E,L ;YDOT NOW IN DE
- ;XPOS AND YPOS NOW CONTAIN LAST POS. ATTEMPTED- MAY NOT BE IN WINDOW
- LXI H,MAXX ;PUT LIMITS OF X IN HL
- XCHECK MOV A,B ;CHECK FOR NEG X-SIGN IN HI BYTE
- ORA A ;IS XDOT NEGATIVE?
- RM ;XDOT NEG- RETURN W/O PLOTTING
- MOV A,H ;WORK WITH HIGH BYTE FIRST
- CMP B ;COMPARE MAX & X HIGH BYTES
- RC ;X>MAX- THEREFORE RETURN
- JNZ YCHECK ;X IS OK- CHECK Y
- MOV A,L ;HIGH BYTES ARE= LOOK @ LOW BYTE
- CMP C ;COMPARE X & MAX LOW BYTES
- RC ;X>MAX- RETURN W/O PLOTTING
- YCHECK LXI H,MAXY ;PUT LIMIT OF Y IN HL
- MOV A,D ;YDOT HI BYTE CONTAINS SIGN
- ORA A ;IS YDOT NEGATIVE?
- RM ;YDOT NEG- RETURN W/O PLOTTING
- MOV A,H ;HIGH BYTES FIRST
- CMP D ;COMPARE MAX & Y HIGH BYTES
- RC ;Y>MAX- RETURN W/O PLOTTING
- JNZ XYOK ;Y IS OK- PLOT DOT
- MOV A,L ;HIGH BYTES= LOOK @ LOW BYTES
- CMP E ;COMPARE LOW BYTES
- RC ;Y IS > MAX- RETURN W/O PLOTTING
- XYOK CALL LOCDOT ;GET ADDRESS OF BYTE FOR X,YDOT
- CALL DIGIT ;FORM MASK FOR PLOTTING
- MOV A,B ;DETERMINE IF BYTE IS GRAPHIC
- ORA A ;GRAPHIC?
- RM ;MINUS= CHARACTER: RETURN W/O PLOTTING
- LDA COLOR ;GET COLOR VALUE
- ORA A ;SET FLAGS
- JZ WHITE ;0 = WHITE
- JM COMPL ;-1 = COMPLEMENTARY COLOR
- MOV A,B ;COLOR IS BLACK
- ORA C ;MODIFY BYTE BY TURNING BIT ON
- MOV M,A ;STORE BACK IN MEMORY
- RET ;DONE- ( AT LAST)
- ;
- WHITE MOV A,B ;WORK W/ BYTE CONTAINING X,Y
- CMA ;COMPLEMENT BYTE
- ORA C ;MODIFY BYTE BY TURNING ON BIT
- CMA ;COMPLEMENT BYTE BACK- BIT 0FF
- MOV M,A ;STORE BYTE BACK IN MEMORY
- RET ;DONE- (FINALY)
- ;
- COMPL MOV A,B ;WORK W/ BYTE CONTAINING X,Y
- XRA C ;COMPLEMENT BIT
- MOV M,A ;STORE IT
- RET ;DONE-
- ;
- ;-----------------------------------------------------------------------
- ; PLOT POINT ROUTINE
- ;
- ; INPUTS:
- ; BUFFER @ DMA
- ; OUTPUTS:
- ; POINT PLOTTED IN MEMORY
- ; REGISTER STATUS:
- ; ALL VALUES CHANGED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- POINT CALL READXY ;READ COORDINATES FOR POINT
- LHLD X ;FETCH X LOCATION
- SHLD XDOT ;PASS X TO DOT ROUTINE
- LHLD Y ;FETCH Y LOCATION
- SHLD YDOT ;PSSS Y TO DOT ROUTINE
- CALL PLOTDOT
- RET
- ;
- ;-----------------------------------------------------------------------
- ; QUIT
- ; CLOSES OUTPUT FILE, TERMINATES PROGRAM
- ; INPUTS:
- ; FCB FOR OUTPUT FILE @ FCB2
- ; DISK OUTPUT FLAG @ OPDISK
- ; OUTPUTS:
- ; REMAINDER OF RECORD SET TO 0, DISK CLOSED.
- ; REGISTER STATUS:
- ; ALL VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- QUIT: LDA OPDISK ;GET DISK OUTPUT FLAG
- CPI 00H ;IS IT SET?
- JZ BOOT ;NO, SO ALL DONE
- ;
- LDA POINTR2 ;LOOK @ O/P POINTER
- CPI 0 ;IS O/P BUFFER EMPTY?
- JZ BOOT ;YES- DONE
- ;
- ; FILL REMAINDER OF O/P BUFFER WITH NULLS
- ;
- MOV E,A ;SAVE POINTER VALUE IN (E)
- MVI D,00H ;CLEAR HIGH BYTE OF (DE)
- MVI A,128 ;SET MAX VALUE OF POINTER
- SUB E ;(A)= 128- POINTR2
- MOV C,A ;(C) NOW IS COUNT OF EXTRA BUFF.
- ;
- CLRBUF PUSH B ;SAVE COUNTER
- MVI E,00H ;PASS A <NULL>
- CALL PDOS ;PUT IT IN BUFFER
- POP B ;RETRIEVE COUNTER
- DCR C ;COUNTER=COUNTER-1
- JNZ CLRBUF ;LOOP BACK UNTIL BUFFER IS FULL
- ;
- MVI C,10H ;SELECT CLOSE FILE FUNCTION
- LXI D,FCB2 ;PASS O/P FCB
- CALL FDOS ;CLOSE FILE
- ;
- JMP BOOT ;DO WARM BOOT ON EXIT
- ;
- ;-----------------------------------------------------------------------
- ; LINE SEGMENT ROUTINE
- ; INPUTS: FILE BUFFER @ DMA
- ;
- ; OUTPUTS:
- ; XPOS, YPOS UPDATED TO X2,Y2
- ; VISIBLE PORTION OF LINE SEGMENT PLOTTED
- ;
- ; REGISTERS:
- ; ALL REGISTERS VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NO CHECKS MADE IN THIS ROUTINE
- ;
- PLOTSEG CALL READXY ;GET STARTING COORDINATES
- LHLD X ;FETCH STARTING X
- SHLD XDOT ;PASS TO DOT ROUTINE
- LHLD Y ;FETCH STARTING Y
- SHLD YDOT ;PASS TO DOT ROUTINE
- CALL PLOTDOT ;PLOT STARTING POINT
- CALL INCPLT ;PLOT REST OF SEGMENT
- RET ;RETURN TO MAIN PROGRAM
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE RESETS THE PRINTER TO ITS NORMAL MODE
- ;
- ; INPUTS:
- ; NONE
- ; OUTPUTS:
- ; NONE RETURNED
- ; REGISTER STATUS:
- ; ALL REGISTERS CHANGED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- IF EPSON
- PRESET: MVI C,05H
- MVI E,1BH ;PASS ESC CHARACTER
- CALL PDOS ;SEND ESC
- MVI C,05H
- MVI E,'2'
- CALL PDOS ;ESC 2 SETS LINE SPACING TO 6 LINES/IN.
- MVI C,05H
- MVI E,CR ;SEND CARRIAGE RETURN TO RESET HEAD
- CALL PDOS
- RET
- ENDIF ;(EPSON)
- ;
- IF CITOH
- PRESET: MVI C,05H
- MVI E,1BH ;SEND ESC
- CALL PDOS
- MVI C,05H
- MVI E,'A' ;ESC A SETS LINE SPACING TO 6 LINES/IN.
- CALL PDOS
- MVI E,CR
- MVI C,05H
- CALL PDOS ;SEND CARRIAGE RETURN TO RESET HEAD
- RET
- ENDIF ;(CITOH)
- ;
- IF OKI
- PRESET: MVI C,05H
- MVI E,1BH ;ESC % "9" 24 TO SET LINE SPACING
- CALL PDOS
- MVI C,05H
- MVI E,25H ; "%"
- CALL PDOS
- MVI C,05H
- MVI E,39H ; "9"
- CALL PDOS
- MVI C,05H
- MVI E,24D ;RESET TO NORMAL LINE SPACING
- CALL PDOS
- RET
- ;
- ENDIF ;(OKI)
- ;
- ;-----------------------------------------------------------------------
- ; READ RECORD SUBROUTINE
- ; INPUTS:
- ; OPENED FILE
- ; FILE CONTROL BLOCK @ FCB
- ; 128 CHAR FILE BUFFER @ DMA
- ; 1 BYTE CHARACTER POINTER @ POINTER
- ; OUTPUTS:
- ; CHARACTER POINTER RESET TO 0
- ; NEW RECORD IN FILE BUFFER
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; EOF: JUMP TO EOFEXIT INSTEAD OF NORMAL RETURN
- ;
- READ MVI C,26D ;SELECT SET DMA FUNCTION
- LXI D,DMA ;PASS BUFFER ADDRESS
- CALL FDOS ;SET DMA ADDRESS TO I/P BUFFER
- ;
- MVI C,14H ;SELECT SEQUENTIAL READ FUNCTION
- LXI D,FCB ;PASS FCB
- CALL FDOS ;READ RECORD INTO BUFFER @ DMA
- CPI 00H ;READ OK?
- JZ SETPNTR ;RESET POINTER IF NOT EOF
- POP B ;POP RETURN ADDR OFF STACK
- JMP EOFEXIT ;GOTO EXIT INSTEAD OF NORMAL RTN
- SETPNTR MVI A,0 ;CLEAR ACCUM.
- STA POINTER ;RESET POINTER TO 0
- RET ;RETURN-NEW RECORD & POINTER POS
- ;
- EOFEXIT MVI C,09H ;SELECT PRINT STRING FUNCTION
- LXI D,EOFMSG ;PASS MESSAGE
- CALL FDOS ;PRINT EOF MESSAGE
- JMP BOOT ;RETURN TO CP/M COMMAND LEVEL
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE GETS AN XY PAIR
- ;AND CONVERTS IT TO RASTER VALUES. THE GENERAL ALGORITHM IS:
- ;
- ; INTEGER = (FIXED POINT) * (NUMBER OF RASTERS) * 2/ 2^16
- ;
- ; THE FIXED POINT NUMBER IS A 15 BIT VALUE IN THE RANGE 0 TO 1.
- ; WHEN VIEWED AS AN INTEGER, THE FIXED POINT COORDINATES RANGE FROM
- ; 0 TO 32767. WHEN MULTIPLIED BY THE RANGE OF THE RASTER COORDINATES,
- ; THEY MUST BE DIVIDED BY 32767 TO REPRESENT THE TRUE VALUE. THIS IS
- ; APPROXIMATED BY MULTIPLYING BY 2 / 65536 (2/64K). DIVIDING BY 64K
- ; IS ACCOMPLISHED BY SIMPLY DISREGARDING THE LOWER 2 BYTES OF THE RESULT
- ;
- ; INPUTS:
- ; 128 CHARACTER BUFFER @ DMA
- ; CHARACTER POINTER @ POINTER
- ; OUTPUTS:
- ; TWO BYTE VALUE STORED @ X
- ; TWO BYTE VALUE STORED @ Y
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE- BYTE WILL TERMINATE PROGRAM ON EOF IF NECESSARY
- ;
- READXY CALL BYTE ;GET FIRST BYTE OF X
- PUSH PSW ;STORE FIRST BYTE
- CALL BYTE ;GET SECOND BYTE
- MOV B,A ;PUT HIGH BYTE IN [B]
- POP PSW ;GET LOW BYTE
- MOV C,A ;[BC] NOW CONTAINS FIXED POINT X COORD.
- LXI D,MAXX*2 ;PASS MAXIMUM RASTER ADDRESS
- CALL MULT ;MULTIPLY X COORD BY NO. OF X RASTERS
- XCHG ;PUT HIGH BYTES IN [HL]
- SHLD X ;STORE CORRESPONDING RASTER X COORDINATE
- ;
- CALL BYTE ;GET FIRST BYTE OF Y
- PUSH PSW ;STORE FIRST BYTE
- CALL BYTE ;GET SECOND BYTE
- MOV B,A ;PUT HIGH BYTE IN [B]
- POP PSW ;GET LOW BYTE
- MOV C,A ;[BC] NOW CONTAINS FIXED POINT Y COORD.
- LXI D,MAXY*2 ;PASS MAXIMUM RASTER ADDRESS
- CALL MULT ;MULTIPLY Y COORD BY NO. OF Y RASTERS
- XCHG ;PUT HIGH BYTES IN [HL]
- SHLD Y ;STORE CORRESPONDING RASTER Y COORDINATE
- RET
- ;
- ;---------------------------------------
- ;
- ; THIS SUBROUTINE ROTATES THE PATTERNS USED FOR ERASING TO A COLOR
- ;
- ; INPUTS:
- ; ARRAY OF 8 PATTERN BYTES STORED AT PATRN
- ; OUTPUTS:
- ; ARRAY IS ROTATED ONE BIT DOWN
- ; REGISTER STATUS:
- ; [BC],[HL] PRESERVED, ALL OTHERS DESTROYED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- ROTPAT: PUSH B ;SAVE COUNTER IN [BC]
- PUSH H ;SAVE POINTER IN [HL]
- MVI B,8D ;INITIALIZE COUNTER
- LXI H,PATRN ;INITIALIZE ADDRESS OF HEAD OF ARRAY
- ROTPT1: MOV A,M ;GET BYTE
- IF MSBTOP
- RRC ;ROTATE BYTE
- ENDIF ;( MSBTOP )
- IF NOT MSBTOP
- RLC
- ENDIF ;( NOT MSBTOP )
- MOV M,A ;STORE ROTATED BYTE
- ;
- INX H ;MOVE POINTER TO NEXT BYTE
- DCR B ;DECREMENT COUNTER
- JNZ ROTPT1 ;LOOP BACK UNTIL DONE
- POP H ;RETRIEVE SAVED REGISTERS
- POP B
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE INITIALIZES THE VARIABLES USED IN COMPUTING A
- ; LINE SEGMENT
- ;
- ; INPUTS:
- ; XPOS,YPOS PRESENT POSITION
- ; X,Y END POINTS OF SEGMENT
- ; OUTPUTS:
- ; DX,DY X,Y SIZES OF LINE SEGMENT
- ; EPSLNX,EPSLNY,SX,SY,DELTA3 INTERNAL VARIABLES
- ; INITIALIZED
- ; NI COUNTER USED TO DETERMINE WHEN DONE
- ; REGISTER SATUS:
- ; ALL REGISTER VALUES DESTROYED.
- ; ERROR CONDITIONS:
- ; NONE
- ;
- SEGINIT LHLD X ;GET X
- XCHG ;PUT X IN DE
- LHLD XPOS ;PUT PRESENT POS IN HL
- MOV A,E ;CALCULATE DELTA X
- SUB L
- MOV C,A
- MOV A,D
- SBB H
- MOV B,A ;BC NOW CONTAINS DELTA X (DX)
- LHLD Y ;GET Y END POINT VALUE
- XCHG ;PUT Y IN DE
- LHLD YPOS ;GET PRESENT Y POSITION
- MOV A,E ;CALCULATE DELTA Y (DY)
- SUB L
- MOV E,A
- MOV A,D
- SBB H
- MOV D,A ;DE NOW CONTAINS DY
- XCHG ;PUT DY IN HL, YPOS IN DE
- SHLD DELTAY ;STORE DY
- MOV H,B
- MOV L,C
- ;
- SHLD DELTAX ;STORE DELTA X
- LXI H,0000H ;INITIALIZE VARIABLES
- SHLD SX
- SHLD EPSLNY
- LXI H,0001H
- SHLD SY
- SHLD EPSLNX
- LDA DELTAX+1 ;GET DX HIGH BYTE
- ORA A ;SET FLAGS ACCORDING TO DX HI BYTE
- JP CHKDY
- LXI H,0FFFFH ;CHANGE INITIALIZATION FOR -DX
- SHLD EPSLNX
- LHLD DELTAX ;CHANGE SIGN ON DX
- MOV A,H
- CMA ;COMPLEMENT HIGH BYTE
- MOV H,A
- MOV A,L
- CMA ;COMPLEMENT LOW BYTE
- ADI 01H ;ADD 1 TO MAKE IT TWO'S COMP.
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY TO HIGH BYTE
- MOV H,A
- SHLD DELTAX ;STORE NOW POSITIVE DX
- CHKDY LDA DELTAY+1 ;GET DY HIGH BYTE- CONTAINS SIGN
- ORA A ;SET FLAGS ON DY HI BYTE
- JP CHDXDY ;DY IS POS- GOTO TRANSPOSE AXES
- LHLD DELTAY ;DY IS NEGATIVE- CHANGE SIGN
- MOV A,H
- CMA ;COMPLEMENT HI BYTE
- MOV H,A
- MOV A,L
- CMA
- ADI 01H ;COMPLEMENT AND ADD 1
- MOV L,A
- MOV A,H
- ACI 00H ;ADD CARRY FROM LOW BYTE
- MOV H,A
- SHLD DELTAY ;STORE THE NOW POS. DY
- LXI H,0FFFFH ;LOAD -1 IN (HL)
- SHLD SY ;SY= -1
- CHDXDY LHLD DELTAX ;TRANSPOSE AXES IF DX<DY
- XCHG ;PUT DX IN DE
- LHLD DELTAY ;GET DELTA Y
- MOV A,D ;PUT HIGH BYTE OF DX IN A
- CMP H ;DX < DY ? (HIGH BYTES FIRST)
- JC TNSPOS ;DX DEFINITELY < DY
- JNZ LSTINIT ; DX DEFINITELY > DY
- MOV A,E ;HIGH BYTES =, CHECK LOW BYTES
- CMP L
- JNC LSTINIT ;IF NO CARRY, DX>= DY- START PLOTTING
- TNSPOS SHLD DELTAX ;DY WAS IN HL- STORE AS DX
- XCHG ;DX NOW IN HL, DY NOW IN DE
- SHLD DELTAY ;STORE OLD DX AS NEW DY
- LHLD EPSLNX
- SHLD SX ;REINITIALIZE: SX= EPSILON X
-
- LHLD SY
- SHLD EPSLNY ;EPSILON Y = SY
- LXI H,0000H
- SHLD EPSLNX ;EPSILON X = 0
- SHLD SY ;SY = 0
- ;
- LSTINIT STC ;CLEAR CARRY -SET=1, THEN COMPLEMENT
- CMC
- MOV A,D ;CALCULATE DELTAX/2 BY SHIFTING 1 RIGHT
- RAR ;SHIFT
- MOV D,A ;STORE HIGH BYTE DELTAX/2 IN D
- MOV A,E ;NOW THE LOW BYTE
- RAR ;SHIFT (DIVIDE BY 2)
- MOV E,A ;PUT LOW BYTE BACK.
- XCHG ;PUT DX/2 IN (HL)
- SHLD DELTA3 ;STORE IN DELTA3
- ;
- LXI H,0001H ;SET NI=1
- SHLD NI ;SAVE COUNTER VALUE
- RET ;DONE WITH INITIALIZATION
- ;
- ;------------------------------------------------------------------------
- ; STATUS MESSAGE ROUTINE
- ;
- ; THIS ROUTINE DISPLAYS A MESSAGE TO INDICATE THAT THE PROGRAM
- ; IS WORKING.
- ;
- ; INPUTS:
- ; CURRENT COUNT STORED IN STATNO
- ; OUTPUTS:
- ; MESSAGE DISPLAYED
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES PRESERVED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- STAT PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- PUSH H
- ;
- LDA STATNO ;GET COUNTER
- INR A ;UPDATE COUNTER
- STA STATNO
- MVI C,09H ;SELECT WRITE FUNCTION
- CPI 01H ;SELECT MESSAGE
- JNZ STATM2
- LXI D,STAT1
- CALL FDOS ;PRINT MESSAGE
- JMP STATX ;EXIT SUBROUTINE
- ;
- STATM2 CPI 128 ;CHECK FOR OTHER MESSAGE
- JNZ STATX ;NOT TIME FOR EITHER MESSAGE
- LXI D,STAT2
- CALL FDOS ;PRINT OTHER MESSAGE
- ;
- STATX POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET
- ;
- ;------------------------------------------------------------------------
- ; STRING PLOTTING SUBROUTINE
- ; METHOD:
- ; ASCII CODE IS STORED REPEATEDLY IN THE AREA OCCUPIED BY
- ; THE CHARACTER (CWIDTH RASTERS). HI BIT IS SET TO
- ; INDICATE THAT THE BYTE IS ASCII AND NOT DOT IMAGE.
- ;
- ; INPUT:
- ; X,Y IN FILE BUFFER
- ; BYTES READ SEQUENTIALLY FROM BUFFER UNTIL CARRIAGE RTN
- ; IS ENCOUNTERED.
- ;
- ; OUTPUTS:
- ; EACH CHARACTER IS STORED IN THE BYTE CONTAINING THE BIT
- ; MAP COORDINATE INDICATED FOR THE CHARACTER
- ;
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ;
- ; ERROR CONDITIONS:
- ; X,Y LOCATIONS < 0 ARE RESET TO 0
- ; X,Y LOCATIONS > MAX ARE RESET TO 0
- ;
- CR EQU 0DH ;CR = CARRIAGE RETURN
- STRING CALL READXY ;GET STARTING COORDINATES
- STRNG0 CALL BYTE ;GET FIRST CHARACTER
- CPI CR ;IS CHARACTER A CARRIAGE RETURN?
- RZ ;YES- SO RETURN (ALL DONE)
- ORI 10000000B ;SET HIGH BIT
- MOV B,A ;SAVE BYTE IN (B)
- LHLD X ;GET X LOCATION
- MOV A,H ;LOOK AT HIGH BYTE
- ORA A ;SET FLAGS
- JM RESETX ;X IS NEGATIVE- RESET TO 0
- LXI D,MAXX-CWIDTH ;GET MAXIMUM X VALUE
- CMP D ;COMPARE MAX AND X HIGH BYTES
- JC STRNG1 ;MAX DEFINITELY > X (X IS OK)
- JNZ RESETX ;X DEFINITELY > MAX -RESET X
- MOV A,L ;HI BYTES ARE =: LOOK AT LOW BYTES
- CMP E ;IS MAX LOW BYTE > X LOW BYTE?
- JC STRNG1 ;YES IS IS - X IS OK
- JZ STRNG1 ;LOW BYTES ARE =: X IS BARELY OK
- RESETX LXI H,0000H ;CLEAR HL
- SHLD X ;STORE 0 IN X
- STRNG1 LHLD Y ;FETCH Y STARTING LOCATION
- MOV A,H ;LOOK AT Y HIGH BYTE
- ORA A ;SET FLAGS
- JM RESETY ;NEGATIVE - RESET TO 0
- LXI D,MAXY ;USE ENTIRE COORDINATE RANGE FOR Y
- CMP D ;COMPARE MAX AND Y HIGH BYTES
- JC STRNG2 ;Y DEFINITELY OK
- JNZ RESETY ;Y DEFINITELY > MAX - RESET Y
- MOV A,L ;HI BYTES ARE =: LOOK @ LOW BYTES
- CMP E ;COMPARE MAX AND Y LOW BYTES
- JC STRNG2 ;MAX > Y - Y IS OK
- JZ STRNG2 ;Y = MAX
- RESETY LXI H,0000H ;CLEAR OLD VALUE OF Y
- SHLD Y ;Y = 0
- STRNG2 XCHG ;PUT Y IN (DE)
- LHLD X ;FETCH X
- PUSH B ;SAVE BYTE TEMPORARILY
- PUSH D ;SAVE Y COORD TEMPORARILY
- ; MAKE X COORD. A MULTIPLE OF CWIDTH FOR PROPER PRINTER OUTPUT
- SHLD DIVDND ;COMPUTE X=(X/CWIDTH)*CWIDTH
- MVI A,CWIDTH ;GET CWIDTH FOR DIVISOR
- STA DIVSOR
- CALL DIVIDE ;DIVIDE X BY CWIDTH
- LDA QOTENT ;GET RESULTS (NO OVERFLOW AS 0<=X<1530)
- LXI B,CWIDTH ;PASS CHARACTER WIDTH
- CALL BMULT ;[HL] NOW CONTAINS (X/CWIDTH)*CWIDTH
- ;
- MOV B,H ;PUT X IN (BC)
- MOV C,L
- POP D ;RETRIEVE Y COORDINATE
- LXI H,MAXY ;PUT MAX Y IN (HL)
- CALL LOCDOT ;GET LOCATION OF BYTE
- POP B ;RETRIEVE BYTE
- MOV M,B ;PUT BYTE IN ADDRESS CONTAINING X,Y
- ; STORE BYTE REPEATEDLY TO BLANK OUT ENTIRE AREA OCCUPIED BY IT
- MVI A,CWIDTH-1 ;INITIALIZE LOOP COUNTER
- STRNG3: INX H ;INCREMENT ADDRESS
- MOV M,B ;STORE BYTE
- SUI 1 ;DECREMENT LOOP COUNTER
- JNZ STRNG3 ;LOOP BACK UP UNTIL FINISHED
- MVI C,CWIDTH ;PUT CWIDTH IN (C)
- LHLD X ;FETCH X LOCATION
- MVI B,00H ;CLEAR (B)
- DAD B ;INCREMENT X LOCATION FOR NEXT CHARACTER
- SHLD X ;STORE NEW X LOCATION
- JMP STRNG0 ;LOOP UP TO TOP
- ;
- ;-----------------------------------------------------------------------
- ; TEXT
- ;
- ; THIS SUBROUTINE OUTPUTS TEXT IMMEDIATELY TO THE PRINTER
- ; NOTE: TEXT IS NOT PUT INTO MEMORY MAP
- ;
- ; INPUTS:
- ; TEXT STRING IN FILE (ENDS WITH 0 BYTE)
- ; OUTPUTS:
- ; TEXT STRING PRINTED
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE PECULIAR TO THIS ROUTINE
- ;
- TEXT CALL BYTE ;GET NEXT CHARACTER
- CPI 0 ;CHECK FOR END OF STRING
- RZ ;RETURN IF FINISHED
- ;
- MOV E,A ;PASS CHARACTER
- MVI C,05 ;SELECT CP/M LST: OUTPUT
- CALL PDOS ;PRINT IT
- ;
- JMP TEXT ;LOOP BACK UNTIL DONE
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE UPLOADS THE ARRAY DEFINING COLOR PALLET
- ;
- ; INPUTS:
- ; 16 BIT INTEGER SPECIFYING # OF DATA BYTES TO COME
- ; DATA BYTES IN INPUT FILE
- ; OUTPUTS:
- ; NEW COLOR VALUES STORED IN APPROPRIATE ARRAYS
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES DESTROYED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- UPLOAD: CALL BYTE ;GET LOW BYTE OF INTEGER
- MOV C,A ;SAVE INTEGER IN [BC]
- CALL BYTE ;GET HIGH BYTE
- ;
- ORA A ;CHECK VALUE OF HIGH BYTE
- JNZ UPBAD ;FOR THIS PROGRAM, HI BYTE MUST BE 0
- MOV A,C ;LOOK AT LOW BYTE
- CPI 7D ;7 INDICATES UPLOAD PLAID PATTERNS
- JZ UPLAID ;PROCEED TO UPLOAD PLAID VALUES
- CPI 64D ;64 INDICATES UPLOAD DITHER MATRIX
- JZ UPDITH ;PROCEED TO UPLOAD DITHER MATRIX
- CPI 120D ;124 INDICATES UPLOAD SPECIAL PATTERNS
- JZ UPCIF ;PROCEED TO UPLOAD SPECIAL PATTERNS
- ;
- UPBAD: CALL BYTE ;# HAS UNEXPECTED VALUE- SKIP BYTES
- DCX B ;DECREMENT LOOP COUNTER
- MOV A,C
- ORA B ;IS COUNTER = 0 ?
- JNZ UPBAD ;LOOP BACK UNTIL FINISHED
- RET
- ;
- UPLAID: LXI H,PLAIDS+1 ;POINT TO PLAID ARRAY (LEAVE "0" ALONE)
- JMP UPLP1 ;PROCEED TO READ-STORE LOOP
- UPCIF: LXI H,CIFPAT ;SET POINTER AT START OF SPECIAL PATTERNS
- JMP UPLP1
- UPDITH: LXI H,DITHARR ;POINT TO DITHER ARRAY
- UPLP1: CALL BYTE ;GET COLOR PATTERN
- MOV M,A ;STORE PATTERN
- INX H ;POINT TO NEXT PATTERN SLOT
- DCR C ;DECREMENT COUNTER
- JNZ UPLP1 ;LOOP BACK UNTIL FINISHED
- RET
- ;
- ;-----------------------------------------------------------------------
- ; THIS SUBROUTINE IS EXECUTED WHEN OVERFLOW OCCURS IN MULT. OR DIV
- ; INPUTS:
- ; NONE
- ; OUTPUTS:
- ; MESSAGE "OVERFLOW"
- ; ALL REGISTERS PUSHED ON STACK
- ; IN ORDER: PSW, H, D, B
- ; FINAL POSITION OF STACK POINTER SAVED IN OLDSTK
- ; REGISTER STATUS:
- ; ALL INPUT REGISTERS STORED ON STACK, C, DE, HL REG CHANGED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- WOOPS PUSH PSW ;SAVE ALL REGISTERS
- PUSH H
- PUSH D
- PUSH B
- LXI H,0000H ;CLEAR (HL)
- DAD SP ;GET STACK POINTER
- SHLD OLDSTK ;SAVE STACK POINTER FOR DEBUG
- MVI C,09H ;SELECT PRINT FUNCTION
- LXI D,OVFLMSG
- CALL FDOS ; PRINT 'OVERFLOW'
- JMP BOOT ;RETURN TO CP/M COMMAND LEVEL
- OVFLMSG DB 'OVERFLOW$'
- ;
- ;-----------------------------------------------------------------------
- ; WRITE RECORD SUBROUTINE
- ;
- ; INPUTS:
- ; OPENED FILE
- ; FILE CONTROL BLOCK @ FCB2
- ; BUFFER @ DMA2
- ; BUFFER POINTER @ POINTR2
- ; OUTPUTS:
- ; BUFFER WRITTEN TO FILE
- ; BUFFER POINTER RESET TO 0
- ; REGISTER STATUS:
- ; ALL REGISTER VALUES CHANGED
- ; ERROR CONDITIONS:
- ; IF NO SPACE LEFT ON DISK, ERROR MESSAGE WRITTEN
- ; AND PROGRAM TERMINATES.
- ;
- WRITE MVI C,26D ;SELECT SET DMA FUNCTION
- LXI D,DMA2 ;PASS O/P BUFFER
- CALL FDOS ;SET DMA ADDRESS
- ;
- MVI C,21D ;SELECT WRITE SEQUENTIAL
- LXI D,FCB2 ;PASS O/P FCB
- CALL FDOS ;WRITE RECORD
- ;
- CPI 00H ;WAS WRITE OK?
- JNZ FULLXIT ;JUMP TO ERROR SECTION IF NOT
- MVI A,00H ;CLEAR (A)
- STA POINTR2 ;POINTR2=0
- RET ;DONE WITH SUCCESSFUL WRITE
- FULLXIT MVI C,09D ;SELECT PRINT FUNCTION
- LXI D,NOROOM ;PASS ERROR MESSAGE
- CALL FDOS ;PRINT IT
- ;
- JMP BOOT ;TERMINATE WITH WARM START
- ;
- ;-----------------------------------------------------------------------
- ;
- ; THIS SUBROUTINE IS USED FOR NON-STANDARD EXTENSIONS TO PLOT
- ;
- ; INPUTS:
- ; NONE
- ; OUTPUTS:
- ; NONE
- ; REGSISTER STATUS:
- ; ALL VALUES PRESERVED
- ; ERROR CONDITIONS:
- ; NONE
- ;
- XTEND: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- ;
- CALL BYTE ;GET LOW BYTE OF NUMBER OF DATA BYTES
- MOV A,C
- CALL BYTE ;GET HIGH BYTE OF NUMBER OF BYTES
- MOV A,B ;[BC] IS NOW 16 BIT INTEGER
- ORA C ;IS NUMBER = 0?
- JZ XTND2 ;FINISHED IF N = 0
- XTND1: CALL BYTE ;GET DATA BYTE
- DCX B ;DECREMENT COUNTER
- MOV A,C
- ORA B ;IS COUNTER = 0 ?
- JNZ XTND1 ;LOOP BACK IF MORE TO COME
- XTND2: POP H ;RESTORE REGISTERS
- POP D
- POP B
- POP PSW
- RET ;FINISHED
- ;
- ;-----------------------------------------------------------------------
- ;
- ORIGIN ;START OF PICTURE MAP
- ;
- ;-----------------------------------------------------------------------