home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / misc / macros.inc < prev    next >
Text File  |  1990-04-17  |  23KB  |  919 lines

  1.     .Xlist
  2.     Page    58,132
  3.     Subttl    MACROS.INC    Apple Emulator (65C02 Processor)
  4. ;******************************************************************************
  5. ;
  6. ;   Name:    MACROS        Apple Emulator (65C02 Processor)
  7. ;
  8. ;   Group:    Emulator
  9. ;
  10. ;   Revision:    1.00
  11. ;
  12. ;   Date:    January 30, 1988
  13. ;
  14. ;   Author:    Randy W. Spurlock
  15. ;
  16. ;******************************************************************************
  17. ;
  18. ;  Module Functional Description:
  19. ;
  20. ;        This module contains all the macros needed by the
  21. ;    Apple emulator. This module can be included with any needed
  22. ;    source files to define the Apple emulator macros.
  23. ;
  24. ;******************************************************************************
  25. ;
  26. ;  Changes:
  27. ;
  28. ;    DATE     REVISION                DESCRIPTION
  29. ;  --------   --------    -------------------------------------------------------
  30. ;   1/30/88    1.00    Original
  31. ;
  32. ;******************************************************************************
  33. LineUp    Macro    divide,filler
  34.     .Xlist
  35.     Ifb    <filler>
  36. _fill    =    00h
  37.     Else
  38. _fill    =    filler
  39.     Endif
  40. _addr    =    $ - emulate
  41. _amt    =    _addr MOD divide
  42.     If    _amt NE 0
  43. _amt    =    divide - _amt
  44.     Db    _amt dup (filler)    ; Reserved required space to line up
  45.     Endif
  46.     .List
  47.     Endm
  48.  
  49. String    Macro    Str
  50. _cnt    =    0
  51.     Irpc    x,<Str>
  52. _cnt    =    _cnt + 1
  53.     Endm
  54.     Db    _cnt,Str,0Dh,0Ah    ; Define the requested string
  55.     Endm
  56.  
  57. Err_Str Macro    Name, Str
  58.     Def_Err %_Err_Cnt,Name,<Str>
  59. _Err_Cnt    =    _Err_Cnt + 1
  60.     Endm
  61.  
  62. Def_Err Macro    Number,Name,Str
  63. ERR_&Name    Equ    &Number     ; Define the error name
  64.     public    ERR_&Name
  65. Error_&Number    Equ    This Word    ; Define the error string
  66.     String    <Str>
  67.     Endm
  68.  
  69. Err_Tbl Macro
  70. Error_Table    Equ    This Word    ; Declare start of error table
  71. _Err_Num    =    0
  72.     Rept    _Err_Cnt
  73.         Def_Tbl %_Err_Num
  74. _Err_Num    =    _Err_Num + 1
  75.     Endm
  76.     Endm
  77.  
  78. Def_Tbl Macro    Number
  79.     Dw    Error_&Number        ; Define the error table entry
  80.     Endm
  81.  
  82. Reverse Macro    String
  83.     .Xlist
  84. _Value    =    00h
  85. _Shift    =    00h
  86.     Irpc    c,<String>
  87. _Value    =    _Value + (c Shl _Shift)
  88. _Shift    =    _Shift + 1
  89.     Endm
  90.     Db    _Value            ; Define the reversed value
  91.     .List
  92.     Endm
  93.  
  94. Color    Macro    String
  95.     .Xlist
  96. _Value    =    00h
  97.     Irpc    c,<String>
  98. _Color    =    00h
  99.         Ifidn    <C>,<B>
  100. _Color    =    00h
  101.         Endif
  102.         Ifidn    <C>,<G>
  103. _Color    =    01h
  104.         Endif
  105.         Ifidn    <C>,<P>
  106. _Color    =    02h
  107.         Endif
  108. _Value    =    (_Value Shl 2) + _Color
  109.     Endm
  110. _Value    =    _Value Shl 2
  111.     Dw    _Value            ; Define the color word value
  112.     .List
  113.     Endm
  114.  
  115. Shift    Record    Word_Shift:4,Byte_Shift:4
  116.  
  117. Map    Macro    Color_1,Color_2
  118.     Entry    Color_1,%&Color_2
  119.     Endm
  120.  
  121. Entry    Macro    Apple_Color,IBM_Color
  122. _map_&Apple_Color    Equ    IBM_Color
  123.     Endm
  124.  
  125. Convert Macro    Background,Foreground
  126.     .Xlist
  127.     Db    _map_&Background Shl 4 + _map_&Foreground
  128.     .List
  129.     Endm
  130.  
  131. _device_cnt    =    0        ; Initialize the device type counter
  132.  
  133. Device    Macro    Type
  134.     Extrn    &Type&_Init:Near    ; Define device initialization routine
  135.     Extrn    &Type&_Ctrl:Near    ; Define device control routine
  136.     Extrn    &Type&_Rd:Near        ; Define device read routine
  137.     Extrn    &Type&_Wrt:Near     ; Define device write routine
  138.     Extrn    &Type&_Mem_Rd:Near    ; Define device memory read routine
  139.     Extrn    &Type&_Mem_Wrt:Near    ; Define device memory write routine
  140.     Extrn    &Type&_Exp_Rd:Near    ; Define device expansion read routine
  141.     Extrn    &Type&_Exp_Wrt:Near    ; Define device expansion write routine
  142.     Extrn    &Type&_ID:Byte        ; Define device ID name string
  143.     Declare %_device_cnt,Type    ; Declare the device type
  144. _device_cnt    =    _device_cnt + 1 ; Increment the device counter
  145.     Endm
  146.  
  147. Declare Macro    Number,Type
  148. _dev_&Number&_id    Equ    &Type&_ID
  149. _dev_&Number&_init    Equ    &Type&_Init
  150. _dev_&Number&_ctrl    Equ    &Type&_Ctrl
  151. _dev_&Number&_rd    Equ    &Type&_Rd
  152. _dev_&Number&_wrt    Equ    &Type&_Wrt
  153. _dev_&Number&_mem_rd    Equ    &Type&_Mem_Rd
  154. _dev_&Number&_mem_wrt    Equ    &Type&_Mem_Wrt
  155. _dev_&Number&_exp_rd    Equ    &Type&_Exp_Rd
  156. _dev_&Number&_exp_wrt    Equ    &Type&_Exp_Wrt
  157.     Endm
  158.  
  159. Slot    Macro    Number,Type
  160. _slot_&Number&_id    Equ    &Type&_ID
  161. _slot_&Number&_init    Equ    &Type&_Init
  162. _slot_&Number&_ctrl    Equ    &Type&_Ctrl
  163. _slot_&Number&_rd    Equ    &Type&_Rd
  164. _slot_&Number&_wrt    Equ    &Type&_Wrt
  165. _slot_&Number&_mem_rd    Equ    &Type&_Mem_Rd
  166. _slot_&Number&_mem_wrt    Equ    &Type&_Mem_Wrt
  167. _slot_&Number&_exp_rd    Equ    &Type&_Exp_Rd
  168. _slot_&Number&_exp_wrt    Equ    &Type&_Exp_Wrt
  169.     Endm
  170.  
  171. Table    Macro
  172.     .Xlist
  173. Slot_ID     Equ    This Word    ; Define exp. slot ID name table
  174. _cnt    =    0
  175.     Rept    SLOT_MAX
  176.         Build    slot,%_cnt,id
  177. _cnt    =    _cnt + 1
  178.     Endm
  179. Slot_Init    Equ    This Word    ; Define exp. slot initialize table
  180. _cnt    =    0
  181.     Rept    SLOT_MAX
  182.         Build    slot,%_cnt,init
  183. _cnt    =    _cnt + 1
  184.     Endm
  185. Slot_Ctrl    Equ    This Word    ; Define exp. slot control table
  186. _cnt    =    0
  187.     Rept    SLOT_MAX
  188.         Build    slot,%_cnt,ctrl
  189. _cnt    =    _cnt + 1
  190.     Endm
  191. Slot_Read    Equ    This Word    ; Define exp. slot write table
  192. _cnt    =    0
  193.     Rept    SLOT_MAX
  194.         Build    slot,%_cnt,rd
  195. _cnt    =    _cnt + 1
  196.     Endm
  197. Slot_Write    Equ    This Word    ; Define exp. slot read table
  198. _cnt    =    0
  199.     Rept    SLOT_MAX
  200.         Build    slot,%_cnt,wrt
  201. _cnt    =    _cnt + 1
  202.     Endm
  203. Mem_Read    Equ    This Word    ; Define exp. slot memory read table
  204. _cnt    =    0
  205.     Rept    SLOT_MAX
  206.         Build    slot,%_cnt,mem_rd
  207. _cnt    =    _cnt + 1
  208.     Endm
  209. Mem_Write    Equ    This Word    ; Define exp. slot memory write table
  210. _cnt    =    0
  211.     Rept    SLOT_MAX
  212.         Build    slot,%_cnt,mem_wrt
  213. _cnt    =    _cnt + 1
  214.     Endm
  215. Exp_Read    Equ    This Word    ; Define exp. slot ROM/RAM read table
  216. _cnt    =    0
  217.     Rept    SLOT_MAX
  218.         Build    slot,%_cnt,exp_rd
  219. _cnt    =    _cnt + 1
  220.     Endm
  221.     Dw    Special_Read        ; Define the special read routine
  222. Exp_Write    Equ    This Word    ; Define exp. slot ROM/RAM write table
  223. _cnt    =    0
  224.     Rept    SLOT_MAX
  225.         Build    slot,%_cnt,exp_wrt
  226. _cnt    =    _cnt + 1
  227.     Endm
  228.     Dw    Special_Write        ; Define the special write routine
  229. Device_Table    Equ    This Word    ; Define the device table
  230.     Dw    _device_cnt
  231. _cnt    =    0
  232.     Rept    _device_cnt
  233.         Build    dev,%_cnt,id
  234.         Build    dev,%_cnt,init
  235.         Build    dev,%_cnt,ctrl
  236.         Build    dev,%_cnt,rd
  237.         Build    dev,%_cnt,wrt
  238.         Build    dev,%_cnt,mem_rd
  239.         Build    dev,%_cnt,mem_wrt
  240.         Build    dev,%_cnt,exp_rd
  241.         Build    dev,%_cnt,exp_wrt
  242. _cnt    =    _cnt + 1
  243.     Endm
  244.     Endm
  245.  
  246. Build    Macro    Name,Number,Type
  247.     Dw    _&Name&_&Number&_&Type      ; Build the table entry
  248.     .List
  249.     Endm
  250.  
  251. CGA    Macro    String
  252.     .Xlist
  253. _value    =    0
  254.     Irpc    c,<String>
  255.         Ifidn    <c>,<I>
  256. _value    =    _value + 10h
  257.         Endif
  258.         Ifidn    <c>,<r>
  259. _value    =    _value + 04h
  260.         Endif
  261.         Ifidn    <c>,<g>
  262. _value    =    _value + 02h
  263.         Endif
  264.         Ifidn    <c>,<b>
  265. _value    =    _value + 01h
  266.         Endif
  267.     Endm
  268.     Db    _value            ; Define the CGA color value
  269.     .List
  270.     Endm
  271.  
  272. EGA    Macro    String
  273.     .Xlist
  274. _value    =    0
  275.     Irpc    c,<String>
  276.         Ifidn    <c>,<R>
  277. _value    =    _value + 20h
  278.         Endif
  279.         Ifidn    <c>,<G>
  280. _value    =    _value + 10h
  281.         Endif
  282.         Ifidn    <c>,<B>
  283. _value    =    _value + 08h
  284.         Endif
  285.         Ifidn    <c>,<r>
  286. _value    =    _value + 04h
  287.         Endif
  288.         Ifidn    <c>,<g>
  289. _value    =    _value + 02h
  290.         Endif
  291.         Ifidn    <c>,<b>
  292. _value    =    _value + 01h
  293.         Endif
  294.     Endm
  295.     Db    _value            ; Define the EGA color value
  296.     .List
  297.     Endm
  298.  
  299. Encrypt_Byte    Macro
  300.     mov    ah,al            ; Move a copy of byte to AH register
  301.     shr    al,1            ; Shift byte value into position
  302.     or    ax,1010101010101010b    ; Odd/even encrypt the byte value
  303.     Endm
  304.  
  305. Decrypt_Byte    Macro
  306.     rol    al,1            ; Rotate byte value into position
  307.     and    al,ah            ; Odd/even decrypt the byte value
  308.     Endm
  309.  
  310. Encode    Macro    Value
  311. _base    =    Value And 10110101b
  312. _flag_Z =    (Value And 01000000b) Shr 6
  313. _flag_V =    (Value And 00001000b) Shr 3
  314. _flag_M =    (Value And 00000010b) Shr 1
  315. _value    =    _base + (_flag_V Shl 6) + (_flag_M Shl 3) + (_flag_Z Shl 1)
  316.     Db    _value            ; Define the encoded byte value
  317.     Endm
  318.  
  319. Decode    Macro    Value
  320. _base    =    Value And 10110101b
  321. _flag_V =    (Value And 01000000b) Shr 6
  322. _flag_M =    (Value And 00001000b) Shr 3
  323. _flag_Z =    (Value And 00000010b) Shr 1
  324. _value    =    _base + (_flag_Z Shl 6) + (_flag_V Shl 3) + (_flag_M Shl 1)
  325.     Db    _value            ; Define the decoded byte value
  326.     Endm
  327.  
  328. Fill    Macro    Count,Filler
  329.     mov    al,&Filler        ; Get the filler byte value
  330.     mov    cx,&Count        ; Get the filler byte count
  331.     rep    stosb            ; Fill the gap area will filler byte
  332.     Endm
  333.  
  334. Address Macro    Name, Routine
  335.     If2
  336.         Ifndef    _Address_Count
  337. _Address_Count    =    0
  338.         Endif
  339. TYPE_&Name    =    _Address_Count    ; Define the addressing type
  340. _Address_Count    =    _Address_Count + 2
  341.     Endif
  342.     Dw    Routine         ; Define the addressing routine
  343.     Endm
  344.  
  345. Mnemonic    Macro    Name,String
  346.     If2
  347.         Ifndef    _Mnemonic_Count
  348. _Mnemonic_Count =    0
  349.         Endif
  350. OP_&Name    =    _Mnemonic_Count ; Define the mnemonic opcode
  351. _Mnemonic_Count =    _Mnemonic_Count + 1
  352.     Endif
  353.     Db    String,0        ; Define the mnemonic string
  354.     Endm
  355.  
  356. Save    Macro    a,b,c,d,e,f,g,h,i,j
  357.     .Xlist
  358.     Irp    x,<a,b,c,d,e,f,g,h,i,j>
  359.         Ifnb    <x>
  360.             push    x    ; Save the requested register
  361.         Endif
  362.     Endm
  363.     .List
  364.     Endm
  365.  
  366. Restore Macro    a,b,c,d,e,f,g,h,i,j
  367.     .Xlist
  368.     Irp    x,<j,i,h,g,f,e,d,c,b,a>
  369.         Ifnb    <x>
  370.             pop    x    ; Restore the requested register
  371.         Endif
  372.     Endm
  373.     .List
  374.     Endm
  375.  
  376. Fetch    Macro
  377.     local    _addr
  378.     lodsb                ; Load the next opcode byte
  379.     xor    ah,ah            ; Convert opcode to full word
  380.     shl    ax,Op_Base        ; Convert opcode to address
  381.     mov    di,ax            ; Move routine address to DI
  382.     test    dh,CPU_R        ; Check for emulator interrupt
  383.     jnz    _addr            ; Jump if emulator interrupt request
  384.     jmp    di            ; Jump to correct opcode routine
  385. _addr:
  386.     jmp    Interrupt        ; Go process the emulator interrupt
  387.     Endm
  388.  
  389. Setup    Macro
  390.     lodsb                ; Load the next opcode byte
  391.     xor    ah,ah            ; Convert opcode to full word
  392.     shl    ax,Op_Base        ; Convert opcode to address
  393.     mov    di,ax            ; Move routine address to DI
  394.     Endm
  395.  
  396. Flgnz    Macro
  397.     lahf                ; Load flags into AH register
  398.     and    ah,CPU_N + CPU_Z    ; Mask off all but sign/zero flags
  399.     and    dh,Not (CPU_N + CPU_Z)    ; Clear the n and z flags
  400.     or    dh,ah            ; Update the 65C02 status flags
  401.     Endm
  402.  
  403. Flgnzc    Macro
  404.     lahf                ; Load flags into AH register
  405.     and    ah,CPU_N + CPU_Z + CPU_C; Mask off all but sign/carry/zero flags
  406.     and    dh,Not (CPU_N + CPU_Z + CPU_C)
  407.     or    dh,ah            ; Update the 65C02 status flags
  408.     Endm
  409.  
  410. Flgnvzc Macro
  411.     pushf                ; Push the processor flags
  412.     pop    ax            ; Pop flags into AX register
  413.     and    ax,0000100011000001b    ; Mask all but overflow/sign/zero/carry
  414.     or    al,ah            ; Logically OR in overflow flag
  415.     and    dh,Not (CPU_N + CPU_V + CPU_Z + CPU_C)
  416.     or    dh,al            ; Update the 65C02 status flags
  417.     Endm
  418.  
  419. Push_16 Macro
  420.     dec    bl            ; Decrement the stack pointer
  421.     mov    ds:[bx],ax        ; Push the 16-bit value
  422.     dec    bl            ; Decrement the stack pointer
  423.     Endm
  424.  
  425. Push_8    Macro
  426.     mov    ds:[bx],al        ; Push the 8-bit value
  427.     dec    bl            ; Decrement the stack pointer
  428.     Endm
  429.  
  430. Pop_16    Macro
  431.     inc    bl            ; Increment the stack pointer
  432.     mov    ax,ds:[bx]        ; Pop the 16-bit value
  433.     inc    bl            ; Increment the stack pointer
  434.     Endm
  435.  
  436. Pop_8    Macro
  437.     inc    bl            ; Increment the stack pointer
  438.     mov    al,ds:[bx]        ; Pop the 8-bit value
  439.     Endm
  440.  
  441. DoImm    Macro
  442. _type    =    000h
  443.     mov    di,si            ; Setup the effective address
  444.     inc    si            ; Update the program counter
  445.     Endm
  446.  
  447. DoAbs    Macro
  448. _type    =    0FFh
  449.     lodsw                ; Get the absolute address
  450.     mov    di,ax            ; Setup the effective address
  451.     Endm
  452.  
  453. DoDP    Macro
  454. _type    =    000h
  455.     lodsb                ; Get the direct page offset
  456.     xor    ah,ah            ; Convert to direct page address
  457.     mov    di,ax            ; Setup the effective address
  458.     Endm
  459.  
  460. DoDIX    Macro
  461. _type    =    000h
  462.     lodsb                ; Get the direct page offset
  463.     add    al,ch            ; Add in the X index value
  464.     xor    ah,ah            ; Convert to direct page address
  465.     mov    di,ax            ; Setup the effective address
  466.     Endm
  467.  
  468. DoDIY    Macro
  469. _type    =    000h
  470.     lodsb                ; Get the direct page offset
  471.     add    al,cl            ; Add in the Y index value
  472.     xor    ah,ah            ; Convert to direct page address
  473.     mov    di,ax            ; Setup the effective address
  474.     Endm
  475.  
  476. DoAIX    Macro
  477. _type    =    0FFh
  478.     lodsw                ; Get the absolute address
  479.     add    al,ch            ; Add in the X index value
  480.     adc    ah,0            ; Do 16-bit arithmetic
  481.     mov    di,ax            ; Setup the effective address
  482.     Endm
  483.  
  484. DoAIY    Macro
  485. _type    =    0FFh
  486.     lodsw                ; Get the absolute address
  487.     add    al,cl            ; Add in the Y index value
  488.     adc    ah,0            ; Do 16-bit arithmetic
  489.     mov    di,ax            ; Setup the effective address
  490.     Endm
  491.  
  492. DoAI    Macro
  493. _type    =    0FFh
  494.     lodsw                ; Get the absolute address
  495.     mov    di,ax            ; Setup to do the indirection
  496.     mov    di,ds:[di]        ; Setup the effective address
  497.     Endm
  498.  
  499. DoDI    Macro
  500. _type    =    0FFh
  501.     lodsb                ; Get the direct page offset
  502.     xor    ah,ah            ; Convert to direct page address
  503.     mov    di,ax            ; Setup to do the indirection
  504.     mov    di,ds:[di]        ; Setup the effective address
  505.     Endm
  506.  
  507. DoAIIX    Macro
  508. _type    =    0FFh
  509.     lodsw                ; Get the absolute address
  510.     add    al,ch            ; Add in the X index value
  511.     adc    ah,0            ; Do 16-bit arithmetic
  512.     mov    di,ax            ; Setup to do the indirection
  513.     mov    di,ds:[di]        ; Setup the effective address
  514.     Endm
  515.  
  516. DoDIIX    Macro
  517. _type    =    0FFh
  518.     lodsb                ; Get the direct page offset
  519.     add    al,ch            ; Add in the X index value
  520.     xor    ah,ah            ; Convert to direct page address
  521.     mov    di,ax            ; Setup to do the indirection
  522.     mov    di,ds:[di]        ; Setup the effective address
  523.     Endm
  524.  
  525. DoDIIY    Macro
  526. _type    =    0FFh
  527.     lodsb                ; Get the direct page offset
  528.     xor    ah,ah            ; Convert to direct page address
  529.     mov    di,ax            ; Setup to do the indirection
  530.     mov    di,ds:[di]        ; Do the indirection
  531.     mov    al,cl            ; Get the Y index value
  532.     add    di,ax            ; Setup the effective address
  533.     Endm
  534.  
  535. OpADCb    Macro
  536.     If    _type
  537.         call    Read_Memory    ; Call routine to read 65C02 memory
  538.     Else
  539.         mov    al,ds:[di]    ; Read the 65C02 memory value
  540.     Endif
  541.     mov    ah,dh            ; Copy 65C02 flags into AH register
  542.     shr    ah,1            ; Shift 65C02 carry into real carry
  543.     adc    dl,al            ; Add with carry to accumulator
  544.     Flgnvzc             ; Update the 65C02 processor flags
  545.     Endm
  546.  
  547. OpADCd    Macro
  548.     If    _type
  549.         call    Read_Memory    ; Call routine to read 65C02 memory
  550.     Else
  551.         mov    al,ds:[di]    ; Read the 65C02 memory value
  552.     Endif
  553.     mov    ah,dh            ; Copy 65C02 flags into AH register
  554.     shr    ah,1            ; Shift 65C02 carry into real carry
  555.     adc    al,dl            ; Add with carry to accumulator
  556.     daa                ; Do the adjust for decimal mode
  557.     mov    dl,al            ; Update the accumulator value
  558.     Flgnvzc             ; Update the 65C02 processor flags
  559.     Endm
  560.  
  561. OpAND    Macro
  562.     If    _type
  563.         call    Read_Memory    ; Call routine to read 65C02 memory
  564.     Else
  565.         mov    al,ds:[di]    ; Read the 65C02 memory value
  566.     Endif
  567.     and    dl,al            ; AND accumulator with memory
  568.     Flgnz                ; Update the 65C02 processor flags
  569.     Endm
  570.  
  571. OpASL    Macro
  572.     If    _type
  573.         call    Read_Memory    ; Call routine to read 65C02 memory
  574.     Else
  575.         mov    al,ds:[di]    ; Read the 65C02 memory value
  576.     Endif
  577.     shl    al,1            ; Shift the memory location left
  578.     mov    bp,ax            ; Save the memory location value
  579.     Flgnzc                ; Update the 65C02 processor flags
  580.     mov    ax,bp            ; Restore the memory location value
  581.     If    _type
  582.         call    Write_Memory    ; Call routine to write 65C02 memory
  583.     Else
  584.         mov    ds:[di],al    ; Write the 65C02 memory value
  585.     Endif
  586.     Endm
  587.  
  588. OpBIT    Macro
  589.     Local    _addr
  590.     and    dh,Not (CPU_N + CPU_V + CPU_Z)
  591.     If    _type
  592.         call    Read_Memory    ; Call routine to read 65C02 memory
  593.     Else
  594.         mov    al,ds:[di]    ; Read the 65C02 memory value
  595.     Endif
  596.     test    dl,al            ; AND accumulator with memory value
  597.     jnz    _addr            ; Jump if the value is non-zero
  598.     or    dh,CPU_Z        ; Zero result, set the zero flag
  599. _addr:
  600.     and    al,11000000b        ; Mask off all but upper two bits
  601.     xor    ah,ah            ; Convert flag bits to full word
  602.     mov    bp,ax            ; Setup to decode the flag value
  603.     or    dh,cs:[bp + Flag_Decode]; Set correct bits in 65C02 status
  604.     Endm
  605.  
  606. OpBITz    Macro
  607.     Local    _addr
  608.     and    dh,Not CPU_Z        ; Clear the z flag
  609.     If    _type
  610.         call    Read_Memory    ; Call routine to read 65C02 memory
  611.     Else
  612.         mov    al,ds:[di]    ; Read the 65C02 memory value
  613.     Endif
  614.     test    dl,al            ; AND accumulator with memory value
  615.     jnz    _addr            ; Jump if the value is non-zero
  616.     or    dh,CPU_Z        ; Zero result, set the zero flag
  617. _addr:
  618.     Endm
  619.  
  620. OpCMP    Macro
  621.     If    _type
  622.         call    Read_Memory    ; Call routine to read 65C02 memory
  623.     Else
  624.         mov    al,ds:[di]    ; Read the 65C02 memory value
  625.     Endif
  626.     cmp    dl,al            ; Compare accumulator with memory
  627.     cmc                ; Toggle carry to the correct state
  628.     Flgnzc                ; Update the 65C02 processor flags
  629.     Endm
  630.  
  631. OpCPX    Macro
  632.     If    _type
  633.         call    Read_Memory    ; Call routine to read 65C02 memory
  634.     Else
  635.         mov    al,ds:[di]    ; Read the 65C02 memory value
  636.     Endif
  637.     cmp    ch,al            ; Compare X index register with memory
  638.     cmc                ; Toggle carry to the correct state
  639.     Flgnzc                ; Update the 65C02 processor flags
  640.     Endm
  641.  
  642. OpCPY    Macro
  643.     If    _type
  644.         call    Read_Memory    ; Call routine to read 65C02 memory
  645.     Else
  646.         mov    al,ds:[di]    ; Read the 65C02 memory value
  647.     Endif
  648.     cmp    cl,al            ; Compare Y index register with memory
  649.     cmc                ; Toggle carry to the correct state
  650.     Flgnzc                ; Update the 65C02 processor flags
  651.     Endm
  652.  
  653. OpDEC    Macro
  654.     If    _type
  655.         call    Read_Memory    ; Call routine to read 65C02 memory
  656.     Else
  657.         mov    al,ds:[di]    ; Read the 65C02 memory value
  658.     Endif
  659.     dec    al            ; Decrement the memory location
  660.     mov    bp,ax            ; Save the memory location value
  661.     Flgnz                ; Update the 65C02 processor flags
  662.     mov    ax,bp            ; Restore the memory location value
  663.     If    _type
  664.         call    Write_Memory    ; Call routine to write 65C02 memory
  665.     Else
  666.         mov    ds:[di],al    ; Write the 65C02 memory value
  667.     Endif
  668.     Endm
  669.  
  670. OpEOR    Macro
  671.     If    _type
  672.         call    Read_Memory    ; Call routine to read 65C02 memory
  673.     Else
  674.         mov    al,ds:[di]    ; Read the 65C02 memory value
  675.     Endif
  676.     xor    dl,al            ; Exclusive-OR accumulator with memory
  677.     Flgnz                ; Update the 65C02 processor flags
  678.     Endm
  679.  
  680. OpINC    Macro
  681.     If    _type
  682.         call    Read_Memory    ; Call routine to read 65C02 memory
  683.     Else
  684.         mov    al,ds:[di]    ; Read the 65C02 memory value
  685.     Endif
  686.     inc    al            ; Increment the memory location
  687.     mov    bp,ax            ; Save the memory location value
  688.     Flgnz                ; Update the 65C02 processor flags
  689.     mov    ax,bp            ; Restore the memory location value
  690.     If    _type
  691.         call    Write_Memory    ; Call routine to write 65C02 memory
  692.     Else
  693.         mov    ds:[di],al    ; Write the 65C02 memory value
  694.     Endif
  695.     Endm
  696.  
  697. OpJMP    Macro
  698.     mov    si,di            ; Update the program counter
  699.     Endm
  700.  
  701. OpJSR    Macro
  702.     mov    ax,si            ; Get the current program counter
  703.     dec    ax            ; Point to last instruction byte
  704.     Push_16             ; Save the return address on the stack
  705.     mov    si,di            ; Update the program counter
  706.     Endm
  707.  
  708. OpLDA    Macro
  709.     If    _type
  710.         call    Read_Memory    ; Call routine to read 65C02 memory
  711.     Else
  712.         mov    al,ds:[di]    ; Read the 65C02 memory value
  713.     Endif
  714.     mov    dl,al            ; Load accumulator from memory
  715.     or    dl,dl            ; Set the status flags correctly
  716.     Flgnz                ; Update the 65C02 processor flags
  717.     Endm
  718.  
  719. OpLDX    Macro
  720.     If    _type
  721.         call    Read_Memory    ; Call routine to read 65C02 memory
  722.     Else
  723.         mov    al,ds:[di]    ; Read the 65C02 memory value
  724.     Endif
  725.     mov    ch,al            ; Load X index register from memory
  726.     or    ch,ch            ; Set the status flags correctly
  727.     Flgnz                ; Update the 65C02 processor flags
  728.     Endm
  729.  
  730. OpLDY    Macro
  731.     If    _type
  732.         call    Read_Memory    ; Call routine to read 65C02 memory
  733.     Else
  734.         mov    al,ds:[di]    ; Read the 65C02 memory value
  735.     Endif
  736.     mov    cl,al            ; Load Y index register from memory
  737.     or    cl,cl            ; Set the status flags correctly
  738.     Flgnz                ; Update the 65C02 processor flags
  739.     Endm
  740.  
  741. OpLSR    Macro
  742.     If    _type
  743.         call    Read_Memory    ; Call routine to read 65C02 memory
  744.     Else
  745.         mov    al,ds:[di]    ; Read the 65C02 memory value
  746.     Endif
  747.     shr    al,1            ; Shift the memory location right
  748.     mov    bp,ax            ; Save the memory location value
  749.     Flgnzc                ; Update the 65C02 processor flags
  750.     mov    ax,bp            ; Restore the memory location value
  751.     If    _type
  752.         call    Write_Memory    ; Call routine to write 65C02 memory
  753.     Else
  754.         mov    ds:[di],al    ; Write the 65C02 memory value
  755.     Endif
  756.     Endm
  757.  
  758. OpORA    Macro
  759.     If    _type
  760.         call    Read_Memory    ; Call routine to read 65C02 memory
  761.     Else
  762.         mov    al,ds:[di]    ; Read the 65C02 memory value
  763.     Endif
  764.     or    dl,al            ; OR accumulator with memory
  765.     Flgnz                ; Update the 65C02 processor flags
  766.     Endm
  767.  
  768. OpROL    Macro
  769.     If    _type
  770.         call    Read_Memory    ; Call routine to read 65C02 memory
  771.     Else
  772.         mov    al,ds:[di]    ; Read the 65C02 memory value
  773.     Endif
  774.     mov    ah,dh            ; Copy 65C02 flags into AH register
  775.     shr    ah,1            ; Shift 65C02 carry into real carry
  776.     rcl    al,1            ; Rotate the memory location left
  777.     rcr    ah,1            ; Save carry result in AH register
  778.     If    _type
  779.         call    Write_Memory    ; Call routine to write 65C02 memory
  780.     Else
  781.         mov    ds:[di],al    ; Write the 65C02 memory value
  782.     Endif
  783.     or    al,al            ; Set the n and z flags correctly
  784.     rcl    ah,1            ; Restore the carry result
  785.     Flgnzc                ; Update the 65C02 processor flags
  786.     Endm
  787.  
  788. OpROR    Macro
  789.     If    _type
  790.         call    Read_Memory    ; Call routine to read 65C02 memory
  791.     Else
  792.         mov    al,ds:[di]    ; Read the 65C02 memory value
  793.     Endif
  794.     mov    ah,dh            ; Copy 65C02 flags into AH register
  795.     shr    ah,1            ; Shift 65C02 carry into real carry
  796.     rcr    al,1            ; Rotate the memory location right
  797.     rcr    ah,1            ; Save carry result in AH register
  798.     If    _type
  799.         call    Write_Memory    ; Call routine to write 65C02 memory
  800.     Else
  801.         mov    ds:[di],al    ; Write the 65C02 memory value
  802.     Endif
  803.     or    al,al            ; Set the n and z flags correctly
  804.     rcl    ah,1            ; Restore the carry result
  805.     Flgnzc                ; Update the 65C02 processor flags
  806.     Endm
  807.  
  808. OpSBCb    Macro
  809.     If    _type
  810.         call    Read_Memory    ; Call routine to read 65C02 memory
  811.     Else
  812.         mov    al,ds:[di]    ; Read the 65C02 memory value
  813.     Endif
  814.     mov    ah,dh            ; Copy 65C02 flags into AH register
  815.     shr    ah,1            ; Shift 65C02 carry into real carry
  816.     cmc                ; Invert carry to correct state
  817.     sbb    dl,al            ; Subtract from accumulator with borrow
  818.     cmc                ; Invert carry back to correct state
  819.     Flgnvzc             ; Update the 65C02 processor flags
  820.     Endm
  821.  
  822. OpSBCd    Macro
  823.     If    _type
  824.         call    Read_Memory    ; Call routine to read 65C02 memory
  825.     Else
  826.         mov    al,ds:[di]    ; Read the 65C02 memory value
  827.     Endif
  828.     mov    ah,dh            ; Copy 65C02 flags into AH register
  829.     shr    ah,1            ; Shift 65C02 carry into real carry
  830.     cmc                ; Invert carry to correct state
  831.     xchg    al,dl            ; Get the current accumulator value
  832.     sbb    al,dl            ; Subtract from accumulator with borrow
  833.     das                ; Do the adjust for decimal mode
  834.     mov    dl,al            ; Update the accumulator value
  835.     cmc                ; Invert carry to correct state
  836.     Flgnvzc             ; Update the 65C02 processor flags
  837.     Endm
  838.  
  839. OpSTA    Macro
  840.     mov    al,dl            ; Store the accumulator in memory
  841.     If    _type
  842.         call    Write_Memory    ; Call routine to write 65C02 memory
  843.     Else
  844.         mov    ds:[di],al    ; Write the 65C02 memory value
  845.     Endif
  846.     Endm
  847.  
  848. OpSTX    Macro
  849.     mov    al,ch            ; Store X index register in memory
  850.     If    _type
  851.         call    Write_Memory    ; Call routine to write 65C02 memory
  852.     Else
  853.         mov    ds:[di],al    ; Write the 65C02 memory value
  854.     Endif
  855.     Endm
  856.  
  857. OpSTY    Macro
  858.     mov    al,cl            ; Store Y index register in memory
  859.     If    _type
  860.         call    Write_Memory    ; Call routine to write 65C02 memory
  861.     Else
  862.         mov    ds:[di],al    ; Write the 65C02 memory value
  863.     Endif
  864.     Endm
  865.  
  866. OpSTZ    Macro
  867.     xor    al,al            ; Store zero in memory
  868.     If    _type
  869.         call    Write_Memory    ; Call routine to write 65C02 memory
  870.     Else
  871.         mov    ds:[di],al    ; Write the 65C02 memory value
  872.     Endif
  873.     Endm
  874.  
  875. OpTRB    Macro
  876.     Local    _addr
  877.     If    _type
  878.         call    Read_Memory    ; Call routine to read 65C02 memory
  879.     Else
  880.         mov    al,ds:[di]    ; Read the 65C02 memory value
  881.     Endif
  882.     and    dh,Not CPU_Z        ; Clear the z flag
  883.     mov    ah,dl            ; Get a copy of the accumulator
  884.     not    ah            ; Invert the accumulator value
  885.     and    al,ah            ; Mask off the desired memory bits
  886.     If    _type
  887.         call    Write_Memory    ; Call routine to write 65C02 memory
  888.     Else
  889.         mov    ds:[di],al    ; Write the 65C02 memory value
  890.     Endif
  891.     not    ah            ; Restore the accumulator value
  892.     and    ah,al            ; AND accumulator with memory
  893.     jnz    _addr            ; Jump if the result is non-zero
  894.     or    dh,CPU_Z        ; Zero result, set the z flag
  895. _addr:
  896.     Endm
  897.  
  898. OpTSB    macro
  899.     Local    _addr
  900.     If    _type
  901.         call    Read_Memory    ; Call routine to read 65C02 memory
  902.     Else
  903.         mov    al,ds:[di]    ; Read the 65C02 memory value
  904.     Endif
  905.     and    dh,Not CPU_Z        ; Clear the z flag
  906.     mov    ah,dl            ; Get a copy of the accumulator
  907.     or    al,ah            ; Set the desired memory bits
  908.     If    _type
  909.         call    Write_Memory    ; Call routine to write 65C02 memory
  910.     Else
  911.         mov    ds:[di],al    ; Write the 65C02 memory value
  912.     Endif
  913.     and    ah,al            ; AND accumulator with memory
  914.     jnz    _addr            ; Jump if the result is non-zero
  915.     or    dh,CPU_Z        ; Zero result, set the z flag
  916. _addr:
  917.     Endm
  918.     .List
  919.