diff --git a/Source/Apps/ZMP/zmo-rw01.z80 b/Source/Apps/ZMP/zmo-rw01.z80 index 27b59637..6c9f4276 100644 --- a/Source/Apps/ZMP/zmo-rw01.z80 +++ b/Source/Apps/ZMP/zmo-rw01.z80 @@ -4,93 +4,26 @@ ; ; Name ZMO-RW01.Z80 ; -; Dated Sep 14, 1988 -; -; Written by - -; Ron Murray, c/o Z-Node 62, 061-9-450-0200, Perth, Western Australia. -; -; Modified to ZMP v1.2 standard rjm 15/9/88 -; Modified to ZMP v1.3 standard rjm 11/10/88 -; Modified to ZMP v1.4 standard rjm 20/11/88 -; Modified to ZMP v1.5 standard rjm 25/3/89 -; -; ZMO-RW01.Z80 ROMWBW version using HBIOS and https://github.com/mecparts/zmp version of zmodem +; ROMWBW version using HBIOS and https://github.com/mecparts/zmp version of zmodem ; Databits, stop bit, parity setting not supported. -; All i/o is through the hbios. -; Timing delay calcuations based on hbios reported cpu speed. -; Console is assumed to be current hbios CIO console -; Only 1 port is supported by this version of zmp. +; All modem/serial i/o is through the hbios. +; Timing delay calculations based on hbios reported cpu speed. +; Only 1 port is supported by the mecports version of zmp. ; Port setting supports 2 port, port A is CIO 1, port B is CIO 2 ; This overlay is compatible with Ron Murray's original ZMP15 which support two ports. ; Teraterm users may need to change the ZmodemWinSize value to 1024 in teraterm.ini file. ; ;----------------------------------------------------------------------------- ; -; -; System-dependent code overlay for ZMODEM -; -; -; -; Insert your own code as necessary in this file. Code contained herein -; has been written in Z80 code for use with M80 or SLR. Assemble as follows: -; -; SLR ZMO-xx01/h -; MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.HEX -; or -; M80 =ZMO-xx01.Z80 -; RELHEX ZMO-xx01 -; MLOAD ZMP.COM=ZMODEM.COM,ZMO-xx01.HEX -; -; -; (Don't use L80 without changing the source for assembly as a -; cseg file.) -; -;----------------------------------------------------------------------------- -; -; -; Notes on modifying this file: -; -; C requires that functions do not change either index register (IX or IY). -; If your overlay requires either of these to be changed, ensure they are -; restored to the original values on return. -; Since collecting parameters from C functions can be tricky, only change -; the parts marked 'Insert your own code here'. Do NOT modify the jump -; table at the start. Do NOT modify the entry/exit sections of each -; function. Do NOT pass 'GO'. Do NOT collect $200. -; Apart from defining modem functions, this file also defines terminal -; characteristics. Examples provided are for ADM-3A (with a few of my own -; additions). Modify to suit your own terminal. An inline print routine -; is provided for printing strings in the usual way: usage is -; -; call print -; db 'required string',0 -; -;----------------------------------------------------------------------------- -; -; -; Don't forget to set your clock speed at the clkspd variable. -; -; -; If you find your overlay exceeds the maximum size (currently 0400h), -; you will have to contact me for another version. If too many people need -; to do it, we haven't allowed enough room. -; -; Ron Murray 15/8/88 -; -; -; -;--------------------------------------------------------------------------- - false equ 0 true equ not false - +; ;------------------------------------------------------------------------------ - +; ; User-set variables: - -;clkspd equ 10 ; Processor clock speed in MHz +; debug equ false ; to allow debugging of overlay with Z8E etc. - +; ;Set the following two equates to the drive and user area which will contain ; ZMP's .OVR files, .CFG file, .FON file and .HLP file. Set both to zero ; (null) to locate them on the drive from which ZMP was invoked. @@ -103,8 +36,7 @@ overuser equ 0 ; User area to find files initbr equ 10 ; Refer to "baudtbl" table below - brate column ; ;------------------------------------------------------------------------------ - - +; ; NOT user-set variables userdef equ 0145h ; origin of this overlay @@ -112,7 +44,7 @@ userdef equ 0145h ; origin of this overlay ; subsequent revisions. mspeed equ 03ch ; location of current baud rate. ovsize equ 0400h ; max size of this overlay - +; .z80 ; use z80 code aseg ; absolute @@ -121,17 +53,16 @@ ovsize equ 0400h ; max size of this overlay else org userdef endif - - +; esc equ 1bh ctrlq equ 11h cr equ 0dh lf equ 0ah bdos equ 5 fcb equ 05ch+1 ; Command line - +; codebgn equ $ - +; ;Jump table for the overlay: do NOT change this jump_tab: jp scrnpr ; screen print @@ -162,7 +93,7 @@ jump_tab: jp userout ; user-defined exit routine jp getvars ; get system variables jp setport ; set port (0 or 1) - +; ; Spare jumps for compatibility with future versions jp spare ; spare for later use jp spare ; spare for later use @@ -180,42 +111,39 @@ port: db 1 ; current cio port. ; Main code starts here ; ;Screen print function -scrnpr: - ; <== Insert your own code here - call print +scrnpr: call print db 'This function not supported.',cr,lf,0 - ; <== End of your own code -spare: - ret - -; User-defined entry routine: leave empty if not needed +spare: ret +; +; User-defined entry routine: +; +; forcing reinit will resend AT command to modem, reset +; current line defaults and eat up buffered characters +; +; Get and set modem/serial ports to use from the command line ; ; Get the cpu speed reported by romwbw hbios and calculate -; the three required loop counter values for timing. +; the three required loop counter values for timing: ; ; outerva (outv) ; innerval (inv) ; millisv (msv) - -userin: - ld a,-1 ; force re-init ; forcing reinit will resend AT command to modem, reset - ld (mspeed),a ; current line defaults and eat up buffered characters - +; +userin: ld a,-1 ; force re-init + ld (mspeed),a +; ld a,(fcb) ; first character cp ' ' ; of parsed filename - jr z,defport0 ; is port 0 + jr z,dport1 ; is port 0 sub '0' ld (hbport0),a ; set CIO for port 0 ld (port),a ; reconfigure default -defport0: - ld a,(fcb+1) ; second character +dport0: ld a,(fcb+1) ; second character cp ' ' ; of parsed filename - jr z,defport1 ; is port 1 + jr z,dport1 ; is port 1 sub '0' ld (hbport1),a -defport1: -; - push bc +dport1: push bc ld bc,0f8f0h ; get clock speed in l rst 08 ; @@ -227,7 +155,7 @@ defport1: call div_hl_c ; result in hl ld a,l inc a - ld (outv),a + ld (outv),a ; save outerval ; ; innerval equ (6667 / outerval) * clkspd ; @@ -239,21 +167,20 @@ defport1: pop hl ; recall clock ld a,l ; save push af ; clock speed - +; call mult_a_de - ld (inv),hl - + ld (inv),hl ; save innerval ; ; ld de,39 * clkspd ; pop af ; recall clock speed ld de,39 call mult_a_de - ld (msv),hl + ld (msv),hl ; save msec value ; pop bc ret - +; outv: ds 1 ; outer value inv: ds 2 ; inner value msv: ds 2 ; millisec value @@ -261,16 +188,15 @@ msv: ds 2 ; millisec value ; maths helpers ; mult_a_de: ; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Multiplication - ld c, 0 - ld h, c - ld l, h - add a, a ; optimised 1st iteration + ld c,0 + ld h,c + ld l,h + add a,a ; optimised 1st iteration jr nc,$+4 ld h,d ld l,e ld b,7 -_loop2: - add hl,hl +_loop2: add hl,hl rla jr nc,$+4 add hl,de @@ -281,8 +207,7 @@ _loop2: div_hl_c: ; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Division xor a ld b,16 -_loop1: - add hl, hl +_loop1: add hl,hl rla jr c,$+5 cp c @@ -291,51 +216,33 @@ _loop1: inc l djnz _loop1 ; result in hl ret - +; ; User-defined exit routine: leave empty if not needed -userout: - call show +userout:call show ret - - +; ;Get a character from the modem: return in HL -mchin: - push bc - ; <== Insert your own code here - push de +mchin: push bc ld b,00h ld hl,port ld c,(hl) rst 08 - - ld a,e - pop de - ; <== End of your own code - - ld l,a ; put in HL -; ld h,0 -; or a ; set/clear Z + ld l,e pop bc ret ;Send a character to the modem -mchout: - ld hl,2 ; get the character +mchout: ld hl,2 ; get the character add hl,sp - ld a,(hl) - ; <== Insert your own code here - ld e,a + ld e,(hl) ld b,01h ld hl,port ld c,(hl) rst 08 - ; <== End of your own code ret ; done ;Test for output ready: return TRUE (1) in HL if ok -mordy: - ; <== Insert your own code here - ld b,03h +mordy: ld b,03h ld hl,port ld c,(hl) rst 08 @@ -343,80 +250,47 @@ mordy: or a jr z,modrdy1 ld a,1 -modrdy1: - ld l,a - ; <== End of your own code - - ld a,l ; set/clear Z or a +modrdy1:ld l,a ret ;Test for character at modem: return TRUE (1) in HL if so -mirdy: - ; <== Insert your own code here - push bc +mirdy: push bc ld b,02h ld hl,port ld c,(hl) rst 08 + ld h,0 or a jr z,mirdy1 ld a,1 -mirdy1: - ld l,a - ld h,0 + or a +mirdy1: ld l,a pop bc - - ; <== End of your own code -; ld a,l ; set/clear Z -; or a ret - +; ;Send a break to the modem: leave empty if your system can't do it -sndbrk: - ; <== Insert your own code here - - ld hl,300 ; wait 300 mS +sndbrk: ld hl,300 ; wait 300 mS call waithlms - - ; <== End of your own code ret ; ;Test UART flags for error: return TRUE (1) in HL if error. -mdmerr: - ; <== Insert your own code here - ld hl,0 - - ; <== End of your own code - ld a,l ; set/clear Z - or a +mdmerr: xor a ; set/clear Z + ld h,a + ld l,a ret - - - +; ;Turn DTR ON dtron: - ; <== Insert your own code here - - ; <== End of your own code - ret - - - +; ret +; ;Turn DTR OFF dtroff: - ; <== Insert your own code here - - - ; <== End of your own code ret - - - +; ;Initialise the uart - -init: - ld hl,2 ; get parameters +; +init: ld hl,2 ; get parameters add hl,sp ex de,hl call getparm ; in HL @@ -427,20 +301,14 @@ init: ld (data),hl ; data bits (BINARY 7 or 8) call getparm ld (stop),hl ; stop bits (BINARY 1 or 2) - - - ; <== Insert your own code here - ; using values below - call print - db cr,lf,cr,lf,'CIO Init ...',cr,lf,0 - +; ld a,(port) ; get device type ld c,a ld b,06h rst 08 or a ; check if valid jr nz,initerr - +; ld a,(brate) ; get baud rate to set ld c,a ld b,0 @@ -449,7 +317,7 @@ init: ld a,(hl) ; convert to encoded hbios cp a,-1 jr z,initerr - +; push af ld a,(port) ; get line characteristics ld c,a @@ -461,48 +329,42 @@ init: pop af or d ld d,a - +; ld b,04h ; set new ld a,(port) ; speed ld c,a rst 08 or a jr nz,initerr - - call print - db 'Device: ',0 - ld a,(port) - add a,'0' - call cout +; call print - db cr,lf,0 - - ld a,(brate) - ld (mspeed),a ; don't forget to load mspeed with the - ; current brate value if the new rate is - ; valid. See table of values below. - ; <== End of your own code + db 'Initializing device: ',0 + call diport +; + ld a,(brate) ; load mspeed with the current brate value if + ld (mspeed),a ; the new rate is valid. See table of values below. ret -initerr: - call print - db 'Init failed, CIO device: ',0 - ld a,(port) - add a,'0' +; +initerr:call print + db lf,lf,'Initization failed, device: ',0 + call diport + call show ; show cursor, then ... + jp 0 ; bail out to avoid system hang! +; +diport: ld a,(port) ; Display port +diport1:add a,'0' call cout call print db cr,lf,0 - - ;ret - - call show ; show cursor, then ... - jp 0 ; bail out to avoid system hang! - + ret +; ;-------------------------------------------------------------------------- stop: dw 1 ; stop bits parity: dw 'N' ; parity data: dw 8 ; data bits brate: dw initbr ; baud rate: ;-------------------------------------------------------------------------- +; ;Values of brate for each baud rate ; ; hb encode baud rate brate @@ -521,36 +383,24 @@ baudtbl: db 9 ; 38400 10 db 24 ; 57600 11 db 10 ; 76800 12 - ; -; Set the port. ZMP supplies either 0 or 1 as a parameter. You're on your -; own here -- your system is bound to be different from any other! You may -; implement a software switch on all the modem-dependent routines, or perhaps -; you can have one or two centralised routines for accessing the UARTs and -; modify the code from this routine to select one or the other. (Who said -; there was anything wrong with self-modifying code?). If you have only one -; UART port, or if you don't want to go through all the hassles, just have -; this routine returning with no changes made. Note that ZMP calls this -; routine with both values for the port on initialisation. +; Set the port. ZMP supplies either 0 or 1 as a parameter. +; Note that ZMP calls this routine with both values +; for the port on initialisation. ; -; Only originl ZMP calls setport. Mecports +; Only originl ZMP calls setport. Mecports does not support setting ports ; -setport: - ld hl,2 ; get port number +setport:ld hl,2 ; get port number add hl,sp ex de,hl call getparm ; in HL (values are 0 and 1) - - ; <== Insert your own code here - +; ld a,l ; point to which port ld hl,hbport0 ; we want to set or a jr z,isport0 inc hl -isport0: - ld c,(hl) ; get the associated CIO port - +isport0:ld c,(hl) ; get the associated CIO port push hl ld b,06h ; test if a valid cio rst 08 @@ -559,31 +409,17 @@ isport0: ld a,(hl) ; get the associated CIO port jr nz,seterr ld (port),a ; save the valid port - push hl call print db 'Setting CIO device: ',0 - pop hl - - add a,'0' - call cout - call print - db cr,lf,0 - ret -seterr: - push hl + jp diport +; +seterr: push hl call print db 'Unable to set CIO device: ',0 pop hl ld a,(hl) ; get port we wanted to set - add a,'0' - call cout - call print - db cr,lf,0 - ; <== End of your own code - ret - - - + jp diport1 +; ;**************************************************************************** ;Video terminal sequences: these are for VT-100: Modify as you wish ;Cursor addressing: @@ -597,8 +433,7 @@ cursadd: call getparm inc hl ld (col),hl ; column - ; <== Insert your own code here - ; using values in row and col +; call print db esc,'[',0 ld a,(row) ; row first @@ -609,14 +444,12 @@ cursadd: call cursconv ld a,'H' call cout - ; <== end of your own code ret - +; cursconv: ld b,a xor a -ca1: - add a,1 +ca1: add a,1 daa djnz ca1 ld (num),a @@ -628,115 +461,80 @@ ca1: srl a or '0' call cout -ca2: - ld a,(num) +ca2: ld a,(num) and 0fh or '0' call cout ret - +; row: ds 2 ; row col: ds 2 ; column num: ds 1 - +; ;Clear screen: cls: call print db esc,"[H",esc,"[2J",0 ret - +; ;Inverse video on: invon: call print db esc,"[7m",0 ret - +; ;Inverse video off: invoff: call print db esc,"[m",0 ret - +; ;Turn off cursor: hide: call print db esc,'[?25l',0 ret - +; ;Turn on cursor: show: call print db esc,'[?25h',0 ret - +; ;Save cursor position: savecu: call print db esc,'[7',0 ret - +; ;Restore cursor position: rescu: call print db esc,'[8',0 ret - +; ;**************************************************************************** - +; ;Service modem interrupt: mint: - ret ; my system doesn't need this - +; ret ; unused +; ;Initialise interrupt vectors: invec: - ret ; ditto - +; ret ; ditto +; ;De-initialise interrupt vectors: dinvec: ret ; ditto -; Display A in hex -prthexbyte: - push af - push de - call hexascii - ld a,d - call cout - ld a,e - call cout - pop de - pop af - ret - -hexascii: - ld d,a - call hexconv - ld e,a - ld a,d - rlca - rlca - rlca - rlca - call hexconv - ld d,a - ret - -hexconv: - and 0fh - add a,90h - daa - adc a,40h - daa - ret - +; ;****************** End of user-defined code ******************************** ; Do not change anything below here. - +; ;Modem character test for 100 ms mrd: push bc ; save bc ld bc,100 ; set limit -mrd1: - call mirdy ; char at modem? +mrd1: call mirdy ; char at modem? jr nz,mrd2 ; yes, exit ld hl,1 ; else wait 1ms call waithlms @@ -746,30 +544,24 @@ mrd1: jr nz,mrd1 ld hl,0 ; none there, result=0 xor a -mrd2: - pop bc +mrd2: pop bc ret - +; ; Inline print routine: destroys A and HL - -print: - ex (sp),hl ; get address of string -ploop: - ld a,(hl) ; get next +; +print: ex (sp),hl ; get address of string +ploop: ld a,(hl) ; get next inc hl ; bump pointer or a ; done if zero jr z,pdone call cout ; else print jr ploop ; and loop -pdone: - ex (sp),hl ; restore return address +pdone: ex (sp),hl ; restore return address ret ; and quit - ; ;Output a character in A to the console ; -cout: - push bc ; save regs +cout: push bc ; save regs push de push hl ld e,a ; character to E @@ -779,36 +571,31 @@ cout: pop de pop bc ret +; +; Calculate values for loop constants. +; Need to have two loops to avoid 16-bit overflow with clock speeds above 9 MHz. -;Wait(seconds) -wait: - ld hl,2 +;outerval equ (clkspd / 10) + 1 +;innerval equ (6667 / outerval) * clkspd +; +;Wait(seconds) - entry point from C +wait: ld hl,2 add hl,sp ex de,hl ; get delay size call getparm ; fall thru to.. -;Wait seconds in HL +;Wait seconds in HL - entry point for this overlay waithls: push bc ; save bc push de ; de push ix ; and ix ld ix,0 ; then point ix to 0 ; so we don't upset memory-mapped i/o - -;Calculate values for loop constants. Need to have two loops to avoid -; 16-bit overflow with clock speeds above 9 MHz. - -;outerval equ (clkspd / 10) + 1 -;innerval equ (6667 / outerval) * clkspd - -wait10: - ld a,(outv) ; was ld b,outerval +; +wait10: ld a,(outv) ; was ld b,outerval ld b,a -wait11: - ld de,(inv) ; was ld de,innerval - -wait12: - bit 0,(ix) ; time-wasters +wait11: ld de,(inv) ; was ld de,innerval +wait12: bit 0,(ix) ; time-wasters bit 0,(ix) bit 0,(ix) ; 20 T-states each bit 0,(ix) @@ -828,22 +615,18 @@ wait12: pop de ; de pop bc ; and bc ret - -;Wait milliseconds -mswait: - ld hl,2 +; +;Wait milliseconds - entry point from C +mswait: ld hl,2 add hl,sp ex de,hl ; get delay size call getparm ; fall thru to.. -;Wait milliseconds in HL -waithlms: +;Wait milliseconds in HL - entry point for this overlay +waithlms: push de -w1ms0: - ld de,(msv) ; was ld de,39 * clkspd - -w1ms1: - dec de +w1ms0: ld de,(msv) ; was ld de,39 * clkspd +w1ms1: dec de ld a,d or e jr nz,w1ms1 @@ -853,7 +636,7 @@ w1ms1: jr nz,w1ms0 pop de ret - +; ;Get next parameter from (de) into hl getparm: ex de,hl ; get address into hl @@ -863,21 +646,18 @@ getparm: inc hl ; bump for next ex de,hl ; result in hl, address still in de ret - +; ;Get address of user-defined variables - -getvars: - ld hl,uservars +; +getvars:ld hl,uservars ret - +; uservars: dw overdrive ; .OVR etc. drive/user dw overuser - - +; if ($ - codebgn) gt ovsize toobig: jp errval ; Overlay too large! endif - +; end - \ No newline at end of file