; RECEIVE ; ; Nick Kennedy ; ; 11/15/86 ; ; This program is intended to receive ; and run binary files via the ; joystick (PIA) port. ; ; This part of the program creates ; the cassette boot file. ; NORECS: EQU [RECORD-START+127]/128 FLEN: EQU NORECS*128 ; ORG $4000 ; PROC CASFN: DB 'C:', $9B RUNCS: LDX #$40 ; IOCB #4 LDA #3 ; Open STA ICCOM,X LDA #HIGH CASFN STA ICBAH,X LDA #LOW CASFN STA ICBAL,X LDA #8 STA ICAX1,X LDA #%10000000; Short IR gaps STA ICAX2,X JSR CIOV BPL :OK1 STY $600 RTS ; ; Now, put the entire file: ; :OK1: LDX #$40 LDA #$B STA ICCOM,X LDA #HIGH STRT STA ICBAH,X LDA #LOW STRT STA ICBAL,X LDA #HIGH FLEN STA ICBLH,X LDA #LOW FLEN STA ICBLL,X JSR CIOV BPL :OK2 STY $600 RTS ; :OK2: LDA #$C ; Close IOCB STA ICCOM,X JSR CIOV BPL :OK3 STY $601 ; :OK3: RTS ; Back to DOS ; EPROC ; ; System Equates: CH: EQU $2FC ; Keyboard code here CIOV: EQU $E456 ICCOM: EQU $342 ICBAL: EQU $344 ICBAH: EQU $345 ICBLL: EQU $348 ICBLH: EQU $349 ICAX1: EQU $34A ICAX2: EQU $34B RTCLOK: EQU $14 BEEP: EQU $FD CONSOL: EQU $D01F ZLOAD: EQU $CB ; Z-page pointer L=2 ; STRT: LOC $700 ; Cassette start ; ; Put Cassette header bytes: ; LDADR: DB $FF, LOW NORECS, LOW LDADR, HIGH LDADR ; DB LOW INIT1, HIGH INIT1 ; Refer. to OS manual pg 166 and ; De Re Atari pg c-7/8: ; START: LDA #$3C ; Off motor STA $D302 ; (PACTL) LDA #LOW [RECORD+1] STA $237 ; (MEMLO) STA $E ; (APPMHI) LDA #HIGH [RECORD+1] STA $238 STA $F LDA #LOW INIT STA $A ; (DOSVEC) LDA #HIGH INIT STA $B ; (DOSVEC) CLC ; indicate boot success RTS ; End of init. INIT1: RTS ; No boot continuation. ENDL: DS 1 ENDH: DS 1 PLACE: DS 1 TIMER: DS 1 ; My timeout timer FLAG: DS 1 ; ; ; STRINGS: KYBD: DB 'K:',$9B PMPT1: DB 'Input Filespec. Example: D2:FILE',$9B BSTMSG: DB 'Bad status on opening file.', $9B NTLF: DB 'Header error - not a load file.', $9B ; INITIALIZE ; INIT: LDA #0 ; Clear Run/Init adr. STA $2E0 STA $2E1 STA $2E2 STA $2E3 JSR OPENK LDA #$9B JSR PUTBYT LDA #$9B JSR PUTBYT PRINTS PMPT1 LDA #$9B JSR PUTBYT ; ; Stash cursor position: ; LDA $54 PHA LDA $55 PHA LDA $56 PHA GETRK: JSR GETK CMP #$9B BEQ GREC JSR PUTBYT JMP GETRK GREC: PLA STA $56 PLA STA $55 PLA STA $54 LDA #$1F ; CURSOR right JSR PUTBYT LDA #$1E ; left JSR PUTBYT LDA #13 STA ICAX1 ; Forced read LDA #HIGH RECORD STA ICBAH LDA #LOW RECORD STA ICBAL JSR GETREC ; Get filename. PRINTS RECORD ; Echo it. LDA #12 STA ICAX1 JSR CLOSK ; Close #1. ; ; Send the filespec to the other 800: ; PROC JSR TINIT LDY #0 :LOOP: LDA RECORD,Y ; Get byte JSR TLOOP ; Send it LDA RECORD,Y ; again to check CMP #$9B ; For EOL BEQ :DUN INY ; Next byte BNE :LOOP ; Forced branch ; ; Get ready to receive acknowledge: ; :DUN: JSR RINIT JSR RLOOP ; Get status BNE :GOOD PRINTS BSTMSG JMP INIT :GOOD: JSR RLOOP ; check header byts CMP #$FF BNE :BADHD JSR RLOOP CMP #$FF BEQ :GDHD :BADHD: PRINTS NTLF ; Not load file JMP INIT :GDHD: JSR RLOOP ; Get load address STA LOAD+1 STA $605 ;********** STA $607 JSR RLOOP STA LOAD+2 STA $606 ;*********** STA $608 JSR RLOOP ; Get end address STA ENDL JSR RLOOP STA ENDH :RBYTE: LDY #0 ; Dummy index. JSR RLOOP ; Get file byte. LOAD: STA RECORD ; (Dummy address) LDA LOAD+2 CMP ENDH BNE :NOTEQ LDA LOAD+1 CMP ENDL BNE :NOTEQ JMP :SEGDUN ; Segment done :NOTEQ: INC LOAD+1 ; Increment load INC $607;************** BNE :RBYTE ; address. INC LOAD+2 INC $608 ;************** JMP :RBYTE :SEGDUN LDA $2E2 ; Check init adr. BNE :INIT ; No init if = 0. LDA $2E3 BEQ :RDY :INIT: LDA $2E2 ; (:INIT, not INIT) STA :GO+1 ; Set up JSR adr LDA $2E3 STA :GO+2 :GO: JSR HELL ; HELL is dummy ADR. :RDY: JSR JIF2 ; Stall 2 jiffies JSR TINIT JSR TLOOP ; Send any byte. JSR RINIT JSR RLOOP ; EOF? BEQ :RUN ; Yes JMP :GDHD ; :RUN: LDA $2E0 BNE :DORUN LDA $2E1 BNE :DORUN :RUNN: JSR HECK ; HECK is a dummy :DORUN: LDA $2E0 ; if there's a run STA :RUNN+1 ; address, else LDA $2E1 ; we restart. STA :RUNN+2 JMP :RUNN RTS ; In case it comes back EPROC ; ; JIF2: Stall 2 jiffies waiting to ; be sure the other guy gets into ; receive mode. ; JIF2: LDA RTCLOK STA PLACE INC PLACE INC PLACE JIF2A: LDA RTCLOK CMP PLACE BNE JIF2A RTS ; JIF10: LDA RTCLOK ; waste 10/60 sec. ADC #$A STA PLACE JIF10A: LDA RTCLOK CMP PLACE BNE JIF10A RTS ; ; Subroutine to put record to E: ; (Have ICBAH/L loaded before entry) ; (Use MACRO PRINTS) ; PUTREC: LDA #$80 STA ICBLL LDX #0 STX ICBLH LDA #9 ; Put record. STA ICCOM JSR CIOV RTS ; ; Subroutine to get a record from #0 ; User set ICBAL/H. ; GETREC: LDX #0 LDA #5 STA ICCOM LDA #$80 STA ICBLL STX ICBLH JSR CIOV STY $600 RTS ; ; ; Subroutine to put byte to E: ; (Have byte in accumulator on entry) ; PUTBYT: LDX #$B ; Put byte STX ICCOM LDX #0 STX ICBLH STX ICBLL JSR CIOV RTS ; ; ; A routine to get one byte from ; IOCB #0 (assumed to be E:): ; GETBYT: LDX #0 STX ICBLL STX ICBLH LDA #7 STA ICCOM ; Get bytes. JSR CIOV RTS ; ; ; OPEN KEYBOARD, IOCB #1 ; OPENK: LDX #$10 LDA #3 STA ICCOM,X LDA #4 ; Read STA ICAX1,X LDA #HIGH KYBD STA ICBAH,X LDA #LOW KYBD STA ICBAL,X JSR CIOV RTS CLOSK: LDX #$10 ; Close it. LDA #$C STA ICCOM,X JSR CIOV RTS ; GETK: LDX #$10 ; Get one byte from LDA #$7 ; keyboard. STA ICCOM,X LDA #0 STA ICBLL,X STA ICBLH,X JSR CIOV RTS HELL: PRINTS NOINI ; INIT =0 PLA ; We shouldn't be here. PLA JMP INIT HECK: PRINTS RUNZRO ; RUN = 0 PLA ; We shouldn't be here PLA JMP INIT NOINI: DB 'Went to INIT with INIT=0; ERROR!', $9B RUNZRO DB 'Went to RUN but RUN = 0; ERROR!', $9B ; ; ; The following is the transmit/ ; receive portion of TALKP. ; ; System Equates: PACTL: EQU $D302 ; CTLRW: EQU %00111100 ; to R/W port CTLDD: EQU %00111000 ; to write data ; direction. (0=input; 1=output) ; PORTA: EQU $D300 ; ; For STICK 0, bits 0-3 equal pins ; 1-4. (8 is ground) ; ; PINS: ; ; ; 1 2 3 4 5 ; View of jack on ; 6 7 8 9 ; console. ; ; NOTES: ; ; Pin 1 is data. ; Pin 2 is Transmitter status. ; (DATA READY or DR) (0 = READY). ; Pin 3 is Receiver status. ; (RECEIVER READY or RR) (0 = READY). ; ; Initialization: Before each byte ; sent/received all out lines are ; made high. Transmitter makes sure ; RR is high, then sets DATA lo. ; Receiver watches for DR high AND ; Data lo, then is freed to set RR ; lo (ready). Transmitter is then ; free to put data and set DR lo (rdy) ; ; ; DATA DS 1 ; Store/send byte here BITCT: DS 1 ; Bit counter ; ; STRINGS: TOM: DB 'TIMED OUT DURING BYTE TRANSFER', $9B ; ; INITIALIZE ; ; RINIT: LDA #$FF ; Not ready. STA PORTA LDA #$9B JSR PUTBYT LDA #LOW CTLDD ; Make PORTA STA PACTL ; be data direction LDA #%00000100 ; register. STA PORTA ; Made bit 2 input. LDA #LOW CTLRW ; Make PORTA STA PACTL ; be I/O port again RTS ; ; This subroutine receives a byte: ; RLOOP: LDA PORTA ; XMT initialized? AND #3 ; Get bits 0 and 1 CMP #2 ; Data LO & DR HI? BNE RLOOP ; Keep checking LDA #7 ; Bit counter (0-7) STA BITCT RLP3: LDA #$FF - 4 ; clear bit 2 STA PORTA ; (set RR ready) RLP1: LDA BITCT ; We don't time out CMP #7 ; if waiting for the BEQ SEVEN ; first bit. LDA RTCLOK ; But check on CMP TIMER ; later bits BNE NOTO ; No timeout GOON: PRINTS TOM ; timeout message PLA ; Clear return address PLA ; from stack. JMP INIT ; Goto menu SEVEN: LDA RTCLOK ; Set up timer for STA TIMER ; one to two jiff's INC TIMER INC TIMER NOTO: LDA PORTA ; check DR AND #2 ; Mask all but DR line BNE RLP1 ; DATA not ready ASL DATA LDA PORTA ; Read data AND #1 ; Mask non-data CLC ADC DATA ; add it to DATA STA DATA LDA #$0F STA PORTA ; RR not ready RLP2: LDA TIMER CMP RTCLOK BEQ GOON ; Go on. (exit) LDA PORTA ; Check for DR not. AND #2 BEQ RLP2 ; DR not set DEC BITCT ; Next bit BPL RLP3 ; Do 8 bits LDA DATA ; Take it home RTS ; ; ; This subroutine sends a byte out ; over the PIA line: ; TLOOP: STA DATA ; Store the byte TLP4: LDA PORTA ; Check rcvr status AND #4 BEQ TLP4 ; Loop if ready. LDA #2 ; Set DR=1, DATA=0 STA PORTA LDA #7 ; Bit counter STA BITCT ; initialize LDA RTCLOK STA TIMER INC TIMER INC TIMER TLP1: LDA RTCLOK ; Check for time CMP TIMER ;waiting for RR. BNE TLP5 ; No timeout TGOON: PRINTS TOM ; timeout message PLA ; Clear return address PLA ; from stack. PLA ; Also clear data byte. JMP INIT ; Goto menu TLP5: LDA PORTA ; Receiver ready? AND #4 ; Bit 2 is RR line BNE TLP1 ; Not ready ASL DATA ; Knock left bit LDA #0 ; Into carry ADC #0 ; add carry to 0 STA PORTA ; Put data/DR ready TLP2: LDA TIMER CMP RTCLOK BEQ TGOON ; Timed out LDA PORTA ; RCVR accept data? AND #4 ; RR line set? BEQ TLP2 ; Not yet LDA #$0F ; Data not ready. STA PORTA ; Tell RCVR DEC BITCT ; Count the bit BPL TLP1 ; 8 bits sent? RTS ; ; TRANSMIT section follows: ; TINIT: LDA #$0F ; Not ready/Not init STA PORTA LDA #LOW CTLDD STA PACTL ; Data direction LDA #%00000011 STA PORTA LDA #LOW CTLRW STA PACTL ; Data register RTS ; ; RECORD is where I input my filename ; It takes no file space cause it's ; at the end ; OEND: EQU *O RECORD: END RUNCS ;