.xlist ; ;************************************************************************ ;* * ;* Z80-Library by Michael Bischoff * ;* Stand: 18.05.1986 * ;* * ;************************************************************************ ;************************************************************************ ;* * ;* Systemkonstanten * ;* * ;************************************************************************ .z80 ; Zilog CPU if1 ; .printx $ MYLIB.MLB 18.05.1986 included $ endif ; true equ 1 ; false equ 0 ; reg_b equ 8 ; define registers reg_c equ 8 ; reg_d equ 8 ; reg_e equ 8 ; reg_h equ 8 ; reg_l equ 8 ; reg_a equ 8 ; reg_m equ 8 ; m := (hl) (for 8080 fans) .8080 ; dreg_bc equ lxi b ; ld bc,... dreg_de equ lxi d ; ld de,... dreg_hl equ lxi h ; ld hl,... .z80 ; ifndef biosio ; biosio equ false ; endif ; ifndef files ; files equ 0 ; no files! endif ; deffcb equ 005ch ; Default FCB Adresse deffcb2 equ 006ch ; Default FCB Adresse 2 defdma equ 0080h ; Default DMA Adresse ccpsize equ 806h ; ctrl_c equ 'C'-'@' ; Einige ASCII-Steuerzeichen bell equ 'G'-'@' ; bs equ 'H'-'@' ; tab equ 'I'-'@' ; lf equ 'J'-'@' ; cr equ 'M'-'@' ; ctrl_z equ 'Z'-'@' ; esc equ '['-'@' ; ;************************************************************************ ;* * ;* Hilfsmacros * ;* * ;************************************************************************ save macro ; rettet Register auf den Stack push bc ; push de ; push hl ; push ix ; push iy ; endm ; restore macro ; rettet Register vom Stack pop iy ; pop ix ; pop hl ; pop de ; pop bc ; endm ; index macro table ; HL:=table + A ld hl,table ; call _adda## ; endm ; ld_a macro dest,val0,val1,val2,val3 local weiter,lab0,lab1,lab2 or a ; jr z,lab0 ; ifnb ; cp 1 ; jr z,lab1 ; ifnb ; cp 2 ; jr z,lab2 ; ld dest,val3 ; jr weiter ; endif ; lab2: ld dest,val2 ; jr weiter ; endif ; lab1: ld dest,val1 ; jr weiter ; lab0: ld dest,val0 ; weiter: ; endm ; dlb macro label ; "Define Label Byte" label equ $-1 ; endm ; dlw macro label ; "Define Label Word" label equ $-2 ; endm ; ldop macro reg,instr ; load register with opcode ifdef reg_® ; .8080 ; db (mvi reg) ; ld hl,.... .z80 ; else ; db dreg_® ; endif ; instr ; endm ; incb macro address,maxval ; increment byte local weiter ; ifnb
; ld a,address ; endif ; inc a ; ifnb ; cp maxval ; jr c,weiter ; xor a ; weiter: endif ; ifnb
; ld address,a ; then put it there endif ; endm ; incw macro address,maxval ; increment word local weiter ; ld hl,(address) ; inc hl ; ifnb ; maximum value defined? push de ; ld de,maxval ; cmp16 ; jr c,weiter ; ld hl,0 ; weiter: pop de ; endif ; ld (address),hl ; if carry is set, we had some overflow endm ; fill macro length,byte ; f}llt einen Speicherbereich mit rept length ; konstantem Wert voll db byte ; endm ; endm ; cmp16 macro ; Vergleich hl-de local weiter ; ld a,h ; sub d ; jr nz,weiter ; ld a,l ; sub e ; weiter: ; endm ; ;************************************************************************ ;* * ;* COMPARE length,text1,text2 * ;* vergleicht length Bytes * ;* text1 gegen text2 * ;* * ;************************************************************************ compare macro length,text1,text2; ifnb ; ld hl,text2 ; endif ; ifnb ; ld de,text1 ; endif ; ifnb ; ld b,length ; endif ; call _cpmem## ; endm ; ;************************************************************************ ;* * ;* MOVE length,text1,text2 * ;* kopiert length Bytes * ;* ab text1 nach text2 * ;* * ;************************************************************************ move macro length,text1,text2; ifnb ; ld hl,text2 ; endif ; ifnb ; ld de,text1 ; endif ; ifnb ; ld bc,length ; endif ; ldir ; endm ; ;************************************************************************ ;* * ;* EXCHANGE length,text1,text2 * ;* vertauscht length Bytes * ;* text1 mit text2 * ;* * ;************************************************************************ exchange macro length,text1,text2; ifnb ; ld hl,text2 ; endif ; ifnb ; ld de,text1 ; endif ; ifnb ; ld b,length ; endif ; call _exmem## ; endm ; ld_de_von_hl macro ; ld e,(hl) ; inc hl ; ld d,(hl) ; inc hl ; endm ; ld_de_nach_hl macro ; ld (hl),e ; inc hl ; ld (hl),d ; inc hl ; endm ; toupper macro what ; ifnb ; res 5,what ; lower case => upper case else ; res 5,a ; endif ; endm ; tolower macro what ; ifnb ; set 5,what ; lower case => upper case else ; set 5,a ; endif ; endm ; ;************************************************************************ ;* * ;* BIOS function,argument * ;* ruft BIOS-Funktion auf * ;* * ;************************************************************************ bios macro functn,value ; bios-call durchfuehren bios_wboot equ 003h ; bios_const equ 006h ; bios_conin equ 009h ; bios_conout equ 00ch ; bios_list equ 00fh ; bios_punch equ 012h ; bios_reader equ 015h ; bios_home equ 018h ; bios_seldsk equ 01bh ; bios_settrk equ 11eh ; 16 bit argument! bios_setsec equ 121h ; " bios_setdma equ 124h ; " bios_read equ 027h ; bios_write equ 02ah ; bios_listst equ 02dh ; bios_sectran equ 130h ; 16 bit argument! ifnb ; if bios_&functn gt 0ffh ld bc,value ; else ; ld c,value ; endif ; endif ; ld l,bios_&functn AND 0ffh call _bioscall## ; endm ; ;************************************************************************ ;* * ;* BDOS function,argument * ;* ruft BDOS-Funktion auf. * ;* Ist argument nicht angegeben, * ;* wird DE gelassen. * ;* * ;************************************************************************ bdos macro callnr,arg ; system_reset equ 000h ; console_in equ 001h ; console_out equ 002h ; reader_in equ 003h ; punch_out equ 004h ; list_out equ 005h ; direct_conio equ 006h ; get_iobyte equ 007h ; set_iobyte equ 008h ; print_string equ 109h ; 2 Byte Argument inline equ 10ah ; " get_con_status equ 00bh ; return_version equ 00ch ; disk_reset equ 00dh ; select_disk equ 00eh ; open_file equ 10fh ; 2 Byte Argument close_file equ 110h ; srch_for_first equ 111h ; srch_for_next equ 012h ; delete_file equ 113h ; read_seq equ 114h ; write_seq equ 115h ; make_file equ 116h ; rename_file equ 117h ; get_login_vec equ 018h ; get_cur_disk equ 019h ; set_dma_addr equ 11ah ; get_alloc_addr equ 01bh ; set_ro_disk equ 01ch ; get_ro_vector equ 01dh ; set_file_attr equ 11eh ; get_dpb_addr equ 01fh ; set_get_user equ 020h ; read_random equ 121h ; write_random equ 122h ; comp_file_size equ 123h ; set_rand_rec equ 124h ; reset_drive equ 125h ; wr_rand_with_0 equ 128h ; ifnb ; if callnr gt 0ffh ; must be defined ld de,arg ; 2 Byte argument else ; ld e,arg ; 1 Byte argument endif ; endif ; ifnb ; ld c,callnr AND 0ffh; endif ; call 5 ; endm ; ;************************************************************************ ;* * ;* INIT (stacksize) * ;* pr}ft, ob Cp/M 2.2 Betriebssystem aktiv, * ;* ob Z80-CPU, setzt Stack auf (default: 100 Byte) * ;* * ;************************************************************************ init macro stacksiz ; call _version## ; richtiges Cp/M release und z80? dseg ; ifnb ; ds stacksiz ; else ; ds 100 ; endif ; ccpstack: dw 0 ; cseg ; ld (ccpstack),sp ; vielleicht braucht er ihn noch? ld sp,ccpstack ; endm ; ;************************************************************************ ;* * ;* RETURN (returnvalue) * ;* verl{~t Programm und kehrt ins CCP zur}ck. * ;* * ;************************************************************************ return macro retval ; if files ; call _clsall## ; endif ; ld sp,(ccpstack) ; ifnb ; ld a,retval ; endif ; ret ; endm ; ;************************************************************************ ;* * ;* EXIT condition,message * ;* Wenn condition erf}llt oder blank * ;* wird message ausgedruckt, Dateien * ;* werden geschlossen und Programm verlassen. * ;* * ;************************************************************************ exit macro condition,text ; local message ; dseg ; ifnb ; message: db text,0 ; endif ; cseg ; ifnb ; ifnb ; push hl ; ld hl,message ; jp condition,_exit; pop hl ; else ; jp condition,_exit0;do not kill $$$.SUB endif ; else ; ifnb ; ld hl,message ; jp _exit ; else ; jp _exit0 ; endif ; endif ; endm ; ;************************************************************************ ;* * ;* PRINT "message1","message2","message3" * ;* druckt message1,message2,message3 * ;* auf stdout aus * ;* PRINT := use preset HL * ;* * ;************************************************************************ print macro text1,text2,text3 ; druckt Text auf stdout aus local weiter,zeile ; ifnb ; dseg ; zeile: db text1 ; ifnb ; db text2 ; ifnb ; db text3 ; endif ; endif ; db 0 ; cseg ; ld hl,zeile ; endif ; call _prmes## ; endm ; ;************************************************************************ ;* * ;* AWAIT char1,char2,char3,char4 * ;* wartet, bis eines der angegebenen * ;* Zeichen oder Ctrl-C an der Console * ;* eingegeben wird. Bei Ctrl-C Kaltstart * ;* * ;************************************************************************ await macro c1,c2,c3,c4 ; erwarte eines von maximal local weiter,getch,flush; 4 Zeichen von der Console flush: call stdsts ; jr z,getch ; call stdin ; jr flush ; getch: call stdin ; Console Input ifnb ; cp c1 ; erstes Zeichen? jr z,weiter ; endif ; ifnb ; cp c2 ; jr z,weiter ; endif ; ifnb ; cp c3 ; jr z,weiter ; endif ; ifnb ; cp c4 ; jr z,weiter ; endif ; cp ctrl_c ; jr nz,getch ; exit ,"^C" ; weiter: ; endm ; ;************************************************************************ ;* * ;* PRINTF [iocvector], string, argumente... * ;* druckt String und Zahlen formatiert aus. * ;* Wenn iovector nicht angegeben wird, entf{llt * ;* Neudefinition des Vektors. Ist iovector = 0, so wird * ;* in Abh{ngigkeit von BIOSIO die Standardausgaberoutine * ;* benutzt, bei anderen Werten iowr_(iovector). * ;* Werden nicht gen}gend Argumente angegeben, so werden * ;* weitere vom Stack geholt (first pushed = last used) * ;* * ;************************************************************************ printf macro iovec,string,arg1,arg2,arg3 local strptr ; dseg ; strptr: db string,0 ; cseg ; ifnb ; ld iy,iovec ; endif ; ifnb ; ifnb ; ifnb ; ld hl,arg3 ; arg3 specified push hl ; endif ; ld hl,arg2 ; arg2 specified push hl ; endif ; ld hl,arg1 ; arg1 specified push hl ; endif ; ld hl,strptr ; call _printf## ; call output routine endm ; ;************************************************************************ ;* * ;* SCANF iovector,string * ;* pr}ft String und liest Werte ein * ;* * ;************************************************************************ scanf macro iovec,string ; we return everything in HL local strptr ; dseg ; strptr: db string,0 ; cseg ; ifnb ; special input routine specified? ld iy,iovec ; then use user defined input endif ; else assume user has loaded iy before ld hl,strptr ; call _scanf## ; endm ; ;************************************************************************ ;* * ;* Standard und Error I/O-Vektoren * ;* * ;************************************************************************ entry _exit, _exit0 ; entry stdin, stdout, stdsts entry errin, errout, errsts _exit: ld de,(errout+1) ; error-vector ld (stdout+1),de ; is stdout call _prmes## ; ifndef no_delsub ; bdos delete_file,subfcb dseg ; subfcb: db 1,'$$$ SUB' ; do not continue JOB-Control fill 21,0 ; cseg ; endif ; _exit0: if files ; call _clsal## ; endif ; if biosio ; bios wboot ; stdin: jp _biosin## ; stdout: jp _biosout## ; stdsts: jp _biossts## ; errin: jp _biosin## ; errout: jp _biosout## ; errsts: jp _biossts## ; else ; bdos system_reset ; stdin: jp _bdosin## ; stdout: jp _bdosout## ; stdsts: jp _bdossts## ; errin: jp _bdosin## ; errout: jp _bdosout## ; errsts: jp _bdossts## ; endif ; .list ;