home *** CD-ROM | disk | FTP | other *** search
/ Go64! / Go64_1999-08_1999_CSW_Side_A.d64 / inputdrvsrc.txt < prev    next >
Text File  |  2023-02-26  |  14KB  |  626 lines

  1. ;ACME 0.07
  2.  
  3.  
  4. ; --- Configurable values
  5.  
  6. ; Start address
  7. *=$c000; C64 value
  8. ;*=$0c00; C128 value
  9.  
  10. ; Output file name
  11. !to "inputdrv64.bin"; C64 file name
  12. ;!to "inputdrv128.bin"; C128 file name
  13.  
  14. ; Pointer's maximum coordinates
  15. MaximumCoordinateX = 319; VIC value
  16. ;MaximumCoordinateX = 639; VDC value
  17. MaximumCoordinateY = 199
  18.  
  19. ; Maximum step size ("speed") for
  20. ; joystick acceleration routine, in
  21. ; pixels.
  22. MaxStep = $10; (max. $7f)
  23.  
  24. ; Distance before acceleration starts,
  25. ; in pixels.
  26. MaxTime = $04; (max. $7f)
  27.  
  28. ; Sprites to use for overlay pointer
  29. Sprite_A = 0
  30. Sprite_B = 1
  31.  
  32. ; Coordinates of "pointer pixel" within
  33. ; pointer sprites; adjust these if you
  34. ; use different sprites.
  35. ; (0,0) is sprite's upper left pixel.
  36. Sprite_HotspotX = 1
  37. Sprite_HotspotY = 1
  38.  
  39. ; Base of VIC registers to write to.
  40. VIC_Base = $d000; C64 value
  41. ;VIC_Base = $11d6; C128 value, location
  42. ; of mirror registers.
  43.  
  44. ; Locations to store button states,
  45. ; $ff = pressed, $00 = not pressed.
  46. ; Mouse uses both buttons, joystick
  47. ; only uses "LeftButton".
  48. LeftButton  = $a4; C64 value
  49. RightButton = $a5; C64 value
  50. ;LeftButton  = $fa; C128 value
  51. ;RightButton = $ff; C128 value
  52.  
  53. ; Location to store pointer's current
  54. ; pixel coordinates. The driver code
  55. ; relies on having *four consecutive*
  56. ; bytes:
  57. ; x low, x high, y low, y high.
  58. Coordinates = $fb; $fb-$fe
  59.  
  60. ; Location to store pointer's current
  61. ; character coordinates.
  62. CharX = $b3; C64 value
  63. CharY = $b4; C64 value
  64. ;CharX = $9b; C128 value
  65. ;CharY = $9c; C128 value
  66.  
  67.  
  68. ; --- System constants
  69.  
  70. ; Interrupt vector
  71. sys_iirq = $0314
  72.  
  73. ; I/O registers
  74. sid_pot   = $d419
  75. cia1_pra  = $dc00
  76. cia1_prb  = $dc01
  77. cia1_ddrb = $dc03
  78. ;mmu_cr    = $ff00; C128 only
  79.  
  80.  
  81. ; --- Label definitions
  82.  
  83. ; New names for some precalculated
  84. ; values, only to improve readability.
  85. ; Don't change these.
  86. PointerXnow = Coordinates
  87. PointerYnow = Coordinates+2
  88. SpriteA_X = VIC_Base+2*Sprite_A
  89. SpriteA_Y = VIC_Base+2*Sprite_A+1
  90. SpriteB_X = VIC_Base+2*Sprite_B
  91. SpriteB_Y = VIC_Base+2*Sprite_B+1
  92. Sprites_OF = VIC_Base+16; X Overflow
  93. ; The character "^" in the following
  94. ; calculation means "to the power of".
  95. ; It is ACME syntax - if your assembler
  96. ; cannot do this, you may want to use
  97. ; hardcoded values here instead of
  98. ; calculations.
  99. Sprites_Bitmask = 2^Sprite_A+2^Sprite_B
  100. SpriteOffset_X = $18-Sprite_HotspotX
  101. SpriteOffset_Y = $32-Sprite_HotspotY
  102. ; In the sprite coordinate system, the
  103. ; graphics pixel (0,0) has the
  104. ; coordinates ($18,$32), so these are
  105. ; needed for converting. Blame the VIC.
  106.  
  107.  
  108. ; --- Entry point
  109.  
  110. ; Because this routine is the first,
  111. ; the file can be BOOTed on a C128.
  112. Init
  113. ; Initialisation code, installs driver
  114. ; on IRQ vector.
  115. ; Fetch IRQ vector and write to end
  116.         lda sys_iirq
  117.         ldx sys_iirq+1
  118.         sta mod16+1
  119.         stx mod16+2
  120. ; Let IRQ vector point to driver code
  121.         lda #<Entry
  122.         ldx #>Entry
  123.         php
  124.         sei
  125.         sta sys_iirq
  126.         stx sys_iirq+1
  127.         plp
  128. ; The following five commands are only
  129. ; needed on the C128.
  130. ;       lda mmu_cr
  131. ;       tay
  132. ;       and #$fe; activate I/O chips
  133. ;       sta mmu_cr
  134. ; Init mouse buttons
  135.         lda #$11
  136.         sta cia1_prb
  137. ;       sty mmu_cr; C128 only
  138.  
  139. ; The following three mini-routines are
  140. ; only needed on the C64.
  141.  
  142. ; Copy sprites to tape buffer
  143.         ldx #127
  144. CpLp    lda Sprites,x
  145.         sta $0340,x
  146.         dex
  147.         bpl CpLp
  148.         lda #Sprites_Bitmask
  149. ; Set sprite block pointers
  150.         ldx #$0d
  151.         stx 2040+Sprite_A
  152.         inx
  153.         stx 2040+Sprite_B
  154. ; Activate pointer sprites
  155.         ora VIC_Base+21
  156.         sta VIC_Base+21
  157.  
  158. ; From here on, both C64+C128 again. :)
  159.         rts
  160.  
  161.  
  162. ; --- Variables
  163.  
  164. ; Pixel counter before accelerating
  165. JoyWaittime !byte 0
  166.  
  167.  
  168. ; --- Main code
  169.  
  170. Entry
  171. ; The driver consists of several
  172. ; distinct parts. To minimise
  173. ; performance wastage, you should
  174. ; remove all parts you don't need for
  175. ; the specific application.
  176.  
  177.  
  178. ; --- Part 0, initialisations
  179.  
  180. ; Make sure decimal mode is off
  181.         cld
  182. ; Set button states to "not pressed",
  183. ; so the other parts only have to deal
  184. ; with setting them to "pressed".
  185.         lda #$00
  186.         sta LeftButton
  187.         sta RightButton
  188.  
  189.  
  190. ; --- Part 1, handling mouse movements
  191.  
  192. ; mouse x
  193.         ldx #$00; 0 means "x stuff"
  194.         jsr PotDelta
  195. ; Now signed x movement is in A/Y.
  196. ; Add to current x value.
  197.         clc
  198.         adc PointerXnow
  199.         sta PointerXnow
  200.         tya
  201.         adc PointerXnow+1
  202.         sta PointerXnow+1
  203. ; mouse y
  204.         ldx #$01; 1 means "y stuff"
  205.         jsr PotDelta
  206. ; Now signed y movement is in A/Y.
  207. ; Mouse and computer use different y
  208. ; directions, so don't add to, but
  209. ; subtract from current y value.
  210. ; This is a reverse subtraction - it
  211. ; might be harder to understand, but it
  212. ; is faster and smaller than the usual
  213. ; way.
  214.         clc
  215.         sbc PointerYnow
  216.         eor #$ff
  217.         sta PointerYnow
  218.         tya
  219.         sbc PointerYnow+1
  220.         eor #$ff
  221.         sta PointerYnow+1
  222.  
  223.  
  224. ; --- Part 2, handling mouse buttons
  225.  
  226. ; Prepare CIA by setting bits to input
  227.         ldy #$11
  228.         sty cia1_ddrb
  229.         ldx #$ff; $ff means "pressed"
  230.         lda #$10; check left button
  231.         bit cia1_prb
  232.         bne NotLB
  233.         stx LeftButton; store state
  234. NotLB   lda #$01; check right button
  235.         bit cia1_prb
  236.         bne NotRB
  237.         stx RightButton; store state
  238. ; Reset CIA to normal state
  239. NotRB   ldy #$00
  240.         sty cia1_ddrb
  241.  
  242.  
  243. ; --- Part 3, handling the joystick
  244.  
  245. ; Fetch byte holding direction flags
  246.         lda cia1_pra
  247.         tax; ...and remember it
  248.  
  249. ; Check 'up' direction
  250.         ror
  251.         bcs down
  252. ; Subtract current step size from y
  253. ; value if needed.
  254.         tay
  255.         sec
  256.         lda PointerYnow
  257.         sbc JoyStepsize
  258.         sta PointerYnow
  259.         bcs fixHiUp
  260.         dec PointerYnow+1
  261. fixHiUp tya
  262.  
  263. ; Check 'down' direction
  264. down    ror
  265.         bcs left
  266. ; Add current step size to y value if
  267. ; needed.
  268.         tay
  269.         ;clc; C is always clear here
  270.         lda PointerYnow
  271.         adc JoyStepsize
  272.         sta PointerYnow
  273.         bcc fixHiDown
  274.         inc PointerYnow+1
  275. fixHiDown       tya
  276.  
  277. ; Check 'left' direction
  278. left    ror
  279.         bcs right
  280. ; Subtract current step size from x
  281. ; value if needed.
  282.         tay
  283.         sec
  284.         lda PointerXnow
  285.         sbc JoyStepsize
  286.         sta PointerXnow
  287.         bcs fixHiLeft
  288.         dec PointerXnow+1
  289. fixHiLeft       tya
  290.  
  291. ; Check 'right' direction
  292. right   ror
  293.         bcs Part3End
  294. ; Add current step size to x value if
  295. ; needed.
  296.         tay
  297.         ;clc; C is always clear here
  298.         lda PointerXnow
  299.         adc JoyStepsize
  300.         sta PointerXnow
  301.         bcc fixHiRight
  302.         inc PointerXnow+1
  303. fixHiRight      tya
  304. Part3End
  305.  
  306.  
  307. ; --- Part 4, handling joystick button
  308.  
  309.         ror
  310.         bcs Part4End
  311.         lda #$ff; $ff means "pressed"
  312.         sta LeftButton
  313. Part4End
  314.  
  315.  
  316. ; --- Part 5, joystick acceleration
  317.  
  318. ; Restore joystick direction bits and
  319. ; check whether to set speed to zero.
  320.         txa
  321.         and #$0f; Clear unneeded bits
  322.         cmp #$0f; Any direction bit ?
  323.         bne inctempo
  324. ; No direction was used, so reset speed
  325. ; and wait counter to normal.
  326.         lda #$01
  327.         sta JoyStepsize
  328.         lda #MaxTime
  329.         sta JoyWaittime
  330.         jmp Part5End
  331. inctempo
  332. ; A direction bit was used, so check
  333. ; whether to accelerate: If speed is
  334. ; already maximum speed, don't
  335. ; accelerate.
  336. JoyStepsize=*+1
  337.         lda #$00; (self-modifying)
  338. ; If the variable "JoyStepsize" would
  339. ; have been defined as a separate
  340. ; location (using "!byte"), it would
  341. ; have taken a byte of memory. By
  342. ; storing the value inside an LDA
  343. ; command's argument, we save that one
  344. ; byte. It might make a difference. :)
  345.         cmp #MaxStep; If speed is max.,
  346.         bcs Part5End; don't accelerate.
  347. ; Speed isn't maximum yet. Check
  348. ; whether we have to wait before
  349. ; accelerating.
  350.         dec JoyWaittime
  351.         bpl Part5End
  352. ; Counter has underrun, so accelerate.
  353.         inc JoyWaittime; reset counter
  354.         inc JoyStepsize; increase speed
  355. Part5End
  356.  
  357.  
  358. ; --- Part 6, restrict coordinate range
  359.  
  360. ; restrict x value
  361.         ldx #$00; 0 means "x stuff"
  362.         jsr Restrict
  363. ; restrict y value
  364.         ldx #$02; 2 means "y stuff"
  365.         jsr Restrict
  366.  
  367.  
  368. ; --- Part 7, positioning sprites
  369.  
  370. ; Set sprites' x positions
  371.         lda PointerXnow
  372.         clc
  373.         adc #SpriteOffset_X
  374.         sta SpriteA_X; set both sprites
  375.         sta SpriteB_X
  376.         lda Sprites_OF; get x overflow
  377.         bcs SetOF
  378.         ldx PointerXnow+1
  379.         bne SetOF
  380.         and #Sprites_Bitmask EOR $ff
  381.         bcc StoreOF; C is clear here
  382.  
  383. SetOF   ora #Sprites_Bitmask
  384. StoreOF sta Sprites_OF; set x overflow
  385.  
  386. ; Set sprites' y positions
  387.         lda PointerYnow
  388.         clc
  389.         adc #SpriteOffset_Y
  390.         sta SpriteA_Y
  391.         sta SpriteB_Y
  392. ; The y value's high byte is useless in
  393. ; this case.
  394.  
  395.  
  396. ; --- Part 8, making char coordinates
  397.  
  398. ; Convert x coordinate. There are
  399. ; different "best" routines for
  400. ; different resolutions, so I've given
  401. ; the VIC and VDC routines.
  402.         lda PointerXnow
  403.         lsr
  404.         lsr
  405.         lsr
  406.         ldx PointerXnow+1
  407.         beq SetCX; VIC only
  408.         ora #$20; VIC only
  409. ;       ora OrTable,x; VDC only
  410. SetCX   sta CharX
  411.  
  412. ; Convert y coordinate.
  413.         lda PointerYnow
  414.         lsr
  415.         lsr
  416.         lsr
  417.         sta CharY
  418.  
  419.  
  420. ; --- Add further parts here
  421.  
  422. ; Here you can add further routines,
  423. ; for example to use the button states
  424. ; to fake keypresses etc.
  425.  
  426.  
  427. ; --- The end
  428.  
  429. ; The initialisation routine sets the
  430. ; argument to the address of the
  431. ; previous IRQ routine.
  432. mod16   jmp $ffff; (self-modifying)
  433.  
  434. ; This table is for part 8.
  435. ;OrTable !byte 0,32,64; VDC only
  436.  
  437.  
  438. ; --- "Restrict" subroutine
  439.  
  440. PointerXmax !word MaximumCoordinateX
  441. PointerYmax !word MaximumCoordinateY
  442. ; "y" word must follow directly after
  443. ; "x" word in memory.
  444.  
  445. Restrict
  446. ; Restrict internal coordinates to
  447. ; configured range. Entry conditions:
  448. ; X is direction handle (0 = x, 2 = y)
  449.         lda PointerXnow+1,x
  450.         bmi SetTo0
  451.         cmp PointerXmax+1,x
  452.         bcc Eosr
  453.         bne ResetCo
  454.         lda PointerXmax,x
  455.         cmp PointerXnow,x
  456.         bcs Eosr
  457. ResetCo lda PointerXmax,x
  458.         ldy PointerXmax+1,x
  459.         jmp DefCo
  460.  
  461. SetTo0  lda #0
  462.         tay
  463. DefCo   sta PointerXnow,x
  464.         sty PointerXnow+1,x
  465. Eosr    rts
  466.  
  467.  
  468. ; --- "Pot" subroutine
  469.  
  470. ; This routine computes the mouse
  471. ; movements and therefore contains the
  472. ; self-calibration stuff and the other
  473. ; improvements over the standard 1351
  474. ; driver.
  475. PotMax !word 0; max. POTs yet plus 1 !
  476. PotMin !word $ffff; lowest POTs yet
  477. PotOld !word 0; old values
  478. PotWidth !word 0; interval width
  479. HalfPotWidth !word 0; half width
  480. ; (buffered for speed increase)
  481. ; The above variables are not really
  482. ; words: The first byte is the x value,
  483. ; the second byte is the y value
  484. ; respectively.
  485.  
  486. PotDelta
  487. ; Compute the signed distance of mouse
  488. ; movement. Entry conditions:
  489. ; X is direction handle (0 = x, 1 = y)
  490. ; Exit conditions:
  491. ; A/Y are signed distance (low/high)
  492.  
  493. ; First, get new value and clear
  494. ; "recalculate signal width" flag.
  495.         lda sid_pot,x
  496.         ldy #$00
  497. ; Check whether new value is lower than
  498. ; lowest known.
  499.         cmp PotMin,x
  500.         bcs m0
  501. ; Store new "lowest" und set
  502. ; "recalculate signal width" flag.
  503.         sta PotMin,x
  504.         ldy #$ff
  505.  
  506. ; Check whether new value is higher
  507. ; than highest known.
  508. m0      cmp PotMax,x
  509.         bcc m1
  510. ; Set "recalculate signal width" flag
  511. ; and store new "highest".
  512.         ldy #$ff
  513.         pha; Remember current value
  514.         adc #$00; Add one (C is set)
  515.         sta PotMax,x
  516. ; Value $ff (0 after adding) means that
  517. ; there is no mouse connected, so reset
  518. ; min/max in that case.
  519.         beq ResetMM; Stack is untidy...
  520.         pla; Restore current value
  521.  
  522. ; If flag is set, recalculate signal
  523. ; width.
  524. m1
  525.         iny; Check flag
  526.         bne m3
  527.         tay; Buffer current value.
  528.         lda PotMax,x; Get highest+1
  529.         sec; Subtract lowest
  530.         sbc PotMin,x
  531.         bcc m2
  532.         sta PotWidth,x; Store signal
  533.         lsr; width and half signal
  534.         sta HalfPotWidth,x; width
  535. m2      tya; Restore current value.
  536.  
  537. ; Calculate distance
  538. m3      tay; Buffer current value.
  539.         sec
  540.         sbc PotOld,x
  541.         pha
  542.         tya
  543.         sta PotOld,x
  544.         pla
  545.         beq zero; If not moved, exit.
  546.         bcc minus; Negative difference
  547.  
  548. ; Positive difference:
  549. ; Check whether movement caused a value
  550. ; wrap-around.
  551.         cmp HalfPotWidth,x
  552.         bcc Decrease
  553.         beq Decrease
  554. ; It did, so calculate "real" distance
  555. ; and jump to exit
  556.         ;sec; C is always set here
  557.         sbc PotWidth,x; Fix distance
  558.  
  559. ; We now know that the (fixed) distance
  560. ; is really negative, so we finally
  561. ; wipe out that annoying bit 0 noise by
  562. ; incrementing the value.
  563. Increase
  564.         ;clc; C is always clear here
  565.         adc #$01
  566.         beq zero; If increasing
  567. ; delivers zero, jump to zero handler.
  568.         ldy #$ff; Set up high byte for
  569. ; negative values.
  570.         rts
  571.  
  572. ; Negative difference:
  573. ; Check whether movement caused a value
  574. ; wrap-around.
  575. minus   eor #$ff; Complement
  576. ; If we would do a real negation (by
  577. ; adding "1"), then we would need to
  578. ; branch using BCC *and* BEQ. So the
  579. ; above way might be harder to
  580. ; understand, but it is both shorter
  581. ; *and* faster - which I like. :)
  582.         cmp HalfPotWidth,x
  583.         eor #$ff; Restore value
  584.         bcc Increase
  585. ; Movement caused a value wrap-around,
  586. ; so calculate "real" distance and
  587. ; exit.
  588.         clc
  589.         adc PotWidth,x; Fix distance
  590.  
  591. ; We now know that the (fixed) distance
  592. ; is really positive, so we finally
  593. ; wipe out that annoying bit 0 noise by
  594. ; decrementing the value.
  595. Decrease
  596.         sec
  597.         sbc #$01
  598.  
  599. ; No difference or positive difference;
  600. ; both need zero as the high byte.
  601. zero    ldy #0
  602.         rts
  603.  
  604. ; If there is no mouse, reset "lowest"
  605. ; ("highest" will have been reset
  606. ; already) and return zero.
  607. ResetMM tay; Set Y to zero.
  608.         pla; Tidy stack
  609.         lda #$ff; Reset "lowest"
  610.         sta PotMin,x
  611.         tya; Return with A/Y = 0
  612.         rts
  613.  
  614.  
  615. ; --- Include sprites
  616.  
  617. ; Because the C64 version copies the
  618. ; sprite data into the tape buffer on
  619. ; initialisation, the data is included
  620. ; right here.
  621. ; In the C128 version, we skip memory
  622. ; until we reach $0e00 - this is where
  623. ; the sprites are stored by default.
  624. ;       !align $ffff,$e00,$0;C128 only
  625. Sprites !binary "pointersprites",, 2
  626.