mirror of https://github.com/wwarthen/RomWBW.git
Browse Source
- ZMP was crashing in most scenarios. This was corrected. - Minor adjustments to ZMP usage - Added ZMP documentationpull/534/head
39 changed files with 1037 additions and 64 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,10 +1,10 @@ |
|||
OBJECTS = zmp.com *.ovr *.hlp zmp.doc |
|||
OBJECTS = zmp.com *.ovr zmp.cfg zmp.fon *.hlp zmp.doc |
|||
DEST = ../../../Binary/Apps |
|||
TOOLS = ../../../Tools |
|||
OTHERS = *.hex |
|||
NODELETE = *.ovr zmp.doc *.hlp |
|||
NODELETE = *.ovr zmp.doc zmp.cfg zmp.fon *.hlp |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
|
|||
zmp.com: zmo-rw01.hex |
|||
$(ZXCC) MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-RW01 |
|||
zmp.com: zmo-wbw.hex |
|||
$(ZXCC) MLOAD25 -ZMP.COM=ZMPX.COM,ZMO-WBW |
|||
|
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,844 @@ |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; Overlay for ZMP (Z-Modem Program) |
|||
; |
|||
; Name ZMO-WBW.Z80 |
|||
; |
|||
; Dated April 14, 2025 |
|||
; |
|||
; Written by - |
|||
; Phil Summers, Wayne Warthen |
|||
; |
|||
; ROMWBW version using HBIOS and https://github.com/mecparts/zmp |
|||
; version of zmodem |
|||
; |
|||
; - All modem/serial i/o is through RomWBW HBIOS. |
|||
; |
|||
; - Data bits, stop bits, and parity are determined by HBIOS. |
|||
; The ZMP settings will have no effect. Use RomWBW MODE |
|||
; command to set serial port config before starting ZMP. |
|||
; |
|||
; - Timing delay calculations based on HBIOS reported CPU speed. |
|||
; |
|||
; - The pcfg equate determines whether the overlay will |
|||
; implement port initialization. Normally, pcfg will be |
|||
; set to false because ZMP does not allow configuring |
|||
; many HBIOS speeds (notably the 115200 baud hardwired |
|||
; into many RCBus systems). In this case, you must |
|||
; configure the modem port using the RomWBW |
|||
; MODE command as desired before starting ZMP. |
|||
; |
|||
; - The modem port is assigned to an HBIOS character unit. By |
|||
; default, the modem is assigned to HBIOS character unit 1. |
|||
; An alternate HBIOS character unit may be specified as a |
|||
; parameter on the command line as a single number. For |
|||
; example, the following will assign HBIOS port 3 as the |
|||
; ZMP modem port: |
|||
; |
|||
; ZMP 3 |
|||
; |
|||
; - The original version of ZMP from Ron Murray allows you to |
|||
; select from 2 logical modem ports. This overlay ignores |
|||
; any attempt to select ports from within ZMP. The desired |
|||
; modem port should be assigned using the command line |
|||
; parameter as described above. |
|||
; |
|||
; - Teraterm users may need to change the ZmodemWinSize value |
|||
; to 1024 in the teraterm.ini configuration 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: |
|||
|
|||
debug equ false ; to allow debugging of overlay with Z8E etc. |
|||
clkspd equ 8 ; Processor clock speed in MHz |
|||
pcfg equ false ; Allow ZMP to configure port |
|||
|
|||
; |
|||
;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. |
|||
|
|||
overdrive equ 0 ; Drive to find overlay files on ('A'-'P') |
|||
overuser equ 0 ; User area to find files |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
|
|||
|
|||
; NOT user-set variables |
|||
|
|||
userdef equ 0145h ; origin of this overlay |
|||
; This address should not change with |
|||
; subsequent revisions. |
|||
mspeed equ 03ch ; location of current baud rate. |
|||
ovsize equ 0400h ; max size of this overlay |
|||
|
|||
fcb equ 05ch ; primary command line CP/M fcb |
|||
|
|||
.z80 ; use z80 code |
|||
aseg ; absolute |
|||
|
|||
if debug |
|||
org 100h ; so you can debug it with cebug, zsid, etc |
|||
else |
|||
org userdef |
|||
endif |
|||
|
|||
|
|||
esc equ 1bh |
|||
ctrlq equ 11h |
|||
cr equ 0dh |
|||
lf equ 0ah |
|||
bdos equ 5 |
|||
|
|||
|
|||
codebgn equ $ |
|||
|
|||
;Jump table for the overlay: do NOT change this |
|||
jump_tab: |
|||
jp scrnpr ; screen print |
|||
jp mrd ; modem read with timeout |
|||
jp mchin ; get a character from modem |
|||
jp mchout ; send a character to the modem |
|||
jp mordy ; test for tx buffer empty |
|||
jp mirdy ; test for character received |
|||
jp sndbrk ; send break |
|||
jp cursadd ; cursor addressing |
|||
jp cls ; clear screen |
|||
jp invon ; inverse video on |
|||
jp invoff ; inverse video off |
|||
jp hide ; hide cursor |
|||
jp show ; show cursor |
|||
jp savecu ; save cursor position |
|||
jp rescu ; restore cursor position |
|||
jp mint ; service modem interrupt |
|||
jp invec ; initialise interrupt vectors |
|||
jp dinvec ; de-initialise interrupt vectors |
|||
jp mdmerr ; test uart flags for error |
|||
jp dtron ; turn DTR on |
|||
jp dtroff ; turn DTR OFF |
|||
jp init ; initialise uart |
|||
jp wait ; wait seconds |
|||
jp mswait ; wait milliseconds |
|||
jp userin ; user-defined entry routine |
|||
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 |
|||
jp spare ; spare for later use |
|||
jp spare ; spare for later use |
|||
jp spare ; spare for later use |
|||
jp spare ; spare for later use |
|||
|
|||
; Local storage |
|||
|
|||
hbunit db 1 ; Active HBIOS unit for modem I/O |
|||
cpumhz db clkspd ; CPU clock speed in MHz |
|||
|
|||
; |
|||
; Main code starts here |
|||
; |
|||
;Screen print function |
|||
scrnpr: |
|||
; <== Insert your own code here |
|||
call print |
|||
db 'Screen print not supported.',cr,lf,0 |
|||
; <== End of your own code |
|||
spare: |
|||
ret |
|||
|
|||
|
|||
; User-defined entry routine: leave empty if not needed |
|||
userin: |
|||
push bc |
|||
push de |
|||
push hl |
|||
|
|||
call print |
|||
db cr,lf,'ZMP Overlay for RomWBW HBIOS v1.0',cr,lf,0 |
|||
|
|||
; Scan and parse default FCB to initialize HBIOS unit if |
|||
; specified. |
|||
ld a,(fcb + 1) ; get parm from fcb |
|||
cp ' ' ; anything there? |
|||
jr z,userin1 ; if empty, done |
|||
sub '0' ; ASCII to binary |
|||
jr c,parmerr ; less than 0, parm error |
|||
cp 10 ; >= 10? |
|||
jr nc,parmerr ; greater than 9, parm error |
|||
ld (hbunit),a ; save it |
|||
|
|||
userin1: |
|||
call showcom ; show com port info |
|||
|
|||
; check that unit is actually available in HBIOS |
|||
ld bc,0f800h ; get HBIOS char unit count |
|||
rst 8 ; do it |
|||
ld a,(hbunit) ; get active modem unit |
|||
cp e ; compare to units available |
|||
jr nc,porterr ; unit too high, port error |
|||
|
|||
if pcfg |
|||
|
|||
; Force port initialization by setting an invalid |
|||
; baud rate (mspeed). |
|||
; speed to an arbitrary value of 8 (9600 baud). |
|||
ld a,-1 |
|||
ld (mspeed),a |
|||
|
|||
else |
|||
|
|||
; We don't support port configuration. Here we set the modem |
|||
; speed to an arbitrary value of 8 (9600 baud). |
|||
ld a,8 |
|||
ld (mspeed),a |
|||
|
|||
endif |
|||
|
|||
|
|||
ld bc,0f8f0h ; HBIOS func get CPU info |
|||
rst 08 ; do it, l = CPU speed in MHz |
|||
ld a,l ; to accum |
|||
ld (cpumhz),a ; and save it for wait loop |
|||
|
|||
ld hl,2 |
|||
call waithls |
|||
|
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
ret |
|||
|
|||
parmerr: |
|||
; Handle a bad parameter |
|||
call print ; print error message |
|||
db cr,lf,'ZMP parameter error!',cr,lf,0 |
|||
rst 0 ; bail out to OS |
|||
|
|||
porterr: |
|||
; Handle a bad port |
|||
call print ; print error message |
|||
db cr,lf,'Invalid HBIOS unit for ZMP Modem port!',cr,lf,0 |
|||
rst 0 ; bail out to OS |
|||
|
|||
showcom: |
|||
; Display the HBIOS unit to be used for the ZMP Modem |
|||
call print |
|||
db cr,lf,'ZMP Modem on HBIOS Unit #',0 |
|||
ld a,(hbunit) |
|||
add a,'0' |
|||
call cout |
|||
call print |
|||
db cr,lf,0 |
|||
|
|||
; User-defined exit routine: leave empty if not needed |
|||
userout: |
|||
ret |
|||
|
|||
;Get a character from the modem: return in HL |
|||
mchin: |
|||
push bc |
|||
|
|||
; <== Insert your own code here |
|||
ld a,(hbunit) |
|||
ld c,a |
|||
ld b,00h |
|||
rst 08 |
|||
ld a,e |
|||
; <== End of your own code |
|||
|
|||
ld l,a ; put in HL |
|||
ld h,0 |
|||
or a ; set/clear Z |
|||
pop bc |
|||
ret |
|||
|
|||
;Send a character to the modem |
|||
mchout: |
|||
ld hl,2 ; get the character |
|||
add hl,sp |
|||
ld a,(hl) |
|||
|
|||
; <== Insert your own code here |
|||
push bc |
|||
ld e,a |
|||
ld a,(hbunit) |
|||
ld c,a |
|||
ld b,01h |
|||
rst 08 |
|||
pop bc |
|||
; <== End of your own code |
|||
|
|||
ret ; done |
|||
|
|||
;Test for output ready: return TRUE (1) in HL if ok |
|||
mordy: |
|||
; <== Insert your own code here |
|||
push bc |
|||
ld a,(hbunit) |
|||
ld c,a |
|||
ld b,03h |
|||
rst 08 |
|||
ld h,0 |
|||
ld l,a |
|||
pop bc |
|||
; <== End of your own code |
|||
|
|||
ld a,l ; set/clear Z |
|||
or a |
|||
ret |
|||
|
|||
;Test for character at modem: return TRUE (1) in HL if so |
|||
mirdy: |
|||
; <== Insert your own code here |
|||
push bc |
|||
ld a,(hbunit) |
|||
ld c,a |
|||
ld b,02h |
|||
rst 08 |
|||
ld h,0 |
|||
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 |
|||
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 |
|||
xor a ; not implemented |
|||
; <== End of your own code |
|||
|
|||
ld a,l ; set/clear Z |
|||
or a |
|||
ret |
|||
|
|||
|
|||
|
|||
;Turn DTR ON |
|||
dtron: |
|||
; <== Insert your own code here |
|||
|
|||
; <== End of your own code |
|||
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 |
|||
add hl,sp |
|||
ex de,hl |
|||
call getparm ; in HL |
|||
ld (brate),hl ; baud rate |
|||
call getparm |
|||
ld (parity),hl ; parity |
|||
call getparm |
|||
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 |
|||
; don't forget to load mspeed with the |
|||
; current brate value if the new rate is |
|||
; valid. See table of values below. |
|||
|
|||
push bc |
|||
|
|||
; If pcfg is true, attempt to initialize the active |
|||
; HBIOS unit. If false, initialization if bypassed with |
|||
; the assumption that the RomWBW MODE command was used |
|||
; to initialize the port priot to running ZMP. |
|||
|
|||
if pcfg |
|||
|
|||
call print |
|||
db 'Initializing device: ',0 |
|||
call diport |
|||
|
|||
ld a,(hbunit) ; 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 |
|||
ld hl,baudtbl |
|||
add hl,bc |
|||
ld a,(hl) ; convert to encoded hbios |
|||
cp a,-1 |
|||
jr z,initerr |
|||
|
|||
push af |
|||
ld a,(hbunit) ; get line characteristics |
|||
ld c,a |
|||
ld b,05h |
|||
rst 08 |
|||
ld a,d ; mask out exisitng |
|||
and 11100000b ; replace with rate |
|||
ld d,a |
|||
pop af |
|||
or d |
|||
ld d,a |
|||
|
|||
ld b,04h ; set new |
|||
ld a,(hbunit) ; speed |
|||
ld c,a |
|||
rst 08 |
|||
or a |
|||
jr nz,initerr |
|||
|
|||
ld a,(brate) ; load mspeed with the current brate value if |
|||
ld (mspeed),a ; the new rate is valid. See table of values below. |
|||
|
|||
call print |
|||
db lf,lf,'Initization completed, device: ',0 |
|||
call diport |
|||
|
|||
jr init_z |
|||
|
|||
initerr:call print |
|||
db lf,lf,'Initization failed, device: ',0 |
|||
call diport |
|||
|
|||
jr init_z |
|||
|
|||
diport: ld a,(hbunit) ; Display port |
|||
diport1:add a,'0' |
|||
call cout |
|||
call print |
|||
db cr,lf,0 |
|||
ld hl,2 |
|||
call waithls |
|||
ret |
|||
|
|||
else |
|||
|
|||
;call print |
|||
;db cr,lf,'Modem port initialization...',0 |
|||
;ld hl,2 |
|||
;call waithls |
|||
|
|||
ld b,05h ; HBIOS port reset function |
|||
ld a,(hbunit) ; get active modem port |
|||
ld c,a ; and put in accum |
|||
rst 8 ; reset port |
|||
or a ; check result |
|||
jr nz,init1 ; if error, handle it |
|||
ld a,8 ; dummy value for speed |
|||
ld (mspeed),a ; save it |
|||
jr init_z ; done |
|||
|
|||
init1: |
|||
; Handle error return from initialization |
|||
call print |
|||
db cr,lf,'Modem port initialization failed!',cr,lf,0 |
|||
ld hl,2 |
|||
call waithls |
|||
|
|||
jr init_z |
|||
|
|||
endif |
|||
|
|||
init_z: |
|||
pop bc |
|||
|
|||
; <== End of your own code |
|||
|
|||
ret |
|||
;-------------------------------------------------------------------------- |
|||
|
|||
stop: dw 1 ; stop bits |
|||
parity: dw 'N' ; parity |
|||
data: dw 8 ; data bits |
|||
brate: dw 7 ; baud rate: |
|||
|
|||
;-------------------------------------------------------------------------- |
|||
; |
|||
;Values of brate for each baud rate |
|||
; |
|||
; hb encode baud rate brate |
|||
; |
|||
baudtbl: |
|||
db -1 ; 110 0 not supported |
|||
db 2 ; 300 1 |
|||
db 17 ; 450 2 |
|||
db 3 ; 600 3 |
|||
db -1 ; 710 4 not supported |
|||
db 4 ; 1200 5 |
|||
db 5 ; 2400 6 |
|||
db 6 ; 4800 7 |
|||
db 7 ; 9600 8 |
|||
db 8 ; 19200 9 |
|||
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. |
|||
; |
|||
; Only originl ZMP calls setport. MECPARTS variant does not. |
|||
; |
|||
; We ignore this call. Since we are using a command line parameter |
|||
; to specify the desired modem port, it makes no sense. |
|||
; |
|||
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 |
|||
|
|||
; <== End of your own code |
|||
|
|||
ret |
|||
|
|||
|
|||
; |
|||
;**************************************************************************** |
|||
;Video terminal sequences: these are for VT-100: Modify as you wish |
|||
;Cursor addressing: |
|||
cursadd: |
|||
ld hl,2 ; get parameters |
|||
add hl,sp |
|||
ex de,hl |
|||
call getparm ; in HL |
|||
inc hl |
|||
ld (row),hl ; row |
|||
call getparm |
|||
inc hl |
|||
ld (col),hl ; column |
|||
; |
|||
push bc |
|||
|
|||
call print |
|||
db esc,'[',0 |
|||
ld a,(row) ; row first |
|||
call cursconv |
|||
ld a,';' |
|||
call cout |
|||
ld a,(col) ; same for column |
|||
call cursconv |
|||
ld a,'H' |
|||
call cout |
|||
|
|||
pop bc |
|||
|
|||
ret |
|||
; |
|||
cursconv: |
|||
ld b,a |
|||
xor a |
|||
ca1: add a,1 |
|||
daa |
|||
djnz ca1 |
|||
ld (num),a |
|||
and 0f0h |
|||
jr z,ca2 |
|||
srl a |
|||
srl a |
|||
srl a |
|||
srl a |
|||
or '0' |
|||
call cout |
|||
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 ; handled in HBIOS |
|||
|
|||
;Initialise interrupt vectors: |
|||
invec: |
|||
ret ; ditto |
|||
|
|||
;De-initialise interrupt vectors: |
|||
dinvec: |
|||
ret ; ditto |
|||
|
|||
;****************** 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? |
|||
jr nz,mrd2 ; yes, exit |
|||
ld hl,1 ; else wait 1ms |
|||
call waithlms |
|||
dec bc ; loop till done |
|||
ld a,b |
|||
or c |
|||
jr nz,mrd1 |
|||
ld hl,0 ; none there, result=0 |
|||
xor a |
|||
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 |
|||
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 |
|||
ret ; and quit |
|||
|
|||
; |
|||
;Output a character in A to the console |
|||
; |
|||
cout: |
|||
push bc ; save regs |
|||
push de |
|||
push hl |
|||
ld e,a ; character to E |
|||
ld c,2 |
|||
call bdos ; print it |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
ret |
|||
|
|||
|
|||
;Wait seconds |
|||
wait: |
|||
ld hl,2 |
|||
add hl,sp |
|||
ex de,hl ; get delay size |
|||
call getparm |
|||
; fall thru to.. |
|||
;Wait seconds in HL |
|||
waithls: |
|||
push hl ; save loop control |
|||
ld hl,1000 ; 1000ms = 1 second |
|||
call waithlms |
|||
pop hl ; restore loop control |
|||
dec hl |
|||
ld a,h |
|||
or l |
|||
jr nz,waithls |
|||
ret |
|||
|
|||
|
|||
|
|||
;Wait milliseconds |
|||
mswait: |
|||
ld hl,2 |
|||
add hl,sp |
|||
ex de,hl ; get delay size |
|||
call getparm |
|||
; fall thru to.. |
|||
;Wait milliseconds in HL |
|||
waithlms: |
|||
; burn 1000us (1ms) |
|||
ld a,(cpumhz) |
|||
ld e,a |
|||
hlms1: |
|||
; burn 1000 t-states |
|||
; 50 * 20 = 1000 t-states |
|||
ld d,50 |
|||
hlms2: |
|||
nop ; 4 |
|||
dec d ; 4 |
|||
jr nz,hlms2 ; 12 20 |
|||
|
|||
dec e |
|||
jr nz,hlms1 |
|||
|
|||
dec hl |
|||
ld a,h |
|||
or l |
|||
jr nz,waithlms |
|||
|
|||
ret |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
;Get next parameter from (de) into hl |
|||
getparm: |
|||
ex de,hl ; get address into hl |
|||
ld e,(hl) ; get lo |
|||
inc hl |
|||
ld d,(hl) ; then hi |
|||
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 |
|||
ret |
|||
|
|||
uservars: |
|||
dw overdrive ; .OVR etc. drive/user |
|||
dw overuser |
|||
|
|||
|
|||
if ($ - codebgn) gt ovsize |
|||
toobig: jp errval ; Overlay too large! |
|||
endif |
|||
|
|||
end |
|||
|
|||
Binary file not shown.
Loading…
Reference in new issue