; ; ************************** ; * * ; * CO-ED: * ; * * ; * A Ripsoft Product * ; * * ; * ( C ) * ; * * ; ************************** ; COED ORG $1900 ; (In the explanations below, 'upper' and 'lower' correspond to ; the notion of a file as a long sheet of paper laid out in front ; of you - not as the addresses where the file is stored.) ; As a first approximation, this editor can be considered to ; work on files entirely in store. The file is stored as two parts: ; the top part being all the text to the left and above the cursor, ; and the bottom part being the text to the right of and below the ; cursor. Moving around the file consists of copying text across ; the gap between the two parts. The overhead of this technique is ; far outweighed by the simplicity of insertion and deletion it ; offers. ; In fact, the file is not necessarily completely in store: ; if the file fits in the space available, then all is well; if not, ; then the ends of the top and bottom parts (the ends farthest from ; the gap) are slaved to disc. This is transparent to all but a little ; of the editor code, as it is implemented 'behind the scenes'. ; There are various pointers to places in the file image. ; These are explained below. ; FBEG - the start of the file (inclusive) ; FEND - the end of the file (exclusive) ; LBEG - the start of the current line (inclusive) ; LEND - the end of the current line (points to the CR at the end) ; FP - the File Pointer. - the character under the cursor ; PP - the Previous Pointer - the last character in the ; top part of the file (exclusive) ; SBEG - the start of real memory ; SLIM - the end of real memory ; (SBEG and SLIM correspond roughly to FBEG and FEND) ; The actual implementation of slaving to disc is as follows: ; When the size of the file increases such that one of the two parts, ; (say the top part) is too large for memory and has to be expelled, ; it is written to disk on a push-down stack of fixed length blocks. ; (These blocks do not correspond in any way to lines, or other file ; structures - they are merely convenient sizes to write to disk.) ; The pointers to all positions in the top part of the file are ; then moved back by the blocksize. E.g. PP becomes PP - 256. ; The file thus appears to have moved up in memory by 256 locations. ; The part of the file starting at FBEG is actually on disc, but ; appears to be in memory. FBEG therefor points to the location ; 256 bytes before SBEG - the real start of store. ; Now, when an access is made which passes SBEG in the upward ; direction, it is trapped by the 'behind the scenes' routines, ; which move the top part of the file back down again and read in ; the appropriate block from file. The pointers are also relocated. ; It may help to explain the pointers graphically: ; ; O N E CR T W . . . O CR N E X T CR . . CR L A S T CR ; | | | | | | ; F L P F L F ; B B P P E E ; E E N N ; G G D D ; ; ; To cut down the number of unseen tests for data on disc, ; everything between LBEG and LEND is always assumed to be in store. ; The code is arranged so that only LBEG and LEND creep past the ; store-limit boundaries - and so the slaving tests therefor only ; need to compare LBEG with SBEG and LEND with SLIM. PP and FP ; never need to be checked as they are always between LBEG and LEND. ; ; (The extra s are for bouncing off when scanning ; through data looking for line starts/ends when the cursor ; is at the beginning or the end of the file. Their use will ; be more obvious later on...) ; ; ; ; +---------------------------------+ ; FBEG -> | | ; | <- 256 bytes -> +------------+ ; +--------------------+ <- SBEG | ; | | ; | | ; LBEG -> | +----------------+ ; +----------------+ PP + ; ; {GAP} ; ; + FP +-----------+ ; +----------------+ CR| <- LEND ; | | ; | CR| ; +---------------------------------+ <- FEND, SLIM ; ; Similarly SLIM works with FEND as SBEG does with FBEG ; (Because the two ends of the file are not synchronised, there ; are two files to which data is slaved - one for data popping up ; from the top of the file, and one for data dropping down off ; the bottom. Both are implemented as push down stacks with the ; unit size being one block {currently pitched at 256 bytes}) OSWRCH * $FFEE OSRDCH * $FFE0 OSFIND * $FFCE OSBGET * $FFD7 OSBYTE * $FFF4 Gap * %512 Blocksize * %256 Initbuff * %40 ;Initials lines read in... ^ $20 ; Base of Page-0 variables HIMEM # %2 PP # %2 FP # %2 LBEG # %2 LEND # %2 FBEG # %2 FEND # %2 SBEG # %2 SLIM # %2 VBEG # %2 VLIM # %2 CURRENT # %2 PAGE # %2 Vgap # %1 PTR # %2 RETN # %2 SWITCH # %2 XMin # %1 YMin # %1 XMax # %1 YMax # %1 X # %2 Y # %2 XX # %2 YY # %2 ScrollOneShot # %1 TEMP # %1 SYM # %1 INFILE # %1 ; Input file ID DPEND # %1 ; Data Pending flag UPDATE # %1 JSR Init REFRESH LDA UPDATE BEQ GETCHAR JSR DISPPAGE LDAIM %0 STA UPDATE GETCHAR LDAIM %129 LDXIM %0 LDYIM %0 JSR OSBYTE TYA BNE REFRESH LDAIM %1 STA UPDATE TXA ; INPUT CHAR CMPIM %13 BEQ RETURN CMPIM %127 BEQ RUBOUT CMPIM %128 BCC DATAVAL CMPIM %144 BCC VAL CMPIM %160 BCC SHIFTVAL CMPIM %176 BCC CONTROLVAL JSR PSTR = "***Illegal input",%0 JMP VAL DATAVAL JSR AddChar JMP GETCHAR VAL ANDIM %15 ; Subtract 128 TAX LDAAX SWILOW STA SWITCH LDAAX SWIHIGH STA SWITCH + %1 JMI SWITCH SHIFTVAL ANDIM %15 TAX LDAAX LOSHITABLE STA SWITCH LDAAX HISHITABLE STA SWITCH + %1 JMI SWITCH CONTROLVAL ANDIM %15 TAX LDAAX LOCNTAB STA SWITCH LDAAX HICNTAB STA SWITCH + %1 JMI SWITCH RETURN Jsr Break JMP GETCHAR RUBOUT JSR DelLeft ;For now... JMP GETCHAR IR LdaIM %32 Sta SYM Jsr InsRight JMP GETCHAR IL LdaIM %32 Sta SYM Jsr InsLeft JMP GETCHAR DL Jsr DelRight JMP GETCHAR DR Jsr DelLeft ;I know... JMP GETCHAR IU Jsr InsUp JMP GETCHAR ID Jsr InsDown JMP GETCHAR DD Jsr DelDown JMP GETCHAR DU Jsr DelUp JMP GETCHAR RR RL Jsr Join ; for now JMP GETCHAR RU RD JMP GETCHAR ST M0 ; for now JSR WINDUP JMP GETCHAR WINDDOWN JSR TestFBEG JSR MovUp JMP WINDDOWN RT JSR WINDDOWN ; for now JSR Left JMP GETCHAR NP JMP GETCHAR GP JMP GETCHAR EM RM JSR GETPAGE ;re-initialise Jsr CLEARSCREEN Jsr DispPage ;TEMP JMP GETCHAR WINDUP JSR TestFEND JSR MovDown JMP WINDUP AB JSR WINDUP JSR Right JSR PSTR = %12,">*SAVE FILE ",%0 LDX FBEG LDY FBEG + %1 JSR PHEX LDAIM %32 JSR OSWRCH LDX PP LDY PP + %1 JSR PHEX JSR PSTR = " to save your file",%13,%10,%0 RTS RTS TA STA CTA LdaIM %32 Sta SYM Jsr InsLeft Jsr InsLeft Jsr InsLeft JMP GETCHAR CO SCO CCO JMP GETCHAR CLE LDA XMin BEQ LE DEC XMin DEC XMax LE SLE Jsr MovLeft JMP GETCHAR CRI INC XMin INC XMax RI SRI Jsr MovRight JMP GETCHAR SDO CDO LdaIM %0 Sta ScrollOneShot DO Jsr MovDown JMP GETCHAR SUP CUP LdaIM %0 Sta ScrollOneShot UP Jsr MovUp JMP GETCHAR CLEARSCREEN LDAIM %12 JMP OSWRCH AddChar Sta SYM JMP InsLeft ;{And return to GETCHAR} ; VALUES OF XMAX AND YMAX FOR MODES 0 - 7 XMAXTAB = %79,%39,%19,%79,%39,%19,%39,%39 YMAXTAB = %31,%31,%31,%24,%31,%31,%24,%24 ; DEFAULT EFFECTS FOR UNSHIFTED FN-KEYS SWILOW = IR = DL = IU = DD = RR = RU = ST = RT = EM = AB = TA = CO = LE = RI = DO = UP SWIHIGH = IR/ = DL/ = IU/ = DD/ = RR/ = RU/ = ST/ = RT/ = EM/ = AB/ = TA/ = CO/ = LE/ = RI/ = DO/ = UP/ ; SHIFTED FUN KEYS LOSHITABLE = IL = DR = ID = DU = RL = RD = NP = GP = RM = AB = STA = SCO = SLE = SRI = SDO = SUP HISHITABLE = IL/ = DR/ = ID/ = DU/ = RL/ = RD/ = NP/ = GP/ = RM/ = AB/ = STA/ = SCO/ = SLE/ = SRI/ = SDO/ = SUP/ LOCNTAB = IR = DL = IU = DD = RR = RU = ST = RT = EM = AB = CTA = CCO = CLE = CRI = CDO = CUP HICNTAB = IR/ = DL/ = IU/ = DD/ = RR/ = RU/ = ST/ = RT/ = EM/ = AB/ = CTA/ = CCO/ = CLE/ = CRI/ = CDO/ = CUP/ ; Procedure ReadLine ; { Fill line with text from PP onwards.} ; {Initially, LBEG = PP} ; repeat ; Sym = GET ; exit if Sym = eot ; if Sym = cr then begin ; FP = FP - 1 ; Byte (FP) = cr ; LEND = FP ; LSTAR ; return ; end ; Byte (PP) = Sym ; PP = PP + 1 ; MakeSpace ; until false ; DataPending = false ; end RDLine Lda DPEND Bne RDret RDagain Ldy INFILE Jsr OSBGET Bcs RDeot CmpIM %4 Beq RDeot CmpIM %13 Bne RDskip PHA Jsr DecFP PLA Jsr StoreFP Jsr SetLEND JSR DecVLIM ; FIX FOR A MIRIAD OF PROBLEMEN Jmp Left RDskip JSR StorePP Jsr IncPP Jsr MakSpace Jmp RDagain RDeot LdaIM %1 {False} Sta DPEND RDret Rts ; Procedure DeleteLeft (Sym) ; { ERASE THE CHARACTER TO THE LEFT OF THE CURSOR } ; return if PP = LBEG ; PP = PP - 1 ; end DelLeft Jsr TestLBEG ; return if ; PP = LBEG Jmp DecPP ; PP = PP - 1 ;Rts ; Procedure DeleteRight (Sym) ; { ERASE THE CHARACTER UNDER THE CURSOR } ; return if FP = LEND ; FP = FP + 1 ; end DelRight Jsr TestLEND ; return if ; FP = LEND Jmp IncFP ; FP = FP + 1 ;Rts ; Procedure InsertLeft (Sym) ; { INSERT A CHARACTER TO THE LEFT OF ; THE CURSOR, AND MOVE RIGHT } ; Byte (PP) = Sym ; PP = PP + 1 ; MakeSpace ; End InsLeft Lda Sym ; @PP = Sym Jsr StorePP Jsr IncPP ; PP = PP + 1 Jmp MakSpace ; MakeSpace ;Rts ; Procedure InsertRight (Sym) ; { INSERT A CHARACTER UNDER THE CURSOR, ; PUSHING THE REMAINING TEXT TO THE RIGHT } ; FP = FP - 1 ; MakeSpace ; Byte (FP) = Sym ; end InsRight Jsr DecFP ; FP = FP-1 Jsr MakSpace ; MakeSpace Lda Sym ; @FP = Sym Jmp StoreFP ;Rts ; Procedure MoveRight ; { MOVE THE CURSOR RIGHT ONE CHARACTER } ; return if FP = LEND ; Byte (PP) = Byte (FP) ; PP = PP + 1 ; FP = FP + 1 ; end MovRight Jsr TestLEND ; return if FP = LEND Jmp ToPP ; @PP = @FP ; PP = PP + 1 ; FP = FP + 1 ;Rts ; Procedure MoveLeft ; { MOVE THE CURSOR LEFT ONE CHARACTER } ; return if PP = LBEG ; PP = PP - 1 ; FP = FP - 1 ; Byte (FP) = Byte (PP) ; end MovLeft Jsr TestLBEG ; return if LBEG = PP Jmp ToFP ; @FP = @PP ; PP = PP - 1 ; FP = FP - 1 ;Rts ; Procedure InsertUp ; { MOVE THE CURRENT LINE, AND ALL THOSE ABOVE, ; UP BY ONE - LEAVING THE CURRENT LINE BLANK } ; RSTAR ; Byte (PP) = cr ; PP = PP + 1 ; MakeSpace ; LBEG = PP ; VBEG down ; end InsUp Jsr Right ; RSTAR LdaIM %13 ; @PP = cr Jsr StorePP Jsr IncPP ; PP = PP + 1 Jsr SetLBEG ; LBEG = PP Jsr MakSpace Inc Vgap Jmp VBdown ;Rts ; Procedure InsertDown ; { MOVE THE CURRENT LINE, AND ALL THOSE BELOW, ; DOWN BY ONE - LEAVING THE CURRENT LINE BLANK } ; LSTAR ; FP = FP - 1 ; MakeSpace ; Byte (FP) = cr ; LEND = FP ; VLIM up ; end InsDown Jsr Left ; LSTAR Jsr DecFP ; FP = FP - 1 Jsr MakSpace LdaIM %13 ; @FP = cr Jsr StoreFP Jsr SetLEND ; LEND = FP Inc Vgap Jmp VLup ;Rts ; Procedure DeleteDown ; { DELETE THE CURRENT LINE, AND LEAVE ; THE CURSOR ON THE LINE ABOVE } ; if LBEG = FBEG then DeleteUP and return ; FP = LEND ; PP = LBEG - 1 ; LBEG = PP ; LBEG = LBEG - 1 until Byte (LBEG) = cr ; LBEG = LBEG + 1 ; VBEG up ; end DelDown Lda LBEG ; if LBEG = FBEG Cmp FBEG Bne Skip11 Lda LBEG + %1 Cmp FBEG + %1 Beq DelUP ; then DeleteUp ;Rts ; and return Skip11 Jsr SetFP ; FP = LEND Jsr SetPP ; PP = LBEG Jsr DecPP ; - 1 Jsr NewLBEG ; grope LBEG Dec Vgap Jmp VBup ;Rts ; Procedure DeleteUp ; { DELETE THE CURRENT LINE, AND LEAVE THE ; CURSOR ON THE LINE BELOW } ; return if LEND = FEND ; PP = LBEG ; FP = LEND + 1 ; LEND = FP ; LEND = LEND + 1 while Byte (LEND) <> cr ; VLIM down ; end ; needs readline call??? DelUp Jsr TestFEND ; return if LEND = FEND Jsr SetPP ; PP = LBEG Jsr SetFP ; FP = LEND Jsr IncFP ; + 1 LDA FEND CMP FP BNE DU1 LDA FEND + %1 CMP FEND + %1 BNE DU1 JSR RDLine DU1 Jsr NewLEND ; grope LEND Dec Vgap Jsr VLdown Rts Break LdaIM %13 Jsr StorePP Jsr IncPP Jsr MakSpace Jsr SetLBEG Inc Vgap Jmp VLup Join Jsr TestFBEG Jsr Left Jsr DecPP Jsr NewLBEG Dec Vgap JSR VLdown RTS ; Procedure LSTAR ; { GO TO THE LEFT HAND SIDE OF THE ; CURRENT LINE } ; while PP <> LBEG do ; ToFP { PP = PP - 1 } ; { FP = FP - 1 } ; { Byte (FP) = Byte (PP) } ; end ; end Leftagain ; Leftagain: Jsr ToFP ; PP = PP - 1 ; FP = FP - 1 ; @FP = @PP Left ; procedure LSTAR Lda LBEG ; if PP <> LBEG then Cmp PP ; goto Leftagain Bne Leftagain Lda LBEG + %1 Cmp PP + %1 Bne Leftagain Rts ; end ; Procedure RSTAR ; { GO TO THE RIGHT HAND SIDE OF THE ; CURRENT LINE } ; while FP <> LEND do ; ToPP { Byte (PP) = Byte (FP) } ; { PP = PP + 1 } ; { FP = FP + 1 } ; end ; end Rightagain ; Rightagain: Jsr ToPP ; @PP = @FP ; PP = PP + 1 ; FP = FP + 1 Right ; procedure RSTAR Lda LEND ; if FP <> LEND then Cmp FP ; goto Rightagain Bne Rightagain Lda LEND + %1 Cmp FP + %1 Bne Rightagain Rts ; end ; Procedure MoveUp ; { MOVE THE CURSOR TO THE RIGHT HAND SIDE OF ; THE LINE ABOVE } ; return if LBEG = FBEG ;****BALLS - ORDER WRONG... **** ; if Scrolling then begin ; VLIM up ; VBEG up ; end ; if LBEG = VBEG then begin ; VLIM up {*** Order ***} ; VBEG up ; end {Won't scroll twice because VBEG will be on line above} ; LSTAR ; PP = PP - 1 ; FP = FP - 1 ; Byte (FP) = Byte (PP) {=cr} ; LEND = FP ; LBEG = PP ; LBEG = LBEG - 1 until Byte (LBEG) = cr ; LBEG = LBEG + 1 ; end MovUp ; procedure MoveUp Jsr TestFBEG ; return if LBEG = FBEG Lda VBEG Cmp LBEG Bne MVU10 Lda VBEG + %1 Cmp LBEG + %1 Bne MVU10 LdaIM %0 Sta ScrollOneShot MVU10 Jsr Left ; LSTAR Jsr ToFP ; PP = PP - 1 ; FP = FP - 1 ; @FP = @PP {cr} Jsr SetLEND ; LEND = FP Jsr NewLBEG ; grope LBEG Lda ScrollOneShot Bne MVUdone Jsr VBup Inc ScrollOneShot ;WAS 0 (Always) MVUdone RTS ; Procedure MoveDown ; { MOVE THE CURSOR TO THE LEFT HAND SIDE ; OF THE LINE BELOW } ; return if LEND = FEND ; if Scrolling then begin ; VBEG down ; VLIM down ; end ; if LEND = VLIM then begin ; VBEG down {Similar comments as for MoveUp} ; VLIM down ; end ; RSTAR ; Byte (PP) = Byte (FP) ; PP = PP + 1 ; FP = FP + 1 ; LBEG = PP ; if FP = FEND and DataPending then ReadLine ; LEND = FP ; LEND = LEND + 1 while Byte (LEND) <> cr ; end MovDown ; procedure MoveDown Jsr TestFEND ; return if LEND = FEND Lda VLIM Cmp LEND Bne MVD10 Lda VLIM + %1 Cmp LEND + %1 Bne MVD10 LdaIM %0 Sta ScrollOneShot MVD10 Jsr Right ; RSTAR Jsr ToPP ; @PP = @FP ; PP = PP + 1 ; FP = FP + 1 Jsr SetLBEG ; LBEG = PP LDA FP CMP FEND BNE MVDDONE LDA FP + %1 CMP FEND + %1 BNE MVDDONE JSR RDLine MVDDONE Jsr NewLEND ; grope LEND Lda ScrollOneShot Bne MVDend Jsr VLdown Inc ScrollOneShot MVDend RTS LNK BOT ;********* Internal procedures from here down ********* ; Procedure grope LEND ; LEND = FP ; {SLAVE LEND} ; while Byte (LEND) <> cr do ; LEND = LEND + 1 ; end ; end NewLend ; procedure grope LEND Jsr SetLEND ; LEND = FP Jsr SlvLEND ; SLAVE LEND Loop2 ; while @LEND <> cr do LdyIM %0 LdaIY LEND CmpIM %13 Beq EXIT1 Jsr IncLEND ; LEND = LEND + 1 Jmp Loop2 ; end while Exit1 Rts ; end proc VLdown JSR TestVLIM VLDgrope JSR IncVLIM LDYIM %0 LDAIY VLIM CMPIM %13 BNE VLDgrope INC Vgap LDA Vgap CMP YMax BEQ VBdown RTS VBdown ;I dont thinks its possible ; to call VBdown when cusor is ; on the top line - it it were ; it would cause trouble LDYIM %0 LDAIY VBEG JSR IncVBEG ; Preserves A CMPIM %13 BNE VBdown DEC Vgap RTS VLup ; If the cursor is on the line with VLim - HELP!!! Lda VLIM Cmp LEND Bne VLuploop Lda VLIM + %1 Cmp LEND + %1 Bne VLuploop JMP VBdown VLuploop JSR DecVLIM LDYIM %0 LDAIY VLIM CMPIM %13 BNE VLuploop DEC Vgap RTS VBup JSR TestVBEG ; return if VBEG = FBEG JSR DecVBEG VBUrep JSR DecVBEG LDYIM %0 LDAIY VBEG CMPIM %13 BNE VBUrep VBUdone JSR IncVBEG INC Vgap LDA Vgap CMP YMax BEQ VLup RTS ; procedure grope LBEG ; LBEG = PP ; {SLAVE LBEG} ; repeat ; LBEG = LBEG - 1 ; until Byte (LBEG) = cr ; LBEG = LBEG + 1 ; end NewLBEG ; procedure grope LBEG Jsr SetLBEG ; LBEG = PP Jsr SlvLBEG ; SLAVE LBEG Loop1 ; repeat Jsr DecLBEG ; LBEG = LBEG - 1 LdyIM %0 ; until @LBEG = cr LdaIY LBEG CmpIM %13 Bne Loop1 Jmp IncLBEG ; LBEG = LBEG + 1 ;Rts ; Procedure SetFP ; FP = LEND ; end SetFP ; procedure SetFP Ldx LEND Ldy LEND + %1 Stx FP Sty FP + %1 Rts ; Procedure SetPP ; PP = LBEG ; end SetPP Ldx LBEG Ldy LBEG + %1 Stx PP Sty PP + %1 Rts ; procedure ToFP ; PP = PP - 1 ; FP = FP - 1 ; Byte (FP) = Byte (PP) ; end ToFP ; procedure ToFP Jsr DecPP ; PP = PP - 1 Jsr DecFP ; FP = FP - 1 Jsr LoadPP ; A = @PP Jmp StoreFP ; @FP = A ;Rts ; end ; procedure ToPP ; Byte (PP) = Byte (FP) ; PP = PP + 1 ; FP = FP + 1 ; end ToPP ; procedure ToPP Jsr LoadFP ; A = @FP Jsr StorePP ; @PP = A Jsr IncPP ; PP = PP + 1 Jmp IncFP ; FP = FP + 1 ;Rts ; end ; procedure LoadPP ; A = Byte (PP) ; end LoadPP LdyIM %0 LdaIY PP Rts ; procedure LoadFP ; A = Byte (FP) ; end LoadFP LdyIM %0 LdaIY FP Rts ; procedure StorePP ; Byte (PP) = A ; end StorePP LdyIM %0 StaIY PP Rts ; procedure StoreFP ; Byte (FP) = A ; end StoreFP LdyIM %0 StaIY FP Rts ; procedure IncPP ; PP = PP + 1 ; end IncPP Inc PP Bne Skip3 Inc PP + %1 Skip3 Rts ; procedure IncFP ; FP = FP + 1 ; end IncFP Inc FP Bne Skip4 Inc FP + %1 Skip4 Rts IncVBEG Inc VBEG Bne IVB1 Inc VBEG + %1 IVB1 RTS IncVLIM Inc VLIM Bne IVL1 Inc VLIM + %1 IVL1 RTS ; procedure DecPP ; PP = PP - 1 ; end DecPP Lda PP Bne Skip5 Dec PP + %1 Skip5 Dec PP Rts ; procedure DecFP ; FP = FP - 1 ; end DecFP Lda FP Bne Skip6 Dec FP + %1 Skip6 Dec FP Rts DecVBEG Lda VBEG Bne DVB1 Dec VBEG + %1 DVB1 Dec VBEG RTS DecVLIM Lda VLIM Bne DVL1 Dec VLIM + %1 DVL1 Dec VLIM RTS ; procedure TestLBEG ; if PP=LBEG then return two levels ; end TestLBEG Lda PP Cmp LBEG Bne Skip9 Lda PP + %1 Cmp LBEG + %1 Bne Skip9 Pla Pla Skip9 Rts ; procedure TestLEND ; if FP=LEND then return two levels ; end TestLEND Lda FP Cmp LEND Bne Skip10 Lda FP + %1 Cmp LEND + %1 Bne Skip10 Pla Pla Skip10 Rts ; procedure TestFBEG ; if LBEG = FBEG then return two levels ; end TestFBEG Lda LBEG Cmp FBEG Bne Skip12 Lda LBEG + %1 Cmp FBEG + %1 Bne Skip12 Pla Pla Skip12 Rts ; procedure TestFEND ; if LEND = FEND then return two levels ; end TestFEND Lda LEND Cmp FEND Bne Skip13 Lda LEND + %1 Cmp FEND + %1 Bne Skip13 Pla Pla Skip13 Rts TestVBEG Lda FBEG Cmp VBEG Bne TVB1 Lda FBEG + %1 Cmp VBEG + %1 Bne TVB1 Pla Pla TVB1 RTS TestVLIM Lda FEND Cmp VLIM Bne TVL1 Lda FEND + %1 Cmp VLIM + %1 Bne TVL1 Pla Pla TVL1 RTS ; procedure SetLBEG ; LBEG = PP ; end SetLBEG Ldx PP Ldy PP + %1 Stx LBEG Sty LBEG + %1 Rts ; procedure SetLEND ; LEND = FP ; end SetLEND Ldx FP Ldy FP + %1 Stx LEND Sty LEND + %1 Rts ; procedure IncLBEG ; LBEG = LBEG + 1 ; end IncLBEG Inc LBEG Bne Skip14 Inc LBEG + %1 Skip14 Rts ; procedure DecLBEG ; LBEG = LBEG - 1 ; { creep into unknown territory - so perform ; automatic swapping if necessary } ; {SLAVE LBEG} ; end DecLBEG Lda LBEG Bne Skip7 Dec LBEG + %1 Skip7 Dec LBEG Jmp SlvLBEG ;Rts ; procedure IncLEND ; LEND = LEND + 1 ; {SLAVE LEND} ; { Similar comment as for Dec LBEG } ; end IncLEND Inc LEND Bne Skip15 Inc LEND + %1 Skip15 Jmp SlvLEND ;Rts ; procedure DecLEND ; LEND = LEND - 1 ; end DecLEND Lda LEND Bne Skip8 Dec LEND + %1 Skip8 Dec LEND Rts ; procedure Slave LBEG ; return if LBEG<>SBEG ; return if SBEG=FBEG ; GetTop ; end SlvLBEG Rts ; procedure Slave LEND ; return if LEND <> SLIM ; return if SLIM=FEND ; GetBot ; end SlvLEND Rts ; NOTE THAT Gap >= BlockSize and that Blocksize is optimal at 256 ; procedure MakeSpace ; return if PP+Gap <= FP {if PP<>FP ???} { Gap is big enough } ; if SBEG+BlockSize < PP then PutTop { Plenty data at top to expel } ; else if FP+BlockSize < SLIM then PutBot { ... or at bottom } ; else ERROR "Available memory too small" { no?? - no room } ; { *** Should really expel from end farthest from cursor - ; I'll change it some day to avoid the pathological case ; of thrashing the top of the screen in and out when ; displaying a page } ; end MakSpace Rts ; procedure PutTop ; WriteTopBlock ; MoveUpTop ; end PutTop Rts ; procedure GetTop ; MoveDownTop ; ReadTopBlock ; end GetTop Rts ; procedure PutBot ; WriteBotBlock ; MoveDownBot ; end PutBot Rts ; procedure GetBot ; MoveUpBot ; ReadBotBlock ; end GetBot Rts ; procedure Initialise ; Byte (LOMEM) = cr ; LOMEM = LOMEM + 1 ; PP = LOMEM ; LBEG = PP ; FBEG = LBEG ; VBEG = LBEG ; SBEG = FBEG ; FP = PP + GAP { Guarantee the minimum gap } ; {HAVE TO THINK ABOUT THIS} ; FEND = FP ; LEND = FEND ; VLIM = LEND ; Byte (HIMEM) = cr ; SLIM = HIMEM ; end Init JSR PSTR = "Welcome to CO-ED V0.1" = %13,%10,%0 LDAIM %0 TAY JSR OSFIND ;Close all open files. LDXIM $40 LDYIM $01 TXA JSR OSFIND PHA LDAIM %132 JSR OSBYTE STX HIMEM STY HIMEM + %1 LDA HIMEM BNE T2 DEC HIMEM + %1 T2 DEC HIMEM PLA BNE WELCOME JSR PSTR = "CO-ED Fails - file not found." = %13,%10,%0 RTS WELCOME STA INFILE LDAIM $00 STA DPEND {Data Pending = true} LDAIM %1 STA ScrollOneShot ;Forced scroll = false STA UPDATE ; Initial update desired LDAIM %0 STA Vgap LDAIM %225 LDXIM %128 LDYIM %0 ; NORMAL - 128 to 143 JSR OSBYTE LDAIM %226 LDXIM %144 LDYIM %0 ; SHIFTED - 144 to 159 JSR OSBYTE LDAIM %227 LDXIM %160 LDYIM %0 ; CONTROL - 160 to 175 JSR OSBYTE LDAIM %4 LDXIM %2 LDYIM %0 ; CURSOR KEYS ARE SOFT JSR OSBYTE LDAIM %12 LDXIM %3 ;FAST AUTO-REPEAT JSR OSBYTE LDAIM %229 LDXIM %1 LDYIM %0 ; ESC BECOMES ASCII KEY JSR OSBYTE JSR PSTR = %23,%255,%255,%129,%153,%129,%153,%165,%129,%255 = %23,%254,%1,%3,%7,%15,%31,%63,%127,%255,%0 LDAIM LOMEM STA PTR LDAIM LOMEM/ STA PTR + %1 LDAIM %135 LDXIM %0 LDYIM %0 JSR OSBYTE ; GET MODE IN Y TYA TAX LDAAX YMAXTAB STA YMax LDAAX XMAXTAB STA XMax LDAIM %0 STA XMin STA YMin LDYIM %0 LDAIM %13 STAIY PTR INC PTR BNE T99 INC PTR + %1 T99 LDA PTR STA PP STA LBEG STA FBEG STA VBEG STA SBEG LDA PTR + %1 STA PP + %1 STA LBEG + %1 STA FBEG + %1 STA VBEG + %1 STA SBEG + %1 LDA HIMEM STA FP STA FEND STA LEND STA VLIM STA SLIM LDA HIMEM + %1 STA FP + %1 STA FEND + %1 STA LEND + %1 STA VLIM + %1 STA SLIM + %1 LDAIM %13 LDYIM %0 STAIY FEND ; EVENTUALLY REPLACE WITH OPTIONAL LOADUP DIRECTLY... JSR RDLine JSR VLdown LDAIM Initbuff STA TEMP BLOOP LDA TEMP BEQ ENCORE LDX LEND LDY LEND + %1 STX VLIM STY VLIM + %1 JSR MovDown DEC TEMP JMP BLOOP ENCORE LDA TEMP CMPIM Initbuff BEQ INCORE JSR MovUp INC TEMP JMP ENCORE INCORE JSR MovUp JSR Left LDAIM %12 JSR OSWRCH JSR GETPAGE RTS PSYM LDA X CMP XMin BEQ RDY BCC PSNO CMP XMax ; THE IM Version said + 1 here... BCS PSNO RDY LDYIM %0 LDAIY CURRENT; GET OLD CHARACTER STA TEMP LDA Sym ; REPLACE WITH NEW ONE STAIY CURRENT INC CURRENT BNE NOCURRY INC CURRENT + %1 NOCURRY LDA Sym CMP TEMP ; COMPARE THEM BEQ PSNO ; AND PRINT IF DIFFERS... ; [[[[ compare CX and CY, skip to print if = ]]] LDAIM %31 JSR OSWRCH LDA X SEC SBC XMin JSR OSWRCH LDA Y JSR OSWRCH ;[[[ Save X+1, Y into NX,NY ]]] LDA Sym JSR OSWRCH PSNO RTS ; {On startup, set page image to all spaces; this means ; DisplayPage can be used straight to display the initial ; page} ; procedure DisplayPage DispPage ; while VBEG < SLIM do MoveDownTop ;! Assumed ; PTR = VBEG {Slaved I hope. Must fix later...} LDX VBEG STX PTR LDY VBEG + %1 STY PTR + %1 ; Y = YMin { = 0 unless this editor changes a lot} LDA YMin STA Y LDAIM %0 STA X ;@@@ INIT CURRENT TO START OF PAGE @@@ LDA PAGE STA CURRENT LDA PAGE + %1 STA CURRENT + %1 ; X = XMin { ditto } ; repeat LDAIM %0 STA TEMP JSR VDUCURS DiREP ; PTR = FP if PTR = PP LDA PP CMP PTR BNE RR4 LDA PP + %1 CMP PTR + %1 BNE RR4 LDX FP STX PTR LDY FP + %1 STY PTR + %1 LDX X ; Note cursor pos... ;[[[USE NX,NY FOR ACCURACY]]] STX XX LDY Y STY YY RR4 ; {Also note X and Y and use to set cursor!!} ; exit if PTR = VLIM ; {SLAVE PTR???} LDA FEND CMP PTR BNE YY1 LDA FEND + %1 CMP PTR + %1 BNE YY1 JMP DiEXIT YY1 LDYIM %0 LDAIY PTR CMPIM %13 BNE YY2 ;PAD LINE WITH SPACES LDAIM %32 STA Sym PADLOOP LDA X CMP XMax ; IM Verison said + %1 BCS PADDONE ; until col. XMAX JSR PSYM; PSYM stops after XMax anyway INC X ; so a few extra won't hurt. JMP PADLOOP PADDONE LDAIM '? ; TAKE OUT THAT LINE IF NO ???s APPEAR JSR PSYM ; for luck LDA Y CMP YMax BEQ NoBLOB ; OH GOD NOT AGAIN. ;never actually happens. WHY????? ; suppose that must mean VLIM always gets it right... INC Y ; THIS SCHEME MAY CAUSE TROUBLE WITH LONG LINES AND SIDEWAYS SCROLL.... LDAIM %0 STA X JMP DiEND YY2 STA Sym JSR PSYM INC X ; if Byte (PTR) = cr then begin ; WipeLine {using global X, Y} ; SetCursor and return if Y = YMax ; Y = Y + 1 ; X = 0 ; end ; else begin ; PSym (Byte (PTR)) {using global X, Y} ; { Psym draws the character if it is different from ; the one below and stores its character in the page ; image ready for the next update. It also knows ; about XMax and doesn't draw off the screen. ; When we implement (IF...) sideways scroll (for P.B.) ; PSym will do the work of adding the offset - thus ; making it transparent to the rest of the editor ; (Except of course the input routine...) } ; X = X + 1 ; end DiEND LDA VLIM CMP PTR BNE YZY2 LDA VLIM + %1 CMP PTR + %1 BNE YZY2 LDAIM %254 STA Sym JSR PSYM JMP NoBLOB YZY2 INC PTR BNE UU1 INC PTR + %1 UU1 JMP DiREP DiEXIT LDAIM %255 ;BLOB CHARACTER {defined elsewhere} STA Sym JSR PSYM NoBLOB LDAIM %32 STA Sym INC X SHITLOOP POOP2 LDA X CMP XMax ; ANOTHER IM + %1 TO BE FIXED Bcs PAD2 JSR PSYM INC X JMP POOP2 PAD2 JSR PSYM; kill this when sober... LDAIM %0 STA X LDA Y CMP YMax BEQ SCursor INC Y JMP SHITLOOP SCursor LDAIM %31 JSR OSWRCH LDA XX CMP XMin BCC MINIMUM CMP XMax BCS MAXIMUM MEET SEC SBC XMin JSR OSWRCH LDA YY JSR OSWRCH LDAIM %1 STA TEMP JSR VDUCURS RTS MINIMUM LDA XMin JMP MEET MAXIMUM LDA XMax JMP MEET ; until false ; { End of file. } ; Put (BLODGE) {at last X, Y set after drawing last character} ; repeat ; WipeLine ; X = 0 ; return if Y = YMax ; Y = Y + 1 ; until false ; SetCursor ; end VDUCURS LDAIM %23 JSR OSWRCH LDAIM %1 JSR OSWRCH LDA TEMP JSR OSWRCH LDAIM %0 JSR OSWRCH JSR OSWRCH JSR OSWRCH JSR OSWRCH JSR OSWRCH JSR OSWRCH JSR OSWRCH RTS ; procedure WriteTopBlock ; {Expel bytes from SBEG onwards to file #1} ; end WrTopBlock Rts ; procedure WriteBotBlock ; {Expel bytes from SLIM backwards to file #2} ; end WrBotBlock Rts ; procedure MoveUpTop ; {Move up data from SBEG+256 to SBEG, ; and adjust pointers appropriately} ; end MvUpTop Rts ; procedure MoveDownBot ; {Move down data from SLIM-257 to SLIM-1??, ; similarly adjusting respective pointers} ; {I.e. FBEG, VBEG, LBEG, PP} ; end MvDnBot Rts ; procedure MoveDownTop ; {Reverse of MoveUpTop, except that may need ; to push down bottom too, to make space...} ; {I.e. FP, LEND, VLIM, FEND} ; end MvDnTop Rts ; procedure MoveUpBot ; {Likewise and also...} ; end MvUpBot Rts ;*************** SERVICE ROUTINES **************** ; Print STRing following JSR PSTR instruction, ; terminated by a NULL in data. PSTR PLA STA RETN PLA STA RETN + %1 LDYIM %0 LP1 JSR INCRETN LDAIY RETN BEQ DONE JSR OSWRCH JMP LP1 DONE JSR INCRETN JMI RETN INCRETN INC RETN BNE SKIP INC RETN + %1 SKIP RTS PHEX TYA JSR OUTHEX TXA OUTHEX PHA LSRA LSRA LSRA LSRA JSR OUTNIB PLA ANDIM $F OUTNIB CMPIM $A BCC NOADD ADCIM %6 NOADD ADCIM '0 JMP OSWRCH ; CLAIM FIXED SPACE FOR PAGE IMAGE ; (THE EASY WAY...) GETPAGE LDAIM IMAGE STA PAGE STA PTR LDAIM IMAGE/ STA PAGE + %1 STA PTR + %1 LDYIM %0 WIPELOOP LDAIM %32 STAIY PTR INC PTR BNE EEERRRTTT INC PTR + %1 EEERRRTTT LDA PTR CMPIM LOMEM BNE WIPELOOP LDA PTR + %1 CMPIM LOMEM/ BNE WIPELOOP RTS IMAGE = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " = " " LOMEM END ; OF CO-ED