	opt f+h-				; Do not generate exe headers

PALFLG	equ 0				; 0 = NTSC / 1 = PAL
FASTFP	equ 0				; 0 = Standard Math / 1 = Fast Math

;
;	Include math package
;
 ift FASTFP
	ins 'fastmath.bin'		; Include floating point math package
 els
	ins 'fp.bin'			; Include floating point math package
 eif
;
;		 COLLEEN OPERATING SYSTEM EQUATE FILE
;
;
;		 MODULE ORIGIN TABLE
;
CHRORG	equ $E000			;CHARACTER SET
VECTBL	equ $E400			;VECTOR TABLE
VCTABL	equ $E480			;RAM VECTOR INITIAL VALUE TABLE
CIOORG	equ $E4A6			;CENTRAL I/O HANDLER
INTORG	equ $E6D5			;INTERRUPT HANDLER
SIOORG	equ $E944			;SERIAL I/O DRIVER
DSKORG	equ $EDEA			;DISK HANDLER
PRNORG	equ $EE78			;PRINTER HANDLER
CASORG	equ $EF41			;CASSETTE HANDLER
MONORG	equ $F0E3			;MONITOR/POWER UP MODULE
KBDORG	equ $F3E4			;KEYBOARD/DISPLAY HANDLER
;
;
;
;
;		VECTOR TABLE
;
;HANDLER ENTRY POINTS ARE CALLED OUT IN THE FOLLOWING VECTOR
;TABLE. THESE ARE THE ADDRESSES MINUS ONE.
;
;
;EXAMPLE FOR EDITOR
;
;	 E400		 OPEN
;		 2		 CLOSE
;		 4		 GET
;		 6		 PUT
;		 8		 STATUS
;		 A		 SPECIAL
;		 C		 JUMP TO POWER ON INITIALIZATION ROUTINE
;		 F		 NOT USED
;
;
EDITRV	equ $E400			;EDITOR
SCRENV	equ $E410			;TELEVISION SCREEN
KEYBDV	equ $E420			;KEYBOARD
PRINTV	equ $E430			;PRINTER
CASETV	equ $E440			;CASSETTE
;
;		 JUMP VECTOR TABLE
;
;THE FOLLOWING IS A TABLE OF JUMP INSTRUCTIONS
;TO VARIOUS ENTRY POINTS IN THE OPERATING SYSTEM.
;
DISKIV	equ $E450			;DISK INITIALIZATION
DSKINV	equ $E453			;DISK INTERFACE
CIOV	equ $E456			;CENTRAL INPUT OUTPUT ROUTINE
SIOV	equ $E459			;SERIAL INPUT OUTPUT ROUTINE
SETVBV	equ $E45C			;SET SYSTEM TIMERS ROUTINE
SYSVBV	equ $E45F			;SYSTEM VERTICAL BLANK CALCULATIONS
XITVBV	equ $E462			;EXIT VERTICAL BLANK CALCULATIONS
SIOINV	equ $E465			;SERIAL, INPUT OUTPUT INITIALIZATION
SENDEV	equ $E468			;SEND ENABLE ROUTINE
INTINV	equ $E46B			;INTERRUPT HANDLER INITIALIZATION
CIOINV	equ $E46E			;CENTRAL INPUT OUTPUT INITIALIZATION
BLKBDV	equ $E471			;BLACKBOARD MODE
WARMSV	equ $E474			;WARM START ENTRY POINT
COLDSV	equ $E477			;COLD START ENTRY POINT
RBLOKV	equ $E47A			;CASSETTE READ BLOCK ENTRY POINT VECTOR
CSOPIV	equ $E47D			;CASSETTE OPEN FOR INPUT VECTOR
;VCTABL	equ $E480
;
;
; OPERATING SYSTEM EQUATES
;
; COMMAND CODES FOR IOCB
OPEN	equ $03				;OPEN FOR INPUT/OUTPUT
GETREC	equ $05				;GET RECORD (TEXT)
GETCHR	equ $07				;GET CHARACTER(S)
PUTREC	equ $09				;PUT RECORD (TEXT)
PUTCHR	equ $0B				;PUT CHARACTER(S)
CLOSE	equ $0C				;CLOSE DEVICE
STATIS	equ $0D				;STATUS REQUEST
SPECIL	equ $0E				;BEGINNING OF SPECIAL ENTRY COMMANDS
;
; SPECIAL ENTRY COMMANDS
DRAWLN	equ $11				;DRAW LINE
FILLIN	equ $12				;DRAW LINE WITH RIGHT FILL
RENAME	equ $20				;RENAME DISK FILE
DELETE	equ $21				;DELETE DISK FILE
FORMAT	equ $22				;FORMAT
LOCKFL	equ $23				;LOCK FILE TO READ ONLY
UNLOCK	equ $24				;UNLOCK LOCKED FILE
POINT	equ $25				;POINT SECTOR
NOTE	equ $26				;NOTE SECTOR
IOCFRE	equ $FF				;IOCB "FREE"
;
; AUX1 EQUATES
; () INDICATES WHICH DEVICES USE BIT
APPEND	equ $01				;OPEN FOR WRITE APPEND (D), OR SCREEN READ (
DIRECT	equ $02				;OPEN FOR DIRECTORY ACCESS (D)
OPNIN	equ $04				;OPEN FOR INPUT (ALL DEVICES)
OPNOT	equ $08				;OPEN FOR OUTPUT (ALL DEVICES)
OPNINO	equ OPNIN+OPNOT		;OPEN FOR INPUT AND OUTPUT (ALL DEVICES)
MXDMOD	equ $10				;OPEN FOR MIXED MODE (E,S)
INSCLR	equ $20				;OPEN WITHOUT CLEARING SCREEN (E,S)
;
; DEVICE NAMES
SCREDT	equ 'E'				;SCREEN EDITOR (R/W)
KBD		equ 'K'				;KEYBOARD (R ONLY)
D1SPLY	equ 'S'				;SCREEN DISPLAY (R/W)
PRINTR	equ 'P'				;PRINTER (W ONLY)
CASSET	equ 'C'				;CASSETTE
MODEM	equ 'M'				;MODEM
DISK	equ 'D'				;DISK (R/W)
;
; SYSTEM EOL (CARRIAGE RETURN)
CR		equ $9B
;
;
;		 OPERATING SYSTEM STATUS CODES
;
SUCCES	equ $01				;SUCCESSFUL OPERATION
;
BRKABT	equ $80				;BREAK KEY ABORT
PRVOPN	equ $81				;IOCB ALREADY OPEN
NONDEV	equ $82				;NON-EXISTANT DEVICE
WRONLY	equ $83				;IOCB OPENED FOR WRITE ONLY
NVALID	equ $84				;INVALID COMMAND
NOTOPN	equ $85				;DEVICE OR FILE NOT OPEN
BADIOC	equ $86				;INVALID IOCB NUMBER
RDONLY	equ $87				;IOCB OPENED FOR READ ONLY
EOFERR	equ $88				;END OF FILE
TRNRCD	equ $89				;TRUNCATED RECORD
TIMOUT	equ $8A				;PERIPHERAL DEVICE TIME OUT
DNACK	equ $8B				;DEVICE DOES NOT ACKNOWLEDGE COMMAND
FRMERR	equ $8C				;SERIAL BUS FRAMING ERROR
CRSROR	equ $8D				;CURSOR OVERRANCE
OVRRUN	equ $8E				;SERIAL BUS DATA OVERRUN
CHKERR	equ $8F				;SERIAL BUS CHECKSUM ERROR
;
DERROR	equ $90				;PERIPHERAL DEVICE ERROR (OPERATION NOT COMP
BADMOD	equ $91				;BAD SCREEN MODE NUMBER
FNCNOT	equ $92				;FUNCTION NOT IMPLEMENTED IN HANDLER
SCRMEM	equ $93				;INSUFICIENT MEMORY FOR SCREEN MODE
;
;
;
;
;
;
;		 PAGE ZERO RAM ASSIGNMENTS
;
LINZBS	equ $0000			;LINBUG RAM (WILL BE REPLACED BY MONITOR RAM)
;
; THESE LOCATIONS ARE NOT CLEARED
CASINI	equ $0002			;CASSETTE INIT LOCATION
RAMLO	equ $0004			;RAM POINTER FOR MEMORY TEST
TRAMSZ	equ $0006			;TEMPORARY REGISTER FOR RAM SIZE
TSTDAT	equ $0007			;RAM TEST DATA REGISTER
;
; CLEARED ON COLDSTART ONLY
WARMST	equ $0008			;WARM START FLAG
BOOT? 	equ $0009			;SUCCESSFUL BOOT FLAG
DOSVEC	equ $000a			;DISK SOFTWARE START VECTOR
DOSINI	equ $000c			;DISK SOFTWARE INIT ADDRESS
APPMHI	equ $000e			;APPLICATIONS MEMORY HI LIMIT
;
; CLEARED ON COLD OR WARM START
INTZBS	equ $0010			;INTERRUPT HANDLER
POKMSK	equ $0010			;SYSTEM MASK FOR POKEY IRQ ENABLE
BRKKEY	equ $0011			;BREAK KEY FLAG
RTCLOK	equ $0012			;REAL TIME CLOCK (IN 16 MSEC UNITS)
;
BUFADR	equ $0015			;INDIRECT BUFFER ADDRESS REGISTER
;
ICCOMT	equ $0017			;COMMAND FOR VECTOR
;
DSKFMS	equ $0018			;DISK FILE MANAGER POINTER
DSKUTL	equ $001a			;DISK UTILITIES POINTER
;
PTIMOT	equ $001c			;PRINTER TIME OUT REGISTER
PBPNT 	equ $001d			;PRINT BUFFER POINTER
PBUFSZ	equ $001e			;PRINT BUFFER SIZE
PTEMP 	equ $001f			;TEMPORARY REGISTER
;
ZIOCB	equ $0020			;ZERO PAGE I/O CONTROL BLOCK
IOCBSZ	equ 16				;NUMBER OF BYTES PER IOCB
MAXIOC	equ 8*IOCBSZ		;LENGTH OF THE IOCB AREA
IOCBAS	equ $0020
ICHIDZ	equ $0020			;HANDLER INDEX NUMBER (FF = IOCB FREE)
ICDNOZ	equ $0021			;DEVICE NUMBER (DRIVE NUMBER)
ICCOMZ	equ $0022			;COMMAND CODE
ICSTAZ	equ $0023			;STATUS OF LAST IOCB ACTION
ICBALZ	equ $0024			;BUFFER ADDRESS LOW BYTE
ICBAHZ	equ $0025
ICPTLZ	equ $0026			;PUT BYTE ROUTINE ADDRESS - 1
ICPTHZ	equ $0027
ICBLLZ	equ $0028			;BUFFER LENGTH LOW BYTE
ICBLHZ	equ $0029
ICAX1Z	equ $002a			;AUXILIARY INFORMATION FIRST BYTE
ICAX2Z	equ $002b
ICSPRZ	equ $002c			;4 SPARE BYTES (CIO LOCAL USE)
ICIDNO	equ ICSPRZ+2		;IOCB NUMBER X 16
CIOCHR	equ ICSPRZ+3		;CHARACTER BYTE FOR CURRENT OPERATION
;
STATUS	equ $0030			;INTERNAL STATUS STORAGE
CHKSUM	equ $0031			;CHECKSUM (SINGLE BYTE SUM WITH CARRY)
BUFRLO	equ $0032			;POINTER TO DATA BUFFER (LO BYTE)
BUFRHI	equ $0033			;POINTER TO DATA BUFFER (HI BYTE)
BFENLO	equ $0034			;NEXT BYTE PAST END OF THE DATA BUFFER (LO B
BFENHI	equ $0035			;NEXT BYTE PAST END OF THE DATA BUFFER (HI B
CRETRY	equ $0036			;NUMBER OF COMMAND FRAME RETRIES
DRETRY	equ $0037			;NUMBER OF DEVICE RETRIES
BUFRFL	equ $0038			;DATA BUFFER FULL FLAG
RECVDN	equ $0039			;RECEIVE DONE FLAG
XMTDON	equ $003a			;TRANSMISSION DONE FLAG
CHKSNT	equ $003b			;CHECKSUM SENT FLAG
NOCKSM	equ $003c			;NO CHECKSUM FOLLOWS DATA FLAG
;
;
BPTR	equ $003d
FTYPE 	equ $003e
FEOF	equ $003f
FREQ	equ $0040
SOUNDR	equ $0041			;NOISY I/O FLAG. (ZERO IS QUIET)
CRITIC	equ $0042			;DEFINES CRITICAL SECTION (CRITICAL IF NON-Z
;
FMSZPG	equ $0043			;DISK FILE MANAGER SYSTEM ZERO PAGE
;
;
CKEY	equ $004a			;FLAG SET WHEN GAME START PRESSED
CASSBT	equ $004b			;CASSETTE BOOT FLAG
DSTAT 	equ $004c			;DISPLAY STATUS
;
ATRACT	equ $004d			;ATRACT FLAG
DRKMSK	equ $004e			;DARK ATRACT MASK
COLRSH	equ $004f			;ATRACT COLOR SHIFTER (EOR'ED WITH PLAYFIELD
;
LEDGE	equ 2				;LMARGN'S VALUE AT COLD START
REDGE	equ 39				;RMARGN'S VALUE AT COLD START
TMPCHR	equ $0050
HOLD1 	equ $0051
LMARGN	equ $0052			;LEFT MARGIN (SET TO 1 AT POWER ON)
RMARGN	equ $0053			;RIGHT MARGIN (SET TO 38 AT POWER ON)
ROWCRS	equ $0054			;CURSOR COUNTERS
COLCRS	equ $0055
DINDEX	equ $0057
SAVMSC	equ $0058
OLDROW	equ $005a
OLDCOL	equ $005b
OLDCHR	equ $005d			;DATA UNDER CURSOR
OLDADR	equ $005e
NEWROW	equ $0060			;POINT DRAW GOES TO
NEWCOL	equ $0061
LOGCOL	equ $0063			;POINTS AT COLUMN IN LOGICAL LINE
ADRESS	equ $0064
MLTTMP	equ $0066
OPNTMP	equ MLTTMP			;FIRST BYTE IS USED IN OPEN AS TEMP
SAVADR	equ $0068
RAMTOP	equ $006a			;RAM SIZE DEFINED BY POWER ON LOGIC
BUFCNT	equ $006b			;BUFFER COUNT
BUFSTR	equ $006c			;EDITOR GETCH POINTER
BITMSK	equ $006e			;BIT MASK
SHFAMT	equ $006f
ROWAC	equ $0070
COLAC	equ $0072
ENDPT	equ $0074
DELTAR	equ $0076
DELTAC	equ $0077
ROWINC	equ $0079
COLINC	equ $007a
SWPFLG	equ $007b			;NON-0 IF TXT AND REGULAR RAM IS SWAPPED
HOLDCH	equ $007c			;CH IS MOVED HERE IN KGETCH BEFORE CNTL & SH
INSDAT	equ $007d
COUNTR	equ $007e
;
;
;
;
;		 30 - FF ARE RESERVED FOR USER APPLICATIONS
;
;
;
;		 NOTE : SEE FLOATING POINT SUBROUTINE AREA FOR ZERO PAGE CELLS
;
;
;
;
;		 PAGE 1	-	 STACK
;
;
;
;
;		 PAGE TWO RAM ASSIGNMENTS
;
INTABS	equ $0200			;INTERRUPT RAM
VDSLST	equ $0200			;DISPLAY LIST NMI VECTOR
VPRCED	equ $0202			;PROCEED LINE IRQ VECTOR
VINTER	equ $0204			;INTERRUPT LINE IRQ VECTOR
VBREAK	equ $0206			;SOFTWARE BREAK (00) INSTRUCTION IRQ VECTOR
VKEYBD	equ $0208			;POKEY KEYBOARD IRQ VECTOR
VSERIN	equ $020a			;POKEY SERIAL INPUT READY IRQ
VSEROR	equ $020c			;POKEY SERIAL OUTPUT READY IRQ
VSEROC	equ $020e			;POKEY SERIAL OUTPUT COMPLETE IRQ
VTIMR1	equ $0210			;POKEY TIMER 1 IRQ
VTIMR2	equ $0212			;POKEY TIMER 2 IRQ
VTIMR4	equ $0214			;POKEY TIMER 4 IRQ
VIMIRU	equ $0216			;IMMEDIATE IRQ VECTOR
CDTMV1	equ $0218			;COUNT DOWN TIMER 1
CDTMV2	equ $021a			;COUNT DOWN TIMER 2
CDTMV3	equ $021c			;COUNT DOWN TIMER 3
CDTMV4	equ $021e			;COUNT DOWN TIMER 4
CDTMV5	equ $0220			;COUNT DOWN TIMER S
VVBLKI	equ $0222			;IMMEDIATE VERTICAL BLANK NMI VECTOR
VVBLKD	equ $0224			;DEFERRED VERTICAL BLANK NMI VECTOR
CDTMA1	equ $0226			;COUNT DOWN TIMER 1 JSR ADDRESS
CDTMA2	equ $0228			;COUNT DOWN TIMER 2 JSR ADDRESS
CDTMF3	equ $022a			;COUNT DOWN TIMER 3 FLAG
SRTIMR	equ $022b			;SOFTWARE REPEAT TIMER
CDTMF4	equ $022c			;COUNT DOWN TIMER 4 FLAG
INTEMP	equ $022d			;IAN'S TEMP (RENAMED FROM T1 BY POPULAR DEMA
CDTMF5	equ $022e			;COUNT DOWN TIMER FLAG 5
SDMCTL	equ $022f			;SAVE DMACTL REGISTER
SDLSTL	equ $0230			;SAVE DISPLAY LIST LOW BYTE
SDLSTH	equ $0231			;SAVE DISPLAY LIST HI BYTE
SSKCTL	equ $0232			;SKCTL REGISTER RAM
							; Spare $0233
;
LPENH 	equ $0234			;LIGHT PEN HORIZONTAL VALUE
LPENV 	equ $0235			;LIGHT PEN VERTICAL VALUE
BRKKY	equ $0236			;BREAK KEY VECTOR
;
							; Spare 2-bytes $0238
;
CDEVIC	equ $023a			;COMMAND FRAME BUFFER - DEVICE
CCOMND	equ $023b			;COMMAND
CAUX1 	equ $023c			;COMMAND AUX BYTE 1
CAUX2 	equ $023d			;COMMANDAUX BYTE 2
;	NOTE: MAY NOT BE THE LAST WORD ON A PAGE
TEMP	equ $023e			;TEMPORARY RAM CELL
;	NOTE: MAY NOT BE THE LAST WORD ON A PAGE
ERRFLG	equ $023f			;ERROR FLAG - ANY DEVICE ERROR EXCEPT TIME
;
DFLAGS	equ $0240			;DISK FLAGS FROM SECTOR ONE
DBSECT	equ $0241			;NUMBER OF DISK BOOT SECTORS
BOOTAD	equ $0242			;ADDRESS WHERE DISK BOOT LOADERWILL BE PUT
COLDST	equ $0244			;COLDSTART FLAG (1=IN MIDDLE OF COLDSTART)
;
							; Spare $0245
;
DSKTIM	equ $0246			;DISK TIME OUT REGISTER
;
LINBUF	equ $0247			;CHAR LINE BUFFER (40 bytes)
;
GPRIOR	equ $026F			;GLOBAL PRIORITY CELL
;
PADDL0	equ $0270			;POTENTIOMETER 0 RAM CELL
PADDL1	equ $0271
PADDL2	equ $0272
PAODL3	equ $0273
PADDL4	equ $0274
PADDL5	equ $0275
PADDL6	equ $0276
PADDL7	equ $0277
STICK0	equ $0278			;JOYSTICK 0 RAM CELL
STICK1	equ $0279
STICK2	equ $027a
STICK3	equ $027b
PTRIG0	equ $027c			;PADDLE TRIGGER 0
PTRIG1	equ $027d
PTRIG2	equ $027e
PTRIG3	equ $027f
PTRIG4	equ $0280
PTRIG5	equ $0281
PTRIG6	equ $0282
PTRIG7	equ $0283
STRIG0	equ $0284			;JOYSTICK TRIGGER 0
STRIG1	equ $0285
STRIG2	equ $0286
STRIG3	equ $0287
;
CSTAT 	equ $0288
WMODE 	equ $0289
BLIM	equ $028a
IMASK 	equ $028b
JVECK	equ $028c
;
							; Spare 2-bytes $028e
;
;
;
;
TXTROW	equ $0290			;TEXT ROWCRS
TXTCOL	equ $0291			;TEXT COLCRS
TINDEX	equ $0293			;TEXT INDEX
TXTMSC	equ $0294			;FOOLS CONVRT INTO NEW MSC
TXTOLD	equ $0296			;OLDROW & OLDCOL FOR TEXT (AND THEN SOME)
TMPX1 	equ $029c
HOLD3 	equ $029d
SUBTMP	equ $029e
HOLD2 	equ $029f
DMASK 	equ $02a0
TMPLBT	equ $02a1
ESCFLG	equ $02a2			;ESCAPE FLAG
TABMAP	equ $02a3
LOGMAP	equ $02b2			;LOGICAL LINE START BIT MAP
INVFLG	equ $02b6			;INVERSE VIDEO FLAG (TOGGLED BY ATARI KEY)
FILFLG	equ $02b7			;RIGHT FILL FLAG FOR DRAW
TMPROW	equ $02b8
TMPCOL	equ $02b9
SCRFLG	equ $02bb			;SET IF SCROLL OCCURS
HOLD4 	equ $02bc			;TEMP CELL USED IN DRAW ONLY
HOLD5 	equ $02bd			;DITTO
SHFLOK	equ $02be
BOTSCR	equ $02bf			;BOTTOM OF SCREEN : 24 NORM 4 SPLIT
;
;
PCOLR0	equ $02c0			;P0 COLOR
PCOLR1	equ $02c1			;P1 COLOR
PCOLR2	equ $02c2			;P2 COLOR
PCOLP3	equ $02c3			;P3 COLOR
COLOR0	equ $02c4			;COLOR 0
COLOR1	equ $02c5
CQLOR2	equ $02c6
COLOR3	equ $02c7
COLOR4	equ $02c8
;
;
							; Spare 23-bytes $02c9
;
;
;
GLBABS	equ $02e0			;GLOBAL VARIABLES
;
							; Spare 4-bytes $02e0
;
RAMSIZ	equ $02e4			;RAM SIZE (HI BYTE ONLY)
MEMTOP	equ $02e5			;TOP OF AVAILABLE USER MEMORY
MEMLO	equ $02e7			;BOTTOM OF AVAILABLE USER MEMORY
							; Spare $02e9
DVSTAT	equ $02ea			;STATUS BUFFER
CBAUDL	equ $02ee			;CASSETTE BAUD RATE LOW BYTE
CBAUDH	equ $02ef
;
CRSINH	equ $02f0			;CURSOR INHIBIT (00 = CURSOR ON)
KEYDEL	equ $02f1			;KEY DELAY
CH1		equ $02f2
;
CHACT 	equ $02f3			;CHACTL REGISTER RAM
CHBAS 	equ $02f4			;CHBAS REGISTER RAM
;
							; Spare 5-bytes $02f5
;
CHAR	equ $02fa
ATACHR	equ $02fb			;ATASCII CHARACTER
CH	 	equ $02fc			;GLOBAL VARIABLE FOR KEYBOARD
FILDAT	equ $02fd			;RIGHT FILL DATA (DRAW)
DSPFLG	equ $02fe			;DISPLAY FLAG : DISPLAY CNTLS IF NON-ZERO
SSFLAG	equ $02ff			;START/STOP FLAG FOR PAGING (CNTL 1). CLEARE
;
;
;
;
;
;
;
;		 PAGE THREE RAM ASSIGNMENTS
;
DCB		equ $0300			;DEVICE CONTROL BLOCK
DDEVIC	equ $0300			;PERIPHERAL UNIT 1 BUS ID. NUMBER
DUNIT 	equ $0301			;UNIT NUMBER
DCOMND	equ $0302			;BUS COMMAND
DSTATS	equ $0303			;COMMAND TYPE/STATUS RETURN
DBUFLO	equ $0304			;DATA BUFFER POINTER LOW BYTE
DBUFHI	equ $0305
DTIMLO	equ $0306			;DEVICE TIME OUT IN 1 SECOND UNITS
DUNUSE	equ $0307			;UNUSED BYTE
DBYTLO	equ $0308			;NUMBER OF BYTES TO BE TRANSFERRED LOW BYTE
DBYTHI	equ $0309
DAUX1 	equ $030a			;COMMAND AUXILIARY BYTE 1
DAUX2 	equ $030b
;
TIMER1	equ $030c			;INITIAL TIMER VALUE
ADDCOR	equ $030e			;ADDITION CORRECTION
CASFLG	equ $030f			;CASSETTE MODE WHEN SET
TIMER2	equ $0310			;FINAL TIMER VALUE. THESE TWO TIMER VALUES
; ARE USED TO COMPUTE INTERVAL FOR BAUD RATE
TEMP1	equ $0312			;TEMPORARY STORAGE REGISTER
TEMP2 	equ $0314			;TEMPORARY STORAGE REGISTER
TEMP3 	equ $0315			;TEMPORARY STORAGE REGISTER
SAVIO 	equ $0316			;SAVE SERIAL IN DATA PORT
TIMFLG	equ $0317			;TIME OUT FLAG FOR BAUD RATE CORRECTION
STACKP	equ $0318			;SIO STACK POINTER SAVE CELL
TSTAT 	equ $0319			;TEMPORARY STATUS HOLDER
;
;
;
HATABS	equ $031a			;HANDLER ADDRESS TABLE 38-bytes
MAXDEV	equ $21				;MAXIMUM HANDLER ADDRESS INDEX (33 bytes)
;
;	  NOTE : THE ENTIRE IOCB DEFINITIONS HAVE BEEN MODIFIED
;
IOCB	equ $0340			;I/O CONTROL BLOCKS
ICHID 	equ $0340			;HANDLER INDEX NUMBER (FF = IOCB FREE)
ICDNO 	equ $0341			;DEVICE NUMBER (DRIVE NUMBER)
ICCOM 	equ $0342			;COMMAND CODE
ICSTA 	equ $0343			;STATUS OF LAST IOCB ACTION
ICBAL 	equ $0344			;BUFFER ADDRESS LOW BYTE
ICBAH 	equ $0345
ICPTL 	equ $0346			;PUT BYTE ROUTINE ADDRESS - 1
ICPTH 	equ $0347
ICBLL 	equ $0348			;BUFFER LENGTH LOW BYTE
ICBLH 	equ $0349
ICAX1 	equ $034a			;AUXILIARY INFORMATION FIRST BYTE
ICAX2 	equ $034b
ICSPR 	equ $034c			;FOUR SPARE BYTES
;
PRNBUF	equ $03c0			;PRINTER BUFFER (40-bytes)
;
							; Spare 21-bytes $03e8
;
;
;
;
;
;
;
;		 PAGE FOUR RAM ASSIGNMENTS
;
CASBUF	equ $03fd			;CASSETTE BUFFER 131-bytes
;
; USER AREA STARTS HERE AND GOES TO END OF PAGE FIVE
USAREA	equ $0480			;SPARE 128-bytes
;
;
;
;
;
;
;
;		 PAGE FIVE RAM ASSIGNMENTS
;
;		 PAGE FIVE IS RESERVED AS A USER WORK SPACE
;
;		 NOTE:	SEE FLOATING POINT SUBROUTINE AREA FOR PAGE FIVE CELLS
;
;
;		 PAGE SIX RAM ASSIGNMENTS
;
; PAGE SIX IS RESERVED AS A USER'S USER WORK SPACE
;
;
;
;
;		 FLOATING POINT SUBROUTINES
;
FPREC	equ $06				;FLOATING PT PRECISION (# OF BYTES)
							; IF CARRY USED THEN CARRY CLEAR => NO ERROR, CARR
AFP		equ $D800			;ASCII->FLOATING POINT(FP)
							; INBUFF+CIX -> FR0, CIX, CARRY
FASC	equ $D8E6			;FP -> ASCII FR0 -> LBUFF (INBUFF)
IFP		equ $D9AA			;INTEGER -> FP
							; 0-$FFFF (LSB,MSB) IN FR0,FR0+1->FR0
FPI		equ $D9D2			;FP -> INTEGER FR0 -> FR0,FR0+1, CARRY
FSUB	equ $DA60			;FR0 <- FR0 - FR1 ,CARRY
FADD	equ $DA66			;FR0 <- FR0 + FR1 ,CARRY
FMUL	equ $DADB			;FR0 <- FR0 * FR1 ,CARRY
FDIV	equ $DB28			;FR0 <- FR0 / FR1 ,CARRY
FLD0R	equ $DD89			;FLOATING LOAD REG0	FR0  <- (X,Y)
FLD0P	equ $DD80			;	"		"	 "	  FR0  <- (FLFTR)
FLD1R	equ $DD98			;	"		"	REG1	FR1  <- (X,Y)
FLD1P	equ $DD9C			;	"		"	 "	  FR1  <- (FLPTR)
FSTOR	equ $DDA7			;FLOATING STORE REG0 (X,Y) <- FR0
FSTOP	equ $DDAB			;	 "	  "	 " (FLPTR)  <- FR0
FMOVE	equ $DDB6			;FR1 <- FR0
PLYEVL	equ $DD40			;FR0 <- P(Z) = SUM(I=N TO 0) (A(I)*Z**I) CAR
							; INPUT:  (X,Y) = A(N),A(N-1)...A(0) -> PLYARG
							;         ACC	= # OF COEFFICIENTS = DEGREE+1
							;         FR0	= Z
EXP		equ $DDC0			;FR0 <- E**FR0 = EXP10(FR0 * LOG10(E)) CARRY
EXP10	equ $DDCC			;FR0 <- 10**FR0 CARRY
LOG		equ $DECD			;FR0 <- LN(FR0) = LOG10(FR0)/LOG10(E) CARRY
LOG10	equ $DED1			;FR0 <- LOG10 (FR0) CARRY
; THE FOLLOWING ARE IN BASIC CARTRIDGE:
SIN		equ $BDB1			;FR0 <- SIN(FR0) DEGFLG=0 =>RADS, 6=>DEG. CA
COS		equ $BD73			;FR0 <- COS(FR0) CARRY
ATAN	equ $BE43			;FR0 <- ATAN(FR0) CARRY
SQR		equ $BEB1			;FR0 <- SQUAREROOT(FR0) CARRY
; FLOATING POINT ROUTINES ZERO PAGE (NEEDED ONLY IF V.P. ROUTINES ARE CA
FR0		equ $d4				;FP REG0
FRE		equ $da
FR1		equ $e0				;FP REG1
FR2		equ $e6
FRX		equ $ec				;FP SPARE
EEXP	equ $ed				;VALUE OF E
NSIGN 	equ $ee				;SIGN OF #
ESIGN 	equ $ef				;SIGN OF EXPONENT
FCHRFLG	equ $f0				;1ST CHAR FLAG
DIGRT 	equ $f1				;# OF DIGITS RIGHT OF DECIMAL
CIX		equ $f2				;CURRENT INPUT INDEX
INBUFF	equ $f3				;POINTS TO USER'S LINE INPUT BUFFER
ZTEMP1	equ $f5
ZIEMP4	equ $f7
ZTEMP3	equ $f9
DEGFLG	equ $fb
RADFLG	equ $fb				;0=RADIANS, 6=DEGREES
RADON	equ $00				;INDICATES RADIANS
DEGON	equ $06				;INDICATES DEGREES
FLPTR	equ $fc			;POINTS TO USER'S FLOATING PT NUMBER
FPTR2	equ $fe
; FLOATING PT ROUTINES' NON-ZERO PAGE RAM
; (NEEDED ONLY IF F.P. ROUTINES CALLED)
LBPR1	equ $057E			;LBUFF PREFIX 1
LBPR2	equ $057F			;LBUFF PREFIX 2
LBUFF	equ $0580			;LINE BUFFER 128-bytes
PLYARG	equ LBUFF+$60		;POLYNOMIAL ARGUMENTS
FPSCR	equ PLYARG+FPREC
FPSCR1	equ FPSCR+FPREC
FSCR	equ FPSCR
FSCR1	equ FPSCR1
LBFEND	equ $05FF			;END OF LBUFF
;
;
;
;
;
;
;
;
;
;		 COLLEEN MNEMONICS
;
POKEY	equ $D200			;VBLANK ACTION:			  DESCRIPTION:
POT0	equ POKEY+0			;POT0-->PADDL0			  0-227 IN RAM CELL
POT1	equ POKEY+1			;POT1-->PADDL1			  0-227 IN RAM CELL
POT2	equ POKEY+2			;POT2-->PADDL2			  0-227 IN RAM CELL
POT3	equ POKEY+3			;POT3-->PADDL3			  0-227 IN RAM CELL
POT4	equ POKEY+4			;POT4-->PADDL4			  0-227 IN RAM CELL
POT5	equ POKEY+5			;POT5-->PADDL5			  0-227 IN RAM CELL
POT6	equ POKEY+6			;POT6-->PADDL6			  0-227 IN RAM CELL
POT7	equ POKEY+7			;POT7-->PADDL7			  0-227 IN RAM CELL
ALLPOT	equ POKEY+8			;???
KBCODE	equ POKEY+9
RANDOM	equ POKEY+10
POTGO	equ POKEY+11		;STROBED
SERIN	equ POKEY+13
IRQST	equ POKEY+14
SKSTAT	equ POKEY+15
AUDF1	equ POKEY+0
AUDC1	equ POKEY+1
AUDF2	equ POKEY+2
AUDC2	equ POKEY+3
AUDF3	equ POKEY+4
AUDC3	equ POKEY+5
AUDF4	equ POKEY+6
AUDC4	equ POKEY+7
AUDCTL	equ POKEY+8			;NONE					 AUDCTL<--[SIO]
STIMER	equ POKEY+9
SKRES	equ POKEY+10		;NONE					  SKRES<--[SIO]
SEROUT	equ POKEY+13		;NONE					 SEROUT<--[SIO]
IRQEN	equ POKEY+14		;POKMSK-->IRQEN (AFFECTED BY OPEN S: OR E:)
SKCTL	equ POKEY+15		;SSKCTL-->SKCTL		SSKCTL<--[SIO]
;
CTIA	equ $D000			;VBLANK ACTION:		 DESCRIPTION:
HPOSP0	equ CTIA+0
HPOSP1	equ CTIA+1
HPOSP2	equ CTIA+2
HPOSP3	equ CTIA+3
HPOSM0	equ CTIA+4
HPOSM1	equ CTIA+5
HPOSM2	equ CTIA+6
HPOSM3	equ CTIA+7
SIZEP0	equ CTIA+8
SIZEP1	equ CTIA+9
SIZEP2	equ CTIA+10
SIZEP3	equ CTIA+11
SIZEM	equ CTIA+12
GRAFP0	equ CTIA+13
GRAFP1	equ CTIA+14
GRAFP2	equ CTIA+15
GRAFP3	equ CTIA+16
GRAFM	equ CTIA+17
COLPM0	equ CTIA+18			;PCOLR0-->COLPM0		WITH ATTRACT MODE
COLPM1	equ CTIA+19			;PCOLR1-->COLPM1		WITH ATTRACT MODE
COLPM2	equ CTIA+20			;PCOLR2-->COLPM2		WITH ATTRACT MODE
COLPM3	equ CTIA+21			;PCOLR3-->COLPM3		WITH ATTRACT MODE
COLPF0	equ CTIA+22			;COLOR0-->COLPF0		WITH ATTRACT MODE
COLPF1	equ CTIA+23			;COLOR1-->COLPF1		WITH ATTRACT MODE
COLPF2	equ CTIA+24			;COLOR2-->COLPF2		WITH ATTRACT MODE
COLPF3	equ CTIA+25			;COLOR3-->COLPF3		WITH ATTRACT MODE
COLBK	equ CTIA+26			;COLOR4-->COLBK		 WITH ATTRACT MODE
PRIOR	equ CTIA+27			;(ON OPEN S: OR E:)	GPRIOR-->PRIOR
VDELAY	equ CTIA+28
GRACTL	equ CTIA+29
HITCLR	equ CTIA+30
CONSOL	equ CTIA+31			;$08-->CONSOL			TURN OFF SPEAKER
M0PF	equ CTIA+0
M1PF	equ CTIA+1
M2PF	equ CTIA+2
M3PF	equ CTIA+3
P0PF	equ CTIA+4
P1PF	equ CTIA+5
P2PF	equ CTIA+8
P3PF	equ CTIA+7
M0PL	equ CTIA+8
M1PL	equ CTIA+9
M2PL	equ CTIA+10
M3PL	equ CTIA+11
P0PL	equ CTIA+12
P1PL	equ CTIA+13
P2PL	equ CTIA+14
P3PL	equ CTIA+15
TRIG0	equ CTIA+16			;TRIG0-->STRIG0
TRIG1	equ CTIA+17			;TRIG1-->STRIG1
TRIG2	equ CTIA+18			;TRIG2-->STRIG2
TRIG3	equ CTIA+19			;TRIG3-->STRIG3
;
ANTIC	equ $D400			;VBLANK ACTION		  DESCRIPTION
DMACTL	equ ANTIC+0			;DMACTL<--SDMCTL		ON OPEN S: OR E:
CHACTL	equ ANTIC+1			;CHACTL<--CHACT		 ON OPEN S: OR E:
DLISTL	equ ANTIC+2			;DLISTL<--SDLSTL		ON OPEN S: OR E:
DLISTH	equ ANTIC+3			;DLISTH<--SDLSTH		ON OPEN S: OR E:
NSCROL	equ ANTIC+4
VSCROL	equ ANTIC+5
PMBASE	equ ANTIC+7
CHBASE	equ ANTIC+9			;CHBASE<--CHBAS		 ON OPEN S: OR E:
WSYNC	equ ANTIC+10
VCOUNT	equ ANTIC+11
PENH	equ ANTIC+12
PENV	equ ANTIC+13
NMIEN	equ ANTIC+14		;NMIEN<--40 POWER	  ON AND [SETVBV]
NMIRES	equ ANTIC+15		;STROBED
NMIST	equ ANTIC+15
PIA		equ $D300			;VBLANK ACTION		  DESCRIPTION
PORTA	equ PIA+0			;PORTA-->STICK0,1	  X-Y CONTROLLERS
PORTB	equ PIA+1			;PORTB-->STICK2,3	  X-Y CONTROLLERS
PACTL	equ PIA+2			;NONE					  PACTL<--3C [INIT]
PBCTL	equ PIA+3			;NONE					  PBCTL<--3C [INIT]
;
;
; Character Set
;
	org CHRORG				; $E000
	dta b($00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$18,$18,$00,$18,$00)
	dta b($00,$66,$66,$66,$00,$00,$00,$00,$00,$66,$FF,$66,$66,$FF,$66,$00)
	dta b($18,$3E,$60,$3C,$06,$7C,$18,$00,$00,$66,$6C,$18,$30,$66,$46,$00)
	dta b($1C,$36,$1C,$38,$6F,$66,$3B,$00,$00,$18,$18,$18,$00,$00,$00,$00)
	dta b($00,$0E,$1C,$18,$18,$1C,$0E,$00,$00,$70,$38,$18,$18,$38,$70,$00)
	dta b($00,$66,$3C,$FF,$3C,$66,$00,$00,$00,$18,$18,$7E,$18,$18,$00,$00)
	dta b($00,$00,$00,$00,$00,$18,$18,$30,$00,$00,$00,$7E,$00,$00,$00,$00)
	dta b($00,$00,$00,$00,$00,$18,$18,$00,$00,$06,$0C,$18,$30,$60,$40,$00)
	dta b($00,$3C,$66,$6E,$76,$66,$3C,$00,$00,$18,$38,$18,$18,$18,$7E,$00)
	dta b($00,$3C,$66,$0C,$18,$30,$7E,$00,$00,$7E,$0C,$18,$0C,$66,$3C,$00)
	dta b($00,$0C,$1C,$3C,$6C,$7E,$0C,$00,$00,$7E,$60,$7C,$06,$66,$3C,$00)
	dta b($00,$3C,$60,$7C,$66,$66,$3C,$00,$00,$7E,$06,$0C,$18,$30,$30,$00)
	dta b($00,$3C,$66,$3C,$66,$66,$3C,$00,$00,$3C,$66,$3E,$06,$0C,$38,$00)
	dta b($00,$00,$18,$18,$00,$18,$18,$00,$00,$00,$18,$18,$00,$18,$18,$30)
	dta b($06,$0C,$18,$30,$18,$0C,$06,$00,$00,$00,$7E,$00,$00,$7E,$00,$00)
	dta b($60,$30,$18,$0C,$18,$30,$60,$00,$00,$3C,$66,$0C,$18,$00,$18,$00)
	dta b($00,$3C,$66,$6E,$6E,$60,$3E,$00,$00,$18,$3C,$66,$66,$7E,$66,$00)
	dta b($00,$7C,$66,$7C,$66,$66,$7C,$00,$00,$3C,$66,$60,$60,$66,$3C,$00)
	dta b($00,$78,$6C,$66,$66,$6C,$78,$00,$00,$7E,$60,$7C,$60,$60,$7E,$00)
	dta b($00,$7E,$60,$7C,$60,$60,$60,$00,$00,$3E,$60,$60,$6E,$66,$3E,$00)
	dta b($00,$66,$66,$7E,$66,$66,$66,$00,$00,$7E,$18,$18,$18,$18,$7E,$00)
	dta b($00,$06,$06,$06,$06,$66,$3C,$00,$00,$66,$6C,$78,$78,$6C,$66,$00)
	dta b($00,$60,$60,$60,$60,$60,$7E,$00,$00,$63,$77,$7F,$6B,$63,$63,$00)
	dta b($00,$66,$76,$7E,$7E,$6E,$66,$00,$00,$3C,$66,$66,$66,$66,$3C,$00)
	dta b($00,$7C,$66,$66,$7C,$60,$60,$00,$00,$3C,$66,$66,$66,$6C,$36,$00)
	dta b($00,$7C,$66,$66,$7C,$6C,$66,$00,$00,$3C,$60,$3C,$06,$06,$3C,$00)
	dta b($00,$7E,$18,$18,$18,$18,$18,$00,$00,$66,$66,$66,$66,$66,$7E,$00)
	dta b($00,$66,$66,$66,$66,$3C,$18,$00,$00,$63,$63,$6B,$7F,$77,$63,$00)
	dta b($00,$66,$66,$3C,$3C,$66,$66,$00,$00,$66,$66,$3C,$18,$18,$18,$00)
	dta b($00,$7E,$0C,$18,$30,$60,$7E,$00,$00,$1E,$18,$18,$18,$18,$1E,$00)
	dta b($00,$40,$60,$30,$18,$0C,$06,$00,$00,$78,$18,$18,$18,$18,$78,$00)
	dta b($00,$08,$1C,$36,$63,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00)
	dta b($00,$36,$7F,$7F,$3E,$1C,$08,$00,$18,$18,$18,$1F,$1F,$18,$18,$18)
	dta b($03,$03,$03,$03,$03,$03,$03,$03,$18,$18,$18,$F8,$F8,$00,$00,$00)
	dta b($18,$18,$18,$F8,$F8,$18,$18,$18,$00,$00,$00,$F8,$F8,$18,$18,$18)
	dta b($03,$07,$0E,$1C,$38,$70,$E0,$C0,$C0,$E0,$70,$38,$1C,$0E,$07,$03)
	dta b($01,$03,$07,$0F,$1F,$3F,$7F,$FF,$00,$00,$00,$00,$0F,$0F,$0F,$0F)
	dta b($80,$C0,$E0,$F0,$F8,$FC,$FE,$FF,$0F,$0F,$0F,$0F,$00,$00,$00,$00)
	dta b($F0,$F0,$F0,$F0,$00,$00,$00,$00,$FF,$FF,$00,$00,$00,$00,$00,$00)
	dta b($00,$00,$00,$00,$00,$00,$FF,$FF,$00,$00,$00,$00,$F0,$F0,$F0,$F0)
	dta b($00,$1C,$1C,$77,$77,$08,$1C,$00,$00,$00,$00,$1F,$1F,$18,$18,$18)
	dta b($00,$00,$00,$FF,$FF,$00,$00,$00,$18,$18,$18,$FF,$FF,$18,$18,$18)
	dta b($00,$00,$3C,$7E,$7E,$7E,$3C,$00,$00,$00,$00,$00,$FF,$FF,$FF,$FF)
	dta b($C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$00,$00,$00,$FF,$FF,$18,$18,$18)
	dta b($18,$18,$18,$FF,$FF,$00,$00,$00,$F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0)
	dta b($18,$18,$18,$1F,$1F,$00,$00,$00,$78,$60,$78,$60,$7E,$18,$1E,$00)
	dta b($00,$18,$3C,$7E,$18,$18,$18,$00,$00,$18,$18,$18,$7E,$3C,$18,$00)
	dta b($00,$18,$30,$7E,$30,$18,$00,$00,$00,$18,$0C,$7E,$0C,$18,$00,$00)
	dta b($00,$18,$3C,$7E,$7E,$3C,$18,$00,$00,$00,$3C,$06,$3E,$66,$3E,$00)
	dta b($00,$60,$60,$7C,$66,$66,$7C,$00,$00,$00,$3C,$60,$60,$60,$3C,$00)
	dta b($00,$06,$06,$3E,$66,$66,$3E,$00,$00,$00,$3C,$66,$7E,$60,$3C,$00)
	dta b($00,$0E,$18,$3E,$18,$18,$18,$00,$00,$00,$3E,$66,$66,$3E,$06,$7C)
	dta b($00,$60,$60,$7C,$66,$66,$66,$00,$00,$18,$00,$38,$18,$18,$3C,$00)
	dta b($00,$06,$00,$06,$06,$06,$06,$3C,$00,$60,$60,$6C,$78,$6C,$66,$00)
	dta b($00,$38,$18,$18,$18,$18,$3C,$00,$00,$00,$66,$7F,$7F,$6B,$63,$00)
	dta b($00,$00,$7C,$66,$66,$66,$66,$00,$00,$00,$3C,$66,$66,$66,$3C,$00)
	dta b($00,$00,$7C,$66,$66,$7C,$60,$60,$00,$00,$3E,$66,$66,$3E,$06,$06)
	dta b($00,$00,$7C,$66,$60,$60,$60,$00,$00,$00,$3E,$60,$3C,$06,$7C,$00)
	dta b($00,$18,$7E,$18,$18,$18,$0E,$00,$00,$00,$66,$66,$66,$66,$3E,$00)
	dta b($00,$00,$66,$66,$66,$3C,$18,$00,$00,$00,$63,$6B,$7F,$3E,$36,$00)
	dta b($00,$00,$66,$3C,$18,$3C,$66,$00,$00,$00,$66,$66,$66,$3E,$0C,$78)
	dta b($00,$00,$7E,$0C,$18,$30,$7E,$00,$00,$18,$3C,$7E,$7E,$18,$3C,$00)
	dta b($18,$18,$18,$18,$18,$18,$18,$18,$00,$7E,$78,$7C,$6E,$66,$06,$00)
	dta b($08,$18,$38,$78,$38,$18,$08,$00,$10,$18,$1C,$1E,$1C,$18,$10,$00)
;
;
; Vector Table
;
;	org VECTBL
;
	org EDITRV				; $E400
;
; SCREEN EDITOR HANDLER ENTRY POINT
;
EDITOR
	dta a(EOPEN-1)
	dta a(RETUR1-1)			;(CLOSE)
	dta a(EGETCH-1)
	dta a(EOUTCH-1)
	dta a(RETUR1-1)			;(STATUS)
	dta a(NOFUNC-1)			;(SPECIAL)
	jmp PWRONA
 ift PALFLG
	dta b($60)				; PAL Checksum Byte 1
 els
	dta b($9F)				; NTSC Checksum Byte 1
 eif
;
;
	org SCRENV				; $E410
;
; DISPLAY HANDLER ENTRY POINT
;
DISPLA
	dta a(DOPEN-1)
	dta a(RETUR1-1)			;(CLOSE)
	dta a(GETCH-1)
	dta a(OUTCH-1)
	dta a(RETUR1-1)			;(STATUS)
	dta a(DRAW-1)			;(SPECIAL)
	jmp PWRONA
 ift PALFLG
	dta b($ED)				; PAL Checksum Byte 1
 els
	dta b($EC)				; NTSC Checksum Byte 2
 eif
;
;
; KEYBOARD HANDLER ENTRY POINT
;
KBDHND
	dta a(RETUR1-1)
	dta a(RETUR1-1)			;(CLOSE)
	dta a(KGETCH-1)
	dta a(NOFUNC-1)			;(OUTCH)
	dta a(RETUR1-1)			;(STATUS)
	dta a(NOFUNC-1)			;(SPECIAL)
	jmp PWRONA
	dta b($00)				;ROM FILLER BYTE
;
;
;		 PRINTER HANDLER ENTRY POINTS
;
	org PRINTV				; $E430
;
	dta a(PHOPEN-1)			;PRINTER HANDLER OPEN
	dta a(PHCLOS-1)			;PH CLOSE
	dta a(BADST-1)			;PH READ
	dta a(PHWRIT-1)			;PH WRITE
	dta a(PHSTAT-1)			;PH STATUS
	dta a(BADST-1)			;PH SPECIAL
	jmp PHINIT				;PH INIT
	dta b(0)				;ROM FILLER
;
;
	org CASETV				; $E440
;
	dta a(OPENC-1,CLOSEC-1,GBYTE-1,PBYTE-1,STATU-1,SPECIAL-1)
;
	jmp INIT
	dta b(0)				;ROM FILLER BYTE
;
;

;
;		 VECTORS
;
	org DISKIV				; $E450
;
	jmp DINIT				;DISK INIT. VECTOR
;
	org DSKINV				; $E453
;
	jmp DSKIF				;DISK INTERFACE ENTRY POINT
;
;
;	'CENTRAL INPUT/OUTPUT (CIO) 2-7-79'
;					UPDATED BY AL MILLER 3-9-79
ASCZER	equ '0'				;ASCII ZERO
COLON	equ $3A				;ASCII COLON
EOL		equ $9B				;END OF RECORD
;
; CIO JUMP VECTOR FOR USERS
	org CIOV				; $E456
	jmp CIO					;GO TO CIO
;
;		 SIO
;
;
	org SIOV				; $E459
	jmp SIO					;SIO ENTRY POINT
;
;
; THIS IS TO MAKE DOS 2 WORK WHICH USED AN ABSOLUTE ADDRESS
;
	org SETVBV				; $E45C
	jmp SETVBL
	jmp SYSVBL
	jmp XITVBL
;
	org SIOINV				; $E465
	jmp SIOINT				;SIO INITIALIZATION ENTRY POINT
;
	org SENDEV				; $E468
	jmp SENDEN				;SEND ENABLE ENTRY POINT
;
	org INTINV				; $E46B
	jmp IHINIT
;
;
; CIO INIT JUMP VECTOR FOR POWER UP
	org CIOINV				; $E46E
	jmp CIOINT				;GO TO INIT
;
;
;
;		 ENTRY POINT VECTOR
;
	org BLKBDV				; $E471
;
	jmp SIGNON				;BLACK BOARD VECTOR
;
	org WARMSV				; $E474
;
	jmp RESET				;WARM START VECTOR
;
	org COLDSV				; $E477
;
	jmp PWRUP				;COLD START VECTOR (9000 FOR RAM VECTOR WRIT
;
;
;
; USED IN MONITP FOR CASSETTE BOOT
;
	org RBLOKV				; $E47A
	jmp RBLOK
;
	org CSOPIV				; $E47D
	jmp OPINP
;
;
; RAM Vector Init Table
	org VCTABL				; $E480
;
	org VCTABL+INTABS-VDSLST
	dta a(SYRTI)			;VDSLST
	dta a(SYIRQB)			;VPRCED
	dta a(SYIRQB)			;VINTER
	dta a(SYIRQB)			;VBREAK
;
; INTERRUPT VECTOR TABLE ENTRY
	org VCTABL-INTABS+VKEYBD
	dta a(PIRQ5)			;KEYBOARD IRQ INTERRUPT VECTOR
;
	org VCTABL-INTABS+VSERIN
	dta a(ISRSIR)			;VSERIN
	dta a(ISRODN)			;VSEROR
	dta a(ISRTD)			;VSEROC
;
	dta a(SYIRQB)			;VTMIR1
	dta a(SYIRQB)			;VTIMR2
	dta a(SYIRQB)			;VTMIR4
	dta a(SYIRQ)			;VIMIRQ
	dta a(0,0,0,0,0)		;CDTMV1-4
	dta a(SYSVBL)			;VVBLKI
	dta a(XITVBL)			;VVSLKD
;
;
; ERROR ROUTINE ADDRESS EQUATE
;
;
	org CIOORG				; $E4A6
;
; CIO INITIALIZATION (CALLED BY MONITOR AT POWER UP)
CIOINT
	ldx #0
CIOI1
 	lda #IOCFRE				;SET ALL IOCB'S TO FREE
	sta ICHID,X				;BY SETTING HANDLER ID'S=$FF
	lda #<ERRTN
	sta ICPTL,X				;POINT PUT TO ERROR ROUTINE
	lda #>ERRTN
	sta ICPTH,X
	txa
	clc
	adc #IOCBSZ				;BUMP INDEX BY SIZE
	tax
	cmp #MAXIOC				;DONE?
	bcc CIOI1				;NO
	rts						;YES, RETURN
;
; ERROR ROUTINE FOR ILLEGAL PUT
ERRTN	equ *-1
	ldy #NOTOPN				;IOCB NOT OPEN
	rts
;
; CIO LOCAL RAM (USES SPARE BYTES IN ZERO PAGE IOCB)
ENTVEC	equ ICSPRZ
;
; CIO MAIN ROUTINE
;
; CIO INTERFACES BETWEEN USER AND INPUT/OUTPUT DE
CIO
	sta CIOCHR				;SAVE POSSIBLE OUTPUT CHARACTER
	stx ICIDNO				;SAVE IOCB NUMBER * N
;
; CHECK FOR LEGAL IOCB
	txa
	and #$0F				;IS IOCB MULTIPLE OF 16?
	bne CIERR1				; NO, ERROR
	cpx #MAXIOC				;IS INDEX TOO LARGE?
	bcc IOC1				; NO
;
; INVALID IOCB NUMBER -- RETURN ERROR
CIERR1
	ldy #BADIOC				;ERROR CODE
	jmp CIRTN1				;RETURN
;
; MOVE USER IOCB TO ZERO PAGE
IOC1
	ldy #0
IOC1A
 	lda IOCB,X				;USER IOCB
	sta IOCBAS,Y			;TO ZERO PAGE
	inx
	iny
	cpy #12					;12 BYTES
	bcc IOC1A
;
; COMPUTE CIO INTERNAL VECTOR FOR COMMAND
	ldy #NVALID				;ASSUME INVALID CODE
	lda ICCOMZ				;COMMAND CODE TO INDEX
	cmp #OPEN				;IS COMMAND LEGAL?
	bcc CIERR4				; NO
	tay
;
; MOVE COMMAND TO ZERO BASE FOR INDEX
	cpy #SPECIL				;IS COMMAND SPECIAL?
	bcc IOC2				; NO
	ldy #SPECIL				; YES, SET SPECIAL OFFSET INDEX
IOC2
	sty ICCOMT				;SAVE COMMAND FOR VECTOR
	lda COMTAB-3,Y			;GET VECTOR OFFSET FROM TABLE
	beq CIOPEN				;GO IF OPEN COMMAND
	cmp #2					;IS IT CLOSE?
	beq CICLOS				; YES
	cmp #8					;IS IT STATUS OR SPECIAL?
	bcs CISTSP				; YES
	cmp #4					;IS IT READ?
	beq CIREAD				; YES
	jmp CIWRIT				;ELSE, MUST BE WRITE
;
; OPEN COMMAND
;
; FIND DEVICE HANDLER IN HANDLER ADDRESS TABLE
CIOPEN
	lda ICHIDZ				;GET HANDLER ID
	cmp #IOCFRE				;IS THIS IOCB CLOSED?
	beq IOC6				;YES
;
; ERROR -- IOCB ALREADY OPEN
CIERR3
	ldy #PRVOPN				;ERROR CODE
CIERR4
	jmp CIRTN1				;RETURN
;
; GO FIND DEVICE
IOC6
	jsr DEVSRC				;CALL DEVICE SEARCH
	bcs CIERR4				;GO IF DEVICE NOT FOUND
;
; DEVICE FOUND, INITIALIZE IOCB FOR OPEN
;
; COMPUTE HANDLER ENTRY POINT
IOC7
	jsr COMENT
	bcs CIERR4				;GO IF ERROR IN COMPUTE
;
; GO TO HANDLER FOR INITIALIZATION
	jsr GOHAND				;USE INDIRECT JUMP
;
; STORE PUT BYTE ADDRESS-1 INTO IOCB
	lda #PUTCHR				;SIMULATE PUT CHARACTER
	sta ICCOMT
	jsr COMENT				;COMPUTE ENTRY POINT
	lda ICSPRZ				;MOVE COMPUTED VALUE
	sta ICPTLZ				;TO PUT BYTE ADDRESS
	lda ICSPRZ+1
	sta ICPTHZ
	jmp CIRTN2				;RETURN TO USER
;
;
; CLOSE COMMAND
CICLOS
	ldy #SUCCES				;ASSUME GOOD CLOSE
	sty ICSTAZ
	jsr COMENT				;COMPUTE HANDLER ENTRY POINT
	bcs CICLO2				;GO IF ERROR IN COMPUTE
	jsr GOHAND				;GO TO HANDLER TO CLOSE DEVICE
CICLO2
	lda #IOCFRE				;GET IOCB "FREE" VALUE
	sta ICHIDZ				;SET HANDLER ID
	lda #>ERRTN
	sta ICPTHZ				;SET PUT BYTE TO POINT TO ERROR
	lda #<ERRTN
	sta ICPTLZ
	jmp CIRTN2				;RETURN
;
;
; STATUS AND SPECIAL REQUESTS
; DO IMPLIED OPEN IF NECESSARY AND GO TO DEVICE
CISTSP
	lda ICHIDZ				;IS THERE A HANDLER ID?
	cmp #IOCFRE
	bne CIST1				; YES
;
; IOCB IS FREE, DO IMPLIED OPEN
	jsr DEVSRC				;FIND DEVICE IN TABLE
	bcs CIERR4				;GO IF ERROR IN COMPUTE
;
; COMPUTE AND GO TO ENTRY POINT IN HANDLER
CIST1
 	jsr COMENT				;COMPUTER HANDLER ENTRY VECTOR
	jsr GOHAND				;GO TO HANDLER
;
; RESTORE HANDLER INDEX (DO IMPLIED CLOSE)
	ldx ICIDNO				;IOCB INDEX
	lda ICHID,X				;GET ORIGINAL HANDLER ID
	sta ICHIDZ				;RESTORE ZERO PAGE
	jmp CIRTN2				;RETURN
;
; READ -- DO GET COMMANDS
CIREAD
	lda ICCOMZ				;GET COMMAND BYTE
	and ICAX1Z				;IS THIS READ LEGAL?
	bne RCI1A				; YES
;
; ILLEGAL READ -- IOCB OPENED FOR WRITE ONLY
	ldy #WRONLY				;ERROR CODE
RCI1B
 	jmp CIRTN1				;RETURN
;
; COMPUTE AND CHECK ENTRY POINT
RCI1A
 	jsr COMENT				;COMPUTE ENTRY POINT
	bcs RCI1B				;GO IF ERROR IN COMPUTE
;
; GET RECORD OR CHARACTERS
	lda ICBLLZ
	ora ICBLLZ+1			;IS BUFFER LENGTH ZERO?
	bne RCI3				; NO
	jsr GOHAND
	sta CIOCHR
	jmp CIRTN2
;
; LOOP TO FILL BUFFER OR END RECORD
RCI3
	jsr GOHAND				;GO TO HANDLER TO GET BYTE
	sta CIOCHR				;SAVE BYTE
	bmi RCI4				;END TRANSFER IF ERROR
	ldy #0
	sta (ICBALZ),Y			;PUT BYTE IN USER BUFFER
	jsr INCBFP				;INCREMENT BUFFER POINTER
	lda ICCOMZ				;GET COMMAND CODE
	and #2					;IS IT GET RECORD?
	bne RCI1				; NO
;
; CHECK FOR EOL ON TEXT RECORDS
	lda CIOCHR				;GET BYTE
	cmp #EOL				;IS IT AN EOL?
	bne RCI1				; NO
	jsr DECBFL				; YES, DECREMENT BUFFER LENGTH
	jmp RCI4				;END TRANSFER
;
; CHECK BUFFER FULL
RCI1
	jsr DECBFL				;DECREMENT BUFFER LENGTH
	bne RCI3				;CONTINUE IF NON ZERO
;
; BUFFER FULL. RECORD NOT ENDED
; DISCARD BYTES UNTIL END OF RECORD
RCI2
	lda ICCOMZ				;GET COMMAND BYTE
	and #2					;IS IT GET CHARACTER?
	bne RCI4				; YES, END TRANSFER
;
; LOOP TO WAIT FOR EOL
RCI6
	jsr GOHAND				;GET BYTE FROM HANDLER
	sta CIOCHR				;SAVE CHARACtER
	bmi RCI4				;GO IF ERROR
;
; TEXT RECORD. WAIT FOR EOL
	lda CIOCHR				;GET GOT BYTE
	cmp #EOL				;IS IT EOL?
	bne RCI6				;NO, CONTINUE
;
; END OF RECORD. BUFFER FULL -- SEND TRUNCATED RECORD MESSAGE
RCI1I
 	lda #TRNRCD				;ERROR CODE
	sta ICSTAZ				;STORE IN 10GB
;
; TRANSFER DONE
RCI4
	jsr SUBBFL				;SET FINAL BUFFER LENGTH
	jmp CIRTN2				;RETURN
;
; WRITE -- DO PUT COMMANDS
CIWRIT
	lda ICCOMZ				;GET COMMAND BYTE
	and ICAX1Z				;IS THIS WRITE LEGAL?
	bne WCIIA				; YES
;
; ILLEGAL WRITE -- DEVICE OPENED FOR READ ONLY
	ldy #RDONLY				;ERROR CODE
WCI1B
 	jmp CIRTN1				;RETURN
;
;  COMPUTE AND CHECK ENTRY POINT
WCIIA
 	jsr COMENT				;COMPUTE HANDLER ENTRY POINT
	bcs WCI1B				;GO IF ERROR IN COMPUTE
;
; PUT RECORD OR CHARACTERS
	lda ICBLLZ
	ora ICBLLZ+1			;IS BUFFER LENGTH ZERO?
	bne WCI3				; NO
	lda CIOCHR				;GET CHARACTER
	inc ICBLLZ				;SET SUFFER LENOTHI
	bne WCI4				;THEN JUST TRANSFER ONE BYTE
;
; LOOP TO TRANSFER BYTES FROM BUFFER TO HANDLER
WCI3
	ldy #0
	lda (ICBALZ),Y			;GET BYTE FROM BUFFER
	sta CIOCHR				;SAVE
WCI4
	jsr GOHAND				;GO PUT BYTE
	bmi WCI5				;END IF ERROR
	jsr INCBFP				;INCREMENT BUFFER POINTER
;
; CHECK FOR TEXT RECORD
	lda ICCOMZ				;GET COMMAND BYTE
	and #2					;IS IT PUT RECORD?
	bne WCI1				; NO
;
; TEXT RECORD -- CHECK FOR EOL TRANSFER
	lda CIOCHR				;GET LAST CHARACTER
	cmp #EOL				;IS IT AN EOL?
	bne WCI1				; NO
	jsr DECBFL				;DECREMENT BUFFER LENGTH
	jmp WCI5				;END TRANSFER
;
; CHECK FOR BUFFER EMPTY
WCI1
	jsr DECBFL				;DECREMENT BUFFER LENGTH
	bne WCI3				;CONTINUE IF NON ZERO
;
; BUFFER EMPTY, RECORD NOT FILLED
; CHECK TYPE OF TRANSFER
WCI2
	lda ICCOMZ				;GET COMMAND CODE
	and #2					;IS IT PUT CHARACTER?
	bne WCI5				; YES, END TRANSFER
;
; PUT RECORD (TEXT), BUFFER ,EMPTY, SEND EOL
	lda #EOL
	jsr GOHAND				;GO TO HANDLER
;
; END PUT TRANSFER
WCI5
	jsr SUBBFL				;SET ACTUAL PUT BUFFER LENGTH
	jmp CIRTN2				;RETURN
;
; CIO RETURNS
; RETURNS WITH Y=STATUS
CIRTN1
	sty ICSTAZ				;SAVE STATUS
;
; RETURNS WITH STATUS STORED IN ICSTAZ
; MOVE IOCB IN ZERO PAGE BACK TO USER AREA
CIRTN2
	ldy ICIDNO				;GET IOCB INDEX
	lda ICBAL,Y
	sta ICBALZ				;RESTORE USER BUFFER POINTER
	lda ICBAH,Y
	sta ICBAHZ
	ldx #0					;LOOP COUNT AND INDEX
CIRT3
 	lda IOCBAS,X			;ZERO PAGE
	sta IOCB,Y				;TO USER AREA
	inx
	iny
	cpx #12					;12 BYTES
	bcc CIRT3
;
; RESTORE A,X, & Y
	lda CIOCHR				;GET LAST CHARACTER
	ldx ICIDNO				;IOCB INDEX
	ldy ICSTAZ				;GET STATUS AND SET FLAGS
	rts						;RETURN TO USER
;
;
; CIO SUBROUTINES
;
; COMENT -- CHECK AND COMPUTE HANDLER ENTRY POINT
COMENT
	ldy ICHIDZ				;GET HANDLER INDEX
	cpy #MAXDEV+1			;IS IT A LEGAL INDEX?
	bcc COM1				; YES
;
; ILLEGAL HANDLER INDEX MEANS DEVICE NOT OPEN FOR OPERATION
	ldy #NOTOPN				;ERROR CODE
	bcs COM2				;RETURN
;
; USE HANDLER ADDRESS TABLE AND COMMAND TABLE TO GET VECTOR
COM1
	lda HATABS+1,Y			;GET LOW BYTE OF ADDRESS
	sta ICSPRZ				;AND SAVE IN POINTER
	lda HATABS+2,Y			;GET HI BYTE OF ADDRESS
	sta ICSPRZ+1
	ldy ICCOMT				;GET COMMAND CODE
	lda COMTAB-3,Y			;GET COMMAND OFFSET
	tay
	lda (ICSPRZ),Y			;GET LOW BYTE OF VECTOR FROM
	tax						;HANDLER ITSELF AND SAVE
	iny
	lda (ICSPRZ),Y			;GET HI BYTE OF VECTOR
	sta ICSPRZ+1
	stx ICSPRZ				;SET LO BYTE
	clc						;SHOW NO ERROR
COM2
	rts
;
;
; DECBFL -- DECREMENT BUFFER LENGTH DOUBLE BYTE
; Z FLAG = 0 ON RETURN IF LENGTH = 0 AFTER DECREMENT
DECBFL
	dec ICBLLZ				;DECREMENT LOW BYTE
	lda ICBLLZ				;CHECK IT
	cmp #$FF				;DID IT GO BELOW?
	bne DECBF1				; NO
	dec ICBLLZ+1			;DECREMENT HI BYTE
DECBF1
	ora ICBLLZ+1			;SET Z IF BOTH ARE ZERO
	rts
;
;
; INCBFP -- INCREMENT WORKING BUFFER POINTER
INCBFP
	inc ICBALZ				;BUMP LOW BYTE
	bne INCBF1				;GO IF NOT ZERO
	inc ICBALZ+1			;ELSE, BUMP HI BYTE
INCBF1
	rts
;
;
; SUBBFL -- SET BUFFER LENGTH = BUFFER LENGTH - WORKING BYTE COUNT
SUBBFL
	ldx ICIDNO				;GET IOCB INDEX
	sec
	lda ICBLL,X				;GET LOW BYTE OF INITIAL LENGTH
	sbc ICBLLZ				;SUBTRACT FINAL LOW BYTE
	sta ICBLLZ				;AND SAVE BACK
	lda ICBLH,X				;GET HI BYTE
	sbc ICBLLZ+1
	sta ICBLHZ
	rts
;
;
; GOHAND -- GO INDIRECT TO A DEVICE HANDLER
; Y= STATUS ON RETURN, N FLAG=1 IF ERROR ON RETURN
GOHAND
	ldy #FNCNOT				;PREPARE NO FUNCTION STATUS FOR HANDLER	rts
	jsr CIJUMP				;USE THE INDIRECT JUMP
	sty ICSTAZ				;SAVE STATUS
	cpy #0					;AND SET N FLAG
	rts
;
; INDIRECT JUMP TO HANDLER BY PAUL'S METHOD
CIJUMP
	tax						;SAVE A
	lda ICSPRZ+1			;GET JUMP ADDRESS HI BYTE
	pha						;PUT ON STACK
	lda ICSPRZ				;GET JUMP ADDRESS LO BYTE
	pha						;PUT ON STACK
	txa						;RESTORE A
	ldx ICIDNO				;GET IOCB INDEX
	rts						;GO TO HANDLER INDIRECTLY
;
; DEVSRC -- DEVICE SEARCH, FIND DEVICE IN HANDLER ADDRESS TABLE
;
; LOOP TO FIND DEVICE
DEVSRC
	ldy #0
	lda (ICBALZ),Y			;GET DEVICE NAME FROM USER
	beq CIERR2
	ldy #MAXDEV				;INITIAL COMPARE INDEX
DEVS1
 	cmp HATABS,Y			;IS THIS THE DEVICE?
	beq DEVS2				; YES
	dey
	dey						; ELSE, POINT TO NEXT DEVICE NAME
	dey
	bpl DEVS1				;CONTINUE FOR ALL DEVICES
;
; NO DEVICE FOUND, DECLARE NON-EXISTENT DEVICE ERROR
CIERR2
	ldy #NONDEV				;ERROR CODE
 	sec						;SHOW ERROR
	bcs DEVS4				;AND RETURN
;
; FOUND DEVICE, SET ICHID,ICDNO, AND INIT DEVICE
DEVS2
 	tya
	sta ICHIDZ				;SAVE HANDLER INDEX
	sec
	ldy #1
	lda (ICBALZ),Y			;GET DEVICE NUMBER (DRIVE NUMBER)
	sbc #ASCZER				;SUBTRACT ASCII ZERO
	cmp #$A					;IS NUMBER IN RANGE?
	bcc DEVS3				; YES
	lda #1					; NO. DEFAULT TO ONE
DEVS3
	sta ICDNOZ				;SAVE DEVICE NUMBER
	clc						;SHOW NO ERROR
;
; RETURN
DEVS4
	rts
;
;
; CIO ROM TABLES
;
; COMMAND TABLE
; MAPS EACH COMMAND TO OFFSET FOR APPROPRIATE VECTOR IN HANDLER
COMTAB	dta b(0,4,4,4,4,6,6,6,6,2,8,10)


LENGTH	equ LENGTH-CIOINT
;
;	'INTERRUPT HANDLER'
;LIVES ON DK1:INTHV.SRC
SRTIM2	equ 6				;SECOND REPEAT INTERVAL
;
;
;	org $900C
;
;	lda #>PIRQ				;SET UP RAM VECTORS FOR LINBUG VERSION
;	sta $FFF9
;	lda #<PIRQ
;	sta $FFF8
;	lda #>PNMI
;	sta $FFFB
;	lda #<PNMI
;	sta $FFFA
;	rts
;
; IRQ HANDLER
;
; JUMP THRU IMMEDIATE IRQ VECTOR, WHICH ORDINARILY POINTS TO
; SYSTEM IRQ; DETERMINE & CLEAR CAUSE, JUMP THRU SOFTWARE VECTOR.
;
	org INTORG				; $E6D5
IHINIT
	lda #$40				;VBL ON BUF DLIST OFF***FOR NOW***
	sta NMIEN				;ENABLE DISPLAY LIST, VERTICAL BLANK
	lda #$38				;LOOK AT DATA DIRECTION REGISTERS IN PIA
	sta PACTL
	sta PBCTL
	lda #0					;MAKE ALL INPUTS
	sta PORTA
	sta PORTB
	lda #$3C				;BACK TO PORTS
	sta PACTL
	sta PBCTL
	rts
PIRQ
	jmp (VIMIRU)
CMPTAB
	dta b($80)				;BREAK KEY
	dta b($40)				;KEY STROKE
	dta b($04)				;TIMER 4
	dta b($02)				;TIMER 2
	dta b($01)				;TIMER 1
	dta b($08)				;SERIAL OUT COMPLETE
	dta b($10)				;SERIAL OUT READY
	dta b($20)				;SERIAL IN READY

; THIS IS A TABLE OF OFFSETS INTO PAGE 2.  THEY POINT TO
ADRTAB
	dta b(BRKKY-INTABS)
	dta b(VKEYBD-INTABS)
	dta b(VTIMR4-INTABS)
	dta b(VTIMR2-INTABS)
	dta b(VTIMR1-INTABS)
	dta b(VSEROC-INTABS)
	dta b(VSEROR-INTABS)
	dta b(VSERIN-INTABS)

SYIRQ
 	pha						;SAVE ACCUMULATOR
	lda IRQST				; CHECK FOR SERIAL IN
	and #$20
	bne SYIRQ2
	lda #$DF				; MASK ALL OTHERS
	sta IRQEN
	lda POKMSK
	sta IRQEN
	jmp (VSERIN)
SYIRQ2
	txa						;PUT X INTO ACC
	pha						;SAVE K ONTO STACK
	ldx #$6					;START WITH SIX OFFSET
LOOPM
 	lda CMPTAB,X			;LOAD MASK
	cpx #5					;CHECK TO SEE IF COMPLETE IS SET
	bne LOOPM2
	and POKMSK				;IS THIS INTERUPT ENABLED?
	beq LL
LOOPM2
	bit IRQST				; IS IT THE INTERUPT?
	beq JMPP
LL
	dex						;NO DEC X AND TRY NEXT MASK
	bpl LOOPM				;IF NOT NEC 0010 LOOPH
	jmp SYIRQ8				;DONE BUT NO INTERUPT
JMPP
	eor #$FF				;COMPLEMENT MASK
	sta IRQEN				;ENABLE ALL OTHERS
	lda POKMSK				; GET POKE MASK
	sta IRQEN				; ENABLE THOSE IN POKE MASK
	lda ADRTAB,X
	tax
	lda INTABS,X			; GET ADDRESS LOW PART
	sta JVECK				; PUT IN VECTOR
	lda INTABS+1,X			; GET ADDRESS HIGH PART
	sta JVECK+1				; PUT IN VECTOR HIGH PART
	pla						; PULL X REGISTER FROM STACK
	tax						; PUT IT INTO X
	jmp (JVECK)				; JUMP TO THE PROPER ROUTINE
BRKKY2
	lda #0					; BREAK KEY ROUTINE
	sta BRKKEY				; SET BREAK KEY FLAG
	sta SSFLAG				; START/STOP FLAG
	sta CRSINH				; CURSOR INHIBIT
	sta ATRACT				; TURN OFF ATRACT MODE
	pla
	rti						;EXIT FROM INT
SYIRQ8
	pla
	tax
	bit PACTL				;PROCEED ***I GUESS***
	bpl SYIRQ9
	lda PORTA				;CLEAR INT STATUS BIT
	jmp (VPRCED)
SYIRQ9
	bit PBCTL				;INTERRUPT ***I GUESS***
	bpl SYIRQA
	lda PORTB				;CLEAR INT STATUS
	jmp (VINTER)
SYIRQA
	pla
	sta JVECK
	pla
	pha
	and #$10				;B BIT OF P REGISTER
	beq SYRTI2
	lda JVECK
	pha
	jmp (VBREAK)
SYRTI2
	lda JVECK
	pha
SYIRQB
	pla
SYRTI
	rti						;UNIDENTIFIED INTERRUPT, JUST RETURN
;
; NMI HANDLER
;
; DETERMINE CAUSE AND JUMP THRU VECTOR
;
PNMI
	bit NMIST
	bpl PNMI1				;SEE IF DISPLAY LIST
	jmp (VDSLST)
PNMI1
 	pha
	lda NMIST
	and #$20				;SEE IF RESET
	beq *+5
	jmp WARMSV				;DO THRU WARM START JUMP
	txa						;SAVE REGISTERS
	pha
	tya
	pha
	sta NMIRES				;RESET INTERRUPT STATUS
	jmp (VVBLKI)			;JUMP THRU VECTOR
;
; SYSTEM VBLANK ROUTINE
;
; INC FRAME COUNTER. PROCESS COUNTDOWN TIMERS. EXIT IF I WAS SET. CLEAR
; SET DLISTL, DLISTH, DMACTL FROM RAM CELLS. DO SOFTWARE REPEAT.
;
SYSVBL
	inc RTCLOK+2			;INC FRAME COUNTER
	bne SYSVB1
	inc ATRACT				;INCREMENT ATRACT (CAUSES ATRACT WHEN MINUS)
	inc RTCLOK+1
	bne SYSVB1
	inc RTCLOK
SYSVB1
	lda #$FE				;{ATRACT] SET DARK MASK TO NORMAL
	ldx #0					;SET COLRSH TO NORMAL
	ldy ATRACT				;TEST ATRACT FOR NEGATIVE
	bpl VBATRA				;WHILE POSITIVE DONT GO INTO ATRACT
	sta ATRACT				;IN ATRACTI SO STAY BY STA $FE
	ldx RTCLOK+1			;COLOR SHIFT FOLLOWS RICLOK+1
	lda #$F6				;SET DARK MASK TO DARK
VBATRA
	sta DRKMSK
	stx COLRSH
	ldx #0					;POINT TO TIMER1
	jsr DCTIMR				;GO DECREMENT TIMER1
	bne SYSVB2				;BRANCH IF STILL COUNTING
	jsr JTIMR1				;GO JUMP TO ROUTINE
SYSVB2
	lda CRITIC
	bne XXIT				;GO IF CRITICAL SET
	tsx						;SEE IF I WAS SET
	lda $104,X				;GET STACKED P
	and #$04				;I BIT
	beq SYSVB3				;BRANCH IF OK
XXIT
	jmp XITVBL				;I WAS SET, EXIT
SYSVB3
	lda PENV
	sta LPENV
	lda PENH
	sta LPENH
	lda SDLSTH
	sta DLISTH
	lda SDLSTL
	sta DLISTL
	lda SDMCTL
	sta DMACTL
	lda GPRIOR				;GLOBAL PRIOR
	sta PRIOR
	ldx #$08				;TURN OFF KEYBOARD SPEAKER
	stx CONSOL
SCOLLP
	cli						;DISABLE INTERUPTS
	lda PCOLR0,X			;LOAD COLOR REGISTERS FROMRAM
	eor COLRSH				;DO COLOR SHIFT
	and DRKMSK				;AND DARK ATRACT
	sta COLPM0,X
	dex
	bpl SCOLLP
	lda CHBAS
	sta CHBASE
	lda CHACT
	sta CHACTL
	ldx #2					;POINT TO TIMER 2
	jsr DCTIMR
	bne SYSVB4				;IF DIDNT GO ZERO
	jsr JTIMR2				;GO JUMP TO TIMER2 ROUTINE
SYSVB4
	ldx #2					;RESTORE X
SYSVBB
	inx
	inx
	lda CDTMV1,X
	ora CDTMV1+1,X
	beq SYSVBA
	jsr DCTIMR				;DECREMENT AND SET FLAG IF NONZERO
	sta CDTMF3-4,X
SYSVBA
	cpx #8					;SEE IF DONE ALL 3
	bne SYSVBB				;LOOP
; CHECK DEBOUNCE COUNTER
	lda SKSTAT
	and #$04				;KEY DOWN BIT
	beq SYVB6A				;IF KEY DOWN
; KEY UP SO COUNT IT
	lda KEYDEL				;KEY DELAY COUNTER
	beq SYVB6A				;IF COUNTED DOWN ALREADY
	dec KEYDEL				;COUNT IT
; CHECK SOFTWARE REPEAT TIMER
SYVB6A
	lda SRTIMR
	beq SYSVB7				;DOESN'T COUNT
	lda SKSTAT
	and #$04				;CHECK KEY DOWN BIT
	bne SYSVB6				;BRANCH IF NO LONGER DOWN
	dec SRTIMR				;COUNT FRAME OF KEY DOWN
	bne SYSVB7				;BRANCH IF NOT RUN OUT
; TIMER RAN OUT - RESET AND SIMULATE KEYBOARD IRQ
	lda #SRTIM2				;TIMER VALUE
	sta SRTIMR				;SET TIMER
	lda KBCODE				;GET THE KEY
	sta CH					;PUT INTO CH
; READ GAME CONTROLLERS
SYSVB7
	ldy #1
	ldx #3
STLOOP
	lda PORTA,Y
	lsr @
	lsr @
	lsr @
	lsr @
	sta STICK0,X			;STORE JOYSTICK
	dex
	lda PORTA,Y
	and #$F
	sta STICK0,X			;STORE JOYSTICK
	dex
	dey
	bpl STLOOP
;
	ldx #3
STRL
	lda TRIG0,X				;MOVE JOYSTICK TRIGGERS
	sta STRIG0,X
	lda POT0,X				;MOVE POT VALUES
	sta PADDL0,X
	lda POT4,X
	sta PADDL4,X
	dex
	bpl STRL
	sta POTGO				;START POTS FOR NEXT TIME
;
	ldx #6
	ldy #3
PTRLP
 	lda STICK0,Y			;TRANSFER BITS FROM JOYSTICKS
	lsr @					;TO PADDLE TRIGGERS
	lsr @
	lsr @
	sta PTRIG1,X
	lda #0
	rol @
	sta PTRIG0,X
	dex
	dex
	dey
	bpl PTRLP
;
	jmp (VVBLKD)			;GO TO DEFERRED VBLANK ROUTINE
SYSVB6
	lda #0
	sta SRTIMR				;ZERO TIMER
	beq SYSVB7				;UNCOND
JTIMR1
	jmp (CDTMA1)
JTIMR2
	jmp (CDTMA2)
;
; SUBROUTINE TO DECREMENT A COUNTDOWN TIMER
; ENTRY X=OFFSET FROM TIMER 1
; EXIT A,P=ZERO IF WENT ZERO, FF OTHERWISE
;
DCTIMR
	ldy CDTMV1,X			;LO BYTE
	bne DCTIM1				; NONZERO, GO DEC IT
	ldy CDTMV1+1,X			;SEE IF BOTH ZERO
	beq DCTXF				; YES, EXIT NONZERO
	dec CDTMV1+1,X			;DEC HI BYTE
DCTIM1
	dec CDTMV1,X			;DEC LO BYTE
	bne DCTXF
	ldy CDTMV1+1,X
	bne DCTXF
	lda #0					;WENT ZERO. RETURN ZERO
	rts
DCTXF
 	lda #$FF				;RETURN NONZERO
	rts
;
; SUBROUTINE TO SET VERTICAL BLANK VECTORS AND TIMERS
; ENTRY X=HI,Y=LO BYTE TO SET
;		 A= 1-5 TIMERS 1-5
;			 6 IMM VBLANK
;			 7 DEF VBLANK
;
SETVBL
	asl @					;MUL BY 2
	sta INTEMP
	txa
	ldx #5
	sta WSYNC				;WASTE 20 CPU CYCLES
SETLOP
	dex						;TO ALOWD VBLANK TO HAPPEN
	bne SETLOP				;IF THIS IS LINE "7C"
	ldx INTEMP
	sta CDTMV1-1,X
	tya
	sta CDTMV1-2,X
	rts
;
; EXIT FROM VERTICAL BLANK
;
XITVBL
	pla						;UNSTACK Y
	tay
	pla						;UNSTACK X
	tax
	pla						;UNSTACK A
	rti						;AND GO BACK FROM WHENCE.
;
;	'SIO ( SERIAL BUS INPUT/OUTPUT CONTROLLER )'
;		 COLLEEN OPERATING SYSTEM
;
;		 SIO  ( SERIAL BUS INPUT/OUTPUT CONTROLLER )
;		 WITH SOFTWARE BAUD RATE CORRECTION ON CASSETTE
;
;
;					AL MILLER		 3-APR-19
;
;
; THIS MODULE HAS ONE ENTRY POINT.  IT IS CALLED BY THE DEVICE
; HANDLERS.  IT INTERPRETS A PREVIOUSLY ESTABLISHED DEVICE CONTROL
; BLOCK (STORED IN GLOBAL RAM) TO ISSUE COMMANDS
; TO THE SERIAL BUS TO CONTROL TRANSMITTING AND RECEIVING DATA.
;
;
;
;
; EQUATES
;
; DCD DEVICE BUS ID NUMBERS
FLOPPY	equ $30
;PRINTR	equ $40
;CASSET	equ $80				;!!!!! *****
CASET	equ $60				;!!!!! *****
;
;
;BUS COMMANDS
;
READ	equ 'R'
WRITE	equ 'W'
;STATIS	equ 'S'
;FORMAT	equ '!'
;
;
; COMMAND AUX BYTES
;
SIDWAY	equ 'S'				;PRINT 18 CHARACTERS SIDEWAYS
NORMAL	equ 'N'				;PRINT 40 CHARACTERS NORMALLY
DOUBLE	equ 'D'				;PRINT 20 CHARACTERS DOUBLE WIDE
PLOT	equ 'P'				;PLOT MODE
;
;
; BUS RESPONSES
;
ACK		equ 'A'				;DEVICE ACKNOWLEDGES INFORMATION
NACK	equ 'N'				;DEVICE DID NOT UNDERSTAND
COMPLT	equ 'C'				;DEVICE SUCCESSFULLY COMPLETED OPERATION
ERROR	equ 'E'				;DEVICE INCURRED AN ERROR IN AN ATTEMPTED OP
;
;
; MISCELLANEOUS EQUATES
;
B192LO	equ $28				;19200 BAUD RATE POKEY COUNTER VALUES (LO BY
B192HI	equ $00				;(HI BYTE)
B600LO	equ $CC				;600 BAUD (LO BYTE)
B600HI	equ $05				;(HI BYTE)
HITONE	equ $05				;FSK HI FREQ POKEY COUNTER VALUE (5326 HZ)
LOTONE	equ $07				;FSK LO FREQ POKEY COUNTER VALUE (3995 HZ)
;
 ift PALFLG
WIRGLO	equ 150				;WRITE INTER RECORD GAP (IN 1/60 SEC)
RIRGLO	equ 100				;READ INTER RECORD GAP (IN 1/60 SEC)
WSIRG	equ 13				;SHORT WRITE INTER RECORD GAP
RSIRG	equ 8				;SHORT READ INTER RECORD GAP
 els
WIRGLO	equ 180				;WRITE INTER RECORD GAP (IN 1/60 SEC)
RIRGLO	equ 120				;READ INTER RECORD GAP (IN 1/60 SEC)
WSIRG	equ 15				;SHORT WRITE INTER RECORD GAP
RSIRG	equ 10				;SHORT READ INTER RECORD GAP
 eif
WIRGHI	equ 0
RIRGHI	equ 0
;
NCOMLO	equ $34				;PIA COMMAND TO LOWER NOT COMMAND LINE
NCOMHI	equ $3C				;PIA COMMAND TO RAISE NOT COMMAND LINE
MOTRGO	equ $34				;PIA COMMAND TO TURN ON CASSETTE MOTOR
MOTRST	equ $3C				;PIA COMMAND TO TURN OFF MOTOR
;
CRETRI	equ 13				;NUMBER OF COMMAND FRAME RETRIES
DRETRI	equ 1				;NUMBER OF DEVICE RETRIES
CTIMLO	equ 2				;COMMAND FRAME ACK TIME OUT (LO BYTE)
CTIMHI	equ 0				;COMMAND FRAME ACK TIME OUT (HI BYTE)
;
;
; Unknown data
	dta b($66,$66,$7E,$66,$00,$00,$7C)
;
; THIS IS TO MAKE DOS 2 WORK WHICH USED AN ABSOLUTE ADDRESS
;
	org $E912
	jmp SETVBL				; E8ED
;
; Unknown data
	dta b($66,$7C,$00,$00,$3C,$66,$60,$60,$66,$3C,$00,$00,$78,$6C,$66,$66)
	dta b($6C,$78,$00,$00,$7E,$60,$7C,$60,$60,$7E,$00,$00,$7E,$60,$7C,$60)
	dta b($60,$60,$00,$00,$3E,$60,$60,$6E,$66,$3E,$00,$00,$66,$66,$7E)
;
	org SIOORG				; $E944
;
; SIO INITIALIZATION SUBROUTINE
;
SIOINT
	lda #MOTRST
	sta PACTL				;TURN OFF MOTOR
;
	lda #NCOMHI
	sta PBCTL				;RAISE NOT COMMAND LINE
;
;
	lda #3
	sta SSKCTL				;GET POKEY OUT OF INITIALIZE MODE
	sta SOUNDR				;INIT POKE ADDRESS FOR QUIET I/O
	sta SKCTL
	rts						;RETURN
;
;
;
;
;
SIO
	tsx
	stx STACKP				;SAVE STACK POINTER
	lda #1
	sta CRITIC
;
	lda DDEVIC
	cmp #CASET
	bne NOTCST				;BRANCH IF NOT CASSETTE
	jmp CASENT				;OTHERWISE JUMP TO CASSETTE ENTER
;
; ALL DEVICES EXCEPT CASSETTE ARE INTELLIGENT
;
NOTCST
	lda #0
	sta CASFLG				; INIT CASSETTE FLAG TO NO CASSETTE
;
	lda #DRETRI				;SET NUMBER OF DEVICE RETRIES
	sta DRETRY
COMMND
	lda #CRETRI				;SET NUMBER OF COMMAND FRAMERETRIES
	sta CRETRY
;
; SEND A COMMAND FRAME
;
COMFRM
	lda #B192LO				;SET BAUD RATE TO 19200
	sta AUDF3
	lda #B192HI
	sta AUDF4
;
	clc						;SET UP COMMAND BUFFER
	lda DDEVIC
	adc DUNIT
	adc #$FF				;SUBTRACT 1
	sta CDEVIC				;SET BUS ID NUMBER
;
	lda DCOMND
	sta CCOMND				;SET BUS COMMAND
;
	lda DAUX1				;STORE COMMAND FRAME AUX BYTES 1 AND 2
	sta CAUX1
	lda DAUX2
	sta CAUX2				;DONE SETTING UP COMMAND BUFFER
;
	clc						;SET BUFFER POINTER TO COMMAND FRAME BUFFER
	lda #<CDEVIC
	sta BUFRLO				;AND BUFFER END ADDRESS
	adc #4
	sta BFENLO
	lda #>CDEVIC
	sta BUFRHI
	sta BFENHI				;DONE SETTING UP BUFFER POINTER
;
	lda #NCOMLO				;LOWER NOT COMMAND LINE
	sta PBCTL
;
	jsr SENDIN				;SEND THE COMMAND FRAME TO A SMART DEVICE
;
	lda ERRFLG
	bne BADCOM				;BRANCH IF AN ERROR RECEIVED
;
	tya
	bne ACKREC				;BRANCH IF ACK RECEIVED
;
;
BADCOM
	dec CRETRY				;A NACK OR TIME OUT OCCURED
	bpl COMFRM				;SO BRANCH IF ANY RETRIES LEFT
;
	jmp DERR1				;OTHERWISE, JUMP TO RETURN SECTION
;
;
ACKREC
	lda DSTATS				;ACK WAS RECEIVED
	bpl WATCOM				;BRANCH TO WAIT FOR COMPLETE
; IF THERE IS NO DATA TO BE SENT
;
;
;
; SEND A DATA FRAME TO PERIPHERAL
;
	lda #CRETRI				;SET NUMBER OF RETRIES
	sta CRETRY
;
	jsr LDPNTR				;LOAD BUFFER POINTER WITH DCB INFORMATION
;
	jsr SENDIN				;GO SEND THE DATA FRAME TO A SMART DEVICE
;
	beq BADCOM				;BRANCH IF BAD
;
;
;
; WAIT FOR COMPLETE SIGNAL FROM PERIPHERAL
;
WATCOM
	jsr STTMOT				;SET DDEVICE TIME OUT VALUES IN Y,X
;
	lda #$00
	sta ERRFLG				;CLEAR ERROR FLAG
;
	jsr WAITER				;SET UP TIMER AND WAIT
	beq DERR				;BRANCH IF TIME OUT
;
;
; DEVICE DID NOT TIME OUT
;
	bit DSTATS
	bvs MODATA				;BRANCH IF MORE DATA FOLLOWS
;
	lda ERRFLG
	bne DERR1				;BRANCH IF AN ERROR OCCURRED
	beq RETURN				;OTHERWISE RETURN
;
;
;
;
; RECEIVE A DATA FRAME FROM PERIPHERAL
;
MODATA
	jsr LDPNTR				;LOAD BUFFER POINTER WITH DCB INFORMATION
;
	jsr RECEIV				;GO RECEIVE A DATA FRAME
;
DERR
	lda ERRFLG
	beq NOTERR				;BRANCH IF NO ERROR PRECEEDED DATA
;
	lda TSTAT				;GET TEMP STATUS
	sta STATUS				;STORE IN REAL STATUS
;
;
NOTERR
	lda STATUS
	cmp #SUCCES
	beq RETURN				;BRANCH IF COMPLETELY SUCCESSFUL
;
DERR1
 	dec DRETRY
	bmi RETURN				;BRANCH IF OUT OF DEVICE RETRIES
;
	jmp COMMND				;OTHERWISE ONE MORE TIME
;
;
;
;
RETURN
	jsr SENDDS				;DISABLE POKEY INTERRUPTS
	lda #0
	sta CRITIC
	ldy STATUS				;RETURN STATUS IN Y
	sty DSTATS				;AND THE DCB STATUS WORD
	rts						;RETURN
;
;
;
;
; WAIT SUBROUTINE
;
; WAITS FOR COMPLETE OR ACK
; RETURNS Y=$FF IF SUCCESSFUL, Y=$00 IF NOT
;
WAIT
	lda #$00
	sta ERRFLG				;CLEAR ERROR FLAG
;
	clc						;LOAD BUFFER POINTER WITH ADDRESS
	lda #<TEMP				;OF TEMPORARY RAM CELL
	sta BUFRLO
	adc #1
	sta BFENLO				;ALSO SET BUFFER END +1 ADDRESS
	lda #>TEMP
	sta BUFRHI
	sta BFENHI				;DONE LOADING POINTER
;
	lda #$FF
	sta NOCKSM				;SET NO CHECKSUM FOLLOWS DATA FLAG
;
	jsr RECEIV				;GO RECEIVE A BYTE
;
	ldy #$FF				;ASSUME SUCCESS
	lda STATUS
	cmp #SUCCES
	bne NWOK				;BRANCH IF IT DID NOT WORK OK
;
;
;
;
WOK
	lda TEMP				;MAKE SURE THE BYTE SUCCESSFULLY RECEIVED
	cmp #ACK				;WAS ACTUALLY AN ACK OR COMPLETE
	beq GOOD
	cmp #COMPLT
	beq GOOD
;
	cmp #ERROR
	bne NOTDER				;BRANCH IF DEVICE DID NOT SEND BACK
; A DEVICE ERROR CODE
	lda #DERROR
	sta STATUS				;SET DEVICE ERROR STATUS
	bne NWOK
;
NOTDER
	lda #DNACK				;OTHERWISE SET HACK STATUS
	sta STATUS
;
NWOK
	lda STATUS
	cmp #TIMOUT
	beq BAD					;BRANCH IF TIME OUT
;
	lda #$FF
	sta ERRFLG				;SET SOME ERROR FLAG
	bne GOOD				;RETURN WITH OUT SETTING Y = 0
;
BAD
	ldy #0
;
GOOD
	lda STATUS
	sta TSTAT
	rts						;RETURN
;
;
;
;
;
; SEND SUBROUTINE
;
; SENDS A BUFFER OF BYTES OUT OVER THE SERIAL BUS
;
;
SEND
	lda #SUCCES				;ASSUME SUCCESS
	sta STATUS
;
	jsr SENDEN				;ENABLE SENDING
;
	ldy #0
	sty CHKSUM				;CLEAR CHECK SUM
	sty CHKSNT				;CHECKSUM SENT FLAG
	sty XMTDON				;TRANSMISSION DONE FLAG
;
;
	lda (BUFRLO),Y			;PUT FIRST BYTE FROM BUFFER
	sta SEROUT				;INTO THE SERIAL OUTPUT REGISTER
;
;
	sta CHKSUM				;PUT IT IN CHECKSUM
;
NOTDON
	lda BRKKEY
	bne NTBRKO
	jmp BROKE				;JUMP IF BREAK KEY PRESSED
;
NTBRKO
	lda XMTDON				;LOOP UNTIL TRANSMISSION IS DONE
	beq NOTDON
;
	jsr SENDDS				;DISABLE SENDING
;
	rts						;RETURN
;
;
;
;
;
;
; OUTPUT DATA NEEDED INTERRUPT SERVICE ROUTINE
;
ISRODN
	tya
	pha						;SAVE Y REG ON STACK
;
	inc BUFRLO				;INCREMENT DUFFER POINTER
	bne NOWRPO
	inc BUFRHI
;
NOWRPO
	lda BUFRLO				;CHECK IF PAST END OF BUFFER
	cmp BFENLO
	lda BUFRHI				;HIGH PART
	sbc BFENHI
	bcc NOTEND				;BRANCH IF NOT PAST END OF BUFFER
;
	lda CHKSNT
	bne RELONE				;BRANCH IF CHECKSUM ALREADY SENT
;
	lda CHKSUM
	sta SEROUT				;SEND CHECK SUM
	lda #$FF
	sta CHKSNT				;SET CHECKSUM SENT FLAG
	bne CHKDON
;
RELONE
	lda POKMSK				;ENABLE TRANSMIT DONE INTERRUPT
	ora #$08
	sta POKMSK
	sta IRQEN
;
CHKDON
	pla
	tay						;RESTORE Y REG
	pla						;RETURN FROM INTERRUPT
	rti
;
;
NOTEND
	ldy #0
	lda (BUFRLO),Y			;PUT NEXT BYTE FROM BUFFER
	sta SEROUT				;INTO THE SERIAL OUTPUT REGISTER
;
	clc						;ADD IT TO CHECKSUM
	adc CHKSUM
	adc #0
	sta CHKSUM
;
	jmp CHKDON				;GO RETURN
;
;
;
;
;
;
; TRANSMIT DONE INTERRUPT SERVICE ROUTINE
;
ISRTD
 	lda CHKSNT
	beq FOOEY				;BRANCH IF CHECKSUM NOT YET SENT
;
	sta XMTDON				;OTHERWISE SET TRANSMISSION DONE FLAG
;
	lda POKMSK				;DISABLE TRANSMIT DONE INTERRUPT
	and #$F7
	sta POKMSK
	sta IRQEN
;
FOOEY
	pla						;RETURN FROM INTERRUPT
	rti
;
;
;
;
;
;
;
;
; RECEIVE SUBROUTINE
;
RECEIV
	lda #0
;
	ldy CASFLG
	bne NOCLR				;BRANCH IF CASSETTE
;
	sta CHKSUM				;CLEAR CHKSUM
NOCLR
	sta BUFRFL				;BUFFER FULL FLAG
	sta RECVDN				;RECEIVE DONE FLAG
;
;
;
	lda #SUCCES
	sta STATUS				;SET GOOD STATUS FOR DEFAULT CASE.
	jsr RECVEN				;DO RECEIVE ENABLE
	lda #NCOMHI				;COMMAND FRAME HI COMMAND
	sta PBCTL				;STORE IN PIA
CHKTIM
	lda BRKKEY
	bne NTBRK1
	jmp BROKE				;JUMP IF BREAK KEY PRESSED
;
NTBRK1
	lda TIMFLG				;NO,
	beq TOUT				;IF TIMEOUT, GO SET ERROR STATUS
	lda RECVDN
	beq CHKTIM				;DONE ?
GOBACK
	rts
TOUT
	lda #TIMOUT				;YES,
	sta STATUS				;SET TIMEOUT STATUS
;
RRETRN
	rts						;RETURN
;
;
;
;
; SERIAL INPUT READY INTERRUPT SERVICE ROUTINE
;
ISRSIR
	tya
	pha						;SAVE Y REG ON STACK
;
;
;
	lda SKSTAT
	sta SKRES				;RESET STATUS REGISTER
; ********	THIS MAY NOT BE THE PLACE TO DO IT	*********
;
	bmi NTFRAM				;BRANCH IF NO FRAMING ERROR
;
	ldy #FRMERR
	sty STATUS				;SET FRAME ERRORR STATUS
;
NTFRAM
	and #$20
	bne NTOVRN				;BRANCH IF NO OVERRUN ERROR
;
	ldy #OVRRUN
	sty STATUS				;SET OVERRUN ERROR STATUS
;
NTOVRN
	lda BUFRFL
	beq NOTYET				;BRANCH IF BUFFER WAS NOTYET FILLED
;
	lda SERIN				;THIS INPUT BYTE 15 THE CHECKSUM
	cmp CHKSUM
	beq SRETRN				;BRANCH IF CHECKSUMS MATCH
;
	ldy #CHKERR
	sty STATUS				;SET CHECKSUM ERROR STATUS
;
SRETRN
	lda #$FF				;SET RECEIVE DONE FLAG
	sta RECVDN
;
SUSUAL
	pla
	tay						;RESTORE Y REG
	pla						;RETURN FROM INTERRUPT
	rti
;
;
;
NOTYET
	lda SERIN
	ldy #0
	sta (BUFRLO),Y			;STORE INPUT REGISTER INTO BUFFER
;
	clc						;ADD IT TO CHECKSUM
	adc CHKSUM
	adc #0
	sta CHKSUM
;
	inc BUFRLO				;INCREMENT BUFFER POINTER
	bne NTWRP1
	inc BUFRHI
;
NTWRP1
	lda BUFRLO
	cmp BFENLO
	lda BUFRHI
	sbc BFENHI
	bcc SUSUAL				;BRANCH IF NEW BUFFER ADDRESS IS IN BUFFER L
;
	lda NOCKSM
	beq GOON				;BRANCH IF A CHECKSUM WILL FOLLOW DATA
;
	lda #0
	sta NOCKSM				;CLEAR NO CHECKSUM FLAG
;
	beq SRETRN				;GO RETURN AND SET RECEIVE DONE FLAG
;
;
GOON
	lda #$FF
	sta BUFRFL				;SET BUFFER FULL FLAG
;
	bne SUSUAL				;GO RETURN
;
;
;
;
;
;
; LOAD BUFFER POINTER SUBROUTINE
;
; LOAD BUFFER POINTER WITH DCB BUFFER INFORMATION
;
LDPNTR
	clc
	lda DBUFLO
	sta BUFRLO
	adc DBYTLO
	sta BFENLO				;ALSO SET SUFFER END + 1 ADDRESS
;
	lda DBUFHI
	sta BUFRHI
	adc DBYTHI
	sta BFENHI
;
	rts						;RETURN
;
;
;
;
;
;
; CASSETTE HANDLING CODE
;
CASENT
	lda DSTATS
	bpl CASRED				;BRANCH IF INPUT FROM CASSETTE
;
; WRITE A RECORD
;
	lda #B600LO				;SET BAUD RATE TO 600
	sta AUDF3
	lda #B600HI
	sta AUDF4
;
	jsr SENDEN				;TURN ON POKEY MARK TONE
;
	ldy #WSIRG				;LOAD SHORT WRITE INTER RECORD GAP TIME
	lda DAUX2
	bmi SRTIR0				;BRANCH IF SHORT GAP IS DESIRED
;
	ldy #WIRGLO				;SET WRITE IRQ TIME
SRTIR0
	ldx #WIRGHI
	jsr SETVBX
;
	lda #MOTRGO
	sta PACTL				;TURN ON MOTOR
;
TIMIT
 	lda TIMFLG				;LOOP UNTIL DONE
	bne TIMIT
;
	jsr LDPNTR				;LOAD BUFFER POINTER WITH DCB INFORMATION
;
	jsr SEND				;SEND A BUFFER
;
	jmp CRETRN				;GO, RETURN
;
;
;
; RECEIVE A RECORD
;
CASRED
	lda #$FF
	sta CASFLG				;SET SET CASSETTE FLAG
;
	ldy #RSIRG				;LOAD SHORT READ INTER RECORD GAP TIME
	lda DAUX2
	bmi SRTIR1				;BRANCH IF SHORT GAP IS DESIRED
;
	ldy #RIRGLO				;SET TIME OUT FOR READ IRQ
SRTIR1
	ldx #RIRGHI
	jsr SETVBX
;
	lda #MOTRGO
	sta PACTL				;TURN ON MOTOR
;
TIMIT1
	lda TIMFLG				;LOOP UNTIL DONE
	bne TIMIT1
;
	jsr LDPNTR				;LOAD BUFFER POINTER WITH DOS INFORMATION
;
	jsr STTMOT				;SET DEVICE TIME OUT IN Y,X
	jsr SETVBX
;
	jsr BEGIN				;SET INITIAL BAUD RATE
;
	jsr RECEIV				;GO RECEIVE A BLOCK
;
CRETRN
	lda DAUX2
	bmi SRTIR2				;BRANCH IF DOING SHORT INTER RECORD GAPS
; DON'T TURN OFF CASSETTE MOTOR
	lda #MOTRST
	sta PACTL				;TURN OFF MOTOR
;
SRTIR2
	jmp RETURN				;GO RETURN
;
;
;
;
;
JTIMER
	lda #$00
	sta TIMFLG				;SET TIME OUT FLAG
	rts
;
;
;
;
;
;
; SEND ENABLE SUBROUTINE
;
SENDEN
	lda #$07				;MASK OFF PREVIOUS SERIAL BUS CONTROL BITS
	and SSKCTL
	ora #$20				;SET TRANSMIT MODE
;
	ldy DDEVIC
	cpy #CASET
	bne NOTCAS				;BRANCH IF NOT CASSETTE
;
	ora #$08				;SET THE FSK OUTPUT BIT
;
	ldy #LOTONE				;SET FSK TONE FREQUENCIES
	sty AUDF2
	ldy #HITONE
	sty AUDF1
;
NOTCAS
	sta SSKCTL				;STORE NEW VALUE TO SYSTEM MASK
	sta SKCTL				;STORE TO ACTUAL REGISTER
;
	lda #$C7				;MASK OFF PREVIOUS SERIAL BUS INTERRUPT BITS
	and POKMSK
	ora #$10				;ENABLE OUTPUT DATA NEEDED INTERRUPT
;
;
	jmp CONTIN				;GO CONTINUE IN RECEIVE ENABLE SUBROUTINE
;
;
;
;
;
;
; RECEIVE ENABLE SUBROUTINE
;
RECVEN
	lda #$07				;MASK OFF PREVIOUS SERIAL BUS CONTROL BITS
	and SSKCTL
	ora #$10				;SET RECEIVE MODE ASYNCH.
	sta SSKCTL				;STORE NEW VALUE TO SYSTEM MASK
	sta SKCTL				;STORE TO ACTUAL REGISTER
;
	sta SKRES				;RESET SERIAL PORT/KEYBOARD STATUS REGISTER
;
	lda #$C7				;MASK OFF PREVIOUS SERIAL BUS INTERRUPTBITS
	and POKMSK
	ora #$20				;ENABLE RECEIVE INTERRUPT
CONTIN
	sta POKMSK				;STORE NEW VALUE TO SYSTEM MASK
	sta IRQEN				;STORE TO ACTUAL. REGISTER
;
;
	lda #$28				;CLOCK CH.3 WITH 1.79 MHZ
	sta AUDCTL				;CLOCK CH.4 WITH CH. 3
;
	ldx #6					;SET PURE TONES, NO VOLUME
	lda #$A8
	ldy SOUNDR				;TEST QUIET I/O FLAG
	bne NOISE1				;NE IS NORMAL (NOISY)
	lda #$A0
NOISE1
	sta AUDC1,X
	dex
	dex
	bpl NOISE1
;
	lda #$A0
	sta AUDC3				;TURN OFF SOUND ON CHANNEL 3
	ldy DDEVIC
	cpy #CASET
	beq CAS31				;BRANCH IF CASSETTE IS DESIRED
	sta AUDC1				;OTHERWISE TURN OFF CHANNELS 1 AND 2
	sta AUDC2
;
;
CAS31
	rts						;RETURN
;
;
;
;
; DISABLE SEND AND DISABLE RECEIVE SUBROUTINES
;
SENDDS
	nop
RECVDS
	lda #$C7				;MASK OFF SERIAL BUS INTERRUPTS
	and POKMSK
	sta POKMSK				;STORE NEW VALUE TO SYSTEM MASK
	sta IRQEN				;STORE TO ACTUAL REGISTER
;
	ldx #6
	lda #0
ZERIT
	sta AUDC1,X
	dex
	dex
	bpl ZERIT				;TURN OFF AUDIO VOLUME
;
	rts						;RETURN
;
;
;
; SET DDEVICE TIME OUT VALUES IN Y,X SUBROUTINE
;
STTMOT
	lda DTIMLO				;GET DEVICE TIME OUT IN 1 SECOND INCR
	ror @					;PUT 6 HI BITS IN X, LO 2 BITS IN Y
	ror @
	tay						;TEMP SAVE
	and #$3F				;MASK OFF 2 HI BITS
	tax						;THIS IS HZ BYTE OF TIME OUT
;
	tya						;RESTORE
	ror @
	and #$C0				;MASK OFF ALL BUT 2 HI BITS
	tay						;THIS IS LO BYTE OF TIME OUT
;
	rts
;
;
;
;
;
;
;
INTTBL
	dta a(ISRSIR)			;SERIAL INPUT READY
	dta a(ISRODN)			;OUTPUT DATA NEEDED
	dta a(ISRTD)			;TRANSMISSION DONE
;
;
;
; SEND A DATA FRAME TO AN INTELLIGENT PERIPHERAL SUBROUTINE
;
;
SENDIN
	ldx #$01
DELAY0
	ldy #$FF
DELAY1
	dey
	bne DELAY1
	dex
	bne DELAY0
;
	jsr SEND				;GO SEND THE DATA FRAME
;
	ldy #CTIMLO				;SET ACK TIME OUT
	ldx #CTIMHI
WAITER
	jsr SETVBX
;
	jsr WAIT				;WAIT FOR ACK
;
	tya						;IF Y=0, A TIME OUT OR NACK OCCURED
;
	rts						;RETURN
;
;
;
;
;
;
;
;
; COMPUTE VALUE FOR POKEY FREQ REGS FOR THE BAUD RATE AS
; MEASURED BY AN INTERVAL OF THE 'VCOUNT' TIMER.
;
COMPUT
	sta TIMER2
	sty TIMER2+1			;SAVE FINAL TIMER VALUE
	jsr ADJUST				;ADJUST VCOUNT VALUE
	sta TIMER2				;SAVE ADJUSTED VALUE
	lda TIMER1
	jsr ADJUST				;ADJUST
	sta TIMER1				;SAVE ADJUSTED TIMER1 VALUE
	lda TIMER2
	sec
	sbc TIMER1
	sta TEMP1				;FIND VCOUNT DIFFERENCE
	lda TIMER2+1
	sec
	sbc TIMER1+1
	tay						;FIND VBLANK COUNT DIFFERENCE
 ift PALFLG
	lda #-$9C
HITIMR
	clc
	adc #$9C
 els
	lda #-$83
HITIMR
	clc
	adc #$83				;ACCUMULATE MULTIPLICATION
 eif
	dey
	bpl HITIMR				;DONE?
	clc
	adc TEMP1				;TOTAL VCOUNT DIFFERENCE
FINDX
	tay						;SAVE ACCUM
	lsr @
	lsr @
	lsr @
	asl @
	sec
	sbc #22					;ADJUST TABLE INDEX
	tax						;DIVIDE INTERVAL BY 4 TO CET TABLE INDEX
	tya						;RESTORE ACCUM
	and #7
	tay						;PULL OFF 3 LO BITS OF INTERVAL
	lda #-11
DOINTP
	clc
	adc #11					;ACCUMULATE INTERPOLATION CONSTANT
	dey
	bpl DOINTP				;INTERPOLATION CONSTANT COMPUTATION DONE?
;
ENINTP
	ldy #0
	sty ADDCOR				;CLEAR ADDITION CORRECTION FLAG
	sec
	sbc #7					;ADJUST INTERPOLATION CONSTANT
	bpl PLUS
	dec ADDCOR
PLUS
	clc
	adc POKTAB,X			;ADD CONSTANT TO LO BYTE TABLE VALUE
	tay						;LO BYTE POKEY FREQ VALUE
	lda ADDCOR
	adc POKTAB+1,X			;ADD CARRY TO HI BYTE TABLEVALUE
; HI BYTE POKEY FREQ VALUE
	rts
;
;
;
;		 ROUTINE TO ADJUST VCOUNT VALUE
;
ADJUST
	cmp #$7C
	bmi ADJ1				;LAROER THAN '7C' ?
	sec						;YES
	sbc #$7C
	rts
ADJ1
	clc
 ift PALFLG
	adc #$20
 els
	adc #$7
 eif
	rts
;
;
;
;
;
;
;		 INITIAL BAUD RATE MEASUREMENT -- USED TO SET THE
;					BAUD RATE AT THE START OF A RECORD.
;
;					IT IS ASSUMED THAT THE FIRST TWO BYTES OF EVERY
; RECORD ARE 'AA' HEX.
;
BEGIN
 	lda BRKKEY
	bne NTBRK2
	jmp BROKE				;JUMP IF BREAK KEY PRESSED
;
NTBRK2
	sei
;
	lda TIMFLG
	bne OKTIM1				;BRANCH IF NOT TIMEDOUT
	beq TOUT1				;BRANCH IF TIME OUT
;
OKTIM1
	lda SKSTAT
	and #$10				;READ SERIAL PORT
	bne BEGIN				;START BIT?
	sta SAVIO				;SAVE SER. DATA IN
	ldx VCOUNT				;READ VERTICAL LINECOUNTER
	ldy RTCLOK+2			;READ LO BYTE OF VBLANK CLOCK
	stx TIMER1
	sty TIMER1+1			;SAVE INITIAL TIMER VALUE
;
	ldx #1					;SET MODE FLAG
	stx TEMP3
	ldy #10					;SET BIT COUNTER FOR 10 BITS
COUNT
 	lda BRKKEY
	beq BROKE				;BRANCH IF BREAK KEY PRESSED
;
	lda TIMFLG
	bne OKTIMR				;BRANCH IF NOT TIMED OUT
TOUT1
	cli
	jmp TOUT				;BRANCH IF TIME OUT
;
OKTIMR
	lda SKSTAT
	and #$10				;READ SERIAL PORT
	cmp SAVIO				;DATA IN CHANGED YET?
	beq COUNT
	sta SAVIO				;YES,SAVE SER. DATA IN
	dey						;DECR. BIT COUNTER
	bne COUNT				;DONE?
;
	dec TEMP3				;YES,
	bmi GOREAD				;DONE WITH BOTH MODES?
	lda VCOUNT
	ldy RTCLOK+2			;READ TIMER LO & HI BYTES
	jsr COMPUT				; NO, COMPUTE SAUD RATE
	sty CBAUDL
	sta CBAUDH				;SET BAUD RATE INTO RAM CELLS
	ldy #9					;SET BIT COUNTER FOR 9 BITS
	bne COUNT
;
GOREAD
	lda CBAUDL
	sta AUDF3
	lda CBAUDH
	sta AUDF4				;SET POKEY FREQ REGS FOR BAUD RATE
	lda #0
	sta SKSTAT
	lda SSKCTL
	sta SKSTAT				; INIT. POKEY SERIAL PORT
	lda #$55
	sta (BUFRLO),Y			;STORE '$55' AS FIRST RCV. BUFFER
	iny
	sta (BUFRLO),Y
	lda #$AA
	sta CHKSUM				;STORE CHECKSUM FOR 2 BYTES OF '$AA'
	clc
	lda BUFRLO
	adc #2
	sta BUFRLO
	lda BUFRHI
	adc #0
	sta BUFRHI				;INCR. BUFFER POINTER BY 1
	cli
	rts
;
;
;
BROKE
 	jsr SENDDS				;BREAK KEY WAS PRESSED, SO PREPARE
	lda #MOTRST				;TO RETURN
	sta PACTL				;TURN OFF MOTOR
	sta PBCTL				;RAISE NOT COMMAND LINE
;
	lda #BRKABT
	sta STATUS				;STORE BREAK ABORT STATUS CODE
;
	ldx STACKP
	txs						;RESTORE STACK POINTER
;
	dec BRKKEY				;SET BREAK KEY FLAG TO NONZERO
	cli						;ALLOW IRQ'S
;
	jmp RETURN				;GO RETURN
;
;
;
;
;
SETVBX
	lda #<JTIMER			;STORE TIME OUT ROUTINE ADDRESS
	sta CDTMA1
	lda #>JTIMER
	sta CDTMA1+1
;
	lda #1					;SET FOR TIMER 1
;
	sei						;THE SETVBL ROUTINE NEEDS THIS TO CUT SHORT
	jsr SETVBV				;ANY VBLANKS THAT OCCUR
	lda #1					;SET FOR TIMER 1
	sta TIMFLG				;SET FLAG TO NOT TIMED OUT
	cli
	rts
;
;
;
;
;
;
;
; 'VCOUNT' INTERVAL TIMER MEASUREMENT -- TO -- POKEY FREQ REG VALUE
;					CONVERSION TABLE
;
;
; THE VALUES STORED IN THE TABLE ARE 'AUDF+7'.
;
;		 THE FOLLOWING FORMULAS WERE USED TO DETERMINE THE TABLE VALUES:
;
;					F OUT F IN/(2*(AUDF+M)) , WHERE F IN=1.78979 MHZ. & M=7
;
;		  FROM THIS WAS DERIVED THE FORMULA USED TO COMPUTE THE
;		  TABLE VALUES BASED ON A MEASUREMENT OF THE PERIOD BY
;		  AN INTERVAL OF THE 'VCOUNT' TIMER.
;
;					AUDF+7=(11.365167)*T OUT, WHERE T OUT=# OF COUNTS
;					(127 USEC. RESOLUTION) OF 'VCOUNT' FOR 1
;					CHARACTER TIME (10 BIT TIMES).
;
;
;
;
;		AUDF+7			BAUD RATE		VCOUNT INTERVAL
;		------			-----------		----------------
;	dta a($27C)			;1407			56
;	dta a($2D7)			;1231			64
;	dta a($332)			;1094			72
;	dta a($38D)			;985			80
POKTAB
	dta a($3E8)			;895			88
	dta a($443)			;820			96
	dta a($49E)			;757			104
	dta a($4F9)			;703			112
	dta a($554)			;656			120
	dta a($5AF)			;615			128
	dta a($60A)			;579			136
	dta a($665)			;547			144
	dta a($6C0)			;518			152
	dta a($71A)			;492			160
	dta a($775)			;469			168
	dta a($7D0)			;447			176
;	dta a($828)			;428			184
;	dta a($886)			;410			192
;	dta a($8E1)			;394			200
;	dta a($93C)			;379			208
;	dta a($997)			;365			216
;	dta a($9F2)			;352			224
;	dta a($A4D)			;339			232
;	dta a($AA8)			;328			240
;	dta a($803)			;318			248
;
;
;
;
;
;	'DISK  ***** DISKP.SRC ***** 3/9/79 *****  4:00:00 P.M.'
;
;
;
;
;
;		 CONSTANT EQUATES
;
DISKID	equ $31				;SERIAL BUS DISK I.D.
PUTSEC	equ $50				;DISK PUT SECTOR DCB COMMAND
; READ	equ $52				;DISK GET SECTOR DCB COMMAND
; WRITE	equ $57				;DISK PUT SECTOR WITH READ CHECK DCB COMMAND
STATC	equ $53				;DISK STATUS DCB COMMAND
FOMAT	equ $21				;DISK FORMAT DCB COMMAND !!!!! *****
NODAT	equ 0				;SIO COMMAND FOR "NO DATA" OPERATION
GETDAT	equ $40				;SIO COMMAND FOR "DATA FROM DEVICE"
PUTDAT	equ $80				;SIO COMMAND FOR "DATA TO DEVICE"
;
;
	dta b($24,$85)			; Unknown data
;
;		 CONSTANTS
;
	org DSKORG				; $EDEA
;
;
;
;***********************************************************************
;		 DISK INTERFACE ROUTINE STARTS HERE
;***********************************************************************
;
;		 DISK INTERFACE INITIALIZATION ROUTINE
;
DINIT
 	lda #160
	sta DSKTIM				;SET INITIAL DISK TIMEOUT TO 160 SEC
	rts
;
;
;
;		 DISK INTERFACE ENTRY POINT
;
DSKIF
 	lda #DISKID
	sta DDEVIC				;SET SERIAL BUS ID IN DCB
	lda DSKTIM
	ldx DCOMND
	cpx #FOMAT				;IS COMMAND A FORMAT COMMAND?
	beq PUTDTO
	lda #7					;NO, SET TIMEOUT TO 7 SECS.
PUTDTO
	sta DTIMLO				;PUT DISK TIMEOUT IN DCB
	ldx #GETDAT				;SET "GET DATA" COMMAND FOR SIO
	ldy #$80				;SET BYTE COUNT TO 128
	lda DCOMND				;READ COMMAND IN DCB
	cmp #WRITE				;IS COMMAND A "PUT SECTOR" COMMAND?
	bne CKSTC
	ldx #PUTDAT				;YES, SET "PUT DATA" COMMAND FOR 610
CKSTC
 	cmp #STATC				;IS COMMAND A STATUS COMMAND?
	bne PUTCNT
	lda #<DVSTAT
	sta DBUFLO
	lda #>DVSTAT
	sta DBUFHI				;SET BUFFER ADDR TO GLOBAL STATUS BUFFER
	ldy #4					;YES, SET BYTE COUNT TO 4
PUTCNT
	stx DSTATS				;PUT STATUS COMMAND FOR SIO IN DCB
	sty DBYTLO
	lda #0
	sta DBYTHI				;PUT BYTE COUNT IN DCB
	jsr SIOV				;CALL SERIAL I/O.
	bpl GOODST				;NO ERROR
	rts						;NO, GO BACK
GOODST
	lda DCOMND				;READ THE COMMAND
	cmp #STATC				;WAS IT A STATUS COMMAND?
	bne PUTBC
	jsr PUTADR				;PUT BUFFER ADDR IN TEMP REQ.
	ldy #2
	lda (BUFADR),Y			;READ DISK TIMEOUT VALUE BYTE OF STATUS
	sta DSKTIM				;PUT IT IN DISK TIMEOUT REQ.
PUTBC
 	lda DCOMND
	cmp #FOMAT				;WAS COMMAND A FORMAT COMMAND?
	bne ENDDIF
FMTD
	jsr PUTADR				;YES PUT BUFFER, ADDR INTO TEMP REC
	ldy #$FE				;SET BUFFER POINTER
TWICE
	iny
	iny						;INCR BUFFER POINTER BY 2
RDBAD
 	lda (BUFADR),Y			;READ LO BYTE BAD SECTOR DATA
	cmp #$FF
	bne TWICE				;IS IT "FF" ?
	iny						; YES,
	lda (BUFADR),Y			;READ HI BYTE BAD SECTOR DATA
	iny
	cmp #$FF
	bne RDBAD				;IS IT "FF" ?
	dey
	dey						; YES
	sty DBYTLO				;PUT BAD SECTOR BYTE COUNT INTO DCB
	lda #0
	sta DBYTHI
ENDDIF
	ldy DSTATS
	rts
;
;
;
;
;		 SUBROUTINES
;
;
;		 PUT BUFFER ADDR FROM DCB INTO TEMP REQ
;
PUTADR
	lda DBUFLO
	sta BUFADR
	lda DBUFHI
	sta BUFADR+1			;PUT BUFFER ADDR IN TEMP REQ
	rts
;***********************************************************************
;
;
;	'PRINTER ***** PRINTP.SRC ***** 3/9/79 ***** 4:00:00 P
;
;
;		 DEVICE NUMBER OR CODE EQUATES
;
OPNOUT	equ $2				;IOCB OPEN FOR OUTPUT COMMAND
NBUFSZ	equ 40				;PRINT NORMAL BUFFER SIZE
DBUFSZ	equ 20				;PRINT DOUBLE BUFFFER SIZE
SBUFSZ	equ 29				;PRINT SIDEWAYS BUFFER SIZE
PDEVN	equ $40				;PRINTER DEVICE NUMBER
; STATC	equ $53				;DCB STATUS COMMAND CODE
WRITEC	equ $57				;DCB WRITE COMMAND
SPACE	equ $20				;ASCII SPACE CHAR.
N		equ $4E				;ASCII "N" CHAR.
D		equ $44				;ASCII "D" CHAR.
S		equ $53				;ASCII "S" CHAR.
;
;
;
	org PRNORG				; $EE78
;
;
;		 PRINTER HANDLER INITIALIZATION ROUTINE
;
PHINIT
	lda #30
	sta PTIMOT				;SET UP INITIAL PRINTER TIMEOUT OF 30 sec.
	rts
;
;
;		 PRINTER HANDLER CONSTANTS
;
PHSTLO	dta a(DVSTAT)		;STATUS BUFFER POINTER
PHCHLO	dta a(PRNBUF)		;CHAR. BUFFER POINTER
;
;
;
;		 ************************
;		 PRINTER HANDLER ROUTINES
;		 ************************
;
;
;
;
;
;		 PRINTER HANDLER STATUS ROUTINE
;
PHSTAT
	lda #4
	sta PBUFSZ				;SET BUFFER SIZE TO 4 BYTES
	ldx PHSTLO
	ldy PHSTLO+1			;SET POINTER TO STATUS BUFFER
	lda #STATC				;SETCOMMAND TO "STATUS"
	sta DCOMND				;SET STATUS COMMAND
	sta DAUX1
	jsr SETDCB				;GO SETUP DCH
	jsr SIOV				;SEND STATUS COMMAND
	bmi BADST				;GO IF ERROR
	jsr PHPUT				;YES, PUT STATUS INTO GLOBAL BUFFER.
BADST
	rts
;
;
;
;
;		 PRINTER HANDLER OPEN ROUTINE
;
PHOPEN
	jsr PHSTAT				;DO STATUS COMMAND TO SIO
	lda #0
	sta PBPNT				;CLEAR PRINT BUFFER POINTER
	rts
;
;
;
;
;		 PRINTER HANDLER WRITE ROUTINE
;
PHWRIT
	sta PTEMP				;SAVE ACCUM
	jsr PRMODE				;GO DETERMINE PRINTMODE
	ldx PBPNT
	lda PTEMP				;GET CHAR. SENT BY CID
	sta PRNBUF,X			;PUT CHAR. IN PRINT BUFFER
	inx						;INCR. BUFFER POINTER
	cpx PBUFSZ				;BUFFER POINTERBUFFER SIZE?
	beq BUFFUL
	stx PBPNT				;SAVE SUFFER POINTER
	cmp #CR					;IS CHAR. = EOL ?
	beq BLFILL				;IF YES, GO DO BLANK FILL.
	ldy #SUCCES				;PUT GOOD STATUS IN Y REQ FOR CIO.
	rts
BLFILL
	lda #SPACE				;PUT BLANK IN ACCUM.
FILLBF
	sta PRNBUF,X			;STORE IT IN PRINT BUFFER.
	inx
	cpx PBUFSZ
	bne FILLBF				;BUFFER BLANK FILLED?
BUFFUL
	lda #0
	sta PBPNT				;CLEAR PRINT BUFFER POINTER
	ldx PHCHLO
	ldy PHCHLO+1			;SET POINTER TO PRINT BUFFER
	jsr SETDCB				;GO SETUP OCR
	jsr SIOV				;SEND PRINT COMMAND
	rts						;YES
;
;
;
;
;		 PRINTER HANDLER CLOSE ROUTINE
;
PHCLOS
	jsr PRMODE				;GO DETERMINE PRINT MODE
	ldx PBPNT
	bne BLFILL
	ldy #SUCCES
	rts
;
;
;
;
;		 S U B R O U T I N E S
;
;
;
;		 SET UP DCB TO CALL SIO
;
SETDCB
	stx DBUFLO
	sty DBUFHI				;SET BUFFER POINTER
	lda #PDEVN
	sta DDEVIC				;SET PRINTER BUS I.D. FOR DCB
	lda #1
	sta DUNIT				;SET UNIT NUMBER TO 1
	lda #$80				;DEVICE WILL EXPECT DATA
	ldx DCOMND
	cpx #STATC				;STATUS COMMAND?
	bne PSIOC
	lda #$40				;EXPECT DATA FROM DEVICE
PSIOC
	sta DSTATS				;SET SIO MODE COMMAND
	lda PBUFSZ
	sta DBYTLO				;SET LO BYTE COUNT
	lda #0
	sta DBYTHI				;SET HI BYTE COUNT
	lda PTIMOT
	sta DTIMLO				;SET DEVICE TIMEOUT COUNT
	rts
;
;
;
;
; GET DEVICE TIMEOUT FROM STATUS & SAVE IT
;
PHPUT
 	lda DVSTAT+2
	sta PTIMOT				;SAVE DEVICE TIMEOUT
	rts
;
;
;
;
; DETERMINE PRINT MODE & SETUP PRINT BUFFER SIZE, DCB PRINT
; COMMAND, &. DCB AUX1 FOR PRINT MODE
;
PRMODE
	ldy #WRITEC				;PUT WRITE COMMAND IN Y REG
	lda ICAX2Z				;READ PRINT MODE
CMODE
 	cmp #N
	bne CDUBL				;PRINT NORMAL ?
	ldx #NBUFSZ				;YES, SET NORMAL CHAR. BUFFER SIZE
	bne SETBSZ
CDUBL
 	cmp #D
	bne CSIDE				;PRINT DOUBLE?
	ldx #DBUFSZ				;YES, SET DOUBLE CHAR. BUFFER SIZE
	bne SETBSZ
CSIDE
 	cmp #S					;PRINT SIDEWAYS ?
	bne GOERR				;IF NOT, GO TO ERROR ROUTINE
	ldx #SBUFSZ				;YES, SET SIDEWAYS BUFFER SIZE
SETBSZ
	stx PBUFSZ				;STORE PRINT BUFFER SIZE
	sty DCOMND				;STORE DCB COMMAND
	sta DAUX1				;STORE DCB AUX1 PRINT MODE
	rts
GOERR
 	lda #N					;SET DEFAULT PRINT MODE TO NORMAL
	bne CMODE
;*************************************************************
;
;
;	'CASSET HANDLER 3/12 (DK1:CASCV)'
SRSTA	equ $40				;SIO READ STATUS
SWSTA	equ $80				;SIO WRITE STATUS
;MOTRGO	equ $34
;MOTRST	equ $3C
;
;
DTA		equ $FC				;DATA RECORD TYPE BYTE
DT1		equ $FA				;LAST DATA RECORD
EOT		equ $FE				;END OF TAPE
HDR		equ $FB				;HEADER
TONE1	equ 2				;CHANGE TO RECORD MODE TONE
TONE2	equ 1				;PRESS PLAY TONE
;
;
;
	org CASORG				; $EF41
;
;
; INIT ROUTINE
;
INIT
	lda #$CC
	sta CBAUDL
	lda #$05
	sta CBAUDH				;SET CASSET BAUD RATE TO 600
SPECIAL
	rts						;THATS ALL FOLKS
;
; OPEN FUNCTION - WITH NO TIMING ADJUST
;
OPENC
 	lda ICAX2Z				;GET AX2
	sta FTYPE				;SAVE IT FOR FUTURE REFERENCE
	lda ICAX1Z
	and #$0C				;IN AND OUT BITS
	cmp #$04
	beq OPINP
	cmp #$08				;SEE IF OPEN FOR OUTPUT
	beq OPOUT
	rts						;IF ALREADY OPEN, RETURN LEAVING STATUS=$84
OPINP
 	lda #0
	sta WMODE				;SET READ MODE
	sta FEOF				;NO EOF YET
SFH
	lda #TONE2				;TONE FOR PRESS PLAY
	jsr BEEP				;GO BEEP
	bmi OPNRTN				;IF ERROR DURING BEEP
	lda #MOTRGO
	sta PACTL				;TURN MOTOR ON
 ift PALFLG
	ldy #$E0
	ldx #1
 els
	ldy #$40				;5-31-79 9 SEC READ LEADER
	ldx #2
 eif
	lda #3
	sta CDTMF3
	jsr SETVBV				;SET UP YBLANK TIMER
WAITTM
	lda CDTMF3
	bne WAITTM				;WAIT FOR MOTOR TO COME UP TO SPEED
	lda #$80				;NEXT BYTE=NO BYTES IN BUFFER
	sta BPTR
	sta BLIM
	jmp OPOK				;OPEN OK
;
; OPEN FOR OUTPUT
;
PBRK
	ldy #BRKABT				;BREAK KEY ABORT STATUS
	dec BRKKEY				;RESET BREAK KEY
OPNRTN
	lda #0					;CLEAR WRITE MODE FLAG
	sta WMODE
	rts						;AND EXIT.
;
OPOUT
 	lda #$80
	sta WMODE				;SET WRITE MODE
	lda #TONE1				;TELL USER TO TURN ON RECORD MODE
	jsr BEEP
	bmi OPNRTN				;IF ERROR DURING BEEP
	lda #$CC				;SET BAUD RATE
	sta AUDF3				;WHICH SEEMS TO BE NESSECARY
	lda #$05				;FOR SOME OBSCURE REASON
	sta AUDF4
	lda #$60
	sta DDEVIC
	jsr SENDEV				;TELL POKEY TO WRITE MARKS
	lda #MOTRGO				;WRITE 5 SEC BLANK TAPE
	sta PACTL
	lda #3
 ift PALFLG
	ldx #$3
	ldy #$C0
 els
	ldx #4					;5/30/79 20 SEC LEADER
	ldy #$80
 eif
	jsr SETVBV
	lda #$FF
	sta CDTMF3
WDLR
	lda BRKKEY
	beq PBRK				;IF BREAK DURING WRITE LEADER
	lda CDTMF3
	bne WDLR
	lda #0					;INIT BUFFER POINTER
	sta BPTR
OPOK
	ldy #SUCCES
	rts
;
; GET BYTE
;
GBYTE
 	lda FEOF				;IF AT EOF ALREADY
	bmi ISEOF				;RETURN EOF STATUS
	ldx BPTR				;BUFFER POINTER
	cpx BLIM				;IF END OF BUFFER
	beq RBLOK				;READ ANOTHER BLOCK
	lda CASBUF+3,X			;GET NEXT BYTE
	inc BPTR				;DUMP POINTER
	ldy #SUCCES				;OK STATUS
GBX
	rts
RBLOK
 	lda #'R'				;READ OPCODE
	jsr SIOSB				;SIO ON SYS BUF
	tya
	bmi GBX					;IF SIO ERRORS, RETURN
	lda #0
	sta BPTR				;RESET POINTER
	ldx #$80				;DEFAULT # BYTES
	lda CASBUF+2
	cmp #EOT
	beq ATEOF				;IF HEADER, GO READ AGAIN
	cmp #DT1				;IF LAST DATA REC
	bne NLR
	ldx CASBUF+130			;LAST DATA RECORD, GET # BYTES
NLR
	stx BLIM
	jmp GBYTE				;GET NEXT BYTE
ATEOF
 	dec FEOF				;SET FEOF
ISEOF
 	ldy #EOFERR				;ENDFILE STATUS
	rts
;
; PUT BYTE TO BUFFER
;
PBYTE
	ldx BPTR				;BUFFER POINTER
	sta CASBUF+3,X			;STORE CHAR AWAY
	inc BPTR				;BUMP POINTER
	ldy #SUCCES				;OK STATUS
	cpx #127				;IF BUFFER FULL
	beq WRBUF
	rts
; WRITE OUT THE BUFFER
WRBUF
	lda #DTA				;RECORD TYPE = DATA
	jsr WSIOSB				;DO WRITE ON SYSTEM BUFFER
	lda #0
	sta BPTR				;RESET BUFFER POINTER
	rts						;EXIT.
;
; STATUS - RETURN STATUS INFO THRU DVSTAT
;
STATU
 	ldy #SUCCES
	rts
;
; CLOSE
;
CLOSEC
	lda WMODE				;SEE IF WRITING
	bmi CLWRT				;300 CLOSE FOR WRITE
; CLOSE FOR READ - FLAG CLOSED
	ldy #SUCCES				;SUCCESSFULL
FCAX
	lda #MOTRST				;STOP THE MOTOR IN CASE WAS SHORT IRQ MODE
	sta PACTL
	rts
CLWRT
	ldx BPTR				;BUFFER POINTER
	beq WTLR				;IF NO DATA BYTES IN BUFFER, NO DT1 REC
	stx CASBUF+130			;WRITE TO LAST RECORD
	lda #DT1				;REC TYPE
	jsr WSIOSB				;WRITE OUT USER BUFFER
	bmi FCAX				;GO IF ERROR
WTLR
	ldx #127				;ZERO BUFFER
	lda #0
ZTBUF
	sta CASBUF+3,X
	dex
	bpl ZTBUF
	lda #EOT				;WRITE EOT RECORD
	jsr WSIOSB
	jmp FCAX				;FLAG CLOSED AND EXIT
;
; SUBROUTINES
;
; BEEP - GENERATE TONE ON KEYBOARD SPEAKER
; ON ENTRY A= FREQ
;
BEEP
	sta FREQ
BEEP1
 	lda RTCLOK+2			;CURRENT CLOCK
	clc
 ift PALFLG
	adc #25
 els
	adc #30					; 1 SEC TONE
 eif
	tax
WFL
	lda #$FF
	sta CONSOL				;TURN ONSPEAKER
	lda #0
	ldy #$F0
BPLOOP
	dey
	bne BPLOOP
	sta CONSOL				;TURN OFF SPEAKER
	ldy #$F0
BPDLOOP
	dey
	bne BPDLOOP
	cpx RTCLOK+2			;SEE IF 1 SEC IS UP YET
	bne WFL
	dec FREQ				;COUNT BEEPS
	beq WFAK				;IF ALL DONE GO WAIT FOR KEY
	txa
	clc
 ift PALFLG
	adc #8
 els
	adc #10
 eif
	tax
	cpx RTCLOK+2
	bne *-2
	beq BEEP1				;UNCOND DO BEEP AGIN
WFAK
	jsr WFAK1				;USE SIMULATED "JMP (KGETCH)"
	tya
	rts
WFAK1
 	lda KEYBDV+5
	pha
	lda KEYBDV+4			;SIMULATE "JMP (KGETCH)"
	pha
	rts
;
; SIOBS - CALL SIO ON SYSTEM BUFFER
;
SIOSB
	sta DCOMND				;SAVE COMMAND
	lda #0
	sta DBYTHI				;SET BUFFER LENGTH
	lda #131
	sta DBYTLO
	lda #>CASBUF
	sta DBUFHI				;SET BUFFER ADDRESS
	lda #<CASBUF
	sta DBUFLO
CSIO
	lda #$60				;CASSET PSEUDO DEVICE
	sta DDEVIC
	lda #0
	sta DUNIT
	lda #35					;DEVICE TIMEOUT (5/30/79)
	sta DTIMLO
	lda DCOMND				;GET COMMAND SACK
	ldy #SRSTA				;SIO READ STATUS COMMAND
	cmp #'R'
	beq RWSTATUS
	ldy #SWSTA				;SIC WRITE STATUS COMMAND
RWSTATUS
	sty DSTATS				;SET STATUS FOR SIO
	lda FTYPE
	sta DAUX2				;INDICATE IF SHORT IRQ MODE
	jsr SIOV				;GO CALL SIO
	rts
;
; WSIOSB - WRITE SIC SYSTEM SUFFER
;
WSIOSB
	sta CASBUF+2			;STORE TYPE BYTE
	lda #$55
	sta CASBUF+0
	sta CASBUF+1
	lda #'W'				;WRITE
	jsr SIOSB				;CALL SIO ON SYSTEM BUFFER
	rts						;RETURN
;
;	'MONITOR  ***** MONITP.SRC ***** 3/9/79 *****  4:00:00 P
;
;
;
;		 CONSTANT EQUATES
;
PUTTXT	equ $09				;"PUT TEXT RECORD" CIO COMMANDCODE
GETCAR	equ $07				;"GET CHARACTER" CIO COMMAND CODE
PUTCAR	equ $0B				;"PUT CHARACTER" CIO COMMAND CODE
INIMLL	equ $00				;INITIAL HEM LO LOW BYTE
INIMLH	equ $07				;INITIAL HEM LO HIGH BYTE
; GOOD	equ $01				;GOOD STATUS CODE
; WRITE	equ $57				;WRITE COMMAND
; READ	equ $52				;READ COMMAND
; STATC	equ $53				;STATUS COMMAND
SEX		equ $00				;SCREEN EDITOR 10CR INDEX
CLS		equ $7D				;CLEAR SCREEN CODE
CTRLC	equ $92				;KEYBOARD CODE FOR 'CONTROL C'
EOF		equ $88				;CASSETTE END OF FILE CODE
LIRQ	equ $00				;LONG IRQ TYPE CODE
;
;
;
; THE FOLLOWING EQUATES ARE IN THE CARTRIDGE ADDRESS SPACE.
;
;
; "B" CARTRIDGE ADDR'S ARE 8000-9FFF (36K CONFIG. ONLY)
; "A" CART. ADDR'S ARE A000-BFFF (36K CONFIG. ONLY)
;
; "A" CART. ADDR'S ARE B000-BFFF (48K CONFIG. ONLY)
;
CARTCS	equ $BFFA			;CARTRIDGE COLD START ADDRESS
CART	equ $BFFC			;CARTRIDGE AVAILABLE FLAG BYTE
CARTFG	equ $BFFD			;CARTRIDGE FLAG BYTE. BIT 0=FLAG1
CARTAD	equ $BFFE			;2-BYTE CARTRIDGE START VECTOR
;
;
;		 CARTRIDGE FLAG ACTION DEFINITIONS
;
;
;		 BIT				ACTION IF SET
;
;		 7					SPECIAL -- DON'T POWER-UP, JUST RUN CARTRIDGE
;		 6-3				NONE
;		 2					RUN CARTRIDGE
;		 1					NONE
;		 0					BOOT DOS
;
;
;		 *****
;		 NOTE
;		 *****
;
;		 1.IF BIT2 IS 0, GOTO BLACKBOARD MODE.
;		 2.IF BIT0 SET THE DISK WILL BE BOOTED BEFORE ANY
;			OTHER ACTION.
;
;
;
;
;
;
;		 POWER-UP VECTOR
;
;***************************
;		 org $FFFC
;
; PVECT	dta a(PWRUP)				POWER-UP VECTOR
;************************
;
;
;	org $9000
;	jsr $900C
;	jmp PWRUP				;(TO HANDLE RAM VECTOR WRITING)
;	jsr $900C
;	jmp RESET
;
;
;
	org MONORG				; $F0E3
;
;
;
;
;		 HANDLER TABLE ENTRIES
;
TBLENT
	dta b('P'),a(PRINTV)
	dta b('C'),a(CASETV)
	dta b('E'),a(EDITRV)
	dta b('S'),a(SCRENV)
	dta b('K'),a(KEYBDV)
;
;
;TBLLEN	equ IDENT-TBLENT-1  HANDLER TABLE LENGTH.  "MOVED TO LINE 8
;
;		 ***** PRINT MESSAGES *****
;
;
IDENT	dta b(CLS),c'ATARI COMPUTER - MEMO PAD',CR
;
TBLLEN	equ IDENT-TBLENT-1	;HANDLER TABLE LENGTH
;
DERR5	dta c'BOOT ERROR',CR	;DISK ERROR MSG POINTER
;
;
;
;
;
;		 DEVICE/FILENAME SPECIFICATIONS
;
OPNEDT	dta c'E:',CR		;"OPEN SCREEN EDITOR" DEVICE SPEC.
;
;
;
;
;*****************************************************************
;		 RESET BUTTON ROUTINE STARTS HERE
;
;
RESET
 	sei						;DISABLE IRQ INTERRUPTS
	lda COLDST				;WERE WE IN MIDDLE OF COLDSTART?
	bne PWRUP				;YES, GO TRY IT AGAIN
	lda #$FF
	bne PWRUP1				;SET WARM START FLAG
;
;
;
;***************************************************************
;		 POWER UP ROUTINES START HERE
;***************************************************************
;
PWRUP
 	sei						;DISABLE IRQ INTERRUPTS
	lda #0					;CLEAR WARMSTART FLAG
PWRUP1
	sta WARMST
	cld						;CLEAR DECIMAL FLAG.
	ldx #$FF
	txs						;SET STACK POINTER
	jsr SPECL				;CARTRIDGE SPECIAL CASE?
	jsr HARDI				;DO HARDWARE INITIALIZATION
	lda WARMST				;IS IT WARMSTART?
	bne ZOSRAM				;YES, ONLY ZERO OS RAM
;
ZERORM
	lda #0
	ldy #WARMST
	sta RAMLO
	sta RAMLO+1				;INITIALIZE RAM POINTER
CLRRAM
	sta (RAMLO),Y			;CLEAR MEMORY LOC.
	iny
	cpy #0					;AT END OF PAGE?
	bne CLRRAM
	inc RAMLO+1				;YES. INCR PAGE POINTER
	ldx RAMLO+1
	cpx TRAMSZ				;AT END OF MEM?
	bne CLRRAM				;NO.
;
; INITIALIZE DOSVEC TO POINT TO SIGNON (BLACKBOARD)
	lda BLKBDV+1
	sta DOSVEC				;USE BLACKBOARD VECTOR
	lda BLKBDV+2			;FOR DOSVEC
	sta DOSVEC+1
	lda #$FF
	sta COLDST				;SET TO SHOW IN MIDDLE OF COLDSTART
	bne ESTSCM				;GO AROUND ZOSRAM
;
; CLEAR OS RAM (FOR WARMSTART)
ZOSRAM
	ldx #0
	txa
ZOSRM2
	sta $200,X				;CLEAR PAGES 2 AND 3
	sta $300,X
	dex
	bne ZOSRM2
	ldx #INTZBS
ZOSRM3
	sta 0,X					;CLEAR ZERO PAGE LOCATIONS INTZBS-7F
	inx
	bpl ZOSRM3
;
; ESTABLISH SCREEN MARGINS
ESTSCM
	lda #LEDGE
	sta LMARGN
	lda #REDGE
	sta RMARGN
;
;
; MOVE VECTOR TABLE FROM ROM TO RAM
OPSYS
	ldx #$25
MOVVEC
	lda VCTABL,X			;ROM TABLE
	sta INTABS,X			;TO RAM
	dex
	bpl MOVVEC
	jsr OSRAM				;DO O.S. RAM SETUP
	cli						;ENABLE IRQ INTERRUPTS
;
;
;		 LINK HANDLERS
;
	ldx #TBLLEN
NXTENT
	lda TBLENT,X			;READ HANDLER TABLE ENTRY
	sta HATABS,X			;PUT IN TABLE
	dex
	bpl NXTENT				;DONE WITH ALL ENTRIES?
;
;
;
;
;
; INTERROGATE CARTRIDGE ADDR. SPACE TO SEE WHICH CARTRIDGES THERE ARE
;
	ldx #0
	stx TSTDAT				;CLEAR "B" CART. FLAG
	stx TRAMSZ				;CLEAR "A" CART. FLAG
	ldx RAMSIZ
	cpx #$90				;RAM IN "B" CART. SLOT?
	bcs ENDBCK
	lda CART-$2000			;NO.
	bne ENDBCK				;CART. PLUGGED INTO "B" SLOT'?
	inc TSTDAT				;YES, SET "B" CART, FLAG
	jsr CBINI				;INITIALIZE CARTRIDGE "B"
;
ENDBCK
	ldx RAMSIZ
	cpx #$B0				;RAM IN "A" CART. SLOT?
	bcs ENDACK
	ldx CART				;NO,
	bne ENDACK				;CART. PLUGGED INTO "A" SLOT?
	inc TRAMSZ				;YES, SET "A" CART. FLAG
	jsr CAINI				;INITIALIZE CARTRIDGE "A"
;
;
; OPEN SCREEN EDITOR
;
ENDACK
	lda #3
	ldx #SEX
	sta ICCOM,X				;OPEN I/O COMMAND
	lda #<OPNEDT
	sta ICBAL,X
	lda #>OPNEDT
	sta ICBAH,X				;SET BUFFER POINTER TO OPEN SCREEN EDITOR
	lda #$C
	sta ICAX1,X				;SET UP OPEN FOR INPUT/OUTPUT
	jsr CIOV				;GO TO CIO
;
	bpl SCRNOK				;BR IF NO ERROR
	jmp PWRUP				;RETRY PWRUP IF ERROR (SHOULD NEVER HAPPEN!)
SCRNOK
	inx						;SCREEN OK, SO WAIT FOR YBLANK TO
	bne SCRNOK				;BRING UP THE DISPLAY
	iny
	bpl SCRNOK
;
;
; DO CASSETTE BOOT
	jsr CSBOOT				;CHECK, BOOT, AND INIT
;
; CHECK TO SEE IF EITHER CARTRIDGE WANTS DISK BOOT
	lda TRAMSZ				;CHECK BOTH CARTRIDGES
	ora TSTDAT				;
	beq NOCART				;NEITHER CARTRIDGE LIVES
	lda TRAMSZ				;"A" CART?
	beq NOA1				; NO
	lda CARTFG				;GET CARTRIDGE MODE FLAG
NOA1
	ldx TSTDAT				;"B" CART?
	beq NOB1				; NO
	ora CARTFG-$2000		;ADD OTHER FLAG
NOB1
	and #1					;DOES EITHER CART WANT BOOT?
	beq NOBOOT				; NO
;
; DO DISK BOOT
NOCART
	jsr BOOT				;CHECK. BOOT. AND INIT
;
; GO TO ONE OF THE CARTRIDGES IF THEY SO DESIRE
NOBOOT
	lda #0
	sta COLDST				;RESET TO SHOW DONE WITH COLDSTART
	lda TRAMSZ				;"A" CART?
	beq NOA2				; NO
	lda CARTFG				;GET CARTRIDGE MODE FLAG
	and #4					;DOES IT WANT TO RUN?
	beq NOA2				; NO
	jmp (CARTCS)			;RUN "A" CARTRIDGE
NOA2
	lda TSTDAT				;"B" CART?
	beq NOCAR2				; NO
	lda CARTFG-$2000		;GET "B" MODE FLAG
	and #4					;DOES IT WANT TO RUN?
	beq NOCART				; NO
	jmp (CARTCS-$2000)		;RUN "B" CARTRIDGE
;
; NO CARTRIDGES, OR NEITHER WANTS TO RUNS
; SO GO TO DOSVEC (DOS, CASSETTE, OR BLACKBOARD)
NOCAR2
	jmp (DOSVEC)
;
; PRINT SIGN-ON MESSAGE
SIGNON
	ldx #<IDENT
	ldy #>IDENT
	jsr PUTLIN				;GO PUT SIGN-ON MSG ON SCREEN
;
;
;
;		 BLACKBOARD ROUTINE
BLACKB
	jsr BLKB2				;"JSR EGETCH"
	jmp BLACKB				;FOREVER
BLKB2
 	lda EDITRV+5			;HIGH BYTE
	pha
	lda EDITRV+4			;LOW BYTE
	pha
	rts						;SIMULATES "JMP (EDITRV)"
;
;
; CARTRIDGE INITIALIZATION INDIRECT JUMPS
CAINI
 	jmp (CARTAD)
CBINI
 	jmp (CARTAD-$2000)
;
;
;
;
;
;
;					S U B R O U T I N E S
;
;
;
;
;
;
;
; CHECK FOR HOW MUCH RAM & SPECIAL CARTRIDGE CASE.
; IF SPECIAL CARTRIDGE CASE, DON'T GO BACK -- GO TO CART.
;
SPECL
 	lda CART				;CHECK FOR RAM OR CART
	bne ENSPE2				;GO IF NOTHING OR MAYBE RAM
	inc CART				;NOW DO RAM CHECK
	lda CART				;IS IT ROM?
	bne ENSPEC				; NO
	lda CARTFG				; YES,
	bpl ENSPEC				;BIT SET?
	jmp (CARTAD)			; YES, GO RUN CARTRIDGE
;
; CHECK FOR AMOUNT OF RAM
;
;
ENSPEC
	dec CART				;RESTORE RAM IF NEEDED
ENSPE2
	ldy #0
	sty RAMLO+1
	lda #$10
	sta TRAMSZ				;SET RAM POINTER TO 4K.
HOWMCH
	lda (RAMLO+1),Y			;READ RAM LOCATION
	eor #$FF				;INVERT IT.
	sta (RAMLO+1),Y			;WRITE INVERTED DATA.
	cmp (RAMLO+1),Y			;READ RAM AGAIN
	bne ENDRAM
	eor #$FF				;CONVERT IT BACK
	sta (RAMLO+1),Y			;RESTORE ORIGINAL RAMDATA
	lda TRAMSZ
	clc
	adc #$10
	sta TRAMSZ				;INCR. RAM POINTER BY 4K.
	bne HOWMCH				;GO FIND HOW MUCH RAM.
ENDRAM
	rts
;
;
;
;		 HARDWARE INITIALIZATION
;
;
HARDI
 	lda #0
	tax
CLRCHP
	sta $D000,X
	sta $D400,X
	sta $D200,X
	sta $D300,X
	inx
	bne CLRCHP
	rts
;
;
;		 O.S. RAM SETUP
;
OSRAM
 	dec BRKKEY				;TURN OFF BREAK KEY FLAG
	lda #<BRKKY2
	sta BRKKY
	lda #>BRKKY2
	sta BRKKY+1
	lda TRAMSZ				;READ RAM SIZE IN TEMP. REG.
	sta RAMSIZ				;SAVE IT IN RAM SIZE.
	sta MEMTOP+1			;INIT. MEMTOP ADDR HI BYTE
	lda #0
	sta MEMTOP				;INIT. MEMTOP ADDR LO BYTE
	lda #INIMLL
	sta MEMLO
	lda #INIMLH
	sta MEMLO+1				;INITIALIZE MEMLO ADDR VECTOR
	jsr EDITRV+$C			;EDITOR INIT.
	jsr SCRENV+$C			;SCREEN INIT.
	jsr KEYBDV+$C			;KEYBOARD INIT.
	jsr PRINTV+$C			;PRINTER HANDLER INIT
	jsr CASETV+$C			;CASSETTE HANDLER INIT
	jsr CIOINV				;CIO INIT.
	jsr SIOINV				;SIO INIT.
	jsr INTINV				;INTERRUPT HANDLER INIT.
	lda CONSOL
	and #$1
	bne NOKEY				;GAME START KEY DEPRESSED?
	inc CKEY				;YES. SET KEY FLAG.
NOKEY
	rts
;
;
; DO BOOT OF DISK
;
BOOT
	lda WARMST
	beq NOWARM				;WARMSTART?
	lda BOOT?				; YES,
	and #1
	beq NOINIT				;VALID BOOT?
	jsr DINI				; YES, RE-INIT. DOS SOFTWARE
NOINIT
	rts
NOWARM
	lda #1
	sta DUNIT				;ASSIGN DISK DRIVE NO.
	lda #STATC
	sta DCOMND				;SET UPSTATUS COMMAND
	jsr DSKINV				;GO DO DISK STATUS
	bpl DOBOOT				;IS STATUS FROM 510 GOOD?
	rts						; NO, GO BACK WITH BAD BOOT STATUS
;
DOBOOT
	lda #0
	sta DAUX2
	lda #1
	sta DAUX1				;SET SECTOR # TO 1.
	lda #<[CASBUF+3]
	sta DBUFLO
	lda #>[CASBUF+3]
	sta DBUFHI				;SET UP BUFFER ADDR
SECT1
 	jsr GETSEC				;GET SECTOR
	bpl ALLSEC				;STATUS O.K.?
BADDSK
	jsr DSKRDE				; NO, GO PRINT DISK READ ERROR
	lda CASSBT
	beq DOBOOT				;CASSETTE BOOT?
	rts						; YES, QUIT
ALLSEC
	ldx #3
RDBYTE
	lda CASBUF+3,X			;READ A BUFFER BYTE
	sta DFLAGS,X			;STORE IT
	dex
	bpl RDBYTE				;DONE WITH 4 BYTE TRANSFER
	lda BOOTAD				; YES.
	sta RAMLO
	lda BOOTAD+1
	sta RAMLO+1				;PUT BOOT ADDR INTO Z. PAGE RAM
	lda CASBUF+7
	sta DOSINI				;ESTABLISH DOS INIT ADDRESS
	lda CASBUF+8
	sta DOSINI+1
MVBUFF
	ldy #$7F				;YES, SET BYTE COUNT
MVNXB
 	lda CASBUF+3,Y
	sta (RAMLO),Y			;MOVE A BYTE FROM SECTOR BUFFER TO BOOT ADDR
	dey
	bpl MVNXB				;DONE ?
	clc						; YES,
	lda RAMLO
	adc #$80
	sta RAMLO
	lda RAMLO+1
	adc #0
	sta RAMLO+1				;INCR BOOT LOADER BUFFER POINTER
	dec DBSECT				;DECR # OF SECTORS.
	beq ENBOOT				;MORE SECTORS ?
	inc DAUX1				; YES INCR SECTOR #
SECTX
 	jsr GETSEC				;GO GET SECTOR.
	bpl MVBUFF				;STATUS O.K. ?
	jsr DSKRDE				; NO, GO PRINT DISK READ ERROR
	lda CASSBT
	bne BADDSK				;IF CASSETTE, QUIT.
	beq SECTX				;IF DISK, TRY SECTOR AGAIN.
ENBOOT
	lda CASSBT
	beq XBOOT				;A CASSETTE BOOT ?
	jsr GETSEC				; YES, GET EOF RECORD, BUT DON'T USE IT.
XBOOT
 	jsr BLOAD				;GO EXECUVE BOOT LOADER
	bcs BADDSK				;IF BAD BOOT, DO IT OVER AGAIN
	jsr DINI				;GO INIT. SOFTWARE
	inc BOOT?				;SHOW BOOT SUCCESS
	rts
BLOAD
 	clc
	lda BOOTAD
	adc #6
	sta RAMLO
	lda BOOTAD+1
	adc #0
	sta RAMLO+1				;PUT START ADDR OF BOOTLOADER INTO RAM
	jmp (RAMLO)
DINI
	jmp (DOSINI)
;
;
;
;
; DISPLAY DISK READ ERROR MSG
;
DSKRDE
	ldx #<DERR5
	ldy #>DERR5
;
;
;
; PUT LINE ON SCREEN AT PRESENT CURSOR POSITION
;
;	X-REG -- LO BYTE, BEGIN ADDR OF LINE
;	Y-REG -- HI BYTE, BEGIN ADDR OF LINE
;
PUTLIN
	txa
	ldx #SEX
	sta ICBAL,X
	tya
	sta ICBAH,X				;SET UP ADDR OF BEGIN OF LINE
	lda #PUTTXT
	sta ICCOM,X				;"PUT TEXT RECORD" COMMAND
	lda #$FF
	sta ICBLL,X				;SET BUFFER LENGTH
	jsr CIOV				;PUT LINE ON SCREEN
	rts
;
;
;
;
; GET SECTOR FROM DISK 0
;
GETSEC
	lda CASSBT
	beq DISKM				;CASSETTE BOOT?
	jmp RBLOKV				;YES, GO TO READ BLOCK ROUTINE
DISKM
 	lda #READ
	sta DCOMND				;SET READ SECTOR COMMAND
	lda #1
	sta DUNIT				;SET DRIVE NO. TO DRIVE 0
	jsr DSKINV				;GET SECTOR
	rts
;
;
;
; DO CHECK FOR CASSETTE BOOT & IF SO DO BOOT
;
CSBOOT
	lda WARMST				;WARMSTART?
	beq CSBOT2				; NO
	lda BOOT?				;GET BOOT FLAG
	and #2					;WAS CASSETTE BOOT SUCCESFULL?
	beq NOCSB2				; NO
	jsr CINI				; YES, INIT CASSETTE SOFTWARE
NOCSB2
	rts
;
CSBOT2
	lda CKEY
	beq NOCSBT				;"C" KEY FLAG SET ?
	lda #$80				; YES,
	sta FTYPE				;SET LONG IRQ TYPE
	inc CASSBT				;SET CASSETTE BOOT FLAG
	jsr CSOPIV				;OPEN CASSETTE FOR INPUT
	jsr SECT1				;DO BOOT & INIT.
	lda #0
	sta CASSBT				;RESET CASSETTE BOOT FLAG
	sta CKEY				;CLEAR KEY FLAG
	asl BOOT?				;SHIFT BOOT FLAG (NOW=2 IF SUCCESS)
	lda DOSINI
	sta CASINI				;MOVE INIT ADDRESS FOR CASSETTE
	lda DOSINI+1
	sta CASINI+1
NOCSBT
	rts
;
CINI
	jmp (CASINI)	 ;INIT CASSETTE
;****************************************************************
;
;	'DISPLAY HANDLER  -- 10-30-78 -- DISPLC'
;
; HANDLER DEPENDENT EQUATES
;
CLRCOD	equ $7D				;CLEAR SCREEN ATASCI CODE
CNTL1	equ $9F				;POKEY KEY CODE FOR ^1
;
FRMADR	equ SAVADR
TOADR	equ MLTTMP
;
;
	org KBDORG				; $F3E4
;
PWRONA
	lda #$FF
	sta CH
	lda MEMTOP+1
	and #$F0				;INSURE 4K PAGE BOUNDARY
	sta RAMTOP
	lda #$40				;DEFAULT TO UPPER CASE ALPHA AT PWRON
	sta SHFLOK
	rts						;POWER ON COMPLETED
;
;
; BEGIN DISPLAY HANDLER OPEN PROCESSING
;
DOPEN
 	lda ICAX2Z				;GET AUX 2 BYTE
	and #$F
	bne OPNCOM				;IF MODE ZERO, CLEAR ICAX1Z
EOPEN
 	lda ICAX1Z				;CLEAR "CLR INHIBIT" AND "MXD MODE" BITS
	and #$F
	sta ICAX1Z
	lda #0
OPNCOM
	sta DINDEX
	lda #$E0				;INITIALIZE GLOBAL VBLANK RAM
	sta CHBAS
	lda #2
	sta CHACT
	sta SDMCTL				;TURN OFF DMA NEXT VBLANK
	lda #SUCCES
	sta DSTAT				;CLEAR STATUS
	lda #$C0				;DO IRQEN
	ora POKMSK
	sta POKMSK
	sta IRQEN
	lda #0
	sta TINDEX				;TEXT INDEX MUST ALWAYS BE 0
	sta ADRESS
	sta SWPFLG
	sta CRSINH				;TURN CURSOR ON ATOPEN
	ldy #14					;CLEAR TAB STOPS
	lda #1					;INIT TAB STOPS TO EVERY 8 CHARACTERS
CLRTBS
	sta TABMAP,Y
	dey
	bpl CLRTBS
	ldx #4					;LOAD COLOR REGISTERS
DOPEN8
	lda COLRTB,X
	sta COLOR0,X
	dex
	bpl DOPEN8
	ldy RAMTOP				;DO TXTMSC=$2C40 (IF MEMTOP=3000)
	dey
	sty TXTMSC+1
	lda #$60
	sta TXTMSC
	ldx DINDEX
	lda ANCONV,X			;CONVERT IT TO ANTIC CODE
	bne DOPENA				;IF ZERO, IT IS ILLEGAL
OPNERR
	lda #BADMOD				;SET ERROR STATUS
	sta DSTAT
DOPENA
	sta HOLD1
	lda RAMTOP				;SET UP AN INDIRECT POINTER
	sta ADRESS+1
	ldy ALOCAT,X			;ALLOCATE N BLOCKS OF 40 BYTES
DOPEN1
	lda #40
	jsr DBSUB
	dey
	bne DOPEN1
	lda GPRIOR				;ICLEAR GTIA MODES
	and #$3F
	sta OPNTMP+1
	tay
	cpx #8					;TEST IF 320X1
	bcc NOT8
	txa						;GET 2 LOW BITS
	ror @
	ror @
	ror @
	and #$C0				;NOW 2 TOP BITS
	ora OPNTMP+1
	tay
	lda #16					;SUBTRACT 16 MORE FOR PAGE BOUNDARY
	jsr DBSUB
	cpx #11					;TEST MODE 11
	bne NOT8				;IF MODE = 11
	lda #6					;PUT GTIA LUM VALUE INTO BACKGROUND REGISTER
	sta COLOR4
NOT8
	sty GPRIOR				;STORE NEW PRIORITY
	lda ADRESS				;SAVE MEMORY SCAN COUNTER ADDRESS
	sta SAVMSC
	lda ADRESS+1
	sta SAVMSC+1
VBWAIT
	lda VCOUNT				;WAIT FOR NEXT VBLANK BEFORE MESSING
	cmp #$7A				;WITH THE DISPLAY LIST
	bne VBWAIT
	jsr DBDEC				;START PUTTING DISPLAY LIST RIGHT UNDER RAM
	lda PAGETB,X			;TEST IF DISPLAY LIST WILL BE IN TROUBLE
	beq NOMOD				;OF CROSSING A 256 BYTE PAGE BOUNDARY
	lda #$FF				;IF SO, DROP DOWN A PAGE
	sta ADRESS
	dec ADRESS+1
NOMOD
 	lda ADRESS				;SAVE END OF DISPLAY LIST FOR LATER
	sta SAVADR
	lda ADRESS+1
	sta SAVADR+1
	jsr DBDDEC				;(DOUBLE BYTE DOUBLE DECREMENT)
	lda #$41				;(ANTIC) WAIT FOR VBLANK AND JMP TO TOP
	jsr STORE
	stx OPNTMP
	lda #24					;INITIALIZE BOTSCR
	sta BOTSCR
	lda DINDEX				;DISALLOW MIXED MODE IF MODE.GE.9
	cmp #9
	bcs NOTMXD
	lda ICAX1Z				;TEST MIXED MODE
	and #$10
	beq NOTMXD
	lda #4
	sta BOTSCR
	ldx #2					;ADD 4 LINES OF TEXT AT BOTTOM OF SCREEN
DOPEN2
	lda #2
	jsr STORE
	dex
	bpl DOPEN2
	ldy RAMTOP				;RELOAD MSC FOR TEXT
	dey
	tya
	jsr STORE
	lda #$60
	jsr STORE
	lda #$42
	jsr STORE
	clc
	lda #MXDMDE-NUMDLE		;POINT X AT MIXED MODE TABLE
	adc OPNTMP
	sta OPNTMP
NOTMXD
	ldy OPNTMP
	ldx NUMDLE,Y			;GET NUMBER OF DISPLAY LIST ENTRIES
DOPEN3
	lda HOLD1				;STORE N DLE'S
	jsr STORE
	dex
	bne DOPEN3
	lda DINDEX				;DO THE MESSY 320X1 PROBLEM
	cmp #8
	bcc DOPEN5
	ldx #93					;GET REMAINING NUMBER OF DLE'S
	lda RAMTOP				;RELOAD MEMORY SCAN COUNTER
	sec
	sbc #$10
	jsr STORE
	lda #0
	jsr STORE
	lda #$4F				;(ANTIC) RELOAD MSC CODE
	jsr STORE
DOPEN4
	lda HOLD1				;DO REMAINING DLE'S
	jsr STORE
	dex
	bne DOPEN4
DOPEN5
	lda SAVMSC+1			;POLISH OFF DISPLAY LIST
	jsr STORE
	lda SAVMSC
	jsr STORE
	lda HOLD1
	ora #$40
	jsr STORE
	lda #$70				;24 BLANK LINES
	jsr STORE
	lda #$70
	jsr STORE
	lda ADRESS				;SAVE DISPLAY LIST ADDRESS
	sta SDLSTL
	lda ADRESS+1
	sta SDLSTL+1
	lda #$70				;ADD LAST BLANK LINE ENTRY
	jsr STORE				;POSITION ADRESS=SDLSTL-1
	lda ADRESS				;STORE NEW MEMTOP
	sta MEMTOP
	lda ADRESS+1
	sta MEMTOP+1
	lda SAVADR
	sta ADRESS
	lda SAVADR+1
	sta ADRESS+1
	lda SDLSTL+1
	jsr STORE
	lda SDLSTL
	jsr STORE
	lda DSTAT				;IF ERROR OCURRED ON ALLOCATION, OPEN THE ED
	bpl DOPEN9
	pha						;SAVE STATUS
	jsr EOPEN				;OPEN THE EDITOR
	pla						;RESTORE STATUS
	tay						;AND RETURN IT TO CIO
	rts
DOPEN9
	lda ICAX1Z				;TEST CLEAR INHIBIT BIT
	and #$20
	bne DOPEN7
	jsr CLRSCR				;CLEAR SCREEN
	sta TXTROW				;AND HOME TEXT CURSOR (AC IS ZERO)
	lda LMARGN
	sta TXTCOL
DOPEN7
	lda #$22				;EVERYTHING ELSE IS SET UP
	ora SDMCTL				;SO TURN ON DMACTL
	sta SDMCTL
	jmp RETUR2
;
;
GETCH
 	jsr RANGE				;GETCH DOES INCRSR. GETPLT DOESN'T
	jsr GETPLT
	jsr INATAC				;CONVERT INTERNAL CODE TO ATASCII
	jsr INCRSB
	jmp RETUR1
GETPLT
	jsr CONVRT				;CONVERT ROW/COLUMN TO ADRESS
	lda (ADRESS),Y
	and DMASK
SHIFTD
	lsr SHFAMT				;SHIFT DATA DOWN TO LOW BITS
	bcs SHIFT1
	lsr @
	bpl SHIFTD				;(UNCONDITIONAL)
SHIFT1
	sta CHAR
	cmp #0					;RESTORE FLAGS ALSO
	rts
;
;
;
OUTCH
	sta ATACHR
	jsr RANGE
;	jsr OFFCRS
OUTCHA
	lda ATACHR				;TEST FOR CLEAR SCREEN
	cmp #CLRCOD
	bne OUTCHE
	jsr CLRSCR
	jmp RETUR2
OUTCHE
	lda ATACHR				;TEST FOR CARRIAGE RETURN
	cmp #CR
	bne OUTCHB
	jsr DOCRWS				;DO CR
	jmp RETUR2
OUTCHB
	jsr OUTPLT
	jsr INCRSR
	jmp RETUR2
;
;
OUTPLT
	lda SSFLAG				;*****LOOP HERE IF START/STOP FLAG ISNON-0
	bne OUTPLT
	ldx #2
CRLOOP
	lda ROWCRS,X			;SAVE CURSOR LOCATION FOR DRAW LINE TO DRAW
	sta OLDROW,X
	dex
	bpl CRLOOP
	lda ATACHR				;CONVERT ATASCII(ATACHR) TO INTERNAL(CHAR)
	tay						;SAVE ATACHR
	rol @
	rol @
	rol @
	rol @
	and #3
	tax						;X HAS INDEX INTO ATAINT
	tya						;RESTORE ATACHR
	and #$9F				;STRIP OFF COLUMN ADDRESS
	ora ATAINT,X			;OR IN NEW COLUMN ADDRESS
OUTCH2
	sta CHAR
	jsr CONVRT
	lda CHAR
SHIFTU
	lsr SHFAMT				;SHIFT UP TO PROPER POSITION
	bcs SHIFT2
	asl @
	jmp SHIFTU
SHIFT2
	and DMASK
	sta TMPCHR				;SAVE SHIFTED DATA
	lda DMASK				;INVERT MASK
	eor #$FF
	and (ADRESS),Y			;MASK OFF OLD DATA
	ora TMPCHR				;OR IN NEW DATA
	sta (ADRESS),Y
	rts
;
;
RETUR2
	jsr GETPLT				;DO CURSOR ON THE WAY OUT
	sta OLDCHR
	ldx DINDEX				;GRAPHICS HAVE INVISIBLE CURSOR
	bne RETUR1
	ldx CRSINH				;TEST CURSOR INHIBIT
	bne RETUR1
	eor #$80				;TOGGLE MSB
	jsr OUTCH2				;DISPLAY IT
RETUR1
	ldy DSTAT				;RETURN TO CIO WITH STATUS IN Y
	lda #SUCCES
	sta DSTAT				;SET STATUS= SUCCESSFUL COMPLETION
	lda ATACHR				;PUT ATACHR IN AC FOR RETURN TO CIO
NOFUNC
	rts						;(NON-EXISTENT FUNCTION RETURN POINT)
;
;
;
; END OF DISPLAY HANDLER
;
;
;
;
;
EGETCH
	jsr SWAP
	jsr ERANGE
	lda BUFCNT				;ANYTHING IN THE BUFFER?
	bne EGETC3				; YES
	lda ROWCRS				; NO, SO SAVE BUFFER START ADDRESS
	sta BUFSTR
	lda COLCRS
	sta BUFSTR+1
EGETC1
	jsr KGETCH				;LET'S FILL OUR BUFFER
	sty DSTAT				;SAVE KEYBOARD STATUS
	lda ATACHR				;TEST FOR CR
	cmp #CR
	beq EGETC2
	jsr DOSS				;NO, GO PRINT IT
	jsr SWAP				;JSR DOSS DID SWAP SO SWAP BACK
	lda LOGCOL				;BEEP IF NEARING LOGICAL COL 120
	cmp #113
	bne EGETC6
	jsr BELL
EGETC6
	jmp EGETC1
EGETC2
	jsr OFFCRS				;GET BUFFER COUNT
	jsr DOBUFC
	lda BUFSTR				;RETURN A CHARACTER
	sta ROWCRS
	lda BUFSTR+1
	sta COLCRS
EGETC3
	lda BUFCNT
	beq EGETC5
EGETC7
	dec BUFCNT				;AND RETURN TILL BUFCNT=0
	beq EGETC5
	lda DSTAT				;IF ERR, LOOP ON EGETC7 UNTIL BUFR IS E1IPTIE
	bmi EGETC7
	jsr GETCH
	sta ATACHR
	jmp SWAP				;AND RETURN WITHOUT TURNING CURSOR BACK ON
EGETC5
	jsr DOCRWS				;DO REAL CARRIAGE RETURN
	lda #CR					;AND RETURN EOL
	sta ATACHR
	jsr RETUR2				;TURN ON CURSOR THEN SWAP
	sty DSTAT				;SAVE KEYBOARD STATUS
	jmp SWAP				;AND RETURN THROUGH RETUR1
;
JSRIND
	jmp (ADRESS)			;J5R TO THIS CAUSES JSR INDIRECT
;
EOUTCH
	sta ATACHR				;SAVE ATASCII VALUE
	jsr SWAP
	jsr ERANGE
DOSS
	jsr OFFCRS				;TURN OFF CURSOR
	jsr TSTCTL				;TEST FOR CONTROL CHARACTERS (Z=1 IF CTL)
	beq EOUTC5
EOUTC6
	asl ESCFLG				;ESCFLG ONLY WORKS ONCE
	jsr OUTCHE
ERETN
 	jmp SWAP				;AND RETURN THROUGH RETUR1
EOUTC5
	lda DSPFLG				;DO DSPFLG AND ESCFLC
	ora ESCFLG
	bne EOUTC6				;IF NON-0 DISPLAY RATHER THAN EXECUTE IT
	asl ESCFLG
	inx						;PROCESS CONTROL CHARACTERS
	lda CNTRLS,X			;GET DISPLACEMENT INTO ROUTINE
	sta ADRESS
	lda CNTRLS+1,X			;GET HIGH BYTE
	sta ADRESS+1
	jsr JSRIND				;DO COMPUTED JSR
	jsr RETUR2				;DO CURSOR
	jmp SWAP				;ALL DONE SO RETURN THROUGH RETUR1
;
;
;
;
; END SCREEN EDITOR.
;
;
; BEGIN KEYBOARD HANDLER
;
;
;
;
KGETC2
	lda #$FF
	sta CH
KGETCH
	lda ICAX1Z				;TEST LSB OF AUX1 FOR SPECIAL EDITOR READ MO
	lsr @
	bcs GETOUT
	lda #BRKABT
	ldx BRKKEY				;TEST BREAK
	beq K7					;IF BREAK, PUT BRKABT IN DSTAT AND CRIN ATA
	lda CH
	cmp #$FF
	beq KGETCH
	sta HOLDCH				;SAVE CH FOR SHIFT LOCK PROC
	ldx #$FF				;"CLEAR" CH
	stx CH
	jsr CLICK				;DO KEYBOARD AUDIO FEEDBACK (A IS OK)
KGETC3
	tax						;DO ASCCON
	cpx #$C0				;TEST FOR CTL & SHIFT TOGETHER
	bcc ASCCO1
	ldx #3					;BAD CODE
ASCCO1
	lda ATASCI,X
	sta ATACHR				;DONE
	cmp #$80				;DO NULLS
	beq KGETC2
	cmp #$81				;CHECK ATARI KEY
	bne KGETC1
	lda INVFLG
	eor #$80
	sta INVFLG
	jmp KGETC2				;DONT RETURN A VALUE
KGETC1
	cmp #$82				;CAPS/LOWER.
	bne K1
	lda #0					;CLEAR SHFLOK
	sta SHFLOK
	beq KGETC2
K1
 	cmp #$83				;SHIFT CAPS/LOWER
	bne K2
	lda #$40
	sta SHFLOK				;SHIFT BIT
	bne KGETC2
K2
 	cmp #$84				;CNTL CAPS/LOWER
	bne K3
	lda #$80				;CNTL BIT
	sta SHFLOK
	bne KGETC2
K3
 	cmp #$85				;DO EOF
	bne K6
	lda #EOFERR
K7
	sta DSTAT
	sta BRKKEY				;RESTORE BREAK
GETOUT
	lda #CR					;PUT CR IN ATACHR
	bne K8					;(UNCONDITIONAL)
K6
 	lda HOLDCH				;PROCESS SHIFT LOCKS
	cmp #$40				;REGULAR SHIFT AND CONTROL TAKE PRECEDENCE
	bcs K5					; OVER LOCK
	lda ATACHR				;TEST FOR ALPHA
	cmp #$61				;LOWER CASE A
	bcc K5					; NOT ALPHA IF LT
	cmp #$7B				;LOWER CASE Z+1
	bcs K5					; NOT ALPHA IF GE
	lda SHFLOK				;DO SHIFT/CONTROL LOCK
	beq K5					; IF NO LOCK. DONT RE-DO IT
	ora HOLDCH
	jmp KGETC3				;DO RETRY
K5
 	jsr TSTCTL				;DONT INVERT M58 OF CONTROL CHARACTERS
	beq K4
	lda ATACHR
	eor INVFLG
K8
	sta ATACHR
K4
 	jmp RETUR1				;ALL DONE
;
;
;
;CONTROL CHARACTER PROCESSORS
;
ESCAPE
	lda #$80				;SET ESCAPE FLAG
	sta ESCFLG
	rts
CRSRUP
	dec ROWCRS
	bpl COMRET
	ldx BOTSCR				;WRAPAROUND
	dex
UPDNCM
	stx ROWCRS
COMRET
	jmp STRBEG				;CULVERT ROW AND COL TO LOGCOL AND RETURN
CRSRDN
	inc ROWCRS
	lda ROWCRS
	cmp BOTSCR
	bcc COMRET
	ldx #0
	beq UPDNCM				;(UNCONDITIONAL)
CRSRLF
	dec COLCRS
	lda COLCRS
	bmi CRSRL1				;(IF LMARGN=0, THIS ELIMINATES PROBLEM CASE)
	cmp LMARGN
	bcs COMRE1
CRSRL1
	lda RMARGN
LFRTCM
	sta COLCRS
COMRE1
	jmp DOLCOL				;COLVERT ROW AND COL TO LOGCOL AND RETURN
CRSRRT
	inc COLCRS
	lda COLCRS
	cmp RMARGN
	bcc COMRE1
	beq COMRE1				;(CAUSE OLE)
	lda LMARGN
	jmp LFRTCM				;UNCONDITIONAL TO COMMON STORE
CLRSCR
	jsr PUTMSC
	ldy #0
	tya						;PUT 0 IN THEAC
CLRSC2
	sta (ADRESS),Y			;(AC IS ZERO)
	iny
	bne CLRSC2
	inc ADRESS+1
	ldx ADRESS+1
	cpx RAMTOP
	bcc CLRSC2
	lda #$FF				;CLEAN UP LOGICAL LINE BITMAP
CLRSC3
	sta LOGMAP,Y			;(Y IS ZERO AFTER CLRSC2 LOOP)
	iny
	cpy #4
	bcc CLRSC3
HOME
	jsr COLCR				;PLACE COLCRS AT LEFT EDGE
	sta LOGCOL
	sta BUFSTR+1
	lda #0
	sta ROWCRS
	sta COLCRS+1
	sta BUFSTR
	rts
;
BS
 	lda LOGCOL				;BACKSPACE
	cmp LMARGN
	beq BS1
BSA
	lda COLCRS				;LEFT EDGE?
	cmp LMARGN
	bne BS3					;NO
	jsr DELTIM				;YES, SEE IF LINE SHOULD BE DELETED
BS3
	jsr CRSRLF
	lda COLCRS
	cmp RMARGN
	bne BS2
	lda ROWCRS
	beq BS2
	jsr CRSRUP
BS2
	lda #$20				;MAKE BACKSPACE DESTRUCTIVE
	sta ATACHR
	jsr OUTPLT
BS1
	jmp DOLCOL				;AND RETURN
TAB
	jsr CRSRRT				;BEGIN SEARCH
	lda COLCRS				;TEST FOR NEW LINE
	cmp LMARGN
	bne TAB1				;NO
	jsr DOCR				;DO CARRIAGE RETURN
	jsr LOGGET				;CHECK IF END OF LOGICAL LINE
	bcc TAB1				;NO, CONTINUE
	bcs TAB2				;(UNCONDITIONAL)
TAB1
	lda LOGCOL				;CHECK FOR TAB STOP
	jsr BITGET
	bcc TAB					;NO, SO KEEP LOOKING
TAB2
	jmp DOLCOL				;CULVERT ROW AND COL TO LOGCOL AND RETURN
SETTAB
	lda LOGCOL
	jmp BITSET				;SET BIT IN MAP AND RETURN
CLRTAB
	lda LOGCOL
	jmp BITCLR				;CLEAR " " " " "
INSCHR
	jsr	phaCRS
	jsr GETPLT				;GET CHARACTER UNDER CURSOR
	sta INSDAT
	lda #0
	sta SCRFLG
INSCH4
	jsr OUTCH2				;STORE DATA
	lda LOGCOL				;SAVE LOGCOL: IF AFTER INCRSA LOGCOL IS
	pha						; < THAN IT IS NOW, END LOOP
	jsr INCRSA				;SPECIAL INCRSR ENTRY POINT
	pla
	cmp LOGCOL
	bcs INSCH3				;QUIT
INSCH1
	lda INSDAT				;KEEP GOING
	pha
	jsr GETPLT
	sta INSDAT
	pla
	jmp INSCH4
INSCH3
	jsr PLACRS
INSCH6
	dec SCRFLG
	bmi INSCH5				;IF SCROLL OCCURRED
	dec ROWCRS				;MOVE CURSOR UP
	bne INSCH6				;(UNCOND) CONTINUE UNTIL SCRFLG IS MINUS
INSCH5
	jmp DOLCOL				;CULVERT ROW AND COL TO LOGCOL AND RETURN
;
;
DELCHR
	jsr	phaCRS
DELCH1
	jsr CONVRT				;GET DATA TO THE RIGHT OF THE CURSOR
	lda ADRESS
	sta SAVADR				;SAVE ADRESS TO KNOW WHERE TO PUT DATA
	lda ADRESS+1
	sta SAVADR+1
	lda LOGCOL
	pha
	jsr INCRSB				;PUT CURSOR OVER NEXT CHARACTER
	pla
	cmp LOGCOL				;TEST NEW LOGCOL AGAINST OLD LOGCOL
	bcs DELCH2				;IF OLD.GE.NEW THEN QUIT
	lda ROWCRS				;IS ROW OFF SCREEN?
	cmp BOTSCR
	bcs DELCH2				;YES, SO QUIT
	jsr GETPLT				;GET DATA UNDER CURSOR
	ldy #0
	sta (SAVADR),Y			;PUT IT IN PREVIOUS POSITION
	beq DELCH1				;AND LOOP (UNCONDITIONAL)
DELCH2
	ldy #0
	tya
	sta (SAVADR),Y			;CLEAR THE LAST POSITION
	jsr DELTIA				;TRY TO DELETE A LINE
	jsr PLACRS
	jmp DOLCOL				;AND RETURN
INSLIN
	sec						;INSLIN PUTS "1" INTO BIT MAP
INSLIA
	jsr EXTEND				;ENTRY POINT FOR C=0
	lda LMARGN				;DO CARRIAGE RETURN (NO LF)
	sta COLCRS
	jsr CONVRT				;GET ADDRESS
	lda ADRESS				;SET UP TO=40+FROM (FROM = CURSOR)
	sta FRMADR
	clc
	adc #40
	sta TOADR
	lda ADRESS+1
	sta FRMADR+1
	adc #0
	sta TOADR+1
	ldx ROWCRS				;SET UP LOOP COUNTER
	cpx #23
	beq INSLI2
INSLI1
	jsr MOVLIN
	inx
	cpx #23
	bne INSLI1
INSLI2
	jsr CLRLIN				;CLEAR CURRENT LINE
	jmp DOLCOL				;COLVERT ROW AND COL TO LOGCOL AND RETURN
DELLIN
	jsr DOLCOL				;GET BEGINNING OF LOG LINE (HOLD1)
DELLIA
	ldy HOLD1				;SQUEEZE BIT MAP
	sty ROWCRS				;PUT CURSOR THERE
DELLIB
	ldy ROWCRS
DELLI1
	tya
	sec
	jsr LO2GET				;GET NEXT BIT
	php
	tya
	clc
	adc #120
	plp
	jsr BITPUT				;WRITE IT OVER PRESENT BIT
	iny
	cpy #24
	bne DELLI1				;LOOP
	lda LOGMAP+2			;SET LSB
	ora #1
	sta LOGMAP+2
DELLI2
	lda LMARGN				;DELETE LINE OF DATA USING PART OF SCROLL
	sta COLCRS				;CR NO LF
	jsr CONVRT
	jsr SCROL1
	jsr LOGGET				;TEST NEXT LINE FOR CONTINUATION
; IS IT A NEW LOG LINE?
	bcc DELLIB				;NO SO DELETE ANOTHER
	jmp DOLCOL				;YES SO DOLCOL AND RETURN
BELL
	ldy #$20
BELL1
 	jsr CLICK
	dey
	bpl BELL1
	rts
;
;
; ROUTINES
;
;
; DOUBLE BYTE DECREMENT OF INDIRECT POINTER
; INCLUDING DB SUBTRACT AND DB DOUBLE DECREMENT
;
DBDDEC
	lda #2
	bne DBSUB				;(UNCONDITIONAL)
;
; STORE DATA INDIRECT AND DECREMENT POINTER
; (PLACED HERE TO SAVE JMP DBDEC AFTER STORE)
STORE
 	ldy DSTAT				;RETURN ON ERROR
	bmi STROK
	ldy #0
STOREI
	sta (ADRESS),Y
;	jmp DBDEC				;DECREMENT AND RETURN
;
DBDEC
 	lda #1
DBSUB
	sta SUBTMP
	lda DSTAT				;RETURN ON ERROR
	bmi STROK
	lda ADRESS
	sec
	sbc SUBTMP
	sta ADRESS
	bcs DBSUB1
	dec ADRESS+1
DBSUB1
	lda APPMHI+1			;MARE SURE NOTHING EVER OVERWRITES APPMHI
	cmp ADRESS+1
	bcc STROK				;OK
	bne STRERR				;ERROR
	lda APPMHI
	cmp ADRESS
	bcc STROK
STRERR
	lda #SCRMEM				;SHOW MEM TOO SMALL FOR SCREEN ERROR
	sta DSTAT
STROK
	rts
;
;
;
; CONVERT ROW/COLUMN CURSOR INTO REAL ADDRESS (FROM SAVMSC ON UP)
;
CONVRT
	lda ROWCRS				;SAVE CURSOR
	pha
	lda COLCRS
	pha
	lda COLCRS+1
	pha
	jsr PUTMSC
	lda ROWCRS				;PUT 10*ROWCRS INTO MLTTMP
	sta MLTTMP
	lda #0
	sta MLTTMP+1
	lda MLTTMP				;QUICK X8
	asl @
	rol MLTTMP+1
	sta HOLD1				;(SAVE 2X VALUE)
	ldy MLTTMP+1
	sty HOLD2
	asl @
	rol MLTTMP+1
	asl @
	rol MLTTMP+1
	clc						;ADD IN 2X
	adc HOLD1
	sta MLTTMP
	lda MLTTMP+1
	adc HOLD2
	sta MLTTMP+1
	ldx DINDEX				;NOW SHIFT MLTTMP LEFT DHLINE TIMES TO FINIS
	ldy DHLINE,X			;MULTIPLY
CONVR1
	dey						;LOOP N TIMES
	bmi CONVR2
	asl MLTTMP
	rol MLTTMP+1
	jmp CONVR1
CONVR2
	ldy DIV2TB,X			;NOW DIVIDE HCRSR TO ACCOUNT FOR PARTIAL BYT
	lda COLCRS
	ldx #7					;* TRICKY *
CONVR3
	dey
	bmi CONVR4
	dex
	lsr COLCRS+1
	ror @
	ror TMPLBT				;SAVE LOW BITS FOR MASK
	jmp CONVR3
CONVR4
	iny						;SO Y IS ZERO UPON RETURN FROM THIS ROUTINE
	clc
	adc MLTTMP				;ADD SHIFTED COLCRS TO MLTThP
	sta MLTTMP
	bcc CONVR5
	inc MLTTMP+1
CONVR5
	sec						;* TRICKY *
CONVR6
	ror TMPLBT				;SLIDE A "1" UP AGAINST LOW BITS (CONTINUE T
	clc
	dex						;AND FINISH SHIFT SO LOW BITS ARE
	bpl CONVR6				;RIGHT JUSTIFIED.
	ldx TMPLBT				;TMPLBT IS NOW THE INDEX INTO DMASKTB
	lda MLTTMP				;PREPARE FOR RETURN
	clc
	adc ADRESS
	sta ADRESS
	sta OLDADR				;REMEMBER THIS ADDRESS FOR CURSOR
	lda MLTTMP+1
	adc ADRESS+1
	sta ADRESS+1
	sta OLDADR+1
	lda DMASKT,X
	sta DMASK
	sta SHFAMT
	pla
	sta COLCRS+1
	pla
	sta COLCRS
	pla
	sta ROWCRS
	rts
;
;
; INCREMENT CURSOR AND DETECT BOTH END OF LINE AND END OF SCREEN
;
INCRSB
	lda #0					;NON-EXTEND ENTRY POINT
	beq INCREC
INCRSR
	lda #$9B				;SPECIAL CASE ELIMINATOR
INCREC
	sta INSDAT
INCRSA
	inc LOGCOL				;(INSCHR ENTRY POINT)
	inc COLCRS
	bne INCRS2				;DO HIGH BYTE
	inc COLCRS+1
INCRS2
	lda COLCRS				;TEST END OF LINE
	ldx DINDEX
	cmp COLUMN,X			;TEST TABLED VALUE FOR ALL SCREEN MODES
	beq INC2A				;DO CR IF EQUAL
	cpx #0					;MODE 0?
	bne INCRS3				;IF NOT. JUST RETURN
	cmp RMARGN				;TEST AGAINST RMARGN
	beq INCRS3				;EGUAL IS OK
	bcs INC2A				;IF GREATER THAN, DO CR
INCRS3
	rts
INC2A
	cpx #8					;CHECK MODE
	bcc DOCR1				;NOT 320X1 $O DO IT
	lda COLCRS+1			;TEST MED
	beq INCRS3				;ONLY AT 64 SO DON'T DO IT
DOCR1
 	lda DINDEX				;DON'T MESS WITH LOGMAP IF NO MODE ZERO
	bne DOCR
	lda LOGCOL				;TEST LINE OVERRUN
	cmp #81
	bcc DOCR1B				;IF LESS THAN 81 IT IS DEFINITELY NOT LINE 3
	lda INSDAT
	beq DOCR				;ONLY DO LOG LINE OVERFLOW IF INSDAT <>0
	jsr DOCRWS				;LOG LINE OVERFLOW IS SPECIAL CASE
	jmp INCRS1				;RETURN
DOCR1B
	jsr DOCR				;GET IT OVER WITH
	lda ROWCRS
	clc						;TEST LOGICAL LINE BIT MAP
	adc #120
	jsr BITGET
	bcc DOCR1A				;DON'T EXTEND IF OVERRUN IS INTO MIDDLE OF L
	lda INSDAT				;DON'T EXTEND IF INSDAT IS ZERO
	beq DOCR1A				;(INSCHR SPECIAL CASE)
	clc						;INSERT "0" INTO BIT MAP
	jsr INSLIA
DOCR1A
	jmp DOLCOL				;CONVERT ROW AND COL TO LOGCOL AND RETURN
NOSCRL
	lda #0					;DOCR WITHOUT SCROLL
	beq NOSCR1				;(UNCONDITIONAL)
DOCRWS
	lda #$9B				;DOCR WITH SCROLLING (NORMAL MODE)
NOSCR1
	sta INSDAT
DOCR
	jsr COLCR				;PLACE COLCRS AT LEFT EDGE
	lda #0
	sta COLCRS+1
	inc ROWCRS
DOCR2
	ldx DINDEX
	ldy #24					;SET UP SCROLL LOOP COUNTER
	bit SWPFLG
	bpl DOCR2A				;BRANCH IF NORMAL
	ldy #4
	tya
	bne DOCR2B				;(UNCONDITIONAL)
DOCR2A
	lda NOROWS,X			;GET NO OF ROWS
DOCR2B
	cmp ROWCRS
	bne INCRS1
	sty HOLD3
	txa						;DON'T SCROLL IF MODE <> 0
	bne INCRS1
	lda INSDAT				;OR IF INSDAT = 0
	beq INCRS1
;	lda INSDAT				;IF INSDAT <> $9B THEN ROLL IN A 0
	cmp #$9B				;TO EXTEND BOTTOM LOGICAL LINE
	sec
	beq DOCR4B
	clc
DOCR4B
	jsr SCROLL				;LOOP SACK TO HERE IF >1 SCROLLS
	inc SCRFLG
	dec BUFSTR				;ROWS MOVE UP SO BUFSTR SHOULD TOO
	dec HOLD3
	lda LOGMAP
	sec						;FOR PARTIAL LINES ROLL IN A "1"
	bpl DOCR4B				;AGAIN IF PARTIAL LOGICAL LINE
	lda HOLD3				;PLACE CURSOR AT NEW LINE NEAR THE BOTTOM
	sta ROWCRS
INCRS1
	jmp DOLCOL				;COLVERT ROW AND COL TO LOGCDL AND RETURN
;
;
; SUBEND: SUBTRACT ENDPT FROM ROWAC OR COLAC. (X=0 OR 2)
;
SUBEND
	sec
	lda ROWAC,X
	sbc ENDPT
	sta ROWAC,X
	lda ROWAC+1,X
	sbc ENDPT+1
	sta ROWAC+1,X
	rts
;
;
; RANGE: DO CURSOR RANGE TEST. IF ERROR, POP STACK TWICE AND JMP RETURN
;		  (ERANGE IS EDITOR ENTRY POINT AND TEST IF EDITOR IS OPEN.
;			IF IT ISNT IT OPENS THE EDITOR AND CONTINUES)
;
ERANGE
	lda BOTSCR				; IF BOTSCR=4
	cmp #4
	beq RANGE				;THEN IT IS IN MIXED NODE AND OK
	lda DINDEX				;IF MODE = 0
	beq RANGE				;THEN IT IS INEDITOR MODE AND OK
	jsr EOPEN				;IF NOT, OPEN EDITOR
RANGE
 	lda #39					;***** RANGE CHECK RMARGN ***** SET UP AC
	cmp RMARGN				;***** RANGE CHECK RMARGN ***** COMPARE
	bcs RANGE3				;***** RANGE CHECK RMARGN ***** BRANCH GE
	sta RMARGN				;***** RANGE CHECK RMARGN ***** BAD SO STORE
RANGE3
	ldx DINDEX
	lda NOROWS,X			;CHECK ROWS
	cmp ROWCRS
	bcc RNGERR				;(ERROR IF TABLE.GE.ROWCRS)
	beq RNGERR
	cpx #8					;CHECK FOR 320X1
	bne RANGE1				;SPECIAL CASE IT
	lda COLCRS+1
	beq RNGOK				;IF HIGH BYTE IS 0, COL IS OK
	cmp #1
	bne RNGERR				;IF >1, BAD
	beq RANGE2				;IF 1, GO CHECK LOWBYTE
RANGE1
	lda COLCRS+1			;FOR OTHERS, NON-ZERO HIGH BYTE IS BAD
	bne RNGERR
RANGE2
	lda COLUMN,X			;CHECK LOWBYTE
	cmp COLCRS
	bcc RNGERR
	beq RNGERR
RNGOK
 	lda #SUCCES				;SET STATUS OK
	sta DSTAT
	lda #BRKABT				;PREPARE BREAK ABORT STATUS
	ldx BRKKEY				;CHECK BREAK KEY FLAG
	sta BRKKEY				;'CLEAR' BREAK
	beq RNGER2				;IF BREAK, QUIT IMMEDIATELY AND RETURN TO CI
	rts
RNGERR
	jsr HOME				;ON RANGE ERROR, BRING CURSOR BACK
	lda #CRSROR				;SHOW CURSOR OVERRANGE ERROR
RNGER2
	sta DSTAT
RNGER1
	pla						;RESTORE STACK (THIS ROUTINE IS ALWAYS 1 LEV
	pla						;AWAY FROM RETURN TO CIO)
	lda SWPFLG				;IF SWAPPED. SWAP BACK
	bpl RETUR3
	jsr SWAPA				;AND DONT DO RETUR1
RETUR3
	jmp RETUR1				;RETURN TO CIO
;
;
;
; OFFCRS: RESTORE OLD DATA UNDER CURSOR SO IT CAN BE MOVED
;
OFFCRS
	ldy #0
	lda OLDCHR
	sta (OLDADR),Y
	rts
;
;
;
; BITMAP ROUTINES:
;
; BITCON: PUT MASK IN BITMSK AND INDEX IN X
; BITPUT: PUT CARRY INTO BITMAP
; BITROL: ROL CARRY INTO BOTTOM OF BiTMAP (SCROLL)
; BITSET: SET PROPER BIT
; BITCLR: CLEAR PROPER BIT
; BITGET: RETURN CARRY SET IF BIT IS THERE
; LOGGET: DO BITGET FOR LOGMAP INSTEAD OF TABMAP
;
BITCON
	pha
	and #7
	tax						;GET MASK
	lda MASKTB,X
	sta BITMSK
	pla						;PROCESS INDEX
	lsr @
	lsr @
	lsr @
	tax
	rts
;
;
BITROL
	rol LOGMAP+2
	rol LOGMAP+1
	rol LOGMAP
	rts
;
;
BITPUT
	bcc BITCLR				;AND RETURN
; OTHERWISE FALL THROUGH TO BITSET AND RETURN
BITSET
	jsr BITCON
	lda TABMAP,X
	ora BITMSK
	sta TABMAP,X
	rts
;
BITCLR
	jsr BITCON
	lda BITMSK
	eor #$FF
	and TABMAP,X
	sta TABMAP,X
	rts
;
LOGGET
	lda ROWCRS
LO1GET
	clc
LO2GET
	adc #120
BITGET
	jsr BITCON
	clc
	lda TABMAP,X
	and BITMSK
	beq BITGE1
	sec
BITGE1
	rts
;
;
;
;
; INATAC: INTERNAL(CHAR) TO ATASCII(ATACHR) CONVERSION
;
INATAC
	lda CHAR
	ldy DINDEX				;IF GRAPHICS MODES
	cpy #3
	bcs INATA1				;THEN DON'T CHANGE CHAR
	rol @
	rol @
	rol @
	rol @
	and #3
	tax
	lda CHAR
	and #$9F
	ora INTATA,X
INATA1
	sta ATACHR
	rts
;
;
;
; MOVLLN: MOVE 40 BYTES AT FRMADR TO TOADR SAVING OLD TOAOR
;		 DATA IN THE LINBUF. THEN MAKE NEXT FRMADR
;		 BE AT LINBUF FOR NEXT TRANSFER & TOADR=TOADR+40
;
MOVLIN
	lda #>LINBUF			;SET UP ADRESS=LINBUF$=247
	sta ADRESS+1
	lda #<LINBUF
	sta ADRESS
	ldy #39
MOVLI1
	lda (TOADR),Y			;SAVE TO DATA
	sta TMPCHR
	lda (FRMADR),Y			;STORE DATA
	sta (TOADR),Y
	lda TMPCHR
	sta (ADRESS),Y
	dey
	bpl MOVLI1
	lda ADRESS+1			;SET UP FRMADR=LAST LINE
	sta FRMADR+1
	lda ADRESS
	sta FRMADR
	clc						;ADD 40 TO TOADR
	lda TOADR
	adc #40
	sta TOADR
	bcc MOVLI2
	inc TOADR+1
MOVLI2
	rts
;
;
;
; EXTEND: EXTEND BIT MAP FROM ROWCRS (EXTEND LOGICAL LINE
;
EXTEND
	php						;SAVE CARRY
	ldy #23
EXTEN1
	tya
	jsr LO1GET
	php
	tya
	clc
	adc #121
	plp
	jsr BITPUT
EXTEN3
	dey
	bmi EXTEN4
	cpy ROWCRS
	bcs EXTEN1
EXTEN4
	lda ROWCRS
	clc
	adc #120
	plp
	jmp BITPUT				;STORE NEW LINE'S BIT AND RETURN
;
;
;
; CLRLIN: CLEAR LINE CURSOR IS ON
;
CLRLIN
	lda LMARGN
	sta COLCRS
	jsr CONVRT
	ldy #39
	lda #0
CLRLI1
	sta (ADRESS),Y
	dey
	bpl CLRLI1
	rts
;
;
;
;
; SCROLL: SCROLL SCREEN
;
SCROLL
	jsr BITROL				;ROLL IN CARRY
	lda SAVMSC				;SET UP WORKING REGISTERS
	sta ADRESS
	lda SAVMSC+1
	sta ADRESS+1
SCROL1
	ldy #40					;LOOP
	lda (ADRESS),Y
	ldx RAMTOP				;TEST FOR LAST LINE
	dex
	cpx ADRESS+1
	bne SCROL2
	ldx #$D7
	cpx ADRESS
	bcs SCROL2
	lda #0					;YES SO STORE ZERO DATA FOR THIS ENTIRE LINE
SCROL2
	ldy #0
	sta (ADRESS),Y
	inc ADRESS
	bne SCROL1
	inc ADRESS+1
	lda ADRESS+1
	cmp RAMTOP
	bne SCROL1
	jmp DOLCOL				;AND RETURN
;
;
; DOLCOL: DO LOGICAL COLUMN FROM BITMAP AND COLCRS
;
DOLCOL
	lda #0					;START WITH ZERO
	sta LOGCOL
	lda ROWCRS
	sta HOLD1
DOLCO1
	lda HOLD1				;ADD IN ROW COMPONENT
	jsr LO1GET
	bcs DOLCO2				;FOUND BEGINNING OF LINE
	lda LOGCOL				;ADD 40 AND LOOK BAC ONE
	clc
	adc #40
	sta LOGCOL
	dec HOLD1				;UP ONE LINE
	jmp DOLCO1
DOLCO2
	clc						;ADD IN COLCRS
	lda LOGCOL
	adc COLCRS
	sta LOGCOL
	rts
;
;
;
; DOBUFC: COMPUTE BUFFER COUNT AS THE NUMBER OF BYTES FROM
;			BUFSTR TO END OF LOGICAL LINE WITH TRAILING SPACES REMOVED
;
DOBUFC
	jsr	phaCRS
	lda LOGCOL
	pha
	lda BUFSTR				;START
	sta ROWCRS
	lda BUFSTR+1
	sta COLCRS
	lda #1
	sta BUFCNT
DOBUF1
	ldx #23					;NORMAL
	lda SWPFLG				;IF SWAPPED, ROW 3 IS THE LAST LINE ON SCREE
	bpl DOB1
	ldx #3
DOB1
	cpx ROWCRS				;TEST IF CRSR IS AT LAST SCREEN POSITION
	bne DOBU1A
	lda COLCRS
	cmp RMARGN
	bne DOBU1A
	inc BUFCNT				;YES, SO FAKE INCRSP TO AVOID SCROLLING
	jmp DOBUF2
DOBU1A
	jsr INCRSB
	inc BUFCNT
	lda LOGCOL
	cmp LMARGN
	bne DOBUF1				;NOT YET EOL
	dec ROWCRS				;BACK UP ONE INCRSR
	jsr CRSRLF
DOBUF2
	jsr GETPLT				;TEST CURRENT COLUMN FOR NON-ZERO DATA
	bne DOBUF4				;QUIT IF NON-ZERO
	dec BUFCNT				;DECREMENT COUNTER
	lda LOGCOL				;BEGINNING OF LOGICAL LINE YET?
	cmp LMARGN
	beq DOBUF4				;YES, SO QUIT
	jsr CRSRLF				;BACK UP CURSOR
	lda COLCRS				;IF LOGCOL=RMARGN, GO UP 1 ROW
	cmp RMARGN
	bne DOBUF3
	dec ROWCRS
DOBUF3
	lda BUFCNT
	bne DOBUF2				;LOOP UNLESS BUFCNT JUST WENT TO ZERO
DOBUF4
	pla
	sta LOGCOL
	jsr PLACRS
	rts
;
;
;
;
; STRBEG: MOVE BUFSTR TO BEGINNING OF LOGICAL LINE.
;
STRBEG
	jsr DOLCOL				;USE DOLCOL TO POINT HOLD1 AT BOL
	lda HOLD1
	sta BUFSTR
	lda LMARGN
	sta BUFSTR+1
	rts
;
;
;
;
;
; DELTIM:  TIME TO DELETE A LINE IF IT IS EMPTY AND AN EXTENSION
;
DELTIA
	lda LOGCOL				;IF LOGCOL<>LMARGN
	cmp LMARGN				; THEN DONT MOVE UP ONE
	bne DELTIG				;LINE BEFORE TESTING DELTIM
	dec ROWCRS
DELTIG
	jsr DOLCOL
DELTIM
	lda LOGCOL				;TEST FOR EXTENSION
	cmp LMARGN
	beq DELTI3				; NO
	jsr CONVRT
	lda RMARGN				;SET UP COUNT
	sec
	sbc LMARGN
	tay
DELTI1
	lda (ADRESS),Y
	bne DELTI3				;FOUND A NON-0 SD QUIT AND RETURN
	dey
	bpl DELTI1
DELTI2
	jmp DELLIB				;DELETE A LINE AND RETURN
DELTI3
	rts	  
;
;
;
; TSTCTL: SEARCH CNTRLS TABLE TO SEE IF ATACHR IS A CNTL CHAR
;
TSTCTL
	ldx #45					;PREPARE TO SEARCH TABLE
TSTCT1
	lda CNTRLS,X
	cmp ATACHR
	beq TSTCT2
	dex
	dex
	dex
	bpl TSTCT1
TSTCT2
	rts
;
;
;
; PUSH ROWCRS,COLCRS AND COLCRS+1
;
PHACRS
	ldx #2
PHACR1
	lda ROWCRS,X
	sta TMPROW,X
	dex
	bpl	phaCR1
	rts
;
;
; PULL COLCRS+1,COLCRS AND ROWCRS
;
PLACRS
	ldx #2
PLACR1
	lda TMPROW,X
	sta ROWCRS,X
	dex
	bpl	PLACR1
	rts
;
;
;
; SWAP: IF MIXED MODE, SWAP TEXT CURSORS WITH REGULAR CURSORS
;
SWAP
	jsr SWAPA				;THIS ENTRY POINT DOESRETUR1
	jmp RETUR1
SWAPA
 	lda BOTSCR
	cmp #24
	beq SWAP3
	ldx #11
SWAP1
 	lda ROWCRS,X
	pha
	lda TXTROW,X
	sta ROWCRS,X
	pla
	sta TXTROW,X
	dex
	bpl SWAP1
	lda SWPFLG
	eor #$FF
	sta SWPFLG
SWAP3
	rts
;
;
; CLICK: MAKE CLICK THROUGH KEYBOARD SPEAKER
;
CLICK
	ldx #$7F
CLICK1
	stx CONSOL
	stx WSYNC
	dex
	bpl CLICK1
	rts
;
;
; COLCR:  PUTS EITHER 0 OR LMARQN INTO COLCRS BASED ON MODE AND SWPFLG
;
COLCR
 	lda #0
	ldx SWPFLG
	bne COLCR1
	ldx DINDEX
	bne COLCR2
COLCR1
	lda LMARGN
COLCR2
	sta COLCRS
	rts
;
;
; PUTMSC: PUT SAVMSC INTO ADRESS
;
PUTMSC
	lda SAVMSC				;SETUP ADDRESS
	sta ADRESS
	lda SAVMSC+1
	sta ADRESS+1
	rts
;
;
;
; DRAW -- DRAW A LINE FROM OLDROW,OLDCOL TO NEWROW,NEWCOL
; (THE AL MILLER METHOD FROM BASKETBALL)
DRAW
	ldx #0
	lda ICCOMZ				;TEST COMMAND: $11=DRAW $12=FILL
	cmp #$11
	beq DRAWA
	cmp #$12				;TEST FILL
	beq DRAWB				; YES
	ldy #NVALID				; NO, SO RETURN INVALID COMMAND
	rts
DRAWB
	inx
DRAWA
 	stx FILFLG
	lda ROWCRS				;PUT CURSOR INTO NEWROW,NEWCOL
	sta NEWROW
	lda COLCRS
	sta NEWCOL
	lda COLCRS+1
	sta NEWCOL+1
	lda #1
	sta ROWINC				;SET UP INITIAL DIRECTIONS
	sta COLINC
	sec
	lda NEWROW				;DETERMINE DELTA ROW
	sbc OLDROW
	sta DELTAR
	bcs DRAW1				;DO DIRECTION AND ABSOLUTE VALUE
	lda #$FF				;BORROW WAS ATTEMPTED
	sta ROWINC				;SET DIRECTION DOWN
	lda DELTAR
	eor #$FF				;DELTAR = |DELTAR|
	clc
	adc #1
	sta DELTAR
DRAW1
	sec
	lda NEWCOL				;NOW DELTA COLUMN
	sbc OLDCOL
	sta DELTAC
	lda NEWCOL+1			;TWO-BYTE QUANTITY
	sbc OLDCOL+1
	sta DELTAC+1
	bcs DRAW2				;DIRECTION AND ABSOLUTE VALUE
	lda #$FF				;BORROW WAS ATTEMPTED
	sta COLINC				;SET DIRECTION = LEFT
	lda DELTAC
	eor #$FF				;DELTAC = |DELTAC|
	sta DELTAC
	lda DELTAC+1
	eor #$FF
	sta DELTAC+1
	inc DELTAC				;ADD ONE FOR TWOS COMPLEMENT
	bne DRAW2
	inc DELTAC+1
DRAW2
	ldx #2					;ZERO RAM FOR DRAW LOOP
	ldy #0
	sty COLAC+1
DRAW3A
	tya
	sta ROWAC,X
	lda OLDROW,X
	sta ROWCRS,X
	dex
	bpl DRAW3A
	lda DELTAC				;FIND LARGER ONE (ROW OR COL)
;			sta COUNTR		(PREPARE COUNTR AND ENDPT)
;			sta ENDPT
	inx						;MAKE X 0
	tay
	lda DELTAC+1
	sta COUNTR+1
	sta ENDPT+1
	bne DRAW3				;AUTOMATICALLY LARGER IF MSD>0
	lda DELTAC
	cmp DELTAR				;LOW COL >LOW ROW?
	bcs DRAW3				;YES
	lda DELTAR
	ldx #2
	tay
DRAW3
 	tya						;PUT IN INITIAL CONDITIONS
	sta COUNTR
	sta ENDPT
	pha						;SAVE AC
	lda ENDPT+1				;PUT LSB OF HIGH BYTE
	lsr @					;INTO CARRY
	pla						;RESTORE AC
	ror @					;ROR THE 9 BIT ACUMULATOR
	sta ROWAC,X
DRAW4A
	lda COUNTR				;TEST ZERO
	ora COUNTR+1
	bne DRAWI1				;IF COUNTER IS ZERO, LEAVE DRAW
	jmp DRAW10
DRAWI1
	clc						;ADD ROW TO ROWAC (PLOT LOOP)
	lda ROWAC
	adc DELTAR
	sta ROWAC
	bcc DRAW5
	inc ROWAC+1
DRAW5
 	lda ROWAC+1				;COMPARE ROW TO ENDPOINT
	cmp ENDPT+1				;IF HIGH BYTE OF ROW IS .LT. HIGH
	bcc DRAW6				;BYTE OF ENDPT, BLT TO COLUMN
	bne DRAW5A
	lda ROWAC
	cmp ENDPT				;LOW BYTE
	bcc DRAW6				;ALSO TILT
DRAW5A
	clc						;GE SO MOVE POINT
	lda ROWCRS
	adc ROWINC
	sta ROWCRS
	ldx #0					;AND SUBTRACT ENDPT FROM ROWAC
	jsr SUBEND
DRAW6
 	clc						;DO SAME FOR COLUMN (DOUBLE BYTE ADD)
	lda COLAC				;ADD
	adc DELTAC
	sta COLAC
	lda COLAC+1
	adc DELTAC+1
	sta COLAC+1
	cmp ENDPT+1				;COMPARE HIGH BYTE
	bcc DRAW8
	bne DRAW6A
	lda COLAC				;COMPARE LOW BYTE
	cmp ENDPT
	bcc DRAW8
DRAW6A
	bit COLINC				;+ OR - ?
	bpl DRAW6B
	dec COLCRS				;DO DOUBLE BYTE DECREMENT
	lda COLCRS
	cmp #$FF
	bne DRAW7
	lda COLCRS+1
	beq DRAW7				;DON'T DEC IF ZERO
	dec COLCRS+1
	bpl DRAW7				;(UNCONDITIONAL)
DRAW6B
	inc COLCRS				;DO DOUBLE BYTE INCREMENT
	bne DRAW7
	inc COLCRS+1
DRAW7
	ldx #2					;AND SUBTRACT ENDPT FROM COLAC
	jsr SUBEND
DRAW8
 	jsr RANGE
	jsr OUTPLT				;PLOT POINT
	lda FILFLG				;TEST RIGHT FILL
	beq DRAW9
	jsr	phaCRS
	lda ATACHR
	sta HOLD4
DRAW8A
	lda ROWCRS				;SAVE ROW IN CASE OF CR
	pha
	jsr INCRSA				;POSITION CURSOR ONE PAST DOT
	pla						;RESTORE ROWCRS
	sta ROWCRS
DRAW8C
	jsr RANGE
	jsr GETPLT				;GET DATA
	bne DRAW8B				;STOP IF NON-ZERO DATA IS ENCOUNTERED
	lda FILDAT				;FILL DATA
	sta ATACHR
	jsr OUTPLT				;DRAW IT
	jmp DRAW8A				;LOOP
DRAW8B
	lda HOLD4
	sta ATACHR
	jsr PLACRS
DRAW9
 	sec						;DO DOUBLE BYTE SUBTRACT
	lda COUNTR
	sbc #1
	sta COUNTR
	lda COUNTR+1
	sbc #0
	sta COUNTR+1
	bmi DRAW10
	jmp DRAW4A
DRAW10
	jmp RETUR1
;
;
; TABLES
;
;
; MEMORY ALLOCATION
;
ALOCAT	dta b(24,16,10,10,16,28,52,100,196,196,196,196)


;
;
; NUMBER OF DISPLAY LIST ENTRIES
;
NUMDLE	dta b(23,23,11,23,47,47,95,95,97,97,97,97)


MXDMDE	dta b(19,19,9,19,39,39,79,79,65,65,65,65)	;(EXT OF NUMDLE)


;
;
; ANTIC CODE FROM INTERNAL MODE CONVERSION TABLE
;
;	INTERNAL			ANTIC CODE				 DESCRIPTION
;		 0					2					40X2X8  CHARACTERS
;		 1					6					20X5X8		""
;		 2					7					20X5X16	  ""
;		 3					8					40X4X8  GRAPHICS
;		 4					9					80X2X4	  ""
;		 5					A					80X4X4	  ""
;		 4					B					160X2X2	 ""
;		 7					D					160X4X2	 ""
;		 8					F					320X2X1	 ""
;		 9					SAME AS 8 BUT GTIA 'LUM' MODE
;		 10				  SAME AS 8 BUT GTIA 'COL/LUM REGISTER' MODE
;		 11				  SAME AS 8 BUT GTIA 'COLOR' MODE
;
ANCONV	dta b(2,6,7,8,9,$A,$B,$D,$F,$F,$F,$F)	;ZEROS FOR RANGE TEST IN


;
;
; PAGE TABLE TELLS WHICH DISPLAY LISTS ARE IN DANGER OF
; CROSSING A 256 BYTE PAGE BOUNDARY
;
PAGETB	dta b(0,0,0,0,0,0,0,1,1,1,1,1)


;
;
; THIS IS THE NUMBER OF LEFT SHIFTS NEEDED TO MULTIPLY
; COLCRS BY 10,20, OR 40.  (ROWCRS*10)/(2**DHLINE)
;
DHLINE	dta b(2,1,1,0,0,1,1,2,2,2,2,2)


;
;
; COLUMN: NUMBER OF COLUMNS
;
COLUMN	dta b(40,20,20,40,80,80,160,160,64,80,80,80)	;MODE 8 IS SPECIAL


;
;
;
; NOROWS: NUMBER OF ROWS
;
NOROWS	dta b(24,24,12,24,48,48,96,96,192,192,192,192)


;
;
;
;
; DIV2TB: HOW MANY RIGHT SHIFTS FOR HCRSR FOR PARTIAL BYTE MODES
;
DIV2TB	dta b(0,0,0,2,3,2,3,2,3,1,1,1)


;
;
; DMASKT: DISPLAY MASK TABLE
;
DMASKT
	dta b($00,$FF,$F0,$0F)
	dta b($C0,$30,$0C,$03)
;
; MASKTB: BIT MASK.	(ALSO PART OF DMASKTB DO NOT SEPARATE)
;
MASKTB	dta b($80,$40,$20,$10,$08,$04,$02,$01)

;
;
;
;
COLRTB	dta b($28,$CA,$94,$46,$00)

;
;
;
;
;CNTRLS: CONTROL CODES AND THEIR DISPLACEMENTS INTO THE
;		  CONTROL CHARACTER PROCESSORS
;
CNTRLS
	dta b($1B),a(ESCAPE)
	dta b($1C),a(CRSRUP)
	dta b($1D),a(CRSRDN)
	dta b($1E),a(CRSRLF)
	dta b($1F),a(CRSRRT)
	dta b($7D),a(CLRSCR)
	dta b($7E),a(BS)
	dta b($7F),a(TAB)
	dta b($9B),a(DOCRWS)
	dta b($9C),a(DELLIN)
	dta b($9D),a(INSLIN)
	dta b($9E),a(CLRTAB)
	dta b($9F),a(SETTAB)
	dta b($FD),a(BELL)
	dta b($FE),a(DELCHR)
	dta b($FF),a(INSCHR)
;
;
;
; ATAINT: ATASCI TO INTERNAL TABLE
;
ATAINT	dta b($40,$00,$20,$60)
;
;
; INTATA: INTERNAL TO ATASCI TABLE
;
INTATA	dta b($20,$40,$00,$60)
;
;
; ATASCI: ATASCII CONVERSION TABLE
;
ATASCI
	dta b($6C,$6A,$3B,$80,$80,$6B,$2B,$2A)	;LOWER CASE
	dta b($6F,$80,$70,$75,$9B,$69,$2D,$3D)
	dta b($76,$80,$63,$80,$80,$62,$78,$7A)
	dta b($34,$80,$33,$36,$1B,$35,$32,$31)
	dta b($2C,$20,$2E,$6E,$80,$6D,$2F,$81)
	dta b($72,$80,$65,$79,$7F,$74,$77,$71)
	dta b($39,$80,$30,$37,$7E,$38,$3C,$3E)
	dta b($66,$68,$64,$80,$82,$67,$73,$61)
	dta b($4C,$4A,$3A,$80,$80,$4B,$5C,$5E)	;UPPER CASE
	dta b($4F,$80,$50,$55,$9B,$49,$5F,$7C)
	dta b($56,$80,$43,$80,$80,$42,$58,$5A)
	dta b($24,$80,$23,$26,$1B,$25,$22,$21)
	dta b($5B,$20,$5D,$4E,$80,$4D,$3F,$81)
	dta b($52,$80,$45,$59,$9F,$54,$57,$51)
	dta b($28,$80,$29,$27,$9C,$40,$7D,$9D)
	dta b($46,$48,$44,$80,$83,$47,$53,$41)
	dta b($0C,$0A,$7B,$80,$80,$0B,$1E,$1F)	;CONTROL
	dta b($0F,$80,$10,$15,$9B,$09,$1C,$1D)
	dta b($16,$80,$03,$80,$80,$02,$18,$1A)
	dta b($80,$80,$85,$80,$1B,$80,$FD,$80)
	dta b($00,$20,$60,$0E,$80,$0D,$80,$81)
	dta b($12,$80,$05,$19,$9E,$14,$17,$11)
	dta b($80,$80,$80,$80,$FE,$80,$7D,$FF)
	dta b($06,$08,$04,$80,$84,$07,$13,$01)

;
;
;
;
;
PIRQ5
 	lda KBCODE
	cmp CH1					;TEST AGAINST LAST KEY PRESSED
	bne PIRQ3				; IF NOT, GO PROCESS KEY
	lda KEYDEL				;IF KEY DELAY BYTE > 0
	bne PIRQ4				; IGNORE KEY AS BOUNCE
PIRQ3
 	lda KBCODE				;RESTORE AC
	cmp #CNTL1				;TEST CONTROL 1 (SSFLAG)
	bne PIRQ1
	lda SSFLAG
	eor #$FF
	sta SSFLAG
	bcs PIRQ4				;(UNCONDITIONAL) MAKE ^1 INVISIBLE
PIRQ1
	sta CH
	sta CH1
	lda #3
	sta KEYDEL				;INITIALIZE KEY DELAY FOR DEBOUNCE
	lda #0					;CLEAR COLOR SHIFT BYTE
	sta ATRACT
PIRQ4
	lda #$30
	sta SRTIMR
PIRQ2
	pla
	rti
;
;
	dta b($FF,$FF,$FF,$FF,$FF,$FF)
;
;
 ift PALFLG
	dta b($22,$58)			; PAL Checksum
 els
	dta b($29,$58)			; NTSC Checksum
 eif
;
	dta a(PNMI)
	dta a(PWRUP)
	dta a(PIRQ)
