1;*************************************************************
2; VIO TERMINAL FIRMWARE  REQUIRES REFRESH MEMORY TO BE AT
3; F000 AND FIRMWARE ITSELF AT F800
4; COPYRIGHT IMSAI MANUFACTURING COMPANY
5;           SAN LEANDRO, CALIFORNIA
6;           6/1/77
7;
8; MODIFIED TO ASSEMBLE WITH INTEL 8080 CROSS ASSEMBLER
9; AND PRETTIFIED SOURCE
10;           UDO MUNK
11;           1/3/2017
12;
13; CHANGED DEFINITIONS OF SYSRAM VARIABLES FROM DB/DW TO DS
14; SO THAT NO CODE IS EMITTED
15;           UDO MUNK
16;           02/17/2017
17;**************************************************************
18REFRESH EQU  0F000H     ;REFRESH MEMORY ON VIO
19SYSRAM  EQU  0F780H     ;SYSTEM RAM
20VIOFM   EQU  0F800H     ;FIRMWARE BEGINNING
21        ORG  VIOFM+7FDH
22        DB   'VI0'      ;SYSTEM IDENTIFIER
23CTRPORT EQU  REFRESH+7FFH ;HARDWARE CONTROL WORD
24        ORG  SYSRAM
25CURLIN: DS   1          ;CURRENT LINE # 0-23
26CURCOL: DS   1          ;CURRENT COL # 0-79
27INVIDIO:DS   1          ;INVERSE VIDIO MODE(BY CHAR)
28VDIMDE: DS   1          ;MODE 0=GRAPHICS, NOT 0= TEXT
29INSRT:  DS   1          ;INSERTING CHARS MODE
30ESCCNT: DS   1          ;ESCAPE CHAR COUNT
31ESCCDE: DS   1          ;ESCAPE CODE LAST USED
32USRCTR: DS   2          ;USER CTR TBLE PTR, NON ZERO
33USRESC: DS   2          ;USER ESCAPE TBLE PTR,NON ZERO
34USERCMD:DS   2          ;USER MONITOR COMMAND TABLE
35RAMPTR: DS   2          ;RAM SPACE PTR WITH DIRECT I/O
36CURPTR: DS   2          ;CURSOR ADDRESS
37PRTMD:  DS   1          ;PROTECTED MODE 0=NO
38CCUR:   DS   1          ;CHAR UNDER CURSOR(FOR GRAPHICS MODE)
39CCHAR:  DS   1          ;CURRENT CHARACTER TO DISPLAY
40CTRLC:  DS   1          ;CONTROL WORD AS FOLLOWS
41;                               7 SCROLL MODE 0=SCROLL,1=WRAP
42;                               6 UNUSED
43;                               5 UP/LOW        0=UP,1=UP+LOW
44;                               4 1=INVERSE VIDIO SCREEN
45;                               3 00=BLANK,01=LOW128+INV,10=HIGH128+INV
46;                               2 11=256 CHAR GRAPHICS
47;                               1 #LINES 0=24,1=12
48;                               0 #CHARS 0=80,1=40
49TAB     EQU  $
50        ORG  $+10       ;80 BITS FOR TAB CONTROL
51CLINE:  DS   2          ;CHARS/LINE
52LPAGE:  DS   1          ;LINES/PAGE-1
53NCHARS: DS   2          ;#CHARS ON DISPLAY
54PRUPRF: DS   1          ;TRANSITION PROTECT FLAG
55USERF:  DS   1          ;ENTRY POINT FLAG 0=INIT48,1=CHAR48,2=USER
56LASTC:  DS   2          ;LAST CHAR ON SCREEN PTR+1
57;***********************************
58; USER ENTRY POINTS
59;***********************************
60        ORG  VIOFM
61        JMP  INIT               ;INITIALIZATION POINT
62        JMP  CHAROUT            ;CHARACTER OUTPUT
63        JMP  MONT               ;MONITOR ENTRY POINT
64VIOTEST:LXI  SP,SYSRAM+7EH
65        CALL INIT
66        CALL CHIN
67        JMP  VIOTEST+6          ;DEMO TESTER
68;**********************************************
69INIT:   PUSH H
70        PUSH D
71        PUSH B
72        PUSH PSW
73        LXI  H,CURLIN           ;START OF ZEROED AREA
74        MVI  B,CLINE-CURLIN AND 0FFH
75        XRA  A
76INIT1:  MOV  M,A                ;ZERO AREA
77        INX  H
78        DCR  B
79        JNZ  INIT1
80        LXI  H,REFRESH  ;BEGIN CURSOR POS
81        SHLD CURPTR
82        LXI  H,1920     ;DEFAULT CHARS/SCREEN
83        SHLD NCHARS
84        CALL BLNKS      ;CLEAR SCREEN AND HOME
85        MVI  A,8H       ;DEFAULT 80X24 SCREEN TEXT MODE
86        LXI  D,BMP1     ;SET UP RETURN ADDR
87        PUSH D
88;SUBROUTINE TO SET HARDWARE CONTROL PORT
89SETCMD: STA  CTRLC
90        STA  CTRPORT    ;HARDWARE CONTROL PORT
91        CMA
92        ANI  3
93        RRC             ;FINDING NCHARS ON SCREEN
94        LXI  H,40       ;COLS/LINE
95        JNC  $+4        ;ENOUGH
96        DAD  H          ;COLS/LINE=80
97        SHLD CLINE
98        LXI  H,LPAGE    ;PT AT LINES/PAGE
99        MVI  M,11
100        RAR
101        JNC  $+5
102        MVI  M,23
103        LXI  H,480      ;COUNT FOR 12 X 40 SCREEN
104        JNC  $+4
105        DAD  H
106        ORA  A          ;SET FLAGS
107        JZ   $+4
108        DAD  H
109        SHLD NCHARS
110        LXI  D,REFRESH
111        DAD  D
112        SHLD LASTC      ;LAST CHAR ON SCREEN PTR+1
113        LDA  CTRLC      ;CONTROL CODE
114        ANI  0CH        ;MODE BITS ONLY
115        XRI  0CH
116        STA  VDIMDE     ;0=GRAPHICS
117;CHECK CURSOR WITHIN POSSIBLE NEW BOUNDS
118ESCRET: XRA  A
119        STA  ESCCNT     ;COUNT=0
120        RET
121;****************************************************************
122; THIS IS THE NORMAL ENTRY POINT FOR COMMUNICATING WITH THE
123; VIDIO MONITOR AS YOU WOULD A CRT.
124;****************************************************************
125CHAROUT:PUSH H
126        PUSH D
127        PUSH B
128        PUSH PSW
129        STA  CCHAR
130        LHLD CURPTR     ;CURSOR POSITION
131        LDA  CCUR       ;CHAR UNDER CURSOR
132        MOV  M,A        ;REMOVE CURSOR
133        LXI  H,CCHAR    ;PT AT CURRENT CHAR
134        MOV  A,M        ;GET CHAR
135        CPI  1BH        ;ESCAPE CHAR?
136        JZ   ESCAPE
137        LDA  ESCCNT     ;ARE WE IN ESCAPE SEQ ALREADY?
138        ORA  A
139        JNZ  ESCAPE     ;YES
140        MOV  A,M        ;CURRENT CHAR
141        CPI  7FH        ;DELETE CHAR (RUBOUT)?
142        JZ   NOUSER+3   ;YES
143        LDA  VDIMDE     ;GRAPHICS MODE?
144        ORA  A
145        JZ   CHAR1      ;YES
146        MOV  A,M
147        CPI  0FFH       ;DUMMY PAD FROM USER?
148        JZ   BMP1       ;YES
149        ANI  7FH        ;STRIP PARITY BIT
150        MOV  M,A
151        SBI  20H        ;CONTROL CODE?
152        JM   CONTROL    ;YES
153        LDA  CTRLC      ;CONTROL WORD
154        MOV  B,A        ;TMP SAVE
155        ANI  0CH        ;MODE ONLY
156        CPI  08H        ;LOW HALF OF CHAR GEN ROM?
157        JNZ  CHAR1      ;NO,UPPER HALF
158        MOV  A,B        ;CONTROL WORD
159        ANI  20H        ;UP/LOW CASE
160        JNZ  CHAR1      ;LOWER OK AS IS
161        MOV  A,M        ;CURRENT CHAR
162        SBI  61H        ;LOWER CASE A
163        JM   CHAR1      ;NOT ALPHA
164        SBI  7BH-61H
165        JP   CHAR1      ;NOT ALPHA
166        ADI  7BH-20H    ;RESTORE AND CONVERT TO UPPER CASE
167        MOV  M,A
168CHAR1:  CALL INSCHR     ;INSERT CCHAR AT CURSOR POS
169        CALL BMPCUR
170BMP10:  CALL CALPOS     ;CURSOR POS
171BMP1:   CALL INSCURS    ;INSERT CURSOR
172        POP  PSW
173        POP  B
174        POP  D
175        POP  H
176        RET
177BMPCUR  EQU  $
178        CALL BMPC       ;BUMP CURSOR CHAR POSITION
179        CZ   BMPC1      ;DO LINE FEED
180        LDA  PRTMD      ;PROTECT MODE?
181        XCHG            ;H,L=CURRENT CURSOR PTR
182        ANA  M          ;IS IT PROTECTED?
183        JM   BMPCUR     ;YES,SKIP PROTECTED FIELD
184        RET             ;GO INSERT CURSOR
185LFEED:  LXI  H,CURLIN
186BMPC1:  INR  M
187        LDA  LPAGE      ;MAX LINES/PAGE
188        CMP  M          ;EXCEED MAX?
189        RP
190        DCR  M          ;LEAVE AT LAST LINE
191;********************************************
192;SCROLL UP OR WRAP AROUND AS SET BY CTRLC
193;********************************************
194SCROLL: LDA  CTRLC      ;KIND OF SCROLL?
195        ANI  8CH        ;LEAVE SCROLL AND MODE BITS
196        JM   SCR3       ;WRAP AROUND
197        CPI  0CH        ;GRAPHICS MODE
198        JNZ  SCR1       ;NO, ALLOW SCROLL
199SCR3:   XRA  A
200        MOV  M,A        ;HOME CURSOR FOR WRAP AROUND
201        INX  H
202        MOV  M,A
203        RET
204SCR1:   LHLD CLINE      ;COLS/LINE
205        PUSH H          ;SAVE COLS/LINE
206        XCHG
207        LHLD NCHARS     ;# CAHRS PER PAGE
208        MOV  A,L
209        SUB  E
210        MOV  C,A
211        MOV  B,H
212        XCHG
213        LXI  D,REFRESH
214        DAD  D          ;HL=SOURCE,DE=DEST.
215        CALL MVCUP
216SCR2:   JMP  DLN1       ;ERASE CURRENT LINE AND RETURN
217;******************************
218;PROCESS CONTROL CODES
219;******************************
220CONTROL:XCHG            ;D,E=CCHR PTR
221        LHLD USRCTR     ;USER TABLE IF ANY
222        MOV  A,H
223        ORA  A
224        LDAX D          ;CCHAR IN A
225        JZ   NOUSER     ;NO TABLE USER DEFINED
226        CALL LOOKUP
227        JNZ  FNDCTRL    ;FOUND TABLE ENTRY
228NOUSER: LDA  CCHAR
229        LXI  H,CTRTBL
230        CALL LOOKUP
231        JZ   BMP1       ;NOT FOUND
232FNDCTRL:LXI  D,BMP10    ;RETURN ADDRESS
233        PUSH D          ;ON STACK
234        LXI  D,CURCOL
235        PCHL
236;****************************************
237;PROCESS ESCAPE SEQUENCES
238;****************************************
239ESCAPE: LXI  D,BMP10    ;RETURN ADDR
240        PUSH D
241        XCHG
242        LXI  H,ESCCNT
243        MOV  A,M        ;ESCCAPE COUNT
244        INR  M          ;ESCCNT=ESCCNT+1
245        ORA  A
246        RZ
247        DCR  A
248        INX  H
249        LDAX D          ;GET CCHAR
250        JNZ  ESC1       ;ESCCNT>1
251        MOV  M,A        ;SAVE ESCAPE CODE
252ESC1:   LHLD USRESC     ;USER ESCAPE TABLE PTR
253        MOV  A,H
254        ORA  A
255        LDAX D          ;ESCCODE
256        JZ   NUESC      ;NO USER DEFINED TABLE
257        CALL LOOKUP     ;LOOKUP IN USERS TABLE
258        JNZ  FNDESC     ;FOUND ESCAPE SEQ IN USER
259NUESC:  LDA  ESCCDE     ;TRY AGAIN IN VIO TABLE
260        ANI  0DFH       ;REMOVE LOWER CASE BIT
261        LXI  H,ESCTBL
262        CALL LOOKUP
263        JZ   ESCRET     ;NOT FOUND
264FNDESC: LDA  CTRLC
265        LXI  D,SETCMD
266        PCHL
267;************************
268;CURSOR CONTROL
269;************************
270UPLINE: DCX  D          ;D,E=CURLIN PTR
271BCKLNE: LDAX D          ;D,E=CURLIN OR CURCOL
272        ORA  A          ;SET FLAGS
273        RZ
274        DCR  A          ;BACK UP 1
275BCKL1:  STAX D
276        RET
277CRET:   XRA  A
278        STA  INSRT      ;REMOVE INSERT MODE
279        JMP  BCKL1
280;**********************************
281;TOGGLE PROTECTED MODE FLAG
282;**********************************
283PRTECT: LXI  H,PRTMD    ;PT AT FLAG
284        JMP  INSMDE+3   ;GO TOGGLE IT
285;*************************************
286;TOGGLE INSERT MODE FLAG
287;*************************************
288INSMDE: LXI  H,INSRT
289        MOV  A,M
290        CMA
291        MOV  M,A
292        RET
293;***********************
294;BLANK SCREEN AND HOME
295;***********************
296BLNKS:  LHLD NCHARS     ;#CHARS ON SCREEN
297        XCHG
298        LXI  H,REFRESH
299BLNK1:  LDA  PRTMD      ;IN PROTECTED MODE?
300        ANI  80H
301        ANA  M          ;PROTECTED?
302        JM   BLNK2      ;IS PROTECTED, DO NOT BLANK
303        MVI  M,' '
304BLNK2:  INX  H
305        DCX  D
306        MOV  A,D
307        ORA  E          ;DONE YET?
308        JNZ  BLNK1      ;NO
309HOME:   LXI  H,0
310        SHLD CURLIN
311        RET
312;***********************************************
313;BLANK FROM CURSOR TO END OF UNPROTECTED FIELD
314;***********************************************
315BLANKL: CALL CHARLN     ;CALC # CHARS TO END OF FIELD
316BLAN3:  LDA  PRTMD      ;PROTECTED MODE?
317        ORA  A
318        JZ   BLAN1      ;NOT PROTECTED,SKIP CHECK
319        MOV  A,M        ;GET CHAR
320        ORA  A
321        JM   BLAN1+3    ;IS PROTECTED,DO NOT BLANK
322BLAN1:  MVI  A,' '
323        MOV  M,A        ;INSERT BLANK
324        INX  H          ;NEXT CHAR
325        DCR  C          ;COUNT
326        JNZ  BLAN3
327        RET
328;**********************************************
329;TURN ON PROTECTED FIELD/TURN OFF PROT FIELD
330;**********************************************
331PROTC:  LXI  H,INVIDIO  ;PT AT INVERTED VIDIO FLAG
332        JMP  INSMDE+3
333;****************************************************
334;DELETE CHAR AND SHIFT PROTECTED FIELD LEFT ONE PLACE
335;****************************************************
336DELETE: CALL CHARLN
337        LHLD CURPTR     ;CURSOR POSITION
338        MOV  D,H
339        MOV  E,L
340        INX  H
341        CALL MVCUP      ;SHIFT LINE LEFT ONE PLACE
342        MVI  A,' '
343        DCX  D          ;BACK UP ONE
344        STAX D          ;INSERT FINAL BLANK
345        RET
346;**********************************************************
347;CALC # CHARS FROM CURSOR TO END OF UNPROT FIELD INCLUSIVE
348; RETURN H,L=CURSOR PTR
349;**********************************************************
350CHARLN: LDA  PRTMD      ;PROTECT MODE FLAG
351        ANI  80H
352        MOV  D,A        ;SAVE PROTECT MODE BIT
353        LHLD CURPTR     ;CURSOR POSITION
354        PUSH H
355        LDA  CURCOL
356        MOV  E,A        ;E=CURRENT COLUMN
357        LXI  B,0        ;# CHARS TO END
358CHRL1:  LDA  CLINE      ;COLS/LINE
359        SUB  E
360        INR  E
361        INX  H
362        INR  C          ;COUNT INCREASED
363        DCR  A          ;DNE YET WITH LINE
364        JZ   CHRL2      ;END OF LINE RETURN
365        MOV  A,M        ;H,L=END +1
366        ANA  D          ;PROTECTED?
367        JP   CHRL1      ;NO, KEEP GOING
368CHRL2:  POP  H          ;CURSOR POSITION
369        RET
370;*******************************************************************
371;TABLE LOOK UP ROUTINE. SEARCHES FIRST BYTE OF THREE BYTE TABLE OF
372;RECORDS FOR A MATCH OR ZERO. ZERO INDICATES END OF TABLE WITH NO
373;MATCH, RETURNED IN A REG.H,L LOADED WITH SECOND TWO BYTES OF TABLE
374;IF MATCH FOUND.
375;*******************************************************************
376LOOKUP: MOV  B,A        ;SAVE
377        MOV  A,M        ;GET FIRST BYTE OF RECORD
378        LXI  D,CURLIN
379        ORA  A
380        RZ              ;DONE,NO MATCH
381        CMP  B          ;SAME AS REQUESTED?
382        JNZ  TBLUP1     ;NO
383        INX  H
384        MOV  E,M
385        INX  H
386        MOV  D,M
387        XCHG
388        ORA  A          ;SET FLAGS
389        RET
390TBLUP1: INX  H
391        INX  H
392        INX  H          ;BUMP TO NEXT RECORD
393        JMP  LOOKUP+1   ;
394;*************************************************
395;DELETE CURRENT LINE AND RETURN CURSOR
396;*************************************************
397DLINE:  CALL NMCHM      ;SET UP FOR MOVE
398        PUSH H          ;SAVE COLS/LINE
399        DAD  D          ;H,L=SOURCE BEGIN
400        CALL MVCUP
401DLN1:   POP  B          ;COLS/LINE
402        XCHG
403        JMP  EN1        ;ERASE LINE
404;***********************************************
405;ENTER NEW LINE AT CURSOR LINE,PUSH BOTTOM DOWN
406;***********************************************
407ENLINE: CALL NMCHM      ;SET UP FOR MOVE
408        PUSH H          ;SAVE COLS/LINE
409        DAD  D          ;H,L=SOURCE BEGIN
410        DAD  B          ;H,L=END OF DEST+1
411        XCHG
412        DAD  B          ;H,L=END OF SOURCE+1
413        DCX  H
414        DCX  D
415        CALL MVCDN      ;MOVE DOWN 1 LINE
416        POP  B
417        INX  H
418EN1:    MVI  M,' '
419        INX  H
420        DCR  C
421        JNZ  EN1
422        RET
423NMCHM:  XRA  A
424        STAX D          ;COL=0
425        CALL CHARSN     ;#CHARS TO END OF SCREEN
426        XCHG            ;D,E=DEST.
427        LHLD CLINE      ;COLS/LINE
428        MOV  A,L        ;COLS/LINE
429        DCX  B
430        DCR  A
431        JNZ  $-2        ;DECREASE COUNT BY ONE LINES WORTH
432        RET
433;********************************************
434;CALC # CHARS TO END OF SCREEN FROM CURSOR
435;********************************************
436CHARSN: CALL CALPOS
437        PUSH H          ;SAVE
438        XCHG            ;D,E=CURSOR POS
439        LHLD LASTC      ;LAST CHAR POSITION+1
440        MOV  A,D
441        CMA
442        MOV  D,A
443        MOV  A,E
444        CMA
445        MOV  E,A
446        INX  D          ;COMPLIMENT D,E
447        DAD  D          ;H,L=# CHARS TO END-1
448        PUSH H
449        POP  B          ;B,C=#CHARS TO END
450        POP  H          ;CURRENT POSITION CURSOR
451        RET
452;************************
453;ESCAPE CODE PROCESSING
454;************************
455HIGH128:ANI  0F3H
456        ORI  4H
457        XCHG            ;H,L=SETCMD ADDR
458        PCHL
459;GRAPHIC MODE 256 CHAR ROM,NO INVERSE VIDIO
460GRAPHIC:ORI  0CH
461        XCHG            ;H,L=SETCMD ADDR
462        PCHL
463;LOWER HALF OF ROM+REVERSE VIDIO
464LOW128: ANI  0F3H
465        ORI  8H
466        XCHG            ;H,L=SETCMD ADDR
467        PCHL
468;SCROLL TOGGLE
469SCRL:   XRI  80H
470        XCHG            ;H,L=SETCMD ADDR
471        PCHL
472;UPPER LOWER CASE TOGGLE
473UPLOW:  XRI  20H
474        XCHG            ;H,L=SETCMD ADDR
475        PCHL
476;INVERSE VIDIO TOGGLE
477VIDIO:  XRI  10H
478        XCHG            ;H,L=SETCMD ADDR
479        PCHL
480;# LINES PER PAGE SWITCH
481LINES:  XRI  02H
482        XCHG            ;H,L=SETCMD ADDR
483        PCHL
484;#COLS/LINE TIGGLE
485COLS:   XRI  01H
486        XCHG            ;H,L=SETCMD ADDR
487        PCHL
488;**************************************
489;INSERT CURSOR CHAR AT PROPER POSITION
490;**************************************
491INSCURS:LHLD CURPTR
492        MOV  A,M
493        STA  CCUR       ;SAVE CHAR UNDER CURSOR FOR GRAPHICS MODE
494        ORI  80H        ;BIT 7 FOR INVERSE VIDIO
495        MOV  M,A        ;STORE BACK
496        LDA  VDIMDE
497        ORA  A
498        RNZ             ;NO GRAPHICS
499        MVI  M,7FH      ;BLOCK FOR GRAPHICS MODE
500        RET
501;*****************************************
502;CLEAR TABS
503;*****************************************
504CLRTBS: LXI  H,TAB      ;TABS BITS
505        MVI  B,10       ;#BYTES FOR TABS
506        XRA  A
507CLRT1:  MOV  M,A
508        INX  H
509        DCR  B
510        JNZ  CLRT1
511        JMP  ESCRET     ;PUT IN CURSOR
512;***********************************
513;SET OR CLEAR TAB TOGGLE BIT
514;***********************************
515SETTAB: CALL FNDTB
516        XRI  80H        ;INVERT TAB BIT
517SETD2:  RRC
518        DCR  B
519        JNZ  SETD2
520        STAX D          ;STORE TAB BYTE
521        JMP  ESCRET     ;DO CURSOR
522;FIND TAB BIT, LEAVE IN A REG BIT 7
523FNDTB:  LDA  CURCOL     ;COL #
524        MOV  H,A
525        INR  H
526        LXI  D,TAB      ;WORD PTR
527FNDT1:  MVI  C,8        ;BIT COUNTER
528        DCR  H
529        JZ   FNDTDN     ;FOUND IT
530        DCR  C          ;BIT COUNTER
531        JNZ  FNDT1+2
532        INX  D          ;PT AT NEXT BYTE
533        JMP  FNDT1
534FNDTDN: LDAX D          ;GET TAB BYTE BITS
535        MOV  B,C        ;SAVE COUNT OF BITS
536FNDT2:  RLC
537        DCR  C
538        JNZ  FNDT2      ;ROTATE UNTIL FOUND
539        RET
540;*****************************************************************
541;TAB TO BEGINNING OF NEXT UNPROTECTED FIELD OR TAB OR HOME IF NONE
542;*****************************************************************
543TABB:   XRA  A
544        STA  PRUPRF     ;PROTECT/UNPROTECT TRANSITION FLAG
545TAB3:   CALL BMPC       ;BUMP CURSOR POSITION
546        JNZ  TAB1       ;NO LINE FEED NECESSARY
547        INR  M          ;BUMP LINE #
548        CMP  M          ;EXCEED LPAGE?
549        JM   SCR3       ;YES,HOME AND RETURN
550TAB1:   LDA  PRTMD      ;PROTECT MODE FLAG
551        XCHG            ;H,L PTS AT CHAR
552        ANA  M          ;PROTECTED?
553        MOV  A,M        ;GET CHAR
554        LXI  D,PRUPRF   ;TRANSITION FLAG
555        JP   TAB2       ;NO PROTECTED FIELD
556        STAX D          ;SET TRANSITION FLAG
557        JMP  TAB3
558TAB2:   LDAX D          ;GET TRANSITION FLAG
559        ORA  A
560        RM              ;UNPROT FIELD WITH TRANSITION
561        CALL FNDTB      ;FIND TAB POSITION BIT
562        ORA  A          ;SET FLAGS
563        RM              ;TAB IS SET
564        JMP  TAB3
565;**************************************************
566;CALCULATE CURSOR POSITION FROM CURLIN AND CURCOL
567;**************************************************
568CALPOS: LHLD CLINE      ;CHARS/LINE-1
569        XCHG
570        LHLD CURLIN     ;L=CURLIN,H=CURCOL
571        MOV  C,H
572        MOV  B,L
573        LXI  H,REFRESH  ;BOTTOM OF REFRESH MEMORY
574        INR  B
575CALP1:  DCR  B          ;DONE YET
576        JZ   CALP2      ;YES
577        DAD  D          ;ADD ANOTHER LINE OF CHARS
578        JMP  CALP1
579CALP2:  DAD  B          ;ADD CURRENT COL
580        SHLD CURPTR     ;SAVE
581        RET
582;**********************************************************
583;BMPC BUMP CURSOR 1 PLACE. ON RETURN
584; D,E=CURSOR POSITION
585; H,L=CURCOL PTR OR CURLIN PTR DEPENDING ON Z FLAG
586; Z FLAG=0 IF NO LINE FEED NEEDED,1 IF LINE FEED NEEDED
587; CURLIN AND CURCOL AND CURPTR ARE UPDATED AS IF LINE FEED
588; A REG =LPAGE IF LINE FEED NEEDED
589;**********************************************************
590BMPC:   LHLD CURPTR
591        INX  H
592        SHLD CURPTR     ;UPDATE ABS CURSOR ADDRESS
593        XCHG            ;D,E=PTR
594        LXI  H,CURCOL
595        INR  M          ;BUMP COLUMN
596        LDA  CLINE      ;MAX COLS/LINE
597        SUB  M          ;ZERO IF EXCEED LINE
598        RNZ             ;OK AS IS
599        MOV  M,A        ;COL=0
600        DCX  H
601        LDA  LPAGE      ;MAX LINES/PAGE
602        RET
603;************************************************
604;ADDRESSABLE CURSOR FUNCTION
605;************************************************
606ADDCURS:LXI  H,ESCCNT   ;PT AT ESCAPE COUNT
607        LXI  D,CURLIN   ;PT AT CURRENT LINE COUNT
608        LDA  CCHAR
609        SUI  20H        ;REMOVE OFFSET FOR COUNT
610        MOV  B,A
611        MOV  A,M        ;GET COUNT
612        SUI  3
613        RM              ;NO VALID NUMBS YET
614        JNZ  XADD       ;X AXIS VALUE
615;Y-AXIS VALUE
616        LDA  LPAGE
617XADD3:  STAX D          ;MAX LINE #
618        CMP  B
619        RM
620        MOV  A,B
621        STAX D
622        RET
623XADD:   MVI  M,0        ;ESCCNT=0
624        LDA  CLINE      ;MAX COL/LINE
625        INX  D
626        DCR  A
627        JMP  XADD3
628;************************************************************
629;INSERT CHAR AT CURSOR POSITION.EITHER WRITES OVER PREVIOS
630;CHAR OR PUSHES ENTIRE FIELD OVER ONE CHAR BEFORE INSERTING.
631;************************************************************
632INSCHR: LHLD CURPTR     ;CURSOR ADDRESS
633        PUSH H          ;SAVE
634        LDA  INSRT      ;INSERT FLAG
635        ORA  A
636        JZ   INSC3      ;OVERWRITE
637        CALL CHARLN
638        DCX  B          ;3CHARS-1 TO END
639        DAD  B          ;H,L PTS AT LAST CHAR ON LINE
640        MOV  D,H
641        MOV  E,L
642        DCX  D          ;D,E PTS AT SOURCE
643        XCHG            ;H,L=SOURCE,D,E=DEST
644        CALL MVCDN      ;MOVE CHARS RIGHT
645INSC3:  POP  H          ;CURSOR POSITION
646        LDA  INVIDIO
647        ANI  80H
648        MOV  B,A        ;INVERT BIT
649        LDA  CCHAR
650        ORA  B          ;MERGE WITH INVERT BIT
651INSC4:  MOV  M,A
652        RET
653;********************************************************
654;SHIFT CHARS RIGHT FROM D,E TO H,L,  B,C CHARS FROM RIGHT
655;********************************************************
656MVCDN:  MOV  A,C
657        ORA  B
658        RZ              ;DONE
659        MOV  A,M
660        STAX D
661        DCX  H
662        DCX  D
663        DCX  B
664        JMP  MVCDN
665;CONTROL FUNCTION JUMP TABLE
666CTRTBL  EQU  $
667        DB   0DH        ;CARRIAGE RETURN
668        DW   CRET
669        DB   0AH        ;LINE FEED
670        DW   LFEED
671        DB   0BH        ;UP CURSOR (CTRL K)
672        DW   UPLINE
673        DB   0CH        ;FORWARD CURSOR (CTRL L)
674        DW   BMPCUR
675        DB   08H        ;BACK CURSOR (CTRL H)
676        DW   BCKLNE
677        DB   1EH        ;HOME CURSOR (CTRL ^)
678        DW   HOME
679        DB   1AH        ;SCREEN ERASE (CTRL Z)
680        DW   BLNKS
681        DB   15H        ;CLEAR TO EOL (CTRL U)
682        DW   BLANKL
683        DB   16H        ;PROTECTED FIELDS (CTRL V)
684        DW   PROTC
685        DB   09H        ;TAB (CTRL I)
686        DW   TABB
687        DB   7FH        ;DELETE CHAR (RUBOUT)
688        DW   DELETE
689        DB   14H        ;INSERT MODE (CTRL T)
690        DW   INSMDE
691        DB   04H        ;DELETE LINE CTRL D
692        DW   DLINE
693        DB   05H        ;INSERT LINE (CTRL E)
694        DW   ENLINE
695        DB   10H        ;PROTECTED MODE TOGGLE (CTRL P)
696        DW   PRTECT
697        DB   0          ;TERMINATOR
698;ESCAPE FUNCTION JUMP TABLE
699ESCTBL  EQU  $
700        DB   1DH        ;CURSOR CONTROL ('=' LESS BIT 5 LOWER CASE)
701        DW   ADDCURS
702        DB   49H        ;SET TAB
703        DW   SETTAB
704        DB   09H        ;CLEAR TABS
705        DW   CLRTBS
706        DB   'T'        ;LOWER 128 BYTES OF ROM
707        DW   LOW128
708        DB   'E'        ;EXTENDED MODE UPPER 128
709        DW   HIGH128
710        DB   'G'        ;GRAPHIC SET
711        DW   GRAPHIC
712        DB   'S'        ;SCROLL TOGGLE
713        DW   SCRL
714        DB   'U'        ;UPPER/LOWER CASE
715        DW   UPLOW
716        DB   'V'        ;INVERSE VIDIO TOGGLE
717        DW   VIDIO
718        DB   'L'        ;LINES/PAGE
719        DW   LINES
720        DB   'C'        ;COLS/LINE
721        DW   COLS
722        DB   0          ;TERMINATOR
723;*******************************************************
724;8085 MONITOR PROGRAM USING THE VIO FIRMWARE
725; COPYRIGHT IMSAI MANUFACTURING COMPANY, INC.
726; SAN LEANDRO,CALIFORNIA
727; 6/7/77
728;*******************************************************
729MONT:   LXI  SP,REFRESH+7FFH ;TOP OF MEMORY
730        MVI  A,0AAH
731        OUT  3
732        CMA
733        OUT  3
734        CMA
735        OUT  3
736        MVI  A,27H
737        OUT  3          ;SET UP USART
738        CALL INIT       ;INIT VIO
739        LXI  H,SIGNON
740        CALL MSGNC      ;SIGNON MSG
741PRMPT:  LXI  SP,REFRESH+7FFH
742        CALL CRLF
743        MVI  A,'?'
744        CALL CHAROUT
745        CALL CHIN       ;GET COMMAND
746        MOV  B,A        ;SAVE IT
747        LXI  D,PRMPT
748        PUSH D          ;RETURN ADDRESS
749        LHLD USERCMD    ;USER COMMAND TABLE
750        MOV  A,H
751        ORA  A          ;SET FLAGS
752        MOV  A,B        ;RETRIEVE CODE
753        JZ   NUCMD      ;NO USER COMMAND TABLE
754        CALL LOOKUP     ;LOOKUP IN USER TABLE
755        JNZ  FNDCMD     ;FOUND COMMAND
756NUCMD:  MOV  A,B        ;GET COMMAND AGAIN
757        LXI  H,CMDTBL   ;COMAND TABLE PTR
758        CALL LOOKUP
759        RZ              ;NO  ENTRY,PROMPT AGIN
760        MVI  B,1        ;FOR PROT/UNPROT
761FNDCMD: PCHL            ;GO TO ROUTINE
762SIGNON: DB   'IMSAI SMP/80.0',0
763        DB   'COPYRIGHT 6/77'
764;*************************************************
765;JUMP TO MEMORY "JAAAA"
766;CALL MEMORY WITH RETURN TO MONITOR
767;*************************************************
768JUMP:   POP  D          ;REMOVE RETURN ADDRESS
769CALL1:  CALL IHEX       ;GET JUMP ADDRESS
770        PCHL            ;DO IT
771;******************************************************
772;ENTER BYTE INTO MEMORY AND MODIFY IF DESIRED
773;******************************************************
774ENTR:   CALL IHEX       ;START ADDR
775        CALL CRLF
776        CALL OHEXHL     ;DISPLAY ADDRESS
777        MOV  A,M        ;GET BYTE IN MEMORY
778        MOV  E,A        ;PRESET FOR IHEX
779        CALL OHEXB      ;DISPLAY BYTE
780        XCHG            ;D,E=ADDRESS,L=DEFAULT CHAR
781        CALL IHEX+3     ;GET MODIFIER OR DEFAULT
782        XCHG            ;H,L=ADDR,E=BYTE
783        MOV  M,E
784        DCX  H
785        CPI  0AH        ;DONE?
786        RZ              ;YES
787        CPI  '-'        ;BACKWARD
788        JZ   ENTR+3     ;YES
789        INX  H
790        INX  H          ;DEFAULT FORWARD
791        JMP  ENTR+3
792;*****************************************************
793;DISPLAY MEMORY "D,START,END CR"
794;*****************************************************
795DISP:   CALL SIZE       ;H,L=START,B,C=SIZE
796        LDA  CTRLC      ;#LINES/COLS
797        RRC             ;#LINES BIT IN CARRY
798        RRC
799        MVI  D,12
800        JC   $+5
801        MVI  D,24
802DISP2:  CALL CRLF
803        IN   3
804        ANI  2          ;ANY INPUT
805        RNZ             ;YES,INTERRRUPT
806        MVI  E,8
807        LDA  CTRLC
808        RRC
809        JC   $+5
810        MVI  E,16
811        CALL OHEXHL     ;OUTPUT ASCII H,L REG
812DISP1:  MOV  A,M        ;GET DATA BYTE
813        CALL OHEXB      ;OUTPUT WITH TRAIL BLANK
814        INX  H
815        DCX  B
816        MOV  A,B
817        ORA  C
818        RZ              ;DONE
819        DCR  E
820        JNZ  DISP1      ;KEEP WITH CURRENT LINE
821        DCR  D          ;FILLED PAGE YET?
822        JNZ  DISP2
823        CALL CHIN       ;WAIT FOR PAGE PROMT
824        JMP  DISP+3
825;*********************************
826;ALLOW ESCAPE SEQUENCES TO CONTROL
827;*********************************
828ESCCO:  CALL CHIN       ;READ ESCAPE SEQUENCE CODE
829        RET
830;********************************
831;OUTPUT HEX WITH TRAILING BYTE
832;********************************
833OHEXB:  CALL OHEX
834        MVI  A,' '
835        CALL CHAROUT
836        RET
837;*********************************
838;OUTPUT 16 BIT ASCII HEX FROM H,L
839;*********************************
840OHEXHL: MOV  A,H
841        CALL OHEX
842        MOV  A,L
843        CALL OHEXB
844        RET
845;*******************************************
846;PROTECT /UNPROTECT RAM4A-4 MEMORY
847;*******************************************
848PROT:   INR  B          ;PROTECT/UNPROTECT FLAG
849UNPRT:  CALL PARM2      ;GET START,END ADDRESSES IN H,L D,E
850MEMP:   MOV  A,D
851        ANI  0FCH       ;GET 1K OFFSET ONLY
852        ORA  B
853        MOV  D,A
854        MOV  A,H
855        ANI  0FCH
856        ORA  B
857PROT1:  OUT  0FEH       ;DO IT
858        CMP  D          ;DONE?
859        RZ              ;YES
860        ADI  4          ;SET FOR NEXT 1K BLOCK
861        JMP  PROT1
862;**************************************************
863;INTEL LOADER LOADS INTEL FORMAT TAPES FROM
864;TELETYPE (PORT 2,3)
865;**************************************************
866INTEL:  CALL CHIN       ;READ WITHOUT ECHO
867        SBI  ':'        ;RCORD MARKER?
868        JNZ  INTEL      ;NO
869        MOV  D,A        ;ZERO CHECKSUM
870        CALL IBYTE      ;INPUT 2 HEX CHARS
871        ORA  A          ;SET FLAGS
872        RZ              ;COUNT =0 MEANS END
873        MOV  D,A        ;BYTE COUNT
874        CALL IBYTE
875        MOV  H,A
876        CALL IBYTE
877        MOV  L,A
878        CALL IBYTE      ;DUMMY RECORD TYPE IGNORED
879DATA:   CALL IBYTE
880        MOV  M,A
881        INX  H
882        DCR  D
883        JNZ  DATA
884        CALL IBYTE      ;READ AND ADD CHECKSUM
885        JZ   INTEL      ;OK AS IS
886        MVI  A,'C'
887        CALL CHAROUT    ;ERROR MESSAGE
888        RET
889;********************************************
890;READ 2 ASCII HEX BYTES AND CONVERT TO BINARY
891;********************************************
892IBYTE:  CALL CHIN       ;READ CHAR
893        CALL ASBI       ;CONVERT TO BINARY
894        JC   ERR2
895        ADD  A
896        ADD  A
897        ADD  A
898        ADD  A
899        MOV  E,A        ;SAVE
900        CALL CHIN
901        CALL ASBI
902        JC   ERR2       ;INVALID ASCII HEX CHAR
903        ADD  E
904        MOV  E,A        ;SAVE CHAR
905        ADD  D          ;ADD TO CHECKSUM
906        MOV  D,A
907        RET
908;*************************************************
909;SIZE INPUTS START,END ADDR AND CONVERTS TO START
910;  AND SIZE IN H,L AND B,C
911;*************************************************
912SIZE:   CALL PARM2      ;H,L=START D,E=END
913        PUSH PSW
914        MOV  A,E
915        SUB  L          ;LOW BYTE SIZE
916        MOV  C,A
917        MOV  A,D
918        SBB  H          ;HIGH BYTE SIZE
919        MOV  B,A
920        INX  B          ;ADD 1
921        POP  PSW
922        RET
923;***********************************************
924;MEMORY MOVE "M SOURCE BEG,SOURCE END,DEST BEG"
925;***********************************************
926MOVE:   CALL PARM4      ;START,END,DEST
927MOVE1:  CALL MVCUP      ;DO MOVE
928        RET
929;******************************
930;FILL MEMORY WITH CHAR
931;******************************
932FILL:   CALL PARM4      ;START,END,FILL CHAR IN L
933        MOV  A,E        ;FILL CHAR
934        MOV  M,A        ;STORE IN FIRST LOCATION
935        DCX  B
936        MOV  D,H
937        MOV  E,L        ;DEST ADDR
938        INX  D          ;=START ADDR+1
939        JMP  MOVE1
940;*******************************
941;MEMORY TEST ROUTINE
942;*******************************
943MEMTEST:CALL SIZE       ;H,L=START,B,C=SIZE
944        DCX  B          ;B,C=SIZE-1 OR 0
945MEM2:   XRA  A
946        MOV  D,M        ;SAVE CELL
947MEM1:   MOV  M,A
948        CMP  M
949        JNZ  MEMERR     ;NOT GOOD
950        DCR  A          ;NEXT PATTERN
951        JNZ  MEM1
952        MOV  M,D        ;RESTORE MEMORY
953        IN   3
954        ANI  2          ;BAIL OUT?
955        RNZ             ;YES
956        INX  H
957        DCX  B
958        MOV  A,B
959        ORA  C
960        JNZ  MEM2
961        RET
962MEMERR: INX  H          ;ADJUST FOR PRNMEM
963        MOV  E,A        ;SAVE
964        CALL PNTMEM     ;PRINT ADDR,CONTENTS
965        MOV  A,E        ;RESTORE
966        JMP  SRCP1      ;PRINT SOULD BE
967;******************************************
968;DO DIRECT INPUT/OUTPUT FROM SPECIFIED PORT
969;******************************************
970INPORT: DCR  B          ;B=0=INPUT,B=1=OUTPUT
971OUTPORT:CALL PARM2      ;INPUT PORT,VALUE IN H,L AND D,E
972        MOV  A,B        ;FLAG
973        RLC
974        RLC
975        RLC
976        XRI  08H        ;INVERT BIT 3
977        ORI  0D3H       ;FORM I/O INST
978        MOV  D,L
979        LHLD RAMPTR     ;GET AVAIL RAM PTR
980        MOV  M,A
981        CMP  M
982        RNZ             ;INVALID RAM
983        PUSH H
984        INX  H
985        MOV  M,D        ;PORT #
986        INX  H
987        MVI  M,0C9H     ;RETURN
988        LXI  H,IORET
989        XTHL            ;PUT RETURN ADDRESS,GET START ADDR
990        MOV  A,B
991        ORA  A          ;SET FLAG FOR IN OR OUT
992        MOV  A,E        ;OUTPUT BYTE
993        PCHL
994IORET:  RNZ             ;DONE IF OUTPUT INST
995        CALL OHEXB      ;PRINT VALUE IF INPUT
996        RET
997;************************************
998;SET FREE RAM PTR FOR DIRECT IO INSTS
999;************************************
1000RAMFND: CALL IHEX       ;GET RAM ADDR
1001        SHLD RAMPTR     ;SAVE IN VIO RAM
1002        RET
1003;************************************************
1004;COMPARE MEMORY BLOCKS AND PRINT DIFFERENCES
1005;************************************************
1006CMPBLK: CALL PARM4      ;START,SIZE,DEST IN HL BC,DE
1007CMPB1:  LDAX D          ;DEST BYTE
1008        CMP  M          ;SAME AS SOURCE BYTE?
1009        INX  H
1010        INX  D
1011        JZ   CMPB2      ;YES, NO PRINT
1012        CALL PNTMEM     ;PRINT ADDR,SOURCE DEST
1013        XCHG
1014        CALL PNTMEM+3   ;NO CRLF
1015        XCHG
1016CMPB2:  DCX  B
1017        MOV  A,B
1018        ORA  C
1019        RZ              ;YES,RETURN
1020        IN   3
1021        ANI  2
1022        RNZ             ;BAIL OUT
1023        JMP  CMPB1
1024;*****************************************
1025;SEARCH MEMORY FOR MASKED 16 BIT VALUE
1026;S,FROM,TO,16BIT VALUE,16 BIT MASK
1027;*****************************************
1028SEARCH: CALL PARM4      ;START,SIZE,VALUE IN H,L B,C D,E
1029        PUSH H          ;SAVE
1030        LXI  H,-1       ;DEFAULT MASK ALL
1031        CPI  0AH        ;USER SPECIFIED MASK?
1032        CNZ  IHEX       ;YES,READ IT INTO H,L
1033        XTHL            ;MASK ON STACK,START IN H,L
1034SEAR1:  MOV  A,M        ;LOW BYTE
1035        XTHL            ;H,L=MASK VALUE
1036        ANA  H          ;MASK HIGH BYTE
1037        CMP  D          ;IS IT CORRECT VALUE?
1038        XTHL            ;RESTORE START PTR
1039        INX  H          ;BUMP PTR
1040        JNZ  CMP16      ;NO MATCH
1041        MOV  A,M        ;LOW BYTE
1042        XTHL            ;GET MASK IN H,L
1043        ANA  L
1044        CMP  E
1045        XTHL            ;H,L=START,STACK=MASK
1046        CZ   SRCPNT     ;PRINT MATCH IF FOUND
1047CMP16:  DCX  B
1048        MOV  A,B
1049        ORA  C
1050        JNZ  SEAR1
1051        POP  B          ;REMOVE MASK VALUE
1052        RET
1053;**************************************************
1054;PARM4 INPUTS START,END,VALUE AND
1055;CONVERTS TO START,SIZE,VALUE IN H,L B,C AND D,E
1056;RESPECTIVELY
1057;**************************************************
1058PARM4:  CALL SIZE
1059        JMP  PARM3
1060;************************************************
1061;MVCUP MOVE B,C CHARS FROM H,L TO D,E FROM BOTTOM
1062;************************************************
1063MVCUP:  MOV  A,B
1064        ORA  C
1065        RZ
1066        MOV  A,M
1067        STAX D          ;MOVE IT
1068        DCX  B
1069        INX  H
1070        INX  D
1071        JMP  MVCUP      ;KEEP GOING
1072;**************************************************
1073;LOAD OR EXECUTE CASETTE FILE USING HEADER OR
1074;USER SPECIFIED START,END,EXEC ADDRESSES
1075;**************************************************
1076EXEC:   DCR  B          ;EXECUTE FLAG
1077LOAD:   PUSH B          ;SAVE EXEC/LOAD FLAG
1078        CALL PARM2      ;ANY PARMS SPECIFIED?
1079        MOV  A,D
1080        ORA  E
1081        JZ   HEADER     ;NO PARMS,OR NOT ENOUGH PARMS
1082;SKIP HEADER IF PRESENT
1083        PUSH H          ;START
1084        PUSH D          ;END
1085        CALL IHEX       ;GET EXEC IF ANY
1086        PUSH H          ;EXEC ADDR
1087        CALL RDHEAD     ;READ HEADER IF THERE
1088        JNZ  RDRCRDS    ;NOT THERE DO OBJECT
1089        POP  PSW
1090        POP  PSW
1091        POP  PSW        ;REMOVE HEADER PARMS
1092        JMP  RDRCRDS    ;DO OBJECT
1093HEADER: CALL RDHEAD     ;READ HEADER
1094ERR2:   MVI  A,'T'      ;TYPE CODE ERROR
1095        JZ   RDRCRDS    ;NO ERROR
1096ERR1:   CALL CHAROUT
1097        JMP  PRMPT      ;BAIL OUT
1098RDRCRDS:POP  B          ;EXEC
1099        POP  H          ;END
1100        POP  D          ;START
1101        PUSH B          ;RETURN EXEC ADDR
1102        PUSH H          ;END
1103        PUSH D          ;START
1104        MOV  A,L
1105        SUB  E
1106        MOV  L,A
1107        MOV  A,H
1108        SBB  D
1109        MOV  H,A
1110        DAD  H
1111        MOV  C,H
1112        INR  C          ;RECORD COUNT TO READ
1113RDRCO:  CALL CASIN      ;TYPE CODE
1114RDRC1:  CPI  81H        ;ABS BINARY?
1115        JNZ  ERR2       ;TYPE CODE ERROR
1116        CALL CASIN      ;BYTE COUNT
1117        MOV  B,A        ;SAVE RECORD BYTE COUNT
1118        LXI  H,0        ;0 CHECKSUM
1119RDATA:  CALL CAINCK     ;READ DATA BYTE
1120        STAX D          ;STORE IT
1121        INX  D
1122        DCR  B
1123        JNZ  RDATA      ;CONTINUE IF NOT DONE
1124        PUSH D          ;SAVE MEMORY PTR
1125        XCHG            ;DE=CHECKSUM
1126        CALL CASWD      ;READ TAPE CHECKSUM
1127        MOV  H,L
1128        MOV  L,A        ;REVERSE BYTES
1129        DAD  D          ;ADD TO COMPUTED CHECKSUM
1130        MOV  A,H
1131        ORA  L
1132        MVI  A,'C'      ;CHECKSUM ERROR
1133        CNZ  CHAROUT    ;TYPE 'C'
1134        JNZ  $+8
1135        MVI  A,'*'
1136        CALL CHAROUT    ;TYPE * FOR GOOD RECORD
1137        POP  D          ;RETRIEVE MEMORY PTR
1138        DCR  C          ;ALL RECORDS READ YET
1139        JNZ  RDRCO      ;NO READ ANOTHER
1140        CALL CRLF
1141        MVI  C,3
1142LP2:    POP  H
1143        CALL OHEXHL
1144        DCR  C
1145        JNZ  LP2
1146        POP  PSW        ;EXEC/LOAD FLAG
1147        RAR
1148        RC              ;DONE
1149        PCHL
1150;******************************
1151;READ HEADER RECORD
1152;******************************
1153RDHEAD: CALL CAINIT     ;INIT CASETTE
1154        CALL CASIN      ;READ TYPE CODE
1155        CPI  1          ;HEADER RECORD?
1156        RNZ             ;NO
1157        CALL CASIN      ;RECORD LENGTH
1158        MVI  C,5        ;NAME SIZE
1159NM1:    CALL CASIN      ;NAME BYTE
1160        CALL CHAROUT    ;DISPLAY IT
1161        DCR  C
1162        JNZ  NM1        ;DO IT TILL DONE
1163        MVI  C,3
1164ADDRS:  CALL CASWD      ;INPUT START,END,EXEC
1165        XTHL            ;EXCH RETURN ADDR WITH PARM
1166        PUSH H          ;PUSH RETURN ADDR AGAIN
1167        DCR  C
1168        JNZ  ADDRS
1169        CALL CASWD      ;DUMMY CHECKSUM
1170        XRA  A          ;ZER FLAGS FOR NORMAL RETURN
1171        RET
1172;**********************************************
1173;CAINIT READ CASETTE UNTIL 32 SYNC BYTES READ
1174;**********************************************
1175CAINIT: CALL BYTESET    ;READ FIRST SYNC
1176        MVI  B,31
1177CAIN2:  CALL CASIN
1178        CPI  0E6H
1179        MVI  A,'I'
1180        JNZ  ERR1
1181        DCR  B
1182        JNZ  CAIN2
1183        RET
1184;*******************************
1185;CASETTE OUTPUT BYTE
1186;*******************************
1187CASOUT: PUSH PSW        ;SAVE IT
1188        IN   3
1189        ANI  4
1190        JZ   CASOUT+1
1191        POP  PSW
1192        OUT  0          ;WRITE BYTE
1193        RET
1194;*****************************
1195;GENERATE SYNC STREAM
1196;*****************************
1197GEN:    CALL IHEX       ;WAIT FOR RETURN
1198        MVI  A,10H
1199        OUT  3          ;WRITE ENABLE MIO
1200GEN1:   MVI  A,0E6H
1201        CALL CASOUT
1202        IN   3
1203        ANI  2
1204        RNZ
1205        JMP  GEN1
1206;************************************************
1207;READ BYTE FROM CASETTE WITHOUT CHECKSUM
1208;************************************************
1209CASIN:  IN   3
1210        RRC
1211        RRC             ;C=SERIAL READY
1212        JC   PRMPT      ;BAIL OUT
1213        RRC             ;C=CASETTE READY
1214        JNC  CASIN      ;KEEP TRYING
1215        IN   0          ;DATA PORT
1216        RET
1217;*****************************************
1218;CAINCK- READ BYTE WITH CHECKSUM
1219;*****************************************
1220CAINCK: CALL CASIN
1221CHKSUM: PUSH B
1222        MOV  C,A        ;NEW CHAR IN LOW BYTE
1223        MVI  B,0
1224        DAD  B          ;ADD TO CHECKSUM
1225        POP  B          ;RESTORE
1226        RET
1227;**********************************************
1228;ALLIGN CASETTE BY READING AND DISPLAYING BYTES
1229;**********************************************
1230ALIGN:  CALL CHIN       ;WAIT FOR CR
1231        CALL BYTESET
1232ALL4:   LXI  H,REFRESH
1233        LXI  D,481      ;FILL SMALLEST SCREEN
1234ALL3:   DCX  D
1235        MOV  A,D
1236        ORA  E
1237        JZ   ALL4       ;START AGAIN EVERY 256 CHARS
1238        MVI  M,7FH
1239        CALL CASIN      ;READ NEXT CHAR
1240        MOV  M,A        ;PUT IN SCREEN
1241        INX  H
1242        JMP  ALL3
1243;*******************************************
1244;GET CASETTE IN BYTE MODE IE READ FIRST 0E6H
1245;*******************************************
1246BYTESET:MVI  A,60H      ;BIT MODE
1247        OUT  3
1248BYTE1:  CALL CASIN      ;READ BYTE EVERY BIT TIME
1249        CPI  0E6H       ;SYNC YET
1250        JNZ  BYTE1      ;NO
1251        MVI  A,20H      ;BYTE MODE
1252        OUT  3
1253        RET
1254;*******************************************
1255;CASWD-INPUT WORD TO H,L ADD FIRST BYTE ONLY
1256;TO CHECKSUM
1257;*******************************************
1258CASWD:  CALL CASIN      ;READ LOW BYTE
1259        MOV  L,A
1260        CALL CASIN      ;READ HIGH BYTE
1261        MOV  H,A
1262        RET
1263;********************************
1264;CHARACTER INPUT ROUTINES
1265;********************************
1266CHIN:   CALL CHIN1
1267        CPI  03         ;CRTL C?
1268        JZ   MONT       ;YES,RESET AND PROMPT
1269        CALL CHAROUT
1270        CPI  0DH
1271        CZ   CRLF       ;ADD LINE FEED
1272        RET
1273CHIN1:  IN   3
1274        ANI  2
1275        JZ   CHIN1
1276        IN   2          ;READ PORT 2
1277        ANI  7FH        ;MASK PARITY
1278        RET
1279        DB   0,0,0,0,0,0,0,0,0,0,0,0,0
1280;********************************************************
1281;PARM2 READ 2 PARAMATERS 16 BITS EACH INTO H,L AND D,E
1282;********************************************************
1283PARM2:  CALL IHEX
1284        MOV  D,H
1285        MOV  E,L
1286        CPI  0AH        ;TERMINATED?
1287        RZ              ;YES,USE SAME VALUE
1288        CPI  ','
1289        JZ   PARM3
1290        CPI  ' '
1291        RNZ             ;INVALID
1292PARM3:  XCHG
1293        CALL IHEX       ;GET SECOND PARM
1294        XCHG
1295        RET
1296;*********************************
1297;CRLF DO CARRIAGE RETURN/LINE FEED
1298;*********************************
1299CRLF:   MVI  A,0DH
1300        CALL CHAROUT
1301        MVI  A,0AH
1302        CALL CHAROUT
1303        RET
1304;:************************************************
1305;INPUT CHARS ASSUMED HEX AND CONVERT TO BINARY
1306;TERMINATES ON FIRST NO HEX CHAR WHICH IS LEFT
1307;IN A REG. H,L RETURNS WITH VALUE
1308;*************************************************
1309IHEX:   LXI  H,0
1310        CALL CHIN       ;READ CHAR
1311        PUSH PSW
1312        CALL ASBI       ;CONVERT TO BIBARY
1313        JNC  IHEX1
1314        POP  PSW
1315        RET
1316IHEX1:  DAD  H
1317        DAD  H
1318        DAD  H
1319        DAD  H          ;ADD NEW DIGIT
1320        ADD  L
1321        MOV  L,A
1322        POP  PSW
1323        JMP  IHEX+3
1324;********************************************************
1325;CONVERT ASCII HEX CHAR IN A-REG TO BINARY IN A REG
1326;RETURN WITH CARRY SET IF INVALID CHAR,RESET OTHERWISE
1327;********************************************************
1328ASBI:   SUI  30H        ;REMOVE ASCII BIAS
1329        RC              ;INVALID <0
1330        CPI  10
1331        JC   ASBI1      ;VALID 0-9
1332        SUI  17
1333        RC              ;INVALID
1334        ADI  10
1335        CPI  16         ;SET CARRY IF <0FH
1336ASBI1:  CMC
1337        RET
1338;*****************************************
1339;PRINT H,L AND 16 BIT MEMORY AT H,L
1340;*****************************************
1341SRCPNT: CALL PNTMEM
1342        MOV  A,M        ;BYTE 2
1343SRCP1:  CALL OHEX
1344        RET
1345PNTMEM: CALL CRLF
1346        DCX  H          ;BACK UP 1
1347        CALL OHEXHL
1348        MOV  A,M
1349        CALL OHEXB
1350        INX  H
1351        RET
1352;**********************************************
1353;OUTPUT HEX CHARS TO VIDIO FROM A REG
1354;**********************************************
1355OHEX:   PUSH PSW        ;SAVE CHAR
1356        RRC
1357        RRC
1358        RRC
1359        RRC
1360        CALL BIAS       ;BINARY TO ASCII AND OUT
1361        POP  PSW
1362        CALL BIAS
1363        RET
1364;****************************
1365;CONVERT BINARY TO ASCII
1366;****************************
1367BIAS:   ANI  0FH        ;MASK NIBBLE
1368        ADI  90H
1369        DAA
1370        ACI  40H
1371        DAA
1372        CALL CHAROUT
1373        RET
1374;*********************************************
1375;OUTPUT MESSAGE PTED TO BY H,L AND TERMINATED
1376;BY ONE BYTE OF BINARY ZEROS
1377;*********************************************
1378MSG:    CALL CRLF
1379MSGNC:  MOV  A,M
1380        ORA  A
1381        RZ
1382        CALL CHAROUT
1383        INX  H
1384        JMP  MSGNC
1385CMDTBL  EQU  $
1386        DB   'H'
1387        DW   INTEL      ;INTEL HEX LOADS
1388        DB   'R'        ;FREE RAM LOCATION
1389        DW   RAMFND
1390        DB   'G'
1391        DW   GEN        ;GENERATE SYNC STREAM
1392        DB   'A'
1393        DW   ALIGN      ;ALLIGN CASETTE ON MIO
1394        DB   'V'
1395        DW   CMPBLK     ;COMPARE MEMORY BLOCKS
1396        DB   'I'
1397        DW   INPORT     ;INPUT FROM SPECIFIED PORT
1398        DB   'O'
1399        DW   OUTPORT    ;OUPUT TO SPECIFIED PORT
1400        DB   'T'
1401        DW   MEMTEST
1402        DB   'J'
1403        DW   JUMP       ;JUMP TO ADDRESS
1404        DB   'C'
1405        DW   CALL1      ;CALL MEMORY WITH RETURN
1406        DB   'D'        ;DISPLAY MEMORY
1407        DW   DISP
1408        DB   'E'
1409        DW   ENTR       ;ENTER INTO MEMORY
1410        DB   'M'
1411        DW   MOVE       ;MOVE MEMORY BLOCK
1412        DB   'F'        ;FILL MEMORY
1413        DW   FILL
1414        DB   'U'
1415        DW   UNPRT      ;UNPROTECT MEMORY
1416        DB   'P'
1417        DW   PROT       ;PROTECT MEMORY
1418        DB   'L'
1419        DW   LOAD       ;LOAD CASETTE
1420        DB   'S'
1421        DW   SEARCH     ;16 BIT MASKED SEARCH
1422        DB   'X'
1423        DW   EXEC       ;EXECUTE FROM CASETTE
1424        DB   1BH        ;ESCAPE CODE
1425        DW   ESCCO
1426        DB   0
1427        END
1428