*****************************************************
;FLASH WRITER CUSTOM CPM IO ROUTINES FOR 2D
;THINKERTOY.  DRIVER IS FOR PASCAL.
; MODES M.JACOBY  OCT.28,79
**************************************************
;      SYSTEM EQUATES
******************************************************
MSIZE  EQU     48              ;CP/M SYSTEM SIZE IN KBYTES
BIAS   EQU     (MSIZE-16)*1024
CPMB   EQU     2600H+BIAS      ;LOCATION OF CCP
BDOS   EQU     2E00H+BIAS      ;LOCATION OF BDOS
BIOS   EQU     3B00H+BIAS      ;LOCATION OF BIOS
USER   EQU     BIOS+380H       ;START OF USER AREA
OFFSET EQU     1E80H-BIOS      ;TO SYSGEN IMAGE
;
;*********************************************************
;      DISK PARAMETERS - DOUBLE DENSITY DISK JOCKEY
;*********************************************************
;      ON DISK                 IN SYSGEN       IN 24K SYSTEM
;      TRACK   SECTOR          ADDRESS
;BOOT  0       1                900H           0E700H
;CCP   1       1               0980H           4600H
;BDOS  1       17              1180H           4E00H
;BIOS  1       43              1E80H           5B00H
;MODE  1       49              21FFH           5E7FH
;USER  1       50-52           2200H           5E80H
;TOP OF SYSTEM                 237FH           5FFFH
;
;DOUBLE DENSITY SKIP TABLE
;      1,2,19,20,37,38,3,4,21,22,39,40,5,6,23,24,41,42
;      7,8,25,26,43,44,9,10,27,28,45,46,11,12,29,30,47,48
;      13,14,31,32,49,50,15,16,33,34,51,52,17,18,35,36
;
;*********************************************************
;MODE BYTE OPTIONS AND DENSITY SETTINGS OF VARIOUS DRIVES
;*********************************************************
;
       ORG     USER-8          ;5E78H IN 24K SYSTEM
DNSTY: DB      1,0,1,1         ;DRIVE B SD, OTHERS DD
               ;B0=DENSITY     0=SNGL, 1=DBL
       DB      0               ;RESERVED
MODE:  DB      1               ;MODE BYTE
               ;BIT0=1 DOES AUTO ON COLD BOOT
               ;BIT1=1 DOES AUTO ON WARM BOOT
;
 ;*********************************************************
;      SAMPLE USER AREA
;*********************************************************
;
;TTY EQUATES
STATUS EQU     0               ;TTY STATUS PORT
DATA   EQU     1               ;TTY DATA PORT
RDA    EQU     10H             ;DATA AVAILABLE MASK
RDAMSK EQU     RDA             ;SENSE IS ACTIVE LOW
TBE    EQU     20H             ;BUFFER EMPTY MASK
TBEMSK EQU     TBE             ;SENSE IS ACTIVE LOW
STOPCHR EQU    'Q'-40H         ;STOPS EVERYTHING
;
       ORG     USER            ;5E80H IN DIST SYSTEM
;
;JUMP TABLE - JMPS MUST REMAIN HERE, IN SAME ORDER
INIT   JMP     INITR           ;INITIALIZATION
CONST  JMP     TTYST           ;CONSOLE STATUS
CONIN  JMP     TTYIN           ;CONSOLE INPUT
CONOUT JMP     DRIVE           ;CONSOLE OUTPUT FLASHWRITER
LIST   JMP     TTYOUT          ;LIST OUTPUT
PUNCH  JMP     TTYOUT          ;PUNCH OUTPUT
READER JMP     TTYIN           ;READER INPUT
PRST   JMP     TTYPRST         ;PRINTER STATUS
;
;*********************************************************
;CONSOLE INPUT CHAR TO REGISTER A
;*********************************************************
TTYIN:
       IN STATUS               ;GET STATUS BYTE
       ANI RDA                 ;EXAMINE STATUS BIT
       XRI     RDAMSK          ;MAKE ACTIVE LOW
       JNZ     TTYIN           ;LOOP FOR CHARACTER
       IN      DATA            ;INPUT THE CHARACTER
       ANI     7FH             ;STRIP PARITY
       RET
;*********************************************************
;CONSOLE STATUS AND STOP ROUTINE
;*********************************************************
TTYST:
       IN      STATUS          ;KEY PRESSED ?
       ANI     RDA
       XRI     RDAMSK
       MVI     A,0             ;NO  A=0
       RNZ                     ;EXIT
       CMA
       RET
;       IN      DATA            ;YES
;       ANI     7FH             ;GET CHARACTER
;       CPI     STOPCHR         ;CHARACTER=STOP?
;       JZ      ST1
;       MVI     A,0             ;NO
;       RET                     ;   EXIT
                               ;CHECK FOR STOP KEY TO CONTINUE
; ST1   IN      STATUS          ;KEY PRESSED ?
;       ANI     RDA
;       XRI     RDAMSK
;       MVI     A,0
;       JNZ     ST1             ;N0  GO BACK CHECK AGAIN
;       RET                     ;YES ALL DONE
;
;
;*********************************************************
;CONSOLE OUTPUT CHAR FROM REGISTER C
;*********************************************************
TTYOUT:
       IN      STATUS          ;GET STATUS BYTE
       ANI     TBE             ;EXAMINE STATUS BIT
       XRI     TBEMSK          ;MAKE ACTIVE LOW
       JNZ     TTYOUT          ;LOOP FOR CHAR
       MOV     A,C             ;CHAR INTO C REG
       OUT     DATA            ;AND OUTPUT
       RET
;
;*********************************************************
;PRINTER STATUS CHECK, NOT YET IMPLEMENTED
;*********************************************************
TTYPRST:
       XRA     A               ;NO CHAR READY
       RET                     ;SO RET WITH ACC=0
;
;*********************************************************
;INITIALIZATION ROUTINE GOES HERE IF NEEDED
;MAKE SURE IT ENDS WITH A RET.
;*********************************************************
INITR:; LXI     H,VADD
;       SHLD    CURS
       MVI     C,16H   ;CLEAR SCREAN SYM.
       CALL    DRIVE
       RET
;***********************************************************
;THIS AREA DEFINES THE EQUATES USED BY THE FLWR TYPE
;VIDEO DRIVERS.
VADD   EQU     0F000H  ;FLASHWRT BOARD RAM
HADD   EQU     0F0H    ;HI BYTE OF ADDRESS
BS     EQU     'H'-40H ;BACK-SPACE
LF     EQU     0AH     ;LINE FEED
ETB    EQU     'W'-40H ;CURSOR UP SYM
DC3    EQU     'S'-40H ;CURSOR RIGHT.
SYN    EQU     16H     ;HOME AND CLEAR SCREEN
RUB1   EQU     95H     ;RUB CHAR
SSEQ   EQU     1DH     ;GOTOXY START SEQUENCE BYTE.
;
;**** DRIVE
;FLWR DRIVER WITH X-Y CURSOR ADDRESSING.
;CURSOR ADDRESSING IS DONE WITH THE SEQUENCE:
; 1DH,Y-BYTE,X-BYTE  (1DH,HORIZ,VERT).
;
DRIVE:
       MOV     A,C
       PUSH PSW        ;SAVE REGISTERS
       PUSH B
       PUSH D
       PUSH H
       MOV     B,A
       LHLD    XYADD   ;SETUP FOR XY
       LDA     XYFLAG  ;OPERATION
       ORA     A       ;HAS IT BEEN SET
       JNZ     DOX     ;X-Y SEQ HAS STARTED.
       MOV     A,B     ;GET BACK ACCUM.
       CPI     SSEQ    ;CHECK FOR FIRST GOTXY REQUEST.
       JZ      STARTXY ;YEP, IT STARTED.
       CPI     07H     ;BELL?
       JZ      GOBACK
       ORA     A       ;NULL?
       JZ      GOBACK
DISPL   LHLD    CURS
       MOV     A,M     ;TURN OF CURSER
       ANI     7FH
       MOV     M,A
       MOV     A,B
       CPI     BS      ;(8)  BACKSPACE?
       JZ      BKSPC
       CPI     LF      ;(10) LINEFEED?
       JZ      LNFD
       CPI     0DH     ;(13)  CARRAIGE RETURN?
       JZ      CURET
       CPI     ETB     ;(23)  REVERSE LINEFEED?
       JZ      RLINFD
       CPI     DC3     ;(19)  FORWARD SPACE?
       JZ      FWSPC
       CPI     02H     ;(2)   HOME CURSER
       JZ      HOMER
       CPI     SYN     ;(22)  CLEAR AND HOME SCREEN?
       JZ      CLRSC
       CPI     RUB1    ;(95)  RUBOUT?
       JZ      BKSPC
       CPI     1AH     ;(26)  CLEAR WHOLE LINE?
       JZ      BLKLN
       CPI     1CH     ;(28)  CLEAR TO END OF LINE?
       JZ      CLRLN
       CPI     19H     ;(25)  CLEAR TO END OF SCREEN?
       JZ      CLR
       ANI     07FH
       MOV     M,A
FWSPC:
       MOV     A,L
       ANI     3FH
       CPI     3FH
       JZ      RETRN
       INX     H
ONSCR   MOV     A,L
       ANI     3FH
       CPI     3FH
       JZ      RETRN
       MOV     A,H
       CPI     HADD+4
       JNZ     RETRN
       LXI     H,VADD
       LXI     D,VADD+64
SCROL   LDAX    D
       MOV     M,A
       INX     D
       INX     H
       MOV     A,D
       CPI     HADD+4
       JNZ     SCROL
BLKLN   MOV     A,L
       ANI     0C0H
       MOV     L,A
       SHLD    CURS
CLRLN   MVI     M,020H
       MOV     A,L
       ANI     3FH
       CPI     3FH
       INX     H
       JNZ     CLRLN
       LHLD    CURS
RETRN   MOV     A,M     ;TURN ON CURSER
       ORI     80H
       MOV     M,A
       SHLD    CURS
GOBACK  POP     H
       POP     D
       POP     B
       POP     PSW
       RET
CLRSC   LXI     H,VADD
       SHLD    CURS
CLR     LHLD    CURS
WRSPC   MVI     M,20H
       INX     H
       MOV     A,H
       CPI     HADD+8
       JNZ     WRSPC
       JMP     RETRN-3
LNFD    LXI     D,64
       DAD     D
       JMP     ONSCR
BKSPC   DCX     H
       JMP     RETRN
RLINFD  LXI     D,-64           ;REVERSE LINE FEED
       DAD     D
       JMP     RETRN
CURET:  MOV     A,L
       ANI     0C0H
       MOV     L,A
       JMP     RETRN
HOMER:  LXI     H,VADD
       JMP     RETRN
;BEGINNING OF XY ROUTINES
STARTXY MVI     L,0FFH
       SHLD    XYADD
       MOV     A,L
       STA     XYFLAG
       JMP     GOBACK
DOX:   MVI     A,0FFH          ;GETS HERE IF L HAS BEEN
       CMP     L               ;SET
       JNZ     DOXY            ;IF NO MATCH,STAGE IS SET
       MOV     A,B             ;A CONTAINS Y-BYTE NOW
       SUI     20H
       ANI     3FH
       MOV     L,A             ;BINARY VAL. TO L
       SHLD    XYADD           ;SAVE IT
       JMP     GOBACK          ;FOR LATER
DOXY:  PUSH    H       ;SAVE H,L
       LHLD    CURS    ;GET OLD CURSOR LOCATION
       MOV     A,M
       ANI     7FH
       MOV     M,A     ;RESTORE CHAR AND WIPE OUT CURSOR.
       POP     H       ;RESTORE LATEST H,L
       MOV     A,B     ;B CONTAINS X-BYTE NOW
       SUI     20H
       ANI     0FH
       ORA     A               ;IS IT A ZERO?
       JZ      FIXCUR          ;IF SO,SKIP DADS.
       LXI     D,64            ;NO. OF CHARS/LINE.
LDOWN:  DAD     D               ;DOWN ONE LINE
       DCR     A               ;COUNT IT WITH X-BYTE
       JNZ     LDOWN
FIXCUR: XCHG            ;H,L TO D,E
       LXI     H,VADD          ;GET BEGINNING
       DAD     D               ;H,L NOW POINTS AT X-Y ADDR.
CHKLOC: MOV     A,H
       CPI     HADD+4
       JM      ONSCRN
       JMP     ZIPIT
ONSCRN: SHLD    CURS            ;X-Y ADDR IN CURS
ZIPIT: LXI     H,0             ;BIG ZERO
       SHLD    XYADD           ;ZERO THIS, WE ARE DONE
       XRA     A               ;SMALL ZERO
       STA     XYFLAG  ;SET THIS ALSO
       JMP     RETRN-3
;DEFINE STORAGE AREA FOR FLW DRIVER
;
CURS   DW      VADD            ;INITIALLY BOARD ADDRESS
XYFLAG DB      0               ;INITIALLY ZERO
XYADD  DW      0