home *** CD-ROM | disk | FTP | other *** search
/ ABBUC Magazin 60B / ABBUC_Magazin_60_2000_ABBUC_Side_B.atr / irg.m65 < prev    next >
Text File  |  2023-02-26  |  8KB  |  387 lines

  1. ; irg.m65: CC65 functions for the infrared gateway (IRG) Version 0.1
  2. ; ------------------------------------------------------------------
  3. ; Copyright 1994 David Deaven version 0.1
  4. ; Permission to use, copy, and distribute this code is granted
  5. ; provided that it is not used for commercial applications.
  6. ; David Deaven -- deaven@iastate.edu
  7. ;
  8. ; This ra65 library package provides access to an infrared gateway,
  9. ; or IRG, connected to an Atari 400/800/XL/XE 8-bit computer.  A
  10. ; description of how to build the IRG circuit, which simply plugs into
  11. ; a joystick port, can be found in the file README.HARDWARE included 
  12. ; with this distribution.  The functions defined here are:
  13. ;
  14. ; void IRGinit(int sample, int ton, int toff, int repeat,
  15. ;   int tonmin, int toffmax, int qtime, int totime)
  16. ; int IRGread(char *buffer, int size) = # bytes returned
  17. ; int IRGwrite(char *buffer) = 0, or 1 if IRG is active
  18. ;
  19. ; See the file README for more information, and the C program
  20. ; irgdemo.c which demonstrates the use of these functions.
  21. ; ------------------------------------------------------------------
  22. rdblen    =    128 ; internal read buffer length (<256)
  23.  
  24. ; Some device things that the standard CC65 headers don't have
  25. PACTL    =    $D302
  26. PORTA    =    $D300
  27. TRIG0    =    $D010
  28. GRACTL    =    $D01D
  29.  
  30. ; ------------------------------------------------------------------
  31. ; Start the vertical blank service routine and set parameters.
  32. ;
  33. ; void IRGinit(int sample, int ton, int toff, int repeat,
  34. ;   int tonmin, int toffmax, int qtime, int totime)
  35. ;
  36. _irginit:
  37.     jsr    enterfun    ; get all arguments
  38.     ldy    #16
  39.     jsr    ldaxysp
  40.     sta    sample
  41.     ldy    #14
  42.     jsr    ldaxysp
  43.     sta    ton
  44.     ldy    #12
  45.     jsr    ldaxysp
  46.     sta    toff
  47.     ldy    #10
  48.     jsr    ldaxysp
  49.     sta    repeat
  50.     ldy    #8
  51.     jsr    ldaxysp
  52.     sta    tonmin
  53.     ldy    #6
  54.     jsr    ldaxysp
  55.     sta    toffmax
  56.     ldy    #4
  57.     jsr    ldaxysp
  58.     sta    qtime
  59.     ldy    #2
  60.     jsr    ldaxysp
  61.     sta    totime
  62.  
  63.     LDA #%00111001    ; set up PIA
  64.     STA PACTL    ; output bit A0
  65.     LDA #%00000001
  66.     STA PORTA
  67.     LDA #%00111101
  68.     STA PACTL
  69.     LDA #0        ; turn IRG output off
  70.     STA PORTA
  71.  
  72.     LDA #0
  73.     STA nread    ; clear read buffer
  74.     sta nwrite
  75.     sta rdbuf
  76.     sta irgstat    ; no invalid events
  77.  
  78.     LDA #6        ; new immediate VBLANK
  79.     LDX #VImm^
  80.     LDY #VImm\
  81.     JSR SETVBV
  82.  
  83.     LDA #7        ; new deferred VBLANK
  84.         LDX #VBlank^
  85.         LDY #VBlank\
  86.         JSR SETVBV
  87.  
  88.     jmp exitfun
  89.  
  90. ; ------------------------------------------------------------------
  91. ; Read the IRG buffer safely into a user buffer.
  92. ;
  93. ; int IRGread(char *buffer, int size) = # bytes returned
  94. ;
  95. _irgread:
  96.     jsr    enterfun
  97.     ldy    #2        ; get arguments
  98.     jsr    ldaxysp
  99.     sta    blen
  100.     ldy    #4
  101.     jsr    ldaxysp
  102.     jsr    psave
  103.     sta    ptr1        ; set to point at buffer
  104.     stx    ptr1+1
  105.  
  106.     LDX nread
  107.     ldy #0        ; # bytes transferred
  108. fine:    cpx nwrite    ; end of buffer?
  109.     beq rddone
  110.     LDA rdbuf,x    ; transfer one byte
  111.     STA (ptr1),Y
  112.     iny
  113.     INX
  114.     CPX #rdblen
  115.     BNE skip1
  116.     ldx #0
  117. skip1:  cmp #0        ; end of buffer?
  118.     bne skip2
  119.     dey         ; zero byte is meaningless, remove
  120.     jmp rddone
  121. skip2:    cpy blen     ; buffer overflow?
  122.     bmi fine
  123.  
  124. rddone:    stx nread    ; update next read position
  125.     tya        ; return # bytes
  126.     ldy irgstat    ; bad buffer?
  127.     beq rddo2    
  128.     lda #0
  129. rddo2:    ldx #0
  130.     jsr prest
  131.     jmp exitfun
  132.  
  133. ; ------------------------------------------------------------------
  134. ; Send a buffer out (null-terminated string).
  135. ;
  136. ; int IRGwrite(char *buffer) = 0, or 1 if IRG is active
  137. ;
  138. _irgwrite:
  139.     jsr enterfun
  140.     ldy #2
  141.     jsr ldaxysp
  142.     jsr psave
  143.     sta ptr1
  144.     stx ptr1+1
  145.  
  146.     LDA CRITIC    ; is anything else
  147.     BEQ    ok2    ; going on?
  148.     ldax    #1    ; if so, don't send
  149.     jsr    prest
  150.     jmp    exitfun
  151.  
  152. ok2:    JSR IStop    ; stop DMA etc.
  153.     lda repeat
  154.     sta nwr
  155. wr0:    LDY #$FF
  156.     LDX #8
  157. loop:    INY
  158.     LDA (ptr1),Y
  159.     BEQ eot
  160.     STA bytbuf
  161. sloop:    LDA #0
  162.     ROL bytbuf
  163.     ROL A
  164.     STA PORTA
  165.     TXA
  166.     LDX ton
  167. loop1:  JSR DELAY
  168.     DEX
  169.     BNE loop1
  170.     STX PORTA
  171.     LDX toff
  172. loop0:  JSR DELAY
  173.     DEX
  174.     BNE loop0
  175.     TAX
  176.     DEX
  177.     BNE sloop
  178.     LDX #8
  179.     BNE loop
  180.  
  181. eot:    ldx qtime
  182. eot8:    jsr delay
  183.     dex
  184.     bne eot8
  185.     dec nwr
  186.     bne wr0
  187.     JSR IStart    ; restart DMA etc
  188.     ldax #0
  189.     jsr prest
  190.     jmp exitfun
  191. nwr:    .byte 0
  192.  
  193. ; ------------------------------------------------------------------
  194. ; Immediate vertical blank code.  Unlike the Atari OS code, if CRITIC is
  195. ; set, _nothing_ gets done.  This state should not be maintained too
  196. ; long, but for the length of an IR packet it's OK.
  197. ;
  198. VImm:    LDA CRITIC
  199.     BEQ cont
  200.     JMP XITVBV    ; outta here
  201. cont:    JMP $E45F    ; OS Stage 1
  202.  
  203. ; ------------------------------------------------------------------
  204. ; Deferred vertical blank code.  Examine TRIG0 for new IR input,
  205. ; catch all input by keeping TRIG0 in hardware latch mode.  When TRIG0 has
  206. ; been low, display DMA is turned off, CRITIC is enabled, and this routine
  207. ; becomes the "mainline" code with the interrupt return info still on the
  208. ; stack. An attempt is made to read a valid code into the buffer, then
  209. ; control is returned to the interrupted code.
  210. ;
  211. VBlank: LDA CRITIC
  212.     BNE leave    ; never happens?
  213.     LDA TRIG0
  214.     BEQ rec        ; IRG has been active
  215.     LDA #%100
  216.     STA GRACTL    ; set TRIG0 latch
  217. leave:  JMP XITVBV     ; outta here
  218.  
  219. rec:    JSR IStop
  220.     LDA #0
  221.     STA GRACTL    ; clear TRIG0 latch
  222.  
  223. still:  LDX qtime    ; detect record gap
  224.     LDA #1        ; IR input bit is LSB
  225. wait:   JSR Delay
  226.     BIT TRIG0
  227.     BEQ still    ; (input not quiet)
  228.     DEX
  229.     BNE wait    ; we'll wait as long as it takes!
  230.  
  231.     LDY totime    ; looking for a "1" bit to start 
  232. retry:  LDX qtime
  233. mark:   BIT TRIG0
  234.     BEQ st0        ; got "1", go for it
  235.     JSR Delay
  236.     DEX
  237.     BNE mark
  238.     DEY
  239.     BNE retry
  240.     JMP exit    ; time-out, no harm done
  241.  
  242. st0:    LDY #8        ; bit counter
  243. start:  LDX #0
  244. wton:   JSR Delay
  245.     INX
  246.     BIT TRIG0
  247.     BEQ wton
  248.  
  249.     CPX tonmin    ; bit long enough?
  250.     BPL okbit
  251.     LDA #1        ; bad "1" bit
  252.     STA irgstat
  253.     JMP exit
  254.  
  255. okbit:  SEC        ; store a "1" bit
  256.     JSR store
  257.     LDX #0        ; wait for "0" to end
  258. wtoff:  JSR Delay
  259.     INX
  260.     BEQ eott    ; never? forced EOT (very long "0")
  261.     BIT TRIG0
  262.     BNE wtoff
  263.     CPX qtime    ; the space is EOT?
  264.     BPL eott
  265.     CPX toffmax    ; a "0" bit?
  266.     BMI start    ; normal space
  267.     CLC        ; store a "0" bit
  268.     JSR store
  269.     JMP start
  270.  
  271. eott:   CPY #8        ; normal EOT
  272.     BEQ done    ; last data byte has been written
  273.     CLC
  274.     JSR store    ; pad buffer w/zeroes
  275.     JMP eott
  276.  
  277. done:   ldy #8         ; terminate buffer with zero
  278. pad:    clc
  279.     jsr store
  280.     cpy #8
  281.     bne pad
  282.     LDA #0
  283.     STA irgstat    ; normal operation
  284.     JMP exit
  285.  
  286. ; ------------------------------------------------------------------
  287. ; Store bits MSB to LSB in memory at rdbuf
  288. ;
  289. ; C = bit (0/1)
  290. ; X = not saved
  291. ; Y = #bits in bytbuf (0-7), 8==0
  292. ; A = saved
  293. ;
  294. store:  ROL bytbuf    ; store byte pre-buffer
  295.     DEY
  296.     BEQ byte
  297.     RTS
  298. byte:   TAX        ; save A
  299.     LDA bytbuf
  300.     LDY nwrite
  301.     STA rdbuf,Y
  302.     INY
  303.     cpy #rdblen
  304.     bne byte1
  305.     ldy #0
  306. byte1:    cpy nread    ; buffer full?
  307.     beq over
  308.     sty nwrite
  309.     LDY #8        ; new byte
  310.     TXA
  311.     RTS
  312.  
  313. over:    dey        ; back off one
  314.     cpy #$ff
  315.     bne over1
  316.     ldy #rdblen
  317.     dey
  318. over1:    lda #0
  319.     sta rdbuf,y    ; insert artificial terminator
  320.     sty nwrite
  321.         PLA        ; pop "jsr store" return address
  322.     PLA
  323.     LDA #2        ; buffer overrun...
  324.     STA irgstat    ; ...fall through to exit
  325.  
  326. exit:   JSR IStart    ; restart DMA etc.
  327.     JMP XITVBV    ; outta here
  328.  
  329. ; ------------------------------------------------------------------
  330. ; Wait one delay time, saving A, X, Y
  331. ; time = (20+5*sample) clock pds
  332. Delay:  PHA        ; 3 cycles
  333.     TXA        ; 2
  334.     LDX sample    ; 3
  335. dloop:    DEX        ; 2
  336.     BNE dloop    ; 3
  337.     TAX        ; 2
  338.     PLA        ; 4
  339.     RTS        ; 6
  340.  
  341. ; ------------------------------------------------------------------
  342. IStop:  LDA #0
  343.     STA DMACTL    ; prevent DMA
  344.     LDA #1
  345.     STA CRITIC
  346.     RTS
  347. IStart: LDA SDMCTL
  348.     STA DMACTL    ; enable DMA
  349.     LDA #0
  350.     STA CRITIC
  351.     RTS
  352.  
  353. ; ------------------------------------------------------------------
  354. psave:    ldy ptr1    ; save system pointer
  355.     sty svp1
  356.     ldy ptr1+1
  357.     sty svp1+1
  358.     rts
  359. prest:    ldy svp1    ; restore system pointer
  360.     sty ptr1
  361.     ldy svp1+1
  362.     sty ptr1+1
  363.     rts
  364. svp1:    .word    0
  365.  
  366. ; ------------------------------------------------------------------
  367. nread:        .byte 0
  368. nwrite:        .byte 0
  369. sample:        .byte 2
  370. ton:        .byte 20
  371. toff:        .byte 20
  372. tonmin:        .byte 10
  373. toffmax:    .byte 30
  374. qtime:        .byte 100
  375. totime:        .byte 25
  376. repeat:        .byte 3
  377. bytbuf:        .byte 0
  378. blen:        .byte 0
  379. rdbuf:        .blkb rdblen
  380. irgstat:    .word 0
  381.  
  382.     .globl _irginit
  383.     .globl _irgread
  384.     .globl _irgwrite
  385.  
  386.