home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.tar / ftp.whtech.com / club100 / ref / sandr.asm < prev    next >
Assembly Source File  |  2006-10-19  |  22KB  |  1,280 lines

  1. ;----------------------------------------------------------
  2. ;Option ROM Header must be ORGed at 0 by the assembler
  3. ;or linked at 0 by the linker.
  4. ;----------------------------------------------------------
  5.  
  6. ;Routine to turn on the Option ROM
  7.  
  8. OPON:    EQU    0FAA4H
  9.  
  10. ;Globals on the Telcom Back Page to temporarily hold HL and
  11. ;DE registers during a CALL to Standard ROM, or during an
  12. ;Interrupt.
  13.  
  14. HOLDH:    EQU    0FCC0H
  15. HOLDD:    EQU    0FCC2H
  16. INTH:    EQU    0FCC4H
  17. INTD:    EQU    0FCC6H
  18.  
  19.  
  20. ;Entry point arrived at by CALL 63012
  21.  
  22. RST0?:
  23.     INX    SP
  24.     INX    SP
  25.     JMP    PROGRAM
  26.     DB    0,0,0
  27.  
  28. RST1?:                ;Not used
  29.     RET
  30.     DB    0,0,0,0,0,0,0
  31.  
  32. RST2?:                ;Not used
  33.     RET
  34.     DB    0,0,0,0,0,0,0
  35.  
  36. RST3?:                ;Not Used
  37.     RET
  38.     DB    0,0,0,0,0,0,0
  39.  
  40. RST4?:                ;Not Used
  41.     RET
  42.     DB    0,0,0
  43.  
  44. TRAP?:
  45.     DI
  46.     JMP    INTRAP
  47.  
  48. RST5?:                ;Not Used
  49.     RET
  50.     DB    0,0,0
  51.  
  52. RST55?:
  53.     DI
  54.     JMP    INT55
  55.  
  56. ;RST 6 used as short call to a Standard ROM routine.
  57.  
  58. RST6?:
  59.     JMP    STDCALL
  60.     DB    0
  61.  
  62. ;Replaces the 6.5 interrupt and sets up a call to 6.5 in
  63. ;Standard ROM
  64.  
  65. RST65?:
  66.     DI
  67.     JMP    INT65
  68.  
  69. RST7?:                ;Not Used
  70.     RET
  71.     DB    0,0,0
  72.  
  73. ;Replaces the 7.5 interrupt and sets up a call to 7.5 in
  74. ;Standard ROM
  75.  
  76. RST75?:
  77.     DI
  78.     JMP    INT75
  79.  
  80. ;An image of the OPON routine copied to FAA4H by the
  81. ;Model 100 power up logic.
  82.  
  83. OPONIMG:
  84.     PUSH    PSW
  85.     MVI    A,1
  86.     OUT    0E0H
  87.     POP    PSW
  88.     RET
  89.     DB    0
  90.  
  91. ;---------------------------------------------------------
  92. ;The STDCALL routine allows a program running in the
  93. ;the Option ROM to call and return to an address in the
  94. ;Option ROM.
  95. ;Syntax is to use a RST 6 plus the address to be called.
  96. ;
  97. ;    RST    6
  98. ;    DW    04B44H
  99. ;---------------------------------------------------------
  100.  
  101. STDCALL:
  102.     DI
  103.     SHLD    HOLDH        ;Caller's HL
  104.     XCHG
  105.     SHLD    HOLDD        ;Caller's DE
  106.     POP    H        ;(HL)=Routine to Call
  107.     MOV    E,M
  108.     INX    H
  109.     MOV    D,M        ;DE=Routine to Call
  110.     INX    H        ;HL=Return Address
  111.     PUSH    H
  112.     LXI    H,OPON        ;return through OPON
  113.     PUSH    H
  114.     PUSH    D        ;Return Address
  115.     LHLD    HOLDD        ;Caller's DE
  116.     XCHG
  117.     LHLD    HOLDH        ;Caller's HL
  118.     EI
  119.     JMP    STDON
  120.  
  121.  
  122. ;Routines for each of the hardware traps.
  123. INTRAP:
  124.     CALL    INTCALL
  125.     DW    0024H
  126.     RET
  127.  
  128. INT55:
  129.     CALL    INTCALL
  130.     DW    002CH
  131.     RET
  132.  
  133. INT65:
  134.     CALL    INTCALL
  135.     DW    0034H
  136.     RET
  137.  
  138. INT75:
  139.     CALL    INTCALL
  140.     DW    003CH
  141.     RET
  142.  
  143. OPX:
  144. ;Turns off the Option ROM (or turns on Standard ROM)
  145. ;Depending on your viewpoint.
  146. ;This routine must be ORGed at 85H. Ensure the the previous
  147. ;Code does not overlap into 85H
  148.  
  149.     ORG    85H
  150. STDON:
  151.     PUSH    PSW
  152.     PUSH    H
  153.     LXI    H,26C8H
  154.     XTHL
  155.     XRA    A
  156. OPEXIT:
  157.     OUT    0E0H
  158.     RET
  159.  
  160. ;---------------------------------------------------------
  161. ;The INTCALL routine allows a program running in the Option
  162. ;ROM to call an interrupt routine.
  163. ;Syntax: CALL INTCALL plus the address to be called.
  164. ;
  165. ;    CALL    INTCALL
  166. ;    DW    24H
  167. ;---------------------------------------------------------
  168. INTCALL:
  169.     SHLD    INTH        ;Caller's HL
  170.     XCHG
  171.     SHLD    INTD        ;Caller's DE
  172.     POP    H        ;(HL)=Routine to Call
  173.     MOV    E,M
  174.     INX    H
  175.     MOV    D,M        ;DE=Routine to Call
  176.     INX    H        ;HL=Return Address
  177.     PUSH    H
  178.     LXI    H,OPON        ;return through OPON
  179.     PUSH    H
  180.     PUSH    D        ;Return Address
  181.     LHLD    INTD        ;Caller's DE
  182.     XCHG
  183.     LHLD    INTH        ;Caller's HL
  184.     JMP    STDON
  185.  
  186. ;END OF ROM HEADER PORTION OF CODE
  187.  
  188.  
  189.  
  190. ;================Model 100 Routines===============
  191. ;Poll the keyboard and return with or without key
  192. ;Entry:    None
  193. ;Exit:    Z if no key. Carry set if afunction key pressed
  194. KYREAD:        EQU    07242H
  195. ;------
  196.  
  197. ;Clear The Screen
  198. CLS:        EQU    04231H
  199. ;------
  200.  
  201. ;Output a character to LCD
  202. ;Entry Character in A Reg
  203. CHROUT:        EQU    04B44H
  204. ;------
  205.  
  206. ;Retrieve next directory entry of an active file
  207. ;Entry:    HL should point to one directory entry less than the
  208. ;    point at which to begin the search. The search routine
  209. ;    starts by incrementing to the next entry
  210. ;Exit:    Z set = no more entries
  211. ;        else
  212. ;    HL points to the next directory entry with an
  213. ;        active file.
  214. NXTDIR:     EQU      020D5H
  215. ;------
  216.  
  217. ;Locate an empty directory slot.
  218. ;Entry:    none
  219. ;Exit:    HL points to a free slot
  220. FREDIR: EQU      020ECH
  221. ;------
  222.  
  223. ;Position the cursor
  224. ;Entry:    H=Column    1-40
  225. ;    L=Row        1-8
  226. ;Exit:    None
  227. CURPOS:        EQU    0427CH
  228. ;------
  229.  
  230. ;Erase to end of the current line
  231. ERAEOL:        EQU    0425DH
  232. ;------
  233.  
  234. ;Turn Cursor On
  235. CURSON:        EQU    04249H
  236. ;------
  237.  
  238. ;Turn Cursor Off
  239. CUROFF:        EQU    0424EH
  240. ;------
  241.  
  242. ;Position the cursor to 1 of 24 bar cursor positions
  243. ;Entry    HL = position 0-23
  244. BARPOS:        EQU    059C9H
  245. ;------
  246.  
  247. ;Toggle bar cursor to opposite state at poisition
  248. ;Specified in HL
  249. ;Entry:    HL = Position 0-23
  250. BARCUR:        EQU    059E5H
  251. ;------
  252.  
  253. ;Convert Model 100 directory name 'FILE  DO' to 
  254. ;Displayable name 'FILE.DO'
  255. ;Entry:    DE points to Directory name
  256. ;    HL points to buffer for formatted output
  257. MKPNAM:        EQU    059ADH
  258. ;------
  259.  
  260. ;Sound the beeper
  261. BEEP:        EQU    04229H
  262. ;------
  263.  
  264. ;Make a hole (space) in RAM file
  265. ;Entry:    HL = where to make the hole
  266. ;    BC = Size of the hole
  267. MAKHOL:        EQU    06B6DH
  268. ;------
  269.  
  270. ;Delete bytes in a file
  271. ;Entry:    HL= where to delete
  272. ;    BC= number of bytes to delete
  273. MASDEL:        EQU    06B9FH
  274. ;------
  275.  
  276. ;Reorganize directory pointers
  277. DIROK:        EQU    02146H
  278. ;------
  279.  
  280. ;=============Model 100 Addresses===============
  281.  
  282. ;Beginning of the User Directory Area
  283. USRDIR:        EQU    0F9BAH
  284. ;------
  285.  
  286. ;Beginning of free space
  287. MOAT:        EQU    0FBB6H
  288. ;------
  289.  
  290.  
  291. ;=====Globals Allocated to TELCOM back page====
  292.  
  293. ;Pointer to the start of the search string.
  294. ;And its length
  295. SEARCH:        EQU    0FCCAH
  296. SEARCHLEN:    EQU    0FCCCH
  297. ;------
  298.  
  299. ;Pointer to the Replace String and its length
  300. REPLACE:    EQU    0FCCEH
  301. REPLACELEN:    EQU    0FCD0H
  302. ;------
  303.  
  304. ;Current location in the TEXT file
  305. LOC:        EQU    0FCD2H
  306. ;------
  307.  
  308.  
  309. ;==============================================
  310. ;MAIN PROGRAM BEGINS HERE
  311. ;==============================================
  312.  
  313. ;------
  314. PROGRAM:
  315. ;------
  316. ;Check Stack, Install the ROM name and call the search
  317. ;and replace routine.
  318.  
  319. ;1.    Check that at least 512 bytes of free space
  320. ;    Exists.
  321.  
  322.     LXI    H,0
  323.     DAD    SP
  324.     XCHG
  325.     LHLD    MOAT
  326.  
  327. ;2.    Subtract High bytes of Moat from Stack. Result
  328. ;    Must be at least 2 (0200H = 512)
  329.  
  330.     MOV    A,D
  331.     SUB    H
  332.     JC    OMEM
  333.     CPI    2
  334.     JC    OMEM
  335.     
  336. ;3.    Install The ROM name
  337.     LXI    H,ROMNAME    ;Name to appear on Menu
  338.     CALL    TRGINS        ;Install it
  339.  
  340. ;4.    Execute the main program
  341.     CALL    SANDR
  342.  
  343. ;5.    Return
  344.     JMP    STDON
  345.  
  346. ROMNAME:    DB    'SandR',0
  347.  
  348.  
  349. ;------
  350. OMEM:
  351. ;------
  352. ;Print insufficient Memory message and exit
  353.  
  354.     LXI    H,NOMEM
  355.     CALL    DSPMSG
  356.     CALL    GETCH
  357.     JMP    STDON
  358.  
  359.  
  360. NOMEM:        DB    12,'Insufficient Memory',13,10
  361.         DB    'Any Key to Exit',0
  362.  
  363.  
  364. ;------
  365. TRGINS:
  366. ;------
  367. ;Installs a 6 OR LESS character name as a ROM trigger file on the
  368. ;Model 100 directory.
  369. ;Entry: HL points to 6 OR LESS null TERMINATED
  370. ;    character string to use for the name.
  371. ;Exit:  None
  372.  
  373. ;1.    Test if a Trigger file exists
  374.  
  375.     PUSH    H        ;Save New File name.
  376.     CALL    FOTRG        ;Find an old trigger file
  377.     POP    D        ;File Name
  378.  
  379. ;2.    If so then install over it
  380.  
  381.     JNZ    TRGINS1        ;If found install over it.
  382.  
  383. ;3.    Otherwise locate a free directory
  384.  
  385.     PUSH    D        ;else
  386.     RST    6        ;Call Std ROM to
  387.     DW    FREDIR        ;Find an empty Slot.
  388.     POP    D        ;and install
  389.  
  390. ;4.    Copy in 0F0H file type and 0FFFFH start
  391.  
  392. TRGINS1:
  393.     MVI    M,0F0H        ;Trigger File type
  394.     INX    H        ;Step past start
  395.     MVI    M,0FFH        ;Set start to 0FFFFH
  396.     INX    H
  397.     MVI    M,0FFH
  398.     INX    H
  399.  
  400. ;5.    Copy the name to the first null and then
  401. ;    nulls to the rest of the name.
  402.     MVI    C,8        ;and copy in the name
  403.  
  404. TRGINS2:
  405.     LDAX    D
  406.     MOV    M,A
  407.     INX    H        ;Fill the rest of the
  408.     ORA    A        ;name with nulls when we
  409.     JZ    TRGINS3        ;hit the null terminator
  410.     INX    D
  411. TRGINS3:
  412.     DCR    C        ;directory name with nulls
  413.     JNZ    TRGINS2
  414.     RET
  415.  
  416. ;------
  417. FOTRG:
  418. ;------
  419. ;Searches the directory for an already existing trigger
  420. ;file and returns a pointer to it in HL if found.
  421. ;Entry:    None
  422. ;Exit:    Z set if none found
  423. ;        else
  424. ;    HL points to the directory entry
  425.  
  426.  
  427. ;1.    Starting behind the free directory
  428.     LXI    H,USRDIR-11    ;Free dir - 1 entry
  429.  
  430. ;2.    Get the next in use File
  431.  
  432. FOTRG1:
  433.     RST    6        ;Call Std ROM to
  434.     DW    NXTDIR        ;get Next Live File
  435.     RZ            ;no file found
  436.  
  437. ;3.    Return Pointing to it if it is a ROM
  438. ;    trigger file.
  439.  
  440.     MOV    A,M        ;is it a ROM Trigger
  441.     CPI    0F0H        ;Type
  442.     JNZ    FOTRG1        ;No - Go again
  443.     ANA    A        ;Clear Z flag
  444.     RET
  445.  
  446. ;------
  447. SANDR:
  448. ;------
  449. ;This routine calls a menu display like the Model 100
  450. ;System Menu but only including visible .DO files.
  451. ;The user may position the bar cursor over a file
  452. ;name and press enter to select a file for search
  453. ;and replace operations.
  454.  
  455. ;1.    Allocate Stack space for 24 words and
  456. ;    save the pointer to the space.
  457.     LXI    H,-48
  458.     DAD    SP
  459.     SPHL
  460. SANDR1:
  461.     PUSH    H
  462.  
  463. ;2.    Set all 48 bytes to 0FFH
  464.     MVI    C,48
  465. SANDR2:
  466.     MVI    M,0FFH
  467.     INX    H
  468.     DCR    C
  469.     JNZ    SANDR2
  470.  
  471. ;3.    Locate all DO files and save pointers to
  472. ;    Directory entries for each
  473.     POP    H        ;Pointer in HL
  474.     PUSH    H
  475.     CALL    FINDDO
  476.  
  477. ;4.    Display an empty menu
  478.     CALL    DISPEMPTY
  479.  
  480. ;5.    Write any active .DO files over the empty
  481. ;    slots.
  482.     POP    H        ;Pointer
  483.     PUSH    H
  484.     CALL    DISPDO
  485.  
  486. ;6.    Let user position the cursor and pick
  487.     POP    H        ;Pointer
  488.     PUSH    H
  489.     CALL    PICKDO
  490.  
  491.     POP    D        ;Pointer
  492. ;7.    If User selected F8 (7 in a reg) then exit
  493.     CPI    7
  494.     JZ    SANDR3
  495.  
  496. ;8.    The only other posibility is ENTER. Check
  497. ;    That the cursor was over a valid entry
  498. ;    Not 0FFFFH as user could have been looking
  499. ;    At a display with no .DO files. Directory user is
  500. ;    pointing to is returned in HL
  501.  
  502.     PUSH    D        ;Pointer
  503.     MOV    A,L
  504.     ANA    H
  505.     INR    A
  506.  
  507. ;9.    If it is legal then call the search and
  508. ;    Replace routine
  509.     CNZ    SR
  510.     POP    H
  511.  
  512. ;10.    And Redisplay the menu
  513.     JMP    SANDR1
  514.  
  515. SANDR3:
  516. ;7.    Deallocate the stack space.
  517.     LXI    H,48
  518.     DAD    SP
  519.     SPHL
  520.     RET
  521.  
  522. ;------
  523. FINDDO:
  524. ;------
  525. ;Entry:    HL points to a memory area for the storage of up to
  526. ;    24 pointers.
  527. ;Exit:    The memory area has been loaded with pointers to
  528. ;    Directory entries if any of .DO files in the
  529. ;    system.
  530.  
  531.     PUSH    H        ;Save Pointer
  532.  
  533. ;1.    Starting from one behind the first free
  534. ;    user directory slot.
  535.  
  536.     LXI    H,USRDIR-11    ;Start back one
  537.  
  538. ;2.    Find the next active file and return if none found
  539.  
  540. FINDDO1:
  541.     RST    6        ;Call Std ROM
  542.     DW    NXTDIR        ;To locate next active file
  543.     POP    D        ;Pointer
  544.     RZ            ;No more files
  545.  
  546. ;3.    Test the type byte for C0H = .DO file
  547.  
  548.     MOV    A,M        ;Get File Type
  549.     CPI    0C0H        ;Is it .DO type
  550.     JNZ    FINDDO2        ;Skip if not
  551.  
  552. ;4.    And save it if it is
  553.  
  554.     XCHG            ;else save pointer
  555.     MOV    M,E
  556.     INX    H
  557.     MOV    M,D
  558.     INX    H
  559.     XCHG
  560. FINDDO2:
  561.     PUSH    D
  562.     JMP    FINDDO1
  563.  
  564.  
  565. ;------
  566. DISPEMPTY:
  567. ;------
  568. ;Display a menu and screen of .DO Files
  569.  
  570. ;1.    Clear Screen
  571.  
  572.     RST    6        ;Call Std ROM to
  573.     DW    CLS        ;Clear The Screen
  574.  
  575. ;2.    Display the Logo
  576.  
  577.     LXI    H,LOGO        ;Display MSG
  578.     CALL    DSPMSG
  579.  
  580. ;3.    Position to the last line
  581.  
  582.     CALL    ROW8
  583.  
  584. ;4.    Display a mini-menu (Exit Option Only)
  585.  
  586.     LXI    H,MINIMENU
  587.     CALL    DSPMSG
  588.  
  589. ;5.    Display 24 empty slots
  590.  
  591.     CALL    SLOTS
  592.     RET
  593.  
  594.             ;1234567890123456789012345678901234567890
  595. LOGO:        DB    '   Search and Replace (c)1988 KCSI',0
  596. MINIMENU:    DB    ' --   --   --   --   --   --   --  Exit',0
  597.  
  598. ;------
  599. SLOTS:
  600. ;------
  601. ;Display 24 Empty slot positions on the bar cursor
  602. ;style screen
  603.  
  604. ;1.    From 0 to 23
  605.  
  606.     XRA    A        ;Starting from 0
  607. SLOTS1:
  608.     CPI    24        ;Stop when A passes 23
  609.     RZ
  610.  
  611. ;2.    Position to that slot
  612.  
  613.     MVI    H,0
  614.     MOV    L,A
  615.     PUSH    PSW        ;Save slot count
  616.     RST    6        ;Call Std ROM
  617.     DW    BARPOS        ;to move to bar position
  618.  
  619. ;3.    And print the '-.-' empty entry
  620.  
  621.     LXI    H,EMPTY        ;and print an empty
  622.     CALL    DSPMSG
  623.  
  624. ;4.    Next Slot
  625.  
  626.     POP    PSW        ;Slot count
  627.     INR    A
  628.     JMP    SLOTS1
  629.  
  630. EMPTY:        DB    '-.-',0
  631.  
  632.  
  633. ;------
  634. DISPDO:
  635. ;------
  636. ;Display .DO files at bar cursor positions.
  637. ;Entry    HL points to memory holding up to 24
  638. ;    pointers to directory entries of .DO files
  639.  
  640. ;1.    Save pointer and Allocate 10 bytes for formatted name
  641.  
  642.     XCHG
  643.     LXI    H,-10
  644.     DAD    SP
  645.     SPHL
  646.     XCHG
  647.  
  648. ;2.    For 0 to 23 entries
  649.  
  650.     MVI    C,0
  651. DISPDO1:
  652.     MOV    A,C
  653.     CPI    24
  654.     JZ    DISPDO2
  655.  
  656. ;3.    Or until the pointer points to 0FFFFH
  657.  
  658.     MOV    A,M
  659.     INX    H
  660.     ANA    M
  661.     INR    A
  662.     JZ    DISPDO2
  663.  
  664. ;4.    Get the Directory Entry
  665.  
  666.     PUSH    H        ;Pointer to Pointers
  667.     MOV    A,M
  668.     DCX    H
  669.     MOV    L,M
  670.     MOV    H,A
  671.  
  672. ;5.    Step to the file name portion
  673.  
  674.     INX    H
  675.     INX    H
  676.     INX    H
  677.  
  678. ;6.    Format    The Name
  679.  
  680.     PUSH    D        ;Buffer
  681.     PUSH    B        ;Slot Number
  682.     XCHG
  683.     RST    6        ;Call Std ROM
  684.     DW    MKPNAM        ;to Format the name
  685.     POP    H        ;Slot Number
  686.     PUSH    H
  687.  
  688. ;7.    Position the cursor
  689.  
  690.     RST    6        ;Call Std ROM
  691.     DW    BARPOS        ;for bar position
  692.     POP    B        ;Position
  693.     POP    H        ;Pointer to Buffer
  694.     PUSH    H
  695.     PUSH    B
  696.  
  697. ;8.    Display the formatted name
  698.  
  699.     CALL    DSPMSG        ;Display The Name
  700.  
  701. ;9.    Square up and go again
  702.  
  703.     POP    B        ;Bar Position
  704.     POP    D        ;Buffer Again
  705.     POP    H        ;Pointer to Pointers
  706.     INX    H        ;Adjusted
  707.     INR    C
  708.     JMP    DISPDO1
  709. DISPDO2:
  710.  
  711. ;10.    Clean up the stack
  712.  
  713.     LXI    H,10
  714.     DAD    SP
  715.     SPHL
  716.     RET
  717.     
  718. ;------
  719. PICKDO:
  720. ;------
  721. ;Allows bar cursor to be moved with left and right
  722. ;Arrows only
  723. ;Entry:    HL Contains base of array of pointers to 
  724. ;    to directory entries
  725. ;Exit:    HL Points to the Directory Entry the Bar Cursor
  726. ;    Was Over.
  727.  
  728.     XCHG            ;Pointer to DE
  729.  
  730. ;1.    Turn the cursor on at 0
  731.  
  732.     LXI    H,0        ;Starting from 0
  733.     PUSH    D
  734. PICKDO1:
  735.     CALL    BARTOG
  736.     JMP    PICKDO3
  737.  
  738. ;This entry is used to ring the beeper if the
  739. ;Key stroke is an error.
  740.  
  741. PICKDO2:
  742.     PUSH    H
  743.     RST    6        ;Call Std ROM
  744.     DW    BEEP        ;to BEEP
  745.     POP    H
  746.  
  747. ;2.    Get User Key stroke and dispatch accordingly
  748.  
  749. PICKDO3:
  750.     PUSH    H
  751.     CALL    GETCH
  752.  
  753. ;3.    Carry set indicates a function Key
  754. ;    If it is F8 (A=7) then bail out
  755.  
  756.     JNC    PICKDO4
  757.     POP    H
  758.     CPI    7
  759.     JNZ    PICKDO2        ;Beep and try again
  760.     POP    D        ;Else clear the stack
  761.     RET
  762.  
  763. ;3.    Left Arrow can move only if not at position zero.
  764.  
  765. PICKDO4:
  766.     CPI    29        ;Left Arrow
  767.     JNZ    PICKDO5
  768.     POP    H
  769.     MOV    A,H
  770.     ORA    L
  771.     JZ    PICKDO2        ;Can't move
  772.     CALL    BARTOG        ;else current position off
  773.     DCX    H
  774.     JMP    PICKDO1
  775.  
  776. ;4.    Right Arrow can move if new pointer is valid
  777. ;    If not valid, the cursor wraps to position 0
  778.  
  779. PICKDO5:
  780.     CPI    28        ;Right Arrow
  781.     JNZ    PICKDO7
  782.     POP    H        ;Can always move
  783.     CALL    BARTOG        ;SO toggle off
  784.     POP    D        ;Now Where do we go
  785.     INX    H        ;Up one
  786.     PUSH    H
  787.     DAD    H        ;Double it
  788.     DAD    D        ;Offset into table
  789.     MOV    A,M        ;If not FFFFH
  790.     INX    H        ;Then Move is legal
  791.     ANA    M
  792.     INR    A
  793.     POP    H
  794.     JNZ    PICKDO6        ;Legal
  795.     LXI    H,0        ;Not legal, wrap to zero
  796. PICKDO6:
  797.     PUSH    D        ;Restore the pointer
  798.     JMP    PICKDO1
  799.  
  800. ;5.    Last chance is for an ENTER key. If it is enter
  801. ;    Then return what is being pointed to.
  802.  
  803. PICKDO7:
  804.     CPI    13
  805.     POP    H
  806.     JNZ    PICKDO2        ;Invalid Key
  807.     POP    D
  808.     DAD    H        ;Position times 2
  809.     DAD    D        ;Plus Table base
  810.     MOV    A,M        ;and load the value
  811.     INX    H
  812.     MOV    H,M
  813.     MOV    L,A
  814.     RET
  815.  
  816. ;------
  817. BARTOG:
  818. ;------
  819. ;Toggles the bar cursor at the position specified in HL
  820. ;Hl is preserved and restored.
  821.  
  822.     PUSH    H
  823.     RST    6        ;Call Std ROM
  824.     DW    BARCUR        ;to toggle BAR
  825.     POP    H
  826.     RET    
  827.  
  828. ;------
  829. GETCH:
  830. ;------
  831. ;Poll the keyboard until a key is hit.
  832. ;Return the value in A register.
  833. ;C set if its a function key and A will =
  834. ;0=F1, 1=F2 ... 7=F8,8=LABEL,9=PRINT,10=SHIFT-PRINT,11=PASTE
  835.  
  836.     RST    6        ;Call Std ROM to
  837.     DW    KYREAD        ;Poll the keyboard
  838.     JZ    GETCH        ;Keep at it til something
  839.     RET            ;gotten
  840.  
  841.  
  842. ;------
  843. DSPMSG:
  844. ;------
  845. ;Display a NULL terminated message on the LCD
  846. ;Entry HL points to the message
  847. ;Exit HL points to the NULL at the end of the message
  848.  
  849. ;1.    Until the Character is null
  850.  
  851.     MOV    A,M        ;Get char
  852.     ORA    A
  853.     RZ            ;Return if NULL
  854.  
  855. ;2.    Send it to the screen
  856.  
  857.     PUSH    H        ;Save pointer
  858.     RST    6        ;Call Std ROM to
  859.     DW    CHROUT        ;Display it
  860.     POP    H        ;Restore Pointer
  861.  
  862. ;3.    Point to the next character
  863.  
  864.     INX    H        ;Next char
  865.     JMP    DSPMSG
  866.  
  867. ;------
  868. ROW8
  869. ;------
  870. ;Position Cursor to Column 1, Row 8
  871.  
  872.     LXI    H,(256*1)+8    ;Col 1 Row 8
  873.     RST    6        ;Call Std ROM
  874.     DW    CURPOS        ;to position cursor
  875.     RET
  876.  
  877. ;------------------------------------------------------
  878. ;Search and Replace Routine.
  879. ;------------------------------------------------------
  880.  
  881. ;------
  882. SR:
  883. ;------
  884. ;Ask User for Search and Replace strings and execute.
  885. ;Entry:    HL Points to a directory Entry for a TEXT
  886. ;File to be processed.
  887.  
  888. ;1.    Retrieve the start pointer from the directory
  889. ;    and save it
  890.  
  891.     INX    H
  892.     LXI    D,LOC
  893.     MOV    A,M
  894.     STAX    D
  895.     INX    H
  896.     INX    D
  897.     MOV    A,M
  898.     STAX    D
  899.  
  900. ;2.    Allocate two 21 byte buffers on the stack to hold
  901. ;    The search and Replace Strings and save pointers
  902.  
  903.     LXI    H,-42
  904.     DAD    SP
  905.     SPHL
  906.     SHLD    SEARCH
  907.     LXI    D,21
  908.     DAD    D
  909.     SHLD    REPLACE
  910.  
  911. ;3.    At ROw 8 Ask user for a search string and erase
  912. ;    the rest of Row 8
  913.  
  914.     CALL    ROW8
  915.  
  916.     LXI    H,SPROMPT
  917.     CALL    DSPMSG
  918.     RST    6        ;Call Std ROM
  919.     DW    ERAEOL        ;To clear to EOL
  920.  
  921. ;4.    Point to the search buffer and allow the user to
  922. ;    enter up to 20 bytes
  923.  
  924.     LXI    D,20
  925.     LHLD    SEARCH
  926.     CALL    GETSTR
  927.  
  928.  
  929. ;5.    The GETSTR routine returns the length of the
  930. ;    entered string in HL so save it
  931.  
  932.     SHLD    SEARCHLEN
  933.  
  934. ;6.    If the length is 0 (no search string) then
  935. ;    exit
  936.  
  937.     MOV    A,L
  938.     ORA    H
  939.     JZ    SR1
  940.  
  941. ;7.    At Row 8 ask the user for a replace string
  942. ;    and erase to end of line.
  943.  
  944.     CALL    ROW8
  945.  
  946.     LXI    H,RPROMPT
  947.     CALL    DSPMSG
  948.     RST    6        ;Call Std ROM
  949.     DW    ERAEOL        ;To clear to EOL
  950.  
  951. ;8.    Point to the replace buffer and allow 20
  952. ;    characters of replace text
  953.  
  954.     LXI    D,20
  955.     LHLD    REPLACE
  956.     CALL    GETSTR
  957.  
  958. ;9.    Save the length
  959.  
  960.     SHLD    REPLACELEN
  961.  
  962. ;10.    And do the search and replace
  963.  
  964.     CALL    SANDRPL
  965.  
  966. ;11.    Square up stack for the exit.
  967.  
  968. SR1:
  969.     LXI    H,42
  970.     DAD    SP
  971.     SPHL
  972.     RET
  973.  
  974. SPROMPT:    DB    'Search for :',0
  975. RPROMPT:    DB    'Replace with :',0
  976.  
  977. ;------
  978. SANDRPL:
  979. ;------
  980.  
  981. ;1.    Retrieve start of the file.
  982.  
  983.     LHLD    LOC
  984.  
  985. ;2.    If it is CTRLZ then we're all done.
  986.  
  987.     MOV    A,M
  988.     CPI    26
  989.     JZ    SANDRPL1
  990.  
  991. ;3.    Load file into HL and search string to DE
  992.  
  993.     XCHG
  994.     LHLD    SEARCH
  995.     XCHG
  996.  
  997. ;4.    And look for it
  998.  
  999.     CALL    CMPSTR
  1000.  
  1001. ;5.    Replace it there's a match
  1002.  
  1003.     CZ    RPL
  1004.  
  1005. ;6.    Step forward one in the file and try again
  1006.  
  1007.     LHLD    LOC
  1008.     INX    H
  1009.     SHLD    LOC
  1010.     JMP    SANDRPL
  1011.  
  1012. ;7.    On exit reorganize the directory before returning.
  1013.  
  1014. SANDRPL1:
  1015.     RST    6        ;Call Std ROM
  1016.     DW    DIROK        ;to re-organize
  1017.  
  1018.     RET
  1019. ;------
  1020. RPL:
  1021. ;------
  1022. ;Replace routine.
  1023. ;Entry:    LOC = Where to replace.
  1024. ;This routine could probably be improved since
  1025. ;MASDEL and MAKHOL supposedly preserve the HL
  1026. ;Register. It wouldn't be necessary to keep
  1027. ;reloading.
  1028.  
  1029. ;1.    Delete the length of the search string from the
  1030. ;    The file
  1031.  
  1032.     LHLD    SEARCHLEN
  1033.     PUSH    H
  1034.     POP    B
  1035.     LHLD    LOC
  1036.     RST    6        ;Call Std ROM
  1037.     DW    MASDEL        ;To Delete bytes
  1038.  
  1039. ;2.    Make a hole the length of the replace string
  1040.  
  1041.     LHLD    REPLACELEN
  1042.     PUSH    H
  1043.     POP    B
  1044.     LHLD    LOC
  1045.     RST    6        ;Call Std ROM
  1046.     DW    MAKHOL        ;to make the hole
  1047.  
  1048. ;3.    Copy the replacement string to the hole
  1049.  
  1050.     LHLD    REPLACELEN
  1051.     PUSH    H
  1052.     POP    B
  1053.     LHLD    LOC
  1054.     XCHG
  1055.     LHLD    REPLACE
  1056.     CALL    MEMCPY
  1057.  
  1058. ;4.    Increment the LOC pointer by Length - 1
  1059. ;    So that we don't end up with recursive
  1060. ;    Replacement
  1061.  
  1062.     LHLD    REPLACELEN
  1063.     XCHG
  1064.     LHLD    LOC
  1065.     DAD    D
  1066.     DCX    H
  1067.     SHLD    LOC
  1068.     RET
  1069.  
  1070. ;------
  1071. GETSTR
  1072. ;------
  1073. ;Allows entry of a string of the specified length (1-255)
  1074. ;Entry:    HL points to the receiving buffer
  1075. ;    DE contains the maximum length allowed
  1076. ;Exit:    HL contains actual length entered.
  1077.  
  1078.     PUSH    H        ;Buffer
  1079.  
  1080. ;1.    Get the pointer to the end of the string on
  1081. ;    the stack END = Start + Length and the start
  1082. ;    over that.
  1083.  
  1084.     PUSH    H        ;Buffer
  1085.     DAD    D        ;Limit or end of the buffer
  1086.     XTHL
  1087.  
  1088.  
  1089. ;2.    Turn on the cursor
  1090.  
  1091.     PUSH    H
  1092.     RST    6        ;Call Std ROM
  1093.     DW    CURSON        ;to turn it on.
  1094.     POP    D        ;Buffer
  1095.  
  1096. ;3.    Save the Buffer
  1097.  
  1098.     PUSH    D
  1099.  
  1100. ;4.    Get a character
  1101.  
  1102. GETSTR1:
  1103.     CALL    GETCH
  1104.  
  1105. ;5.    Ignore Function keys (Carry Set) Beep and go again
  1106.  
  1107.     JC    GETSTR4
  1108.  
  1109. ;6.    Carriage Return is the end of user input
  1110.  
  1111. GETSTR2:
  1112.     CPI    13
  1113.     JZ    GETSTR6
  1114.  
  1115. ;7.    A backspace can only be done if
  1116. ;    The current buffer pointer not =
  1117. ;    the start of the buffer
  1118.  
  1119.     CPI    8
  1120.     JNZ    GETSTR3
  1121.     POP    D        ;Current pointer
  1122.     POP    B        ;Buffer end
  1123.     POP    H        ;Buffer Start
  1124.     PUSH    H
  1125.     PUSH    B
  1126.     PUSH    D
  1127.     CALL    CMPHLDE        ;Compare HL and DE
  1128.     JZ    GETSTR4        ;Ignore if HL=DE
  1129.  
  1130. ;8.    If Okay then decrement the current buffer
  1131. ;    pointer
  1132.     POP    D
  1133.     DCX    D
  1134.     PUSH    D
  1135.  
  1136. ;9.    And display BS-SPACE-BS to clear the character
  1137. ;    on the screen and go again.
  1138.  
  1139.     LXI    H,RUBOUT
  1140.     CALL    DSPMSG
  1141.     JMP    GETSTR1
  1142.     
  1143. ;10.    Ignore all other control characters
  1144.  
  1145. GETSTR3:
  1146.     CPI    ' '
  1147.     JC    GETSTR4
  1148.  
  1149. ;11.    And hex 7FH
  1150.  
  1151.     CPI    07FH
  1152.     JZ    GETSTR4
  1153.  
  1154. ;12.    So we have a valid ASCII character. Check if the
  1155. ;    The current pointer is at the end of the buffer.
  1156. ;    If it is then ignore the input.
  1157.  
  1158.     MOV    C,A        ;Save The Character
  1159.     POP    D        ;Current Pointer
  1160.     POP    H        ;End of Buffer
  1161.     PUSH    H
  1162.     PUSH    D
  1163.     CALL    CMPHLDE        ;Compare
  1164.     JZ    GETSTR4        ;Ignore if equal
  1165.  
  1166. ;13.    The character is placed in the buffer and the
  1167. ;    Buffer is incremented.
  1168.  
  1169.     MOV    A,C
  1170.     POP    D
  1171.     STAX    D
  1172.     INX    D
  1173.     PUSH    D
  1174.  
  1175. ;14.    Display the character and go again.
  1176.  
  1177.     RST    6        ;Call Std ROM
  1178.     DW    CHROUT        ;to Display it
  1179.     JMP    GETSTR1
  1180.  
  1181. ;    Jumping to this address causes a beep and
  1182. ;    a jump back to the top, used for invalid characters
  1183.  
  1184. GETSTR4:
  1185.     RST    6        ;Call Std ROM
  1186.     DW    BEEP        ;to beep
  1187.     JMP    GETSTR1        ;And jump to the top
  1188.  
  1189. ;15.    This is the exit when CR is pressed. First
  1190. ;    Turn the cursor off
  1191.  
  1192. GETSTR6:
  1193.     RST    6        ;Call Std ROM
  1194.     DW    CUROFF        ;to turn it off
  1195.  
  1196. ;16.    Store a null at the current buffer pointer.
  1197.  
  1198.     POP    H        ;Buffer pointer
  1199.     XRA    A
  1200.     MOV    M,A
  1201.  
  1202. ;17.    Get the length in HL and exit
  1203.  
  1204.     POP    D        ;Limit or end of buffer
  1205.     POP    D        ;Start of Buffer
  1206.     MOV    A,L
  1207.     SUB    E
  1208.     MOV    L,A
  1209.     MOV    A,H
  1210.     SBB    D
  1211.     MOV    H,A
  1212.     RET
  1213.  
  1214. RUBOUT:        DB    8,' ',8,0
  1215.  
  1216. ;------
  1217. CMPHLDE
  1218. ;------
  1219. ;Compare HL and DE
  1220. ;Entry:    HL and DE with value to compare
  1221. ;Exit:    Z flag set if HL=DE
  1222. ;    Carry Set if DE>HL
  1223.  
  1224.     MOV    A,H
  1225.     CMP    D
  1226.     RNZ
  1227.     MOV    A,L
  1228.     CMP    E
  1229.     RET
  1230.  
  1231. ;------
  1232. CMPSTR:
  1233. ;------
  1234. ;Compare strings pointed to by HL and DE
  1235. ;Comparison stops when (DE)=0 success
  1236. ;Or (DE)<>(HL) = nomatch
  1237. ;Entry:    DE points to null terminated string to search for
  1238. ;    HL points to where in the file to match
  1239. ;Exit:    NZ if the match fails or Z if successful
  1240.  
  1241. ;1.    Retrieve a character from the search string.
  1242. ;    If it is null, then the search is successful
  1243.  
  1244.     LDAX    D
  1245.     ORA    A
  1246.     RZ
  1247.  
  1248. ;2.    Otherwise compare and return for mismatch
  1249.  
  1250.     CMP    M
  1251.     INX    H
  1252.     INX    D
  1253.     RNZ
  1254.  
  1255. ;3.    Go again
  1256.  
  1257.     JMP    CMPSTR
  1258.  
  1259. ;------
  1260. MEMCPY
  1261. ;------
  1262. ;Copy (HL) to (DE) for BC bytes
  1263.  
  1264. ;1.    Exit when BC exhausted
  1265.  
  1266.     MOV    A,C
  1267.     ORA    B
  1268.     RZ
  1269.  
  1270. ;2.    Otherwise move it and increment
  1271.  
  1272.     MOV    A,M
  1273.     STAX    D
  1274.     INX    H
  1275.     INX    D
  1276.     DCX    B
  1277.     JMP    MEMCPY
  1278.  
  1279.     END
  1280.