home.social

#ay38910 — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #ay38910, aggregated by home.social.

  1. RC2014/Z80 Minimal ROM

    I want to ROM-ify the messing about I’ve been doing with the AY-3-8910 driver and video code, so I need to figure out what boot-strapping is required to get a basic Z80 machine up and running from power-on. Then I can programme it all into a ROM and just have it startup automatically.

    Some key resources:

    To start, we can note the following from the Z80 User Manual:

    “RESET. Reset (input, active Low).”

    “RESET initializes the CPU as follows: it resets the interrupt enable flip-flop, clears the Program Counter and registers I and R, and sets the interrupt status to Mode 0. During reset time, the address and data bus enter a high-imped ance state, and all control output signals enter an inactive state. R must be active for a minimum of three full clock cycles before a reset operation is complete.”

    So execution will be starting from address $0000 (a cleared Program Counter).

    There are several special addresses that will require code – these are the RST locations associated with the RST instruction as described here: https://jnz.dk/z80/rst_p.html. RST is basically a 1-byte CALL equivalent, but it can only call one of eight locations: $00, $08, $10, $18, $20, $28, $30, $38.

    A key location for me will be RST $38 which is the interrupt handler I’ll need to handle for the /INT 50Hz interrupt.

    Other things that will have to be done on first power up include:

    • Any required memory initialisation – e.g. if any of it has to be set to zero or copied from ROM to RAM or anything that needs presetting to a specific value.
    • Any required hardware initialisation – e.g. for a R2014 this usually means getting the serial link up and running.
    • Set the stack pointer to somewhere at the top of RAM.
    • Initialise any hardware registers and then jump to the main application.

    I don’t think I need to do anything special to the CPU registers or flags, but happy to be corrected! I haven’t found an obvious “this is what you do to start a Z80” type resource so far, so I’m just inferring from the references listed above right now.

    AY Driver ROM

    Most of the code and data for the AY driver and tune can be relocated to ROM, but there are several blocks of state variables that must be placed in RAM. Consequently, I’ve had to do the following:

    • Create a RAM block at origin $8000 for the state variables.
    • Remove the origin statements for Code_Start and Data_Start, but I’ve replaced them with assembler labels.
    • Add in some code to pre-initialise the state variables all to zero on startup.
    • As well as the AY driver state variables, there are a few additional state variables associated with the following:
      • Positions related to the display harness
      • Some values associated with the CLOCK, one of which (FIFTY) also needs initialising to 50 on power up.
      • The AY driver’s internal “stack” (e.g. SP_A).
    • And it also turns out that it has to be able to clear the keypress that my own harness pre-sets to “0” otherwise it constantly resets to play the first tune. So I need to move that to RAM too.

    My initialisation code is as follows:

    ; RESET and Bootstrap
    .org $00
    jp AYSTART

    ; RST jump tables
    .org $08
    ret
    .org $10
    ret
    .org $18
    ret
    .org $20
    ret
    .org $28
    ret
    .org $30
    ret
    .org $38 ; Maskable /INT
    ei
    reti ; Return from interrupt
    .org $66 ; Non-maskable /NMI
    retn ; Return from non-maskable interrupt

    ; Bootstrap code
    .org $100
    AYSTART:
    ; Initialise stack
    ld sp, $FF00

    ; Set all AYVars in RAM to 0
    xor a
    VARINITLoop:
    ld hl, AYVARSTART
    ld bc,(AYVAREND-AYVARSTART)
    ld (hl),a
    inc hl
    dec bc
    jp nz,VARINITLoop

    ; Initialise any specific variable values
    ld hl,FIFTY
    ld a,50
    ld (hl),a

    ; Preset the keypress for first tune
    ld hl,LASTK
    ld a,48 ; Preset keypress to "0" for the first tune
    ld (hl),a

    ; Enable the 50Hz Interrupt
    im 1
    ei

    ; Run the driver
    jp Code_Start

    There are a couple of hard-coded references to address 50000 (decimal) which is Data_Start. These have had to be changed. The locations/definitions between the original CODE_BOT: and DATA_TOP: labels are now as follows:

    CODE_BOT:

    CALC1: EQU CODE_BOT-CODE_TOP
    ;--------------------------------------

    ; ORG Data_Start
    Data_Start:
    NTUNES: EQU 1
    NEFFECTS: EQU 1

    ;--------------------------------------
    CALC2: DW CALC
    Tunes: DB NTUNES
    Effects: DB NEFFECTS
    ;--------------------------------------

    DATA_TOP:

    The original code has 5 tunes and 21 effects which can be selected by pressing a key. I’ve not ported any keyboard handling over as yet, so it only plays the one tune. I’ve cleared out the data for four of the tunes and all the effects bar one. I’ve left one effect in as I don’t know how the code handles having zero effects.

    This has an advantage in that all fixed data and code now fits within 8K, which is the standard, common ROM block size for RC2014.

    Programming

    I can now take the standard ROM that came with my Classic II from here: https://github.com/RC2014Z80/RC2014/blob/master/ROMs/Factory/R0000009.BIN, which has the following ROMs built in:

    $0000-$1FFFRC2014 32K BASIC$2000-$3FFF
    $4000-$5FFF
    $6000-$7FFF
    $A000-$BFFF
    $C000-$DFFFUnused$E000-$EFFFSCM Z80 Monitor

    I can thus load this image into a programmer and then add in the HEX records for the AY driver at location $2000-3FFF remembering not to clear the loaded contents first. Then it will be selectable via the ROM jumpers

    The above location are EEPROM locations. The jumpers control the state of A13, A14, A15 as seen by the EEPROM. From the RC2014 point of view any selected image will always appear at address $0000-$1FFF in the wider memory map no matter its position in the EPROM.

    I’ve programmed it to W27C512s and used it with my RC2014 micro module, which takes 27C512 ROMS. My Classic II is described as also taking 27C512 ROMs, but the latest revision of the board actually uses half of a 128K ST39SF010.

    Conclusion

    It is great to be able to just turn on the RC2014 and have it come up playing the AY music. This means that for a complete player I now have:

    Kevin

    #ay38910 #rc2014 #zxSpectrum
  2. RC2014/Z80 Minimal ROM

    I want to ROM-ify the messing about I’ve been doing with the AY-3-8910 driver and video code, so I need to figure out what boot-strapping is required to get a basic Z80 machine up and running from power-on. Then I can programme it all into a ROM and just have it startup automatically.

    Some key resources:

    To start, we can note the following from the Z80 User Manual:

    “RESET. Reset (input, active Low).”

    “RESET initializes the CPU as follows: it resets the interrupt enable flip-flop, clears the Program Counter and registers I and R, and sets the interrupt status to Mode 0. During reset time, the address and data bus enter a high-imped ance state, and all control output signals enter an inactive state. R must be active for a minimum of three full clock cycles before a reset operation is complete.”

    So execution will be starting from address $0000 (a cleared Program Counter).

    There are several special addresses that will require code – these are the RST locations associated with the RST instruction as described here: https://jnz.dk/z80/rst_p.html. RST is basically a 1-byte CALL equivalent, but it can only call one of eight locations: $00, $08, $10, $18, $20, $28, $30, $38.

    A key location for me will be RST $38 which is the interrupt handler I’ll need to handle for the /INT 50Hz interrupt.

    Other things that will have to be done on first power up include:

    • Any required memory initialisation – e.g. if any of it has to be set to zero or copied from ROM to RAM or anything that needs presetting to a specific value.
    • Any required hardware initialisation – e.g. for a R2014 this usually means getting the serial link up and running.
    • Set the stack pointer to somewhere at the top of RAM.
    • Initialise any hardware registers and then jump to the main application.

    I don’t think I need to do anything special to the CPU registers or flags, but happy to be corrected! I haven’t found an obvious “this is what you do to start a Z80” type resource so far, so I’m just inferring from the references listed above right now.

    AY Driver ROM

    Most of the code and data for the AY driver and tune can be relocated to ROM, but there are several blocks of state variables that must be placed in RAM. Consequently, I’ve had to do the following:

    • Create a RAM block at origin $8000 for the state variables.
    • Remove the origin statements for Code_Start and Data_Start, but I’ve replaced them with assembler labels.
    • Add in some code to pre-initialise the state variables all to zero on startup.
    • As well as the AY driver state variables, there are a few additional state variables associated with the following:
      • Positions related to the display harness
      • Some values associated with the CLOCK, one of which (FIFTY) also needs initialising to 50 on power up.
      • The AY driver’s internal “stack” (e.g. SP_A).
    • And it also turns out that it has to be able to clear the keypress that my own harness pre-sets to “0” otherwise it constantly resets to play the first tune. So I need to move that to RAM too.

    My initialisation code is as follows:

    ; RESET and Bootstrap
    .org $00
    jp AYSTART

    ; RST jump tables
    .org $08
    ret
    .org $10
    ret
    .org $18
    ret
    .org $20
    ret
    .org $28
    ret
    .org $30
    ret
    .org $38 ; Maskable /INT
    ei
    reti ; Return from interrupt
    .org $66 ; Non-maskable /NMI
    retn ; Return from non-maskable interrupt

    ; Bootstrap code
    .org $100
    AYSTART:
    ; Initialise stack
    ld sp, $FF00

    ; Set all AYVars in RAM to 0
    xor a
    VARINITLoop:
    ld hl, AYVARSTART
    ld bc,(AYVAREND-AYVARSTART)
    ld (hl),a
    inc hl
    dec bc
    jp nz,VARINITLoop

    ; Initialise any specific variable values
    ld hl,FIFTY
    ld a,50
    ld (hl),a

    ; Preset the keypress for first tune
    ld hl,LASTK
    ld a,48 ; Preset keypress to "0" for the first tune
    ld (hl),a

    ; Enable the 50Hz Interrupt
    im 1
    ei

    ; Run the driver
    jp Code_Start

    There are a couple of hard-coded references to address 50000 (decimal) which is Data_Start. These have had to be changed. The locations/definitions between the original CODE_BOT: and DATA_TOP: labels are now as follows:

    CODE_BOT:

    CALC1: EQU CODE_BOT-CODE_TOP
    ;--------------------------------------

    ; ORG Data_Start
    Data_Start:
    NTUNES: EQU 1
    NEFFECTS: EQU 1

    ;--------------------------------------
    CALC2: DW CALC
    Tunes: DB NTUNES
    Effects: DB NEFFECTS
    ;--------------------------------------

    DATA_TOP:

    The original code has 5 tunes and 21 effects which can be selected by pressing a key. I’ve not ported any keyboard handling over as yet, so it only plays the one tune. I’ve cleared out the data for four of the tunes and all the effects bar one. I’ve left one effect in as I don’t know how the code handles having zero effects.

    This has an advantage in that all fixed data and code now fits within 8K, which is the standard, common ROM block size for RC2014.

    Programming

    I can now take the standard ROM that came with my Classic II from here: https://github.com/RC2014Z80/RC2014/blob/master/ROMs/Factory/R0000009.BIN, which has the following ROMs built in:

    $0000-$1FFFRC2014 32K BASIC$2000-$3FFF
    $4000-$5FFF
    $6000-$7FFF
    $A000-$BFFF
    $C000-$DFFFUnused$E000-$EFFFSCM Z80 Monitor

    I can thus load this image into a programmer and then add in the HEX records for the AY driver at location $2000-3FFF remembering not to clear the loaded contents first. Then it will be selectable via the ROM jumpers

    The above location are EEPROM locations. The jumpers control the state of A13, A14, A15 as seen by the EEPROM. From the RC2014 point of view any selected image will always appear at address $0000-$1FFF in the wider memory map no matter its position in the EPROM.

    I’ve programmed it to W27C512s and used it with my RC2014 micro module, which takes 27C512 ROMS. My Classic II is described as also taking 27C512 ROMs, but the latest revision of the board actually uses half of a 128K ST39SF010.

    Conclusion

    It is great to be able to just turn on the RC2014 and have it come up playing the AY music. This means that for a complete player I now have:

    Kevin

    #ay38910 #rc2014 #zxSpectrum