├── src ├── z8e.ws ├── z8e.rel ├── z8e.sym ├── buildm.sub ├── Makefile ├── buildz.sub ├── buildc.sub ├── config.inc ├── z8e1.inc ├── z8e2.inc ├── 18e1.inc ├── 18e2.inc ├── z8e42.txt ├── z8e41.txt ├── terminal.inc ├── vt52.tty ├── ansi.tty ├── d8227.tty └── adm3a.tty ├── bin ├── 18e1.com ├── 18e2.com ├── z8e1.com └── z8e2.com └── README.md /src/z8e.ws: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/src/z8e.ws -------------------------------------------------------------------------------- /bin/18e1.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/bin/18e1.com -------------------------------------------------------------------------------- /bin/18e2.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/bin/18e2.com -------------------------------------------------------------------------------- /bin/z8e1.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/bin/z8e1.com -------------------------------------------------------------------------------- /bin/z8e2.com: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/bin/z8e2.com -------------------------------------------------------------------------------- /src/z8e.rel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hperaza/Z8E/HEAD/src/z8e.rel -------------------------------------------------------------------------------- /src/z8e.sym: -------------------------------------------------------------------------------- 1 | 24FD ATTYI 250D ATTYO 24F0 ATTYQ 0105 COMASK 2 | 0103 HEIGHT 0A77 INIT 24E4 MCLS 2E50 MCLSTR 3 | 2495 MTTYI 24A1 MTTYO 248E MTTYQ 24A7 MXYCP 4 | 0104 RSTVEC 5 | 6 | TTYQ 0105 COMASK 7 | 0103 HEIGHT 0A77 INIT 24E4 MCLS 2E50 MCLSTR 8 | 2495 MTTYI 24A1 MTTYO 248E MTTYQ 24 -------------------------------------------------------------------------------- /src/buildm.sub: -------------------------------------------------------------------------------- 1 | pip config.inc=18e1.inc 2 | m80 =z8e.z80 3 | l80 z8e,z8e/n/y/e 4 | erase 18e1.com 5 | rename 18e1.com=z8e.com 6 | 7 | pip config.inc=18e2.inc 8 | m80 =z8e.z80 9 | l80 z8e,z8e/n/y/e 10 | erase 18e2.com 11 | rename 18e2.com=z8e.com 12 | 13 | pip config.inc=z8e1.inc 14 | m80 =z8e.z80 15 | l80 z8e,z8e/n/y/e 16 | erase z8e1.com 17 | rename z8e1.com=z8e.com 18 | 19 | pip config.inc=z8e2.inc 20 | m80 =z8e.z80 21 | l80 z8e,z8e/n/y/e 22 | erase z8e2.com 23 | rename z8e2.com=z8e.com 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Z8E Debugger 2 | 3 | Z8E is a full-screen symbolic debugger for the Z80 CPU, known from the 4 | former CP/M User Groups. 5 | 6 | Main features: 7 | 8 | * Screen-oriented. 9 | * Animated debugging. 10 | * Z80 and Z180 versions. 11 | * Auxiliary terminal support. 12 | 13 | The current version is 4.2, which fixes an obscure bug that affected reading 14 | of symbol table files that ended exactly at a record boundary without an 15 | explicit end-of-file character (a valid CP/M condition). 16 | 17 | More details [here](http://p112.sourceforge.net/index.php?z8e). 18 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | .PREFIX: 2 | .PREFIX: .z80 .rel 3 | 4 | SRCS = z8e.z80 5 | 6 | all: z8e.z80 7 | cp 18e1.inc config.inc 8 | zxcc m80 -"=z8e.z80" 9 | zxcc l80 -"z8e,z8e/n/y/e" 10 | mv z8e.com 18e1.com 11 | cp 18e2.inc config.inc 12 | zxcc m80 -"=z8e.z80" 13 | zxcc l80 -"z8e,z8e/n/y/e" 14 | mv z8e.com 18e2.com 15 | cp z8e1.inc config.inc 16 | zxcc m80 -"=z8e.z80" 17 | zxcc l80 -"z8e,z8e/n/y/e" 18 | mv z8e.com z8e1.com 19 | cp z8e2.inc config.inc 20 | zxcc m80 -"=z8e.z80" 21 | zxcc l80 -"z8e,z8e/n/y/e" 22 | mv z8e.com z8e2.com 23 | 24 | clean: 25 | rm -f *.com *.rel *.prn *.sym core *~ 26 | -------------------------------------------------------------------------------- /src/buildz.sub: -------------------------------------------------------------------------------- 1 | ; A CP/M Plus script to build all four configurations of Z8E using the SLR 2 | ; assembler Z80ASM. This script is easily adapted to work on CP/M 2.2 or 3 | ; to use any of the other SLR assemblers which recognise Zilog mnemonics 4 | ; (e.g. SLR180, Z80ASMP) 5 | 6 | pip config.inc=18e1.inc 7 | z80asm z8e/a 8 | erase 18e1.com 9 | rename 18e1.com=z8e.com 10 | 11 | pip config.inc=18e2.inc 12 | z80asm z8e/a 13 | erase 18e2.com 14 | rename 18e2.com=z8e.com 15 | 16 | pip config.inc=z8e1.inc 17 | z80asm z8e/a 18 | erase z8e1.com 19 | rename z8e1.com=z8e.com 20 | 21 | pip config.inc=z8e2.inc 22 | z80asm z8e/a 23 | erase z8e2.com 24 | rename z8e2.com=z8e.com 25 | -------------------------------------------------------------------------------- /src/buildc.sub: -------------------------------------------------------------------------------- 1 | ; CP/M Plus script to build Z8E variants using Cromemco assembler and linker. 2 | ; The assembler and linker are asssumed to be named ZASMB.COM and LINKB.COM 3 | ; respectively. This is to avoid naming conflicts with other tools. 4 | ; The Cromemco linker is a clone of Microsoft's LINK-80 (L80.COM) so that can 5 | ; be used of LINKB.COM (as in this script).. 6 | ; 7 | ; Z8E.Z80 must be edited to enable ZASMB. 8 | 9 | pip config.inc=18e1.inc 10 | zasm z8e 11 | l80 z8e,18e1/n/e 12 | 13 | pip config.inc=18e2.inc 14 | zasm z8e 15 | l80 z8e,18e2/n/e 16 | 17 | pip config.inc=z8e1.inc 18 | zasm z8e 19 | l80 z8e,z8e1/n/e 20 | 21 | pip config.inc=z8e2.inc 22 | zasm z8e 23 | l80 z8e,z8e2/n/e 24 | -------------------------------------------------------------------------------- /src/config.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; Z80 debugger with auxiliary debug terminal 3 | ;----------------------------------------------------------------------------- 4 | 5 | ; Setting Z180 to TRUE enables Hitachi HD64180/Z180 support. Set it to FALSE 6 | ; for a Z80-only version of Z8E. 7 | 8 | z180 equ false ; Z80 only 9 | 10 | ; Define the console terminal 11 | 12 | conterm equ ansi 13 | 14 | ; Define the auxiliary terminal 15 | 16 | auxterm equ ansi 17 | 18 | ; If you are running under CP/M Plus then you can set CPM3 to true in which 19 | ; case the auxiliary input status routine will be a simple BDOS call. 20 | 21 | CPM3 equ true 22 | -------------------------------------------------------------------------------- /src/z8e1.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; Z80 debugger with auxiliary debug terminal 3 | ;----------------------------------------------------------------------------- 4 | 5 | ; Setting Z180 to TRUE enables Hitachi HD64180/Z180 support. Set it to FALSE 6 | ; for a Z80-only version of Z8E. 7 | 8 | z180 equ false ; Z80 only 9 | 10 | ; Define the console terminal 11 | 12 | conterm equ ansi 13 | 14 | ; Define the auxiliary terminal 15 | 16 | auxterm equ none 17 | 18 | ; If you are running under CP/M Plus then you can set CPM3 to true in which 19 | ; case the auxiliary input status routine will be a simple BDOS call. 20 | 21 | CPM3 equ true 22 | -------------------------------------------------------------------------------- /src/z8e2.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; Z80 debugger with auxiliary debug terminal 3 | ;----------------------------------------------------------------------------- 4 | 5 | ; Setting Z180 to TRUE enables Hitachi HD64180/Z180 support. Set it to FALSE 6 | ; for a Z80-only version of Z8E. 7 | 8 | z180 equ false ; Z80 only 9 | 10 | ; Define the console terminal 11 | 12 | conterm equ ansi 13 | 14 | ; Define the auxiliary terminal 15 | 16 | auxterm equ ansi 17 | 18 | ; If you are running under CP/M Plus then you can set CPM3 to true in which 19 | ; case the auxiliary input status routine will be a simple BDOS call. 20 | 21 | CPM3 equ true 22 | -------------------------------------------------------------------------------- /src/18e1.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; HD64189/Z180 debugger with one terminal 3 | ;----------------------------------------------------------------------------- 4 | 5 | ; Setting Z180 to TRUE enables Hitachi HD64180/Z180 support. Set it to FALSE 6 | ; for a Z80-only version of Z8E. 7 | 8 | z180 equ true ; Enable Z180/HD64180 support 9 | 10 | ; Define the console terminal 11 | 12 | conterm equ ansi 13 | 14 | ; Define the auxiliary terminal 15 | 16 | auxterm equ none 17 | 18 | ; If you are running under CP/M Plus then you can set CPM3 to true in which 19 | ; case the auxiliary input status routine will be a simple BDOS call. 20 | 21 | CPM3 equ true 22 | -------------------------------------------------------------------------------- /src/18e2.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; HD64189/Z180 debugger with auxiliary debug terminal 3 | ;----------------------------------------------------------------------------- 4 | 5 | ; Setting Z180 to TRUE enables Hitachi HD64180/Z180 support. Set it to FALSE 6 | ; for a Z80-only version of Z8E. 7 | 8 | z180 equ true ; Enable Z180/HD64180 support 9 | 10 | ; Define the console terminal type 11 | 12 | conterm equ ansi 13 | 14 | ; Define the auxiliary terminal type 15 | 16 | auxterm equ adm3a 17 | 18 | ; If you are running CP/M Plus then you can set CPM3 true in which case the 19 | ; auxiliary input status routine becomes a simple BDOS call, otherwise you 20 | ; may need to provide some hardware-specific code. 21 | 22 | CPM3 equ true 23 | -------------------------------------------------------------------------------- /src/z8e42.txt: -------------------------------------------------------------------------------- 1 | Z8E is a CP/M-hosted screen-oriented assembly-language debugger for the Z80 2 | and Z180 (HD64180) processors. It can take advantage of a second monitor if 3 | one is available to separate the debugging dialogue from the console I/O of 4 | the application program being analysed. 5 | 6 | These notes apply to version 4.2 of Z8E. 7 | 8 | Z8E version 4.2 9 | =============== 10 | 11 | Version 4.2 fixes a bug in the symbol table load routine: if the file 12 | ended exactly at a record boundary, a "Symbol Table Not Found" error was 13 | displayed and no symbols were loaded. 14 | 15 | In addition, clearing of the screen is now done by sending the appropriate 16 | control sequences to the terminal. The old method of clearing the screen 17 | with a string of line-feeds left garbage on the screen in certain cases. 18 | 19 | Hector Peraza 20 | peraza@newsguy.com 21 | -------------------------------------------------------------------------------- /src/z8e41.txt: -------------------------------------------------------------------------------- 1 | Z8E is a CP/M-hosted screen-oriented assembly-language debugger for the Z80 2 | and Z180 (HD64180) processors. It can take advantage of a second monitor if 3 | one is available to separate the debugging dialogue from the console I/O of 4 | the application program being analysed. 5 | 6 | These notes apply to version 4.1 of Z8E. 7 | 8 | Z8E version 4.1 9 | =============== 10 | 11 | Version 4.1 introduces a minor optimisation to Z8E which applies when the 12 | secondary terminal is the same as the primary. That makes it possible for 13 | both terminals to share code and data and in so doing reduces the amount of 14 | memory used by the debugger itself. 15 | 16 | Adaptation of Z8E to various hardware and software environments has been 17 | substantially reworked. Versions prior to 4.0 allowed binary patching for 18 | terminal configuration but that was abandoned on the premise that anyone 19 | debugging at the assembly language level is likely to have the ability to 20 | write or modify an assembly language source file to tailor Z8E to his needs. 21 | 22 | The source code in 4.0 was a bit of a mess and hard to modify. Just figuring 23 | out what needed to be done was difficult. That issue has been addressed. 24 | Small external source files containing the environment-specific code and data 25 | are included during assembly. It is just a matter of copying two or three 26 | suitably-tailored source files to have the expected names and then assembling 27 | Z8E from the source code. 28 | 29 | The behaviour of Z8E at the command level was a bit inconsistent, particularly 30 | in respect to repeating the same command and in recognising command changes. 31 | An attempt has been made to clean that up. 32 | 33 | The Z8E manual has been updated. 34 | 35 | Some CP/M Plus submit files are supplied, each tailored to a different 36 | assembler toolset 37 | 38 | BUILDM.SUB Microsoft M80/L80 39 | BUILDZ.SUB SLR's Z80ASM or equivalent 40 | BUILDC.SUB Cromemco CDOS Z80 Macro Assembler 41 | 42 | These srcipts generate all four versions of Z8E: 43 | 44 | 18E1.COM Z180 support, one terminal 45 | 18E2.COM Z180 support, two terminals 46 | Z8E1.COM Z80, one terminal ("standard" version) 47 | Z8E2.COM Z80, two terminals 48 | 49 | To use any of the scripts the requirements for assembling Z8E must be met. 50 | The Z8E manual describes the build process. These scripts merely automate it. 51 | 52 | Jon Saxton 53 | tesseract@triton.vg 54 | -------------------------------------------------------------------------------- /src/terminal.inc: -------------------------------------------------------------------------------- 1 | ;----------------------------------------------------------------------------- 2 | ; Terminal types. 3 | ;----------------------------------------------------------------------------- 4 | 5 | if termdef ; Once only table definition 6 | 7 | ;----------------------------------------------------------------------------- 8 | ; This just assigns a number to each terminal type. The numbers themselves 9 | ; don't matter just so long as there are no duplicates. If you add a terminal 10 | ; then make up a new entry for it here and add an entry to the two inclusion 11 | ; lists. (Remember that the file names in the inclusion lists must be in 12 | ; upper case for them to work with all versions of M80.) 13 | ; 14 | ; Any synonyms should be defined in this section. For example, the ADM3A, 15 | ; Soroc and and Televideo terminals use the same control sequences so they 16 | ; should be given the same number. When soroc is called for, the ADM3A 17 | ; definitions will be used. 18 | ;----------------------------------------------------------------------------- 19 | 20 | none equ 0 21 | adm3a equ 1 22 | ansi equ 2 23 | d8227 equ 3 24 | vt52 equ 4 25 | soroc equ 4 ; Soroc is a synonym for adm3a 26 | tvi equ 4 ; Televideo also 27 | 28 | ;----------------------------------------------------------------------------- 29 | 30 | termdef defl false ; Don't touch this 31 | 32 | else ; termdef 33 | 34 | ;----------------------------------------------------------------------------- 35 | ; Include console terminal code or data upon request 36 | ;----------------------------------------------------------------------------- 37 | 38 | if slr or zasmb 39 | if terminal eq console 40 | 41 | if conterm eq adm3a 42 | include ADM3A.TTY 43 | endif 44 | 45 | if conterm eq ansi 46 | include ANSI.TTY 47 | endif 48 | 49 | if conterm eq d8227 50 | include D8227.TTY 51 | endif 52 | 53 | if conterm eq vt52 54 | include VT52.TTY 55 | endif 56 | 57 | endif ; console 58 | ;----------------------------------------------------------------------------- 59 | ; Include auxiliary terminal code or data upon request 60 | ;----------------------------------------------------------------------------- 61 | 62 | if terminal eq auxiliary 63 | if auxterm eq adm3a 64 | include ADM3A.TTY 65 | endif 66 | 67 | if auxterm eq ansi 68 | include ANSI.TTY 69 | endif 70 | 71 | if auxterm eq d8227 72 | include D8227.TTY 73 | endif 74 | 75 | if auxterm eq vt52 76 | include VT52.TTY 77 | endif 78 | endif ;terminal eq auxiliary 79 | endif ; slr or zasmb 80 | 81 | ;----------------------------------------------------------------------------- 82 | ; M80 does not allow nested includes. To import the correct file for each 83 | ; terminal I resorted to this artifice. It is rather ugly but the idea is 84 | ; to keep the list of terminals in this file where it is easier to maintain 85 | ; than it would be if it were in the main source file. 86 | ; 87 | ; It would be nice to think of a more uniform approach. 88 | ;----------------------------------------------------------------------------- 89 | 90 | if m80 91 | if terminal eq console 92 | if conterm eq adm3a 93 | conincl macro 94 | include ADM3A.TTY 95 | endm 96 | endif 97 | 98 | if conterm eq ansi 99 | conincl macro 100 | include ANSI.TTY 101 | endm 102 | endif 103 | 104 | if conterm eq d8227 105 | conincl macro 106 | include D8227.TTY 107 | endm 108 | endif 109 | 110 | if conterm eq vt52 111 | conincl macro 112 | include VT52.TTY 113 | endm 114 | endif 115 | endif ; terminal eq console 116 | 117 | if terminal eq auxiliary 118 | if auxterm eq adm3a 119 | auxincl macro 120 | include ADM3A.TTY 121 | endm 122 | endif 123 | 124 | if auxterm eq ansi 125 | auxincl macro 126 | include ANSI.TTY 127 | endm 128 | endif 129 | 130 | if auxterm eq d8227 131 | auxincl macro 132 | include D8227.TTY 133 | endm 134 | endif 135 | 136 | if auxterm eq vt52 137 | auxincl macro 138 | include VT52.TTY 139 | endm 140 | endif 141 | endif ; terminal eq auxiliary 142 | endif ; M80 143 | endif ; termdef 144 | -------------------------------------------------------------------------------- /src/vt52.tty: -------------------------------------------------------------------------------- 1 | ; ___________________________________________________________________________ 2 | ;| | 3 | ;| VT52.TTY | 4 | ;| | 5 | ;| Device-specific and hardware-dependent code for Z8E debugger. | 6 | ;| | 7 | ;| This file is intended to support one or two DEC VT52 or similar terminals | 8 | ;| either real or virtual. | 9 | ;| | 10 | ;| Some assembly-time conditionals are provided to help adapting this file | 11 | ;| to different environments. | 12 | ;|___________________________________________________________________________| 13 | ;| | 14 | ;| There was a time when it was possible to patch the object code to support | 15 | ;| specific hardware. That facility is no longer offered. It is assumed | 16 | ;| that anyone who is likely to be interested in using this program to debug | 17 | ;| software at the assembly language detail would have the means to write or | 18 | ;| adapt a module like this one and to rebuild the debugger from the source | 19 | ;| code. | 20 | ;|___________________________________________________________________________| 21 | ;| | 22 | ;| This file is written to be as generic as possible and so should be easy | 23 | ;| to adapt to different hardware. | 24 | ;|___________________________________________________________________________| 25 | 26 | 27 | ; This file is included twice when assembling. The first time just loads 28 | ; the code, the second time defines the data associated with the code. 29 | 30 | if defcode ; Load code 31 | 32 | ; ___________________________________________________________________ 33 | ;| | 34 | ;| Z8E imposes only one restriction on the code you write. In order | 35 | ;| to guarantee that your routines can be relocated into high memory | 36 | ;| by Z8E do not load any 16 bit constants into register pairs; | 37 | ;| instead do two 8 bit loads. For example, do not use the | 38 | ;| following statement: | 39 | ;| | 40 | ;| ld de,1234h | 41 | ;| | 42 | ;| Rather, code it like this: | 43 | ;| | 44 | ;| ld d,12h | 45 | ;| ld e,34h | 46 | ;| | 47 | ;| With luck you won't need to load a constant into an index | 48 | ;| register but if you do there are a few ways around the problem. | 49 | ;| This one will work on a Z80 (but not on a Z180), does not depend | 50 | ;| on the assembler chosen and does not touch any other register: | 51 | ;| | 52 | ;| Instead of: ld ix,5678h ld iy,5678h | 53 | ;| | 54 | ;| code: defb 0DDh defb 0FDh | 55 | ;| ld h,56h ld h,56h | 56 | ;| defb 0DDh defb 0FDh | 57 | ;| ld l,78h ld l,78h | 58 | ;|___________________________________________________________________| 59 | 60 | if (terminal eq console) and (conterm eq vt52) 61 | 62 | ;;=========================================================================== 63 | ;; mttyq: 64 | ;; Main console input status routine 65 | ;; 66 | ;; This a conditional input routine, i.e. a non-blocking read. If a console 67 | ;; key has been pressed then it returns the character generated by that key 68 | ;; otherwise it returns 0. 69 | ;;=========================================================================== 70 | export mttyq 71 | ;mttyq: 72 | ld c,11 ; Console input status 73 | call bdos 74 | and a ; Is a character available? 75 | ret z ; Return zero if nothing there 76 | ; Othersise fall through to input 77 | ; routine 78 | 79 | ;;=========================================================================== 80 | ;; mttyi: 81 | ;; Main physical keyboard input routine 82 | ;; (Default is CP/M console device) 83 | ;;=========================================================================== 84 | export mttyi 85 | ;mttyi: 86 | ld c,6 87 | 88 | if CPM3 89 | ld e,0FDh ; CP/M+ interpretation of E register: 90 | ; FF -> return 0 if nothing available 91 | ; -> otherwise the character 92 | ; FE -> return 0 if nothing available 93 | ; -> return FF if there is something 94 | ; (in which case a 2nd call is 95 | ; needed to fetch the character). 96 | ; FD -> Block until character is ready 97 | ; then return it. 98 | else ; 99 | ld e,0FFh ; CP/M 2 doesn't assign special meaning 100 | endif ; to E=FE or FD. 101 | 102 | call bdos ; Fetch character 103 | and 7FH ; Mask off high bit 104 | jr z,mttyi ; Loop if no character or a NUL 105 | ret 106 | 107 | ;;=========================================================================== 108 | ;; mttyo: 109 | ;; Main physical console output routine 110 | ;; (Default is CP/M console device) 111 | ;;=========================================================================== 112 | 113 | export mttyo 114 | ;mttyo: 115 | ld e,a 116 | ld c,6 117 | call bdos 118 | ret 119 | 120 | ;;=========================================================================== 121 | ;; mxycp: 122 | ;; Main console screen cursor positioning routine 123 | ;; 124 | ;; Uses MXYSTR, MROWB4, MROW and MCOL for configuration. 125 | ;; 126 | ;; The version supplied here is for a DEC VT52 terminal 127 | ;; 128 | ;; This routine places the cursor at the row in B and the column in C. 129 | ;; Position (0,0) is the top left corner of the screen. 130 | ;; 131 | ;; If Z8E is being assembled to use two terminals and those two terminals 132 | ;; have very similar characteristics then the code herein may also be used 133 | ;; as the auxiliary screen cursor positioning routine. 134 | ;;=========================================================================== 135 | 136 | export mxycp 137 | ;mxycp: 138 | 139 | ld hl,mxystr ; Cursor addressing string 140 | ld a,(mrow) ; Get row bias 141 | add a,b ; Add row 142 | ld b,a ; Save row selector 143 | ld a,(mcol) ; Get column bias 144 | add a,c ; Add column 145 | ld c,a ; Save column selector 146 | ld e,(hl) ; Get length of cursor addressing string 147 | mxy0: 148 | inc hl ; Step string pointer 149 | ld a,(hl) ; Get character from cursor addressing string 150 | call ttyo ; Send character to terminal 151 | dec e ; Count down 152 | jr nz,mxy0 ; Loop until all sent 153 | ld a,(mrow4) ; Row first or column first? 154 | and a 155 | jr nz,mxy1 ; Skip if row first 156 | ld a,b ; x,y addressing, interchange row and column 157 | ld b,c 158 | ld c,a 159 | mxy1: 160 | ld a,b ; Send first coordinate 161 | call ttyo 162 | ld a,c ; Send second coordinate 163 | call ttyo 164 | ret 165 | 166 | ;;=========================================================================== 167 | ;; mcls: 168 | ;; Main console screen clearing routine 169 | ;; 170 | ;; Uses MCLSTR for configuration. 171 | ;; 172 | ;; The version supplied here is for an DEC VT52 or similar terminal. 173 | ;;=========================================================================== 174 | 175 | export mcls 176 | ;mcls: 177 | 178 | ld hl,mclstr ; Screen clearing string 179 | ld b,(hl) ; Get length of string 180 | mcls0: 181 | inc hl ; Step string pointer 182 | ld a,(hl) ; Get character from screen clearing string 183 | call ttyo ; Send character to terminal 184 | djnz mcls0 ; Count down and loop until all sent 185 | ret 186 | 187 | endif ; (conterm eq vt52) and (terminal eq console) 188 | 189 | ;############################################################################ 190 | ;# THE CODE FROM HERE ONWARDS ONLY EXISTS IF Z8E IS BEING ASSEMBLED TO USE # 191 | ;# AN AUXILIARY TERMINAL FOR THE DEBUGGING DISPLAY, LEAVING THE CONSOLE FOR # 192 | ;# USE BY THE APPLICATION BEING MONITORED. # 193 | ;############################################################################ 194 | 195 | ; Load these drivers to support an auxiliary terminal 196 | 197 | if terminal eq auxiliary 198 | if auxterm eq vt52 199 | 200 | ;;=========================================================================== 201 | ;; attyq: 202 | ;; Auxiliary physical keyboard input status routine. 203 | ;; 204 | ;; This only exists if Z8E is being assembled to support dual terminals. 205 | ;; 206 | ;; This is a conditional input routine - a non-blocking read. It returns a 207 | ;; character from the auxiliary terminal if a key has been pressed, otherwise 208 | ;; it returns 0. 209 | ;;=========================================================================== 210 | 211 | export attyq 212 | ;attyq: 213 | 214 | ; If only the main console is active then use that. 215 | 216 | ld a,(auxon) ; Is auxiliary terminal active? 217 | or a 218 | jr z,mttyq ; No - check console status instead 219 | 220 | ; Auxiliary terminal is in use ... 221 | 222 | ; For CP/M+ the auxiliary input status is available as a BDOS call. 223 | 224 | if cpm3 225 | 226 | ld c,7 ; Auxiliary input status 227 | call bdos 228 | or a ; Is a character available? 229 | ret z ; No: return a zero 230 | ; Yes: fall through to input routine 231 | else 232 | 233 | ; Not CP/M+. Insert code to read a port here. 234 | ; Example for SB180's serial port 0: 235 | 236 | xor a 237 | ld b,a 238 | in a,(4) ; Read serial port status register 239 | and 80h ; Isolate high bit 240 | ret z ; Return zero if nothing there 241 | ; Fall through to input routine 242 | endif 243 | 244 | ;;=========================================================================== 245 | ;; attyi: 246 | ;; Auxiliary physical keyboard input routine 247 | ;; (Default is CP/M reader input device) 248 | ;;=========================================================================== 249 | 250 | export attyi 251 | ;attyi: 252 | ld a,(auxon) ; Is 2nd terminal active? 253 | or a 254 | jr z,mttyi ; No, use console 255 | 256 | ld c,3 ; Auxiliary input (blocking) 257 | call bdos 258 | 259 | and 7Fh ; Mask off the high bit 260 | jr z,attyi ; Ignore a NUL character 261 | ret 262 | 263 | 264 | ;;=========================================================================== 265 | ;; attyo: 266 | ;; Auxiliary physical console output routine 267 | ;; (Default is CP/M punch output device) 268 | ;;=========================================================================== 269 | 270 | export attyo 271 | ;attyo: 272 | ld c,4 ; AUX/PUN output 273 | call bdos 274 | ret 275 | 276 | ;;=========================================================================== 277 | ;; axycp: 278 | ;; Auxiliary terminal cursor positioning routine 279 | ;; 280 | ;; Uses AXYSTR, AROWB4, AROW and ACOL for configuration. 281 | ;; 282 | ;; The version supplied here is for a DEC VT52. 283 | ;; 284 | ;; This routine places the cursor at the row in B and the column in C. 285 | ;; Position (0,0) is the top left corner of the screen. 286 | ;;=========================================================================== 287 | 288 | ; This driver is only needed if the console and auxiliary terminals are 289 | ; different types. If they are the same then Z8E can use the console driver 290 | ; to position the cursor on the auxiliary screen. 291 | 292 | if auxterm ne conterm 293 | 294 | export axycp 295 | ;axycp: 296 | 297 | ld hl,axystr ; Cursor addressing string 298 | ld a,(arow) ; Get row bias 299 | add a,b ; Add row 300 | ld b,a ; Save row selector 301 | ld a,(acol) ; Get column bias 302 | add c ; Add column 303 | ld c,a ; Save column selector 304 | ld e,(hl) ; Get length of cursor addressing string 305 | axy0: 306 | inc hl ; Step string pointer 307 | ld a,(hl) ; Get character from cursor addressing string 308 | call ttyo ; Send character to terminal 309 | dec e ; Count down 310 | jr nz,axy0 ; Loop until all sent 311 | ld a,(arowb4) ; Row first or column first? 312 | and a 313 | jr nz,axy1 ; Skip if row first 314 | ld a,b ; x,y addressing, interchange row and column 315 | ld b,c 316 | ld c,a 317 | axy1: 318 | ld a,b ; Send first coordinate 319 | call ttyo 320 | ld a,c ; Send second coordinate 321 | call ttyo 322 | ret 323 | 324 | ;;=========================================================================== 325 | ;; acls: 326 | ;; Auxiliary terminal screen clearing routine 327 | ;; 328 | ;; Uses ACLSTR for configuration. 329 | ;; 330 | ;; The version supplied here is for an DEC VT52 terminal or similar. 331 | ;;=========================================================================== 332 | 333 | export acls 334 | ;acls: 335 | 336 | ld hl,aclstr ; Screen clearing string 337 | ld b,(hl) ; Get length of string 338 | acls0: 339 | inc hl ; Step string pointer 340 | ld a,(hl) ; Get character from screen clearing string 341 | call ttyo ; Send character to terminal 342 | djnz acls0 ; Count down and loop until all sent 343 | ret 344 | 345 | endif ; auxterm ne conterm 346 | endif ; auxterm ne vt52 347 | endif ; terminal ne auxiliary 348 | endif ; defcode 349 | 350 | if defdata 351 | ;###################################################################### 352 | ;# Second round inclusion ... define data areas for code shown above. # 353 | ;###################################################################### 354 | 355 | ; The code portions are loaded by including this file twice, once for each 356 | ; terminal. The data portions are handled in a single inclusion. 357 | 358 | ; Configuration bytes for console - DEC VT52 359 | 360 | if conterm eq vt52 361 | 362 | export mrowb4 363 | ;mrowb4: 364 | defb 1 ; VT52 uses y,x addressing, i.e. row first. 365 | ; This is the more common coordinate order 366 | export mrow 367 | ;mrow: 368 | defb ' ' ; Bias for row 369 | 370 | export mcol 371 | ;mcol: 372 | defb ' ' ; Bias for column 373 | 374 | export mxystr ; Cursor position lead-in 375 | ;mxystr: 376 | defb 2,esc,'Y' 377 | 378 | export mclstr ; Screen clearing 379 | ;mclstr: 380 | defb 4,esc,'H',esc,'J' 381 | 382 | endif ; conterm = vt52 383 | 384 | ; Configuration bytes for auxiliary terminal - DEC VT52 385 | 386 | if auxterm eq vt52 387 | 388 | export arowb4 389 | ;arowb4: 390 | defb 1 ; VT-52 uses y,x addressing, i.e. row first. 391 | ; This is the more common coordinate order. 392 | 393 | export arow 394 | ;arow: 395 | defb ' ' ; Bias for cursor row coordinates 396 | 397 | export acol 398 | ;acol: 399 | defb ' ' ; Same for column 400 | 401 | export axystr 402 | ;axystr: 403 | defb 2,esc,'Y' ; VT-52 cursor positioning 404 | 405 | export aclstr 406 | ;aclstr: 407 | defb 4,esc,'H',esc,'J' ; VT-52 screen clearing 408 | 409 | endif ; auxterm = vt52 410 | endif ; defdata 411 | -------------------------------------------------------------------------------- /src/ansi.tty: -------------------------------------------------------------------------------- 1 | .sall 2 | ; ___________________________________________________________________________ 3 | ;| | 4 | ;| ANSI.TTY | 5 | ;| | 6 | ;| Device-specific and hardware-dependent code for Z8E debugger. | 7 | ;| | 8 | ;| This file is intended to support one or two ANSI terminals, either real | 9 | ;| or virtual. Candidates would include DEC VT100 and similar, along with | 10 | ;| most xterm implementations. | 11 | ;| | 12 | ;| Some assembly-time conditionals are provided to help adapting this file | 13 | ;| to different environments. | 14 | ;|___________________________________________________________________________| 15 | ;| | 16 | ;| There was a time when it was possible to patch the object code to support | 17 | ;| specific hardware. That facility is no longer offered. It is assumed | 18 | ;| that anyone who is likely to be interested in using this program to debug | 19 | ;| software at the assembly language detail would have the means to write or | 20 | ;| adapt a module like this one and to rebuild the debugger from the source | 21 | ;| code. | 22 | ;|___________________________________________________________________________| 23 | ;| | 24 | ;| This file is written to be as generic as possible and so should be easy | 25 | ;| to adapt to different hardware. | 26 | ;|___________________________________________________________________________| 27 | 28 | ; This file is included twice when assembling. The first time just loads 29 | ; the code, the second time defines the data associated with the code. 30 | 31 | .lall 32 | if defcode ; Load code 33 | 34 | .sall 35 | ; ___________________________________________________________________ 36 | ;| | 37 | ;| Z8E imposes only one restriction on the code you write. In order | 38 | ;| to guarantee that your routines can be relocated into high memory | 39 | ;| by Z8E do not load any 16 bit constants into register pairs; | 40 | ;| instead do two 8 bit loads. For example, do not use the | 41 | ;| following statement: | 42 | ;| | 43 | ;| ld de,1234h | 44 | ;| | 45 | ;| Rather, code it like this: | 46 | ;| | 47 | ;| ld d,12h | 48 | ;| ld e,34h | 49 | ;| | 50 | ;| With luck you won't need to load a constant into an index | 51 | ;| register but if you do there are a few ways around the problem. | 52 | ;| This one will work on a Z80 (but not on a Z180), does not depend | 53 | ;| on the assembler chosen and does not touch any other register: | 54 | ;| | 55 | ;| Instead of: ld ix,5678h ld iy,5678h | 56 | ;| | 57 | ;| code: defb 0DDh defb 0FDh | 58 | ;| ld h,56h ld h,56h | 59 | ;| defb 0DDh defb 0FDh | 60 | ;| ld l,78h ld l,78h | 61 | ;|___________________________________________________________________| 62 | 63 | .xall 64 | if terminal eq console 65 | if conterm eq ansi ; then we need to load the physical 66 | ; drivers for the console 67 | 68 | ;;=========================================================================== 69 | ;; mttyq: 70 | ;; Main console input status routine 71 | ;; 72 | ;; This a conditional input routine, i.e. a non-blocking read. If a console 73 | ;; key has been pressed then it returns the character generated by that key 74 | ;; otherwise it returns 0. 75 | ;;=========================================================================== 76 | export mttyq 77 | ;mttyq: 78 | ld c,11 ; Console input status 79 | call bdos 80 | and a ; Is a character available? 81 | ret z ; Return zero if nothing there 82 | ; Othersise fall through to input 83 | ; routine 84 | 85 | ;;=========================================================================== 86 | ;; mttyi: 87 | ;; Main physical keyboard input routine 88 | ;; (Default is CP/M console device) 89 | ;;=========================================================================== 90 | export mttyi 91 | ;mttyi: 92 | ld c,6 93 | 94 | if CPM3 95 | ld e,0FDh ; CP/M+ interpretation of E register: 96 | ; FF -> return 0 if nothing available 97 | ; -> otherwise the character 98 | ; FE -> return 0 if nothing available 99 | ; -> return FF if there is something 100 | ; (in which case a 2nd call is 101 | ; needed to fetch the character). 102 | ; FD -> Block until character is ready 103 | ; then return it. 104 | else ; 105 | ld e,0FFh ; CP/M 2 doesn't assign special meaning 106 | endif ; to E=FE or FD. 107 | 108 | call bdos ; Fetch character 109 | and 7FH ; Mask off high bit 110 | jr z,mttyi ; Loop if no character or a NUL 111 | ret 112 | 113 | ;;=========================================================================== 114 | ;; mttyo: 115 | ;; Main physical console output routine 116 | ;; (Default is CP/M console device) 117 | ;;=========================================================================== 118 | 119 | export mttyo 120 | ;mttyo: 121 | ld c,6 ; Character for transmission is already in E 122 | call bdos 123 | ret 124 | 125 | ;;=========================================================================== 126 | ;; mxycp: 127 | ;; Main console screen cursor positioning routine 128 | ;; 129 | ;; The version supplied here is for an ANSI-type terminal such as a VT100. 130 | ;; It doesn't use the usual MXYSTR, MROWB4, MROW and MCOL for configuration. 131 | ;; 132 | ;; This routine places the cursor at the row in B and the column in C. 133 | ;; Position (0,0) is the top left corner of the screen. 134 | ;; 135 | ;; If Z8E is being assembled to use two terminals and those two terminals 136 | ;; have very similar characteristics then the code herein may also be used 137 | ;; as the auxiliary screen cursor positioning routine. 138 | ;;=========================================================================== 139 | 140 | export mxycp 141 | ;mxycp: 142 | 143 | ; ANSI screen driver - jrs - 27 May 87 144 | ; Tested and corrected 29 Dec 88 - jrs 145 | 146 | inc b ;Add 1 to row and column 147 | inc c 148 | push bc 149 | 150 | ld a,1Bh ;Send ESC 151 | call ttyo 152 | ld a,'[' ;Send [ 153 | call ttyo 154 | pop bc ;Send row (Y) coordinate 155 | push bc 156 | ld a,b 157 | call xycp00 158 | ld a,';' ;Send ; 159 | call ttyo 160 | pop bc ;Send column (X) coordinate 161 | ld a,c 162 | call xycp00 163 | ld a,'H' ;Send H 164 | call ttyo 165 | ret 166 | 167 | xycp00: 168 | ex af,af' 169 | xor a 170 | ex af,af' 171 | xycp10: 172 | ex af,af' 173 | inc a 174 | ex af,af' 175 | sub 10 176 | jr nc,xycp10 177 | ex af,af' 178 | dec a 179 | jr z,xycp20 180 | add a,'0' 181 | call ttyo 182 | xycp20: 183 | ex af,af' 184 | add a,'0'+10 185 | call ttyo 186 | ret 187 | 188 | ;;=========================================================================== 189 | ;; mcls: 190 | ;; Main console screen clearing routine 191 | ;; 192 | ;; Uses MCLSTR for configuration. 193 | ;; 194 | ;; The version supplied here is for an ANSI-type terminal such as a VT100. 195 | ;; 196 | ;; If Z8E is being assembled to use two terminals and those two terminals 197 | ;; have very similar characteristics then the code herein may also be used 198 | ;; as the auxiliary screen cursor positioning routine. 199 | ;;=========================================================================== 200 | 201 | export mcls 202 | ;mcls: 203 | 204 | ld hl,mclstr ; Screen clearing string 205 | ld b,(hl) ; Get length of string 206 | mcls0: 207 | inc hl ; Step string pointer 208 | ld a,(hl) ; Get character from screen clearing string 209 | call ttyo ; Send character to terminal 210 | djnz mcls0 ; Count down and loop until all sent 211 | ret 212 | 213 | endif ; conterm = ansi 214 | endif ; terminal = console 215 | 216 | ;############################################################################ 217 | ;# THE CODE FROM HERE ONWARDS ONLY EXISTS IF Z8E IS BEING ASSEMBLED TO USE # 218 | ;# AN AUXILIARY TERMINAL FOR THE DEBUGGING DISPLAY, LEAVING THE CONSOLE FOR # 219 | ;# USE BY THE APPLICATION BEING MONITORED. # 220 | ;############################################################################ 221 | 222 | ; Load these drivers if we need support for an auxiliary terminal. 223 | 224 | if auxterm eq ansi 225 | if (terminal eq auxiliary) 226 | 227 | ;;=========================================================================== 228 | ;; attyq: 229 | ;; Auxiliary physical keyboard input status routine. 230 | ;; 231 | ;; This only exists if Z8E is being assembled to support dual terminals. 232 | ;; 233 | ;; This is a conditional input routine - a non-blocking read. It returns a 234 | ;; character from the auxiliary terminal if a key has been pressed, otherwise 235 | ;; it returns 0. 236 | ;;=========================================================================== 237 | 238 | export attyq 239 | ;attyq: 240 | 241 | ; If only the main console is active then use that. 242 | 243 | ld a,(auxon) ; Is auxiliary terminal active? 244 | or a 245 | jr z,mttyq ; No - check console status instead 246 | 247 | ; Auxiliary terminal is in use ... 248 | 249 | ; For CP/M+ the auxiliary input status is available as a BDOS call. 250 | 251 | if CPM3 252 | 253 | ld c,7 ; Auxiliary input status 254 | call bdos 255 | or a ; Is a character available? 256 | ret z ; No: return a zero 257 | ; Yes: fall through to input routine 258 | else 259 | 260 | ; Not CP/M+. Insert code to read a port here. 261 | ; Example for SB180's serial port 0: 262 | 263 | xor a ; Force address lines A8-A15 low 264 | ld b,a 265 | in a,(4) ; Read serial port status register 266 | and 80h ; Isolate high bit 267 | ret z ; Return zero if nothing there 268 | ; Fall through to input routine 269 | endif 270 | 271 | ;;=========================================================================== 272 | ;; attyi: 273 | ;; Auxiliary physical keyboard input routine 274 | ;; (Default is CP/M reader input device) 275 | ;;=========================================================================== 276 | 277 | export attyi 278 | ;attyi: 279 | ld a,(auxon) ; Is 2nd terminal active? 280 | or a 281 | jr z,mttyi ; No, use console 282 | 283 | ld c,3 ; Auxiliary input (blocking) 284 | call bdos 285 | 286 | and 7Fh ; Mask off the high bit 287 | jr z,attyi ; Ignore a NUL character 288 | ret 289 | 290 | ;;=========================================================================== 291 | ;; attyo: 292 | ;; Auxiliary physical console output routine 293 | ;; (Default is CP/M punch output device) 294 | ;;=========================================================================== 295 | export attyo 296 | ;attyo: 297 | ; Character for transmission is 298 | ; already in E 299 | ld c,4 ; AUX/PUN output 300 | call bdos 301 | ret 302 | 303 | ;;=========================================================================== 304 | ;; axycp: 305 | ;; Auxiliary terminal cursor positioning routine 306 | ;; 307 | ;; The version supplied here is for an ANSI-type terminal such as a VT100. 308 | ;; It doesn't use the usual AXYSTR, AROWB4, AROW and ACOL for configuration. 309 | ;; 310 | ;; This routine places the cursor at the row in B and the column in C. 311 | ;; Position (0,0) is the top left corner of the screen. 312 | ;;=========================================================================== 313 | 314 | ; This driver is only needed if the console and auxiliary terminals are 315 | ; different types. If they are the same then Z8E can use the console driver 316 | ; to position the cursor on the auxiliary screen. 317 | 318 | if auxterm ne conterm 319 | 320 | export axycp 321 | ;axycp: 322 | 323 | ; ANSI screen driver - jrs - 27 May 87 324 | ; Tested and corrected 29 Dec 88 - jrs 325 | 326 | inc b ;Add 1 to row and column 327 | inc c 328 | push bc 329 | 330 | ld a,1Bh ;Send ESC 331 | call ttyo 332 | ld a,'[' ;Send [ 333 | call ttyo 334 | pop bc ;Send row (Y) coordinate 335 | push bc 336 | ld a,b 337 | call xycp00 338 | ld a,';' ;Send ; 339 | call ttyo 340 | pop bc ;Send column (X) coordinate 341 | ld a,c 342 | call xycp00 343 | ld a,'H' ;Send H 344 | call ttyo 345 | ret 346 | 347 | xycp00: 348 | ex af,af' 349 | xor a 350 | ex af,af' 351 | xycp10: 352 | ex af,af' 353 | inc a 354 | ex af,af' 355 | sub 10 356 | jr nc,xycp10 357 | ex af,af' 358 | dec a 359 | jr z,xycp20 360 | add a,'0' 361 | call ttyo 362 | xycp20: 363 | ex af,af' 364 | add a,'0'+10 365 | call ttyo 366 | ret 367 | 368 | ;;=========================================================================== 369 | ;; acls: 370 | ;; Auxiliary terminal screen clearing routine 371 | ;; 372 | ;; Uses ACLSTR for configuration. 373 | ;; 374 | ;; The version supplied here is for an ANSI-type terminal such as a VT100. 375 | ;;=========================================================================== 376 | 377 | export acls 378 | ;acls: 379 | 380 | ld hl,aclstr ; Screen clearing string 381 | ld b,(hl) ; Get length of string 382 | acls0: 383 | inc hl ; Step string pointer 384 | ld a,(hl) ; Get character from screen clearing string 385 | call ttyo ; Send character to terminal 386 | djnz acls0 ; Count down and loop until all sent 387 | ret 388 | 389 | endif ; conterm ne auxterm 390 | endif ; terminal ne auxiliary 391 | endif ; auxterm ne ansi 392 | endif ; defcode 393 | 394 | if defdata 395 | ;###################################################################### 396 | ;# Second round inclusion ... define data areas for code shown above. # 397 | ;###################################################################### 398 | 399 | ; The code portions are loaded by including this file twice, once for 400 | ; each terminal. The data portions are handled in a single inclusion. 401 | 402 | ; Console ... 403 | 404 | if terminal eq console 405 | if conterm eq ansi ; then we definitely need these 406 | 407 | export mclstr 408 | ;mclstr: 409 | defb 4,esc,'[2J' ; ANSI screen clearing 410 | 411 | endif ; conterm = ansi 412 | endif ; terminal eq console 413 | 414 | ; Auxiliary ... 415 | 416 | if auxterm eq ansi 417 | 418 | ; The following string is only needed if the console and auxiliary terminals 419 | ; are different types 420 | 421 | if auxterm ne conterm 422 | 423 | export aclstr 424 | ;aclstr: 425 | defb 4,esc,'[2J' ; ANSI screen clearing 426 | 427 | endif ; auxterm ne conterm 428 | endif ; auxterm eq ansi 429 | 430 | endif ;defdata 431 | -------------------------------------------------------------------------------- /src/d8227.tty: -------------------------------------------------------------------------------- 1 | ; ___________________________________________________________________________ 2 | ;| | 3 | ;| D8227.INC | 4 | ;| | 5 | ;| Device-specific and hardware-dependent code for Z8E debugger. | 6 | ;| | 7 | ;| This file is intended to support one or two Datapoint 8227 terminals, | 8 | ;| either real or virtual. Only two of these terminals ever existed but it | 9 | ;| is highly probable that the code will work for other Datapoint terminals | 10 | ;| in the 82xx series. | 11 | ;| | 12 | ;| Some assembly-time conditionals are provided to help adapting this file | 13 | ;| to different environments. | 14 | ;|___________________________________________________________________________| 15 | ;| | 16 | ;| There was a time when it was possible to patch the object code to support | 17 | ;| specific hardware. That facility is no longer offered. It is assumed | 18 | ;| that anyone who is likely to be interested in using this program to debug | 19 | ;| software at the assembly language detail would have the means to write or | 20 | ;| adapt a module like this one and to rebuild the debugger from the source | 21 | ;| code. | 22 | ;|___________________________________________________________________________| 23 | ;| | 24 | ;| This file is written to be as generic as possible and so should be easy | 25 | ;| to adapt to different hardware. | 26 | ;|___________________________________________________________________________| 27 | 28 | ; This file is included twice when assembling. The first time just loads 29 | ; the code, the second time defines the data associated with the code. 30 | 31 | if defcode ; Load code 32 | 33 | ; ___________________________________________________________________ 34 | ;| | 35 | ;| Z8E imposes only one restriction on the code you write. In order | 36 | ;| to guarantee that your routines can be relocated into high memory | 37 | ;| by Z8E do not load any 16 bit constants into register pairs; | 38 | ;| instead do two 8 bit loads. For example, do not use the | 39 | ;| following statement: | 40 | ;| | 41 | ;| ld de,1234h | 42 | ;| | 43 | ;| Rather, code it like this: | 44 | ;| | 45 | ;| ld d,12h | 46 | ;| ld e,34h | 47 | ;| | 48 | ;| With luck you won't need to load a constant into an index | 49 | ;| register but if you do there are a few ways around the problem. | 50 | ;| This one will work on a Z80 (but not on a Z180), does not depend | 51 | ;| on the assembler chosen and does not touch any other register: | 52 | ;| | 53 | ;| Instead of: ld ix,5678h ld iy,5678h | 54 | ;| | 55 | ;| code: defb 0DDh defb 0FDh | 56 | ;| ld h,56h ld h,56h | 57 | ;| defb 0DDh defb 0FDh | 58 | ;| ld l,78h ld l,78h | 59 | ;|___________________________________________________________________| 60 | 61 | ;;=========================================================================== 62 | ;; mttyq: 63 | ;; Main console input status routine 64 | ;; 65 | ;; This a conditional input routine, i.e. a non-blocking read. If a console 66 | ;; key has been pressed then it returns the character generated by that key 67 | ;; otherwise it returns 0. 68 | ;;=========================================================================== 69 | export mttyq 70 | ;mttyq: 71 | ld c,11 ; Console input status 72 | call bdos 73 | and a ; Is a character available? 74 | ret z ; Return zero if nothing there 75 | ; Othersise fall through to input 76 | ; routine 77 | 78 | ;;=========================================================================== 79 | ;; mttyi: 80 | ;; Main physical keyboard input routine 81 | ;; (Default is CP/M console device) 82 | ;;=========================================================================== 83 | export mttyi 84 | ;mttyi: 85 | ld c,6 86 | 87 | if CPM3 88 | ld e,0FDh ; CP/M+ interpretation of E register: 89 | ; FF -> return 0 if nothing available 90 | ; -> otherwise the character 91 | ; FE -> return 0 if nothing available 92 | ; -> return FF if there is something 93 | ; (in which case a 2nd call is 94 | ; needed to fetch the character). 95 | ; FD -> Block until character is ready 96 | ; then return it. 97 | else ; 98 | ld e,0FFh ; CP/M 2 doesn't assign special meaning 99 | endif ; to E=FE or FD. 100 | 101 | call bdos ; Fetch character 102 | and 7FH ; Mask off high bit 103 | jr z,mttyi ; Loop if no character or a NUL 104 | ret 105 | 106 | ;;=========================================================================== 107 | ;; mttyo: 108 | ;; Main physical console output routine 109 | ;; (Default is CP/M console device) 110 | ;;=========================================================================== 111 | 112 | export mttyo 113 | ;mttyo: 114 | ld c,6 115 | call bdos 116 | ret 117 | 118 | ;;=========================================================================== 119 | ;; mxycp: 120 | ;; Main console screen cursor positioning routine 121 | ;; 122 | ;; Uses MXYSTR, MROWB4, MROW and MCOL for configuration. 123 | ;; 124 | ;; The version supplied here is for a Datapoint 8227 terminal, only two of 125 | ;; which ever existed. 126 | ;; 127 | ;; This routine places the cursor at the row in B and the column in C. 128 | ;; Position (0,0) is the top left corner of the screen. 129 | ;; 130 | ;; If Z8E is being assembled to use two terminals and those two terminals 131 | ;; have very similar characteristics then the code herein may be shared with 132 | ;; the auxiliary screen cursor positioning routine. 133 | ;;=========================================================================== 134 | 135 | export mxycp 136 | ;mxycp: 137 | 138 | ld hl,mxystr ; Cursor addressing string 139 | ld a,(mrow) ; Get row bias (zero for 8227) 140 | add a,b ; Add row 141 | ld b,a ; Save row selector 142 | ld a,(mcol) ; Get column bias (zero for 8227) 143 | add a,c ; Add column 144 | ld c,a ; Save column selector 145 | ld e,(hl) ; Get length of cursor addressing string 146 | mxy0: 147 | inc hl ; Step string pointer 148 | ld a,(hl) ; Get character from cursor addressing string 149 | call ttyo ; Send character to terminal 150 | dec e ; Count down 151 | jr nz,mxy0 ; Loop until all sent 152 | ld a,(mrow4) ; Row first or column first? 153 | and a 154 | jr nz,mxy1 ; Skip if row first 155 | ld a,b ; x,y addressing, interchange row and column 156 | ld b,c 157 | ld c,a 158 | mxy1: 159 | ld a,b ; Send first coordinate 160 | call ttyo 161 | ld a,c ; Send second coordinate 162 | call ttyo 163 | ret 164 | 165 | ;;=========================================================================== 166 | ;; mcls: 167 | ;; Main console screen clearing routine 168 | ;; 169 | ;; Uses MCLSTR for configuration. 170 | ;; 171 | ;; The version supplied here is for a Datapoint 8227 terminal, only two of 172 | ;; which ever existed. 173 | ;; 174 | ;; If Z8E is being assembled to use two terminals and those two terminals 175 | ;; have very similar characteristics then the code herein may also be used 176 | ;; as the auxiliary screen cursor positioning routine. 177 | ;;=========================================================================== 178 | 179 | export mcls 180 | ;mcls: 181 | 182 | ld hl,mclstr ; Screen clearing string 183 | ld b,(hl) ; Get length of string 184 | mcls0: 185 | inc hl ; Step string pointer 186 | ld a,(hl) ; Get character from screen clearing string 187 | call ttyo ; Send character to terminal 188 | djnz mcls0 ; Count down and loop until all sent 189 | ret 190 | 191 | endif ; conterm = d8227 192 | endif ; terminal = console 193 | 194 | ;############################################################################ 195 | ;# THE CODE FROM HERE ONWARDS ONLY EXISTS IF Z8E IS BEING ASSEMBLED TO USE # 196 | ;# AN AUXILIARY TERMINAL FOR THE DEBUGGING DISPLAY, LEAVING THE CONSOLE FOR # 197 | ;# USE BY THE APPLICATION BEING MONITORED. # 198 | ;############################################################################ 199 | 200 | ; Load these drivers if we need support for an auxiliary terminal 201 | if terminal eq auxiliary 202 | if auxterm eq d8227 203 | 204 | ;;=========================================================================== 205 | ;; attyq: 206 | ;; Auxiliary physical keyboard input status routine. 207 | ;; 208 | ;; This only exists if Z8E is being assembled to support dual terminals. 209 | ;; 210 | ;; This is a conditional input routine - a non-blocking read. It returns a 211 | ;; character from the auxiliary terminal if a key has been pressed, otherwise 212 | ;; it returns 0. 213 | ;;=========================================================================== 214 | 215 | export attyq 216 | ;attyq: 217 | 218 | ; If only the main console is active then use that. 219 | 220 | ld a,(auxon) ; Is auxiliary terminal active? 221 | or a 222 | jr z,mttyq ; No - check console status instead 223 | 224 | ; Auxiliary terminal is in use ... 225 | 226 | ; For CP/M+ the auxiliary input status is available as a BDOS call. 227 | 228 | if cpm3 229 | 230 | ld c,7 ; Auxiliary input status 231 | call bdos 232 | or a ; Is a character available? 233 | ret z ; No: return a zero 234 | ; Yes: fall through to input routine 235 | else ; cpm3 236 | 237 | ; Not CP/M+. Insert code to read a port here. 238 | ; Example for SB180's serial port 0: 239 | 240 | xor a 241 | ld b,a 242 | in a,(4) ; Read serial port status register 243 | and 80h ; Isolate high bit 244 | ret z ; Return zero if nothing there 245 | ; Fall through to input routine 246 | endif ; cpm3 247 | 248 | ;;=========================================================================== 249 | ;; attyi: 250 | ;; Auxiliary physical keyboard input routine 251 | ;; (Default is CP/M reader input device) 252 | ;;=========================================================================== 253 | 254 | export attyi 255 | ;attyi: 256 | ld a,(auxon) ; Is 2nd terminal active? 257 | or a 258 | jr z,mttyi ; No, use console 259 | 260 | ld c,3 ; Auxiliary input (blocking) 261 | call bdos 262 | 263 | and 7Fh ; Mask off the high bit 264 | jr z,attyi ; Ignore a NUL character 265 | ret 266 | 267 | 268 | ;;=========================================================================== 269 | ;; attyo: 270 | ;; Auxiliary physical console output routine 271 | ;; (Default is CP/M punch output device) 272 | ;;=========================================================================== 273 | 274 | export attyo 275 | ;attyo: 276 | ld c,4 ; AUX/PUN output 277 | call bdos 278 | ret 279 | 280 | ;;=========================================================================== 281 | ;; axycp: 282 | ;; Auxiliary terminal cursor positioning routine 283 | ;; 284 | ;; Uses AXYSTR, AROWB4, AROW and ACOL for configuration. 285 | ;; 286 | ;; The version supplied here is for a Datapoint 82xx terminal. 287 | ;; 288 | ;; This routine places the cursor at the row in B and the column in C. 289 | ;; Position (0,0) is the top left corner of the screen. 290 | ;;=========================================================================== 291 | 292 | ; This driver is only needed if the console and auxiliary terminals are of 293 | ; different types. If they are the same then Z8E can use the console driver 294 | ; to position the cursor on the auxiliary screen. 295 | 296 | if auxterm ne conterm 297 | 298 | export axycp 299 | ;axycp: 300 | 301 | ld hl,axystr ; Cursor addressing string 302 | ld a,(arow) ; Get row bias 303 | add a,b ; Add row 304 | ld b,a ; Save row selector 305 | ld a,(acol) ; Get column bias 306 | add c ; Add column 307 | ld c,a ; Save column selector 308 | ld e,(hl) ; Get length of cursor addressing string 309 | axy0: 310 | inc hl ; Step string pointer 311 | ld a,(hl) ; Get character from cursor addressing string 312 | call ttyo ; Send character to terminal 313 | dec e ; Count down 314 | jr nz,axy0 ; Loop until all sent 315 | ld a,(arowb4) ; Row first or column first? 316 | and a 317 | jr nz,axy1 ; Skip if row first 318 | ld a,b ; x,y addressing, interchange row and column 319 | ld b,c 320 | ld c,a 321 | axy1: 322 | ld a,b ; Send first coordinate 323 | call ttyo 324 | ld a,c ; Send second coordinate 325 | call ttyo 326 | ret 327 | 328 | ;;=========================================================================== 329 | ;; acls: 330 | ;; Auxiliary terminal screen clearing routine 331 | ;; 332 | ;; Uses ACLSTR for configuration. 333 | ;; 334 | ;; The version supplied here is for a Datapoint 82xx terminal. 335 | ;;=========================================================================== 336 | 337 | export acls 338 | ;acls: 339 | 340 | ld hl,aclstr ; Screen clearing string 341 | ld b,(hl) ; Get length of string 342 | acls0: 343 | inc hl ; Step string pointer 344 | ld a,(hl) ; Get character from screen clearing string 345 | call ttyo ; Send character to terminal 346 | djnz acls0 ; Count down and loop until all sent 347 | ret 348 | 349 | endif ; auxterm ne conterm 350 | endif ; auxterm ne d8227 351 | endif ; terminal ne auxiliary 352 | endif ; defcode 353 | 354 | ;###################################################################### 355 | ;# Second round inclusion ... define data areas for code shown above. # 356 | ;###################################################################### 357 | 358 | if defdata 359 | 360 | ; The code portions are loaded by including this file twice, once for each 361 | ; terminal. The data portions are handled in a single inclusion. 362 | 363 | ; Auxiliary 364 | 365 | if auxterm eq d8227 366 | 367 | ; Configuration bytes for auxiliary terminal - Datapoint 8227 and similar. 368 | 369 | export arowb4 370 | ;arowb4: 371 | defb 0 ; 8227 uses x,y addressing, i.e. column first. 372 | ; y,x (row first) is more common. 373 | 374 | export arow 375 | ;arow: 376 | defb 0 ; No bias for cursor row coordinates 377 | 378 | export acol 379 | ;acol: 380 | defb 0 ; Same for column 381 | 382 | export axystr 383 | ;axystr: 384 | defb 1, tab ; 8227 cursor positioning 385 | 386 | export aclstr 387 | ;aclstr: 388 | defb 2,15h,17h ; 8227 screen clearing 389 | 390 | endif ; auxterm eq d8227 391 | 392 | ; Console 393 | 394 | if conterm eq d8227 395 | 396 | ; Configuration bytes for console - Datapoint 8227 and similar 397 | 398 | export mrowb4 399 | ;mrowb4: 400 | defb 0 ; D8227 uses x,y addressing, i.e. column 401 | ; first. Most others use y,x addressing. 402 | 403 | export mrow 404 | ;mrow: 405 | defb 0 ; D8227 uses no bias for cursor coordinates 406 | ; Most others use ' ' 407 | 408 | export mcol 409 | ;mcol: 410 | defb 0 ; Same for column 411 | 412 | export mxystr 413 | ;mxystr: 414 | defb 1,tab ; D8227 wants tab,col,row to position cursor 415 | ; so the leadin string is just one byte 416 | 417 | export mclstr 418 | ;mclstr: 419 | defb 2,15h,17h ; 8227 screen clearing 420 | 421 | endif ; conterm eq d8227 422 | 423 | endif ; defdata 424 | -------------------------------------------------------------------------------- /src/adm3a.tty: -------------------------------------------------------------------------------- 1 | ; ___________________________________________________________________________ 2 | ;| | 3 | ;| ADM3A.INC | 4 | ;| | 5 | ;| Device-specific and hardware-dependent code for Z8E debugger. | 6 | ;| | 7 | ;| This file is intended to support one or two Lear-Siegler ADM3A or similar | 8 | ;| terminals, either real or virtual. | 9 | ;| | 10 | ;| Because the cursor positioning sequence is common to several terminals | 11 | ;| including Wyse, Televideo and Soroc models it may be possible to match | 12 | ;| use this file for other terminals. | 13 | ;| | 14 | ;| Some assembly-time conditionals are provided to help adapting this file | 15 | ;| to different environments. | 16 | ;|___________________________________________________________________________| 17 | ;| | 18 | ;| There was a time when it was possible to patch the object code to support | 19 | ;| specific hardware. That facility is no longer offered. It is assumed | 20 | ;| that anyone who is likely to be interested in using this program to debug | 21 | ;| software at the assembly language detail would have the means to write or | 22 | ;| adapt a module like this one and to rebuild the debugger from the source | 23 | ;| code. | 24 | ;|___________________________________________________________________________| 25 | ;| | 26 | ;| This file is written to be as generic as possible and so should be easy | 27 | ;| to adapt to different hardware. | 28 | ;|___________________________________________________________________________| 29 | 30 | 31 | ; This file is included twice when assembling. The first time just loads 32 | ; the code, the second time defines the data associated with the code. 33 | 34 | if defcode ; Load code 35 | 36 | ; ___________________________________________________________________ 37 | ;| | 38 | ;| Z8E imposes only one restriction on the code you write. In order | 39 | ;| to guarantee that your routines can be relocated into high memory | 40 | ;| by Z8E do not load any 16 bit constants into register pairs; | 41 | ;| instead do two 8 bit loads. For example, do not use the | 42 | ;| following statement: | 43 | ;| | 44 | ;| ld de,1234h | 45 | ;| | 46 | ;| Rather, code it like this: | 47 | ;| | 48 | ;| ld d,12h | 49 | ;| ld e,34h | 50 | ;| | 51 | ;| With luck you won't need to load a constant into an index | 52 | ;| register but if you do there are a few ways around the problem. | 53 | ;| This one will work on a Z80 (but not on a Z180), does not depend | 54 | ;| on the assembler chosen and does not touch any other register: | 55 | ;| | 56 | ;| Instead of: ld ix,5678h ld iy,5678h | 57 | ;| | 58 | ;| code: defb 0DDh defb 0FDh | 59 | ;| ld h,56h ld h,56h | 60 | ;| defb 0DDh defb 0FDh | 61 | ;| ld l,78h ld l,78h | 62 | ;|___________________________________________________________________| 63 | 64 | if terminal eq console 65 | if conterm eq adm3a 66 | 67 | ;;=========================================================================== 68 | ;; mttyq: 69 | ;; Main console input status routine 70 | ;; 71 | ;; This a conditional input routine, i.e. a non-blocking read. If a console 72 | ;; key has been pressed then it returns the character generated by that key 73 | ;; otherwise it returns 0. 74 | ;;=========================================================================== 75 | export mttyq 76 | ;mttyq: 77 | ld c,11 ; Console input status 78 | call bdos 79 | and a ; Is a character available? 80 | ret z ; Return zero if nothing there 81 | ; Othersise fall through to input 82 | ; routine 83 | 84 | ;;=========================================================================== 85 | ;; mttyi: 86 | ;; Main physical keyboard input routine 87 | ;; (Default is CP/M console device) 88 | ;;=========================================================================== 89 | export mttyi 90 | ;mttyi: 91 | ld c,6 92 | 93 | if CPM3 94 | ld e,0FDh ; CP/M+ interpretation of E register: 95 | ; FF -> return 0 if nothing available 96 | ; -> otherwise the character 97 | ; FE -> return 0 if nothing available 98 | ; -> return FF if there is something 99 | ; (in which case a 2nd call is 100 | ; needed to fetch the character). 101 | ; FD -> Block until character is ready 102 | ; then return it. 103 | else ; 104 | ld e,0FFh ; CP/M 2 doesn't assign special meaning 105 | endif ; to E=FE or FD. 106 | 107 | call bdos ; Fetch character 108 | and 7FH ; Mask off high bit 109 | jr z,mttyi ; Loop if no character or a NUL 110 | ret 111 | 112 | ;;=========================================================================== 113 | ;; mttyo: 114 | ;; Main physical console output routine 115 | ;; (Default is CP/M console device) 116 | ;;=========================================================================== 117 | 118 | export mttyo 119 | ;mttyo: 120 | ld e,a 121 | ld c,6 122 | call bdos 123 | ret 124 | 125 | ;;=========================================================================== 126 | ;; mxycp: 127 | ;; Main console screen cursor positioning routine 128 | ;; 129 | ;; Uses MXYSTR, MROWB4, MROW and MCOL for configuration. 130 | ;; 131 | ;; The version supplied here is for an ADM3A or similar terminal. 132 | ;; 133 | ;; This routine places the cursor at the row in B and the column in C. 134 | ;; Position (0,0) is the top left corner of the screen. 135 | ;; 136 | ;; If Z8E is being assembled to use two terminals and those two terminals 137 | ;; have very similar characteristics then the code herein may also be used 138 | ;; as the auxiliary screen cursor positioning routine. 139 | ;;=========================================================================== 140 | 141 | export mxycp 142 | ;mxycp: 143 | 144 | ld hl,mxystr ; Cursor addressing string 145 | ld a,(mrow) ; Get row bias 146 | add a,b ; Add row 147 | ld b,a ; Save row selector 148 | ld a,(mcol) ; Get column bias 149 | add a,c ; Add column 150 | ld c,a ; Save column selector 151 | ld e,(hl) ; Get length of cursor addressing string 152 | mxy0: 153 | inc hl ; Step string pointer 154 | ld a,(hl) ; Get character from cursor addressing string 155 | call ttyo ; Send character to terminal 156 | dec e ; Count down 157 | jr nz,mxy0 ; Loop until all sent 158 | ld a,(mrow4) ; Row first or column first? 159 | and a 160 | jr nz,mxy1 ; Skip if row first 161 | ld a,b ; x,y addressing, interchange row and column 162 | ld b,c 163 | ld c,a 164 | mxy1: 165 | ld a,b ; Send first coordinate 166 | call ttyo 167 | ld a,c ; Send second coordinate 168 | call ttyo 169 | ret 170 | 171 | ;;=========================================================================== 172 | ;; mcls: 173 | ;; Main console screen clearing routine 174 | ;; 175 | ;; Uses MCLSTR for configuration. 176 | ;; 177 | ;; The version supplied here is for an ADM3A or similar terminal. 178 | ;; 179 | ;; If Z8E is being assembled to use two terminals and those two terminals 180 | ;; have very similar characteristics then the code herein may also be used 181 | ;; as the auxiliary screen cursor positioning routine. 182 | ;;=========================================================================== 183 | 184 | export mcls 185 | ;mcls: 186 | 187 | ld hl,mclstr ; Screen clearing string 188 | ld b,(hl) ; Get length of string 189 | mcls0: 190 | inc hl ; Step string pointer 191 | ld a,(hl) ; Get character from screen clearing string 192 | call ttyo ; Send character to terminal 193 | djnz mcls0 ; Count down and loop until all sent 194 | ret 195 | 196 | endif ; conterm = adm3a 197 | endif ; terminal = console 198 | 199 | ;############################################################################ 200 | ;# THE CODE FROM HERE ONWARDS ONLY EXISTS IF Z8E IS BEING ASSEMBLED TO USE # 201 | ;# AN AUXILIARY TERMINAL FOR THE DEBUGGING DISPLAY, LEAVING THE CONSOLE FOR # 202 | ;# USE BY THE APPLICATION BEING MONITORED. # 203 | ;############################################################################ 204 | 205 | ; Load these drivers if we need support for an auxiliary terminal 206 | if terminal eq auxiliary 207 | if auxterm eq adm3a 208 | 209 | ;;=========================================================================== 210 | ;; attyq: 211 | ;; Auxiliary physical keyboard input status routine. 212 | ;; 213 | ;; This only exists if Z8E is being assembled to support dual terminals. 214 | ;; 215 | ;; This is a conditional input routine - a non-blocking read. It returns a 216 | ;; character from the auxiliary terminal if a key has been pressed, otherwise 217 | ;; it returns 0. 218 | ;;=========================================================================== 219 | 220 | export attyq 221 | ;attyq: 222 | 223 | ; If only the main console is active then use that. 224 | 225 | ld a,(auxon) ; Is auxiliary terminal active? 226 | or a 227 | jr z,mttyq ; No - check console status instead 228 | 229 | ; Auxiliary terminal is in use ... 230 | 231 | ; For CP/M+ the auxiliary input status is available as a BDOS call. 232 | 233 | if cpm3 234 | 235 | ld c,7 ; Auxiliary input status 236 | call bdos 237 | or a ; Is a character available? 238 | ret z ; No: return a zero 239 | ; Yes: fall through to input routine 240 | else ;cpm3 241 | 242 | ; Not CP/M+. Insert code to read a port here. 243 | ; Example for SB180's serial port 0: 244 | 245 | xor a ; Force high address lines to zero 246 | ld b,a 247 | in a,(4) ; Read serial port status register 248 | and 80h ; Isolate high bit 249 | ret z ; Return zero if nothing there 250 | ; Fall through to input routine 251 | endif ;cpm3 252 | 253 | ;;=========================================================================== 254 | ;; attyi: 255 | ;; Auxiliary physical keyboard input routine 256 | ;; (Default is CP/M reader input device) 257 | ;;=========================================================================== 258 | 259 | export attyi 260 | ;attyi: 261 | ld a,(auxon) ; Is 2nd terminal active? 262 | or a 263 | jr z,mttyi ; No, use console 264 | 265 | ld c,3 ; Auxiliary input (blocking) 266 | call bdos 267 | 268 | and 7Fh ; Mask off the high bit 269 | jr z,attyi ; Ignore a NUL character 270 | ret 271 | 272 | ;;=========================================================================== 273 | ;; attyo: 274 | ;; Auxiliary physical console output routine 275 | ;; (Default is CP/M punch output device) 276 | ;;=========================================================================== 277 | 278 | export attyo 279 | ;attyo: 280 | ld c,4 ; AUX/PUN output 281 | call bdos 282 | ret 283 | 284 | ;;=========================================================================== 285 | ;; axycp: 286 | ;; Auxiliary terminal cursor positioning routine 287 | ;; 288 | ;; Uses AXYSTR, AROWB4, AROW and ACOL for configuration. 289 | ;; 290 | ;; The version supplied here is for an ADM3A but may work for others such as 291 | ;; Wyse, Televideo or Soroc. 292 | ;; 293 | ;; This routine places the cursor at the row in B and the column in C. 294 | ;; Position (0,0) is the top left corner of the screen. 295 | ;;=========================================================================== 296 | 297 | ; This driver is only needed if the console and auxiliary terminal are 298 | ; different types. If they are the same then Z8E can use the console driver 299 | ; to position the cursor on the auxiliary screen. 300 | 301 | if auxterm ne conterm 302 | 303 | export axycp 304 | ;axycp: 305 | 306 | ld hl,axystr ; Cursor addressing string 307 | ld a,(arow) ; Get row bias 308 | add a,b ; Add row 309 | ld b,a ; Save row selector 310 | ld a,(acol) ; Get column bias 311 | add a,c ; Add column 312 | ld c,a ; Save column selector 313 | ld e,(hl) ; Get length of cursor addressing string 314 | axy0: 315 | inc hl ; Step string pointer 316 | ld a,(hl) ; Get character from cursor addressing string 317 | call ttyo ; Send character to terminal 318 | dec e ; Count down 319 | jr nz,axy0 ; Loop until all sent 320 | ld a,(arowb4) ; Row first or column first? 321 | and a 322 | jr nz,axy1 ; Skip if row first 323 | ld a,b ; x,y addressing, interchange row and column 324 | ld b,c 325 | ld c,a 326 | axy1: 327 | ld a,b ; Send first coordinate 328 | call ttyo 329 | ld a,c ; Send second coordinate 330 | call ttyo 331 | ret 332 | 333 | ;;=========================================================================== 334 | ;; acls: 335 | ;; Auxiliary terminal screen clearing routine 336 | ;; 337 | ;; Uses ACLSTR for configuration. 338 | ;; 339 | ;; The version supplied here is for an ADM3A but may work for others such as 340 | ;; Wyse, Televideo or Soroc. 341 | ;;=========================================================================== 342 | 343 | export acls 344 | ;acls: 345 | 346 | ld hl,aclstr ; Screen clearing string 347 | ld b,(hl) ; Get length of string 348 | acls0: 349 | inc hl ; Step string pointer 350 | ld a,(hl) ; Get character from screen clearing string 351 | call ttyo ; Send character to terminal 352 | djnz acls0 ; Count down and loop until all sent 353 | ret 354 | 355 | endif ; auxterm ne conterm 356 | endif ; terminal ne adm3a 357 | endif ; terminal ne auxiliary 358 | endif ; defcode 359 | 360 | if defdata 361 | ;###################################################################### 362 | ;# Second round inclusion ... define data areas for code shown above. # 363 | ;###################################################################### 364 | 365 | ; The code portions are loaded by including this file twice, once for 366 | ; each terminal. The data portions are handled in a single inclusion. 367 | 368 | ; Console ... 369 | 370 | if conterm eq adm3a ; then we definitely need these 371 | 372 | ; Configuration bytes for main terminal - ADM3A (and similar) 373 | 374 | export mrowb4 375 | ;mrowb4: 376 | defb 1 ; ADM3A uses y,x addressing, i.e. row first. 377 | ; This is the more common coordinate order. 378 | 379 | export mrow 380 | ;mrow: 381 | defb ' ' ; Bias for cursor row coordinates 382 | 383 | export mcol 384 | ;mcol: 385 | defb ' ' ; Same for column 386 | 387 | export mxystr 388 | ;mxystr: 389 | defb 2,esc,'=' ; ADM3A cursor positioning 390 | 391 | export mclstr 392 | ;mclstr: 393 | defb 1,1Ah ; ADM3A screen clearing 394 | 395 | endif ; conterm = adm3a 396 | 397 | ; Auxiliary ... 398 | 399 | if auxterm eq adm3a 400 | 401 | ; Configuration bytes for auxiliary terminal - ADM3A and similar 402 | 403 | export arowb4 404 | ;arowb4: 405 | defb 1 ; ADM3A uses y,x addressing, i.e. row first. 406 | ; This is the more common coordinate order. 407 | 408 | export arow 409 | ;arow: 410 | defb ' ' ; Bias for cursor row coordinates 411 | 412 | export acol 413 | ;acol: 414 | defb ' ' ; Same for column 415 | 416 | ; The lead-in string is only needed if the console and auxiliary terminals 417 | ; are different types 418 | 419 | if auxterm ne conterm 420 | 421 | export axystr 422 | ;axystr: 423 | defb 2,esc,'=' ; ADM3A cursor positioning 424 | 425 | export aclstr 426 | ;aclstr: 427 | defb 1,1Ah ; ADM3A screen clearing 428 | 429 | endif ; auxterm ne conterm 430 | endif ; auxterm eq adm3a 431 | endif ;defdata 432 | --------------------------------------------------------------------------------