home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-12 | 29.2 KB | 1,002 lines |
- .%0200! ;*** FETCH( [ZP1]=╞AR╙OURCE, (ZW1)=╥AM0─EST, .┴┘=╠ENGTH )
- .%0201!
-
- ╙OME WORKING STORAGE LOCATIONS ARE NECESSARY FOR THIS ROUTINE, SINCE IT IS
- DESIGNED TO COPY DATA A PAGE AT A TIME. ╘HE SOURCE (ZP1+1) AND DESTINATION
- (ZW1+1) PAGE ADDRESSES ARE SAVED AND LATER RESTORED BECAUSE THIS ROUTINE
- ALTERS THEM WHILE COPYING. ╔F THE FAR ADDRESS IS IN EXPANSION MEMORY, THIS
- ROUTINE DISPATCHES TO THE ╥┼╒ FETCH/STASH CODE.
-
- .%0202! FETCH╠ENGTH = SYS╫ORK
- .%0203! FETCH╙AVE╙OURCE = SYS╫ORK+2
- .%0204! FETCH╙AVE─EST = SYS╫ORK+3
- .%0205!
- .%0206! INTERN╥AM0╞ETCH = *
- .%0207! LDX ZP1+2
- .%0208! BPL +
- .%0209! LDX #$91
- .%0210! JMP DO╥EU
-
- ╔F THE TRANSFER IS LESS THAN ONE PAGE LONG, IT CAN BE DONE BY CALLING THE
- FETCH╨AGE CODE DIRECTLY. ╧THERWISE, THE LONG FETCH CODE HAS TO BE CALLED.
-
- .%0211! + CPY #0
- .%0212! BNE FETCH╠ONG
- .%0213! TAY
- .%0214! BNE FETCH╨AGE
- .%0215! RTS
- .%0216!
-
- ╔F THE (INTERNAL) PAGE TO BE FETCHED IS ON ╥┴═1, THE COMMON CODE ROUTINE IS
- CALLED; OTHERWISE, THE COPY IS DONE HERE BY SWITCHING ╥┴═0 INTO CONTEXT. ╫E
- CAN COPY BETWEEN ╥┴═0 LOCATIONS WITHOUT SWITCHING CONTEXTS FOR EVERY BYTE.
-
- .%0217! FETCH╨AGE = *
- .%0218! CPX #BK╥AM0
- .%0219! BEQ +
- .%0220! JMP COM├OPY╥AM1╘O╥AM0-COM├ODE╙TART+COM├ODE┬UFFER
- .%0221! + STX BK╙ELECT
- .%0222! DEY
- .%0223! BEQ +
- .%0224! - LDA (ZP1),Y
- .%0225! STA (ZW1),Y
- .%0226! DEY
- .%0227! BNE -
- .%0228! + LDA (ZP1),Y
- .%0229! STA (ZW1),Y
- .%0230! LDA #BK╙YS
- .%0231! STA BK╙ELECT
- .%0232! RTS
- .%0233!
-
- ╘HIS IS CALLED FOR LONG (>=256 BYTE) (INTERNAL) FETCHES. ╔T CALLS THE
- FETCH╨AGE CODE REPEATEDLY, AFTER INCREMENTING THE SOURCE AND DESTINATION PAGE
- NUMBERS. ╘HE TRANSFER LENGTH IS DECREMENTED UNTIL IT IS LESS THAN 256 BYTES.
-
- .%0234! FETCH╠ONG = *
- .%0235! STA FETCH╠ENGTH
- .%0236! STY FETCH╠ENGTH+1
- .%0237! LDA ZP1+1
- .%0238! STA FETCH╙AVE╙OURCE
- .%0239! LDA ZW1+1
- .%0240! STA FETCH╙AVE─EST
- .%0241! LDA FETCH╠ENGTH+1
- .%0242! BEQ FETCH╠ONG┼XIT
- .%0243! - LDX ZP1+2
- .%0244! LDY #0
- .%0245! JSR FETCH╨AGE
- .%0246! INC ZP1+1
- .%0247! INC ZW1+1
- .%0248! DEC FETCH╠ENGTH+1
- .%0249! BNE -
- .%0250!
- .%0251! FETCH╠ONG┼XIT = *
-
- ╘HIS FETCHES THE LAST CHUNK OF LESS THAN 256 BYTES AND THEN RESTORES THE ZP1
- AND ZW1 PARAMETERS TO WHAT THEY WERE BEFORE THIS ROUTINE WAS CALLED.
-
- .%0252! LDY FETCH╠ENGTH
- .%0253! BEQ +
- .%0254! LDX ZP1+2
- .%0255! JSR FETCH╨AGE
- .%0256! + LDA FETCH╙AVE╙OURCE
- .%0257! STA ZP1+1
- .%0258! LDA FETCH╙AVE─EST
- .%0259! STA ZW1+1
- .%0260! RTS
- .%0261!
- .%0262! ;*** STASH( (ZW1)=╥AM0╙OURCE, [ZP1]=╞AR─EST, .┴┘=LENGTH )
- .%0263!
-
- ╙TASH HAS EXACTLY THE SAME STRUCTURE AS FETCH.
-
- .%0264! STASH╠ENGTH = SYS╫ORK
- .%0265! STASH╙AVE╙OURCE = SYS╫ORK+2
- .%0266! STASH╙AVE─EST = SYS╫ORK+3
- .%0267!
- .%0268! INTERN╥AM0╙TASH = *
- .%0269! LDX ZP1+2
- .%0270! BPL +
- .%0271! LDX #$90
- .%0272! JMP DO╥EU
- .%0273! + CPY #0
- .%0274! BNE STASH╠ONG
- .%0275! TAY
- .%0276! BNE STASH╨AGE
- .%0277! RTS
- .%0278!
- .%0279! STASH╨AGE = *
- .%0280! CPX #BK╥AM0
- .%0281! BEQ +
- .%0282! JMP COM├OPY╥AM0╘O╥AM1-COM├ODE╙TART+COM├ODE┬UFFER
- .%0283! + STX BK╙ELECT
- .%0284! DEY
- .%0285! BEQ +
- .%0286! - LDA (ZW1),Y
- .%0287! STA (ZP1),Y
- .%0288! DEY
- .%0289! BNE -
- .%0290! + LDA (ZW1),Y
- .%0291! STA (ZP1),Y
- .%0292! LDA #BK╙YS
- .%0293! STA BK╙ELECT
- .%0294! RTS
- .%0295!
- .%0296! STASH╠ONG = *
- .%0297! STA STASH╠ENGTH
- .%0298! STY STASH╠ENGTH+1
- .%0299! LDA ZW1+1
- .%0300! STA STASH╙AVE╙OURCE
- .%0301! LDA ZP1+1
- .%0302! STA STASH╙AVE─EST
- .%0303! LDA STASH╠ENGTH+1
- .%0304! BEQ STASH╠ONG┼XIT
- .%0305! - LDX ZP1+2
- .%0306! LDY #0
- .%0307! JSR STASH╨AGE
- .%0308! INC ZP1+1
- .%0309! INC ZW1+1
- .%0310! DEC STASH╠ENGTH+1
- .%0311! BNE -
- .%0312!
- .%0313! STASH╠ONG┼XIT = *
- .%0314! LDY STASH╠ENGTH
- .%0315! BEQ +
- .%0316! LDX ZP1+2
- .%0317! JSR STASH╨AGE
- .%0318! + LDA STASH╙AVE╙OURCE
- .%0319! STA ZW1+1
- .%0320! LDA STASH╙AVE─EST
- .%0321! STA ZP1+1
- .%0322! RTS
- .%0323!
- .%0324! ;*** RAM0 LOAD/STORE(.╪) EXPN MEMORY [ZP1] <- -> (ZW1) FOR .┴┘ BYTES
- .%0325!
-
- ╘HIS IS THE CODE THAT DOES THE FETCHING AND STASHING FROM/TO EXPANSION
- MEMORY. ╘HE ONLY DIFFERENCE BETWEEN A FETCH AND A STASH IS THE ╥┼╒ ├ONTROLLER
- COMMAND CODE, SO THAT IS AN INPUT PARAMETER. ╘HE ╥┼╒ ├ONTROLLER REGISTERS ARE
- SET UP, THE CLOCK IS SLOWED, THE TRANSFER HAPPENS, AND THEN THE CLOCK SPEED IS
- RESTORED. ╘HE BULK TRANSFER IS DONE ENTIRELY BY THE ╥┼╒ ├ONTROLLER.
- ╔NTERESTINGLY, IT WOULD HAVE BEEN FASTER TO TRANSFER THE INTERNAL MEMORY TO
- EXPANSION MEMORY AND THEN FETCH IT BACK AGAIN IN ORDER TO ACHIEVE AN INTERNAL
- MEMORY TRANSFER (IF YOU HAVE AN ╥┼╒), BUT ╔ DIDN'T BOTHER WITH THAT.
-
- .%0326! DO╥EU = *
- .%0327! STA REU+7
- .%0328! STY REU+8
- .%0329! LDA ZW1
- .%0330! LDY ZW1+1
- .%0331! STA REU+2
- .%0332! STY REU+3
- .%0333! LDA ZP1
- .%0334! LDY ZP1+1
- .%0335! STA REU+4
- .%0336! STY REU+5
- .%0337! LDA ZP1+2
- .%0338! STA REU+6
- .%0339! LDY VIC+$30
- .%0340! LDA #0
- .%0341! STA VIC+$30
- .%0342! STX REU+1
- .%0343! STY VIC+$30
- .%0344! RTS
- .%0345!
- .%0346! ;*** SNIFF╥┼╒ - DETERMINE NUMBER OF BANKS OF EXPANSION MEMORY
- .%0347!
-
- ╘HE WORK LOCATIONS ARE USED TO STORE A STRING TO THE FIRST FOUR ADDRESSES OF
- EACH EXPANSION MEMORY BANK AND THEN FETCH THEM BACK AGAIN IN ORDER TO
- DETERMINE WHETHER THE BANK EXISTS OR NOT. ┼XPANSION BANK #0 IS ALSO CHECKED
- AFTER EACH BANK TO SEE IF A BANK NUMBER WRAP-AROUND OCCURED. ╘HE
- "REU╙IZE╠IMIT" WILL FORCE THIS ROUTINE TO STOP SEARCHING AFTER THAT NUMBER OF
- BANKS HAVE BEEN SNIFFED. ╘HE MAXIMUM VALUE IS 127, SINCE ONLY BANK NUMBERS
- $80 TO $╞┼ ARE AVAILABLE. ┬Y CHANGING THIS VALUE, YOU CAN STOP THIS PACKAGE
- FROM USING EXPANSION MEMORY RESERVED BY ANOTHER PROGRAM. ╬OTE THAT THIS
- PROGRAM USES EXPANSION BANKS 0 UP TO BUT NOT INCLUDING "REU╙IZE╠IMIT".
-
- .%0348! SNIFF╫ORK1 = SYS╫ORK
- .%0349! SNIFF╫ORK2 = SYS╫ORK+4
- .%0350! REU╙IZE╠IMIT .BYTE 127
- .%0351!
- .%0352! SNIFF╥┼╒ = *
-
- ╚ERE ╔ SAVE THE DATA IN THE MEMORY "BENEATH" THE ╥┼╒ ├ONTROLLER REGISTERS. ╔F
- THERE ISN'T A ╥┼╒ INSTALLED, THIS MEMORY WOULD OTHERWISE BE CORRUPTED BY ╔/╧
- ADDRESSES BLEEDING THROUGH TO THE UNDERLYING ╥┴═.
-
- .%0353! LDA #BK╥AM0
- .%0354! STA BK╙ELECT
- .%0355! LDX #$A
- .%0356! - LDA REU,X
- .%0357! STA WORK┬UFFER,X
- .%0358! DEX
- .%0359! BPL -
- .%0360! LDA #BK╙YS
- .%0361! STA BK╙ELECT
-
- ╚ERE ╔ INITIALIZE THE CONFIGURATION ╥┼╒ ├ONTROLLER REGSTERS. ╘HEY ARE SET
- ONLY ONCE BY THIS PACKEAGE.
-
- .%0362! LDA #$00
- .%0363! STA REU+$9
- .%0364! STA REU+$A
- .%0365! LDA REU+$0
-
- ╘HE THREE-BYTE IDENTIFIER STRING IS COPIED INTO THE SOURCE TAG. ╘HE FOURTH
- BYTE WILL BE FILLED IN BY THE BANK NUMBER.
-
- .%0366! LDX #2
- .%0367! - LDA EXP╥AM╔D,X
- .%0368! STA SNIFF╫ORK1,X
- .%0369! DEX
- .%0370! BPL -
-
- ╔NITIALIZATION CONTINUES.
-
- .%0371! LDA #0
- .%0372! STA N┼XP┬ANKS
- .%0373! LDA #$00
- .%0374! LDX #BK┼XP0
- .%0375! STA ZP1
- .%0376! STA ZP1+1
- .%0377! STX ZP1+2
- .%0378!
-
- ╘HIS IS THE MAIN LOOP. ╔T TESTS THE CURRENT EXPANSION BANK AND THEN GOES ON
- TO THE NEXT ONE IF OK. ╧THERWISE, IT STOPS AT THE NUMBER OF OKAY BANKS.
-
- .%0379! - JSR TEST┼XP┬ANK
- .%0380! BCS +
- .%0381! INC N┼XP┬ANKS
- .%0382! INC ZP1+2
- .%0383! BNE -
- .%0384! + LDA N┼XP┬ANKS
- .%0385! BNE +
-
- ╥ESTORE THE UNDERLYING ╥┴═ CONTENTS AND EXIT.
-
- .%0386! LDA #BK╥AM0
- .%0387! STA BK╙ELECT
- .%0388! LDX #$A
- .%0389! - LDA WORK┬UFFER,X
- .%0390! STA REU,X
- .%0391! DEX
- .%0392! BPL -
- .%0393! LDA #BK╙YS
- .%0394! STA BK╙ELECT
- .%0395! + RTS
- .%0396!
- .%0397! ;*** TEST EXPANSION BANK( [ZP1]=┬ANK╨TR ) : .├├=OK
- .%0398!
-
- ╞IRST CHECKS THAT THE MAXIMUM NUMBER OF ALLOWED EXPANSION BANKS HAS NOT BEEN
- EXCEEDED. ╙TORES THE TEST STRING THROUGH THE BANK POINTER AND THEN TESTS TO
- SEE THAT THE STRING HAS BEEN STORED CORRECTLY AND THAT THE STRING ON EXPANSION
- BANK 0 IS STILL OK (IT WOULDN'T BE OK IF A WRAP-AROUND OCCURED).
-
- .%0399! TEST┼XP┬ANK = *
- .%0400! LDA N┼XP┬ANKS
- .%0401! CMP REU╙IZE╠IMIT
- .%0402! BCC +
- .%0403! RTS
- .%0404! + LDA ZP1+2
- .%0405! STA SNIFF╫ORK1+3
- .%0406! LDX #SNIFF╫ORK1
- .%0407! LDY #4
- .%0408! JSR ZPSTORE
- .%0409! JSR TEST┼XP┬ANK╔NTERNAL ;TEST CURRENT BANK
- .%0410! BCS +
- .%0411! LDA ZP1+2
- .%0412! PHA
- .%0413! LDA #BK┼XP0
- .%0414! STA ZP1+2
- .%0415! STA SNIFF╫ORK1+3
- .%0416! JSR TEST┼XP┬ANK╔NTERNAL ;TEST EXPANSION BANK 0
- .%0417! PLA
- .%0418! STA ZP1+2
- .%0419! + RTS
- .%0420!
-
- ╘HIS ROUTINE READS THE BYTES AT ADDRESS [ZP1] AND MAKES SURE THEY ARE THE SAME
- AS THE PREVIOUS ROUTINE PUT THERE. ╧N RETURN, THE CARRY FLAG IS SET IF THE
- STRING FOUND IS NOT THE SAME AS WHAT WAS PREVIOUSLY PUT OUT.
-
- .%0421! TEST┼XP┬ANK╔NTERNAL = *
- .%0422! LDA #$00
- .%0423! STA SNIFF╫ORK2
- .%0424! STA SNIFF╫ORK2+3
- .%0425! LDX #SNIFF╫ORK2
- .%0426! LDY #4
- .%0427! JSR ZPLOAD
- .%0428! LDX #3
- .%0429! - LDA SNIFF╫ORK2,X
- .%0430! CMP SNIFF╫ORK1,X
- .%0431! BNE +
- .%0432! DEX
- .%0433! BPL -
- .%0434! CLC
- .%0435! RTS
- .%0436! + SEC
- .%0437! RTS
- .%0438!
-
- ╘HIS IS THE THREE-BYTE STRING PUT INTO THE EXPANSION BANKS. ╘HE VALUE MEANS
- "╥┴═ IDENTIFIER".
-
- .%0439! EXP╥AM╔D .BYTE "R"
- .%0440! .BYTE "╔"
- .%0441! .BYTE "D"
- .%0442!
- .%0443! ;--------------------------------------------------------------------
- .%0444! ;*** INITIALIZE DYNAMICALLY ALLOCATED MEMORY() : N┼XP┬ANKS
- .%0445!
-
- ╘HIS ROUTINE CALLS "FREE" TO INITIALIZE THE FREE MEMORY ON EACH EXISTING
- BANK. ╥┴═0 IS SET TO BE FREE FROM $4000 TO THE TOP OF ┬┴╙╔├ MEMORY, SO YOU'LL
- HAVE TO CHANGE THE "RAM0╞REE╙TART╨AGE" PARAMETER IF YOU WANT TO HAVE A PROGRAM
- THAT OCCUPIES MEMORY HIGHER THAN THIS ADDRESS. ╥┴═1 IS DECLARED TO BE FREE
- FROM $0400 TO $╞┼╞╞
-
- .%0446! RAM0╞REE╙TART╨AGE .BYTE $40
- .%0447! RAM1╞REE╙TART╨AGE .BYTE $04
- .%0448! RAM1╞REE╠ENGTH .BYTE 256-1-$04
- .%0449!
- .%0450! CURRENT┼XP┬ANK = SYS╫ORK+$F
- .%0451!
- .%0452! INIT─YNAMIC═EMORY = *
-
- ╙ET THE MEMORY ALLOCATION FIRST FREE CHUNK POINTER TO ╬ULL AND SET THE NUMBER
- OF BYTES OF FREE MEMORY TO 0.
-
- .%0453! LDX #2
- .%0454! - LDA #$00
- .%0455! STA FREE═EMORY,X
- .%0456! LDA #$FF
- .%0457! STA MALLOC╚EAD,X
- .%0458! DEX
- .%0459! BPL -
-
- ─ETERMINE THE LENGTH OF FREE MEMORY ON ╥┴═0 AND FREE THE MEMORY.
-
- .%0460! SEC
- .%0461! LDA $1212 ;TOP OF ┬┴╙╔├ PROGRAM ╠OW
- .%0462! BEQ +
- .%0463! CLC
- .%0464! + LDA $1213 ;TOP OF ┬┴╙╔├ PROGRAM ╚IGH
- .%0465! SBC RAM0╞REE╙TART╨AGE
- .%0466! TAY
- .%0467! LDA RAM0╞REE╙TART╨AGE
- .%0468! LDX #BK╥AM0
- .%0469! JSR INIT╔NTERNAL┬ANK═ALLOC
-
- ╞REE THE MEMORY OF ╥┴═1
-
- .%0470! LDA RAM1╞REE╙TART╨AGE
- .%0471! LDY RAM1╞REE╠ENGTH
- .%0472! LDX #BK╥AM1
- .%0473! JSR INIT╔NTERNAL┬ANK═ALLOC
- .%0474!
-
- ╞OR EACH EXISTING EXPANSION BANK, FREE IT FROM ADDRESSES $0000 TO $╞╞╞7. ┘OU
- CANNOT FREE ALL 65536 BYTES SINCE THIS WOULD CAUSE THE LENGTH OF THE FREE
- CHUNK TO BE SET TO $0000 WHICH WOULD CAUSE PROBLEMS LATER ON. $╞╞╞8 BYTES ARE
- SET TO FREE SINCE THEN LENGTH HAS TO BE A MULTIPLE OF EIGHT BYTES.
-
- .%0475! LDA #0
- .%0476! STA CURRENT┼XP┬ANK
- .%0477! - LDA CURRENT┼XP┬ANK
- .%0478! CMP N┼XP┬ANKS
- .%0479! BCS +
- .%0480! ORA #BK┼XP0
- .%0481! STA ZP1+2
- .%0482! LDA #$00
- .%0483! STA ZP1
- .%0484! STA ZP1+1
- .%0485! LDA #$F8
- .%0486! LDY #$FF
- .%0487! JSR FREE
- .%0488! INC CURRENT┼XP┬ANK
- .%0489! BNE -
- .%0490! + RTS
- .%0491!
-
- ╘HIS ROUTINE IS CALLED FOR FREEING BANKS ╥┴═0 AND ╥┴═1. ╔T DOES NOTHING OTHER
- THAN SET PARAMETERS AND IS PUT IN FOR CONVENIENCE.
-
- .%0492! INIT╔NTERNAL┬ANK═ALLOC = *
- .%0493! STA ZP1+1
- .%0494! STX ZP1+2
- .%0495! LDA #0
- .%0496! STA ZP1
- .%0497! JMP FREE
- .%0498!
- .%0499! ;--------------------------------------------------------------------
- .%0500! ;*** MALLOC( .┴┘=┬YTES ) : [ZP1]=╞AR╨OINTER
- .%0501!
-
- ╧NE OF THE BIGGIES. ╘HE "═EM╬EXT╨TR" AND "═EM╠ENGTH" VARIABLES ARE USED TO
- STORE THE INFORMATION AT THE START OF THE CURRENT FREE MEMORY CHUNK. "╠ENGTH"
- IS USED TO HOLD THE LENGTH INPUT PARAMETER AND "╤" IS THE POINTER TO THE
- PREVIOUS FREE MEMORY CHUNK WHEREAS "ZP1" IS USED TO POINT TO THE CURRENT FREE
- CHUNK. ╔ PREFIX THESE VARIABLES WITH "MALLOC" TO AVOID NAMING COLLISIONS WITH
- OTHER ROUTINES. ╘HE CONCEPT OF LOCAL VARIABLES MIGHT BE A NICE THING FOR
- FUTURE ASSEMBLERS TO HAVE.
-
- .%0502! MALLOC═EM╬EXT╨TR = SYS╫ORK
- .%0503! MALLOC═EM╠ENGTH = SYS╫ORK+3
- .%0504! MALLOC╠ENGTH = SYS╫ORK+5
- .%0505! MALLOC╤ = SYS╫ORK+7
- .%0506!
- .%0507! INTERN┴LLOC = *
-
- ┴LIGN THE NUMBER OF BYTES REQUESTED TO AN EVEN MULTIPLE OF EIGHT.
-
- .%0508! CLC
- .%0509! ADC #7
- .%0510! BCC +
- .%0511! INY
- .%0512! + AND #$F8
- .%0513! STA MALLOC╠ENGTH
- .%0514! STY MALLOC╠ENGTH+1
-
- ╙ET THE CURRENT FREE CHUNK POINTER TO THE FIRST FREE CHUNK AND SET ╤ TO ╬ULL.
-
- .%0515! LDX #2
- .%0516! - LDA MALLOC╚EAD,X
- .%0517! STA ZP1,X
- .%0518! LDA #$FF
- .%0519! STA MALLOC╤,X
- .%0520! DEX
- .%0521! BPL -
- .%0522!
-
- ╙EARCH FOR A FREE CHUNK THAT IS LONG ENOUGH TO SATISFY THE REQUEST.
-
- .%0523! MALLOC╠OOK = *
-
- ╔F THE CURRENT FREE CHUNK POINTER IS ╬ULL, THEN WE ARE ╙.╧.╠. (╧UT OF ╠UCK)
- SINCE THAT MEANS WE HAVE EXHAUSTED THE LIST OF FREE CHUNKS AND HAVE TO REPORT
- THAT NO FREE MEMORY COULD BE FOUND.
-
- .%0524! LDA ZP1+2
- .%0525! CMP #$FF
- .%0526! BNE +
- .%0527!
- .%0528! MALLOC┼RROR┼XIT = *
- .%0529! LDA #$FF ;RETURN A ╬ULL POINTER
- .%0530! STA ZP1
- .%0531! STA ZP1+1
- .%0532! STA ZP1+2
- .%0533! LDA #ERR╔NSUFFICIENT═EMORY
- .%0534! STA ERRNO
- .%0535! SEC
- .%0536! RTS
- .%0537!
-
- ╞ETCH THE HEADER INFORMATION OF THE CURRENT FREE CHUNK AND CHECK THE LENGTH.
- ╔F THE CURRENT FREE CHUNK IS NOT LARGE ENOUGH, THEN WE SET THE ╤ POINTER TO
- THE CURRENT POINTER, AND TAKE THE NEW VALUE FOR THE CURRENT POINTER FROM THE
- HEADER OF THE CURRENT FREE CHUNK (MALLOC═EM╬EXT╨TR) AND THEN CONTINUE
- SEARCHING.
-
- .%0538! + LDX #MALLOC═EM╬EXT╨TR
- .%0539! LDY #5
- .%0540! JSR ZPLOAD
- .%0541! LDA MALLOC═EM╠ENGTH
- .%0542! CMP MALLOC╠ENGTH
- .%0543! LDA MALLOC═EM╠ENGTH+1
- .%0544! SBC MALLOC╠ENGTH+1
- .%0545! BCS MALLOC╟OT┬LOCK
- .%0546! LDX #2
- .%0547! - LDA ZP1,X
- .%0548! STA MALLOC╤,X
- .%0549! LDA MALLOC═EM╬EXT╨TR,X
- .%0550! STA ZP1,X
- .%0551! DEX
- .%0552! BPL -
- .%0553! JMP MALLOC╠OOK
- .%0554!
-
- ╬OW, WE'VE FOUND A BLOCK THAT IS LARGE ENOUGH.
-
- .%0555! MALLOC╟OT┬LOCK = *
- .%0556! SEC
-
- ╙UBTRACT THE NUMBER OF BYTES REQUESTED FROM THE TOTAL NUMBER OF BYTES FREE.
-
- .%0557! LDA FREE═EMORY
- .%0558! SBC MALLOC╠ENGTH
- .%0559! STA FREE═EMORY
- .%0560! LDA FREE═EMORY+1
- .%0561! SBC MALLOC╠ENGTH+1
- .%0562! STA FREE═EMORY+1
- .%0563! BCS +
- .%0564! DEC FREE═EMORY+2
-
- ╔F THE SIZE OF THE CURRENT FREE CHUNK IS EXACTLY THE SAME AS THE NUMBER OF
- BYTES REQUESTED, THEN BRANCH AHEAD.
-
- .%0565! + LDA MALLOC═EM╠ENGTH
- .%0566! CMP MALLOC╠ENGTH
- .%0567! BNE +
- .%0568! LDA MALLOC═EM╠ENGTH+1
- .%0569! SBC MALLOC╠ENGTH+1
- .%0570! BEQ MALLOC╘AKE╫HOLE┬LOCK
-
- ╙UBTRACT THE NUMBER OF BYTES REQUESTED FROM THE LENGTH OF THE CURRENT FREE
- CHUNK AND THEN WRITE THE UPDATED HEADER BACK TO THE CURRENT FREE CHUNK.
-
- .%0571! + SEC
- .%0572! LDA MALLOC═EM╠ENGTH
- .%0573! SBC MALLOC╠ENGTH
- .%0574! STA MALLOC═EM╠ENGTH
- .%0575! LDA MALLOC═EM╠ENGTH+1
- .%0576! SBC MALLOC╠ENGTH+1
- .%0577! STA MALLOC═EM╠ENGTH+1
- .%0578! LDX #MALLOC═EM╬EXT╨TR
- .%0579! LDY #5
- .%0580! JSR ZPSTORE
-
- ┴DD THE LENGTH OF THE FREE CHUNK TO THE POINTER TO THE START OF THE FREE CHUNK
- TO DETERMINE THE ADDRESS OF THE MEMORY THAT HAS JUST BEEN ALLOCATED. ╘HEN
- EXIT, RETURNING THIS ADDRESS.
-
- .%0581! CLC
- .%0582! LDA ZP1
- .%0583! ADC MALLOC═EM╠ENGTH
- .%0584! STA ZP1
- .%0585! LDA ZP1+1
- .%0586! ADC MALLOC═EM╠ENGTH+1
- .%0587! STA ZP1+1
- .%0588! CLC
- .%0589! RTS
- .%0590!
-
- ╚ERE, THE SIZE OF THE FREE CHUNK IS EXACTLY THE SAME SIZE AS THE REQUEST, SO
- THE ENTIRE BLOCK HAS TO BE ALLOCATED AND THUS REMOVED FROM THE FREE CHUNK
- LIST. ╘HIS IS WHY THE ╤ POINTER HAS BEEN MAINTAINED.
-
- .%0591! MALLOC╘AKE╫HOLE┬LOCK = *
-
- ╔F THERE IS NO PREVIOUS BLOCK (╤ == ╬ULL) THEN SET THE FREE CHUNK LIST HEAD
- POINTER TO THE NEXT FREE CHUNK AFTER THE CURRENT ONE. ╘HEN EXIT WITH THE
- CURRENT CHUNK AS THE RETURN POINTER.
-
- .%0592! LDA MALLOC╤+2
- .%0593! CMP #BK╬ULL
- .%0594! BNE +
- .%0595! LDX #2
- .%0596! - LDA MALLOC═EM╬EXT╨TR,X
- .%0597! STA MALLOC╚EAD,X
- .%0598! DEX
- .%0599! BPL -
- .%0600! CLC
- .%0601! RTS
-
- ╔F THERE IS AN ACTUAL PREVIOUS CHUNK, THEN WE HAVE TO SET IT TO POINT TO THE
- NEXT CHUNK FROM THE CURRENT CHUNK. ╘HIS WILL UNLINK THE CURRENT FREE CHUNK
- FROM THE FREE CHUNK LIST, THEREBY ALLOCATING IT.
-
- ╞IRST, WE SWAP THE ╤ AND CURRENT POINTERS, SINCE WE CAN ONLY ACCESS MEMORY
- THROUGH THE "ZP1" POINTER.
-
- .%0602! + LDX #2
- .%0603! - LDA ZP1,X
- .%0604! LDY MALLOC╤,X
- .%0605! STA MALLOC╤,X
- .%0606! STY ZP1,X
- .%0607! DEX
- .%0608! BPL -
-
- ╘HEN WE SET THE THE ╬EXT╨OINTER OF THE PREVIOUS FREE CHUNK TO POINT TO THE
- NEXT FREE CHUNK AFTER THE CURRENT CHUNK.
-
- .%0609! LDX #MALLOC═EM╬EXT╨TR
- .%0610! LDY #3
- .%0611! JSR ZPSTORE
-
- ┴ND THEN WE RESTORE THE CURRENT CHUNK POINTER AND RETURN IT TO THE USER.
-
- .%0612! LDX #2
- .%0613! - LDA MALLOC╤,X
- .%0614! STA ZP1,X
- .%0615! DEX
- .%0616! BPL -
- .%0617! CLC
- .%0618! RTS
- .%0619!
- .%0620! ;*** FREE( [ZP1]=╞AR╨OINTER, .┴┘=╠ENGTH ) █ALTERS [ZP1]▌
- .%0621!
-
- ┴ND HERE IS THE REAL BIGGIE, SINCE ╞REE IS MORE COMPLICATED THAN ═ALLOC. ╘HE
- VARIABLES ARE THE SAME AS FOR FREE, EXCEPT THAT "╬EW╨TR" IS REQUIRED TO
- REMEMBER THE INPUT PARAMETER TO NEW CHUNK TO BE FREED.
-
- .%0622! FREE═EM╬EXT╨TR = SYS╫ORK
- .%0623! FREE═EM╠ENGTH = SYS╫ORK+3
- .%0624! FREE╠ENGTH = SYS╫ORK+5
- .%0625! FREE╬EW╨TR = SYS╫ORK+7
- .%0626! FREE╤ = SYS╫ORK+10
- .%0627!
- .%0628! INTERN╞REE = *
-
- ┴GAIN, ALIGN THE LENGTH OF THE CHUNK. ╘HE POINTER TO THE START OF THE NEW
- CHUNK IS ASSUMED TO BE ALIGNED (SINCE MALLOC ONLY RETURNS ALIGNED CHUNKS). ╔F
- THE CHUNK POINTER IS NOT ALIGNED, ALL HELL CAN BREAK LOOSE.
-
- .%0629! CLC
- .%0630! ADC #7
- .%0631! BCC +
- .%0632! INY
- .%0633! + AND #$F8
- .%0634! STA FREE╠ENGTH
- .%0635! STY FREE╠ENGTH+1
-
- ╙AVE THE NEW CHUNK INPUT PARAMETER AND SET "ZP1" FOR SEARCHING THE FREE CHUNK
- LIST. ┴LSO SET ╤ TO ╬ULL SINCE ╤ WILL BE USED TO REMEMBER THE PREVIOUS BLOCK
- TO "ZP1".
-
- .%0636! LDX #2
- .%0637! - LDA ZP1,X
- .%0638! STA FREE╬EW╨TR,X
- .%0639! LDA MALLOC╚EAD,X
- .%0640! STA ZP1,X
- .%0641! LDA #$FF
- .%0642! STA FREE╤,X
- .%0643! DEX
- .%0644! BPL -
- .%0645!
-
- ╙EARCH FOR THE TWO FREE CHUNKS WHOSE ADDRESSES STRADDLE THE NEW FREE CHUNK.
-
- .%0646! FREE╙EARCH╠OOP = *
-
- ╔F THE CURRENT FREE CHUNK POINTER IS ╬ULL OR IF THE CURRENT FREE CHUNK'S BANK
- NUMBER IS LESS THAN THE NEW CHUNK'S BANK NUMBER, THEN WE CAN STOP SEARCHING;
- WE HAVE FOUND A FREE CHUNK THAT IS "HIGHER" THAN THE NEW CHUNK, SO ╤ AND ZP1
- MUST STRADDLE THE ADDRESS OF THE NEW CHUNK. ╬OTE THAT BY USING A "BCC" ON
- LINE 652, EXTERNAL MEMORY FREE CHUNKS WILL BE ALLOCATED FIRST. ╔F ╔ HAD USED
- A "BCS" THERE, THE INTERNAL MEMORY STARTING FROM ╥┴═0 WOULD BE ALLOCATED
- FIRST.
-
- .%0647! LDA ZP1+2
- .%0648! CMP #$FF
- .%0649! BEQ FREE├OALESCE╤AND╬EW
- .%0650! LDA ZP1+2
- .%0651! CMP FREE╬EW╨TR+2
- .%0652! BCC FREE├OALESCE╤AND╬EW ;** DETERMINES BANK ORDER
-
- ╚ERE WE KNOW THAT THE BANK NUMBER IS NOT "HIGHER", SO IF THE BANK NUMBERS ARE
- NOT EQUAL, THEN WE CONTINUE SEARCHING. ╔F THE BANK NUMBERS ARE EQUAL, WE MUST
- CHECK THE ADDRESSES WITHIN THE BANK TO SEE IF ZP1 IS HIGHER THAN THE NEW
- CHUNK. ╔F SO, WE STOP SEARCHING.
-
- .%0653! BNE +
- .%0654! LDA ZP1
- .%0655! CMP FREE╬EW╨TR
- .%0656! LDA ZP1+1
- .%0657! SBC FREE╬EW╨TR+1
- .%0658! BCS FREE├OALESCE╤AND╬EW
-
- ╚ERE WE CONTINUE SEARCHING. ╫E STICK THE CURRENT FREE CHUNK POINTER INTO ╤
- AND GET THE NEXT FREE CHUNK POINTER FROM THE CURRENT CHUNK IN MEMORY. ╘HEN WE
- GO BACK TO THE TOP OF THE SEARCH.
-
- .%0659! + LDX #FREE═EM╬EXT╨TR
- .%0660! LDY #3
- .%0661! JSR ZPLOAD
- .%0662! LDX #2
- .%0663! - LDA ZP1,X
- .%0664! STA FREE╤,X
- .%0665! LDA FREE═EM╬EXT╨TR,X
- .%0666! STA ZP1,X
- .%0667! DEX
- .%0668! BPL -
- .%0669! BMI FREE╙EARCH╠OOP
- .%0670!
-
- ╚ERE WE KNOW THAT ╤ AND ZP1 STRADDLE THE NEW CHUNK, AND WE TRY TO COALESCE THE
- NEW CHUNK TO THE ╤ CHUNK.
-
- .%0671! FREE├OALESCE╤AND╬EW = *
- .%0672! LDX #2
- .%0673! - LDA FREE╤,X
- .%0674! STA ZP1,X
- .%0675! DEX
- .%0676! BPL -
-
- ╔F THE ╤ POINTER IS ╬ULL, THEN THERE IS NO ╤ CHUNK TO COALESCE WITH, SO THE
- FREE CHUNK HEAD POINTER IS SET TO POINT TO THE NEW CHUNK AND THE NEW CHUNK
- HEADER IS SET TO THE SIZE OF THE NEW CHUNK. ╘HEN NEXT POINTER FOR THE NEW
- CHUNK IS SET TO WHAT WAS PREVIOUSLY THE HEAD POINTER.
-
- .%0677! LDA ZP1+2
- .%0678! CMP #$FF
- .%0679! BNE +
- .%0680! LDX #2
- .%0681! - LDA MALLOC╚EAD,X
- .%0682! STA FREE═EM╬EXT╨TR,X
- .%0683! LDA FREE╬EW╨TR,X
- .%0684! STA MALLOC╚EAD,X
- .%0685! DEX
- .%0686! BPL -
- .%0687! LDA FREE╠ENGTH
- .%0688! LDY FREE╠ENGTH+1
- .%0689! STA FREE═EM╠ENGTH
- .%0690! STY FREE═EM╠ENGTH+1
- .%0691! JMP FREE├OALESCE╬EW┴ND╨
- .%0692!
-
- ╚ERE THERE ACTUALLY IS A PREVIOUS (╤) CHUNK, SO ITS HEADER IS FETCHED. ╔F IT
- IS NOT ON THE SAME BANK AS THE NEW CHUNK, THEN THE NEW CHUNK CANNOT BE
- COALESCED WITH IT. ┴LSO, IF THE ADDRESS OF THE NEW CHUNK DOES NOT EXACTLY
- FOLLOW THE ╤ CHUNK, THEN THEY CANNOT BE COALESCED.
-
- .%0693! + LDX #FREE═EM╬EXT╨TR
- .%0694! LDY #5
- .%0695! JSR ZPLOAD
- .%0696! LDA ZP1+2
- .%0697! CMP FREE╬EW╨TR+2
- .%0698! BNE +
- .%0699! CLC
- .%0700! LDA ZP1
- .%0701! ADC FREE═EM╠ENGTH
- .%0702! TAX
- .%0703! LDA ZP1+1
- .%0704! ADC FREE═EM╠ENGTH+1
- .%0705! CMP FREE╬EW╨TR+1
- .%0706! BNE +
- .%0707! CPX FREE╬EW╨TR
- .%0708! BNE +
-
- ╚ERE, WE KNOW THAT THE PREVIOUS CHUNK AND THE NEW CHUNK CAN BE COALESCED. ╫E
- ADD THE LENGTH OF THE NEW CHUNK TO THE LENGTH OF THE PREVIOUS CHUNK AND CHANGE
- THE NEW CHUNK POINTER TO POINT TO THE PREVIOUS CHUNK.
-
- .%0709! CLC
- .%0710! LDA FREE═EM╠ENGTH
- .%0711! ADC FREE╠ENGTH
- .%0712! STA FREE═EM╠ENGTH
- .%0713! LDA FREE═EM╠ENGTH+1
- .%0714! ADC FREE╠ENGTH+1
- .%0715! STA FREE═EM╠ENGTH+1
- .%0716! LDX #2
- .%0717! - LDA FREE╤,X
- .%0718! STA FREE╬EW╨TR,X
- .%0719! DEX
- .%0720! BPL -
- .%0721! BMI FREE├OALESCE╬EW┴ND╨
- .%0722!
-
- ╚ERE, WE KNOW THAT THE PREVIOUS AND NEW CHUNKS CANNOT BE COALESCED. ╫E CHANGE
- THE ACTUAL HEADER OF THE PERVIOUS CHUNK TO POINT TO THE NEW CHUNK AND CHANGE
- THE NEW CHUNK HEADER LENGTH TO THE FREE REQUEST LENGTH. ╘HE POINTER TO THE
- NEXT CHUNK IS ALREADY IN THE NEW CHUNK HEADER FROM BEFORE. ╬OTE THAT NOW WE
- ARE USING "═EM╬EXT╨TR" AND "═EM╠ENGTH" TO CONSTRUCT THE NEW FREE CHUNK
- HEADER. ╠INE 729 CAUSED ═R. ┬RUCE SOME PROBLEMS BECAUSE HE FORGOT TO STICK
- THE "+1" THERE AFTER EXTRACTING THE CODE FROM ┌ED.
-
- .%0723! + LDX #FREE╬EW╨TR
- .%0724! LDY #3
- .%0725! JSR ZPSTORE
- .%0726! LDA FREE╠ENGTH
- .%0727! LDY FREE╠ENGTH+1
- .%0728! STA FREE═EM╠ENGTH
- .%0729! STY FREE═EM╠ENGTH+1
- .%0730!
-
- ┴T THIS POINT, WE ARE FINISHED TRYING TO COALESCE THE NEW CHUNK WITH THE
- PREVIOUS CHUNK, SO WE WILL ATTEMPT TO COALESCE THE NEW CHUNK WITH THE NEXT
- HIGHER ADDRESS FREE CHUNK. ╘HE "═EM╬EXT╨TR" AND "═EM╠ENGTH" VARIABLES HOLD
- THE HEADER INFORMATION FOR THE NEW CHUNK (THE "═EM╬EXT╨TR" ALSO POINTS TO THE
- NEXT FREE CHUNK), AND "╬EW╨TR" POINTS TO THE NEW CHUNK. ╫E CHECK TO SEE IF
- THE NEW CHUNK IMMEDIATELY PRECEEDS THE NEXT CHUNK IN THE SAME WAY AS BEFORE.
- ╬OTE THAT THE CASE OF A ╬ULL NEXT CHUNK POINTER IS HANDLED HERE IMPLICITLY,
- SINCE THE BANK NUMBERS WON'T MATCH.
-
- .%0731! FREE├OALESCE╬EW┴ND╨ = *
- .%0732! LDA FREE╬EW╨TR+2
- .%0733! CMP FREE═EM╬EXT╨TR+2
- .%0734! BNE +
- .%0735! CLC
- .%0736! LDA FREE╬EW╨TR
- .%0737! ADC FREE═EM╠ENGTH
- .%0738! TAX
- .%0739! LDA FREE╬EW╨TR+1
- .%0740! ADC FREE═EM╠ENGTH+1
- .%0741! CMP FREE═EM╬EXT╨TR+1
- .%0742! BNE +
- .%0743! CPX FREE═EM╬EXT╨TR
- .%0744! BNE +
- .%0745!
-
- ╚ERE, WE KNOW THAT THE NEW CHUNK CAN BE COALESCED WITH THE NEXT CHUNK. ╫E
- HAVE TO FETCH THE HEADER OF THE NEXT CHUNK TO KNOW THE LENGTH AND THE POINTER
- TO THE FREE CHUNK AFTER THE NEXT CHUNK. ╫E THEN ADD THE LENGTH OF THE NEXT
- CHUNK TO THE LENGTH OF THE NEW CHUNK AND KEEP THE POINTER TO THE CHUNK AFTER
- THE NEXT CHUNK FOR THE NEW CHUNK HEADER. ┼FFECTIVELY, THE NEXT FREE CHUNK IS
- UNLINKED (SINCE NOTHING IS LEFT TO POINT TO IT) AND THE NEW CHUNK GROWS TO
- SWALLOW IT UP.
-
- .%0746! LDX #2
- .%0747! - LDA FREE═EM╬EXT╨TR,X
- .%0748! STA ZP1,X
- .%0749! DEX
- .%0750! BPL -
- .%0751! LDA FREE═EM╠ENGTH+1
- .%0752! PHA
- .%0753! LDA FREE═EM╠ENGTH
- .%0754! PHA
- .%0755! LDX #FREE═EM╬EXT╨TR
- .%0756! LDY #5
- .%0757! JSR ZPLOAD
- .%0758! CLC
- .%0759! PLA
- .%0760! ADC FREE═EM╠ENGTH
- .%0761! STA FREE═EM╠ENGTH
- .%0762! PLA
- .%0763! ADC FREE═EM╠ENGTH+1
- .%0764! STA FREE═EM╠ENGTH+1
- .%0765!
-
- ╚ERE, WE WRAP THINGS UP. ╫E HAVE THE HEADER FOR THE NEW FREE CHUNK ALL
- PREPARED AND WE HAVE TRIED TO COALESCE THE TWO NEIGHBORING CHUNKS TO THE NEW
- CHUNK. ┴LL WE DO NOW IS WRITE THE NEW CHUNK HEADER OUT TO MAIN MEMORY AND
- INCREASE THE NUMBER OF BYTES FREE VARIABLE BY THE LENGTH OF THE (ORIGINAL)
- FREE REQUEST.
-
- .%0766! + LDX #2
- .%0767! - LDA FREE╬EW╨TR,X
- .%0768! STA ZP1,X
- .%0769! DEX
- .%0770! BPL -
- .%0771! LDX #FREE═EM╬EXT╨TR
- .%0772! LDY #5
- .%0773! JSR ZPSTORE
- .%0774! CLC
- .%0775! LDA FREE═EMORY
- .%0776! ADC FREE╠ENGTH
- .%0777! STA FREE═EMORY
- .%0778! LDA FREE═EMORY+1
- .%0779! ADC FREE╠ENGTH+1
- .%0780! STA FREE═EMORY+1
- .%0781! BCC +
- .%0782! INC FREE═EMORY+2
-
- ╫E ALWAYS RETURN WITH CARRY CLEARED, SINCE WE DON'T CHECK FOR ANY ERRORS.
-
- .%0783! + CLC
- .%0784! RTS
- .%0785!
- .%0786! ;--------------------------------------------------------------------
- .%0787! ;*** SORT - THE APPLICATION: READS FROM FILE #1, WRITES TO FILE #2
- .%0788!
-
- ╘HIS IS WHERE THE ACTUAL APPLICATION CODE STARTS. ╔F YOU WANT TO WRITE YOUR
- OWN PROGRAM THAT USES THE DYNAMIC MEMORY ALLOCATION PACKAGE, THEN YOU CAN
- FOLLOW THE STRUCTURE OF THIS APPLICATION.
-
- ╫E START OFF BY DECLARING THE STORAGE AREAS FOR THE CURRENT LINE BEING
- PROCESSED AND FOR THE LINE BEING COMPARED TO THE CURRENT LINE. ╘HE ADDRESSES
- REFLECT THE STRUCTURE OF THE RECORD FOR THE INPUT LINE THAT WAS DISCUSSED
- EARLIER. ╘HE SORTING FIELD STARTING COLUMN NUMBER PARAMETER IS CAN BE PUT AT
- $8╞╞ SINCE THE INPUT LINE CAN ONLY BE 242 CHARACTERS LONG.
-
- .%0789! SORTBUF = $B00
- .%0790! SORTBUFLEN = $B03
- .%0791! SORTLINE = $B04
- .%0792! CMPBUF = $800
- .%0793! CMPBUFLEN = $803
- .%0794! CMPLINE = $804
- .%0795! SORT├OLUMN = $8FF
- .%0796!
-
- ╘HESE ARE THE ZERO PAGE LOCATIONS THAT SORT USES.
-
- .%0797! EOFSTAT = $02 ;DEFERRED ╙╘ VARIABLE ($90)
- .%0798! SORTHEAD = $03 ;POINTER TO FIRST LINE IN LINE LIST
- .%0799! SORT╨ = $06 ;CURRENT LINE FOR LIST SEARCHING
- .%0800! SORT╤ = $09 ;PREVIOUS LINE FOR LIST SEARCHING
- .%0801! HEADER = $0C ;4 BYTES - HOLDS THE CURRENT LINE RECORD'S HEADER
- .%0802!
-
- ┴ND THESE ARE THE KERNEL ROUTINES THAT ARE CALLED.
-
- .%0803! KERNEL├HKIN = $FFC6
- .%0804! KERNEL├HKOUT = $FFC9
- .%0805! KERNEL├LRCHN = $FFCC
- .%0806! KERNEL├HRIN = $FFCF
- .%0807! KERNEL├HROUT = $FFD2
-
- "ECHO╙TATUS" CAN BE CHANGED TO POINT TO AN ╥╘╙ IF YOU DO NOT WANT SORT TO
- PRINT STATUS INFORMATION OUT WHILE IT IS WORKING.
-
- .%0808! ECHO╙TATUS = KERNEL├HROUT
- .%0809!
- .%0810! ;*** GETLINE( SORTLINE ) : .├╙=EOF
- .%0811!
-
- ╘HIS ROUTINE READS A NEW LINE IN FROM THE CURRENT INPUT CHANNEL AND PUTS IT
- INTO THE PROCESSING BUFFER. ╔T RETURNS WITH CARRY SET IF THERE ARE NO MORE
- LINES TO READ OR IF A READ ERROR OCCURS.
-
- .%0812! GETLINE = *
- .%0813! LDY #0
-
- ╘HE "EOFSTAT" IS CHECKED FIRST TO SEE IF THE PREVIOUS CHARACTER READ BEFORE
- THE NEW CALL WAS THE LAST OF THE FILE. ╘HIS OVERCOMES THE KERNEL'S AWKWARD
- WAY OF SETTING ┼╧╔ FOR THE LAST CHARACTER RATHER THAN WHEN FOR WHEN YOU GO
- BEYOND THE LAST CHARACTER.
-
- .%0814! - BIT EOFSTAT
- .%0815! BVS GETLINE┼OF
- .%0816! JSR KERNEL├HRIN
- .%0817! BCS GETLINE┼OF
- .%0818! STA SORTLINE,Y
- .%0819! INY
- .%0820! LDX $90
- .%0821! STX EOFSTAT
-
- ╔T EXITS WHEN THE MAXIMUM LINE LENGTH IS EXCEEDED OR WHEN A CARRIAGE RETURN IS
- ENCOUNTERED.
-
- .%0822! CPY #242
- .%0823! BCS GETLINE┼XIT
- .%0824! CMP #13
- .%0825! BNE -
- .%0826! DEY
- .%0827!
-
- ┴ TRAILING '\0' IS APPENDED TO THE STRING FOR EASIER PROCESSING LATER, AND THE
- LENGTH OF THE INPUT LINE RECORD IS RECORDED. ╘HE LENGTH OF THE ENTIRE RECORD
- RATHER THAN THE LENGTH OF JUST THE TEXT IS MORE CONVENIENT TO KNOW WHEN
- WORKING WITH THE MEMORY PACKAGE.
-
- .%0828! GETLINE┼XIT = *
- .%0829! LDA #0
- .%0830! STA SORTLINE,Y
- .%0831! CLC
- .%0832! TYA
- .%0833! ADC #5
- .%0834! STA SORTBUFLEN
- .%0835! CLC
- .%0836! RTS
- .%0837!
-
- ╧N END OF FILE, WE EXIT WITH CARRY SET. ╔F, HOWEVER, WE HAVE READ CHARACTERS
- BEFORE THE ┼╧╞ WAS ENCOUNTERED, THEY ARE RETURNED AS BELONGING TO THE LAST
- LINE OF THE FILE. ╘RUE ┼╧╞ WILL BE RETURNED ON THE NEXT CALL.
-
- .%0838! GETLINE┼OF = *
- .%0839! LDA #$40
- .%0840! STA EOFSTAT
- .%0841! CPY #0
- .%0842! BNE GETLINE┼XIT
- .%0843! SEC
- .%0844! RTS
- .%0845!
- .%0846! ;*** PUTLINE( APPLINE )
- .%0847!
-
- ╘HIS ROUTINE SIMPLY WRITES OUT THE CURRENT LINE ('\0' TERMINATED) AND WRITES
- AN ADDITIONAL CARRIAGE RETURN, SINCE THE GETLINE ROUTINE STRIPS OFF THE ├╥.
-
- .%0848! PUTLINE = *
- .%0849! LDY #0
- .%0850! - LDA SORTLINE,Y
- .%0851! BEQ +
- .%0852! JSR KERNEL├HROUT
- .%0853! INY
- .%0854! BNE -
- .%0855! + LDA #13
- .%0856! JMP KERNEL├HROUT
- .%0857!
- .%0858! ;*** FETCHLINE( SORT╨=╠INE╨TR, .┴┘=╥AM0BUF )
- .%0859!
-
- ╘HIS ROUTINE FETCHES THE LINE AT THE POINTER SORT╨ INTO ╥┴═0 AT THE GIVEN
- ADDRESS. ╔T HAS TO ZPLOAD THE LINE HEADER FIRST TO DETERMINE THE RECORD SIZE
- TO FETCH.
-
-