; QTERM patch file for the Sinclair ZX Spectrum +3, running Locomotive ; CP/M Plus. ; Russell Marks, 94/06/07 (rm1ajy3@gre.ac.uk from Oct. 94, probably) ; You'll need this file (qt-plus3.z) as well as qterm.com, zsm.com and ; zpatch.com. Qterm.com is in qterm43e.lbr, the latter two are in ; qtpat42.lbr. (See /pub/cpm/starter-kit and /pub/cpm/gendoc/os-cpm.faq ; if you don't know what a '.lbr' file is.) ; Then do this to make a speccy qterm.com: ; A>zsm qt-plus3.z ; ZSM V2.3 - (C) Copyright DPG 1987 ; ; A>zpatch qterm.com qt-plus3.o ; ZPATCH V2.3 - (C) Copyright DPG 1987 ; ; Then try it out, but you'll have to set up the SIO with setsio ; before starting, as I haven't bothered to add the SIO config. ; patch bits yet. Sorry. ; Cheers, and good luck! (From a CP/M newbie of three weeks) ; This patch mostly uses the I/O functions supplied by the bdos ; which deal with AUX:, so you may be able to get them to work with ; the external modem port (that plugs into the expansion bit on the ; back). However it's intended for use with the nasty old internal ; 6-pin weirdo serial port, and has only been tested on such. ; the escape char is ^\, which is EXTEND + EDIT unless you've remapped ; your keyboard. ; Since the +3 is a strange beast, this isn't quite as easy as it should ; be. I initially tried a straight patch using bdos calls, which worked ; but only responded to keypresses if the key was held down for a fair ; time (half a second or so). This patch kludges round that by only ; allowing the 'modem input status' routine to really check the SIO ; status every 8 tries, which seems to give a reasonable time for the ; interrupt-driven keyboard read routine in CP/M to do its' work. ; (It disables interrupts when checking the 'serial port', you see.) ; However, this slows down the serial input a fair bit, so I also check ; if the last time it really checked the input status there was a char. ; ready. If so, it skips the delay and allows the real SIO check to ; happen straight away. This is the best compromise I can come up with, ; and it's quite useable, I think. It also works ok for file transfers. .org 0x0110 modist: jp kludge ;jump to large-ish routine described above .org 0x0120 modin: ld c,3 call 5 ;bdos, read char. from AUX ret .org 0x130 modost: ld c,8 call 5 and a ret .org 0x0140 modout: ld c,4 ld e,a call 5 ret ;no break for now .org 0x0150 sbreak: ret .org 0x0160 ebreak: ret ;no dtr raise/drop for now .org 0x0170 dtroff: ret .org 0x0180 dtron: ret ;set baud rate - uh, guess :) ;you'll have to use 'setsio' for now. .org 0x0190 setbd: ret .org 0x01a0 baudtb: b38400: db 0,0 b19200: db 0,0 b9600: db 0,0 b4800: db 0,0 b2400: db 0,0 b1200: db 0,0 b600: db 0,0 b300: db 0,0 ;more of the same .org 0x01b0 setmod: ret ; [from qt-patch.z, in case I decide to do this stuff sometime] ; Communication Mode Table. Single byte values for 12 combinations of ; number-of-bits(7/8), parity(none/even/odd), number-of-stop-bits(1/2). .org 0x01c0 modetb: n17: db 0b10000000 ;0x80, 7n1 n18: db 0b11000000 ;0xc0, 8n1 n27: db 0b10001000 ;0x88, 7n2 n28: db 0b11001000 ;0xc8, 8n2 e17: db 0b10000011 ;0x83, 7e1 e18: db 0b11000011 ;0xc3, 8e1 e27: db 0b10001011 ;0x8b, 7e2 e28: db 0b11001011 ;0xcb, 8e2 o17: db 0b10000001 ;0x81, 7o1 o18: db 0b11000001 ;0xc8, 8o1 o27: db 0b10001001 ;0x89, 7o2 o28: db 0b11001001 ;0xc9, 8o2 .org 0x01cc resvd: db 0 xfersz: db 8 speed: db 4 ;3.55 MHz, rounded up escape: db '\\' & 0x1f ;escape char. - ^\, better known as EXTEND MODE + EDIT .org 0x1d0 signon: db 'Sinclair ZX Spectrum +3',0 .org 0x1f0 clrs: db '\eH\eJ',0 ;clear screen with ESC H ESC J .var scrout 0x109 ; move to h,l on screen .org 0x200 moveto: push hl ld c,27 call scrout ld c,'Y' call scrout pop hl push hl ld a,h call addprn pop hl ld a,l addprn: add a,32 ld c,a jp scrout ; [from qt-patch.z] ; Terminal Capability Bits. The eight bits stand for each of the following ; strings. They count from 01h=bright to 80h=clear-to-end-of-screen. .var b_brit 0b00000001 ; 0: bright (1.) -- NOT mandatory .var b_dim 0b00000010 ; 1: dim (2.) -- NOT mandatory .var b_dlln 0b00000100 ; 2: delete line (4.) -- important .var b_inln 0b00001000 ; 3: insert line (8.) -- important .var b_dlch 0b00010000 ; 4: delete character (16.)-- unused by QTERM .var b_inch 0b00100000 ; 5: insert character (32.)-- NOT mandatory .var b_clel 0b01000000 ; 6: clear to end-of-line(64.) -- important .var b_cles 0b10000000 ; 7: clear to end-of-screen(128.)-- important .org 0x022f trmcap: db b_brit + b_dim + b_dlln + b_inln + b_dlch + b_clel + b_cles ; Here I render the bright/dim as underline, as reverse video is damned ; hard to read on a TV. :( Change to ESC q and ESC p respectively if ; you want rev. video. .org 0x0230 brites: db '\eu',0 ;stop underline .org 0x0238 dims: db '\er',0 ;start underline .org 0x0240 dlstr: db '\eM',0 ;delete line .org 0x0248 ilstr: db '\eL',0 ;insert line .org 0x0250 dcstr: db '\eN',0 ;delete char. - unused? .org 0x0258 icstr: db 0 ;speccy doesn't have one .org 0x0260 ceol: db '\eK',0 ;clear to end of line .org 0x0268 ceos: db '\eJ',0 ;clear to end of screen ;now the various hooks. ;these are in xyzzy mode at the moment, i.e. nothing happens. :) .org 0x0270 entry: ret .org 0x0273 exit: ret .org 0x0276 user: ret ;maybe I should fix the cursors or summink, but I can't be bothered .org 0x0279 kbmap: ret ;extra patch area from 0x280 .var cinit 8 ;the input-status-delay kludge .org 0x0280 kludge: ld a,(lastb) and a jr nz,rcheck ld a,(count) dec a ld (count),a jr z,rcheck xor a ret rcheck: ld a,cinit ld (count),a ld c,7 call 5 ;actually check it and a push af ld a,1 jr nz,skip xor a skip: ld (lastb),a pop af ret count: db cinit lastb: db 0