IMD 1.18: 30/01/2015 20:34:34 BIG BOARD USER DISK #2 Micro Cornucopia PO BOX 223 Bend, OR 97709  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  CROWE3 COM: CROWE3 Z80 CROWE3 Z80 !"#$%&'()CROWE3 Z80*+,-./0123456789*͑, @F#͑ ;8 8˰~' p +~F(x@G ( (,(; p(#xF˸~( ~) 2USRDISKDOC COPY ASM'COPY DOCBITMAP COM4  f ( :uO(ů2H2+!+"i!u˖!w#pů2v2#2$2 <2>92!:   (   CROWE3 Z80:;<=>?@ABCDEFGHICROWE3 Z80JKLMNOPQRSTUVWXYCROWE3 Z80Z[\]^_`abcdefghiCROWE3 Z80jklmnopqrstuvwxy#+~͘0  #y a' # y2(S!Mmk(DOq :k(y %~+(- yOO(a@("q""sѧR KOSBIOS DOC%CRCK3 COMSBOOT22 HEXSBOOT14 HEX ͺ!( w#2'2o2p!"q"s"k*#"%!uˆˎ?!> 2":  O (F (J (((` Iͪy; CROWE3 Z80z{|}~DKCOPY ASMXDKCOPY COM DKCOPY DOC(D@("q"sx(!~#(*(#N#y@(2o2p< ůG22R8v~͡8#͘8#.(?'( SCBIOS22HEXSCBIOS14HEX2USRDISKBAK2USRDISKCRCw#B  wOBJ #LͪwB q#B>((!~ # (=;(9A8 [0(~:(P #~ ( (BMAP7/11ASMMCROWE3 Z80oCROWELETTXTCROWLINKZ80>ØÁ`Í;y1!Yͧ(:!!uV(!?͙ SYMBOL TABLE OVERFLOW !b͙ CROWE Z80 ASSEMBLER V1.2 CO() $(g+͂͢ [##k|rv:( @(]2 =8@vc(_:G{0{D:DCROWELETTXT;(  !2"<*͑ (=;(9͘0A#>83~͘8x2~ ( (; !kk( "< SBOOT MACMDIR COM SCBIOS MAClCOPY COMPYRIGHT PAT CROWE 1978 ~(O#!͙!͙OGxQ(18502!< PASS NO. = A͌ͽD("͞(:k  (pˀ_{͸(g#>D(Yˀ_#c(T(͸(G_c( (9͸(0͜(): #H(Aͪ<IV!OSBͪ( ͑' )#T] ~ (# ͑ ( ;(Sͪ<Sͪ:oG:pO*q[s:k(K͉:k_!H ^#V|͜(͜(|(:+|͜(͜(|(#+|͜(8͜(2˰˸|  | ٧Z p(x(|D z>{>H>@>>AywD |>}:oD H͏:lAyD ͏>xD >xD y:0O 2s#r<ɯ!:(2O ^#V:l:lH͸:l~f0#+~B(D(hH3O(.Q(*Y~f020 0Ó͚#B #~f7~f0800Ó ͚#O(Q #~f7G~#($(* Sͪ(##N#fi!6 h Ʉ ͜(>͜(8˰˸z& |/  |/ R> p x(|͜(͜( zW{_|͜(͜( zW{_|D >xwD :l͸xwD :lͩ}xwD A͏:l͞xD yD >:lBxwD >͸x ͜(|͜( !R|͜( z/W{/_|͜(Z|͜(|ˈ͜(0͜(*| ||(||+|(|}͏:l͞H:l͏:l4͞xD ͏H:l|D }D (>F>H:l͸͏>~f0:00OBḰ͚͍́́#D #~f~f0G00 8Ó ͚#H #~f7͡A8GH( O(Q(7!111=EIWpjw@p@p@**@KTbk}z!(͜( zW{_|͜(͜( R |͜(͜(zƀW|ƀgR0|͜(͜(zƀW|ƀgR0|͜wD >ͩ}xwD A͏>͞xD y yD ͏> xwD > xwD >>WxwD >:ywD H͋ <͜(Czt ͜(8zt R0DM!z(:0 J 0!Ct |͜( ͜( |͜( ͞:l}D >:l͸M}D A͏>M͞:l͏>H>>PD Hͥ> )Vͪ 0Vͪ (ͩ ^#VUͪ# ^# V# 7ɧ~' #~'ɯ#~͘0 (#. :/DQZlxwyt{wyt{&vFrU}igyIG' t2{2yEwWd| *q"#"%!u(͜( R0|͜(͜( R0|!H!w# *͔ (y!8 ( HZ *͔ (y!8 (y2'>͏>6ͩ͞}xD H͏>xHD ( >>K͏>*͏>p͸͞ywD H>>Gy͜( |z(zt zt z Zͪ!5#: !:R8 PY{Oyt At !R?}ͥ>}ͥ>}[#R}怴(}/(Rͪ>>H>}ǴD }xw0!kF#((2= ~* >52#!: 0O <2w<ɯ!:( =2O <~!Sͪ:k( "%|( Sͪ*#DM(0( jSͪc ͩ(:(PͪH>C:(.##N(Mͪ/ wD >2yAD ( >>C͏>"xAO͏>F͞H>ͩ}>@͸HxD yAD ͏>:o(SRL8BIT@SETRESRETRSTPOPADCSBCADDSUB CALLDEFLDEFBDEFWDEFSDEFMHALT vRLCA RRCA LDIR LDDR CPIR~(# ~ ~# xŁ=_!+N ()!F##~8 ## ((( >O  :(O2*2$!#"(D  NO SOURCE FILE FOUND $:xO+͌(>O2Q2K!#"OG:pX>P(>Xͩ}|(<(VͪGyGyGy}|!(:'_w{2'*#:'_ CPDR RETI MRETN EINIR INDR OUTI OTIR OUTD OTDR DJNZPUSHTITLE SlAwBpCqDrEsHtLuZPMI R!AFBCDEHLSPIXIY<:0*m!k :0m!Mk(Wͪ7*[iR0!u+ѧ*iR#*iT]:O "i********* ;INITIALIZE PASS ;**************************************************************************** INITP: PUSH BC ; S C ͺ#~+~##  N#(M(  ͺ:!80<2!  !uN( ͲEF(Ͳ<:'G(3*%:v DISK ERROR,ASSEMBLY ABORTED $:QOR͌(>O2x2r!'"v:xO(:QO#*O+ '*vR}(6ŷR <"#Sͪ>2':((:" BVV:uOT!Ny (#:"O *%:'W!( zNCNZPEPOAF'@HLPa`qʺξORzEQGTLTNOTLOW'RES.MODMSHRUSHL]ANDsXORUGTULTHIGH+-\*=/E&s^z=>!~ #A8[ɷ08:ɷ:" y2"ɿELDJPCP 8INOR 0DI EI IMRLRRJREXINC DEC OUTAVE REG XOR A ; CLEAR ACC. LD (OBJCNT),A ; CLEAR OBJECT BUFFER COUNT LD (ADREFC),A ; SET ADDR REF CNTR = 0 LD (ADREF "w#"%!(Y~!{:v_w{<2v Ͳ :v(3G:x*w!{~# z  2v:W*E(!&6C€}ƀo0$*v|+(q#"vÈ!'R!':ʄ*O|'(q#"OÈ!(&~##({  ͺ ͺC ͺGOxOzW 007:|}:!< Z80N EINIR INDR OUTI OTIRC PRNDJNZPUSHTITLE SlC HEXLuZPMI R!AFBCDEHLC:G:AND ORGEQUENDEXX DAA 'CPL /CCF ?SCF 7NOP RLA RRA LDI LDD CPI CPD NEG DRLD oRRD gINI IND XOR (RLCSLA RRCSRAC+1),A LD (PAGE+1),A ; SET PAGE NO. = 1 INC A LD (PAGE),A LD A,PLINES-9 ; SET LINE NO. = MAX SIZE LD (LINE),A LD Ay>z  x#x( ~P8p~P0#A8[08:?(_(7?7:G_~#fo#+!#*(|#(~#"(È( {_0 !80 <2!   ͺ  ͺ!1yCROWE Z80 ASSEMBLER V1.2 PAGE ͇;2!  !Hy  ͺ~(Oy :*O*~#"Q1(^2]3ʥ4(P1423Q!e~N( B >2+#~N( B >2R ,(PASSNO) ; GET PASS NO. CP 3 JR NZ,INITP1 ; JUMP IF NOT CALL RUNOUT ; PUNCH 30 CM RUNOUT LD C,CR ; PUNCH CR CAL TOKEN FOR 'DEFM' PSUEDO-OP PLUTOK EQU 07H ; TOKEN FOR MONADIC PLUS MINTOK EQU 0FH ; TOKEN FOR MONADIC MINUS LBTOK EQU 0B; ASCII DELETE CTOK EQU 71H ; TOKEN FOR UNCONDIT. OPND KW 'C' CCOND EQU 8BH ; TOKEN FOR CONDITIONAL OPND KW 'C' XYMASK EQ ;EOF CHARACTER ;**************************************************************************** ;START OF PROGRAM. ;I/O ROUNGLAND ; THE 'LBFSZ-1' AND ; THE "EX AF,AF'" BUGS FIXED BY ; THOMAS HAMEENAHO ; DJAKNEGATAN 7 ; S-754 23 UPPSALA ; TING STKSIZ EQU 68 ; SIZE OF STACK ; CP/M LINKS CPM EQU 5 ;FDOS ENTRY BOOT EQU 0 ;WARM START SETDMA EQU 26 ;CP/M FL PCHO LD C,LF ; PUNCH LF CALL PCHO JR INITP3 INITP1: CP 2 ; PASS 2? JR Z,INITP2 ; JUMP IF SO CP 4 ; PASS 4? 0H ; TOKEN FOR '(' EXPTOK EQU 35H ; TOKEN FOR EXPONENTIATION ASKTOK EQU 3DH ; TOKEN FOR MULTIPLY MAXFSK EQU 10D ; MAU 0FBH ; MASK TO RECOGNISE IX/IY TOKENS IXORIY EQU 1AH ; COMMON VALUE OF IX/IY TOKENS INTTOK EQU 90H ; OPERAND TOKEN FORTINE JUMP TABLE. ;THE USER SHOULD PLACE THE ADDRESSES OF HIS ;OWN I/O SUBROUTINES IN THE LOCATIONS IN ;THIS TABLE CONTAINING  SWEDEN ;************************************************************************* ;CONSTANTS ;******************************UNCTION OPNFIL EQU 15 ;OPEN FILE CLSFIL EQU 16 ;CLOSE FILE DELFIL EQU 19 ;DELETE FILE MAKFIL EQU 22 ;CREATE FILE RDNR E TITLE 'Crowe Z80 assembler' ;COPYRIGHT 1978 BY PAT CROWE ;*******************************************************************X SIZE OF ARITHMETIC ; FUNCTION STACK MAXASK EQU 20D ; MAX SIZE OF ARITH STACK PLINES EQU 66 ; NO OF LINES ON LIST D 'INTEGER' ORGTOK EQU 1 ; TOKEN FOR 'ORG' PSEUDO-OP EQUTOK EQU 2 ; TOKEN FOR 'EQU' PSEUDO-OP DEFLTK EQU 3 ; TOKEN FOR 'THE DESTINATIONS OF ;JP INSTRUCTIONS. ALL I/O IS PERFORMED VIA ;THIS TABLE. ;******************************************************************************************* CR EQU 0DH ; ASCII CARRIAGE RETURN LF EQU 0AH ; ASCII LINE FEED HT EQU 09H QU 20 ;READ NEXT RECORD WRNR EQU 21 ;WRITE NEXT RECORD PRBUF EQU 9 ;PRINT STRING ON CONSOLE DFCB EQU 5CH ;DEFAULT FCB DE*** ; Z80 ASSEMBLER VERSION 1.2 ; WRITTEN BY PAT CROWE ; 22 RINGSBURY CLEVICE PAGE LBFSZ EQU 64 ; LINE BUFFER CAPACITY ACBSIZ EQU 32 ; SIZE OF ASSD CODE BUFFER TITSIZ EQU 32 ; SIZE OF TITLE BDEFL' PSEUDO-OP DEFSTK EQU 7 ; TOKEN FOR 'DEFS' PSEUDO-OP TITTOK EQU 09H ; TOKEN FOR 'TITLE' PSEUDO-OP DEFMTK EQU 08H ;**************************** ORG 100H START: JR MAIN ; JUMP PAST JUMP TABLE CI: JP CONIN ; JUMP TO USER CONSOLE IN SUB; ASCII HORIZ. TAB FORMFD EQU 0CH ; ASCII FORM FEED NUL EQU 0 ; ASCII NULL SPACE EQU 20H ; ASCII SPACE DEL EQU 0FFH FBUF EQU 80H ;DEFAULT BUFFER GETCON EQU 0F009H ;PFM-80 CONSOLE INPUT PUTCON EQU 0F00CH ;PFM-80 CONSOLE OUTPUT CTLZ EQU 1AHOSE ; PURTON ; SWINDON ; SN5 9DE ; EUFFER RECSIZ EQU 16 ; MAX NO OF DATA BYTES PER OBJ RECORD SPERL EQU 5 ; NO OF SYMBOLS PER LINE ; IN SYMBOL TABLE LIS R CO: JP CONOUT ; JUMP TO USER CONSOLE OUT SUBR LO: JP LSTO ; JUMP TO USER LIST OUT SUBR RI: JP RDRIN ; JUMP TO USERRKER IS 0 ;.............................................. CONST: PUSH BC ; SAVE REG CONST1: LD A,(HL) AND A JR Z,CONSTINT HERALD ON CONSOLE DEVICE. ;**************************************************************************** PHRLD: PUSH HL HL RET ; AND RETURN CRLF: DEFB CR DEFB LF DEFB 0 PASNO?: DEFM 'PASS NO. = ' DEFB 0 ;******************************TA ; IF SO, INITIALIZE CALL PASS ; PERFORM 1 PASS LD HL,AFLAGS ; TEST SYMB TAB OVERFLOW FLAG BIT 2,(HL) ; JRI ; GET CHAR FROM CONSOLE KEYBOARD LD C,A ; SAVE IN B AND C REGISTERS LD B,A CALL CO ; ECHO CHAR TO CONSOLE LD  READER IN SUBR PCHO: JP PCHOUT ; JUMP TO USER PUNCH OUT SUBR MEMCHK: JP MEMCK ; JUMP TO USER MEM CHECK SUBR EXEC: JP BO2 LD C,A CALL CO INC HL JR CONST1 CONST2: POP BC ; REPLACE REG RET ;*********************************************; SAVE REG LD HL,HERALD ; SET POINTER TO HERALD MESSAGE CALL CONST POP HL ; REPLACE REG RET HERALD: DEFB CR DEFB********************************************** ;PERFORM A PASS ;************************************************************** Z,MAIN1 ; JUMP IF NOT SET LD HL,WARNNG ; ELSE PRINT WARNING ON CONSOLE CALL CONST JR MAIN1 ; GO DO ANOTHER PASS ;A,B CP 'Q' ; QUIT? JR Z,GTPNO2 ; JUMP IF SO CP '1' ; INPUT IN RANGE 1-4 ? JR C,GTPNO1 ; NO, GO ASK FOR ANOTHEROT ; JUMP TO USER MONITOR ENTRY POINT ;MAIN PROGRAM LOOP. ;**************************************************************************************** ;GET PASS NUMBER ;ZERO FLAG SET IF 'Q' TYPED ;***************************************************** LF DEFM 'CROWE Z80 ASSEMBLER V1.2' DEFB CR DEFB LF DEFM 'COPYRIGHT PAT CROWE 1978' DEFB CR DEFB LF DEFB 0 ;.************** PASS: CALL INITP ; INITIALIZE FOR PASS PASS1: CALL INITL ; INITIALIZE FOR LINE CALL GLIN ; GET A L................................................ WARNNG: DEFB CR ; SYMTAB OVERFLOW WARNING MESSAGE DEFB LF DEFM 'SYMBOL  CP '5' JR NC,GTPNO1 ; DITTO AND 7 ; MASK TO GET BINARY PASS NO. LD (PASSNO),A ; SAVE IN PASS NO. STORE LD HL,************* MAIN: LD SP,0F900H ; SET STACK POINTER CALL INITA ; INITIALIZE ASSEMBLER CALL PHRLD ; PRINT HERALD M***************** GTPNO: PUSH HL ; SAVE REGISTERS PUSH BC GTPNO1: LD HL,CRLF ; POINT TO CR LF STRING CALL CONST ; O............................................. ;PRINT STRING ON CONSOLE DEVICE ;ON ENTRY HL POINTS AT STRING ;END OF STRING MAINE CALL GLAB ; GET LABEL JR Z,PASS4 ; JMP IF NO MORE PROC. REQD. CALL GETOR ; GET OPERATOR TOKEN JR TABLE OVERFLOW' DEFB CR DEFB LF DEFB 0 ;**************************************************************************** ;PRCRLF ; OUTPUT ANOTHER CR LF TO CONSOLE XOR A ; CLEAR ZERO FLAG INC A GTPNO2: POP BC ; REPLACE REGISTERS POP AIN1: CALL GTPNO ; GET PASS NO. JR Z,EXEC ; RETURN TO SYSTEM MONITOR LD A,(PASSNO) ; IS IT PASS 1? CP 1 CALL Z,INIUTPUT STRING TO CONSOLE DEVICE LD HL,PASNO? ; POINT TO 'PASS NO.?' STRING CALL CONST ; OUTPUT STRING TO CONSOLE CALL C Z,PASS4 ; JUMP IF NO MORE PROC. REQD. LD A,(ORTKBF) ; IS OPERATOR 'TITLE'? CP TITTOK ; TOKEN FOR TITLE? JR NZ,PAS. = MAX SIZE LD (LINE),A LD A,(PASSNO) ; GET PASS NO. CP 3 JR NZ,INITP1 ; JUMP IF NOT CALL RUNOUT ; PUNCH 30 CM RU ; SAVE IN MEMTOP LD (HL),A INC HL LD (HL),B POP BC ; REPLACE REGS POP HL RET ;**********************************R OPERATOR TOKEN BUFFER LD HL,(ADREFC) ; COPY ADDR REF CNTR LD (ADDISR),HL ; INTO ADDR DIS REG LD HL,AFLAGS ; SET PNTR *********************************************** ;INITIALIZE ASSEMBLER ;********************************************************************************************************* INITL: PUSH BC ; SAVE REGS PUSH HL XOR A ; CLEAR ACC LD HL,ASSCOD S2 ; NO, IS OPERATOR 'DEFM'? CALL TITL ; YES, PROCESS ITS OPERAND JR PASS5 PASS2: CP DEFMTK ; TOKEN FOR 'DEFM'? JNOUT LD C,CR ; PUNCH CR CALL PCHO LD C,LF ; PUNCH LF CALL PCHO JR INITP3 INITP1: CP 2 ; PASS 2? JR Z,INITP2 ****************************************** ;INITIALIZE PASS ;*****************************************************************TO ASSEMBLER FLAGS RES 0,(HL) ; CLEAR ADDR DISCONTINUITY FLAG RES 1,(HL) ; CLEAR 'END' FLAG POP HL POP BC RET ;********************* INITA: PUSH HL ; SAVE REGS PUSH BC ; XOR A ; CLEAR ACC LD (TITBUF),A ; EMPTY TITLE BUFFER  ; SET PNTR TO ASSD CODE BUFFER LD B,ACBSIZ ; LOAD CNTR WITH SIZE OF BUFFER INITL1: LD (HL),A ; CLEAR A LOCATION INC HL R NZ,PASS3 CALL DM ; YES, PROCESS ITS OPERAND JR PASS5 PASS3: CALL GTOD ; NEITHER, PROCESS NORMAL OPERANDS JR Z,PASS; JUMP IF SO CP 4 ; PASS 4? JR NZ,INITP3 ; JUMP IF NOT INITP2: LD C,FORMFD ; LIST FORM FEED CALL LO LD C,CR ; LIS*********** INITP: PUSH BC ; SAVE REG XOR A ; CLEAR ACC. LD (OBJCNT),A ; CLEAR OBJECT BUFFER COUNT LD (ADREFC),A ; ********************************************************************** ;GET LINE FROM READER ;COPIES LINE OF SOURCE TEXT INTO  LD (SYMTAB),A ; CLEAR SYMBOL TABLE LD HL,SYMTAB ; PUT SYMBOL TABLE START ADDR LD (SYMEND),HL ; INTO 'END OF SYMBOL TABLE ; INCR PNTR DJNZ INITL1 ; LOOP UNTIL DONE LD (ASCDNO),A ; SET 'BYTES ASSD CODE' = 0 LD (ODBT1),A ; CLEAR OPERAND TOK4 ; JMP IF NO MORE PROC. REQD. PASS5: CALL PTOK ; PROCESS TOKENS PASS4: CALL PFRLO ; PERFORM RELEVANT OUTPUT LD A,(AFT CR CALL LO LD C,LF ; LIST 3 LF'S LD B,3 CALL OUTC CALL LFEED ; LIST PAGE HEADER INITP3: POP BC ; REPLACE REG SET ADDR REF CNTR = 0 LD (ADREFC+1),A LD (PAGE+1),A ; SET PAGE NO. = 1 INC A LD (PAGE),A LD A,PLINES-9 ; SET LINE NOLINBUF ;ECHOES TO PRINTER IF PASS2 ;************************************************************************* GLIN: PUSH HL ' STORE LD HL,AFLAGS ; CLEAR SYMTAB OVERFLOW FLAG RES 2,(HL) CALL MEMCHK ; GET HIGHEST AVAIL MEM IN B-A LD HL,MEMTOP EN BUFFERS LD (ODBT2),A LD HL,0 ; CLEAR OPERAND INTEGER BUFFERS LD (ODINT1),HL LD (ODINT2),HL LD (ORTKBF),HL ; CLEALAGS) ; TEST FOR END STATEMENT BIT 1,A JR Z,PASS1 ; GO PROCESS ANOTHER LINE IF NOT RET ;*************************** RET ;************************************************************************** ;INITIALIZE LINE ;*************************  ; SAVE REGS PUSH DE PUSH BC LD B,LBFSZ-1 ; SET LINE BUFFER SIZE LD HL,LINBUF ; SET POINTER TO LINE BUFFER LD DE,0  ; REACHED NEXT TAB POSITION? LD A,7 AND E JR Z,GLIN11 DEC B ; BUFFER FULL? JR Z,GLIN9 JR GLIN3 GLIN4: POP BC ;; PUT CR IN BUFFER LD C,A ; IF PASS 2 FLAG SET BIT 0,D CALL NZ,LO ; OUTUT CR TO LIST DEVICE BIT 1,D ; REACHED COMMT LABEL JR GLAB7 GLAB3: INC HL LD A,(HL) GLAB7: CP SPACE ; FOLLOWED BY SP/CR/;? JR Z,GLAB4 CP CR JR Z,GLAB4 CP 'R CONTROL CHAR? JR NZ,GLIN5 LD C,'I' ; PUT 'ILLEGAL CHAR'IN ERROR DISP CALL ERROR JR GLIN1 GLIN5: LD A,C ; GET CHAEG GLAB1: LD A,(HL) ; SCAN TO FIRST NON SPACE CHAR CP SPACE JR NZ,GLAB2 SET 2,B ; SET 'NOT FIRST COL' FLAG INC HL  ; CLEAR TAB COUNTER (E) & STATUS REG LD A,SPACE ; PUT SPACE CHAR IN ERROR BUFFER LD (ERRBUF),A LD A,(PASSNO) ; SET 'PA REPLACE REGS POP DE POP HL RET ;********************************************************************** ;GET LABEL ;LOCENT BEFORE BUFFER FULL? JR NZ,GLIN4 LD C,'L' ; PUT 'LINE TOO LONG' IN ERROR DISP CALL ERROR JR GLIN4 GLIN2: LD (HL),A;' JR Z,GLAB4 GLAB5: CALL DNOPS ; RESERVE 4 DEFAULT NOP'S CALL ADJARC ; ADJUST ADDRESS REF COUNTER XOR A ; SET ZEROR BACK CP ';' ; SET COMMENT FLAG IF ';' JR NZ,GLIN7 SET 1,D GLIN7: LD (HL),A ; PUT IN BUFFER INC HL ; INCREMENT B ; POINT TO NEXT CHAR JR GLAB1 GLAB2: CP CR ; NULL LINE? JR Z,GLAB8 CP ';' ; COMMENT? JR Z,GLAB8 CP 'A' ; IT ISSS2' FLAG IF PASS 2 CP 2 JR NZ,GLIN1 SET 0,D GLIN1: CALL RI ; GET CHAR FROM READER LD C,A ; SAVE IT IN C CP CR ATES LABEL (IF ANY) IN LINBUF AND PUTS IT IN LABBUF. ;LEAVES POINTER TO CHARACTER AFTER LABEL IN LINPNT. ;ZERO SET IF NOTHING  ; PUT CR IN BUFFER BIT 0,D ; IF PASS 2 FLAG SET CALL NZ,LO ; OUTPUT TO LIST DEVICE JR GLIN4 GLIN3: LD C,SPACE ;  FLAG JR GLAB8 GLAB6: LD HL,LINBUF ; SET POINTER TO START OF LINBUF XOR A ; SET 'NO LABEL IN BUFFER' LD (LABBUF),A GLUFFER POINTER BIT 0,D ; IF PASS 2 FLAG SET, CALL NZ,LO ; OUTPUT CHAR TO LIST DEVICE INC E ; INCREMENT TAB COUNTER G A-Z? JR C,GLAB5 CP 'Z'+1 JR NC,GLAB5 CALL GSYM ; PUT SYMBOL IN BUFFER LD A,(HL) ; FOLLOWED BY ':'? CP ':' JR ; IS IT CR? JR Z,GLIN2 CP HT ; IS IT TAB? JR Z,GLIN3 CP LF ; IS IT LINE FEED? JR Z,GLIN1 ; IGNORE CP NUL ; IELSE TO PROCESS ;********************************************************************** GLAB: PUSH HL ; SAVE REGS PUSH DE TAB. PUT SPACE IN BUFFER LD (HL),C INC HL BIT 0,D ; IF PASS 2 FLAG SET, CALL NZ,LO ; OUTPUT TO LIST DEVICE INC E AB4: LD (LINPNT),HL ; DEPOSIT LINE POINTER XOR A ; CLEAR ZERO FLAG INC A GLAB8: POP BC ; REPLACE REGS POP DE POP HLIN11: DEC B ; BUFFER FULL? JR NZ,GLIN1 GLIN9: CALL RI ; SCAN TO NEXT CR FROM READER CP CR JR NZ,GLIN9 LD (HL),A Z,GLAB3 ; JUMP IF FOLLOWED BY ':' ; I.E. IT'S A LABEL BIT 2,B ; STARTED IN FIRST COLUMN? JR NZ,GLAB6 ; JUMP IF NOS IT A NULL CHAR? JR Z,GLIN1 ; IGNORE CP DEL ; IS IT A DELETE CHAR? JR Z,GLIN1 ; IGNORE AND 60H ; IS IT ANY OTHE PUSH BC LD HL,LINBUF ; SET POINTER TO LINE BUFFER LD DE,LABBUF ; SET POINTER TO LABEL BUFFER LD B,0 ; CLEAR STATUS R  L RET ;********************************************************************* ;GET OPERATOR TOKEN, ;LOCATES OPERATOR (IF ANP'S CALL ADJARC ; ADJUST ADDRESS REF COUNTER XOR A ; SET ZERO FLAG JR GETOR7 ;***************************************CH NEXT CHAR AGAIN CP SPACE JR Z,GETOR6 CP CR JR Z,GETOR6 CP ';' JR NZ,GETOR3 ; INVALID SYNTAX GETOR6: EXX ; SEN A CP '''' ; IS IT A '? JR NZ,GTOD18 ; JUMP IF NOT BIT 6,B ; QUOTE FLAG SET? JR NZ,QUOTE ; IF SO, QUOTE PUSH HLIT A LETTER? JR NC,GETOR3 ; NO, SYNTAX ERROR LD DE,SYMBUF+1 ; SET POINTER TO SYMBOL BUFFER LD B,0 ; SET COUNT = 0 GETBRACKETS' FLAG & 'QUOTE' FLAG) GTOD1: CALL SCNSP ; SCAN TO FIRST NON SPACE CHAR CP ',' ; IS IT A COMMA? JR NZ,GTOD2 BY) AND PUTS TOKEN AND VALUE FOR IT IN ORTKBF. ;LEAVES POINTER TO CHARACTER AFTER OPERATOR IN LINPNT ;ZERO FLAG SET IF NOTHING ******************************* ;GET OPERAND TOKENS AND VALUES ;LOCATES OPERANDS (IF ANY) AND SETS TOKENS FOR THEM IN ODBT1/ODT UP PARAMETERS FOR OPTOK LD HL,ORLSTP LD DE,ORTKBF LD C,2 CALL OPTOK ; GET TOKENS FROM LIST EXX JR Z,GETOR3 ; IN ; PREP TO CHECK IF AF' DEC HL ; POINT TO PREV CHAR LD A,(HL) POP HL ; RESTORE POINTER CP 'F' ; IS IT 'F'? JR OR4: LD (DE),A ; PUT CHAR IN OPERATOR BUFFER INC HL ; INCR LINBUF POINTER INC DE ; INCREMENT SYMBUF POINTER INC B IT 0,B ; YES, FOUND 1 OPERAND? JP Z,GTOD25 ; NO, SYNTAX ERROR INC HL ; YES, SCAN TO NEXT NON SP CHAR CALL SCNSP JR ELSE TO PROCESS. ;********************************************************************** GETOR: PUSH HL ; SAVE REGISTERS PBT2 ;AND CORRESPONDING INTEGER VALUES (IF ANY) IN ODINT1/ODINT2. ;ZERO FLAG SET IF NOTHING ELSE TO PROCESS ;*****************VALID SYNTAX, NOT IN LIST GETOR2: LD (LINPNT),HL ; DEPOSIT LINE BUFFER POINTER XOR A ; CLEAR ZERO FLAG INC A GETOR7: POZ,GTOD28 ; YES, THEN NO QUOTE QUOTE: LD A,B ; COMPLEMENT QUOTE FLAG XOR 01000000B LD B,A JR GTOD28 ; AND CONTINUE TO; INCR CHAR COUNT LD A,5 ; GREATER THAN 5? CP B JR C,GETOR3 ; YES, SYNTAX ERROR LD A,(HL) ; GET NEXT CHAR CALL ALGTOD3 GTOD2: CP ';' ; IS IT A ';'? JP Z,GTOD24 CP CR ; OR A CR? JP Z,GTOD24 GTOD3: PUSH HL ; NO, SET POINTER TO STUSH DE PUSH BC EXX PUSH HL PUSH DE PUSH BC LD HL,(LINPNT) ; FETCH POINTER TO LINE BUFFER GETOR1: CALL SCNSP ; SC***************************************************** GTOD: PUSH IX ; SAVE REGISTERS PUSH IY PUSH HL PUSH DE PUSH BC P BC ; RECOVER REGISTERS POP DE POP HL EXX POP BC POP DE POP HL RET GETOR3: CALL DNOPS ; RESERVE 4 DEFAULT NO SCAN GTOD18: CP CR ; IS IT CR? JR Z,GTOD5 ; FOUND DELIMITER, JUMP CP SPACE ; IS IT SPACE JR Z,GTOD27 ; JUMP IF SOPHA ; IS IT A LETTER JR C,GETOR4 ; YES, LOOP LD A,B ; SAVE # OF OPR CHARS IN SYMBUF LD (SYMBUF),A LD A,(HL) ; FETART POP IX ; OF OPERAND IN IX ; SCAN TO NEXT DELIMITER RES 6,B ; CLEAR QUOTE FLAG GTOD4: LD A,(HL) ; GET CHAR IAN TO FIRST NON SPACE CHAR GETOR5: CP CR ; IS IT CR? JR Z,GETOR2 CP ';' ; IS IT ';'? JR Z,GETOR2 CALL ALPHA ; IS  EXX PUSH HL PUSH DE PUSH BC LD HL,(LINPNT) ; GET LINE BUFFER POINTER LD B,0 ; CLEAR B (OPERAND COUNTER, ; '   CP ',' ; IS IT A COMMA? JR Z,GTOD27 ; JUMP IF SO CP ';' ; IS IT ; ? JR NZ,GTOD28 ; CONTINUE SCAN OF NONE OF THESEOR CONDITIONAL? JR Z,GTOD12 LD C,CCOND ; TOKEN FOR CONDITIONAL 'C' GTOD12: LD A,C ; GET TOKEN AND XYMASK ; IS IT IXIT '? JR NZ,GTOD8 LD (DE),A ; SAVE IT IN BUFFER INC HL ; POINT TO CHAR FOLLOWING INC C ; INCREMENT COUNT GTOD ; YES, CHECK IF VALID, POINT TO LIST GTOD20: LD A,(HL) ; GET A TOKEN INC HL ; POINT TO REPLACEMENT TOKEN AND A ; IS  NZ,GTOD6 SET 7,B ; SET BRACKETS FLAG IN B INC IX ; AND CLOSE IN POINTERS DEC IY GTOD6: PUSH IX ; GET POINTER TO STGTOD14: PUSH IY ; END OF OPERAND? POP DE AND A ; CLEAR CARRY FLAG SBC HL,DE JR NZ,GTOD25 ; SYNTAX ERROR JR GTOD11 GTOD27: BIT 6,B ; IS QUOTE FLAG SET? JR Z,GTOD5 ; JUMP IF NOT, FOUND DELIMITER GTOD28: INC HL ; POINT TO NEXT CHAR /IY ? CP IXORIY JR NZ,GTOD14 LD A,(HL) ; GET FOLLOWING CHAR CP '+' JR Z,GTOD13 CP '-' JR NZ,GTOD14 GTOD13: LD A8: LD A,C ; PUT COUNT IN SYMBUF LD (SYMBUF),A AND A ; IF COUNT=0 THEN JR Z,GTOD9 ; GO TO EVAL EXPRESSION EXX ; TOKEN 0 ? JR Z,GTOD25 ; YES, NOT IN LIST, SYN. ERR. CP C ; IS IT EQUAL TO ACTUAL TOKEN? JR Z,GTOD19 ; YES, GO REPLACE ART OF OPERAND POP HL LD DE,SYMBUF+1 ; SET POINTER TO SYMBUF LD C,0 ; ZERO CHAR COUNT GTOD10: LD A,(HL) ; FETCH A CH GTOD9: CALL EVAL ; EVALUATE EXPRESSION ; RESULT IN HL JR Z,GTOD25 ; SYNTAX ERROR BIT 0,B ; FOUND 1 OPERAND? JJR GTOD4 ; AND LOOP ; FOUND DELIMITER GTOD5: PUSH HL ; SET POINTER (IY) TO CHAR POP IY ; AFTER END OF OPERAND I,C ; CONVERT TOKEN TO DUMMY VALUE AND 0FH OR 0C0H LD C,A PUSH HL ; CLOSE POINTER IN TO START OF EXPRESS POP IGET OPERAND KEYWORD TOKEN LD HL,OPKLST LD DE,TEMP LD C,1 ; 1 BYTE PER TOKEN CALL OPTOK EXX JR Z,GTOD9 ; JUMP IFIT INC HL ; POINT TO NEXT TOKEN JR GTOD20 GTOD19: LD C,(HL) ; REPLACE TOKEN WITH ; BRACKETTED VERSION. INC IY AR CALL ALPHA ; IS IT A LETTER? JR NC,GTOD7 LD (DE),A INC C ; INCR COUNT INC HL ; AND POINTERS INC DE LD A,R Z,GTOD17 LD (ODINT1),HL ; SAVE VALUE IN FIRST OPERAND BUFFER JR GTOD16 GTOD17: LD (ODINT2),HL ; SAVE VALUE IN 2ND OPND NC B ; INCR # OF OPERANDS FOUND LD A,B ; IS IT > 2 ? AND 3 CP 3 JP Z,GTOD25 ; YES, SYNTAX ERROR RES 7,B ; CLEARX CALL EVAL ; GET VALUE OF EXPRESSION IN HL JR Z,GTOD25 ; SYNTAX ERROR BIT 0,B ; FOUND 1 OPERAND? JR Z,GTOD15 LD  NO KEYWORD FOUND LD C,A ; SAVE TOKEN IN C CP CTOK ; TOKEN FOR C? JR NZ,GTOD12 LD A,(ORTKBF) BIT 7,A ; IS OPERAT ; OPEN OUR FINAL POINTER AGAIN GTOD21: LD A,C ; SAVE TOKEN IN RELEVANT BUFFER BIT 0,B ; FOUND 1 OPERAND? JR Z,GTOD22 C CP 3 JR NZ,GTOD10 JR GTOD9 ; MORE THAN 2 LETTERS, GO ; EVALUATE EXPRESSION GTOD7: CP '''' ; NOT LETTER, IS BUFF GTOD16: LD C,INTTOK ; SET TOKEN FOR 'INTEGER' GTOD11: BIT 7,B ; WAS IT IN BRACKETS? JR Z,GTOD21 ; NO LD HL,BKLST  BRACKETS FLAG LD A,(IX) ; DOES IT START WITH ( ? CP '(' JR NZ,GTOD6 LD A,(IY-1) ; DOES IT END WITH ) ? CP ')' JR(ODINT1),HL ; SAVE VALUE IN 1ST OPERAND BUFFER JR GTOD11 GTOD15: LD (ODINT2),HL ; SAVE VALUE IN 2ND OPND BUFF JR GTOD11   LD (ODBT1),A ; SAVE TOKEN IN 1ST OPND BUFF JR GTOD23 GTOD22: LD (ODBT2),A ; SAVE TOKEN IN 2ND OPND BUFF GTOD23: PUSH IY GO PROC. R.H. BRKT CP '$' ; IS IT '$'? JR Z,CURLC ; YES, GO PROC. CURR. LOC. SCHF: CALL PSCF ; PROCESS AS SINGLE CHAR HL,DE EX DE,HL JP Z,EOEX ; END OF EXPRESSION JP C,EVAL6 ; END OF EXPRESSION ERROR LD A,(HL) ; GET A CHAR CALL DCTION JR Z,FUN4 ; NO PREVIOUS FUN, PUSH NEW ONE LD E,A ; SAVE TOP OF STACK IN E LD A,(FTOKR) ; GET NEW FUNCTION TOKENINTS AT CHAR AFTER END OF EXPRESSION ;ON EXIT: ; HL CONTAINS VALUE OF EXPRESSION ; AND ZERO FLAG IS SET IF SYNTAX ERROR ;***AL1 MCF: CALL PMCF JP Z,EVAL6 ; SYNTAX ERROR FUN: LD A,(FTOKR) ; GET FUNCTION TOKEN CP PLUTOK ; IS IT TOKEN FOR +?  ; POINT AT NEXT THING POP HL JP GTOD1 ; GO PROCESS NEXT TOKEN GTOD24: XOR A ; CLEAR ZERO FLAG INC A GTOD26: POP BC . FUNCTION JP Z,EVAL3 ; INVALID CHAR ERROR JR FUN LIT: CALL PLIT ; PROCESS AS LITERAL JR OPND SYMB: CALL PSYMB JR IGIT ; IS IT A DIGIT? JR C,LIT ; YES, GO PROCESS LITERAL CALL ALPHA ; IS IT A LETTER? JR C,SYMB ; YES, GO PROCESS  AND 7 ; MASK OFF PRIORITY BITS IN NEW OPR LD B,A ; SAVE IN B LD A,E AND 7 ; MASK OFF PRIORITY BITS OF TOS CP B ********************************************************************* EVAL: PUSH DE ; SAVE REGISTERS PUSH BC EXX PUSH BJR Z,FUN1 CP MINTOK ; IS IT TOKEN FOR -? JR NZ,FUN2 ; +/- FUN1: EXX ; WAS LAST UNIT START/(/FUNCTION ? BIT 0, ; REPLACE SAVED REGISTERS POP DE POP HL EXX POP BC POP DE POP HL POP IY POP IX RET GTOD25: CALL DNOPS ; OPND ASC: CALL PASC ; PROCESS OS ASCII STRING JR OPND CURLC: LD DE,(ADREFC) ; CURRENT VALUE OF ADDR REF ; COUNTER RSYMBOL CP '.' ; IS IT A '.'? JR Z,MCF ; YES, GO PROCESS M/CHAR FUNCTION CP '''' ; IS IT A '? JR Z,ASC ; YES, GO  ; COMPARE PRIORITIES JR NC,FUN5 ; GO DO A FUNCTION ; NEW FUNCTION HAS HIGHER ; PRIORITY SO PUSH IT ON ; C XOR A ; CLEAR ROUTINE FLAG REGISTER LD B,A EXX LD (ARCNT),A ; CLEAR STACKS LD (FCNT),A PUSH IX ; POINT TO STAB EXX JR Z,FUN3 ADD A,5DH ; CHANGE TOKEN TO DIADIC LD (FTOKR),A JR FUN3 FUN2: CP 3DH ; DIADIC FUNCTION JR C,FUNAPPEND DEFAULT NOP'S CALL ADJARC ; ADJUST ADDRESS REF COUNTER XOR A JR GTOD26 ;****************************************EQUIRED INC HL ; POINT TO NEXT EXPR CHAR JR OPND1 OPND: JP C,EVAL4 ; 'VALUE' ERROR OPND1: CALL PUDE ; PUSH VALUE (INPROC. ASCII CHAR CP '(' ; IS IT A '('? JP Z,LBKT ; YES, GO PROC. LEFT BRKT CP ')' ; IS IT ')'? JP Z,RBKT ; YES, STACK. LD A,E ; FIRST PUSH BACK TOP OF STACK CALL PUFU FUN4: LD A,(FTOKR) ; THEN PUSH NEW FUNCTION CALL PUFU JR Z,EVRT OF EXPR. POP HL EVAL1: PUSH IY ; END OF EXPRESSION? POP DE ; I.E. HL=IY ? EX DE,HL AND A ; CLEAR CARRY SBC3 EXX ; WAS LAST UNIT START/(/FUNCTION? BIT 0,B EXX JP Z,EVAL6 ; SYNTAX ERROR FUN3: CALL POFU ; GET PREVIOUS FUN******************************** ;EVALUATE AN EXPRESSION ;ON ENTRY AND EXIT: ; IX POINTS AT FIRST CHAR OF EXPRESSION ; IY PO DE) ONTO ; ARITHMETIC STACK JP Z,EVAL5 ; STACK OVERFLOW ERROR EXX ; SET 'LAST UNIT' FLAG SET 0,B EXX JR EV  AL5 ; STACK OVERFLOW ERROR EXX ; CLEAR 'LAST UNIT' FLAG RES 0,B EXX JP EVAL1 FUN5: LD A,E ; PUT T O S IN ACC LOW ERROR JR EVAL8 EVAL6: LD C,'S' ; SYNTAX ERROR JR EVAL8 EVAL7: LD C,'B' ; BALANCE ERROR EVAL8: CALL ERROR ; SET EXPR VALUE IN DE JR Z,EVAL6 ; SYNTAX ERROR (STACK EMPTY) LD A,(ARCNT) ; CHECK IF STACK NOW EMPTY AND A JR NZ,EVAL6 ;ITERAL JR PDEC ; DECIMAL LITERAL ;********************************************************************** ;PROCESS BINARY LANCE ERROR CP LBTOK ; IS IT A (? JR Z,RBKT1 CALL FUNC ; PERFORM THE FUNCTION JR Z,EVAL6 ; SYNTAX ERROR JR RBKT2 LIT. PLIT1: LD A,(HL) ; GET CHAR CALL HEXDG ; IS IT VALID DIG FOR LIT.? JR NC,PLIT2 INC HL ; YES, POINT TO NEXT CHA CALL FUNC ; PERFORM A FUNCTION JR Z,EVAL6 ; SYNTAX ERROR JR FUN3 ; GO TRY NEXT FUNCTION ON STACK ;..................ERROR INDICATOR XOR A ; SET ZERO (ERROR) FLAG JR EOEX3 ; AND PREPARE TO EXIT ;***************************************** SYNTAX ERROR EX DE,HL EXX BIT 1,B ; TEST FOR ARITH OVERFLOW EXX JR Z,EOEX2 LD C,'A' EOEX4: CALL ERROR ; INDICAITERAL. ;********************************************************************** PBIN: PUSH BC ; SAVE REGISTERS LD DE,0 ; ; MORE OPS TO DO ? RBKT1: EXX ; SET 'LAST UNIT' FLAG SET 0,B EXX JP EVAL1 ;........................................R JR PLIT1 PLIT2: DEC HL ; NO, GO BACK TO LAST CHAR LD A,(HL) ; FETCH IT TO ACC. POP HL ; REPLACE POINTER TO START ................................ LBKT: INC HL ; POINT TO NEXT EXPR CHAR LD A,LBTOK ; SET TOKEN FOR '(' CALL PUFU ; PU***************************** ;PROCESS LITERAL. ;THIS SUBROUTINE INCLUDES PBIN, PDEC, ;PHEX, POCT. ;ON ENTRY: ; HL POINTS TTE ARITH OVERFLOW EOEX2: XOR A ; CLEAR ZERO FLAG INC A EOEX3: EXX POP BC EXX POP BC POP DE RET EVAL3: LD C,'I'  CLEAR 16 BIT ACC. PBIN1: LD A,(HL) ; GET CHAR CALL HEXDG ; VALID IN A LITERAL? JR NC,PBIN2 CP '1'+1 ; VALID IN BIN......... ; END OF EXPRESSION EOEX: CALL POFU ; POP FUNCTION STACK JR Z,EOEX1 ; NO MORE FUNCTIONS CP LBTOK JR ZOF LIT. CP 'B' ; WAS FINAL CHAR 'B' JR Z,PBIN ; BINARY LITERAL CP 'D' ; 'D'? JR Z,PDEC ; DECIMAL LITERAL CP 'HSH ON FUNCTION STACK JR Z,EVAL5 ; STACK OVERFLOW ERROR EXX ; CLEAR 'LAST UNIT' FLAG RES 0,B EXX JP EVAL1 ;.....O FIRST CHAR OF LITERAL ;ON EXIT: ; HL POINTS TO CHAR AFTER LITERAL ; DE CONTAINS VALUE OF LITERAL ; CARRY FLAG IS SET FOR V JR EVAL8 EVAL4: LD C,'V' ; VALUE ERROR LD HL,0 ; SET RESULT=0 JR EOEX4 ; NOT FATAL EVAL5: LD C,'O' ; STACK OVERFARY LIT.? JR NC,PBIN2 SUB '0' ; CONVERT ASCII TO BINARY LD C,A CALL SHLDE ; SHIFT DE LEFT CALL ADCDE ; & ADD,EVAL7 ; BALANCE ERROR CALL FUNC ; PERFORM THE FUNCTION JR Z,EVAL6 ; SYNTAX ERROR JR EOEX EOEX1: CALL PODE ; GET ' ; 'H'? JP Z,PHEX ; HEX LITERAL CP 'O' ; 'O'? JR Z,POCT ; OCTAL LITERAL CP 'Q' ; 'Q'? JR Z,POCT ; OCTAL L............................................. RBKT: INC HL RBKT2: CALL POFU ; POP FUNCTION STACK JR Z,EVAL7 ; EMPTY, BALALUE ERROR ;********************************************************************** PLIT: PUSH HL ; SAVE POINTER TO START OF   NEW DIG. TO DE INC HL ; INCREMENT POINTER TO NEXT CHAR. JR PBIN1 PBIN2: CP 'B' ; CHAR NOT BIN. DIG.. IS IT 'B'? JR NE ; DE X 5 CALL SHLDE ; DE X 10 POP BC ; RECOVER NEW DIGIT CALL ABCDE ; ADD IN NEW DIGIT INC HL ; POINT TO NEXFOR ERROR JR POCT5 ;********************************************************************* ;PROCESS DECIMAL LITERAL. ;******************************************* ;HEXDG. IS CHAR IN ACC VALID IN A LITERAL. ;CARRY SET IF HEX DIGIT OR H/O/Q. ;*********IT.? JR NC,POCT3 SUB '0' ; CONVERT ASCII TO BINARY LD C,A LD B,3 ; SHIFT DE LEFT 3 TIMES POCT2: CALL SHLDE DEC B  10D JR C,PHEX2 SUB 'A'-'0'-10D PHEX2: LD C,A LD B,4 ; SHIFT DE LEFT 4 TIMES PHEX3: CALL SHLDE DEC B ; DONE4 SHIFTZ,PBIN4 INC HL ; YES, POINT TO NEXT CHAR LD A,(HL) ; GET IT IN ACC CALL HEXDG ; VALID CHAR FOR A LIT.? PBIN3: POP BT CHAR JR PDEC1 PDEC2: CP 'D' JR NZ,PDEC3 INC HL LD A,(HL) ; GET IT IN ACC PDEC3: CALL HEXDG POP BC RET ;********************************************************************* PDEC: PUSH BC LD DE,0 ; CLEAR 16 BIT ACC. PDEC1: LD A,(HL)********************************************************** HEXDG: CALL DIGIT ; CARRY SET IF 0-9 RET C CP 'A' JR C,HEXDG ; DONE 3 SHIFTS YET? JR NZ,POCT2 CALL ADCDE ; ADD NEW DIGIT TO DE INC HL ; INCR POINTER TO NEXT CHAR JR POCT1 POCS YET? JR NZ,PHEX3 CALL ADCDE ; ADD NEW DIGIT TO DE INC HL ; INCREMENT POINTER TO NEXT CHAR JR PHEX1 PHEX4: CP 'H' C RET PBIN4: SCF ; SET CARRY FOR ERROR JR PBIN3 ;*********************************************************************************************************************************** ;PROCESS HEXADECIMAL LITERAL. ;********************************* ; GET CHAR CALL HEXDG ; VALID IN A LIT.? JR NC,PDEC2 CP '9'+1 ; VALID IN A DEC. LIT.? JR NC,PDEC2 SUB '0' ; C1 CP 'F'+1 RET C CP 'H' JR Z,HEXDG2 CP 'O' JR Z,HEXDG2 CP 'Q' JR Z,HEXDG2 HEXDG1: AND A ; NOT HEX DIG., CLEART3: CP 'O' ; CHAR NOT OCT DIG. IS IT 'O'? JR Z,POCT4 CP 'Q' ; IS IT 'Q'? JR NZ,POCT6 POCT4: INC HL ; YES, POINT TO  ; CHAR NOT HEX. IS IT 'H'? JR NZ,PHEX6 ; NO INC HL ; YES, POINT TO NEXT CAR LD A,(HL) ; GET IT IN ACC CALL HEXDG  ;PROCESS OCTAL LITERAL ;********************************************************************** POCT: PUSH BC LD DE,0 ; C********************************** PHEX: PUSH BC LD DE,0 ; CLEAR 16 BIT ACC. PHEX1: LD A,(HL) ; GET CHAR CALL HEXDG ONVERT ASCII TO BINARY LD C,A LD B,0 PUSH BC LD B,D LD C,E CALL SHLDE ; DE X 2 CALL SHLDE ; DE X 4 CALL ADCD CARRY RET HEXDG2: SCF ; HEX DIGIT, SET CARRY RET ;********************************************************************NEXT CHAR LD A,(HL) ; GET IT IN ACC CALL HEXDG ; VALID CHAR IN A LIT.? POCT5: POP BC RET POCT6: SCF ; SET CARRY  ; VALID CHAR FOR A LIT.? PHEX5: POP BC RET PHEX6: SCF ; SET CARRY FOR ERROR JR PHEX5 ;******************************LEAR 16 BIT ACC. POCT1: LD A,(HL) ; GET CHAR CALL HEXDG ; VALID IN LITERAL? JR NC,POCT3 CP '7'+1 ; VALID IN OCTAL L; VALID IN A LITERAL? JR NC,PHEX4 CP 'F'+1 ; VALID IN A HEX LIT.? JR NC,PHEX4 SUB '0' ; CONVERT ASCII TO BINARY CP * ;SHIFT DE LEFT 1 BIT - ENTER 0 FROM RIGHT. ;SET 'VALUE' ERROR IF OVERFLOW. ;***********************************************CE REGISTERS POP BC AND A ; CLEAR CARRY FLAG SO RET ; AS NOT TO INDICATE 'VALUE' ERROR ;****************************ALUE ;IN DE. ;******************************************************************** PSYMB: PUSH BC ; SAVE REGISTERS LD DE,RY: HL POINTS AT THE NEXT ITEM, ON EXIT: HL ;HAS BEEN INCREMENTED IF DOUBLE QUOTE. ZERO SET IF CHAR. ;........................ DE JR NC,ABCDE1 LD C,'V' ; CARRYOUT SO INDICATE 'V' ERROR CALL ERROR ABCDE1: POP BC RET ;**************************LD E,(HL) ; OTHERWISE SAVE CHAR IN E INC HL ; POINT TO NEXT CHAR CALL DOUBQ ; NEXT CHAR CLOSE QUOTE? JR NZ,PASC2 ; ********************** SHLDE: EX DE,HL ; DO SHIFT BY ADDITION IN HL ADD HL,HL EX DE,HL RET NC ; NO CARRY, SO RETURN ***************************************** ;PROCESS ASCII LITERAL. ;RETURN VALUE OF 1 OR 2 ASCII CHARACTERS. ;ON ENTRY: ; SYMBUF ; SET PNTR TO SYMBOL BUFFER CALL GSYM ; GET SYMB FROM LINE TO SYMBUF PUSH HL ; SAVE PNTR TO CHAR AFTER SYMB CA.............................. DOUBQ: LD A,(HL) ; GET CHAR CP '''' ; IS IT A QUOTE? JR NZ,DOUBQ1 ; JUMP IF NOT INC H******************************************* ;ADD C TO DE - NO OVERFLOW INDICATION ;*******************************************JUMP IF SO LD D,(HL) ; OTHERWISE SAVE IN D INC HL ; POINT TO NEXT CHAR CALL DOUBQ ; NEXT CHAR CLOSE QUOTE? JR NZ,P PUSH BC ; CARRY, SO INDICATE 'V' ERROR LD C,'V' CALL ERROR POP BC RET ;******************************************** HL POINTS TO START QUOTE ;ON EXIT: ; HL POINTS TO CHAR AFTER CLOSE QUOTE ; DE CONTAINS VALUE ; LL LOCATE ; FIND SYMB IN SYMTAB JR NZ,PSYMB1 ; NOT IN TABLE? LD E,(HL) ; MOVE VALUE TO DE INC HL LD D,(HL) JR PSYL ; POINT TO NEXT CHAR LD A,(HL) ; GET IT CP '''' ; IS IT A QUOTE? RET ; ZERO SET FOR CHAR ; CLEARED IF LA************************** ADCDE: PUSH BC EX DE,HL LD B,0 ADD HL,BC EX DE,HL POP BC RET ;*************************ASC2 ; JUMP IF SO PASC1: SCF ; ERROR, SET CARRY RET PASC2: AND A ; NO ERROR, CLEAR CARRY RET ;.....................************************* ;ADD BC TO DE - SET 'VALUE' ERROR IF OVERFLOW. ;**************************************************** CARRY FLAG SET IF ERROR ;*********************************************************************** PASC: LD DE,0 ; CLEAR 1MB2 PSYMB1: LD C,'U' ; INDICATE 'UNDEFINED' ERROR CALL ERROR LD DE,0 ; SET DE=0 DEFAULT VALUE PSYMB2: POP HL ; REPLAST QUOTE WAS ; CLOSE QUOTE. DOUBQ1: XOR A ; LIT CHAR. SET ZERO. RET ;******************************************************************************************* ;PROCESS SYMBOL. ;GET SYMBOL AND FETCH ITS VALUE FROM THE SYMBOL TABLE. RETURN V................................. ;DOUBLE QUOTE. ;IS NEXT ITEM IN STRING A CHARACTER OF THE END OF THE ASCII ;LITERAL? ON ENT***************** ABCDE: PUSH BC EX DE,HL ; DO ADDITION IN HL ADD HL,BC ; DO ADDITION EX DE,HL ; GET RESULT BACK TO6 BIT ACC. DE INC HL ; POINT TO CHAR AFTER QUOTE CALL DOUBQ ; IS NEXT CHAR CLOSING QUOTE? JR NZ,PASC2 ; JUMP IF SO  ********************* ;PROCESS MULTI-CHAR FUNCTION. ;ON ENTRY: ; HL POINTS TO FIRST CHAR OF FUNCTION STRING ;ON EXIT: ; HL  DE ; INCR. PNTR. TO TOKEN JR Z,PSCF2 ; JUMP IF MATCH INC DE ; OTHERWISE POINT TO NEXT ENTRY JR PSCF1 ; LOOP PSCON. ;ON ENTRY: ; HL POINTS AT FUNCTION CHAR ;ON EXIT: ; HL POINTS TO CHAR AFTER FUNCTION CHAR(S) ; FTOKR CONTAINS TOKEN FOR IN HL INC A ; INCREMENT STACK COUNTER LD (FCNT),A ; AND STORE NEW VALUE EX AF,AF' ; GET FUNCTION BACK LD (HL),A '.'? JR NZ,PMCF2 ; JUMP IF NOT LD A,(SYMBUF) ; GET NO OF CHARS CP 5 ; MORE THAN 4? JR NC,PMCF2 ; JUMP IF SO LD DEH ACC TO FUNCTION STACK. ;BYTE IN A IS PUSHED ONTO THE FUNCTION ;STACK (FSTK). IF NOT POSSIBLE OWING TO ;THE STACK BEING FULPOINTS TO CHAR AFTER FUNCTION STRING ; FTOKR CONTAINS TOKEN FOR FUNCTION ; ZERO FLAG SET FOR ERROR ;*************************F2: LD A,(DE) ; GET THE TOKEN LD (FTOKR),A ; & PUT IN TOKEN REG. CP ASKTOK ; IS IT * ?(MAYBE **) JR NZ,PSCF4 ; JUMP FUNCTION ; ZERO FLAG SET IF ERROR ;*********************************************************************** PSCF: PUSH BC ;; PUSH ONTO FUNCTION STACK XOR A ; CLEAR ZERO FLAG INC A PUFU1: POP BC ; REPLACE REGISTERS POP HL RET PUFU2: XOR A,FTOKR ; PNTR TO TOKEN REG. LD HL,MFLSTP ; PNTR TO OPR LIST LD C,1 ; 1 TOKEN/ENTRY IN LIST CALL OPTOK ; GET TOKEN L, THEN THE ZERO FLAG ;IS SET ON EXIT. ;*********************************************************************** PUFU: PUSH******************************************* PMCF: PUSH BC ; SAVE REGISTERS PUSH DE INC HL ; POINT TO CHAR AFTER '.' L IF NOT LD A,(HL) ; GET NEXT CHAR CP '*' ; IS IT '*'? JR NZ,PSCF4 ; JUMP IF NOT LD A,EXPTOK ; PUT TOKEN FOR ** IN  SAVE REGISTERS PUSH DE LD B,(HL) ; GET POTENTIAL FUNCTION INC HL ; & INCR PNTR LD DE,SCF1 ; SET UP POINTER TO LIS ; SET ZERO FLAG (STACK FULL) JR PUFU1 ;*********************************************************************** ;POP FROM JR PMCF3 PMCF1: XOR A ; SET ZERO TO INDICATE ERR. JR PMCF4 PMCF2: XOR A ; SET ZERO TO INDICATE ERROR PMCF3: POP HL PMC HL ; SAVE REGISTERS PUSH BC EX AF,AF' ; SAVE FUNCTION LD HL,FSTK ; LOAD START OF STACK ADDR LD A,(FCNT) ; GET STD A,(HL) ; GET IT CALL ALPHA ; IS IT A LETTER? JR NC,PMCF1 ; NO, SYNTAX ERROR LD DE,SYMBUF ; SET POINTER TO SYMBUF REG LD (FTOKR),A INC HL ; AND INCR PNTR AND A ; CLEAR ZERO FLAG JR PSCF4 PSCF3: XOR A ; SET ZERO TO INDICATE ERROT PSCF1: LD A,(DE) ; GET LIST ENTRY AND A ; IS IT ZERO? JR Z,PSCF3 ; END OF LIST, INVAL. CHAR CP B ; MATCH? INCFUNCTION STACK TO ACC ;THE TOP BYTE ON THE FUNCTION STACK IS ;POPPED INTO THE A REG. IF THE STACK WAS ;ALREADY EMPTY, THE ZERF4: POP DE POP BC RET ;*********************************************************************** ;PROCESS SINGLE CHAR FUNCTIACK COUNTER CP MAXFSK ; IS STACK FULL? JR NC,PUFU2 LD C,A ; COMPUTE TOP OF STACK LD B,0 ADD HL,BC ; TOP OF STACK CALL GSYM ; GET FUNCTION IN SYMBUF INC HL ; INCR PNTR PUSH HL ; AND SAVE IT ON STACK CP '.' ; WAS CHAR AFT. FUN. R PSCF4: POP DE ; REPLACE REGS POP BC RET ;*********************************************************************** ;PUS O FLAG IS SET ON ;EXIT ;*********************************************************************** POFU: PUSH HL ; SAVE REGS.  LD A,(ARCNT) ; GET STACK COUNTER AND A ; IS STACK EMPTY? JR Z,PODE1 SUB 2 ; DECR STACK COUNTER LD (ARCNT),A ; ANDXOR A ; CLEAR ZERO FLAG INC A PUDE1: POP BC POP HL RET PUDE2: XOR A ; SET ZERO FLAG (ERROR) JR PUDE1 ;***********DDR POINTER LD HL,FUNLST ADD HL,BC LD E,(HL) ; PUT SUBR START ADDR IN HL INC HL LD D,(HL) EX DE,HL LD DE,FUNC1 G FULL, THEN ;THE ZERO FLAG IS SET ON EXIT. ;*********************************************************************** PUDE: PUT THERE. ; IF THE STACK DID NOT CONTAIN ENOUGH ; VALUES THEN THE ZERO FLAG IS SET. ; ;THE FOLLOWING SUBROUTINES STARTI PUSH BC LD HL,FSTK ; LOAD START OF STACK ADDR LD A,(FCNT) ; GET STACK COUNTER AND A ; TEST FOR EMPTY STACK JR Z,P SAVE NEW VALUE LD C,A ; COMPUTE TOP OF STACK LD B,0 ADD HL,BC LD E,(HL) ; POP STACK TO DE INC HL LD D,(HL) XO*********************************************************** ;POP FROM ARITHMETIC STACK TO DE ;THE TOP WORD ON THE ARITHMETIC S; CALL RELEVANT FUNCTION INDIRECTLY PUSH DE JP (HL) FUNC1: POP BC POP DE POP HL RET ;...............................SH HL ; SAVE REGS. PUSH BC LD HL,ARSTK ; LOAD START OF STACK ADDR LD A,(ARCNT) ; GET STACK COUNTER CP MAXASK NG WITH ;THE LETTER F ARE ALL ASSEMBLY TIME ;ARITHMETIC/LOGIC FUNCTIONS, OPERATING ON ;THE ARITHMETIC STACK, AND BEING CALLEDOFU1 DEC A LD (FCNT),A LD C,A LD B,0 ADD HL,BC XOR A ; CLEAR ZERO FLAG INC A LD A,(HL) ; GET STACK TOP TO ACR A ; CLEAR ZERO FLAG INC A PODE1: POP BC ; REPLACE REGS POP HL RET ;**********************************************TACK ;IS POPPED INTO THE DE REG PAIR. IF ;THE STACK WAS EMPTY, THEN THE ZERO ;FLAG IS SET ON EXIT ;*************************.............................. ;FUNCTION LIST. ;CONTAINS POINTERS TO THE FUNCTION ;SUBROUTINES, USED BY SUBR 'FUNC' ;FOR AN  ; IS STACK FULL? JR NC,PUDE2 LD C,A ; COMPUTE TOP OF STACK LD B,0 ADD HL,BC ; TOP OF STACK IN HL ADD A,2 ; INC ;INDIRECTLY BY FUNC ;******************************************************************** FUNC: PUSH HL ; SAVE REGS. PUSC POFU1: POP BC ; REPLACE REGS. POP HL RET ;*********************************************************************** ;PU*********************** ;PERFORM A FUNCTION ;ON ENTRY: ; A CONTAINS THE COMBINED FUNCTION ; TOKEN/PRIORITY VALUE. ;ON EXIT:********************************************* PODE: PUSH HL ; SAVE REGS PUSH BC LD HL,ARSTK ; LOAD START OF STACK ADDR INDIRECT SUBR CALL BASED ON ;THE VALUE OF THE ARITHMETIC ;FUNCTION TOKEN. ;..................................................REMENT COUNTER BY 1 WORD LD (ARCNT),A ; STORE NEW VALUE OF COUNTER LD (HL),E ; PUSH DE ONTO STACK INC HL LD (HL),D H DE PUSH BC SRL A ; GET (FUNC TOKEN)*2 SRL A AND 0FEH LD C,A ; COMPUTE POINTER TO SUBROUTINE LD B,0 ; START ASH FROM DE TO ARITHMETIC STACK ;THE WORD IN DE IS PUSHED ONTO THE ;ARITHMETIC STACK. IF NOT POSSIBLE ;OWING TO THE STACK BEIN ; THE REQUIRED ASSEMBLY TIME FUNCTION ; HAS BEEN PERFORMED USING VALUE(S) ; ON THE ARITHMETIC STACK AND LEAVING ; THE RESUL ........... FUNLST: DEFW FMNPL DEFW FMNMN DEFW FNOT DEFW FHIGH DEFW FLOW DEFW FRES DEFW FEXP DEFW FMULT DEFW F************************* FHIGH: PUSH DE ; SAVE REGISTERS CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FHIGH1 ; ERROR I******************* ;FUNCTION NOT ;************************************************************** FNOT: PUSH DE ; SAVE REG. ; JMP IF ARITH STACK EMPTY EX DE,HL ; PUT EXPONENT IN HL CALL PODE ; GET OTHER NUMBER IN DE JR Z,FEXP5 ; JUMP IF ST******************************************************* ;FUNCTION MONADIC MINUS. ;********************************************ET ;*************************************************************** ;FNCTION RESULT ;CLEARS ARITHMETIC OVERFLOW FLAG ;******DIV DEFW FMOD DEFW FSHR DEFW FSHL DEFW FDIPL DEFW FDIMN DEFW FAND DEFW FOR DEFW FXOR DEFW FEQ DEFW FGT DEFF EMPTY LD E,D ; PUT HIGH BYTE IN DE LD D,0 CALL PUDE ; PUSH RESULT ON ARITH STACK FHIGH1: POP DE RET ;*********** CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FNOT1 ; JUMP IF EMPTY LD A,D ; COMPLEMENT DE CPL LD D,A LD A,E ACK EMPTY LD A,H ; EXPONENT ZERO? OR L JR NZ,FEXP1 ; JUMP IF NOT LD DE,1 ; RESULT = 1 CALL PUDE ; PUSH IT ON ST****************** FMNMN: PUSH DE ; SAVE REGS. PUSH HL CALL PODE ; GET VALUE OFF ARITH STACK JR Z,FMNMN1 ; JUMP IF E********************************************************* FRES: EXX ; CLEAR OVERFLOW FLAG RES 1,B ; BIT 1 IN REG B EXXW FLT DEFW FUGT DEFW FULT ;************************************************************** ;FUNCTION MONADIC PLUS. ;********************************************************* ;FUNCTION LOW. ;RETURNS LOW BYTE OF ARGUMENT AS RESULT. ;****************CPL LD E,A CALL PUDE ; PUSH BACK ON ARITH STACK FNOT1: POP DE ; REPLACE REG. RET ;**********************************ACK JR FEXP5 FEXP1: BIT 7,H ; EXPONENT NEGATIVE? JR Z,FEXP2 ; JUMP IF NOT LD DE,0 ; RESULT = 0 CALL PUDE ; PUSHMPTY LD HL,0 ; PUT 0 INTO HL AND A ; CLEAR CARRY SBC HL,DE ; SUBTRACT VALUE FROM 0 EX DE,HL ; GET RESULT IN DE  RET ;*************************************************************** ;FUNCTION EXPONENTIATE ;************************************************************************************* FMNPL: PUSH DE ; SAVE REG CALL PODE ; SEE IF VALUE AVAILABLE ON ********************************************** FLOW: PUSH DE ; SAVE REGISTERS CALL PODE ; GET VALUE FROM ARITH STACK JR**************************** ;FUNCTION HIGH. ;RETURNS HIGH BYTE OF ARGUMENT AS RESULT. ;************************************* IT ON STACK JR FEXP5 FEXP2: CALL PUDE ; PUSH THE NUMBER FEXP3: DEC HL ; DECR EXPONENT LD A,H ; IS IT ZERO NOW? OR CALL PUDE ; PUSH BACK ON STACK FMNMN1: POP HL ; REPLACE REGS. POP DE RET ;***************************************************************************** FEXP: PUSH HL ; SAVE REGS PUSH DE CALL PODE ; GET EXPONENT FROM STACK JR Z,FEXP5 STACK JR Z,FMNPL1 ; JUMP IF NOT (ZERO SET) CALL PUDE ; PUSH BACK ON STACK FMNPL1: POP DE ; REPLACE REG RET ;******* Z,FLOW1 ; ERROR IF EMPTY LD D,0 ; LOW BYTE ONLY REQD CALL PUDE ; PUSH BACK RESULT FLOW1: POP DE ; REPLACE REGS R  L JR Z,FEXP4 ; JUMP IF SO CALL PUDE ; PUSH THE NUMBER CALL FMULT ; & MULTIPLY JR FEXP3 ; LOOP FEXP4: XOR A ; NZ,NEGDE CALL PUDE ; PUSH PRODUCT ONTO ARITH STACK FMULT6: EXX ; REPLACE REGS. POP DE EXX POP BC POP DE POP H5 ; JUMP IF FINISHED SRL D ; SHIFT DE RIGHT INTO CARRY RR E JR NC,FMULT4 ; JUMP IF ZERO CARRY AND A ; CLEAR CARRY CK FMOD1: POP DE ; REPLACE REGISTERS POP HL RET ;**********************************************************************  ; SIGN FLAG EX DE,HL CALL PODE ; GET ANOTHER VALUE FROM STACK JR Z,FMULT6 ; JUMP IF EMPTY BIT 7,D ; IS IT -VE  REGISTERS POP HL RET ;********************************************************************** ;FUNCTION MODULO ;********* CLEAR ZERO FLAG INC A FEXP5: POP DE ; REPLACE REGISTERS POP HL RET ; **********************************************L RET ;*********************************************************************** ;FUNCTION DIVIDE ;************************** ADC HL,BC ; ADD MULTIPLICAND TO RUNNING TOTAL JP M,FMULT3 ; JUMP IF OVERFLOW TO BIT 15 JR NC,FMULT4 ; JUMP IF NO O/F T ;DIVIDE ;THIS SUBROUTINE IS USED BY FDIV AND FMOD ;IT DIVIDES DE BY HL, LEAVING THE QUOTIENT ;IN DE AND THE REMAINDER IN HL. CALL NZ,NEGDE ; IF SO, NEGATE, AND COMPL. ; SIGN FLAG AND A ; CLEAR CARRY SBC HL,DE ; TEST FOR LARGER NO. ADD************************************************************* FMOD: PUSH HL ; SAVE REGISTERS PUSH DE CALL PODE ; GET DI********************* ; FUNCTION MULTIPLY ; ******************************************************************* FMULT: PUSH H********************************************* FDIV: PUSH HL ; SAVE REGISTERS PUSH DE CALL PODE ; GET DIVISOR FROM ARITHO BIT 16 FMULT3: EXX ; SET OVERFLOW FLAG SET 1,B EXX FMULT4: SLA C ; SHIFT MULTIPLICAND LEFT RL B JR FMULT2 ; L ;SIGNED 16 BIT ARITHMETIC IS USED. ;********************************************************************** DIV: PUSH BC ;  HL,DE ; MULTIPLIER SHOULD BE SMALLER JR NC,FMULT1 ; JUMP IF CORRECT EX DE,HL ; OTHERWISE SWAP NOS. FMULT1: LD B,H ;VISOR FROM ARITH STACK JR Z,FMOD1 ; JUMP IF EMPTY EX DE,HL ; PUT IN HL CALL PODE ; GET DIVIDEND FOM ARITH STACK JRL ; SAVE REGISTERS PUSH DE PUSH BC EXX PUSH DE LD E,0 ; CLEAR E' (SIGN FLAG) EXX CALL PODE ; GET A VALUE  STACK JR Z,FDIV1 ; JUMP IF EMPTY EX DE,HL ; PUT IN HL CALL PODE ; GET DIVIDEND FROM ARITH STACK JR Z,FDIV1 ; JUOOP FMULT5: EX DE,HL ; GET RESULT BACK IN DE EXX ; SHOULD RESULT BE -VE? BIT 0,E ; (PRODUCT SIGN IN E') EXX CALLSAVE REGISTERS EXX PUSH DE LD DE,0 ; CLEAR DE' (D'=PLACE COUNT) ; (E'=SIGN COUNT) EXX BIT 7,D ; IS DIVIDEND  PUT MULTIPLICAND IN BC LD C,L LD HL,0 ; CLEAR HL FOR ACCUMALATOR FMULT2: LD A,D ; IS MULTIPLIER 0? OR E JR Z,FMULT Z,FMOD1 ; JUMP IF EMPTY CALL DIV ; DO THE DIVISION EX DE,HL ; GET REMAINDER IN DE CALL PUDE ; PUSH ONTO ARITH STAFROM ARITH STACK JR Z,FMULT6 ; JUMP IF EMPTY BIT 7,D ; IS IT NEGATIVE? CALL NZ,NEGDE ; IF SO, NEGATE, AND COMPLEMENT MP IF EMPTY CALL DIV ; DO THE DIVISION CALL PUDE ; PUSH QUOTIENT (IN DE) ONTO STACK FDIV1: POP DE ; REPLACE -VE? JR Z,DIV1 ; JUMP IF NOT EXX ; OTHERWISE FLAG IN E', BIT 7 SET 7,E ; TO GIVE SIGN OF REMAINDER EXX DIV1: BIT***************************************************** NEGDE: PUSH HL ; SAVE HL LD HL,0 ; NEGATE SIGNED NO. IN DE AND A ITH REMAINDER EXX ; GET SIGN FLAGS INTO C LD A,E EXX LD C,A BIT 7,C ; WAS DIVIDEND -VE? CALL NZ,NEGDE ; N************************* FSHL: PUSH DE ; SAVE REGS. PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FSHL3 ; JU RL D ; SET, COUNTING NO. OF PLACES JP P,DIV2 LD BC,0 ; CLEAR QUOTIENT REG BC DIV3: SLA C ; SHIFT QUOTIENT LEFT RL DE ; GET VALUE TO BE SHIFTED JR Z,FSHR3 ; JUMP IF EMPTY, ERROR FSHR1: LD A,H ; TEST HL FOR ZERO OR L ; AND CLEAR CA 7,D ; IS DIVIDEND -VE? CALL NZ,NEGDE ; IF SO NEGATE, AND INCR ; QUOTIENT SIGN BIT (E' BIT 0) EX DE,HL ; SWAP NOS ; CLEAR CARRY SBC HL,DE ; SUBTRACT DE FROM 0 EX DE,HL ; GET RESULT INTO DE EXX ; COMPLEMENT PRODUCT SIGN ; EGATE REMAINDER IF SO EX DE,HL ; SWAP BACK NOS. BIT 0,C ; IS QUOTIENT -VE? CALL NZ,NEGDE ; NEGATE IF SO DIV6: EXX MP IF EMPTY, ERROR EX DE,HL ; GET VALUE IN HL CALL PODE ; GET VALUE TO BE SHIFTED JR Z,FSHL3 ; ERROR IF EMPTY FSHL1B SRL D RR E AND A ; CLEAR CARRY SBC HL,DE ; SUBTRACT DIVISOR FROM DIVIDEND JR C,DIV4 ; JUMP IF TOO MUCH SUBTRACRRY JR Z,FSHR2 ; JUMP IF NO MORE SHIFTING SRL D ; SHIFT DE RIGHT ONE BIT RR E DEC HL ; DECR NO. OF SHIFTS REQD J. BIT 7,D ; IS DIVISOR -VE? CALL NZ,NEGDE ; IF SO NEGATE AND ; INCR QUOTIENT SIGN FLAG LD A,D ; IS DIVISOR ZEROBIT IN E' RR E CCF RL E EXX POP HL RET ;************************************************************************ ; ; REPLACE REGISTERS POP DE EXX POP BC RET ;************************************************************************* : LD A,H ; TEST HL FOR ZERO OR L ; AND CLEAR CARRY JR Z,FSHL2 SLA E ; SHIFT DE LEFT 1 BIT RL D DEC HL ; DTION INC BC ; OTHERWISE INCR QUOTIENT JR DIV5 DIV4: ADD HL,DE ; REPLACE EXCESSIVE SUBTRACTION DIV5: EXX ; DECR PLACR FSHR1 ; LOOP FSHR2: CALL PUDE ; PUSH RESULT BACK ON STACK FSHR3: POP HL ; REPLACE REGS POP DE RET ;**************? OR E JR NZ,DIV2 ; JUMP IF NOT LD C,'Z' ; FLAG 'DIV BY ZERO' ERROR CALL ERROR LD HL,0 ; RETURN ZERO RESULTS LFUNCTION SHIFT RIGHT. ;************************************************************************ FSHR: PUSH DE ; SAVE REGS. ;NEGATE DE ;USED BE FMULT AND DIV TO NEGATE CONTENTS OF DE ;AND COMPLEMENT A SIGN FLAG HELD IN E' BIT 0 ;********************ECR NO. OF SHIFTS REGD. JR FSHL1 ; LOOP FSHL2: CALL PUDE ; PUSH RESULT ON ARITH STACK FSHL3: POP HL ; REPLACE REGS. E COUNT DEC D EXX JR NZ,DIV3 ; LOOP IF NOT FINISHED LD D,B ; TRANSFER QUOTIENT TO DE LD E,C EX DE,HL ; SWAP W********************************************************* ;FUNCTION SHIFT LEFT ;**********************************************D DE,0 JR DIV6 ; GO TO END DIV2: EXX ; INCR PLACE COUNT INC D EXX SLA E ; SHIFT DIVISOR LEFT UNTIL SIGN  PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FSHR3 ; ERROR IF EMPTY EX DE,HL ; OTHERWISE PUT IN HL CALL PO POP DE RET ;********************************************************************* ;FUNCTION DIADIC ADDITION ;**************,FDIMN2 ; JUMP IF OF OPPOSITE SIGN ; NO OVERFLOW POSSIBLE EXX ; OTHERWISE SET SET 7,B ; +VE EXPECS. ;******************************************************************** FDIMN: PUSH HL ; SAVE REGS. PUSH DE CALL PODE  ; JUMP IF EMPTY EX DE,HL CALL PODE ; GET THE OTHER VALUE JR Z,FAND1 ; JUMP IF STACK EMPTY LD A,D ; DO 16 BIT LE? OR D JP M,FDIPL2 EXX ; YES, SET BOTH +VE FLAG SET 7,B EXX FDIPL2: AND A ; CLEAR CARRY FLAG ADC HL,DE ; ADFLOW FDIMN3: BIT 7,B ; RESULT -VE, WAS +VE EXPECTED? JR Z,FDIMN5 ; JUMP IF NOT FDIMN4: SET 1,B ; SET OVERFLOW FLAG (1,B******************************************************* FDIPL: PUSH HL ; SAVE REGISTERS PUSH DE CALL PODE ; GET 1ST VALTED FLAG EXX JR FDIMN2 FDIMN1: LD A,H ; TEST SIGN OF MINUEND AND A JP M,FDIMN2 ; JUMP IF OF OPPOSITE SIGN ; N ; GET MINUEND FROM STACK JR Z,FDIMN6 ; JUMP IF EMPTY, ERROR EX DE,HL ; PUT IN HL CALL PODE ; GET SUBTRAHEND JR Z,FOGICAL AND AND H LD D,A ; WITH RESULT IN DE LD A,E AND L LD E,A CALL PUDE ; PUSH RESULT ON STACK FAND1: POP HL D THE 2 VALUES EXX JP M,FDIPL3 BIT 6,B ; RESULT +VE JR Z,FDIPL5 JR FDIPL4 ; SET OVERFLOW FLAG FDIPL3: BIT 7,B J') FDIMN5: EXX ; SWITCH REGS BACK CALL PUDE ; PUSH RESULT ON ARITH STACK FDIMN6: POP DE ; REPLACE REGS POP HL RETUE TO BE ADDED JR Z,FDIPL6 ; STACK EMPTY- ERROR EX DE,HL ; PUT 1ST VALUE IN HL CALL PODE ; GET 2ND VALUE JR Z,FDIPLO OVERFLOW POSSIBLE EXX ; SET '-VE EXPECTED' FLAG SET 6,B EXX FDIMN2: EX DE,HL ; GET SUBTRAHEND IN HL AND A ; CLDIMN6 ; JUMP IF EMPTY EXX ; CLEAR +VE/-VE FLAGS IN B' RES 6,B ; (-VE EXPECTED FLAG) RES 7,B ; (+VE EXPECTED FLAG)  ; REPLACE REGS POP DE RET ;********************************************************************* ;FUNCTION OR ;***R Z,FDIPL5 FDIPL4: SET 1,B ; SET OVERFLOW FLAG FDIPL5: EXX EX DE,HL ; GET RESULT IN DE CALL PUDE ; PUSH RESULT ON ST ;********************************************************************** ;FUNCTION AND ;*************************************6 ; STACK EMPTY ERROR EXX ; CLEAR +VE/-VE FLAGS IN B' RES 6,B ; (-VE) RES 7,B ; (+VE) EXX LD A,H ; BOTH VALUEAR CARRY SBC HL,DE ; DO THE SUBTRACTION EX DE,HL ; GET THE RESULT IN DE EXX ; PREPARE TO EXAMINE B' JP M,FDIMN3  EXX LD A,D AND A ; TEST SIGN OF SUBTRAHEND JP M,FDIMN1 ; JUMP IF -VE LD A,H AND A ; TEST SIGN OF MINUEND JP P****************************************************************** FOR: PUSH DE ; SAVE REGS. PUSH HL CALL PODE ; GET VAACK FDIPL6: POP DE POP HL RET ;******************************************************************** ;FUNCTION DIADIC MINU********************************* FAND: PUSH DE ; SAVE REGISTERS PUSH HL CALL PODE ; GET VALUE FROM STACK JR Z,FAND1ES -VE? AND D JP P,FDIPL1 EXX ; YES, SET 'BOTH -VE' FLAG SET 6,B EXX JR FDIPL2 FDIPL1: LD A,H ; BOTH VALUES +V ; JUMP IF -VE RESULT BIT 6,B ; RESULT +VE, WAS -VE EXPECTED? JR NZ,FDIMN4 ; JUMP IF SO JR FDIMN5 ; OTHERWISE NO OVER LUE FROM ARITH STACK JR Z,FOR1 ; JUMP IF STACK EMPTY EX DE,HL ; PUT IN HL CALL PODE ; GET THE OTHER VALUE JR Z,FOR**************************************************************** FGT: PUSH DE ; SAVE REGS. PUSH HL CALL PODE ; GET VALUTH STACK JR Z,FEQ2 ; JUMP IF STACK EMPTY EX DE,HL ; PUT IT IN HL CALL PODE ; GET ANOTHER VALUE IN DE JR Z,FEQ2 ;E ; COMPARE VALUES LD DE,0 ; RESULT IN DE (0 OR 1) JR NC,FLT1 ; JUMP IF NOT LESS THAN DEC DE ; OTHERWISE RESULT= -L ; PUT IT IN HL CALL PODE ; GET THE OTHER VALUE JR Z,FXOR1 ; JUMP IF STACK EMPTY LD A,D ; DO 16 BIT XOR ON HL AND*********************************************** ;FUNCTION LESS THAN ;*********************************************************1 ; JUMP IF STACK EMPTY LD A,D ; DO 16 BIT LOGICAL OR OR H ; ON HL AND DE LD D,A ; RESULT IN DE LD A,E OR L E FROM ARITH STACK JR Z,FGT2 ; JUMP IF STACK EMPTY EX DE,HL CALL PODE ; GET THE OTHER VALUE IN DE JR Z,FGT2 ; JUMP JUMP IF STACK EMPTY AND A ; CLEAR CARRY SBC HL,DE ; COMPARE VALUES LD DE,0 ; RESULT IN DE (0 OR 1) JR NZ,FEQ1 ;1 FLT1: CALL PUDE ; PUSH RESULT ON STACK FLT2: POP HL ; REPLACE REGS POP DE RET ;************************************ DE XOR H LD D,A ; RESULT IN DE LD A,E XOR L LD E,A CALL PUDE ; PUSH RESULT ON ARITH STACK FXOR1: POP HL ; RE************ FLT: PUSH DE ; SAVE REGS PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FLT2 ; JUMP IF STACK EMPTLD E,A CALL PUDE ; PUSH RESULT ON STACK FOR1: POP HL ; REPLACE REGS POP DE RET ;************************************ IF STACK EMPTY LD A,D ; ADD 8000H TO EACH NO. ADD A,80H LD D,A LD A,H ADD A,80H LD H,A AND A ; CLEAR CARRY  JUMP IF VALUES NOT EQUAL DEC DE ; OTHERWISE LET RESULT= -1 FEQ1: CALL PUDE ; PUSH RESULT ON STACK FEQ2: POP HL ; REPL******************************** ;FUNCTION UNSIGNED GREATER THAN ;************************************************************PLACE REGS POP DE RET ;******************************************************************* ;FUNCTION EQUALS ;************Y EX DE,HL ; PUT VALUE IN HL CALL PODE ; GET THE OTHER VALUE IN DE JR Z,FLT2 ; JUMP IF STACK EMPTY LD A,D ; ADD ******************************** ;FUNCTION EXCLUSIVE OR ;******************************************************************** SBC HL,DE ; COMPARE VALUES LD DE,0 ; RESULT IN DE (0 OR 1) JR NC,FGT1 ; JUMP IF NOT GREATER THAN DEC DE ; OTHERACE REGS POP DE RET ;********************************************************************* ;FUNCTION GREATER THAN ;************* FUGT: PUSH DE ; SAVE REGS PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FUGT2 ; JUMP IF STACK EMPTY ******************************************************* FEQ: PUSH DE ; SAVE REGS PUSH HL CALL PODE ; GET VALUE FROM ARI8000H TO EACH NO. ADD A,80H LD D,A LD A,H ADD A,80H LD H,A EX DE,HL ; SWAP NOS. AND A ; CLEAR CARRY SBC HL,D FXOR: PUSH DE ; SAVE REGS PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FXOR1 ; JUMP IF STACK EMPTY EX DE,HWISE RESULT= -1 FGT1: CALL PUDE ; PUSH RESULT ON STACK FGT2: POP HL ; REPLACE REGS POP DE RET ;**********************  EX DE,HL CALL PODE ; GET THE OTHER VALUE IN DE JR Z,FUGT2 ; JUMP IF STACK EMPTY AND A ; CLEAR CARRY SBC HL,DE ND LD A,C ; GET COUNT OF STRING CP TITSIZ+1 ; MORE CHARS THAN SIZE OF TITBUF? JR C,TITL2 LD C,TITSIZ ; YES, FORCE TO) POINTS AT CHAR AFTER THE ; 'TITLE' PSEUDO-OPERATOR. ;ON EXIT: ; THE OPERAND (A STRING BETWEEN SINGLE SSD BYTES LD (ASCDNO),A NOP ; ROOM FOR SPARE INSTRUCTION NOP NOP EX DE,HL ; DO TRANSFER LD DE,ASSCOD DM3: CALL EX DE,HL ; PUT VALUE IN HL CALL PODE ; GET THE OTHER VALUE IN DE JR Z,FULT2 ; JUMP IF STACK EMPTY EX DE,HL ; SWAPBETWEEN QUOTES) ; HAS BEEN TRANSFERED INTO THE ; ASSEMBLED CODE BUFFER. ;****************************************; COMPARE VALUES LD DE,0 ; RESULT IN DE (0 OR 1) JR NC,FUGT1 ; JUMP IF NOT GREATER THAN DEC DE ; OTHERWISE RESULT= -1 TITBUF SIZE JR TITL3 TITL2: AND A ; IS IT 0 CHARS? JR Z,TITL5 TITL3: EX DE,HL ; DO TRANSFER LD DE,TITBUF TITL4: CA ; QUOTES) HAS BEEN TRANSFERED TO THE TITLE BUFFER. ;*******************************************************************  DOUBQ ; SKIP CHAR IF DOUBLE QUOTE LDI ; TRANSFER A CHAR JP PE,DM3 ; JUMP IF TRANSFER NOT COMPLETE DM4: POP BC ; R NOS. AND A ; CLEAR CARRY SBC HL,DE ; COMPARE VALUES LD DE,0 ; RESULT IN DE (0 OR 1) JR NC,FULT1 ; JUMP IF NO ******************************** DM: PUSH HL ; SAVE REGISTERS PUSH DE PUSH BC LD HL,(LINPNT) ; GET LINE POINTER CALL FUGT1: CALL PUDE ; PUSH RESULT ON STACK FUGT2: POP HL ; REPLACE REGS POP DE RET ;***********************************LL DOUBQ ; SKIP CHAR IF COUBLE QUOTE LDI ; TRANSFER A CHAR JP PE,TITL4 ; JUMP IF TRANSFER NOT COMPLETE TITL5: POP B TITL: PUSH HL ; SAVE REGISTERS PUSH DE PUSH BC LD HL,TITBUF ; CLEAR TITLE BUFFER LD C,TITSIZ+1 XOR A TITL1: LDEPLACE REGISTERS POP DE POP HL RET ;************************************************************************** ;LOCATE SLESS THAN DEC DE ; OTHERWISE RESULT= -1 FULT1: CALL PUDE ; PUSH RESULT ON STACK FULT2: POP HL ; REPLACE REGS POP DE STR ; FIND STRING JR Z,DM4 ; NOT FOUND LD A,C ; GET COUNT OF STRING CP ACBSIZ+1 ; MORE CHARS THAN SIZE OF A.C. BUF********************************* ;FUNCTION UNSIGNED LESS THAN ;**************************************************************C ; REPLACE REGISTERS POP DE POP HL RET ;************************************************************************ ;GE (HL),A INC HL DEC C JR NZ,TITL1 LD HL,(LINPNT) ; GET LINE POINTER CALL STR ; FIND STRING JR Z,TITL5 ; NOT FOUTRING ;ON ENTRY: ; HL POINTS TO CHAR AFTER OPERAND ;ON EXIT: ; HL POINTS TO FIRST CHAR OF ACTUAL STRING. ;  RET ;******************************************************************* ;GET TITLE TO TITLE BUFFER. ;ON ENTRY: ; (LINPNTF? JR C,DM1 ; NO LD C,ACBSIZ ; YES, FORCE TO SIZE OF BUFFER JR DM2 DM1: AND A JR Z,DM4 DM2: LD A,C ; SET NO. OF A****** FULT: PUSH DE ; SAVE REGS. PUSH HL CALL PODE ; GET VALUE FROM ARITH STACK JR Z,FULT2 ; JUMP IF STACK EMPTY T DEFM OPERAND. ;ON ENTRY: ; (LINPNT) POINTS AT CHAR AFTER ; DEFM PSEUDO-OPERATOR. ;ON EXIT: ; THE OPERAND (A STRING   BC CONTAINS NO OF CHARS IN THAT STRING ; (COUNTING 2 QUOTES AS 1 CHAR) ; ZERO FLAG IS SET FOR SYNTAX ERROR ; ; SAVE REGS PUSH DE PUSH BC LD A,(ORTKBF) ; GET TOKEN AGAIN AND 7FH ; MASK OFF CONDITIONAL FLAG BIT ADD A,A ; DO CODE IN BUFFER BASED ON OPERATOR ;AND OPERAND TOKENS. ;**********************************************************************OPS ; SYNTAX ERROR, APPEND NOP'S JR PTOK8 PTOK4: CALL PORG ; PROCESS ORG JR PTOK7 PTOK8: CALL ADJARC ; ADJUST ADDR R CNTR JR STR1 ; LOOP STR2: CALL SCNSP ; FIND NEXT NON SP CHAR CP CR ; MUST BE CR/; JR Z,STR3 CP ';' JR Z,STR3  JR Z,PTOK8 CP 0FDH ; END OF LIST - ERROR IND ONLY JR NZ,PTOK9 LD C,'S' ; INDICATE SYNTAX ERROR CALL ERROR JR PT************************************************************************** STR: CALL SCNSP ; SCAN TO NEXT NON SP CHAR CP 'UBLE IT LD E,A ; PUT INTO DE LD D,0 LD HL,PORL ; PUT 'PROCESS OPR' LIST PNTR IN HL ADD HL,DE ; ADD DE TO GE* PTOK: PUSH IX ; SAVE REGS PUSH HL PUSH DE PUSH BC LD A,(ODBT1) ; PUT OPD BYTE 1 IN B LD B,A LD A,(ODBT2) ; PUEF CNTR EXX ; REPLACE REGS POP BC POP DE POP HL EXX PTOK7: POP BC POP DE POP HL POP IX RET ;************* PUSH BC ; SYNTAX ERROR, BUT STRING FOUND LD C,'S' CALL ERROR ; INDICATE SYNTAX ERROR POP BC STR3: XOR A INC A REOK8 PTOK9: CP B ; COMPARE TOKEN JR Z,PTOK2 ; JUMP IF MATCH INC HL ; POINT TO NEXT TOKEN INC HL JR PTOK1 ; AND L''' ; IS IT A ' ? JR NZ,STR4 ; SYNTAX ERROR, STRING NOT FOUND INC HL ; POINT TO NEXT CHAR LD D,H ; SAVE POINTER INT PNTR TO PNTR TO ROUTIN LD E,(HL) ; GET POINTER IN DE INC HL LD D,(HL) EX DE,HL ; PUT IN HL CALL ODPBT ; GET OT OPD BYTE 2 IN C LD C,A LD HL,(ODINT1) ; PUT OPD INTEGER IN HL LD DE,(ODINT2) ; PUT OPD INTEGER IN DE LD A,(ORTKBF) ******************************************************** ;SYNTAX ERROR ;ALL THE FOLLOWING PROCESS SUBROUTINES ;RETURN VIA THIT STR4: LD C,'S' ; SYNTAX ERROR, STRING NOT FOUND CALL ERROR ; INDICATE ERROR XOR A ; SET ZERO FLAG (FOR ERROR) REOOP PTOK2: LD C,(HL) ; GET ADDR OF SUBROUTINE FROM LIST INC HL LD H,(HL) LD L,C PUSH HL ; GET ADDR IN IX P DE LD E,L LD BC,0 ; CLEAR BC STR1: ; COUNT CHARS TO NEXT 7 CALL DOUBQ ; END OF STRING QUOTE? JR NZ,STR2 ; JUPD PAIR BYTE LD B,A ; SAVE IN B PTOK1: LD A,(HL) ; GET VALID TOKEN FROM LIST INC HL ; INCR LIST POINTER CP 0FFH ; ; GET OPERATOR TOKEN CP ORGTOK ; TOKEN FOR ORG? JR Z,PTOK4 ; JUMP IF SO CALL PLAB ; PROCESS LABEL EXX PUSH HL S SUBROUTINE IF THEY ;NEED TO APPEND NOP'S IF THE CASE OF ;A SYNTAX ERROR. ;*************************************************T ; AND RETURN ;*********************************************************************** ;PROCESS TOKENS ;PRODUCE ASSEMBLEDOP IX LD HL,PTOK8 ; PUSH RETURN ADDR PUSH HL EXX ; SWAP REGISTER BANKS JP (IX) ; AND CALL INDIRECT PTOK3: CALL DNMP IF SO LD A,(HL) ; GET CHAR CP CR ; IS IT CR? JR Z,STR4 ; JUMP IF SO, ERROR INC HL ; INCR PNTR INC C ; AND COMPARE WITH END OF LIST FLAG JR Z,PTOK3 ; END OF LIST, NOT VALID COMBINATION CP 0FEH ; E.O.L. - NO NOP'S, NO ERROR IND ******************** SYNERR: CALL DNOPS ; ERROR, APPEND DEFAULT NOP'S RET ;..................................................... LST07: DEFB 90H ; DEFS N DEFW GP07 DEFB 0FDH ;......................................................... LST0B: D........................................... LSTNUL: DEFB 0FEH ;......................................................... LST0PR B,(IX+D)/(IY+) DEFW GP102 DEFB 0FFH ;........................................................... LST11: DEFB 40H ; JPSINGLE BYTE, NO OPERAND DEFW LST0B ; DOUBLE BYTE, NO OPERAND DEFW LST0C ; AND OR XOR CP SUB DEFW LST0D ; INC DEC DFW GP0D3 DEFB 0FFH ;.......................................................... LST0E: DEFB 90H ; IM N DEFW GP0E DEFB 0.... ;PROCESS OPERATOR LIST ;CONTAINS ADDRESSES OF SUBROUTINES ;TO PROCESS VARIOUS OPERATOR GROUPS. ;.......................EFB 0 ; NO OPERAND DEFW GP0B DEFB 0FFH ;......................................................... LST0C: DEFB 70H ; OP4: DEFB 0 ; NO OPD DEFW GP04 DEFB 90H ; SINGLE INTEGER DEFW GP04 DEFB 0FDH ;....................................... (HL)/(IX)/(IY) DEFW GP111 DEFB 89H ; JP CC,NN DEFW GP112 DEFB 90H ; JP NN DEFW GP113 DEFB 0FFH ;..............EFW LST0E ; IM DEFW LST0F ; RLC RL SLA RRC RR SRA SRL DEFW LST10 ; BIT SET RES DEFW LST11 ; JP DEFW LST12 ; JRFFH ;.......................................................... LST0F: DEFB 70H ; OPR R DEFW GP0F1 DEFB 40H ; OPR (HL)............................ PORL: DEFW LSTNUL ; NULL ROUTINE FOR NO OPERATOR DEFW LSTNUL ; NULL ROUTINE FOR ORG DEFW LR R DEFW GP0C1 DEFB 90H ; OPR N DEFW GP0C2 DEFB 40H ; OPR (HL)/(IX)/(IY) DEFW GP0C3 DEFB 0B0H ; OPR (IX.................. LST05: DEFB 90H ; DEFB N DEFW GP05 DEFB 0FFH ;.............................................................................................. LST12: DEFB 89H ; JR CC,E DEFW GP121 DEFB 90H ; JR E DEFW GP122 DEFB DEFW LST13 ; DJNZ DEFW LST14 ; CALL DEFW LST15 ; RET DEFW LST16 ; RST DEFW LST17 ; IN DEFW LST18 ; OUT /(IX)/(IY) DEFW GP0F2 DEFB 0B0H ; OPR (IX+D)/(IY+D) DEFW GP0F2 DEFB 0FFH ;......................................STNUL ; NULL ROUTINE FOR EQU DEFW LSTNUL ; NULL FOUTINE FOR DEFL DEFW LST04 ; END DEFW LST05 ; DEFB DEFW LST06 +D)/(IY+D) DEFW GP0C3 DEFB 0FFH ;......................................................... LST0D: DEFB 70H ; OPR R DEF......... LST06: DEFB 90H ; DEFW NN DEFW GP06 DEFB 0FFH ;................................................... 0FFH ;............................................................ LST13: DEFB 90H ; DJNZ NN DEFW GP13 DEFB 0FFH ;.... DEFW LST19 ; PUSH POP DEFW LST1A ; EX DEFW LST1B ; ADC SBC DEFW LST1C ; ADD DEFW LST1D ; LD ;.................................. LST10: DEFB 97H ; OPR B,R DEFW GP101 DEFB 94H ; OPR B,(HL)/(IX)/(IY) DEFW GP102 DEFB 9BH ; O ; DEFW DEFW LST07 ; DEFS DEFW LSTNUL ; NULL ROUTINE FOR DEFM DEFW LSTNUL ; NULL ROUTINE FOR TITLE DEFW LST0B ; W GP0D1 DEFB 40H ; OPR (HL)/(IX)/(IY) DEFW GP0D2 DEFB 0B0H ; OPR (IX+D)/(IY+D) DEFW GP0D2 DEFB 10H ; OPR RP DE ....................................................... LST14: DEFB 89H ; CALL CC,NN DEFW GP141 DEFB 90H ; CALL NN....................................... LST1D: DEFB 76H ; LD A,(BC)/(DE) DEFW GP1D1 DEFB 72H ; LD A,I/R DE1 DEFB 79H ; OPR A,N DEFW GP1B2 DEFB 74H ; OPR A,(HL)/(IX)/(IY) DEFW GP1B3 DEFB 7BH ; OPR A,(IX+D)/(IY+D) DEFW ASSEMBLED CODE HAS BEEN PLACED IN ASSEMBLED ; CODE BUFFER (ASSCOD). ; ADDRESS REFERENCE COUNTER HAS BEEN ADJUST: DEFB 0A7H ; OUT (C),R DEFW GP181 DEFB 0D7H ; OUT (N),A DEFW GP182 DEFB 0FFH ;.................................... DEFW GP1DC DEFB 7BH ; LD R,(IX+D)/(IY+D) DEFW GP1DC DEFB 79H ; LD R,N DEFW GP1DD DEFB 77H ; LD R,R DEFW GP1DE DEFW GP142 DEFB 0FFH ;............................................................ LST15: DEFB 00H ; RET DEFW GP151 FW GP1D2 DEFB 7DH ; LD A,(NN) DEFW GP1D3 DEFB 67H ; LD (BC)/(DE),A DEFW GP1D4 DEFB 49H ; LD (HL)/(IX)/(IY),N D GP1B3 DEFB 11H ; OPR HL,SS DEFW GP1B4 DEFB 0FFH ;............................................................... LST1ED. ;********************************************************************** ; ;*********************************************......................... LST19: DEFB 10H ; OPR RP DEFW GP19 DEFB 0FFH ;................................................ DEFB 11H ; LD SP,HL/IX/IY DEFW GP1DF DEFB 0FFH ;********************************************************************** DEFB 80H ; RET CC DEFW GP152 DEFB 0FFH ;............................................................ LST16: DEFB 90H EFW GP1D5 DEFB 19H ; LD RP,NN DEFW GP1D6 DEFB 1DH ; LD RP,(NN) DEFW GP1D7 DEFB 47H ; LD (HL)/(IX)/(IY),R DEFW C: DEFB 77H ; ADD A,R DEFW GP1C1 DEFB 79H ; ADD A,N DEFW GP1C2 DEFB 74H ; ADD A,(HL)/(IX)/(IY) DEFW GP1C3 DEFB************************* ;PROCESS ORG ;********************************************************************** PORG: PUSH HL ............. LST1A: DEFB 51H ; EX (SP),HL/IX/IY DEFW GP1A1 DEFB 1EH ; EX AF,AF' DEFW GP1A2 DEFB 11H ; EX DE,HL  ;ENTRY AND EXIT CONDITIONS FOR PORG, PLAB AND ;ALL GP... SUBROUTINES. ; ;ON ENTRY: ; B CONTAINS OPERAND-1 TOKEN BYTE; RST N DEFW GP16 DEFB 0FFH ;............................................................ LST17: DEFB 7DH ; IN A,(N) DGP1D8 DEFB 27H ; LD I/R,A DEFW GP1D9 DEFB 0B9H ; LD (IX+D)/(IY+D),N DEFW GP1D5 DEFB 0B7H ; LD (IX+D)/(IY+D),R  7BH ; ADD A,(IX+D)/(IY+D) DEFW GP1C3 DEFB 11H ; ADD HL/IX/IY,RP DEFW GP1C4 DEFB 0FFH ;........................ ; SAVE REGS PUSH BC CALL ODPBT ; GET OPERAND PAIR BYTE IN A CP 90H ; SINGLE INTEGER? JR NZ,PORG1 ; JUMP OTHERWISE DEFW GP1A3 DEFB 0FFH ;............................................................. LST1B: DEFB 77H ; OPR A,R DEFW GP1B ; C CONTAINS OPERAND-2 TOKEN BYTE ; HL CONTAINS OPERAND-1 INTEGER ; DE CONTAINS OPERAND-2 INTEGER ;ON EXIT: ;EFW GP171 DEFB 7AH ; IN R,(C) DEFW GP172 DEFB 0FFH ;............................................................ LST18DEFW GP1D8 DEFB 0D7H ; LD (NN),A DEFW GP1DA DEFB 0D1H ; LD (NN),RP DEFW GP1DB DEFB 74H ; LD (HL)/(IX)/(IY)   LD HL,(ODINT1) ; GET OPERAND-1 INTEGER LD (ADREFC),HL ; PUT IN ADDR REG CNTR LD (ADDISR),HL ; AND ADDR DISP REG  JUMP IF SO LD C,'P' ; OTHERWISE INDICATE PHASE ERROR CALL ERROR JR PLAB12 PLAB7: CALL INSERT ; INSERT IN SYMBOL TABLR NC,PLAB5 ; JUMP IF NOT PLAB13: POP AF ; GET OPR TOKEN PUSH AF CP DEFLTK ; IS IT DEFL? JR Z,PLAB4 CP EQUTOK ; OAB14: SET 1,(HL) ; SET MULT DEFN FLAG PLAB12: POP AF ; REPLACE REGS POP BC POP DE POP HL RET ;******************** Z,PLAB1 CP EQUTOK ; OR EQU? JR NZ,PLAB2 PLAB1: LD (ADDISR),HL ; DISPLAY VALUE IF SO CALL ODPBT ; GET OPD PAIR BYTE  D,(HL) DEC HL LD E,(HL) EX DE,HL ; GET IT INTO HL AND A ; CLEAR CARRY SBC HL,BC ; AND COMPARE OLD AND NEW VA LD HL,AFLAGS ; SET ADDR DISCONTINUITY FLAG SET 0,(HL) JR PORG2 PORG1: LD C,'S' ; INDICATE SYNTAX ERROR CAE JR PLAB12 ; ALREADY IN TABLE PLAB8: LD A,(PASSNO) ; IS THIS PASS 1? CP 1 JR Z,PLAB11 ; JUMP IF SO INC HL ; R EQU? JR NZ,PLAB12 PLAB4: LD C,'S' ; INDICATE SYNTAX ERROR IF SO CALL ERROR JR PLAB12 PLAB5: POP AF ; GET OPR TOKEN*********************************************** ;PROCESS END (GROUP 04) ;***************************************************** CP 90H ; SINGLE INTEGER? JR Z,PLAB3 ; JUMP IF SO, OK LD C,'S' ; ELSE INDICATE SYNTAX ERROR CALL ERROR JR PLAB3 LUES JR Z,PLAB12 ; JUMP IF EQUAL EX DE,HL ; ELSE INSERT NEW VALUE LD (HL),C INC HL LD (HL),B LD C,'P' ; AND INDLL ERROR PORG2: POP BC ; REPLACE REGS POP HL RET ;**********************************************************************MULT DEFN FLAG SET? INC HL BIT 1,(HL) JR Z,PLAB9 ; JUMP IF NOT LD C,'M' ; INDICATE MULT DEFN ERROR CALL ERROR J PUSH AF CP DEFLTK ; IS IT DEFL? JR NZ,PLAB6 ; JUMP IF NOT SET 0,(HL) ; SET DEFL FLAG IN ATTRIB PLAB6: CALL LOCATE************** GP04: LD (STADDR),HL ; LOAD START ADDR WITH INTEGER LD (ADDISR),HL ; LOAD ADDR DIS REG WITH INTEGER LD HL, PLAB2: LD HL,(ADREFC) ; GET CURRENT ADDR (LABEL VALUE) PLAB3: LD B,H ; COPY LABEL VALUE INTO BC LD C,L CALL LBSYM ICATE PHASE ERROR CALL ERROR JR PLAB12 PLAB11: INC HL ; POINT TO ATTRIBUTE BYTE INC HL POP AF ; GET OPR TOKEN PUS ;PROCESS LABEL (INCLUDES EQU AND DEFL) ;********************************************************************** PLAB: PUSH HLR PLAB12 PLAB9: POP AF ; GET OPR TOKEN PUSH AF CP DEFLTK ; IS IT DEFL? JR NZ,PLAB10 ; JUMP IF NOT DEC HL ; INSER ; LOCATE IN SYMBOL TABLE JR Z,PLAB8 ; JUMP IF ALREADY IN TABLE LD A,(PASSNO) ; IS THIS PASS 1? CP 1 JR Z,PLAB7 ;AFLAGS ; SET 'END' FLAG SET 1,(HL) RET ;******************************************************************** ;PROCESS DEF ; PUT LABEL AND VALUE IN SYMBUF JR Z,PLAB13 ; JUMP IF NO LABEL PRESENT CALL SYMCH ; CHECK IF SYMBOL IS RESERVED WORD JH AF CP DEFLTK ; IS IT DEFL? JR NZ,PLAB14 ; JUMP IF NOT BIT 0,(HL) ; TEST DEFL FLAG JR NZ,PLAB12 ; JUMP IF SET PL ; SAVE REGS PUSH DE PUSH BC LD A,(ORTKBF) ; GET OPR TOKEN PUSH AF ; SAVE ON STACK CP DEFLTK ; IS IT DEFL? JRT NEW VALUE LD (HL),B DEC HL LD (HL),C JR PLAB12 PLAB10: ; HAS VALUE CHANGED? DEC HL ; GET OLD VALUE IN DE LD B ;******************************************************************** GP05: CALL CHKOF ; CHECK FOR OVERFLOW BEYOND ;SSD CODE BUFFER RET ;******************************************************************** ;GROUP 0C - N ;******************LD A,(ORTKBF+1) ; GET OPCODE IN A CALL APPBT ; AND APPEND TO ASSD CODE BUFF RET ;*************************************** ; BUILD OP-CODE CALL IDREG ; INSERT REGISTER BITS CALL APPBT ; APPEND OPCODE TO BUFFER RET ;************************ LD DE,(ADREFC) ; ADD INTEGER TO ADDR REF CNTR ADD HL,DE LD (ADREFC),HL LD HL,AFLAGS ; SET ADDR DISCONT. FLAG SET 0,(HD LD A,(ORTKBF+1) ; GET OPR DISTING BITS OR 10000110B ; BUILD OP-CODE CALL APPBT ; APPEND TO ASSD CODE BUFF CA 8 BIT VALUE (AND FLAG IF SO) LD A,L ; APPEND 1 BYTE TO ASSD CODE BUFF CALL APPBT ; APPEND BYTE TO ASSD CODE BUFF RET ************************************************** GP0C2: LD A,(ORTKBF+1) ; GET OPR DISTING BITS OR 11000110B ; BUILD OP-CO***************************** ;PROCESS AND/OR/XOR/CP/SUB (GROUP 0C) ;*************************************************************************************************** ;GROUP 0D - (HL)/(IX+D)/(IY+D) ;***************************************************L) RET ;******************************************************************** ;PROCESS NO OPERAND. ;************************LL DISBT ; APPEND DISP. IF REQD RET ;******************************************************************* ;PROCESS INC/DEC  ;******************************************************************** ;PROCESS DEFW ;****************************************DE CALL APPBT ; APPEND IT TO ASSD CODE BUFF CALL CHKOF ; INDICATE OVERFLOW ERROR IF ANY LD A,L ; PUT INTEGER IN ASSD*********** ;GROUP 0C - R ;******************************************************************** GP0C1: LD A,(ORTKBF+1) ; GET*************** GP0D2: CALL INDPF ; GENERATE INDEX PREFIX IF REGD LD A,(ORTKBF+1) ; GET OPERATOR DISTING. BIT AND 000000******************************************** GP0B: LD A,(ORTKBF) ; GET OPR GROUP CP 0AH ; IS IT GROUP 0A? JR Z,GP0B1 (GROUP 0D) ;******************************************************************* ;GROUP 0D - R ;********************************************************** GP06: CALL APPWD ; APPEND TO ASSD CODE BUFF RET ;******************************************** CODE BUFFER CALL APPBT RET ;******************************************************************* ;GROUP 0C - (HL)/(IX+D)/( OPR DISTING BITS LD C,B ; COMBINE REG BITS CALL ISREG OR 10000000B ; BUILD OP-CODE CALL APPBT ; APPEND RESULT TO A01B OR 00110100B ; GENERATE OP-CODE CALL APPBT ; APPEND TO BUFFER CALL DISBT ; APPEND DISP. IF REQD RET ;*********; SKIP PREFIX BYTE IF SO LD A,0EDH ; LOAD PREFIX BYTE TO ASSD CODE BUFF CALL APPBT ; APPEND TO ASSD CODE BUFFER GP0B1: ************************************* GP0D1: LD C,B LD A,(ORTKBF+1) ; GET OPR DISTING. BIT AND 00000001B OR 00000100B ************************ ;PROCESS DEFS (GROUP 07) ;******************************************************************** GP07:IY+D) ;******************************************************************* GP0C3: CALL INDPF ; GENERATE INDEX PREFIX, IF REQ ********************************************************* ;GROUP 0D - IX/IY/BC/DE/HL/SP ;*************************************BT RET ;****************************************************************** ;GROUP OF - (HL)/(IX+D)/(IY+D) ;****************ALL APPBT ; APPEND TO ASSD CODE BUFF RET ;****************************************************************** ;PROCESS RLC/ BUFFER RET ;************************************************************************ ;GROUP 10 - B,(HL)/(IX+D)/(IY+D) ;************************************************************ GP0E: LD A,H ; GET HIGH BYTE AND A ; CHECK IT IS 0 JP NZ,SYNE ;GROUP 10 - B,R ;************************************************************************* GP101: ; OPD INTEGER ; ***************************** GP0D3: LD A,B ; GET OPERAND BYTE-1 CP 17H ; CHECK IF AF REFERENCE JP Z,SYNERR ; JUMP IF ************************************************** GP0F2: CALL INDPF ; APPEND INDEX PREFIX BYTE IF REQD LD A,0CBH CALL APRL/SLA/RRC/RR/SRA/SRL (GROUP 0F) ;****************************************************************** ;GROUP 0F - R ;****************************************************************************** GP102: ; OPD INTEGER ; MUST BE IN RANGE 0-7 LRR ; ERROR IF NOT, SO JUMP LD A,L ; GET LOW BYTE CP 3 ; IS IT 0,1 OR 2? JP NC,SYNERR ; JUMP IF NOT, ERROR AND A MUST BE IN RANGE 0-7 LD A,L ; SEE IF ANY BITS OTHER THAN AND 11111000B ; 3 L.S. BITS ARE 1 OR H JP NZ,SYNERR ; JUMPIT IS, ERROR CALL INDPF ; GENERATE INDEX PREFIX IF REQD LD C,B ; PUT OPERAND BYTE IN C LD A,(ORTKBF+1) ; GET OPR DISTPBT ; APPEND PREFIX BYTE CALL DISBT ; APPEND DISPLACEMENT BYTE IF REQD LD A,(ORTKBF+1) ; GET OPR DISTING. BITS OR 000******************************************************* GP0F1: LD A,0CBH ; APPEND PREFIX BYTE CALL APPBT ; TO ASSD CODE BD A,L ; SEE IF ANY BITS OTHER THAN AND 11111000B ; 3 L.S. BITS ARE 1 OR H JP NZ,SYNERR ; JUMP IF SO, ERROR LD B; IS IT ZERO? JR Z,GP0E1 ; JUMP IF SO INC A ; OTHERWISE INCREMENT GP0E1: LD C,A ; PUT IT IN C LD A,0EDH ; APPEND  IF SO, ERROR LD A,0CBH ; APPEND PREFIX BYTE TO BUFFER CALL APPBT LD A,(ORTKBF+1) ; GET OPD DISTING. BITS CALL ISREG ING. BIT AND 00001000B OR 00000011B ; BUILD OP-CODE CALL IREGP ; INSERT REGISTER PAIR BITS CALL APPBT ; APPEND THIS00110B ; BUILD OP-CODE CALL APPBT ; APPEND TO ASSD CODE BUFF RET ;******************************************************UFF LD C,B ; PUT OPD BYTE 1 IN C LD A,(ORTKBF+1) ; GET OPD DISTING. BITS CALL ISREG ; INSERT REGISTER BITS CALL APP,C CALL INDPF ; APPEND INDEX PREFIX IF REQD LD A,0CBH ; APPEND OP-CODE PREFIX CALL APPBT LD C,L ; GET INTEGER IN CPREFIX BYTE CALL APPBT ; TO ASSD CODE BUFFER LD A,01000110B ; GENERATE OP-CODE CALL IDREG ; INSERT PARAMETER BITS C ; COMBINE REGISTER BITS LD C,L ; GET INTEGER IN C CALL IDREG ; COMBINE INTEGER BITS CALL APPBT ; APPEND OP-CODE TO OPCODE TO BUFFER RET ;****************************************************************** ;PROCESS IM (GROUP 0E) ;**************************** ;PROCESS BIT/SET/RES (GROUP 10) ;*************************************************************************  EX DE,HL ; GET DISPLACEMENT INTEGER CALL DISBT ; APPEND IF REQD LD A,(ORTKBF+1) ; GET OPD DISTING. BITS OR 00000112,B ; CHECK IF PO/PE/P/M JP NZ,SYNERR ; JUMP IF SO, ERROR LD C,B ; PUT OPR BYTE 1 IN C EX DE,HL ; GET OPD INTEGER 2********************************************************************* GP113: LD A,0C3H ; APPEND OP-CODE TO BUFFER CALL APPB************************************************************ ;CALCULATE DISPLACEMENT ;****************************************X TO BUFFER CALL APPBT RET ;*********************************************************************** ;GROUP 11 - CC,NN ;**UCTION NOP NOP LD A,18H ; APPEND OP-CODE TO BUFFER CALL APPBT LD A,L ; APPEND DISP TO BUFFER CALL APPBT RET ;0B ; BUILD OP-CODE CALL IDREG ; COMBINE INTEGER BITS CALL APPBT RET ;************************************************* CALL CDIS ; CALCULATE DISPLACEMENT NOP ; ROOM FOR SPARE INSTRUCTION NOP NOP LD A,00100000B ; BUILD OP-CODE CAT CALL APPWD ; APPEND INTEGER RET ;********************************************************************** ;PROCESS JR (G***************************** CDIS: PUSH DE ; SAVE REGS PUSH BC LD DE,(ADREFC) ; GET ADDR REF CNTR INC DE ; ADD 2 (A********************************************************************* GP112: LD C,B ; GET OPD BYTE 1 IN C LD A,11000010B ********************************************************************* ;PROCESS DJNZ (GROUP 13) ;**************************************************** ;PROCESS JP (GROUP 11) ;*********************************************************************** ;*****LL IDREG ; COMBINE CONDITION BITS CALL APPBT ; APPEND OP-CODE TO BUFFER LD A,L ; GET DISPLACEMENT CALL APPBT ; APROUP 12) ;********************************************************************** ;********************************************LLOW FOR INCRD PC) INC DE AND A ; CLEAR CARRY SBC HL,DE ; GET DISPLACEMENT FROM CURR LOC. LD A,L ; CHECK FOR 8 BIT; BUILD OP-CODE CALL IDREG ; COMBINE CONDITION BITS CALL APPBT ; APPEND OP-CODE TO BUFFER EX DE,HL ; GET INTEGER C*************************************** GP13: CALL CDIS ; CALCULATE DISPLACEMENT NOP ; ROOM FOR SPARE INSTRUCTION ****************************************************************** ;GROUP 11 - (HL)/(IX)/(IY) ;*******************************PEND TO BUFFER RET ;********************************************************************* ;GROUP 12 - E ;******************************************** ;GROUP 12 CC,E ;********************************************************************** GP121: BIT  OVERFLOW AND 10000000B OR H JR Z,CDIS2 ; JUMP IF NO OVERFLOW LD A,L ; CHECK -VE OVERFLOW OR 01111111B AND H CALL APPWD ; APPEND LOW BYTE RET ;********************************************************************** ;GROUP 11 - NN ;*NOP NOP LD A,10H ; APPEND OP-CODE TO BUFFER CALL APPBT LD A,L ; APPEND DISP TO BUFFER CALL APPBT RET ;************************************************* GP111: CALL INDPF ; APPEND INDEX PREFIX IF REQD LD A,0E9H ; APPEND OP-CODE PREFI*************************************************** GP122: CALL CDIS ; CALCULATE DISPLACEMENT NOP ; ROOM FOR SPARE INSTR PL AND A JR Z,CDIS2 ; JUMP IF NO OVERFLOW CDIS1: LD C,'R' ; INDICATE RANGE ERROR CALL ERROR XOR A ; CLEAR ZS CALL APPBT ; APPEND OP-CODE TO BUFFER RET ;******************************************************************** ;PROCE********** ;******************************************************************** ;GROUP 15 - NO OPERAND ;********************************** ;GROUP 17 - R,(C) ;******************************************************************** GP172: LD A,0EDH ; AAPPBT ; APPEND OP-CODE TO BUFFER EX DE,HL ; GET INTEGER CALL APPWD ; APPEND INTEGER RET ;*************************************************************************************** ;GROUP 17 - A,(N) ;*********************************************ERO FLAG INC A CDIS2: POP BC ; REPLACE REGS POP DE RET ;**************************************************************SS RST (GROUP 16) ;******************************************************************** GP16: ; INTEGER MAY ONLY BE 0/08H/************************************************ GP151: LD A,0C9H ; APPEND OP-CODE TO BUFFER CALL APPBT RET ;***********PPEND OP-CODE PREFIX TO BUFFER CALL APPBT LD C,B ; GET OPD BYTE 1 IN C LD A,01000000B ; BUILD OP-CODE CALL IDREG ;****************************************** ;GROUP 14 - NN ;****************************************************************************************** GP171: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD****** ;PROCESS CALL (GROUP 14) ;******************************************************************** ;********************** ; 10H/18H/20H/28H/30H/38H LD A,L ; CHECK FOR INVALID VALUE AND 11000111B OR H JP NZ,SYNERR ; JUMP IF INVALID ********************************************************* ;GROUP 15 - CC ;**************************************************** COMBINE REG BITS CALL APPBT RET ;******************************************************************** ;PROCESS OUT (GR* GP142: LD A,0CDH ; APPEND OP-CODE TO BUFFER CALL APPBT CALL APPWD ; APPEND INTEGER RET ;************************** A,D ; INTEGER MUST BE < 256 AND A NOP ; ROOM FOR SPARE INSTRUCTION NOP NOP LD A,0DBH ; APPEND OP-CODE TO BUFFE********************************************** ;GROUP 14 - CC,NN ;************************************************************ LD A,L ; BUILD OP-CODE OR 11000111B CALL APPBT ; APPEND TO BUFFER RET ;************************************************************* GP152: LD C,B ; GET OPD BYTE 1 IN C LD A,11000000B ; BUILD OP-CODE CALL IDREG ; COMBINE CONDITION BITOUP 18) ;******************************************************************** ;***************************************************************************************** ;PROCESS RET (GROUP 15) ;**********************************************************R CALL APPBT LD A,E ; APPEND INTEGER TO BUFFER CALL APPBT RET ;************************************************************** GP141: LD C,B ; GET OPD BYTE 1 IN C LD A,11000100B ; BUILD OP-CODE CALL IDREG ; COMBINE CONDITION BIT CALL *********************** ;PROCESS IN (GROUP 17) ;******************************************************************** ;******* ********************* ;GROUP 18 - (C),R ;******************************************************************** GP181: LD A,0EDPPEND INDEX PREFIX IF REQD LD A,0E3H ; APPEND AP-CODE TO BUFFER CALL APPBT RET ;***********************************CALL APPBT ; APPEND TO BUFFER RET ;******************************************************************** ;PROCESS EX (GROUP JUMP IF NOT, ERROR LD A,(ORTKBF+1) ; GET OPD DISTING BITS AND 00010000B ; AND MASK IT OR 10001000B ; BUILD OP-CODE C ; APPEND OP-CODE TO BUFFER CALL APPBT LD A,L ; APPEND INTEGER TO BUFFER CALL APPBT RET ;****************************R ; JUMP IF NOT, ERROR LD A,C ; GET OPD BYTE 2 CP 12H ; MUST BE HL JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,0EBH ;H ; APPEND OP-CODE PREFIX TO BUFFER CALL APPBT LD A,01000001B ; BUILD OP-CODE CALL IDREG ; COMBINE REG BITS CALL********************************* ;GROUP 1A - AF,AF' ;******************************************************************** G 1A) ;******************************************************************** ;**************************************************ALL ISREG ; COMBINE REGISTER BITS CALL APPBT ; APPEND BYTE TO BUFFER RET ;************************************************************************************ ;PROCESS PUSH/POP (GROUP 19) ;******************************************************** APPEND OP-CODE TO BUFFER CALL APPBT RET ;******************************************************************** ;PROCESS AD APPBT ; APPEND TO BUFFER RET ;******************************************************************* ;GROUP 18 - (N),A ;***P1A2: LD A,B ; GET OPD BYTE 1 CP 17H ; MUST BE AF JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,08H ; APPEND OP-CODE TO BU****************** ;GROUP 1A - (SP),HL/IX/IY ;******************************************************************** GP1A1: LD ********************** ;GROUP 1B - A,N ;******************************************************************* GP1B2: LD A,B *********** GP19: LD A,(ODBT1) ; GET OPD BYTE 1 CP 13H ; SP NOT PERMITTED JP Z,SYNERR LD C,B ; GET OPD BYTE 1 IN C C/SBC (GROUP 1B) ;******************************************************************** ;GROUP 1B - A,R ;************************************************************************************* GP182: LD A,C ; GET OPD BYTE 2 CP 77H ; MUST BE 'A' REG FFER CALL APPBT RET ;******************************************************************** ;GROUP 1A - DE,HL ;************B,C ; GET OPR BYTE 2 IN C LD A,C AND 3 ; MUST BE HL/IX/IY CP 2 JP NZ,SYNERR ; JUMP IF NOT, ERROR CALL INDPF ; A; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,(ORTKBF+1) ; GET OPR DISTING BITS A CALL INDPF ; APPEND INDEX PREFIX IF REQD LD A,(ORTKBF+1) ; GET APR DISTING. BITS CALL IREGP ; COMBINE REG PAIR BITS *********************************************** GP1B1: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JP NZ,SYNERR ; JUMP IF NOT LD A,H ; MUST BE < 256 AND A NOP ; ROOM FOR SPARE INSTRUCTION NOP NOP LD A,0D3H ******************************************************** GP1A3: LD A,B ; GET SPD BYTE 1 CP 11H ; MUST BE DE JP NZ,SYNER  ND 00010000B ; AND MASK IT OR 11001110B ; BUILD OP-CODE CALL APPBT ; APPEND TO BUFFER EX DE,HL ; GET INTEGER IN HL  A,R ;******************************************************************* GP1C1: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST B ; JUMP IF NOT, ERROR LD A,0EDH ; APPEND PREFIX BYTE TO BUFFER CALL APPBT LD A,(ORTKBF+1) ; GET OPR DISTING BIT AN DISBT ; APPEND IT IF REQD RET ;******************************************************************** ;GROUP 1C - HL/IX/IY,D MASK IT OR 10001110B ; BUILD OP-CODE CALL APPBT ; APPEND IT TO BUFFER EX DE,HL ; GET DISP. INTEGER CALL DISBT ;FLAG ANY OVERFLOW FROM L LD A,L ; APPEND INTEGER TO BUFFER CALL APPBT RET ;******************************************** CALL CHKOF ; FLAG OVERFLOW FROM L IF ANY LD A,L ; APPEND INTEGER TO BUFFER CALL APPBT RET ;*************************E 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,10000000B ; BUILD OP-CODE CALL ISREG ; COMBINE REG BITS CALL APPBT D 00001000B ; MASK IT OR 01000010B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS CALL APPBT ; APPEND IT TO BUFFRP ;******************************************************************** GP1C4: LD A,B ; GET OPD BYTE 1 AND 11B ; MUST  APPEND DISPLACEMENT INTEGER IF REQD RET ;******************************************************************** ;GROUP 1B - H************************ ;GROUP 1C - A,(HL)/(IX+D)/(IY+D) ;************************************************************************************************************ ;GROUP 1B A,(HL)/(IX+D)/(IY+D) ;*************************************************** ; APPEND TO BUFFER RET ;******************************************************************* ;GROUP 1C - A,N ;*********ER RET ;******************************************************************* ;PROCESS ADD (GROUP 1C) ;**********************BE HL/IX/IY CP 10B JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,C ; GET OPD BYTE 2 AND 11B ; IS IT BC/DE/SP CP 10B JRL,BC/DE/HL/SP ;******************************************************************** GP1B4: LD A,B ; GET OPD BYTE 1 CP 12H ** GP1C3: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR LD B,C ; PUT OPD BYTE 2 IN B CALL INDPF **************** GP1B3: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD B,C ********************************************************** GP1C2: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP N********************************************* ;******************************************************************* ;GROUP 1C - NZ,GP1C41 ; JUMP IF SO LD A,C ; IS IT SAME AS OPD 1? CP B JP NZ,SYNERR ; JUMP IF NOT, ERROR GP1C41: CALL INDPF ; A ; MUST BE HL JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,C ; GET OPD BYTE 2 CP 14H ; MUST BE BC/DE/HL/SP JP NC,SYNERR  ; APPEND INDEX PREFIX IF REQD LD A,86H ; APPEND OP-CODE TO BUFFER CALL APPBT EX DE,HL ; GET DISP INTEGER IN HL CALL; PUT OPD BYTE 2 IN B CALL INDPF ; APPEND INDEX PREFIX IF ANY LD A,(ORTKBF+1) ; GET OPR DISTING BIT AND 00010000B ; ANZ,SYNERR ; JUMP IF NOT, ERROR LD A,0C6H ; APPEND OP-CODE CALL APPBT EX DE,HL ; GET INTEGER IN HL CALL CHKOF ; ! PPEND INDEX PREFIX IF REQD LD A,00001001B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS CALL APPBT RET ;*******D4: LD A,C ; GET OPD BYTE 2 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD C,B ; PUT OPD BYTE 1 IN C*********************** ;GROUP 1D - A,(NN) ;******************************************************************** GP1D3: LD AODE EX DE,HL ; GET INTEGER IN HL CALL APPWD ; APPEND INTEGER RET ;***************************************************END OP-CODE TO BUFFER RET ;******************************************************************** ;GROUP 1D - A,I/R ;********L ; APPEND INTEGER TO BUFFER CALL APPBT RET ;******************************************************************* ;GROUP ************************************************************* ;PROCESS LD (GROUP 1D) ;**************************************** LD A,00000010B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS CALL APPBT ; APPEND OP-CODE TO BUFFER RET ;****,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR EX DE,HL ; GET INTEGER IN HL LD A,**************** ;GROUP 1D - BC/DE/HL/SP/IX/IY,(NN) ;******************************************************************* GP1D************************************************************ GP1D2: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' REG JP1D - BC/DE/HL/SP/IX/IY,NN ;******************************************************************* GP1D6: LD A,B ; GET OPD BYTE **************************** ;******************************************************************** ;GROUP 1D - A,(BC)/(DE) ;**************************************************************** ;GROUP 1D - (HL)/(IX+D)/(IY+D),N ;****************************3AH ; APPEND OP-CODE TO BEFFER CALL APPBT CALL APPWD ; APPEND INTEGER RET ;******************************************7: LD A,B ; GET OPD BYTE 1 LD C,B ; PUT IN C CP 17H ; MUST NOT BE AF JP Z,SYNERR ; JUMP IF IT IS, ERROR AND 11B  NZ,SYNERR ; JUMP IF NOT, ERROR LD A,0EDH ; APPEND PREFIX BYTE TO BUFFER CALL APPBT LD A,01010111B ; BUILD OP-CODE 1 CP 17H ; MUST NOT BE AF REG PAIR JP Z,SYNERR ; JUMP IF IT IS, ERROR LD C,B ; GET OPD BYTE 1 IN C CALL INDPF ; A******************************************************************* GP1D1: LD A,B ; GET OPD BYTE 1 CP 77H ; MUST BE 'A' R*************************************** GP1D5: CALL INDPF ; APPEND INDEX PREFIX TO BUFFER LD A,36H CALL APPBT ; APPEND ************************** ;GROUP 1D - (BC)/(DE),A ;******************************************************************** GP1 ; TEST FOR HL/IX/IY CP 10B ; TREAT HL/IX/IY SEPARATELY JR Z,GP1D71 ; JUMP IF HL/IX/IY LD A,0EDH ; APPEND PREFIX BYTE CALL IDREG ; COMBINE REG BIT CALL APPBT ; APPEND OP-CODE TO BUFFER RET ;*********************************************PPEND INDEX PREFIX IF REQD LD A,00000001B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS CALL APPBT ; APPEND OP-CEG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,00001010B ; BUILD OP-CODE CALL IREGP ; COMBINE REG BITS CALL APPBT ; APPOP-CODE CALL DISBT ; APPEND DISP BYTE IF REQD EX DE,HL ; GET INTEGER IN HL CALL CHKOF ; FLAG OVERFLOW FROM L LD A,"  CALL APPBT LD A,01001011B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS JR GP1D72 GP1D71: CALL INDPF ; APPENGET OPD BYTE 2 LD B,C ; PUT IN B CP 17H ; MUST NOT BE AF JP Z,SYNERR ; JUMP IF IT IS, ERROR AND 11B ; TEST FOR HL******************************** ;GROUP 1D - (NN),A ;******************************************************************** GP1A,00000110B ; BUILD OP-CODE CALL IDREG ; COMBINE REG BITS CALL APPBT ; APPEND OP-CODE TO BUFFER EX DE,HL ; GET INTEND TO BUFFER IF REQD RET ;******************************************************************** ;GROUP 1D - I/R,A ;************************************* GP1DC: LD A,B ; SWAP B AND C LD B,C LD C,A CALL INDPF ; APPEND INDEX PREFIX IF REQD LDD INDEX PREFIX IF REQD LD A,2AH ; APPEND OP-CODE TO BUFFER GP1D72: CALL APPBT EX DE,HL ; GET INTEGER IN HL CALL APPWD/IX/IY CP 10B JR Z,GP1DB1 ; JUMP TO TREAT HL/IX/IY SEPARATELY LD A,0EDH ; APPEND PREFIX BYTE CALL APPBT LD A,010000DA: LD A,C ; GET OPD BYTE 2 CP 77H ; MUST BE 'A' REG JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,32H ; APPEND OP-CODE TOGER IN HL CALL CHKOF ; FLAG OVERFLOW FROM L LD A,L ; APPEND INTEGER TO BUFFER CALL APPBT RET ;******************************************************************************** GP1D9: LD A,C ; GET OPD BYTE 2 CP 77H ; MUST BE 'A' REG JP  A,01000110B ; BUILD OP-CODE CALL IDREG ; COMBINE REG BITS CALL APPBT ; APPEND OP-CODE EX DE,HL ; GET INTEGER IN HL ; APPEND INTEGER RET ;******************************************************************** ;GROUP 1D - (HL)/(IX+D)/(IY+D)11B ; BUILD OP-CODE CALL IREGP ; COMBINE REG PAIR BITS JR GP1DB2 GP1DB1: CALL INDPF ; APPEND INDEX PREFIX IF REQD LD BUFFER CALL APPBT CALL APPWD ; APPEND INTEGER RET ;******************************************************************************************************************** ;GROUP 1D - R,R ;***********************************************************NZ,SYNERR ; JUMP IF NOT, ERROR LD C,B ; PUT OPD BYTE 1 IN C LD A,0EDH ; APPEND PREFIX BYTE CALL APPBT LD A,01000111 CALL DISBT ; APPEND DISP BYTE IF REQD RET ;********************************************************************** ;GROU,R ;******************************************************************** GP1D8: CALL INDPF ; APPEND INDEX PREFIX IF REQD L A,22H ; PUT OP-CODE IN A GP1DB2: CALL APPBT ; APPEND OP-CODE CALL APPWD ; APPEND INTEGER RET ;********************** ;GROUP 1D = (NN),BC/DE/HL/SP/IX/IY ;******************************************************************** GP1DB: LD A,C ; *********** GP1DE: LD A,01000000B ; BUILD OP-CODE CALL ISREG ; COMBINE SOURCE REG BITS LD C,B CALL IDREG ; COMBINE DB ; BUILD OP-CODE CALL IDREG ; COMBINE REG BIT CALL APPBT ; APPEND OP-CODE RET ;************************************P 1D - R,N ;********************************************************************** GP1DD: LD C,B ; PUT OPD BYTE 1 IN C LD D A,01110000B ; BUILD OP-CODE CALL ISREG ; COMBINE REG BITS CALL APPBT ; APPEND OP-CODE TO BUFFER CALL DISBT ; APPE************************************************* ;GROUP 1D - R,(HL)/(IX+D)/(IY+D) ;******************************************# EST REG BITS CALL APPBT ; APPEND OP-CODE RET ;********************************************************************* ;GROAPPENDED TO ASSD CODE BUFFER IF ;OPERAND IS IX OR IY. ;****************************************************************** IND ; SAVE BC LD A,(ODBT1) ; GET 1ST OPERAND BYTE AND 0F0H ; MASK OPERAND GROUP NIBBLE LD B,A ; SAVE IN B LD A,(ODB JR Z,CHKOF1 ; IF SO, NO OVERFLOW INC A ; WAS IT -1? (FF) JR Z,CHKOF1 ; IF SO, NO OVERFLOW LD C,'V' ; OTHERWISE INDI ;THE M.S. NIBBLE OF AN OPERAND TOKEN BYTE ;SIGNIFIES THE OPERAND GROUP (0-E). THIS ;SUBROUTINE BUILDS A BYTE WHOSE M.S. NIBBBT: BIT 3,B ; IS OPERAND IX OR IY? RET Z ; IF NOT, NO DISP. BYTE REQD CALL CHKOF ; CHECK NO. IN HL FOR 8 BIT OVERFLOW UP 1D - SP,HL/IX/IY ;********************************************************************* GP1DF: LD A,B ; GET OPD BYTE 1 PF: BIT 3,B ; IS OPERAND IX OR IY? RET Z ; NO PREFIX IF NOT, RETURN LD A,0DDH ; PUT PREFIX BYTE FOR IX IN A BIT 2,B T2) ; GET 2ND OPERAND BYTE AND 0F0H ; MASK OPERAND GROUP NIBBLE RRCA ; SHIFT INTO LOWER 4 BITS RRCA RRCA RRCA CATE 'VALUE' ERROR CALL ERROR CHKOF1: POP BC ; REPLACE BC RET ;*********************************************************LE ;IS THE GROUP OF OPERAND 1 AND WHOSE L.S. ;NIBBLE IS THE GROUP OF OPERAND 2. ;THIS COMPOSITE BYTE IS CALLED THE OPERAND ; LD A,L ; GET L.S. BYTE IN ACC. CALL APPBT ; AND APPEND TO ASSD CODE BUFFER RET ;*************************************CP 13H ; MUST BE SP JP NZ,SYNERR ; JUMP IF NOT, ERROR LD A,C ; GET OPD BYTE 2 LD B,C ; PUT IN B AND 11B ; MUST  ; IS OPERAND IY? JR Z,INDPF1 ; JUMP IF NOT LD A,0FDH ; PUT PREFIX BYTE FOR IY IN A INDPF1: CALL APPBT ; APPEND BYTE OR B ; CONSTRUCT COMPOSITE OPERAND ; GROUP BYTE IN A POP BC ; REPLACE BC RET ;******************************************* ;INSERT SOURCE REG ;ON ENTRY: ; C CONTAINS OPERAND BYTE ; A CONTAINS CODE BYTE BEING BUILT ;ON EXIT: PAIR BYTE AND IS USED TO DETERMINE WHICH ;PROCESSING SUBROUTINE (GP...) TO USE TO ;GENERATE THE ASSEMBLED CODE. ; ;ON EXIT: ***************************** ;CHECK OVERFLOW FROM L ;VALUE ERROR INDICATED IF SO ;******************************************BE HL/IX/IY CP 10B JP NZ,SYNERR ; JUMP IF NOT, ERROR CALL INDPF ; APPEND INDEX PREFIX IF REQD LD A,0F9H ; APPEND OPTO ASSD CODE BUFFER RET ;****************************************************************** ;GENERATE DISPLACEMENT BYTE ;US******************************* ;GENERATE INDEX REGISTER PREFIX BYTE ;ON ENTRY: ; B CONTAINS OPERAND TOKEN ;PREFIX IS ; A HAS HAD THE REGISTER VALUE INSERTED ; TO BITD 0,1 & 2 ;******************************************************* ; A CONTAINS THE OPERAND BYTE PAIR ;******************************************************************* ODPBT: PUSH BC ************************ CHKOF: PUSH BC ; SAVE BC LD A,H ; GET REG CONTAINING POSSIBLE OVERFLOW AND A ; IS IT ZERO? -CODE TO BUFFER CALL APPBT RET ;******************************************************************* ;GET OPERAND PAIR BYTEE NO. IN HL FOR DISPLACEMENT ;B CONTAINS OPERAND BYTE ;****************************************************************** DIS$ ********** ISREG: PUSH BC ; SAVE REG LD B,A ; SAVE CODE BEING BUILT IN B LD A,C ; GET OPERAND BYTE FROM C AND 00000; APPEND LOW BYTE CALL APPBT LD A,H ; APPEND HIGH BYTE CALL APPBT RET ;************************************************************************* IREGP: PUSH BC ; SAVE BC LD B,A ; SAVE CODE BEING BUILT IN B LD A,C ; GET OPERAND BYTE FRP HL RET ;****************************************************************** ;DEFAULT NOP'S ;****************************** A,C ; GET OPERAND BYTE FROM C AND 00000111B ; MASK REGISTER VALUE RLCA ; SHIFT TO DESTINATION REG POSITION RLCA RA ; IN 'NO. BYTES ASSD CODE' POP DE ; REPLACE REGS POP HL RET ;*******************************************************111B ; MASK REGISTER VALUE OR B ; COMBINE WITH CODE BEING BUILT POP BC ; REPLACE REG RET ;*********************************************** ;APPEND BYTE TO ASSEMBLED CODE BUFFER ;*****************************************************************OM C AND 00000011B ; MASK REGISTER PAIR VALUE RLCA ; SHIFT TO CORRECT REG PAIR POSITION RLCA RLCA RLCA OR B ; ************************************ DNOPS: PUSH BC ; SAVE BC LD C,'S' ; INDICATE SYNTAX ERROR CALL ERROR LD A,4 LCA OR B ; COMBINE WITH CODE BEING BUILT POP BC ; REPLACE BC RET ;*************************************************************** ;ADJUST ADDRESS REFERENCE COUNTER ;******************************************************************* ADJARC: P**************************************** ;INSERT DESTINATION REGISTER ;ON ENTRY: ; C CONTAINS OPERAND BYTE ; A C** APPBT: PUSH HL ; SAVE REGISTERS PUSH DE EX AF,AF' ; SAVE NEW BYTE IN A' LD HL,ASSCOD ; SET POINTER TO ASSD CODE COMBINE WITH CODE BEING BUILT POP BC ; REPLACE BC RET ;****************************************************************** ; RESERVE 4 BYTES NOP'S LD (ASCDNO),A POP BC ; REPLACE BC RET ;********************************************************************** ;INSERT REGISTER PAIR ;ON ENTRY: ; C CONTAINS OPERAND BYTE ; A CONTAINS CODE BYTE BEING BUILT ;USH HL ; SAVE REGS PUSH DE LD HL,(ADREFC) ; GET ADDR REF CNTR LD A,(ASCDNO) ; ADD TO THIS VALUE THE NO. LD E,A LD ONTAINS CODE BYTE BEING BUILT ;ON EXIT: ; A HAS HAD THE REGISTER VALUE INSERTED ; TO BITS 3,4 & 5 ;***********BUFF LD A,(ASCDNO) ; GET 'NO. BYTES ASSD CODE' LD E,A ; TO E LD D,0 ; CLEAR D ADD HL,DE ; ADD TO POINTER EX AF,* ;APPEND WORD TO ASSEMBLED CODE BUFFER ;******************************************************************* APPWD: LD A,L *********** ;PERFORM RELEVANT OUTPUT ;****************************************************************** PFRLO: LD A,(PASSNO)ON EXIT: ; A HAS HAD THE REGISTER PAIR VALUE ; INSERTED TO BITS 4 & 5. ;***************************************D,0 ; OF BYTES OF ASSD CODE ADD HL,DE ; AND PUT BACK INTO LD (ADREFC),HL ; ADDR REF CNTR POP DE ; REPLACE REGS PO******************************************************* IDREG: PUSH BC ; SAVE BC LD B,A ; SAVE CODE BEING BUILT IN B LDAF' ; RECOVER NEW BYTE LD (HL),A ; AND PUT IN ASSD CODE BUFF INC E ; INCR CNTR LD A,E ; AND REPLACE LD (ASCDNO),%  ; WHICH PASS? CP 1 RET Z ; NO OUTPUT ON PASS 1 CP 2 JR Z,PFRLO1 ; JUMP IF PASS 2 CP 3 JR Z,PFRLO2 ; JUMP IF PANOT LSTLN1: LD A,(IX) ; GET BYTE PUSH DE ; PRESERVE D CALL LISTBT ; PRINT 1 BYTE POP DE INC IX ; INCR POINTER T DE PUSH BC PUSH IX LD A,(ERRBUF) ; PRINT CONTENTS OF ERROR BUFFER LD C,A CALL LO LD C,SPACE ; PRINT SPACE CMPUTE CHECKSUMS. ;******************************************************************* LISTBT: PUSH BC ; SAVE REGS LD B,A ******************** OLNBF: PUSH HL ; SAVE REGS PUSH BC LD HL,LINBUF ; SET POINTER TO LINE BUFFER OLNBF1: LD C,(HL) ;S POP BC POP DE POP HL RET ;******************************************************************* ;OUTPUT CHAR N TIMES TSS 3 LD A,(ERRBUF) CP SPACE RET Z CALL OLNBF ; OUTPUT LINE BUFFER TO LIST DEV. CALL LSTLN ; LIST RESULTS OF ASSEMBO NEXT BYTE INC HL ; INCR CORRES. ADDR. REF. DEC E DEC D ; DECR NO OF BYTES JR Z,LSTLN4 ; JUMP IF NONE LEFT LD A,ALL LO LD HL,(ADDISR) ; GET CONT. OF ADDR DISP. REG LD A,(ASCDNO) ; GET NO. OF BYTES OF ASSD. CODE LD D,A ; INTO D L ; SAVE BYTE IN B AND 0F0H ; GET M.S. NIBBLE RRCA RRCA RRCA RRCA CALL BINHX ; CONVERT TO ASCII HEXADECIMAL LD  GET A CHAR CALL LO ; OUTPUT TO LIST DEVICE LD A,C ; WAS IT CR? CP CR JR Z,OLNBF2 ; JUMP IF SO INC HL JR OLNBF1O LIST DEVICE ;******************************************************************* OUTC: CALL LO ; COUNT IN B DJNZ OUTC LY RET PFRLO1: CALL LSTLN ; LIST RESULTS OF ASSEMBLY LD A,(AFLAGS) ; TEST 'END' FLAG BIT 1,A RET Z ; LOOP IF NOT EE ; PRINTED 4 ON THIS LINE? AND A JR NZ,LSTLN1 ; JUMP IF NOT LSTLN2: CALL LFEED LD C,CR ; PRINT CR CR SP SP LD B,2D IX,ASSCOD ; SET POINTER TO ASSD. CODE LSTLN3: LD E,4 ; MAX. NO. OF BYTES/LINE PUSH DE ; PRESERVE D CALL LISTAD ; PC,A ; OUTPUT TO RELEVANT DEVICE CALL XO LD A,B ; GET BYTE AGAIN AND 0FH ; GET L.S. NIBBLE CALL BINHX ; CONVERT T OLNBF2: POP BC ; REPLACE REGS POP HL RET ;**************************************************************** ;LIST RESULRET ;******************************************************************* ;LIST BYTE ;CONVERTS BYTE IN ACC TO 2 ASCII ;HEXADEND CALL LSYMT ; LIST SYMBOL TABLE RET PFRLO2: CALL OBJO ; DO OBJECT FILE OUTPUT RET ;******************************* CALL OUTC LD C,SPACE LD B,2 CALL OUTC JR LSTLN3 LSTLN4: RLC E ; PRINT SPACES UP TO BEGINNING OF TEXT INC ERINT ADDR REF. POP DE LD C,SPACE ; PRINT SPACE CALL LO LD A,D ; ANY BYTES TO PRINT AND A JR Z,LSTLN4 ; JUMP IF O ASCII HEX LD C,A ; OUTPUT TO RELEVANT DEVICE CALL XO LD A,D ; GET CUMULATIVE CHECKSUM SUB B ; SUBTRACT NEW BYTE T OF ASSEMBLY OF 1 LINE. ;**************************************************************** LSTLN: PUSH HL ; SAVE REGS PUSHCIMAL CHARACTERS AND OUTPUTS THEM ;TO LIST OR PUNCH DEVICE DEPENDING ON PASS. ;THE BYTE IS ALSO SUBTRACTED FROM D TO ;HELP CO********************************** ;OUTPUT CONTENTS OF LINE BUFFER TO LIST DEV. ;********************************************* LD B,E LD C,SPACE CALL OUTC ; OUTPUT CHAR N TIMES CALL LFEED ; PRINT LF OR NEW PAGE HEADER POP IX ; REPLACE REG&  LD D,A ; REPLACE CHECKSUM POP BC ; REPLACE REG RET ;................................................................. ZERO LINE NO. LD (LINE),A LD C,CR ; PRINT CR LF CALL LO LD C,LF CALL LO LD HL,TITBUF ; PRINT CONTENTS OF TITLE S RET ;********************************************************************* ;PRINT PAGE HEADER ON LIST DEVICE ;***********.......................... PNT2DG: RLD ; ROTATE NIBBLES CALL PNTDG ; PRINT A DIGIT RLD ; ROTATE NIBBLES CALL PNTDAD: LD A,H CALL LISTBT LD A,L CALL LISTBT RET ;********************************************************************** ST2: POP BC ; REPLACE REGS RET ;********************************************************************** ;PRINT PAGE NO. ;* BINHX: CP 10D ; CONVERT VALUE IN A TO ASCII HEX JR NC,BINHX1 ADD A,'0' RET BINHX1: ADD A,'A'-10D RET ;************BUFFER CALL LSTST LD C,CR ; PRINT CR, 3 X LR, 16 X SP CALL LO LD C,LF LD B,3 CALL OUTC POP BC ; REPLACE REGS ********************************************************** HEADR: PUSH HL ; SAVE REGS PUSH BC LD C,CR ; PRINT CR, 5 X LG ; PRINT A DIGIT RLD ; ROTATE NIBBLES RET ;................................................................... ;PRIN ;LINE FEED. ;********************************************************************** LFEED: PUSH BC ; SAVE REGS LD A,(LINE********************************************************************* PRNTP: PUSH HL ; SAVE REGS PUSH DE LD DE,0 ; CLEA********************************************************** ;OUTPUT TO DEVICE RELEVANT TO PASS NO. ;*************************** POP HL RET ;********************************************************************** ;LIST STRING ;*************************F CALL LO LD C,LF LD B,5 CALL OUTC LD HL,PHEAD ; POINTER TO PAGE HEADING CALL LSTST JR HEADR1 PHEAD: DEFMT A DIGIT ;................................................................... PNTDG: PUSH BC ; SAVE REG LD B,A ; INCR D) ; TIME FOR A NEW PAGE? CP PLINES-9-1 JR NC,LFEED1 INC A ; INCREMENT LINE NO. LD (LINE),A LD C,LF ; PRINT LF CR DIGIT CNTR AND NON ZERO FLAG LD HL,PAGE+1 CALL PNT2DG DEC HL CALL PNT2DG POP DE ; REPLACE REGS POP HL RET ;..******************************************* XO: LD A,(PASSNO) CP 3 JP Z,PCHO JP LO ;********************************************************************************* LSTST: PUSH BC ; SAVE REG LSTST1: LD A,(HL) ; GET A CHAR AND A ; TEST FO 'CROWE Z80 ASSEMBLER V1.2 PAGE ' DEFB 0 HEADR1: CALL PRNTP ; PRINT PAGE NO. CALL INCP ; INCREMENT PAGE NO. XOR A ;IGIT COUNT INC E AND 0FH JR NZ,PNTDG1 ; IS IT 0? BIT 0,D ; LEADING ZERO? JR NZ,PNTDG2 JR PNTDG3 PNTDG1: SET 0,D ALL LO JR LFEED2 LFEED1: CALL HEADR ; PRINT PAGE HEADER LD C,SPACE LD B,16D CALL OUTC LFEED2: POP BC ; REPLACE REG.................................................................. ;PRINT 2 DIGITS ;..........................................********************************** ;LIST ADDRESS ;********************************************************************** LISTR TERMINATOR CHAR JR Z,LSTST2 LD C,A ; IF NOT, PRINT IT CALL LO INC HL ; INCREMENT POINTER JR LSTST1 ; LOOP LST'  ; NON ZERO, SET FLAG PNTDG2: OR 30H ; CONVERT TO ASCII LD C,A ; PRINT IT CALL LO PNTDG3: LD A,B POP BC ; REPLACE ; AND OUTPUT THAT NO. CALL OUTC ; OF SPACES INC HL ; INCR PNTR TO VALUE LD A,(HL) ; GET M.S. BYTE PUSH DE ; SAVNT AT SYMBOL TABLE LSYMT4: LD D,SPERL ; LOAD NO OF SYMBOLS PER LINE LSYMT5: LD A,(HL) ; GET CHAR COUNT AND A ; IS IT ZPUT OF OBJECT CODE USING THE INTEL ;HEXADECIMAL OBJECT FORMAT WITH RECORD LENGTH ;OF 'RECSIZ' ;*************************************************************** ;LIST SYMBOL TABLE ;******************************************************************* LSYOUTPUT 2 SPACES LD B,2 CALL OUTC JR LSYMT5 ; AND LOOP LSYMT8: LD A,(LINE) ; GET LINE NO. CP PLINES-9-1 ; BOTTOM OF  REG RET ;******************************************************************* ;INCREMENT PAGE NO. ;************************E DE CALL LISTBT ; OUTPUT IN HEX DEC HL ; POINT AT L.S. BYTE LD A,(HL) ; GET IT CALL LISTBT ; OUTPUT IN HEX POERO? JR Z,LSYM10 ; JUMP IF SO, END OF TABLE LD B,A ; PUT COUNT IN B LD E,7 ; SPACES COUNT IN E INC HL ; INCR PNTR********************************* OBJO: PUSH HL ; SAVE REGS PUSH DE PUSH BC LD HL,AFLAGS ; END FLAG SET? BIT 1,(HL) MT: PUSH HL ; SAVE REGS PUSH DE PUSH BC LD C,CR ; OUTPUT CR CALL LO LD A,(LINE) ; GET LINE NO. LSYMT1: CP PLINESPAGE? JR NC,LSYMT9 ; JUMP IF SO INC A ; ELSE INCR LINE NO. LD (LINE),A LD C,CR ; LIST CR/LF CALL LO LD C,LF ******************************************* INCP: PUSH HL ; SAVE REG LD HL,(PAGE) ; GET PAGE NO (4 DIG BCD) LD A,L ; IP DE ; REPLACE DE INC HL ; POINT TO ATTRIBUTE BYTE INC HL LD C,SPACE ; OUTPUT A SPACE CALL LO LD C,SPACE ; SET ; PRINT SYMBOL LSYMT6: LD C,(HL) ; GET CHAR IN C CALL LO ; OUTPUT TO LIST DEVICE INC HL ; INCR PNTR DEC E  JR Z,OBJO2 ; JUMP IF NOT CALL ODREC ; PUNCH DATA RECORD CALL OEREC ; PUNCH EOF RECORD CALL RUNOUT ; PUCH TAPE RU-9-1 ; BOTTOM OF PAGE? JR NC,LSYMT3 ; JUMP IF SO INC A ; ELSE INCR LINE NO. LD B,A ; SAVE IN B LD C,LF ; OUTPUT  CALL LO JR LSYMT4 ; AND LOOP LSYMT9: CALL HEADR ; PRINT PAGE HEADER JR LSYMT4 ; AND LOOP LSYM10: POP BC ; REPLANCREMENT L.S. BYTE ADD A,1 DAA ; DECIMAL ADJUST LD L,A LD A,H ; CARRY TO M.S. BYTE ADC A,0 DAA  UP A FURTHER SPACE BIT 1,(HL) ; M FLAG SET? INC HL ; (INCR POINTER) JR Z,LSYMT7 ; JUMP IF NOT LD C,'M' ; CHANGE ; DECR SPACE CNTR DEC B ; DECR CHAR CNTR JR NZ,LSYMT6 ; LOOP IF NOT FINISHED LD B,E ; GET SPACES COUNT LD C,SPACE NOUT JR OBJO7 OBJO2: BIT 0,(HL) ; ADDR DISCONTINUITY FLAG SET? JR Z,OBJO3 ; JUMP IF NOT CALL ODREC ; PUNCH DATA RECLF CALL LO LD A,B ; GET LINE NO. IN A JR LSYMT1 ; LOOP LSYMT3: CALL HEADR ; PRINT PAGE HEADER LD HL,SYMTAB ; POICE REGS POP DE POP HL RET ;*************************************************************** ;OBJECT OUTPUT. ;PERFORM OUT; DECIMAL ADJUST LD H,A LD (PAGE),HL ; REPLACE PAGE NO. POP HL ; REPLACE REG RET ;**********************************SPACE TO 'M' LSYMT7: CALL LO ; OUTPUT CHAR DEC D ; DECR SYM/LINE CNT JR Z,LSYMT8 ; JUMP IF DONE LD C,SPACE ; ELSE ( ORD JR OBJO7 OBJO3: LD C,0 ; CLEAR PNTR TO ASSD CODE BUFFER LD A,(ASCDNO) ; ANY BYTES OF ASSD CODE? LD B,A ; SAVE NOIF SO LD B,A ; PUT COUNT IN B LD C,':' ; OUTPUT RECORD MARK CALL PCHO ; TO PUNCH DEVICE LD D,0 ; CLEAR CHECKSUMNT ASD CODE BUFF CNTR DEC B ; DECR NO OF BYTES JR OBJO4 ; AND LOOP OBJO7: POP BC ; REPLACE REGS POP DE POP HL RADDR) ; GET START ADDR CALL LISTAD ; AND OUTPUT IT LD A,1 ; OUTPUT RECORD TYPE (1) CALL LISTBT LD A,D ; OUTPUT CHE FOR TRANSFER LD A,(HL) ; GET BYTE EX AF,AF' ; SAVE IN A' LD HL,OBJBUF ; POINT AT OBJECT BUFF LD A,(OBJCNT) ; PUT ODREC2: POP BC ; REPLACE REGS POP DE POP HL RET ;********************************************************************. IN B AND A ; ZERO? OBJO4: JR Z,OBJO7 ; JUMP IF ZERO LD HL,(ADDISR) ; GET ADDR DISP REG IN HL LD A,(OBJCNT) ; ANY  REG D LD A,B ; OUTPUT BYTE COUNT CALL LISTBT LD HL,(RECADR) ; OUTPUT RECORD ADDR CALL LISTAD XOR A ; OUTPUTET ;*********************************************************************** ;OUTPUT DATA RECORD ;OUTPUTS DATA RECORD USING INECKSUM CALL LISTBT LD C,CR ; OUTPUT CR CALL PCHO LD C,LF ; OUTPUT LF CALL PCHO POP BC ; REPLACE REGS POP DE  OBJ BUFF CNTR IN DE LD E,A ADD HL,DE ; COMPUTE PNTR TO INSERT POSITION EX AF,AF' ; GET BACK BYTE LD (HL),A ; AND  ;OUTPUT END OF FILE RECORD ;OUTPUTS END OF FILE RECORD TO PUNCH DEVICE ;USING INTEL'S HEXADECIMAL OBJECT FORMAT ;**********BYTES IN OBJECT BUFFER? AND A JR NZ,OBJO5 ; JUMP IF SO LD (RECADR),HL ; ELSE COPY ADDR DISP REG ; INTO RECORD A RECORD TYPE (0) CALL LISTBT LD HL,OBJBUF ; SET PNTR TO OBJECT BUFFER ODREC1: LD A,(HL) ; OUTPUT DATA BYTE CALL LISTBTTEL'S HEXADECIMAL ;OBJECT CODE FORMAT ;*********************************************************************** ODREC: PUSH HL POP HL RET ;******************************************************************* ;RUNOUT ;OUTPUTS 30 CM OF BLANK TAPE FOR APPEND TO OBJECT BUFFER LD A,E ; GET OBJ COUNT INC A ; INCREMENT IT LD (OBJCNT),A ; REPLACE COUNT IN OBJCNT CP RECS********************************************************** OEREC: PUSH HL ; SAVE REGS PUSH DE PUSH BC LD C,':' ; OUTPDDR OBJO5: INC HL ; INCR ADDR DISP REG LD (ADDISR),HL ; TRANSFR BYTE FROM ASSD CODE BUFF ; TO OBJECT BUFFER  INC HL ; INCR PNTR DEC B ; DECR COUNT JR NZ,ODREC1 ; LOOP IF NOT ZERO LD A,D ; OUTPUT CHECKSUM CALL LISTBT L ; SAVE REGS PUSH DE PUSH BC LD A,(OBJCNT) ; GET NO OF BYTES IN OBJ BUFF AND A ; IS IT ZERO? JR Z,ODREC2 ; JUMP PUNCHED TAPE ;LEADER AND TRAILER. ;IF NOT REQUIRED PUT 'RET' IN FIRST LOCATION ;OF SUBROUTINE. ;****************************IZ ; ENOUGH BYTES FOR A RECORD JR NZ,OBJO6 ; JUMP IF NOT CALL ODREC ; ELSE OUTPUT DATA RECORD OBJO6: INC C ; INCREMEUT RECORD MARK CALL PCHO XOR A ; CLEAR A AND CHECKSUM (IN D) LD D,A CALL LISTBT ; OUTPUT ZERO BYTE COUNT LD HL,(ST LD HL,ASSCOD ; POINT AT ASSD CODE BUFF LD E,C ; PUT ASSD CODE BUFF CNTR IN DE LD D,0 ADD HL,DE ; COMPUTE PNTR TO BYTD C,CR ; OUTPUT CR CALL PCHO LD C,LF ; OUTPUT LF CALL PCHO XOR A ; SET NO. OF BYTES IN OBJBUF=0 LD (OBJCNT),A) *************************************** RUNOUT: RET;PUSH BC ; SAVE REG LD B,120 ; PUT COUNT IN B LD C,NUL ; PUT NULL LID, CLEAR CARRY FLAG. CCF RET VALID3: SCF ; VALID, SET CARRY FLAG RET ;************************************** JR NC,GSYM3 INC HL JR GSYM2 ;********************************************************************** ;VALID LABEL CHAR?  ; NO, COMPARE A CHAR CP (HL) EX DE,HL INC HL ; INCR POINTERS INC DE JR NZ,OPTOK2 ; CHARS NOT EQU, GO TO NEXT ENTRYE ; SAVE START OF BUFFER POINTER POP IX INC DE ; LEAVE SPACE IN BUFF FOR CHAR COUNT GSYM1: LD (DE),A ; PUT CHAR IN BUGET NO. OF BYTES IN STRING LD B,A PUSH BC ; SAVE TOKEN BYTE COUNT (C) ; AND STRING CHAR COUNT (B) SUB 1 ; (BYTESCHAR IN C RUN1: CALL PCHO ; OUTPUT CHAR TO PUNCH DJNZ RUN1 ; LOOP UNTIL DONE POP BC ; REPLACE REG RET ;****************************************** ;GET TOKEN(S) FROM LIST ;ON ENTRY: ; SYMBUF CONTAINS SYMBOL ; HL CONTAINS POINTE;ON ENTRY: ; A CONTAINS CHARACTER ;ON EXIT: ; A CONTANS CHARACTER ; CARRY FLAG IS SET IF VALID. ;******* DEC B ; CHARS EQU, DECR COUNT LD A,(HL) ; GET A CHAR JR NZ,OPTOK1 ; MORE CHARS TO COMPARE POP BC ; NO MORE CHARSFFER INC DE ; INCREMENT POINTERS INC HL INC B ; AND COUNTER LD A,B ; IS THAT 6 CHARS? CP 6 JR Z,GSYM2 L IN STRING - 1) RLCA ; *2 LD E,A LD D,0 ADD HL,DE ; POINTER TO CORRECT WORD OF PNTR TABL LD A,(HL) INC HL LD ******************************************************** ;GET SYMBOL ;ON ENTRY: ; HL POINTS AT 1ST CHAR OF SYMBOL ; DR TO LIST POINTER TABLE ; DE POINTS AT DESTINATION FOR TOKENS ; C CONTAINS NO. OF TOKEN BYTES PER LIST ENTRY. ;ON***************************************************************** VALID: CP 'A' JR C,VALID1 CP 'Z'+1 RET C ; VALID VAL TO COMPARE POP DE ; MATCH FOUND, GET POINTER AND ; COUNT FOR TOKEN BUFFER. OPTOK5: LD A,(HL) LD (DE),A ; TRANSFED A,(HL) ; FETCH NEXT CHAR CALL VALID ; IS IT VALID IN A SYMBOL? JR C,GSYM1 ; JUMP IF SO GSYM3: LD (IX),B ; NO, ENDH,(HL) LD L,A ; HL POINTS TO CORRECT SECTION OF LIST OPTOK3: LD DE,SYMBUF+1 POP BC PUSH BC ; B CONTAINS NO. OF CHARS E POINTS AT BUFFER ;ON EXIT: ; HL POINTS AT CHAR AFTER SYMBOL ; BUFFER CONTAINS SYMBOL ;********************** EXIT: ; TOKEN(S) ARE IN DESTINATION. ; LAST ONE IS ALSO IN A ; ZERO FLAG SET IF NOT IN LIST. ;***********ID1: CP '0' JR C,VALID2 CP '9'+1 RET C ; VALID VALID2: CP '?' JR Z,VALID3 CP '_' JR Z,VALID3 SCF ; NOT VAR A BYTE INC HL INC DE DEC C JR NZ,OPTOK5 INC C ; CLEAR ZERO FLAG RET ; AND RETURN OPTOK4: POP BC ; ADJUST S OF SYMBOL POP BC ; REPLACE SAVED REGISTERS POP IX RET GSYM2: LD A,(HL) ; SCAN TO FIRST NON VALID CHAR CALL VALID IN STRING LD A,(HL) ; GET FIRST CHAR OF LIST ENTRY OR A ; IS IT 0? JR Z,OPTOK4 ; YES, END OF LIST OPTOK1: EX DE,HL ********************************************* GSYM: PUSH IX ; SAVE REGISTERS PUSH BC LD B,0 ; CLEAR CHAR COUNT PUSH D*********************************************************** OPTOK: PUSH DE ; SAVE PTR TO DEST FOR TOKENS. LD A,(SYMBUF) ; * TACK POP DE RET ; AND RETURN OPTOK2: LD A,B ; ADD REMAINING COUNT+ ; (NO OF TOKENS)-1 TO LIST PNTR POP BC PUNTRY ; (ADD COUNTER+3 TO TABLE POINTER) ADD A,C LD C,A LD B,0 ADD HL,BC JR LOC1 LOC3: INC C ; TOO FAR, RESETT INC IX ; CHARS OF SYMBOLS LOC2: LD A,(IX) ; COMPARE A CHAR CP (HL) JR C,LOC3 ; TOO FAR JR NZ,LOC5 ; NOT FAR  INC A LBSYM1: POP DE ; REPLACE REGS POP BC RET ;**********************************************************************IF FOUND IN TABLE. ;************************************************************************* LOCATE: PUSH BC ; SAVE REGISTELABEL? AND A ; IS IT ZERO? JR Z,LBSYM1 ; JUMP IF SO, NO LABEL INC A ; ADD 1 TO NUMBER LD C,A ; AND PUT IT IN BC SH BC ADD A,C DEC A LD E,A LD D,0 ADD HL,DE ; HL POINTING TO NEXT LIST ENTRY JR OPTOK3 ; GO CHECK NEXT ENTRY ;* ZERO FLAG LOC4: POP IX ; REPLACE REGS & RETURN POP BC ; WITH ZERO FLAG=0 RET ; DE CONTAINS START OF ENTRY ;*******ENOUGH ; CHARS EQUAL SO FAR INC HL ; MOVE BOTH POINTERS ON 1 INC IX DEC C ; DECR TABL SYM CHAR COUNT JR Z,L* ;CHECK SYMBOL IS NOT RESERVED WORD ;ON ENTRY SYMBOL IS IN SYMBUF ;CARRY FLAG SET IF RESERVED WORD. ;**********************RS PUSH IX LD HL,SYMTAB ; SET POINTER TO SYMBOL TABLE LOC1: PUSH HL ; SAVE POINTER TO START OF ENTRY POP DE ; IN DE  LD B,0 PUSH HL ; SAVE VALUE OF LABEL LD HL,LABBUF ; SET SOURCE PNTR = LABEL BUFFER LD DE,SYMBUF ; SET DEST PNTR = SYM************************************************************************ ;LOCATE A GIVEN SYMBOL IN THE SYMBOL TABLE, ;OR THE C**************************************************************** ;TRANSFER LABEL (AND VALUE) TO SYMBOL BUFFER ;ON ENTRY: HL COC6 DEC B ; DECR SEARCHED SYM CHAR COUNT JR Z,LOC3 ; TOO FAR JR LOC2 ; EQUAL SO FAR LOC6: DEC B JR Z,LOC4 ; MAT************************************************* SYMCH: PUSH HL ; SAVE REGISTERS PUSH DE PUSH BC ; CHECK IF SYMB = LD C,(HL) ; SAVE NO OF CHARS IN SYM IN C INC C ; TEST C FOR ZERO DEC C JR Z,LOC3 ; IF ZERO THEN END OF TABLE LD BOL BUFFER LDIR ; TRANSFER LABEL TO SYMBOL BUFFER EX DE,HL ; PUT SYMBOL BUFF PNTR IN HL POP DE ; GET VALUE IN DE ORRECT ALPHABETIC LOCATION FOR IT. ;ON ENTRY: ; SEARCHED SYMBOL IS IN SYMBOL BUFFER. ;ON EXIT: ; DE CONTAINS PNTONTAINS VALUE OF LABEL ;ON EXIT: HL CONTAINS POINTER TO ATTRIBUTE BYTE ; IN SYMBOL BUFFER ;*********************CH FOUND, RETURN WITH ZERO ; FLAG SET, DE POINTING AT ; ENTRY, & HL AT VALUE LOC5: LD A,3 ; SET POINTER TO NEXT E RESERVED WORD LD A,(SYMBUF) ; GET NO OF CHARS IN SYMB CP 6 ; MORE THAN 5 ? JR NC,SYMCH3 ; IF SO NOT RESERVED WORD LIX,SYMBUF ; SET POINTER TO SYMBOL BUFFER LD B,(IX) ; SAVE NO OF CHARS IN SEARCHED SYM INC HL ; MOVE BOTH POINTERS TO 1SLD (HL),E ; AND PUT IN SYMBUF INC HL LD (HL),D INC HL LD (HL),0 ; CLEAR ATTRIBUTES BYTE XOR A ; CLEAR ZERO FLAG R TO START OF ENTRY ; OR ALPHABETIC INSERTION POSITION. ; HL POINTS AT VALUE IF PRESENT ; ZERO FLAG SET ************************************************** LBSYM: PUSH BC ; SAVE REGS PUSH DE LD A,(LABBUF) ; HOW MANY CHARS IN + D DE,TEMP ; CHECK IF IN OPERATOR LIST LD HL,ORLSTP ; PNTR TO OPR LIST PNTR TABLE LD C,2 ; 2 TOKENS/ENTRY IN LIST CALLL,(SYMEND) ; FIND NO OF BYTES BETWEEN INSERTION SBC HL,DE ; POSITION AND END OF SYMBOL INC HL ; TABLE PUSH HL ; SAV ENTRY) LD DE,(SYMEND) ; GET PNTR TO END OF SYMBOL TABLE AND A ; CLEAR CARRY SBC HL,DE ; IS TABLE FULL? JR NC,INSRTY FLAG IF SO. ;********************************************************************* ALPHA: CP 'A' JR C,ALPHA1 CP 'Z'+1  ; REPLACE REGISTERS POP DE POP HL RET ;********************************************************************** ;INSERT********************************************************** ;SCAN TO NEXT NON SPACE CHAR ;ON ENTRY: ; HL CONTAINS POINTE OPTOK ; IN LIST? JR NZ,SYMCH1 ; JUMP IF SO LD A,(SYMBUF) ; GET NO OF CHARS IN SYMB CP 4 ; MORE THAT 3? JR NC,SYMCE NO OF BYTES ON STACK LD HL,(SYMEND) LD D,H LD E,L LD A,(SYMBUF) ; CALCULATE NO OF BYTES FOR INSERTION ADD A,4 LD 1 ; JUMP IF NOT LD HL,AFLAGS ; SET SYM TAB OVERFLOW FLAG SET 2,(HL) POP DE ; ADJUST STACK JR INSRT2 INSRT1: PORET ALPHA1: OR A ; NOT LETTER, CLEAR CARRY RET ;********************************************************************* ;CH SYMBOL INTO SYMBOL TABLE ;ON ENTRY DE POINTS AT INSERTION POSITION ;SYMBOL IS IN SYMBOL BUFFER (SYMBUF) ;*******************R ;ON EXIT: ; HL POINTS AT FIRST NON-SPACE CHAR ;********************************************************************* H3 ; IF SO NOT RESERVED WORD LD DE,TEMP ; CHECK IF IN OPND KW LIST LD HL,OPKLST ; PNTR TO LIST PNTR TABLE LD C,1 ; 1C,A ; PUT IN BC LD B,0 PUSH BC ; SAVE IN BC' EXX POP BC EXX ADD HL,BC LD (SYMEND),HL ; SAVE NEW END OF SYMBOLP DE ; LEAVE PNTR TO INSERT POS IN DE' PUSH DE EXX POP DE ; GET PNTR TO INSERT POS ; OPEN UP A GAP IN TABLE USINECK IF DIGIT (0-9) IN ACC. ;IF SO, RETURN WITH CARRY SET. ;********************************************************************************************************************** INSERT: EXX ; SAVE REGS PUSH HL PUSH DE PUSH BC EXX PUSH HL  SCNSP: LD A,(HL) ; GET A CHAR CP SPACE ; IS IT A SPACE? RET NZ ; IF NOT RETURN INC HL ; INCREMENT POINTER JR SC TOKEN/ENTRY IN LIST CALL OPTOK ; IN LIST? JR Z,SYMCH2 ; JUMP IF NOT ; RESERVED WORD USED SYMCH1: LD C,'W' ; IND TABLE EX DE,HL POP BC ; NO OF BYTES LDDR ; MOVE BLOCK TO OPEN GAP ; INSERT NEW SYMBOL RECORD ; INTO GAP G ; BLOCK MOVE. DE WILL CONTAIN DEST. ; HL THE SOURCE AND BC THE NO. ; OF BYTES AND A ; CLEAR CARRY LD H** DIGIT: CP '0' JR C,DIGIT1 CP '9'+1 RET DIGIT1: OR A ; NOT DIGIT, CLEAR CARRY RET ;******************************PUSH BC PUSH DE LD HL,(MEMTOP) ; GET POINTER TO TOP OF LD DE,-10 ; AVAILABLE RAM (WITH ROOM FOR ANOTHER ADD HL,DE ;NSP ;********************************************************************* ;CHECK IF ASCII CHAR IN ACC ;IS A LETTER. SET CARRICATE ERROR CALL ERROR SCF ; SET CARRY FLAG JR SYMCH3 SYMCH2: AND A ; NOT RESERVED WORD, CLEAR CARRY SYMCH3: POP BC EXX LD HL,SYMBUF LDIR INSRT2: POP BC ; REPLACE REGS POP HL EXX POP BC POP DE POP HL EXX RET ;***********, ************************************** ;ERROR ROUTINE. SET ERROR CHAR IF NOT ;ALREADY SET. ;ON ENTRY: ; C CONTAINS ASC DEFB 2FH DEFM 'CCF' DEFB 0AH DEFB 3FH DEFM 'SCF' DEFB 0AH DEFB 37H DEFM 'NOP' DEFB 0AH DEFB 00H DEFM 'RLA' DEFB 0EH DEFB 00H DEFM 'RL' DEFB 0FH DEFB 10H DEFM 'RR' DEFB 0FH DEFB 18H DEFM 'JR' DEFB 92H DEFB 00H DEFMDEFB 00H DEFM 'DEFB' DEFB 05H DEFB 00H DEFM 'DEFW' DEFB 06H DEFB 00H DEFM 'DEFS' DEFB 07H DEFB 00H DEFM 'DEF************************************************************* ORLSTP: DEFW OR1 ; POINTER LIST TO THE SECTIONS DEFW OR2 ;  DEFB 08H DEFM 'SRA' DEFB 0FH DEFB 28H DEFM 'SRL' DEFB 0FH DEFB 38H DEFM 'BIT' DEFB 10H DEFB 40H DEFM 'SETII ERROR CHAR ;ON EXIT: ; ERRBUF CONTAINS ERROR CHAR ;***************************************************************** DEFB 0AH DEFB 17H DEFM 'RRA' DEFB 0AH DEFB 1FH DEFM 'LDI' DEFB 0BH DEFB 0A0H DEFM 'LDD' DEFB 0BH DEFB 0A8H 'EX' DEFB 1AH DEFB 00H DEFB 00H OR3: DEFM 'INC' DEFB 0DH DEFB 00H DEFM 'DEC' DEFB 0DH DEFB 09H DEFM 'OUT' M' DEFB 08H DEFB 00H DEFM 'HALT' DEFB 0AH DEFB 76H DEFM 'RLCA' DEFB 0AH DEFB 07H DEFM 'RRCA' DEFB 0AH DEFBOF THE OPERATOR LIST WITH DEFW OR3 ; DIFFERENT NOS. OF CHARS DEFW OR4 DEFW OR5 OR1: DEFB 0 ; OPERATOR LIST ITSELF O' DEFB 10H DEFB 0C0H DEFM 'RES' DEFB 10H DEFB 80H DEFM 'RET' DEFB 95H DEFB 00H DEFM 'RST' DEFB 16H DEFB 00** ERROR: LD A,(ERRBUF) ; GET CONTENT OF ERROR DISPLAY REG. CP SPACE ; IS IT A SPACE? RET NZ LD A,C ; YES, REPLACE W DEFM 'CPI' DEFB 0BH DEFB 0A1H DEFM 'CPD' DEFB 0BH DEFB 0A9H DEFM 'NEG' DEFB 0BH DEFB 44H DEFM 'RLD' DEFB DEFB 18H DEFB 00H DEFM 'AND' DEFB 0CH DEFB 20H DEFM 'ORG' DEFB 01H DEFB 00H DEFM 'EQU' DEFB 02H DEFB 00H D 0FH DEFM 'LDIR' DEFB 0BH DEFB 0B0H DEFM 'LDDR' DEFB 0BH DEFB 0B8H DEFM 'CPIR' DEFB 0BH DEFB 0B1H DEFM R2: DEFM 'LD' DEFB 1DH DEFB 00H DEFM 'JP' DEFB 91H DEFB 00H DEFM 'CP' DEFB 0CH DEFB 38H DEFM 'IN' DEFB 17H H DEFM 'POP' DEFB 19H DEFB 0C1H DEFM 'ADC' DEFB 1BH DEFB 08H DEFM 'SBC' DEFB 1BH DEFB 10H DEFM 'ADD' DEFB ITH ERROR INDICATOR LD (ERRBUF),A RET ;******************************************************************* ;OPERATOR LIST 0BH DEFB 6FH DEFM 'RRD' DEFB 0BH DEFB 67H DEFM 'INI' DEFB 0BH DEFB 0A2H DEFM 'IND' DEFB 0BH DEFB 0AAH DEFMEFM 'END' DEFB 04H DEFB 00H DEFM 'EXX' DEFB 0AH DEFB 0D9H DEFM 'DAA' DEFB 0AH DEFB 27H DEFM 'CPL' DEFB 0AH 'CPDR' DEFB 0BH DEFB 0B9H DEFM 'RETI' DEFB 0BH DEFB 4DH DEFM 'RETN' DEFB 0BH DEFB 45H DEFM 'INIR' DEFB 0BH  DEFB 00H DEFM 'OR' DEFB 0CH DEFB 30H DEFM 'DI' DEFB 0AH DEFB 0F3H DEFM 'EI' DEFB 0AH DEFB 0FBH DEFM 'IM' 1CH DEFB 00H DEFM 'SUB' DEFB 0CH DEFB 10H DEFB 00H OR4: DEFM 'CALL' DEFB 94H DEFB 00H DEFM 'DEFL' DEFB 03H  ;EACH SECTION OF LIST CONTAINS OPERATOR ;STRING FOLLOWED BY OPERATOR GROUP TOKEN ;(1-1D) FOLLOWED BY OPERATOR VALUE. ;****** 'XOR' DEFB 0CH DEFB 28H DEFM 'RLC' DEFB 0FH DEFB 00H DEFM 'SLA' DEFB 0FH DEFB 20H DEFM 'RRC' DEFB 0FH-  DEFB 0B2H DEFM 'INDR' DEFB 0BH DEFB 0BAH DEFM 'OUTI' DEFB 0BH DEFB 0A3H DEFM 'OTIR' DEFB 0BH DEFB 0B3H DEFM60H ; (BC) DEFB 71H ; C DEFB 0A0H ; (C) DEFB 0CAH ; IX+D DEFB 0BAH ; (IX+D) DEFB 0CEH ; IY+D DEFB 0BEH FM 'NZ' DEFB 88H DEFM 'PE' DEFB 8DH DEFM 'PO' DEFB 8CH DEFB 00H OPKW3: DEFM 'AF''' DEFB 0E0H DEFB 00H ;*******DEFB 3DH DEFM '/' DEFB 45H DEFM '&' DEFB 73H DEFM '^' DEFB 7AH DEFM '=' DEFB 89H DEFM '>' DEFB 91H DEFM '<ERAND DEFW OPKW3 ; KEYWORD LIST. OPKW1: DEFB 'A' DEFB 77H DEFB 'B' DEFB 70H DEFB 'C' DEFB 71H DEFB 'D' DEFB 7M 'MOD' DEFB 4DH DEFM 'SHR' DEFB 55H DEFM 'SHL' DEFB 5DH DEFM 'AND' DEFB 73H DEFM 'XOR' DEFB 82H DEFM 'UGT'  'OUTD' DEFB 0BH DEFB 0ABH DEFM 'OTDR' DEFB 0BH DEFB 8BH DEFM 'DJNZ' DEFB 13H DEFB 00H DEFM 'PUSH' DEFB 19H  ; (IY+D) DEFB 90H ; N DEFB 0D0H ; (N) DEFB 00H ; END OF LIST ;****************************************************************************************************************** ;BRACKETABLE OPERAND LIST. ;***********************************' DEFB 99H DEFB 0 ; ;****************************************************************** ; LINKAGES TO CP/M START HERE - J2H DEFB 'E' DEFB 73H DEFB 'H' DEFB 74H DEFB 'L' DEFB 75H DEFB 'Z' DEFB 89H DEFB 'P' DEFB 8EH DEFB 'M' DE DEFB 0A1H DEFM 'ULT' DEFB 0A9H DEFB 0 MCF4: DEFM 'HIGH' DEFB 1FH DEFB 0 ;***************************************** DEFB 0C5H DEFB 00H OR5: DEFM 'TITLE' DEFB 09H DEFB 00H DEFB 00H ;******************************************************************** ;MULTI-CHARACTER FUNCTION LIST. ;********************************************************************* MFLS********************************** BKLST: DEFB 12H ; HL DEFB 40H ; (HL) DEFB 1AH ; IX DEFB 48H ; (IX) DEFB 1EH .P.J. 4/5/82 ;****************************************************************** ; ; SRCFCB: DEFB 0 ;FCB STARTS WITH 0 FORFB 8FH DEFB 'I' DEFB 20H DEFB 'R' DEFB 21H DEFB 00H OPKW2: DEFM 'AF' DEFB 17H DEFM 'BC' DEFB 10H DEFM 'DE' ****************************** ;SINGLE CHAR FUNCTION LIST. ;************************************************************************************* ;OPERAND KEYWORD LIST ;CONTAINS OPERAND KEYWORDS FOLLOWED BY ;TOKENS FOR THEM. ;************************TP: DEFW MCF1 DEFW MCF2 DEFW MCF3 DEFW MCF4 MCF1: DEFB 0 MCF2: DEFM 'OR' DEFB 7AH DEFM 'EQ' DEFB 89H DEFM 'G ; IY DEFB 4CH ; (IY) DEFB 13H ; SP DEFB 50H ; (SP) DEFB 11H ; DE DEFB 61H ; (DE) DEFB 10H ; BC DEFB  DEFAULT DRIVE SRCFN: DEFM ' ' ;RESERVE 8 CHARS FOR FILE NAME DEFM 'Z80' ;USE EXTENSION OF Z80 DEFB 0 ;START WITH DEFB 11H DEFM 'HL' DEFB 12H DEFM 'SP' DEFB 13H DEFM 'IX' DEFB 1AH DEFM 'IY' DEFB 1EH DEFM 'NC' DEFB 8AH DE***** SFLSTP: DEFW SCF1 ; POINTER TO LIST SCF1: DEFM '+' DEFB 7H DEFM '-' DEFB 0FH DEFM '\' DEFB 17H DEFM '*' ********************************************** OPKLST: DEFW OPKW1 ; POINTER LIST TO DIFFERENT DEFW OPKW2 ; SECTIONS OF OPT' DEFB 91H DEFM 'LT' DEFB 99H DEFB 0 MCF3: DEFM 'NOT' DEFB 17H DEFM 'LOW' DEFB 27H DEFM 'RES' DEFB 2EH DEF. EXTENT 0 DEFS 23 ;23 BYTES FOR CP/M SRCPTR: DEFS 2 ;FOR CHARACTER POINTER SRCOPN: DEFM 'C' ;DECLARE CLOSED ; LSTFCB: DEU 0AH TPA EQU 0100H BDOS EQU 5 BOOT EQU 0 ; ; ORG TPA LD SP,LSTACK LD DE,SIGNON LD C,9 CALL BDOS ;PRINT SIGNON  * ;* DKCOPY * ;* * ;* A FILE COPY PROGRAM CP 2AH ;CHECK FOR * JR NZ,NOTSTAR-$ LD A,(NAMEPT) ;CHARACTER IS A STAR. CP 9 ;CHECK JR NC,TYPE-$ ;FOR FILE NAME ORRAL RETURN FOR ALL SUBR'S POP DE POP BC RET ; ; OPNOUT: PUSH DE ;OPEN (DE) FCB FOR OUTPUT LD C,DELFIL ;FIRST DELETLL BDOS ;CHARACTER. CP 3 ;CHECK FOR CNTL-C JP Z,BOOT CP 8 ;CHECK FOR BACKSPACE JR NZ,NOTBS-$ LD A,(NAMEPT) ;CHEFB 0 ;LISTING FILE SETUP LSTFN: DEFM ' ' DEFM 'PRN' ;PRINT FILE DEFB 0 ;EXTENT 0 DEFS 23 LSTPTR: DEFS 2 LSTOPMESSAGE ; ; RSET LD A,0 ;CLEAR TWO FLAGS LD (AST),A ;ASTERISK IN NAME OR TYPE LD (FIRSTF),A ;FILE COUNTER ; GETFIL * ;* FOR SINGLE DRIVE SYSTEMS * ;* * ;*  TYPE. LD HL,(FCBBSPT) ;FILE NAME-LOAD IN INC HL ;???????? FOR NAME. PUSH HL POP DE INC DE LD BC,7 LD (HL),3FH E CURRENT CALL CPM POP DE LD C,MAKFIL ;THEN RE-CREATE JP CPM ; CONIN: PUSH BC ;CONSOLE INP IS ONLY COMMON PUSH DE CK FOR BEGINNING OF LINE CP 1 JR Z,FNAME-$ DEC A ;NOT BEGINNING OF LINE LD (NAMEPT),A ;DECREMENT NAME POINTER LD E,N: DEFM 'C' ; HEXFCB: DEFB 0 ;SAME FOR HEX FILE HEXFN: DEFM ' ' DEFM 'HEX' DEFB 0 DEFS 23 HEXPTR: DEFS 2 HEXE LD HL,(FCBBSPT) ;CLEAR OUT LD (HL),0 ;DR FIELD. INC HL ;PUT BLANKS PUSH HL ;INTO POP DE INC DE ;NAME LD B * ;**************************************** ; ; ASSEMBLED WITH Z80ASM FROM CPMUG VOL #16 ; ; WRITTEN JAN 24,1981 BY ;  LDIR LD A,9 ;SET CHARACTER LD (NAMEPT),A ;POINTER TO FILE TYPE. LD A,1 ;TURN ON LD (AST),A ;NAME-STAR FLAG. J ; POINT FOR ALL PASSES SO DO PUSH HL ; SETUP HERE ; LD A,(SRCOPN) ;IS SRC OPEN? CP 'O' CALL NZ,CPYFCB ;IF NOT, CREAA ;RESTORE SPACE IN NAME LD D,0 LD HL,(FCBBSPT) ADD HL,DE LD (HL),20H LD E,20H LD C,2 CALL BDOS ;SPACE LD E,OPN: DEFM 'C' ; MEMCK: LD A, (7H) ;GET HIGH ORDER BYTE OF BDOS ENTRY LD B,A ;XFER TO B LD A, (6H) ;LOW BYTE TO A REC,11 ;AND LD (HL),20H ;TYPE LDIR ;FIELDS. LD (HL),0 LD BC,30 ;CLEAR OUT REST OF FCB LDIR ; LD E,25H ;OUTP; KEN STEPHENSON ; PHYSICS DIVISION ; ARGONNE NATIONAL LABORATORY ; ARGONNE,IL 60439 ; ; CRLF EQU 0D0AH CR EQU 0DH LF EQR FNAME-$ ;KEEP GOING UNTIL DECIMAL PT. ; TYPE LD HL,(FCBBSPT) ;FORM POINTER LD DE,9 ;IN HL ADD HL,DE ;TO FILE TYPE; ;**************************************** ;* * ;* 8 LD C,2 CALL BDOS ;BACKSPACE JR FNAME-$ NOTBS CP CR JR Z,CKDONE-$ ;IF RETURN, NAME IS IN- ;GO SEE IF DONE. T ; CONOUT: PUSH BC ;NO REGISTERS MAY BE DESTROYED PUSH DE PUSH HL OUT4: LD A,C CALL PUTCON ; GENRET: POP HL ;GENEUT LD C,2 ;PROMPT. CALL BDOS ; LD A,1 ;INITIALIZE FOR FILE LD (NAMEPT),A ;NAME FETCH. ; FNAME LD C,1 ;GET CA/  AREA. LD D,3FH ;LOAD IN LD (HL),D ;??? INC HL ;FOR LD (HL),D ;FILE INC HL ;TYPE. LD (HL),D LD A,12 ;SP 0 ;FOR FIRST FILE. JR NZ,NOT1ST-$ LD DE,FCBNAME ;1ST FILE. LD HL,(FCBBSPT) ;COPY NAME LD BC,33 ;INTO LDIR ; ;END OF FCB. INC DE LD (HL),0 LD BC,20 LDIR LD HL,(FCBBSPT) ;CHECK FOR ? IN NAME ;OR TYPE FIELDS. LD B,11  NMATCH LD DE,NOMATCH ;NO FILE MATCH. LD C,9 ;OUTPUT CALL BDOS ;ERROR MESSAGE. JP RSET ;GO BACK FOR MORE. ; ; O CP 7BH JR NC,UPPERC-$ AND 01011111B UPPERC LD (HL),A ;STORE CHARACTER. INC E ;INCREMENT LD A,E LD (NAMEPT),A ;C5 JP Z,RSET JR SLOOP-$ GOTFILE POP AF ;SEARCH WAS SUCCESSFUL ADD A ADD A ;A*32 POINTS ADD A ;TO LOCATION ADD ET CHARACTER POINTER PAST LD (NAMEPT),A ;FILE TYPE AREA. LD A,1 ;TURN ON LD (AST),A ;TYPE-STAR FLAG. JR FNAME-$ ;STORAGE AREA. NOT1ST LD DE,(FCBBSPT) ;COPY NAME LD HL,FCBNAME ;INTO FCB. LD BC,33 LDIR LD A,0 ;ZERO FILE LD (FCOU QLOOP INC HL LD A,(HL) CP '?' JR NZ,NOTQ-$ LD A,1 ;THERE IS A ? IN NAME OR LD (AST),A ;TYPE FIELDS - FLAG FOR PEN LD DE,(FCBBSPT) ;OPEN FILE. LD C,15 CALL BDOS CP 255 ;CHECK STATUS OF OPEN JR NZ,FILEOK-$ LD DE,NOTOPN LD C,9HARACTER COUNTER. JP FNAME ;GO BACK FOR ANOTHER CHAR. ; CKDONE LD E,LF ;OUTPUT A LINEFEED LD C,2 CALL BDOS LD HL,(A ;OF FCB IN ADD A ;DMA AREA. LD HL,80H LD D,0 LD E,A ADD HL,DE ;HL POINTS TO FCB AS READ INC HL ;FROM DISK.KEEP GOING UNTIL CARRIAGE RET. ; NOTSTAR CP 2EH ;CHECK FOR DECIMAL PT. JR NZ,NOTDOT-$ LD A,9 ;CHARACTER IS DECIMAL PT.NT),A ;COUNTER. LD DE,(FCBBSPT) LD C,17 CALL BDOS ;CPM SEARCH FOR FIRST FUNC. CP 255 JR Z,NMATCH-$ SLOOP PUSH AF  ;LOOP ON ALL NAME MATCHES. NOTQ DJNZ QLOOP-$ ;TEST ASTERISK OR ? FLAGS LD A,(AST) CP 1 JP NZ,OPEN ;NO FLAGS-GO ;FILE NOT OPENED-OUTPUT CALL BDOS ;ERROR MESSAGE. JP RSET ;START OVER. ; FILEOK LD DE,(FCBBSPT) ;FILE OPENED SUCCEFCBBSPT) ;CHECK FOR BLANK IN INC HL ;FIRST LD A,(HL) ;BYTE CP 20H ;OF NAME. JP Z,WRITEF ;IF SO,THEN DONE WITH RE LD DE,(FCBBSPT) ;COPY NAME INC DE ;INTO NEW LD BC,11 ;FCB AREA. LDIR CALL OUTFCB ;PRINT FILE NAME. LD DE,MAT LD (NAMEPT),A ;SET CHAR. PT. TO FILE TYPE. JP FNAME ;GO BACK FOR FILE TYPE. ; NOTDOT LD HL,(FCBBSPT) ;CHARACTER PASSE LD A,(FIRSTF) ;SEE IF LD C,A ;THIS LD A,(FCOUNT) ;FILE CP C ;HAS ALREADY JR Z,GOTFILE-$ ;BEEN STORED. INC A  OPEN FILE. ; STAR LD DE,80H ;STAR FLAG SET. LD C,26 ;SET DMA ADDRESS TO CALL BDOS ;80H. LD A,(FIRSTF) ;CHECK CSSFULLY. LD C,35 CALL BDOS ;CPM COMPUTE FILE SIZE FUNC. LD BC,(FCBBSPT) LD HL,34 ;COMPUTE RAM SPACE ADD HL,BC ;LADS. ; LD HL,(FCBBSPT) ;MORE FILES TO READ. LD DE,12 ADD HL,DE ;CLEAR OUT SPURIOUS PUSH HL ;CHARACTERS AT POP DECHED LD C,9 CALL BDOS LD A,(FIRSTF) ;INCREMENT SEARCH INC A ;POINTER. LD (FIRSTF),A JR OPEN-$ ;GO OPEN FILE. ;S ALL TRAPS LD DE,(NAMEPT) ;FORM LD D,0 ;POINTER ADD HL,DE ;IN HL. CP 61H ;CHECK FOR LOWER CASE JR C,UPPERC-$ ;YES, GO ON LD (FCOUNT),A ;TO SEARCH FOR POP AF ;NEXT LD C,18 ;FILE CALL BDOS ;CPM SEARCH FOR NEXT FUNC. CP 250 EFT FOR FILES. PUSH HL POP BC LD HL,(BDOS+1) ;FBASE INTO HL OR A SBC HL,BC ;HL CONTAINS RAM SPACE IN BYTES LD C,HR. ; GORITE LD DE,NLINE LD C,9 CALL BDOS LD HL,BUFSTRT ;STARTING FCB ADDR. LD (FCBBSPT),HL LD DE,(FCBBSPT)  INC A ;COUNTER. LD (NUMFILE),A LD HL,(DATAPT) ;CALCULATE LD (FCBBSPT),HL LD A,(AST) ;AS WE IN ASTERISK LOOP? CP DE,MAKEBAD ;ERROR IN FILE CREATION. LD C,9 CALL BDOS JP DONE ; MAKEOK CALL OUTFCB ;FILE CREATED SUCCESSFULLY LD DE, ;NOW HL IS DMA POINTER. LD (DATAPT),HL ; GETREC LD DE,(DATAPT) ;START READ LOOP. LD C,26 ;SET DMA ADDRESS. CALL BDE- ;GO TRY ANOTHER DISK. DRVOK LD DE,NLINE LD C,9 CALL BDOS LD C,13 ;WRITE ENABLE DISK CALL BDOS FLOOP LD LD L,H ;CALCULATE # OF 128 BYTE SCTRS LD H,0 LD B,0 ADD HL,BC DEC HL ;LESS 128 BYTES FOR OVERHEAD. LD IX,(FCBBSLD C,15 ;TRY TO OPEN A FILE CALL BDOS ;SOLE PURPOSE OF THIS ;IS TO FORCE CPM TO TEST ;FOR A DISK CHANGE. LD 1 JP Z,STAR JP RSET ;NOT STAR LOOP- ;BACK FOR KEYBD INPUT. ; ; WRITEF LD C,29 CALL BDOS LD DE,WMSG LD C,9 CREATED LD C,9 CALL BDOS ; LD HL,(FCBBSPT) ;CALCULATE LD DE,33 ;ADDRESS OF ADD HL,DE ;RECORD LD (RECNTPT),HL OS LD DE,(FCBBSPT) LD C,20 ;READ A CALL BDOS ;SECTOR. CP 0 ;END OF FILE? JR NZ,ENDFR-$ LD HL,(DATAPT) ;NOT EO A,(NUMFILE) ;SEE IF MORE FILES TO RITE. CP 0 JP Z,DONE LD DE,(FCBBSPT) ;MORE FILES. LD C,19 ;DELETE PRESENT FILE IFPT) LD B,(IX+34) ;BC CONTAINS # LD C,(IX+33) ;RECORDS IN FILE. OR A SBC HL,BC ;COMPARE RAM SPACE WITH DISK JR NC,MC,29 ;RETURN CALL BDOS ;R/O VECTOR. BIT 0,L ;BIT 0 OF L SET MEANS JR NZ,DRVOK-$ ;DISK HAS BEEN CHANGED. LD DE,DCH CALL BDOS LD E,23H ;KEYBD PROMPT LD C,2 CALL BDOS LD C,1 CALL BDOS CP 3 ;CHECK FOR CNTL-C JP Z,BOOT CP 47H ;COUNTER. INC HL INC HL ;STARTING ADDR LD (DATAPT),HL ;OF DATA. ; RLOOP LD HL,(RECNTPT) ;SEE IF ALL RECORDS HAVE LF LD DE,128 ;INCREMENT ADD HL,DE ;DMA POINTER. LD (DATAPT),HL LD HL,(RECNTPT) ;INCREMENT LD D,(HL) ;RECORD IN CALL BDOS ;ALREADY ON DISK. ; LD HL,(FCBBSPT) ;CLEAR OUT NON-NAME PART LD DE,12 ADD HL,DE PUSH HL ;OF FCB POP EMOK-$ LD DE,SHRTMEM ;NOT ENOUGH MEMORY FOR FILE. LD C,9 CALL BDOS JP RSET ; MEMOK LD HL,(FCBBSPT) ;FORM POINTER TO ANGE ;CPM SAYS DISK HAS LD C,9 ;NOT BEEN CHANGED. CALL BDOS LD E,23H LD C,2 CALL BDOS ;KEYBD PROMPT LD C,1 ;L ;WAIT FOR CONSOLE INPUT OF JR Z,GORITE-$ ;G OR g BEFORE STARTING. CP 67H JR Z,GORITE-$ JR WRITEF-$ ;KEYBD ENTRY ERROD A,(HL) ;BEEN READ. CP 0 JR NZ,MOREREC-$ INC HL LD A,(HL) CP 0 JR NZ,MOREREC-$ LD DE,(FCBBSPT) ;NO MORE RECORDC HL ;COUNTER. LD E,(HL) INC DE LD (HL),E DEC HL LD (HL),D JR GETREC-$ ; ENDFR LD A,(NUMFILE) ;INCREMENT FILE DE INC DE LD (HL),0 LD BC,20 LDIR LD DE,(FCBBSPT) ;CREATE FILE. LD C,22 CALL BDOS CP 255 JR NZ,MAKEOK-$ LD  LD DE,33 ;RECORD ADD HL,DE ;COUNTER. LD (RECNTPT),HL LD (HL),0 ;INITIALIZE COUNTER. INC HL LD (HL),0 INC HLET USER OVERIDE CALL BDOS ;IF HE WANTS. CP 47H JR Z,DRVOK-$ CP 67H JR Z,DRVOK-$ JR WRITEF-$ ;ABORT IN NICK OF TIM1 S IN LD C,16 ;THIS FILE. CLOSE FILE. CALL BDOS LD HL,(DATAPT) ;SET NEW FCB ADDR. LD (FCBBSPT),HL LD A,(NUMFILE) ;D'TYPE RETURN TO END' DEFW CRLF DEFB '$' WMSG DEFW CRLF DEFB ' LOAD IN WRITE DISK' DEFW CRLF DEFB ' WHEN READY TO TBUF DEFB ' . IS $' MATCHED DEFB 'MATCHED' DEFW CRLF DEFB '$' CREATED DEFB 'CREATED' DEFW CRLF DEFB '$' ; [o[t *o"o*qV#^s+r:v<2v*o"t:  #G(g(l !w"t[tEMENT DATA POINTER LD DE,128 ADD HL,DE LD (DATAPT),HL JP RLOOP ; DONE JP 0 ;DONE - TRY TO BOOT CPM ; ; ; ; OUTF1: >22*t6# 6 6%>2s $:s(=2s_*t6   (h* ;:s 0*t#ECREMENT FILE COUNTER. DEC A LD (NUMFILE),A JR FLOOP-$ ; MOREREC LD DE,(DATAPT) ;SET DMA ADDR. LD C,26 CALL BDOS GO, TYPE G ' DEFW CRLF DEFB '$' MAKEBAD DEFB ' COULD NOT CREATE FILE' DEFW CRLF DEFB '$' DISKFUL DEFB ' DISK FULL - FISIGNON DEFW CRLF DEFB ' COPY ROUTINE FOR SINGLE DRIVE SYSTEMS' DEFW CRLF DEFB LF DEFB ' INSERT READ DISK ' DEFW E  #G(g(l  :vs[t*t 6[t  sv *tCB LD HL,(FCBBSPT) ;TRANSFER FILE NAME INC HL LD DE,OUTBUF ;TO BUFFER. LD BC,8 LDIR INC DE ;SAME FOR FILE TYPE. 6?> 2s>2*t ?r#r#r> 2s>2. > 2s6*t[sa8{0_w{2s6 *t#~ E*t 6*t #~? LD DE,(FCBBSPT) ;WRITE SECTOR. LD C,21 CALL BDOS CP 0 ;CHECK FOR DISK FULL. JR Z,RITEOK-$ LD DE,DISKFUL ;DISK IS FLE DELETED' DEFW CRLF DEFB '$' DCHANGE DEFW CRLF DEFB ' CPM SAYS DISK NOT CHANGED ' DEFW CRLF DEFB ' TO OVERIDCRLF DEFB '$' ; DEFS 32 ;LOCAL STACK AREA LSTACK EQU $ ; NOMATCH DEFB ' NO MATCH ' DEFW CRLF DEFB '$' ; NOTOPN D!"q##"o*q~ #~ [t*o"t:v=2v[o[t( [ts*qV#^s+r*o"o *t#LD BC,3 LDIR LD DE,OUTBUF LD C,9 CALL BDOS ;PRINT STRING RET ; ; DATA AREA ; AST DEFB 0 ;ASTERISK FLAG FIRSTF>2:›: *t![t!!>2[t(H:O:(<2 񇇇!_#[t vULL. LD C,9 CALL BDOS LD DE,(FCBBSPT) ;DELETE LAST FILE. LD C,19 CALL BDOS JP DONE ; RITEOK LD HL,(RECNTPT) ;DECE - TYPE G OR g ' DEFW CRLF DEFB ' TO ABORT - TYPE ANYTHING ELSE' NLINE DEFW CRLF DEFB '$' ; DATAPT DEFW BUFSTRT+35EFB ' FILE COULD NOT BE OPENED ' DEFW CRLF DEFB '$' ; SHRTMEM DEFB ' NOT ENOUGH MEMORY FOR FILE - TRY ANOTHER OR ' DEFB  #G(g(l  . IS $MATCHED $CREATED $ COPY ROUTINE FOR SINGLE DRIVE SYSTE DEFB 0 ;FILE SEARCH POINTER. FCOUNT DEFB 0 ;FILE COUNTER IN SEARCH. FCBNAME DEFS 33 ;STORAGE FOR FILE NAME,TYPE. ; OU :<2 :  [t G  [t#Kt!" *BLl& +*tF"N!B0 d  *t!"q6#6#"oREMENT LD D,(HL) ;RECORD INC HL ;COUNTER. LD E,(HL) DEC DE LD (HL),E DEC HL LD (HL),D LD HL,(DATAPT) ;INCR RECNTPT DEFW BUFSTRT+33 NAMEPT DEFB 1 FCBBSPT DEFW BUFSTRT NUMFILE DEFB 0 BUFSTRT DEFB 0 ENDLAB END 2 MS INSERT READ DISK $[t*o"t:v=2v[o NO MATCH $ FILE COULD NOT BE OPENED $ NOT ENOUGH MEMORY FOR FILE rive A, then boot CP/M and type DKCOPY. The program prints a sign-on message and gives the prompt %. At this point, the user them stopped working. This left me with no good way to transfer files from disk to disk. DKCOPY is a program that I wrote w.HEX IS MATCHED DKCOPY .COM IS MATCHED %letterto.ed1 % LOAD IN WRITE DISK WHEN READY TO GO, TYPE G #g DKCOPY .DOC. The program uses the built-in CP/M software tests to determine whether or not a different disk has actually been inserted. - TRY ANOTHER OR TYPE RETURN TO END $ LOAD IN WRITE DISK WHEN READY TO GO, TYPE G $ COULD NOT CREATE FILE $ DISK FULL -  types in the names of files to be copied in the usual format, with name and extension separated by a decimal point and the exhich reads files from one disk, waits for you to swap disks, and then writes the files onto the new disk. The size and number IS CREATED DKCOPY .ASM IS CREATED DKCOPY .HEX IS CREATED DKCOPY .COM IS CREATED LETTERTO.ED1 IS CREATED A> This p Finally, the program writes the files onto the new disk, deleting any file existing on the disk which has the same name as oFILE DELETED $ CPM SAYS DISK NOT CHANGED TO OVERIDE - TYPE G OR g TO ABORT - TYPE ANYTHING ELSE $wtension followed by a carriage return. Asterisks in name and/or extension fields are allowed and ? symbols can be used in pla of files that can be copied at a time is limited by the memory space available on the Big Board (about 52k). The program autorogram may not particularly useful to those who work with files larger than 52k. On the other hand, for people who work with ne being written. A sample session with the program might go as follows (user input is shown as lower case): A>dkcopy Cce of letters. After the last file name has been entered, a carriage return should be given in response to the next prompt. matically limits the number of files read in to fit into memory. To use the program, make sure your drive is configured as dsmall files, it is possible to get along very nicely with this program and only one drive. This may be of interest to those wDKCOPY - A FILE COPY ROUTINE FOR ONE DRIVE SYSTEMS Eight hours after I had my two new Shugart drives up and running, one ofOPY ROUTINE FOR SINGLE DRIVE SYSTEMS INSERT READ DISK %dkcopy.* DKCOPY .DOC IS MATCHED DKCOPY .ASM IS MATCHED DKCOPY At this point, the program indicates that file writing is imminent and that a different disk should be inserted into the drive3 ho are thinking about purchasing a Big Board but balk at the $800+ for two disk drives. ; ; ; org base+100h ; start of TPA ; lxi h,0 ; clear HL dad sp it than to try and ; patch it for 2.0, 2.1, 2.2. ; ; ; ***** EQUATES ***** ; base equ 0  push b ; ...the registers push psw mvi c,ochar ; tell bdos mov er inx h ; increment the pointer cpi '$' ; endmark? jz inlprt2 ; load HL with CCP sp shld oldsp ; save it for later lxi sp,stack ; initialize ; 'normal' CP/M bdos equ base+5 ; jump to bdos ochar equ 2 ; bdos console output sdsk e,a ; bdos wants it in E call bdos ; let bdos do it pop psw ; reinst; ; BITMAP for CP/M 2.0+ as of 7/11/80 ; ; ; Lauren Guimont ; 14211 8th Avenue South ;  ; if so, prepare to exit call conout ; output to console jmp inlprt1 ; go get our own sp jmp start ; bypass some subroutines ds 48 ; stack space stack e equ 14 ; select disk curdsk equ 25 ; current disk gtaloc equ 27 ; get aate all registers pop b pop d pop h ret ; return to caller Seattle, Washington 98168 ; ; ; ;The bitmap idea is based upon Ward Christensen's original ; bitmap program, which refuse another inlprt2 xthl ; orig HL...sp at end of msg ret ; return to end of msg qu $ ; our own stack oldsp ds 2 ; old stack from ccp ; inlprt: llocation address dskpar equ 31 ; get disk parameters fcb equ base+5ch ; file control block ; crlf call inlprt ; use in line print db 0dh,0ah,'$' ; ...for cr & lf ret d to run on 2.0+ systems. ; After giving his program a quick going over with SID, I ; decided it would be easier to rewrite ; conout push h ; single character console push d ; ...output; 1st save all  ; in line print xthl ; HL to stack...pointer to HL inlprt1 mov a,m ; get a charact4  ; return to caller ; one push psw ; save Acc mvi a,'1' ; print a '1' to co ; direct return to CCP ; ;We need a little internal storage ; drive ds 1 ; current drive aldrv dd b xchg mov a,h ora l cnz bndec2 mov a,e adi '0'  lda drive ; get drive to bitmap mvi c,sdsk ; set call for disk select mov e, h pop psw ; restore Acc ret ; return to caller ; ;Binary to decimalprint db 'BITMAP 2.2 AS OF ' db '7/11/80',0dh,0ah,0dh,0ah,'$' mvi c,curdsk ; nsole call conout ; do it pop psw ; restore Acc ret ;s 1 ; alternate specified drv dpb ds 2 ; disk parameter block add tbtr ds 2  call conout pop h pop d pop b ret ; err1 call inlprt a ; bdos wants it in E call bdos ; let bdos do it mvi c,dskpar ; we want  output routine. Enter with 8 bit binary ;number in . Second entry at BNDEC2 assumes 16 bit nb. in ; bndec1 mvi get current disk in call bdos ; ...use from bdos sta drive ; save it lda  return to caller ; zero push psw ; save Acc mvi a,'0' ; print a '0' to console  ; total bits to read alloc ds 2 ; allocation address blksiz ds 1 ; bloc ; in line print db 0dh,0ah,'Nonstandard disk ' db 'parameter block error' db 0dh,0ahdsk parameter blk call bdos ; get it, and..... shld dpb ; ...save it lxih,0 mov l,a ; now has number ; bndec2 push b push d push h l aldrv ; get any alternate drv ora a ; any specified? jz dpblk ; call conout ; do it push h ; save lhld free ; get nb of frk size code free dw 0 ; count of free blocks ; ;The actual start of it all ; start lda fcb ,'$' ; finis lhld oldsp ; get CCP sp sphl ; retore it ret  d,5 ; offset for total blks used dad d ; add it to HL mov e,m xi b,-10 lxi d,-1 bndc dad b inx d jc bndc lxi b,10 da if not, skip next dcr a ; less one sta drive ; save as drive to use ; dpblkee blocks inx h ; add one free shld free ; store total free count pop ; get any alternate drv sta aldrv ; save it for later call inlprt ; in line 5  ; lsb into E inx h ; point to msb mov d,m ; get it xchg  bdos ; let bdos do it mvi c,gtaloc ; get the allocation address call bdos  ; less block size code count jnz lp ; loop till = 0 call bndec2 ; print siz ; restore bit pattern dcr c ; decrement line count jz bmap ; new ; nonstandard size cpi 1 ; check for less than 1 jc err1 ; nonstandard size mvi b,8 ; it has 8 bits bmap2 rlc ; runn'em through carry cc one  ; put it in HL... inx h ; alloc size = (dsm/8)+1 shld tbtr ; ...and ; ...from bdos pop d ; tbtr from stack dcx h ; back allocation up one e in K ; dpbend call inlprt ; finish message db ' bytes per block',0dh,0ah,'$' lhld tbt line if zero dcr b ; decrment bit count jz bmap1 ; new byte if zero  push psw ; save it call inlprt ; in line print db 'Allocated disk bl ; carry set = print '1' cnc zero ; carry not set = print '0' dcx d  save it lhld dpb ; get dsk parameter blk add inx h ; ...and increment HL to ; ; ;We now have the total number of bits to read in DE, and ; the address to start reading them at in HL for the ; properr ; total bits to read push h ; save it in the stack lda drive ; aga jmp bmap2 ; finish this byte ; bmapend pop psw ; not neccessary, but keeps the call ock size is $' pop psw ; get block size back sta blksiz ; save it for end  ; decrement bit count push psw ; save the bit pattern mov a,d ; check to see i inx h ; ...the 3rd byte mov a,m ; it has the block size sui 2  drive. So now let's print the bitmap. ; ; bmap mvi c,48 ; 1's and 0's per line call crlf in to be safe mov e,a ; into E for bdos mvi c,sdsk ; reselect disk call  crlf ; ...stack straight..send cr,lf call crlf lda drive ;get drive used  lxi h,512 ; set 1/2k counter lp dad h ; multiply * 2=1024 dcr a f... ora e ; ...DE = 0 jz bmapend ; if so, we're finished pop psw  ; it will be 3-7 (make it 1-5) cpi 5+1 ; check for over 5 jnc err1  ; followed by a cr,lf bmap1 inx h ; kick the pointer mov a,m ; get the byte 6  adi 'A' call conout call inlprt db ': R/W, Space: $' lda blksiz KIP FLAG FOR LST CP 'N' JR Z,CPYF1 ;IF N,SKIP THE SRC LIST CP 'B' ;PUT ON DRIVE B? JR NZ,DOIT ;NO,PUT LISTING ON DRIL ;SAVE POINTER PUSH AF ; CP 'Q' ;QUIT ? CALL Z,FLUSH ;YES,FLUSH BUFFERS POP AF PUSH AF ; CP '1' ;PASS 1? NCTION CALL CPM CALL GETCON ;WAIT FOR KEYSTROKE TO EXIT JP BOOT ; NFMSG: DEFB CR DEFB LF DEFM 'NO SOURCE FILE FOUNPOP BC PUSH BC CALL MOVFCB ; LD DE,HEXFN POP BC ; MOVFCB: LD HL,DFCB+1 ;FILE NAME STARTS IN POS 1 LDIR RET ; P ; get block size code lhld free ; get nb of free blocks lp1 dcr a jz don VE A LD A, 2 ;B IS DRIVE 2 LD (LSTFCB),A ;SET DRIVE BYTE TO 'B' JR DOIT CPYF1: LD (DE),A ;SKIP IT DOIT: INC HL ;POJR Z,PAS1 CP '2' ;PASS 2? JP Z,PAS2 CP '3' ;PASS 3? JP Z,PAS3 CP '4' ;PASS 4 USES CONSOLE OUTPUT JR Z,PD' DEFB CR DEFB LF DEFM '$' ; PAS2: LD A,(HEXOPN) ;HEX FILE OPEN FROM PREV? CP 'O' CALL Z,FLUSH ;YES,FLUSH AND CLOAS1: XOR A ;MAKE SURE OPEN FIRST LD (SRCFCB+12),A ; EXTENT LD DE,SRCFCB LD C,OPNFIL CALL CPM CP 0FFH ;SUCESSFUL ; multiplied by size of block dad h ; times 2 jmp lp1 ; don call bndec2 INT TO HEX SWITCH INC DE ;POINT TO PASS 3 FLAG LD A,(HL) ;GET DRIVE/SKIP FOR HEX CP 'N' ;SKIP? JR Z,CPYF2 ;IF Z,SKAS1 INPRET: POP AF ;IF NONE OF ABOVE,EXIT JR GENRET ; NXTPAS: DEFW SEQNO ;SEQUENCE # POINTER SEQNO: DEFM '1423Q' ;DSE ; LD DE,LSTFCB ;OPEN LISTING FILE CALL OPNOUT CP 0FFH ;SUCESSFUL? JR Z,DSKERR ;NO,ERROR MSG LD A,'O' LD (LS? JR Z,NOSRC ; NO,LET US KNOW LD A,'O' ; DECLARE OPEN LD (SRCOPN),A XOR A ;FIRST RECORD IS #0 LD (SRCFCB+32),A  ; print size of free space call inlprt db 'k',0dh,0ah,'$' jmp finis ; resIP CP 'B' ;PUT ON DRIVE B? JR NZ,COPYIT ;IF NOT 'B' NO LD A,2 ;B IS DRIVE 2 LD (HEXFCB),A JR COPYIT CPYF2: LD (DEFAULT SEQUENCE CPYFCB: LD HL,DFCB+9 ;POINT TO FILE EXTENSION LD DE,SEQNO+2 ;POINT TO PASS 2 FLAG LD A,(HL) ;GET DRIVE/STOPN),A ;DECLARE OPEN XOR A ;START WITH RECORD 0 LD (LSTFCB+32),A LD HL,LSTBUF ;DECLARE EMPTY LD (LSTPTR),HL JR PATE FCB'S LD HL,(NXTPAS) ;POINT TO PASS SEQUENCE LD A,(HL) ;GET NEXT PASS NUMBER INC HL ;UPDATE POINTER LD (NXTPAS),H LD HL,SRCBUF+1024 LD (SRCPTR),HL JR INPRET ; NOSRC: LD DE,NFMSG ;NO FILE MESSAGE ERROUT: LD C,PRBUF ;PRINT STRING FUtore things and GET OUT ; end E),A ;DON'T DO IT COPYIT: LD BC,8H ;SETUP FOR LDIR ; LD DE,SRCFN ;DESTINATION PUSH BC CALL MOVFCB ; LD DE,LSTFN 7 S1 ;GO OPEN SRC ; DSKERR: LD DE,ERRMSG JR ERROUT ;GOTO ERROR OUTPUT RTN ; ERRMSG: DEFB CR DEFB LF DEFM 'DISK ERROD (HL),'C' ;DECLARE CLOSED RET ; FLBUF: PUSH BC ;B=#RECS,C=CHAR PUSH HL ;HL=BUFFER POINTER PUSH DE ;DE=FCB PTR ; ARE RECORDS TO WRITE POP BC ;ELSE EXIT RET ; AREREC: LD B,7 ;B = SHIFT COUNTER DIV128: SRL H ; BYTES/128 = # RECORDTBUF+1025)/256 ;FULL? JR Z,DMPLST ;YES,FLUSH ; LSTCHR: LD (HL),C ;STORE CHAR IN I/O BUFFER INC HL ;UPDATE POINTER LO' ; IF O,YES RET NZ ; NO OPEN OUTPUT FILES,EXIT ; LD DE,LSTBUF ;DE POINTS TO START LD HL,(LSTPTR) ;HL POINTS TO CU,DMPHEX ;IF Z,BUFFER FULL ; HEXCHR: LD (HL),C INC HL ;NOT FULL,JUST STORE CHAR LD (HEXPTR),HL JP GENRET ; DMPHEX: R,ASSEMBLY ABORTED' DEFB CR DEFB LF DEFM '$' ; PAS3: LD A,(LSTOPN) ;LIST STILL OPEN? CP 'O' CALL Z,FLUSH ;YES,FLUSEX DE,HL ;DE NOW = BUFFER PTR LD C,SETDMA CALL CPM ;DMA NOW = BUFFER ; POP DE ;GET FCB PTR BACK PUSH DE LD C,WRNR S RR L DJNZ DIV128 ;LOOP TIL DONE ; LD B,L ;B = # RECORDS OR A ;FIND IF EVEN RECORD AGAIN JR Z,EVNREC ; ID (LSTPTR),HL JP GENRET ; DMPLST: PUSH BC LD B,8 ;BUFFER = 8 RECORDS LD HL,LSTBUF ;START AT BEGINNING LD DE,LSTFCB RRENT CHAR LD BC,LSTFCB ;NEED FCB PTR FOR CP/M JR MTBUF ; HEXFL: LD DE,HEXBUF ;COMMENTS AS FOR LST FILE LD HL,(HEXPTPUSH BC ;SAVE CHAR LD B,8 ;8 RECORD BUFFER LD HL,HEXBUF ;SETUP FOR FLBUF LD DE,HEXFCB CALL FLBUF ; POP BC ;GET CH AND CLOSE LD DE,HEXFCB CALL OPNOUT ;OPEN HEX FILE FOR OUTPUT CP 0FFH ;SUCESS? JR Z,DSKERR ;NO,ABORT ; LD A,'O' ;WRITE NEXT REC FUNCTION CALL CPM ; OR A ;SET FLAGS JP NZ,DSKERR ; POP DE POP HL POP BC ; DEC B RET Z ;INC B ;DON'T WANT TO LOSE PARTIAL EVNREC: EX DE,HL ;HL = BUFFER POINTER POP DE ;DE = FCB POINTER ; CALL FLBUF ;WRITE B ;FCB FOR CP/M CALL FLBUF ; POP BC ;GET THIS OUTPUT CHAR BACK LD HL,LSTBUF ;RESTART AT BEGINNING JR LSTCHR ; RDRIR) LD BC,HEXFCB ; MTBUF: LD A,L ;FIND IF ON RECORD BOUNDARY AND 127 JR Z,MTBUF2 ;IF Z,YES LD (HL),CTLZ ;PUT ^Z ASHAR BACK LD HL,HEXBUF ;START AT BEGINNING AGAIN JR HEXCHR ; LSTO: PUSH BC PUSH DE PUSH HL LD A,(PASSNO) ;GET CUR LD (HEXOPN),A ;DECLARE OPEN XOR A LD (HEXFCB+32),A LD HL,HEXBUF ;DECLARE EMPTY LD (HEXPTR),HL JP PAS1 ;GO OPEF Z,ALL RECORDS WRITTEN ; LD A,L ADD A,128 ;UPDATE DATA POINTER LD L,A JR NC,FLBUF INC H JR FLBUF ; PCHOUT: UFFER TO DISK LD C,CLSFIL ;CLOSE FUNCTION PUSH DE CALL CPM POP DE LD HL,38 ;(DE+38) = FILE OPEN FLAG ADD HL,DE LN: PUSH BC PUSH DE PUSH HL LD HL,(SRCPTR) ;GET SRC POINTER LD A,H CP (SRCBUF+1025)/256 ;PAST END? JR Z,SRCRD ; EOF MARK ; MTBUF2: PUSH BC ;SAVE FCB PTR OR A ;CLEAR CARRY SBC HL,DE ;CALC # BYTES IN BUFFER JR NZ,AREREC ;IF NZ,RENT PASS CP 4 ;IS IT PASS 4 ? JP Z,OUT4 ;IF YES,OUTPUT TO CONSOLE LD HL,(LSTPTR) ;NO,OUTPUT TO .PRN LD A,H CP (LSN SRC ; FLUSH: LD A,(HEXOPN) ;HEX FILE OPEN? CP 'O' ; IF O,YES JR Z,HEXFL ; LD A,(LSTOPN) ;LIST FILE OPEN? CP 'PUSH BC PUSH DE PUSH HL LD HL,(HEXPTR) ;BUFFER POINTER LD A,H ;GET HIGH ORDER CP (HEXBUF+1025)/256 ;FULL? JR Z8 YES,GO GET MORE ; NXTCHR: LD A,(HL) ;GET CHAR INC HL LD (SRCPTR),HL ;SAVE POINTER JP GENRET ; SRCRD: LD BC,0880H ;BFLAG ; BIT 2 - SYMB TABLE O/F FLAG OBJCNT: DEFS 1 ; NO OF BYTES IN OBJ BUFF RECADR: DEFS 2 ; TARGET ADDR OF 1ST BYTEER ASCDNO: DEFS 1 ; NO. OF BYTES OF ASSEMBLED CODE ASSCOD: DEFS ACBSIZ ; ASSEMBLED CODE BUFFER TITBUF: DEFS TITSIZ+1 ; T> M: 9 ; $* |):$o5|g}o" B K0_2h2|:%ª>2%!\&STORAGE AREA. ;********************************************************************** MEMTOP: DEFS 2 ; HIGHEST AVAILABLE RAMBOL TABLE HERE TO MEMTOP END DARY ; SRCBUF: DEFS 1024 LSTBUF: DEFS 1024 HEXBUF: DEFS 1024 ; SYMTAB: DEFS 0 ; SYM=#RECS,C=BYTES/REC LD DE,SRCBUF ;DESTINATION ; NXTREC: PUSH DE PUSH BC LD C,SETDMA CALL CPM ; LD DE,SRCFCB LD C, OF RECORD STADDR: DEFS 2 ; START ADDR BUFFER FOR 'END' OPD OBJBUF: DEFS RECSIZ ; OBJECT CODE BUFFER FTOKR: DEFS 1 ; FUITLE BUFFER SYMEND: DEFS 2 ; POINTER TO END OF SYMBOL TABLE ORTKBF: DEFS 2 ; OPERATOR TOKEN BUFFER TEMP: DEFS 2 ; DUMMY :\22!&\ \!2\ \!&\ \<7=Ɓo&3 ]  LOC. ADDR PASSNO: DEFS 1 ; PASS NUMBER LINPNT: DEFS 2 ; POINTER TO LINE BUFFER LINBUF: DEFS LBFSZ ; LINE BUFFER LABBURDNR ;READ NEXT RECORD CALL CPM ; POP BC POP DE CP 1 ;1 MEANS FILE DONE JR Z,SRCDON ; LD A,E ;UPDATE DESTINNCTION TOKEN REGISTER FCNT: DEFS 1 ; FUNCTION STACK COUNTER FSTK: DEFS MAXFSK ; START OF FUNCTION STACK ARCNT: DEFS 1 ; LOCATION ODBT1: DEFS 1 ; OPERAND-1 TOKEN BUFFER ODBT2: DEFS 1 ; OPERAND-2 TOKEN BUFFER ODINT1: DEFS 2 ; OPERAND-1 VALU 2h2|~# x  *~):F: DEFS 7 ; LABEL BUFFER SYMBUF: DEFS 10 ; SYMBOL BUFFER PAGE: DEFS 2 ; PAGE NO. (BCD) LINE: DEFS 1 ; LINE NUMBER ERCRCK ver 3.0 8/3/80 !9"~1~5CRCK ver 3.0 $ ZL:f;TDONE$!]z !e ͏--> FILE: XXXXXXATION ADD A,C LD E,A JR NC,DOK INC D DOK: DEC B ;DONE 8 RECORDS? JR NZ,NXTREC ;NO,CONTINUE ; SRCDON: LD HL,SR ARITHMETIC STACK COUNTER ARSTK: DEFS MAXASK ; ARITHMETIC STACK DEFS STKSIZ STACK: DEFS 0 ; STACK FROM HERE BACK ^ ; E ODINT2: DEFS 2 ; OPERAND-2 VALUE AFLAGS: DEFS 1 ; ASSEMBLY FLAGS ; BIT 0 - ADDR DISCONT. FLAG ; BIT 1 - END RBUF: DEFS 1 ; ERROR INDICATOR BUFFER ADREFC: DEFS 2 ; ADDRESS REFERENCE COUNTER ADDISR: DEFS 2 ; ADDRESS DISPLAY REGISTXX.XXX CRC = $ \<¶ ++OPEN FAILED++$!" !""*"| \!~2$#"":!9CBUF ;START AT BEGINNING JR NXTCHR ; ; ; ;********************************************************************** ;RAM ORG 1F00H ; MUST START ON PAGE BOUNDARY ; SRCBUF: DEFS 1024 LSTBUF: DEFS 1024 HEXBUF: DEFS 1024 ; SYMTAB: DEFS 0 ; SYM9 ally in machine language. The assembler is quite good providing all the features of Zilog's assembler except for mac--> FILE: 2USRDISK.DOC CRC = 08 9D --> FILE: 2USRDISK.CRC CRC = 00 00 DONEros, conditional assembly and lower case. It was written to be used with cassette or paper tape, with the desired pass: MDIR .COM CRC = 8F B7 --> FILE: SCBIOS .MAC CRC = B2 04 --> FILE: COPY .COM CRC = F7 99 --> FILE: CROWE 5826 Southwest Ave. St.Louis, MO 63139 April 18, 1982 FILES --------------------------------------------ros, conditional assembly and lower case. It was written to be used with cassette or paper tape, with the desired pass 5826 Southwest Ave. St.Louis, MO 63139 April 18, 1982 FILES -------------------------------------------- number entered from the console. For each pass, the source is re-read and the appropriate output generated. Pass 1 buLET.TXT CRC = 23 BA --> FILE: COPY .ASM CRC = 34 47 --> FILE: COPY .DOC CRC = BE 05 --> FILE: BITMAP .COM ------------------------ CROWLINK: These are the linkages between CP/M and the Crowe Z-80 assembler. I bought this asseCRCK ver 3.0 --> FILE: CROWE3 .COM CRC = A0 09 --> FILE: CROWE3 .Z80 CRC = EC 24 --> FILE: DKCOPY .ASM CRC = E number entered from the console. For each pass, the source is re-read and the appropriate output generated. Pass 1 bu------------------------ CROWLINK: These are the linkages between CP/M and the Crowe Z-80 assembler. I bought this asseilds the symbol table and is required. Pass 2 outputs the assembly listing, pass 3 writes Intel format hex object and pa CRC = 49 B8 --> FILE: SBIOS .DOC CRC = 55 E2 --> FILE: CRCK3 .COM CRC = C5 45 --> FILE: SBOOT22 .HEX CRC = 6mbler two years ago from Byte Nybbles for $4! It was available only as an assembly listing and so I entered it manuC 11 --> FILE: DKCOPY .COM CRC = 48 3B --> FILE: DKCOPY .DOC CRC = C2 D9 --> FILE: BMAP7/11.ASM CRC = 37 8B ilds the symbol table and is required. Pass 2 outputs the assembly listing, pass 3 writes Intel format hex object and pambler two years ago from Byte Nybbles for $4! It was available only as an assembly listing and so I entered it manuss 4 gives an assembly listing of those lines containing errors on the console. The linkage routines are written so 9 03 --> FILE: SBOOT14 .HEX CRC = 56 EB --> FILE: SCBIOS22.HEX CRC = 30 A4 --> FILE: SCBIOS14.HEX CRC = 1D 46 ally in machine language. The assembler is quite good providing all the features of Zilog's assembler except for mac--> FILE: EXAF .Z80 CRC = 6F C0 --> FILE: CROWLINK.Z80 CRC = 34 A7 --> FILE: SBOOT .MAC CRC = E5 72 --> FILEss 4 gives an assembly listing of those lines containing errors on the console. The linkage routines are written so :  TITLE 'Z80-ASSEMBLER TO CP/M LINKAGES' ; ; EQUATE TABLE ; CR EQU 13 LF EQU 10 ENTRY EQU 5 ;FDOS ENTRY BOOT EQU 0 ;WAR POINT FOR ALL PASSES SO DO PUSH HL ; SETUP HERE ; LD A, (SRCOPN) ;IS SRC OPEN? CP 'O' CALL NZ, CPYFCB ;IF NOT, CREAFM ' ' DEFM 'HEX' DEFS 21 HEXPTR DEFS 2 HEXOPN DEFM 'C' ; MEMCHK LD A, 0FFH ;MAX MEM = 23FFH LD B, 23H RET  ; LD DE, HEXFN POP BC ; MOVFCB LD HL, DFCB+1 ;FILE NAME STARTS IN POS 1 LDIR RET ; PASS1 XOR A ;MAKE SURE OPEN JP CONOUT JP LSTO JP RDRIN JP PCHO JP MEMCHK JP BOOT ; ORG 2400H ;PUT ABOVE SYMBOL TABLE ; SRCFCB DEFB 0 ;FCB S1423Q' ;DEFAULT SEQUENCE CPYFCB LD HL, DFCB+9 ;POINT TO FILE EXTENSION LD DE, SEQNO+2 ;POINT TO PASS 2 FLAG LD A, 'N' M START SETDMA EQU 26 ;CP/M FUNCTION NUMBER OPNFIL EQU 15 ;OPEN FILE CLSFIL EQU 16 ;CLOSE FILE DELFIL EQU 19 ;DELETE FILTE FCB'S LD HL, (NXTPAS) ;POINT TO PASS SEQUENCE LD A, (HL) ;GET NEXT PASS NUMBER INC HL ;UPDATE POINTER LD (NXTPAS); CONOUT PUSH BC ;NO REGISTERS MAY BE DESTROYED PUSH DE PUSH HL OUT4 LD A,C CALL PUTCON ; GENRET POP HL ;GENERAL REFIRST LD (SRCFCB+12), A ; EXTENT LD DE, SRCFCB LD C, OPNFIL CALL ENTRY CP 0FFH ;SUCESSFUL? JR Z, NOSRC ; NO,TARTS WITH 0 SRCFN DEFM ' ' ;RESERVE 8 CHARS FOR FILE NAME DEFM 'Z80' ;USE EXTENSION OF Z80 DEFS 21 ;21 BYTES FOR ;IF N, SKIP PASS CP (HL) ;SKIP IT? JR NZ DOIT ;NO, DO LISTING LD (DE), A ;SKIP IT DOIT INC HL ;POINT TO HEX SWITCH E MAKFIL EQU 22 ;CREATE FILE RDNR EQU 20 ;READ NEXT RECORD WRNR EQU 21 ;WRITE NEXT RECORD PRBUF EQU 9 ;PRINT STRING DFC, HL ;SAVE POINTER PUSH AF ; CP 'Q' ;QUIT ? CALL Z FLUSH ;YES, FLUSH BUFFERS POP AF PUSH AF ; CP '1' ;PASS 1TURN FOR ALL SUBR'S POP DE POP BC RET ; ; OPNOUT PUSH DE ;OPEN (DE) FCB FOR OUTPUT LD C, DELFIL ;FIRST DELETE CURR LET US KNOW LD A, 'O' ; DECLARE OPEN LD (SRCOPN), A XOR A ;FIRST RECORD IS #0 LD (SRCFCB+32), A LD HL, SRCBUF+1024CP/M SRCPTR DEFS 2 ;FOR CHARACTER POINTER SRCOPN DEFM 'C' ;DECLARE CLOSED ; LSTFCB DEFB 0 ;LISTING FILE SETUP LSTFN DEFM INC DE ;POINT TO PASS 3 FLAG CP (HL) ;SKIP IT? JR NZ COPYIT ;NO, DO HEX FILE LD (DE), A ;DON'T DO IT COPYIT LD BCB EQU 5CH ;CP/M DEFAULT FCB DEFBUF EQU 80H ;CP/M DEFAULT I/O ADDR PASSNO EQU 1B03H ;CURRENT PASS NO. ; GETCON EQU 0F009H ? JR Z, PASS1 CP '2' ;PASS 2? JP Z, PASS2 CP '3' ;PASS 3? JP Z, PASS3 CP '4' ;PASS 4 USES CONSOLE OUTPUTENT CALL ENTRY POP DE LD C, MAKFIL ;THEN RE-CREATE JP ENTRY ; CONIN PUSH BC ;CONSOLE INP IS ONLY COMMON PUSH DE ; LD (SRCPTR), HL JR INPRET ; NOSRC LD DE, NFMSG ;NO FILE MESSAGE ERROUT LD C, PRBUF ;PRINT STRING FUNCTION CALL EN ' ' DEFM 'PRN' ;PRINT FILE DEFS 21 LSTPTR DEFS 2 LSTOPN DEFM 'C' ; HEXFCB DEFB 0 ;SAME FOR HEX FILE HEXFN DE, 8H ;SETUP FOR LDIR ; LD DE, SRCFN ;DESTINATION PUSH BC CALL MOVFCB ; LD DE, LSTFN POP BC PUSH BC CALL MOVFCB ;MONITOR CONSOLE INPUT PUTCON EQU 0F00CH ;MONITOR CONSOLE OUTPUT CTLZ EQU 1AH ;^Z = EOF MARK ; ; ORG 102H JP CONIN  JR Z, PASS1 INPRET POP AF ;IF NONE OF ABOVE, EXIT JR GENRET ; NXTPAS DEFW SEQNO ;SEQUENCE # POINTER SEQNO DEFM '; TRY CALL GETCON ;WAIT FOR KEYSTROKE TO EXIT JP BOOT ; NFMSG DEFB CR DEFB LF DEFM 'NO SOURCE FILE FOUND' DEFB CR DNZ, AREREC ;IF NZ, ARE RECORDS TO WRITE POP BC ;ELSE EXIT RET ; AREREC LD B, 7 ;B = SHIFT COUNTER DIV128 SRL H ; N? CP 'O' ; IF O, YES RET NZ ; NO OPEN OUTPUT FILES, EXIT ; LD DE, LSTBUF ;DE POINTS TO START LD HL, (LSTPTR) ;HL HIGH ORDER CP 34H ;FULL? JR Z, DMPHEX ;IF Z, BUFFER FULL ; HEXCHR LD (HL),C INC HL ;NOT FULL, JUST STEMBLY ABORTED' DEFB CR DEFB LF DEFM '$' ; PASS3 LD A, (LSTOPN) ;LIST STILL OPEN? CP 'O' CALL Z, FLUSH ;YES, FLUSH FER POINTER PUSH DE ;DE=FCB PTR ; EX DE, HL ;DE NOW = BUFFER PTR LD C, SETDMA CALL ENTRY ;DMA NOW = BUFFER ; POP EFB LF DEFM '$' ; PASS2 LD A, (HEXOPN) ;HEX FILE OPEN FROM PREV? CP 'O' CALL Z, FLUSH ;YES, FLUSH AND CLOSE ; LD DEBYTES/128 = # RECORDS RR L DJNZ DIV128 ;LOOP TIL DONE ; LD B, L ;B = # RECORDS OR A ;FIND IF EVEN RECORD AGAIN  POINTS TO CURRENT CHAR LD BC, LSTFCB ;NEED FCB PTR FOR CP/M JR MTBUF ; HEXFL LD DE, HEXBUF ;COMMENTS AS FOR LST FILE ORE CHAR LD (HEXPTR), HL JP GENRET ; DMPHEX PUSH BC ;SAVE CHAR LD B, 8 ;8 RECORD BUFFER LD HL, HEXBUF ;SETUP FOR FAND CLOSE LD DE, HEXFCB CALL OPNOUT ;OPEN HEX FILE FOR OUTPUT CP 0FFH ;SUCESS? JR Z, DSKERR ;NO, ABORT ; LD A, 'DE ;GET FCB PTR BACK PUSH DE LD C, WRNR ;WRITE NEXT REC FUNCTION CALL ENTRY ; OR A ;SET FLAGS JP NZ, DSKERR ; , LSTFCB ;OPEN LISTING FILE CALL OPNOUT CP 0FFH ;SUCESSFUL? JR Z, DSKERR ;NO, ERROR MSG LD A, 'O' LD (LSTOPN),A  JR Z, EVNREC ; INC B ;DON'T WANT TO LOSE PARTIAL EVNREC EX DE, HL ;HL = BUFFER POINTER POP DE ;DE = FCB POINTER ;  LD HL, (HEXPTR) LD BC, HEXFCB ; MTBUF LD A, L ;FIND IF ON RECORD BOUNDARY AND 127 JR Z, MTBUF2 ;IF Z, YES LD (HLLBUF LD DE, HEXFCB CALL FLBUF ; POP BC ;GET CHAR BACK LD HL, HEXBUF ;START AT BEGINNING AGAIN JR HEXCHR ; LSTOO' LD (HEXOPN),A ;DECLARE OPEN XOR A LD (HEXFCB+32), A LD HL, HEXBUF ;DECLARE EMPTY LD (HEXPTR), HL JP PASS1 ;POP DE POP HL POP BC ; DEC B RET Z ;IF Z, ALL RECORDS WRITTEN ; LD A, L ADD A, 128 ;UPDATE DATA POINTER LD L,;DECLARE OPEN XOR A ;START WITH RECORD 0 LD (LSTFCB+32), A LD HL, LSTBUF ;DECLARE EMPTY LD (LSTPTR), HL JR PASS1  CALL FLBUF ;WRITE BUFFER TO DISK LD C, CLSFIL ;CLOSE FUNCTION PUSH DE CALL ENTRY POP DE LD HL, 35 ;(DE+35) = FILE), CTLZ ;PUT ^Z AS EOF MARK ; MTBUF2 PUSH BC ;SAVE FCB PTR OR A ;CLEAR CARRY SBC HL, DE ;CALC # BYTES IN BUFFER JR  PUSH BC PUSH DE PUSH HL LD A,(PASSNO) ;GET CURRENT PASS CP 4 ;IS IT PASS 4 ? JP Z, OUT4 ;IF YES, OUTPUT TO CONSOLGO OPEN SRC ; FLUSH LD A, (HEXOPN) ;HEX FILE OPEN? CP 'O' ; IF O, YES JR Z, HEXFL ; LD A, (LSTOPN) ;LIST FILE OPE A JR NC, FLBUF INC H JR FLBUF ; PCHO PUSH BC PUSH DE PUSH HL LD HL, (HEXPTR) ;BUFFER POINTER LD A,H ;GET ;GO OPEN SRC ; DSKERR LD DE, ERRMSG JR ERROUT ;GOTO ERROR OUTPUT RTN ; ERRMSG DEFB CR DEFB LF DEFM 'DISK ERROR, ASS OPEN FLAG ADD HL, DE EX DE, HL LD (HL), 'C' ;DECLARE CLOSED RET ; FLBUF PUSH BC ;B=#RECS, C=CHAR PUSH HL ;HL=BUF< E LD HL, (LSTPTR) ;NO, OUTPUT TO .PRN LD A, H CP 30H ;FULL? JR Z, DMPLST ;YES, FLUSH ; LSTCHR LD (HL), C ;STORE  COLD START LOADER FOR CP/M V2.2 -- * ;* * ;* Russell Smith 7-October-80 * ;* Modified 1/20/82 * ;******** ;I/O BUFFERS SRCBUF DEFS 1024 LSTBUF DEFS 1024 HEXBUF DEFS 1024 ; END D BC,0C03H CALL RDLOOP ;READ ODD SECTORS ON TRK 0 LD C,1 ;LOAD C WITH TRACK# CALL MONITR+33 ;CALL MONITOR SEEK ROUTINE HL ;SAVE POINTER JP GENRET ; SRCRD LD BC, 0880H ;B=#RECS, C=BYTES/REC LD DE, SRCBUF ;DESTINATION ; NXTREC PUSH DE PE800 CCP EQU 3400H+BASE ;This is what DRC is shipping CBIOS EQU 4A00H+BASE ;BASE OF CUSTOM BIOS endif ;CHAR IN I/O BUFFER INC HL ;UPDATE POINTER LD (LSTPTR), HL JP GENRET ; DMPLST PUSH BC LD B, 8 ;BUFFER = 8 RECORDS ************************************************ ; ;Modifications ; 1-20-82 Add switch for 1.4 and syntax for M80 ; CPM14  JR NZ,ERROR LD HL,CCP+0C80H LD BC,0D01H CALL RDLOOP ;READ ODD SECTORS ON TRK 1 LD HL,CCP+0D00H LD BC,0D02H CALL RUSH BC LD C, SETDMA CALL ENTRY ; LD DE, SRCFCB LD C, RDNR ;READ NEXT RECORD CALL ENTRY ; POP BC POP DE CP 1  ; ; ASEG ORG 900H ;Load address for sysgen .PHASE 128 ;execution address ;  LD HL, LSTBUF ;START AT BEGINNING LD DE, LSTFCB ;FCB FOR CP/M CALL FLBUF ; POP BC ;GET THIS OUTPUT CHAR BACK LD HL, EQU 1 ;Assemble for V1.4(0 for 2.2) ; MSIZE EQU 60 ;MEMORY CAPACITY IN KBYTES MONITR EQU 0F000H ;BASE ADLOOP ;READ EVEN SECTORS ON TRK 1 ; JP CBIOS ;JUMP TO CP/M COLD START ENTRY ; ; RDLOOP: PUSH HL ;SAVE PARAMETERS PUS ;1 MEANS FILE DONE JR Z, SRCDON ; LD A, E ;UPDATE DESTINATION ADD A, C LD E, A JR NC, DOK INC D DOK DEC B  START: JR BOOT ; if CPM14 DEFM '59K CP/M V1.4 ' else DEFM '60K CP/M V2.2 ' endif ;  LSTBUF ;RESTART AT BEGINNING JR LSTCHR ; RDRIN PUSH BC PUSH DE PUSH HL LD HL, (SRCPTR) ;GET SRC POINTER LD A, HDDRESS OF MONITOR if CPM14 EXTRA EQU MSIZE-20 BASE EQU EXTRA*1024 CCP EQU 3500H+ title Cold Start Loader (1/20/82) .z80 ;******************************************************** ;* * ;* -- H BC CALL MONITR+36 ;CALL MONITOR DISK READ ROUTINE POP BC POP HL JR NZ,ERROR ;READ ERROR IF Z FLAG SET INC H ;BUMP D ;DONE 8 RECORDS? JR NZ, NXTREC ;NO, CONTINUE ; SRCDON LD HL, SRCBUF ;START AT BEGINNING JR NXTCHR ; ; ORG 2800H PAGE BOOT: LD E,0 ;LOAD E WITH TRACK# LD HL,CCP LD BC,0D02H CALL RDLOOP ;READ EVEN SECTORS ON TRK 0 LD HL,CCP+80H L CP 2CH ;PAST END? JR Z, SRCRD ;YES, GO GET MORE ; NXTCHR LD A, (HL) ;GET CHAR INC HL LD (SRCPTR), BASE CBIOS EQU 4A00H+BASE else EXTRA EQU MSIZE-20 BASE EQU EXTRA*1024-200H ;Use the -200H only if you org at = ATA POINTER BY 256 INC C INC C ;BUMP SECTOR# BY 2 DJNZ RDLOOP RET ; ; ERROR: LD HL,MSG ;POINT TO ERROR MESSAGE PMS#V|ʋn*"|¢}?>2*>^#V|o*"|}ªo_ | UU ~&o:<2))))V*!s#r*!s#rÓ|g}oSSSS S S SS,~u# U~lu#`_ _ G: LD A,(HL) CALL MONITR+9 ;OUTPUT TO MONITOR CONSOLE LD A,(HL) INC HL OR A ;CHECK FOR END OF STRING JR NZ,PMSG ;PRo#}:dd|&}1> uP |=}I_ P_ *"͋>ku*"_Drive :u!9"1:]2 !!] 6?# >?2h:\3<@2n2!"!"s# yP\++NOT FOUND$\  ڔ |ċ{0u ~w#ïINT ANOTHER BYTE OF NOT JP MONITR+3 ;JUMP BACK TO MONITOR MSG: DEFM ' LOAD ABORTED' DEFB 0 ; .DEPHASE E_: - *͋_ Files (*͋_ entries) *: yoxg͋: _k bytes remaining_k bytes matched *!oҕ$"#ͭ ~!"*^#V|*# *"ñ ##tx~# ND 1*:o=!o)"!"!**|6""""s**|T}[**|i}p/* * :<2**!s#r*"*"t!""*^#V|o*^#V|ʋ*"^#V|ʋ*>^}o"^#V"*^#V* *"Ó*^#V* *"÷**|}*^#V*^#> ;******************************************************** ;* * ;* CUSTOM BIOS FOR CP/M VERSION 1.4 and 2.2 * ;* ETURN LSTDAT EQU 8 ;List device, data LSTAC EQU 9 ;List device, control LSTINT EQU  PAGE 51 MSIZE EQU 60 ;MEMORY CAPACITY IN KBYTES MONITR EQU 0F000H ;BASE OF SYSTEM MONITOR ; ; CP/M REFERENCE  A,0Fh ; Select output mode for PIO OUT (LSTAC),A LD A,LSTINT ; Set vector in Prived heavily from BIOS by Russel Smith ;Modifications: ;X0 1-8-82 Syntax Changes for Microsoft M80 Assembler ; ICE VECTOR JP CONOUT ;PUNCH DEVICE VECTOR JP MONITR+9 ;READER DEVICE VECTOR JP HOME JP SELECT JP SEEK JP SETSEC J * ;* Mark Stieglitz * ;* * ;********************************************************  1Ch ;Vector Offset LSVLOC EQU 0FF00h+LSTINT ;Hardware vector location ; page ASEG CONSTANTS ; if CPM14 BIAS EQU (MSIZE-20)*1024 CCP EQU 3500H+BIAS BDOS EQU CCP+806H CBIOIO OUT (LSTAC),A LD BC,LSTIH ; Store handler address LD (LSVLOC),BC ; at Correct WBOOT to retain selected drive ; Add switch for CP/M 1.4 compatibility ;X1 1-11-82 Add list dev drP SETPTR JP READ JP WRITE JP LSTST ;LIST DEVICE STATUS VECTOR JP TRANS ; ; ; BOOT: XOR A LD (0003H),A ;RES .z80 title Stieglitz's Z80 CBIOS name ('CBIOS') ; cpm14 EQU 1 ;1 for version 1.4 (EQU 0 for 2.2)  if CPM14 ORG 1E80h ;sysgen load address else ORG 1F80h endif .S EQU CCP+1500H else BIAS EQU (MSIZE-20)*1024-200H ;Which is what DRC is shipping at E800 CCP EQU 3400H+BIA vector location LD A,87h ; Enable PIO interrupts OUT (LSTAC),A JR GOCPM ; ; Wiver (pioa w/ints) ;X2 1-17-82 Mod to defer drive select until actual I/O ;X3 2-09-82 Add conditional assy to ORG addresET IOBYTE TO ZEROS LD (4),A ;Initialize CP/M unit to A: LD HL,SIGNON CALL PMSG ;PRINT SIGNON MESSAGsovers EQU 'X4' ;version identifier for signon ; if1 if CPM14 .PRINTX /Assembling CBIPHASE CBIOS ; JP BOOT ;STANDARD JUMP TABLE TO JP WBOOT ;THE SUBROUTINES OF CBIOS JP MONITR+6 ;MoniS BDOS EQU CCP+806H CBIOS EQU CCP+1600H endif ; ; ;I/O Constants LF EQU 0AH ;LINE FEED CR EQU 0DH ;CARRIAGE RBOOT: LD SP,STACK LD C,0 CALL SELECT ;SELECT UNIT 0 CALL HOME ;SEEK TRACK ZERO LD HL,CCP ;Start from base of s for 2.2 ;X4 2-18-82 Add call to SELNOW in HOME to fix WBOOT problem ; if called when not already on A:. ; E LD A,0FFh ;Initialize list device LD (LSTRDY),A ; Set flag to "ready" LD OS for CPM V1.4/ else .PRINTX /Assembling CBIOS for CPM V2.2/ endif endif ; ; ;Detor console status rtn. IVECTR: JP MONITR+9 ;Monitor console input rtn. OVECTR: JP CONOUT JP LSTOUT ;LIST DEV? CP/M LD BC,0D02H CALL RDLOOP ;READ EVEN SECTORS ON TRK 0 LD HL,CCP+80h LD BC,0C03H CALL RDLOOP ;READ ODD SECT ; ; LSTOUT: LD A,(LSTRDY) ;List output routine. OR A ; Wait for device ready  DJNZ RDLOOP RET ; ; BOMB: LD HL,DEAD CALL PMSG LOOP: JR LOOP DEAD: DEFB CR,LF DEFM 'boot er$' page ;*****W 26 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT CONST. DEFB 7 ;BLOCK MASK CONST. DEFB 0 ;EXTENT MASK CONST. DEFW 242 ;MSK BUFFER=0080H LD A,(4) ;Remind CP/M of previously LD C,A ; selected drive JP CCP store users stack EI RETI PAGE ;******************************************************** ;* ORS ON TRK 0 LD C,1 CALL SEEK ;SEEK TO TRACK 1 JR NZ,BOMB LD HL,CCP+0C80h LD BC,0A01H CALL RDLOOP ;READ ODD SECTO JR Z,LSTOUT ; XOR A ; Then set device busy LD (LSTRDY),A LD A,C *************************************************** ;* * ;* Simple Character I/O Routines * ;* AX BLOCK# DEFW 63 ;MAX DIRECTORY ENTRY# DEFB 11000000B ;ALLOCATION MASK MSB DEFB 00000000B ;' ' LSB DEFW 16 ; ;Entry: B=Sector Count, C=Starting Sector, HL=Start Address ;Reads every other sector (1 sector interleve) RDLOOP* ;* DISK I/O SUBROUTINES FOR CP/M CBIOS * ;* * ;******************************************************** ; ; ; SECRS ON TRK 1 LD HL,CCP+0D00h LD BC,0902H CALL RDLOOP ;READ EVEN SECTORS ON TRK 1 ; GOCPM: LD A,0C3H ;STORE JUMP VECTORS OUT (LSTDAT),A ; and output the char RET ; ; ;List device interrupt handler. Simply sets "ready * ;******************************************************** ; CONOUT: LD A,C JP MONITR+12 ;MONITOR CONSOLE OUTPUT RTN ;CHECK SIZE DEFW 2 ;RESERVED TRACKS ; ; ; DISK PARAMETER HEADERS FOR A 4 DISK SYSTEM ; DPHTAB: DEFW SECTAB,0000H ;DPH : LD (POINTR),HL ;STORE ADDR. PASSED IN HL LD A,C LD (SECTOR),A ;STORE SECT# PASSED IN C PUSH HL PUSH BC CALL READ ;RTOR TRANSLATE TABLE FOR STANDARD ; 1 IN 6 INTERLEAVE FACTOR ; SECTAB: DEFB 1,7,13,19 DEFB 25,5,11,17 DEFB 23,3,9,15 DEF IN RAM LD (00H),A LD HL,CBIOS+3 ;JUMP TO CBIOS WARM BOOT AT 00H LD (01H),HL LD (05H),A LD HL,BDOS ;JUMP TO BDOS GOES" flag. LSTIH: LD (SAVSTK),SP ;Save users stack pointer LD SP,STACK PUSH AF LD . ; ; LSTST: LD A,(LSTRDY) ;Check List device status RET ; A=0 if not ready, else FFFOR UNIT 0 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK0,ALL0 DEFW SECTAB,0000H ;DPH FOR UNIT 1 DEFW 0000H,0000H DEAD THE SPECIFIED SECTOR POP BC POP HL JR NZ,BOMB INC H ;BUMP LOAD ADDRESS BY 256 INC C INC C ;BUMP SECTOR# BY 2 B 21,2,8,14 DEFB 20,26,6,12 DEFB 18,24,4,10 DEFB 16,22 ; ; ; DISK PARAMETER BLOCK FOR STANDARD 8" FLOPPY ; DPBLK: DEF AT 05H LD (06H),HL LD (38H),A LD HL,MONITR ;JUMP TO MONTR GOES AT 38H LD (39H),HL LD BC,0080H CALL SETPTR ;MAKE DI A,0FFh ;Set ready code into flag LD (LSTRDY),A POP AF LD SP,(SAVSTK) ;Re@ EFW DIRBUF,DPBLK DEFW CHK1,ALL1 DEFW SECTAB,0000H ;DPH FOR UNIT 2 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK2,ALL2 ;else report error CALL REPORT JR NZ,SELERR ;give up if ^C typed after msg.  C,A ; old unit and LD A,(TUNIT) ; check if same as request CP C  ;RETURN IF NO ERRORS LD C,3 ;INDICATE READ ERROR TO HANDLER CALL REPORT ;REPORT DISK ERROR TO CONSOLE JR Z,READ ;REr ;immediatly and sets the new unit number in TUNIT for the ;official select call to SELNOW in the read, write, ;and seek r),A ;Save for possible error CALL SELNOW ;Select drive SEEK1: LD A,(TRACK) ;put back in C for  DEFW SECTAB,0000H ;DPH FOR UNIT 3 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK3,ALL3 ; ; ; ; ; TRANS: EX DE,HL LD A,(UNIT) ; else retry JR SEL2 ; SELERR: POP HL ;Skip return address and return  ; RET Z ; and return if same LD (UNIT),A ;otherwise save new unit as perm. S-TRY READ IF INDICATED RET ; ; ; WRITE: CALL SELNOW LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+39 ;outines. ; SELECT: LD HL,0 ;PREP TO CHECK FOR MAX UNIT# LD A,C CP 4 RET NC ;RETURN WITH HL=0 IF C > 3 LD (TUNIT),A ;monitor LD C,A CALL MONITR+33 ;CALL SEEK ROUTINE IN MONITOR RET Z ;EXIT IF NO ERRORS INDICATED LD C, ;ADD TRANSLATION TABLE ADDRESS ADD HL,BC ; PASSED IN DE TO SECTOR# IN BC LD L,(HL) LD H,0 ;LOOKUP PHYSICAL SECTOR NUMBE LĠ A, ; t CP/ w/ A=to RET ; indicate error ; ; ; HOME: CALL EL2: LD C,A ; put in C for monitor call LD B,0 ;seek speed (useless??) CACALL WRITE ROUTINE IN MONITOR RET Z ;RETURN IF NO ERRORS LD C,4 ;INDICATE WRITE ERROR TO HANDLER CALL REPORT ;REPORT DISTORE C AS NEW DRIVE UNIT# LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ;MULTIPLY UNIT# BY 16 LD DE,DPHTAB ADD 2 CALL REPORT ;REPORT SEEK ERROR TO CONSOLE RET NZ ;RETURN PERMANENT ERROR UNLESS JR SEEK1 ; ; ; READ: CALL SELNOR RET ; AND RETURN IT IN HL ; ; SETSEC: LD A,C LD (SECTOR),A ;STORE SECTOR NUMBER PASSED RET ; VIA BC ; SETPTR: L SELNOW ;Select drive for home CALL MONITR+30 ;CALL HOME ROUTINE IN MONITOR RET Z ;RETURN IF ALL WENT WELL LL MONITR+27 ; and do seek thru monitor RET Z ; exiting if no error LD C,1 SK ERROR TO CONSOLE JR Z,WRITE ;RE-TRY WRITE IF INDICATED RET ;ELSE RETURN PERMANENT ERROR ; ; REPORT: LD (FLAGS),A ;HL,DE ;ADD START ADDRESS OF DHP BLOCK RET ; SELNOW: LD A,(UNIT) ;Do select now. Retreive LD W ;drive select LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+36 ;CALL READ ROUTINE IN MONITOR RET ZD (POINTR),BC ;STORE DATA POINTER PASSED RET ; VIA BC page ;SELECT returns the correct Disk Parameter Block pointe LD C,2 CALL REPORT JR Z,HOME ;RE-TRY HOME IF ERROR INDICATED RET ; ; SEEK: LD A,C ;GET TRACK # FROM C LD (TRACKA STORE 1771 I/O STATUS FLAGS LD A,C LD (CLASS),A ;STORE COMMAND CLASS OF ERROR LD HL,DSKMSG CALL PMSG ;PRINT OUT START O TO BY HL UNTIL A DOLLAR SIGN IS ENCOUNTERED PMSG: LD A,(HL) ;HL POINTS TO ASCII STRING CP '$' INC HL RET Z LD C,A ,'/' CALL OVECTR LD A,(SECTOR) CALL PUT2HX REP7: LD A,1 OR A ;RETURN PERM ERROR INDICATION IN A RET ; REP8: LD HL, DEFB (sovers AND 0FF00h) SHR 8 ;sign on version DEFB sovers AND 0FFh DEFM ')' DEFB '$GES REP2: LD B,5 RES 0,D REP4: SLA E ;SHIFT OUT A 1771 STATUS REG BIT JR NC,REP5 LD C,',' BIT 0,D CALL NZ,OVECTR ;P ;drive not ready RWERRS: DEFM 'wp$' ;write protect DEFM 'wf$' ;write fault DEFM 'rnf$' F MESSAGE DEC HL LD A,(CLASS) LD B,A REP1: CALL SKIP ;SKIP TO NEXT '$' IN STRING @ HL DJNZ REP1 CALL PMSG ;PRINT ST;PRINT CHARACTER IF NOT DOLLAR SIGN CALL OVECTR JR PMSG ; ; PUT2HX: PUSH AF RRA RRA RRA RRA CALL PUTNIB POP ARDYMSG CALL PMSG ;PRINT DISK-NOT-READY MESSAGE CALL IVECTR ; AND WAIT FOR CONSOLE INPUT CP 'C'-64 JR Z,REP7 XOR A ;' ; ; LSTRDY: DEFS 1 ;List device ready flag UNIT: DEFS 1 TUNIT: DEFS 1 ;Temp unit number TRACK: DEFS 1 SECTORRINT COMMA BETWEEN STRINGS IF D=1 CALL PMSG ;THEN PRINT ERROR MESSAGE @ HL SET 0,D ;FLAG THAT A STRING WAS PRINTED JR RE ;record not found DEFM 'crc$' ;bad CRC DEFM 'do$' ;data overrun ; TSMSG: DEFM ' t/s = $' RING NOW POINTED TO BY HL LD HL,ERRMSG CALL PMSG ;PRINT 'error ' AFTER TYPE LD A,(FLAGS) RLA ;TEST FIRST FOR DRIVE-NF PUTNIB: AND 00001111B ADD A,90H DAA ADC A,40H DAA LD C,A CALL OVECTR ;PRINT A HEX-ASCII CHARACTER RET ; RETURN A=0 IF SOMETHING OTHER THAN RET ; CONTROL-C WAS TYPED AT THE CONSOLE ; SKIP: PUSH BC ;SAVE BC LD B,255 LD A,'$: DEFS 1 POINTR: DEFS 1 FLAGS: DEFS 1 CLASS: DEFS 1 DEFS 32 STACK: DEFS 1 ;LOCAL STACK FOR WARM BOOT SAVSTK: DEFS 2 P6 REP5: CALL SKIP ;SKIP TO NEXT STRING @ HL RES 0,D ;FLAG THAT A STRING WAS SKIPPED REP6: DJNZ REP4 ;REPEAT FOR ALL 5  ;track/sector ; SIGNON: DEFB CR,LF DEFB 1Ah ;Clear screen DEFM 'Hi Mark, this iOT-READY ERROR JR C,REP8 ; AND JUMP IF THAT IS THE PROBLEM LD E,A ;GET REMAINING 1771 ERROR BITS INTO E LD HL,RWERRS  page DSKMSG: DEFB CR,LF DEFM 'bios $' DEFM 'sel $' DEFM 'seek $' DEFM 'rd $' DEFM 'wr $' ; ERRMSG: DEFM 'er' CPIR ;SCAN MEMORY LOOKING FOR '$' POP BC RET ; ; ; ; CHARACTER STRING OUTPUT ROUTINE. PRINTS ASCII DATA ; POINTED page ;******************************************************** ;* * ;* DISK I/O BUFFERS FOR BDOS FILE HANDLER POSSIBLE ERRORS LD HL,TSMSG CALL PMSG ;PRINT TRACK/SECTOR# HEADER LD A,(TRACK) CALL PUT2HX ;PRINT TRACK# IN HEX LD Cs CP/M V' ; if CPM14 DEFM '1.4' else DEFM '2.2' endif ; DEFM ' ('  LD A,(CLASS) CP 3 ;DETERMINE IF SELECT/SEEK OF R/W ERROR JR NC,REP2 LD HL,SKERRS ;POINT HL TO PROPER SET OF MESSAror $' ; SKERRS: DEFM '$' DEFM '$' DEFM 'cannot seek$' DEFM 'crc$' DEFM 'no restore$' RDYMSG: DEFM 'not rdy -$' B  * ;* * ;******************************************************** ; ; ; DIRBUF: DEFS 128 ;SCRATCH DIRECTORY BUFFER j'±:=ʡ2|j;9<̱\ x!T]= $TYPE "Y" WHEN DESTINAark Stieglitz which can be assembled (by M80) for either CP/M 1.4 or 2.2 and includes a number of very nice extensions. Most o the source of this neat Z80 assembler. (So it's very important to us, at least.) NOTE THOMAS HAMEENAHO OF SWEEDEN HAS FIXED ; ALL0: DEFS 32 ;UNIT 0 ALLOCATION BUFFER CHK0: DEFS 16 ;UNIT 0 CHECK VECTOR ALL1: DEFS 32 ;UNIT 1 ALLOCATION VECTOR CHKTION DISC IS IN DRIVE $NO SOURCE FILE$OUT OF DATA SPACE$WRITE PROTECTED$NO DIRECTORY SPACE$COPY COMPLETE$f you don't even need the assembler to use this one because the HEX files are already on the disk. 1. It returns to the la THE BUGS IN THE CROWE ASSEMBLER SO IT NOW ASSEMBLES ITSELF. HOORAY! IT APPEARS TO BE CLEAN NOW. SINGLE DISK COPY PROGRAMS 1: DEFS 16 ;UNIT 1 CHECK VECTOR ALL2: DEFS 32 ;UNIT 2 ALLOCATION VECTOR CHK2: DEFS 16 ;UNIT 2 CHECK VECTOR ALL3: DEFS 32  FIL FRO ON DIS ONT BACKU DIS USINǠ ONL٠ ON DIS DRIVE THŠ SKELETOΠ OƠ TH PROGRA I BORROWE FRO st drive selected after a boot 2. Adds a parallel printer driver that checks the busy line. (See Letters to the editor in There are two single-disk copy routines, DKCOPY.* by K Stephenson and COPY by John Davis. These are will documented and th;UNIT 3 ALLOCATION VECTOR CHK3: DEFS 16 ;UNIT 3 CHECK VECTOR ; ; ; ; .DEPHASE ; END Well, hello there. This is number two of the Micro-C user disks. There are three especially interesting items on this dis issue 7 for PIO jumpers) 3. No longer does unnecessary drive selects (head banging). LAST AND LEAST And finally, a n1l!jw# 2\͹<̱\>& Y>  j>jI<̱x2ose of you with single- drive systems know how important these are. A SUPER CBIOS This is a very interesting CBIOS by Mk. First, there is the source of the Crowe Assembler. Sandy and I (mostly Sandy) entered 60 pages of source so you would haveC umber of people have asked about the source for COPYFAST so they could do their own modifications. I intended to put the souring as operand of a DEFM statement. If this limit is exceeded NO error message is generated, the string is truncated. If yo .PRN and the object with an extension of .HEX. Only minimal error checking and reporting is done. If no source file with E FUNC# READF EQU 20 ;SEQUENTIAL READ WRITEF EQU 21 ;SEQUENTIAL WRITE MAKEF EQU 22 ;MAKE FILE FUNC# RESETD EQU 13 ;RESETring as operand of a DEFM statement. If this limit is exceeded NO error message is generated, the string is truncated. If yo * ;******************************************************************* rce on this disk. However, the CROWE files wound up taking more space than originally planned so something had to go. Those of ;******************************************************************* ;* the correct name is found a message is displayed. If any other disk error on a BDOS call occurs, that is reported. In  DISK SYSTEM DMA EQU 26 ;SET DMA ADDRESS ; ORG TPA ;BEGINNING OF TPA START: LXI SP,STACK ;LOCAL STACK ; ; MOVE SECOND Fthat the assembler can be run as a standard CP/M .COM file with the following command format. CROWEASM FILENAME.YY The  ; BOOT EQU 000H ;SYSTEM REBOOT BDOS EQU 0005H ;BDOS ENTRY POINT FCBL EQU 005CH ;FIRST FILE NAME SFCB EQU FCBL ;SOURCE  you waiting for COPYFAST should get usr disk 3 for an even nicer version. Happy computering. David Thompson * ;* THIS PROGRAM COPIES A FILE FROM * ;* ONE DISC TO ANOTHER USING ONLeither case, the routine waits for a keystroke before exiting to CP/M. _____________________________________________________ILE NAME TO DFCB MVI C,16 ;HALF AN FCB LXI D,FCB2 ;SOURCE OF MOVE LXI H,DFCB ;DESTINATION FCB MFCB: LDAX D ;SOURCE FCB characters in the normal file extension position are Y/N selects (default is Y), the first for listing file and the secondFCB FCB2 EQU 006CH ;SECOND FILE NAME TPA EQU 100H ;BEGINNING OF TPA SAVE EQU 80H ; CONSIN EQU 1 ;CONSOLE INPUT FUNC# Peither case, the routine waits for a keystroke before exiting to CP/M. _____________________________________________________Y ONE DISC DRIVE * ;* PROGRAM BY JTS SOFTWARE; ALL RIGHTS RESERVED * ;* DATE: 7/16/81 ______________ An additional note about the assembler the way it stands: there is a limit of 32 characters for a quoted st INX D ;READY NEXT MOV M,A ;DESTINATION FCB INX H ;READY NEXT DCR C ;COUNT 16...0 JNZ MFCB ;LOOP 16 TIMES ; ; NAME for the hex object file. The source must have a file extension of .Z80 while the listing is created with an extension of RINTF EQU 9 ;PRINT BUFFER FUNC# OPENF EQU 15 ;OPEN FILE FUNC# CLOSEF EQU 16 ;CLOSE FILE FUNC# DELETEF EQU 19 ;DELETE FIL______________ An additional note about the assembler the way it stands: there is a limit of 32 characters for a quoted st * ;* EDITION: 1 * ;* D  HAS BEEN MOVED, ZERO CR XRA A ;A = 00 STA DFCBCR ;CURRENT REC = 0 ; ; SOURCE AND DESTINATION FCB'S READY ; LXI D,SFCBESTINATION CALL WRITE ;WRITE RECORD LXI D,SPACE ;READY MESSAGE ORA A ;00 IF WRITE OK JNZ FINIS ;END IF DISC IS FULL HAS RIGHT DISC NUM STAX D ;STORE ZERO IN FIRST BYTE OF DFCB CALL DELETE ;REMOVE IF PRESENT ; LXI D,DFCB ;DESTINATION C DCR A ;DECR COUNTR JNZ LOOP ;JMP BACK IF NOT DONE RET ; CONSOLE MESSAGES CRLF DB 0DH,0AH,'$' READY: DB 'TYPE "Y" WHENARE TO COPY EOFILE: LXI D,READY ;READY MESSAGE MVI C,PRINTF ; CALL BDOS ;WRITE MESSAGE MVI C,CONSIN ; CALL BDOS ;GET OK SYSTEM INTERFACE SUBROUTINES ; (ALL RETURN DIRECTLY FROM BDOS) ; OPEN: MVI C,OPENF JMP BDOS ; CLOSE: MVI C,CLOSEF JMP  ;SOURCE FILE CALL OPEN ;ERROR IF 255 LXI D,NOFILE ;READY MESSAGE INR A ;255 BECOMES 0 CZ FINIS ;DONE IF NO FILE ; ;  LDA STORE ;GET COUNTR DCR A ;DECREMENT COUNTR JZ DONE ;DONE ? STA STORE ;STORE COUNTR IF NOT DONE POP B INR B ;INALL MAKE ;CREATE THE FILE LXI D,NODIR ;READY MESSAGE INR A ;255 BECOMES 0 CZ FINIS ;DONE IF NO DIR SPACE ; ; DEST FILE  DESTINATION DISC IS IN DRIVE $' NOFILE: DB 'NO SOURCE FILE$' SPACE: DB 'OUT OF DATA SPACE$' WRPROT: DB 'WRITE PROTECTED$'  FROM OPERATOR THAT DEST IS READY ANI 0DFH ;AND OFF 5TH BIT FOR SHIFT CPI 59H ;IF OP TYPED Y THEN DISC IS READY JNZ EOFILBDOS ; DELETE: MVI C,DELETEF JMP BDOS ; READ: MVI C,READF JMP BDOS ; WRITE: MVI C,WRITEF JMP BDOS ; MAKE: MVI C,MASOURCE FILE OPEN, COPY UNTIL ; END OF FILE ON SOURCE MVI B,01H COPY: CALL UPDATE ;UP TO RIGHT DATA BUFFER PUSH B MVI C,DCREMENT RECORD COUNTR JMP COPY2 ;LOOP UNTIL EOF ; END OF FILE, CLOSE DESTINATION DONE: LXI D,DFCB ;DESTINATION CALL CLOSE OPEN, ; COPY UNTIL END OF FILE ON SOURCE POP B ;RETREIVE COUNTR MOV A,B STA STORE ;STORE COUNTR IN BUFFER MVI B,01H ;NODIR: DB 'NO DIRECTORY SPACE$' NORMAL: DB 'COPY COMPLETE$' ; ; DATA AREAS DFCB: DS 33 ;DESTINATION FCB DFCBCR: EQU DFCB+3E ;JMP BACK IF NOT READY LXI D,CRLF ;CARRAGE RET LINE FEED MVI C,PRINTF ;PRINT CARRAGE RET LINE CALL BDOS ;DO IT ; ; PREKEF JMP BDOS UPDATE: LXI D,300H ;BASE ADDRESS FOR DATA BUFFER MOV A,B ;MOV COUNTR TO A REG FOR MANIPULATION LOOP: PUSH H MA ;SET DMA ADDRESS CALL BDOS ; LXI D,SFCB ;SOURCE CALL READ ;READ NEXT RECORD ORA A ;END OF FILE? JNZ EOFILE ;JMP TO;255 IF ERROR LXI D,WRPROT ;READY MESSAGE INR A ;255 BECOMES 00 CZ FINIS ;SHOULDN'T HAPPEN ; ;COPY COMPLETE, END LXI SET RECORD COUNTR COPY2: CALL UPDATE ;UPDATE DBUFF POINTR PUSH B MVI C,DMA ;UPDATE DMA NUMBER CALL BDOS ; LXI D,DFCB ;D2 ;CURRENT RECORD ; DS 32 ;16 LEVEL STACK STACK: STORE: DS 1 END PARE DESTINATION FILE MVI C,RESETD ;RESET DISK SYSTEM CALL BDOS ; LXI D,DFCB ;DESTINATION MVI A,00H ;MAKE SURE DEST FCB  LXI H,80H ; DAD D ;ADD BASE FOR ADDRESS UPDATE MOV D,H ;RESTORE D REG MOV E,L ;RESTORE E REG POP H ;RETORE H AND L CLOSE SOURCE FILE ; ; NOT END OF FILE, CONTINUE TO READ POP B INR B ; JMP COPY ;LOOP UNTIL EOF ; ; END OF FILE, PREPD,NORMAL ;READY MESSAGE ; FINIS: ;WRITE MESSAGE GIVEN BY DE, REBOOT MVI C,PRINTF CALL BDOS ;WRITE MASSAGE JMP BOOT ; ;E  PUSH B 0180 0E1A MVI C,DMA ;UPDATE DMA NUMBER 0182 CD0500 CALL BDOS ; 0185 116A02 LXI D,DFCB ;DESTINATION R 1 N SOURC FIL EXIST 2 FIL I T LARG FO DAT SPAC 3.TH DESTINATIO DIS I WRIT PROTECTE 4 THERE IS NO DIRENSED THŠ USEҠ IӠ THEΠ PROMPTE WITȠ THŠ MESSAGE "TYPŠ ٠ WHE DESTINATIO DIS I I DRIVE" AFTE TH BACKU  $ FIL FRO ON DIS ONT BACKU DIS USINǠ ONL٠ ON DIS DRIVE THŠ SKELETOΠ OƠ TH PROGRA I BORROWE FRO !9"=1=~#$MO@_? $>1O>0O*#"&ECTORY SPACE ON THE DESTINATION DISK. THE PROGRAM IS ENTERED USING THE COMMAND BACKUP A:X.Y A:U.V WHER A:X. I THDIS IӠ LOADE INT TH DRIV AN "Y I DETECTE FRO TH KEYBOARD TH PROGRA RESETӠ TH DIS SYSTE AN CREATE TH FIAΠ EXAMPLŠ CP/ PROGRA͠ GIVEΠ I DIGITA RESEARCH' CP/ 2. INTERFACŠ GUIDE TH PROGRA USE MAN O TH CP/ SYSTEo ڊ |ā{0O? Nonstandard disk parameter block error $*=!:\2?BITMAP 2.2 AS OF 7/ COPY ROUTINE FOR SINGLE DISC SYSTEMS BY JOHN DAVIS APT. 155 ISAQUEENA APT'S. CENTRAL, S.C. 29630 BEINǠ O SOUN MIN A SOURC FIL NAM AN A:U. I THŠ DESTINATIO FILE NAME. ITӠ THA SIMPLE AN OTHE SINGL DIS PROGRAM WOUL BŠ WEL O TH BACKUР DISK TH FIL I THE REA FRO MEMOR UNTI TH END-OF-FIL I SENSED. THERŠ ARŠ NUMBE O ERRO C CALL AN THU I GOO EXAMPLE OF THESE OPERATIONS. AFTE TH STAC POINTE I SET TH SECON FIL NAM I STORE T 11/80 $2:=2:_"^#V#"*##~ңڣ?Allocated disk block size is $2!)=ú?N LIMITE FINANCES FOUN THA HA T FINĠ WA٠ T SURVIV USIN ONL ON DISˠ DRIVŠ OΠ M٠ HOM SYSTEM TH PL APPRECIATED BY YOURS TRULY.ONDITION THA CA EXISԠ ANĠ TH USEҠ IӠ PROMPTEĠ B TH PROGRA I AN ERROҠ EXISTӠ IΠ FIL TRANSFER TH ERROR A IT DESIGNATE LOCATIO I MEMORY TH FIL O TH SOURCŠ DIS IӠ OPENE AN TH FIL I COPIE UNTI A END-OF-FIL I S bytes per block $*:_+0^#~emz ʧʬð^^:AO?: R/W, Space: $:*=)́?kROBLE THA EXISTE WA HO T TRANSFE FIL FRO ONŠ DISˠ TϠ ANOTHER THI ARTICL DESCRIBE ROUTINŠ THA COPIEMA ;SET DMA ADDRESS CALL BDOS ; LXI D,SFCB ;SOURCE CALL READ ;READ NEXT RECORD ORA A ;END OF FILE? JNZ EOFILE ;JMP TOF  Mark Stieglitz ue (thos tha ar no followe b a I/ operatio bu rathe b anothe selec bac t th original drive thannoyin "B: command eac tim M80 PI o anothe progra runnin o B terminate tha doe jum t z th progra i memor othe tha wher i woul normall resid (withou these yo ge "ou o memor errors") T dis paramete block an secto translatio routin ma als b omitte fo versio 1. i th spac i as comments Thes program wer assemble wit Microsoft' M80 First use your text editor to set up the .MAC files forWestern Digital Corporation 2445 McCabe Way Irvine, Caa cause th hea t unload Thi i noticabl whe usin Microsof Basi loade fro A t loa basi progrero. 3 printe drive (simila t th on publishe i MC #2 ha bee integrate int th CBIOS I i initihe link commands are: (for CP/M 1.4) L80 /P:1E80,SCBIOS,SCBIOS/N/X/E L80 /P:900,SBOOT,SBOOT/N/X/E (for CP/Mneede fo somethin els bu anythin adde relyin o thi are woul no fi i 2. CBIOS Als not tha  either CP/M 1.4 or 2.2 and note the comment on the BIAS calculation for both files. Then enter M80 =SCBIOS.MAC and lifornia 92714 S-CBIOS FEATURES 1 ha CP/ versio 1. o anothe syste an sinc pla t us onl SSS a fro B: Th ol CBIO cause th driv B hea t continuall loa an unloa whil th ne on keep i loalize during col boo an implement th lis bus test. 4 Th selec driv routin ha bee modifie t defe 2.2) L80 /P:1F80,SCBIOS,SCBIOS/N/X/E L80 /P:900,SBOOT,SBOOT/N/X/E Th resultan he file wil automaticall lo 1. CP/ mus b generate fo 59 t expec th CBIO a EA00. 2 Th CBIO no retain th las driv selecteM80 =SBOOT.MAC Note, The source files had to be modified for M80. Thi require severa mino syntacti changes Rdiskettes sa n nee t mov u t versio 2.2 Thus adde conditiona assembl switc t allo ade fo th duration. T sav memor (n par o th CBIO ma exten past EE7F an stil fi o th diskette sever th actua selec unti a I/ operatio occurs Thi prevent th unnecessar select tha CP/ sometime issa a 90 an 1E8 (or 1F80) fo sysge withou an offset. THE .HEX FILES ALREADY ON THE DISK WERE ASSEMBLED FOR CP/M 1.4 A an return th valu t CP/ o war boot Thi cause CP/ t retur t th driv yo wer using savin elativ jump d no requir th - an th .RES i delete fro EQUates Th Phas an DEPHAS pseudo-op allo L8 t lin operatio wit 1.4 Th onl differenc th loa addres an sign-o messag (sam wit th boo program) Tha o th erro message wer abbreviated. I general th change hav mad ar identifiabl b th us o lowe cG ND FOR CP/M 2.2 (WITH THE BASE OF THE 2.2 BIOS AT E800). IF THE BASE OF YOUR 2.2 BIOS IS AT EA00 THEN YOU WILL NEED TO CHANGE0,0,0,0,0,0 ;8 NOP's org $-1 ;leave next byte intact db 7 u're not careful, the terminating '$' for a CP/M output string could be lost and the results would be unpredictable. _______you then you can go in and change the message. ******************************************************************** Ythe correct name is found a message is displayed. If any other disk error on a BDOS call occurs, that is reported. In  THE BASE DISPLACEMENT IN THE .MAC FILES (THEY ARE COMMENTED) AND THEN REASSEMBLE. Now do the following: SYSGEN (Selectthat the assembler can be run as a standard CP/M .COM file with the following command format. CROWEASM FILENAME.YY The  Mark Stieglitz ____________________________________________________________ The CROWE.Z80 file has the linkages incorporated into it, neao ma b intereste i patc t th CP/ CC tha allow th RUBOUԠ ke t "backspace withou ech (lik th back-either case, the routine waits for a keystroke before exiting to CP/M. _____________________________________________________ a source drive and then a for a destination) SAVE 36 CPM.COM DDT CPM.COM ISBOOT.HEX R ISCBIOS.HEX R characters in the normal file extension position are Y/N selects (default is Y), the first for listing file and the secondr the end. As it now stands, the symbol table is limited only by the amount of available memory since the assembler reads thearro does) I work wit versio 2. an i patche i afte th CBIOӠ an BOO ar adde prio t SYSGEN (i othe______________ An additional note about the assembler the way it stands: there is a limit of 32 characters for a quoted st ^C SYSGEN (Enter for source and then select a destination drive) Now put the destination drive in drive A, do a har for the hex object file. The source must have a file extension of .Z80 while the listing is created with an extension of  start address of BDOS from locations 6&7 and sets that as the top of available symbol space. There has been one minor impr words whe CP͠ i i memor fro 98 up) Th sourc o thi wa remot CP/ system. 139b: db 0,0,ring as operand of a DEFM statement. If this limit is exceeded NO error message is generated, the string is truncated. If yodware reset followed by a boot. That's all there is It will come up Hi Mark, CPM/X.X Version (xx) If that doesn't thrill  .PRN and the object with an extension of .HEX. Only minimal error checking and reporting is done. If no source file with H ovement to the assembler: you can now specify that the .LST or .HEX files should be sent to drive B rather than the current de____________________________________________________________ The CROWE.Z80 file has the linkages incorporated into it, neafault drive by putting a B in the proper position in the normal filename extension. E.g. CROWE2 CROWE.NB would assemble the f4F5254454400CA :00000001FF 300E8E5C5CD24F0C1E12006240C0C10F2C921DE007ECDB8 :1A09540009F07E23B720F7C303F02020204C4F4144204142addition, it flags as un- defined the symbol LBFSZ in the instruction LD B,LBFSZ-1. Again, cause unknown. The assembler willile CROWE.Z80, skip the .LST file and send the .HEX file to drive B. The source file must still reside on the same drive as fault drive by putting a B in the proper position in the normal filename extension. E.g. CROWE2 CROWE.NB would assemble the fr the end. As it now stands, the symbol table is limited only by the amount of available memory since the assembler reads theile CROWE.Z80, skip the .LST file and send the .HEX file to drive B. The source file must still reside on the same drive as  assemble itself if you change the six EX AF,AF' commands to DEFB 8 commands. The source is currently set up for the CRthe assembler. The source is currently set up for the CROWE assembler. To assemble it with M80 you will need to add ASEG anile CROWE.Z80, skip the .LST file and send the .HEX file to drive B. The source file must still reside on the same drive as  start address of BDOS from locations 6&7 and sets that as the top of available symbol space. There has been one minor imprthe assembler. There are still bugs in the assembler. I have found and fixed the bug relating to the .HEX output. When you OWE2 assembler. To assemble it with M80 you will need to add ASEG and .Z80 commands to it. John P Jones :1C090000180E36304B2043502F4D2056322E32201E002100D201020DCDC00021DE :1C091C0080D201030CCDC0000E01CD21F020242180DE01010DCDC00021the assembler. When you try to assemble CROWE.Z80 with CROWE2 the six EX AF,AF' instructions are flagged as syntax erroovement to the assembler: you can now specify that the .LST or .HEX files should be sent to drive B rather than the current deu're not careful, the terminating '$' for a CP/M output string could be lost and the results would be unpredictable. _______ovement to the assembler: you can now specify that the .LST or .HEX files should be sent to drive B rather than the current de00DF0183 :1C093800020DCDC000C300E8E5C5CD24F0C1E12006240C0C10F2C921DE007ECDB8 :1A09540009F07E23B720F7C303F02020204C4F4144204142rs for no apparent reason. If you assemble the file EXAF.Z80 it assembles those instructions as expected. Very strange! In fault drive by putting a B in the proper position in the normal filename extension. E.g. CROWE2 CROWE.NB would assemble the fI 3205002106DA22060032380021F3 :1C20280000F0223900018000CD81E93A04004FC300D2222EEB79322DEBE5C5CD02 :1C204400E3E9C1E12006240C0C10E2FCD0CE83A2DEBCD9EEA3E01B7C921F4EACD93EACD09E830 :1C220400FE0328EFAFC9C506FF3E24EDB1C1C97EFE2423C84FCD0CE818F5F51F1E :1C22200BB9C83262 :1C2124002AEB4F0600CD1BF0C80E01CD0FEA20053A2AEB18EDE13E01C9CD9AE90E :1C214000CD1EF0C80E02CD0FEA28F2C979322CEBCD9AE93EBC921D8E8CD93EA18FE0D0A626F6F7420655B :1C206000722479C30CF03A29EBC93A29EBB728FAAF3229EB79D308C9ED7352EBA9 :1C207C003151EBF53E:1C1F8000C333E8C35AE8C306F0C309F0C3E2E8C3EAE8C3E2E8C309F0C3BDE9C356 :1C1F9C0086E9C3CCE9C37CE9C381E9C3E3E9C3F9E9C3E6E8C376E9AF3201F1F1FCDA7EAF1E60FC69027CE40274FCD0CE8C90D0A62696F7320246E :1C223C0073656C20247365656B202472642024777220246572726F722020242419A2CEB4FCD21F0C80EC1 :1C215C0002CD0FEAC018F0CD9AE92A2EEB3A2DEB4FCD24F0C80E03CD0FEA28EB10 :1C217800C9CD9AE92A2EEB3A2DEB4FCD27F0C:1C090000180E35394B2043502F4D2056312E34201E002100D501020DCDC00021D2 :1C091C0080D501030CCDC0000E01CD21F020242180E101010DCDC00021FF3229EBF1ED7B52EBFBED4D01070D1319050B1117030913 :1C2098000F1502080E141A060C1218040A10161A00030700F2003F00C00010002D :1C20B400030032F0 :1C1FB80004002117EBCD93EA3EFF3229EB3E0FD3093E1CD30901F8E8ED431CFF8E :1C1FD4003E87D30918363151EB0E00CD86E9CDBDE92100D2 :1C2258002463616E6E6F74207365656B24637263246E6F20726573746F72652456 :1C2274006E6F7420726479202D24777024776624726E66246372632480E04CD0FEA28EBC9322FEB7932F7 :1C21940030EB21B4EACD93EA2B3A30EB47CD8AEA10FBCD93EA21CFEACD93EA3A50 :1C21B0002FEB1738465F21FEEA300E2017A :1C093800020DCDC000C300EAE5C5CD24F0C1E12006240C0C10F2C921DE007ECDB6 :1A09540009F07E23B720F7C303F02020204C4F414420414202000DE900000000000054EB27E9F4EBD4EB0DE900000000000054EBF6 :1C20D00027E924EC04EC0DE900000000000054EB27E954EC34EC0DE90000000049 01020DCDBAE82180C5 :1C1FF000D201030CCDBAE80E01CDCCE920522180DE01010ACDBAE82100DF010284 :1C200C0009CDBAE83EC33200002103E8220100646F242034 :1C229000742F73203D20240D0A1A43502F4D2056322E32202858342924280000EA :1C22AC0000000000000000000000000000000000000000A30EBFE03300321D7EA0605CB82CB23300E0EFF :1C21CC002CCB42C40CE8CD93EACBC21805CD8AEACB8210E7210FEBCD93EA3A2CC2 :1C21E800EBCD9EEA04F5254454400CA :00000001FF 300EAE5C5CD24F0C1E12006240C0C10F2C921DE007ECDB6 :1A09540009F07E23B720F7C303F02020204C4F4144204142 :1C20EC00000054EB27E984EC64ECEB096E2600C979322DEBC9ED432EEBC92100B9 :1C2108000079FE04D0322BEB6F292929291136E919C93A2AEB4F3A2BEJ 00000000000000000016 :1C22C80000000000000000000000000000000000000000000000000000000000FA :1C22E4000000000000000000000000000000FF3229EDF1ED7B52EDFBED4D01070D1319050B111703090E :1C1F98000F1502080E141A060C1218040A10161A00030700F2003F00C00010002E :1C1FB400030032E1 :1C1EB80004002117EDCD93EC3EFF3229ED3E0FD3093E1CD30901F8EAED431CFF87 :1C1ED4003E87D30918363151ED0E00CD86EBCDBDEB2100D5 :1C2158002463616E6E6F74207365656B24637263246E6F20726573746F72652457 :1C2174006E6F7420726479202D24777024776624726E6624637263249 :1C23C40000000000000000000000000000000000000000000000000000000000FD :1C23E0000000000000000000000000000000000000000000000000080E04CD0FEC28EBC9322FED7932EE :1C20940030ED21B4ECCD93EC2B3A30ED47CD8AEC10FBCD93EC21CFECCD93EC3A41 :1C20B0002FED1738465F21FEEC30000000000000000000000000000DE :1C23000000000000000000000000000000000000000000000000000000000000C1 :1C231C0000000000000000000002000DEB00000000000054ED27EBF4EDD4ED0DEB00000000000054EDE9 :1C1FD00027EB24EE04EE0DEB00000000000054ED27EB54EE34EE0DEB0000000038 01020DCDBAEA2180BB :1C1EF000D501030CCDBAEA0E01CDCCEB20522180E101010ACDBAEA2100E2010276 :1C1F0C0009CDBAEA3EC33200002103EA220100646F242035 :1C219000742F73203D20240D0A1A43502F4D2056312E34202858342924280000EA :1C21AC0000000000000000000000000000000000000000000000000E1 :1823FC00000000000000000000000000000000000000000000000000C9 :00000001FF 0000000000000000000000000000000000000000A30EDFE03300321D7EC0605CB82CB23300E0EF8 :1C20CC002CCB42C40CEACD93ECCBC21805CD8AECCB8210E7210FEDCD93EC3A2CB9 :1C20E800EDCD9EEC000000000000000000000000000000000000000A5 :1C2338000000000000000000000000000000000000000000000000000000000089 :1C23540000000000 :1C1FEC00000054ED27EB84EE64EEEB096E2600C979322DEDC9ED432EEDC92100AE :1C2008000079FE04D0322BED6F292929291136EB19C93A2AED4F3A2BE3205002106DD22060032380021ED :1C1F280000F0223900018000CD81EB3A04004FC300D5222EED79322DEDE5C5CDFA :1C1F4400E3EBC1E12006240C0C1000000000000000000017 :1C21C80000000000000000000000000000000000000000000000000000000000FB :1C21E4000000000000000000000000000000E2FCD0CEA3A2DEDCD9EEC3E01B7C921F4ECCD93ECCD09EA21 :1C210400FE0328EFAFC9C506FF3E24EDB1C1C97EFE2423C84FCD0CEA18F5F51F1D :1C212000000000000000000000000000000000000000000000000006D :1C2370000000000000000000000000000000000000000000000000000000000051 :1C238CDB9C8325B :1C2024002AED4F0600CD1BF0C80E01CD0FEC20053A2AED18EDE13E01C9CD9AEB07 :1C204000CD1EF0C80E02CD0FEC28F2C979322CEDCD9AEB3EBC921D8EACD93EC18FE0D0A626F6F74206556 :1C1F6000722479C30CF03A29EDC93A29EDB728FAAF3229ED79D308C9ED7352EDA2 :1C1F7C003151EDF53E0000000000000000000000000000DF :1C22000000000000000000000000000000000000000000000000000000000000C2 :1C221C00000000000000000000:1C1E8000C333EAC35AEAC306F0C309F0C3E2EAC3EAEAC3E2EAC309F0C3BDEBC34B :1C1E9C0086EBC3CCEBC37CEBC381EBC3E3EBC3F9EBC3E6EAC376EBAF3201F1F1FCDA7ECF1E60FC69027CE40274FCD0CEAC90D0A62696F7320246B :1C213C0073656C20247365656B202472642024777220246572726F72202024241A000000000000000000000000000000000000000000000000000000000035 :1C23A800000000000000000000000000000000000000000000000000000000001A2CED4FCD21F0C80EBA :1C205C0002CD0FECC018F0CD9AEB2A2EED3A2DED4FCD24F0C80E03CD0FEC28EB07 :1C207800C9CD9AEB2A2EED3A2DED4FCD27F0CK 00000000000000000000000000000000000000A6 :1C223800000000000000000000000000000000000000000000000000000000008A :1C22540000000000ping into someone else's domain. Needless to say, finding the little bugger will require some first-class detective work. Ynot be set. The other bug (LBFSZ-1) resulted because the minus character (instead of the "_" character) was declared legal io something had to go. Those of you waiting for COPYFAST will have to wait a little longer. Happy computering. David Tassembler to use this one because the HEX files are already on the disk. 1. It returns to the last drive selected after a bo0000000000000000000000000000000000000000000000006E :1C2270000000000000000000000000000000000000000000000000000000000052 :1C228Cou can reach John Jones at 5826 Southwest Ave, St. Louis, MO 63139. SINGLE DISK COPY PROGRAMS There are two single-disk n a label. Probably a typing error when entering the source code. So now CROWE3.COM will assemble CROWE3.Z80. Thomas Hamhompsond .Z80 commands to it. John Jones ************************************************************************ But fixes frot 2. Adds a printer driver that checks the busy line. 3. No longer does unnecessary drive selects (head banging). LA000000000000000000000000000000000000000000000000000000000036 :1C22A800000000000000000000000000000000000000000000000000000000001copy routines, DKCOPY.* by K Stephenson and COPY by John Davis. These are will documented and those of you with single- drieenaho Djaknegatan 7 S-754 23 Uppsala Sweden om Thomas Hameenaho The first bug resulted when the single quote character in EX AF,AF' caused the assembler to expect the fST AND LEAST And finally, a number of people have asked about the source for COPYFAST so they could do their own modificatioA :1C22C40000000000000000000000000000000000000000000000000000000000FE :1C22E00000000000000000000000000000000000000000000000000ve systems know how important these are. A SUPER CBIOS This is a very interesting CBIOS by Mark Stieglitz which can be  HAVE (OR A FIX EVEN). AND I WOULD BE TICKLED TO RUN THE FIX IN MICRO C. My guess is that a stack or something may be stepollowing characters to be a text string. Now I test if the character preceding the ' is a 'F', if so, the 'QUOTE' flag should ns. I intended to put the source on this disk. However, the CROWE files wound up taking more space than originally planned s000000000E2 :1822FC00000000000000000000000000000000000000000000000000CA :00000001FF 0000000000000000000000000000000000000000assembled (by M80) for either CP/M 1.4 or 2.2 and includes a number of very nice extensions. Most of you don't even need the L addition, it flags as un- defined the symbol LBFSZ in the instruction LD B,LBFSZ-1. Again, cause unknown. The assembler will assemble itself if you change the six EX AF,AF' commands to DEFB 8 commands. The source is currently set up for the CROWE2 assembler. To assemble it with M80 you will need to add ASEG and .Z80 commands to it. John P Jonesd:crowe.doc: file not found rs for no apparent reason. If you assemble the file EXAF.Z80 it assembles those instructions as expected. Very strange! In