; LOADER.S ; THIS FILE CONTAINS TWO ROUTINES: THE MOVING CHARACTER LOADER, "MLOADER", ; WHICH IS CALLED EVERY OTHER FRAME, AND THE FIXED CHARACTER ; LOADER, "FLOADER", WHICH IS CALLED ONCE AT THE BEGINNING OF EACH ; RACK. ; ; THIS LOADER ASSUMES 16-HIGH ZONES, NUMBERED WITH ZONE 0 AT THE BOTTOM OF ; THE SCREEN; WITH "OFFSET" DECREMENTING THROUGH EACH ZONE, SO THAT ; THE CHARACTER TABLES MUST BE STORED UPSIDE DOWN. ; ; BECAUSE OF THE IMMANENT MARIA II, I'VE CHANGED MY STAMP ORGANIZATION ; TO REFLECT THE ONCOMING "HOLY ROM". THUS, EVEN THE FIXED CHARACTERS ; HAVE ZERO PADDING FOR NOW, TO SIMULATE THE WAY THE HOLY ROM WILL ; ACTUALLY APPEAR. ALL CHARACTERS HAVE THEIR FIRST REAL INFO AT ; EITHER "BLOCK1" ($50) OR "BLOCK2" ($70) ; AND ALL CHARACTERS EXTEND THROUGH 16 PAGES OF ; ROM. ; SINCE "MLOADER" INCREMENTS INDICES, THE HERO HAS LOWEST PRIORITY, THE CHEFS ; NEXT LOWEST, AND THE MOVING FOODS HAVE HIGHEST. ALL MOVING CHARS. ; HAVE PRIORITY OVER FIXED CHARACTERS. GLBL MLOADER MLOADER LDX #NUMZONES-1 ; INDEX OF THE LAST ZONE ; INITIALIZE THE SIZE OF EACH LIST TO BE AFTER THE FIXED CHARACTERS ALREADY ; IN THE LISTS. ZLOAD00 LDA LISTSTRT,X STA LISTSIZE,X DEX BPL ZLOAD00 ; THE LOADER ITSELF: LDY #0 ; REGISTER Y WILL CONTAIN THE CH INDEX GETSTAMP LDA CYPOS,Y STY LTEMPY ; STORES THE CHARACTER INDEX BEQ JMPNXTS ; IF Y = 0, STAMP IS INVISIBLE STA TEMPYPOS ; Y POSITION LSR A ; DIVIDE BY 16 LSR A LSR A LSR A ; "A" NOW CONTAINS THE ZONE NUMBER CMP #11 ; IF GREATER THAN 10, WE FUCKED UP BPL JMPNXTS TAX ; REGISTER X IS THE ZONE INDEX MOVE CXPOS,Y,HEADER3 ; SETUP THE HEADER BYTES WHICH MOVE CSTAMP,Y,HEADER0 ; ARE CONSTANT ACROSS ZONES MOVE CHSTAMP,Y,HEADER2 MOVE CPALW,Y,HEADER1 MOVE CSECOND,Y,LSECOND ; FOR LATER OVERLAP TEST ; THE FOLLOWING LOOP, "OVERLAPS", GETS EXECUTED ONCE FOR EACH ZONE WHICH ; THE CHARACTER IS IN. THE ONLY THING WHICH CHANGES IS THE HIGH ; BYTE OF THE HEADER; THE VARIABLE "HIGHPOS" KEEPS TRACK OF THE ; CURRENT HIGH BYTE. THE CHARACTER INFO IS FINISHED WHEN THE ; VALUE AT (HIGHPOS+8,HEADER0) IS 0; WHEN THIS CONDITION IS ; SATISFIED, I KNOW THE LAST ZONE OF THIS CHARACTER HAS JUST ; BEEN LOADED, AND I CAN BRANCH TO "NXTSTAMP". OVERLAPS LDY LISTSIZE,X ; SEE IF DLIST IS ALREADY FULL CPY #LISTLENG BCC NUFFROOM ; If there's no room for this stamp, it'll be invisible anyway, so remove ; it from gameplay. ; Assume that this is a food; if a chef, it'll become immediately obvious AALOAD LDY LTEMPY character index LDA #0 STA CYPOS,Y LDA STATUS if food is flying through air to hero, CMP #STATHIT make sure this gets decremented BNE NXTSTAMP LDA CSTATE,Y must be a food with state ANGLE CMP #ANGLE BNE NXTSTAMP LDA #6 make the splat sound JSR TUNIN DEC NUMINAIR JMPNXTS BPL NXTSTAMP a jump-- numinair is always positive ; REGISTER Y IS NOW AN INDEX TO THE NEXT FREE HEADER BYTE IN THE DLIST. NUFFROOM MOVE LISTTABL,X,LISTPTR ; ELSE SET UP THE LIST POINTER MOVE LISTTABH,X,LISTPTR+1 LDA HEADER0 STA (LISTPTR),Y ; FIRST BYTE OF HEADER INY LDA HEADER1 ; SECOND BYTE OF HEADER STA (LISTPTR),Y INY ; THE THIRD BYTE IS THE ONLY TRICKY ONE. IF THIS IS THE FIRST ZONE OF THE ; CHARACTER, "HIGHPOS" MUST BE INITIALIZED TO ; (LAST CHAR INFO) - (16 LINES) + (# ZEROS NEEDED). ; NOTE THAT (# ZEROS NEEDED) = (TOPZONE,X) - (TEMPYPOS). LDA TOPZONE,X ; CALCULATE NUMBER OF ZEROS SEC SBC TEMPYPOS BCC HIGHSET ; IF NEGATIVE, THIS ISN'T THE FIRST ZONE CLC ; ELSE WE NEED TO SET HIGHPOS ADC HEADER2 ; HIGH BYTE OF CHAR. TABLES STA HIGHPOS HIGHSET LDA HIGHPOS STA (LISTPTR),Y ; FINALLY, STORE THE THIRD HEADER BYTE INY LDA HEADER3 ; NOW THE LAST HEADER BYTE STA (LISTPTR),Y INY STY LISTSIZE,X ; READY FOR THE NEXT HEADER ; WE'RE FINISHED WITH THIS HEADER. CHECK TO SEE IF THIS CHARACTER IS ; FINISHED. THIS WILL BE TRUE IF "HIGHPOS" IS LESS THAN OR EQUAL TO ; THE HIGH BYTE OF THE FIRST PAGE OF REAL CHARACTER INFO (THE VALUE ; "STAMPHGH"). ; NOTE: IF THE VALUE IN "CSECOND" IS NON-ZERO, DON'T DO THE SECOND ; HEADER OF THIS STAMP. (FOR FALLING AND GROWING FROM HOLES) LDA LSECOND ; VALUE FROM ABOVE BNE NXTSTAMP ; IF NON-ZERO, SKIP NEXT HALF LDA HIGHPOS SEC SBC #1 ; TO GET <= OPERATION CMP HEADER2 BCC NXTSTAMP ; IF LAST REAL INFO HAS BEEN DISPLAYED LDA HIGHPOS SEC SBC #16 ; GET NEW "HIGHPOS" VALUE STA HIGHPOS DEX ; POINT TO NEXT LOWER ZONE BPL OVERLAPS ; IF IT'S ON THE SCREEN, DO IT NXTSTAMP LDY LTEMPY ; REMEMBER, THIS IS THE CHAR. INDEX ! INY CPY #TOTALCH BPL ENDLOAD temporary for bug detection JMP GETSTAMP ; BMI GETSTAMP ; KEEP GOING UNTIL ALL ARE DONE ENDLOAD ; NOW, LOOP THROUGH ALL THE ZONES ONE MORE TIME, AND PLACE TERMINATING ; ZEROS IN THE SECOND BYTE OF THE FIRST FREE HEADER: LDX #NUMZONES-1 ENDLIST LDY LISTSIZE,X INY MOVE LISTTABL,X,LISTPTR ; CALCULATE ZONE POINTER MOVE LISTTABH,X,LISTPTR+1 LDA #0 STA (LISTPTR),Y DEX BPL ENDLIST RTS ; FLOADER ; THIS ROUTINE IS ALMOST IDENTICAL TO "MLOADER". IT'S ISOMORPHIC, BUT ; WITH ALL MOVING CHAR REFERENCES REPLACED BY FIXED CHAR REFERENCES. ; NOTE: THE INDEX IN THE MAIN LOOP HERE INCREMENTS (UNLIKE "MLOADER" ; WHICH DECREMENTS). IT MUST DO THIS DUE TO THE WAY I'VE ; IMPLEMENTED FOOD PILES; I CREATE THEM WHILE INCREMENTING, THUS ; I HAVE TO BE ABLE TO KNOW THEIR DLIST POSITIONS AT CREATION TIME. ; THIS IS POSSIBLE ONLY IF I ALSO INCREMENT HERE. FLOADER LDX #NUMZONES-1 ; RESTORE LISTSIZE FROM LISTSTRT ZFLOAD00 LDA LISTSTRT,X STA LISTSIZE,X DEX BPL ZFLOAD00 LDY #0 ; REGISTER Y WILL CONTAIN THE CH INDEX GETFIXED LDA FYPOS,Y STY LTEMPY ; STORES THE CHARACTER INDEX BEQ NXTFIXED ; IF Y = 0, STAMP IS INVISIBLE STA TEMPYPOS ; Y POSITION LSR A LSR A LSR A LSR A ; "A" NOW CONTAINS THE ZONE NUMBER TAX ; REGISTER X IS THE ZONE INDEX MOVE FXPOS,Y,HEADER3 ; SETUP THE HEADER BYTES WHICH MOVE FSTAMP,Y,HEADER0 ; ARE CONSTANT ACROSS ZONES MOVE FHSTAMP,Y,HEADER2 MOVE FPALW,Y,HEADER1 ; THE FOLLOWING LOOP, "FOVERLAP", GETS EXECUTED ONCE FOR EACH ZONE WHICH ; THE CHARACTER IS IN. THE ONLY THING WHICH CHANGES IS THE HIGH ; BYTE OF THE HEADER; THE VARIABLE "HIGHPOS" KEEPS TRACK OF THE ; CURRENT HIGH BYTE. THE CHARACTER INFO IS FINISHED WHEN THE ; HIGHPOS IS <= #FIXEDHGH; WHEN THIS CONDITION IS ; SATISFIED, I KNOW THE LAST ZONE OF THIS CHARACTER HAS JUST ; BEEN LOADED, AND I CAN BRANCH TO "NXTSTAMP". FOVERLAP LDY LISTSIZE,X ; SEE IF DLIST IS ALREADY FULL CPY #LISTLENG BCS NXTFIXED ; IF IT IS, GO ON TO THE NEXT STAMP ; REGISTER Y IS NOW AN INDEX TO THE NEXT FREE HEADER BYTE IN THE DLIST. MOVE LISTTABL,X,LISTPTR ; ELSE SET UP THE LIST POINTER MOVE LISTTABH,X,LISTPTR+1 LDA HEADER0 STA (LISTPTR),Y ; FIRST BYTE OF HEADER INY LDA HEADER1 ; SECOND BYTE OF HEADER STA (LISTPTR),Y INY ; THE THIRD BYTE IS THE ONLY TRICKY ONE. IF THIS IS THE FIRST ZONE OF THE ; CHARACTER, "HIGHPOS" MUST BE INITIALIZED TO ; (LAST CHAR INFO) - (16 LINES) + (# ZEROS NEEDED). ; NOTE THAT (# ZEROS NEEDED) = (TOPZONE,X) - (TEMPYPOS). LDA TOPZONE,X ; CALCULATE NUMBER OF ZEROS SEC SBC TEMPYPOS BCC FHIGHSET ; IF NEGATIVE, THIS ISN'T THE FIRST ZONE CLC ; ELSE WE NEED TO SET HIGHPOS ADC HEADER2 STA HIGHPOS FHIGHSET LDA HIGHPOS STA (LISTPTR),Y ; FINALLY, STORE THE THIRD HEADER BYTE INY LDA HEADER3 ; NOW THE LAST HEADER BYTE STA (LISTPTR),Y INY STY LISTSIZE,X ; READY FOR THE NEXT HEADER ; WE'RE FINISHED WITH THIS HEADER. CHECK TO SEE IF THIS CHARACTER IS ; FINISHED. THIS WILL BE TRUE IF "HIGHPOS" IS LESS THAN OR EQUAL TO ; THE BEGINNING OF THE STAMP TABLE, "STAMPHGH" ($4F). LDA HIGHPOS SEC SBC #1 ; SUBTRACT 1 TO GET <= OPERATION CMP HEADER2 BCC NXTFIXED LDA HIGHPOS SEC SBC #16 ; GET NEW "HIGHPOS" VALUE STA HIGHPOS DEX ; POINT TO NEXT LOWER ZONE JMP FOVERLAP ; ELSE, DO NEXT ZONE-- "HIGHPOS" ; IS ALREADY SET NXTFIXED LDY LTEMPY ; REMEMBER, THIS IS THE CHAR. INDEX ! INY TYA CMP #TOTALFX BMI GETFIXED ; DO ALL UP TO, BUT NOT INCLUDING, ; #TOTALFX ; NOW THAT WE'RE FINISHED, SET THE TABLE "LISTSTRT" TO BE EQUAL TO THE VALUES ; WE JUST DERIVED FOR "LISTSIZE". LDX #NUMZONES-1 ZLOAD08 LDA LISTSIZE,X STA LISTSTRT,X DEX BPL ZLOAD08 ; LDX #NUMZONES-1 ; SETUP FOR "ENDLIST" JMP ENDLOAD