Generate due dates using function in a select statement
One solution uses recursion:

Setup

CREATE TABLE dbo.Test
(
    instno integer PRIMARY KEY,
    amount money NOT NULL,
    duedate date NULL
);
GO
INSERT dbo.Test
    (instno, amount, duedate)
VALUES
    (1, 1000.00, '20200130'),
    (2, 1000.00, NULL),
    (3, 1000.00, NULL),
    (4, 1000.00, NULL),
    (5, 1000.00, NULL);


CREATE FUNCTION dbo.SemiMonthlyAmortizationScheduleDate
    (@dt date)
RETURNS table
WITH SCHEMABINDING
AS
RETURN
    SELECT
        ScheduleDate =
            CASE 
                WHEN DAY(@dt) &lt; 16 
                THEN 
                    CASE 
                        WHEN MONTH(@dt) = 2 -- IF FEBRUARY, THEN GET LAST DAY OF MONTH 
                        THEN EOMONTH(@dt) 
                        ELSE DATEADD(DAY, 30 - DAY(@dt), @dt) -- SET AS 30
                    END 
            ELSE 
               DATEADD(MONTH, 1, DATEADD(DAY, 15 - DAY(@dt), @dt)) -- SET AS 15
            END;


Solution

WITH
    R AS
    (
        SELECT
            T.instno,
            T.amount,
            T.duedate
        FROM dbo.Test AS T
        ORDER BY 
            T.instno
            OFFSET 0 ROWS
            FETCH FIRST 1 ROW ONLY

        UNION ALL

        SELECT
            Top1.instno,
            Top1.amount,
            duedate = SD.ScheduleDate
        FROM 
        (
            SELECT
                T.instno,
                T.amount,
                R.duedate,
                rn = ROW_NUMBER() OVER (
                    ORDER BY T.instno ASC)
            FROM R
            JOIN dbo.Test AS T
                ON T.instno &gt; R.instno
        ) AS Top1
        CROSS APPLY dbo.SemiMonthlyAmortizationScheduleDate(Top1.duedate) AS SD
        WHERE
            Top1.rn = 1
    )
SELECT
    R.instno,
    R.amount,
    R.duedate
FROM R
ORDER BY
    R.instno;


Try it online at db&lt;>fiddle demo

The ROW_NUMBER thing is just a way to get TOP in the recursive part of a CTE see Performance Tuning the Whole Query Plan for details on that if you need it.

If you can use SQL CLR, a faster solution is available using the technique I show in my answer to How can I eliminate this costly index seek operation from my query?