Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.86 KB | None | 0 0
  1. ; Adapted for Z80 Spectrum syntax, assembled with pasmo
  2. ; Z80 disassembly routine in Z80
  3.  
  4. ORG 50000
  5.  
  6. LD A,2 ; upper screen
  7. CALL 5633 ; open channel
  8.  
  9. LD DE,0 ; first address to disassembly
  10. LD BC,30 ; number of lines
  11. CALL _disz80
  12.  
  13. ; need to return to lower screen
  14. LD A,1 ; lower screen
  15. CALL 5633 ; open channel
  16.  
  17. CALL $15DE ; WAIT-KEY1
  18.  
  19. RET
  20.  
  21.  
  22. ; This code is been found in a ZX Spectrum tool called UTILITY3 v1.3
  23.  
  24.  
  25. _disz80:
  26. push ix
  27.  
  28. dizloop:
  29. push bc
  30. call DISASM
  31. pop bc
  32. ld a,13
  33. call CHROP
  34. dec bc
  35. ld a,b
  36. or c
  37. jr nz,dizloop
  38. ld h,d
  39. ld l,e
  40. pop ix
  41. ret
  42.  
  43. ; ====================
  44. ; DIS-Z80 was published in the SUBSET column of Personal Computer World 1987.
  45. ; The routine disassembles a single Z80 instruction at address DE.
  46. ; It is required to be followed by a routine called CHROP that outputs a
  47. ; single ASCII character.
  48. ; It was originally developed for CP/M on an Amstrad CPC128.
  49.  
  50. ; The original ORG was $0100. I have added $5000 to all addresses.
  51. ; The stated aim was to write a Z80 disassembly routine in as short a space
  52. ; as possible and, at just over 1K (1090 bytes), it is a rather incredible
  53. ; program.
  54.  
  55. ; The SUBSET editor David Barrow was able to trim only one byte from John
  56. ; Kerr's compact code. I've forgotten where so there's a challenge.
  57. ; ====================
  58.  
  59. ; STRUCTURAL CONCEPTS
  60. ; DATA
  61. ;
  62. ; Disassembled line:
  63. ; field 1: instruction 1st byte location (5 cols).
  64. ; field 2: instruction bytes (12 cols).
  65. ; field 3: mnemonic (5 cols).
  66. ; field 4: operand(s) (13 cols).
  67. ;
  68. ; Location address : ASCII hex (4 digits).
  69. ; Instruction bytes : ASCII hex (2 digits sequence).
  70. ; Operand data & : ASCII hex with appended "H" if >9,
  71. ; addresses : and preceeding "0" if 1st digit >9.
  72. ; Operand offsets : signed decimal, linked "+" or "-".
  73.  
  74. ; PROGRAM DETAILS
  75. ;
  76. ; INPUT DE addresses 1st byte of instruction to disassemble.
  77. ; OUTPUT 35 character disassembled line to uotput device.
  78. ; STATE CHANGES DE updated to address 1st byte of next instruction.
  79. ; AF BC HL changed.
  80. ; I/O ERRORS None.
  81. ; OPTIMISATION Not given.
  82. ; INTERRUPT EFFECT May be interrupted and re-entered.
  83. ; LOCATION NEEDS Not specific. Not relocatable. PROMable.
  84. ; (Listing in this datasheet is assembled at 0100H)
  85. ; PROGRAM BYTES 695: code 206 + referenced tables:-
  86. ; GROUP2 (27), GROUP1 (168), GROUP3 (86),
  87. ; MONICS (208).
  88. ; STACK BYTES 46 maximum.
  89. ; CLOCK CYCLES Not given.
  90.  
  91.  
  92. DISASM: CALL ADRSP ; Output the source pointer.
  93.  
  94. LD BC,$0900 ; Create an 18-byte output
  95. LD HL,$2020 ; buffer in the stack area.
  96.  
  97. BUFFER: PUSH HL ; Buffer initially contains
  98. DJNZ BUFFER ; 18 ASCII spaces (20H).
  99.  
  100. LD H,B ; Copy SP into HL, so the
  101. LD L,C ; first byte of the output
  102. ADD HL,SP ; buffer is addressed by HL.
  103.  
  104. PUSH BC ; Save original IX and
  105. EX (SP),IX ; initialize to zero.
  106. PUSH BC ; Initialize temp storage
  107. PUSH BC ; (workspace) to all zeros.
  108. ADD IX,SP ; Point IX to workspace.
  109.  
  110. PUSH HL ; Save buffer pointer; point
  111. LD HL,GROUP3 ; to "ED" instruction group.
  112.  
  113. TRYNDX: CALL FETCH ; Fetch a byte of code.
  114.  
  115. LD B,C ; First check whether this
  116. CP $ED ; is an "ED" instruction.
  117. JR Z,CONFLG ; Yes; clear the index flag.
  118.  
  119. INC B ; Ready to set flag to "1"
  120. CP $DD ; if the byte is 0DDH (an
  121. JR Z,CONFLG ; instruction using IX).
  122.  
  123. INC B ; Ready to set flag to "2"
  124. CP $FD ; if the byte is 0FDH (an
  125. JR NZ,NOTNDX ; instruction using IY).
  126.  
  127. CONFLG: LD (IX+1),B ; Condition the index flag.
  128. INC B ; Repeat index tests if the
  129. DJNZ TRYNDX ; pre-byte was 0DDH or 0FDH.
  130. JR NXBYTE ; Otherwise continue.
  131.  
  132. NOTNDX: LD C,A ; Save byte; check if index
  133. LD A,(IX+1) ; flag was set (Allows any
  134. OR A ; series of 0DDH and/or OFDH
  135. JR Z,NODISP ; bytes, as per Zilog spec).
  136.  
  137. LD A,C ; If so, check for presence
  138. CP $CB ; of any displacement.
  139. JR Z,GETDIS ; 0CBH needs a displacement.
  140.  
  141. AND $44 ; A displacement is required
  142. CP 4 ; if opcode has bit 2 set
  143. JR Z,GETDIS ; and bit 6 reset.
  144.  
  145. LD A,C ; A displacemnet is required
  146. AND $C0 ; if opcode has bit 6 set
  147. CP $40 ; and bit 7 reset.
  148. JR NZ,NODISP
  149.  
  150. GETDIS: CALL FETCH ; Get displacement if needed
  151. LD (IX+2),A ; and save it in workspace.
  152.  
  153. NODISP: LD HL,GROUP1 ; "Main" instruction gorup.
  154. LD A,C ; Recover opcode & check
  155. CP $CB ; for OCBH ("bit" group).
  156. JR NZ,NEWMSK ; No; start the search.
  157.  
  158. LD HL,GROUP2 ; Yes; point to "CB" group.
  159.  
  160. NXBYTE: CALL FETCH ; Fetch the last non-data
  161. LD C,A ; byte and store it in C.
  162.  
  163. NEWMSK: LD A,(HL) ; Fetch a mask from table.
  164. OR A ; Mask value of 0 indicates
  165. JR Z,TABEND ; end of table; quit search.
  166.  
  167. AND C ; Otherwise mask the opcode
  168. INC HL ; and address the mode byte.
  169.  
  170. NEWMOD: LD B,(HL) ; Fetch the mode byte in B.
  171. INC HL ; Point to the match byte.
  172. INC B ; Test if the mode is 0FFH
  173. JR Z,NEWMSK ; and if so, get a new mak.
  174.  
  175. TRYMAT: CP (HL) ; Is the masked opcode
  176. INC HL ; equal to the match byte?
  177. JR Z,GETNDX ; Stop searching if it is.
  178.  
  179. BIT 7,(HL) ; index byte bit 7 is set if
  180. INC HL ; address mode changes.
  181. JR Z,TRYMAT ; No change; try next match.
  182.  
  183. JR NEWMOD ; Change; get a new mode.
  184.  
  185. GETNDX: LD A,(HL) ; Matched: fetch mnemonic
  186. AND $7F ; index, mask bit 7, and
  187. DEC B ; restore the mode byte.
  188.  
  189. TABEND: POP HL ; Save the source pointer
  190. PUSH DE ; below the output buffer
  191. PUSH HL ; pointer on stack.
  192.  
  193. EX DE,HL ; Point HL to start of the
  194. LD HL,MONICS ; mnemonics table.
  195. CALL XTRACT ; Copy mnemonic to buffer.
  196.  
  197. POP HL ; Restore output pointer
  198. LD DE,5 ; and adjust to align
  199. ADD HL,DE ; any operands present.
  200. POP DE ; Restore source pointer.
  201.  
  202. LD A,B ; Test high-order B to see
  203. AND $F0 ; if any "first" operand
  204. JR Z,SECOND ; is present.
  205.  
  206. RRA ; Yes; move the operand
  207. RRA ; index into the lower
  208. RRA ; half of A.
  209. RRA ; Then save
  210. PUSH BC ; operand and opcode.
  211.  
  212. LD B,A ; Operand index in B.
  213. LD A,C ; Restore opcode to A.
  214. CALL OPRND1 ; Process the operand.
  215.  
  216. POP BC ; Restore the operand byte
  217. LD A,B ; and opcode; test
  218. AND $0F ; low-order B for any
  219. JR Z,OPDONE ; "second" operand.
  220.  
  221. LD (HL),44 ; Opearnd index in B.
  222. INC HL ; Restore opcode to A.
  223.  
  224. SECOND: LD A,B ; Check for the presence
  225. AND $0F ; of a "second" operand.
  226.  
  227. LD B,A ; Operand index in B.
  228. LD A,C ; Restore opcode to A.
  229. CALL NZ,OPRND2 ; Process any operand.
  230.  
  231. OPDONE: LD A,3 ; Check how many bytes
  232. SUB (IX+0) ; have been fetched.
  233.  
  234. POP HL ; Discard workspace.
  235. POP HL
  236. POP IX ; Restore index register.
  237.  
  238. JR C,OUTEXT ; 4 or more bytes fetched.
  239.  
  240. INC A ; Less than four bytes
  241. LD B,A ; fetched; so output
  242. ADD A,B ; enough spaces to
  243. ADD A,B ; align the mnemonics.
  244. LD B,A
  245.  
  246. SPACES: LD A,$20 ; Output spaces
  247. CALL CHROP ; to start of
  248. DJNZ SPACES ; mnemonic field.
  249.  
  250. OUTEXT: LD B,18 ; Set buffer byte count.
  251.  
  252. PUTOUT: DEC SP ; Copy stored text, byte
  253. POP HL ; at a time, from output
  254. LD A,H ; buffer on stack to
  255. CALL CHROP ; the output channel.
  256. DJNZ PUTOUT
  257.  
  258. RET ; Instruction disassembled.
  259.  
  260. ;***********************
  261.  
  262. GROUP2: defb $C0,$36,$40
  263. defb $04,$80,$2D,$C0,$BE
  264. defb $FF,$F8,$06,$00,$33
  265. defb $08,$38,$10,$35,$18
  266. defb $3A,$20,$3F,$28,$40
  267. defb $30,$00,$38,$C1
  268.  
  269.  
  270. GROUP1: defb $FF,$00,$00
  271. defb $24,$07,$32,$0F,$37
  272. defb $17,$31,$1F,$36,$27
  273. defb $0D,$2F,$0B,$37,$3D
  274. defb $3F,$06,$76,$14,$C9
  275. defb $30,$D9,$12,$F3,$0F
  276. defb $FB,$91,$72,$C6,$02
  277. defb $CE,$01,$DE,$BC,$02
  278. defb $D6,$42,$E6,$03,$EE
  279. defb $43,$F6,$25,$FE,$8C
  280. defb $04,$08,$93,$01,$10
  281. defb $10,$18,$9D,$AF,$22
  282. defb $A2,$FA,$2A,$A2,$A7
  283. defb $32,$A2,$7A,$3A,$A2
  284. defb $03,$C3,$1C,$CD,$85
  285. defb $97,$D3,$AA,$79,$DB
  286. defb $9B,$5F,$E3,$93,$0E
  287. defb $E9,$9C,$05,$EB,$93
  288. defb $DF,$F9,$A2,$FF,$C0
  289. defb $B6,$40,$A2,$FF,$F8
  290. defb $76,$80,$02,$88,$01
  291. defb $98,$BC,$06,$90,$42
  292. defb $A0,$03,$A8,$43,$B0
  293. defb $25,$B8,$8C,$FF,$C7
  294. defb $0B,$04,$16,$05,$8E
  295. defb $B2,$06,$A2,$20,$C0
  296. defb $B0,$23,$C2,$1C,$C4
  297. defb $85,$10,$C7,$BB,$FF
  298. defb $CF,$D3,$01,$A2,$0D
  299. defb $03,$16,$0B,$8E,$FD
  300. defb $09,$82,$60,$C1,$2B
  301. defb $C5,$AC,$FF,$E7,$21
  302. defb $20,$9D,$FF,$EF,$E7
  303. defb $02,$A2,$7E,$0A,$A2
  304.  
  305.  
  306. GROUP3: defb $FF,$00,$44
  307. defb $23,$45,$2F,$4D,$2E
  308. defb $4E,$00,$67,$39,$6F
  309. defb $34,$70,$00,$71,$00
  310. defb $A0,$21,$A1,$0A,$A2
  311. defb $1A,$A3,$29,$A8,$1F
  312. defb $A9,$08,$AA,$18,$AB
  313. defb $28,$B0,$20,$B1,$09
  314. defb $B2,$19,$B3,$27,$B8
  315. defb $1E,$B9,$07,$BA,$17
  316. defb $BB,$A6,$FF,$C7,$B8
  317. defb $40,$9B,$8B,$41,$AA
  318. defb $FF,$CF,$FD,$42,$3C
  319. defb $4A,$81,$AD,$43,$A2
  320. defb $DA,$4B,$A2,$FF,$E7
  321. defb $40,$46,$95,$FF,$F7
  322. defb $C7,$47,$A2,$7C,$57
  323. defb $A2,$FF,$00
  324.  
  325. ;_______________
  326.  
  327. MONICS: defb $BF
  328. defb 'A','D','C'+$80 ; ADC
  329. defb 'A','D','D'+$80 ; ADD
  330. defb 'A','N','D'+$80 ; AND
  331. defb 'B','I','T'+$80 ; BIT
  332. defb 'C','A','L','L'+$80 ; CALL
  333. defb 'C','C','F'+$80 ; CCF
  334. defb 'C','P','D','R'+$80 ; CPDR
  335. defb 'C','P','D'+$80 ; CPD
  336. defb 'C','P','I','R'+$80 ; CPIR
  337. defb 'C','P','I'+$80 ; CPI
  338. defb 'C','P','L'+$80 ; CPL
  339. defb 'C','P'+$80 ; CP
  340. defb 'D','A','A'+$80 ; DAA
  341. defb 'D','E','C'+$80 ; DEC
  342. defb 'D','I'+$80 ; DI
  343. defb 'D','J','N','Z'+$80 ; DJNZ
  344. defb 'E','I'+$80 ; EI
  345. defb 'E','X','X'+$80 ; EXX
  346. defb 'E','X'+$80 ; EX
  347. defb 'H','A','L','T'+$80 ; HALT
  348. defb 'I','M'+$80 ; IM
  349. defb 'I','N','C'+$80 ; INC
  350. defb 'I','N','D','R'+$80 ; INDR
  351. defb 'I','N','D'+$80 ; IND
  352. defb 'I','N','I','R'+$80 ; INIR
  353. defb 'I','N','I'+$80 ; INI
  354. defb 'I','N'+$80 ; IN
  355. defb 'J','P'+$80 ; JP
  356. defb 'J','R'+$80 ; JR
  357. defb 'L','D','D','R'+$80 ; LDDR
  358. defb 'L','D','D'+$80 ; LDD
  359. defb 'L','D','I','R'+$80 ; LDIR
  360. defb 'L','D','I'+$80 ; LDI
  361. defb 'L','D'+$80 ; LD
  362. defb 'N','E','G'+$80 ; NEG
  363. defb 'N','O','P'+$80 ; NOP
  364. defb 'O','R'+$80 ; OR
  365. defb 'O','T','D','R'+$80 ; OTDR
  366. defb 'O','T','I','R'+$80 ; OTIR
  367. defb 'O','U','T','D'+$80 ; OUTD
  368. defb 'O','U','T','I'+$80 ; OUTI
  369. defb 'O','U','T'+$80 ; OUT
  370. defb 'P','O','P'+$80 ; POP
  371. defb 'P','U','S','H'+$80 ; PUSH
  372. defb 'R','E','S'+$80 ; RES
  373. defb 'R','E','T','I'+$80 ; RETI
  374. defb 'R','E','T','N'+$80 ; RETN
  375. defb 'R','E','T'+$80 ; RET
  376. defb 'R','L','A'+$80 ; RLA
  377. defb 'R','L','C','A'+$80 ; RLCA
  378. defb 'R','L','C'+$80 ; RLC
  379. defb 'R','L','D'+$80 ; RLD
  380. defb 'R','L'+$80 ; RL
  381. defb 'R','R','A'+$80 ; RRA
  382. defb 'R','R','C','A'+$80 ; RA
  383. defb 'R','R','C'+$80 ; RRC
  384. defb 'R','R','D'+$80 ; RRD
  385. defb 'R','R'+$80 ; RR
  386. defb 'R','S','T'+$80 ; RST
  387. defb 'S','B','C'+$80 ; SBC
  388. defb 'S','C','F'+$80 ; SCF
  389. defb 'S','E','T'+$80 ; SET
  390. defb 'S','L','A'+$80 ; SLA
  391. defb 'S','R','A'+$80 ; SRA
  392. defb 'S','R','L'+$80 ; SRL
  393. defb 'S','U','B'+$80 ; SUB
  394. defb 'X','O','R'+$80 ; XOR
  395.  
  396.  
  397. ; OPRNDZ Operand Disassembler. To disassembler and output a valid
  398. ; Z80 machine code operand.
  399. ; OPRND1 Entry point for certain modes (see DATA)
  400. ; OPRND2 Entry point for certain modes (see DATA)
  401.  
  402. ; STRUCTURAL CONCEPTS
  403. ; DATA
  404. ;
  405. ; Operand: Standard Z80 assembler format.
  406. ; The operand mode is determined by an input
  407. ; index (1 - 15) and by point of entry:-
  408. ;
  409. ; Index OPRND1 OPRND2
  410. ; ------------------------------------------------------
  411. ; 1 RST address Relative address
  412. ; 2 Condition Immediate byte
  413. ; 3 Bit number Immediate word
  414. ; 4 Interrupt mode AF,AF'
  415. ; 5 (SP) DE,HL
  416. ; 6 Register pair 8-bit source
  417. ; ------------------------------------------------------
  418. ; 7 A
  419. ; 8 (C)
  420. ; 9 (port number)
  421. ; A (Absolute address)
  422. ; B 8-bit destination
  423. ; C I or R
  424. ; D 16-bit register
  425. ; E Address in 16-bit register
  426. ; F Index register
  427. ;
  428. ; PROGRAM DETAILS
  429. ; INPUT
  430. ; A = opcode.
  431. ; B = operand index.
  432. ; DE addresses next instruction byte.
  433. ; HL addresses next free byte in output buffer.
  434. ; (IX+0) = no. of instruction bytes fetched.
  435. ; (IX+1) = index register flag (1=IX, 2=IY, else 0).
  436. ; (IX+2) = displacement for any indexed instruction.
  437. ;
  438. ; OUTPUT Operand is in output buffer.
  439. ; DE and HL are updated.
  440. ; STATE CHANGES AF BC are changed.
  441. ; IX IY (IX+0,1,2) are unchanged.
  442. ;*****************
  443.  
  444. OPRND1: DJNZ CONDIT ; First entry point; is mode
  445. RSTADR: AND $38 ; a restart address? If so,
  446. JR DA ; isolate opcode bits 5-3.
  447.  
  448. OPRND2: DJNZ DAT8 ; 2nd entry point; is mode
  449. RELADR: CALL FETCH ; PC relative? If so, fetch
  450. LD C,A ; displacement & extend
  451. RLA ; sign; put full 16-bit
  452. SBC A,A ; signed displacemnet into
  453. LD B,A ; BC.
  454. EX DE,HL ; Move source pointer to HL,
  455. PUSH HL ; save it on stack, compute
  456. ADD HL,BC ; destination address & send
  457. JR DHL ; to the output buffer.
  458.  
  459. CONDIT: RRA ; Opcode bits 2-0 are not
  460. RRA ; needed for any of the
  461. RRA ; following modes (OPRND1).
  462. DJNZ BITNUM ; Is operand a condition?
  463. BIT 4,A ; If so, check whether the
  464. JR NZ,ABS ; address mode is relative
  465. AND 3 ; or absolute. If relative,
  466. ABS: AND 7 ; adjust condition index.
  467. ADD A,$14 ; Index condition in table.
  468. JR PS1 ; Copy it to the output buffer.
  469.  
  470. DAT8: DJNZ DAT16 ; Is operand immediate byte?
  471.  
  472. D8: CALL FETCH ; Fetch a byte.
  473. JR DA ; Send to output buffer.
  474.  
  475. BITNUM: DJNZ INTMOD ; Is operand a bit number?
  476. AND 7 ; Yes; isolate the index.
  477.  
  478. DA: LD C,A ; Move 8-bit data for output
  479. SUB A ; from A into AC (so A=0)
  480. JR DAC ; and send to output buffer.
  481.  
  482. DAT16: DJNZ EXAF ; Is operand an address?
  483. D16: CALL FETCH ; Fetch low-order byte.
  484. LD C,A ; Save it in C.
  485. CALL FETCH ; Fetch high order byte.
  486.  
  487. DAC: EX DE,HL ; Exchange source & output
  488. PUSH HL ; pointers. Save the source
  489. LD H,A ; pointer & copy output data
  490. LD L,C ; from AC into HL.
  491.  
  492. DHL: LD C,$F8 ; Specify hex conversion.
  493. PUSH HL ; Save output for checking.
  494. CALL CONVHL ; Perform ASCII conversion.
  495. POP HL ; retrieve output value.
  496.  
  497. LD BC,$000A ; Check whether the value
  498. OR A ; output was greater than 9.
  499. SBC HL,BC ; Result of test in Cy.
  500.  
  501. POP HL ; Restore source & output
  502. EX DE,HL ; pointers to their originall
  503. RET C ; registers. Exit if output
  504. LD (HL),'H' ; value was 9 or less; else
  505. INC HL ; put "H" (denoting hex)
  506. RET ; after the output & exit.
  507.  
  508. INTMOD: DJNZ STKTOP ; Is operand interrupt mode?
  509. AND 3 ; Index the list of
  510. ADD A,$1C ; interrupt modes (0,1,2)
  511. PS1: JR PS3 ; Copy to output buffer.
  512.  
  513. STKTOP: LD C,$13 ; The constant operand (SP)
  514. DEC B ; is entry number 19 in the
  515. JR Z,PS2 ; RGSTRS table.
  516.  
  517. REG16P: DJNZ COMMON2 ; Is the operand register pair?
  518. RRA ; Isolate the two bits of the
  519. AND 3 ; opcode which determine the
  520. CP 3 ; pair. Is it AF?
  521. JR NZ,RX ; No; go to double register.
  522. DEC A ; Yes, adjust pointer.
  523. JR RNX ; Copy out register name.
  524.  
  525. EXAF: LD C,$0A ; The constant operand
  526. DEC B ; AF,AF' is entry number 10
  527. JR Z,PS2 ; in the RGSTRS table.
  528.  
  529. EXDE: INC C ; The constant operand DE,HL
  530. DEC B ; is entry number 11 in the
  531. JR Z,PS2 ; RGSTRS table.
  532.  
  533. REG8S: DJNZ ACCUM ; Is operand 8-bit source?
  534.  
  535. R8: AND 7 ; Get register number.
  536. CP 6 ; Is it a memory location?
  537. JR NZ,PS3 ; No; so it's B/C/D/E/H/L/A.
  538. LD (HL),'(' ; Yes; put the left parenthesis
  539. INC HL ; into the output buffer.
  540. CALL REGX ; Copy register HL/IX/IY.
  541. LD A,(IX+2) ; Retrieve offset; check if
  542. OR A ; it is zero. If so, don't
  543. JR Z,RP ; bother to print it.
  544. LD (HL),43 ; Otherwise, put a "+" sign
  545. RLCA ; into the output buffer, but
  546. RRCA ; now test the offset sign.
  547. JR NC,POS ; If negative, change the
  548. LD (HL),45 ; sign to "-" and negate
  549. NEG ; the offset.
  550.  
  551. POS: INC HL ; Update the output pointer.
  552. EX DE,HL ; Exchange pointers, saving
  553. PUSH HL ; source pointer on stack.
  554. LD H,B ; Put the absolute value
  555. LD L,A ; of the offset into HL.
  556. LD C,$FB ; Specify decimal and
  557. CALL CONVHL ; perform ASCII convesion.
  558. POP HL ; Restore pointers to their
  559. EX DE,HL ; original registers.
  560. JR RP ; Go put right parenthesis.
  561.  
  562. ACCUM: RRA ; Opcode bits 2-0 can now
  563. RRA ; be discarded by OPRND2.
  564. RRA
  565.  
  566. COMMON2:
  567. LD C,7 ; OPRND1 and OPRND2 merge.
  568. DEC B ; Accumulator addressing;
  569. JR Z,PS2 ; put "A" to output buffer.
  570.  
  571. PORTC: DEC C ; Constant operand "(C)" is
  572. DJNZ IDAT8 ; entry number 6 in RGSTRS.
  573. PS2: LD A,C ; Copy string number into A.
  574. PS3: JR PS4 ; Go copy out the string.
  575.  
  576. IDAT8: DJNZ IDAT16 ; Is operand a constant port
  577. LD (HL),'(' ; number? If so, that's just
  578. INC HL ; like an immediate byte but
  579. CALL D8 ; inside brackets.
  580. JR RP ; Close the brackets.
  581.  
  582. IDAT16: DJNZ REG8 ; Is operand an address for
  583. LD (HL),'(' ; data? That's just like a
  584. INC HL ; CALL or JP address but
  585. CALL D16 ; inside brackets.
  586. JR RP ; Close the brackets.
  587.  
  588. REG8: DEC B ; Use 8-bit source routine
  589. JR Z,R8 ; for an 8-bit destination.
  590.  
  591. IPAREF: DJNZ REG16 ; Is operand I or R?
  592. AND 9 ; Yes, then copy the correct
  593. JR PS4 ; string from RGSTRS.
  594.  
  595. REG16: RRA ; Is operand a
  596. DJNZ IREG16 ; 16-bit register?
  597.  
  598. R16: AND 3 ; Check for index register.
  599.  
  600. RX: CP 2 ; If it's an index register,
  601. JR Z,REGX ; go use separate routine.
  602.  
  603. RNX: ADD A,$0C ; Not an index register;
  604. JR PS4 ; point ot BC/DE/AF/SP.
  605.  
  606. IREG16: DJNZ REGX ; Is the operand an address
  607. LD (HL),'(' ; contained in a register?
  608. INC HL ; Then just put brackets
  609. CALL R16 ; round the result from R16.
  610.  
  611. RP: LD (HL),')' ; Put right parenthesis in
  612. INC HL ; output buffer, update
  613. RET ; pointer, then exit.
  614.  
  615. REGX: LD A,(IX+1) ; Use the index flag to
  616. ADD A,$10 ; select an index register.
  617.  
  618. PS4: EX DE,HL ; Copy a string from RGSTRS.
  619. PUSH HL ; Exchange pointers; save
  620. LD HL,RGSTRS ; source pointer; point HL
  621. CALL XTRACT ; to start of table and
  622. POP HL ; copy out the string. Then
  623. EX DE,HL ; restore pointers to their
  624. RET ; original registers, exit.
  625.  
  626. ;*************
  627.  
  628. RGSTRS: defb 'B' +$80
  629. defb 'C' +$80
  630. defb 'D' +$80
  631. defb 'E' +$80
  632. defb 'H' +$80
  633. defb 'L' +$80
  634. defb '(','C',')' +$80
  635. defb 'A' +$80
  636. defb 'I' +$80
  637. defb 'R' +$80
  638. defb 'A','F',',','A','F','\' +$80
  639. defb 'D','E',',','H','L' +$80
  640. defb 'B','C' +$80
  641. defb 'D','E' +$80
  642. defb 'A','F' +$80
  643. defb 'S','P' +$80
  644. defb 'H','L' +$80
  645. defb 'I','X' +$80
  646. defb 'I','Y' +$80
  647. defb '(','S','P',')' +$80
  648. defb 'N','Z' +$80
  649. defb 'Z' +$80
  650. defb 'N','C' +$80
  651. defb 'C' +$80
  652. defb 'P','O' +$80
  653. defb 'P','E' +$80
  654. defb 'P' +$80
  655. defb 'M' +$80
  656. defb '0' +$80
  657. defb '?' +$80
  658. defb '1' +$80
  659. defb '2' +$80
  660.  
  661. ;********************
  662.  
  663. CONVHL: SUB A
  664.  
  665. CVHL1: PUSH AF
  666. SUB A
  667. LD B,16
  668.  
  669. CVHL2: ADD A,C
  670. JR C,CVHL3
  671. SUB C
  672.  
  673. CVHL3: ADC HL,HL
  674. RLA
  675. DJNZ CVHL2
  676.  
  677. JR NZ,CVHL1
  678.  
  679. CP 10
  680. INC B
  681. JR NC,CVHL1
  682.  
  683. CVHL4: CP 10
  684. SBC A,$69
  685. DAA
  686. LD (DE),A
  687. INC DE
  688. POP AF
  689. JR NZ,CVHL4
  690.  
  691. RET
  692.  
  693. ;****************
  694.  
  695. XTRACT: OR A
  696. JR Z,COPY
  697.  
  698. SKIP: BIT 7,(HL)
  699. INC HL
  700. JR Z,SKIP
  701.  
  702. DEC A
  703. JR NZ,SKIP
  704.  
  705. COPY: LD A,(HL)
  706. RLCA
  707. SRL A
  708. LD (DE),A
  709.  
  710. INC DE
  711. INC HL
  712. JR NC,COPY
  713.  
  714. RET
  715.  
  716. ;*******************
  717.  
  718. FETCH: LD A,(DE)
  719. INC DE
  720. INC (IX+0)
  721. PUSH AF
  722. CALL BYTSP
  723. POP AF
  724. RET
  725.  
  726. ADRSP: LD A,D
  727. CALL BYTOP
  728. LD A,E
  729.  
  730. BYTSP: CALL BYTOP
  731. LD A,$20
  732. JR CHROP
  733.  
  734. BYTOP: PUSH AF
  735. RRA
  736. RRA
  737. RRA
  738. RRA
  739. CALL HEXOP
  740. POP AF
  741.  
  742. HEXOP: AND $0F
  743. CP 10
  744. SBC A,$69
  745. DAA
  746.  
  747. ; -----------------------------------
  748. ;
  749. ; End of John Kerr's DIS-Z80 routine.
  750. ;
  751. ; The next routine outputs a character.
  752. ;
  753. ; -------------------------------------
  754.  
  755. CHROP: PUSH HL
  756. PUSH DE
  757. PUSH BC
  758.  
  759. push AF ; parameter passing
  760. RST 16
  761. pop AF
  762.  
  763. POP BC
  764. POP DE
  765. POP HL
  766.  
  767. RET
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement