MAIN     PROC    NEAR
         JMP     N102
N100:    DB      1Ch    DUP   (?)
N101:    DB      'É','', 19h  DUP  ('Í','') ,'»','',' ',''
         DB      0Ah DUP ('º','', 19h DUP (' ','p') ,'º','',' ','')
         DB      'È','', 19h DUP ('Í','') ,'¼','',' ',''
FNAME:   DB      'MEMO.N',30h,30h,' $'
N102:    CALL    VID
FN0:     MOV     DX,OFFSET FNAME
         MOV     W[010Ch],DX       ;file name location
         MOV     BP,DX    
         INC     B[BP+07h]         ;unit digit
         CMP     B[BP+07h],3Ah     ;is it 10?
         JNZ     FN1
         MOV     AH,30h
         MOV     B[BP+07h],AH
         INC     B[BP+06h]         ;add carry digit
         CMP     B[BP+06h],3Ah     ;is it 100?
         JZ      FN2               ;stop
FN1:     CALL    CREATE            ;create the named file
         CALL    SET               ;set up the window for it
         CALL    FILL              ;transfer data to the file
         CALL    CLOSE             ;close the file
         MOV     AH,00h            ;set mode
         MOV     AL,B[0103h]       ;mode from vid
         MOV     BH,00h            ;page
         INT     10h
         MOV     AH,07h            ;scroll down
         MOV     AL,19h            ;clear screen
         MOV     BH,07h            ;blank line attribute
         MOV     CX,0000h          ;upper left
         MOV     DX,194Fh          ;lower right
         INT     10h
         MOV     AH,09h            ;display message
         MOV     DX,FN3            ;at offset
         INT     21h
         MOV     AH,09h            ;
         MOV     DX,FNAME
         INT     21h
         MOV     AH,09h            ;
         MOV     DX,FN3A
         INT     21h
FN4:     MOV     AH,00h            ;get keyboard character
         INT     16h
         CMP     AH,00h            ;special?
         JZ      FN4
         CMP     AL,4Eh            ;N for no
         JZ      FN2
         CMP     AL,6Eh            ;n for no
         JZ      FN2
         CMP     AL,59h            ;Y for yes
         JZ      FN0               ;back to get new name
         CMP     AL,79h            ;y for yes
         JZ      FN0
         JMP     FN4               ;ignore all others
FN2:     INT     20h               ;stop on no
         RET
FN3:     DB      'That was file  $'
FN3A:    DB      0Dh,0Ah,'Do you want to make another one?'
         DB      0Dh,0Ah,'    ( Press  Y  or  N  )',0Dh,0Ah,'$'
         ENDP 
SET      PROC    NEAR
         CALL    SETONE            ;subroutine
         CALL    SETTHREE          ;subroutine
         RET
         ENDP
VID      PROC    NEAR              ;get video state
         MOV     AH, 30h           ;what dos are we under?   
         INT     21h   
         CMP     AL,2              ;dos 2.0 or over?   
         JAE     A1                ;yes, skip   
         MOV     AH, 09h           ;no, bitch   
         MOV     DX, OFFSET BADDOS  
         INT     21h   
         INT     20h               ;and exit   
A1:      MOV     AH,0Fh            ;
         INT     10h
         SUB     AH,019h           ;sub. 25 from line count
         SHL     AH,1h             ;mult. by 2, lose high bit
         MOV     B[0102h],AH       ;store count
         MOV     B[0103h],AL       ;store mode
         CMP     AL,7h             ;is it HGA Text?
         JZ      M7
         CMP     AL,3h             ;is it CGA?
         JZ      M3
         CMP     AL,2h             ;is it CGA?
         JZ      M2
M7:      MOV     W[104h],03BAh     ;HGA retrace port
         MOV     W[106h],0B000h    ;HGA video segment
         JMP     MM
M3:      NOP
M2:      MOV     W[104h],03DAh     ;CGA retrace port
         MOV     W[106h],0B800h    ;CGA video segment
MM:      RET
BADDOS:  DB      'This program requires DOS 2.0!$'
         ENDP
SETONE   PROC    NEAR
         MOV     AH,02h            ;set cursor position
         MOV     BX,0000h          ;page
         MOV     DX,0000h          ;upper left corner
         INT     10h
         MOV     AX,0719h          ;clear screen
         MOV     BH,07h            ;normal attributes
         MOV     CX,0000h          ;upper left corner
         MOV     DX,194Fh          ;lower right corner
         INT     10h
         MOV     BX,[106h]
         MOV     ES,BX             ;get proper Video address
         MOV     CS:DI,0670h       ;position box
         MOV     BX,0000h          ;initialize counter
         MOV     CX,000Ch          ;total lines
N104:    MOV     DX,1Ch            ;total columns, row loop
N105:    CALL    SETTWO            ;fill row
         DEC     DX                ;step counter
         JNZ     N105              ;loop for column
         ADD     CS:DI,0068h       ;to align column
         LOOP    N104              ;fill row
         RET
         ENDP
SETTWO   PROC    NEAR
         PUSH    DX                ;save column count
         MOV     SI,0002h          ;both char and attribute
         MOV     DX,[0104h]        ;retrace port
N107:    IN      AL,DX             ;wait for beginning
         TEST    AL,01h            ;of scan retrace
         JNZ     N107              ;to minimize  
N108:    IN      AL,DX             ;snow and
         TEST    AL,01h            ;flicker
         JZ      N108              ;loop
         MOV     AH,[BX+011Fh]     ;from memory
         MOV     ES:[DI],AH        ;to display
         INC     DI                ;step counters
         INC     BX                ;step counter
         DEC     SI                ;step counter
         JNZ     N107              ;loop for row
         POP     DX                ;pop column count
         RET
         ENDP
SETTHREE PROC    NEAR
         MOV     AH,02h            ;position cursor
         MOV     BH,00h
         MOV     DH,04h
         MOV     DL,05h
         INT     10h
         MOV     AH,09h            ;display message
         MOV     DX,MSG1           ;message offset
         INT     21h
         MOV     AH,02h            ;position cursor
         MOV     BH,00h
         MOV     DH,0Bh            ;in the
         MOV     DL,19h            ;highlighted box
         INT     10h
         JMP     G0
MSG1:    DB      'Fill the highlighted box with the 10 row by 25 column'
         DB      0Dh,0Ah,20h,20h,20h,20h,20h
         DB      'Panel to be displayed by  MEMO.COM  ',0Dh,0Ah
         DB      0Dh,0Ah,20h,20h,20h,20h,20h
         DB      'Do not use   ENTER   until you are done. Then press'
         DB      0Dh,0Ah,20h,20h,20h,20h,20h
         DB      'ENTER  to make the necessary file.',0Dh,0Ah,'$'
G0:      MOV     AH,0h             ;wait for character
         INT     16h               ;from keyboard
         MOV     B[10Ah],AH        ;store scan code
         MOV     B[10Bh],AL        ;and ASCII code
         CMP     AL,0Dh            ;is it ENTER?
         JNZ     G1
         CMP     AH,1Ch            ;is it ENTER?
         JZ      JJ
G1:      CMP     AL,08h            ;is it BACKSPACE?
         JNZ     G2
         CMP     AH,0Eh            ;is it BACKSPACE?
         JZ      WB
G2:      CMP     AL,00h            ;is it ARROW?
         JNZ     J2
         CMP     AH,4Bh            ;is it LEFT?
         JZ      WL
         CMP     AH,4Dh            ;is it RIGHT?
         JZ      WR
         CMP     AH,50h            ;is it DOWN?
         JZ      WD
         CMP     AH,48h            ;is it UP?
         JZ      WU
         JMP     G0  
J2:      CALL    CHR               ;call sub.
         JMP     G0
WB:      CALL    BACK              ;call sub.
         JMP     G0
WL:      CALL    LEFT              ;call sub.
         JMP     G0 
WR:      CALL    RIGHT             ;call sub.
         JMP     G0
WU:      CALL    UP                ;call sub.
         JMP     G0
WD:      CALL    DOWN              ;call sub.
         JMP     G0 
JJ:      CALL    DONE              ;call sub.
         RET
         ENDP
CHR      PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         MOV     AH,02h            ;output character
         MOV     DL,B[10Bh]        ;by its ASCII code
         INT     21h
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DL,32h            ;right edge of box?
         JB      C1
         SUB     DL,19h            ;to left edge
         MOV     AH,02h            ;move cursor
         INT     10h 
         CALL    DOWN              ;and down
C1:      RET
         ENDP
BACK     PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DL,19h            ;left edge?
         JG      B1
         ADD     DL,18h            ;to right edge
         MOV     AH,02h            ;move cursor
         INT     10h
         CALL    UP                ;and up
         MOV     AH,03h            ;read cursor position
         INT     10h
         PUSH    DX                ;save position
         MOV     AH,02h            ;cover char
         MOV     DL,20h            ;with space
         INT     21h
         POP     DX                ;recover position
         MOV     AH,02h            ;move cursor
         INT     10h
         JMP     B2
B1:      CALL    LEFT
         MOV     AH,02h            ;cover char.
         MOV     DL,20h            ;with space
         INT     21h
         CALL    LEFT
B2:      RET
         ENDP
LEFT     PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DL,19h            ;left edge?
         JLE     L1
         DEC     DL                ;to left
         MOV     AH,02h            ;move cursor
         INT     10h
L1:      RET
         ENDP
RIGHT    PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DL,31h            ;right edge?
         JGE     R1
         INC     DL                ;to right
         MOV     AH,02h            ;move cursor
         INT     10h
R1:      RET
         ENDP
UP       PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DH,0Bh            ;top edge?
         JLE     U1
         DEC     DH                ;move up
         MOV     AH,02h            ;move cursor
         INT     10h
U1:      RET
         ENDP
DOWN     PROC    NEAR
         MOV     AH,03h            ;read cursor position
         INT     10h
         CMP     DH,14h            ;bottom edge?
         JGE     D1
         INC     DH                ;move down
         MOV     AH,02h            ;move cursor
         INT     10h
D1:      RET
         ENDP
DONE     PROC    NEAR
         MOV     BX,[106h]
         MOV     ES,BX             ;set video segment
         MOV     ES:SI,0712h
         MOV     CS:DI,BUFF
         MOV     CX,0A19h
LP1:     MOV     DH,ES:B[SI]
         MOV     CS:B[DI],DH
         INC     ES:SI             ;step counter
         INC     ES:SI             ;skip attribute
         INC     CS:DI             ;step counter
         DEC     CL                ;step counter
         JNZ     LP1               ;loop to row end
         ADD     SI,6Eh            ;skip wrap around
         ADD     CL,19h            ;skip wrap around
         DEC     CH                ;step counter
         JNZ     LP1               ;loop for columns
         RET
BUFF:    DB      0FAh    DUP  (?)  ;250 byte buffer
         ENDP
CREATE   PROC    NEAR
         MOV     AH,5Bh            ;create new file
         MOV     CX,0000h          ;normal attribute
         MOV     DX,W[010Ch]       ;offset of name
         INT     21h
         MOV     W[010Eh],AX       ;store file handle
         JNC     CREND
         MOV     AH,09h            ;display message
         MOV     DX,CRMSG          ;message offset
         INT     21h
         INT     20h               ;stop if problem
CREND:   RET
CRMSG:   DB      'That file already exists. ',0Dh,0Ah
         DB      'I will not write over it.',0Dh,0Ah,0Dh,0Ah
         DB      'I am terminating this run so you can ',0Dh,0Ah
         DB      'DEL  or  REN  the  MEMO.Nxx  files.',0Dh,0Ah,'$'
         ENDP
FILL     PROC    NEAR
         MOV     AH,40h            ;write to file
         MOV     BX,W[010Eh]       ;file handle
         MOV     CX,0FAh            ;how many bytes
         MOV     DX,BUFF           ;buffer offset
         INT     21h
         CMP     AX,0FAh            ;all of them?
         JZ      FIEND
         INT     20h               ;stop if problem
FIEND:   RET
         ENDP
CLOSE    PROC    NEAR 
         MOV     AH,3Eh            ;close file
         MOV     BX,W[010Eh]       ;file handle
         INT     21h
         RET
         ENDP
