PAGE SBTTL "--- MACHINE-DEPENDENT ROUTINES: ATARI ---" ; ------------ ; CLEAR SCREEN ; ------------ ; CLEAR SCREEN TO WHITE IF [ARG1] NEGATIVE ; CLEAR SCREEN TO BLACK IF [ARG1] POSITIVE GCLEAR: LDA #LOW SCREEN ; MAKE [I] POINT TO STA I+LO ; THE 1ST BYTE OF LDA #HIGH SCREEN ; SCREEN RAM STA I+HI LDX #30 ; # PAGES TO CLEAR LDY #0 ; INIT LOOP INDEX LDA ARG1+HI ; IF [ARG1] BMI GCLSN ; NEGATIVE CLEAR TO WHITE LDA #00 BEQ GCLS ; CLEAR SCREEN TO BLACK GCLSN: LDA #$FF ; ELSE CLEAR TO WHITE GCLS: STA (I),Y INY BNE GCLS INC I+HI DEX BNE GCLS RTS ; ------------------------ ; TEXT (ATARI SCREEN CODE) ; ------------------------ ERRM: DB 41,110,116,101,114,110,97,108,0 ; INTERNAL DB 37,114,114,111,114,0,3,0 ; ERROR # ERRML EQU $-ERRM ENDM: DB 37,46,36,0,47,38,0 ; END OF DB 51,37,51,51,41,47,46 ; SESSION ENDML EQU $-ENDM ; ----- ; ERROR ; ----- ; ENTRY: ERROR CODE IN [A] GERROR: STA $00 ; SAVE ERROR CODE JSR STATUS ; SET UP STATUS LINE LDX #LOW ERRM ; GET LSB LDA #HIGH ERRM ; AND MSB OF TEXT ADDRESS LDY #ERRML ; AND ITS LENGTH JSR PRINT ; PRINT "INTERNAL ERROR #" LDA $00 ; RETRIEVE ERROR CODE JSR HEX ; DISPLAY IT IN HEX LDA #0 JSR CHAR ; PRINT A SPACE JMP GOVER ; AND PRINT "GAME OVER" ; ---- ; QUIT ; ---- GQUIT: JSR STATUS ; SET UP MESSAGE LINE LDA #13 STA CURSOR ; CENTER TEXT GOVER: LDX #LOW ENDM ; LSB AND LDA #HIGH ENDM ; MSB OF TEXT ADDRESS LDY #ENDML ; LENGTH JSR PRINT ; PRINT "GAME OVER" HOLD: LDA CONSOL ; WAIT FOR CONSOLE KEYPRESS CMP #7 BEQ HOLD LETGO: LDA CONSOL ; WAIT FOR KEY RELEASE CMP #7 BNE LETGO JMP COLD ; AND DO A COLDSTART ; ----------------- ; CLEAR STATUS LINE ; ----------------- NEWLIN: LDX #79 LDA #0 NEWL0: STA TEXT,X DEX BPL NEWL0 RTS ; ------------------ ; SET UP STATUS LINE ; ------------------ ; FOR ERRORS & DEBUGGER STATUS: JSR NEWLIN LDA #0 STA CURSOR LDX #LOW DL1 ; TELL THE D-LIST WHERE LDA #HIGH DL1 ; TO START ITSELF STX DLTOP+LO STA DLTOP+HI STX SDLSTL+LO ; ALSO TELL ANTIC STA SDLSTL+HI ; WHERE TO FIND OUR LIST RTS ; ---------------- ; PRINT [A] IN HEX ; ---------------- ; HEX CHARS IN ATARI SCREEN CODE HCHARS: DB 16,17,18,19,20,21,22,23,24,25 ; 0-9 DB 33,34,35,36,37,38 ; A-F HEX: PHA ; SAVE HERE LSR A ; SHIFT TOP NIBBLE LSR A ; INTO POSITION LSR A LSR A JSR NIBBLE ; AND PRINT IT PLA ; RETRIEVE BYTE NIBBLE: AND #%00001111 ; ISOLATE BITS 3-0 TAX LDA HCHARS,X ; FALL THROUGH ... ; ----------------- ; PRINT CHAR IN [A] ; ----------------- CHAR: LDX CURSOR STA TEXT,X INC CURSOR RTS ; ---------- ; PRINT TEXT ; ---------- ; ENTRY: TEXT ADDRESS IN [X/A] (LSB/MSB) ; TEXT LENGTH IN [Y] PRINT: STX LINE+LO ; LSB OF ADDRESS STA LINE+HI ; MSB OF ADDRESS STY LEN ; LENGTH LDY #0 LDX CURSOR PR0: LDA (LINE),Y STA TEXT,X INX INY DEC LEN BNE PR0 STX CURSOR RTS ; ------ ; MEMTOP ; ------ ; EXIT: [A]=$A0 IF 48K, ELSE [A]=0 MEMTOP: LDA #0 ; CLEAR $A000 STA $A000 LDX $A000 ; CHECK THE VALUE BNE EMPTY ; RETURN [A]=0 IF NON-ZERO LDA #$A0 ; ELSE RETURN $A0 EMPTY: RTS ; ------ ; RANDOM ; ------ ; EXIT: RANDOM 16-BIT WORD IN [X/A] DORAND: LDA RANDOM NOP ; A PAUSE ... LDX RANDOM RTS ; ------------ ; SIMPLE DELAY ; ------------ ; ENTRY: NEGATIVE JIFFY COUNT IN [VALUE] DELAY: LDA #0 ; WAIT A JIFFY STA RTCLOK DEL1: LDA RTCLOK BEQ DEL1 INC VALUE+LO BNE DELAY INC VALUE+HI BNE DELAY BEQ MOVED ; GET A VALUE AND RETURN ; ----- ; INPUT ; ----- GINPUT: LDA ARG1+LO ; MOVE [ARG1] INTO [VALUE] STA VALUE+LO LDA ARG1+HI STA VALUE+HI LDA NARGS ; IF THERE ARE 2 ARGS THEN DO THE TABLE CMP #1 ; ITERATIONS BEQ NOIT JMP ITRATE ; YES VIRGINIA, A JUMP NOIT: LDA VALUE+HI BMI DELAY ; DO A SIMPLE DELAY ORA VALUE+LO ; IF NON-ZERO, BNE TICK ; ENTER SENSE LOOP MOVED: JSR SENSE ; ELSE READ JUST ONCE MOVED2: JMP PUTBYT ; ELSE RETURN [A] ; INPUT SENSE LOOP TICK: JSR SENSE ; GET READING INTO [A] CMP #%10001111 ; ANY INPUT? BNE MOVED2 ; YES, RETURN IT LDA #0 ; ELSE WAIT 1 JIFFY STA RTCLOK TICK1: LDA RTCLOK BEQ TICK1 JSR DECVAL ; DECREMENT COUNT LDA VALUE+LO ORA VALUE+HI ; ZERO YET? BNE TICK ; NO, LOOP BACK BEQ MOVED ; RETURN ; ------------------------- ; CHECK KEYBOARD & JOYSTICK ; ------------------------- ; EXIT: INPUT STATUS IN [A] SENSE: LDA #0 STA ATRACT ; KILL ATTRACT MODE LDA CH ; READ THE KEYBOARD REGISTER CMP #$FF ; KEY PRESSED YET? BEQ STICK ; IF NOT, CHECK STICK TAY ; ELSE SAVE KEYCODE HERE LDX #$FF ; RESET THE STX CH ; KEYBOARD REGISTER AND #%11000000 ; SHIFT OR CTRL CHAR? BNE STICK ; IGNORE IF SO LDA ATASCI,Y ; GET ATASCII CODE INTO [A] CMP #'a' ; CONVERT TO BCC KEXIT ; UPPER CASE ALPHA CMP #'z'+1 ; IF NECESSARY BCS KEXIT SEC SBC #$20 KEXIT: AND #%01111111 ; MAKE SURE IT'S POSITIVE RTS ; CHECK THE JOYSTICK STICK: LDA STICK0 AND #%00001111 ; MASK GARBAGE LDX STRIG0 ; ALSO CHECK TRIGGER BNE STIKEX ; EXIT IF NOT PRESSED ORA #%00010000 ; ELSE SET BIT 4 STIKEX: ORA #%10000000 ; NEGATIVE FOR STICK READING RTS ; RETURN WITH CODE IN [A] ; ------------------------ ; ATASCII CONVERSION TABLE ; ------------------------ ATASCI: DB $6C,$6A,$3B,$8A,$8B,$6B,$2B,$2A DB $6F,$80,$70,$75,$9B,$69,$2D,$3D DB $76,$80,$63,$8C,$8D,$62,$78,$7A DB $34,$80,$33,$36,$1B,$35,$32,$31 DB $2C,$20,$2E,$6E,$80,$6D,$2F,$81 DB $72,$80,$65,$79,$7F,$74,$77,$71 DB $39,$80,$30,$37,$7E,$38,$3C,$3E DB $66,$68,$64,$80,$82,$67,$73,$61 ; -------------------- ; DUMP BLOCK TO SCREEN ; -------------------- ; ENTRY: BLOCK TO DUMP IN [BLOCK] (TOP BYTE IN [BLOCK+7]) ; X-COORDINATE IN [X], Y-COORDINATE IN [A] DUMP: STX TOX ; SAVE X-COORDINATE ASL A ; MULTIPLY Y-COORD BY 8 ASL A ; TO GET MODE LINE (0-191) ASL A TAY ; USE AS INDEX LDX #7 ; INIT BLOCK-FETCHING INDEX DUMP0: LDA VLOWS,Y ; GET LSB OF LINE ADDR CLC ADC TOX ; ADD X-POS STA TOADR+LO ; TO GET LSB OF SCREEN ADDR LDA VHIGHS,Y ; GET MSB OF LINE ADDR ADC #0 STA TOADR+HI ; FORM MSB OF SCREEN ADDR LDA BLOCK,X ; GET BLOCK DATA DB $8D ; 6502 "STA nnnn" INSTRUCTION TOADR: DW $0000 ; SCREEN RAM ADDRESS INY ; NEXT SCAN LINE DEX ; DONE 8 BYTES YET? BPL DUMP0 ; NO, FETCH MORE RTS ; ----------------------------------------------- ; DUMP BLOCK TO SCREEN WITH MASK ; ; IF THE MASK BIT IS 1 THEN THE SCREEN SHOWS THRU ; IF THE MASK BIT IS 0 THEN THE ICON IS DISPLAYED ; ----------------------------------------------- ; ENTRY: BLOCK TO DUMP IN [BLOCK] (TOP BYTE IN [BLOCK+7]) ; MASK IN [MASK] ; X-COORDINATE IN [X], Y-COORDINATE IN [A] DMPMSK: STX TOX ; SAVE X-COORDINATE ASL A ; MULTIPLY Y-COORD BY 8 ASL A ; TO GET MODE LINE (0-191) ASL A TAY ; USE AS INDEX LDX #7 ; INIT BLOCK-FETCHING INDEX DMSK0: LDA VLOWS,Y ; GET LSB OF LINE ADDR CLC ADC TOX ; ADD X-POS STA TOADR2+LO+1 ; TO GET LSB OF SCREEN ADDR STA TOADR3+LO+1 LDA VHIGHS,Y ; GET MSB OF LINE ADDR ADC #0 STA TOADR2+HI+1 ; FORM MSB OF SCREEN ADDR STA TOADR3+HI+1 TOADR2: LDA $FFFF ; DUMMY GET SCREEN BYTE EOR BLOCK,X AND MASK,X EOR BLOCK,X TOADR3: STA $FFFF ; DUMMY PUT BACK ON SCREEN INY ; NEXT SCAN LINE DEX ; DONE 8 BYTES YET? BPL DMSK0 ; NO, FETCH MORE RTS ; ----- ; SOUND ; ----- ; PLAY SOUND [ARG1] (1-127) GSOUND: LDA ARG1+LO BMI SNDERR ; RANGE ERROR! CMP #SOUNDS+1 BCS SNDERR ; SOUND NOT DEFINED SEC SBC #1 ; ZERO-ALIGN ASL A ; AND WORD-ALIGN TAX ; THE SOUND ID INDEX LDA STABLE+LO,X ; GET LSB OF EXECUTION ADDR STA PLAY+LO LDA STABLE+HI,X ; AND MSB STA PLAY+HI DB $4C ; 6502 "JMP" INSTRUCTION PLAY: DW $0000 ; SOUND JUMP VECTOR ; *** ERROR #13: UNDEFINED SOUND *** SNDERR: LDA #13 JMP GERROR ; ----- ; COPY? ; ----- ; IS THIS A LEGAL COPY OF THE DISK? GCOPYP EQU PREDS ; ------- ; VERIFY? ; ------- ; ARE THE GAME AND IMAGE FILES INTACT? ; NOTE: THIS DOES NOT OBSERVE EXTRA BIT LOW ; BUT USES EXTRA BIT HIGH! Le GVERP: LDA #0 ; CLEAR STA J+LO ; ACCUM FOR CHECKSUM STA J+HI STA K+LO STA DBLOCK ; START AT 1ST GAME SECTOR STA VPCH ; START @ BYTE 0064 STA VPC0 ; USE AS HIGH BIT LDA #64 ; 64 W/LOW BIT IN VPC0 STA VPCL LDA GBEGIN+GLEN ; SET BYTE LENGTH STA I+HI ; FOR GAME CHECK LDA GBEGIN+GLEN+1 ; (LENGTH IN WORDS - ASL A ; SO MULTIPLY BY 2 STA I+LO ; TO GET BYTES ROL I+HI ROL K+LO JMP READIN ; READ 1ST PAGE IN VSUM: LDA VPCL ; NEW PAGE? BNE VSUM2 ; NO, CONTINUE READIN: LDX #0 ; SET UP FOR GETDSK STX DBTOP STX DCNT INX STX DUNIT LDA #$52 ; "READ" STA DCOMND LDA #HIGH BUFFER ; NO MOVE STA DBUFF+HI LDA DBLOCK JSR GETGME VSUM2: LDY VPCL ; GET THIS BYTE LDA BUFFER,Y INC VPCL ; SET FOR NEXT BYTE BNE VSUM3 INC VPCH BNE VSUM3 INC VPC0 VSUM3: CLC ADC J+LO ; ADD IT TO ACCUM STA J+LO BCC VSUM0 INC J+HI VSUM0: LDA VPCL ; CHECK IF ALL BYTES DONE CMP I+LO BNE VSUM LDA VPCH CMP I+HI BNE VSUM LDA VPC0 CMP K+LO BNE VSUM ; AS WORD ALIGNED SIZE LDA GBEGIN+GCHECK CMP J+HI BEQ VSUM4 JMP BADVER ; OOPS VSUM4: LDA GBEGIN+GCHECK+1 CMP J+LO BEQ IFILE JMP BADVER ; GAME FILE OK, CHECK IMAGE FILE IFILE: LDA #0 STA K+LO LDA ICODE+LO ; FIND VIRTUAL IBEGIN STA J+LO LDA ICODE+HI STA J+HI LDY #ILEN ; OFFSET TO LENGTH LDA (J),Y STA I+HI ; SET I TO LENGTH INY LDA (J),Y ASL A ; *2 AS WORD VALUE STA I+LO ROL I+HI ROL K+LO LDY #ICHECK ; GET CHECKSUM LDA (J),Y ; WHILE IT'S EASY STA CHKSUM+HI ; SAVE IT HERE INY LDA (J),Y STA CHKSUM+LO LDA #0 ; CLEAR FOR IMAGE FILE STA J+LO STA J+HI STA VPCH STA VPC0 STA DBLOCK ; SET TO START OF IMAGE SECTORS. LDA #8 STA VPCL ; HEADER OF IMAGE FILE JMP IRDIN ISUM: LDA VPCL ; NEW PAGE? BNE ISUM2 ; NO, CONTINUE IRDIN: LDX #0 ; SET UP FOR GETDSK STX DBTOP STX DCNT INX STX DUNIT LDA #$52 ; "READ" STA DCOMND LDA #HIGH BUFFER ; NO MOVE STA DBUFF+HI LDA DBLOCK JSR GETIMG ISUM2: LDY VPCL ; GET THIS BYTE LDA BUFFER,Y INC VPCL ; SET FOR NEXT BYTE BNE ISUM3 INC VPCH BNE ISUM3 INC VPC0 ISUM3: CLC ADC J+LO ; ADD IT TO ACCUM STA J+LO BCC ISUM0 INC J+HI ISUM0: LDA VPCL ; CHECK IF ALL BYTES DONE CMP I+LO BNE ISUM LDA VPCH CMP I+HI BNE ISUM LDA VPC0 CMP K+LO BNE ISUM ; AS WORD ALIGNED SIZE LDA CHKSUM+LO ; COMPARE TO SAVED CHECKSUM CMP J+LO BNE BADVER LDA CHKSUM+HI CMP J+HI BNE BADVER JMP PREDS ; SUCCESS! BADVER: JMP PREDF END