home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / misc / emu / z80 / machine_macs.i < prev    next >
Text File  |  1993-12-21  |  11KB  |  545 lines

  1. ** Machine-specific macros for the implementation-dependent
  2. ** Z80 instructions.
  3.  
  4. ** These are intended for the Spectrum emulator only.
  5.  
  6.     XREF    _SOUNDDATA
  7.  
  8.     INCLUDE "envdata.i"
  9.  
  10. ** ---------------------------------------------------------------------
  11.  
  12. ** I/O ports on the ZX Spectrum
  13. **
  14. **  In general:
  15. **
  16. **    The address bits 0 to 4 are usually set. At most one of them
  17. **    should be reset at any time. A reset bit signals an I/O operation.
  18. **    Bits 5 to 7 are normally set, and are not used by the standard
  19. **    hardware. The address bits 8 to 15 are in some cases (e.g. when
  20. **    reading the keyboard) used to give more information. Usually they
  21. **    are ignored.
  22. **
  23. **  Port xxFE    (bit 0 reset)
  24. **    General I/O port
  25. **    Input:
  26. **        Bit 7        Unknown
  27. **        Bit 6        Value of EAR port
  28. **        Bit 5        Unknown
  29. **        Bits 4 to 0    Keyboard data
  30. **
  31. **    The keyboard rows are ordered from 0 (Caps Shift to V) through
  32. **    3 (1 to 5), 4 (0 to 6) and 7 (Space to B).
  33. **      The bits 0 to 4 represent keys in a row, where bit 0 is the
  34. **    outermost key. A bit is low if the key is pressed, and high if
  35. **    it is not pressed.
  36. **      The address bits 8 to 15 correspond to rows 0 to 7 respectively,
  37. **    and specify which rows will be read. A reset bit means the row
  38. **    will be read. The selected rows are bitwise combined. In the
  39. **    result, each bit is reset if one of the bits in the same position
  40. **    was reset, and set if none of them were reset. Taking the bit
  41. **    pattern 11111 and bitwise AND:ing with all selected rows would
  42. **    give the same result.
  43. **      The value of bit 6 is not affected by the high address bits.
  44. **
  45. **    Output:    
  46. **        Bits 7 to 5    Not used
  47. **        Bit 4        Speaker control
  48. **        Bit 3        MIC port control
  49. **        Bits 2 to 0    Border colour code
  50. **
  51. **    The speaker and MIC ports are active low.
  52. **      The colour codes are specified as on/off flags for the RGB
  53. **    components, where bits 2 through 0 correspond to Green, Red and
  54. **    Blue respectively, giving totally 8 different colours. There is
  55. **    no Bright mode flag for the border.
  56. **
  57. **  Port xxFD    (bit 1 reset)
  58. **    Used for Microdrive, Networking or RS232C. I have no details.
  59. **    Input:
  60. **    Output:    
  61. **    
  62. **  Port xxFB    (bit 2 reset)
  63. **    ZX Printer control port
  64. **    Input:
  65. **        Bit 7        High when stylus is in write position.
  66. **        Bit 6        Low only if the printer is present.
  67. **        Bits 5 to 0    Unknown
  68. **
  69. **    Output:
  70. **        Bit 7        High "for the actual printing".
  71. **        Bits 6 to 3    Unknown
  72. **        Bit 2        Low starts the motor.
  73. **        Bit 1        High slows the motor.
  74. **        Bit 0        Unknown
  75. **
  76. **  Port xxF7    (bit 3 reset)
  77. **    Used for Microdrive, Networking or RS232C. I have no details.
  78. **    Input:
  79. **    Output:    
  80. **
  81. **  Port xxEF    (bit 4 reset)
  82. **    Used for Microdrive, Networking or RS232C. I have no details.
  83. **    Input:
  84. **    Output:    
  85. **
  86. **  Port xx1F    (bits 0 to 4 set, bits 5 to 7 reset)
  87. **    Kempston interface port (external hardware)
  88. **    Input:
  89. **        Bits 7 to 5    Unknown
  90. **        Bit 4        Fire
  91. **        Bit 3        Up
  92. **        Bit 2        Down
  93. **        Bit 1        Left
  94. **        Bit 0        Right
  95. **
  96. **    Bits 4 to 0 are active high.
  97. **
  98. **    Output:    Unknown
  99. **
  100.  
  101. ** ---------------------------------------------------------------------
  102.  
  103. ** The keyboard data:
  104. **    An array of 8 bytes (0 to 7) corresponding exactly to the
  105. **    keyboard rows 0 to 7. Bits 5 to 7 are zero.
  106.  
  107. Kbd = Z80_Envdata+Envd_Kbd    ;offset from control structure base
  108.  
  109. ** ---------------------------------------------------------------------
  110.  
  111.     IFD VERBOSE
  112.     LIST
  113. ** Compiling the machine.i file designed for the ZX Spectrum emulator.
  114.     NOLIST
  115.     ENDC
  116.  
  117.  
  118. ** A default read value, used by some lazy routines like Inir:
  119. DEFAULT_IN = $FF
  120.  
  121.  
  122.     ;Macro for fast keyboard data reading.
  123.     ;RowSpec (register) corresponds to high byte of I/O address.
  124.     ;Dest (register) must be $FF before macro call.
  125. KBD_READ    MACRO    ;RowSpec, Dest
  126.         add.b    \1,\1
  127.         bcs.s    .7set
  128.         and.b    Kbd+7(TableB),\2   ;row 7
  129. .7set        add.b    \1,\1
  130.         bcs.s    .6set
  131.         and.b    Kbd+6(TableB),\2
  132. .6set        add.b    \1,\1
  133.         bcs.s    .5set
  134.         and.b    Kbd+5(TableB),\2
  135. .5set        add.b    \1,\1
  136.         bcs.s    .4set
  137.         and.b    Kbd+4(TableB),\2
  138. .4set        add.b    \1,\1
  139.         bcs.s    .3set
  140.         and.b    Kbd+3(TableB),\2
  141. .3set        add.b    \1,\1
  142.         bcs.s    .2set
  143.         and.b    Kbd+2(TableB),\2
  144. .2set        add.b    \1,\1
  145.         bcs.s    .1set
  146.         and.b    Kbd+1(TableB),\2
  147. .1set        add.b    \1,\1
  148.         bcs.s    .0set
  149.         and.b    Kbd+0(TableB),\2     ;row 0
  150. .0set
  151.     ENDM
  152.  
  153.  
  154. **
  155. ** The instruction macros themselves:
  156. **
  157.  
  158.     ;sadly, one can't nest macros.
  159.  
  160. In_r_1C1_subm    MACRO
  161.         cmp.b    #$fe,C
  162.         st    \1    ;flags unaffected
  163.         bne.s    .end
  164.         move.b    B,d7
  165.         KBD_READ d7,\1
  166. .end        tst.b    \1    ;V cleared
  167.         putsr    d7
  168.         eor.b    d7,d6
  169.         and.w    #1,d6
  170.         eor.b    d7,d6    ;keep old carry
  171.         parity    \1
  172.         skip 1
  173.         next
  174.         ENDM
  175.  
  176. In_A_1C1_mac    MACRO
  177.         In_r_1C1_subm    A
  178.         ENDM
  179. In_B_1C1_mac    MACRO
  180.         In_r_1C1_subm    B
  181.         ENDM
  182. In_C_1C1_mac    MACRO
  183.         In_r_1C1_subm    C
  184.         ENDM
  185. In_D_1C1_mac    MACRO
  186.         In_r_1C1_subm    D
  187.         ENDM
  188. In_E_1C1_mac    MACRO
  189.         In_r_1C1_subm    E
  190.         ENDM
  191. In_L_1C1_mac    MACRO
  192.         In_r_1C1_subm    L
  193.         ENDM
  194.  
  195. In_H_1C1_mac    MACRO
  196.         swap    d6    ;save flags
  197.         move.w    #$00ff,d6    ;for parity indexing
  198.         cmp.b    #$fe,C
  199.         bne.s    .end
  200.         move.b    B,d7
  201.         KBD_READ d7,d6
  202. .end        move.w    HL,(Work)
  203.         move.b    d6,(Work)       ;V cleared,N & Z tested
  204.         putsr    d7
  205.         or.b    Z80_Parity(TableB,d6.w),d7 ;set parity in d7
  206.         move.w    (Work),HL
  207.         swap    d6    ;get old flags
  208.         eor.b    d7,d6
  209.         and.w    #1,d6
  210.         eor.b    d7,d6    ;keep old carry
  211.         skip 1
  212.         next
  213.         ENDM
  214.  
  215.     ;"Undocumented" instruction. Reads from the port but does not
  216.     ;store the value. Flags are affected by the read value as usual,
  217.     ;and this instruction is sometimes named "In F,(C)". The name
  218.     ;"In (HL),(C)" would be symmetric, but is not correct.
  219. In_xx_1C1_mac    MACRO
  220.         swap    d6    ;save flags
  221.         move.w    #$00ff,d6    ;for parity indexing
  222.         cmp.b    #$fe,C
  223.         bne.s    .end
  224.         move.b    B,d7
  225.         KBD_READ d7,d6
  226. .end        tst.b    d6    ;V cleared,N & Z tested
  227.         putsr    d7
  228.         or.b    Z80_Parity(TableB,d6.w),d7 ;set parity in d7
  229.         swap    d6    ;forget the value, get old flags
  230.         eor.b    d7,d6
  231.         and.w    #1,d6
  232.         eor.b    d7,d6    ;keep old carry
  233.         skip 1
  234.         next
  235.         ENDM
  236. ** ----
  237. In_A_1n1_mac    MACRO
  238.         getRPC
  239.         getz    d7,d7
  240.         cmp.b    #$fe,d7
  241.         bne.s    .notFE
  242.         move.b    A,d7
  243.         st    A
  244.         KBD_READ d7,A
  245. .end        skip 1
  246.         next
  247.  
  248. .notFE        st    A
  249.         bra.s    .end
  250.         ENDM
  251. ** ----
  252.  
  253. ** The block In instructions do not bother to 'read ports'.
  254. ** They simply "read" the default in value.
  255.  
  256. Ind_mac     MACRO
  257.         move.b    #DEFAULT_IN,d7
  258.         putz    d7,HL
  259.         decw    HL
  260.         and.w    #%1011,d6
  261.         decb    B
  262.         bne.s    .nz
  263.         or.w    #%0100,d6
  264. .nz        skip 1
  265.         next
  266.         ENDM
  267. ** ----
  268. Indr_mac    MACRO
  269.         move.b    #DEFAULT_IN,d7
  270. .loop        putz    d7,HL
  271.         decw    HL
  272.         decb    B
  273.         bne.s    .loop
  274.         or.w    #%0100,d6
  275.         skip 1
  276.         next
  277.         ENDM
  278. ** ----
  279. Ini_mac     MACRO
  280.         move.b    #DEFAULT_IN,d7
  281.         putz    d7,HL
  282.         incw    HL
  283.         and.w    #%1011,d6
  284.         decb    B
  285.         bne.s    .nz
  286.         or.w    #%0100,d6
  287. .nz        skip 1
  288.         next
  289.         ENDM
  290. ** ----
  291. Inir_mac    MACRO
  292.         move.b    #DEFAULT_IN,d7
  293. .loop        putz    d7,HL
  294.         incw    HL
  295.         decb    B
  296.         bne.s    .loop
  297.         or.w    #%0100,d6
  298.         skip 1
  299.         next
  300.         ENDM
  301. ** ----
  302. Ld_A_R_mac    MACRO
  303.         getRPC    ;take bits from RPC (since PPC is always even)
  304.         move.b    Z80_R(TableB),A
  305.         eor.w    d7,d6
  306.         and.w    #80,d6    ;keep bit 7 of stored R
  307.         eor.w    d7,d6    ;V is cleared, Z and N tested.
  308.         putsr    d7
  309.         eor.w    d7,d6
  310.         and.w    #1,d6    ;keep old carry
  311.         eor.w    d7,d6
  312.         tst.b    Z80_IFF(TableB)    ;test IFF2
  313.         beq.s    .clear
  314.         or.w    #%0010,d6    ;set V if IFF2 set
  315. .clear        skip 1
  316.         next
  317.         ENDM
  318. ** ----
  319. Ld_R_A_mac    MACRO
  320.         move.b    A,Z80_R(TableB)    ;(the bits 6-0 are never reused)
  321.         skip 1
  322.         next
  323.         ENDM
  324. ** ----
  325.  
  326. ** It is OK for Otir and Otdr to be a bit inefficient. The real Z80
  327. ** instruction does a complete re-execution each time it loops.
  328. ** If that is done here as well, the block output timing will be nicer.
  329.  
  330. Otdr_mac    MACRO
  331. .loop        getz    HL,d7
  332.         cmp.b    #$fe,C
  333.         bne.s    .end
  334.         and.b    #$10,d7     ;speaker(0 or 16)
  335.         add.b    d7,d7
  336.         move.b    d7,_SOUNDDATA
  337.         move.b    d7,_SOUNDDATA+1
  338.         getz    HL,d7
  339.         and.b    #8,d7        ;mic(0 or 8)
  340.         add.b    d7,d7
  341.         add.b    d7,d7
  342.         move.b    d7,_SOUNDDATA+2
  343.         move.b    d7,_SOUNDDATA+3
  344. .end        decw    HL
  345.         decb    B
  346.         bne.s    .loop
  347.         or.w    #%0100,d6    ;Set Z
  348.         skip 1
  349.         next
  350.         ENDM
  351. ** ---
  352. Otir_mac    MACRO
  353. .loop        getz    HL,d7
  354.         cmp.b    #$fe,C
  355.         bne.s    .end
  356.         and.b    #$10,d7     ;speaker(0 or 16)
  357.         add.b    d7,d7
  358.         move.b    d7,_SOUNDDATA
  359.         move.b    d7,_SOUNDDATA+1
  360.         getz    HL,d7
  361.         and.b    #8,d7        ;mic(0 or 8)
  362.         add.b    d7,d7
  363.         add.b    d7,d7
  364.         move.b    d7,_SOUNDDATA+2
  365.         move.b    d7,_SOUNDDATA+3
  366. .end        incw    HL
  367.         decb    B
  368.         bne.s    .loop
  369.         or.w    #%0100,d6    ;Set Z
  370.         skip 1
  371.         next
  372.         ENDM
  373. ** ----
  374.  
  375.     ;no macro nesting, sadly
  376. Out_1C1_r_subm    MACRO
  377.         cmp.b    #$fe,C
  378.         bne.s    .end
  379.         move.b    \1,d7        ;sp